Community
Bifrost Forum
Welcome to the Bifrost Forum. This is the place for artists using Bifrost to ask and answer questions, browse popular topics, and share knowledge about creating effects procedurally using Bifrost. You can also visit the Bifrost Community on AREA to download an array of ready-to-use graphs, read Bifrost news and updates, and find the latest tutorials.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

BiFrost Gemotery traversal

7 REPLIES 7
SOLVED
Reply
Message 1 of 8
calibrix
1205 Views, 7 Replies

BiFrost Gemotery traversal

Hi BiFrost peeps!

I'm trying to wrap my head around understanding the mesh structure in BiFrost and can't seem to find much about it in the documentation. I'm given to understand that meshes have 3 components: points, vertices, and faces. From what I've been able to piece together from forum posts and blogs is that face_vertex_components can be accessed by using face_offset to search the face_vertex array. What I can't figure out is how to relate face_vertex_components to point_components, as there doesn't seem to be a point_offset array. I was hoping to find nodes that mimicked these commands from houdini: https://www.sidefx.com/docs/houdini/vex/geometry.html as this makes traversing geometry rather simple. I'm not exactly sure how to use a point to look up data about a face_vertex. I'll give a practical example: The read alembic node imports vertex colorsets as face_vertex_components (array<Math::float4>) and I want to convert them to a point_component. However, I can't just use a get_geo_property node because the resulting face_vertex_component array size is larger than the point_component array. However, I can't figure out how the point_component relates to the face_vertex_component in order to extract the data. I found this post (https://forums.autodesk.com/t5/bifrost-forum/converting-face-vertex-compontent-property-to-point-com...) that includes a compound that promotes face_vertex_component data into point_component data, but it doesn't explain any of the logic why that would be the correct way to do that. Further frustrating my efforts to understand this are nodes inside the compound that lack documentation or hints as to their exact function (EG: update_mesh_adjacency). If there are any of you guys that understand these data structures I'd love to hear more about how they work so I can better use them.

Thanks in advance,

Chris

Labels (3)
7 REPLIES 7
Message 2 of 8

@mjcg91 has an excellent blog post about Strands which you just need to translate to meshes. Hopefully it'll be helpful to you.

 

Message 3 of 8
calibrix
in reply to: calibrix

@mjcg91's blog has been a great resource. It's where I learned that the "_offset" represented. So, I'm able to use the "face_offset" attribute to access the "face_vertex_components", but as I mentioned I don't see how to get "point_components" as there is no related "point_face_offset" or "point_vertex_offset". Obviously points and vertices are related, but I can't find any nodes or data to suggest that point0 relates to vertex25 for example. I did find a compound that does exactly what I want (transfer a face_vertex_component to a point_component) but I would rather understand how it works. Since many of the important nodes inside the compound lack documentation, my only way to learn on my own if to infer what those nodes might be doing. I'm hoping to get a more in-depth explanation from you fine experts here.

Message 4 of 8
mjcg91
in reply to: calibrix

I think the compound you found make use of the mesh's adjacency data to get a point's corresponding face vertices easily. I don't know what algorithm it uses since update_mesh_adjacency is an operator, but it is used to get the points' face neighbors. This it also holds the information about which side on the faces are the point's location, you can use it easily to get the points' face_vertex_indices.

You can definitely compute the point's face vertex neighbors using only the graph. though it will be a sequential operation which can be slow for high resolution geometry. Here's the steps:

_Init a 2D array of type long and size = point_count using resize_array. Call it point_face_vertex_neighbors.

_With an iterate compound, loop on each face_vertex element.
_For each face_vertex element, use the value with get_from_array to get the corresponding sub-array from point_face_vertex_neighbors.

_Using a build_array node, connect the result of get_from_array AND connect the current_index port.

_Set the the updated sub-array back in point_face_vertex_neighbors using set_in_array.
_Output the result of set_in_array. (There should be a state port between this and its input).
_Repeat until loop is done

You now have a 2D array where each sub-array represents the point's corresponding face_vertex.

FYI, face_offset is used to get the range of face_vertex of the faces. Unlike for strands, you don't use it to get point indices but face_vertex indices. The face vertex indices are the actual values pointing to the point indices. 

Maxime Jeanmougin - Technical Artist
https://maximejeanmougin.com

Join the Bifrost Addicts community on Discord:
https://discord.gg/bifrost-addicts
Message 5 of 8

Just to be clear, for meshes point_component keeps track of the number of unique points in the mesh - nothing more, nothing less. Geometry properties like point_position, point_normal and point_color have their "target" set to point_component so they always have the correct number of, well, points. A mesh also has a face_component which keeps track of the number of faces (e.g. triangles and quads) in the mesh, again, nothing more, nothing less. Again, face geometry, like face_normal, would target face_component to make sure it always has the correct number of elements (one for each face). Finally, you have face_vertex_component which keeps track of the number of face vertices (one for each corner of a face, so e.g. 6*4=24 in total for a cube made of quads). Per face-vertex geometry like face_vertex_normal and face_vertex_uv would target this component.

 

Face offsets (face_offset) and face vertices (face_vertex) are used to specify faces of a mesh. For instance, if the following is your mesh:

mesh.png

Then face_vertex would be an array: [1,4,2,4,5,3,2] corresponding to the two faces traversed in counter-clockwise order (note, you could start anywhere in the face, i.e. 1,4,2 and 4,2,1 are equivalent) and face_offset would be an array: [0,4,7] corresponding to the first face starting at 0th position (we start counting from zero rather than one), the second face starting at the 4th position and the final entry is always the number of elements in the face_vertex array, here 7.

Message 6 of 8
calibrix
in reply to: calibrix

Ah! I get it. Thanks so much guys. This is very helpful. Each face_vertex data is that point number. All that needs to be done to retrieve face_vertex_component data is to search the array for matching point numbers. In my case, I know the face_vertex_component data is the same for all shared verts and can just find the first one. I’ve already been able to mock up a simple prototype. This has been really helpful.

Message 7 of 8

I would also recommend you watch Marcus Nordenstam's tutorial. It goes into details on how to iterate over a mesh using get_mesh_structure, access_offset_array and slice_array.

Message 8 of 8
stephen.yee
in reply to: calibrix

It's a bit buried, but the documentation for the geometry data structures has some description and examples which may be of help. It is located in the Bifrost plugin installation directory under:
<install dir>\plug-ins\bifrost\resources\bif\jsonLibs\doc\getting_started\geometry_basics.md

 

Hope that helps!

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums