MeshCNN icon indicating copy to clipboard operation
MeshCNN copied to clipboard

Edge queue runs out of edges

Open SorteKanin opened this issue 5 years ago • 14 comments

So I'm trying to use MeshCNN on some quite large meshes, around ~10000 faces, ~16000 edges. When running the train script however, I get the following error:

File "C:\MeshCNN\models\layers\mesh_pool.py", line 50, in __pool_main
    value, edge_id = heappop(queue)
IndexError: index out of range

It seems that the queue of edges runs out of edges before it has reached the number of edges required by the pool_res argument? Is this correct?

I'm also guessing this is happening because __pool_edge in the same file returns false for too many of the edges in my mesh.

Does anyone have any idea how I might rectify this? Is there a way to make sure that the queue does not run out of edges so that I can continue removing edges, regardless of how many edges I started with?

SorteKanin avatar Jul 01 '19 07:07 SorteKanin

Hi @SorteKanin ,

Thanks for letting me know. So first of all, may I ask, are you trying to learn classification or segmentation?

So currently the default configuration collapses the input mesh to 180 edges for classification and 600 for segmentation. If you have 16k edges, you should increase this. You can do so by changing the --pool_res flag. Instead of passing

--pool_res 600 450 300 180

try passing:

--pool_res 15000 14000 12000 10000

for example.

The number of edges you can collapse is related to a few things: first, we do not collapse any edges near the boundaries, but we could have (following this issue, I checked how to do it but didn't test it out fully yet). So if you have a lot of boundaries it can prevent simplification to a small number. Also, meshes with a high genus (topological "holes") cannot be simplified past a certain amount (mathematically speaking).

In general, another tip I suggest is to simplify the meshes beforehand, to make the network capacity smaller (sort of like resizing images). If you don't have scripts to do that, I hope to add them here soon, but it will take me another couple weeks or so.

ranahanocka avatar Jul 03 '19 14:07 ranahanocka

Hi @ranahanocka, I got the same issue trying to use MeshCNN as classifier, over a dataset where the meshes have different number of faces (and therefore of edges) over the different classes. Even if I avoided this error, it is still failing. So I was wandering if could be possible to run the classification in this case? Differences between the meshes are very big (something like 10k faces in a certain class, while 300 faces in another one). Is it possible? Thank you so much in advance.

SaraCasti avatar Jul 24 '19 16:07 SaraCasti

Hi @SaraCasti , Thanks for letting me know. It seems a bit odd to me to have a network which works on 10k and 300 faces, but I didn't try it, and maybe it can work.

The first option is to process the data: add some more faces to the small resolution meshes, and simplify the larger ones, and get the shapes to be roughly the same size (or at least in a closer range). I recommend this route (at least, I expect this approach to work well).

The second option is leaving your meshes as is, and trying to modify the hyper-params of meshCNN to get it to work with your data. Note that 300 faces is 450 edges (if there are no boundaries), and 10k faces is 15k edges. So the current default --pool_res 600 450 300 210 is probably way too aggressive. If you take this approach, you should modify the --pool_res flag, first check what the smallest number of edges the network can collapse your data to. Let's say the smallest number you can collapse to is 300 edges across all meshes, so in that case I would suggest a lot of pooling layers, --pool_res 9000 6000 3000 600 300 . This route seems slow , and inefficient, but I am curious to know if it works !

Also, make sure you modify --ninput_edges flag to be the max number of input edges. If it is 15k edges, so --ninput_edges 15000

Let me know how it goes :)

ranahanocka avatar Jul 29 '19 19:07 ranahanocka

Hello I tested your code for classificaton I had the same problems, I corrected them as you said but I had another type error: File "MeshCNN/models/layers/mesh_pool.py", line 181, in __remove_triplete assert(len(vertex) == 1) AssertionError I want to inform you that I use models (ShapeNet) with : V: 1530 E: 4860 F: 3240 Unreferenced Vertices 0 Boundary Edges 0 Mesh is composed by 2 connected component(s) Mesh has is two-manifold Mesh has 0 holes Genus is 47 can someone help me plz

