14#ifndef ALICEO2_CADSUPPORT_O2BVHSURFACESOLID_
15#define ALICEO2_CADSUPPORT_O2BVHSURFACESOLID_
68 std::vector<BVHSurfaceCurveRecord>
curves;
93 const std::vector<Point2D>& outerWire,
94 const std::vector<std::vector<Point2D>>& innerWires = {});
132 std::vector<double> splineWeights, std::vector<double> splineKnots)
136 curve.
degree = splineDegree;
137 curve.
poles = std::move(splinePoles);
138 curve.
weights = std::move(splineWeights);
139 curve.
knots = std::move(splineKnots);
146 const std::vector<PlanarBoundaryCurve>& outerWire,
147 const std::vector<std::vector<PlanarBoundaryCurve>>& innerWires = {});
151 double radius,
double heightMin,
double heightMax,
double phiStart = 0.,
152 double phiSweep = 6.283185307179586,
bool innerWall =
false);
156 double radius,
double heightMin,
double heightMax,
double phiStart,
double phiSweep,
157 bool innerWall,
const std::vector<PlanarBoundaryCurve>& outerTrim,
158 const std::vector<std::vector<PlanarBoundaryCurve>>& innerTrims = {});
162 double radius,
double thetaMin = 0.,
double thetaMax = 3.141592653589793,
163 double phiStart = 0.,
double phiSweep = 6.283185307179586,
bool innerWall =
false);
167 double radius,
double thetaMin,
double thetaMax,
double phiStart,
double phiSweep,
168 bool innerWall,
const std::vector<PlanarBoundaryCurve>& outerTrim,
169 const std::vector<std::vector<PlanarBoundaryCurve>>& innerTrims = {});
173 double radiusAtMin,
double radiusAtMax,
double heightMin,
double heightMax,
174 double phiStart = 0.,
double phiSweep = 6.283185307179586,
bool innerWall =
false);
178 double radiusAtMin,
double radiusAtMax,
double heightMin,
double heightMax,
double phiStart,
179 double phiSweep,
bool innerWall,
const std::vector<PlanarBoundaryCurve>& outerTrim,
180 const std::vector<std::vector<PlanarBoundaryCurve>>& innerTrims = {});
184 double majorRadius,
double minorRadius,
double phiStart = 0.,
185 double phiSweep = 6.283185307179586,
double tubeStart = 0.,
186 double tubeSweep = 6.283185307179586,
bool innerWall =
false);
190 double majorRadius,
double minorRadius,
double phiStart,
double phiSweep,
double tubeStart,
191 double tubeSweep,
bool innerWall,
const std::vector<PlanarBoundaryCurve>& outerTrim,
192 const std::vector<std::vector<PlanarBoundaryCurve>>& innerTrims = {});
204 const std::vector<unsigned char>& edgeFlags);
252 std::vector<ContainsCrossing>& loopCrossings)
const;
256 std::vector<ContainsCrossing>& bvhCrossings,
257 std::vector<ContainsCrossing>& loopCrossings)
const;
359 const TBuffer3D&
GetBuffer3D(
int reqSections, Bool_t localFrame)
const override;
360 void GetMeshNumbers(
int& nvert,
int& nsegs,
int& npols)
const override;
372 void Print(Option_t* option =
"")
const override;
374 void SetPoints(
double* points)
const override;
379 Double_t
DistFromOutside(
const Double_t* point,
const Double_t* dir, Int_t iact = 1,
380 Double_t step = TGeoShape::Big(), Double_t* safe =
nullptr)
const override;
381 Double_t
DistFromInside(
const Double_t* point,
const Double_t* dir, Int_t iact = 1,
382 Double_t step = TGeoShape::Big(), Double_t* safe =
nullptr)
const override;
383 bool Contains(
const Double_t* point)
const override;
391 Double_t stepmax = TGeoShape::Big())
const;
393 Double_t stepmax = TGeoShape::Big())
const;
394 Double_t
Safety(
const Double_t* point, Bool_t in = kTRUE)
const override;
395 void ComputeNormal(
const Double_t* point,
const Double_t* dir, Double_t* norm)
const override;
397 Double_t
Safety_Loop(
const Double_t* point, Bool_t in = kTRUE)
const;
398 void ComputeNormal_Loop(
const Double_t* point,
const Double_t* dir, Double_t* norm)
const;
406 bool containsByParity(
const Double_t* point,
bool useBVH)
const;
409 void computeNormalFrom(
const Double_t* point,
const Double_t* dir, Double_t* norm,
bool useLoop)
const;
412 bool RebuildFromRecords();
415 bool ProjectOntoPatch(
int surfaceIndex,
double* point)
const;
418 Impl* fImpl =
nullptr;
421 std::vector<BVHSurfaceRecord> fRecords;
424 double fModelTolerance = 0.;
header::DataOrigin origin
O2BVHSurfaceSolid & operator=(const O2BVHSurfaceSolid &)=delete
Double_t DistFromOutside_Loop(const Double_t *point, const Double_t *dir, Double_t stepmax=TGeoShape::Big()) const
Non-BVH DistFrom* over all surfaces: the oracles the BVH paths must match exactly.
@ Reliable
closed, consistently oriented 2-manifold: parity is well defined
@ Undetermined
CloseShape() has not run yet: no diagnostics exist.
bool AddCylindricalSurface(const Point3D ¢erPoint, const Point3D &axis, const Point3D &referenceAxisU, double radius, double heightMin, double heightMax, double phiStart=0., double phiSweep=6.283185307179586, bool innerWall=false)
Add a cylindrical wall of radius around axis over a height range and a phi sweep; innerWall points th...
double GetRimMatchTolerance() const
The declared rim match tolerance in cm, the model's own or a fallback: the floor of each chord's matc...
void Print(Option_t *option="") const override
static void ResetSafetyCandidateCounter()
Per-thread count of surfaces handed to distanceSqToPatch by Safety and ComputeNormal since the last r...
TBuffer3D * MakeBuffer3D() const override
static bool GetSafetyBoundUnsoundForTest()
int GetReversedSourceEdgeCount() const
bool ContainsAlongDirection(const Double_t *point, const Double_t *direction) const
Diagnostic: the parity answer for one explicit direction, bypassing Contains()'s re-shoot policy.
void GetMeshNumbers(int &nvert, int &nsegs, int &npols) const override
void InspectShape() const override
bool Contains_Loop(const Double_t *point) const
int GetNonManifoldEdgeCount() const
Double_t DistFromInside_Loop(const Double_t *point, const Double_t *dir, Double_t stepmax=TGeoShape::Big()) const
double GetUnmatchedRimLength() const
int GetRimCount() const
Rim counts: total, and split by the same four states as the edge counters above.
const TBuffer3D & GetBuffer3D(int reqSections, Bool_t localFrame) const override
bool HasEdgeIdentity() const
void SavePrimitive(std::ostream &, Option_t *) 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
int GetReversedEdgeCount() const
int GetNonManifoldRimCount() const
static void SetSafetyBoundUnsoundForTest(bool enable)
Test-only sabotage: prune on the distance to the box centre, which bounds nothing,...
void CloseShape(bool check=true)
Finalize the shape: bounding box, display mesh, BVH and closure diagnostics, reported when check is s...
void ComputeNormal_Loop(const Double_t *point, const Double_t *dir, Double_t *norm) const
static bool GetRayTMaxPruning()
double GetModelTolerance() const
int CountBVHRayCandidates(const Point3D &point, const Point3D &direction) const
Test hook: distinct surfaces whose cover boxes the ray traverses; -1 without a BVH.
static long long GetSafetyCandidateCount()
double GetRimChordResolution() const
double GetMaxRimIsolation() const
int GetMatchedRimCount() const
void SetPoints(double *points) const override
int GetDegenerateSourceEdgeCount() const
Double_t Safety_Loop(const Double_t *point, Bool_t in=kTRUE) const
Non-BVH Safety/ComputeNormal over all surfaces: the oracles the BVH traversal must match bit for bit.
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 ComputeNormal(const Double_t *point, const Double_t *dir, Double_t *norm) const override
int GetBoundarySourceEdgeCount() const
Bool_t GetPointsOnSegments(Int_t npoints, Double_t *array) const override
Fill array with npoints points on the solid's exact boundary; kFALSE below GetNmeshVertices() so ROOT...
bool Contains(const Double_t *point) const override
void SetSegsAndPols(TBuffer3D &buff) const override
void GetSurfaceCapacityContributions(std::vector< double > &contributions) const
Each face's divergence-theorem contribution to Capacity(), in record order.
Double_t Capacity() const override
O2BVHSurfaceSolid(const O2BVHSurfaceSolid &)=delete
std::array< double, 3 > Point3D
int GetNonManifoldSourceEdgeCount() const
bool GetBVHRootBounds(Point3D &lower, Point3D &upper) const
Fill the BVH root-node bounding box; returns false when no BVH has been built.
int DistancetoPrimitive(int, int) override
NavigationReliability GetNavigationReliability() const
The reliability state derived from the last CloseShape(); Undetermined before it has run.
std::array< double, 2 > Point2D
int GetMeasuredSharedEdgeCount() const
static void SetRayTMaxPruning(bool enable)
Ray tmax tightening in the distance queries, on by default; it never changes an answer....
int GetBoundaryRimCount() const
int GetSourceEdgeCount() const
Distinct source edges and their incidence: shared, boundary, non-manifold, reversed and degenerate.
bool IsOrientationConsistent() const
bool AddCurvedPlanarSurface(const Point3D &origin, const Point3D &axisU, const Point3D &axisV, const std::vector< PlanarBoundaryCurve > &outerWire, const std::vector< std::vector< PlanarBoundaryCurve > > &innerWires={})
Add an exact planar surface bounded by line/arc wires; axisU and axisV are orthonormal and axisU x ax...
static long long GetRayCandidateCount()
int GetSharedSourceEdgeCount() const
Double_t Safety(const Double_t *point, Bool_t in=kTRUE) const override
The distance to the nearest patch, rounded down by one ulp so that Safety is never too large.
int GetNmeshVertices() const override
double GetMaxSharedEdgeDeviation() const
Largest Hausdorff distance between the two faces' realisations of one shared edge,...
static const char * GetNavigationReliabilityName(NavigationReliability reliability)
const std::vector< RimReport > & GetRimReports() const
bool AddConicalSurface(const Point3D ¢erPoint, const Point3D &axis, const Point3D &referenceAxisU, double radiusAtMin, double radiusAtMax, double heightMin, double heightMax, double phiStart=0., double phiSweep=6.283185307179586, bool innerWall=false)
Add a conical wall whose radius runs linearly from radiusAtMin to radiusAtMax; one radius may be zero...
static constexpr double kSurfacePointTolerance
void SetModelTolerance(double toleranceCm)
~O2BVHSurfaceSolid() override
int GetReversedRimCount() const
bool SetSurfaceBoundaryEdges(int surfaceIndex, const std::vector< unsigned int > &edgeIds, const std::vector< unsigned char > &edgeFlags)
Attach surface surfaceIndex's edge identities in trim-curve order; false on a bad index or mismatched...
const std::vector< BVHSurfaceRecord > & GetSurfaceRecords() const
The Add*Surface calls this solid was built from, in order.
bool AddSphericalSurface(const Point3D ¢er, const Point3D &polarAxis, const Point3D &referenceAxisU, double radius, double thetaMin=0., double thetaMax=3.141592653589793, double phiStart=0., double phiSweep=6.283185307179586, bool innerWall=false)
Add a spherical surface of radius trimmed to a theta range and a phi sweep; the defaults give a full ...
bool AddToroidalSurface(const Point3D ¢erPoint, const Point3D &axis, const Point3D &referenceAxisU, double majorRadius, double minorRadius, double phiStart=0., double phiSweep=6.283185307179586, double tubeStart=0., double tubeSweep=6.283185307179586, bool innerWall=false)
Add a toroidal surface trimmed to a phiRing x phiTube rectangle; the defaults give a full torus,...
void Sizeof3D() const override
double GetTotalRimLength() const
Summed trim-boundary length, and the part with no other face within the match band,...
void DescribeContainsCrossings(const Point3D &point, std::vector< ContainsCrossing > &bvhCrossings, std::vector< ContainsCrossing > &loopCrossings) const
Diagnostic: the parity ray's crossings at point from the BVH and from the loop, sorted by distance.
bool AddPlanarSurface(const Point3D &origin, const Point3D &axisU, const Point3D &axisV, const std::vector< Point2D > &outerWire, const std::vector< std::vector< Point2D > > &innerWires={})
static void ResetRayCandidateCounter()
Per-thread count of surfaces handed to the BVH leaf callback by DistFrom* since the last reset.
@ kEdgeAnchored
entry i is trim curve i of this face, so it can be measured
@ kEdgeReversed
the face runs against the edge's own direction
@ kEdgeDegenerate
cone apex / sphere pole: a point, so it has no second face
bool HasBVH() const
Whether the BVH acceleration structure has been built (after CloseShape).
int GetUnmeasuredSharedEdgeCount() const
void ComputeBBox() override
int GetBoundaryEdgeCount() const
Per-chord closure counts: diagnostics only; GetNavigationReliability() reads the rim counts below.
GLuint const GLchar * name
GLsizei GLsizei GLfloat distance
GLuint GLsizei GLsizei * length
void check(const std::vector< std::string > &arguments, const std::vector< ConfigParamSpec > &workflowOptions, const std::vector< DeviceSpec > &deviceSpecs, CheckMatrix &matrix)
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
One boundary curve of a BVHSurfaceRecord in the flat form ROOT streams: a segment,...
std::vector< double > poles
B-spline control points, flattened (u, v) pairs.
std::vector< double > knots
B-spline clamped flat knot vector.
int degree
B-spline degree.
std::vector< double > weights
B-spline weights (empty => non-rational)
int kind
PlanarBoundaryCurve::Kind: 0 = Line, 1 = Arc, 2 = BSpline.
The persistent record of one successful Add*Surface call; reading a solid back replays the records.
std::vector< int > wireSizes
std::vector< BVHSurfaceCurveRecord > curves
std::vector< double > scalars
std::vector< double > polygonPoints
The wires, outer first: PlanarPolygon stores (u, v) pairs in polygonPoints, the others curves; wireSi...
bool trimmed
the wire-trim overload was used (quadrics only)
double axisA[3]
axisU / axis / polarAxis
double axisB[3]
axisV / referenceAxisU
std::vector< unsigned char > boundaryEdgeFlags
static int expectedScalarCount(int recordKind)
How many entries scalars must hold for kind, or -1 for an unknown kind.
std::vector< unsigned int > boundaryEdgeIds
Sidecar v3 boundary edge identities in curve order: an edge-table index and a BoundaryEdgeFlag byte; ...
double origin[3]
origin / centerPoint / center
One crossing of the containment parity ray, as seen by Contains().
bool onTrimBoundary
The hit lay in its patch's on-boundary band, so a tie-break kept it; Contains() re-shoots on these.
One boundary curve in the surface's local (u, v) frame: a line segment, a circular arc or a clamped (...
std::vector< double > weights
B-spline weights (empty ⇒ non-rational)
static PlanarBoundaryCurve makeLine(const Point2D &start, const Point2D &end)
static PlanarBoundaryCurve makeBSpline(int splineDegree, std::vector< Point2D > splinePoles, std::vector< double > splineWeights, std::vector< double > splineKnots)
std::vector< double > knots
B-spline clamped flat knot vector.
std::vector< Point2D > poles
B-spline control points.
static PlanarBoundaryCurve makeArc(const Point2D &c, double r, double start, double end)
int degree
B-spline degree.
One trim loop of one face as the closure measurement saw it, naming the rim and its worst chord.
std::array< double, 3 > maxIsolationPoint
double maxIsolation
Largest distance from a chord midpoint of this rim to another face's chord, where,...
NavigationReliability state
int unmatchedChords
of them, how many found no other face within the tolerance
int surface
index into GetSurfaceRecords() of the face owning this rim
int rimOnSurface
which trim loop of that face, in the order the face emits them
bool closed
the rim polyline returns to its own first point