edges and groupings

   9235   18   3
User Avatar
Member
17 posts
Joined: March 2019
Offline
So I have a model made entirely out of cubes.

I need to be able to do something differently based around each face or edge, for example :
  • if an edge is on a corner
  • if edge joins two faces as an innner-corner or outer-corner (horizontally or vertically)
  • orientation of each face
  • turn some faces into slopes
  • remove edges inside the selection so that I have a perimeter.

I'm finding working with edges/faces like this really difficult (despite the mesh being built around this concept…) D:


Is there some way I can handle these use-cases with built-in nodes?

As a new user, I haven't delved into VEX yet (so if an easy way to handle some of these exists there, please let me know), but the seemingly-mandatory (and involved) math scares me away. If VEX is necessary, would somebody be gracious enough to provide an example .hip file showing how to deal withv some of the above scenarios?
I would seriously appreciate any help on this – I've been stumped for weeks!! D:
Edited by awesomedata - March 23, 2019 22:50:42

Attachments:
dungeon-test.png (501.9 KB)

User Avatar
Member
17 posts
Joined: March 2019
Offline
Nobody can help?
I've been neck deep in tutorials and documentation looking for a good approach to understanding edges, but I've found nothing to help me find a general approach to them.

Any advice on edges and faces (mainly in terms of identifying them) would be much appreciated!
Edited by awesomedata - March 24, 2019 12:50:31
User Avatar
Member
670 posts
Joined: Sept. 2013
Online
You can detect corners with the group node set to ‘edges’ and ‘min edge angle’.
The orientation of each face can be read from the primitive normals inside a primitive VOP.
https://procegen.konstantinmagnus.de/ [procegen.konstantinmagnus.de]
User Avatar
Member
17 posts
Joined: March 2019
Offline
Konstantin Magnus
The orientation of each face can be read from the primitive normals inside a primitive VOP

Would you mind giving a little more detail about how to do this?

Also, is there any way to specifically-identify the normals for the edges as well? (i.e. NE/SE/NW/SW)
For example, I want to select all edges (or faces associated) with THIS angle:
Edited by awesomedata - March 25, 2019 12:43:55

Attachments:
normal.png (1.0 MB)

User Avatar
Member
17 posts
Joined: March 2019
Offline
That's crazy – I can't find any information anywhere on the internet how to do the above.

Has anyone _ever_ done this procedurally before?
User Avatar
Member
710 posts
Joined: July 2005
Online
Also, is there any way to specifically-identify the normals for the edges as well? (i.e. NE/SE/NW/SW)
Use the Keep by Normals option in the Group Create SOP. See image for example.

The options under the Include by Edges section like Min/Max Edge Angle and Unshared Edges will probably also be of interest. Also remember that you are able to composite groups with Group Combine, which will probably be necessary for a lot of what you want to do. The ability to promote groups (ex: points to edges) is also very handy.
Edited by Siavash Tehrani - March 27, 2019 11:11:54

Attachments:
group_edges.png (195.5 KB)

User Avatar
Member
17 posts
Joined: March 2019
Offline
DaJuice
Use the Keep by Normals option in the Group Create SOP. See image for example.

Thanks for the help, and that would be handy if it worked, but the below is what I get when I use that:



It is definitely my normals – but I'm not entirely sure what to do about it.
These are not extruded Houdini cubes unfortunately.
The .obj file I've imported doesn't “double-up” the normals on the inside (straight) “non-corner” edges like an Extruded cube face does.
Using the Normals node doesn't fix this either.

Here's what the Houdini cube vs. my non-Houdini cube (with “Normal” node) look like with normals displayed:

Houdini cubes

My cubes



I'm at a loss.

I read somewhere I _might_ be able to check the vert count on each point (using VEX) to tell whether it belongs to a corner, and somehow make that an edge (and group it somehow too), but I'm not sure how I would actually go about doing that.
Edited by awesomedata - March 27, 2019 14:01:37

Attachments:
normal+edgegroup.png (536.8 KB)
normal+edgegroup (houdini-cube).png (396.4 KB)
normal+edgegroup (non-houdini-cube).png (590.5 KB)

User Avatar
Member
710 posts
Joined: July 2005
Online
It looks like all your faces are detached from one another (three separate blue normal guides on each corner). If you insert a Fuse node before your Group, the Keep by Normals settings should work. Feel free to upload a scene file as well.
User Avatar
Member
17 posts
Joined: March 2019
Offline
DaJuice
If you insert a Fuse node before your Group, the Keep by Normals settings should work.

