Created attachment 650 [details] tarball containing the two GDML files to demonstrate the bug described I have created a multi-union that demonstrates a bug in G4MultiUnion::GetPointOnSurface. A point on the surface of one of the nodes is correctly generated, but it never passes the `Inside(point) != EInside::kSurface` check at the end of the do/while loop. This means that it gets stuck in an infinite loop, most notably during overlap checking. As all generated points on the nodes are never points on the surface of the multi-union, this suggests a bug, as the geometry in question is nothing crazy or pathological. The solution is not to introduce a "try 100k before giving up" as in `G4BooleanSolid::GetPointOnSurface`, I don't think. I believe the bug itself ultimately lies within G4Voxelizer. I posted this originally on the Geant4 forum, where evc (Evgueni Tcherniaev) has confirmed that this is a bug and asked me to post a bug report here: https://geant4-forum.web.cern.ch/t/multiunion-overlap-checking-broken-in-comparison-to-binary-union/4021/6 I have attached a tarball containing the two GDML files that can be used to demonstrate the bug. They are equivalent geometries, one expressed in terms of a multi-union (`r3-multi-union.gdml`), and the other expressed in terms of a conventional binary union (`r3-union.gdml`). To test it out, compile the example in `extended/persistency/gdml/G01`, and do `./load_gdml r3-multi-union.gdml`. It will get stuck during the overlap check and never terminate, occasionally emitting warnings. ``./load_gdml r3-union.gdml` in contrast finishes the overlap check very quickly. There are perhaps some additional details in the forum post linked above. The workaround for now is to change `G4MultiUnion::Inside`, replacing the body of this function simply with `return InsideNoVoxels(aPoint);` (i.e DON'T call `InsideWithExclusion`). Thanks to Evgueni Tcherniaev for this workaround.
The problem was caused by incorrect calculation of bounding box position in G4Voxelizer::BuildVoxelLimits(), namely the following line: fBoxes[i].pos = transl.getTranslation(); Correct expression is: fBoxes[i].pos = (max + min) / 2.;