| Summary: | Boolean solids are not handled properly in visualization | ||
|---|---|---|---|
| Product: | Geant4 | Reporter: | Leo Piilonen <piilonen> |
| Component: | visualization/VRML | Assignee: | Satoshi Tanaka <stanaka> |
| Status: | RESOLVED INVALID | ||
| Severity: | minor | CC: | John.Allison, laurent.garnier |
| Priority: | P4 | ||
| Version: | 10.3 | ||
| Hardware: | All | ||
| OS: | All | ||
The recursive building of a polyhedron for a Boolean solid is performed, correctly, in G4BooleanSolid::StackPolyhedron. So that's not the problem. I think your problem is to do with a long-standing issue we have in Geant4 whereby the Boolean Processor (BooleanProcessor.cc in the graphics_reps category) cannot handle the complicated problem of creating polygons when surfaces of the components of the solid coincide, or nearly coincide, Your workaround is to shift one of the components by a small amount, or make it slightly larger or smaller, so that surfaces do not coincide. If subtracting, the subtractor can be larger without affecting the resulting solid shape. This problem is purely one of visualisation. Tracking is not affected. You may use Ray Tracer, a visualisation driver that uses tracking instead of polygons, to verify this. |
After issuing the following GEANT4 commands to VRML-visualize a certain detector geometry, GEANT4 issues several error messages and then freezes. /vis/open VRML2FILE /vis/drawVolume /vis/viewer/update /vis/viewer/flush GEANT4 output: =========================================== Output VRML 2.0 file: g4_00.wrl Maximum number of files in the destination directory: 100 (Customizable with the environment variable: G4VRMLFILE_MAX_FILE_NUM) =========================================== G4VSceneHandler::RequestPrimitives Polyhedron not available for outerBox. This means it cannot be visualized on most systems. Contact the Visualization Coordinator. (this is repeated 8 times) ERROR: G4VSceneHandler::RequestPrimitives Polyhedron not available for endmountBox. This means it cannot be visualized on most systems. Contact the Visualization Coordinator. (after this, GEANT4 freezes) It appears that this is triggered by the attempted creation of a HepPolyhedron for a boolean solid - G4VSolid::GetPolyhedron() - in which the second solid is itself a boolean solid. The following [recursive] code properly creates the HepPolyhedron from any G4VSolid (named "solid"), but doesn't - can't - store it in the G4VSolid's internal state: HepPolyhedron* polyhedron = NULL; if ((solid->GetEntityType() == "G4IntersectionSolid") || (solid->GetEntityType() == "G4UnionSolid") || (solid->GetEntityType() == "G4SubtractionSolid") || (solid->GetEntityType() == "G4BooleanSolid")) { polyhedron = getBooleanSolidPolyhedron(solid); } else { polyhedron = solid->GetPolyhedron(); } HepPolyhedron* getBooleanSolidPolyhedron(G4VSolid* solid) { G4VSolid* solidA = solid->GetConstituentSolid(0); G4VSolid* solidB = solid->GetConstituentSolid(1); HepPolyhedron* polyhedronA = NULL; if ((solidA->GetEntityType() == "G4IntersectionSolid") || (solidA->GetEntityType() == "G4UnionSolid") || (solidA->GetEntityType() == "G4SubtractionSolid") || (solidA->GetEntityType() == "G4BooleanSolid")) { polyhedronA = getBooleanSolidPolyhedron(solidA); } else { polyhedronA = new HepPolyhedron(*(solidA->GetPolyhedron())); } HepPolyhedron* polyhedronB = NULL; G4VSolid* solidB2 = solidB; if (solidB->GetEntityType() == "G4DisplacedSolid") { solidB2 = ((G4DisplacedSolid*)solidB)->GetConstituentMovedSolid(); } if ((solidB2->GetEntityType() == "G4IntersectionSolid") || (solidB2->GetEntityType() == "G4UnionSolid") || (solidB2->GetEntityType() == "G4SubtractionSolid") || (solidB2->GetEntityType() == "G4BooleanSolid")) { polyhedronB = getBooleanSolidPolyhedron(solidB2); if (solidB != solidB2) { // was solidB a G4DisplacedSolid? polyhedronB->Transform(G4Transform3D( ((G4DisplacedSolid*)solidB)->GetObjectRotation(), ((G4DisplacedSolid*)solidB)->GetObjectTranslation())); } } else { polyhedronB = new HepPolyhedron(*(solidB->GetPolyhedron())); } HepPolyhedron* result = new HepPolyhedron(); if (solid->GetEntityType() == "G4UnionSolid") { *result = polyhedronA->add(*polyhedronB); } else if (solid->GetEntityType() == "G4SubtractionSolid") { *result = polyhedronA->subtract(*polyhedronB); } else if (solid->GetEntityType() == "G4IntersectionSolid") { *result = polyhedronA->intersect(*polyhedronB); } else { // warning: "getBooleanSolidPolyhedron(): Unrecognized boolean solid " << solid->GetName() << " of type " << solid->GetEntityType() } delete polyhedronA; delete polyhedronB; return result; }