Jump to content

Atom

Members
  • Content count

    3,079
  • Donations

    0.00 CAD 
  • Joined

  • Last visited

  • Days Won

    94

Everything posted by Atom

  1. I made an attempt at modernizing the FOREACH loops in that scene. You can check out the revised file, here:
  2. copy/stamp, alternative ways?

    Here is the basic "fake" stamp that evolved after CopyToPoints nodes was released. If you run it, inside a FOREACH loop, you can reliably fetch attributes from point #0. This image shows the standard point instancing technique, which is faster than the CopyToPoints, fake stamp. The main reason you might still want to use CopyToPoints, is if you are generating geometry that you need to export. ap_fake_stamp_090619.hiplc
  3. What I have done before is to pre-generate the start and end frame, then only generate a valid s@instancefile, when I am within that frame range. Use a null based geo file to reference in all other cases. if((@Frame>@start) && (@Frame<@end)){ int current_frame = @Frame-@start; s@instancefile = sprintf("myfile_%02d.rs",current_frame); } else { s@instancefile = "my_blank.rs"; }
  4. Issue performing if statement on an array

    I have found that the exact comparison between two float values in Houdini can sometimes fail. Try revising your detection IF statement to be more of a threshold, or close to the mark type of detection. float threshold = 0.04; //ch("threshold") or add slider. if(abs(APC-@Cd.x) > threshold ) { //Different. } else { // Close enough. }
  5. Issue performing if statement on an array

    I wonder if VEX is failing on the setpointgroup, because you have two different styles of quotes? Try double quoting set.
  6. Redshift issue with pyrofx

    You have to leave black on the left side of the ramp.
  7. importing Cops images

    There are some COP width/height limits when using Apprentice. Try using a test image that fits within the 1920x1080 specs for Apprentice.
  8. growing line effects

    One technique for making a line out of a particle is to use the Add node to construct a line, based upon the @id of the particle. All trails inherit this @id, so you can build a line by conecting all points that have the same @id. ap_brain_wire_glow.hiplc
  9. Flip Fluids deforming collision objects

    Here is the i@stopped attribute included inside the if statement. I dropped the viscosity threshold, quite a bit, so the fluid would come to a stop quicker. if (@viscosity>3600){ @viscosity = 3600; @v = set(0,0,0); i@stopped = 1; } ap_SimCon1.hiplc
  10. Check out this thread. You need to use special named attributes to change the values.
  11. I created a short python script to help out with the excessive nodes that are presented when importing detailed FBX files. My example is a vehicle with 278 object nodes referencing 37 materials inside the materials subnet generated by the import. This script scans the materials subnet and creates a new object level geo for each material it finds. Inside this new geo node it creates an ObjectMerge node and populates the node with all object references to the FBX material. It assigns the new material to this new geo node that points to /shop instead of the FBX materials subnet. Then it reviews the FBX materials and creates a new Redshift material for each FBX material detected. It scans the FBX Surface node and extracts a few parameters like diffuse color, specular etc... The net result is that I only have 37 nodes to manage instead of 278 after running the script. Also my nodes have Redshift placeholder materials assigned so I can get right to rendering. Add this code to a new shelf button and adjust the paths, at the bottom of the script, to point to your FBX subnet. The texture path is not really used at this time. # Scan a FBX subnet for materials. # Create a geo object with an object merge for each object that references the material. # Create a place holder Redshift material by reviewing the FBX materials in the subnet. # Atom 08-22-2018 # 10-14-2018 import hou, os, re def returnValidHoudiniNodeName(passedItem): # Thanks to Graham on OdForce for this function! # Replace any illegal characters for node names here. return re.sub("[^0-9a-zA-Z\.]+", "_", passedItem) def createRedshiftImageMapMaterial(passedSHOP, passedImageFilePath, passedName, passedDiffuse=[0,0,0], passedSpecular=[0,0,0], passedWeight=0.1, passedRoughness=0.23, passedIOR=1.0, passedOpacity=1.0): #print "->%s [%s] [%s]" % (passedSHOP, passedImageFilePath, passedName) rs_vop = hou.node(passedSHOP).createNode("redshift_vopnet",passedName) if rs_vop != None: rs_output = hou.node("%s/%s/redshift_material1" % (passedSHOP, passedName)) # Detect the default closure node that should be created by the redshift_vopnet. if rs_output != None: # Create. rs_mat = rs_vop.createNode("redshift::Material","rs_Mat") if rs_mat != None: # Set passed values. rs_mat.parm("diffuse_colorr").set(passedDiffuse[0]) rs_mat.parm("diffuse_colorg").set(passedDiffuse[1]) rs_mat.parm("diffuse_colorb").set(passedDiffuse[2]) rs_mat.parm("refl_colorr").set(passedSpecular[0]) rs_mat.parm("refl_colorg").set(passedSpecular[1]) rs_mat.parm("refl_colorb").set(passedSpecular[2]) rs_mat.parm("refl_weight").set(passedWeight) rs_mat.parm("refl_roughness").set(passedRoughness) if passedIOR ==0: # A zero based IOR means activate mirror mode for the reflection section. rs_mat.parm("refl_fresnel_mode").set("1") rs_mat.parm("refl_brdf").set("1") rs_mat.parm("refl_reflectivityr").set(0.961998) rs_mat.parm("refl_reflectivityg").set(0.949468) rs_mat.parm("refl_reflectivityb").set(0.91724) rs_mat.parm("refl_edge_tintr").set(0.998643) rs_mat.parm("refl_edge_tintg").set(0.998454) rs_mat.parm("refl_edge_tintb").set(0.998008) rs_mat.parm("refl_samples").set(128) rs_mat.parm("diffuse_weight").set(0) else: rs_mat.parm("refl_ior").set(passedIOR) rs_mat.parm("opacity_colorr").set(passedOpacity) rs_mat.parm("opacity_colorg").set(passedOpacity) rs_mat.parm("opacity_colorb").set(passedOpacity) rs_tex = rs_vop.createNode("redshift::TextureSampler",returnValidHoudiniNodeName("rs_Tex_%s" % passedName)) if rs_tex != None: # Wire try: rs_output.setInput(0,rs_mat) can_continue = True except: can_continue = False if can_continue: if passedImageFilePath.find("NOT_DETECTED")==-1: # Only plug in texture if the texture map was specified. rs_mat.setInput(0,rs_tex) # input #0 is diffuse color. extension = os.path.splitext(passedImageFilePath)[1] files_with_alphas = [".png",".PNG",".tga",".TGA",".tif",".TIF",".tiff",".TIFF",".exr",".EXR"] if extension in files_with_alphas: # Place a sprite after the rsMaterial to implment opacity support. rs_sprite = rs_vop.createNode("redshift::Sprite",returnValidHoudiniNodeName("rs_Sprite_%s" % passedName)) if rs_sprite != None: rs_sprite.parm("tex0").set(passedImageFilePath) # set the filename to the texture. rs_sprite.parm("mode").set("1") rs_sprite.setInput(0,rs_mat) rs_output.setInput(0,rs_sprite) #rs_mat.setInput(46,rs_tex) # input #46 is opacity color (i.e. alpha). rs_tex.parm("tex0").set(passedImageFilePath) # set the filename to the texture. # Remove luminosity from texture using a color corrector. rs_cc = rs_vop.createNode("redshift::RSColorCorrection",returnValidHoudiniNodeName("rs_CC_%s" % passedName)) if rs_cc != None: rs_cc.setInput(0,rs_tex) rs_cc.parm("saturation").set(0) # Add a slight bump using the greyscale value of the diffuse texture. rs_bump = rs_vop.createNode("redshift::BumpMap",returnValidHoudiniNodeName("rs_Bump_%s" % passedName)) if rs_bump != None: rs_bump.setInput(0,rs_cc) rs_bump.parm("scale").set(0.25) # Hard coded, feel free to adjust. rs_output.setInput(2,rs_bump) # Layout. rs_vop.moveToGoodPosition() rs_tex.moveToGoodPosition() rs_cc.moveToGoodPosition() rs_bump.moveToGoodPosition() rs_mat.moveToGoodPosition() rs_output.moveToGoodPosition() else: print "problem creating redshift::TextureSampler node." else: print "problem creating redshift::Material node." else: print "problem detecting redshift_material1 automatic closure." else: print "problem creating redshift vop net?" def childrenOfNode(node, filter): # Return nodes of type matching the filter (i.e. geo etc...). result = [] if node != None: for n in node.children(): t = str(n.type()) if t != None: for filter_item in filter: if (t.find(filter_item) != -1): # Filter nodes based upon passed list of strings. result.append((n.name(), t)) result += childrenOfNode(n, filter) return result def groupByFBXMaterials(node_path, rewrite_original=False): lst_geo_objs = [] lst_fbx_mats = [] s = "" material_nodes = childrenOfNode(hou.node("%s/materials" % node_path),["Shop material"]) #Other valid filters are Sop, Object, cam. for (name, type) in material_nodes: node_candidate = "%s/%s" % ("%s/materials" % node_path, name) n = hou.node(node_candidate) if n !=None: lst_fbx_mats.append(node_candidate) object_nodes = childrenOfNode(hou.node(node_path),["Object geo"]) #Other valid filters are Sop, Object, cam. for (name, type) in object_nodes: node_candidate = "%s/%s" % (node_path, name) n = hou.node(node_candidate) if n !=None: lst_geo_objs.append(node_candidate) # Make an object geo node for each material detected. # Inside the object will reside an object merge to fetch in each object that references the material. root = hou.node("/obj") if root != None: for mat in lst_fbx_mats: mat_name = os.path.basename(mat) shader_name = "rs_%s" % mat_name geo_name = "geo_%s" % mat_name ''' node_geo = root.createNode("geo", geo_name) if node_geo: # Delete the default File node that is automatically created as well. if (len(node_geo.children())) > 0: n = node_geo.children()[0] if n: n.destroy() node_geo.parm("shop_materialpath").set("/shop/%s" % shader_name) node_obm = node_geo.createNode("object_merge","object_merge1") if node_obm != None: p = node_obm.parm("objpath1") all_obj = "" for obj in lst_geo_objs: temp_node = hou.node(obj) if temp_node != None: smp = temp_node.parm("shop_materialpath").eval() if smp.find(mat_name) != -1: all_obj += "%s " % obj p.set(all_obj) node_obm.parm("xformtype").set(1) ''' # Make a place holder Redshift material by reviewing the FBX material. opacity = 1.0 ior = 1.025 reflection_weight = 0.1 reflection_roughness = 0.23 diffuse_color = [0,0,0] specular_color = [0,0,0] # Typically the FBX Surface Shader is the second node created in the FBX materials subnet. n = hou.node(mat).children()[1] if n != None: r = n.parm("Cdr").eval() g = n.parm("Cdg").eval() b = n.parm("Cdb").eval() diffuse_color = [r,g,b] sm = n.parm("specular_mult").eval() if sm > 1.0: sm = 1.0 reflection_weight = 1.0-sm if (sm==0) and (n.parm("Car").eval()+n.parm("Cdr").eval()==2): # Mirrors should use another Fresnel type. ior=0 r = n.parm("Csr").eval() g = n.parm("Csg").eval() b = n.parm("Csb").eval() specular_color = [r,g,b] opacity = n.parm("opacity_mult").eval() reflection_roughness = n.parm("shininess").eval()*0.01 em = n.parm("emission_mult").eval() if em > 0: # We should create an rsIncandescent shader, using this color, instead. r = n.parm("Cer").eval() g = n.parm("Ceg").eval() b = n.parm("Ceb").eval() # Try to fetch the diffuse image map, if any. tex_map = n.parm("map1").rawValue() if len(tex_map) > 0: pass else: tex_map = "%s/%s" % (texture_path,"NOT_DETECTED") createRedshiftImageMapMaterial("/shop", tex_map, shader_name, diffuse_color, specular_color, reflection_weight, reflection_roughness, ior, opacity) if rewrite_original: # Re-write the original object node's material reference to point to the Redshift material. for obj in lst_geo_objs: node_geo = hou.node(obj) if node_geo: m = node_geo.parm("shop_materialpath").eval() if len(m): mat_name = os.path.basename(m) shader_name = "/shop/rs_%s" % mat_name # To do this right, we need to add a material node to the end of the network and populate it with the shop_materialpath value. node_display = node_geo.displayNode() if node_display != None: node_mat = node_geo.createNode("material","material1") # Create new node. if node_mat != None: node_mat.parm("shop_materialpath1").set(shader_name) node_mat.setInput(0,node_display) # Wire it into the network. node_mat.setDisplayFlag(True) # Move the display flag to the new node. node_mat.setRenderFlag(True) # Move the render flag to the new node. node_mat.moveToGoodPosition() # Program starts here. texture_path = '/media/banedesh/Storage/Documents/Models/Ford/Ford_F-150_Raptor_2017_crewcab_fbx' #Not really used yet. fbx_subnet_path = "/obj/Container_Ship_Generic_FBX" groupByFBXMaterials(fbx_subnet_path, True)
  12. Houdini "proxy"

    The @instancefile attribute is only for file based objects, you can't use op: pathing. In your case, write the rubbertoy to the disc, then reference that file. To leverage local geometry that is installed in your scene, there is a companion attribute @instance. You can use the op: with that attribute. But referencing large pieces of geometry, from memory, instead of disc, may reduce some of the gains achieved by instancing.
  13. A keyframe every frame? That kind of defeats the purpose of MPEG. Try using the Animation codec, instead.
  14. Pro tips for flip meshing?

    One way to make better use of the particles that you already have, is to increase the Surface Oversampling of the reseeding. It defaults to 1.5, but I typically raise it up to 5-9, or even higher (24-36). This will spread out the particles, that are contained within each voxel. From the look I see in your video, you do have the Influence and Drop scale set very close to one another. Try widening the gab between those two values.
  15. Houdini "proxy"

    You can leverage the split output nature of the SOP network. Have two attribute wrangles at the end. One is for rendering and the other is for the viewport. Assign the filename to the hi-res geometry inside the RENDER version of the attribute wrangle. CTRL-CLICK on the Display flag of a node to move the RENDER flag to that node.
  16. biological modelling methods

    Here is one way to add UVs to those lines. It does not convert to VDB, it uses a sweep to loft the mesh along the line. If you need VDB output, you can do that at the end and use an AttributeInterpolate to transfer the UVs to your final mesh. This setup drops in an attribute VOP to add a secondary displacement map along the length of each spline. This means mesh displacement is happening prior to render, but you can still add more normal maps or bump maps to the surface when you get to adding materials. ap_uv_curly_curves_081819.hiplc
  17. I'm not sure why you're not just creating a collision object? You can also look into the minpos() function. which will help keep points on a surface. http://www.tokeru.com/cgwiki/index.php?title=HoudiniDops#Pop_stick_to_surface
  18. Particles — Redshift Emission

    Make sure you have enabled global illumination. You will get no emission from Redshift, until you do.
  19. FLIP colliders flickering

    Make sure your collision object has no holes in it. Most characters do have holes (such as the eyes, mouth etc) that you may need to fill. A polyfill node ,set to single polygon, often is all you need.
  20. FLIP Divergence

    That is a nice tip, unlocking the solver and changing the drop down to Set Always. Most of the time when I work with FLIP I also change the Grid Scale to 1.0 on the FLIP Object and then head over to the Reseeding tab of the FLIP Solver. I typically add one more particle per voxel to the Particle Per Voxel expression. ceil(pow(ch("../flipfluidobject/gridscale"), 3))+1 Then I increase the surface over sampling to somewhere like 6-18. this gif shows an over sampling of 9. Over sampling helps smooth things out, so you can use a higher particle separation, in some cases. ap_animated_FLIP_Divergence_v0100.hiplc
  21. Converting Hard Constraints into Glue Constraints Help

    You do have a misspelling of the attribute, @strength.
  22. Quads instead of triangles

    The simplest trick is to drop down a VDBFromPolygons then drop down a ConvertVDB (defaults to volume, change to polygons) to turn the volume back into polygons. You will get all quads, but not necessarily flowing loop cuts.
  23. UV out of range

    Make sure you use SPACE-5 in the viewport to visualize the layout of your UVs. Mari NC only supports one UDIM tile so you have to fit all your UVs within that first box.
  24. Apply force on certain rbd objects

    The force to a group may be working, but the members of that group might still be bound by constraints to members that are not in the group. If you have constraints to the windows, that could be it. Try turning the windows into a static collision object, instead...?
  25. Central gravity force

    It may seem odd, but you can reference the location of a moving NULL, and tie it to the goal vector of a pop steer seek, using a relative reference. Then all the points in the RBD sim, that are in range of the field, will be attracted to it. The force is activated by animation, which causes the RBD chunks to attract to the green NULL. ap_particles_attract_to_point.hiplc
×