📄 tetgen.h
字号:
// //// The data structure of tetrahedron also stores the geometrical information.//// Let t be a tetrahedron, v0, v1, v2, and v3 be the 4 nodes corresponding //// to the order of their storage in t. v3 always has a negative orientation //// with respect to v0, v1, v2 (ie,, v3 lies above the oriented plane passes //// through v0, v1, v2). Let the 4 faces of t be f0, f1, f2, and f3. Vertices //// of each face are stipulated as follows: f0 (v0, v1, v2), f1 (v0, v3, v1), //// f2 (v1, v3, v2), f3 (v2, v3, v0). //// //// A subface has 3 pointers to vertices, 3 pointers to adjoining subfaces, 3 //// pointers to adjoining subsegments, 2 pointers to adjoining tetrahedra, a //// boundary marker(an integer). Like a tetrahedron, the pointers to vertices,//// subfaces, and subsegments are ordered in a way that indicates their geom- //// etric relation. Let s be a subface, v0, v1 and v2 be the 3 nodes corres- //// ponding to the order of their storage in s, e0, e1 and e2 be the 3 edges,//// then we have: e0 (v0, v1), e1 (v1, v2), e2 (v2, v0). //// //// A subsegment has exactly the same data fields as a subface has, but only //// uses some of them. It has 2 pointers to its endpoints, 2 pointers to its //// adjoining (and collinear) subsegments, a pointer to a subface containing //// it (there may exist any number of subfaces having it, choose one of them //// arbitrarily). The geometric relation between its endpoints and adjoining //// subsegments is kept with respect to the storing order of its endpoints. //// //// The data structure of point is relatively simple. A point is a list of //// floating-point numbers, starting with the x, y, and z coords, followed by //// an arbitrary number of optional user-defined floating-point attributes, //// an integer boundary marker, an integer for the point type, and a pointer //// to a tetrahedron (used for speeding up point location). //// //// For a tetrahedron on a boundary (or a hull) of the mesh, some or all of //// the adjoining tetrahedra may not be present. For an interior tetrahedron, //// often no neighboring subfaces are present, Such absent tetrahedra and //// subfaces are never represented by the NULL pointers; they are represented //// by two special records: `dummytet', the tetrahedron fills "outer space", //// and `dummysh', the vacuous subfaces which are omnipresent. //// //// Tetrahedra and adjoining subfaces are glued together through the pointers //// saved in each data fields of them. Subfaces and adjoining subsegments are //// connected in the same fashion. However, there are no pointers directly //// gluing tetrahedra and adjoining subsegments. For the purpose of saving //// space, the connections between tetrahedra and subsegments are entirely //// mediated through subfaces. The following part explains how subfaces are //// connected in TetGen. //// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //// The subface-subface and subface-subsegment connections //// //// Adjoining subfaces sharing a common edge are connected in such a way that //// they form a face ring around the edge. It is indeed a single linked list //// which is cyclic, e.g., one can start from any subface in it and traverse //// back. When the edge is not a subsegment, the ring only has two coplanar //// subfaces which are pointing to each other. Otherwise, the face ring may //// have any number of subfaces (and are not all coplanar). //// //// How is the face ring formed? Let s be a subsegment, f is one of subfaces //// containing s as an edge. The direction of s is stipulated from its first //// endpoint to its second (according to their storage in s). Once the dir of //// s is determined, the other two edges of f are oriented to follow this dir.//// The "directional normal" N_f is a vector formed from any point in f and a //// points orthogonally above f. //// //// The face ring of s is a cyclic ordered set of subfaces containing s, i.e.,//// F(s) = {f1, f2, ..., fn}, n >= 1. Where the order is defined as follows: //// let fi, fj be two faces in F(s), the "normal-angle", NAngle(i,j) (range //// from 0 to 360 degree) is the angle between the N_fi and N_fj; then fi is //// in front of fj (or symbolically, fi < fj) if there exists another fk in //// F(s), and NAangle(k, i) < NAngle(k, j). The face ring of s is: f1 < f2 < //// ... < fn < f1. //// //// The easiest way to imagine how a face ring is formed is to use the right- //// hand rule. Make a fist using your right hand with the thumb pointing to //// the direction of the subsegment. The face ring is connected following the //// direction of your fingers. //// //// The subface and subsegment are also connected through pointers stored in //// their own data fields. Every subface has a pointer to its adjoining sub- //// segment. However, a subsegment only has one pointer to a subface which is //// containing it. Such subface can be chosen arbitrarily, other subfaces are //// found through the face ring. //// ///////////////////////////////////////////////////////////////////////////////// // The tetrahedron data structure. Fields of a tetrahedron contains: // - a list of four adjoining tetrahedra; // - a list of four vertices; // - a list of four subfaces (optional, used for -p switch); // - a list of user-defined floating-point attributes (optional); // - a volume constraint (optional, used for -a switch); // - an integer of element marker (optional, used for -n switch); // - a pointer to a list of high-ordered nodes (optional, -o2 switch); typedef REAL **tetrahedron; // The shellface data structure. Fields of a shellface contains: // - a list of three adjoining subfaces; // - a list of three vertices; // - a list of two adjoining tetrahedra; // - a list of three adjoining subsegments; // - a pointer to a badface containing it (used for -q); // - an area constraint (optional, used for -q); // - an integer for boundary marker; // - an integer for type: SHARPSEGMENT, NONSHARPSEGMENT, ...; // - an integer for pbc group (optional, if in->pbcgrouplist exists); typedef REAL **shellface; // The point data structure. It is actually an array of REALs: // - x, y and z coordinates; // - a list of user-defined point attributes (optional); // - a list of REALs of a user-defined metric tensor (optional); // - a pointer to a simplex (tet, tri, edge, or vertex); // - a pointer to a parent (or duplicate) point; // - a pointer to a tet in background mesh (optional); // - a pointer to another pbc point (optional); // - an integer for boundary marker; // - an integer for verttype: INPUTVERTEX, FREEVERTEX, ...; typedef REAL *point;///////////////////////////////////////////////////////////////////////////////// //// The mesh handle (triface, face) data types //// //// Two special data types, 'triface' and 'face' are defined for maintaining //// and updating meshes. They are like pointers (or handles), which allow you //// to hold one particular part of the mesh, i.e., a tetrahedron, a triangle, //// an edge and a vertex. However, these data types do not themselves store //// any part of the mesh. The mesh is made of the data types defined above. //// //// Muecke's "triangle-edge" data structure is the prototype for these data //// types. It allows a universal representation for every tetrahedron, //// triangle, edge and vertex. For understanding the following descriptions //// of these handle data structures, readers are required to read both the //// introduction and implementation detail of "triangle-edge" data structure //// in Muecke's thesis. //// //// A 'triface' represents a face of a tetrahedron and an oriented edge of //// the face simultaneously. It has a pointer 'tet' to a tetrahedron, an //// integer 'loc' (range from 0 to 3) as the face index, and an integer 'ver' //// (range from 0 to 5) as the edge version. A face of the tetrahedron can be //// uniquly determined by the pair (tet, loc), and an oriented edge of this //// face can be uniquly determined by the triple (tet, loc, ver). Therefore, //// different usages of one triface are possible. If we only use the pair //// (tet, loc), it refers to a face, and if we add the 'ver' additionally to //// the pair, it is an oriented edge of this face. //// //// A 'face' represents a subface and an oriented edge of it simultaneously. //// It has a pointer 'sh' to a subface, an integer 'shver'(range from 0 to 5) //// as the edge version. The pair (sh, shver) determines a unique oriented //// edge of this subface. A 'face' is also used to represent a subsegment, //// in this case, 'sh' points to the subsegment, and 'shver' indicates the //// one of two orientations of this subsegment, hence, it only can be 0 or 1. //// //// Mesh navigation and updating are accomplished through a set of mesh //// manipulation primitives which operate on trifaces and faces. They are //// introduced below. //// ///////////////////////////////////////////////////////////////////////////////// class triface { public: tetrahedron* tet; int loc, ver; // Constructors; triface() : tet(0), loc(0), ver(0) {} // Operators; triface& operator=(const triface& t) { tet = t.tet; loc = t.loc; ver = t.ver; return *this; } bool operator==(triface& t) { return tet == t.tet && loc == t.loc && ver == t.ver; } bool operator!=(triface& t) { return tet != t.tet || loc != t.loc || ver != t.ver; } }; class face { public: shellface *sh; int shver; // Constructors; face() : sh(0), shver(0) {} // Operators; face& operator=(const face& s) { sh = s.sh; shver = s.shver; return *this; } bool operator==(face& s) {return (sh == s.sh) && (shver == s.shver);} bool operator!=(face& s) {return (sh != s.sh) || (shver != s.shver);} };///////////////////////////////////////////////////////////////////////////////// //// The badface structure //// //// A multiple usages structure. Despite of its name, a 'badface' can be used //// to represent the following objects: //// - a face of a tetrahedron which is (possibly) non-Delaunay; //// - an encroached subsegment or subface; //// - a bad-quality tetrahedron, i.e, has too large radius-edge ratio; //// - a sliver, i.e., has good radius-edge ratio but nearly zero volume; //// - a degenerate tetrahedron (see routine checkdegetet()). //// - a recently flipped face (saved for undoing the flip later). //// //// It has the following fields: 'tt' holds a tetrahedron; 'ss' holds a sub- //// segment or subface; 'cent' is the circumcent of 'tt' or 'ss', 'key' is a //// special value depending on the use, it can be either the square of the //// radius-edge ratio of 'tt' or the flipped type of 'tt'; 'forg', 'fdest', //// 'fapex', and 'foppo' are vertices saved for checking the object in 'tt' //// or 'ss' is still the same when it was stored; 'noppo' is the fifth vertex //// of a degenerate point set. 'previtem' and 'nextitem' implement a double //// link for managing many basfaces. //// ///////////////////////////////////////////////////////////////////////////////// struct badface { triface tt;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -