Merge remote-tracking branch 'upstream/develop' into enhancement/unify-set-reset-buttons

This commit is contained in:
Roy Nieterau 2023-03-15 10:40:19 +01:00
commit 88400b2173
70 changed files with 6731 additions and 5596 deletions

View file

@ -1,6 +1,854 @@
# Changelog
[Full Changelog](https://github.com/ynput/OpenPype/compare/3.15.1...3.15.2)
### **🆕 New features**
<details>
<summary>maya gltf texture convertor and validator <a href="https://github.com/ynput/OpenPype/pull/4261">#4261</a></summary>
<strong>Continuity of the gltf extractor implementation
</strong>Continuity of the gltf extractor https://github.com/pypeclub/OpenPype/pull/4192UPDATE:**Validator for GLSL Shader**: Validate whether the mesh uses GLSL Shader. If not it will error out. The user can choose to perform the repair action and it will help to assign glsl shader. If the mesh with Stringray PBS, the repair action will also check to see if there is any linked texture such as Color, Occulsion, and Normal Map. If yes, it will help to relink the related textures to the glsl shader.*****If the mesh uses the PBS Shader,
___
</details>
<details>
<summary>Unreal: New Publisher <a href="https://github.com/ynput/OpenPype/pull/4370">#4370</a></summary>
<strong>Implementation of the new publisher for Unreal.
</strong>The implementation of the new publisher for Unreal. This PR includes the changes for all the existing creators to be compatible with the new publisher.The basic creator has been split in two distinct creators:
- `UnrealAssetCreator`, works with assets in the Content Browser.
- `UnrealActorCreator` that works with actors in the scene.
___
</details>
<details>
<summary>Implementation of a new splash screen <a href="https://github.com/ynput/OpenPype/pull/4592">#4592</a></summary>
Implemented a new splash screen widget to reflect a process running in the background. This widget can be used for other tasks than UE. **Also fixed the compilation error of the AssetContainer.cpp when trying to build the plugin in UE 5.0**
___
</details>
<details>
<summary>Deadline for 3dsMax <a href="https://github.com/ynput/OpenPype/pull/4439">#4439</a></summary>
<strong>Setting up deadline for 3dsmax
</strong>Setting up deadline for 3dsmax by setting render outputs and viewport camera
___
</details>
<details>
<summary>Nuke: adding nukeassist <a href="https://github.com/ynput/OpenPype/pull/4494">#4494</a></summary>
<strong>Adding support for NukeAssist
</strong>For support of NukeAssist we had to limit some Nuke features since NukeAssist itself Nuke with limitations. We do not support Creator and Publisher. User can only Load versions with version control. User can also set Framerange and Colorspace.
___
</details>
### **🚀 Enhancements**
<details>
<summary>Maya: OP-2630 acescg maya <a href="https://github.com/ynput/OpenPype/pull/4340">#4340</a></summary>
<strong>Resolves #2712
</strong>
___
</details>
<details>
<summary>Default Ftrack Family on RenderLayer <a href="https://github.com/ynput/OpenPype/pull/4458">#4458</a></summary>
<strong>With default settings, renderlayers in Maya were not being tagged with the Ftrack family leading to confusion when doing reviews.
</strong>
___
</details>
<details>
<summary>Maya: Maya Playblast Options - OP-3783 <a href="https://github.com/ynput/OpenPype/pull/4487">#4487</a></summary>
<strong>Replacement PR for #3912. Adds more options for playblasts to preferences/settings.
</strong>Adds the following as options in generating playblasts, matching viewport settings.
- Use default material
- Wireframe on shaded
- X-ray
- X-ray Joints
- X-ray active component
___
</details>
<details>
<summary>Maya: Passing custom attributes to alembic - OP-4111 <a href="https://github.com/ynput/OpenPype/pull/4516">#4516</a></summary>
<strong>Passing custom attributes to alembic
</strong>This PR makes it possible to pass all user defined attributes along to the alembic representation.
___
</details>
<details>
<summary>Maya: Options for VrayProxy output - OP-2010 <a href="https://github.com/ynput/OpenPype/pull/4525">#4525</a></summary>
<strong>Options for output of VrayProxy.
</strong>Client requested more granular control of output from VrayProxy instance. Exposed options on the instance and settings for vrmesh and alembic.
___
</details>
<details>
<summary>Maya: Validate missing instance attributes <a href="https://github.com/ynput/OpenPype/pull/4559">#4559</a></summary>
<strong>Validate missing instance attributes.
</strong>New attributes can be introduced as new features come in. Old instances will need to be updated with these attributes for the documentation to make sense, and users do not have to recreate the instances.
___
</details>
<details>
<summary>Refactored Generation of UE Projects, installation of plugins moved to the engine <a href="https://github.com/ynput/OpenPype/pull/4369">#4369</a></summary>
<strong>Improved the way how OpenPype works with generation of UE projects. Also the installation of the plugin has been altered to install into the engine
</strong>OpenPype now uses the appropriate tools to generate UE projects. Unreal Build Tool (UBT) and a "Commandlet Project" is needed to properly generate a BP project, or C++ code in case that `dev_mode = True`, folders, the .uproject file and many other resources.On the plugin's side, it is built seperately with the UnrealAutomationTool (UAT) and then it's contents are moved under the `Engine/Plugins/Marketplace/OpenPype` directory.
___
</details>
<details>
<summary>Unreal: Use client functions in Layout loader <a href="https://github.com/ynput/OpenPype/pull/4578">#4578</a></summary>
<strong>Use 'get_representations' instead of 'legacy_io' query in layout loader.
</strong>This is removing usage of `find_one` called on `legacy_io` and use rather client functions as preparation for AYON connection. Also all representations are queried at once instead of one by one.
___
</details>
<details>
<summary>General: Support for extensions filtering in loaders <a href="https://github.com/ynput/OpenPype/pull/4492">#4492</a></summary>
<strong>Added extensions filtering support to loader plugins.
</strong>To avoid possible backwards compatibility break is filtering exactly the same and filtering by extensions is enabled only if class attribute 'extensions' is set.
___
</details>
<details>
<summary>Nuke: multiple reformat in baking review profiles <a href="https://github.com/ynput/OpenPype/pull/4514">#4514</a></summary>
<strong>Added support for multiple reformat nodes in baking profiles.
</strong>Old settings for single reformat node is supported and prioritised just in case studios are using it and backward compatibility is needed. Warnings in Nuke terminal are notifying users to switch settings to new workflow. Settings are also explaining the migration way.
___
</details>
<details>
<summary>Nuke: Add option to use new creating system in workfile template builder <a href="https://github.com/ynput/OpenPype/pull/4545">#4545</a></summary>
<strong>Nuke workfile template builder can use new creators instead of legacy creators.
</strong>Modified workfile template builder to have option to say if legacy creators should be used or new creators. Legacy creators are disabled by default, so Maya has changed the value.
___
</details>
<details>
<summary>Global, Nuke: Workfile first version with template processing <a href="https://github.com/ynput/OpenPype/pull/4579">#4579</a></summary>
<strong>Supporting new template workfile builder with toggle for creation of first version of workfile in case there is none yet.
</strong>
___
</details>
<details>
<summary>Fusion: New Publisher <a href="https://github.com/ynput/OpenPype/pull/4523">#4523</a></summary>
<strong>This is an updated PR for @BigRoy 's old PR (https://github.com/ynput/OpenPype/pull/3892).I have merged it with code from OP 3.15.1-nightly.6 and made sure it works as expected.This converts the old publishing system to the new one. It implements Fusion as a new host addon.
</strong>
- Create button removed in OpenPype menu in favor of the new Publisher
- Draft refactor validations to raise PublishValidationError
- Implement Creator for New Publisher
- Implement Fusion as Host addon
___
</details>
<details>
<summary>TVPaint: Use Publisher tool <a href="https://github.com/ynput/OpenPype/pull/4471">#4471</a></summary>
<strong>Use Publisher tool and new creation system in TVPaint integration.
</strong>Using new creation system makes TVPaint integration a little bit easier to maintain for artists. Removed unneeded tools Creator and Subset Manager tools. Goal is to keep the integration work as close as possible to previous integration. Some changes were made but primarilly because they were not right using previous system.All creators create instance with final family instead of changing the family during extraction. Render passes are not related to group id but to render layer instance. Render layer is still related to group. Workfile, review and scene render instances are created using autocreators instead of auto-collection during publishing. Subset names are fully filled during publishing but instance labels are filled on refresh with the last known right value. Implemented basic of legacy convertor which should convert render layers and render passes.
___
</details>
<details>
<summary>TVPaint: Auto-detect render creation <a href="https://github.com/ynput/OpenPype/pull/4496">#4496</a></summary>
<strong>Create plugin which will create Render Layer and Render Pass instances based on information in the scene.
</strong>Added new creator that must be triggered by artist. The create plugin will first create Render Layer instances if were not created yet. For variant is used color group name. The creator has option to rename color groups by template defined in settings -> Template may use index of group by it's usage in scene (from bottom to top). After Render Layers will create Render Passes. Render Pass is created for each individual TVPaint layer in any group that had created Render Layer. It's name is used as variant (pass).
___
</details>
<details>
<summary>TVPaint: Small enhancements <a href="https://github.com/ynput/OpenPype/pull/4501">#4501</a></summary>
<strong>Small enhancements in TVPaint integration which did not get to https://github.com/ynput/OpenPype/pull/4471.
</strong>It was found out that `opacity` returned from `tv_layerinfo` is always empty and is dangerous to add it to layer information. Added information about "current" layer to layers information. Disable review of Render Layer and Render Pass instances by default. In most of productions is used only "scene review". Skip usage of `"enabled"` key from settings in automated layer/pass creation.
___
</details>
<details>
<summary>Global: color v3 global oiio transcoder plugin <a href="https://github.com/ynput/OpenPype/pull/4291">#4291</a></summary>
<strong>Implements possibility to use `oiiotool` to transcode image sequences from one color space to another(s).
</strong>Uses collected `colorspaceData` information about source color spaces, these information needs to be collected previously in each DCC interested in color management.Uses profiles configured in Settings to create single or multiple new representations (and file extensions) with different color spaces.New representations might replace existing one, each new representation might contain different tags and custom tags to control its integration step.
___
</details>
<details>
<summary>Deadline: Added support for multiple install dirs in Deadline <a href="https://github.com/ynput/OpenPype/pull/4451">#4451</a></summary>
<strong>SearchDirectoryList returns FIRST existing so if you would have multiple OP install dirs, it won't search for appropriate version in later ones.
</strong>
___
</details>
<details>
<summary>Ftrack: Upload reviewables with original name <a href="https://github.com/ynput/OpenPype/pull/4483">#4483</a></summary>
<strong>Ftrack can integrate reviewables with original filenames.
</strong>As ftrack have restrictions about names of components the only way how to achieve the result was to upload the same file twice, one with required name and one with origin name.
___
</details>
<details>
<summary>TVPaint: Ignore transparency in Render Pass <a href="https://github.com/ynput/OpenPype/pull/4499">#4499</a></summary>
<strong>It is possible to ignore layers transparency during Render Pass extraction.
</strong>Render pass extraction does not respect opacity of TVPaint layers set in scene during extraction. It can be enabled/disabled in settings.
___
</details>
<details>
<summary>Anatomy: Preparation for different root overrides <a href="https://github.com/ynput/OpenPype/pull/4521">#4521</a></summary>
<strong>Prepare Anatomy to handle only 'studio' site override on it's own.
</strong>Change how Anatomy fill root overrides based on requested site name. The logic which decide what is active site was moved to sync server addon and the same for receiving root overrides of local site. The Anatomy resolve only studio site overrides anything else is handled by sync server. BaseAnatomy only expect root overrides value and does not need site name. Validation of site name happens in sync server same as resolving if site name is local or not.
___
</details>
<details>
<summary>Nuke | Global: colormanaged plugin in collection <a href="https://github.com/ynput/OpenPype/pull/4556">#4556</a></summary>
<strong>Colormanaged extractor had changed to Mixin class so it can be added to any stage of publishing rather then just to Exctracting.Nuke is no collecting colorspaceData to representation collected on already rendered images.
</strong>Mixin class can no be used as secondary parent in publishing plugins.
___
</details>
### **🐛 Bug fixes**
<details>
<summary>look publishing and srgb colorspace in maya <a href="https://github.com/ynput/OpenPype/pull/4276">#4276</a></summary>
<strong>Check the OCIO color management is enabled before doing linearize colorspace for converting the texture maps into tx files.
</strong>Check whether the OCIO color management is enabled before the condition of converting the texture to tx extension.
___
</details>
<details>
<summary>Maya: extract Thumbnail "No active model panel found" - OP-3849 <a href="https://github.com/ynput/OpenPype/pull/4421">#4421</a></summary>
<strong>Error when extracting playblast with no model panel.
</strong>If `project_settings/maya/publish/ExtractPlayblast/capture_preset/Viewport Options/override_viewport_options` were off and publishing without showing any model panel, the extraction would fail.
___
</details>
<details>
<summary>Maya: Fix setting scene fps with float input <a href="https://github.com/ynput/OpenPype/pull/4488">#4488</a></summary>
<strong>Returned value of float fps on integer values would return float.
</strong>This PR fixes the case when switching between integer fps values for example 24 > 25. Issue was when setting the scene fps, the original float value was used which makes it unpredictable whether the value is float or integer when mapping the fps values.
___
</details>
<details>
<summary>Maya: Multipart fix <a href="https://github.com/ynput/OpenPype/pull/4497">#4497</a></summary>
<strong>Fix multipart logic in render products.
</strong>Each renderer has a different way of defining whether output images is multipart, so we need to define it for each renderer. Also before the `multipart` class variable was defined multiple times in several places, which made it tricky to debug where `multipart` was defined. Now its created on initialization and referenced as `self.multipart`
___
</details>
<details>
<summary>Maya: Set pool on tile assembly - OP-2012 <a href="https://github.com/ynput/OpenPype/pull/4520">#4520</a></summary>
<strong>Set pool on tile assembly
</strong>Pool for publishing and tiling jobs, need to use the settings (`project_settings/deadline/publish/ProcessSubmittedJobOnFarm/deadline_pool`) else fallback on primary pool (`project_settings/deadline/publish/CollectDeadlinePools/primary_pool`)
___
</details>
<details>
<summary>Maya: Extract review with handles <a href="https://github.com/ynput/OpenPype/pull/4527">#4527</a></summary>
<strong>Review was not extracting properly with/without handles.
</strong>Review instance was not created properly resulting in the frame range on the instance including handles.
___
</details>
<details>
<summary>Maya: Fix broken lib. <a href="https://github.com/ynput/OpenPype/pull/4529">#4529</a></summary>
<strong>Fix broken lib.
</strong>This commit from this PR broke the Maya lib module.
___
</details>
<details>
<summary>Maya: Validate model name - OP-4983 <a href="https://github.com/ynput/OpenPype/pull/4539">#4539</a></summary>
<strong>Validate model name issues.
</strong>Couple of issues with validate model name;
- missing platform extraction from settings
- map function should be list comprehension
- code cosmetics
___
</details>
<details>
<summary>Maya: SkeletalMesh family loadable as reference <a href="https://github.com/ynput/OpenPype/pull/4573">#4573</a></summary>
<strong>In Maya, fix the SkeletalMesh family not loadable as reference.
</strong>
___
</details>
<details>
<summary>Unreal: fix loaders because of missing AssetContainer <a href="https://github.com/ynput/OpenPype/pull/4536">#4536</a></summary>
<strong>Fixing Unreal loaders, where changes in OpenPype Unreal integration plugin deleted AssetContainer.
</strong>`AssetContainer` and `AssetContainerFactory` are still used to mark loaded instances. Because of optimizations in Integration plugin we've accidentally removed them but that broke loader.
___
</details>
<details>
<summary>3dsmax unable to delete loaded asset in the scene inventory <a href="https://github.com/ynput/OpenPype/pull/4507">#4507</a></summary>
<strong>Fix the bug of being unable to delete loaded asset in the Scene Inventory
</strong>Fix the bug of being unable to delete loaded asset in the Scene Inventory
___
</details>
<details>
<summary>Hiero/Nuke: originalBasename editorial publishing and loading <a href="https://github.com/ynput/OpenPype/pull/4453">#4453</a></summary>
<strong>Publishing and loading `originalBasename` is working as expected
</strong>Frame-ranges on version document is now correctly defined to fit original media frame range which is published. It means loading is now correctly identifying frame start and end on clip loader in Nuke.
___
</details>
<details>
<summary>Nuke: Fix workfile template placeholder creation <a href="https://github.com/ynput/OpenPype/pull/4512">#4512</a></summary>
<strong>Template placeholder creation was erroring out in Nuke due to the Workfile template builder not being able to find any of the plugins for the Nuke host.
</strong>Move `get_workfile_build_placeholder_plugins` function to NukeHost class as workfile template builder expects.
___
</details>
<details>
<summary>Nuke: creator farm attributes from deadline submit plugin settings <a href="https://github.com/ynput/OpenPype/pull/4519">#4519</a></summary>
<strong>Defaults in farm attributes are sourced from settings.
</strong>Settings for deadline nuke submitter are now used during nuke render and prerender creator plugins.
___
</details>
<details>
<summary>Nuke: fix clip sequence loading <a href="https://github.com/ynput/OpenPype/pull/4574">#4574</a></summary>
<strong>Nuke is loading correctly clip from image sequence created without "{originalBasename}" token in anatomy template.
</strong>
___
</details>
<details>
<summary>Fusion: Fix files collection and small bug-fixes <a href="https://github.com/ynput/OpenPype/pull/4423">#4423</a></summary>
<strong>Fixed Fusion review-representation and small bug-fixes
</strong>This fixes the problem with review-file generation that stopped the publishing on second publish before the fix.The problem was that Fusion simply looked at all the files in the render-folder instead of only gathering the needed frames for the review.Also includes a fix to get the handle start/end that before throw an error if the data didn't exist (like from a kitsu sync).
___
</details>
<details>
<summary>Fusion: Updated render_local.py to not only process the first instance <a href="https://github.com/ynput/OpenPype/pull/4522">#4522</a></summary>
Moved the `__hasRun` to `render_once()` so the check only happens with the rendering. Currently only the first render node gets the representations added.Critical PR
___
</details>
<details>
<summary>Fusion: Load sequence fix filepath resolving from representation <a href="https://github.com/ynput/OpenPype/pull/4580">#4580</a></summary>
<strong>Resolves issue mentioned on discord by @movalex:The loader was incorrectly trying to find the file in the publish folder which resulted in just picking 'any first file'.
</strong>This gets the filepath from representation instead of taking the first file from listing files from publish folder.
___
</details>
<details>
<summary>Fusion: Fix review burnin start and end frame <a href="https://github.com/ynput/OpenPype/pull/4590">#4590</a></summary>
Fix the burnin start and end frame for reviews. Without this the asset document's start and end handle would've been added to the _burnin_ frame range even though that would've been incorrect since the handles are based on the comp saver's render range instead.
___
</details>
<details>
<summary>Harmony: missing set of frame range when opening scene <a href="https://github.com/ynput/OpenPype/pull/4485">#4485</a></summary>
<strong>Frame range gets set from DB everytime scene is opened.
</strong>Added also check for not up-to-date loaded containers.
___
</details>
<details>
<summary>Photoshop: context is not changed in publisher <a href="https://github.com/ynput/OpenPype/pull/4570">#4570</a></summary>
<strong>When PS is already open and artists launch new task, it should keep only opened PS open, but change context.
</strong>Problem were occurring in Workfile app where under new task files from old task were shown. This fixes this and adds opening of last workfile for new context if workfile exists.
___
</details>
<details>
<summary>hiero: fix effect item node class <a href="https://github.com/ynput/OpenPype/pull/4543">#4543</a></summary>
<strong>Collected effect name after renaming is saving correct class name.
</strong>
___
</details>
<details>
<summary>Bugfix/OP-4616 vray multipart <a href="https://github.com/ynput/OpenPype/pull/4297">#4297</a></summary>
<strong>This fixes a bug where multipart vray renders would not make a review in Ftrack.
</strong>
___
</details>
<details>
<summary>Maya: Fix changed location of reset_frame_range <a href="https://github.com/ynput/OpenPype/pull/4491">#4491</a></summary>
<strong>Location in commands caused cyclic import
</strong>
___
</details>
<details>
<summary>global: source template fixed frame duplication <a href="https://github.com/ynput/OpenPype/pull/4503">#4503</a></summary>
<strong>Duplication is not happening.
</strong>Template is using `originalBasename` which already assume all necessary elements are part of the file name so there was no need for additional optional name elements.
___
</details>
<details>
<summary>Deadline: Hint to use Python 3 <a href="https://github.com/ynput/OpenPype/pull/4518">#4518</a></summary>
<strong>Added shebank to give deadline hint which python should be used.
</strong>Deadline has issues with Python 2 (especially with `os.scandir`). When a shebank is added to file header deadline will use python 3 mode instead of python 2 which fix the issue.
___
</details>
<details>
<summary>Publisher: Prevent access to create tab after publish start <a href="https://github.com/ynput/OpenPype/pull/4528">#4528</a></summary>
<strong>Prevent access to create tab after publish start.
</strong>Disable create button in instance view on publish start and enable it again on reset. Even with that make sure that it is not possible to go to create tab if the tab is disabled.
___
</details>
<details>
<summary>Color Transcoding: store target_colorspace as new colorspace <a href="https://github.com/ynput/OpenPype/pull/4544">#4544</a></summary>
<strong>When transcoding into new colorspace, representation must carry this information instead original color space.
</strong>
___
</details>
<details>
<summary>Deadline: fix submit_publish_job <a href="https://github.com/ynput/OpenPype/pull/4552">#4552</a></summary>
<strong>Fix submit_publish_job
</strong>Resolves #4541
___
</details>
<details>
<summary>Kitsu: Fix task itteration in update-op-with-zou <a href="https://github.com/ynput/OpenPype/pull/4577">#4577</a></summary>
From the last PR (https://github.com/ynput/OpenPype/pull/4425) a comment-commit last second messed up the code and resulted in two lines being the same, crashing the script. This PR fixes that.
___
</details>
<details>
<summary>AttrDefs: Fix type for PySide6 <a href="https://github.com/ynput/OpenPype/pull/4584">#4584</a></summary>
<strong>Use right type in signal emit for value change of attribute definitions.
</strong>Changed `UUID` type to `str`. This is not an issue with PySide2 but it is with PySide6.
___
</details>
### **🔀 Refactored code**
<details>
<summary>Scene Inventory: Avoid using ObjectId <a href="https://github.com/ynput/OpenPype/pull/4524">#4524</a></summary>
<strong>Avoid using conversion to ObjectId type in scene inventory tool.
</strong>Preparation for AYON compatibility where ObjectId won't be used for ids. Representation ids from loaded containers are not converted to ObjectId but kept as strings which also required some changes when working with representation documents.
___
</details>
### **Merged pull requests**
<details>
<summary>SiteSync: host dirmap is not working properly <a href="https://github.com/ynput/OpenPype/pull/4563">#4563</a></summary>
<strong>If artists uses SiteSync with real remote (gdrive, dropbox, sftp) drive, Local Settings were throwing error `string indices must be integers`.
</strong>Logic was reworked to provide only `local_drive` values to be overrriden by Local Settings. If remote site is `gdrive` etc. mapping to `studio` is provided as it is expected that workfiles will have imported from `studio` location and not from `gdrive` folder.Also Nuke dirmap was reworked to be less verbose and much faster.
___
</details>
<details>
<summary>General: Input representation ids are not ObjectIds <a href="https://github.com/ynput/OpenPype/pull/4576">#4576</a></summary>
<strong>Don't use `ObjectId` as representation ids during publishing.
</strong>Representation ids are kept as strings during publishing instead of converting them to `ObjectId`. This change is pre-requirement for AYON connection.Inputs are used for integration of links and for farm publishing (or at least it looks like).
___
</details>
<details>
<summary>Shotgrid: Fixes on Deadline submissions <a href="https://github.com/ynput/OpenPype/pull/4498">#4498</a></summary>
<strong>A few other bug fixes for getting Nuke submission to Deadline work smoothly using Shotgrid integration.
</strong>Continuing on the work done on this other PR this fixes a few other bugs I came across with further tests.
___
</details>
<details>
<summary>Fusion: New Publisher <a href="https://github.com/ynput/OpenPype/pull/3892">#3892</a></summary>
<strong>This converts the old publishing system to the new one. It implements Fusion as a new host addon.
</strong>
- Create button removed in OpenPype menu in favor of the new Publisher
- Draft refactor validations to raise `PublishValidationError`
- Implement Creator for New Publisher
- Implement Fusion as Host addon
___
</details>
<details>
<summary>Make Kitsu work with Tray Publisher, added kitsureview tag, fixed sync-problems. <a href="https://github.com/ynput/OpenPype/pull/4425">#4425</a></summary>
<strong>Make Kitsu work with Tray Publisher, added kitsureview tag, fixed sync-problems.
</strong>This PR updates the way the module gather info for the current publish so it now works with Tray Publisher.It fixes the data that gets synced from Kitsu to OP so all needed data gets registered even if it doesn't exist on Kitsus side.It also adds the tag "Add review to Kitsu" and adds it to Burn In so previews gets generated by default to Kitsu.
___
</details>
<details>
<summary>Maya: V-Ray Set Image Format from settings <a href="https://github.com/ynput/OpenPype/pull/4566">#4566</a></summary>
<strong>Resolves #4565
</strong>Set V-Ray Image Format using settings.
___
</details>
## [3.15.1](https://github.com/ynput/OpenPype/tree/3.15.1)
[Full Changelog](https://github.com/ynput/OpenPype/compare/3.15.0...3.15.1)

View file

@ -367,11 +367,15 @@ def run(script):
"--timeout",
help="Provide specific timeout value for test case",
default=None)
@click.option("-so",
"--setup_only",
help="Only create dbs, do not run tests",
default=None)
def runtests(folder, mark, pyargs, test_data_folder, persist, app_variant,
timeout):
timeout, setup_only):
"""Run all automatic tests after proper initialization via start.py"""
PypeCommands().run_tests(folder, mark, pyargs, test_data_folder,
persist, app_variant, timeout)
persist, app_variant, timeout, setup_only)
@main.command()

View file

@ -39,7 +39,6 @@ class HostDirmap(object):
self._project_settings = project_settings
self._sync_module = sync_module # to limit reinit of Modules
self._log = None
self._mapping = None # cache mapping
@property
def sync_module(self):
@ -70,29 +69,28 @@ class HostDirmap(object):
"""Run host dependent remapping from source_path to destination_path"""
pass
def process_dirmap(self):
def process_dirmap(self, mapping=None):
# type: (dict) -> None
"""Go through all paths in Settings and set them using `dirmap`.
If artists has Site Sync enabled, take dirmap mapping directly from
Local Settings when artist is syncing workfile locally.
Args:
project_settings (dict): Settings for current project.
"""
if not self._mapping:
self._mapping = self.get_mappings(self.project_settings)
if not self._mapping:
if not mapping:
mapping = self.get_mappings()
if not mapping:
return
self.log.info("Processing directory mapping ...")
self.on_enable_dirmap()
self.log.info("mapping:: {}".format(self._mapping))
for k, sp in enumerate(self._mapping["source-path"]):
dst = self._mapping["destination-path"][k]
for k, sp in enumerate(mapping["source-path"]):
dst = mapping["destination-path"][k]
try:
# add trailing slash if missing
sp = os.path.join(sp, '')
dst = os.path.join(dst, '')
print("{} -> {}".format(sp, dst))
self.dirmap_routine(sp, dst)
except IndexError:
@ -110,28 +108,24 @@ class HostDirmap(object):
)
continue
def get_mappings(self, project_settings):
def get_mappings(self):
"""Get translation from source-path to destination-path.
It checks if Site Sync is enabled and user chose to use local
site, in that case configuration in Local Settings takes precedence
"""
local_mapping = self._get_local_sync_dirmap(project_settings)
dirmap_label = "{}-dirmap".format(self.host_name)
if (
not self.project_settings[self.host_name].get(dirmap_label)
and not local_mapping
):
return {}
mapping_settings = self.project_settings[self.host_name][dirmap_label]
mapping_enabled = mapping_settings["enabled"] or bool(local_mapping)
mapping_sett = self.project_settings[self.host_name].get(dirmap_label,
{})
local_mapping = self._get_local_sync_dirmap()
mapping_enabled = mapping_sett.get("enabled") or bool(local_mapping)
if not mapping_enabled:
return {}
mapping = (
local_mapping
or mapping_settings["paths"]
or mapping_sett["paths"]
or {}
)
@ -141,28 +135,27 @@ class HostDirmap(object):
or not mapping.get("source-path")
):
return {}
self.log.info("Processing directory mapping ...")
self.log.info("mapping:: {}".format(mapping))
return mapping
def _get_local_sync_dirmap(self, project_settings):
def _get_local_sync_dirmap(self):
"""
Returns dirmap if synch to local project is enabled.
Only valid mapping is from roots of remote site to local site set
in Local Settings.
Args:
project_settings (dict)
Returns:
dict : { "source-path": [XXX], "destination-path": [YYYY]}
"""
project_name = os.getenv("AVALON_PROJECT")
mapping = {}
if not project_settings["global"]["sync_server"]["enabled"]:
if (not self.sync_module.enabled or
project_name not in self.sync_module.get_enabled_projects()):
return mapping
project_name = os.getenv("AVALON_PROJECT")
active_site = self.sync_module.get_local_normalized_site(
self.sync_module.get_active_site(project_name))
remote_site = self.sync_module.get_local_normalized_site(
@ -171,11 +164,7 @@ class HostDirmap(object):
"active {} - remote {}".format(active_site, remote_site)
)
if (
active_site == "local"
and project_name in self.sync_module.get_enabled_projects()
and active_site != remote_site
):
if active_site == "local" and active_site != remote_site:
sync_settings = self.sync_module.get_sync_project_setting(
project_name,
exclude_locals=False,
@ -188,7 +177,15 @@ class HostDirmap(object):
self.log.debug("local overrides {}".format(active_overrides))
self.log.debug("remote overrides {}".format(remote_overrides))
current_platform = platform.system().lower()
remote_provider = self.sync_module.get_provider_for_site(
project_name, remote_site
)
# dirmap has sense only with regular disk provider, in the workfile
# wont be root on cloud or sftp provider
if remote_provider != "local_drive":
remote_site = "studio"
for root_name, active_site_dir in active_overrides.items():
remote_site_dir = (
remote_overrides.get(root_name)

View file

@ -10,7 +10,7 @@
import hou
from openpype.tools.utils import host_tools
parent = hou.qt.mainWindow()
host_tools.show_creator(parent)
host_tools.show_publisher(parent, tab="create")
]]></scriptCode>
</scriptItem>
@ -30,7 +30,7 @@ host_tools.show_loader(parent=parent, use_context=True)
import hou
from openpype.tools.utils import host_tools
parent = hou.qt.mainWindow()
host_tools.show_publisher(parent)
host_tools.show_publisher(parent, tab="publish")
]]></scriptCode>
</scriptItem>

View file

@ -101,7 +101,9 @@ class MaxCreator(Creator, MaxCreatorBase):
instance_node = rt.getNodeByName(
instance.data.get("instance_node"))
if instance_node:
rt.delete(rt.getNodeByName(instance_node))
rt.select(instance_node)
rt.execute(f'for o in selection do for c in o.children do c.parent = undefined') # noqa
rt.delete(instance_node)
self._remove_instance_from_context(instance)

View file

@ -11,6 +11,7 @@ import maya.mel as mel
from openpype import resources
from openpype.tools.utils import host_tools
from .lib import get_main_window
from ..tools import show_look_assigner
log = logging.getLogger(__name__)
@ -112,7 +113,7 @@ def override_toolbox_ui():
annotation="Look Manager",
label="Look Manager",
image=os.path.join(icons, "lookmanager.png"),
command=host_tools.show_look_assigner,
command=show_look_assigner,
width=icon_size,
height=icon_size,
parent=parent

View file

@ -3576,6 +3576,65 @@ def get_color_management_output_transform():
return colorspace
def image_info(file_path):
# type: (str) -> dict
"""Based on tha texture path, get its bit depth and format information.
Take reference from makeTx.py in Arnold:
ImageInfo(filename): Get Image Information for colorspace
AiTextureGetFormat(filename): Get Texture Format
AiTextureGetBitDepth(filename): Get Texture bit depth
Args:
file_path (str): Path to the texture file.
Returns:
dict: Dictionary with the information about the texture file.
"""
from arnold import (
AiTextureGetBitDepth,
AiTextureGetFormat
)
# Get Texture Information
img_info = {'filename': file_path}
if os.path.isfile(file_path):
img_info['bit_depth'] = AiTextureGetBitDepth(file_path) # noqa
img_info['format'] = AiTextureGetFormat(file_path) # noqa
else:
img_info['bit_depth'] = 8
img_info['format'] = "unknown"
return img_info
def guess_colorspace(img_info):
# type: (dict) -> str
"""Guess the colorspace of the input image filename.
Note:
Reference from makeTx.py
Args:
img_info (dict): Image info generated by :func:`image_info`
Returns:
str: color space name use in the `--colorconvert`
option of maketx.
"""
from arnold import (
AiTextureInvalidate,
# types
AI_TYPE_BYTE,
AI_TYPE_INT,
AI_TYPE_UINT
)
try:
if img_info['bit_depth'] <= 16:
if img_info['format'] in (AI_TYPE_BYTE, AI_TYPE_INT, AI_TYPE_UINT): # noqa
return 'sRGB'
else:
return 'linear'
# now discard the image file as AiTextureGetFormat has loaded it
AiTextureInvalidate(img_info['filename']) # noqa
except ValueError:
print(("[maketx] Error: Could not guess"
"colorspace for {}").format(img_info["filename"]))
return "linear"
def len_flattened(components):
"""Return the length of the list as if it was flattened.

View file

@ -12,6 +12,7 @@ from openpype.pipeline.workfile import BuildWorkfile
from openpype.tools.utils import host_tools
from openpype.hosts.maya.api import lib, lib_rendersettings
from .lib import get_main_window, IS_HEADLESS
from ..tools import show_look_assigner
from .workfile_template_builder import (
create_placeholder,
@ -139,7 +140,7 @@ def install():
cmds.menuItem(
"Look assigner...",
command=lambda *args: host_tools.show_look_assigner(
command=lambda *args: show_look_assigner(
parent_widget
)
)

View file

@ -134,7 +134,7 @@ class ConnectGeometry(InventoryAction):
bool
"""
from Qt import QtWidgets
from qtpy import QtWidgets
accept = QtWidgets.QMessageBox.Ok
if show_cancel:

View file

@ -149,7 +149,7 @@ class ConnectXgen(InventoryAction):
bool
"""
from Qt import QtWidgets
from qtpy import QtWidgets
accept = QtWidgets.QMessageBox.Ok
if show_cancel:

View file

@ -2,7 +2,6 @@ import os
import clique
import maya.cmds as cmds
import mtoa.ui.arnoldmenu
from openpype.settings import get_project_settings
from openpype.pipeline import (
@ -36,6 +35,11 @@ class ArnoldStandinLoader(load.LoaderPlugin):
color = "orange"
def load(self, context, name, namespace, options):
# Make sure to load arnold before importing `mtoa.ui.arnoldmenu`
cmds.loadPlugin("mtoa", quiet=True)
import mtoa.ui.arnoldmenu
version = context['version']
version_data = version.get("data", {})

View file

@ -3,7 +3,7 @@ import os
import maya.cmds as cmds
import xgenm
from Qt import QtWidgets
from qtpy import QtWidgets
import openpype.hosts.maya.api.plugin
from openpype.hosts.maya.api.lib import (

View file

@ -23,6 +23,9 @@ class CollectReview(pyblish.api.InstancePlugin):
task = legacy_io.Session["AVALON_TASK"]
# Get panel.
instance.data["panel"] = cmds.playblast(activeEditor=True)
# get cameras
members = instance.data['setMembers']
cameras = cmds.ls(members, long=True,

View file

@ -16,6 +16,7 @@ import pyblish.api
from openpype.lib import source_hash, run_subprocess
from openpype.pipeline import legacy_io, publish
from openpype.hosts.maya.api import lib
from openpype.hosts.maya.api.lib import image_info, guess_colorspace
# Modes for transfer
COPY = 1
@ -367,16 +368,25 @@ class ExtractLook(publish.Extractor):
for filepath in files_metadata:
linearize = False
if do_maketx and files_metadata[filepath]["color_space"].lower() == "srgb": # noqa: E501
linearize = True
# set its file node to 'raw' as tx will be linearized
files_metadata[filepath]["color_space"] = "Raw"
# if OCIO color management enabled
# it won't take the condition of the files_metadata
ocio_maya = cmds.colorManagementPrefs(q=True,
cmConfigFileEnabled=True,
cmEnabled=True)
if do_maketx and not ocio_maya:
if files_metadata[filepath]["color_space"].lower() == "srgb": # noqa: E501
linearize = True
# set its file node to 'raw' as tx will be linearized
files_metadata[filepath]["color_space"] = "Raw"
# if do_maketx:
# color_space = "Raw"
source, mode, texture_hash = self._process_texture(
filepath,
resource,
do_maketx,
staging=staging_dir,
linearize=linearize,
@ -482,7 +492,8 @@ class ExtractLook(publish.Extractor):
resources_dir, basename + ext
)
def _process_texture(self, filepath, do_maketx, staging, linearize, force):
def _process_texture(self, filepath, resource,
do_maketx, staging, linearize, force):
"""Process a single texture file on disk for publishing.
This will:
1. Check whether it's already published, if so it will do hardlink
@ -524,10 +535,47 @@ class ExtractLook(publish.Extractor):
texture_hash
]
if linearize:
self.log.info("tx: converting sRGB -> linear")
additional_args.extend(["--colorconvert", "sRGB", "linear"])
if cmds.colorManagementPrefs(query=True, cmEnabled=True):
render_colorspace = cmds.colorManagementPrefs(query=True,
renderingSpaceName=True) # noqa
config_path = cmds.colorManagementPrefs(query=True,
configFilePath=True) # noqa
if not os.path.exists(config_path):
raise RuntimeError("No OCIO config path found!")
color_space_attr = resource["node"] + ".colorSpace"
try:
color_space = cmds.getAttr(color_space_attr)
except ValueError:
# node doesn't have color space attribute
if cmds.loadPlugin("mtoa", quiet=True):
img_info = image_info(filepath)
color_space = guess_colorspace(img_info)
else:
color_space = "Raw"
self.log.info("tx: converting {0} -> {1}".format(color_space, render_colorspace)) # noqa
additional_args.extend(["--colorconvert",
color_space,
render_colorspace])
else:
if cmds.loadPlugin("mtoa", quiet=True):
img_info = image_info(filepath)
color_space = guess_colorspace(img_info)
if color_space == "sRGB":
self.log.info("tx: converting sRGB -> linear")
additional_args.extend(["--colorconvert",
"sRGB",
"Raw"])
else:
self.log.info("tx: texture's colorspace "
"is already linear")
else:
self.log.warning("cannot guess the colorspace"
"color conversion won't be available!") # noqa
config_path = get_ocio_config_path("nuke-default")
additional_args.extend(["--colorconfig", config_path])
# Ensure folder exists
if not os.path.exists(os.path.dirname(converted)):

View file

@ -118,7 +118,6 @@ class ExtractPlayblast(publish.Extractor):
# Need to explicitly enable some viewport changes so the viewport is
# refreshed ahead of playblasting.
panel = cmds.getPanel(withFocus=True)
keys = [
"useDefaultMaterial",
"wireframeOnShaded",
@ -129,10 +128,12 @@ class ExtractPlayblast(publish.Extractor):
viewport_defaults = {}
for key in keys:
viewport_defaults[key] = cmds.modelEditor(
panel, query=True, **{key: True}
instance.data["panel"], query=True, **{key: True}
)
if preset["viewport_options"][key]:
cmds.modelEditor(panel, edit=True, **{key: True})
cmds.modelEditor(
instance.data["panel"], edit=True, **{key: True}
)
override_viewport_options = (
capture_presets['Viewport Options']['override_viewport_options']
@ -147,12 +148,10 @@ class ExtractPlayblast(publish.Extractor):
# Update preset with current panel setting
# if override_viewport_options is turned off
panel = cmds.getPanel(withFocus=True) or ""
if not override_viewport_options and "modelPanel" in panel:
panel_preset = capture.parse_active_view()
if not override_viewport_options:
panel_preset = capture.parse_view(instance.data["panel"])
panel_preset.pop("camera")
preset.update(panel_preset)
cmds.setFocus(panel)
self.log.info(
"Using preset:\n{}".format(
@ -163,7 +162,10 @@ class ExtractPlayblast(publish.Extractor):
path = capture.capture(log=self.log, **preset)
# Restoring viewport options.
cmds.modelEditor(panel, edit=True, **viewport_defaults)
if viewport_defaults:
cmds.modelEditor(
instance.data["panel"], edit=True, **viewport_defaults
)
cmds.setAttr("{}.panZoomEnabled".format(preset["camera"]), pan_zoom)

View file

@ -0,0 +1,26 @@
from maya import cmds
import pyblish.api
from openpype.pipeline.publish import ValidateContentsOrder
from openpype.pipeline import PublishValidationError
class ValidateMayaColorSpace(pyblish.api.InstancePlugin):
"""
Check if the OCIO Color Management and maketx options
enabled at the same time
"""
order = ValidateContentsOrder
families = ['look']
hosts = ['maya']
label = 'Color Management with maketx'
def process(self, instance):
ocio_maya = cmds.colorManagementPrefs(q=True,
cmConfigFileEnabled=True,
cmEnabled=True)
maketx = instance.data["maketx"]
if ocio_maya and maketx:
raise PublishValidationError("Maya is color managed and maketx option is on. OpenPype doesn't support this combination yet.") # noqa

View file

@ -0,0 +1,27 @@
from openpype.tools.utils.host_tools import qt_app_context
class MayaToolsSingleton:
_look_assigner = None
def get_look_assigner_tool(parent):
"""Create, cache and return look assigner tool window."""
if MayaToolsSingleton._look_assigner is None:
from .mayalookassigner import MayaLookAssignerWindow
mayalookassigner_window = MayaLookAssignerWindow(parent)
MayaToolsSingleton._look_assigner = mayalookassigner_window
return MayaToolsSingleton._look_assigner
def show_look_assigner(parent=None):
"""Look manager is Maya specific tool for look management."""
with qt_app_context():
look_assigner_tool = get_look_assigner_tool(parent)
look_assigner_tool.show()
# Pull window to the front.
look_assigner_tool.raise_()
look_assigner_tool.activateWindow()
look_assigner_tool.showNormal()

View file

@ -2861,10 +2861,10 @@ class NukeDirmap(HostDirmap):
pass
def dirmap_routine(self, source_path, destination_path):
log.debug("{}: {}->{}".format(self.file_name,
source_path, destination_path))
source_path = source_path.lower().replace(os.sep, '/')
destination_path = destination_path.lower().replace(os.sep, '/')
log.debug("Map: {} with: {}->{}".format(self.file_name,
source_path, destination_path))
if platform.system().lower() == "windows":
self.file_name = self.file_name.lower().replace(
source_path, destination_path)
@ -2878,6 +2878,7 @@ class DirmapCache:
_project_name = None
_project_settings = None
_sync_module = None
_mapping = None
@classmethod
def project_name(cls):
@ -2897,6 +2898,36 @@ class DirmapCache:
cls._sync_module = ModulesManager().modules_by_name["sync_server"]
return cls._sync_module
@classmethod
def mapping(cls):
return cls._mapping
@classmethod
def set_mapping(cls, mapping):
cls._mapping = mapping
def dirmap_file_name_filter(file_name):
"""Nuke callback function with single full path argument.
Checks project settings for potential mapping from source to dest.
"""
dirmap_processor = NukeDirmap(
file_name,
"nuke",
DirmapCache.project_name(),
DirmapCache.project_settings(),
DirmapCache.sync_module(),
)
if not DirmapCache.mapping():
DirmapCache.set_mapping(dirmap_processor.get_mappings())
dirmap_processor.process_dirmap(DirmapCache.mapping())
if os.path.exists(dirmap_processor.file_name):
return dirmap_processor.file_name
return file_name
@contextlib.contextmanager
def node_tempfile():
@ -2942,25 +2973,6 @@ def duplicate_node(node):
return dupli_node
def dirmap_file_name_filter(file_name):
"""Nuke callback function with single full path argument.
Checks project settings for potential mapping from source to dest.
"""
dirmap_processor = NukeDirmap(
file_name,
"nuke",
DirmapCache.project_name(),
DirmapCache.project_settings(),
DirmapCache.sync_module(),
)
dirmap_processor.process_dirmap()
if os.path.exists(dirmap_processor.file_name):
return dirmap_processor.file_name
return file_name
def get_group_io_nodes(nodes):
"""Get the input and the output of a group of nodes."""

View file

@ -1472,13 +1472,15 @@ class SyncServerModule(OpenPypeModule, ITrayModule):
return sync_settings
def get_all_site_configs(self, project_name=None):
def get_all_site_configs(self, project_name=None,
local_editable_only=False):
"""
Returns (dict) with all sites configured system wide.
Args:
project_name (str)(optional): if present, check if not disabled
local_editable_only (bool)(opt): if True return only Local
Setting configurable (for LS UI)
Returns:
(dict): {'studio': {'provider':'local_drive'...},
'MY_LOCAL': {'provider':....}}
@ -1499,9 +1501,21 @@ class SyncServerModule(OpenPypeModule, ITrayModule):
if site_settings:
detail.update(site_settings)
system_sites[site] = detail
system_sites.update(self._get_default_site_configs(sync_enabled,
project_name))
if local_editable_only:
local_schema = SyncServerModule.get_local_settings_schema()
editable_keys = {}
for provider_code, editables in local_schema.items():
editable_keys[provider_code] = ["enabled", "provider"]
for editable_item in editables:
editable_keys[provider_code].append(editable_item["key"])
for _, site in system_sites.items():
provider = site["provider"]
for site_config_key in list(site.keys()):
if site_config_key not in editable_keys[provider]:
site.pop(site_config_key, None)
return system_sites

View file

@ -270,7 +270,7 @@ class PypeCommands:
pass
def run_tests(self, folder, mark, pyargs,
test_data_folder, persist, app_variant, timeout):
test_data_folder, persist, app_variant, timeout, setup_only):
"""
Runs tests from 'folder'
@ -311,6 +311,9 @@ class PypeCommands:
if timeout:
args.extend(["--timeout", timeout])
if setup_only:
args.extend(["--setup_only", setup_only])
print("run_tests args: {}".format(args))
import pytest
pytest.main(args)

View file

@ -330,6 +330,11 @@
"optional": true,
"active": true
},
"ValidateMayaColorSpace": {
"enabled": true,
"optional": true,
"active": true
},
"ValidateAttributes": {
"enabled": false,
"attributes": {}

View file

@ -350,7 +350,7 @@ How output of the schema could look like on save:
- number input, can be used for both integer and float
- key `"decimal"` defines how many decimal places will be used, 0 is for integer input (Default: `0`)
- key `"minimum"` as minimum allowed number to enter (Default: `-99999`)
- key `"maxium"` as maximum allowed number to enter (Default: `99999`)
- key `"maximum"` as maximum allowed number to enter (Default: `99999`)
- key `"steps"` will change single step value of UI inputs (using arrows and wheel scroll)
- for UI it is possible to show slider to enable this option set `show_slider` to `true`
```

View file

@ -144,6 +144,10 @@
{
"key": "ValidateShadingEngine",
"label": "Validate Look Shading Engine Naming"
},
{
"key": "ValidateMayaColorSpace",
"label": "ValidateMayaColorSpace"
}
]
},

View file

@ -295,10 +295,10 @@ class SubsetWidget(QtWidgets.QWidget):
self.model.set_grouping(state)
def _subset_changed(self, text):
if hasattr(self.proxy, "setFilterRegularExpression"):
self.proxy.setFilterRegularExpression(text)
else:
if hasattr(self.proxy, "setFilterRegExp"):
self.proxy.setFilterRegExp(text)
else:
self.proxy.setFilterRegularExpression(text)
self.view.expandAll()
def set_loading_state(self, loading, empty):

View file

@ -482,10 +482,10 @@ class FilterProxyModel(QtCore.QSortFilterProxyModel):
return True
# Filter by regex
if hasattr(self, "filterRegularExpression"):
regex = self.filterRegularExpression()
else:
if hasattr(self, "filterRegExp"):
regex = self.filterRegExp()
else:
regex = self.filterRegularExpression()
pattern = regex.pattern()
if pattern:
pattern = re.escape(pattern)

View file

@ -160,10 +160,10 @@ class SceneInventoryWindow(QtWidgets.QDialog):
self._model.set_hierarchy_view(enabled)
def _on_text_filter_change(self, text_filter):
if hasattr(self._proxy, "setFilterRegularExpression"):
self._proxy.setFilterRegularExpression(text_filter)
else:
if hasattr(self._proxy, "setFilterRegExp"):
self._proxy.setFilterRegExp(text_filter)
else:
self._proxy.setFilterRegularExpression(text_filter)
def _on_outdated_state_change(self):
self._proxy.set_filter_outdated(

View file

@ -272,7 +272,7 @@ class SitesWidget(QtWidgets.QWidget):
)
site_configs = sync_server_module.get_all_site_configs(
self._project_name)
self._project_name, local_editable_only=True)
roots_entity = (
self.project_settings[PROJECT_ANATOMY_KEY][LOCAL_ROOTS_KEY]

View file

@ -27,10 +27,10 @@ class RecursiveSortFilterProxyModel(QtCore.QSortFilterProxyModel):
if not parent.isValid():
return False
if hasattr(self, "filterRegularExpression"):
regex = self.filterRegularExpression()
else:
if hasattr(self, "filterRegExp"):
regex = self.filterRegExp()
else:
regex = self.filterRegularExpression()
pattern = regex.pattern()
if pattern and regex.isValid():
@ -111,10 +111,10 @@ class SearchEntitiesDialog(QtWidgets.QDialog):
def _on_filter_timer(self):
text = self._filter_edit.text()
if hasattr(self._proxy, "setFilterRegularExpression"):
self._proxy.setFilterRegularExpression(text)
else:
if hasattr(self._proxy, "setFilterRegExp"):
self._proxy.setFilterRegExp(text)
else:
self._proxy.setFilterRegularExpression(text)
# WARNING This expanding and resizing is relatively slow.
self._view.expandAll()

View file

@ -5,10 +5,10 @@ from qtpy import QtCore
class RecursiveSortFilterProxyModel(QtCore.QSortFilterProxyModel):
"""Filters to the regex if any of the children matches allow parent"""
def filterAcceptsRow(self, row, parent):
if hasattr(self, "filterRegularExpression"):
regex = self.filterRegularExpression()
else:
if hasattr(self, "filterRegExp"):
regex = self.filterRegExp()
else:
regex = self.filterRegularExpression()
pattern = regex.pattern()
if pattern:
model = self.sourceModel()

View file

@ -38,7 +38,6 @@ class HostToolsHelper:
self._subset_manager_tool = None
self._scene_inventory_tool = None
self._library_loader_tool = None
self._look_assigner_tool = None
self._experimental_tools_dialog = None
@property
@ -219,27 +218,6 @@ class HostToolsHelper:
raise ImportError("No Pyblish GUI found")
def get_look_assigner_tool(self, parent):
"""Create, cache and return look assigner tool window."""
if self._look_assigner_tool is None:
from openpype.tools.mayalookassigner import MayaLookAssignerWindow
mayalookassigner_window = MayaLookAssignerWindow(parent)
self._look_assigner_tool = mayalookassigner_window
return self._look_assigner_tool
def show_look_assigner(self, parent=None):
"""Look manager is Maya specific tool for look management."""
with qt_app_context():
look_assigner_tool = self.get_look_assigner_tool(parent)
look_assigner_tool.show()
# Pull window to the front.
look_assigner_tool.raise_()
look_assigner_tool.activateWindow()
look_assigner_tool.showNormal()
def get_experimental_tools_dialog(self, parent=None):
"""Dialog of experimental tools.
@ -315,9 +293,6 @@ class HostToolsHelper:
elif tool_name == "sceneinventory":
return self.get_scene_inventory_tool(parent, *args, **kwargs)
elif tool_name == "lookassigner":
return self.get_look_assigner_tool(parent, *args, **kwargs)
elif tool_name == "publish":
self.log.info("Can't return publish tool window.")
@ -356,9 +331,6 @@ class HostToolsHelper:
elif tool_name == "sceneinventory":
self.show_scene_inventory(parent, *args, **kwargs)
elif tool_name == "lookassigner":
self.show_look_assigner(parent, *args, **kwargs)
elif tool_name == "publish":
self.show_publish(parent, *args, **kwargs)
@ -436,10 +408,6 @@ def show_scene_inventory(parent=None):
_SingletonPoint.show_tool_by_name("sceneinventory", parent)
def show_look_assigner(parent=None):
_SingletonPoint.show_tool_by_name("lookassigner", parent)
def show_publish(parent=None):
_SingletonPoint.show_tool_by_name("publish", parent)

View file

@ -202,11 +202,20 @@ class RecursiveSortFilterProxyModel(QtCore.QSortFilterProxyModel):
Use case: Filtering by string - parent won't be filtered if does not match
the filter string but first checks if any children does.
"""
def __init__(self, *args, **kwargs):
super(RecursiveSortFilterProxyModel, self).__init__(*args, **kwargs)
recursive_enabled = False
if hasattr(self, "setRecursiveFilteringEnabled"):
self.setRecursiveFilteringEnabled(True)
recursive_enabled = True
self._recursive_enabled = recursive_enabled
def filterAcceptsRow(self, row, parent_index):
if hasattr(self, "filterRegularExpression"):
regex = self.filterRegularExpression()
else:
if hasattr(self, "filterRegExp"):
regex = self.filterRegExp()
else:
regex = self.filterRegularExpression()
pattern = regex.pattern()
if pattern:
@ -219,8 +228,9 @@ class RecursiveSortFilterProxyModel(QtCore.QSortFilterProxyModel):
# Check current index itself
value = model.data(source_index, self.filterRole())
if re.search(pattern, value, re.IGNORECASE):
return True
matched = bool(re.search(pattern, value, re.IGNORECASE))
if matched or self._recursive_enabled:
return matched
rows = model.rowCount(source_index)
for idx in range(rows):

View file

@ -1,3 +1,3 @@
# -*- coding: utf-8 -*-
"""Package declaring Pype version."""
__version__ = "3.15.2-nightly.6"
__version__ = "3.15.3-nightly.1"

View file

@ -1,6 +1,6 @@
[tool.poetry]
name = "OpenPype"
version = "3.15.1" # OpenPype
version = "3.15.2" # OpenPype
description = "Open VFX and Animation pipeline with support."
authors = ["OpenPype Team <info@openpype.io>"]
license = "MIT License"

View file

@ -24,6 +24,11 @@ def pytest_addoption(parser):
help="Overwrite default timeout"
)
parser.addoption(
"--setup_only", action="store", default=None,
help="True - only setup test, do not run any tests"
)
@pytest.fixture(scope="module")
def test_data_folder(request):
@ -45,6 +50,11 @@ def timeout(request):
return request.config.getoption("--timeout")
@pytest.fixture(scope="module")
def setup_only(request):
return request.config.getoption("--setup_only")
@pytest.hookimpl(tryfirst=True, hookwrapper=True)
def pytest_runtest_makereport(item, call):
# execute all other hooks to obtain the report object

View file

@ -243,6 +243,8 @@ class PublishTest(ModuleUnitTest):
PERSIST = True # True - keep test_db, test_openpype, outputted test files
TEST_DATA_FOLDER = None # use specific folder of unzipped test file
SETUP_ONLY = False
@pytest.fixture(scope="module")
def app_name(self, app_variant):
"""Returns calculated value for ApplicationManager. Eg.(nuke/12-2)"""
@ -286,8 +288,13 @@ class PublishTest(ModuleUnitTest):
@pytest.fixture(scope="module")
def launched_app(self, dbcon, download_test_data, last_workfile_path,
startup_scripts, app_args, app_name, output_folder_url):
startup_scripts, app_args, app_name, output_folder_url,
setup_only):
"""Launch host app"""
if setup_only or self.SETUP_ONLY:
print("Creating only setup for test, not launching app")
yield
return
# set schema - for integrate_new
from openpype import PACKAGE_DIR
# Path to OpenPype's schema
@ -316,8 +323,12 @@ class PublishTest(ModuleUnitTest):
@pytest.fixture(scope="module")
def publish_finished(self, dbcon, launched_app, download_test_data,
timeout):
timeout, setup_only):
"""Dummy fixture waiting for publish to finish"""
if setup_only or self.SETUP_ONLY:
print("Creating only setup for test, not launching app")
yield False
return
import time
time_start = time.time()
timeout = timeout or self.TIMEOUT
@ -334,11 +345,16 @@ class PublishTest(ModuleUnitTest):
def test_folder_structure_same(self, dbcon, publish_finished,
download_test_data, output_folder_url,
skip_compare_folders):
skip_compare_folders,
setup_only):
"""Check if expected and published subfolders contain same files.
Compares only presence, not size nor content!
"""
if setup_only or self.SETUP_ONLY:
print("Creating only setup for test, not launching app")
return
published_dir_base = output_folder_url
expected_dir_base = os.path.join(download_test_data,
"expected")

View file

@ -27,4 +27,4 @@ import TabItem from '@theme/TabItem';
- for more details on how to use it go [here](admin_use#check-for-mongodb-database-connection)
## OPENPYPE_USERNAME
- if set it overides system created username
- if set it overrides system created username

View file

@ -142,7 +142,7 @@ Fill in the necessary fields (the optional fields are regex filters)
![new place holder](assets/maya-placeholder_new.png)
- Builder type: Wether the the placeholder should load current asset representations or linked assets representations
- Builder type: Whether the the placeholder should load current asset representations or linked assets representations
- Representation: Representation that will be loaded (ex: ma, abc, png, etc...)

View file

@ -7,12 +7,15 @@ sidebar_label: Working with settings
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
OpenPype stores all of it's settings and configuration in the mongo database. To make the configuration as easy as possible we provide a robust GUI where you can access and change everything that is configurable
OpenPype stores all of its settings and configuration in the mongo database. To make the configuration as easy as possible we provide a robust GUI where you can access and change everything that is configurable
**Settings** GUI can be started from the tray menu *Admin -> Studio Settings*.
Please keep in mind that these settings are set-up for the full studio and not per-individual. If you're looking for individual artist settings, you can head to
[Local Settings](admin_settings_local.md) section in the artist documentation.
:::important Studio Settings versus Local Settings
Please keep in mind that these settings are set up for the full studio and not per-individual. If you're looking for individual artist settings, you can head to
[Local Settings](admin_settings_local.md) section in the documentation.
:::
## Categories
@ -76,7 +79,7 @@ You can also reset any settings to OpenPype default by doing `right click` and `
Many settings are useful to be adjusted on a per-project basis. To identify project
overrides, they are marked with **orange edge** and **orange labels** in the settings GUI.
The process of settting project overrides is similar to setting the Studio defaults. The key difference is to select a particular project you want to be configure. Those projects can be found on the left hand side of the Project Settings tab.
The process of setting project overrides is similar to setting the Studio defaults. The key difference is to select a particular project you want to be configure. Those projects can be found on the left hand side of the Project Settings tab.
In the image below you can see all three overrides at the same time.
1. Deadline has **no changes to the OpenPype defaults** at all — **grey** colour of left bar.

View file

@ -68,7 +68,7 @@ Add `--headless` to run OpenPype without graphical UI (useful on server or on au
`--verbose` `<level>` - change log verbose level of OpenPype loggers.
Level value can be integer in range `0-50` or one of enum strings `"notset" (0)`, `"debug" (10)`, `"info" (20)`, `"warning" (30)`, `"error" (40)`, `"ciritcal" (50)`. Value is stored to `OPENPYPE_LOG_LEVEL` environment variable for next processes.
Level value can be integer in range `0-50` or one of enum strings `"notset" (0)`, `"debug" (10)`, `"info" (20)`, `"warning" (30)`, `"error" (40)`, `"critical" (50)`. Value is stored to `OPENPYPE_LOG_LEVEL` environment variable for next processes.
```shell
openpype_console --verbose debug

View file

@ -47,7 +47,7 @@ This is the core functional area for you as a user. Most of your actions will ta
![Menu OpenPype](assets/3dsmax_menu_first_OP.png)
:::note OpenPype Menu
User should use this menu exclusively for **Opening/Saving** when dealing with work files not standard ```File Menu``` even though user still being able perform file operations via this menu but prefferably just performing quick saves during work session not saving actual workfile versions.
User should use this menu exclusively for **Opening/Saving** when dealing with work files not standard ```File Menu``` even though user still being able perform file operations via this menu but preferably just performing quick saves during work session not saving actual workfile versions.
:::
## Working With Scene Files
@ -73,7 +73,7 @@ OpenPype correctly names it and add version to the workfile. This basically happ
etc.
Basically meaning user is free of guessing what is the correct naming and other neccessities to keep everthing in order and managed.
Basically meaning user is free of guessing what is the correct naming and other necessities to keep everything in order and managed.
> Note: user still has also other options for naming like ```Subversion```, ```Artist's Note``` but we won't dive into those now.

View file

@ -34,7 +34,7 @@ a correct name. You should use it instead of standard file saving dialog.
In AfterEffects you'll find the tools in the `OpenPype` extension:
![Extension](assets/photoshop_extension.PNG) <!-- same menu as in PS -->
![Extension](assets/photoshop_extension.png) <!-- same menu as in PS -->
You can show the extension panel by going to `Window` > `Extensions` > `OpenPype`.
@ -104,7 +104,7 @@ There are currently 2 options of `render` item:
When you want to load existing published work, you can use the `Loader` tool. You can reach it in the extension's panel.
![Loader](assets/photoshop_loader.PNG) <!-- picture needs to be changed -->
![Loader](assets/photoshop_loader.png) <!-- picture needs to be changed -->
The supported families for loading into AfterEffects are:
@ -128,7 +128,7 @@ Now that we have some content loaded, you can manage which version is loaded. Th
Loaded images have to stay as smart layers in order to be updated. If you rasterize the layer, you can no longer update it to a different version using OpenPype tools.
:::
![Loader](assets/photoshop_manage.PNG)
![Loader](assets/photoshop_manage.png)
You can switch to a previous version of the image or update to the latest.

View file

@ -44,7 +44,7 @@ Because the saving to the network location happens in the background, be careful
`OpenPype > Create`
![Creator](assets/harmony_creator.PNG)
![Creator](assets/harmony_creator.png)
These are the families supported in Harmony:

View file

@ -231,14 +231,14 @@ All published instances that will replace the place holder must contain unique i
![Create menu](assets/nuke_publishedinstance.png)
The informations about these objects are given by the user by filling the extra attributes of the Place Holder
The information about these objects are given by the user by filling the extra attributes of the Place Holder
![Create menu](assets/nuke_fillingExtraAttributes.png)
### Update Place Holder
This tool alows the user to change the information provided in the extra attributes of the selected Place Holder.
This tool allows the user to change the information provided in the extra attributes of the selected Place Holder.
![Create menu](assets/nuke_updatePlaceHolder.png)
@ -250,7 +250,7 @@ This tool imports the template used and replaces the existed PlaceHolders with t
![Create menu](assets/nuke_buildWorfileFromTemplate.png)
#### Result
- Replace `PLACEHOLDER` node in the template with the published instance corresponding to the informations provided in extra attributes of the Place Holder
- Replace `PLACEHOLDER` node in the template with the published instance corresponding to the information provided in extra attributes of the Place Holder
![Create menu](assets/nuke_buildworkfile.png)

View file

@ -6,7 +6,7 @@ sidebar_label: Arnold
## Arnold Scene Source (.ass)
Arnold Scene Source can be published as a single file or a sequence of files, determined by the frame range.
When creating the instance, two objectsets are created; `content` and `proxy`. Meshes in the `proxy` objectset will be the viewport representation when loading as `standin`. Proxy representations are stored as `resources` of the subset.
When creating the instance, two objectsets are created; `content` and `proxy`. Meshes in the `proxy` objectset will be the viewport representation when loading as `standin`.
### Arnold Scene Source Proxy Workflow
In order to utilize operators and proxies, the content and proxy nodes need to share the same names (including the shape names). This is done by parenting the content and proxy nodes into separate groups. For example:

View file

@ -75,7 +75,7 @@ enabled instances, you could see more information after clicking on `Details` ta
![Image instances creates](assets/photoshop_publish_validations.png)
In this dialog you could see publishable instances in left colummn, triggered plugins in the middle and logs in the right column.
In this dialog you could see publishable instances in left column, triggered plugins in the middle and logs in the right column.
In left column you could see that `review` instance was created automatically. This instance flattens all publishable instances or
all visible layers if no publishable instances were created into single image which could serve as a single reviewable element (for example in Ftrack).

View file

@ -2,7 +2,7 @@
id: artist_tools_sync_queue
title: Sync Queue
sidebar_label: Sync Queue
description: Track sites syncronization progress.
description: Track sites synchronization progress.
---
# Sync Queue

View file

Before

Width:  |  Height:  |  Size: 8.2 KiB

After

Width:  |  Height:  |  Size: 8.2 KiB

Before After
Before After

View file

@ -24,8 +24,8 @@ It's up to the Loaders to read these values and apply the correct expected color
### Keys
- **colorspace** - string value used in other publish plugins and loaders
- **config** - storing two versions of path.
- **path** - is formated and with baked platform root. It is used for posible need to find out where we were sourcing color config during publishing.
- **template** - unformated tempate resolved from settings. It is used for other plugins targeted to remote publish which could be processed at different platform.
- **path** - is formatted and with baked platform root. It is used for possible need to find out where we were sourcing color config during publishing.
- **template** - unformatted template resolved from settings. It is used for other plugins targeted to remote publish which could be processed at different platform.
### Example
{

View file

@ -45,10 +45,10 @@ openpype/hosts/{host name}
```
### Launch Hooks
Launch hooks are not directly connected to host implementation, but they can be used to modify launch of process which may be crutial for the implementation. Launch hook are plugins called when DCC is launched. They are processed in sequence before and after launch. Pre launch hooks can change how process of DCC is launched, e.g. change subprocess flags, modify environments or modify launch arguments. If prelaunch hook crashes the application is not launched at all. Postlaunch hooks are triggered after launch of subprocess. They can be used to change statuses in your project tracker, start timer, etc. Crashed postlaunch hooks have no effect on rest of postlaunch hooks or launched process. They can be filtered by platform, host and application and order is defined by integer value. Hooks inside host are automatically loaded (one reason why folder name should match host name) or can be defined from modules. Hooks execution share same launch context where can be stored data used across multiple hooks (please be very specific in stored keys e.g. 'project' vs. 'project_name'). For more detailed information look into `openpype/lib/applications.py`.
Launch hooks are not directly connected to host implementation, but they can be used to modify launch of process which may be crucial for the implementation. Launch hook are plugins called when DCC is launched. They are processed in sequence before and after launch. Pre launch hooks can change how process of DCC is launched, e.g. change subprocess flags, modify environments or modify launch arguments. If prelaunch hook crashes the application is not launched at all. Postlaunch hooks are triggered after launch of subprocess. They can be used to change statuses in your project tracker, start timer, etc. Crashed postlaunch hooks have no effect on rest of postlaunch hooks or launched process. They can be filtered by platform, host and application and order is defined by integer value. Hooks inside host are automatically loaded (one reason why folder name should match host name) or can be defined from modules. Hooks execution share same launch context where can be stored data used across multiple hooks (please be very specific in stored keys e.g. 'project' vs. 'project_name'). For more detailed information look into `openpype/lib/applications.py`.
### Public interface
Public face is at this moment related to launching of the DCC. At this moment there there is only option to modify environment variables before launch by implementing function `add_implementation_envs` (must be available in `openpype/hosts/{host name}/__init__.py`). The function is called after pre launch hooks, as last step before subprocess launch, to be able set environment variables crutial for proper integration. It is also good place for functions that are used in prelaunch hooks and in-DCC integration. Future plans are to be able get workfiles extensions from here. Right now workfiles extensions are hardcoded in `openpype/pipeline/constants.py` under `HOST_WORKFILE_EXTENSIONS`, we would like to handle hosts as addons similar to OpenPype modules, and more improvements which are now hardcoded.
Public face is at this moment related to launching of the DCC. At this moment there there is only option to modify environment variables before launch by implementing function `add_implementation_envs` (must be available in `openpype/hosts/{host name}/__init__.py`). The function is called after pre launch hooks, as last step before subprocess launch, to be able set environment variables crucial for proper integration. It is also good place for functions that are used in prelaunch hooks and in-DCC integration. Future plans are to be able get workfiles extensions from here. Right now workfiles extensions are hardcoded in `openpype/pipeline/constants.py` under `HOST_WORKFILE_EXTENSIONS`, we would like to handle hosts as addons similar to OpenPype modules, and more improvements which are now hardcoded.
### Integration
We've prepared base class `HostBase` in `openpype/host/host.py` to define minimum requirements and provide some default method implementations. The minimum requirement for a host is `name` attribute, this host would not be able to do much but is valid. To extend functionality we've prepared interfaces that helps to identify what is host capable of and if is possible to use certain tools with it. For those cases we defined interfaces for each workflow. `IWorkfileHost` interface add requirement to implement workfiles related methods which makes host usable in combination with Workfiles tool. `ILoadHost` interface add requirements to be able load, update, switch or remove referenced representations which should add support to use Loader and Scene Inventory tools. `INewPublisher` interface is required to be able use host with new OpenPype publish workflow. This is what must or can be implemented to allow certain functionality. `HostBase` will have more responsibility which will be taken from global variables in future. This process won't happen at once, but will be slow to keep backwards compatibility for some time.

View file

@ -415,7 +415,7 @@ class CreateRender(Creator):
# - 'asset' - asset name
# - 'task' - task name
# - 'variant' - variant
# - 'family' - instnace family
# - 'family' - instance family
# Check if should use selection or not
if pre_create_data.get("use_selection"):

View file

@ -355,7 +355,7 @@ These inputs wraps another inputs into {key: value} relation
{
"type": "text",
"key": "command",
"label": "Comand"
"label": "Command"
}
]
},
@ -420,7 +420,7 @@ How output of the schema could look like on save:
- number input, can be used for both integer and float
- key `"decimal"` defines how many decimal places will be used, 0 is for integer input (Default: `0`)
- key `"minimum"` as minimum allowed number to enter (Default: `-99999`)
- key `"maxium"` as maximum allowed number to enter (Default: `99999`)
- key `"maximum"` as maximum allowed number to enter (Default: `99999`)
- key `"steps"` will change single step value of UI inputs (using arrows and wheel scroll)
- for UI it is possible to show slider to enable this option set `show_slider` to `true`
```javascript
@ -602,7 +602,7 @@ How output of the schema could look like on save:
- there are 2 possible ways how to set the type:
1.) dictionary with item modifiers (`number` input has `minimum`, `maximum` and `decimals`) in that case item type must be set as value of `"type"` (example below)
2.) item type name as string without modifiers (e.g. [text](#text))
3.) enhancement of 1.) there is also support of `template` type but be carefull about endless loop of templates
3.) enhancement of 1.) there is also support of `template` type but be careful about endless loop of templates
- goal of using `template` is to easily change same item definitions in multiple lists
1.) with item modifiers

View file

@ -57,7 +57,7 @@ Content:
Contains end to end testing in a DCC. Currently it is setup to start DCC application with prepared worfkile, run publish process and compare results in DB and file system automatically.
This approach is implemented as it should work in any DCC application and should cover most common use cases. Not all hosts allow "real headless" publishing, but all hosts should allow to trigger
publish process programatically when UI of host is actually running.
publish process programmatically when UI of host is actually running.
There will be eventually also possibility to build workfile and publish it programmatically, this would work only in DCCs that support it (Maya, Nuke).

View file

@ -4,7 +4,7 @@ title: Ftrack
sidebar_label: Project Manager
---
Ftrack is currently the main project management option for OpenPype. This documentation assumes that you are familiar with Ftrack and it's basic principles. If you're new to Ftrack, we recommend having a thorough look at [Ftrack Official Documentation](https://help.ftrack.com/en/).
Ftrack is currently the main project management option for OpenPype. This documentation assumes that you are familiar with Ftrack and its basic principles. If you're new to Ftrack, we recommend having a thorough look at [Ftrack Official Documentation](https://help.ftrack.com/en/).
## Project management
Setting project attributes is the key to properly working pipeline.

View file

@ -8,7 +8,7 @@ import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
Ftrack is currently the main project management option for OpenPype. This documentation assumes that you are familiar with Ftrack and it's basic principles. If you're new to Ftrack, we recommend having a thorough look at [Ftrack Official Documentation](http://ftrack.rtd.ftrack.com/en/stable/).
Ftrack is currently the main project management option for OpenPype. This documentation assumes that you are familiar with Ftrack and its basic principles. If you're new to Ftrack, we recommend having a thorough look at [Ftrack Official Documentation](http://ftrack.rtd.ftrack.com/en/stable/).
## Prepare Ftrack for OpenPype

View file

@ -7,7 +7,7 @@ sidebar_label: Kitsu
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
Kitsu is a great open source production tracker and can be used for project management instead of Ftrack. This documentation assumes that you are familiar with Kitsu and it's basic principles. If you're new to Kitsu, we recommend having a thorough look at [Kitsu Official Documentation](https://kitsu.cg-wire.com/).
Kitsu is a great open source production tracker and can be used for project management instead of Ftrack. This documentation assumes that you are familiar with Kitsu and its basic principles. If you're new to Kitsu, we recommend having a thorough look at [Kitsu Official Documentation](https://kitsu.cg-wire.com/).
## Prepare Kitsu for OpenPype
@ -41,4 +41,4 @@ openpype_console module kitsu push-to-zou -l me@domain.ext -p my_password
## Q&A
### Is it safe to rename an entity from Kitsu?
Absolutely! Entities are linked by their unique IDs between the two databases.
But renaming from the OP's Project Manager won't apply the change to Kitsu, it'll be overriden during the next synchronization.
But renaming from the OP's Project Manager won't apply the change to Kitsu, it'll be overridden during the next synchronization.

View file

@ -89,7 +89,7 @@ all share the same provider).
Handles files stored on disk storage.
Local drive provider is the most basic one that is used for accessing all standard hard disk storage scenarios. It will work with any storage that can be mounted on your system in a standard way. This could correspond to a physical external hard drive, network mounted storage, internal drive or even VPN connected network drive. It doesn't care about how te drive is mounted, but you must be able to point to it with a simple directory path.
Local drive provider is the most basic one that is used for accessing all standard hard disk storage scenarios. It will work with any storage that can be mounted on your system in a standard way. This could correspond to a physical external hard drive, network mounted storage, internal drive or even VPN connected network drive. It doesn't care about how the drive is mounted, but you must be able to point to it with a simple directory path.
Default sites `local` and `studio` both use local drive provider.

View file

@ -10,7 +10,7 @@ import TabItem from '@theme/TabItem';
Project settings can have project specific values. Each new project is using studio values defined in **default** project but these values can be modified or overridden per project.
:::warning Default studio values
Projects always use default project values unless they have [project override](../admin_settings#project-overrides) (orage colour). Any changes in default project may affect all existing projects.
Projects always use default project values unless they have [project override](../admin_settings#project-overrides) (orange colour). Any changes in default project may affect all existing projects.
:::
## Color Management (ImageIO)
@ -39,14 +39,14 @@ Procedure of resolving path (from above example) will look first into path 1st a
### Using File rules
File rules are inspired by [OCIO v2 configuration]((https://opencolorio.readthedocs.io/en/latest/guides/authoring/rules.html)). Each rule has a unique name which can be overridden by host-specific _File rules_ (example: `project_settings/nuke/imageio/file_rules/rules`).
The _input pattern_ matching uses REGEX expression syntax (try [regexr.com](https://regexr.com/)). Matching rules procedure's intention is to be used during publishing or loading of representation. Since the publishing procedure is run before integrator formate publish template path, make sure the pattern is working or any work render path.
The _input pattern_ matching uses REGEX expression syntax (try [regexr.com](https://regexr.com/)). Matching rules procedure's intention is to be used during publishing or loading of representation. Since the publishing procedure is run before integrator format publish template path, make sure the pattern is working or any work render path.
:::warning Colorspace name input
The **colorspace name** value is a raw string input and no validation is run after saving project settings. We recommend to open the specified `config.ocio` file and copy pasting the exact colorspace names.
:::
### Extract OIIO Transcode
OIIOTools transcoder plugin with configurable output presets. Any incoming representation with `colorspaceData` is convertable to single or multiple representations with different target colorspaces or display and viewer names found in linked **config.ocio** file.
OIIOTools transcoder plugin with configurable output presets. Any incoming representation with `colorspaceData` is convertible to single or multiple representations with different target colorspaces or display and viewer names found in linked **config.ocio** file.
`oiiotool` is used for transcoding, eg. `oiiotool` must be present in `vendor/bin/oiio` or environment variable `OPENPYPE_OIIO_PATHS` must be provided for custom oiio installation.

View file

@ -10,7 +10,7 @@ import TabItem from '@theme/TabItem';
Project settings can have project specific values. Each new project is using studio values defined in **default** project but these values can be modified or overridden per project.
:::warning Default studio values
Projects always use default project values unless they have [project override](../admin_settings#project-overrides) (orage colour). Any changes in default project may affect all existing projects.
Projects always use default project values unless they have [project override](../admin_settings#project-overrides) (orange colour). Any changes in default project may affect all existing projects.
:::
## Workfile Builder

View file

@ -10,7 +10,7 @@ import TabItem from '@theme/TabItem';
Project settings can have project specific values. Each new project is using studio values defined in **default** project but these values can be modified or overridden per project.
:::warning Default studio values
Projects always use default project values unless they have [project override](../admin_settings#project-overrides) (orage colour). Any changes in default project may affect all existing projects.
Projects always use default project values unless they have [project override](../admin_settings#project-overrides) (orange colour). Any changes in default project may affect all existing projects.
:::
## Creator Plugins

View file

@ -8,7 +8,7 @@ import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
Ftrack is currently the main project management option for Pype. This documentation assumes that you are familiar with Ftrack and it's basic principles. If you're new to Ftrack, we recommend having a thorough look at [Ftrack Official Documentation](http://ftrack.rtd.ftrack.com/en/stable/).
Ftrack is currently the main project management option for Pype. This documentation assumes that you are familiar with Ftrack and its basic principles. If you're new to Ftrack, we recommend having a thorough look at [Ftrack Official Documentation](http://ftrack.rtd.ftrack.com/en/stable/).
## Prepare Ftrack for Pype

View file

@ -15,9 +15,9 @@ various usage scenarios.
## Studio Preparation
You can find detailed breakdown of technical requirements [here](dev_requirements), but in general OpenPype should be able
You can find a detailed breakdown of technical requirements [here](dev_requirements), but in general OpenPype should be able
to operate in most studios fairly quickly. The main obstacles are usually related to workflows and habits, that
might not be fully compatible with what OpenPype is expecting or enforcing. It is recommended to go through artists [key concepts](artist_concepts) to get idea about basics.
might not be fully compatible with what OpenPype is expecting or enforcing. It is recommended to go through artists [key concepts](artist_concepts) to get comfortable with the basics.
Keep in mind that if you run into any workflows that are not supported, it's usually just because we haven't hit
that particular case and it can most likely be added upon request.

File diff suppressed because it is too large Load diff