diff --git a/client/ayon_houdini/api/lib.py b/client/ayon_houdini/api/lib.py index 26c1b78438..762aa1395b 100644 --- a/client/ayon_houdini/api/lib.py +++ b/client/ayon_houdini/api/lib.py @@ -89,7 +89,7 @@ def get_output_parameter(node): return node.parm("sopoutput") elif node_type == "comp": return node.parm("copoutput") - elif node_type in {"karma", "opengl"}: + elif node_type in {"karma", "opengl", "flipbook"}: return node.parm("picture") elif node_type == "ifd": # Mantra if node.evalParm("soho_outputmode"): @@ -896,16 +896,19 @@ def get_current_context_template_data_with_entity_attrs(): return template_data -def set_review_color_space(opengl_node, review_color_space="", log=None): +def set_review_color_space(node, review_color_space="", log=None): """Set ociocolorspace parameter for the given OpenGL node. - Set `ociocolorspace` parameter of the given OpenGl node + Set `ociocolorspace` parameter of the given node to to the given review_color_space value. If review_color_space is empty, a default colorspace corresponding to the display & view of the current Houdini session will be used. + Note: + This function expects nodes of type `opengl` or `flipbook`. + Args: - opengl_node (hou.Node): ROP node to set its ociocolorspace parm. + node (hou.Node): ROP node to set its ociocolorspace parm. review_color_space (str): Colorspace value for ociocolorspace parm. log (logging.Logger): Logger to log to. """ @@ -913,23 +916,31 @@ def set_review_color_space(opengl_node, review_color_space="", log=None): if log is None: log = self.log + if node.type().name() not in {"opengl", "flipbook"}: + log.warning( + "Type of given node {} not allowed." + " only types `opengl` and `flipbook` are allowed." + .format(node.type().name()) + ) + # Set Color Correction parameter to OpenColorIO - colorcorrect_parm = opengl_node.parm("colorcorrect") - if colorcorrect_parm.eval() != 2: - colorcorrect_parm.set(2) + colorcorrect_parm = node.parm("colorcorrect") + if colorcorrect_parm.evalAsString() != "ocio": + idx = colorcorrect_parm.menuItems().index("ocio") + colorcorrect_parm.set(idx) log.debug( - "'Color Correction' parm on '{}' has been set to" - " 'OpenColorIO'".format(opengl_node.path()) + "'Color Correction' parm on '{}' has been set to '{}'" + .format(node.path(), colorcorrect_parm.menuLabels()[idx]) ) - opengl_node.setParms( + node.setParms( {"ociocolorspace": review_color_space} ) log.debug( "'OCIO Colorspace' parm on '{}' has been set to " "the view color space '{}'" - .format(opengl_node, review_color_space) + .format(node.path(), review_color_space) ) diff --git a/client/ayon_houdini/plugins/create/create_review.py b/client/ayon_houdini/plugins/create/create_review.py index 3b3644bda7..601349e3ad 100644 --- a/client/ayon_houdini/plugins/create/create_review.py +++ b/client/ayon_houdini/plugins/create/create_review.py @@ -11,11 +11,15 @@ class CreateReview(plugin.HoudiniCreator): """Review with OpenGL ROP""" identifier = "io.openpype.creators.houdini.review" - label = "Review (OpenGL)" + label = "Review" product_type = "review" icon = "video-camera" review_color_space = "" + node_type = "opengl" + # TODO: Publish families should reflect the node type, + # such as `rop.flipbook` for flipbook nodes + # and `rop.opengl` for OpenGL nodes. def get_publish_families(self): return ["review", "rop.opengl"] @@ -29,8 +33,10 @@ def apply_settings(self, project_settings): self.review_color_space = color_settings.get("review_color_space") def create(self, product_name, instance_data, pre_create_data): + + self.node_type = pre_create_data.get("node_type") - instance_data.update({"node_type": "opengl"}) + instance_data.update({"node_type": self.node_type}) instance_data["imageFormat"] = pre_create_data.get("imageFormat") instance_data["keepImages"] = pre_create_data.get("keepImages") @@ -123,8 +129,15 @@ def get_pre_create_attr_defs(self): "bmp", "cin", "exr", "jpg", "pic", "pic.gz", "png", "rad", "rat", "rta", "sgi", "tga", "tif", ] + node_type_enum = ["opengl"] + if hou.applicationVersion() >= (20, 5, 0): + node_type_enum.append("flipbook") return attrs + [ + EnumDef("node_type", + node_type_enum, + default=self.node_type, + label="Node Type"), BoolDef("keepImages", label="Keep Image Sequences", default=False), diff --git a/client/ayon_houdini/plugins/publish/collect_review_data.py b/client/ayon_houdini/plugins/publish/collect_review_data.py index e9a403f070..c35e069a14 100644 --- a/client/ayon_houdini/plugins/publish/collect_review_data.py +++ b/client/ayon_houdini/plugins/publish/collect_review_data.py @@ -69,7 +69,7 @@ def _get_camera_path(self, ropnode): """ if ropnode.type().name() in { - "opengl", "karma", "ifd", "arnold" + "opengl", "karma", "ifd", "arnold", "flipbook" }: return ropnode.parm("camera").eval() diff --git a/client/ayon_houdini/plugins/publish/extract_rop.py b/client/ayon_houdini/plugins/publish/extract_rop.py index 574b31b9db..74a5f52154 100644 --- a/client/ayon_houdini/plugins/publish/extract_rop.py +++ b/client/ayon_houdini/plugins/publish/extract_rop.py @@ -1,5 +1,4 @@ import os - import pyblish.api from ayon_core.pipeline import publish @@ -78,11 +77,11 @@ def update_representation_data(self, pass -class ExtractOpenGL(ExtractROP, - publish.ColormanagedPyblishPluginMixin): +class ExtractOpenGLAndFlipbook(ExtractROP, + publish.ColormanagedPyblishPluginMixin): order = pyblish.api.ExtractorOrder - 0.01 - label = "Extract OpenGL" + label = "Extract Review (OpenGL & Flipbook)" families = ["rop.opengl"] def update_representation_data(self, diff --git a/client/ayon_houdini/plugins/publish/validate_review_colorspace.py b/client/ayon_houdini/plugins/publish/validate_review_colorspace.py index 55f9dd011a..ec99d027e4 100644 --- a/client/ayon_houdini/plugins/publish/validate_review_colorspace.py +++ b/client/ayon_houdini/plugins/publish/validate_review_colorspace.py @@ -66,38 +66,46 @@ def process(self, instance): " skipping check.." ) return - - rop_node = hou.node(instance.data["instance_node"]) - if rop_node.evalParm("colorcorrect") != 2: + rop_node = hou.node(instance.data["instance_node"]) + colorcorrect = rop_node.parm("colorcorrect").evalAsString() + if not colorcorrect.startswith("ocio"): # any colorspace settings other than default requires # 'Color Correct' parm to be set to 'OpenColorIO' raise PublishValidationError( "'Color Correction' parm on '{}' ROP must be set to" - " 'OpenColorIO'".format(rop_node.path()) - ) - - current_color_space = rop_node.evalParm("ociocolorspace") - if current_color_space not in hou.Color.ocio_spaces(): - raise PublishValidationError( - "Invalid value: Colorspace name doesn't exist.\n" - "Check 'OCIO Colorspace' parameter on '{}' ROP" - .format(rop_node.path()) + " use 'OpenColorIO'".format(rop_node.path()) ) - # if houdini/imageio/workfile is enabled and - # Review colorspace setting is empty then this check should - # actually check if the current_color_space setting equals - # the default colorspace value. - # However, it will make the black cmd screen show up more often - # which is very annoying. - if self.review_color_space and \ - self.review_color_space != current_color_space: - - raise PublishValidationError( - "Invalid value: Colorspace name doesn't match" - "the Colorspace specified in settings." - ) + if colorcorrect == "ocio": + # For both opengl and flipbook nodes. + + current_color_space = rop_node.evalParm("ociocolorspace") + if current_color_space not in hou.Color.ocio_spaces(): + raise PublishValidationError( + "Invalid value: Colorspace name doesn't exist.\n" + "Check 'OCIO Colorspace' parameter on '{}' ROP" + .format(rop_node.path()) + ) + + # If `ayon+settings://houdini/imageio/workfile` is enabled + # and the Review colorspace setting is empty, then this check + # should verify if the `current_color_space` setting equals + # the default colorspace value. + if self.review_color_space and \ + self.review_color_space != current_color_space: + + raise PublishValidationError( + "Invalid value: Colorspace name doesn't match" + "the Colorspace specified in settings." + ) + + # TODO: Check if `ociodisplay` and `ocioview` are the same as the default display and view. + # Should be the default value specified in settings? + # OR Should be the current/default value specified in the hip file? + elif colorcorrect == "ocioview": + # For flipbook nodes only. + pass @classmethod def repair(cls, instance): diff --git a/server/settings/create.py b/server/settings/create.py index 595006c665..a11b63291c 100644 --- a/server/settings/create.py +++ b/server/settings/create.py @@ -9,6 +9,22 @@ class CreatorModel(BaseSettingsModel): default_factory=list, ) +def review_node_types_enum(): + return [ + {"label": "OpenGL", "value": "opengl"}, + {"label": "Flipbook", "value": "flipbook"} + ] + +class CreateReviewModel(BaseSettingsModel): + enabled: bool = SettingsField(title="Enabled") + default_variants: list[str] = SettingsField( + title="Default Products", + default_factory=list, + ) + node_type: str = SettingsField( + title="Default Node Type", + enum_resolver=review_node_types_enum, + ) class CreateArnoldAssModel(BaseSettingsModel): enabled: bool = SettingsField(title="Enabled") @@ -82,8 +98,8 @@ class CreatePluginsModel(BaseSettingsModel): CreateRedshiftROP: CreatorModel = SettingsField( default_factory=CreatorModel, title="Create Redshift ROP") - CreateReview: CreatorModel = SettingsField( - default_factory=CreatorModel, + CreateReview: CreateReviewModel = SettingsField( + default_factory=CreateReviewModel, title="Create Review") # "-" is not compatible in the new model CreateStaticMesh: CreateStaticMeshModel = SettingsField( @@ -159,7 +175,8 @@ class CreatePluginsModel(BaseSettingsModel): }, "CreateReview": { "enabled": True, - "default_variants": ["Main"] + "default_variants": ["Main"], + "node_type": "opengl" }, "CreateStaticMesh": { "enabled": True,