-
Notifications
You must be signed in to change notification settings - Fork 1.3k
/
volume_mesh_refiner.h
116 lines (102 loc) · 4.55 KB
/
volume_mesh_refiner.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#pragma once
#include <vector>
#include "drake/common/sorted_pair.h"
#include "drake/geometry/proximity/sorted_triplet.h"
#include "drake/geometry/proximity/volume_mesh.h"
namespace drake {
namespace geometry {
namespace internal {
// (Advanced) %VolumeMeshRefiner refines the input tetrahedral mesh to
// eliminate problematic simplices that evaluate to zero signed-distance in
// its interior. See detect_zero_simplex.h for the definition of a
// problematic simplex.
class VolumeMeshRefiner {
public:
// @pre Assume input_mesh is valid during the lifetime of this class.
explicit VolumeMeshRefiner(const VolumeMesh<double>& input_mesh)
: input_mesh_(input_mesh) {}
// Performs mesh-refinement algorithm and returns the new refined mesh.
//
// @note Depending on how many problematic simplices the input mesh has,
// the output may have four or five times the number of tetrahedra of
// the input mesh.
//
// @note If the input mesh has no problematic simplices, the returned mesh
// is a copy of the input.
VolumeMesh<double> Refine();
private:
// Refines a tetrahedron into four tetrahedra.
//
// @param tetrahedron Tetrahedron index into the mesh.
void RefineTetrahedron(int tetrahedron);
// Refines an interior triangle and its two incident tetrahedra into six
// tetrahedra. Each of the two old tetrahedra becomes three new tetrahedra.
//
// @param triangle Three vertex indices of the triangle.
void RefineTriangle(const SortedTriplet<int>& triangle);
// Refines an interior edge and its n incident tetrahedra into 2n tetrahedra.
// Each of the n old tetrahedron becomes two new tetrahedra.
//
// @param edge Two vertex indices of the edge.
void RefineEdge(const SortedPair<int>& edge);
// Helper of RefineTetrahedron(), RefineTriangle(), and RefineEdge().
// It cuts the given `tetrahedron` into smaller ones by inserting the given
// `new_vertex` into the interior of its `sub_simplex`, which could be its
// edge, its triangle, or the tetrahedron itself.
//
// @param tetrahedron Tetrahedron index into the mesh.
// @pre 0 <= tetrahedron < tetrahedra_.size()
//
// @param sub_simplex A list of two integers for an edge, three
// integers for a triangle, or four integers for a tetrahedron. Each integer
// is a vertex index into the mesh.
// @pre 2 <= sub_simplex.size() <= 4
// @pre 0 <= sub_simplex[i] < vertices_.size()
// @pre sub_simplex[i] != sub_simplex[j] for i != j
// @pre sub_simplex[i] is a vertex of the tetrahedron.
//
// @param new_vertex Index of the new vertex for insertion into the
// sub-simplex of the tetrahedron.
// @pre 0 <= new_vertex < vertices_.size()
// @pre The new vertex is in the relative interior of the sub-simplex.
//
// This function preserves tetrahedron orientation. The sign of the signed
// volume of each of the new tetrahedra is the same as the sign of the
// signed volume of the old tetrahedron.
//
// @note This operation is local to the specified tetrahedron. It does not
// guarantee conformity with neighboring tetrahedra. Callers are responsible
// to call this function on adjacent tetrahedra to maintain conformity.
void CutTetrahedron(int tetrahedron, const std::vector<int>& sub_simplex,
int new_vertex);
// TODO(DamrongGuoy): Consider more efficient data structures for these
// two queries.
// Returns indices of tetrahedra sharing the given triangle. If there is no
// such tetrahedra, return an empty list.
//
// @param v0,v1,v2 Three unique vertex indices of the triangle.
// @pre 0 <= v0, v1, v2 < vertices_.size()
// @pre v0 != v1 && v1 != v2 && v2 != v0
//
// @note This function has linear complexity in the number of tetrahedra.
std::vector<int> GetTetrahedraOnTriangle(int v0, int v1, int v2) const;
// Returns indices of tetrahedra sharing the given edge. If there is no
// such tetrahedra, return an empty list.
//
// @param v0,v1 Two unique vertex indices of the edge.
// @pre 0 <= v0, v1 < vertices_.size()
// @pre v0 != v1
//
// @note This function has linear complexity on the number of tetrahedra.
std::vector<int> GetTetrahedraOnEdge(int v0, int v1) const;
// As we incrementally refine the mesh, we collect tetrahedra and
// vertices into these variables.
std::vector<VolumeElement> tetrahedra_{};
std::vector<Vector3<double>> vertices_{};
// Reference to the input mesh must be valid during the lifetime of this
// object.
const VolumeMesh<double>& input_mesh_;
};
} // namespace internal
} // namespace geometry
} // namespace drake