G4OCCT 0.1.0
Geant4 interface to Open CASCADE Technology (OCCT) geometry definitions
Loading...
Searching...
No Matches
G4OCCT_STEPSolid_impl.cc
Go to the documentation of this file.
1// SPDX-License-Identifier: LGPL-2.1-or-later
2// Copyright (C) 2026 G4OCCT Contributors
3
10
12
13#include "G4OCCT/G4OCCTSolid.hh"
14
15#include <BRepMesh_IncrementalMesh.hxx>
16#include <BRep_Tool.hxx>
17#include <Poly_Triangulation.hxx>
18#include <TopAbs_Orientation.hxx>
19#include <TopExp_Explorer.hxx>
20#include <TopoDS.hxx>
21#include <TopoDS_Face.hxx>
22
23#include <stdexcept>
24#include <string>
25
26G4OCCT_STEPSolidGeometry G4OCCT_ImportSTEPSolid(const std::string& name, const std::string& path) {
27 G4OCCTSolid* solid = nullptr;
28 try {
29 solid = G4OCCTSolid::FromSTEP(name, path);
30 } catch (const std::exception& ex) {
31 throw std::runtime_error("G4OCCT_STEPSolid: failed to import '" + path + "' (" + ex.what() +
32 ")");
33 }
34
35 // Copy the shape out before deleting the solid so we don't hold a reference
36 // into a deleted object. G4OCCTSolid::FromSTEP() returns a heap-allocated
37 // object owned by the caller; the Geant4 solid store keeps a separate entry.
38 const TopoDS_Shape shape = solid->GetOCCTShape();
39 delete solid;
40 solid = nullptr;
41
42 // Tessellate with 1 % relative deflection, matching G4OCCTSolid::CreatePolyhedron().
43 static constexpr double kRelativeDeflection = 0.01;
44 BRepMesh_IncrementalMesh mesher(shape, kRelativeDeflection,
45 /*isRelative=*/Standard_True);
46 (void)mesher;
47
49
50 for (TopExp_Explorer explorer(shape, TopAbs_FACE); explorer.More(); explorer.Next()) {
51 const TopoDS_Face& face = TopoDS::Face(explorer.Current());
52 TopLoc_Location location;
53 const Handle(Poly_Triangulation) & tri = BRep_Tool::Triangulation(face, location);
54 if (tri.IsNull() || tri->NbTriangles() == 0) {
55 continue;
56 }
57
58 const gp_Trsf& transform = location.Transformation();
59 const bool reverseWinding = (face.Orientation() == TopAbs_REVERSED);
60
61 for (Standard_Integer i = 1; i <= tri->NbTriangles(); ++i) {
62 Standard_Integer n1, n2, n3;
63 tri->Triangle(i).Get(n1, n2, n3);
64 if (reverseWinding) {
65 std::swap(n2, n3);
66 }
67
68 const gp_Pnt p1 = tri->Node(n1).Transformed(transform);
69 const gp_Pnt p2 = tri->Node(n2).Transformed(transform);
70 const gp_Pnt p3 = tri->Node(n3).Transformed(transform);
71
72 G4OCCT_Triangle facet;
73 facet.v[0] = {p1.X(), p1.Y(), p1.Z()};
74 facet.v[1] = {p2.X(), p2.Y(), p2.Z()};
75 facet.v[2] = {p3.X(), p3.Y(), p3.Z()};
76 result.triangles.push_back(facet);
77 }
78 }
79
80 if (result.triangles.empty()) {
81 throw std::runtime_error("G4OCCT_STEPSolid: tessellation of '" + path +
82 "' produced no triangles");
83 }
84 return result;
85}
Declaration of G4OCCTSolid.
G4OCCT_STEPSolidGeometry G4OCCT_ImportSTEPSolid(const std::string &name, const std::string &path)
Firewall bridge between the DD4hep plugin TU and G4OCCT/OCCT.
Geant4 solid wrapping an Open CASCADE Technology (OCCT) TopoDS_Shape.
const TopoDS_Shape & GetOCCTShape() const
Read access to the underlying OCCT shape.
static G4OCCTSolid * FromSTEP(const G4String &name, const std::string &path)
std::vector< G4OCCT_Triangle > triangles
Tessellated mesh triangles (mm).
A single triangular facet: three vertices.