-
Posts
591 -
Joined
-
Last visited
-
Days Won
15
Everything posted by acey195
-
Just got another badge after "reacting" to our wonderful memes Does anyone already have a speedrun on getting all the new badges xD?
-
OK yeah, maybe I should have been more clear there are nodes that can done faster in VEX than native, the partition and measure SOPs come to mind. Its just that Remesh is a much complex beast. If you are a researcher in the field or just want to learn how to do it, then by all means go ahead! But I think that those things: remesh, poly reduce and also uv layout and uv relax(hopefully at some point xD) are among the most difficult graphical problems you run into on a regular basis
-
the remesh node is done in C++, doing it yourself in VEX is unlikely to make it faster That said, there are some things that you can optimize on top of the node. One very easy optimization is to split your mesh by connectivity (create a "class" attribute with the connectivity SOP) then loop over this attribute with a foreach block, and in turn, use compile block around that. My suspicion is that because in each iteration of the loop, the remesh node does not have to consider irrelevant (far away) data, doing a bunch of smaller pieces separately (in a compiled fashion) is faster than processing it as one large chunk. This can speed it up a loot, depending on the target mesh density etc.
-
Or if don't have too many points for which you need to process this, you could also make a preparation wrangle, to build primitive groups, for each point, of what they are allowed to connect to: (I wrote this blind, but it should work.... more or less.. xD) //running over the collision primitives: //second input being the points you want to snap later int nOpts = npoints(1), i; float maxAngle = radians(chf("maxConeAngle")); vector oP, oN; string grp; for(i = 0 ; i < nOpts; i++) { oP = point(1, "P", i); oN = point(1, "N", i); oP = normalize(oP - v@P); // get direction vector from the current primitive to each point grp = sprintf("pt%d_primSelection", i); setprimgroup(0, grp, @primnum, acos(dot(oP, oN)) < maxAngle); } then in your actual wrangle you can just use something like: //running over your points //second input your collision geometry with the created groups string grp = sprintf("pt%d_primSelection", @ptnum); v@P = minpos(1, grp, v@P); If your collision geometry is extremely high-res or you are testing a very large amount of points, this solution might be less scalable than ray casting. If your collision geometry is splines, instead of polygons, you probably have to split them into individual segments, for example with a carve node. if you want your check to be more strict, you could also choose to make a point groups instead of prim groups, and then promote them to primitive groups with the "only include when whole thing is selected something something"
-
Yup array slicing is awesome ^^ I'm wondering though, for when I actually cast a string to a character array (or string array, as chars don't exist in hou) it seems to error unfortunately. Of course I could just loop through the entire string to build the array.. but is there also an elegant way to do it? example of working, but "unelegant" code : string test = "Lorem ipsum"; int n = len(test); string charArray[]; resize(charArray, n); for(int i = 0; i < n; i++) charArray[i] = test[i]; printf("%s\n", charArray);
-
By default you will fetch the tokens if you use chs() on an ordered menu parameter. if you use chi() it will give you the index in the list. Do you need to have 2 strings (the token and the label separately) ? If not you can just copy the label value to the token value. For fetching the actual label string.. I'm actually not sure for VEX from the top of my head.
-
Yup that is correct if you are creating these attribs by binding in wrangles, you can specify the attribute type with a prefix (or set the type in the bind export node in vops) in wrangles for example, you can use i@blahblah to create an integer attrib, or v@blahblah to make it a vector(float3) if you do not define the type, by default it will become a singular float attribute type.
-
clicking those buttons should trigger this callback script. But I'm not aware of a built in way to trigger 2 different callback scripts for plus and minus. To do that, I think you have to keep track of the previous number somewhere (which is also not super trivial I guess), and check if the new number is higher or lower than the previous one.
-
Yup never rely on floats with == checks a further alternative would be something like: if(abs(dot(ynorm, {0,1,0})) > 0.001) or if you want to set a specific angle: if(acos(abs(dot(ynorm, {0,1,0}))) > radians(<angle in degrees>))
-
ok you are right, its a bit more finicky than I realized
-
My suggestion for older versions would be to use NURBS curves if you start from a right angled shape, with control points (vertices) at the marked blue locations and convert it to a NURBS order 3, I believe you get what you would want: edit: if you are using an open curve instead of a closed one, you must add at least one more vertex in the middle of any straight segment, and make sure the curve starts there
-
more toggle's for group nodes (like the group combine SOP) to interpret missing groups as an empty group (so you can choose for it to return a warning, instead of an error. While I know there are workarounds, its quite annoying if your delete node cleans a group on empty geometry and then the group combine returns an error :P) for the "Convert line" SOP to be able to maintain vertex ordering (instead of basing the new vertex ordering, on the input point numbering) (sorting by vertex number does not work in cases where you have closed primitives, resulting in the "last" edge of an original primitive to have a reversed direction) Edit: Update the find shortest path, so it can output the start point attribute even when you are not outputting paths (this way you could use this reference attribute to transfer attributes to the flood-filled network from the closest start point: (right now its possible to work around this by setting the output paths to "from EAch start to any end" and then write some vex to find the lowest value in the cost array, that is not -1, and use that to link the points, but its a bit clunky ) Some heavy nodes (in particular the remesh node) could make more use of multithreading, right now, cooking times can be massively decreased by splitting the mesh (using some kind of internal connectivity logic) and using a for loop, even without compiling sometimes as is the case here: and because of how the remesh works it keep those isolated pieces isolated anyways, so "free" perf yay!
-
Generally speaking completely flat N-gons are fine (as long as you keep them in houdini for logic manipulation :P) if they get very concave they might get rendering issues though as it will do internal triangulation for the rendering, that in some rare cases will create self-intersecting geometry (only on the render side) So for render performance keeping your geometry as n-gons does not really help.. HOwever, in terms of RAM in your Houdini session it can save a lot of data.
-
You probably want to store the time in a previous node, that does not "recook" between your outputs you can use a detail (global) variable for that, if you need code reference for that, look for: hou.node and hou.geometry in the documentation then you can reference this stored value in your rop nodes, that should not change, unless you change the input, above the node that stores the time.
-
would actually not be opposed to that idea..
-
It would add a new data type to take into account for the compiler and memory management. Generally speaking, having if checks in shader like languages is not extremely efficient anyway, so optimizing for them might also not really matter that much. I for one looove the fact that you can just add/multiply bools (ints) together, where with most other languages you cannot. I'm happy to pay a tiny bit extra RAM for that. If you have a lot of && checks, you can just multiply them all together, and if one of them was 0, the result is 0, whereas if you have a lot of || checks, you can also just add them all together and check if the sum of that, is larger than 0 and you can still use bitwise operators on ints to cover all the functionality bools have like: |= &= ^
-
what's the Geometry traversal's application in houdini?
acey195 replied to amin.khormaei's topic in Scripting
why not you could do something like (creating a prim attribute from points data): //run this over primitives, to calculate the perimeter using the point data. //note that this is not the most efficient way to do this, but as an example to what options this gives you: int pts[] = primpoints(0, @primnum); float sumOfTheDistances = 0; for(int i=0; i < (@numvtx-1); i++){ vector pos0 = point(0, "P", pts[i]); vector pos1 = point(0, "P", pts[i+1]); sumOfTheDistances += distance(pos0, pos1); } f@perimeter = sumOfTheDistances; // create a primitive attribute or the other way (creating a vertex attribute while processing prims): //run this over primitives to calculate the same thing a polyframe would, but as a vertex attribute, so you do not have to make the points unique: int verts[] = primvertices(0, @primnum); vector forwardDir; for(i = 0; i < (@numvtx-1); i++){ vector pos0 = point(0, "P", vertexpoint(0, verts[i])); //get the point data, from the vertex (just to demo the conversion, vector pos1 = point(0, "P", vertexpoint(0, verts[i])); //the "P" data should also be fetchable here using vertex() instead of point() forwardDir = normalize(pos1 - pos0); setvertexattrib(0, "N", verts[i], -1, forwardDir); } setvertexattrib(0, "N", verts[-1], -1, forwardDir); //put the same data on the last vertex, as the second to last one note that I have coded this "blind" (did not test it) so hopefully the code runs, but there could be a typo somewhere -
what's the Geometry traversal's application in houdini?
acey195 replied to amin.khormaei's topic in Scripting
Hey, you mean this? : https://www.sidefx.com/docs/houdini/vex/geometry.html it allows you to run your vex code over for example primitives, while retrieving(or changing) data on points or vertices among other things -
Your code does look ok, but it does rely on the N attribute to exist on primitives already (usually they are on points or vertices) so you could also do either vector avgN = 0; for (int i=0; i < npoints(0) ; i++) { avgN = avgN + vector(point(0, "N", i)); } avgN = avgN / npoints(0); or directly fetch the primitive normal with the native function for that: vector avgN = 0; for (int i=0; i < nprimitives(0) ; i++) { avgN = avgN + prim_normal(0, i, {0.5, 0.5, 0.5}); } avgN = avgN / nprimitives(0); but like underscoreus said, the easiest way is probably to use an attributepromote SOP (combined with a facet SOP to generate the N attribute for your points)
-
(just in case it helps anyone else) Not completely sure, but I think the problem you were having, were the extra spaces in your while condition without brackets, sometimes it does "connect" the operators in unexpected ways. so while(radius < max && count < 20){ might behave differently than: while((radius < max) && (count < 20)){ or while(radius<max && count<20){ (last 2 should behave the same)
-
How far behind are you / your studio in Houdini version?
acey195 replied to anicg's topic in Lounge/General chat
I don't think this possible for many people to actually say, since its probably going to be somewhat confidential, but I wouldn't be surprised if its a wide range of versions for larger companies. It would make sense to start with the latest version for a production, especially longer ones. But for ongoing projects, or short projects that rely on things that were created before (on older versions) it make sense to just keep working with what you have. -
Maaaybe, I'm not an expert on this topic.. its just what I've heard from colleagues and friends. Perhaps using an intermediary thing, like a webclient would be a work-around for blender. You sacrifice some of the direct access, but you could still make some basic UI to send data (meshes) back and forth https://www.sidefx.com/docs/houdini/hom/hou/webServer/index.html
-
As a matter of fact, from what I've heard, its actually "legally" tricky to embedd it into open source software.. I believe it would be against Blender's licence agreement if I remember correctly.. but yeah SideEffects made a Houdini engine SDK and documentation for a reason so as long as you are not subverting the licensing system of the plugin, I think you should be fine (This would mean your users would need to get your software as well as a Houdini Engine Licence) and yeah talking about it with SideFX would not be a bad idea either. I think they're always interested in hearing about stuff like this
-
Depending on what you are doing in the loop. if the logic is going to be "compilable", You can also look into the "Invoke" SOP that is a way of reusing a part of network, with a different input (generating a different output) but it only works together with a compiled block as a reference.