Question [Solved] Cleanest way to get Mesh Group vertex and triangle connectivity data?

Thunder Chicken

Resident Lua Script Rabble-Rouser
Donator
Joined
Mar 22, 2008
Messages
5,847
Reaction score
5,509
Points
188
Location
Massachusetts
I have been working on a buoyancy force model that requires access to the mesh vertex locations and the corresponding triangle connectivity. I have been just parsing the mesh file directly, but I know the data is available in the simulation and I think I should try to develop getting the necessary data that way.

It seems that oapi.get_meshgroup() gives me this access, but I am not sure of the form of what that returns, and it seems that I must tell it how many vertices to expect and allocate memory for that, and I'm not sure how that is done for a general mesh unless the user physically opens the mesh and looks for the GEOM data.

What I am envisioning is that the user can provide the indices of the mesh groups of the loaded mesh hmesh that correspond to hull surfaces where buoyant forces would be expected, like this:

Code:
hull_meshgroups = {1,2,3,4,5,6}

And something like the following would pull the necessary data from those meshgroups:

Code:
for i = 1, #hull_meshgroups do
    
        structure_that_stores_vertices_and connectivity[i] = oapi.get_meshgroup(hmesh, i)

end

*extract vertex and triangle connectivity data for force calculations*

The above would only need to be run once, perhaps in clbk_setclasscaps or clbk_postcreation, so the vertex data and triangle connectivity would be available before the simulation starts.

I've read the comments and documentation associated with get_meshgroup() but my understanding of what that is explaining is rather muddy.
 
Did you check if oapi.mesh_group does what you need? I think it requires a "mesh template" that you can get with oapi.load_meshglobal
 
Did you check if oapi.mesh_group does what you need?
I wasn't aware of that method, but the documentation suggests it does.

The following runs, and the message reports the type as 'table'.

Code:
    hull_meshgroup = {1,2,3,4,5,6}
    hull_group = {}

    for i = 1, #hull_meshgroup do
    
        hull_group[i] = oapi.mesh_group(hmesh, hull_meshgroup[i])

    end

    message = type(hull_group[1].Vtx)

But this message returns some hexadecimal code and says 'object':

Code:
message = hull_group[1].Vtx[1]

It is giving me something, but I am unclear on how to pull the vertex vectors and connectivity from it.

I think it requires a "mesh template" that you can get with oapi.load_meshglobal
What is this needed for?
 
#hull_group[1].Idx returns 6, which is the correct count, and indexing it #hull_group[1].Idx[j] seems to be giving the index of the triangle vertices, but it appears to be for the wrong group. Have to investigate that a bit more.

#hull_group[1].Vtx returns 4, which is the correct number of vertices for the group. But hull_group[1].Vtx[1] returns some hexadecimal goo and a statement that it is an object.

OK, I think I see it: hull_group[1].Vtx[1].x gives me a number that matches the x coordinate of that element. So it doesn't pass a complete vector, but the components. I can work with that.
 
Progress, but I am trying to get the following indexing to work but it fails, and I am unsure why:

Code:
    hull_meshgroup = {1,2,3,4,5,6}
    hull_group = {}
    vertex_list = {}

    for k = 1, #hull_meshgroup do
   
        hull_group[k] = oapi.mesh_group(hmesh, hull_meshgroup[k])

        vertex = {}

       message = type(#hull_group[k].Vtx) --THIS RETURNS 'NUMBER'
       message = #hull_group[k].Vtx --THIS RETURNS '4' (CORRECT VALUE)


        for j = 1, #hull_group[k].Vtx do --attempt to index field '?' (a nil value)
           
            vertex[j] = {x=hull_group[k].Vtx[j].x, y=hull_group[k].Vtx[j].y, z=hull_group[k].Vtx[j].z}
       
        end
       
        vertex_list[k] = vertex

    end

    message = #hull_group[1].Vtx  --RETURNS 4 (CORRECT)

I'm not understanding why using #hull_group[1].Vtx as an index bound in the for loop fails. It delivers the correct number.
 
Last edited:
I'm at a dead stop right now. I seem to be completely unable to get the size of hull_group[k] in a way I can use as an index.

I've tried #hull_group[k] and hull_group[k].nVtx, both are nil, until I replace k with an integer after the loop, which rather defeats the purpose. How to get the vertices out of this?
 
Here's what I have. I have no idea why this can't work:

In SetClassCaps I pass the mesh handle and the vector of hull mesh groups to function get_triangle.mesh:

Code:
function clbk_setclasscaps(cfg)

    hmesh = oapi.load_meshglobal('Cube/Cube')
    vi:add_mesh(hmesh)
    vi:set_mesh_visibility_mode(0, MESHVIS.ALWAYS)

    hull_meshgroup = {1,2,3,4,5,6}

    get_triangle.mesh(hmesh, hull_meshgroup)

Here is get_triangle.mesh(hmesh, hull_meshgroup):

Code:
function get_triangle.mesh(hmesh, hull_meshgroup)

    vertex_list = {}

    for k = 1, #hull_meshgroup do

        message = hull_meshgroup[k] --this gives '1' at k = 1, which is correct.

        hull_group[k] = oapi.mesh_group(hmesh, hull_meshgroup[k]) --FAILS HERE AT k=1, attempt to index hull_group (a nil value)

        vertex_list[k] = hull_group[k].Vtx

    end

end
 
Sigh the mesh group numbering starts at 0, not at 1. hull_group{1,2,3,4,5,6} needs to be hull_group{0,1,2,3,4,5}.

It's always the mundane details that get you.
 
Glad to see you managed by yourself (y)
ntvertexarrays contain position, normal and UV data so you need to specify the part you need. You should be able to replace the ugly
Code:
vertex[j] = {x=hull_group[k].Vtx[j].x, y=hull_group[k].Vtx[j].y, z=hull_group[k].Vtx[j].z}
with a simpler
Code:
vertex[j] = hull_group[k].Vtx[j].pos
Also note that vertex arrays use Lua style indexing (i.e. starting at 1) so you must add 1 to the indices you get from to the index buffer.
 
Glad to see you managed by yourself (y)
ntvertexarrays contain position, normal and UV data so you need to specify the part you need. You should be able to replace the ugly
Code:
vertex[j] = {x=hull_group[k].Vtx[j].x, y=hull_group[k].Vtx[j].y, z=hull_group[k].Vtx[j].z}
with a simpler
Code:
vertex[j] = hull_group[k].Vtx[j].pos
That's a helpful simplification. Is there a similar sugar for pulling the triangle connectivity out of the Idx table? It seems that the Idx table just dumps an ordered list of the vertex addresses (If #Idx = 6, there are two triangles described, etc). I basically parsed that list by taking each group of 3 vertex addresses and assigning them to a vector associated with each triangle like this:

Code:
        ntri = #idx_list[k]/3

        for i = 1, ntri do

            triangle_list[k][i] = {x=idx_list[k][((i-1)*3)+1], y=idx_list[k][((i-1)*3)+2], z=idx_list[k][((i-1)*3)+3]}

        end

That works fine, but anything that simplifies the code is welcome.
Also note that vertex arrays use Lua style indexing (i.e. starting at 1) so you must add 1 to the indices you get from to the index buffer.
Yep, I found that out. Lua can be made to index from 0 or anything else, but I think I'll leave well enough alone.
 
Back
Top