ranahanocka / MeshCNN

Convolutional Neural Network for 3D meshes in PyTorch
MIT License
1.56k stars 314 forks source link

meaning about the "sides" in the mesh structure #36

Closed chengzg closed 4 years ago

chengzg commented 4 years ago

Hi ranahanocka,

Cheers for the creativity. I am sorry if here is not the right place to ask the questions. I am looking at the code:

1) in the implementation, inside the build_gemm function, what does the "sides" list here mean? Why do we need this information? 2) After unpooling of the mesh, are the mesh exactly the same as the original mesh, i mean the vertex position as well as the mesh connectivity? Will they be different? How can i export the reconstructed mesh?

Thanks & Regards, zg

chengzg commented 4 years ago

Hi,

Can you help me clarify the "sides" doubts? It's really not very clear to me. Thanks a lot.

ranahanocka commented 4 years ago

Hi @chengzg ,

Thanks for letting me know it's not clear :). I added some comments within the build_gemm method:

    gemm_edges: array (#E x 4) of the 4 one-ring neighbors for each edge
    sides: array (#E x 4) indices (values of: 0,1,2,3) indicating where an edge is in the gemm_edge entry of the 4 neighboring edges
    for example edge i -> gemm_edges[gemm_edges[i], sides[i]] == [i, i, i, i]

let me know if it's still not clear.

Thanks, -Rana

ranahanocka commented 4 years ago

2. After unpooling of the mesh, are the mesh exactly the same as the original mesh, i mean the vertex position as well as the mesh connectivity? Will they be different? How can i export the reconstructed mesh?

Yes, the mesh connectivity is exactly the same. The vertex positions are arbitrary, since there is no effect of vertex position in the loss function (they are only used to extract the input features), so they are just for visualization purposes. In the visualizations, we use the same vertex position as the original mesh.

To export the reconstructed mesh, please follow the segmentation examples from this github repo. I also explained that in this issue.

chengzg commented 4 years ago

Hi @chengzg ,

Thanks for letting me know it's not clear :). I added some comments within the build_gemm method:

    gemm_edges: array (#E x 4) of the 4 one-ring neighbors for each edge
    sides: array (#E x 4) indices (values of: 0,1,2,3) indicating where an edge is in the gemm_edge entry of the 4 neighboring edges
    for example edge i -> gemm_edges[gemm_edges[i], sides[i]] == [i, i, i, i]

let me know if it's still not clear.

Thanks, -Rana

@ranahanocka , Thanks so much for your time and answer.

I am sorry but it is still not clear to me. Let's say i have a simple mesh contains 3 faces only as shown below. faces are: F1(0, 2, 1) F2(0, 3, 2) F3(0, 4, 3)

                      4
                     /\
                 3  /__ \ 0
                    \   / \
                      \/___\ 
                     2        1

According to the program, the information will be: 
edge list,    |   edge_nb(gemm_edges)   |    sides 
(0, 2) --> 0             [1, 2, 3, 4]                 [1, 0, 1, 0]
(1, 2) --> 1             [2, 0, -1, -1]              [1, 0, -1, -1]
(0, 1) --> 2             [0, 1, -1, -1]              [1, 0, -1, -1]
(0, 3) --> 3             [4, 0, 5, 6]                 [1, 2, 1, 0]
(2, 3) --> 4             [0, 3, -1, -1]              [3, 0, -1, -1]
(0, 4) --> 5             [6, 3, -1, -1]              [1, 2, -1, -1]
(3, 4) --> 6             [3, 5, -1, -1]              [3, 0, -1, -1]

So for example, edge index 6 whose vertex index pair is (3, 4): its 2 neighbours are edge [3, 5], but its first 2 values of sides are [3, 0] What i do not understand about is the value 3, 0. What are their actual meaning here? Where would there values be used?

Appreciate your time and answer. Thanks.

Thanks & Regards chengzg

ranahanocka commented 4 years ago

Hi @chengzg ,

so think about everything in terms of edge indices. For edge index 6, which is a boundary edge, it has two neighboring edges 3 , 5: gemm_edges[6] = [3, 5, -1, -1]

The first edge neighbor is 3. If we look at the neighboring edges of 3 we have: gemm_edges[3] = [4, 0, 5, 6]

what sides tell us is that edge 6 is the last entry in the edge 3 neighbors ([4, 0, 5, 6]). Since :

sides[6][0] = 3.

In other words sides[E][N] tells us the index of edge E for the the N neighbor.

This data structure is used for the edge collapse in mesh_pool.py. When we delete an edge, each neighboring triangles should merge into a single edge, and so we must update the mesh with the new edges : image this keeps a valid mesh which is dynamically maintained within the network... and that each convolution gets the newly updated 1-ring neighborhood.

You can sort of think of it like a tensor version of the half-edge data structure .

chengzg commented 4 years ago

@ranahanocka, Thanks very much. Now it is very clear to me.