mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-25 05:14:40 +01:00
Merge branch 'develop' into enhancement/OP-6020_Nuke-custom-setFrameRange-script
This commit is contained in:
commit
9353de2770
7 changed files with 213 additions and 10 deletions
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
|||
18
openpype/hosts/max/plugins/create/create_redshift_proxy.py
Normal file
18
openpype/hosts/max/plugins/create/create_redshift_proxy.py
Normal 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
|
||||
63
openpype/hosts/max/plugins/load/load_redshift_proxy.py
Normal file
63
openpype/hosts/max/plugins/load/load_redshift_proxy.py
Normal 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)
|
||||
62
openpype/hosts/max/plugins/publish/extract_redshift_proxy.py
Normal file
62
openpype/hosts/max/plugins/publish/extract_redshift_proxy.py
Normal 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
|
||||
|
|
@ -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
|
||||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||

|
||||
|
|
@ -65,13 +65,13 @@ If not any workfile present simply hit ```Save As``` and keep ```Subversion``` e
|
|||
|
||||

|
||||
|
||||
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
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue