add settings and adjustments based on the new publishers

This commit is contained in:
Kayla Man 2023-03-30 21:19:24 +08:00
parent 69a202a270
commit 7d21437dae
4 changed files with 202 additions and 66 deletions

View file

@ -1,11 +1,11 @@
# -*- coding: utf-8 -*-
"""Creator plugin for creating pointcache alembics."""
from openpype.hosts.houdini.api import plugin
from openpype.pipeline import (
CreatedInstance,
OpenPypePyblishPluginMixin
)
from openpype.pipeline import CreatedInstance
from openpype.lib import EnumDef, BoolDef, NumberDef
class CreateReview(plugin.HoudiniCreator, OpenPypePyblishPluginMixin):
class CreateReview(plugin.HoudiniCreator):
"""Review with OpenGL ROP"""
identifier = "io.openpype.creators.houdini.review"
@ -13,34 +13,30 @@ class CreateReview(plugin.HoudiniCreator, OpenPypePyblishPluginMixin):
family = "review"
icon = "video-camera"
# Default settings for the ROP
# todo: expose in OpenPype settings?
override_resolution = True
width = 1280
height = 720
aspect = 1.0
def create(self, subset_name, instance_data, pre_create_data):
def create(self, subset_name, instance_data, pre_create_data): # type: CreatedInstance
import hou
# Remove the active, we are checking the bypass flag of the nodes
instance_data.pop("active", None)
instance_data["node_type"] = "opengl"
instance_data.update({"node_type": "opengl"})
instance_data["imageFormat"] = pre_create_data.get("imageFormat")
instance_data["keepImages"] = pre_create_data.get("keepImages")
instance = super(CreateReview, self).create(
subset_name,
instance_data,
pre_create_data) # type: CreatedInstance
pre_create_data)
instance_node = hou.node(instance.get("instance_node"))
frame_range = hou.playbar.frameRange()
parms = {
"picture": '$HIP/pyblish/`chs("subset")`/`chs("subset")`.$F4.png',
# Render frame range
"picture": "{}{}".format(
hou.text.expandString("$HIP/pyblish/"),
"{}/{}.$F4.{}".format(
subset_name,
subset_name,
pre_create_data.get("image_format") or "png")),
"trange": 1,
# Unlike many other ROP nodes the opengl node does not default
@ -50,13 +46,13 @@ class CreateReview(plugin.HoudiniCreator, OpenPypePyblishPluginMixin):
"f2": frame_range[1],
}
if self.override_resolution:
# Override resolution
override_resolution = pre_create_data.get("override_resolution")
if override_resolution:
parms.update({
"tres": True, # Override Camera Resolution
"res1": self.width,
"res2": self.height,
"aspect": self.aspect
"tres": override_resolution,
"res1": pre_create_data.get("resx"),
"res2": pre_create_data.get("resy"),
"aspect": pre_create_data.get("aspect"),
})
if self.selected_nodes:
@ -66,9 +62,96 @@ class CreateReview(plugin.HoudiniCreator, OpenPypePyblishPluginMixin):
instance_node.setParms(parms)
# Lock any parameters in this list
to_lock = [
"family",
"id"
]
to_lock = ["id", "family"]
self.lock_parameters(instance_node, to_lock)
def get_pre_create_attr_defs(self):
attrs = super().get_pre_create_attr_defs()
image_format_enum = [
{
"value": "png",
"label": ".png"
},
{
"value": "tif",
"label": ".tif"
},
{
"value": "sgi",
"label": ".sgi"
},
{
"value": "pic.gz",
"label": ".pic.gz"
},
{
"value": "rat",
"label": ".rat"
},
{
"value": "jpg",
"label": ".jpg"
},
{
"value": "cin",
"label": ".cin"
},
{
"value": "rta",
"label": ".rta"
},
{
"value": "rat",
"label": ".rat"
},
{
"value": "bmp",
"label": ".bmp"
},
{
"value": "tga",
"label": ".tga"
},
{
"value": "rad",
"label": ".rad"
},
{
"value": "exr",
"label": ".exr"
},
{
"value": "pic",
"label": ".pic"
}
]
return attrs + [
BoolDef("keepImages",
label="Keep Image Sequences",
default=False),
EnumDef("imageFormat",
image_format_enum,
label="Image Format Options"),
BoolDef("override_resolution",
label="Override resolution",
tooltip="When disabled the resolution set on the camera "
"is used instead.",
default=True),
NumberDef("resx",
label="Resolution Width",
default=1280,
minimum=2,
decimals=0),
NumberDef("resy",
label="Resolution Height",
default=720,
minimum=2,
decimals=0),
NumberDef("aspect",
label="Aspect Ratio",
default=1.0,
minimum=0.0001,
decimals=3)
]

View file

@ -22,19 +22,17 @@ class CollectHoudiniReviewData(pyblish.api.InstancePlugin):
ropnode_path = instance.data["instance_node"]
ropnode = hou.node(ropnode_path)
try:
camera = ropnode.parm("camera").evalAsNode()
except TypeError:
# Not a valid node path set
self.log.error("No valid camera node found on review node: "
"{}".format(ropnode.path()))
return
camera_path = ropnode.parm("camera").eval()
camera_node = hou.node(camera_path)
if not camera_node:
raise RuntimeError("No valid camera node found on review node: "
"{}".format(camera_path))
# Collect focal length.
focal_length_parm = camera.parm("focal")
focal_length_parm = camera_node.parm("focal")
if not focal_length_parm:
self.log.warning("No 'focal' (focal length) parameter found on "
"camera: {}".format(camera.path()))
"camera: {}".format(camera_path))
return
if focal_length_parm.isTimeDependent():
@ -50,3 +48,5 @@ class CollectHoudiniReviewData(pyblish.api.InstancePlugin):
# Store focal length in `burninDataMembers`
burnin_members = instance.data.setdefault("burninDataMembers", {})
burnin_members["focalLength"] = focal_length
instance.data.setdefault("families", []).append('ftrack')

View file

@ -1,53 +1,56 @@
import os
import pyblish.api
from openpype.pipeline import publish
from openpype.hosts.houdini.api.lib import render_rop, get_output_parameter
from openpype.pipeline import (
publish,
OptionalPyblishPluginMixin
)
from openpype.hosts.houdini.api.lib import render_rop
import hou
class ExtractOpenGL(publish.Extractor):
class ExtractOpenGL(publish.Extractor,
OptionalPyblishPluginMixin):
order = pyblish.api.ExtractorOrder
order = pyblish.api.ExtractorOrder - 0.01
label = "Extract OpenGL"
families = ["review"]
hosts = ["houdini"]
optional = True
def process(self, instance):
if not self.is_active(instance.data):
return
ropnode = hou.node(instance.data.get("instance_node"))
ropnode = hou.node(instance.data["instance_node"])
# Get the filename from the filename parameter
# `.evalParm(parameter)` will make sure all tokens are resolved
output = get_output_parameter(ropnode).eval()
staging_dir = os.path.dirname(output)
output = ropnode.evalParm("picture")
staging_dir = os.path.normpath(os.path.dirname(output))
instance.data["stagingDir"] = staging_dir
file_name = os.path.basename(output)
# We run the render
self.log.info("Extracting '%s' to '%s'" % (file_name, staging_dir))
self.log.info("Extracting '%s' to '%s'" % (file_name,
staging_dir))
render_rop(ropnode)
# Unfortunately user interrupting the extraction does not raise an
# error and thus still continues to the integrator. To capture that
# we make sure all files exist
files = instance.data["frames"]
missing = [fname for fname in files
if not os.path.exists(os.path.join(staging_dir, fname))]
if missing:
raise RuntimeError("Failed to complete review extraction. "
"Missing output files: {}".format(missing))
output = instance.data["frames"]
representation = {
"name": "png",
"ext": "png",
"files": files,
tags = ["review"]
if not instance.data.get("keepImages"):
tags.append("delete")
representation = {
"name": instance.data["imageFormat"],
"ext": instance.data["imageFormat"],
"files": output,
"stagingDir": staging_dir,
"frameStart": instance.data["frameStart"],
"frameEnd": instance.data["frameEnd"],
"tags": ["review"]
"tags": tags,
"preview": True,
"camera_name": instance.data.get("review_camera")
}
if "representations" not in instance.data:

View file

@ -0,0 +1,50 @@
# -*- coding: utf-8 -*-
import pyblish.api
from openpype.pipeline import PublishValidationError
import hou
class ValidateSceneReview(pyblish.api.InstancePlugin):
"""Validator Some Scene Settings before publishing the review
1. Scene Path
2. Resolution
"""
order = pyblish.api.ValidatorOrder
families = ["review"]
hosts = ["houdini"]
label = "Scene Setting for review"
def process(self, instance):
invalid = self.get_invalid_scene_path(instance)
if invalid:
raise PublishValidationError(
"Scene path does not exist: %s" % invalid,
title=self.label)
invalid = self.get_invalid_resolution(instance)
if invalid:
raise PublishValidationError(
"Invalid Resolution Setting",
title=self.label)
def get_invalid_scene_path(self, instance):
invalid = list()
node = hou.node(instance.data.get("instance_node"))
scene_path = node.parm("scenepath").eval()
scene_path_node = hou.node(scene_path)
if not scene_path_node:
invalid.append(scene_path_node)
return invalid
def get_invalid_resolution(self, instance):
invalid = list()
node = hou.node(instance.data.get("instance_node"))
res_width = node.parm("res1").eval()
res_height = node.parm("res2").eval()
if res_width == 0:
invalid.append(res_width)
if res_height == 0:
invalid.append(res_height)
return invalid