Skip to content

Commit

Permalink
[geometry] Strengthen VTK to volume mesh error cases (RobotLocomotion…
Browse files Browse the repository at this point in the history
…#20240)

Add some slightly more adversarial VTK files to the test suite, and improve
error reporting for VTK parse failures.
  • Loading branch information
rpoyner-tri authored Sep 28, 2023
1 parent ed56c02 commit 7038449
Show file tree
Hide file tree
Showing 7 changed files with 220 additions and 8 deletions.
4 changes: 4 additions & 0 deletions geometry/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -629,10 +629,14 @@ filegroup(
name = "test_vtk_files",
testonly = 1,
srcs = [
"test/bad_tet.vtk",
"test/cube_as_6_squares.vtk",
"test/non_convex_mesh.vtk",
"test/one_negative_tetrahedron.vtk",
"test/one_tetrahedron.vtk",
"test/some_volume.vtk",
"test/two_tetrahedra_with_field_variable.vtk",
"test/unstructured.vtk",
],
)

Expand Down
40 changes: 35 additions & 5 deletions geometry/proximity/test/vtk_to_volume_mesh_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -58,24 +58,54 @@ GTEST_TEST(VtkToVolumeMeshTest, BadScale) {
const double kNegativeScale = -0.01;
DRAKE_EXPECT_THROWS_MESSAGE(
internal::ReadVtkToVolumeMesh(test_file, kNegativeScale),
"ReadVtkToVolumeMesh: scale=.* is not a positive number.*");
"ReadVtkToVolumeMesh.*: scale=.* is not a positive number.*");

const double kZeroScale = 0.0;
DRAKE_EXPECT_THROWS_MESSAGE(
internal::ReadVtkToVolumeMesh(test_file, kZeroScale),
"ReadVtkToVolumeMesh: scale=.* is not a positive number.*");
"ReadVtkToVolumeMesh.*: scale=.* is not a positive number.*");
}

GTEST_TEST(VtkToVolumeMeshTest, BogusFileName) {
const std::string bogus_filename = "bogus_filename";
EXPECT_THROW(internal::ReadVtkToVolumeMesh(bogus_filename), std::exception);
DRAKE_EXPECT_THROWS_MESSAGE(internal::ReadVtkToVolumeMesh(bogus_filename),
".*at least one tetra.*");
}

GTEST_TEST(VtkToVolumeMeshTest, WrongFileType) {
const std::string require_vtk_but_this_is_obj =
FindResourceOrThrow("drake/geometry/test/non_convex_mesh.obj");
EXPECT_THROW(internal::ReadVtkToVolumeMesh(require_vtk_but_this_is_obj),
std::exception);
DRAKE_EXPECT_THROWS_MESSAGE(
internal::ReadVtkToVolumeMesh(require_vtk_but_this_is_obj),
".*at least one tetra.*");
}

GTEST_TEST(VtkToVolumeMeshTest, WrongFileContentsCube) {
const std::string cube_vtk =
FindResourceOrThrow("drake/geometry/test/cube_as_6_squares.vtk");
DRAKE_EXPECT_THROWS_MESSAGE(internal::ReadVtkToVolumeMesh(cube_vtk),
".*at least one tetra.*");
}

GTEST_TEST(VtkToVolumeMeshTest, WrongFileContentsVolume) {
const std::string volume_vtk =
FindResourceOrThrow("drake/geometry/test/some_volume.vtk");
DRAKE_EXPECT_THROWS_MESSAGE(internal::ReadVtkToVolumeMesh(volume_vtk),
".*at least one tetra.*");
}

GTEST_TEST(VtkToVolumeMeshTest, WrongFileContentsUnstructured) {
const std::string unstructured_vtk =
FindResourceOrThrow("drake/geometry/test/unstructured.vtk");
DRAKE_EXPECT_THROWS_MESSAGE(internal::ReadVtkToVolumeMesh(unstructured_vtk),
".*non-tetra.*");
}

