Merge branch 'develop' into enhancement/OP-6020_Nuke-custom-setFrameRange-script

This commit is contained in:
Jakub Ježek 2023-06-01 16:19:36 +02:00 committed by GitHub
commit 9353de2770
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 213 additions and 10 deletions

View file

@ -128,7 +128,14 @@ def get_all_children(parent, node_type=None):
def get_current_renderer():
"""get current renderer"""
"""
Notes:
Get current renderer for Max
Returns:
"{Current Renderer}:{Current Renderer}"
e.g. "Redshift_Renderer:Redshift_Renderer"
"""
return rt.renderers.production

View file

@ -0,0 +1,18 @@
# -*- coding: utf-8 -*-
"""Creator plugin for creating camera."""
from openpype.hosts.max.api import plugin
from openpype.pipeline import CreatedInstance
class CreateRedshiftProxy(plugin.MaxCreator):
identifier = "io.openpype.creators.max.redshiftproxy"
label = "Redshift Proxy"
family = "redshiftproxy"
icon = "gear"
def create(self, subset_name, instance_data, pre_create_data):
_ = super(CreateRedshiftProxy, self).create(
subset_name,
instance_data,
pre_create_data) # type: CreatedInstance

View file

@ -0,0 +1,63 @@
import os
import clique
from openpype.pipeline import (
load,
get_representation_path
)
from openpype.hosts.max.api.pipeline import containerise
from openpype.hosts.max.api import lib
class RedshiftProxyLoader(load.LoaderPlugin):
"""Load rs files with Redshift Proxy"""
label = "Load Redshift Proxy"
families = ["redshiftproxy"]
representations = ["rs"]
order = -9
icon = "code-fork"
color = "white"
def load(self, context, name=None, namespace=None, data=None):
from pymxs import runtime as rt
filepath = self.filepath_from_context(context)
rs_proxy = rt.RedshiftProxy()
rs_proxy.file = filepath
files_in_folder = os.listdir(os.path.dirname(filepath))
collections, remainder = clique.assemble(files_in_folder)
if collections:
rs_proxy.is_sequence = True
container = rt.container()
container.name = name
rs_proxy.Parent = container
asset = rt.getNodeByName(name)
return containerise(
name, [asset], context, loader=self.__class__.__name__)
def update(self, container, representation):
from pymxs import runtime as rt
path = get_representation_path(representation)
node = rt.getNodeByName(container["instance_node"])
for children in node.Children:
children_node = rt.getNodeByName(children.name)
for proxy in children_node.Children:
proxy.file = path
lib.imprint(container["instance_node"], {
"representation": str(representation["_id"])
})
def switch(self, container, representation):
self.update(container, representation)
def remove(self, container):
from pymxs import runtime as rt
node = rt.getNodeByName(container["instance_node"])
rt.delete(node)

View file

@ -0,0 +1,62 @@
import os
import pyblish.api
from openpype.pipeline import publish
from pymxs import runtime as rt
from openpype.hosts.max.api import maintained_selection
class ExtractRedshiftProxy(publish.Extractor):
"""
Extract Redshift Proxy with rsProxy
"""
order = pyblish.api.ExtractorOrder - 0.1
label = "Extract RedShift Proxy"
hosts = ["max"]
families = ["redshiftproxy"]
def process(self, instance):
container = instance.data["instance_node"]
start = int(instance.context.data.get("frameStart"))
end = int(instance.context.data.get("frameEnd"))
self.log.info("Extracting Redshift Proxy...")
stagingdir = self.staging_dir(instance)
rs_filename = "{name}.rs".format(**instance.data)
rs_filepath = os.path.join(stagingdir, rs_filename)
rs_filepath = rs_filepath.replace("\\", "/")
rs_filenames = self.get_rsfiles(instance, start, end)
with maintained_selection():
# select and export
con = rt.getNodeByName(container)
rt.select(con.Children)
# Redshift rsProxy command
# rsProxy fp selected compress connectivity startFrame endFrame
# camera warnExisting transformPivotToOrigin
rt.rsProxy(rs_filepath, 1, 0, 0, start, end, 0, 1, 1)
self.log.info("Performing Extraction ...")
if "representations" not in instance.data:
instance.data["representations"] = []
representation = {
'name': 'rs',
'ext': 'rs',
'files': rs_filenames if len(rs_filenames) > 1 else rs_filenames[0], # noqa
"stagingDir": stagingdir,
}
instance.data["representations"].append(representation)
self.log.info("Extracted instance '%s' to: %s" % (instance.name,
stagingdir))
def get_rsfiles(self, instance, startFrame, endFrame):
rs_filenames = []
rs_name = instance.data["name"]
for frame in range(startFrame, endFrame + 1):
rs_filename = "%s.%04d.rs" % (rs_name, frame)
rs_filenames.append(rs_filename)
return rs_filenames

View file

@ -0,0 +1,54 @@
# -*- coding: utf-8 -*-
import pyblish.api
from openpype.pipeline import PublishValidationError
from pymxs import runtime as rt
from openpype.pipeline.publish import RepairAction
from openpype.hosts.max.api.lib import get_current_renderer
class ValidateRendererRedshiftProxy(pyblish.api.InstancePlugin):
"""
Validates Redshift as the current renderer for creating
Redshift Proxy
"""
order = pyblish.api.ValidatorOrder
families = ["redshiftproxy"]
hosts = ["max"]
label = "Redshift Renderer"
actions = [RepairAction]
def process(self, instance):
invalid = self.get_redshift_renderer(instance)
if invalid:
raise PublishValidationError("Please install Redshift for 3dsMax"
" before using the Redshift proxy instance") # noqa
invalid = self.get_current_renderer(instance)
if invalid:
raise PublishValidationError("The Redshift proxy extraction"
"discontinued since the current renderer is not Redshift") # noqa
def get_redshift_renderer(self, instance):
invalid = list()
max_renderers_list = str(rt.RendererClass.classes)
if "Redshift_Renderer" not in max_renderers_list:
invalid.append(max_renderers_list)
return invalid
def get_current_renderer(self, instance):
invalid = list()
renderer_class = get_current_renderer()
current_renderer = str(renderer_class).split(":")[0]
if current_renderer != "Redshift_Renderer":
invalid.append(current_renderer)
return invalid
@classmethod
def repair(cls, instance):
for Renderer in rt.RendererClass.classes:
renderer = Renderer()
if "Redshift_Renderer" in str(renderer):
rt.renderers.production = renderer
break

View file

@ -29,6 +29,9 @@ def setup(env):
log.info("Utility Scripts Dir: `{}`".format(util_scripts_paths))
log.info("Utility Scripts: `{}`".format(scripts))
# Make sure scripts dir exists
os.makedirs(util_scripts_dir, exist_ok=True)
# make sure no script file is in folder
for script in os.listdir(util_scripts_dir):
path = os.path.join(util_scripts_dir, script)

View file

@ -30,7 +30,7 @@ By clicking the icon ```OpenPype Menu``` rolls out.
Choose ```OpenPype Menu > Launcher``` to open the ```Launcher``` window.
When opened you can **choose** the **project** to work in from the list. Then choose the particular **asset** you want to work on then choose **task**
When opened you can **choose** the **project** to work in from the list. Then choose the particular **asset** you want to work on then choose **task**
and finally **run 3dsmax by its icon** in the tools.
![Menu OpenPype](assets/3dsmax_tray_OP.png)
@ -65,13 +65,13 @@ If not any workfile present simply hit ```Save As``` and keep ```Subversion``` e
![Save As Dialog](assets/3dsmax_SavingFirstFile_OP.png)
OpenPype correctly names it and add version to the workfile. This basically happens whenever user trigger ```Save As``` action. Resulting into incremental version numbers like
OpenPype correctly names it and add version to the workfile. This basically happens whenever user trigger ```Save As``` action. Resulting into incremental version numbers like
```workfileName_v001```
```workfileName_v002```
etc.
etc.
Basically meaning user is free of guessing what is the correct naming and other necessities to keep everything in order and managed.
@ -105,13 +105,13 @@ Before proceeding further please check [Glossary](artist_concepts.md) and [What
### Intro
Current OpenPype integration (ver 3.15.0) supports only ```PointCache``` and ```Camera``` families now.
Current OpenPype integration (ver 3.15.0) supports only ```PointCache```, ```Camera```, ```Geometry``` and ```Redshift Proxy``` families now.
**Pointcache** family being basically any geometry outputted as Alembic cache (.abc) format
**Camera** family being 3dsmax Camera object with/without animation outputted as native .max, FBX, Alembic format
**Redshift Proxy** family being Redshift Proxy object with/without animation outputted as rs format(Redshift Proxy's very own format)
---
:::note Work in progress
@ -119,7 +119,3 @@ This part of documentation is still work in progress.
:::
## ...to be added