From bcfa803f31d401145745ce60e3ac508e4b5109ac Mon Sep 17 00:00:00 2001 From: Luis Manuel Diaz Angulo Date: Wed, 19 Aug 2026 12:11:49 +0200 Subject: [PATCH] Fix proposed by gpt. NOT GOOD --- src/core/SmootherTools.cpp | 36 +++++++++++- test/app/launcherTest.cpp | 9 +++ test/core/SmootherToolsTest.cpp | 52 ++++++++++++++++++ .../smallSphere.conformal.tessellator.json | 17 ++++++ testData/cases/smallSphere/smallSphere.stl | Bin 0 -> 15184 bytes 5 files changed, 112 insertions(+), 2 deletions(-) create mode 100644 testData/cases/smallSphere/smallSphere.conformal.tessellator.json create mode 100644 testData/cases/smallSphere/smallSphere.stl diff --git a/src/core/SmootherTools.cpp b/src/core/SmootherTools.cpp index dc46199..63ab617 100644 --- a/src/core/SmootherTools.cpp +++ b/src/core/SmootherTools.cpp @@ -565,8 +565,40 @@ Coordinates SmootherTools::collapsePointsOnContour( } if (!validContourIds.empty()) { - for (auto const& interiorId : cG.getInterior()) { - res[interiorId] = coords[*validContourIds.begin()]; + const IdSet interior = cG.getInterior(); + bool collapseToMinExterior = false; + if (interior.size() > 1 && validContourIds.size() == 2) { + const CoordinateId minExt = *validContourIds.begin(); + const CoordinateId maxExt = *validContourIds.rbegin(); + // Preserve the established behavior for a contour run that + // extends toward both anchors: collapse the run as a unit. + for (const auto interiorId : interior) { + if ((coords[interiorId] - coords[maxExt]).norm() + < (coords[interiorId] - coords[minExt]).norm()) { + collapseToMinExterior = true; + break; + } + } + } + + if (collapseToMinExterior) { + const CoordinateId anchor = *validContourIds.begin(); + for (const auto interiorId : interior) { + res[interiorId] = coords[anchor]; + } + } + else { + for (const auto interiorId : interior) { + if (res[interiorId] != coords[interiorId]) { + continue; + } + const IdSet targets = + cG.getClosestVerticesInSet(interiorId, validContourIds); + if (targets.empty()) { + continue; + } + res[interiorId] = coords[*targets.begin()]; + } } } diff --git a/test/app/launcherTest.cpp b/test/app/launcherTest.cpp index 2cf01ab..b7869b8 100644 --- a/test/app/launcherTest.cpp +++ b/test/app/launcherTest.cpp @@ -193,6 +193,15 @@ TEST_F(LauncherTest, launches_conformal_sphere_case) EXPECT_EQ(exitCode, EXIT_SUCCESS); } +TEST_F(LauncherTest, launches_conformal_smallSphere_case) +{ + int ac = 3; + const char* av[] = { NULL, "-i", "testData/cases/smallSphere/smallSphere.conformal.tessellator.json"}; + int exitCode; + EXPECT_NO_THROW(exitCode = launcher(ac, av)); + EXPECT_EQ(exitCode, EXIT_SUCCESS); +} + TEST_F(LauncherTest, launches_conformal_thinCylinder_case) { int ac = 3; diff --git a/test/core/SmootherToolsTest.cpp b/test/core/SmootherToolsTest.cpp index e93a9d0..7edb594 100644 --- a/test/core/SmootherToolsTest.cpp +++ b/test/core/SmootherToolsTest.cpp @@ -299,6 +299,43 @@ class SmootherToolsTest : public ::testing::Test { return res; } + static Mesh buildCollapseEdgeMeshWithInnerDent() + { + // 7-------------6 + // | _-'/| + // | _-' / | + // | _-' / | + // | _-' / | + // 4---3----------5 + // | __-- + // 2-' --__ + // 0----------1 + Mesh res; + res.grid = utils::GridTools::buildCartesianGrid(0.0, 1.0, 2); + res.coordinates = { + Coordinate({0.00, 0.00, 1.00}), // 0 + Coordinate({0.60, 0.00, 1.00}), // 1 + Coordinate({0.00, 0.10, 1.00}), // 2 + Coordinate({0.20, 0.40, 1.00}), // 3 + Coordinate({0.00, 0.40, 1.00}), // 4 + Coordinate({1.00, 0.40, 1.00}), // 5 + Coordinate({1.00, 1.00, 1.00}), // 6 + Coordinate({0.00, 1.00, 1.00}), // 7 + }; + + res.groups.push_back(Group()); + res.groups[0].elements = { + Element({0, 1, 2}, Element::Type::Surface), + Element({1, 3, 2}, Element::Type::Surface), + Element({2, 3, 4}, Element::Type::Surface), + Element({3, 5, 6}, Element::Type::Surface), + Element({3, 6, 4}, Element::Type::Surface), + Element({4, 6, 7}, Element::Type::Surface), + }; + + return res; + } + static Mesh buildElementsToRemesh() { // 4 ---- 5 @@ -649,6 +686,21 @@ TEST_F(SmootherToolsTest, collapse_two_points_in_contour) EXPECT_EQ(collapsed[6], collapsed[7]); } +TEST_F(SmootherToolsTest, collapsePointsInContourWithInnerDent) +{ + Mesh mesh = buildCollapseEdgeMeshWithInnerDent(); + const Elements& elements = mesh.groups[0].elements; + + const Coordinates collapsed = SmootherTools(mesh.grid).collapsePointsOnContour( + elements, mesh.coordinates, alignmentAngle); + + EXPECT_EQ(8, countDifferentCoordinates(mesh.coordinates)); + ASSERT_EQ(6, countDifferentCoordinates(collapsed)); + EXPECT_NE(collapsed[2], collapsed[4]); + EXPECT_EQ(collapsed[2], collapsed[0]); + EXPECT_EQ(collapsed[4], collapsed[7]); +} + /// Build the list of singular Ids corresponding to a corner structure with the following ids /// \verbatim /// 2 ----- 6 diff --git a/testData/cases/smallSphere/smallSphere.conformal.tessellator.json b/testData/cases/smallSphere/smallSphere.conformal.tessellator.json new file mode 100644 index 0000000..0b60d8f --- /dev/null +++ b/testData/cases/smallSphere/smallSphere.conformal.tessellator.json @@ -0,0 +1,17 @@ +{ + "grid": { + "numberOfCells": [5, 5, 5], + "boundingBox": [ + [-3.0, -3.0, -3.0], + [ 2.0, 2.0, 2.0] + ] + }, + "object": {"filename": "smallSphere.stl"}, + "mesher": { + "type": "conformal", + "options": { + "edgePoints": 4, + "forbiddenLength": 0.0 + } + } +} diff --git a/testData/cases/smallSphere/smallSphere.stl b/testData/cases/smallSphere/smallSphere.stl new file mode 100644 index 0000000000000000000000000000000000000000..0ba95a9b4afddcb35af6dbde05c3acc0735ea0cc GIT binary patch literal 15184 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 anE4nYeqRYK@|WxspomidM(}fE^#1}?FttJe literal 0 HcmV?d00001