GTEST_TEST(VtkToVolumeMeshTest, WrongFileContentsBadTet) {
const std::string bad_tet_vtk =
FindResourceOrThrow("drake/geometry/test/bad_tet.vtk");
DRAKE_EXPECT_THROWS_MESSAGE(internal::ReadVtkToVolumeMesh(bad_tet_vtk),
".*at least one tetra.*");
}

} // namespace
Expand Down
18 changes: 15 additions & 3 deletions geometry/proximity/vtk_to_volume_mesh.cc
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ VolumeMesh<double> ReadVtkToVolumeMesh(const std::string& filename,
double scale) {
if (scale <= 0.0) {
throw std::runtime_error(fmt::format(
"ReadVtkToVolumeMesh: scale={} is not a positive number", scale));
"ReadVtkToVolumeMesh('{}', {}): scale={} is not a positive number",
filename, scale, scale));
}
vtkNew<vtkUnstructuredGridReader> reader;
reader->SetFileName(filename.c_str());
Expand All @@ -43,9 +44,21 @@ VolumeMesh<double> ReadVtkToVolumeMesh(const std::string& filename,

std::vector<VolumeElement> elements;
elements.reserve(vtk_mesh->GetNumberOfCells());
vtkCellIterator* iter = vtk_mesh->NewCellIterator();
auto iter =
vtkSmartPointer<vtkCellIterator>::Take(vtk_mesh->NewCellIterator());
for (iter->InitTraversal(); !iter->IsDoneWithTraversal();
iter->GoToNextCell()) {
if (iter->GetCellType() != VTK_TETRA) {
vtkNew<vtkGenericCell> bad_cell;
iter->GetCell(bad_cell);
auto msg = fmt::format(
"ReadVtkToVolumeMesh('{}', {}): file contains a"
" non-tetrahedron(type id={}) cell with type id {}, dimension {},"
" and number of points {}",
filename, scale, static_cast<int>(VTK_TETRA), bad_cell->GetCellType(),
bad_cell->GetCellDimension(), bad_cell->GetNumberOfPoints());
throw std::runtime_error(msg);
}
vtkIdList* vtk_vertex_ids = iter->GetPointIds();
// clang-format off
elements.emplace_back(vtk_vertex_ids->GetId(0),
Expand All @@ -54,7 +67,6 @@ VolumeMesh<double> ReadVtkToVolumeMesh(const std::string& filename,
vtk_vertex_ids->GetId(3));
// clang-format on
}
iter->Delete();

return {std::move(elements), std::move(vertices)};
}
Expand Down
17 changes: 17 additions & 0 deletions geometry/test/bad_tet.vtk
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# vtk DataFile Version 2.0
Example of bad one-tet mesh -- triangle mis-typed as tet
ASCII
DATASET UNSTRUCTURED_GRID
POINTS 3 float
0.0 0.0 0.0
1.0 0.0 0.0
0.0 1.0 0.0

CELLS 1 4
4 0 1 2

CELL_TYPES 1
10



61 changes: 61 additions & 0 deletions geometry/test/cube_as_6_squares.vtk
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# vtk DataFile Version 2.0
Cube represented by six squares from https://examples.vtk.org/site/VTKFileFormats/
ASCII
DATASET POLYDATA
POINTS 8 float
0.0 0.0 0.0
1.0 0.0 0.0
1.0 1.0 0.0
0.0 1.0 0.0
0.0 0.0 1.0
1.0 0.0 1.0
1.0 1.0 1.0
0.0 1.0 1.0
POLYGONS 6 30
4 0 1 2 3
4 4 5 6 7
4 0 1 5 4
4 2 3 7 6
4 0 4 7 3
4 1 2 6 5
CELL_DATA 6
SCALARS cell_scalars int 1
LOOKUP_TABLE default
0
1
2
3
4
5
NORMALS cell_normals float
0 0 -1
0 0 1
0 -1 0
0 1 0
-1 0 0
1 0 0
FIELD FieldData 2
cellIds 1 6 int
0 1 2 3 4 5
faceAttributes 2 6 float
0.0 1.0 1.0 2.0 2.0 3.0 3.0 4.0 4.0 5.0 5.0 6.0
POINT_DATA 8
SCALARS sample_scalars float 1
LOOKUP_TABLE my_table
0.0
1.0
2.0
3.0
4.0
5.0
6.0
7.0
LOOKUP_TABLE my_table 8
0.0 0.0 0.0 1.0
1.0 0.0 0.0 1.0
0.0 1.0 0.0 1.0
1.0 1.0 0.0 1.0
0.0 0.0 1.0 1.0
1.0 0.0 1.0 1.0
0.0 1.0 1.0 1.0
1.0 1.0 1.0 1.0
16 changes: 16 additions & 0 deletions geometry/test/some_volume.vtk
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# vtk DataFile Version 2.0
Example of scalar field on uniform rectilinear grid from https://examples.vtk.org/site/VTKFileFormats/
ASCII
DATASET STRUCTURED_POINTS
DIMENSIONS 3 4 6
ASPECT_RATIO 1 1 1
ORIGIN 0 0 0
POINT_DATA 72
SCALARS volume_scalars char 1
LOOKUP_TABLE default
0 0 0 0 0 0 0 0 0 0 0 0
0 5 10 15 20 25 25 20 15 10 5 0
0 10 20 30 40 50 50 40 30 20 10 0
0 10 20 30 40 50 50 40 30 20 10 0
0 5 10 15 20 25 25 20 15 10 5 0
0 0 0 0 0 0 0 0 0 0 0 0
72 changes: 72 additions & 0 deletions geometry/test/unstructured.vtk
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# vtk DataFile Version 2.0
Example of Unstructured Grid of Many Cell Types from https://examples.vtk.org/site/VTKFileFormats/
ASCII
DATASET UNSTRUCTURED_GRID

POINTS 27 float
0 0 0 1 0 0 2 0 0 0 1 0 1 1 0 2 1 0
0 0 1 1 0 1 2 0 1 0 1 1 1 1 1 2 1 1
0 1 2 1 1 2 2 1 2 0 1 3 1 1 3 2 1 3
0 1 4 1 1 4 2 1 4 0 1 5 1 1 5 2 1 5
0 1 6 1 1 6 2 1 6

CELLS 11 60
8 0 1 4 3 6 7 10 9
8 1 2 4 5 7 8 10 11
4 6 10 9 12
4 11 14 10 13
6 15 16 17 14 13 12
6 18 15 19 16 20 17
4 22 23 20 19
3 21 22 18
3 22 19 18
2 26 25
1 24

CELL_TYPES 11
12
11
10
8
7
6
9
5
4
3
1

POINT_DATA 27
SCALARS scalars float 1
LOOKUP_TABLE default
0.0 1.0 2.0 3.0 4.0 5.0
6.0 7.0 8.0 9.0 10.0 11.0
12.0 13.0 14.0 15.0 16.0 17.0
18.0 19.0 20.0 21.0 22.0 23.0
24.0 25.0 26.0

VECTORS vectors float
1 0 0 1 1 0 0 2 0 1 0 0 1 1 0 0 2 0
1 0 0 1 1 0 0 2 0 1 0 0 1 1 0 0 2 0
0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1
0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1
0 0 1 0 0 1 0 0 1

CELL_DATA 11
SCALARS scalars float 1
LOOKUP_TABLE CellColors
0.0 1.0 2.0 3.0 4.0 5.0
6.0 7.0 8.0 9.0 10.0

LOOKUP_TABLE CellColors 11
.4 .4 1 1
.4 1 .4 1
.4 1 1 1
1 .4 .4 1
1 .4 1 1
1 1 .4 1
1 1 1 1
1 .5 .5 1
.5 1 .5 1
.5 .5 .5 1
1 .5 .4 1

0 comments on commit 7038449

Please sign in to comment.