79 G4OCCTSolid(
const G4String& name,
const TopoDS_Shape& shape);
100 EInside
Inside(
const G4ThreeVector& p)
const override;
103 G4ThreeVector
SurfaceNormal(
const G4ThreeVector& p)
const override;
108 G4double
DistanceToIn(
const G4ThreeVector& p,
const G4ThreeVector& v)
const override;
122 G4double
DistanceToIn(
const G4ThreeVector& p)
const override;
127 G4double
DistanceToOut(
const G4ThreeVector& p,
const G4ThreeVector& v,
128 const G4bool calcNorm =
false, G4bool* validNorm =
nullptr,
129 G4ThreeVector* n =
nullptr)
const override;
133 G4double
DistanceToOut(
const G4ThreeVector& p)
const override;
187 void BoundingLimits(G4ThreeVector& pMin, G4ThreeVector& pMax)
const override;
190 G4bool
CalculateExtent(
const EAxis pAxis,
const G4VoxelLimits& pVoxelLimit,
191 const G4AffineTransform& pTransform, G4double& pMin,
192 G4double& pMax)
const override;
201 std::ostream&
StreamInfo(std::ostream& os)
const override;
216 if (shape.IsNull()) {
217 throw std::invalid_argument(
"G4OCCTSolid::SetOCCTShape: shape must not be null");
222 std::unique_lock<std::mutex> lock(fPolyhedronMutex);
223 fCachedPolyhedron.reset();
226 std::unique_lock<std::mutex> lock(fVolumeAreaMutex);
227 fCachedVolume.reset();
228 fCachedSurfaceArea.reset();
231 std::unique_lock<std::mutex> lock(fSurfaceCacheMutex);
232 fSurfaceCache.reset();
234 fShapeGeneration.fetch_add(1, std::memory_order_release);
243 BRepAdaptor_Surface adaptor;
244 std::optional<gp_Pln> plane;
249 std::vector<gp_Pnt2d> uvPolygon;
253 std::optional<G4ThreeVector> outwardNormal;
257 struct ClosestFaceMatch {
259 G4double distance{kInfinity};
263 std::size_t faceIndex{0};
267 std::optional<std::pair<Standard_Real, Standard_Real>> uv;
271 struct AxisAlignedBounds {
282 struct ClassifierCache {
283 std::uint64_t generation{std::numeric_limits<std::uint64_t>::max()};
284 std::optional<BRepClass3d_SolidClassifier> classifier;
308 struct IntersectorCache {
309 std::uint64_t generation{std::numeric_limits<std::uint64_t>::max()};
310 std::vector<std::unique_ptr<IntCurvesFace_Intersector>> faceIntersectors;
311 std::vector<Bnd_Box> expandedBoxes;
316 struct InscribedSphere {
317 G4ThreeVector centre;
332 struct SphereCacheData {
333 std::vector<InscribedSphere> spheres;
334 std::uint64_t generation{std::numeric_limits<std::uint64_t>::max()};
338 static constexpr std::size_t kMaxInscribedSpheres = 64;
347 struct SurfaceTriangle {
348 G4ThreeVector p1, p2, p3;
361 struct SurfaceSamplingCache {
362 std::vector<TopoDS_Face> faces;
363 std::vector<SurfaceTriangle> triangles;
364 std::vector<G4double> cumulativeAreas;
365 G4double totalArea{0.0};
376 AxisAlignedBounds fCachedBounds;
383 std::vector<FaceBounds> fFaceBoundsCache;
399 std::unordered_map<const TopoDS_TShape*, std::vector<std::size_t>> fFaceAdaptorIndex;
410 std::vector<InscribedSphere> fInitialSpheres;
420 Handle(BRepExtrema_TriangleSet) fTriangleSet;
431 G4double fBVHDeflection{0.0};
442 std::vector<G4double> fFaceDeflections;
447 bool fAllFacesPlanar{
false};
452 std::atomic<std::uint64_t> fShapeGeneration{0};
458 mutable G4Cache<ClassifierCache> fClassifierCache;
464 mutable G4Cache<IntersectorCache> fIntersectorCache;
471 mutable G4Cache<SphereCacheData> fSphereCache;
480 mutable std::unique_ptr<G4Polyhedron> fCachedPolyhedron;
487 mutable std::uint64_t fPolyhedronGeneration{std::numeric_limits<std::uint64_t>::max()};
493 mutable bool fPolyhedronBuilding{
false};
497 mutable std::mutex fPolyhedronMutex;
501 mutable std::condition_variable fPolyhedronCV;
505 mutable std::optional<G4double> fCachedVolume;
509 mutable std::optional<G4double> fCachedSurfaceArea;
512 mutable std::mutex fVolumeAreaMutex;
517 mutable std::optional<SurfaceSamplingCache> fSurfaceCache;
523 mutable std::uint64_t fSurfaceCacheGeneration{std::numeric_limits<std::uint64_t>::max()};
527 mutable std::mutex fSurfaceCacheMutex;
531 BRepClass3d_SolidClassifier& GetOrCreateClassifier()
const;
537 IntersectorCache& GetOrCreateIntersector()
const;
541 SphereCacheData& GetOrInitSphereCache()
const;
547 void TryInsertSphere(
const G4ThreeVector& centre, G4double d)
const;
554 void ComputeBounds();
562 void ComputeInitialSpheres();
566 G4double AABBLowerBound(
const G4ThreeVector& p)
const;
574 G4double BVHLowerBoundDistance(
const G4ThreeVector& p)
const;
587 G4double PlanarFaceLowerBoundDistance(
const G4ThreeVector& p)
const;
596 static std::optional<ClosestFaceMatch>
597 TryFindClosestFace(
const std::vector<FaceBounds>& faceBoundsCache,
const G4ThreeVector& point,
598 G4double maxDistance = kInfinity);
605 const SurfaceSamplingCache& GetOrBuildSurfaceCache()
const;