Jump to content


  • Posts

  • Joined

  • Last visited

  • Days Won


Alain2131 last won the day on April 16

Alain2131 had the most liked content!


Personal Information

  • Name
  • Location

Recent Profile Visitors

1,702 profile views

Alain2131's Achievements


Rookie (2/14)

  • Reacting Well Rare
  • First Post Rare
  • Collaborator Rare
  • Dedicated Rare
  • Week One Done

Recent Badges



  1. Hey, what you want is a mutually exclusive button strip. https://www.sidefx.com/docs/houdini/ref/windows/optype.html#parmtypes If you really need separate buttons for your UI, that would still be possible. I would try using the Callback Script to disable the other buttons.
  2. You are on the right path. You need the seed to change for each sphere. The question is, what is different on each spheres ? You said it, copynum. Sadly, you cannot simply put in copynum into the seed and expect it to work - the parameters are cooked only once, meaning they cannot have different values for different parts of the geometry. So, if one geometry cannot have different parameter values for it, how about multiple geometries ? The solution is to use the for each node. There is a mode where it takes in an attribute, and splits the geometry in batches where the attribute matches. So all copynum of value 0 will be in one batch, value 1 in the next batch, and so on. All the nodes contained within the for each will be cooked as many times as there are batches (iterations). NOTE Luckily, the copynum attribute is on the primitives. If it was on the points, you would have lost the primitives inside the for each. As a workaround, you'd have had to promote copynum from points to primitives. Not applicable here, but a good thing to know. Then, since we have "multiple geometries" (thanks to the different batches), the nodes in the for each loop will cook once for each of these batches, allowing to change any parameters as we see fit between each iterations. We have two choices here. 1. Use the copynum attribute. This will work because we KNOW it is different for each iteration, and the parameter will pick up a different value on each iteration. 2. Use the iteration number. The for each loop keeps track of which iteration it is on, and we can refer to it. There's not really a better solution, use what you like. You can even make your own attribute as a seed, to be able to tweak it to your liking, if you need. For 1), you'll want to use the prim() expression. It requires the geometry to look into (0 being the connected input), which primitive to fetch the attribute (since the attributes often differs and because the parameters can only have one value, we have to choose which one to take. In our case, the value is the same on all primitives WITHIN THE LOOP, so we can take the first primitive, 0), which attribute to fetch (copynum), and which index to fetch (for vectors and arrays, for integers and floats just use 0). For 2), you'll want to use the detail() expression. Specify which geometry to fetch the attribute from (foreach_begin1_metadata1 is the node which stores the iteration value), which attribute to fetch (iteration), and again which index (it's an integer, so we just specify 0). change_sort_seed_for_each_copy_solution_1.hipnc
  3. Copy to Points can still be used. You just have to bake in the consideration you mentioned into the attributes you need. orient can be randomized as you pointed out. Then, you need pscale to be 10% bigger for each copies. Make as many points as you need (point generate, add, or whatever way to create points). Each point has a point number associated with them. If you set the pscale to the point number, then it'll go from 0 to 1, 2, 3, and so on for each points. That would be making each copies 100% bigger each time. If you multiply this by 0.1, then you get 0, 0.1, 0.2, 0.3, and so on. You need the scale to start at 100%, which is pscale 1, so add 1 to the result. You get 1.0, 1.1, 1.2, 1.3, and so on. And there you have it, each copies are 10% bigger than the previous one ! You can edit anything you want on the template points, such as the position (set the position to the point number multiplied by 5 in the y axis, for example). float scale_factor = 0.1; @pscale = @ptnum * scale_factor + 1; @P.y = @ptnum * 5;
  4. Here's a way to figure out what to do to edit a packed prim's rotation. Rotate it with a transform node, then search through the attributes to see where your values are stored ! Spoiler alert, a packed primitive has a primitive intrinsic called transform, which is indeed what the transform node edits. You can use setpackedtransform() to edit it in VEX. matrix3 m = primintrinsic(0, "transform", @primnum); // Enable this line and see that the transform node is ignored. // This is expected, since it will overwrite the transformation that is already applied. //m = ident(); rotate(m, radians(45), {0,1,0}); setpackedtransform(0, @primnum, m); //setprimintrinsic(0, "transform", @primnum, m); // does the same as setpackedtransform() See https://vfxbrain.wordpress.com/2020/07/09/how-to-re-apply-packed-transform/ for more information.
  5. Essentially, both solutions are the same. Speed isn't a concern, and it literally returns the same result (taking into consideration @ptnum+1). Basically, use what makes sense to you, or what you like.
  6. Hi, looks like your foreach node is set to iterate on points. Thinking about it, it makes sense that is discards the primitives representing the connections. It takes in the first point, does whatever to it, then returns that point. Then the second, then the third, and so on. Because of the isolated nature of each iterations, there is no way the primitives can be kept. Sadly, even if you specify a piece attribute, these points will still be disconnected, even if they are within the same iteration. Depends on what you wanna do, but a Rig Attrib Wrangle might work, or even a regular Attrib Wrangle. These are still simple points connected by polylines. Any ol' wrangle can modify whatever you want. The Rig variant is for the special KineFX sauce, should you need it. (Disclaimer - I've rarely used the Rig Wrangle, it might have more uses than I give it credit for)
  7. Hi, You want to start with an array of names string names[] = {"rob", "car", "ed"}; Then, you want a random number, which goes from zero to the amount of items in the array float random_value = rand(@ptnum) * len(names); You need an integer, so you can floor() the result int random_id = floor(random_value); This could be combined with the previous line, like so int random_id = floor(rand(@ptnum) * len(names)); Then, you can fetch the corresponding index from your names array string picked_name = names[random_id]; In the end, this is the result string names[] = {"rob", "car", "ed"}; // Array of names int random_id = floor(rand(@ptnum) * len(names)); // Random ID, from zero to the amount of items in the array string picked_name = names[random_id]; // The name corresponding to the random ID
  8. Hey Mark ! I assume your null parameter interface is a multi-parm block. The idea is, in Python, to set the multiparm block number to the amount of items of your array, then for each items of your array, set the string parameter for the character name. geo = hou.pwd().geometry() characters = geo.stringListAttribValue("characters") hou.parm("../UI/characters").set(len(characters)) for i, character in enumerate(characters): parm_name = "../UI/character_{}".format(i) hou.parm(parm_name).set(character) list_of_string_to_parameter_interface.hipnc
  9. Try using the facet node with Remove Inline Points.
  10. Salut Mattéo ! The issue is from current_pos I figured it out by simply exporting each of your float3 attributes into your force attribute, and comparing the result with VEX's. sumPos has the exact same result, whereas current_pos is different. Which, if you take a closer look at the line where you load it, you used vload() instead of vload3() !
  11. Hello ! I want to "write out" an array variable to discrete float/int attributes (in the format a[0], a[1], a[2], a[3], a[4], a[5], etc). In the Geometry Info, it'd be reported as "a 6flt", as opposed to "a flt[]". I was able to create such an attribute using attribcreate (just set the Size to whatever value). And then, in VEX, the attribute is represented as an array (read using point()). I can change the content, but to write it out I had to use the setpointattrib() function. The f[]@a syntax did nothing, both for reading the attribute, and writing it out. I was able to get the size using the pointattribsize() function. arbitrary_size_float_attribute.hipnc Is there a way to create a float/int attribute of arbitrary size in VEX, like the attribcreate does ? A few constraints : The size is known beforehand. I cannot use the attribcreate node. I want to use the @ syntax for speed, but will settle with setpointattrib() if I can't. A solution could be to write it as an array attribute, then extract that array into a float/int attribute of a fixed size. But I don't know how to do that. Thanks !
  12. Hello Killian, For a detail attribute, you can refer to the attribute with detail(surface_node, attrib_name, attrib_index) https://www.sidefx.com/docs/houdini/expressions/detail.html Here's an example for fetching the detail attribute "stop". surface_node 0 refers to the node connected to your switch, and attrib_index 0 is for attributes with more than one item (vector, array, etc). For integer/float, use 0. detail(0, "stop", 0); For any other attribute type, there is the matching point, prim and vertex functions, although I strongly recommend to use detail for node parameter stuff. A parameter can only have one value (you generally cannot refer to an attribute and expect a different result for each point). Also, note that to get a string attribute, you need the matching details(), points(), prims(), vertexs() function. Read : detail string, point string, etc.
  13. If you could provide your scene so we know the setup that needs to go before the solver, then we could help better. I assume it's just a group where you set the "current" group to a single point, but I don't know for sure. Anyways, I would use a For Each Number loop, set to Feedback Each Iteration and Fetch Feedback. Iterations would be the max iteration amount. Basically, how long you are willing to wait for. There is a Stop Condition. That would be an expression to fetch a detail attribute, set with the wrangle. I'd make a "stop" detail attribute, and set it to 1 when you want to stop the loop. Then, just reference it directly with the detail() expression. What you can then do is just put a big number in Iterations (but not too large that if there's an issue, it doesn't take forever to stop), and check at each iteration if the maze is done. In the example, I just check visitedlist's length, and if it's bigger than 100, I stop. // Arbitrary stop condition, for testing int list[] = detail(0,"visitedlist"); if(len(list) > 100) setdetailattrib(0, "stop", 1); You can see that in this case, the loop ran 158 times before it stopped. The downside with this compared to a Solver is that you cannot see the path it takes through each iterations. To solve that, you could store the iteration number on the "current" point, so that it gives you the path to visualize after. Then, you could make a visualizer wrangle that sets the colors based on the "iteration" value on each point, based on the current frame. stop_condition.hipnc
  14. Hi, read this answer for more detail Tl;DR : You do not need to "Transfer Attributes" when you pack your geometry. That transfers attributes on the "shell", but the content still has the original data, regardless.
  15. Try to untick Pin Border Points, and set the Influence Type to Proximity.
  • Create New...