Jump to content


  • Content count

  • Donations

    50.00 CAD 
  • Joined

  • Last visited

Everything posted by Fenolis

  1. HDA Help card

    Skip to 49:35 of this video for information on adding images to Help. Jeff Wagner talks about the process in great detail and I would recommend watching the video in its entirety if you have the time.
  2. 1. If you think about this carefully, random may not be the way to go here. You can use the modulo operator "%" to step increments - such that the last switch in the chain cycles between say, 10 inputs, 1 per frame. The switch before that uses floor() function, cycles only every 10 frames, so that every combination of the last 2 switches is produced uniquely. switch_input1: $F%10 -> goes 0, 1, 2, ..., 8, 9, 0, ... switch_input2: floor($F/10) - > goes 0, 0, 0, ..., 0, 0, 1, ... One way to simplify this idea - if I have 4 switches 0000, each with <=10 inputs, then I can get every unique output by cycling the digits like counting upwards - 0001, 0002, ... 9999. 2. To control this kind of statistical weighting, you will likely already have a "Has hat" toggle parameter. You can use Wedge TOP to batch out the 100 with hats, and the other 9900 without. 3. I'm not sure how to help with this.
  3. Mapping 2 different ranges

  4. Circle SOP, set to Open Arc. PolyExtrude - use Transform Extruded Front to set height You may have to use Reverse to flip normals since I expect you'll be viewing the inside of the curve screen_arc.hipnc
  5. Controled voronoi fracture

    1. Converting line art to geometry can be done using Trace SOP - import image to trace, resample/remesh to get detail. Works best if shapes are closed. 2. You can use the integer attribute active to define RBD pieces that cannot move. Example 3. After running the simulation, you can Group by Bounding Box and use a Blast SOP at the end to remove pieces outside the box before exporting .abc
  6. Transfer Attribute to control Parameter

    You can take a look at the Sweep SOP's documentation by clicking the question mark on the node, or just Googling.
  7. VDB From Polygons , HOLES IN VDB

    The problem occurs because parts of the mesh are thinner than the voxel size specified during conversion. This results in the creation of voxels that are not "full" and thus allow other voxels like fluids to leak through them. The solution to this kind of leaky problem is to reduce voxel size during conversion (to more accurately represent the bounds of the geometry), matching the voxel size of the fluid sim to the voxel size of the geometry (or have the fluid voxels be smaller, so they don't penetrate the thicker boundaries), or use thickened/solidified proxy geometry.
  8. OSM Buildings Have Holes/Gaps?

    Yes, the original OSM tutorial on SideFX's site is meant to be a guideline to show you how the workflow of OSM > Houdini > Unreal works. However, real world conditions and OSM data is far from perfect and will often require case-by-case modifications and pre-processing to achieve desirable results. You can dive into the OSM tools by right-clicking on the node and selecting "Allow editing of contents", to see how they work. Cleaning up the input data is usually the easiest way to get around problems like these, although I find that building a tool from scratch is better for maintenance reasons.
  9. Sidefxlabs modifications

    You right click on the node and select "Allow editing of contents", but any changes you make will be to your version of the node.
  10. This solution from @mestela may be helpful.
  11. Opdef is empy!

    Jeff Wagner talked about embedding files into HDAs in an Illume Webinar here. The relevant timestamp is about 2:00:45, where he goes into more detail.
  12. Missing Subnet nodes?

    You should just make custom HDAs. Houdini's HDAs are designed specifically for this purpose you describe - the alternative is to copy and paste nodes from another file.
  13. Merging wet streaks

    Metaballs have the property of merging when 2 fields are sufficiently close together. You may be able to use them in conjunction with Fuse and POP Kill to combine particle streams.
  14. Connect opposite points in vex

    Removed my comment, @Alain2131's is more effective.
  15. Separating objects by colour

    You can try several methods: - Fuse points - Measure Curvature and Polycut at tight corners - Run a loop over the lines before Polywire and use Ray to manage layering
  16. Voronoi fracture constraint limit map

    In the video, Simon applies a paint mask for the clustering. You can bake out point color using Maps Baker and there is your constraint map. Modifying that texture and reading it back in as color attribute should allow you to change the way your geometry fractures.
  17. You can try to use Labs Straight Skeleton 3D to get the lines to slice across, apply a Polyframe or Orient Along Curves, use Carve to get a point on the line, and copy a simple grid on that point and use Boolean intersect to get your slices.
  18. Voronoi fracture constraint limit map

    Simon Verstraete has a tutorial here.
  19. Swapping nested multiparms is definitely a recursive process, one that is on the verge of blowing my mind trying to think of how the nested parameter names are formatted. I've updated the snippet above to add the following features: - Can swap multiple (not nested multiparm) parameters at once - Can swap vectors, even ones with different naming schemes (XYZW, RGBA, UVW) - this means you can swap Color parameters - Can swap parameters within nested folders (still not nested multiparm) - Can swap keyframes, channel references, and expressions You may notice I have some unused code - was trying to figure out nested multiparms but I'm not quite there yet.
  20. This is the part where I paraphrase@Noobini: "Share your file so we can figure out how you set it up and diagnose your issue" since it works for me.
  21. add noise to points but only in x and y axis

    Point Jitter SOP - axis scale z: 0 OR Attribute Wrangle (Run Over Points): Remember to click the little icon to create the parameter. vector noise = noise(chv("offset")+@ptnum); noise.z = 0; @P += noise; As with most things in Houdini, there are infinite ways to achieve a given effect.
  22. @konstantin magnus When you are calling the function on the button, use -1 or 1 to swap up/down (technically you can swap with a value that's at any offset but for practical reasons...) #SwapValues(kwargs, hou.ParmTemplate.name a, hou.ParmTemplate.name b) def SwapValues(kwargs, a, b): #a, b are parameter names (not labels) node = kwargs["node"] pA = node.parm(a) pB = node.parm(b) if len(pA.keyframes()) == 0: #if both params have no keyframes if len(pB.keyframes()) == 0: valueSelf = pA.rawValue() valueOther = pB.rawValue() pA.set(valueOther) pB.set(valueSelf) #if A has no keyframes but B does else: valueSelf = pA.rawValue() valueOther = pB.keyframes() pA.setKeyframes(valueOther) pB.deleteAllKeyframes() pB.set(valueSelf) else: #if A has keyframes but B doesn't if len(pB.keyframes()) == 0: valueSelf = pA.keyframes() valueOther = pB.rawValue() pA.deleteAllKeyframes() pA.set(valueOther) pB.setKeyframes(valueSelf) #if both params have keyframes else: valueSelf = pA.keyframes() valueOther = pB.keyframes() pA.deleteAllKeyframes() pB.deleteAllKeyframes() pA.setKeyframes(valueOther) pB.setKeyframes(valueSelf) #GetParamNames(kwargs, hou.parmTemplate mpBlock, int index, int swapIndex, int nestingDepth) def GetParamNames(kwargs, mpBlock, index, swapIndex, nestingDepth): node = kwargs["node"] for i in range(len(mpBlock)): #If the current parameter is of a valid type, check if it has channels if mpBlock[i].type() == hou.parmTemplateType.Int or mpBlock[i].type() == hou.parmTemplateType.Float or mpBlock[i].type() == hou.parmTemplateType.String or mpBlock[i].type() == hou.parmTemplateType.Toggle: #note that vector channels are suffixed after multiparm index - "vector_#x" instead of "vector_x#" if mpBlock[i].numComponents() > 1: for c in range(mpBlock[i].numComponents()): if mpBlock[i].namingScheme() == hou.parmNamingScheme.XYZW: if c == 0: vComponent = "x" elif c == 1: vComponent = "y" elif c == 2: vComponent = "z" elif c == 3: vComponent = "w" elif mpBlock[i].namingScheme() == hou.parmNamingScheme.RGBA: if c == 0: vComponent = "r" elif c == 1: vComponent = "g" elif c == 2: vComponent = "b" elif c == 3: vComponent = "a" elif mpBlock[i].namingScheme() == hou.parmNamingScheme.UVW: if c == 0: vComponent = "u" elif c == 1: vComponent = "v" elif c == 2: vComponent = "w" pName = mpBlock[i].name().replace("#","%s") % index + vComponent pOthrName = mpBlock[i].name().replace("#","%s") % (index+swapIndex) + vComponent SwapValues(kwargs, pName, pOthrName) else: pName = mpBlock[i].name().replace("#","%s") % index pOthrName = mpBlock[i].name().replace("#","%s") % (index+swapIndex) SwapValues(kwargs, pName, pOthrName) #if a folder is found, determine if it's a nested multiparm elif mpBlock[i].type() == hou.parmTemplateType.Folder: #if it is, compare the number of instances in each multiparm if mpBlock[i].folderType() == hou.folderType.MultiparmBlock: getNMP = mpBlock[i].name().replace("#","%s") % index getOthrNMP = mpBlock[i].name().replace("#","%s") % (index+swapIndex) nmpInstances = node.parm(getNMP).evalAsInt() nmpOthrInstances = node.parm(getOthrNMP).evalAsInt() #If both multiparms have the same number of instances, swap nested parameter values if nmpInstances == nmpOthrInstances: for j in range(nmpInstances): pA = node.parm(getNMP).parmTemplate().parmTemplates()[j-1].name().replace("#","%s") % (index, j+1) pB = node.parm(getOthrNMP).parmTemplate().parmTemplates()[j-1].name().replace("#","%s") % (index+swapIndex, j+1) SwapValues(kwargs, pA, pB) #Otherwise, save values to a temporary holder else: tempA = list() tempB = list() for j in range(nmpInstances): nestedParm = node.parm(getNMP).parmTemplate().parmTemplates()[j-1].name().replace("#","%s") % (index, j+1) if len(node.parm(nestedParm).keyframes()) > 0: tempA.append(node.parm(nestedParm).keyframes()) else: tempA.append(node.parm(nestedParm).rawValue()) for j in range(nmpOthrInstances): nestedParm = node.parm(getOthrNMP).parmTemplate().parmTemplates()[j-1].name().replace("#","%s") % (index+swapIndex, j+1) if len(node.parm(nestedParm).keyframes()) > 0: tempB.append(node.parm(nestedParm).keyframes()) else: tempB.append(node.parm(nestedParm).rawValue()) #initialize number of multiparm blocks SwapValues(kwargs, getNMP, getOthrNMP) #and update each block from the temporary holders for k in range(nmpOthrInstances): pA = node.parm(getNMP).parmTemplate().parmTemplates()[k-1].name().replace("#","%s") % (index, k+1) node.parm(pA).deleteAllKeyframes() try: node.parm(pA).set(tempB[k]) except: node.parm(pA).setKeyframes(tempB[k]) for k in range(nmpInstances): pB = node.parm(getOthrNMP).parmTemplate().parmTemplates()[k-1].name().replace("#","%s") % (index+swapIndex, k+1) node.parm(pB).deleteAllKeyframes() try: node.parm(pB).set(tempA[k]) except: node.parm(pB).setKeyframes(tempA[k]) #if it's not a multiparm, dive inside and swap each nested parameter else: GetParamNames(kwargs, mpBlock[i].parmTemplates(), index, swapIndex, 0) #Swap(kwargs, int targetSwapIndex) def Swap(kwargs,targetSwapIndex): node = kwargs["node"] button = kwargs["parm"] #Shorthand to access the index of a multiparm index = int(kwargs["script_multiparm_index"]) #Raise error if parameter hierarchy is configured incorrectly if not button.tuple().isMultiParmInstance(): raise hou.NodeWarning("Button is not inside a multiparm block.") #Get the parent multiparm folder mpFolder = button.tuple().parentMultiParm() #Count the number of multiparm instances -> raise errors if swapping is not allowed mpInstances = node.parm(mpFolder.name()).evalAsInt() #Raise errors if trying to swap up on first block, or swap down on last block if targetSwapIndex > 0: if index == mpInstances: raise hou.NodeWarning("No value below to swap with.") elif targetSwapIndex < 0: if index == 1: raise hou.NodeWarning("No value above to swap with.") #Get the other parameters inside this multiparm block so we can start swapping. mpBlock = node.parm(mpFolder.name()).parmTemplate().parmTemplates() GetParamNames(kwargs, mpBlock, index, targetSwapIndex, 0)
  23. There is a Switch-If upstream that tries to initialize the __piecename attribute on points - you may have to initialize this properly using a Connectivity SOP/Attribute Wrangle to see how it flows. s@__piecename is shorthand - what it's doing is looking for a string @ttribute on the incoming points called __piecename, to be compared with other_piecename. If such an attribute is not found, it returns a result of 0.
  24. Hello there! If you are planning to work in NURBS, you may want to consider setting your primitives to be of type NURBS and use Surfsect instead of polygon Boolean.