Triangular mesh (Triangle mesh)
in the simplest case, a polygon mesh is just a list of polygons, and a triangular mesh is a polygon mesh that consists of all triangles. Polygonal and triangular meshes are widely used in graphics and modelling to simulate the surfaces of complex objects, such as buildings, vehicles, human bodies, and, of course, teapots. Figure 14.1 shows some examples:
Of course, any polygon mesh can be converted into a triangular mesh, the triangular mesh is attractive for its simplicity, and many operations are easier for triangular meshes than for the general polygon mesh.
1 means grid
Triangular meshes are a list of triangles, so the most straightforward way to represent them is with a triangular array:
Listing 14.1:a trivial representation of A triangle mesh
struct Triangle { Vector3 P[3]; };
struct Trianglemesh { int tricount; Triangle *trilist; };
For some applications, this representation is sufficient. However, the connectivity of adjacent triangles implied by the term "grid" is not reflected in this simple representation. Triangle meshes that appear in real-world applications, with each triangle sharing edges with other triangles. Thus, triangular grids need to store three types of information:
- Vertex. Each triangle has three vertices, and each vertex is likely to be shared with other triangles.
.
- Side. Connect the edges of two vertices with three edges per triangle.
.
- Surface. Each triangle corresponds to a polygon, and we can represent the polygon with a vertex or a list of edges.
1.1 Index Triangle grid
In the index triangle grid, we maintain two lists: the vertex table (Vertex buffer) and the Triangle Table (index buffer).
each vertex contains a 3D position, or it may be like additional data such as texture mapping coordinates, surface normals, illumination values, and so on.
Each triangle consists of three indexes of a vertex list. In general, the order in which vertices are listed is very important because we must consider the "front" and "opposite" faces. When viewed from the front, we will list the vertices in a clockwise direction. Other information is also available at this level, such as pre-computed surface normals, surface properties (texture mapping), and so on.
The program listing 14.2 shows a highly simplified code: Listing 14.2:indexed Triangle mesh //struct Vertex is the information we store at the Vertex level Struc T vertex { //3D position of the Vertex Vector3 p; /Other information could include texture mapping coordinates, //a surface norm AL, lighting values, etc. } //struct Triangle is the information we store at the Triangle level struct Trian GLE&NBSP { //Indices into the vertex list int vertex[3]; /Other information could include a normal, material information, etc. } //struct TRIANGLEME SH stores an indexed triangle mesh struct trianglemesh { //The vertices INT Vertexcount; Vertex *vertexlist; //The triangles int trianglecount; Triangle *trianglelist; };
In practice, a triangular grid class will have a series of methods for accessing and maintaining vertices and triangle lists. Of course, storing polygon meshes also requires defining a polygon class to represent polygons with any number of vertices. To simplify and improve efficiency, we can limit the maximum number of fixed points per polygon. Notice that the adjacency information in the index triangle list is implicit. For example, the edge information is not stored directly, but we can still find the common edges by searching the triangle table. This approach does save a lot of space compared to the previous "triangular array" approach. The reason is that the information is at the vertex level, and its integer index is much smaller than the repetition rate of the vertices stored in the triangular array.
1.2 Advanced Technology
simple indexed triangular meshes are sufficient for basic applications, but some improvements can be made to implement some operations more efficiently. The main problem is that the adjacency information is not explicitly expressed, so you must search from the triangle list. Another expression method can obtain this information in a constant time.
by maintaining a list of edges, each edge is defined by two endpoints, while maintaining a list of triangles that share that edge. In this way, the triangle is visible as a list of three edges instead of three points, which means that it is the index of the edge list instead of the point list. An extension of the idea is called the "winged edge" model, which stores the index of the edges that use that point for each vertex.
2 Special expressions for rendering
Most graphics cards do not directly support the indexing triangle, and when rendering a triangle, it is common to submit three vertices simultaneously. In this way, the shared vertices are committed multiple times, and the triangles are submitted one at a time. Because data transfer between memory and graphics hardware is a bottleneck, many APIs and hardware support special triangular network formats to reduce the amount of traffic. The basic idea is to sort the points and polygons so that existing triangles do not need to be transferred again.
from maximum flexibility to minimum flexibility, we discuss three scenarios: Vertex cache, triangle band, triangle fan.
2.1 Vertex Cache
vertex caching is not so much a special storage format as a kind of storage strategy between API and hardware, which is used to realize the consistency of successive triangular vertices. In general, advanced Code does not need to know how the vertex cache is implemented and executed.
similar to other caching mechanisms, vertex caching is based on the principle that the most recently used data will still be used in the future. The graphics processor caches a fraction of the most recently used vertices, such as 16, and when the API sends vertices, it first detects if the cache already exists. Of course, this requires the API to understand the size and replacement mechanism of the graphics card cache. If the vertex is not in the cache, an off-target occurs, the API sends vertices and updates the cache, and if the vertex is within the cache, the API notifies the graphics card to "Use the vertex of location X in cache".
Vertex caching is actually a bottom-up optimization method, and any triangulation can be rendered correctly using advanced code without regard to caching. However, the vertex order is adjusted so that the triangular centralized sending of shared vertices can help improve efficiency. This adjustment only needs to be done once and can be done offline, and it will only be useful for performance and will not degrade the system without caching. The use of caching can reduce the number of vertices sent to the video card to an average of less than one per triangle.
2.2 Triangle Belt
A triangle is a list of triangles in which each triangle shares one side with the previous triangle, and figure 14.2 shows an example of a triangle band.
Note that the order in which vertices are listed makes it possible to make a triangle for every three consecutive points. For example:
- Vertices 1, 2, and 3 form the first triangle.
.
- Vertices 2, 3, and 4 form the second triangle.
.
- Vertices 3, 4, and 5 form a third triangle.
In Figure 14.2, the vertices are numbered in the order in which they form the triangle bands. The index information is no longer needed because the vertex order has implicitly defined the triangle. Typically, the front of the list has a number of vertices, or a special code at the end indicates "End of list."
Notice that the vertex order is constantly changing between the clockwise pointer and the counterclockwise (see Figure 14.3). On some platforms, you need to point out the order of the vertices of the first triangle, while some of the platforms are fixed in order.
In the best case, the triangle band can store n polygons with n+2 vertices. When n is large, each triangle sends a vertex on average, which, unfortunately, is just the best case. In practice, many meshes are a triangular band that cannot be expressed, and more than 3 triangles shared by the vertices are sent to the graphics card multiple times. On the other hand, each triangle sends at least one vertex. In the vertex caching mechanism, however, it is possible to reduce the number of vertices sent per triangle to less than one. Of course, the vertex cache requires additional bookkeeping information (index and cache management data), but although these additional information is relatively large for a single vertex, the operating speed is also relatively slow, but the system that sends the fewest number of vertices is the fastest on a particular platform.
Assuming that a direct method of generating a triangular band is used, the triangular band is used to represent the number of vertices required for t+2s,t, and S is the number of triangular bands. The first triangle of each triangle corresponds to three vertices, and each triangle corresponds to one vertex at a time. Because we want to minimize the number of vertices sent to the graphics card, the number of triangles should be as little as possible, that is, the longer the triangle, the better. The stripe method is used to generate a new approach to the theoretical lower limit of the number of triangular bands.
Another reason to reduce the number of triangle bands is that it takes extra time to build the triangles. On the other hand, it takes longer to render a two-n-long triangle band than to render a triangular band with a length of 2n, even if the triangle in the triangle has more than two triangles in a separate band. As a result, we often use degenerate triangles to connect multiple triangular bands, thus placing the entire grid in a continuous triangular zone, which means that the area is 0. Figure 14.4 shows how vertices are repeated to merge two triangles into one.
The meaning of Figure 14.4 is less obvious, but there are four degenerate triangles for connecting two triangular bands to maintain the correct clockwise and counterclockwise order. The edges between vertices 7 and 8 actually contain two degenerate triangles, and figure 14.5 shows the triangles contained in Figure 14.4.
A degenerate triangular area of 0 does not require rendering, so it does not affect efficiency. The vertices that are actually sent to the graphics card are still just the vertices of the first column:
1,2,3,4,5,6,7,8,9,10,11,12,13
This conforms to the Convention of each of our three successive vertices representing a triangle.
Some hardware, such as GS on PS2, can skip triangles in the triangle by indicating that the "do not have to draw" triangle is indicated by a flag bit on a vertex. This gives us a way to effectively start a new triangle band from any point without having to repeat vertices or use degenerate triangles. For example, the two triangle bands in Figure 14.4 can be connected as 14.6, where Gray indicates that the vertices are labeled "do not have to be drawn."
2.3 Triangle Fan
Triangular fans are similar to triangular bands, but they are less flexible than triangular bands, so they are seldom used. The triangle fan is shown in Figure 14.7.
The triangle fan uses n+2 vertices to store n polygons, which are the same as the triangle bands. However, the first vertex must be shared for all triangles, so it is not always possible to find large triangular fan applications in practice. Also, the triangle fan cannot be connected like a triangular band. Therefore, the triangle fan can only be used in special occasions, for the general application, the Triangle belt more flexible.
The 33 corner mesh holds extra information at the triangle or vertex level.
3.1 Texture mapping coordinates
texture mapping is the process of pasting a bitmap (called a "texture" or short "texture") onto a polygon surface. Here is a highly simplified explanation: we want to paste the texture onto the polygon surface, taking into account the direction of the polygon in the camera space. The 2D texture mapping coordinates are computed for each pixel in the polygon that needs to be rendered, and these coordinates are used to index the texture map to color the corresponding pixels.
in general, texture mapping coordinates are saved at the vertex, and the coordinates of the remaining points in the Triangle polygon are calculated by interpolation.
3.2 surface normal vector
in many applications, a surface normal vector is required for each point on the grid. It can be used to:
- Calculates the light.
.
- Remove the back.
.
- Simulates the effect of "bouncing" particles on the surface.
.
- The collision detection is accelerated by considering only the positive.
surface Normal vectors may be stored at the triangle or vertex level, or both.
triangle-level normal vectors can be easily obtained by means of two-vector cross-multiplication, while the calculation of vertex-level normal vectors is difficult. First, it should be noted that there is no normal vector definition at the vertex, because the mesh surface is not contiguous here. Second, the triangular network is a continuous surface approximation, so what we actually want is a continuous surface of the normal vector. According to the method of generating triangulation, this kind of information is not necessarily readily available. If the mesh is automatically generated, say from the parametric surface, you can get the normal vector directly.
Joffa vectors are not provided, they are generated with ready-made data (vertex positions and triangles). One technique is to mean the surface normal vectors of the average neighboring triangles and standardize the results. Of course, this requires knowing the triangle normal vector. It is generally assumed that the triangle vertices are listed clockwise and the normal vector of the outer surface is calculated by cross-multiplication. If the vertex order cannot be assumed, you can use the method suggested by Glassner.
It is an empirical method to derive the vertex normal vector by means of the average triangle method, which can work well in most cases. However, it is necessary to point out that, in some cases, the results are not expected. The most obvious example is that the two normal vectors of the opposite triangle share a vertex. This situation often occurs on "bulletin board" objects. The "bulletin board" consists of two triangles back-to-back, and its two normal vectors are in the opposite direction, with an average of 0 not standardized. To solve this problem, the so-called "double-sided" triangles must be disassembled.
Another problem with the mean vertex normal vector occurs when the Gouraud coloring is applied, and here is a simplified explanation: the illumination is calculated by point by vertex method. If you use the vertex normal vector computed by the average triangle method vector, some areas that should have sharp edges will appear "too smooth". Take the simplest box for example, there should be a drastic change of care at the edge. If we use the mean vertex normal vector, this drastic change will disappear. 14.8 is shown below:
The fundamental problem is that the edges of the box are discontinuous , and this discontinuity is not very well expressed because there is only one normal vector for each vertex. In fact, you can still use polygon splitting to solve the problem: in other words, repeat vertices at discontinuous points. After doing so, artificial constructs a discontinuity to prevent the vertex normals from being averaged. This "crack" can cause problems in a grid topology, but there are no problems in tasks such as rendering, ray tracing, and so on.
Another small problem is that this average results in a delta offset to more of the same normal vector. For example, several triangles share a vertex, but two of them are coplanar. The average normal vector is offset, since the normal vector of the coplanar triangle repeats two times, with more "say" than other normal vectors. Thus, even if the surface does not change, the vertex normal vector will change. We can fix this error, but fortunately this is not a big problem in practice because the vertex normal vector is an approximation.
3.3 Illumination Value
Another information that is often maintained by vertices is the illumination value. These illumination values are used to interpolate along the surface, and the typical method is Gouraud coloring. In some cases, only normal vectors are stored at the vertex, and the illumination values are dynamically computed during rendering.
4 topology and consistency
A triangular grid topology is a triangular mesh with the same number of vertices and triangular interconnects that are identical when the logical connectivity of the vertex position to other geometric properties is not considered in the triangular mesh, even if the corresponding object is completely different. On the other hand, although the shapes are different, stretching the mesh without breaking the adjacency, we get the same topology as the grid.
there is a special mesh called a closed network, also known as a "manifold." Conceptually, the closed mesh perfectly covers the surface of the object, there is no gap in the mesh, and the back of any triangle cannot be seen from the outside. This is an important grid, its point and edge composition is like a plan, that is, if the vertex as a planar point, with a straight line to connect vertices, this closed mesh can be drawn on a 2D plane, and no edge intersection. The plan conforms to the Euler equation: v-e+f=2, where V is the number of vertices, E is the number of edges, and F is the number of polygons on the mesh.
in practice, we often encounter topological anomalies in the triangular meshes, resulting in a mesh that is not closed:
- Orphaned vertices: vertices are not used by any triangles.
.
- Repeating vertices: exactly the same vertex. The triangles using these points are geometrically contiguous and logically nonadjacent, and in most cases we do not want to see this phenomenon and should be removed.
.
- Degenerate triangle: a triangle that uses a vertex more than once. This means that the triangle has no area, and the triangle should be removed in general.
.
- Open edges: Used only for one triangle.
.
- More than two triangles shared edges: In a closed grid, you must share two triangles on either side.
.
- Repeating polygon: The mesh contains two or more identical faces. This is not to be seen, should be removed from the extra face and only one.
.
depending on the application, the above exception may be a serious error, a minor error, or insignificant.
5 Triangulation/point operation
a triangular mesh is a list of vertices and triangles. A series of basic operations for triangular meshes are the result of applying basic operations on a point-and-by-triangle basis. Most obviously, rendering and conversion are all part of this operation. To render triangular meshes, we render each triangle one by one, such as to apply transformations to a triangular grid, such as rotation and scaling, by vertex.
5.1 weld vertices
when two or more vertices (which may have errors), it is useful to weld them together. To be more precise, delete the rest, only one left. For example, we want to weld A and B in Figure 14.9, with two steps:
- Step 1, scan the triangle list and replace all references to B with a reference to a.
.
- Step 2, now B is an outlier and removes it from the list of vertices.
The weld vertex has two purposes. First, remove duplicate vertices and save memory. This is an important optimization method that makes operations on the grid (such as rendering and conversion) faster. Second, the adjacent edges of the geometry are logically adjacent.
The above discussion is the welding of two vertices, in practice, we often want to find out all the vertices adjacent to the weld point. The idea is very straightforward, but there are a few details that need to be clarified.
(1) Before soldering should remove the outliers, we do not want to let any unused points affect the points being used, as shown in 14.10:
(2) When two vertices are from a "slender" triangle, the weld may produce a degenerate triangle, as shown in 14.11 (this is similar to the edge collapse). Such triangles should be removed, usually with a small number of them. Welding often significantly reduces the number of vertices, while also removing a small portion of slender faces.
(3) When soldering, it seems that the average of the original vertex should be used as a new vertex, rather than simply choosing one and discarding the other. This approach does not favor any vertex, which seems like a good idea when only a small number of vertices need to be welded. However, the automatic welding can cause a "domino" effect, resulting in the original not within the error tolerance of the multiple points are welded.
In figure 14.12, points A and B should be welded in the error tolerance. We "intelligently" weld these two points, calculating the average of a and B to get a new point d. Now C and D are welded within the tolerance range, resulting in E. The result is that points A and C are welded, they are not within the error tolerance. Also, our "smart" attempts have failed because a, B and C are welded, but the result is not the average of these three points.
This is not the worst case, at least there is no point running out of error tolerance. But it is true that this vicious example can be made intentionally with more vertices and in different sequences, and, more unfortunately, in practice, the modeling program and the automatic generation program often do so. In fact, even if the new coordinates are not generated evenly, there will still be problems. For example, regardless of the average coordinate, you can solve this problem by applying a simple rule "always spot the high-order number to the low ordinal vertex".
There are some ways to prevent these problems. For example, you can find the vertex groups within all tolerance limits, weld them, or not consider the vertices that have already been welded, or record the original vertex coordinates, which are not welded when the vertices are outside the tolerance. These methods are too complex, and we should not add complexity to non-significant performance. Welding is to remove the duplicate vertices, not for the mesh reduction: that is, a large number of reduction of the number of triangles, and try to keep the shape of the triangular network unchanged. For mesh reduction, more advanced algorithms must be used.
Another problem is the additional information about the triangular network, such as surface normal vectors, texture mapping coordinates, and so on. When the point is welded, the previous discontinuity disappears, and figure 14.8 is an example.
Finally, the direct implementation of vertex welding is very slow. Even under today's hardware conditions, thousands of-point and face-to-face welding takes a few seconds. The algorithm for finding weld vertex pairs is O (N2) complexity. The vertex index substitution after one weld needs to traverse the entire triangle list; Deleting a vertex also requires traversing the triangle list to fix the index of the vertex that is higher than the delete point ordinal. Fortunately, to think about it, we can find a much faster algorithm.
5.2 Side Split
polygon splits copy vertices so that the edges are no longer shared, and it is just the opposite of welding. Obviously, polygon splits cause topological discontinuities because polygons are no longer contiguous. And that's what we're aiming at, where the geometric discontinuity of the local topology is also intermittent (such as corners and edges). Figure 14.13 shows the split of the two triangles, although we separate the two triangles to show that there are multiple edges and vertices, just to show that the vertices are not moving and that the new vertices and edges are actually coincident.
in practice, we often have to split all the faces.
5.3 Edge collapse
Edge Collapsing is the method of reducing edges to vertices, which corresponds to vertex splitting. 14.14, notice that the edge collapse causes the two vertices of the edge to become one, and the triangles that share the edge (the shaded part in Figure 14.14) disappear. Edge collapse is often used for mesh reduction because it reduces the number of vertices and triangles.
5.4 Mesh Reduction
mesh reduction is a mesh with a large number of triangles and vertices into a grid with a relatively small number of triangles and vertices, and requires the grid appearance and primary vertices to remain as unchanged as possible. Hugues Hoppe points out that the Zhi can achieve good results by only using edge collapse, and choosing the edge to collapse is relatively time-consuming, depending on the complexity of the heuristic method. Although it takes a long time to select a collapsed object, the collapse operation itself is not complex. We can record this process offline and "replay" it when needed in real time to get the style of any fine program. Hoppe's paper describes how vertex splitting can be used to reverse the edge collapse process, and the mesh generated by this inversion method is called the progressive mesh.
From:http://www.cppblog.com/lovedday/archive/2008/03/02/43554.html Http://www.cppblog.com/lovedday/archive/2008/03/02/43557.html Http://www.cppblog.com/lovedday/archive/2008/03/02/43565.html Http://www.cppblog.com/lovedday/archive/2008/03/02/43570.html |