def get_channel_in_tangent_angle_and_weight_at_index(k_channel_obj, index): k = k_channel_obj.keyframes()[index] s = k.inSlope() angle = math.atan2(s, hou.fps()) a = k.inAccel() w = math.sqrt((a * a * (hou.fps() * hou.fps() + s * s)) / (s * s + 1)) return math.degrees(a), w
def check_seq(self, node): # sync with rop node if node.parm('mode').evalAsString( ) == 'out' and node.parm('overver').evalAsInt() != 1: rop_node_path = node.parm('rop').evalAsString() rop_node = hou.node(rop_node_path) if rop_node and rop_node.type().name() == 'sgtk_geometry': rop_node.hm().app().handler.check_seq(rop_node) else: node.parm('seqlabel').set('Invalid Out node!') else: path = node.parm('filepath').evalAsString() if node.parm('mode').evalAsString() == 'file' or node.parm( 'overver').evalAsInt(): path = node.parm('filepath').unexpandedString() returnStr = None if '$F' in path: path = path.replace('$F4', '*') path = path.replace('$F', '*') sequences = pyseq.get_sequences(path) if len(sequences) == 1: seq = sequences[0] if seq: if seq.missing(): returnStr = '[%s-%s], missing %s' % (seq.format( '%s'), seq.format('%e'), seq.format('%M')) else: returnStr = seq.format('%R') else: returnStr = 'Invalid Sequence Object!' else: returnStr = 'No or multiple sequences detected!' elif path.split('.')[-1] == 'abc': if os.path.exists(path): abcRange = abc.alembicTimeRange(path) if abcRange: returnStr = '[%s-%s] - ABC Archive' % (int( abcRange[0] * hou.fps()), int(abcRange[1] * hou.fps())) else: returnStr = 'Single Abc' else: returnStr = 'No Cache!' else: if os.path.exists(path): returnStr = 'Single Frame' else: returnStr = 'No Cache!' node.parm('seqlabel').set(returnStr)
def check_seq(self, node): path = self._compute_output_path(node) node_color = hou.Color((0, 0.8, 0)) return_str = None if '$F4' in path: path = path.replace('$F4', '*') sequences = pyseq.get_sequences(path) if len(sequences) == 1: seq = sequences[0] if seq: if seq.missing(): return_str = '[%s-%s], missing %s' % (seq.format('%s'), seq.format('%e'), seq.format('%M')) else: return_str = seq.format('%R') node_color = hou.Color((0.8, 0, 0)) else: return_str = 'Invalid Sequence Object!' else: return_str = 'No or multiple sequences detected!' elif path.split('.')[-1] == 'abc': if os.path.exists(path): abcRange = abc.alembicTimeRange(path) if abcRange: return_str = '[%s-%s] - ABC Archive' % (int( abcRange[0] * hou.fps()), int(abcRange[1] * hou.fps())) else: return_str = 'Single Abc' node_color = hou.Color((0.8, 0, 0)) else: return_str = 'No Cache!' else: if os.path.exists(path): return_str = 'Single Frame' node_color = hou.Color((0.8, 0, 0)) else: return_str = 'No Cache!' # update shotgun files node as well for file_node in node.dependents(include_children=False): if file_node.type().name() == 'sgtk_file' and file_node.parm( 'mode').evalAsString() == 'out' and file_node.parm( 'rop').evalAsString() == node.path( ) and file_node.parm('overver').evalAsInt() == 0: file_node.parm('seqlabel').set(return_str) node.setColor(node_color) node.parm('seqlabel').set(return_str)
def writeChop(dopImportNode, startFrame, endFrame): dopImportNode[0].parm("importstyle").set(3) objNode = dopImportNode[0].parent() computeTransformationNode = objNode.createNode("copyobjects", "computetransformation") computeTransformationNode.parm("mode").set(1) computeTransformationNode.parm("computeTRS").set(1) computeTransformationNode.setInput(1, dopImportNode[0]) tracksNum = len(computeTransformationNode.geometry().points()) objNodeName = objNode.name() chopNet = hou.node("/ch").createNode("ch", "chop_" + objNodeName) atributes = ['translate', 'rotate'] renameScope = ['tx ty tz', 'rx ry rz'] nodes = {} for n, k in zip(atributes, renameScope): nodes['geometryChopNode_' + n] = chopNet.createNode( "geometry", objNodeName + '_' + n) nodes['geometryChopNode_' + n].parm("soppath").set( computeTransformationNode.path()) nodes['geometryChopNode_' + n].parm("method").set(1) nodes['geometryChopNode_' + n].parm("attribscope").set(n) nodes['geometryChopNode_' + n].parm("renamescope").set(k) nodes['geometryChopNode_' + n].parm("start").set(startFrame / hou.fps()) nodes['geometryChopNode_' + n].parm("end").set(endFrame / hou.fps()) mergeChopNode = chopNet.createNode("merge") mergeChopNode.setFirstInput(nodes['geometryChopNode_' + atributes[0]]) mergeChopNode.setNextInput(nodes['geometryChopNode_' + atributes[1]]) tracks = mergeChopNode.tracks() tracksSort = [] for i in xrange(tracksNum): temp = [] for n in tracks[i::tracksNum]: temp.append(n) tracksSort.append(temp) for j in xrange(tracksNum): buffer = "" for n in xrange(startFrame, endFrame + 1): for m in tracksSort[j]: buffer += "%s %f" % (str(n), m.evalAtFrame(n)) buffer += "\n" fl = open("/home/tfx/" + objNodeName + "." + str(j) + ".chan", "w") fl.write(buffer) fl.close() del buffer computeTransformationNode.destroy() chopNet.destroy()
def writeChop(dopImportNode, startFrame, endFrame): dopImportNode[0].parm("importstyle").set(3) objNode=dopImportNode[0].parent() computeTransformationNode=objNode.createNode("copyobjects","computetransformation") computeTransformationNode.parm("mode").set(1) computeTransformationNode.parm("computeTRS").set(1) computeTransformationNode.setInput(1,dopImportNode[0]) tracksNum=len(computeTransformationNode.geometry().points()) objNodeName=objNode.name() chopNet=hou.node("/ch").createNode("ch","chop_"+objNodeName) atributes=['translate','rotate'] renameScope=['tx ty tz','rx ry rz'] nodes = {} for n,k in zip(atributes,renameScope): nodes['geometryChopNode_'+n]=chopNet.createNode("geometry",objNodeName+'_'+n) nodes['geometryChopNode_'+n].parm("soppath").set(computeTransformationNode.path()) nodes['geometryChopNode_'+n].parm("method").set(1) nodes['geometryChopNode_'+n].parm("attribscope").set(n) nodes['geometryChopNode_'+n].parm("renamescope").set(k) nodes['geometryChopNode_'+n].parm("start").set(startFrame/hou.fps()) nodes['geometryChopNode_'+n].parm("end").set(endFrame/hou.fps()) mergeChopNode=chopNet.createNode("merge") mergeChopNode.setFirstInput(nodes['geometryChopNode_'+atributes[0]]) mergeChopNode.setNextInput(nodes['geometryChopNode_'+atributes[1]]) tracks=mergeChopNode.tracks() tracksSort=[] for i in xrange(tracksNum): temp=[] for n in tracks[i::tracksNum]: temp.append(n) tracksSort.append(temp) for j in xrange(tracksNum): buffer="" for n in xrange(startFrame, endFrame+1): for m in tracksSort[j]: buffer+="%s %f" % (str(n), m.evalAtFrame(n)) buffer+="\n" fl = open("/home/tfx/"+objNodeName+"."+str(j)+".chan","w") fl.write(buffer) fl.close() del buffer computeTransformationNode.destroy() chopNet.destroy()
def set_channel_in_tangent_angle_and_weight_at_index( k_channel_obj, index, angle, weight): k = k_channel_obj.keyframes()[index] s = hou.fps() * math.tan(math.radians(angle)) k.setInSlope(s) if weight != 1.0: k_channel_obj.setKeyframe(k) k.setExpression("bezier()") a = math.sqrt((weight * weight * (s * s + 1)) / (hou.fps() * hou.fps() + s * s)) k.setInAccel(a) k_channel_obj.setKeyframe(k) k = k_channel_obj.keyframes()[index]
def validate_fps(): """Validate current scene FPS and show pop-up when it is incorrect Returns: bool """ fps = lib.get_asset_fps() current_fps = hou.fps() # returns float if current_fps != fps: from ..widgets import popup # Find main window parent = hou.ui.mainQtWindow() if parent is None: pass else: dialog = popup.Popup2(parent=parent) dialog.setModal(True) dialog.setWindowTitle("Maya scene not in line with project") dialog.setMessage("The FPS is out of sync, please fix") # Set new text for button (add optional argument for the popup?) toggle = dialog.widgets["toggle"] toggle.setEnabled(False) dialog.on_show.connect(lambda: set_scene_fps(fps)) dialog.show() return False return True
def control(self, node): parent = node.parent() geo = node.geometry() abc_file = parent.parm('abcFile').evalAsString() cam_path = parent.parm('cameraPath').evalAsString() if abc_file and abc_file != '' and cam_path != '-1' and cam_path != '': frame = parent.parm('samplingFrame').evalAsFloat() / hou.fps() #Set Transforms matrix = hou.Matrix4( abc.getWorldXform(abc_file, cam_path, frame)[0]) trans = matrix.extractTranslates() * parent.evalParm('scaler') rotate = matrix.extractRotates() geo.setGlobalAttribValue('t', trans) geo.setGlobalAttribValue('r', rotate) #Set Camera Parameters cameraDict = abc.alembicGetCameraDict(abc_file, cam_path, frame) #Other Attributes geo.setGlobalAttribValue('aspect', cameraDict.get('aspect')) geo.setGlobalAttribValue('focal', cameraDict.get('focal')) geo.setGlobalAttribValue('aperture', cameraDict.get('aperture')) geo.setGlobalAttribValue('shutter', cameraDict.get('shutter')) geo.setGlobalAttribValue('focus', cameraDict.get('focus')) geo.setGlobalAttribValue('fstop', cameraDict.get('fstop'))
def _load_flipbooks(self): item_paths = [] for item in self._tree_find_selected(): item_paths.append(item.get_path()) item_paths = ' '.join(item_paths) if item_paths: process = QtCore.QProcess(self) # order of arguments important! arguments = '-r {} {} -g -C'.format(hou.fps(), item_paths) system = sys.platform if system == "linux2": program = '%s/bin/mplay-bin' % hou.getenv('HFS') elif system == 'win32': program = '%s/bin/mplay.exe' % hou.getenv('HFS') else: msg = "Platform '%s' is not supported." % (system, ) self._app.log_error(msg) hou.ui.displayMessage(msg) return process.startDetached(program, arguments.split(' ')) process.close()
def __init__( self, ext="jpg", video_format="mp4", flipbook_dir="$JOB/flip", pad_sub_version=3, pad_seq_index=0 ): self._ext = "" self._video_format = "" self._flipbook_dir = "" self._pad_sub_version = 3 self._pad_seq_index = 0 try: self.ext = os.environ["MPLAY_BATCH_EXTENSION"] except KeyError: self.ext = ext try: self.video_format = os.environ["MPLAY_BATCH_VIDEO_FORMAT"] except KeyError: self.video_format = video_format try: self.flipbook_dir = os.environ["MPLAY_BATCH_FLIPBOOK_DIR"] except KeyError: self.flipbook_dir = flipbook_dir try: self.pad_sub_version = os.environ["MPLAY_BATCH_PAD_SUB_VERSION"] except KeyError: self.pad_sub_version = pad_sub_version try: self.pad_seq_index = os.environ["MPLAY_BATCH_PAD_SEQ_INDEX"] except KeyError: self.pad_seq_index = pad_seq_index self.fps = hou.fps()
def addpointvel(n, creatednodes, usevel=True): parent = n.parent() raster = toolutils.findOutputNodeOfType(n, 'volumerasterizeattributes') inn = raster.inputs()[0] velocity = parent.createNode("pointvelocity") #, "get_velocity") if usevel: velocity.parm("init").set(1) velocity.parm("addobjectmotion").set(False) velocity.parm("objpath").set("`opfullpath('..')`") velocity.setInput(0, inn) raster.insertInput(0, velocity) visType = hou.viewportVisualizers.types()[0] vis = hou.viewportVisualizers.createVisualizer( visType, category=hou.viewportVisualizerCategory.Node, node=velocity) vis.setIsActive(1, viewport=None) vis.setName('source_velocity') vis.setParm('style', 'vector') vis.setParm('attrib', 'v') vis.setParm('unitlength', hou.fps()) creatednodes.insert(2, velocity) return velocity, creatednodes
def playblast( fi ): """fi = <path>/file.png import general.houdini.utils as hut hut.playblast( 'D:/testPlay/test.png' ) """ gl = hou.node( '/out' ).createNode( 'opengl' ) gl.setName( 'playblast' ) tmpFile = tempfile.gettempdir() + '/playblastTmp/' + fi.name gl.parm( 'picture' ).set( tmpFile + '.$F4.png' ) gl.parm( 'picture' ).pressButton() gl.parm( 'imgformat' ).set( 'PNG' ) cam = getRenderCamera() gl.parm( 'camera' ).set( cam.path() ) #set frame range gl.parm( 'trange' ).set(1) gl.parm( 'aamode' ).set( 3 ) gl.parm( 'gamma' ).set( 2.2 ) frameRange = getFrameRangeFromTimeline() gl.parm( 'f1' ).set(frameRange[0]) gl.parm( 'f2' ).set(frameRange[1]) gl.parm( 'execute').pressButton() sqFile = sqFil.sequenceFile( tmpFile + '.png' ) sqFile.createMov( fi.dirPath, '', int(hou.fps()), sqFile.name ) os.system("start "+ str( fi.path ) ) shutil.rmtree( tempfile.gettempdir() + '/playblastTmp/' ) gl.destroy()
def validate_fps(): """Validate current scene FPS and show pop-up when it is incorrect Returns: bool """ fps = lib.get_asset_fps() current_fps = hou.fps() # returns float if current_fps != fps: from ..widgets import popup # Find main window parent = hou.ui.mainQtWindow() if parent is None: pass else: dialog = popup.Popup(parent=parent) dialog.setModal(True) dialog.setWindowTitle("Houdini scene does not match project FPS") dialog.setMessage("Scene %i FPS does not match project %i FPS" % (current_fps, fps)) dialog.setButtonText("Fix") # on_show is the Fix button clicked callback dialog.on_clicked.connect(lambda: set_scene_fps(fps)) dialog.show() return False return True
def test(outPath): minFrame = xh.getMinFrame() maxFrame = xh.getMaxFrame() chLst = xh.getChannelsInGroup("MOT") # "EXP" kfr = KfrExporter() kfr.build(chLst, minFrame, maxFrame, hou.fps()) print "Saving keyframes to", outPath kfr.save(outPath)
def test(outPath): minFrame = xhou.getMinFrame() maxFrame = xhou.getMaxFrame() chLst = xhou.getChannelsInGroup("MOT") # "EXP" kfr = KfrExporter() kfr.build(chLst, minFrame, maxFrame, hou.fps()) xcore.dbgmsg("Saving keyframes to " + outPath) kfr.save(outPath)
def check_seq(self, node): path = node.parm('filepath').evalAsString() if node.parm('mode').evalAsString() == 'file' or node.parm( 'overver').evalAsInt(): path = node.parm('filepath').unexpandedString() returnStr = None if '$F' in path: path = path.replace('$F4', '*') path = path.replace('$F', '*') sequences = pyseq.get_sequences(path) if len(sequences) == 1: seq = sequences[0] if seq: if seq.missing(): returnStr = '[%s-%s], missing %s' % (seq.format('%s'), seq.format('%e'), seq.format('%m')) else: returnStr = seq.format('%R') else: returnStr = 'Invalid Sequence Object!' else: returnStr = 'No or multiple sequences detected!' elif path.split('.')[-1] == 'abc': if os.path.exists(path): abcRange = abc.alembicTimeRange(path) if abcRange: returnStr = '[%s-%s] - ABC Archive' % (int( abcRange[0] * hou.fps()), int(abcRange[1] * hou.fps())) else: returnStr = 'Single Abc' else: returnStr = 'No Cache!' else: if os.path.exists(path): returnStr = 'Single Frame' else: returnStr = 'No Cache!' node.parm('seqlabel').set(returnStr)
def __init__(self, rootPath, minFrame, maxFrame): self.fps = hou.fps() self.minFrame = int(minFrame) self.maxFrame = int(maxFrame) self.nodes = [] self.build(hou.node(rootPath), 0) self.maxLvl = 0 for node in self.nodes: self.maxLvl = max(self.maxLvl, node.lvl)
def __init__(self, rootPath, minFrame, maxFrame): self.FPS = hou.fps() self.minFrame = minFrame self.maxFrame = maxFrame self.nodes = [] self.build(hou.node(rootPath), 0) self.maxLvl = 0 for node in self.nodes: self.maxLvl = max(self.maxLvl, node.lvl)
def preSaveChecklist(self): """Checks the scene for inconsistencies""" checklist = [] fpsValue_setting = self.getFPS() fpsValue_current = int(hou.fps()) if fpsValue_setting is not fpsValue_current: msg = "FPS values are not matching with the project settings.\n Project FPS => {0}\n scene FPS => {1}\nDo you want to continue?".format(fpsValue_setting, fpsValue_current) checklist.append(msg) return checklist
def run_mplay(n, nparm): mplay = hou.expandString("$HFS") + "/bin/mplay" path = n.parm(nparm).evalAsString() fps = '-r {}'.format(hou.fps()) #options = None if n.parm('trange').eval() != 0: pathSplit = path.split(".") pathSplit[-2] = "$F" path = ".".join(pathSplit) #options = ' -f {} {} {}'.format(n.parm('f1').eval(),n.parm('f2').eval(),n.parm('f3').eval()) args = [mplay, fps, path] #print args subprocess.Popen(args)
def keyParmFromFile(f, node, parmName, pasteFromFrame): f = open(f, 'r') str = f.read() str = [x.replace("']", "") for x in str.split("['")][1:] digits = [float(x) for x in str] parm = node.parm(parmName) parm.deleteAllKeyframes() frame = pasteFromFrame for value in digits: time = (frame - 1)/hou.fps() parm.setKeyframe(hou.Keyframe(value, time)) frame += 1 f.close()
def minmax_frames(node): try: #Set frame range value. node.parm('f1').deleteAllKeyframes() node.parm('f2').deleteAllKeyframes() f1 = node.evalParm('f1') f2 = node.evalParm('f2') num_frames = abs(f2 - f1) node.parm('num_frames').deleteAllKeyframes() node.parm('num_frames').set(num_frames) speed = hou.fps() / num_frames node.parm('speed').deleteAllKeyframes() node.parm('speed').set(speed) except: return
def importTransformFromClipboard(_o): error_count = 0 is_tuple = False clipboard = QtWidgets.QApplication.clipboard() text = clipboard.text() lines = text.splitlines() if lines[0].startswith('#copytransform'): ls = lines[0].split(',', 2) fps = ls[1] range = ls[2] if fps != str(hou.fps()): print('warning: fps differs from export') if range != str(hou.playbar.timelineRange()): print('warning: animation range differs from export') for p in (_o.parms()): p.deleteAllKeyframes() for line in lines[1:]: ls = line.split(',', 1) if len(ls) == 2: parm_name = ls[0] parm_val = eval(ls[1]) is_tuple = isinstance(parm_val, tuple) try: if is_tuple: for k in parm_val: setKey = hou.Keyframe() setKey.setFrame(k[0]) setKey.setValue(k[1]) _o.parm(parm_name).setKeyframe(setKey) else: _o.parm(parm_name).set(parm_val) except: print('cannot setting parameter: ' + ls[0]) error_count += 1 if error_count > 0: print('transform values imported with: ' + str(error_count) + ' errors') else: print('all transform values successfully imported') else: print('cannot apply clipboad values, wrong type!')
def setFrameRangeByABC(abcpath): frame_range = abc.alembicTimeRange(abcpath) if frame_range is not None: fps = hou.fps() FSTART = frame_range[0] FEND = frame_range[1] hou.hscript("setenv -g F_START='{F_START}'".format(F_START=FSTART * fps)) hou.hscript("setenv -g F_END='{F_END}'".format(F_END=FEND * fps)) hou.playbar.setFrameRange(FSTART * fps, FEND * fps) hou.playbar.setPlaybackRange(FSTART * fps, FEND * fps) else: print "please give a valid path"
def bakeCamAnim(self, node, frameRange): ''' Bake camera to World Space ''' if 'cam' in node.type().name(): bkNd = hou.node('/obj').createNode( 'cam', '%s_bake' % node.name()) for x in ['resx', 'resy']: bkNd.parm(x).set(node.parm(x).eval()) for frame in xrange(int(frameRange[0]), (int(frameRange[1]) + 1)): time = (frame - 1) / hou.fps() tsrMtx = node.worldTransformAtTime(time).explode() for parm in tsrMtx: if 'shear' not in parm: for x, p in enumerate(bkNd.parmTuple(parm[0])): p.setKeyframe(hou.Keyframe(tsrMtx[parm][x], time)) return bkNd
def run_rv(n,nparm): rv = "/opt/rv-Linux-x86-64-7.1.0/bin/rv" fps = '-fps {}'.format(hou.fps()) options = '' path = n.parm(nparm).evalAsString() if n.parm('trange').eval()!=0: pathSplit = path.split(".") pathSplit[-2] = "#" path = ".".join(pathSplit) #options = '%d-%d' % (n.evalParm('f1'),n.evalParm('f2')) cmd = "%s %s %s %s" % (rv, fps, options, path) #args = [rv, path] #print args #subprocess.call(args) #subprocess.call( cmd.strip().split(" ") ) subprocess.Popen( cmd.strip().split(" ") ) #uvl.wait() #launch_mplay()
def __init__(self, k): self.kfr = k self.val = k.value() self.frame = k.frame() if k.isSlopeUsed(): self.outSlope = k.slope() if k.isSlopeTied(): self.inSlope = self.outSlope else: self.inSlope = k.inSlope() else: self.inSlope = 0.0 self.outSlope = 0.0 fps = hou.fps() self.inSlope /= fps self.outSlope /= fps expr = k.expression() self.expr = parse_kfr_expression(expr)
def fps_scene_opened(self): # get shotgun project fps project = self.context.project sg_filters = [['id', 'is', project['id']]] project_fps = self.sgtk.shotgun.find_one('Project', filters=sg_filters, fields=[self._shotgun_fps_field])[self._shotgun_fps_field] # force to self._default_fps if not defined in Shotgun if not project_fps: project_fps = self._default_fps self.log_warning("Shotgun project fps is not defined, assuming it should be {}".format(self._default_fps)) if project_fps != hou.fps(): # check if scene is not empty if len(hou.node('/obj').children()) != 0: self.log_info("Detected that Houdini fps does not match the Shotgun project fps!") # Prompt the user if they want to change the fps, return if negative if hou.ui.displayMessage("The current hip file fps ({}) does not match the Shotgun project fps ({})!\nChange FPS?".format(hou.fps(), project_fps), buttons=("Yes", "No")) != 0: return hou.setFps(project_fps)
def get_fps(): """ @return The frame rate (frames per second) from the current host application. """ try: import maya.cmds as cmds except: cmds = None fps = 24.0 if cmds: currentFps = cmds.currentUnit(query=True, time=True) if currentFps == 'film': fps = 24.0 elif currentFps == 'pal': fps = 25.0 elif currentFps == 'show': fps = 48.0 elif currentFps == 'palf': fps = 50.0 elif currentFps == 'ntscf': fps = 60.0 elif currentFps == 'game': fps = 15.0 return fps try: import hou except: hou = None if hou: fps = hou.fps() return fps
object_id = 0 wirecolor = (0, 0, 0) handle = 0 clipboard = QtWidgets.QApplication.clipboard() text = clipboard.text() lines = text.splitlines() #error_count = 0 if lines[0].startswith('#abc_export'): ls = lines[0].split(',', 2) fps = ls[1] range = ls[2] if fps != str(hou.fps()): print('warning: fps differs from export') if range != str(hou.playbar.timelineRange()): print('warning: animation range differs from export') geo_dir = hou.expandString('$HIP') + '/geo/' if not os.path.exists(geo_dir): os.makedirs(geo_dir) for line in lines[1:]: ls = line.split(',', 1) if len(ls) == 2: if ls[0] == 'name': name = ls[1] elif ls[0] == 'object_id':
quick_select=True, allowed_types = ('cam','hlight','null','geo','subnet')) dir = hou.expandString('$HIP') hip = hou.expandString('$HIPNAME') dirpath = dir + '/' + hip + '.jsx' fname = hou.ui.selectFile( start_directory = dirpath, file_type = hou.fileType.Any, collapse_sequences = False, multiple_select = False, image_chooser = False) if not fname.endswith('.jsx'): fname = fname + '.jsx' fp = open(fname,'w') fps = hou.fps() duration = hou.expandString('$TLENGTH') fend = string.atoi(hou.expandString('$FEND')) fstart = string.atoi(hou.expandString('$FSTART')) firstCam = 0 objCamera = [] objLight = [] objNull = [] for obj in objsel: name = obj.name() objType = obj.type().name() if objType == 'cam': resx = obj.parm('resx').eval() resy = obj.parm('resy').eval() aspect = obj.parm('aspect').eval()
def importLightFromClipboard(): obj = hou.node('/obj') light = None light_name = '' light_type = '' light_target = None is_tuple = False clipboard = QtWidgets.QApplication.clipboard() text = clipboard.text() lines = text.splitlines() error_count = 0 if lines[0].startswith('#light_export'): ls = lines[0].split(',', 2) fps = ls[1] range = ls[2] if fps != str(hou.fps()): print('warning: fps differs from export') if range != str(hou.playbar.timelineRange()): print('warning: animation range differs from export') for line in lines[1:]: ls = line.split(',', 1) if len(ls) == 2: parm_name = ls[0] parm_val = ls[1] if parm_val.startswith('\'') and parm_val.endswith('\''): parm_val = parm_val[1:-1] else: parm_val = eval(parm_val) is_tuple = isinstance(parm_val, tuple) if parm_name == 'name': light_name = parm_val elif line.startswith('type'): light_type = parm_val light = obj.node(light_name) if light == None: light = obj.createNode(light_type) light.setName(light_name) light.setColor(hou.Color(1, 0.898039, 0)) light.setUserData('nodeshape', 'light') light.moveToGoodPosition() out_node = None for n in light.children(): if n.isGenericFlagSet(hou.nodeFlag.Render) == True: out_node = n color = out_node.createOutputNode('color') color.parm('colorr').set(1) color.parm('colorg').set(0.898039) color.parm('colorb').set(0) color.setDisplayFlag(True) if light_type == 'VRayNodeLightSphere': light.node('sphere1').parm('type').set(4) light.node('sphere1').parm('imperfect').set(0) if light_type == 'VRayNodeLightRectangle': light.node('line1').parm('dist').setExpression( '(ch("../u_size") + ch("../v_size")) * 0.333') light.node('grid1').parm('type').set(2) light.node('grid1').parm('orderu').set(2) light.node('grid1').parm('orderv').set(2) switch = light.node('grid1').createOutputNode( 'switch') switch.parm('input').setExpression( 'ch("../is_disc")') circle = light.createNode('circle') circle.parm('type').set(2) circle.parm('radx').setExpression( 'ch("../u_size") / 2') circle.parm('rady').setExpression( 'ch("../v_size") / 2') # light.parm('v_size').setExpression('ch("u_size")') switch.setNextInput(circle) light.node('merge1').setInput(0, switch) # light.layoutChildren() if light_type == 'VRayNodeSunLight': ''' light.node('transform1').parm('sx').setExpression('ch("../size_multiplier")') light.node('transform1').parm('sy').setExpression('ch("../size_multiplier")') light.node('transform1').parm('sz').setExpression('ch("../size_multiplier")') ''' light_target = obj.node(light_name + '_target') if light_target == None: light_target = createLightTarget(obj, light) else: for p in (light_target.parms()): p.deleteAllKeyframes() else: if light.type().name() != light_type: light.changeNodeType(light_type) for p in (light.parms()): p.deleteAllKeyframes() p.revertToDefaults() light.parm('constraints_on').set(1) light.parm('constraints_path').set('constraints') elif parm_name == 'type': light_type = parm_val if light_type == 'target': light_target = obj.node(light_name + '_target') if light_target == None: light_target = createLightTarget(obj, light) else: for p in (light_target.parms()): p.deleteAllKeyframes() elif line.startswith('target_'): if is_tuple: for k in parm_val: setKey = hou.Keyframe() setKey.setFrame(k[0]) setKey.setValue(k[1]) light_target.parm( parm_name[7:]).setKeyframe(setKey) else: light_target.parm(parm_name[7:]).set(parm_val) else: try: if is_tuple: for k in parm_val: setKey = hou.Keyframe() setKey.setFrame(k[0]) setKey.setValue(k[1]) light.parm(parm_name).setKeyframe(setKey) else: light.parm(parm_name).set(parm_val) except: print('cannot setting parameter: ' + parm_name) error_count += 1 if error_count == 0: print('light successfully imported') else: print('light imported with ' + str(error_count) + " errors") else: print('cannot apply clipboad values, wrong type!')
def get_fps(self): """returns the current fps """ return int(hou.fps())
allowed_types=('cam', 'hlight', 'null', 'geo', 'subnet')) dir = hou.expandString('$HIP') hip = hou.expandString('$HIPNAME') dirpath = dir + '/' + hip + '.jsx' fname = hou.ui.selectFile(start_directory=dirpath, file_type=hou.fileType.Any, collapse_sequences=False, multiple_select=False, image_chooser=False) if not fname.endswith('.jsx'): fname = fname + '.jsx' fp = open(fname, 'w') fps = hou.fps() duration = hou.expandString('$TLENGTH') fend = string.atoi(hou.expandString('$FEND')) fstart = string.atoi(hou.expandString('$FSTART')) firstCam = 0 objCamera = [] objLight = [] objNull = [] for obj in objsel: name = obj.name() objType = obj.type().name() if objType == 'cam': resx = obj.parm('resx').eval() resy = obj.parm('resy').eval() aspect = obj.parm('aspect').eval()
def run(scene, selected, binary=False, scene_save_path="/var/www/html/"): """Callback of Houdini's shelf. """ import hou, os binary = True for node in selected: if node.type().name() == "cam": camera = parse_camera(scene, scene.new("camera"), node) scene.add(camera) elif node.type().name() == "hlight": light = parse_light(scene, scene.new("light"), node) # shadow_type = 0 means no shadow, else raytrace or depth shadows: if node.parm('shadow_type').eval(): shadow = scene.new("shadowGenerator") shadow['lightId'] = light['id'] scene.add(shadow) scene.add(light) elif node.type().name() == 'geo': # Babylon mesh is Houdini's Obj, and babylon geometry/vertexData # is closer to Houdini's SOPs. NOTE: We send to the parsers the same # object twise just changing its name (mesh->obj), so Mesh will keep # both geometry and object data. # Parse object level properties: obj = parse_obj(scene, scene.new('mesh'), node) mesh = parse_sop(scene, obj, node.renderNode(), binary) # Binary format: if binary: mesh, bin = convert_to_binary(scene, mesh) filename = mesh['id'] + ".babylonbinarymeshdata" with open(os.path.join(scene_save_path, filename), 'wb') as file: file.write(bin) # Obj level materials for now: material_path = node.parm('shop_materialpath').eval() if material_path != "": material = parse_material(scene, scene.new('material'), hou.node(material_path)) obj['materialId'] = material['id'] scene.add(material) # Animation export. Babylon deals with vector or float animation, # so we have to treat all tuple channeles at once even if only one axe # is animated. if node.isTimeDependent(): start, end = (hou.expandString("$RFSTART"), hou.expandString('$RFEND')) xform = parse_xform(scene, obj, node, int(start), int(end), int(hou.fps())) obj['animations'] = xform scene.add(obj) # link shadows: # TODO: Respect shadow linking. for shadow in scene['shadowGenerators']: for mesh in scene['meshes']: if mesh['id'] not in shadow['renderList']: shadow['renderList'].append(mesh['id']) scene.dump(os.path.join(scene_save_path, "test.binary.babylon")) return scene