def CopyExpandedPrimPathsToNode(self, node=None): if not node and self._sessionId != -1: node = hou.nodeBySessionId(self._sessionId) if node: parm = node.parm(TreeModel.parmUiExpandState) parm.set('\n'.join(self._expandedPrimPaths))
def remove_node_callbacks(self, tree_view): if tree_view is not None: for key in tree_view.node_callbacks: node = hou.nodeBySessionId(key) if node is not None: for callback in tree_view.node_callbacks[key]: node.removeEventCallback((callback[0], ), callback[1])
def CopyImportedPrimPathsFromNode(self, node=None): if not node and self._sessionId != -1: node = hou.nodeBySessionId(self._sessionId) if node: parm = node.parm(self._namePrimPaths) src = parm.eval() dst = '\n'.join(self._importedPrimPaths) if src != dst: srcImportedPrimPaths = src.split('\n') # First un-import any path in self._importedPrimPaths that # isn't included in srcImportedPrimPaths. for primPath in self._importedPrimPaths[:]: if primPath not in srcImportedPrimPaths: item = self.ItemFromVariantPrimPath(primPath) if item: self.SetItemData(item, COL_IMPORT, Qt.Unchecked) # Clear the self._importedPrimPaths list. self._importedPrimPaths = [] # Append each path from srcImportedPrimPaths into # self._importedPrimPaths. for primPath in srcImportedPrimPaths: self._importedPrimPaths.append(primPath) item = self.MakeTreeIncludePrimPath(Sdf.Path(primPath)) if item: self.SetItemData(item, COL_IMPORT, Qt.Checked)
def editorEvent(self, event, model, option, index): self.event_pos = event.pos() self._pressed = (index.row(), index.column()) item = index.model().itemFromIndex(index) if event.type() == QtCore.QEvent.MouseMove: return super(ItemDelegate, self).editorEvent(event, model, option, index) if event.type() == QtCore.QEvent.MouseButtonPress or event.type() == QtCore.QEvent.MouseButtonDblClick: for rect in item.button_rects: if rect.contains(event.pos()) is True: return True self.event_pos = QtCore.QPoint() self._pressed = None return super(ItemDelegate, self).editorEvent(event, model, option, index) elif event.type() == QtCore.QEvent.MouseButtonRelease: if self._pressed == (index.row(), index.column()): if item.button_rects[0].contains(event.pos()): parent_item = index.model().itemFromIndex(index.parent()) if parent_item is None: parent_item = index.model() if item.data()["category"] == "node": remove_callbacks = True session_id = int(item.data()["session_id"]) for check_item in iterate_items(item.model().invisibleRootItem()): if check_item is item or check_item.data()["category"] != "node": continue if int(check_item.data()["session_id"]) == session_id: remove_callbacks = False break if remove_callbacks: node = hou.nodeBySessionId(session_id) for callback in self.parent().node_callbacks[session_id]: node.removeEventCallback((callback[0], ), callback[1]) self.parent().node_callbacks.pop(session_id) parent_item.takeRow(item.row()) if len(item.button_rects) > 1: if item.button_rects[1].contains(event.pos()): panel = self.parent().parent().parent().parent().parent().parent().panel eval_open_item_function(item, panel) if len(item.button_rects) > 2: if item.button_rects[2].contains(event.pos()): if item.data()["category"] == "node": open_parameter_tab(item, event.globalPos()) if item.data()["category"] == "file": open_file(item) self.event_pos = QtCore.QPoint() self._pressed = None return True else: for rect in item.button_rects: if rect.contains(event.pos()) is True: return True return super(ItemDelegate, self).editorEvent(event, model, option, index)
def CopyExpandedPrimPathsFromNode(self, node=None): if not node and self._sessionId != -1: node = hou.nodeBySessionId(self._sessionId) if node: parm = node.parm(TreeModel.parmUiExpandState) src = parm.eval() if src != '': self._expandedPrimPaths = src.split('\n')
def update_item_path(self, node, **kwargs): for item in iterate_items(self.model().invisibleRootItem()): if item.data()["category"] == "node": item_node = hou.nodeBySessionId(int(item.data()["session_id"])) is_parent = hou.node(item_node.path()) if item.data()["session_id"] == str(node.sessionId()) or is_parent: data = item.data() if item.text() == data["path"]: item.setText(item_node.path()) data["path"] = item_node.path() item.setData(data)
def CopyImportedPrimPathsToNode(self, node=None): if not node and self._sessionId != -1: node = hou.nodeBySessionId(self._sessionId) if node: parm = node.parm(self._namePrimPaths) src = '\n'.join(self._importedPrimPaths) dst = parm.eval() if src != dst: parm.set(src)
def open_parameter_tab(item, global_mouse_pos): node = hou.nodeBySessionId(int(item.data().get("session_id"))) if node is None: return desktop = hou.ui.curDesktop() parm_pane_size = (400, 500) global_mouse_pos = global_mouse_pos.toTuple() desktop_widget = QtWidgets.QDesktopWidget() parm_pane_pos = (int(global_mouse_pos[0]-parm_pane_size[1]*0.5), int(desktop_widget.availableGeometry().height()-global_mouse_pos[1]-parm_pane_size[1])) pane = desktop.createFloatingPane(hou.paneTabType.Parm, parm_pane_pos, parm_pane_size) pane.setCurrentNode(node) pane.setShowNetworkControls(False)
def center_on_item(item, panel = hou.ui.curDesktop()): network_editor = panel.paneTabOfType(hou.paneTabType.NetworkEditor) h_item = hou.nodeBySessionId(int(item.data().get("session_id"))) if h_item is None: return if item.data().get("category") == "stickynote": h_item = hou.stickyNoteBySessionId(int(item.data().get("session_id"))) network_editor.cd(h_item.parent().path()) h_pos = h_item.position() bounds = hou.BoundingRect() bounds.setTo(hou.Vector4(h_pos[0]+1,h_pos[1]-8,h_pos[0]+8,h_pos[1]+8)) h_item.setSelected(True, True, True) network_editor.setVisibleBounds(bounds, transition_time=.05, set_center_when_scale_rejected=True)
def update_item_note(self): try: index = self.tab_widget.currentWidget().selectedIndexes()[0] item = self.tab_widget.currentWidget().model().itemFromIndex(index) get_data = item.data() get_data["note"] = self.item_note.toPlainText() item.setData(get_data, QtCore.Qt.UserRole + 1) if item.data().get("category") == "node": node = hou.nodeBySessionId(int(item.data().get("session_id"))) node.setComment(item.data().get("note")) elif item.data().get("category") == "stickynote": stickynote = hou.itemBySessionId(hou.networkItemType.StickyNote, int(item.data().get("session_id"))) stickynote.setText(item.data().get("note")) except: return
def cookNode(self, pdgCallback, itemHolder, upstreamItems=None): node = hou.nodeBySessionId(pdgCallback.customId) parentNode = node.parent() if parentNode.type().name() == "prism_google_docs": auth = parentNode.parm("authorization").eval() docName = parentNode.parm("document").eval() sheetName = parentNode.parm("sheet").eval() entityType = parentNode.parm("entity").evalAsString() fromRow = parentNode.parm("fromRow").eval() useToRow = parentNode.parm("useToRow").eval() toRow = parentNode.parm("toRow").eval() sequenceCol = ord(parentNode.parm("sequence").eval().lower()) - 96 shotCol = ord(parentNode.parm("shot").eval().lower()) - 96 startframeCol = ord( parentNode.parm("startframe").eval().lower()) - 96 endframeCol = ord(parentNode.parm("endframe").eval().lower()) - 96 hierarchyCol = ord( parentNode.parm("hierarchy").eval().lower()) - 96 assetCol = ord(parentNode.parm("asset").eval().lower()) - 96 if not useToRow: toRow = -1 if entityType == "assets": columns = {"hierarchy": hierarchyCol, "asset": assetCol} else: columns = { "sequence": sequenceCol, "shot": shotCol, "startframe": startframeCol, "endframe": endframeCol } from PrismUtils import GoogleDocs entityData = GoogleDocs.readGDocs(self.core, auth, docName, sheetName, sorted(columns.values()), fromRow, toRow) colNames = sorted(columns.keys(), key=lambda x: columns[x]) dataDicts = [] for i in entityData: entityDict = {} for name in colNames: entityDict[name] = i[colNames.index(name)] dataDicts.append(entityDict) self.createWorkItems(itemHolder, upstreamItems, entityType, dataDicts)
def delete_selected(self): indicies = self.selectedIndexes() indicies = sorted(indicies, key=lambda index: int(index.row())) for index in reversed(indicies): item = self.model().itemFromIndex(index) parent_item = index.model().itemFromIndex(index.parent()) if parent_item is None: parent_item = index.model() if item.data()["category"] == "node": remove_callbacks = True session_id = int(item.data()["session_id"]) for check_item in iterate_items(item.model().invisibleRootItem()): if check_item is item or check_item.data()["category"] != "node": continue if int(check_item.data()["session_id"]) == session_id: remove_callbacks = False break if remove_callbacks: node = hou.nodeBySessionId(session_id) for callback in self.node_callbacks[session_id]: node.removeEventCallback((callback[0], ), callback[1]) self.node_callbacks.pop(session_id) parent_item.takeRow(item.row())
def onGenerate(self, item_holder, upstream_items, generation_type): node = hou.nodeBySessionId(self.customId) DEFAULT_TIMEOUT = 10 portnum = node.parm("portnum").evalAsInt() DEFAULT_SLEEP = node.parm("sleep").eval() E = lambda pn: node.parm(pn).eval() S = lambda pn: node.parm(pn).evalAsString() kill = node.parm("kill") isExtraCommand = E("isextra") command1 = S("integrationway") command2 = S("integrationtype") command3 = S("integrationtile") extracommand = S("extracommand") CONNECTTIMES = E("connecttimes") isKeepResult = E("resultdata") if command3 == "none": _command3 = "" else: _command3 = command3 if _command3: for item in upstream_items: x_coord = intData(item, "x_coord", 0) y_coord = intData(item, "y_coord", 0) coord = '_'.join(["x"+str(x_coord), "y"+str(y_coord)]) _command3 = command3.replace("xx_yy", coord) if isKeepResult: item_holder.addWorkItem(cloneResultData=True, preserveType=True, parent=item) else: work_item = item_holder.addWorkItem(index=item.index, parent=item) # send common if not _command3.startswith("&fbxpath"): if not isExtraCommand or extracommand == "none": connectToUE4(portnum, kill, DEFAULT_TIMEOUT, DEFAULT_SLEEP, CONNECTTIMES, command1, command2, _command3) else: if extracommand.endswith(".geo"): _extracommand = extracommand connectToUE4(portnum, kill, DEFAULT_TIMEOUT, DEFAULT_SLEEP, CONNECTTIMES, command1, command2, _command3, _extracommand) # spawn points else: folder = S("actorfolder") if extracommand.startswith("&table"): pointCloudGeo = S("pointcloudgeo") pointCloudLabel = S("pointcloudlabel") _extracommand = "&table=" + pointCloudGeo + "&actorlabel=" + pointCloudLabel + "&actorfolder=" + folder connectToUE4(portnum, kill, DEFAULT_TIMEOUT, DEFAULT_SLEEP, CONNECTTIMES, command1, command2, _command3, _extracommand) # send fbx else: if extracommand == "none": raise IOError("wrong parameters for fbx exporting to UE4") else: fbx_name = S("fbxfilename") fbx_name_ext = S("fbxfilenameext") material_name = S("materialname") uasset_path = S("uasset") _command3 = _command3.replace("XXX.fbx", fbx_name_ext) _extracommand = extracommand # is fbx output if _extracommand.startswith("&uassetpath"): _extracommand = "&uassetpath=" + uasset_path connectToUE4(portnum, kill, DEFAULT_TIMEOUT, DEFAULT_SLEEP, CONNECTTIMES, command1, command2, _command3, _extracommand) else: connectToUE4(portnum, kill, DEFAULT_TIMEOUT, DEFAULT_SLEEP, CONNECTTIMES, command1, command2, _command3) item_holder.addWorkItem(index=0) return pdg.result.Success
def onGenerate(self, item_holder, upstream_items, generation_type): # static parms MULTILAYER = ("RGB", "RGBA", "P", "CMYK", "YCbCr", "LAB", "HSV") SINGLELAYER = ("1", "L", "I", "F") BIT32 = ("I", "F") BIT8 = ("L" ,"P", "RGB", "RGBA", "P", "CMYK", "YCbCr", "LAB", "HSV") BIT1 = ("1") CONVERT32 = 65535.0 CONVERT8 = 255.0 node = hou.nodeBySessionId(self.customId) isprintlog = node.parm("isprintlog").eval() issetattribute = node.parm("setattribute").eval() attributeName = node.parm("nofileattribute").evalAsString() hasher = hashlib.md5() def createHeightFieldGeometry(name, size, center, rotate, heightscale=1, moveheight=0, isFileExists=0, filepath="", initval=0): ''' create HeightField Geometry from file ''' # init geometry fileerror = False geo = hou.Geometry().freeze() geo.addAttrib(hou.attribType.Prim, "name", "") halfsize = size * 0.5 bounds = hou.Geometry().boundingBox() bounds.setTo((-halfsize, -halfsize, -0.5, halfsize, halfsize, 0.5)) # init volume vol = geo.createVolume(size, size, 1, bounds) vol.setAttribValue("name", name) im_hash = "-1" if isFileExists: # read landscape/masks try: im = Image.open(filepath) im = im.transpose(Image.TRANSPOSE) # check image size if im.size[0] != size or im.size[1] != size: im = im.resize((size, size)) # save as image numpy array pix im_hash = hashlib.md5(im.tobytes()).hexdigest() im_hash = str(im_hash) immode = im.mode if immode in SINGLELAYER: if immode in BIT32: pix = np.asarray(im) / CONVERT32 elif immode in BIT8: pix = np.asarray(im) / CONVERT8 else: pix = np.asarray(im) # im_hash = str(im_hash) except: fileerror = True pix = np.full((size, size), initval) else: pix = np.full((size, size), initval) # set pix to volume vol.setAllVoxels((pix*heightscale+moveheight).flatten()) # transform geometry rotationMtx = hou.hmath.buildRotate(-90,-90,0) transformMtx = hou.hmath.buildTranslate(center[0],0,center[1]) geo.transform(rotationMtx) geo.transform(transformMtx) return geo, fileerror, im_hash E = lambda p : node.parm(p).eval() # gather parameters size = node.parm("size").evalAsInt() filepath = node.parm("filepath").evalAsString() center = node.parmTuple('t').eval() rotate = E('rotate') heightscale = E('heightscale') moveheight = E('moveheight') iffilenotexist = E('iffilenotexist') # 0 -> report error # 1 -> set black # 2 -> set white # 3 -> set value setvalue = E('setvalue') # only if iffilenotexist == 3 loadtype = E("loadtype") # 0 -> create heightfield from scrach # 1 -> load to upstream heightfield createtype = E("type") # 0 -> heightfield, # 1 -> mask layername = E("layer") # if load to upstream heightfield, set custom mask name layermode = E("layermode") # 0 -> replace # 1 -> add # 2 -> subtract # 3 -> difference # 4 -> multiply # 5 -> maximum # 6 -> minimum bordertype = E("layerborder") # 0 -> constant # 1 -> repeat # 2 -> streak borderval = E("layerborderval") # only if bordertype == 0 is_set_hash = E("issethash") hash_attrib = E("hashattributename") is_add_hash = E("isaddhash") add_hash_attrib = E("addhashattrib") for upstream_item in upstream_items: fileerror = False # check if file exist isfileexists = checkfile(filepath) initval = 0 if not isfileexists: if iffilenotexist == 0: raise IOError("File not found! Please check your file {0}".format(filepath)) elif iffilenotexist == 2: initval = 1 elif iffilenotexist == 3: initval = setvalue # do works ## node verb for border type (primitive node) maskprimitiveVerb = createVolumePrimitiveVerb("mask") im_hash = -1 if loadtype == 0: heightfieldpeimitiveVerb = createVolumePrimitiveVerb("height") if createtype == 0: name = "height" heightfield, fileerror, im_hash = createHeightFieldGeometry(name, size, center, rotate, heightscale, moveheight, isfileexists, filepath, initval) masklayer, maskerror, _ = createHeightFieldGeometry("mask", size, center, rotate) else: name = "mask" masklayer, fileerror, im_hash = createHeightFieldGeometry(name, size, center, rotate, heightscale, moveheight, isfileexists, filepath, initval) heightfield, maskerror, _ = createHeightFieldGeometry("height", size, center, rotate) heightfieldpeimitiveVerb.execute(heightfield, [heightfield]) maskprimitiveVerb.execute(masklayer, [masklayer]) heightfield.merge(masklayer) else: heightfield = hou.Geometry().freeze() heightfield.loadFromFile(upstream_item.resultData[0][0]) name = layername additionallayer, fileerror, im_hash = createHeightFieldGeometry(name, size, center, rotate, heightscale, moveheight, isfileexists, filepath, initval) additionalPrimitiveVerb = createVolumePrimitiveVerb(name, bordertype, borderval) additionalPrimitiveVerb.execute(additionallayer, [additionallayer]) ismergelayer = 0 for layer in heightfield.prims(): if layer.stringAttribValue("name") == name: ismergelayer = 1 voxels = additionallayer.prims()[0] if layermode == 0: # 0 -> replace layer.setAllVoxels(voxels.allVoxels()) else: in_voxelArray = np.asanyarray(layer.allVoxels) blend_voxelArray = np.asanyarray(voxels.allVoxels) if layermode == 1: # 1 -> add layer.setAllVoxels((in_voxelArray+blend_voxelArray).flatten()) elif layermode == 2: # 2 -> subtract layer.setAllVoxels((in_voxelArray-blend_voxelArray).flatten()) elif layermode == 3: # 3 -> difference layer.setAllVoxels(np.absolute(in_voxelArray-blend_voxelArray).flatten()) elif layermode == 4: # 4 -> multiply layer.setAllVoxels((in_voxelArray*blend_voxelArray).flatten()) elif layermode == 5: # 5 -> maximum layer.setAllVoxels(np.maximum(in_voxelArray+blend_voxelArray).flatten()) elif layermode == 6: # 6 -> minimum layer.setAllVoxels(np.minimum(in_voxelArray+blend_voxelArray).flatten()) if ismergelayer == 0: heightfield.merge(additionallayer) ## node verb for visulization (volumevisualization node) heightfieldVisVerb = createHeightFieldVisVerb() heightfieldVisVerb.execute(heightfield, [heightfield]) work_item = item_holder.addWorkItem(cloneResultData=False, preserveType=True, parent=upstream_item) if is_set_hash: if is_add_hash: im_hash = "%x" % (int(im_hash, 16) + int(add_hash_attrib, 16)) work_item.data.setString(hash_attrib, im_hash, 0) outputfile = node.parm('outputfile').unexpandedString() outputfile = outputfile.replace("`@{0}`".format(hash_attrib), im_hash) outputfile = hou.expandString(outputfile) else: outputfile = E('outputfile') # self.scheduler.localizePath(work_item.resultData[0][0]) makeoutputpathsafe(outputfile) heightfield.saveToFile(outputfile) work_item.addResultData(outputfile, "file/geo", 0) if not isfileexists: if isprintlog: print "File not found: {0}".format(filepath) if issetattribute: work_item.data.setInt(attributeName, 1, 0) else: if issetattribute: if fileerror: work_item.data.setInt(attributeName, 1, 0) else: work_item.data.setInt(attributeName, 0, 0) return pdg.result.Success
def GetNode(self): if self._sessionId != -1: return hou.nodeBySessionId(self._sessionId) else: return None