14#include <TGeoTessellated.h>
24double ClampDistanceToStep(
const double dist,
const double step,
const double infinityCm) {
25 const double boundedStep = std::max(0.0, std::min(step, TGeoShape::Big()));
26 if (std::isinf(dist) || dist >= 0.5 * infinityCm) {
29 return std::min(dist, boundedStep);
37 : TGeoBBox(name, 0.0, 0.0, 0.0)
38 , fBridge(std::make_unique<
g4occt::detail::TGeoOCCTSolidBridge>(shape)) {
45 auto result = std::unique_ptr<TGeoOCCTSolid>(
new TGeoOCCTSolid());
46 result->SetName(name);
48 result->ComputeBBox();
49 return result.release();
55 Double_t origin[3] = {0.0, 0.0, 0.0};
57 SetBoxDimensions(0.0, 0.0, 0.0, origin);
60 const auto bounds = fBridge->Bounds();
61 origin[0] = bounds.origin[0];
62 origin[1] = bounds.origin[1];
63 origin[2] = bounds.origin[2];
64 SetBoxDimensions(bounds.dx, bounds.dy, bounds.dz, origin);
68 Double_t* norm)
const {
75 fBridge->SurfaceNormalCm(point, norm);
82 const auto classification = fBridge->ClassifyCm(point);
87 return TGeoBBox::CouldBeCrossed(point, dir);
91 return TGeoBBox::DistancetoPrimitive(px, py);
95 Double_t step, Double_t* safe)
const {
97 return std::max(0.0, std::min(step, TGeoShape::Big()));
99 const double dist = fBridge->DistFromInsideCm(point, dir, safe);
104 Double_t step, Double_t* safe)
const {
106 return std::max(0.0, std::min(step, TGeoShape::Big()));
108 const double dist = fBridge->DistFromOutsideCm(point, dir, safe);
113 Int_t , Double_t , Double_t ) {
114 Error(
"Divide",
"TGeoOCCTSolid does not support ROOT volume divisions");
121 return TGeoBBox::GetAxisRange(iaxis, xlo, xhi);
125 TGeoBBox::GetBoundingCylinder(param);
129 EnsureDisplayHelper();
130 return fDisplayHelper->GetBuffer3D(reqSections, localFrame);
136 EnsureDisplayHelper();
137 return fDisplayHelper->GetPointsOnSegments(npoints, array);
141 Double_t& dy, Double_t& dz)
const {
142 return TGeoBBox::GetFittingBox(parambox, mat, dx, dy, dz);
146 EnsureDisplayHelper();
147 fDisplayHelper->GetMeshNumbers(nvert, nsegs, npols);
155 runtime->SetRuntime();
165 Info(
"InspectShape",
"Uninitialized TGeoOCCTSolid");
168 const auto bounds = fBridge->Bounds();
169 EnsureDisplayHelper();
173 fDisplayHelper->GetMeshNumbers(nvert, nsegs, npols);
175 "TGeoOCCTSolid '%s' bbox=(dx=%g, dy=%g, dz=%g) cm origin=(%g,%g,%g) cm mesh=(nvert=%d, "
176 "nsegs=%d, npols=%d)",
177 GetName(), bounds.dx, bounds.dy, bounds.dz, bounds.origin[0], bounds.origin[1],
178 bounds.origin[2], nvert, nsegs, npols);
182 EnsureDisplayHelper();
183 return fDisplayHelper->MakeBuffer3D();
187 return fBridge ? fBridge->SafetyCm(point, in == kTRUE) : 0.0;
191 Error(
"SetDimensions",
192 "TGeoOCCTSolid does not support parameterized dimension mutation; use SetOCCTShape");
196 EnsureDisplayHelper();
197 fDisplayHelper->SetPoints(points);
201 EnsureDisplayHelper();
202 fDisplayHelper->SetPoints(points);
206 EnsureDisplayHelper();
207 fDisplayHelper->SetSegsAndPols(buff);
211 EnsureDisplayHelper();
212 fDisplayHelper->Sizeof3D();
217 throw std::runtime_error(
218 "TGeoOCCTSolid::GetOCCTShape called on an uninitialized TGeoOCCTSolid");
220 return fBridge->Shape();
225 fBridge = std::make_unique<g4occt::detail::TGeoOCCTSolidBridge>(shape);
227 fBridge->SetShape(shape);
230 fDisplayHelper.reset();
231 fDisplayGeneration = std::numeric_limits<std::uint64_t>::max();
234void TGeoOCCTSolid::EnsureDisplayHelper()
const {
236 if (!fDisplayHelper) {
237 fDisplayHelper = std::make_unique<TGeoTessellated>(GetName(), 0);
238 fDisplayHelper->CloseShape(
true,
true,
false);
243 const std::uint64_t generation = fBridge->ShapeGeneration();
244 if (fDisplayHelper && fDisplayGeneration == generation) {
248 const auto mesh = fBridge->DisplayMesh();
249 if (mesh->triangles.size() >
static_cast<std::size_t
>(std::numeric_limits<int>::max())) {
250 throw std::runtime_error(
"TGeoOCCTSolid::EnsureDisplayHelper mesh exceeds TGeoTessellated "
251 "facet-count limit");
254 std::make_unique<TGeoTessellated>(GetName(),
static_cast<int>(mesh->triangles.size()));
255 for (
const auto& tri : mesh->triangles) {
256 helper->AddFacet(TGeoTessellated::Vertex_t(tri.p1[0], tri.p1[1], tri.p1[2]),
257 TGeoTessellated::Vertex_t(tri.p2[0], tri.p2[1], tri.p2[2]),
258 TGeoTessellated::Vertex_t(tri.p3[0], tri.p3[1], tri.p3[2]));
260 helper->CloseShape(
true,
true,
false);
261 fDisplayHelper = std::move(helper);
262 fDisplayGeneration = generation;
ROOT-independent bridge from TGeoOCCTSolid to the shared OCCT kernel.
ROOT/TGeo shape adapter over the shared G4OCCT solid-query kernel.
ROOT/TGeo adapter backed by the shared G4OCCT solid-query kernel.
Double_t Safety(const Double_t *point, Bool_t in=kTRUE) const override
void ComputeNormal(const Double_t *point, const Double_t *dir, Double_t *norm) const override
void SetDimensions(Double_t *param) override
Int_t GetFittingBox(const TGeoBBox *parambox, TGeoMatrix *mat, Double_t &dx, Double_t &dy, Double_t &dz) const override
TGeoShape * GetMakeRuntimeShape(TGeoShape *mother, TGeoMatrix *mat) const override
void SetSegsAndPols(TBuffer3D &buff) const override
Bool_t CouldBeCrossed(const Double_t *point, const Double_t *dir) const override
const TopoDS_Shape & GetOCCTShape() const
Int_t DistancetoPrimitive(Int_t px, Int_t py) override
~TGeoOCCTSolid() override
Bool_t IsValidBox() const override
Int_t GetByteCount() const override
TGeoVolume * Divide(TGeoVolume *voldiv, const char *divname, Int_t iaxis, Int_t ndiv, Double_t start, Double_t step) override
const TBuffer3D & GetBuffer3D(Int_t reqSections, Bool_t localFrame) const override
Bool_t GetPointsOnSegments(Int_t npoints, Double_t *array) const override
void SetOCCTShape(const TopoDS_Shape &shape)
Double_t Capacity() const override
void ComputeBBox() override
TBuffer3D * MakeBuffer3D() const override
void InspectShape() const override
Double_t GetAxisRange(Int_t iaxis, Double_t &xlo, Double_t &xhi) const override
Bool_t IsCylType() const override
Bool_t Contains(const Double_t *point) const override
Double_t DistFromInside(const Double_t *point, const Double_t *dir, Int_t iact=1, Double_t step=TGeoShape::Big(), Double_t *safe=nullptr) const override
void SetPoints(Double_t *points) const override
static TGeoOCCTSolid * FromSTEP(const char *name, const std::string &path)
void GetBoundingCylinder(Double_t *param) const override
const char * GetAxisName(Int_t iaxis) const override
void Sizeof3D() const override
void GetMeshNumbers(Int_t &nvert, Int_t &nsegs, Int_t &npols) const override
Double_t DistFromOutside(const Double_t *point, const Double_t *dir, Int_t iact=1, Double_t step=TGeoShape::Big(), Double_t *safe=nullptr) const override
static std::unique_ptr< TGeoOCCTSolidBridge > FromSTEP(const std::string &name, const std::string &path)
static double InfinityCm()