G4OCCT 0.1.0
Geant4 interface to Open CASCADE Technology (OCCT) geometry definitions
Loading...
Searching...
No Matches
G4OCCT_STEPSolid.cc
Go to the documentation of this file.
1// SPDX-License-Identifier: LGPL-2.1-or-later
2// Copyright (C) 2026 G4OCCT Contributors
3
28
29// Two header worlds must not meet in the same TU:
30// DD4hep → ROOT → TString.h declares: extern void Printf(...)
31// G4OCCT → OCCT → Standard_CString.h declares: int Printf(...)
32// Keeping them in separate TUs (firewall pattern) resolves both this Printf
33// conflict and the Handle(Class) macro collision described above.
34// G4OCCT_STEPSolid_impl.{hh,cc} is the OCCT-side TU; this file is the
35// DD4hep-side TU.
36#include <DD4hep/DetFactoryHelper.h>
37#include <DD4hep/Printout.h>
38#include <TGeoTessellated.h>
39
41
42#include <cstddef>
43#include <limits>
44#include <stdexcept>
45#include <string>
46
47using namespace dd4hep;
48
49static Ref_t create_step_solid(Detector& description, xml_h e, SensitiveDetector /*sens*/) {
50 xml_det_t x_det = e;
51 xml_comp_t x_step = x_det.child(_Unicode(step_file));
52 xml_comp_t x_pos = x_det.child(_Unicode(position));
53 xml_comp_t x_rot = x_det.child(_Unicode(rotation));
54 xml_comp_t x_mat = x_det.child(_Unicode(material));
55
56 std::string name = x_det.nameStr();
57 std::string path = x_step.attr<std::string>(_Unicode(path));
58
59 // ── Import STEP solid and tessellate (OCCT side, separate TU) ───────────
61
62 printout(INFO, "G4OCCT_STEPSolid", "Imported '%s' from '%s'; %zu triangles in tessellated solid",
63 name.c_str(), path.c_str(), geom.triangles.size());
64
65 // ── Build a TessellatedSolid for the TGeo/DD4hep representation ──────────
66 // TessellatedSolid wraps ROOT's TGeoTessellated: a polyhedral mesh solid
67 // that can be visualised and used for navigation by TGeo-based tools.
68 // We pass the triangle count as a capacity hint, then add facets one by one.
69 const std::size_t nTriangles = geom.triangles.size();
70 if (nTriangles > static_cast<std::size_t>(std::numeric_limits<int>::max())) {
71 throw std::runtime_error("G4OCCT_STEPSolid: tessellation of '" + path + "' produced " +
72 std::to_string(nTriangles) +
73 " triangles, which exceeds TessellatedSolid's int capacity");
74 }
75 TessellatedSolid tess(name + "_tess", static_cast<int>(nTriangles));
76 for (const auto& tri : geom.triangles) {
77 tess.addFacet(TessellatedSolid::Vertex(tri.v[0].x, tri.v[0].y, tri.v[0].z),
78 TessellatedSolid::Vertex(tri.v[1].x, tri.v[1].y, tri.v[1].z),
79 TessellatedSolid::Vertex(tri.v[2].x, tri.v[2].y, tri.v[2].z));
80 }
81 tess.ptr()->CloseShape(/*check=*/true, /*fixFlipped=*/true, /*verbose=*/false);
82
83 // ── DD4hep volume and placement ──────────────────────────────────────────
84 Material mat = description.material(x_mat.attr<std::string>(_Unicode(name)));
85 Volume vol(name + "_vol", tess, mat);
86 vol.setVisAttributes(description, x_det.visStr());
87
88 DetElement det(name, x_det.id());
89 Position pos(x_pos.x(), x_pos.y(), x_pos.z());
90 RotationZYX rot(x_rot.z(), x_rot.y(), x_rot.x());
91 PlacedVolume pv = description.pickMotherVolume(det).placeVolume(vol, Transform3D(rot, pos));
92 pv.addPhysVolID("system", x_det.id());
93 det.setPlacement(pv);
94 return det;
95}
96
97DECLARE_DETELEMENT(G4OCCT_STEPSolid, create_step_solid)
static Ref_t create_step_solid(Detector &description, xml_h e, SensitiveDetector)
G4OCCT_STEPSolidGeometry G4OCCT_ImportSTEPSolid(const std::string &name, const std::string &path)
Firewall bridge between the DD4hep plugin TU and G4OCCT/OCCT.