-
Notifications
You must be signed in to change notification settings - Fork 52
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Invalid Hull Output #23
Comments
I was doing a bit of testing to identify the issue, while comparing the two implementations, I tried printing the points being added to the hull in each algorithm in order Note : Base refers to the points added to the base tetrahedron, Hull1 is the current implementation, Hull2 is VHACD implementation Hull1 Point Base -18.2869 31.6738 2.175 Hull2 Point Base -17.6332 -17.342 89.9628 The first 5 points forming the hull are same for the both algorithms, so we can safely check for the points after it. I noticed that these 5 points are also coplanar for our case Based on these observations, I thought it could be something related to points having equal distances so I tried changing https://github.com/akuukka/quickhull/blob/master/QuickHull.hpp#L211, I replaced this line with I now plan to try and identify the first iteration of the algorithm where the corresponding output is a non-convex hull and attempt to see what could have caused the extra triangles in the output. I would appreciate some ideas and input on this, so that we can try and fix this bug |
Interesting! I'm afraid I don't have time to investigate this issue thoroughly, but I would be happy to check & merge a pull request if you can fix the problem. |
If here Line 163 in 4ef66c6
instead of if (d>0) { we have if (d>m_epsilon) { then the problem seems to go away - at least in the 18 point case. |
Yeah I've tried that as well, it does seem to fix the issue for this case, but for certain other cases, the outputs varied compared to the other algorithm. I will check their renders to see if the hull is valid, and try to investigate further, and share the results with you. Also, could you explain the significance of the second condition in Line 197 in 4ef66c6
I have been trying a couple of other things as well and I think I might be close to the fix, give me a couple of days. I will get back to you about them. I have also worked on a condition to check if the intermediate polyhedron after each iteration is convex, I will create a draft PR where I can share it, I have identified the iteration where the polyhedron becomes non-convex for the first time, and am trying to identify the issue. I will share some screenshots of the intermediate renders by tonight as well |
That second condition simply tests if the distance to the plane is more than m_epsilon. It looks a bit ugly because we want to avoid doing square roots. |
Alright, thanks for the quick reply. I have to run somewhere right now, I will post some of my results tonight. |
I think it's good idea to use m_epsilon instead of zero as the limit on line 163 (QuickHull.cpp), because otherwise faces that are not visible may appear visible due to numerical inaccuracy. This can corrupt the horizon edge loop and thus eventually the convex hull too. And actually, we should use squared epsilon and take the plane's normal length into account here too, so if (d > m_epsilon) is not the correct check, but if (D > 0 && D*D > m_epsilonSquared * P.m_sqrNLength) { where D is const T D = mathutils::getSignedDistanceToPlane(activePoint, P); |
Ok, so I ran some tests for several cases based on your suggestions and my understanding, but the results I got were not satisfactory, I have shared an example of the result below. For the case you suggested : if (D>0 && D*D > m_epsilonSquared * P,m_sqrNLength) at both lines 163 and 197
These values are normalized to 1 keeping our implementation as the base, so we can interpret this results as the output of our algorithm is wrong by more than 30% for area and more than 20% for volume. If we assume the VHACD implementation to be correct. (Since the outputs of VHACD and CGAL matched with a very small error percentage). Additionally upon checking I could find cases where the output was still an invalid hull. And I obtained similar issues with other cases I tried like just changing the line 163 d>m_epsilon or replacing the d>0 of line 163 and line 197 with d>m_epsilon, you can see some of those commented conditions in the draft PR I have created, just so you can get an idea of the conditions I tried. Based on these it seemed to me that there had to be some other issue as well,so I was going through the code and I noticed at Lines 20 to 23 in 4ef66c6
Clearly the outputs are now within 0.1% precision which is a significant improvement, and upon checking for the number of "invalid" convex hulls using my function isMeshConvex (attached in the draft PR), there were only two cases out of the 10,000 where it gave an "invalid" convex hull, I haven't yet looked at the outputs, but it is possible that they're considered "invalid" just due to precision errors. I feel so because, compared to any other case I tried, they had 100s of "invalid" values. So, I felt that this is a necessary change. And I wanted to verify with you once if you feel this change logically makes sense. Now, I plan to further investigate the two cases, and also other possible ideas that could have caused the issue. If you do think this change is needed, what would you suggest is the next place to look at, so that we can negate those two "invalid" cases as well? |
The quickhull algorithm sometimes produces a non-convex output, which has internal triangles. I've attached some images and tried to explain the issue in elalish/manifold#781,
The gist of it is that I was testing the algorithm on the Thingi10K dataset and I discovered these two cases which had issues:
39202.stl:
From these images it's clear to see that there is an excess volume and area of the object, which is caused due to the piece contained inside the object, this extra piece is produced by this quickhull implementation, which leads to a non-convex output, and is clearly something that should not be present. Since my testing also involved comparing various algorithms, I noticed the VHACD implementation (https://github.com/kmammou/v-hacd/blob/master/include/VHACD.h#L2321) does not have this issue.
Similary for 1750623.stl :
The extra piece is contained inside the object, and it is also produced by this implementation but not the VHACD implementation.
In order to better identify what could cause the issue, I tried narrowing down the set of points, and have reduced the set of points to 18 points, this also has a similar volume inside the "hull" :
This is the file containing the 18 points is called "18points.bin", I've stored the points in binary to avoid loss of precision, and the glb files of the outputs of akuukka implementation and VHACD implementation are also attached, for comparision.
To parse the points, you can use a function similar to
Files.zip
I am looking to fix this issue, as we (@elalish, @pca006132 and me) want to continue using this implementation in our library Manifold
The text was updated successfully, but these errors were encountered: