33
44// //////// helpers to build the Object //////////
55
6- Object Surface::LoOutputOBJ3 (std::vector<glm::vec3> edgePoints)
6+ Object Surface::LoOutputOBJ (std::vector<glm::vec3> edgePoints)
77{
88 // build new Object class (Loop style)
99 std::vector<glm::vec3> VertexPos;
@@ -13,76 +13,28 @@ Object Surface::LoOutputOBJ3(std::vector<glm::vec3> edgePoints)
1313
1414 for (FaceRecord face : m_Faces)
1515 {
16- glm::vec3 vertA = m_Vertices[face.verticesIdx [0 ]].position ;
17- glm::vec3 vertB = m_Vertices[face.verticesIdx [1 ]].position ;
18- glm::vec3 vertC = m_Vertices[face.verticesIdx [2 ]].position ;
16+ int n = static_cast <int >(face.verticesIdx .size ());
1917
20- glm::vec3 edgeAB = edgePoints[getEdgeIndex ({ face.verticesIdx [0 ], face.verticesIdx [1 ] })];
21- glm::vec3 edgeBC = edgePoints[getEdgeIndex ({ face.verticesIdx [1 ], face.verticesIdx [2 ] })];
22- glm::vec3 edgeCA = edgePoints[getEdgeIndex ({ face.verticesIdx [2 ], face.verticesIdx [0 ] })];
23-
24- // use vertex lookup to avoid creating duplicate vertices
25- unsigned int vertAIdx = getVertIndex (vertA, VertexPos, VertLookup);
26- unsigned int vertBIdx = getVertIndex (vertB, VertexPos, VertLookup);
27- unsigned int vertCIdx = getVertIndex (vertC, VertexPos, VertLookup);
28- unsigned int edgeABIdx = getVertIndex (edgeAB, VertexPos, VertLookup);
29- unsigned int edgeBCIdx = getVertIndex (edgeBC, VertexPos, VertLookup);
30- unsigned int edgeCAIdx = getVertIndex (edgeCA, VertexPos, VertLookup);
31-
32- // create new faces (each original traingle will have 4 new triangles)
33- FaceIndices.push_back ({ vertAIdx, edgeABIdx, edgeCAIdx });
34- FaceIndices.push_back ({ edgeABIdx, vertBIdx, edgeBCIdx });
35- FaceIndices.push_back ({ edgeCAIdx, edgeBCIdx, vertCIdx });
36- FaceIndices.push_back ({ edgeCAIdx, edgeABIdx, edgeBCIdx });
37- NumberPolygons[3 ] += 4 ;
38- }
39-
40- // build object
41- Object Obj;
42- Obj.m_Min = m_Min; Obj.m_Max = m_Max;
43- Obj.m_VertexPos = VertexPos; Obj.m_FaceIndices = FaceIndices; Obj.m_TriFaceIndices = FaceIndices;
44- Obj.m_NumPolygons = NumberPolygons;
45-
46- return Obj;
47- }
48-
49- Object Surface::LoOutputOBJ4 (std::vector<glm::vec3> edgePoints)
50- {
51- // build new Object class (Loop style)
52- std::vector<glm::vec3> VertexPos;
53- std::unordered_map<float , std::unordered_map<float , std::unordered_map<float , unsigned int >>> VertLookup;
54- std::vector<std::vector<unsigned int >> FaceIndices;
55- std::unordered_map<int , int > NumberPolygons;
56-
57- for (FaceRecord face : m_Faces)
58- {
59- glm::vec3 vertA = m_Vertices[face.verticesIdx [0 ]].position ;
60- glm::vec3 vertB = m_Vertices[face.verticesIdx [1 ]].position ;
61- glm::vec3 vertC = m_Vertices[face.verticesIdx [2 ]].position ;
62- glm::vec3 vertD = m_Vertices[face.verticesIdx [3 ]].position ;
18+ std::vector<unsigned int > vertsIdx;
19+ std::vector<unsigned int > edgesIdx;
20+ for (int i = 0 ; i < n; i++)
21+ {
22+ glm::vec3 vert = m_Vertices[face.verticesIdx [i]].position ;
23+ vertsIdx.push_back (getVertIndex (vert, VertexPos, VertLookup));
6324
64- glm::vec3 edgeAB = edgePoints[getEdgeIndex ({ face.verticesIdx [0 ], face.verticesIdx [1 ] })];
65- glm::vec3 edgeBC = edgePoints[getEdgeIndex ({ face.verticesIdx [1 ], face.verticesIdx [2 ] })];
66- glm::vec3 edgeCD = edgePoints[getEdgeIndex ({ face.verticesIdx [2 ], face.verticesIdx [3 ] })];
67- glm::vec3 edgeDA = edgePoints[getEdgeIndex ({ face.verticesIdx [3 ], face.verticesIdx [0 ] })];
25+ glm::vec3 edge = edgePoints[getEdgeIndex ({ face.verticesIdx [i], face.verticesIdx [(i + 1 ) % n] })];
26+ edgesIdx.push_back (getVertIndex (edge, VertexPos, VertLookup));
27+ }
6828
69- // use vertex lookup to avoid creating duplicate vertices
70- unsigned int vertAIdx = getVertIndex (vertA, VertexPos, VertLookup);
71- unsigned int vertBIdx = getVertIndex (vertB, VertexPos, VertLookup);
72- unsigned int vertCIdx = getVertIndex (vertC, VertexPos, VertLookup);
73- unsigned int vertDIdx = getVertIndex (vertD, VertexPos, VertLookup);
74- unsigned int edgeABIdx = getVertIndex (edgeAB, VertexPos, VertLookup);
75- unsigned int edgeBCIdx = getVertIndex (edgeBC, VertexPos, VertLookup);
76- unsigned int edgeCDIdx = getVertIndex (edgeCD, VertexPos, VertLookup);
77- unsigned int edgeDAIdx = getVertIndex (edgeDA, VertexPos, VertLookup);
78- unsigned int FaceIdx = getVertIndex (face.facePoint , VertexPos, VertLookup);
29+ // every n-gon gets one n-gon inscribed inside, and gets n more triangles
30+ FaceIndices.push_back (edgesIdx);
31+ for (int i = 0 ; i < n; i++)
32+ {
33+ FaceIndices.push_back ({ vertsIdx[i], edgesIdx[i], edgesIdx[(i + n - 1 ) % n] });
34+ }
7935
80- // create new faces (each original quad will have 4 new quads)
81- FaceIndices.push_back ({ vertAIdx, edgeABIdx, FaceIdx, edgeDAIdx });
82- FaceIndices.push_back ({ vertBIdx, edgeBCIdx, FaceIdx, edgeABIdx });
83- FaceIndices.push_back ({ vertCIdx, edgeCDIdx, FaceIdx, edgeBCIdx });
84- FaceIndices.push_back ({ vertDIdx, edgeDAIdx, FaceIdx, edgeCDIdx });
85- NumberPolygons[4 ] += 4 ;
36+ NumberPolygons[n] += 1 ;
37+ NumberPolygons[3 ] += n;
8638 }
8739
8840 // build object
@@ -91,13 +43,15 @@ Object Surface::LoOutputOBJ4(std::vector<glm::vec3> edgePoints)
9143 Obj.m_VertexPos = VertexPos; Obj.m_FaceIndices = FaceIndices;
9244 Obj.m_NumPolygons = NumberPolygons;
9345 Obj.TriangulateFaces ();
46+
9447 return Obj;
9548}
9649
50+
9751// //////// algorithms //////////
9852
9953// Loop subdivision surface algorithm
100- Object Surface::Loop3 ()
54+ Object Surface::Loop ()
10155{
10256 // make new (odd) vertices (per edge)
10357 std::vector<glm::vec3> edgePoints (m_Edges.size ());
@@ -139,51 +93,5 @@ Object Surface::Loop3()
13993 }
14094 }
14195
142- return LoOutputOBJ3 (edgePoints);
143- }
144-
145- // Loop subdivision surface algorithm
146- Object Surface::Loop4 ()
147- {
148- // make new (odd) vertices (per edge)
149- std::vector<glm::vec3> edgePoints (m_Edges.size ());
150- for (int i = 0 ; i < edgePoints.size (); i++)
151- {
152- EdgeRecord currEdge = m_Edges[i];
153- if (currEdge.adjFacesIdx .size () == 1 ) // boundary edge
154- {
155- // ME point
156- edgePoints[i] = currEdge.midEdgePoint ;
157- }
158- else // edge borders 2 faces
159- {
160- // 3/8 face points + 2/8 edge point
161- edgePoints[i] = 0 .375f * m_Faces[currEdge.adjFacesIdx [0 ]].facePoint +
162- 0 .375f * m_Faces[currEdge.adjFacesIdx [1 ]].facePoint +
163- 0 .25f * currEdge.midEdgePoint ;
164- }
165- }
166-
167- // update old (even) vertices (per vertex)
168- for (int i = 0 ; i < m_Vertices.size (); i++)
169- {
170- VertexRecord vert = m_Vertices[i];
171- glm::vec3 vertPos = vert.position ;
172- float alpha = 0 .2f ;
173- glm::vec3 sumNeighbours{ 0 };
174- for (unsigned int adjEdge : vert.adjEdgesIdx )
175- {
176- sumNeighbours += 2 .0f * m_Edges[adjEdge].midEdgePoint - vertPos;
177- }
178- int neighbours = static_cast <int >(vert.adjEdgesIdx .size ());
179- if (neighbours == 3 )
180- m_Vertices[i].position = 0 .25f * vertPos + 0 .125f * sumNeighbours;
181- else
182- {
183- float invNeigh = 1 / (float )neighbours;
184- m_Vertices[i].position = (1 - alpha) * sumNeighbours * invNeigh + alpha * vertPos;
185- }
186- }
187-
188- return LoOutputOBJ4 (edgePoints);
96+ return LoOutputOBJ (edgePoints);
18997}
0 commit comments