The nature of floating point arithmetic makes these kinds of problems extremely difficult. It’s not so surprising that there are cases that have some odd or unexpected results. With testing and example cases some of the scenarios can be addressed but it must be recognized that achieving perfect results is not going to be attainable. Something like using integers for these kinds of operations (ie scaling to large values and dropping the decimal) can help make the math more stable but there’d be a performance hit and a rewrite and complexity would increase.
I’m familiar with the integer conversion idea. I understand the rewrite and effort, but why the performance hit? Integer math is faster than floating math.
To your questions:
> (1) Why does the result of the subtraction (A2, B2) have degenerate triangles. Is that OK?
Depending on how degenerate they are (literally a triangle with exactly the same 3 vertices?) then they can of course be removed. They should not cause issues, though.
These triangle have at least one side whose length is less than 0.00000001 units. I have defined that as my “zero”, based on the “typical” dimensions of the models I encounter. Based on this condition, the triangles have degenerated to either a line or a point. BTW, what value is your code using as “zero”?
> (2) Why does the volume of the result of a subtraction (A2, B2) exceed that of the parent sometimes?
Again - floating point precision can make these kinds of things difficult. The code for computing mesh volume is in this file and adapted from this stackoverflow answer. Feel free to recommend or contribute improvements if you see them.
OK, I will take a look.
> (3) Why does the bounding box of the A2,B2 model sometimes exceed that of the A1,B1 model?
There’s no guarantees about combing bounding box sizes when merging or computing sibling objects. Consider the bounding box of two merged small but far part spheres. It also looks like three.js’ compute bounding box function does not account for “drawRange” which means some vertices not being rendered could be being included in the BB generation.
I checked the “drawRange” and found that was not an issue. I understand your small sphere merging example, but that seems quite different from my case. And my bounding box changes are quite drastic, when they happen - and usually not on all three dimensions. Usually just in one dimension. Perhaps that is a clue?
> (4) In one experiment, the number of triangles in the resulting mesh increased quite drastically (order of magnitude). Is that OK?
Without seeing a reproduction of the case or how the numbers in your chart are computed it’s hard to say whether or not the increase is reasonable.
If you can provide minimal repro cases of some of these issues - ideally with simple generated geometry if possible - then I’m happy to add them to the list for myself or someone else to look at when availability affords and maybe some improvements can be made the project.
> (I can’t guarantee that my very messy code is bug-free, but I have looked it over quite carefully :)
I will ask that code be cleaned up and simplified so I can more easily follow what’s going on, though, to save time and effort.
I’ve been wondering how to share my data/examples with others. My code is one large monolithic piece that does many other things besides Booleans…very prototype in nature. Since the operations to be reproduced are relatively simple to code (just a Boolean subtract), would it be sufficient to share the models in these experiments? I can share the two objects/meshes for each experiment (located in their final locations in space - no repositioning needed) via “.3mf” model files. THREE has a reader for this file format. Do let me know.
And finally, thank you for your detailed reply