Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Photoshop Integration #516

Open
tokejepsen opened this issue Jan 17, 2020 · 13 comments
Open

Photoshop Integration #516

tokejepsen opened this issue Jan 17, 2020 · 13 comments

Comments

@tokejepsen
Copy link
Collaborator

tokejepsen commented Jan 17, 2020

Issue

This is about a Photoshop (PS) Integration for Avalon.

Implementation

  • PS does not support Python, but we can communicate with PS through its DOM (Document Object Model). Best starting resource is; https://github.com/lohriialo/photoshop-scripting-python.
  • DOM communication with PS may not provide all the access we need. This needs to be investigated.
  • Another communication method would be through socket/port, where PS invokes a server/client relationship with Avalon on demand.
@tokejepsen
Copy link
Collaborator Author

Workfiles prototype

Untitled_ Jan 17 2020 6_30 PM

  • This is using the DOM workflow, which is quite easy to get into.
  • One issue with with Workfiles app, is that it was not intended for DCCs where you can have multiple files open. You can see that I've just resorted to opening v002 instead of closing v001. Maybe the Workfiles app needs to have an Close active workfile option?

@tokejepsen
Copy link
Collaborator Author

Menu Items

  • Menu items are not possible in Photoshop (and I assume the rest of the Adobe products).
  • Could provide a script for each menu item, and access them through File > Scripts. This would certainly be the quickest way to get going, but it would not allow for very easy updates. If we add a menu item, a new script will need to be deployed to each workstation.
  • Make a CEP extension, which can be accessed from Window > Extensions. Again updates to the extension would need to be distributed and installed on each workstation. But CEP can render html, so we could potentially host a local server and have the CEP extension be a passthrough.

@tokejepsen
Copy link
Collaborator Author

Extension

Untitled_ Jan 19 2020 10_50 PM

  • The Workfiles button is hosted in the extension, so not easily updatable but its a start.

@davidlatwe
Copy link
Collaborator

Looks like a good start indeed !!

@tokejepsen
Copy link
Collaborator Author

Separate Flask Server

Untitled_ Jan 20 2020 6_48 PM

  • Simplified the extension to only host a button for "Refresh" and an Iframe for the external process.
  • Running a Flask server with the Workfiles/Create... etc. buttons. Which means no hacked execution of batch scripts;
@app.route("/workfiles_route")
def workfiles_route():
    io.install()
    api.register_host(avalon.photoshop)
    workfiles.show()

    # Required return statement.
    return "nothing"
  • There is an issue where the Flask server exits when you try opening tools for the second time.
  • The tools (except for pyblish-qml) appear behind the Photoshop window. Will need to get them in front.
  • You dont have to restart Photoshop (just refresh the website), and when using Flask's debug mode you dont even have to restart the server.
    Untitled_ Jan 20 2020 6_53 PM
  • The context of the server determines the tools' context. Will need to have a "Launch Photoshop server" action or similar to get started.

@tokejepsen
Copy link
Collaborator Author

Untitled_ Jan 22, 2020 6_09 PM

  • Tools are appearing ontop of Photoshop. Quite possibly a loophole since apps arent supposed to appear infront of the active window. Done by launching a new process, which is how Pyblish-QML was the only one appearing ontop.
  • There are no icons when launching the tools standalone. When trying to investigate how the avalon-launcher fetches the icons, I noticed that its fetching it from outside the avalon module folder; https://github.com/getavalon/launcher/blame/1cec0a92e6af6e627072486d3f38bd53786981b3/launcher/lib.py#L17.
    Is this not "dangerous" since we are assuming the avalon module is pulled as a git repository? @davidlatwe
  • Note to self; since the server can be launched in any context, it might be nice to see the context along with the buttons.

@tokejepsen
Copy link
Collaborator Author

Untitled_ Jan 27, 2020 2_29 PM

  • Reverted using separate processes to launch the tools. This was introducing a world of trouble, when using the context manager because parent processes do not get the environment from their children. Added bonus is that the server only needs to be launched once and the context can be switched.
  • Switched to a vendorized Bottle.py webserver, so there are no external dependencies.
  • The tools are appearing ontop of Photoshop because of this PR; Fix #514 #520

@tokejepsen
Copy link
Collaborator Author

Unfortunately LayerSets cannot store metadata, so a possible solution is to have a layer within the LayerSet that stores the metadata for the container.
Certainly not ideal since the user can move the metadata layer around, but we can also link the layer and LayerSet to ensure we can get the metadata.

@tokejepsen
Copy link
Collaborator Author

One issue with using metadata on a layer, is that the user cannot actually interact with the data.

For example in Maya data is imprinted on the container, which allows users to manually change this data after creation.

It might be useful with a tools that reads/writes this imprinted data, so DCCs like Photoshop can have same interaction as Maya.

@tokejepsen
Copy link
Collaborator Author

tokejepsen commented Jan 29, 2020

  • Reverted back to using the DOM method for communicating with Photoshop.

When getting deeper into the integration it got apparent that passing objects around to different functions (imprint for example), communicating with Photoshop over socket/port became very tricky. So I took the "cheap" way out, and added the pywin32 (on Windows) dependency.
Maybe in the future there will be python library we can make use of.

@tokejepsen
Copy link
Collaborator Author

Untitled_ Jan 30, 2020 3_09 PM

  • Implemented avalon.photoshop.Creator

This involved other required methods; imprint and maintained_selection. Getting deeper into XMPMetadata turned out to be needlessly tricky. Instead I've opted to store the metadata in the file info Headline field. There may be a better place for this, but I chose this because (1) it provides easy access for debugging and (2) the Headline field in Photoshop is a multi-line edit so its a easy to copy.

Since I'm not storing the metadata on each layer instance, I've resorted to using each layers id which is unique. The data is a dictionary with these ids:

{
    "189": {
        "id": "pyblish.avalon.instance",
        "family": "image",
        "asset": "Bruce",
        "subset": "imageDefault",
        "active": true
    }
}

The nice thing about this approach is that LayerSets have ids as well, so there no need for additional layers as described here, making is cleaner and less user error prone.

@tokejepsen
Copy link
Collaborator Author

Documenting this to be fixed later.

When opening the Creator tool for the second time after creating an instance, this message appears:

Traceback (most recent call last):
  File "C:\Users\admin\avalon-docker\volume\git\avalon-core\avalon\tools\creator\app.py", line 465, in <lambda>
    lib.schedule(lambda: widget.setText(""), 5000, channel="message")
RuntimeError: wrapped C/C++ object of type QLabel has been deleted

@tokejepsen
Copy link
Collaborator Author

Publishing and Loading

compressed

Being able to go full circle marks the completion of the draft version of the Photoshop integration.
Will look at documentation and PR tomorrow.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants