Jump to content


  • Posts

  • Joined

  • Last visited

  • Days Won


Alain2131 last won the day on April 9 2022

Alain2131 had the most liked content!

1 Follower

Personal Information

  • Name
  • Location

Recent Profile Visitors

1,606 profile views

Alain2131's Achievements


Newbie (1/14)

  • First Post Rare
  • Collaborator Rare
  • Dedicated Rare
  • Week One Done Rare
  • One Month Later Rare

Recent Badges



  1. 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() !
  2. 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 !
  3. 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.
  4. 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
  5. 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.
  6. Try to untick Pin Border Points, and set the Influence Type to Proximity.
  7. Hi, the issue is that you are transferring UV to your packed geo. That "promotes" the UV to a single value for the entire packed fragment. Then, when you unpack it, it transfers that single value to the entire packed fragment, messing up your UV. 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. If you isolate a single piece, for debug, and look at the vertices in the spreadsheet, you can see that the first UV value is transferred on your packed geo. Then, when unpacking, that value is copied on every vertices for that packed fragment. Just remove the * in the "Transfer Attributes", and it'll work.
  8. Well, bummer. I don't know much about compiled .vex library, but I was able to have a very simple example work. Here are the resources I found : https://forums.odforce.net/topic/26970-creating-vex-libraries/?do=findComment&comment=155341 https://www.sidefx.com/docs/houdini/vex/vcc https://www.sidefx.com/docs/houdini/hom/hou/runVex.html#example Basically, you'll need to place the generated .vex file in this path "%userprofile%\Documents\houdini19.0\vex\include" (you'll need to create the folders "vex" and "include") (Although, now that I think about it, this is only really needed for .vfl to be included in VEX. For python, that's not relevant, and can be anywhere you like) I created a code.vfl file with this content. (the path of the .vfl does not matter, but I put it in the same vex/include folder) cvex add(float x=0; float y=0; export float out=0) { out = x + y; } Then, in a Command Prompt window, I typed : C:\Users\alain>cd C:\Program Files\Side Effects Software\Houdini 19.0.531\bin C:\Program Files\Side Effects Software\Houdini 19.0.531\bin>vcc -o C:\Users\alain\Documents\houdini19.0\vex\include\code.vex C:\Users\alain\Documents\houdini19.0\vex\include\code.vfl That creates a code.vex in the same folder, which can be referenced in Houdini. I used a simple python sop with this code codeFile = r"C:/Users/alain/Documents/houdini19.0/vex/include/code.vex" result = hou.runVex(codeFile, {"x":1.0, "y":0.5}) print(result) Here's an image with all the info. 1. Path to put stuff into 2. The code.vfl file 3. Compiling code.vex 3.5 Showing code.vex's insides (not relevant) 4. Calling hou.runVex() in Houdini And this successfully runs vex code. Yay. The lack of enthusiasm is because we need much more than that, and I'm not able to get any further than that. We need to be able to call "primpoints()" in there, but that requires having access to a geometry stream, which I don't know how to pass through. This page says I don't know the difference between cvex and sop, but that might be relevant. I'm sorry I can't help you more than that, but that might be a dead end. HDK sounds like the all around best way to go about this. That said, I'd love if someone more knowledgeable than me could shed light on this. Or come up with another solution that doesn't require VEX !
  9. Is loading the geometry directly from Python a requirement ? If no, then here's what I did. I used a file node to load the geo, then with a Wrangle I pre-process the pts[] array on each prim. i[]@pts = primpoints(0, @primnum); // In a Wrangle set to run over Primitives, with the File as an input Then, instead of "[pt.number() for pt in pr.points()]", I do "pr.intListAttribValue("pts")" node = hou.pwd() geo = node.geometry() # Need to load the input geo instead of directly from the disk primPoints = [pr.intListAttribValue("pts") for pr in geo.prims()] I did some performance testing Original speed is 21s, if we load with the File node (but keep the same primPoints line), it's 19s, but with the aforementioned method the time it takes goes down to 4s. python_performance_example.hipnc
  10. Take a look at the documentation for detail(). detail(surface_node, attrib_name, attrib_index) You have "surface_node", but you are missing "attrib_name" and "attrib_index". Which makes sense to have, since how is it supposed to know which attribute to get from the node otherwise ? `detail("../foreach_count1/", "iteration", 0)` // When fetching int or float attributes, attrib_index needs to be 0
  11. Here's a revisit of this topic, with a better and simpler answer. The enumerate node does exactly what you need. It's fast, more than 10x faster than the wrangle method I used. (Maybe my code was not optimal, but that's another story) The result is the exact same as the wrangle, though. uniqueValueByName.hipnc
  12. Hello, What you need to do is for each frame (aka "sample", in CHOPs), calculate the distance delta upto the current sample. For instance, let's say we are calculating sample 12. You want to know how much distance has been traveled until then. You cannot look only at frame 11, because who knows what kind of crazy movement there has been before ? Which means, we need to look at every frames, starting from the first one, until frame 12. But what do we need to look for ? We want to know the total distance that was traveled. So, we can look at the distance delta between each frame, and sum it up. In other words, for each frame, compute the distance between it and the previous frame, and add that to a total, rinse and repeat, until the current frame. For our example frame 12, that would be something a bit like that : We need f0 pos; // the position at frame 0 f1 pos; // the position at frame 1 distance delta = distance(f0, f1); // the distance that was traveled between the two frames. distance TOTAL += delta That was for 1 frame let's wrap that in a loop (with better variable names, but this is not the actual code) vector fetchP(int sample) // "sample" is basically the frame number { return positionAtSample; // Not writing the actual code for this just yet, not relevant for the logic. } float totalDistance = 0; // Initialize the totalDistance outside of the loop, since we want to accumulate it foreach(int i=firstFrame; i<currentFrame; i++) // In the example of the frame 12, firstFrame=0 and currentFrame=12 { vector P0 = fetchP(i); // "i" is the "current frame". It will go from 0 to 12 (not inclusive, so 11) vector P1 = fetchP(i-1); // Here, we fetch the previous frame float delta = distance(P0, P1); // Distance delta for the current frame of the loop totalDistance += delta; // Accumulate totalDistance } // Then, if we are in CHOPs, we can assign totalDistance to V (which stands for "V"alue) V = totalDistance; How do we know if our logic is sound ? With simple animations for which we know the actual distance traveled ! I took the liberty to modify your animation in a line to have easier values to work with. It now animates in Z from 2.5 to 9.5 over 100 frames. That means, it has traveled a total of 7 meters. That should translate to the last sample in CHOP being 7. NOTE - Since we are accumulating the distance over time, the result in CHOPs should NEVER go down. It can only go up, or plateau. That means we can middle click on the chop node in the node editor, and look at the Max value. (It's not exactly 7, I assume this is due to float precision issue, but it's close enough) Another "more complex" example that we can still calculate the exact distance for, is to animate two channels, one after the other. I added a corner_anim node, which I applied the following animation : z : 2.5[f1] -> 9.5[f50] x : 0.9[f50] -> 5.9[f100] In z, it's the same animation, over a shorter period, so that's 7 meters. In x, it's 5 more meters. In total, it should be 12 meters total. Behold, 11.994078 meters (basically 12 meters). I hope that makes sense ! Here's the actual VEX I used vector fetchP(int sample) { float x = chinput(1, "tx", sample); float y = chinput(1, "ty", sample); float z = chinput(1, "tz", sample); return set(x, y, z); } // At each "frame" (aka sample), // compute the distance delta // and accumulate it upto the current sample. // For instance, // if the Wrangle is computing sample 12, // then the loop will run 12 times, // summing all the previous samples' deltas. float totalDist = 0; for(int i=S; i<I; i++) // If you wonder what S and I are, look here https://www.sidefx.com/docs/houdini/vex/contexts/chop.html#globals { vector P = fetchP(i); vector P1 = fetchP(i-1); float delta = distance(P, P1); totalDist += delta; } V = totalDist; Hope that helps ! VEX_extract_distance_travelled.hipnc
  13. I meant the points in the line, not the fracture. I'm glad this is working out for you though !
  14. Hi Kilian, If I understand correctly, you want to "apply" the simulation where there are peaks in the curve, correct ? You already have a line with the correct animation applied to it. Doesn't that look like a ramp already ?.. What I would do is sample directly from the line instead of using chramp. (This code requires the "channel_audio_import" node to be the third input of your wrangle) float end = 50.0; float frame = (@Frame + v@P.z*10) % end ; float pos = fit(frame , 1, end, 0.0, 1.0); pos = chramp("AnimCurve", pos); // These two lines are the only difference float sample = 1 - relbbox(0, @P).z; // You can visualize this with "v@Cd = sample;". A 0 to 1 value in the relative bounding box. pos = primuv(2, "audio", 0, set(sample, 0, 0)); // Sample the audio attribute of the line based on sample v@P = primuv(1, "P", @ptnum, set(pos, 0, 0)); [...] // rest of the code is untouched Now, the result might not be what you expected. This clamps when "audio" is higher than 1, so you might want to do some post-process on the audio. retime_sim_with_chops.hipnc Hopefully that's what you want ! P.S. I found that reducing the amount of points in the line yields a better result, you might want to try that (50 points instead of 498). Try it to see if you like that.
  • Create New...