def initializeDrawable(self): # Measure Line 1 self.guide_geo1 = hou.Geometry() line_verb = hou.sopNodeTypeCategory().nodeVerb("line") line_verb.setParms({ "origin": self.startpos, "dir": hou.Vector3(0, 1, 0), "dist": 1 }) line_verb.execute(self.guide_geo1, []) self.drawable1 = hou.SimpleDrawable(self.scene_viewer, self.guide_geo1, "guide_1") self.drawable1.enable(True) self.drawable1.show(True) # Measure Line 2 self.guide_geo2 = hou.Geometry() line_verb = hou.sopNodeTypeCategory().nodeVerb("line") line_verb.setParms({ "origin": self.startpos, "dir": hou.Vector3(0, 1, 0), "dist": 1 }) line_verb.execute(self.guide_geo2, []) self.drawable2 = hou.SimpleDrawable(self.scene_viewer, self.guide_geo2, "guide_2") self.drawable2.enable(True) self.drawable2.show(True)
def __init__(self): self.asset_gui = None # The order in which these nodes appear is the order they will be created in self.dcc_geo_departments = [Department.MODIFY, Department.MATERIAL] self.dcc_character_departments = [Department.HAIR, Department.CLOTH] self.all_departments = [ Department.MODIFY, Department.MATERIAL, Department.HAIR, Department.CLOTH ] # The source HDA's are currently stored inside the pipe source code. self.hda_path = Environment().get_otl_dir() # We define the template HDAs definitions here, for use in the methods below self.hda_definitions = { Department.MATERIAL: hou.hdaDefinition(hou.sopNodeTypeCategory(), "dcc_material", os.path.join(self.hda_path, "dcc_material.hda")), Department.MODIFY: hou.hdaDefinition(hou.sopNodeTypeCategory(), "dcc_modify", os.path.join(self.hda_path, "dcc_modify.hda")), Department.HAIR: hou.hdaDefinition(hou.objNodeTypeCategory(), "dcc_hair", os.path.join(self.hda_path, "dcc_hair.hda")), Department.CLOTH: hou.hdaDefinition(hou.objNodeTypeCategory(), "dcc_cloth", os.path.join(self.hda_path, "dcc_cloth.hda")) } # By default, we ignore "Asset Controls", so that we can put things in there without them being promoted. # See: inherit_parameters() method self.default_ignored_folders = ["Asset Controls"]
def onStateManagerOpen(self, origin): if platform.system() == "Darwin": origin.menubar.setNativeMenuBar(False) if self.core.uiAvailable: origin.enabledCol = QBrush(QColor(204,204,204)) if self.core.uiAvailable: origin.scrollArea.setStyleSheet(hou.qt.styleSheet().replace("QLabel", "QScrollArea")) origin.f_import.setStyleSheet("QFrame { border: 0px; }") origin.f_export.setStyleSheet("QFrame { border: 0px; }") ssheet = "" ssheet += "QTreeWidget::indicator::checked\n{\n image: url(%s/Plugins/Apps/Houdini/UserInterfaces/checkbox_on.svg);\n}" % self.core.prismRoot ssheet += "QTreeWidget::indicator::unchecked\n{\n image: url(%s/Plugins/Apps/Houdini/UserInterfaces/checkbox_off.svg);\n}" % self.core.prismRoot ssheet += "QTreeWidget::indicator { width: 16px; height: 16px;}" origin.tw_export.setStyleSheet(ssheet) origin.b_stateFromNode.setVisible(True) # origin.b_createDependency.setVisible(True) origin.layout().setContentsMargins(0,0,0,0) origin.b_createExport.setText("Exp") origin.b_createRender.setText("Rnd") origin.b_createPlayblast.setText("Pb") origin.b_createImport.setMinimumWidth(80*self.core.uiScaleFactor) origin.b_createImport.setMaximumWidth(80*self.core.uiScaleFactor) origin.b_createExport.setMinimumWidth(55*self.core.uiScaleFactor) origin.b_createExport.setMaximumWidth(55*self.core.uiScaleFactor) origin.b_createRender.setMinimumWidth(55*self.core.uiScaleFactor) origin.b_createRender.setMaximumWidth(55*self.core.uiScaleFactor) origin.b_createPlayblast.setMinimumWidth(50*self.core.uiScaleFactor) origin.b_createPlayblast.setMaximumWidth(50*self.core.uiScaleFactor) origin.b_createDependency.setMinimumWidth(50*self.core.uiScaleFactor) origin.b_createDependency.setMaximumWidth(50*self.core.uiScaleFactor) origin.b_stateFromNode.setMinimumWidth(130*self.core.uiScaleFactor) origin.b_stateFromNode.setMaximumWidth(130*self.core.uiScaleFactor) origin.b_getRange.setMaximumWidth(200*self.core.uiScaleFactor) origin.b_setRange.setMaximumWidth(200*self.core.uiScaleFactor) startframe = hou.playbar.playbackRange()[0] endframe = hou.playbar.playbackRange()[1] origin.sp_rangeStart.setValue(startframe) origin.sp_rangeEnd.setValue(endframe) usdType = hou.nodeType(hou.sopNodeTypeCategory(), "pixar::usdrop") if usdType is not None and ".usd" not in self.plugin.outputFormats: self.plugin.outputFormats.insert(-2, ".usd") elif usdType is None and ".usd" in self.plugin.outputFormats: self.plugin.outputFormats.pop(self.plugin.outputFormats.index(".usd")) rsType = hou.nodeType(hou.sopNodeTypeCategory(), "Redshift_Proxy_Output") if rsType is not None and ".rs" not in self.plugin.outputFormats: self.plugin.outputFormats.insert(-2, ".rs") elif rsType is None and ".rs" in self.plugin.outputFormats: self.plugin.outputFormats.pop(self.plugin.outputFormats.index(".rs"))
def __init__(self, scene_viewer): self.geo = hou.Geometry() self.knob_geo = hou.Geometry() self.knob_pt = self.knob_geo.createPoint() self.scene_viewer = scene_viewer self.sphere_verb = hou.sopNodeTypeCategory().nodeVerb("sphere") self.sphere_verb.setParms({'type': 2, 'rows': 32, 'cols': 32}) self.sphere_verb.execute(self.geo, []) self.circle_verb = hou.sopNodeTypeCategory().nodeVerb("circle") self.circle_verb.setParms({'type': 1, 'divs': 32}) self.circle_geo = hou.Geometry() self.circle_verb.execute(self.circle_geo, []) self.drawable = hou.GeometryDrawable( self.scene_viewer, hou.drawableGeometryType.Face, "rollerball", params={ 'style': hou.drawableGeometryFaceStyle.Plain, 'backface_culling': 1, 'color1': hou.Vector4(0.2, 0.2, 0.2, 0.5), 'fade_factor': 0.2 }) self.knob_drawable = hou.GeometryDrawable( self.scene_viewer, hou.drawableGeometryType.Point, "rollerball_knob", params={ 'style': hou.drawableGeometryPointStyle.SmoothCircle, 'color1': hou.Vector4(1.0, 1.0, 1.0, 1.0), 'radius': 6, 'fade_factor': 0.5 }) self.knob_drawable.setGeometry(self.knob_geo) self.drawable.setGeometry(self.geo) self.is_behind = False self.is_ball = True self.circle_N = hou.Vector3(0, 1, 0) self.start_transform = hou.Matrix4(1) self.start_vec = hou.Vector3() self.start_mouse_x = 0.0 self.start_mouse_y = 0.0 self.start_ray_dir = hou.Vector3(0, 0, 0) self.start_ray_origin = hou.Vector3(0, 0, 0) # vector for twist self.primary_axis = hou.Vector3(0, 0, 1) # vector for bend self.secondary_axis = hou.Vector3(1, 0, 0) self.axis = hou.Vector3(0, 0, 1)
def tesselate_geo_with_verbs(self, gdp): # Delete open primitives as PBRT does not support them convert_verb = hou.sopNodeTypeCategory().nodeVerb("convert") convert_verb.setParms({"lodu": 1, "lodv": 1}) convert_verb.execute(gdp, [gdp]) divide_verb = hou.sopNodeTypeCategory().nodeVerb("divide") divide_verb.execute(gdp, [gdp]) open_prims = [prim for prim in gdp.iterPrims() if not prim.isClosed()] gdp.deletePrims(open_prims) return gdp
def get_definition_by_department(self, source_path): definition = None print("dept: ", self.department) if self.department == Department.MATERIAL: definition = hou.hdaDefinition(hou.sopNodeTypeCategory(), "dcc_material", source_path) elif self.department == Department.MODIFY: definition = hou.hdaDefinition(hou.sopNodeTypeCategory(), "dcc_modify", source_path) elif self.department == Department.HAIR: definition = hou.hdaDefinition(hou.objNodeTypeCategory(), "dcc_hair", source_path) elif self.department == Department.CLOTH: definition = hou.hdaDefinition(hou.objNodeTypeCategory(), "dcc_cloth", source_path) return definition
def tesselate_geo_with_verbs(self, gdp): # Delete open primitives as PBRT does not support them convert_verb = hou.sopNodeTypeCategory().nodeVerb("convert") convert_verb.setParms({"lodu": 1, "lodv": 1}) convert_verb.execute(gdp, [gdp]) divide_verb = hou.sopNodeTypeCategory().nodeVerb("divide") divide_verb.execute(gdp, [gdp]) blast_verb = hou.sopNodeTypeCategory().nodeVerb("blast") blast_verb.setParms({"group": "@intrinsic:closed=0", "grouptype": 4}) blast_verb.execute(gdp, [gdp]) return gdp
def createVolumePrimitiveVerb(volumeType, bordertype=0, borderval=0): primitiveVerb = hou.sopNodeTypeCategory().nodeVerb("primitive") if volumeType == "height": primitiveVerb.setParms({ "dovolvis": 1, "volvis": 4, "dovolume": 1, "volborder": 2 }) elif volumeType == "mask": primitiveVerb.setParms({ "dovolvis": 1, "volvis": 0, "dovolume": 1, "volborder": 0 }) else: primitiveVerb.setParms({ "dovolvis": 1, "volvis": 0, "dovolume": 1, "volborder": bordertype, "volborderval": borderval }) return primitiveVerb
def createViewerStateTemplate(): """ Mandatory entry point to create and return the viewer state template to register. """ #state_typename = kwargs["type"].definition().sections()["DefaultState"].contents() state_typename = "crowdGuideBrush_state" state_label = "Crowd Guide Brush" state_cat = hou.sopNodeTypeCategory() template = hou.ViewerStateTemplate(state_typename, state_label, state_cat) template.bindFactory(CrowdGuideBrush) #template.bindIcon(kwargs["type"].icon()) template.bindMenu(create_menu(state_typename)) # selector #1 template.bindGeometrySelector(name="selector1", prompt="Select Path Points", quick_select=True, use_existing_selection=True, geometry_types=[hou.geometryType.Points], auto_start=False, allow_other_sops=False) return template
def createCircle(self, i): sops = hou.sopNodeTypeCategory() circle_verb = sops.nodeVerb('circle') self.circle_handle = hou.Geometry() u = self.node.parm('{}{}pos'.format(self.ramp_name, i + 1)).eval() pos = self.prim.positionAt(u) rot = self.prim.attribValueAt("rot", u) n = self.prim.attribValueAt("tangentu", u) scale = self.node.parm('{}{}value'.format(self.ramp_name, i + 1)).eval() scale_mult = self.node.parm('handle_scale').eval() circle_verb.setParms({ "t": pos, "r": rot, "scale": scale * scale_mult + 0.05, "type": 1, "divs": 256, "arc": 1 }) circle_verb.execute(self.circle_handle, [None]) self.circle_gadget = self.state_gadgets["circle_gadget"] self.circle_gadget.setGeometry(self.circle_handle) self.circle_gadget.setParams({ "draw_color": [1, 0.5, 0, 1], "locate_color": [1, 0, 0, 1], "pick_color": [1, 1, 0, 1], "line_width": 1.0 })
def published_definition(self, asset_name, department): # Set the node type correctly category = hou.objNodeTypeCategory( ) if department in self.dcc_character_departments else hou.sopNodeTypeCategory( ) hou.hda.reloadAllFiles() # Get the HDA File Path hda_name = asset_name + "_" + department hda_file = hda_name + "_main.hdanc" new_hda_path = os.path.join(Project().get_project_dir(), "production", "hda", hda_file) old_hda_path = os.path.join(Project().get_project_dir(), "production", "otls", hda_file) hda_path = "" # Does it exist? if os.path.islink(new_hda_path): hda_path = os.readlink(new_hda_path) elif os.path.islink(old_hda_path): hda_path = os.readlink(old_hda_path) else: return False # If it does, grab the definition hou.hda.installFile(hda_path) hda_definition = hou.hdaDefinition(category, hda_name, hda_path) # If the definition failed for some reason, don't tab it in. if hda_definition is not None: hda_definition.setPreferred(True) return True else: return False
def createCircleGeometry(): geo = hou.Geometry() circle_verb = hou.sopNodeTypeCategory().nodeVerb("circle") hou.SopVerb.setParms(circle_verb, {'type': 1, 'divs': 12}) hou.SopVerb.execute(circle_verb, geo, []) hou.Geometry.addAttrib(geo, hou.attribType.Point, "Cd", (1, 0, 0)) return geo
def create_new_hda_definition(self, element, asset_name, department, checkout_file, content_hda_filepath=None): # CREATE NEW HDA DEFINITION if content_hda_filepath is None: content_hda_filepath = checkout_file print("content hda filepath: ", content_hda_filepath) operator_name = str(element.get_parent() + "_" + element.get_department()) operator_label = str((asset_name.replace("_", " ") + " " + element.get_department()).title()) self.hda_definitions[department].copyToHDAFile(checkout_file, operator_name, operator_label) hda_type = hou.objNodeTypeCategory( ) if department in self.dcc_character_departments else hou.sopNodeTypeCategory( ) hou.hda.installFile(content_hda_filepath) print("hda type: ", hda_type) print("operator_name: ", operator_name) print("content_hda_filepath : ", content_hda_filepath) hda_definition = hou.hdaDefinition(hda_type, operator_name, content_hda_filepath) try: hda_definition.setPreferred(True) except: print("hda definition was not created")
def findFeENodeType(inputNodeTypeName, nodeTypeCategory=hou.sopNodeTypeCategory(), fuzzy=False): if not isinstance(inputNodeTypeName, str): raise TypeError('must be string') # nodeTypeName = inputNodeTypeName nameComponents = list(splitTypeNametoNameComponents(inputNodeTypeName)) nameComponents[1] = 'FeE' if nameComponents[2].endswith('_fee'): nameComponents[2] = trimFeENodeName(nameComponents[2]) nodeType = findFeENodeType_byNameComponents(nameComponents, nodeTypeCategory, fuzzy) if nodeType is not None: return nodeType nameComponents[2] += '_fee' nodeType = findFeENodeType_byNameComponents(nameComponents, nodeTypeCategory, fuzzy) if nodeType is not None: return nodeType nameComponents[1] = '' nodeType = findFeENodeType_byNameComponents(nameComponents, nodeTypeCategory, fuzzy) if nodeType is not None: return nodeType # nodeTypeName = combineNameComponents(nameComponents) # nodeType = tryFindNodeType(nodeTypeName) if fuzzy else hou.nodeType(nodeTypeCategory, nodeTypeName) #return hasNodeType(nodeTypeName) print('can not found node type' + inputNodeTypeName) return None
def findNodeByType(context, pattern): import fnmatch nodeTypeCategories = {} nodeTypeCategories['Object'] = hou.objNodeTypeCategory() nodeTypeCategories['Sop'] = hou.sopNodeTypeCategory() nodeTypeCategories['Vop'] = hou.vopNodeTypeCategory() nodeTypeCategories['Dop'] = hou.dopNodeTypeCategory() nodeTypeCategories['Cop2'] = hou.cop2NodeTypeCategory() nodeTypeCategories['Chop'] = hou.chopNodeTypeCategory() nodeTypeCategories['Shop'] = hou.shopNodeTypeCategory() nodeTypeCategories['Driver'] = hou.ropNodeTypeCategory() nodeTypeCategories['Top'] = hou.topNodeTypeCategory() nodeTypeCategories['Lop'] = hou.lopNodeTypeCategory() category = nodeTypeCategories[context] nodes = [ nodetype for nodetypename, nodetype in category.nodeTypes().items() if fnmatch.fnmatch(nodetypename, pattern) ] if nodes: return nodes[0] else: return None
def findFeENodeType_byNameComponents( nameComponents, nodeTypeCategory=hou.sopNodeTypeCategory(), fuzzy=False): nodeTypeName = combineNameComponents(nameComponents) nodeType = tryFindNodeType(nodeTypeName) if fuzzy else hou.nodeType( nodeTypeCategory, nodeTypeName) return nodeType
def reload_geo(**kwargs): import hou path = kwargs["path"] files = hou.sopNodeTypeCategory().nodeType("file") for f in files.instances(): parm = f.parm("file") if parm.eval() == path: f.parm("reload").pressButton()
def tryFindNodeType(inputNodeTypeName, nodeTypeCategory=hou.sopNodeTypeCategory()): #print(hou.node('/obj/')) if nodeTypeCategory == hou.sopNodeTypeCategory(): tmp_NodeNetwork = hou.node('/obj/').createNode('geo', run_init_scripts=False, load_contents=False) else: raise ValueError('unsupport nodeTypeCategory') try: newNode = tmp_NodeNetwork.createNode(inputNodeTypeName, run_init_scripts=False, load_contents=False) outNodeType = newNode.type() except: outNodeType = None tmp_NodeNetwork.destroy(disable_safety_checks=True) return outNodeType
def createViewerStateTemplate(): # Choose a name and label state_name = "drawpoints.pystate" state_label = "Draw Points" category = hou.sopNodeTypeCategory() template = hou.ViewerStateTemplate(state_name, state_label, category) template.bindFactory(DrawPoints) return template
def execute(enable_output): # get all inputs input_lst = hou.pwd().inputAncestors() # check if there is a rop_geo node rop_abc_type = hou.nodeType(hou.sopNodeTypeCategory(), "rop_alembic") rop_abc_nodes = rop_abc_type.instances() rop_vdb_type = hou.nodeType(hou.sopNodeTypeCategory(), "rop_geometry") rop_vdb_nodes = rop_vdb_type.instances() # set parms and output for i in input_lst: node_name = i.name() range_x = node_name.split("_")[0] range_y = node_name.split("_")[1] for rop_abc in rop_abc_nodes: file_path = "$HIP/assets_" + node_name + "/abc_output/$OS.abc" rop_abc.setParms({ "trange": 1, "f1": range_x, "f2": range_y, "f3": 1, "filename": file_path }) print file_path if enable_output: rop_abc.parm('execute').pressButton() print "Processing" + file_path + "..." for rop_vdb in rop_vdb_nodes: file_path = "$HIP/assets_" + node_name + "/smk_output/$OS/$OS.$F4.vdb" rop_vdb.setParms({ "trange": 1, "f1": range_x, "f2": range_y, "f3": 1, "sopoutput": file_path }) print file_path if enable_output: rop_vdb.parm('execute').pressButton() print "Processing" + file_path + "..."
def reloadAllAlembics(): sop_node_type=hou.sopNodeTypeCategory().nodeTypes()['alembic'] obj_node_type=hou.objNodeTypeCategory().nodeTypes()['alembicarchive'] for child in hou.node('/obj/').children(): if child.type() == obj_node_type: child.parm('buildHierarchy').pressButton() else: for sopChild in child.allSubChildren(): if child.type() == sop_node_type: child.parm('reload').pressButton()
def createViewerStateTemplate(): state_name = "qLib::camera_zoom_vertigo_ql_sop" state_label = "Camera Zoom/Vertigo (sop) [qL]" template = hou.ViewerStateTemplate( state_name, state_label, hou.sopNodeTypeCategory(), #contexts = [ hou.sopNodeTypeCategory(), hou.dopNodeTypeCategory(), hou.lopNodeTypeCategory(), ], ) template.bindFactory(qLibCameraZoomVertigo.State) return template
def createViewerStateTemplate(): """ Mandatory entry point to create and return the viewer state template to register. """ # state_typename = kwargs["type"].definition().sections()["DefaultState"].contents() state_typename = "crowdTrajectoryTrimBrush_state" state_label = "Crowd Trajectory Trim Brush" state_cat = hou.sopNodeTypeCategory() template = hou.ViewerStateTemplate(state_typename, state_label, state_cat) template.bindFactory(crowdTrajectoryTrimBrush) return template
def onSaveClicked(self): self.preset = addExpression.wranglePreset(2) selectecNodes = hou.selectedNodes() selectecNode = None if len(selectecNodes) == 0: return selectecNode = selectecNodes[0] if selectecNode.type() == hou.sopNodeTypeCategory().nodeTypes()["attribwrangle"]: kwargs = {"parms":[selectecNode.parm("snippet")]} self.preset.saveXML(kwargs)
def readRopFile(): root = hou.node("/obj") node = checkSelection() if node and node.type() == hou.nodeType(hou.sopNodeTypeCategory(), "rop_geometry"): name = node.name() path = node.parm("sopoutput").unexpandedString() geo = root.createNode("geo", node_name=name) file = geo.node("file1") file.setName(name) file.parm("file").set(path) file.setSelected(1)
def createArcGeometry(angle, radius): divs_per_degree = 0.12 #arbitary. works out to 12 divs every 90 degrees geo = hou.Geometry() circle_verb = hou.sopNodeTypeCategory().nodeVerb("circle") hou.SopVerb.setParms( circle_verb, { 'type': 1, 'arc': 1, 'angle': hou.Vector2(0, angle), 'divs': divs_per_degree * angle, 'scale': radius }) hou.SopVerb.execute(circle_verb, geo, []) return geo
def onItemClicked(self, item, column): if item.isSelected() == True: if self.prevClicked is item: selectecNodes = hou.selectedNodes() selectecNode = None if len(selectecNodes) == 0: return selectecNode = selectecNodes[0] if selectecNode.type() == hou.sopNodeTypeCategory().nodeTypes()["attribwrangle"]: self.draggedItem = item.text(1) parmText = selectecNode.parm("snippet").eval() selectecNode.parm("snippet").set(parmText + self.draggedItem) self.prevClicked = item
def createHeightFieldVisVerb(): volvizVerb = hou.sopNodeTypeCategory().nodeVerb("volumevisualization") lin = hou.rampBasis.Linear rampmaskcolor = hou.Ramp((lin,lin), (0,1),((1.0,1.0,1.0), (1.0,0.0,0.0))) rampheightfield = hou.Ramp((lin,lin), (0,1),((1.0,1.0,1.0), (1.0,1.0,1.0))) volvizVerb.setParms({ "vismode":0, "densityfield":"height", "densityramp":rampheightfield, "cdfield":"mask", "cdramp":rampmaskcolor }) return volvizVerb
def createViewerStateTemplate(): """ Mandatory entry point to create and return the viewer state template to register. """ state_typename = kwargs["type"].definition().sections( )["DefaultState"].contents() state_label = "PythonStateTest" state_cat = hou.sopNodeTypeCategory() template = hou.ViewerStateTemplate(state_typename, state_label, state_cat) template.bindFactory(State) template.bindIcon(kwargs["type"].icon()) return template
def createViewerStateTemplate(): # Choose a name and label state_name = "mystate" state_label = "My New State" category = hou.sopNodeTypeCategory() # Create the template template = hou.ViewerStateTemplate(state_name, state_label, category) template.bindFactory(MyState) # Other optional bindings will go here... # returns the 'mystate' template return template
def get_all_tk_alembic_nodes(cls): """ Returns a list of all tk-houdini-alembicnode instances in the current session. """ tk_node_type = TkAlembicNodeHandler.TK_ALEMBIC_NODE_TYPE # get all instances of tk alembic rop/sop nodes tk_alembic_nodes = [] tk_alembic_nodes.extend( hou.nodeType(hou.sopNodeTypeCategory(), tk_node_type).instances()) tk_alembic_nodes.extend( hou.nodeType(hou.ropNodeTypeCategory(), tk_node_type).instances()) return tk_alembic_nodes
def scan_scene(self): """ The scan scene method is executed once at startup and its purpose is to analyze the current scene and return a list of references that are to be potentially operated on. The return data structure is a list of dictionaries. Each scene reference that is returned should be represented by a dictionary with three keys: - "node": The name of the 'node' that is to be operated on. Most DCCs have a concept of a node, path or some other way to address a particular object in the scene. - "type": The object type that this is. This is later passed to the update method so that it knows how to handle the object. - "path": Path on disk to the referenced object. Toolkit will scan the list of items, see if any of the objects matches any templates and try to determine if there is a more recent version available. Any such versions are then displayed in the UI as out of date. """ items = [] # get a list of all regular lembic nodes in the file alembic_nodes = hou.nodeType(hou.sopNodeTypeCategory(), "alembic").instances() # return an item for each alembic node found. the breakdown app will check # the paths of each looking for a template match and a newer version. for alembic_node in alembic_nodes: file_parm = alembic_node.parm("fileName") file_path = os.path.normpath(file_parm.eval()) items.append({ "node": alembic_node.path(), "type": "alembic", "path": file_path, }) return items
def test_getMetaSource(self): TARGET = "Scanned Asset Library Directories" node_type = hou.nodeType(hou.sopNodeTypeCategory(), "explodedview") self.assertEqual(node_type.definition().metaSource(), TARGET)
def test_typeIsNotPython(self): nodeType = hou.nodeType(hou.sopNodeTypeCategory(), "file") self.assertFalse(nodeType.isPython())
def test_typeIsPython(self): nodeType = hou.nodeType(hou.sopNodeTypeCategory(), "tableimport") self.assertTrue(nodeType.isPython())
def convert_to_regular_alembic_nodes(cls, app): """Convert Toolkit Alembic nodes to regular Alembic nodes. :param app: The calling Toolkit Application """ tk_node_type = TkAlembicNodeHandler.TK_ALEMBIC_NODE_TYPE # determine the surface operator type for this class of node sop_types = hou.sopNodeTypeCategory().nodeTypes() sop_type = sop_types[tk_node_type] # determine the render operator type for this class of node rop_types = hou.ropNodeTypeCategory().nodeTypes() rop_type = rop_types[tk_node_type] # get all instances of tk alembic rop/sop nodes tk_alembic_nodes = [] tk_alembic_nodes.extend( hou.nodeType(hou.sopNodeTypeCategory(), tk_node_type).instances()) tk_alembic_nodes.extend( hou.nodeType(hou.ropNodeTypeCategory(), tk_node_type).instances()) if not tk_alembic_nodes: app.log_debug("No Toolkit Alembic Nodes found for conversion.") return # iterate over all the tk alembic nodes and attempt to convert them for tk_alembic_node in tk_alembic_nodes: # determine the corresponding, built-in operator type if tk_alembic_node.type() == sop_type: alembic_operator = cls.HOU_SOP_ALEMBIC_TYPE elif tk_alembic_node.type() == rop_type: alembic_operator = cls.HOU_ROP_ALEMBIC_TYPE else: app.log_warning("Unknown type for node '%s': %s'" % (tk_alembic_node.name(), tk_alembic_node.type())) continue # create a new, regular Alembic node alembic_node = tk_alembic_node.parent().createNode(alembic_operator) # copy the file parms value to the new node filename = _get_output_menu_label( tk_alembic_node.parm(cls.NODE_OUTPUT_PATH_PARM)) alembic_node.parm(cls.NODE_OUTPUT_PATH_PARM).set(filename) # copy across knob values _copy_parm_values(tk_alembic_node, alembic_node, excludes=[cls.NODE_OUTPUT_PATH_PARM]) # store the alembic output profile name in the user data so that we # can retrieve it later. output_profile_parm = tk_alembic_node.parm( cls.TK_OUTPUT_PROFILE_PARM) tk_output_profile_name = \ output_profile_parm.menuLabels()[output_profile_parm.eval()] alembic_node.setUserData(cls.TK_OUTPUT_PROFILE_NAME_KEY, tk_output_profile_name) # copy the inputs and move the outputs _copy_inputs(tk_alembic_node, alembic_node) if alembic_operator == cls.HOU_SOP_ALEMBIC_TYPE: _save_outputs_to_user_data(tk_alembic_node, alembic_node) elif alembic_operator == cls.HOU_ROP_ALEMBIC_TYPE: _move_outputs(tk_alembic_node, alembic_node) # make the new node the same color alembic_node.setColor(tk_alembic_node.color()) # remember the name and position of the original tk alembic node tk_alembic_node_name = tk_alembic_node.name() tk_alembic_node_pos = tk_alembic_node.position() # destroy the original tk alembic node tk_alembic_node.destroy() # name and reposition the new, regular alembic node to match the # original alembic_node.setName(tk_alembic_node_name) alembic_node.setPosition(tk_alembic_node_pos) app.log_debug("Converted: Tk Alembic node '%s' to Alembic node." % (tk_alembic_node_name,))
def convert_back_to_tk_alembic_nodes(cls, app): """Convert Alembic nodes back to Toolkit Alembic nodes. :param app: The calling Toolkit Application Note: only converts nodes that had previously been Toolkit Alembic nodes. """ # get all rop/sop alembic nodes in the session alembic_nodes = [] alembic_nodes.extend(hou.nodeType(hou.sopNodeTypeCategory(), cls.HOU_SOP_ALEMBIC_TYPE).instances()) alembic_nodes.extend(hou.nodeType(hou.ropNodeTypeCategory(), cls.HOU_ROP_ALEMBIC_TYPE).instances()) if not alembic_nodes: app.log_debug("No Alembic Nodes found for conversion.") return # the tk node type we'll be converting to tk_node_type = TkAlembicNodeHandler.TK_ALEMBIC_NODE_TYPE # iterate over all the alembic nodes and attempt to convert them for alembic_node in alembic_nodes: # get the user data dictionary stored on the node user_dict = alembic_node.userDataDict() # get the output_profile from the dictionary tk_output_profile_name = user_dict.get( cls.TK_OUTPUT_PROFILE_NAME_KEY) if not tk_output_profile_name: app.log_warning( "Almbic node '%s' does not have an output profile name. " "Can't convert to Tk Alembic node. Continuing." % (alembic_node.name(),) ) continue # create a new, Toolkit Alembic node: tk_alembic_node = alembic_node.parent().createNode(tk_node_type) # find the index of the stored name on the new tk alembic node # and set that item in the menu. try: output_profile_parm = tk_alembic_node.parm( TkAlembicNodeHandler.TK_OUTPUT_PROFILE_PARM) output_profile_index = output_profile_parm.menuLabels().index( tk_output_profile_name) output_profile_parm.set(output_profile_index) except ValueError: app.log_warning("No output profile found named: %s" % (tk_output_profile_name,)) # copy over all parameter values except the output path _copy_parm_values(alembic_node, tk_alembic_node, excludes=[cls.NODE_OUTPUT_PATH_PARM]) # copy the inputs and move the outputs _copy_inputs(alembic_node, tk_alembic_node) # determine the built-in operator type if alembic_node.type().name() == cls.HOU_SOP_ALEMBIC_TYPE: _restore_outputs_from_user_data(alembic_node, tk_alembic_node) elif alembic_node.type().name() == cls.HOU_ROP_ALEMBIC_TYPE: _move_outputs(alembic_node, tk_alembic_node) # make the new node the same color. the profile will set a color, # but do this just in case the user changed the color manually # prior to the conversion. tk_alembic_node.setColor(alembic_node.color()) # remember the name and position of the original alembic node alembic_node_name = alembic_node.name() alembic_node_pos = alembic_node.position() # destroy the original alembic node alembic_node.destroy() # name and reposition the new, regular alembic node to match the # original tk_alembic_node.setName(alembic_node_name) tk_alembic_node.setPosition(alembic_node_pos) app.log_debug("Converted: Alembic node '%s' to TK Alembic node." % (alembic_node_name,))