def run(self): import toolutils import soptoolutils activepane = toolutils.activePane(kwargs) if activepane.type() == hou.paneTabType.SceneViewer: # Get the current context. sceneviewer = toolutils.sceneViewer() # Create a SOP container. container = soptoolutils.createSopNodeContainer( sceneviewer, "curve_object1") # Create the curve. newnode = soptoolutils.createSopNodeGenerator( container, "curve", None) # Turn on the highlight flag so we see the SOPs selected output. newnode.setHighlightFlag(True) if sceneviewer.isCreateInContext(): newnode.setCurrent(True, True) sceneviewer.enterCurrentNodeState() toolutils.homeToSelectionNetworkEditorsFor(newnode) else: container.setCurrent(True, True) toolutils.homeToSelectionNetworkEditorsFor(container) activepane.setPwd(container.parent()) activepane.setCurrentState("objcurve") elif activepane.type() == hou.paneTabType.NetworkEditor: soptoolutils.genericTool(kwargs, "curve") else: raise hou.Error("Can't run the tool in the selected pane.")
def buildViewPath(viewer_or_scriptargs): """ Get a string representing the current viewport. """ if isinstance(viewer_or_scriptargs, dict): activepane = toolutils.activePane(viewer_or_scriptargs) elif isinstance(viewer_or_scriptargs, hou.SceneViewer): activepane = viewer_or_scriptargs desktop_name = hou.ui.curDesktop().name() if not isinstance(activepane, hou.SceneViewer): raise hou.OperationFailed("Pane is not a Scene Viewer.") # Get the name of the current viewer. pane_name = activepane.name() # Get the name of the current viewer's viewport. viewport_name = activepane.curViewport().name() return "%s.%s.world.%s" % (desktop_name, pane_name, viewport_name)
def buildViewPath(viewer_or_scriptargs): """ Get a string representing the current viewport. """ if isinstance(viewer_or_scriptargs, dict): activepane = toolutils.activePane(viewer_or_scriptargs) elif isinstance(viewer_or_scriptargs, hou.SceneViewer): activepane = viewer_or_scriptargs desktop_name = hou.ui.curDesktop().name() if not isinstance(activepane, hou.SceneViewer): raise hou.OperationFailed("Pane is not a Scene Viewer.") # Get the name of the current viewer. pane_name = activepane.name() # Get the name of the current viewer's viewport. viewport_name = activepane.curViewport().name() return "%s.%s.world.%s" % (desktop_name, pane_name, viewport_name)
import hou import toolutils import soptoolutils import sys import os TOOLS_PATH = hou.getenv('CUSTOM_PYTHON_TOOLS') sys.path.append(TOOLS_PATH) from gui2one_utils import gui2one_utils reload(gui2one_utils) #print kwargs activepane = toolutils.activePane(kwargs) if activepane.type() != hou.paneTabType.SceneViewer: raise hou.Error("This tool cannot run in the current pane") scene_viewer = toolutils.sceneViewer() nodetypename = "delete" # Obtain a geometry selection geo_types = (hou.geometryType.Primitives, ) selection = scene_viewer.selectGeometry( "Select the primitives from which to create debris and press Enter to complete", geometry_types=geo_types, allow_obj_sel=True) # The following will raise an exception if nothing was selected. if len(selection.nodes()) == 0: raise hou.Error("Nothing was selected.")
def resizeFluidSops(kwargs): """ Select fluid and set it up to be resizeable. """ sceneviewer = toolutils.activePane(kwargs) if not isinstance(sceneviewer, hou.SceneViewer): raise hou.Error("Invalid pane type for this operation.") # Select the target fluid box. fluidobjects = sceneviewer.selectDynamics( prompt="Select fluid box to resize. Press Enter to complete.", allow_multisel=False) if len(fluidobjects) < 1: raise hou.Error("No fluid container selected to set initial conditions.") fluidobject = fluidobjects[0] fluidnode = doptoolutils.getDopObjectCreator(fluidobject) if fluidnode is None: raise hou.Error("No fluid object node found.") """ Create and configure the reference container for resizing. """ dopnet = doptoolutils.getCurrentDopNetwork() refobject = fluidnode.parent().parent().createNode("geo","fluid_resize_container", run_init_scripts=False) fluidfields = refobject.createNode("dopio","fluidfields") fluidfields.parm("doppath").set(dopnet.path()) fluidfields.setParmExpressions({"defobj": "chs(\""+fluidnode.path()+"/object_name\")"}) fluidfields.parm("fields").set(2) fluidfields.parm("fieldname1").set("density") fluidfields.parm("fieldname2").set("vel") parms = refobject.parmTemplateGroup() parms.hideFolder("Transform", True) parms.hideFolder("Material", True) parms.hideFolder("Render", True) parms.hideFolder("Misc", True) ref_folder = hou.FolderParmTemplate("ref_folder","Resize Container") ref_folder.addParmTemplate(hou.IntParmTemplate("nptsperarea", "Scatter per Area", 1, default_value=([5000]), min=1000, max=20000, help="Scatter points on simulated density to calculate bounds")) ref_folder.addParmTemplate(hou.FloatParmTemplate("treshold", "Density Treshold", 1, default_value=([0]), min=0, max=1, help="Delete density below this value prior to scattering points")) ref_folder.addParmTemplate(hou.SeparatorParmTemplate("sep1")) ref_folder.addParmTemplate(hou.LabelParmTemplate("merge_source", "Merge Sources")) ref_folder.addParmTemplate(hou.ButtonParmTemplate("update", "Update sources", help="Push this to update ObjectMerge node inside", tags={"script_callback": "import adddoputils; adddoputils.updateSourcesButton()", "script_callback_language": "python"})) ref_folder.addParmTemplate(hou.IntParmTemplate("source_activation", "All Sources Activation", 1, default_value=([1]), min=0, max=1, min_is_strict=True, max_is_strict=True, help="Activation of merging all of the listed sources and additional objects")) ref_folder.addParmTemplate(hou.MenuParmTemplate("xformtype", "Transform", "012", ("None", "Into This Object", "Into Specified Object"), 1)) ref_folder.addParmTemplate(hou.StringParmTemplate("xformpath", "Transform object", 1, "", hou.parmNamingScheme.Base1, hou.stringParmType.NodeReference, disable_when=("{ xformtype != 2 }"))) sources_folder=hou.FolderParmTemplate("source_folder","Sources to Merge",folder_type=hou.folderType.MultiparmBlock) sources_folder.addParmTemplate(hou.ToggleParmTemplate("source_activation#", "Source # Activation", default_value=True )) sources_folder.addParmTemplate(hou.StringParmTemplate("objpath#", "Object #", 1, "", hou.parmNamingScheme.Base1,hou.stringParmType.NodeReference)) sources_folder.addParmTemplate(hou.StringParmTemplate("group#", "Group #", 1, "", hou.parmNamingScheme.Base1,hou.stringParmType.Regular)) ref_folder.addParmTemplate(sources_folder) parms.append(ref_folder) refobject.setParmTemplateGroup(parms) keep_density = refobject.createNode("blast","keep_density") keep_density.setFirstInput(fluidfields) keep_density.parm("group").set("@name==vel*") keep_vel = refobject.createNode("blast","keep_vel") keep_vel.setFirstInput(fluidfields) keep_vel.parm("group").set("@name==density") # VOLUME VOP clamping density field below given treshold density_treshold = keep_density.createOutputNode("volumevop","density_treshold") vopglobals = density_treshold.node("volumevopglobal1") treshold = density_treshold.createNode("parameter", "treshold") treshold.parm("parmname").set("treshold") treshold.parm("parmlabel").set("Treshold") compare_density = density_treshold.createNode("compare", "compare_density") compare_density.parm("cmp").set("gte") compare_density.setInput(0, vopglobals, 1) compare_density.setInput(1, treshold, 0) twoway = compare_density.createOutputNode("twoway","switch_density") twoway.setInput(1, vopglobals, 1) vop_output = density_treshold.node("volumevopoutput1") vop_output.setFirstInput(twoway, 0) density_treshold.setParmExpressions({"treshold": "ch(\"../treshold\")"}) # End of VOLUME VOP scatter = refobject.createNode("scatter","scatter") scatter.setFirstInput(density_treshold) scatter.parm("ptsperarea").set(1) scatter.setParmExpressions({"nptsperarea": "ch(\"../nptsperarea\")"}) add_particles = scatter.createOutputNode("add","add_particles") add_particles.parm("addparticlesystem").set(1) # VOP SOP adding velocity field to density-based pointcloud add_vel = refobject.createNode("vopsop","add_vel") add_vel.parm("vex_numthreads").set(1) add_vel.setFirstInput(add_particles) add_vel.setInput(1, keep_vel, 0) globals = add_vel.node("global1") volumesamplex = add_vel.createNode("volumesample", "volumesample_x") volumesamplex.setInput(2, globals, 0) volumesamplex.parm("input_index").set(1) volumesamplex.parm("primnum").set(0) volumesampley = add_vel.createNode("volumesample", "volumesample_y") volumesampley.setInput(2, globals, 0) volumesampley.parm("input_index").set(1) volumesampley.parm("primnum").set(1) volumesamplez = add_vel.createNode("volumesample", "volumesample_z") volumesamplez.setInput(2, globals, 0) volumesamplez.parm("input_index").set(1) volumesamplez.parm("primnum").set(2) vel = volumesamplex.createOutputNode("floattovec", "vel") vel.setInput(1, volumesampley, 0) vel.setInput(2, volumesamplez, 0) vel_by_fps = vel.createOutputNode("divconst", "vel_by_fps") vel_by_fps.setParmExpressions({"divconst": "$FPS"}) add_vector = globals.createOutputNode("add", "add_vector") add_vector.setNextInput(vel_by_fps, 0) vex_output = add_vel.node("output1") vex_output.setFirstInput(add_vector, 0) # End of VOP SOP merge1 = refobject.createNode("merge","merge1") merge1.setFirstInput(add_particles) merge1.setInput(1, add_vel, 0) bound = merge1.createOutputNode("bound", "bound") # Box to switch from after first simulation frame initial_box = refobject.createNode("box", "initial_box") initial_box.setParmExpressions({"sizex": "ch(\""+initial_box.relativePathTo(fluidnode)+"/sizex\")", "sizey": "ch(\""+initial_box.relativePathTo(fluidnode)+"/sizey\")","sizez": "ch(\""+initial_box.relativePathTo(fluidnode)+"/sizez\")"}) initial_box.setParmExpressions({"tx": "ch(\""+initial_box.relativePathTo(fluidnode)+"/tx\")", "ty": "ch(\""+initial_box.relativePathTo(fluidnode)+"/ty\")","tz": "ch(\""+initial_box.relativePathTo(fluidnode)+"/tz\")"}) initial_switch = initial_box.createOutputNode("switch", "initial_switch") initial_switch.setParmExpressions({"input": "$F>ch(\""+initial_switch.relativePathTo(fluidnode)+"/createframe\")", }) initial_switch.setInput(1, bound, 0) # Null to switch to if merging of simulation sources is disabled no_active_source = refobject.createNode("null", "no_active_source") merge_source = refobject.createNode("object_merge", "merge_source") merge_source.setParmExpressions({"numobj": "ch(\"../source_folder\")", "xformtype": "ch(\"../xformtype\")"}) merge_source.parm("xformpath").set("`chsop(\"../xformpath\")`") numobj = merge_source.parm("numobj").eval() source_switch = no_active_source.createOutputNode("switch", "source_switch") source_switch.setParmExpressions({"input": "ch(\"../source_activation\")"}) source_switch.setInput(1, merge_source, 0) merge2 = initial_switch.createOutputNode("merge","merge2") merge2.setInput(1, source_switch, 0) bound = merge2.createOutputNode("bound", "bound") unroll_edges = bound.createOutputNode("ends", "unroll_edges") unroll_edges.parm("closeu").set(4) out = unroll_edges.createOutputNode("null", "OUT") density_treshold.layoutChildren() add_vel.layoutChildren() refobject.layoutChildren() out.setDisplayFlag(True) out.setRenderFlag(True) resize = resizeFluidToMatchSops(fluidnode, refobject) resize.setCurrent(True, True) sceneviewer.enterCurrentNodeState()
# Set Transform param to be 'Into This Object'. objMerge.parm("xformtype").set(1) # Check if kwargs is enabled by CTRL key. if not ctrlCheck: # Set to absolute path. objMerge.parm("objpath1").set(selectedNode.path()) else: # Set to relative path. objMerge.parm("objpath1").set("../" + selectedNode.name()) # Set name for new Object Merge node and mitigate existing # name matches. # # Specify active pane and network. active_pane = toolutils.activePane(kwargs) network = active_pane.pwd() # Initialize counter for collecting matches. counter = 0 # Search for existing nodes with same name using matcher # object and node parsing operation searchStringPrefix = "get_%s" % selectedNode.name() matcher = parser.parse_query(searchStringPrefix) # Search through all nodes in active network for existing # matches and increase counter for each match. for node in matcher.nodes(network): if matcher.matches(node): counter += 1 # Set name for newly created Object Merge node, and append # with last counter number. This allows for all new Object # Merges to preserve the name of the node from which they
def resizeFluidSops(kwargs): """ Select fluid and set it up to be resizeable. """ sceneviewer = toolutils.activePane(kwargs) if not isinstance(sceneviewer, hou.SceneViewer): raise hou.Error("Invalid pane type for this operation.") # Select the target fluid box. fluidobjects = sceneviewer.selectDynamics( prompt="Select fluid box to resize. Press Enter to complete.", allow_multisel=False) if len(fluidobjects) < 1: raise hou.Error("No fluid container selected to set initial conditions.") fluidobject = fluidobjects[0] fluidnode = doptoolutils.getDopObjectCreator(fluidobject) if fluidnode is None: raise hou.Error("No fluid object node found.") """ Create and configure the reference container for resizing. """ dopnet = doptoolutils.getCurrentDopNetwork() refobject = fluidnode.parent().parent().createNode("geo","fluid_resize_container", run_init_scripts=False) fluidfields = refobject.createNode("dopio","fluidfields") fluidfields.parm("doppath").set(dopnet.path()) fluidfields.setParmExpressions({"defobj": "chs(\""+fluidnode.path()+"/object_name\")"}) fluidfields.parm("fields").set(2) fluidfields.parm("fieldname1").set("density") fluidfields.parm("fieldname2").set("vel") parms = refobject.parmTemplateGroup() parms.hideFolder("Transform", True) parms.hideFolder("Material", True) parms.hideFolder("Render", True) parms.hideFolder("Misc", True) ref_folder = hou.FolderParmTemplate("ref_folder","Resize Container") ref_folder.addParmTemplate(hou.IntParmTemplate("nptsperarea", "Scatter per Area", 1, default_value=([5000]), min=1000, max=20000, help="Scatter points on simulated density to calculate bounds")) ref_folder.addParmTemplate(hou.FloatParmTemplate("treshold", "Density Treshold", 1, default_value=([0]), min=0, max=1, help="Delete density below this value prior to scattering points")) ref_folder.addParmTemplate(hou.SeparatorParmTemplate("sep1")) ref_folder.addParmTemplate(hou.LabelParmTemplate("merge_source", "Merge Sources")) ref_folder.addParmTemplate(hou.ButtonParmTemplate("update", "Update sources", help="Push this to update ObjectMerge node inside", tags={"script_callback": "import adddoputils; adddoputils.updateSourcesButton()", "script_callback_language": "python"})) ref_folder.addParmTemplate(hou.IntParmTemplate("source_activation", "All Sources Activation", 1, default_value=([1]), min=0, max=1, min_is_strict=True, max_is_strict=True, help="Activation of merging all of the listed sources and additional objects")) ref_folder.addParmTemplate(hou.MenuParmTemplate("xformtype", "Transform", "012", ("None", "Into This Object", "Into Specified Object"), 1)) ref_folder.addParmTemplate(hou.StringParmTemplate("xformpath", "Transform object", 1, "", hou.parmNamingScheme.Base1, hou.stringParmType.NodeReference, disable_when=("{ xformtype != 2 }"))) sources_folder=hou.FolderParmTemplate("source_folder","Sources to Merge",folder_type=hou.folderType.MultiparmBlock) sources_folder.addParmTemplate(hou.ToggleParmTemplate("source_activation#", "Source # Activation", default_value=True )) sources_folder.addParmTemplate(hou.StringParmTemplate("objpath#", "Object #", 1, "", hou.parmNamingScheme.Base1,hou.stringParmType.NodeReference)) sources_folder.addParmTemplate(hou.StringParmTemplate("group#", "Group #", 1, "", hou.parmNamingScheme.Base1,hou.stringParmType.Regular)) ref_folder.addParmTemplate(sources_folder) parms.append(ref_folder) refobject.setParmTemplateGroup(parms) keep_density = refobject.createNode("blast","keep_density") keep_density.setFirstInput(fluidfields) keep_density.parm("group").set("@name==vel*") keep_vel = refobject.createNode("blast","keep_vel") keep_vel.setFirstInput(fluidfields) keep_vel.parm("group").set("@name==density") # VOLUME VOP clamping density field below given treshold density_treshold = keep_density.createOutputNode("volumevop","density_treshold") vopglobals = density_treshold.node("volumevopglobal1") treshold = density_treshold.createNode("parameter", "treshold") treshold.parm("parmname").set("treshold") treshold.parm("parmlabel").set("Treshold") compare_density = density_treshold.createNode("compare", "compare_density") compare_density.parm("cmp").set("gte") compare_density.setInput(0, vopglobals, 1) compare_density.setInput(1, treshold, 0) twoway = compare_density.createOutputNode("twoway","switch_density") twoway.setInput(1, vopglobals, 1) vop_output = density_treshold.node("volumevopoutput1") vop_output.setFirstInput(twoway, 0) density_treshold.setParmExpressions({"treshold": "ch(\"../treshold\")"}) # End of VOLUME VOP scatter = refobject.createNode("scatter","scatter") scatter.setFirstInput(density_treshold) scatter.parm("ptsperarea").set(1) scatter.setParmExpressions({"nptsperarea": "ch(\"../nptsperarea\")"}) add_particles = scatter.createOutputNode("add","add_particles") add_particles.parm("addparticlesystem").set(1) # VOP SOP adding velocity field to density-based pointcloud add_vel = refobject.createNode("vopsop","add_vel") add_vel.parm("vex_numthreads").set(1) add_vel.setFirstInput(add_particles) add_vel.setInput(1, keep_vel, 0) globals = add_vel.node("global1") volumesamplex = add_vel.createNode("volumesample", "volumesample_x") volumesamplex.setInput(2, globals, 0) volumesamplex.parm("input_index").set(1) volumesamplex.parm("primnum").set(0) volumesampley = add_vel.createNode("volumesample", "volumesample_y") volumesampley.setInput(2, globals, 0) volumesampley.parm("input_index").set(1) volumesampley.parm("primnum").set(1) volumesamplez = add_vel.createNode("volumesample", "volumesample_z") volumesamplez.setInput(2, globals, 0) volumesamplez.parm("input_index").set(1) volumesamplez.parm("primnum").set(2) vel = volumesamplex.createOutputNode("floattovec", "vel") vel.setInput(1, volumesampley, 0) vel.setInput(2, volumesamplez, 0) vel_by_fps = vel.createOutputNode("divconst", "vel_by_fps") vel_by_fps.setParmExpressions({"divconst": "$FPS"}) add_vector = globals.createOutputNode("add", "add_vector") add_vector.setNextInput(vel_by_fps, 0) vex_output = add_vel.node("output1") vex_output.setFirstInput(add_vector, 0) # End of VOP SOP merge1 = refobject.createNode("merge","merge1") merge1.setFirstInput(add_particles) merge1.setInput(1, add_vel, 0) bound = merge1.createOutputNode("bound", "bound") # Box to switch from after first simulation frame initial_box = refobject.createNode("box", "initial_box") initial_box.setParmExpressions({"sizex": "ch(\""+initial_box.relativePathTo(fluidnode)+"/sizex\")", "sizey": "ch(\""+initial_box.relativePathTo(fluidnode)+"/sizey\")","sizez": "ch(\""+initial_box.relativePathTo(fluidnode)+"/sizez\")"}) initial_box.setParmExpressions({"tx": "ch(\""+initial_box.relativePathTo(fluidnode)+"/tx\")", "ty": "ch(\""+initial_box.relativePathTo(fluidnode)+"/ty\")","tz": "ch(\""+initial_box.relativePathTo(fluidnode)+"/tz\")"}) initial_switch = initial_box.createOutputNode("switch", "initial_switch") initial_switch.setParmExpressions({"input": "$F>ch(\""+initial_switch.relativePathTo(fluidnode)+"/createframe\")", }) initial_switch.setInput(1, bound, 0) # Null to switch to if merging of simulation sources is disabled no_active_source = refobject.createNode("null", "no_active_source") merge_source = refobject.createNode("object_merge", "merge_source") merge_source.setParmExpressions({"numobj": "ch(\"../source_folder\")", "xformtype": "ch(\"../xformtype\")"}) merge_source.parm("xformpath").set("`chsop(\"../xformpath\")`") numobj = merge_source.parm("numobj").eval() source_switch = no_active_source.createOutputNode("switch", "source_switch") source_switch.setParmExpressions({"input": "ch(\"../source_activation\")"}) source_switch.setInput(1, merge_source, 0) merge2 = initial_switch.createOutputNode("merge","merge2") merge2.setInput(1, source_switch, 0) bound = merge2.createOutputNode("bound", "bound") unroll_edges = bound.createOutputNode("ends", "unroll_edges") unroll_edges.parm("closeu").set(4) out = unroll_edges.createOutputNode("null", "OUT") density_treshold.layoutChildren() add_vel.layoutChildren() refobject.layoutChildren() out.setDisplayFlag(True) out.setRenderFlag(True) resize = resizeFluidToMatchSops(fluidnode, refobject) resize.setCurrent(True, True) sceneviewer.enterCurrentNodeState()