sana-aroua avatar Aug 07 '19 12:08 sana-aroua

Hi @sana-aroua ,

Thanks for letting me know. In general, ShapeNet is not manifold. This assertion is failing because of a non-manifold geometry. You can open your model in meshlab, then check Render>show non-manifold edges and also Render>show non-manifold vertices , and it will show you all the bad geometry. Here's a random shapenet model (yes the whole thing is non-manifold so it is show in pink...) image

I mentioned that I would like to find some time to clean & run shapenet in this issue, but I have been busy and still didn't find the time to try it yet, I hope I can find some time to try it soon.

ranahanocka avatar Aug 07 '19 17:08 ranahanocka

thank you for your quick response. I inform you that the information given above are information after testing the manifold code and mesh simplification and the error displayed is after the correction (so I test on manifold mesh ) any idea plz Capture du 2019-08-08 15-38-19

sana-aroua avatar Aug 08 '19 07:08 sana-aroua

I see, thanks for the screenshot. [Maybe the issue is a very small connected component. How did you make this model manifold? Is it with this code? If so, when I tried that, there were like "floating pyramids" and currently the code doesn't handle that, so you should remove them. Try this Filters > Cleaning & Repairing > Remove Isolated pieces w.r.t face num: image and see if it removes pieces. If it does remove the pieces, export the cleaned .obj and then try to re-run the code

ranahanocka avatar Aug 08 '19 15:08 ranahanocka

hi @ranahanocka I did as you advised me and I had this error if min(dihedral[edges]) > 2.65: ValueError: min() arg is an empty sequence

this can be due to points that are not connected to the mesh ? help plz thanks

sana-aroua avatar Aug 09 '19 15:08 sana-aroua

Hi @sana-aroua ,

That is weird. First of all, please delete the meshes in the cache folder (or simply rename the mesh) and re-try. If that still doesn't work try increasing the minimum connected component size in meshlab (and delete the cache again), and try running the MeshCNN code again. If that still doesn't work, let me know and attach the mesh here and I'll take a look

-Rana

ranahanocka avatar Aug 12 '19 02:08 ranahanocka

Hi Thanks for your help . I put the object in attachments test.zip

sana-aroua avatar Aug 12 '19 12:08 sana-aroua

I managed to repair the meshes I had using https://github.com/davidstutz/mesh-fusion. With this solution, there is still a possibility that the meshes have a some unconnected component. To solve that issue, I simply ran meshlabserver with a script that Remove Isolated pieces w.r.t face num

jsll avatar Nov 27 '19 16:11 jsll

Hi @SorteKanin, @SaraCasti, Were you able to solve this error?

I am also getting the same error, it would be helpful to know the steps you have taken to solve it.

dhirajsuvarna avatar Feb 20 '20 06:02 dhirajsuvarna

I never solved it - only used workarounds, like what ranahanocka suggested above or by simply decimating the model files I was using to be less big.

Ultimately I moved away from this approach entirely, so sorry, I have no solution.

SorteKanin avatar Feb 20 '20 07:02 SorteKanin

For other ones' reference, let me share my experience.

I encountered the same problem of "index out of range" while heappop. It seems that the problem is not because the non-manifoldnesss and small components in the input mesh. I carefully checked about them.

Instead, the problem seems to be because that the edge pooling makes the input mesh non-manifold (or turn to include other unexpected edge connectivity). Since the edge pooling depends on the edge features and they seems rather random particularly when the training just started.

Although I did not solve this problem thoroughly, increasing the target number of edges after pooling can be a tentative workaround for this problem.

Also, I think we need to make the network to give a sort of "uniform" features at the initial state and to train the network to slowly adapt to give the purpose-specific features.

tatsy avatar Feb 08 '21 03:02 tatsy