From a896a3a9e9ac398625a47a6f4765723bf3c3cc02 Mon Sep 17 00:00:00 2001 From: karimmozlia Date: Mon, 11 Oct 2021 09:31:50 +0200 Subject: [PATCH 01/19] base func and files --- openpype/hosts/nuke/api/lib.py | 17 ++ .../hosts/nuke/plugins/create/create_geo.py | 53 +++++ .../hosts/nuke/plugins/load/load_geo_abc.py | 187 ++++++++++++++++++ 3 files changed, 257 insertions(+) create mode 100644 openpype/hosts/nuke/plugins/create/create_geo.py create mode 100644 openpype/hosts/nuke/plugins/load/load_geo_abc.py diff --git a/openpype/hosts/nuke/api/lib.py b/openpype/hosts/nuke/api/lib.py index 6fe9af744b..40701605e5 100644 --- a/openpype/hosts/nuke/api/lib.py +++ b/openpype/hosts/nuke/api/lib.py @@ -1823,3 +1823,20 @@ def recreate_instance(origin_node, avalon_data=None): dn.setInput(0, new_node) return new_node + + +def extract_alembic(file, + startFrame=None, + endFrame=None): + """Extract an Alembic Geo. + + This extracts an Alembic Geo .... what was Collected into the instance. + + Arguments: + + startFrame (float): Start frame of output. + + endFrame (float): End frame of output. + + """ + pass \ No newline at end of file diff --git a/openpype/hosts/nuke/plugins/create/create_geo.py b/openpype/hosts/nuke/plugins/create/create_geo.py new file mode 100644 index 0000000000..6aefe6d51a --- /dev/null +++ b/openpype/hosts/nuke/plugins/create/create_geo.py @@ -0,0 +1,53 @@ +from avalon.nuke import lib as anlib +from openpype.hosts.nuke.api import plugin +import nuke + + +class CreateGeo(plugin.PypeCreator): + """Add Publishable Geometry""" + + name = "geo" + label = "Create 3d Geo" + family = "model" + icon = "cube" + defaults = ["Main"] + + def __init__(self, *args, **kwargs): + super(CreateGeo, self).__init__(*args, **kwargs) + self.nodes = nuke.selectedNodes() + self.node_color = "0xff3200ff" + return + + def process(self): + nodes = list() + if (self.options or {}).get("useSelection"): + nodes = self.nodes + + if len(nodes) >= 1: + # loop selected nodes + for n in nodes: + data = self.data.copy() + if len(nodes) > 1: + # rename subset name only if more + # then one node are selected + subset = self.family + n["name"].value().capitalize() + data["subset"] = subset + + # change node color + n["tile_color"].setValue(int(self.node_color, 16)) + # add avalon knobs + anlib.set_avalon_knob_data(n, data) + return True + else: + msg = str("Please select nodes you " + "wish to add to a container") + self.log.error(msg) + nuke.message(msg) + return + else: + # if selected is off then create one node + geo_node = nuke.createNode("Geo2") + geo_node["tile_color"].setValue(int(self.node_color, 16)) + # add avalon knobs + instance = anlib.set_avalon_knob_data(geo_node, self.data) + return instance diff --git a/openpype/hosts/nuke/plugins/load/load_geo_abc.py b/openpype/hosts/nuke/plugins/load/load_geo_abc.py new file mode 100644 index 0000000000..faf63281cc --- /dev/null +++ b/openpype/hosts/nuke/plugins/load/load_geo_abc.py @@ -0,0 +1,187 @@ +from avalon import api, io +from avalon.nuke import lib as anlib +from avalon.nuke import containerise, update_container +import nuke + + +class AlembicGeoLoader(api.Loader): + """ + This will load alembic geo into script. + """ + + families = ["geo"] + representations = ["abc"] + + label = "Load Alembic Geo" + icon = "geo" + color = "orange" + node_color = "0xff3200ff" + + def load(self, context, name, namespace, data): + # get main variables + version = context['version'] + version_data = version.get("data", {}) + vname = version.get("name", None) + first = version_data.get("frameStart", None) + last = version_data.get("frameEnd", None) + fps = version_data.get("fps") or nuke.root()["fps"].getValue() + namespace = namespace or context['asset']['name'] + object_name = "{}_{}".format(name, namespace) + + # prepare data for imprinting + # add additional metadata from the version to imprint to Avalon knob + add_keys = ["source", "author", "fps"] + + data_imprint = {"frameStart": first, + "frameEnd": last, + "version": vname, + "objectName": object_name} + + for k in add_keys: + data_imprint.update({k: version_data[k]}) + + # getting file path + file = self.fname.replace("\\", "/") + + with anlib.maintained_selection(): + geo_node = nuke.createNode( + "Geo2", + "name {} file {} read_from_file True".format( + object_name, file), + inpanel=False + ) + geo_node.forceValidate() + geo_node["frame_rate"].setValue(float(fps)) + + # workaround because nuke's bug is not adding + # animation keys properly + xpos = geo_node.xpos() + ypos = geo_node.ypos() + nuke.nodeCopy("%clipboard%") + nuke.delete(geo_node) + nuke.nodePaste("%clipboard%") + geo_node = nuke.toNode(object_name) + geo_node.setXYpos(xpos, ypos) + + # color node by correct color by actual version + self.node_version_color(version, geo_node) + + return containerise( + node=geo_node, + name=name, + namespace=namespace, + context=context, + loader=self.__class__.__name__, + data=data_imprint) + + def update(self, container, representation): + """ + Called by Scene Inventory when look should be updated to current + version. + If any reference edits cannot be applied, eg. shader renamed and + material not present, reference is unloaded and cleaned. + All failed edits are highlighted to the user via message box. + + Args: + container: object that has look to be updated + representation: (dict): relationship data to get proper + representation from DB and persisted + data in .json + Returns: + None + """ + # Get version from io + version = io.find_one({ + "type": "version", + "_id": representation["parent"] + }) + object_name = container['objectName'] + # get corresponding node + geo_node = nuke.toNode(object_name) + + # get main variables + version_data = version.get("data", {}) + vname = version.get("name", None) + first = version_data.get("frameStart", None) + last = version_data.get("frameEnd", None) + fps = version_data.get("fps") or nuke.root()["fps"].getValue() + + # prepare data for imprinting + # add additional metadata from the version to imprint to Avalon knob + add_keys = ["source", "author", "fps"] + + data_imprint = {"representation": str(representation["_id"]), + "frameStart": first, + "frameEnd": last, + "version": vname, + "objectName": object_name} + + for k in add_keys: + data_imprint.update({k: version_data[k]}) + + # getting file path + file = api.get_representation_path(representation).replace("\\", "/") + + with anlib.maintained_selection(): + geo_node = nuke.toNode(object_name) + geo_node['selected'].setValue(True) + + # collect input output dependencies + dependencies = geo_node.dependencies() + dependent = geo_node.dependent() + + geo_node["frame_rate"].setValue(float(fps)) + geo_node["file"].setValue(file) + + # workaround because nuke's bug is + # not adding animation keys properly + xpos = geo_node.xpos() + ypos = geo_node.ypos() + nuke.nodeCopy("%clipboard%") + nuke.delete(geo_node) + nuke.nodePaste("%clipboard%") + geo_node = nuke.toNode(object_name) + geo_node.setXYpos(xpos, ypos) + + # link to original input nodes + for i, input in enumerate(dependencies): + geo_node.setInput(i, input) + # link to original output nodes + for d in dependent: + index = next((i for i, dpcy in enumerate( + d.dependencies()) + if geo_node is dpcy), 0) + d.setInput(index, geo_node) + + # color node by correct color by actual version + self.node_version_color(version, geo_node) + + self.log.info("udated to version: {}".format(version.get("name"))) + + return update_container(geo_node, data_imprint) + + def node_version_color(self, version, node): + """ Coloring a node by correct color by actual version + """ + # get all versions in list + versions = io.find({ + "type": "version", + "parent": version["parent"] + }).distinct('name') + + max_version = max(versions) + + # change color of node + if version.get("name") not in [max_version]: + node["tile_color"].setValue(int("0xd88467ff", 16)) + else: + node["tile_color"].setValue(int(self.node_color, 16)) + + def switch(self, container, representation): + self.update(container, representation) + + def remove(self, container): + from avalon.nuke import viewer_update_and_undo_stop + node = nuke.toNode(container['objectName']) + with viewer_update_and_undo_stop(): + nuke.delete(node) From a6c1037de2671b491df51a7fa8d33e1834685835 Mon Sep 17 00:00:00 2001 From: karimmozlia Date: Wed, 13 Oct 2021 11:41:56 +0200 Subject: [PATCH 02/19] model family name instead of geo --- .../create/{create_geo.py => create_model.py} | 16 +- .../load/{load_geo_abc.py => load_model.py} | 66 +++---- .../nuke/plugins/publish/collect_model.py | 50 +++++ .../nuke/plugins/publish/extract_model.py | 185 ++++++++++++++++++ .../nuke/plugins/publish/validate_model.py | 58 ++++++ 5 files changed, 334 insertions(+), 41 deletions(-) rename openpype/hosts/nuke/plugins/create/{create_geo.py => create_model.py} (79%) rename openpype/hosts/nuke/plugins/load/{load_geo_abc.py => load_model.py} (78%) create mode 100644 openpype/hosts/nuke/plugins/publish/collect_model.py create mode 100644 openpype/hosts/nuke/plugins/publish/extract_model.py create mode 100644 openpype/hosts/nuke/plugins/publish/validate_model.py diff --git a/openpype/hosts/nuke/plugins/create/create_geo.py b/openpype/hosts/nuke/plugins/create/create_model.py similarity index 79% rename from openpype/hosts/nuke/plugins/create/create_geo.py rename to openpype/hosts/nuke/plugins/create/create_model.py index 6aefe6d51a..26b80788ff 100644 --- a/openpype/hosts/nuke/plugins/create/create_geo.py +++ b/openpype/hosts/nuke/plugins/create/create_model.py @@ -3,17 +3,17 @@ from openpype.hosts.nuke.api import plugin import nuke -class CreateGeo(plugin.PypeCreator): - """Add Publishable Geometry""" +class CreateModel(plugin.PypeCreator): + """Add Publishable Modelmetry""" - name = "geo" - label = "Create 3d Geo" + name = "model" + label = "Create 3d Model" family = "model" icon = "cube" defaults = ["Main"] def __init__(self, *args, **kwargs): - super(CreateGeo, self).__init__(*args, **kwargs) + super(CreateModel, self).__init__(*args, **kwargs) self.nodes = nuke.selectedNodes() self.node_color = "0xff3200ff" return @@ -46,8 +46,8 @@ class CreateGeo(plugin.PypeCreator): return else: # if selected is off then create one node - geo_node = nuke.createNode("Geo2") - geo_node["tile_color"].setValue(int(self.node_color, 16)) + model_node = nuke.createNode("Model2") + model_node["tile_color"].setValue(int(self.node_color, 16)) # add avalon knobs - instance = anlib.set_avalon_knob_data(geo_node, self.data) + instance = anlib.set_avalon_knob_data(model_node, self.data) return instance diff --git a/openpype/hosts/nuke/plugins/load/load_geo_abc.py b/openpype/hosts/nuke/plugins/load/load_model.py similarity index 78% rename from openpype/hosts/nuke/plugins/load/load_geo_abc.py rename to openpype/hosts/nuke/plugins/load/load_model.py index faf63281cc..4ff568214e 100644 --- a/openpype/hosts/nuke/plugins/load/load_geo_abc.py +++ b/openpype/hosts/nuke/plugins/load/load_model.py @@ -4,16 +4,16 @@ from avalon.nuke import containerise, update_container import nuke -class AlembicGeoLoader(api.Loader): +class AlembicModelLoader(api.Loader): """ - This will load alembic geo into script. + This will load alembic model into script. """ - families = ["geo"] + families = ["model"] representations = ["abc"] - label = "Load Alembic Geo" - icon = "geo" + label = "Load Alembic Model" + icon = "model" color = "orange" node_color = "0xff3200ff" @@ -44,30 +44,30 @@ class AlembicGeoLoader(api.Loader): file = self.fname.replace("\\", "/") with anlib.maintained_selection(): - geo_node = nuke.createNode( - "Geo2", + model_node = nuke.createNode( + "Model2", "name {} file {} read_from_file True".format( object_name, file), inpanel=False ) - geo_node.forceValidate() - geo_node["frame_rate"].setValue(float(fps)) + model_node.forceValidate() + model_node["frame_rate"].setValue(float(fps)) # workaround because nuke's bug is not adding # animation keys properly - xpos = geo_node.xpos() - ypos = geo_node.ypos() + xpos = model_node.xpos() + ypos = model_node.ypos() nuke.nodeCopy("%clipboard%") - nuke.delete(geo_node) + nuke.delete(model_node) nuke.nodePaste("%clipboard%") - geo_node = nuke.toNode(object_name) - geo_node.setXYpos(xpos, ypos) + model_node = nuke.toNode(object_name) + model_node.setXYpos(xpos, ypos) # color node by correct color by actual version - self.node_version_color(version, geo_node) + self.node_version_color(version, model_node) return containerise( - node=geo_node, + node=model_node, name=name, namespace=namespace, context=context, @@ -97,7 +97,7 @@ class AlembicGeoLoader(api.Loader): }) object_name = container['objectName'] # get corresponding node - geo_node = nuke.toNode(object_name) + model_node = nuke.toNode(object_name) # get main variables version_data = version.get("data", {}) @@ -123,42 +123,42 @@ class AlembicGeoLoader(api.Loader): file = api.get_representation_path(representation).replace("\\", "/") with anlib.maintained_selection(): - geo_node = nuke.toNode(object_name) - geo_node['selected'].setValue(True) + model_node = nuke.toNode(object_name) + model_node['selected'].setValue(True) # collect input output dependencies - dependencies = geo_node.dependencies() - dependent = geo_node.dependent() + dependencies = model_node.dependencies() + dependent = model_node.dependent() - geo_node["frame_rate"].setValue(float(fps)) - geo_node["file"].setValue(file) + model_node["frame_rate"].setValue(float(fps)) + model_node["file"].setValue(file) # workaround because nuke's bug is # not adding animation keys properly - xpos = geo_node.xpos() - ypos = geo_node.ypos() + xpos = model_node.xpos() + ypos = model_node.ypos() nuke.nodeCopy("%clipboard%") - nuke.delete(geo_node) + nuke.delete(model_node) nuke.nodePaste("%clipboard%") - geo_node = nuke.toNode(object_name) - geo_node.setXYpos(xpos, ypos) + model_node = nuke.toNode(object_name) + model_node.setXYpos(xpos, ypos) # link to original input nodes for i, input in enumerate(dependencies): - geo_node.setInput(i, input) + model_node.setInput(i, input) # link to original output nodes for d in dependent: index = next((i for i, dpcy in enumerate( d.dependencies()) - if geo_node is dpcy), 0) - d.setInput(index, geo_node) + if model_node is dpcy), 0) + d.setInput(index, model_node) # color node by correct color by actual version - self.node_version_color(version, geo_node) + self.node_version_color(version, model_node) self.log.info("udated to version: {}".format(version.get("name"))) - return update_container(geo_node, data_imprint) + return update_container(model_node, data_imprint) def node_version_color(self, version, node): """ Coloring a node by correct color by actual version diff --git a/openpype/hosts/nuke/plugins/publish/collect_model.py b/openpype/hosts/nuke/plugins/publish/collect_model.py new file mode 100644 index 0000000000..f764c9d9ac --- /dev/null +++ b/openpype/hosts/nuke/plugins/publish/collect_model.py @@ -0,0 +1,50 @@ +import pyblish.api +import nuke + + +@pyblish.api.log +class CollectModel(pyblish.api.InstancePlugin): + """Collect Model (group) node instance and its content + """ + + order = pyblish.api.CollectorOrder + 0.22 + label = "Collect Model (Group)" + hosts = ["nuke"] + families = ["model"] + + def process(self, instance): + + grpn = instance[0] + + # add family to familiess + instance.data["families"].insert(0, instance.data["family"]) + # make label nicer + instance.data["label"] = "{0} ({1} nodes)".format( + grpn.name(), len(instance) - 1) + + # Get frame range + handle_start = instance.context.data["handleStart"] + handle_end = instance.context.data["handleEnd"] + first_frame = int(nuke.root()["first_frame"].getValue()) + last_frame = int(nuke.root()["last_frame"].getValue()) + + # Add version data to instance + version_data = { + "handles": handle_start, + "handleStart": handle_start, + "handleEnd": handle_end, + "frameStart": first_frame + handle_start, + "frameEnd": last_frame - handle_end, + "colorspace": nuke.root().knob('workingSpaceLUT').value(), + "families": [instance.data["family"]] + instance.data["families"], + "subset": instance.data["subset"], + "fps": instance.context.data["fps"] + } + + instance.data.update({ + "versionData": version_data, + "frameStart": first_frame, + "frameEnd": last_frame + }) + self.log.info("Model content collected: `{}`".format(instance[:])) + self.log.info("Model instance collected: `{}`".format(instance)) diff --git a/openpype/hosts/nuke/plugins/publish/extract_model.py b/openpype/hosts/nuke/plugins/publish/extract_model.py new file mode 100644 index 0000000000..bd6fa1e337 --- /dev/null +++ b/openpype/hosts/nuke/plugins/publish/extract_model.py @@ -0,0 +1,185 @@ +import nuke +import os +import math +import pyblish.api +import openpype.api +from avalon.nuke import lib as anlib +from pprint import pformat + + +class ExtractModel(openpype.api.Extractor): + """ 3D model exctractor + """ + label = 'Exctract Model' + order = pyblish.api.ExtractorOrder + families = ["model"] + hosts = ["nuke"] + + # presets + write_geo_knobs = [ + ("file_type", "abc"), + ("storageFormat", "Ogawa"), + ("writeGeometries", False), + ("writePointClouds", False), + ("writeAxes", False) + ] + + def process(self, instance): + handle_start = instance.context.data["handleStart"] + handle_end = instance.context.data["handleEnd"] + first_frame = int(nuke.root()["first_frame"].getValue()) + last_frame = int(nuke.root()["last_frame"].getValue()) + step = 1 + output_range = str(nuke.FrameRange(first_frame, last_frame, step)) + + self.log.info("instance.data: `{}`".format( + pformat(instance.data))) + + rm_nodes = list() + self.log.info("Crating additional nodes") + subset = instance.data["subset"] + staging_dir = self.staging_dir(instance) + + # get extension form preset + extension = next((k[1] for k in self.write_geo_knobs + if k[0] == "file_type"), None) + if not extension: + raise RuntimeError( + "Bad config for extension in presets. " + "Talk to your supervisor or pipeline admin") + + # create file name and path + filename = subset + ".{}".format(extension) + file_path = os.path.join(staging_dir, filename).replace("\\", "/") + + with anlib.maintained_selection(): + # bake model with axeses onto word coordinate XYZ + rm_n = bakeModelWithAxeses( + nuke.toNode(instance.data["name"]), output_range) + rm_nodes.append(rm_n) + + # create scene node + rm_n = nuke.createNode("Scene") + rm_nodes.append(rm_n) + + # create write geo node + wg_n = nuke.createNode("WriteGeo") + wg_n["file"].setValue(file_path) + # add path to write to + for k, v in self.write_geo_knobs: + wg_n[k].setValue(v) + rm_nodes.append(wg_n) + + # write out model + nuke.execute( + wg_n, + int(first_frame), + int(last_frame) + ) + # erase additional nodes + for n in rm_nodes: + nuke.delete(n) + + self.log.info(file_path) + + # create representation data + if "representations" not in instance.data: + instance.data["representations"] = [] + + representation = { + 'name': extension, + 'ext': extension, + 'files': filename, + "stagingDir": staging_dir, + "frameStart": first_frame, + "frameEnd": last_frame + } + instance.data["representations"].append(representation) + + instance.data.update({ + "path": file_path, + "outputDir": staging_dir, + "ext": extension, + "handleStart": handle_start, + "handleEnd": handle_end, + "frameStart": first_frame + handle_start, + "frameEnd": last_frame - handle_end, + "frameStartHandle": first_frame, + "frameEndHandle": last_frame, + }) + + self.log.info("Extracted instance '{0}' to: {1}".format( + instance.name, file_path)) + + +def bakeModelWithAxeses(model_node, output_range): + """ Baking all perent hiearchy of axeses into model + with transposition onto word XYZ coordinance + """ + bakeFocal = False + bakeHaperture = False + bakeVaperture = False + + model_matrix = model_node['world_matrix'] + + new_cam_n = nuke.createNode("Model2") + new_cam_n.setInput(0, None) + new_cam_n['rotate'].setAnimated() + new_cam_n['translate'].setAnimated() + + old_focal = model_node['focal'] + if old_focal.isAnimated() and not (old_focal.animation(0).constant()): + new_cam_n['focal'].setAnimated() + bakeFocal = True + else: + new_cam_n['focal'].setValue(old_focal.value()) + + old_haperture = model_node['haperture'] + if old_haperture.isAnimated() and not ( + old_haperture.animation(0).constant()): + new_cam_n['haperture'].setAnimated() + bakeHaperture = True + else: + new_cam_n['haperture'].setValue(old_haperture.value()) + + old_vaperture = model_node['vaperture'] + if old_vaperture.isAnimated() and not ( + old_vaperture.animation(0).constant()): + new_cam_n['vaperture'].setAnimated() + bakeVaperture = True + else: + new_cam_n['vaperture'].setValue(old_vaperture.value()) + + new_cam_n['win_translate'].setValue(model_node['win_translate'].value()) + new_cam_n['win_scale'].setValue(model_node['win_scale'].value()) + + for x in nuke.FrameRange(output_range): + math_matrix = nuke.math.Matrix4() + for y in range(model_matrix.height()): + for z in range(model_matrix.width()): + matrix_pointer = z + (y * model_matrix.width()) + math_matrix[matrix_pointer] = model_matrix.getValueAt( + x, (y + (z * model_matrix.width()))) + + rot_matrix = nuke.math.Matrix4(math_matrix) + rot_matrix.rotationOnly() + rot = rot_matrix.rotationsZXY() + + new_cam_n['rotate'].setValueAt(math.degrees(rot[0]), x, 0) + new_cam_n['rotate'].setValueAt(math.degrees(rot[1]), x, 1) + new_cam_n['rotate'].setValueAt(math.degrees(rot[2]), x, 2) + new_cam_n['translate'].setValueAt( + model_matrix.getValueAt(x, 3), x, 0) + new_cam_n['translate'].setValueAt( + model_matrix.getValueAt(x, 7), x, 1) + new_cam_n['translate'].setValueAt( + model_matrix.getValueAt(x, 11), x, 2) + + if bakeFocal: + new_cam_n['focal'].setValueAt(old_focal.getValueAt(x), x) + if bakeHaperture: + new_cam_n['haperture'].setValueAt(old_haperture.getValueAt(x), x) + if bakeVaperture: + new_cam_n['vaperture'].setValueAt(old_vaperture.getValueAt(x), x) + + return new_cam_n diff --git a/openpype/hosts/nuke/plugins/publish/validate_model.py b/openpype/hosts/nuke/plugins/publish/validate_model.py new file mode 100644 index 0000000000..03b7092767 --- /dev/null +++ b/openpype/hosts/nuke/plugins/publish/validate_model.py @@ -0,0 +1,58 @@ +import pyblish +from avalon.nuke import lib as anlib +import nuke + + +class OpenFailedGroupNode(pyblish.api.Action): + """ + Centering failed instance node in node grap + """ + + label = "Open Model in Node Graph" + icon = "wrench" + on = "failed" + + def process(self, context, plugin): + + # Get the errored instances + failed = [] + for result in context.data["results"]: + if (result["error"] is not None and result["instance"] is not None + and result["instance"] not in failed): + failed.append(result["instance"]) + + # Apply pyblish.logic to get the instances for the plug-in + instances = pyblish.api.instances_by_plugin(failed, plugin) + + # maintain selection + with anlib.maintained_selection(): + # collect all failed nodes xpos and ypos + for instance in instances: + grpn = instance[0] + nuke.showDag(grpn) + + +@pyblish.api.log +class ValidateModel(pyblish.api.InstancePlugin): + """Validate amount of output nodes in model (group) node""" + + order = pyblish.api.ValidatorOrder + optional = True + families = ["model"] + label = "Validate Model (Group)" + hosts = ["nuke"] + actions = [OpenFailedGroupNode] + + def process(self, instance): + grpn = instance[0] + + with grpn: + connections_out = nuke.allNodes('Output') + msg_multiple_outputs = "Only one outcoming connection from " + "\"{}\" is allowed".format(instance.data["name"]) + assert len(connections_out) <= 1, msg_multiple_outputs + + connections_in = nuke.allNodes('Input') + msg_missing_inputs = "At least one Input node has to be used in: " + "\"{}\"".format(instance.data["name"]) + assert len(connections_in) >= 1, msg_missing_inputs From 6c53bc172417843c4cea7012464f20777412b371 Mon Sep 17 00:00:00 2001 From: karimmozlia Date: Wed, 13 Oct 2021 11:45:36 +0200 Subject: [PATCH 03/19] add mode to nuke josn --- openpype/hosts/nuke/api/__init__.py | 3 ++- openpype/settings/defaults/project_settings/nuke.json | 1 + .../schemas/projects_schema/schemas/schema_nuke_publish.json | 3 +++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/openpype/hosts/nuke/api/__init__.py b/openpype/hosts/nuke/api/__init__.py index e6dab5cfc9..e684b48fa3 100644 --- a/openpype/hosts/nuke/api/__init__.py +++ b/openpype/hosts/nuke/api/__init__.py @@ -70,7 +70,8 @@ def install(): family_states = [ "write", "review", - "nukenodes" + "nukenodes", + "model", "gizmo" ] diff --git a/openpype/settings/defaults/project_settings/nuke.json b/openpype/settings/defaults/project_settings/nuke.json index dd65df02e5..4085409e23 100644 --- a/openpype/settings/defaults/project_settings/nuke.json +++ b/openpype/settings/defaults/project_settings/nuke.json @@ -32,6 +32,7 @@ "PreCollectNukeInstances": { "sync_workfile_version_on_families": [ "nukenodes", + "model", "camera", "gizmo", "source", diff --git a/openpype/settings/entities/schemas/projects_schema/schemas/schema_nuke_publish.json b/openpype/settings/entities/schemas/projects_schema/schemas/schema_nuke_publish.json index 74b2592d29..8764435ed3 100644 --- a/openpype/settings/entities/schemas/projects_schema/schemas/schema_nuke_publish.json +++ b/openpype/settings/entities/schemas/projects_schema/schemas/schema_nuke_publish.json @@ -24,6 +24,9 @@ { "nukenodes": "nukenodes" }, + { + "model": "model" + }, { "camera": "camera" }, From bdcafe328e41098aef595f42c35944ca2879271c Mon Sep 17 00:00:00 2001 From: karimmozlia Date: Wed, 13 Oct 2021 12:18:57 +0200 Subject: [PATCH 04/19] add write geo extension to jsons --- .../hosts/nuke/plugins/create/create_model.py | 2 +- .../hosts/nuke/plugins/load/load_model.py | 2 +- .../nuke/plugins/publish/extract_model.py | 101 ++---------------- .../defaults/project_settings/nuke.json | 3 + .../projects_schema/schema_project_nuke.json | 14 +++ 5 files changed, 30 insertions(+), 92 deletions(-) diff --git a/openpype/hosts/nuke/plugins/create/create_model.py b/openpype/hosts/nuke/plugins/create/create_model.py index 26b80788ff..e458e0677b 100644 --- a/openpype/hosts/nuke/plugins/create/create_model.py +++ b/openpype/hosts/nuke/plugins/create/create_model.py @@ -4,7 +4,7 @@ import nuke class CreateModel(plugin.PypeCreator): - """Add Publishable Modelmetry""" + """Add Publishable Model Geometry""" name = "model" label = "Create 3d Model" diff --git a/openpype/hosts/nuke/plugins/load/load_model.py b/openpype/hosts/nuke/plugins/load/load_model.py index 4ff568214e..7e11abbae3 100644 --- a/openpype/hosts/nuke/plugins/load/load_model.py +++ b/openpype/hosts/nuke/plugins/load/load_model.py @@ -45,7 +45,7 @@ class AlembicModelLoader(api.Loader): with anlib.maintained_selection(): model_node = nuke.createNode( - "Model2", + "ReadGeo2", "name {} file {} read_from_file True".format( object_name, file), inpanel=False diff --git a/openpype/hosts/nuke/plugins/publish/extract_model.py b/openpype/hosts/nuke/plugins/publish/extract_model.py index bd6fa1e337..f050ec92bb 100644 --- a/openpype/hosts/nuke/plugins/publish/extract_model.py +++ b/openpype/hosts/nuke/plugins/publish/extract_model.py @@ -19,7 +19,7 @@ class ExtractModel(openpype.api.Extractor): write_geo_knobs = [ ("file_type", "abc"), ("storageFormat", "Ogawa"), - ("writeGeometries", False), + ("writeGeometries", True), ("writePointClouds", False), ("writeAxes", False) ] @@ -32,6 +32,7 @@ class ExtractModel(openpype.api.Extractor): step = 1 output_range = str(nuke.FrameRange(first_frame, last_frame, step)) + self.log.info("instance.data: `{}`".format( pformat(instance.data))) @@ -40,28 +41,21 @@ class ExtractModel(openpype.api.Extractor): subset = instance.data["subset"] staging_dir = self.staging_dir(instance) - # get extension form preset - extension = next((k[1] for k in self.write_geo_knobs - if k[0] == "file_type"), None) - if not extension: - raise RuntimeError( - "Bad config for extension in presets. " - "Talk to your supervisor or pipeline admin") + # get extension form setting or from preset + extension = instance.context.data["modelFormat"] + if not extension : + extension = next((k[1] for k in self.write_geo_knobs + if k[0] == "file_type"), None) + if not extension: + raise RuntimeError( + "Bad config for extension in presets. " + "Talk to your supervisor or pipeline admin") # create file name and path filename = subset + ".{}".format(extension) file_path = os.path.join(staging_dir, filename).replace("\\", "/") with anlib.maintained_selection(): - # bake model with axeses onto word coordinate XYZ - rm_n = bakeModelWithAxeses( - nuke.toNode(instance.data["name"]), output_range) - rm_nodes.append(rm_n) - - # create scene node - rm_n = nuke.createNode("Scene") - rm_nodes.append(rm_n) - # create write geo node wg_n = nuke.createNode("WriteGeo") wg_n["file"].setValue(file_path) @@ -110,76 +104,3 @@ class ExtractModel(openpype.api.Extractor): self.log.info("Extracted instance '{0}' to: {1}".format( instance.name, file_path)) - - -def bakeModelWithAxeses(model_node, output_range): - """ Baking all perent hiearchy of axeses into model - with transposition onto word XYZ coordinance - """ - bakeFocal = False - bakeHaperture = False - bakeVaperture = False - - model_matrix = model_node['world_matrix'] - - new_cam_n = nuke.createNode("Model2") - new_cam_n.setInput(0, None) - new_cam_n['rotate'].setAnimated() - new_cam_n['translate'].setAnimated() - - old_focal = model_node['focal'] - if old_focal.isAnimated() and not (old_focal.animation(0).constant()): - new_cam_n['focal'].setAnimated() - bakeFocal = True - else: - new_cam_n['focal'].setValue(old_focal.value()) - - old_haperture = model_node['haperture'] - if old_haperture.isAnimated() and not ( - old_haperture.animation(0).constant()): - new_cam_n['haperture'].setAnimated() - bakeHaperture = True - else: - new_cam_n['haperture'].setValue(old_haperture.value()) - - old_vaperture = model_node['vaperture'] - if old_vaperture.isAnimated() and not ( - old_vaperture.animation(0).constant()): - new_cam_n['vaperture'].setAnimated() - bakeVaperture = True - else: - new_cam_n['vaperture'].setValue(old_vaperture.value()) - - new_cam_n['win_translate'].setValue(model_node['win_translate'].value()) - new_cam_n['win_scale'].setValue(model_node['win_scale'].value()) - - for x in nuke.FrameRange(output_range): - math_matrix = nuke.math.Matrix4() - for y in range(model_matrix.height()): - for z in range(model_matrix.width()): - matrix_pointer = z + (y * model_matrix.width()) - math_matrix[matrix_pointer] = model_matrix.getValueAt( - x, (y + (z * model_matrix.width()))) - - rot_matrix = nuke.math.Matrix4(math_matrix) - rot_matrix.rotationOnly() - rot = rot_matrix.rotationsZXY() - - new_cam_n['rotate'].setValueAt(math.degrees(rot[0]), x, 0) - new_cam_n['rotate'].setValueAt(math.degrees(rot[1]), x, 1) - new_cam_n['rotate'].setValueAt(math.degrees(rot[2]), x, 2) - new_cam_n['translate'].setValueAt( - model_matrix.getValueAt(x, 3), x, 0) - new_cam_n['translate'].setValueAt( - model_matrix.getValueAt(x, 7), x, 1) - new_cam_n['translate'].setValueAt( - model_matrix.getValueAt(x, 11), x, 2) - - if bakeFocal: - new_cam_n['focal'].setValueAt(old_focal.getValueAt(x), x) - if bakeHaperture: - new_cam_n['haperture'].setValueAt(old_haperture.getValueAt(x), x) - if bakeVaperture: - new_cam_n['vaperture'].setValueAt(old_vaperture.getValueAt(x), x) - - return new_cam_n diff --git a/openpype/settings/defaults/project_settings/nuke.json b/openpype/settings/defaults/project_settings/nuke.json index 4085409e23..0509d65fc7 100644 --- a/openpype/settings/defaults/project_settings/nuke.json +++ b/openpype/settings/defaults/project_settings/nuke.json @@ -26,6 +26,9 @@ "Branch01", "Part01" ] + }, + "CreateModel": { + "extension": ".abc" } }, "publish": { diff --git a/openpype/settings/entities/schemas/projects_schema/schema_project_nuke.json b/openpype/settings/entities/schemas/projects_schema/schema_project_nuke.json index e0b21f4037..10026e3e53 100644 --- a/openpype/settings/entities/schemas/projects_schema/schema_project_nuke.json +++ b/openpype/settings/entities/schemas/projects_schema/schema_project_nuke.json @@ -100,6 +100,20 @@ } } ] + }, + { + "type": "dict", + "collapsible": false, + "key": "CreateModel", + "label": "CreateModel", + "is_group": true, + "children": [ + { + "type": "text", + "key": "extension", + "label": "Extension" + } + ] } ] }, From aa5e6a2b557a2de17caf58c90194f0f8c2c13910 Mon Sep 17 00:00:00 2001 From: karimmozlia Date: Mon, 18 Oct 2021 03:08:26 +0200 Subject: [PATCH 05/19] WriteGeo create_model --- openpype/hosts/nuke/plugins/create/create_model.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/nuke/plugins/create/create_model.py b/openpype/hosts/nuke/plugins/create/create_model.py index e458e0677b..c6368ddb0e 100644 --- a/openpype/hosts/nuke/plugins/create/create_model.py +++ b/openpype/hosts/nuke/plugins/create/create_model.py @@ -46,7 +46,7 @@ class CreateModel(plugin.PypeCreator): return else: # if selected is off then create one node - model_node = nuke.createNode("Model2") + model_node = nuke.createNode("WriteGeo") model_node["tile_color"].setValue(int(self.node_color, 16)) # add avalon knobs instance = anlib.set_avalon_knob_data(model_node, self.data) From 61dd3f419b64fbe206db1bb5bea25d4a3f044f0e Mon Sep 17 00:00:00 2001 From: karimmozlia Date: Mon, 18 Oct 2021 03:10:53 +0200 Subject: [PATCH 06/19] del validatemodel. was in gizmo but not in cam --- .../nuke/plugins/publish/validate_model.py | 58 ------------------- 1 file changed, 58 deletions(-) delete mode 100644 openpype/hosts/nuke/plugins/publish/validate_model.py diff --git a/openpype/hosts/nuke/plugins/publish/validate_model.py b/openpype/hosts/nuke/plugins/publish/validate_model.py deleted file mode 100644 index 03b7092767..0000000000 --- a/openpype/hosts/nuke/plugins/publish/validate_model.py +++ /dev/null @@ -1,58 +0,0 @@ -import pyblish -from avalon.nuke import lib as anlib -import nuke - - -class OpenFailedGroupNode(pyblish.api.Action): - """ - Centering failed instance node in node grap - """ - - label = "Open Model in Node Graph" - icon = "wrench" - on = "failed" - - def process(self, context, plugin): - - # Get the errored instances - failed = [] - for result in context.data["results"]: - if (result["error"] is not None and result["instance"] is not None - and result["instance"] not in failed): - failed.append(result["instance"]) - - # Apply pyblish.logic to get the instances for the plug-in - instances = pyblish.api.instances_by_plugin(failed, plugin) - - # maintain selection - with anlib.maintained_selection(): - # collect all failed nodes xpos and ypos - for instance in instances: - grpn = instance[0] - nuke.showDag(grpn) - - -@pyblish.api.log -class ValidateModel(pyblish.api.InstancePlugin): - """Validate amount of output nodes in model (group) node""" - - order = pyblish.api.ValidatorOrder - optional = True - families = ["model"] - label = "Validate Model (Group)" - hosts = ["nuke"] - actions = [OpenFailedGroupNode] - - def process(self, instance): - grpn = instance[0] - - with grpn: - connections_out = nuke.allNodes('Output') - msg_multiple_outputs = "Only one outcoming connection from " - "\"{}\" is allowed".format(instance.data["name"]) - assert len(connections_out) <= 1, msg_multiple_outputs - - connections_in = nuke.allNodes('Input') - msg_missing_inputs = "At least one Input node has to be used in: " - "\"{}\"".format(instance.data["name"]) - assert len(connections_in) >= 1, msg_missing_inputs From 484c89ac4a0682085c68f37f9e5b2263b36e78eb Mon Sep 17 00:00:00 2001 From: karimmozlia Date: Mon, 18 Oct 2021 03:53:48 +0200 Subject: [PATCH 07/19] clean attr-test 01 - with ext option parameter --- openpype/hosts/nuke/plugins/load/load_model.py | 2 +- openpype/hosts/nuke/plugins/publish/extract_model.py | 2 +- openpype/settings/defaults/project_settings/nuke.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/openpype/hosts/nuke/plugins/load/load_model.py b/openpype/hosts/nuke/plugins/load/load_model.py index 7e11abbae3..c3312a8d31 100644 --- a/openpype/hosts/nuke/plugins/load/load_model.py +++ b/openpype/hosts/nuke/plugins/load/load_model.py @@ -46,7 +46,7 @@ class AlembicModelLoader(api.Loader): with anlib.maintained_selection(): model_node = nuke.createNode( "ReadGeo2", - "name {} file {} read_from_file True".format( + "name {} file {} ".format( object_name, file), inpanel=False ) diff --git a/openpype/hosts/nuke/plugins/publish/extract_model.py b/openpype/hosts/nuke/plugins/publish/extract_model.py index f050ec92bb..293156a4c5 100644 --- a/openpype/hosts/nuke/plugins/publish/extract_model.py +++ b/openpype/hosts/nuke/plugins/publish/extract_model.py @@ -42,7 +42,7 @@ class ExtractModel(openpype.api.Extractor): staging_dir = self.staging_dir(instance) # get extension form setting or from preset - extension = instance.context.data["modelFormat"] + extension = instance.context.data["project_settings"]["nuke"]["create"]["CreateModel"]["extension"] if not extension : extension = next((k[1] for k in self.write_geo_knobs if k[0] == "file_type"), None) diff --git a/openpype/settings/defaults/project_settings/nuke.json b/openpype/settings/defaults/project_settings/nuke.json index 0509d65fc7..83ccd84755 100644 --- a/openpype/settings/defaults/project_settings/nuke.json +++ b/openpype/settings/defaults/project_settings/nuke.json @@ -28,7 +28,7 @@ ] }, "CreateModel": { - "extension": ".abc" + "extension": "abc" } }, "publish": { From be112112563548d1b519f9576e4267bb570c8625 Mon Sep 17 00:00:00 2001 From: karimmozlia Date: Mon, 18 Oct 2021 03:55:32 +0200 Subject: [PATCH 08/19] without ext option - work fine as abc --- .../hosts/nuke/plugins/publish/extract_model.py | 15 ++++++--------- .../settings/defaults/project_settings/nuke.json | 3 --- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/openpype/hosts/nuke/plugins/publish/extract_model.py b/openpype/hosts/nuke/plugins/publish/extract_model.py index 293156a4c5..7303e6cbbb 100644 --- a/openpype/hosts/nuke/plugins/publish/extract_model.py +++ b/openpype/hosts/nuke/plugins/publish/extract_model.py @@ -41,15 +41,12 @@ class ExtractModel(openpype.api.Extractor): subset = instance.data["subset"] staging_dir = self.staging_dir(instance) - # get extension form setting or from preset - extension = instance.context.data["project_settings"]["nuke"]["create"]["CreateModel"]["extension"] - if not extension : - extension = next((k[1] for k in self.write_geo_knobs - if k[0] == "file_type"), None) - if not extension: - raise RuntimeError( - "Bad config for extension in presets. " - "Talk to your supervisor or pipeline admin") + extension = next((k[1] for k in self.write_geo_knobs + if k[0] == "file_type"), None) + if not extension: + raise RuntimeError( + "Bad config for extension in presets. " + "Talk to your supervisor or pipeline admin") # create file name and path filename = subset + ".{}".format(extension) diff --git a/openpype/settings/defaults/project_settings/nuke.json b/openpype/settings/defaults/project_settings/nuke.json index 83ccd84755..4085409e23 100644 --- a/openpype/settings/defaults/project_settings/nuke.json +++ b/openpype/settings/defaults/project_settings/nuke.json @@ -26,9 +26,6 @@ "Branch01", "Part01" ] - }, - "CreateModel": { - "extension": "abc" } }, "publish": { From a46eb634556cc98b0161ef6484d0fca55d281198 Mon Sep 17 00:00:00 2001 From: karimmozlia Date: Mon, 18 Oct 2021 10:53:38 +0200 Subject: [PATCH 09/19] del extension text from schema --- openpype/hosts/nuke/api/lib.py | 17 ----------------- .../projects_schema/schema_project_nuke.json | 14 -------------- 2 files changed, 31 deletions(-) diff --git a/openpype/hosts/nuke/api/lib.py b/openpype/hosts/nuke/api/lib.py index 40701605e5..6fe9af744b 100644 --- a/openpype/hosts/nuke/api/lib.py +++ b/openpype/hosts/nuke/api/lib.py @@ -1823,20 +1823,3 @@ def recreate_instance(origin_node, avalon_data=None): dn.setInput(0, new_node) return new_node - - -def extract_alembic(file, - startFrame=None, - endFrame=None): - """Extract an Alembic Geo. - - This extracts an Alembic Geo .... what was Collected into the instance. - - Arguments: - - startFrame (float): Start frame of output. - - endFrame (float): End frame of output. - - """ - pass \ No newline at end of file diff --git a/openpype/settings/entities/schemas/projects_schema/schema_project_nuke.json b/openpype/settings/entities/schemas/projects_schema/schema_project_nuke.json index 10026e3e53..e0b21f4037 100644 --- a/openpype/settings/entities/schemas/projects_schema/schema_project_nuke.json +++ b/openpype/settings/entities/schemas/projects_schema/schema_project_nuke.json @@ -100,20 +100,6 @@ } } ] - }, - { - "type": "dict", - "collapsible": false, - "key": "CreateModel", - "label": "CreateModel", - "is_group": true, - "children": [ - { - "type": "text", - "key": "extension", - "label": "Extension" - } - ] } ] }, From 83a9c1e6e83042e32d6cee007207b8695db41088 Mon Sep 17 00:00:00 2001 From: karimmozilla Date: Fri, 22 Oct 2021 10:41:40 +0200 Subject: [PATCH 10/19] Update openpype/hosts/nuke/plugins/load/load_model.py MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jakub Ježek --- openpype/hosts/nuke/plugins/load/load_model.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/nuke/plugins/load/load_model.py b/openpype/hosts/nuke/plugins/load/load_model.py index c3312a8d31..b6893066e3 100644 --- a/openpype/hosts/nuke/plugins/load/load_model.py +++ b/openpype/hosts/nuke/plugins/load/load_model.py @@ -15,7 +15,7 @@ class AlembicModelLoader(api.Loader): label = "Load Alembic Model" icon = "model" color = "orange" - node_color = "0xff3200ff" + node_color = "0x4ecd91ff" def load(self, context, name, namespace, data): # get main variables From e21249d8c4b1f79320763bde2194557dc4e272ae Mon Sep 17 00:00:00 2001 From: karimmozilla Date: Fri, 22 Oct 2021 10:41:58 +0200 Subject: [PATCH 11/19] Update openpype/hosts/nuke/plugins/load/load_model.py MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jakub Ježek --- openpype/hosts/nuke/plugins/load/load_model.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/nuke/plugins/load/load_model.py b/openpype/hosts/nuke/plugins/load/load_model.py index b6893066e3..15fa4fa35c 100644 --- a/openpype/hosts/nuke/plugins/load/load_model.py +++ b/openpype/hosts/nuke/plugins/load/load_model.py @@ -13,7 +13,7 @@ class AlembicModelLoader(api.Loader): representations = ["abc"] label = "Load Alembic Model" - icon = "model" + icon = "cube" color = "orange" node_color = "0x4ecd91ff" From 02d08dfcb8f55603c97969719c92879a01f68a39 Mon Sep 17 00:00:00 2001 From: karimmozlia Date: Fri, 22 Oct 2021 10:46:13 +0200 Subject: [PATCH 12/19] update label --- openpype/hosts/nuke/plugins/publish/extract_model.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/openpype/hosts/nuke/plugins/publish/extract_model.py b/openpype/hosts/nuke/plugins/publish/extract_model.py index 7303e6cbbb..7753efc764 100644 --- a/openpype/hosts/nuke/plugins/publish/extract_model.py +++ b/openpype/hosts/nuke/plugins/publish/extract_model.py @@ -1,6 +1,5 @@ import nuke import os -import math import pyblish.api import openpype.api from avalon.nuke import lib as anlib @@ -31,7 +30,6 @@ class ExtractModel(openpype.api.Extractor): last_frame = int(nuke.root()["last_frame"].getValue()) step = 1 output_range = str(nuke.FrameRange(first_frame, last_frame, step)) - self.log.info("instance.data: `{}`".format( pformat(instance.data))) From 7f1e9569311098efbcf52cca37f48565fde265bb Mon Sep 17 00:00:00 2001 From: karimmozlia Date: Fri, 22 Oct 2021 13:41:46 +0200 Subject: [PATCH 13/19] update label --- openpype/hosts/nuke/plugins/publish/collect_model.py | 4 ++-- openpype/settings/defaults/project_settings/nuke.json | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/openpype/hosts/nuke/plugins/publish/collect_model.py b/openpype/hosts/nuke/plugins/publish/collect_model.py index f764c9d9ac..ade9f90987 100644 --- a/openpype/hosts/nuke/plugins/publish/collect_model.py +++ b/openpype/hosts/nuke/plugins/publish/collect_model.py @@ -4,11 +4,11 @@ import nuke @pyblish.api.log class CollectModel(pyblish.api.InstancePlugin): - """Collect Model (group) node instance and its content + """Collect Model node instance and its content """ order = pyblish.api.CollectorOrder + 0.22 - label = "Collect Model (Group)" + label = "Collect Model" hosts = ["nuke"] families = ["model"] diff --git a/openpype/settings/defaults/project_settings/nuke.json b/openpype/settings/defaults/project_settings/nuke.json index 4085409e23..dd65df02e5 100644 --- a/openpype/settings/defaults/project_settings/nuke.json +++ b/openpype/settings/defaults/project_settings/nuke.json @@ -32,7 +32,6 @@ "PreCollectNukeInstances": { "sync_workfile_version_on_families": [ "nukenodes", - "model", "camera", "gizmo", "source", From 56850e6bd374571fd4cafeb6903cdd13a1609393 Mon Sep 17 00:00:00 2001 From: karimmozlia Date: Fri, 22 Oct 2021 14:29:58 +0200 Subject: [PATCH 14/19] del outputrnage --- openpype/hosts/nuke/plugins/publish/extract_model.py | 1 - 1 file changed, 1 deletion(-) diff --git a/openpype/hosts/nuke/plugins/publish/extract_model.py b/openpype/hosts/nuke/plugins/publish/extract_model.py index 7753efc764..1ad93a49e4 100644 --- a/openpype/hosts/nuke/plugins/publish/extract_model.py +++ b/openpype/hosts/nuke/plugins/publish/extract_model.py @@ -29,7 +29,6 @@ class ExtractModel(openpype.api.Extractor): first_frame = int(nuke.root()["first_frame"].getValue()) last_frame = int(nuke.root()["last_frame"].getValue()) step = 1 - output_range = str(nuke.FrameRange(first_frame, last_frame, step)) self.log.info("instance.data: `{}`".format( pformat(instance.data))) From aa5242ac48265df55f34f489d64fad8537623e06 Mon Sep 17 00:00:00 2001 From: karimmozlia Date: Fri, 22 Oct 2021 14:30:48 +0200 Subject: [PATCH 15/19] del step --- openpype/hosts/nuke/plugins/publish/extract_model.py | 1 - 1 file changed, 1 deletion(-) diff --git a/openpype/hosts/nuke/plugins/publish/extract_model.py b/openpype/hosts/nuke/plugins/publish/extract_model.py index 1ad93a49e4..8a7ecbe093 100644 --- a/openpype/hosts/nuke/plugins/publish/extract_model.py +++ b/openpype/hosts/nuke/plugins/publish/extract_model.py @@ -28,7 +28,6 @@ class ExtractModel(openpype.api.Extractor): handle_end = instance.context.data["handleEnd"] first_frame = int(nuke.root()["first_frame"].getValue()) last_frame = int(nuke.root()["last_frame"].getValue()) - step = 1 self.log.info("instance.data: `{}`".format( pformat(instance.data))) From 283d2575c03d5825e5570a726621be31ee22ed52 Mon Sep 17 00:00:00 2001 From: karimmozlia Date: Thu, 18 Nov 2021 09:56:48 +0200 Subject: [PATCH 16/19] publish without selection --- openpype/hosts/nuke/plugins/publish/extract_model.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/openpype/hosts/nuke/plugins/publish/extract_model.py b/openpype/hosts/nuke/plugins/publish/extract_model.py index 8a7ecbe093..7f9e537189 100644 --- a/openpype/hosts/nuke/plugins/publish/extract_model.py +++ b/openpype/hosts/nuke/plugins/publish/extract_model.py @@ -33,6 +33,7 @@ class ExtractModel(openpype.api.Extractor): pformat(instance.data))) rm_nodes = list() + model_node = instance[0] self.log.info("Crating additional nodes") subset = instance.data["subset"] staging_dir = self.staging_dir(instance) @@ -49,6 +50,9 @@ class ExtractModel(openpype.api.Extractor): file_path = os.path.join(staging_dir, filename).replace("\\", "/") with anlib.maintained_selection(): + # select model node + anlib.select_nodes([model_node]) + # create write geo node wg_n = nuke.createNode("WriteGeo") wg_n["file"].setValue(file_path) From b3581c8ba57d51f74b8199266fc6ce8743415ebb Mon Sep 17 00:00:00 2001 From: karimmozlia Date: Thu, 18 Nov 2021 10:12:21 +0200 Subject: [PATCH 17/19] bound --- openpype/hosts/nuke/plugins/publish/extract_model.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/nuke/plugins/publish/extract_model.py b/openpype/hosts/nuke/plugins/publish/extract_model.py index 7f9e537189..43214bf3e9 100644 --- a/openpype/hosts/nuke/plugins/publish/extract_model.py +++ b/openpype/hosts/nuke/plugins/publish/extract_model.py @@ -28,7 +28,7 @@ class ExtractModel(openpype.api.Extractor): handle_end = instance.context.data["handleEnd"] first_frame = int(nuke.root()["first_frame"].getValue()) last_frame = int(nuke.root()["last_frame"].getValue()) - + self.log.info("instance.data: `{}`".format( pformat(instance.data))) From bda21555d5063446e97a79a93b7759ffa9ed8ef6 Mon Sep 17 00:00:00 2001 From: karimmozlia Date: Mon, 22 Nov 2021 12:59:33 +0200 Subject: [PATCH 18/19] last 3d node in branch --- .../hosts/nuke/plugins/create/create_model.py | 32 +++++++++++++++++++ .../nuke/plugins/publish/collect_model.py | 3 +- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/openpype/hosts/nuke/plugins/create/create_model.py b/openpype/hosts/nuke/plugins/create/create_model.py index c6368ddb0e..849c8bcdde 100644 --- a/openpype/hosts/nuke/plugins/create/create_model.py +++ b/openpype/hosts/nuke/plugins/create/create_model.py @@ -22,7 +22,39 @@ class CreateModel(plugin.PypeCreator): nodes = list() if (self.options or {}).get("useSelection"): nodes = self.nodes + for n in nodes : + n['selected'].setValue(0) + end_nodes = list() + # get the latest nodes in tree for selecion + for n in nodes: + x = n + end = 0 + while end == 0: + try: + x = x.dependent()[0] + except: + end_node = x + end = 1 + end_nodes.append(end_node) + + # set end_nodes + end_nodes = list(set(end_nodes)) + + # check if nodes is 3d nodes + for n in end_nodes : + n['selected'].setValue(1) + sn = nuke.createNode("Scene") + if not sn.input(0) : + end_nodes.remove(n) + nuke.delete(sn) + + # loop over end nodes + for n in end_nodes : + n['selected'].setValue(1) + + self.nodes = nuke.selectedNodes() + nodes = self.nodes if len(nodes) >= 1: # loop selected nodes for n in nodes: diff --git a/openpype/hosts/nuke/plugins/publish/collect_model.py b/openpype/hosts/nuke/plugins/publish/collect_model.py index ade9f90987..5fca240553 100644 --- a/openpype/hosts/nuke/plugins/publish/collect_model.py +++ b/openpype/hosts/nuke/plugins/publish/collect_model.py @@ -19,8 +19,7 @@ class CollectModel(pyblish.api.InstancePlugin): # add family to familiess instance.data["families"].insert(0, instance.data["family"]) # make label nicer - instance.data["label"] = "{0} ({1} nodes)".format( - grpn.name(), len(instance) - 1) + instance.data["label"] = grpn.name() # Get frame range handle_start = instance.context.data["handleStart"] From b2f22accb86ff057d0638b796cdd7ec2ab14d1f7 Mon Sep 17 00:00:00 2001 From: karimmozlia Date: Mon, 22 Nov 2021 13:08:27 +0200 Subject: [PATCH 19/19] bound --- openpype/hosts/nuke/plugins/create/create_model.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/openpype/hosts/nuke/plugins/create/create_model.py b/openpype/hosts/nuke/plugins/create/create_model.py index 849c8bcdde..4e30860e05 100644 --- a/openpype/hosts/nuke/plugins/create/create_model.py +++ b/openpype/hosts/nuke/plugins/create/create_model.py @@ -22,7 +22,7 @@ class CreateModel(plugin.PypeCreator): nodes = list() if (self.options or {}).get("useSelection"): nodes = self.nodes - for n in nodes : + for n in nodes: n['selected'].setValue(0) end_nodes = list() @@ -42,15 +42,15 @@ class CreateModel(plugin.PypeCreator): end_nodes = list(set(end_nodes)) # check if nodes is 3d nodes - for n in end_nodes : + for n in end_nodes: n['selected'].setValue(1) sn = nuke.createNode("Scene") - if not sn.input(0) : + if not sn.input(0): end_nodes.remove(n) nuke.delete(sn) # loop over end nodes - for n in end_nodes : + for n in end_nodes: n['selected'].setValue(1) self.nodes = nuke.selectedNodes()