一、派生体系
AbstractTriangluation
|--------> ImplicitTriangulation (如图像,规则网)
|---------> ExplicitTriangulation (三角面片)
|---------> Triangulation
|---> this class has the following members:
(1) AbstractTriangulation *abstractTriangulation_; // 这个要不指向explicitTriangulation_,要不指向implicitTriangulation_
(2) ExplicitTriangulation explicitTriangulation_;
(3) ImplicitTriangulation implicitTriangulation_;
在ttk中,localID通常指在小表中的次序,而globalID - 指大表中的次序。
We refer to 2-dimensional cells of the MS-complex as MS-cells, and 1-dimensional cells as MS-edges. Cell在TTK中相当于最高维的simplex(单纯形):
- A 0-simplex is a point.
- A 1-simplex is a line segment.
- A 2-simplex is a triangle.
- A 3-simplex is a tetrahedron.
- A 4-simplex is a 5-cell.
术语:
(1)quadrilateral - 四边形,也叫quadrangle (对应于triangle),或者tetragon(对应polygon, pertagon, hexagon)
(2) Edge Star of vertex, 和某个vertex链接的所有Edge (Let v be a vertex, and let S(v) be the edge star of v consisting of the set of edges incident to v)
(3) The lower edge star(和某个vertex链接所有Edge, 且另外一个顶点标量值小于vertex的标量值) S ↓ (v) consists of the subset of edges whose endpoints are lower than v with respect to h -- the scalar value of the current vertex。一个最大值,周围的边都符合the lower edge star; 一个极小值,周围没有the lower edge; 一个规则点(regular)周围有部分lower edge以及部分upper edge。
(4) the upper edge star S ↑ (v) = S(v) \ S ↓ (v), 即(和某个vertex链接所有Edge, 且另外一个顶点标量值大于vertex的标量值)。一个最大值,周围不存在the upper edge star; 一个极小值,周围都是the upper edge; 一个规则点(regular)周围有部分lower edge以及部分upper edge。
(5) Wedge: 楔; 楔形物;楔入; 用楔子楔牢; 挤进。 在morse 理论中,相当于saddle点向上/或者向下的部分,相当于鞋拔子部分。
(6) VertexStar, EdgeStar 这些都表示某个点/边所邻接的CELL
2维数据场:vertexStar就是顶点周围的所有三角形, EdgeStar是某条边的所有邻接三角形(最多2个,最少1个)
3维数据场:vertexStar就是顶点周围的所有四面体, EdgeStar即使某条边的所有邻接四面体
即:这个vertexStar是这些Cell的唯一公共点,这个EdgeStar是周围所有Cell的唯一公共边。
二、总的介绍
1. functionalities
Triangulation is a class that provides time and memory efficient traversal methods on triangulations of piecewise linear manifolds. It provides the following features:
(1) Given a vertex, it provides: (顶点-边)
—— the list of edges that are connected to it,
--- the list of its neighbors, its link, its star, etc.
(2) Given an edge, it provides:(边-顶点)
—— its vertices,
—— its star, etc.
(3)Given a triangle, its provides:
-- its vertices,
-- its edges, etc.
—— 邻接三角形
(4)Given a tetrahedron, its provides:
—— its vertices,
—— its edges,
—— its neighbor tetrahedra, etc.
(5) Given a triangulation, it provides:
-- its list of vertices,
-- its list of edges,
-- its list of triangles
-- and its tetrahedra.
2. What's Explicite and Implicite Triangluations
(1) Explicit triangulations: Given a list of points and a list of cells, Triangulation provides time efficient accesses (requiring adequate pre-processing, see the documentation furtherdown).
(2)Implicit triangulations: Given a regular grid (origin, spacings and dimensions), Triangulation will perform an implicit triangulation of the grid, enabling both time and memory efficient traversals of triangulations of regular grids.
三、类AbstractTriangluation
// 是否是边界元素
std::vector<bool> boundaryEdges_,
boundaryTriangles_,
boundaryVertices_;
// CELL - Edge 表, 如果localEdgeID就是指在每个cell对应Edge数据组中的序号,如果EdgeID可能指的就是全局大表中位置
std::vector<std::vector<SimplexId> >
cellEdgeList_;
// CELL的邻居表(若干个邻居)
std::vector<std::vector<SimplexId> > cellNeighborList_;
// 三维标量场才有:每个Cell包含的Triangle表),可以对应多个triangle, 如四面体有三个面~
std::vector<std::vector<SimplexId> > cellTriangleList_;
//每个Edge的邻接?????????
std::vector<std::vector<SimplexId> > edgeLinkList_;
// 边表(边ID,边ID),重要,重要
std::vector<std::pair<SimplexId, SimplexId> > edgeList_;
//???
std::vector<std::vector<SimplexId> > edgeStarList_;
// 每个边的邻接三角形
std::vector<std::vector<SimplexId> > edgeTriangleList_;
//三角形表(3 点1,点2,点3)-(3 点1,点2,点3)
std::vector<std::vector<SimplexId> > triangleList_;
//每个三角形的边表(边1,边2,边3)
std::vector<std::vector<SimplexId> > triangleEdgeList_;
// 每个三角形的邻接三角形?????????????????
std::vector<std::vector<SimplexId> > triangleLinkList_;
//三维标量场才有:?????
std::vector<std::vector<SimplexId> > triangleStarList_;
// 顶点 -边 表, 边1-边2-边3-----。。。。
std::vector<std::vector<SimplexId> > vertexEdgeList_;
// 顶点----??????????????????
std::vector<std::vector<SimplexId> > vertexLinkList_;
//??????????????
std::vector<std::vector<SimplexId> > vertexNeighborList_;
//?????????????
std::vector<std::vector<SimplexId> > vertexStarList_;
// 三维标量场才有:顶点-邻接三角形表
std::vector<std::vector<SimplexId> > vertexTriangleList_;
四、重要函数 // 只讨论显式三角面片的数据结构
特别注意:Cell,在ttk中指最高维的simplicies,如:(3D: tetrahedra, 2D: triangles, 1D: edges).如果是二维标量场,就是Triangle, 三维标量场就是tetrehedra, 一般我们处理的二维标量场,如地形数据,即使triangle.
1. 基本功能,得到点、边信息
—— 得到三角网内顶点数目,存在成员vertexNumber_
inline SimplexId getNumberOfVertices() const { return vertexNumber_;}
—— 得到三角面片中ID为vertexId的顶点坐标 ,存在ExpliciteTriangluation::pointSet_, 存储:x-y-z-x-y-z-x-y-z.....................
int getVertexPoint(const SimplexId &vertexId, float &x, float &y, float &z)
—— 得到边信息(边表 (id1,id2) --(id1,id2) -- (id1, Id2) --(id1, id2) --(id1, Id2) ...................
inline const std::vector<std::pair<SimplexId, SimplexId> > *getEdges()
{
return &edgeList_; // vector< pair<SimplexId, SimplexId> > edgeList_; // 边表,每个节点存储了组成边的节点ID
}
—— 得到三角形信息
inline SimplexId getNumberOfTriangles(); inline const std::vector<std::vector<SimplexId> > *getTriangles()
注意在TTK中,二维标量场的三角面片信息存储在数组中:
pointSet_; // 点信息, x y z x y z x y z
cellNumber_;
cellArray_; // 次序 3 1 2 3, 3 2 3 4, 3 5 6 7 (实际没有逗号,就是 // 定 点数 顶点ID01 顶点ID02 顶点ID03 定点数 顶点ID11 顶点ID12 顶点ID33 .。。。。。
标量信息:
height[vertexId] = pointSet[i]; // 存储标量场信息!!!!!!!!!!!!!
offsets[vertexId] = vertexId; // offsets[]存储的就是ID
—— 得到维度信息
getDimensionality()
3.得到组成cell的边ID(此前需要调用过 耗时的preprocessCellEdges() 函数),存在ExpliciteTriangluation::cellEdgeList_,
inline int getCellEdge(const SimplexId &cellId, // cell id
const int &localEdgeId, // edge在这个cell中的次序,序号!
SimplexId &edgeId) const // 返回边ID,在边表中的次序,最终存在ExpliciteTriangluation::edgeList_;
返回: edgeId = cellEdgeList_[cellId][localEdgeId];
说明: (1)vector<std::pair<SimplexId, SimplexId> > edgeList_; //存储了边的两个顶点的ID号,通过这两个id找到pointSet_就可以把坐标取出来;
(2)inline SimplexId getCellEdgeNumber(const SimplexId &cellId) ---> 这个函数可返回cell中边的数目;
(3)也可以直接调用 inline const std::vector<std::vector<SimplexId> > *getCellEdges()得到整个 cell-边的大表,可直接访问任意cell的任意边信息
二维数据场:等价于GetTriangleEdge() / getTriangleEdgeNumber()
三维数据场:就调这个啦!
4.得到cell的邻居(理论上,也是cell),存储在cellNeighborList_
int getCellNeighbor(const SimplexId &cellId,const int &localNeighborId/*数组下标*/, SimplexId &neighborId/*全局ID*/)
SimplexId getCellNeighborNumber(const SimplexId &cellId); //得到cell neighbor个数
二维标量场:得到三角形
三维标量场:得到四面体
5.得到组成最高维cell的的三角形ID信息(这个cell是tetrehedra),存储在cellTriangleList_,
int getCellTriangle(const SimplexId &cellId,const int &localTriangleId, SimplexId &triangleId)
SimplexId getCellTriangleNumber(const SimplexId &cellId)
const std::vector<std::vector<SimplexId> > *getCellTriangles() // 这个粗暴野蛮,返回全部cell的组成三角形信息
附:vector< vector<SimplexId> > cellTriangleList_; //里面存储了组成本cell的每个三角形ID信息
如四面体的组成三角形:
cellTriangleList_[cellID][0] -->cellTriangleList_[cellID][1] --> cellTriangleList_[cellID][2] -->cellTriangleList_[cellID][3]
特别得:(1) 如果二维情况下,本函数等价于调用getCellNeighbor()
(2) 调用本函数,必须调用过耗时的preprocessCellTriangles()函数
6.得到组成cell的顶点ID信息,特别注意这个Cell也只指最高维simplicies的几何体(3D: tetrahedra, 2D: triangles, 1D: edges).
存储在:ExpliciteTriangluation:: const LongSimplexId *cellArray_; 这个一维数据中!
cellArray_[0]存储了每个cell的点的个数,本质上可以理解成三角面片OFF文件中三角面片的信息如:
3 1 2 3 # 一个cell包含3个顶点,三个顶点的ID分别是1 2 3
3 2 3 4 # 一个cell包含3个顶点,三个顶点的ID分别是2 3 4
如果是3维标量场,第一个数就是4了
inline SimplexId getCellVertexNumber(const SimplexId &cellId) const //每个CELL包含的点数,是常数!
{
return cellArray_[0]; //第一个Cell中点的个数,和其他所有cell包含的点的个数完全一致!
}
int getCellVertex(const SimplexId &cellId,const int &localVertexId, SimplexId &vertexId) // CellID中第localVertexId顶点ID
返回 vertexId = cellArray_[(cellArray_[0] + 1)*cellId + localVertexId + 1];
7.拓扑:求取某Edge连接顶点(输入:edgeId, 第localLinkId个顶点的ID),特别地:The output linkId refers in 2D to a vertex identifier and in 3D to an edge identifier. 也就是说2维向量场,返回的是连接的顶点id
inline int getEdgeLink(const SimplexId &edgeId, const int &localLinkId, SimplexId &linkId) const
SimplexId getEdgeLinkNumber(const SimplexId &edgeId);//某Edge邻接顶点个数!!!丛数据结构上看,这个连接顶点数不定!
说明:
在ExpliciteTriangle中存储在:vector< vector<SimplexId> > edgeLinkList_;
8. 得到一条边的所有邻接CEll数目(EdgeStar of Edge, 还有一个概念是Edge star of Vertex, 前者是得到边的邻接边,后者得到点的邻接三角形,所以在二维标量数据场上,一条边的starEdge最大是2,最小是1;如果是1,意味着它一定是边界边!); \
int getEdgeStar(const SimplexId &edgeId, const int &localStarId, SimplexId &starId
SimplexId getEdgeStarNumber(const SimplexId &edgeId)
const std::vector<std::vector<SimplexId> > *getEdgeStars()
如果2维标量场:EdgeStarNumber()/EdgeStar返回的是邻接三角形的个数或三角形!!!!
如果3维标量场:EdgeStarNumber()/EdgeStar返回的是临界四面体的个数或四面体!!!!
9. getEdgeTriangle(), 在2维向量场上面,这个函数等价于getEdgeStar(),E-T关系
对于三维向量场,这个函数求取以edgeId为边的三角形ID,返回的是triangleId
int getEdgeTriangle(const SimplexId &edgeId,const int &localTriangleId, SimplexId &triangleId)
SimplexId getEdgeTriangleNumber(const SimplexId &edgeId)
const std::vector<std::vector<SimplexId> > *getEdgeTriangles()
10.得到某条边的顶点信息,在1D情况下,等价于getCellVertex().
int getEdgeVertex(const SimplexId &edgeId, const int &localVertexId, SimplexId &vertexId) const
11.得到组成网络的单纯形的个数(3D: tetrahedra, 2D: triangles, 1D: edges),如果二维标量场,就是三角形个数
inline SimplexId getNumberOfCells() const
12.得到边的个数(二维标量场,就是正儿八经的边的个数,特别的:In 1D, equivalent to getNumberOfCells().)
SimplexId getNumberOfEdges() const
13.得到三角形的个数(In 2D, equivalent to getNumberOfCells(),即二维标量场等价于getNumberOfCells(),因为2D的cell就是三角形)
SimplexId getNumberOfTriangles() const
14. 得到顶点个数
SimplexId getNumberOfVertices()
15.在等于或高于三维时,求取三角形的全部 ID信息
SimplexId getNumberOfTriangles() const
const std::vector<std::vector<SimplexId> > *getTriangles()
在2维时,等价于
inline SimplexId getNumberOfCells() const
16.得到第triangleId个三角形的第localEdgeId条边的全局ID信息
inline int getTriangleEdge(const SimplexId &triangleId, const int &localEdgeId, SimplexId &edgeId) const
SimplexId getTriangleEdgeNumber(const SimplexId &triangleId)
std::vector<std::vector<SimplexId> > *getTriangleEdges() // 得到三角形表信息 ,如 3 1 2 3; 3 2 3 4; 3 4 5 6; 3 5 6 7.。。
17.三维标量场函数:得到三角形链接的顶点信息(triangleLink只有在三维向量场中才有意义,二维不需要考虑直接报错!!!!)
inline int getTriangleLink(const SimplexId &triangleId, const int &localLinkId, SimplexId &linkId) const
SimplexId getTriangleLinkNumber(const SimplexId &triangleId)
const std::vector<std::vector<SimplexId> > *getTriangleLinks()
18, 三维标量场函数(低于二维直接报错):得到三角形每条边邻接的四面体ID
int getTriangleStar(const SimplexId &triangleId, const int &localStarId, SimplexId &starId) const
SimplexId getTriangleStarNumber(const SimplexId &triangleId) const
std::vector<std::vector<SimplexId> > *getTriangleStars()
19. 得到三角形顶点信息(二维情况下,等价于getCellVertex()函数)
int getTriangleVertex(const SimplexId &triangleId, const int &localVertexId, SimplexId &vertexId)
20.得到链接顶点的边信息(In 1D, this function is equivalent to getVertexStar().)
inline int getVertexEdge(const SimplexId &vertexId, const int &localEdgeId, SimplexId &edgeId) const
SimplexId getVertexEdgeNumber(const SimplexId &vertexId) const
const std::vector<std::vector<SimplexId> > *getVertexEdges()
22.得到顶点的链接元素(2维:边,三维:三角形)
int getVertexLink(const SimplexId &vertexId, const int &localLinkId, SimplexId &linkId) const
SimplexId getVertexLinkNumber(const SimplexId &vertexId)
const const std::vector<std::vector<SimplexId> > *getVertexLinks()
23.得到顶点的邻居顶点信息
getVertexNeighbor(const SimplexId &vertexId, const int &localNeighborId, SimplexId &neighborId) const
SimplexId getVertexNeighborNumber(const SimplexId &vertexId) const
const std::vector<std::vector<SimplexId> > *getVertexNeighbors()
24.得到一个顶点的邻居CELL ID (3D: tetrahedra, 2D: triangles, 1D: edges) - Get the \p localStarId-th cell of the star of the vertexId-th vertex.
inline int getVertexStar(const SimplexId &vertexId, const int &localStarId, SimplexId &starId) const
SimplexId getVertexStarNumber(const SimplexId &vertexId) const
const std::vector<std::vector<SimplexId> > *getVertexStars()
如果2维标量场:某个顶点紧靠着的某个三角形
如果3维标量场:某个顶点紧靠着的某个四面体
25.得到某个点仅靠这的三角形(V-T,2D时等价于: getVertexStar())
inline int getVertexTriangle(const SimplexId &vertexId,const int &localTriangleId, SimplexId &triangleId) const
SimplexId getVertexTriangleNumber(const SimplexId &vertexId) const
const std::vector<std::vector<SimplexId> > *getVertexTriangles()
26。系列判断函数 及预处理函数(很多拓扑求解都依赖于此)
bool isEdgeOnBoundary(const SimplexId &edgeId) const
bool isEmpty() const
bool isTriangleOnBoundary(const SimplexId &triangleId) const
bool isVertexOnBoundary(const SimplexId &vertexId) const
int preprocessBoundaryEdges() //一定要在前面调用,否则哪些判断函数不可用
int preprocessBoundaryVertices()
int preprocessCellNeighbors() //调后才能调用 /// - getCellNeighbor() /// - getCellNeighbors() /// - getCellNeighborNumber()
int preprocessCellTriangles() //调后才能调用 /// \sa getCellTriangle() /// \sa getCellTriangles() /// \sa getCellTriangleNumber()
int preprocessEdgeLinks() / int preprocessEdgeStars() / int preprocessEdgeTriangles() / int preprocessTriangles()
int preprocessTriangleEdges() /....
27. 涉及是否在边界的数据结构,都是bool型数组,第i个节点在不在,直接查询:boundaryEdges_[i]
boundaryVertices_ //如果它所在的某条边是边界边,她就是边界点!所以遍历它的
boundaryTriangles_ // 只对三维标量场才有意义!!!!!!!!!!2维直接return 0
boundaryEdges_ // 判断第i条边是否边界,看edgeStarList_[i]的元素个数,如果为1,就是边界!!!
28.setInput函数,可以好好看看数据如何交互的。。。