Skip to content
Merged
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
51 changes: 25 additions & 26 deletions geom/geom/src/TGeoTessellated.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -328,38 +328,36 @@ bool TGeoTessellated::FacetCheck(int ifacet) const

void TGeoTessellated::CloseShape(bool check, bool fixFlipped, bool verbose)
{
if (fIsClosed && fBVH) {
const bool initialized = fIsClosed && fBVH;
if (initialized && !check) {
return;
}
// Compute bounding box
fDefined = true;
fNvert = fVertices.size();
fNfacets = fFacets.size();
ComputeBBox();

BuildBVH();
if (fOutwardNormals.size() == 0) {
CalculateNormals();
} else {
// short check if the normal container is of correct size
if (fOutwardNormals.size() != fFacets.size()) {
std::cerr << "Inconsistency in normal container";
}
}
fIsClosed = true;
if (!initialized) {
// Compute bounding box
fDefined = true;
fNvert = fVertices.size();
fNfacets = fFacets.size();
ComputeBBox();

// Cleanup the vertex map
std::multimap<long, int>().swap(fVerticesMap);
BuildBVH();
fIsClosed = true;

// Cleanup the vertex map
std::multimap<long, int>().swap(fVerticesMap);
}

if (fVertices.size() > 0) {
if (!check)
return;
if (check) {
// Check facets
for (auto i = 0; i < fNfacets; ++i)
FacetCheck(i);

// Check facets
for (auto i = 0; i < fNfacets; ++i)
FacetCheck(i);
fClosedBody = CheckClosure(fixFlipped, verbose);
}

fClosedBody = CheckClosure(fixFlipped, verbose);
if (fOutwardNormals.size() != fFacets.size())
CalculateNormals();
}
}

Expand Down Expand Up @@ -422,6 +420,8 @@ bool TGeoTessellated::CheckClosure(bool fixFlipped, bool verbose)
}
if (nfixed && verbose)
Info("Check", "Automatically flipped %d facets to match first defined facet", nfixed);
if (nfixed && !fOutwardNormals.empty())
CalculateNormals();
}
delete[] nn;
delete[] flipped;
Expand Down Expand Up @@ -1277,8 +1277,7 @@ inline Double_t TGeoTessellated::SafetyKernel(const Double_t *point, bool in, in
const auto object_id = mybvh->prim_ids[p_id];

const auto &facet = fFacets[object_id];
auto thissafetySQ =
pointFacetDistSq(Vec3f<float>(point[0], point[1], point[2]), facet, fVertices);
auto thissafetySQ = pointFacetDistSq(Vec3f<float>(point[0], point[1], point[2]), facet, fVertices);

if (thissafetySQ < smallest_safety_sq) {
smallest_safety_sq = thissafetySQ;
Expand Down
31 changes: 31 additions & 0 deletions geom/test/test_tessellated.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,39 @@ CreateTrdLikeTessellated_Triangles(const char *name, double x1, double x2, doubl
return tsl;
}

void AddClosedTetrahedronFacets(TGeoTessellated &tsl)
{
// Closed tetrahedron using the same facet winding as the GDML reproducer
// for ROOT issue #22395.
const Vtx v0(0, 0, 0);
const Vtx v1(10, 0, 0);
const Vtx v2(5, 10, 0);
const Vtx v3(5, 5, 10);

EXPECT_TRUE(tsl.AddFacet(v0, v2, v1));
EXPECT_TRUE(tsl.AddFacet(v0, v1, v3));
EXPECT_TRUE(tsl.AddFacet(v1, v2, v3));
EXPECT_TRUE(tsl.AddFacet(v0, v3, v2));
}

} // namespace

TEST(TGeoTessellated, CloseShapeCanCheckAfterUncheckedClose)
{
// TGDMLParse finalizes tessellated solids with CloseShape(false). This must
// initialize the shape without preventing a later explicit CloseShape(true)
// from running closure validation and setting the closed-body state.
TGeoTessellated tsl("Closed Tetrahedron");
AddClosedTetrahedronFacets(tsl);

tsl.CloseShape(/*check=*/false);
EXPECT_TRUE(tsl.IsDefined());
EXPECT_FALSE(tsl.IsClosedBody());

tsl.CloseShape(/*check=*/true, /*fixFlipped=*/true, /*verbose=*/false);
EXPECT_TRUE(tsl.IsClosedBody());
}

TEST(TGeoTessellated, TrdLike_CoreNavigation)
{
// Representative points (ported)
Expand Down
Loading