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
19 changes: 18 additions & 1 deletion Libs/Mesh/Mesh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -490,7 +490,24 @@ Mesh& Mesh::remesh(int numVertices, double adaptivity) {

numVertices = std::max<int>(numVertices, 1);

remesh->SetForceManifold(true);
// ACVD's ForceManifold treats clusters on an open boundary as non-manifold and keeps splitting
// them, piling extra vertices and sliver triangles along the boundary (e.g. a mesh clipped by a
// cutting plane ends up with more vertices than requested). Only force manifold on closed meshes.
// geometry only: vtkFeatureEdges copies point data, which reads out of bounds on a field that
// doesn't have one value per point
auto geometry = vtkSmartPointer<vtkPolyData>::New();
geometry->SetPoints(this->poly_data_->GetPoints());
geometry->SetPolys(this->poly_data_->GetPolys());
auto boundary_edges = vtkSmartPointer<vtkFeatureEdges>::New();
boundary_edges->SetInputData(geometry);
boundary_edges->BoundaryEdgesOn();
boundary_edges->FeatureEdgesOff();
boundary_edges->NonManifoldEdgesOff();
boundary_edges->ManifoldEdgesOff();
boundary_edges->Update();
bool is_closed = boundary_edges->GetOutput()->GetNumberOfCells() == 0;

remesh->SetForceManifold(is_closed);
remesh->SetInput(surf);
remesh->SetFileLoadSaveOption(0);
remesh->SetConsoleOutput(0);
Expand Down
10 changes: 10 additions & 0 deletions Testing/MeshTests/MeshTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,16 @@ TEST(MeshTests, remeshPercentTest2) {
ASSERT_TRUE(femur == ground_truth);
}

// Remeshing an open (clipped) mesh should hit the requested vertex count instead of piling extra
// vertices along the open boundary (#2672)
TEST(MeshTests, remeshPercentOpenMeshTest) {
Mesh femur(std::string(TEST_DATA_DIR) + "/femur.vtk");
femur.clip(makePlane(Point3({-91.0, 0.0, 1230.0}), makeVector({0.0, 0.0, 1.0})));
auto num_points = femur.numPoints();
femur.remeshPercent(0.40, 1.0);
ASSERT_NEAR(femur.numPoints(), num_points * 0.40, num_points * 0.02);
}

TEST(MeshTests, fieldGradientFloatTest) {
// fields arrive on meshes as floats as often as doubles, and the gradient has to be computed for
// either: a missing gradient array used to be read as a null pointer
Expand Down
4 changes: 2 additions & 2 deletions Testing/data/remeshPercent1.vtk
Git LFS file not shown
4 changes: 2 additions & 2 deletions Testing/data/remeshPercent2.vtk
Git LFS file not shown
Loading