Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion geom/geom/inc/LinkDef1.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@
#pragma link C++ class TGeoXtru + ;
#pragma link C++ class ROOT::Geom::Vertex_t + ;
#pragma link C++ class TGeoFacet + ;
#pragma link C++ class TGeoTessellated + ;
#pragma link C++ class TGeoTessellated - ;
#pragma link C++ class TGeoShapeAssembly + ;
#pragma link C++ class TGeoScaledShape + ;
#pragma link C++ class TGeoVolume - ;
Expand Down
48 changes: 40 additions & 8 deletions geom/geom/inc/TGeoTessellated.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,18 +60,29 @@ class TGeoTessellated : public TGeoBBox {
using Vertex_t = Tessellated::Vertex_t;

private:
int fNfacets = 0; // Number of facets
int fNvert = 0; // Number of vertices
int fNseg = 0; // Number of segments
bool fDefined = false; //! Shape fully defined
bool fClosedBody = false; // The faces are making a closed body
std::vector<Vertex_t> fVertices; // List of vertices
std::vector<TGeoFacet> fFacets; // List of facets
int fNfacets = 0; // Number of facets
int fNvert = 0; // Number of vertices
int fNseg = 0; // Number of segments
bool fDefined = false; //! Shape fully defined
bool fClosedBody = false; // The faces are making a closed body

// for now separate vectors but might be better to group per face
std::vector<Vertex_t> fVertices; // List of vertices
std::vector<TGeoFacet> fFacets; // List of facets
std::vector<Vertex_t> fOutwardNormals; //! Vector of outward-facing normals

std::multimap<long, int> fVerticesMap; //! Temporary map used to deduplicate vertices
bool fIsClosed = false; //! to know if shape still needs closure/initialization
std::vector<unsigned char> fBVHData; // Serialized BVH data for persistence
void *fBVH = nullptr; //! BVH acceleration structure for safety and navigation
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

void * is really bad for any future persistence of this structure, and I/O may become very relevant to avoid re-creating it for very large number of triangles. IMO we need to put here the real type, even if it makes the header directly dependent on bvh::v2.

The destructor of the class should delete fBVH

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we put the real type, can we also use a unique_ptr while we're at it?


TGeoTessellated(const TGeoTessellated &) = delete;
TGeoTessellated &operator=(const TGeoTessellated &) = delete;

// bvh helper functions
void BuildBVH();
void CalculateNormals();

public:
// constructors
TGeoTessellated() {}
Expand Down Expand Up @@ -130,7 +141,28 @@ class TGeoTessellated : public TGeoBBox {
/// Reader from .obj format
static TGeoTessellated *ImportFromObjFormat(const char *objfile, bool check = false, bool verbose = false);

ClassDefOverride(TGeoTessellated, 1) // tessellated shape class
// navigation functions used by TGeoNavigator (attention: only the iact == 3 cases implemented for now)
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;
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;
bool Contains(const Double_t *point) const override;
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;

// these are trivial implementations, just for debugging
Double_t DistFromInside_Loop(const Double_t *point, const Double_t *dir) const;
Double_t DistFromOutside_Loop(const Double_t *point, const Double_t *dir) const;
bool Contains_Loop(const Double_t *point) const;
Comment on lines +154 to +156
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since these are for testing purposes only, leaving them in the public interface may not be the best choice. The alternative could be to move these to a test utility, where we can add also some regression tests in future. What about Safety_Loop ?


Double_t Capacity() const override;

private:
// a safety kernel used in multiple implementations
template <bool closest_facet = false>
Double_t SafetyKernel(const Double_t *point, bool in, int *closest_facet_id = nullptr) const;

ClassDefOverride(TGeoTessellated, 2) // tessellated shape class
};

#endif
65 changes: 33 additions & 32 deletions geom/geom/inc/bvh/v2/bbox.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,38 +10,39 @@ namespace bvh::v2 {

template <typename T, size_t N>
struct BBox {
Vec<T, N> min, max;

BBox() = default;
BVH_ALWAYS_INLINE BBox(const Vec<T, N>& min, const Vec<T, N>& max) : min(min), max(max) {}
BVH_ALWAYS_INLINE explicit BBox(const Vec<T, N>& point) : BBox(point, point) {}

BVH_ALWAYS_INLINE BBox& extend(const Vec<T, N>& point) {
return extend(BBox(point));
}

BVH_ALWAYS_INLINE BBox& extend(const BBox& other) {
min = robust_min(min, other.min);
max = robust_max(max, other.max);
return *this;
}

BVH_ALWAYS_INLINE Vec<T, N> get_diagonal() const { return max - min; }
BVH_ALWAYS_INLINE Vec<T, N> get_center() const { return (max + min) * static_cast<T>(0.5); }

BVH_ALWAYS_INLINE T get_half_area() const {
auto d = get_diagonal();
static_assert(N == 2 || N == 3);
if constexpr (N == 3) return (d[0] + d[1]) * d[2] + d[0] * d[1];
if constexpr (N == 2) return d[0] + d[1];
return static_cast<T>(0.);
}

BVH_ALWAYS_INLINE static constexpr BBox make_empty() {
return BBox(
Vec<T, N>(+std::numeric_limits<T>::max()),
Vec<T, N>(-std::numeric_limits<T>::max()));
}
Vec<T, N> min, max;

BBox() = default;
BVH_ALWAYS_INLINE BBox(const Vec<T, N> &vmin, const Vec<T, N> &vmax) : min(vmin), max(vmax) {}
BVH_ALWAYS_INLINE explicit BBox(const Vec<T, N> &point) : BBox(point, point) {}

BVH_ALWAYS_INLINE BBox &extend(const Vec<T, N> &point) { return extend(BBox(point)); }

BVH_ALWAYS_INLINE BBox &extend(const BBox &other)
{
min = robust_min(min, other.min);
max = robust_max(max, other.max);
return *this;
}

BVH_ALWAYS_INLINE Vec<T, N> get_diagonal() const { return max - min; }
BVH_ALWAYS_INLINE Vec<T, N> get_center() const { return (max + min) * static_cast<T>(0.5); }

BVH_ALWAYS_INLINE T get_half_area() const
{
auto d = get_diagonal();
static_assert(N == 2 || N == 3);
if constexpr (N == 3)
return (d[0] + d[1]) * d[2] + d[0] * d[1];
if constexpr (N == 2)
return d[0] + d[1];
return static_cast<T>(0.);
}

BVH_ALWAYS_INLINE static constexpr BBox make_empty()
{
return BBox(Vec<T, N>(+std::numeric_limits<T>::max()), Vec<T, N>(-std::numeric_limits<T>::max()));
}
};

} // namespace bvh::v2
Expand Down
Loading
Loading