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 : TGeoShape(name), fBridge(std::make_unique<
g4occt::detail::TGeoOCCTSolidBridge>(shape)) {}
42 auto result = std::unique_ptr<TGeoOCCTSolid>(
new TGeoOCCTSolid());
43 result->SetName(name);
45 return result.release();
53 Double_t* norm)
const {
60 fBridge->SurfaceNormalCm(point, norm);
67 const auto classification = fBridge->ClassifyCm(point);
72 auto bbox = BuildBBoxHelper();
73 return bbox.CouldBeCrossed(point, dir);
77 auto bbox = BuildBBoxHelper();
78 return bbox.DistancetoPrimitive(px, py);
82 Double_t step, Double_t* safe)
const {
84 return std::max(0.0, std::min(step, TGeoShape::Big()));
86 const double dist = fBridge->DistFromInsideCm(point, dir, safe);
91 Double_t step, Double_t* safe)
const {
93 return std::max(0.0, std::min(step, TGeoShape::Big()));
95 const double dist = fBridge->DistFromOutsideCm(point, dir, safe);
100 Int_t , Double_t , Double_t ) {
101 Error(
"Divide",
"TGeoOCCTSolid does not support ROOT volume divisions");
106 auto bbox = BuildBBoxHelper();
107 return bbox.GetAxisName(iaxis);
111 auto bbox = BuildBBoxHelper();
112 return bbox.GetAxisRange(iaxis, xlo, xhi);
116 auto bbox = BuildBBoxHelper();
117 bbox.GetBoundingCylinder(param);
121 EnsureDisplayHelper();
122 return fDisplayHelper->GetBuffer3D(reqSections, localFrame);
128 EnsureDisplayHelper();
129 return fDisplayHelper->GetPointsOnSegments(npoints, array);
133 Double_t& dy, Double_t& dz)
const {
134 auto bbox = BuildBBoxHelper();
135 return bbox.GetFittingBox(parambox, mat, dx, dy, dz);
139 EnsureDisplayHelper();
140 fDisplayHelper->GetMeshNumbers(nvert, nsegs, npols);
148 runtime->SetRuntime();
155 auto bbox = BuildBBoxHelper();
156 return bbox.IsValidBox();
161 Info(
"InspectShape",
"Uninitialized TGeoOCCTSolid");
164 const auto bounds = fBridge->Bounds();
165 EnsureDisplayHelper();
169 fDisplayHelper->GetMeshNumbers(nvert, nsegs, npols);
171 "TGeoOCCTSolid '%s' bbox=(dx=%g, dy=%g, dz=%g) cm origin=(%g,%g,%g) cm mesh=(nvert=%d, "
172 "nsegs=%d, npols=%d)",
173 GetName(), bounds.dx, bounds.dy, bounds.dz, bounds.origin[0], bounds.origin[1],
174 bounds.origin[2], nvert, nsegs, npols);
178 EnsureDisplayHelper();
179 return fDisplayHelper->MakeBuffer3D();
183 return fBridge ? fBridge->SafetyCm(point, in == kTRUE) : 0.0;
187 Error(
"SetDimensions",
188 "TGeoOCCTSolid does not support parameterized dimension mutation; use SetOCCTShape");
192 EnsureDisplayHelper();
193 fDisplayHelper->SetPoints(points);
197 EnsureDisplayHelper();
198 fDisplayHelper->SetPoints(points);
202 EnsureDisplayHelper();
203 fDisplayHelper->SetSegsAndPols(buff);
207 EnsureDisplayHelper();
208 fDisplayHelper->Sizeof3D();
213 throw std::runtime_error(
214 "TGeoOCCTSolid::GetOCCTShape called on an uninitialized TGeoOCCTSolid");
216 return fBridge->Shape();
221 fBridge = std::make_unique<g4occt::detail::TGeoOCCTSolidBridge>(shape);
223 fBridge->SetShape(shape);
225 fDisplayHelper.reset();
226 fDisplayGeneration = std::numeric_limits<std::uint64_t>::max();
229TGeoBBox TGeoOCCTSolid::BuildBBoxHelper()
const {
231 Double_t origin[3] = {0.0, 0.0, 0.0};
232 return TGeoBBox(0.0, 0.0, 0.0, origin);
234 const auto bounds = fBridge->Bounds();
235 Double_t origin[3] = {bounds.origin[0], bounds.origin[1], bounds.origin[2]};
236 return TGeoBBox(bounds.dx, bounds.dy, bounds.dz, origin);
239void TGeoOCCTSolid::EnsureDisplayHelper()
const {
241 if (!fDisplayHelper) {
242 fDisplayHelper = std::make_unique<TGeoTessellated>(GetName(), 0);
243 fDisplayHelper->CloseShape(
true,
true,
false);
248 const std::uint64_t generation = fBridge->ShapeGeneration();
249 if (fDisplayHelper && fDisplayGeneration == generation) {
253 const auto mesh = fBridge->DisplayMesh();
254 if (mesh->triangles.size() >
static_cast<std::size_t
>(std::numeric_limits<int>::max())) {
255 throw std::runtime_error(
"TGeoOCCTSolid::EnsureDisplayHelper mesh exceeds TGeoTessellated "
256 "facet-count limit");
259 std::make_unique<TGeoTessellated>(GetName(),
static_cast<int>(mesh->triangles.size()));
260 for (
const auto& tri : mesh->triangles) {
261 helper->AddFacet(TGeoTessellated::Vertex_t(tri.p1[0], tri.p1[1], tri.p1[2]),
262 TGeoTessellated::Vertex_t(tri.p2[0], tri.p2[1], tri.p2[2]),
263 TGeoTessellated::Vertex_t(tri.p3[0], tri.p3[1], tri.p3[2]));
265 helper->CloseShape(
true,
true,
false);
266 fDisplayHelper = std::move(helper);
267 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()