This actually worked (somewhat!) for me!
But now my normals are all weird in some areas and strangely-selected (the Normal node doesn't fix them):




It seems the corner normals need to be pointing at an angle away from the corner point for it to actually select the edges properly.
Not too sure how to enforce this.

The “Fuse” node has the default settings. – Maybe I need to do something there?
Edited by awesomedata - March 27, 2019 15:30:50

Attachments:
normal+fuse (weird normals).png (323.2 KB)

User Avatar
Member
710 posts
Joined: July 2005
Online
That's the expected result for the normal guide display in this case. In Houdini there is a distinction between a point and a vertex. A point is only going to show you a single point normal guide (in blue), which is an average of the vertex normals (green guides). Your corners have one point, but three vertecies. The reason you had three blue guides previously is because faces were unshared and you had points laying on top of each other.

I don't know enough about what end result you are going for in last image, so I'm not sure how to help.
Edited by Siavash Tehrani - March 27, 2019 16:09:50
User Avatar
Member
17 posts
Joined: March 2019
Offline
DaJuice
I don't know enough about what end result you are going for in last image, so I'm not sure how to help.

Basically, I just want the corner to be selected all the way down the edge, from top to the bottom, on a specific angle.
I just need my edge selection to stay vertical all the way down at a particular NW/SW/NE/SE angle like so:



Let's just say this is the SW corner group.
If it helps, my cubes are all aligned to a 1x1 meter grid (starting at 0,0,0), so perhaps this could help get the correct edges/normals more easily?

Essentially, I need this (green-circled edges only):

Edited by awesomedata - March 27, 2019 18:03:53

Attachments:
normal+fuse.png (183.7 KB)
normal+edges.png (120.6 KB)

User Avatar
Member
710 posts
Joined: July 2005
Online
Here is an example using just built-in nodes.

Attachments:
edgeGroups.hip (259.8 KB)
edgeGroups.png (318.0 KB)

User Avatar
Member
17 posts
Joined: March 2019
Offline
DaJuice
Here is an example using just built-in nodes.

Attachments:
edgeGroups.hip (259.8 KB)

Wow – THANK YOU!!
I was under the impression this was not possible without VEX!

This is GREAT! - Plenty to study!

I'm a huge beginner at Houdini, but I understand the concepts and I'm getting more comfortable with its methods (your example will help loads!!)

I program tools in C# already, but after looking at your example, I probably need to get into VEX sooner than I anticipated.
It will take me a lot longer to learn the nuances of that many nodes than it would take me to learn a new language.

If it wouldn't trouble you too much, would you be willing to share an example of how you would do these edgeGroups in VEX?
I'm struggling to understand how to apply this to top/bottom edges using only nodes.
I want to learn both ways because I have a hunch it might be easier (and generally faster, in both productivity and performance) to do this with VEX instead.

Any thoughts?
Edited by awesomedata - March 28, 2019 10:21:53
User Avatar
Member
29 posts
Joined: May 2018
Offline
FYI you can make groups in VEX or Python (and HScript I imagine, but I haven't done this).

I have a Houdini 17.5 indie file on github that demonstrates some group selection's with VEX here [github.com] (see the Wrangle section).



VEX

For VEX, the relevant documentation is here [www.sidefx.com]:

A special virtual attribute of the form @group_groupname lets you get or set group membership for the current element.

You can check if the current point/edge/primitive/particle is inn a named group by checking if @group_name == 1.

You can add or remove the current point/edge/primitive to a group by setting the virtual @group_name attribute. Setting the attribute to 1 (or any non-zero value) puts the current element in that group. Setting the attribute to 0 removes the current element from that group.

Here's the VEXpression for an Attribute Wrangle node that's creates a group named mygroup for even numbered primitives:

@group_mygroup = @primnum % 2 == 0;

Python
The Python documentation is in the Geometry section [www.sidefx.com]. There are functions for manipulating point groups, primitive groups, and edge groups.

Here's an the code for a Python SOP that I used to create a point group made up of points that were the same height as the max point in the input group (within a tolerance). I then promoted the results of this to an edge group and used it to create a UV seam.

inputGroup = "inputGroup" 
outputGroup = "outputGroup"

node = hou.pwd()
geo = node.geometry()
points = geo.findPointGroup(inputGroup).points()

tolerance=0.00001
height=max([p.position().y() for p in points])

group=geo.createPointGroup(outputGroup);
edgeLoopPoints = [p for p in points if abs(p.position().y() - height) < tolerance]
group.add(edgeLoopPoints)

Misc
Not directly related to your question, but something you might find interesting is the Find Shortest Path [www.sidefx.com] geometry node. In my case I was using it to procedurally generate seams for UV unwrapping, but it gives you another tool for selecting edges. To see how to use it to select edges, see this uv_unwrap_parts.hiplc [github.com].
Edited by DougRichardson - March 28, 2019 14:17:59

Attachments:
Capture.PNG (459.0 KB)

User Avatar
Member
17 posts
Joined: March 2019
Offline
drichardson
Here's an the code for a Python SOP that I used to create a point group made up of points that were the same height as the max point in the input group (within a tolerance). I then promoted the results of this to an edge group and used it to create a UV seam.

Thanks for the info – and that Python part is actually pretty cool (and could be useful to what I'm doing.)
How different would doing these same operations in VEX be though? – is there an equivalent? (or a way to mix python and VEX?)



DaJuice
Here is an example using just built-in nodes.

I've been playing with your output file, but for some reason I'm not seeing the groups in your screenshot.
How would I get these to display using the .hip you've provided?
User Avatar
Member
29 posts
Joined: May 2018
Offline
awesomedata
How different would doing these same operations in VEX be though? – is there an equivalent? (or a way to mix python and VEX?)

The overview of Python Scripting [www.sidefx.com] and VEX [www.sidefx.com] discuss where each language is used.

Considering that Python example I gave above that searches for the max element, you can do it in VEX. Here's what the Python SOP looks like translated to VEX. This is the code for a VEXpression in an Attribute Wrangle node with Group Type set to Points and Run Over set to Detail:

// Find the point with the max Y value.
int geo = 0;
int points[] = expandpointgroup(geo, "bottom_scoop");
float maxY = -100000000000000000000.0; // would prefer something like C++'s FLT_MIN but couldn't find it

foreach(int point; points) {
    maxY = max(vector(point(geo, "P", point)).y, maxY);
}

// Create a group from all points within a y tolerence of the max Y value.
float tolerance = 0.00001;
foreach(int point; points) {
    float y = vector(point(geo, "P", point)).y;
    int ingroup = abs(y - maxY) < tolerance;
    setpointgroup(geo, "scoop_seam", point, ingroup);
}

You can also find the VEX and Python versions of this “select highest point” node in this UV unwrap example [github.com].

There's a big performance difference between Python and VEX (VEX is much faster). I cranked up the geometry on my UV unwrap example so I could compare the cook times between the VEX and Python implementations. VEX node cooked in 0.04ms while the Python node cooked in 103.15ms.

Edited by DougRichardson - March 29, 2019 20:55:37

Attachments:
VEX vs Python Performance.PNG (90.9 KB)

User Avatar
Member
4495 posts
Joined: Feb. 2012
Offline
If you MMB on HDAs with subnets, they won't report the actual cook time, so it's inaccurate. You have to dive inside AttribWrangle, and MMB on the attribvop node inside to see the actual cook time.
Senior FX TD @ Industrial Light & Magic
Get to the NEXT level in Houdini & VEX with Pragmatic VEX! [www.pragmatic-vfx.com]

youtube.com/@pragmaticvfx | patreon.com/animatrix | animatrix2k7.gumroad.com
User Avatar
Member
29 posts
Joined: May 2018
Offline
animatrix3d
You have to dive inside AttribWrangle, and MMB on the attribvop node inside to see the actual cook time

Wow, you're right. I ran the comparison again, this time looking at the wrangler's internal VOP and it's taking 109.13ms while the wrangler only reports 0.03ms. That is really surprising. I'm a Houdini newbie and expected cook times reported in node info to be an accumulation of everything inside the node.

Is this a bug, design limitation on HDAs/Subnets, or am I fundamentally misunderstanding what cook time means?

Attachments:
Comparison.PNG (111.5 KB)

User Avatar
Member
4495 posts
Joined: Feb. 2012
Offline
It's a bug, but to get accurate cook times you can use the Performance Monitor. That will do a proper accumulation of all of cook times for each HDA.
Senior FX TD @ Industrial Light & Magic
Get to the NEXT level in Houdini & VEX with Pragmatic VEX! [www.pragmatic-vfx.com]

youtube.com/@pragmaticvfx | patreon.com/animatrix | animatrix2k7.gumroad.com
  • Quick Links