From a896a3a9e9ac398625a47a6f4765723bf3c3cc02 Mon Sep 17 00:00:00 2001 From: karimmozlia Date: Mon, 11 Oct 2021 09:31:50 +0200 Subject: [PATCH] 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)