g4system
Loading...
Searching...
No Matches
buildSolid.cc
Go to the documentation of this file.
1
6
7// gemc
8#include "gutilities.h"
9
10// g4system
11#include "cadSystemFactory.h"
12
13// ───────────────── CADMesh single-header library ────────────────
14// https://github.com/christopherpoole/CADMesh
15//
16// *Modifications applied to the vendor header:*
17// - Marked the following classes `final`
18// • BuiltInReader
19// • TessellatedMesh
20// - Reason: https://devblogs.microsoft.com/oldnewthing/20200619-00/?p=103877
21//
22// *Optional Dependencies*
23// Define `USE_CADMESH_ASSIMP_READER` **before** including `CADMesh.hh`
24// to enable Assimp-based file loading.
25//
26// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
27// !!! SET THIS BEFORE INCLUDING CADMESH.HH TO USE THE ASSIMP READER
28// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
29#define USE_CADMESH_ASSIMP_READER
30// If you want Assimp to be the default reader, uncomment:
31// #define CADMESH_DEFAULT_READER ASSIMP
32
33#include "CADMesh.hh"
34
35// Geant4 units
36#include "CLHEP/Units/SystemOfUnits.h"
37
39 std::unordered_map<std::string,
40 G4Volume*>* g4s) {
41 std::string g4name = s->getG4Name();
42
43 // Dependency check: solids can require other solids (copy/boolean operations).
44 if (!checkSolidDependencies(s, g4s)) return nullptr;
45
46 // Locate or allocate the wrapper used to cache solid/logical/physical pointers.
47 auto thisG4Volume = getOrCreateG4Volume(g4name, g4s);
48 if (thisG4Volume->getSolid() != nullptr) return thisG4Volume->getSolid();
49
50 // If this is a copy of another volume, reuse the source mesh solid instead of loading a mesh:
51 // the copy carries no mesh file of its own (e.g. the LTCC frame plates placed in every sector).
52 std::string copyOf = s->getCopyOf();
53 if (copyOf != "" && copyOf != UNINITIALIZEDSTRINGQUANTITY) {
54 auto sourceName = s->getSystem() + "/" + copyOf;
55 auto sourceG4Volume = getOrCreateG4Volume(sourceName, g4s);
56 if (sourceG4Volume->getSolid() != nullptr) return sourceG4Volume->getSolid();
57 }
58
59 // CAD file handling:
60 // - file path is stored in the volume "description" field
61 // - extension determines which CADMesh reader path is used
62 std::string fileName = s->getDescription(); // full file path from DB
63 G4String g4filename = fileName;
64
65 // File extension (last token after '.').
66 std::string extension =
68
69 // PLY / STL via CADMesh & Assimp reader.
70 if (extension == "ply" || extension == "stl") {
71 auto mesh = CADMesh::TessellatedMesh::From(g4filename,
72 CADMesh::File::ASSIMP());
73
74 // Optional uniform scale factor, authored per volume in the "scale" YAML attribute and
75 // carried through the geometry "parameters" column (CAD solids have no other use for it).
76 // It multiplies the millimetre interpretation, e.g. scale=10 reads a mesh drawn in cm.
77 double scale = 1.0;
78 const std::string pars = s->getParameters();
79 if (!pars.empty() && pars != "NULL") {
80 try { scale = std::stod(pars); }
81 catch (const std::exception&) {
82 log->warning("G4CadSystemFactory: volume <", g4name,
83 "> has a non-numeric scale <", pars, ">; using 1.0");
84 }
85 }
86
87 // The CAD file is interpreted in millimetres (times the per-volume scale) to match
88 // typical detector CAD conventions.
89 mesh->SetScale(CLHEP::mm * scale);
90
91 // Do not flip vertex winding unless the CAD source requires it.
92 mesh->SetReverse(false);
93
94 thisG4Volume->setSolid(mesh->GetSolid(), log);
95 return thisG4Volume->getSolid();
96 }
97
98 // Unsupported extension: return nullptr so the caller can decide whether to treat it as fatal.
99 log->warning("G4CadSystemFactory: file <", fileName,
100 "> has unsupported extension <", extension, ">");
101 return nullptr;
102}
Factory that converts CAD files (PLY / STL) into Geant4 tessellated solids via CADMesh.
G4VSolid * buildSolid(const GVolume *s, std::unordered_map< std::string, G4Volume * > *g4s) override
Create (or fetch) a tessellated solid from a CAD file.
Definition buildSolid.cc:38
G4Volume * getOrCreateG4Volume(const std::string &volume_name, std::unordered_map< std::string, G4Volume * > *g4s)
Get or create a G4Volume wrapper entry in the map.
bool checkSolidDependencies(const GVolume *s, std::unordered_map< std::string, G4Volume * > *g4s)
Check whether all prerequisites to build a solid are satisfied.
Convenience container holding a Geant4 solid, logical, and physical volume.
Definition g4volume.h:52
std::shared_ptr< GLogger > log
std::string getDescription() const
std::string getCopyOf() const
std::string getParameters() const
std::string getG4Name() const
std::string getSystem() const
#define UNINITIALIZEDSTRINGQUANTITY
vector< string > getStringVectorFromStringWithDelimiter(const string &input, const string &x)