I've finished work on QuickHull3D! I solved the memory errors and added a flag to my convexHullCmd
command. Details below.
Iteration Flag
I've added a flag to the convex hull command so that I can limit the number of iterations that QuickHull would run. So for example, convexHullCmd -i 10
or convexHullCmd -iterations 10
would limit the algorithm to 10 iterations. I thought that this would be useful for debugging, but since the issues I faced were memory violations, I never got to use it.
Originally, the command would crash Maya. The fix was to update the registerCommand
function and check for typos. getFlagArgument
is very different from flagArgumentInt
.
QuickHull3D / Half Edge Structure
I had been using shared pointers for ownership of my half-edges (the next
variable owns the next half-edge). However, whenever I accessed them, I returned raw pointers and created new shared pointers when I wanted to transfer ownership. Little did I know that you can't transfer ownership like that. This may or may not have been the cause of my memory problems, but I resolved to replace all half-edge access with some sort of smart pointer just in case.
I kept the next
variables as shared pointers and replaced the prev
and opposite
variables with weak pointers. It turns out that using weak pointers might have saved me a lot of headache, since it was easier to tell if a half-edge went missing.
There were a couple minor problems with the algorithm, but the biggest issue that I had was that weak opposite edge references would empty despite the corresponding shared pointer still existing. I ended up writing code to trace through the algorithm to give me some insight. Part of the struggle with tracing was receiving output via stdout or stderr. Maya redirects those streams to its Output Window, which of course is frozen when you're debugging. I ended up saving the trace to a log file.
With the log file, I was able to pinpoint where the opposite pointer reset, although it took a very long time, partly because Maya was slow to launch and partly because I was looking in all the wrong places. It turned out that my issue was in the destructor of Face, which somehow reset a variable that I didn't mean to. I thought that I had fixed this issue before. Yet if I had really looked at the code, I would've seen that I had two snippets of anti-circular-reference code that were at odds with each other.
In the future, I should rely on the debugger more. I thought that only a trace would reveal the info I needed, but looking back, I could have solved this in the debugger. Hindsight is of course 20/20, but it took so long to set up a trace log that I think it wasn't quite worth it.
Results
The code works now! Here is the dog:
Here is the rat:
For reference, you can see the original models here.
Next Steps
Now I need to implement the shape decomposition paper! I added this convex hull algorithm to get a rough "concavity" measure for each of the points. Then, you could essentially find the ridges of local maximum concavity to separate the model into parts. Hopefully I'll be done in time for the beta review of the project on 11/21.