/src/assimp/contrib/Open3DGC/o3dgcTriangleListDecoder.inl
Line | Count | Source |
1 | | /* |
2 | | Copyright (c) 2013 Khaled Mammou - Advanced Micro Devices, Inc. |
3 | | |
4 | | Permission is hereby granted, free of charge, to any person obtaining a copy |
5 | | of this software and associated documentation files (the "Software"), to deal |
6 | | in the Software without restriction, including without limitation the rights |
7 | | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
8 | | copies of the Software, and to permit persons to whom the Software is |
9 | | furnished to do so, subject to the following conditions: |
10 | | |
11 | | The above copyright notice and this permission notice shall be included in |
12 | | all copies or substantial portions of the Software. |
13 | | |
14 | | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
15 | | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
16 | | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
17 | | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
18 | | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
19 | | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
20 | | THE SOFTWARE. |
21 | | */ |
22 | | |
23 | | #pragma once |
24 | | #ifndef O3DGC_TRIANGLE_LIST_DECODER_INL |
25 | | #define O3DGC_TRIANGLE_LIST_DECODER_INL |
26 | | |
27 | | namespace o3dgc |
28 | | { |
29 | | template<class T> |
30 | | O3DGCErrorCode TriangleListDecoder<T>::Init(T * const triangles, |
31 | | const long numTriangles, |
32 | | const long numVertices, |
33 | | const long maxSizeV2T) |
34 | 0 | { |
35 | 0 | assert(numVertices > 0); |
36 | 0 | assert(numTriangles > 0); |
37 | 0 | m_numTriangles = numTriangles; |
38 | 0 | m_numVertices = numVertices; |
39 | 0 | m_triangles = triangles; |
40 | 0 | m_vertexCount = 0; |
41 | 0 | m_triangleCount = 0; |
42 | 0 | m_itNumTFans = 0; |
43 | 0 | m_itDegree = 0; |
44 | 0 | m_itConfig = 0; |
45 | 0 | m_itOperation = 0; |
46 | 0 | m_itIndex = 0; |
47 | 0 | if (m_numVertices > m_maxNumVertices) |
48 | 0 | { |
49 | 0 | m_maxNumVertices = m_numVertices; |
50 | 0 | delete [] m_visitedVerticesValence; |
51 | 0 | delete [] m_visitedVertices; |
52 | 0 | m_visitedVerticesValence = new long [m_numVertices]; |
53 | 0 | m_visitedVertices = new long [m_numVertices]; |
54 | 0 | } |
55 | | |
56 | 0 | if (m_decodeTrianglesOrder && m_tempTrianglesSize < m_numTriangles) |
57 | 0 | { |
58 | 0 | delete [] m_tempTriangles; |
59 | 0 | m_tempTrianglesSize = m_numTriangles; |
60 | 0 | m_tempTriangles = new T [3*m_tempTrianglesSize]; |
61 | 0 | } |
62 | |
|
63 | 0 | m_ctfans.SetStreamType(m_streamType); |
64 | 0 | m_ctfans.Allocate(m_numVertices, m_numTriangles); |
65 | 0 | m_tfans.Allocate(2 * m_numVertices, 8 * m_numVertices); |
66 | | |
67 | | // compute vertex-to-triangle adjacency information |
68 | 0 | m_vertexToTriangle.AllocateNumNeighborsArray(numVertices); |
69 | 0 | long * numNeighbors = m_vertexToTriangle.GetNumNeighborsBuffer(); |
70 | 0 | for(long i = 0; i < numVertices; ++i) |
71 | 0 | { |
72 | 0 | numNeighbors[i] = maxSizeV2T; |
73 | 0 | } |
74 | 0 | m_vertexToTriangle.AllocateNeighborsArray(); |
75 | 0 | m_vertexToTriangle.ClearNeighborsArray(); |
76 | 0 | return O3DGC_OK; |
77 | 0 | } |
78 | | template<class T> |
79 | | O3DGCErrorCode TriangleListDecoder<T>::Decompress() |
80 | 0 | { |
81 | 0 | for(long focusVertex = 0; focusVertex < m_numVertices; ++focusVertex) |
82 | 0 | { |
83 | 0 | if (focusVertex == m_vertexCount) |
84 | 0 | { |
85 | 0 | m_vertexCount++; // insert focusVertex |
86 | 0 | } |
87 | 0 | CompueLocalConnectivityInfo(focusVertex); |
88 | 0 | DecompressTFAN(focusVertex); |
89 | 0 | } |
90 | 0 | return O3DGC_OK; |
91 | 0 | } |
92 | | template<class T> |
93 | | O3DGCErrorCode TriangleListDecoder<T>::Reorder() |
94 | 0 | { |
95 | 0 | if (m_decodeTrianglesOrder) |
96 | 0 | { |
97 | 0 | unsigned long itTriangleIndex = 0; |
98 | 0 | long prevTriangleIndex = 0; |
99 | 0 | long t; |
100 | 0 | memcpy(m_tempTriangles, m_triangles, m_numTriangles * 3 * sizeof(T)); |
101 | 0 | for(long i = 0; i < m_numTriangles; ++i) |
102 | 0 | { |
103 | 0 | t = m_ctfans.ReadTriangleIndex(itTriangleIndex) + prevTriangleIndex; |
104 | 0 | assert( t >= 0 && t < m_numTriangles); |
105 | 0 | memcpy(m_triangles + 3 * t, m_tempTriangles + 3 * i, sizeof(T) * 3); |
106 | 0 | prevTriangleIndex = t + 1; |
107 | 0 | } |
108 | 0 | } |
109 | 0 | return O3DGC_OK; |
110 | 0 | } |
111 | | template<class T> |
112 | | O3DGCErrorCode TriangleListDecoder<T>::CompueLocalConnectivityInfo(const long focusVertex) |
113 | 0 | { |
114 | 0 | long t = 0; |
115 | 0 | long p, v; |
116 | 0 | m_numConqueredTriangles = 0; |
117 | 0 | m_numVisitedVertices = 0; |
118 | 0 | for(long i = m_vertexToTriangle.Begin(focusVertex); (t >= 0) && (i < m_vertexToTriangle.End(focusVertex)); ++i) |
119 | 0 | { |
120 | 0 | t = m_vertexToTriangle.GetNeighbor(i); |
121 | 0 | if ( t >= 0) |
122 | 0 | { |
123 | 0 | ++m_numConqueredTriangles; |
124 | 0 | p = 3*t; |
125 | | // extract visited vertices |
126 | 0 | for(long k = 0; k < 3; ++k) |
127 | 0 | { |
128 | 0 | v = m_triangles[p+k]; |
129 | 0 | if (v > focusVertex) // vertices are insertices by increasing traversal order |
130 | 0 | { |
131 | 0 | bool foundOrInserted = false; |
132 | 0 | for (long j = 0; j < m_numVisitedVertices; ++j) |
133 | 0 | { |
134 | 0 | if (v == m_visitedVertices[j]) |
135 | 0 | { |
136 | 0 | m_visitedVerticesValence[j]++; |
137 | 0 | foundOrInserted = true; |
138 | 0 | break; |
139 | 0 | } |
140 | 0 | else if (v < m_visitedVertices[j]) |
141 | 0 | { |
142 | 0 | ++m_numVisitedVertices; |
143 | 0 | for (long h = m_numVisitedVertices-1; h > j; --h) |
144 | 0 | { |
145 | 0 | m_visitedVertices[h] = m_visitedVertices[h-1]; |
146 | 0 | m_visitedVerticesValence[h] = m_visitedVerticesValence[h-1]; |
147 | 0 | } |
148 | 0 | m_visitedVertices[j] = v; |
149 | 0 | m_visitedVerticesValence[j] = 1; |
150 | 0 | foundOrInserted = true; |
151 | 0 | break; |
152 | 0 | } |
153 | 0 | } |
154 | 0 | if (!foundOrInserted) |
155 | 0 | { |
156 | 0 | m_visitedVertices[m_numVisitedVertices] = v; |
157 | 0 | m_visitedVerticesValence[m_numVisitedVertices] = 1; |
158 | 0 | m_numVisitedVertices++; |
159 | 0 | } |
160 | 0 | } |
161 | 0 | } |
162 | 0 | } |
163 | 0 | } |
164 | | // re-order visited vertices by taking into account their valence (i.e., # of conquered triangles incident to each vertex) |
165 | | // in order to avoid config. 9 |
166 | 0 | if (m_numVisitedVertices > 2) |
167 | 0 | { |
168 | 0 | long y; |
169 | 0 | for(long x = 1; x < m_numVisitedVertices; ++x) |
170 | 0 | { |
171 | |
|
172 | 0 | if (m_visitedVerticesValence[x] == 1) |
173 | 0 | { |
174 | 0 | y = x; |
175 | 0 | while( (y > 0) && (m_visitedVerticesValence[y] < m_visitedVerticesValence[y-1]) ) |
176 | 0 | { |
177 | 0 | swap(m_visitedVerticesValence[y], m_visitedVerticesValence[y-1]); |
178 | 0 | swap(m_visitedVertices[y], m_visitedVertices[y-1]); |
179 | 0 | --y; |
180 | 0 | } |
181 | 0 | } |
182 | 0 | } |
183 | 0 | } |
184 | 0 | return O3DGC_OK; |
185 | 0 | } |
186 | | template<class T> |
187 | | O3DGCErrorCode TriangleListDecoder<T>::DecompressTFAN(const long focusVertex) |
188 | 0 | { |
189 | 0 | long ntfans; |
190 | 0 | long degree, config; |
191 | 0 | long op; |
192 | 0 | long index; |
193 | 0 | long k0, k1; |
194 | 0 | long b, c, t; |
195 | |
|
196 | 0 | ntfans = m_ctfans.ReadNumTFans(m_itNumTFans); |
197 | 0 | if (ntfans > 0) |
198 | 0 | { |
199 | 0 | for(long f = 0; f != ntfans; f++) |
200 | 0 | { |
201 | 0 | m_tfans.AddTFAN(); |
202 | 0 | degree = m_ctfans.ReadDegree(m_itDegree) +2 - m_numConqueredTriangles; |
203 | 0 | config = m_ctfans.ReadConfig(m_itConfig); |
204 | 0 | k0 = m_tfans.GetNumVertices(); |
205 | 0 | m_tfans.AddVertex(focusVertex); |
206 | 0 | switch(config) |
207 | 0 | { |
208 | 0 | case 0:// ops: 1000001 vertices: -1 -2 |
209 | 0 | m_tfans.AddVertex(m_visitedVertices[0]); |
210 | 0 | for(long u = 1; u < degree-1; u++) |
211 | 0 | { |
212 | 0 | m_visitedVertices[m_numVisitedVertices++] = m_vertexCount; |
213 | 0 | m_tfans.AddVertex(m_vertexCount++); |
214 | 0 | } |
215 | 0 | m_tfans.AddVertex(m_visitedVertices[1]); |
216 | 0 | break; |
217 | 0 | case 1: // ops: 1xxxxxx1 vertices: -1 x x x x x -2 |
218 | 0 | m_tfans.AddVertex(m_visitedVertices[0]); |
219 | 0 | for(long u = 1; u < degree-1; u++) |
220 | 0 | { |
221 | 0 | op = m_ctfans.ReadOperation(m_itOperation); |
222 | 0 | if (op == 1) |
223 | 0 | { |
224 | 0 | index = m_ctfans.ReadIndex(m_itIndex); |
225 | 0 | if ( index < 0) |
226 | 0 | { |
227 | 0 | m_tfans.AddVertex(m_visitedVertices[-index-1]); |
228 | 0 | } |
229 | 0 | else |
230 | 0 | { |
231 | 0 | m_tfans.AddVertex(index + focusVertex); |
232 | 0 | } |
233 | 0 | } |
234 | 0 | else |
235 | 0 | { |
236 | 0 | m_visitedVertices[m_numVisitedVertices++] = m_vertexCount; |
237 | 0 | m_tfans.AddVertex(m_vertexCount++); |
238 | 0 | } |
239 | 0 | } |
240 | 0 | m_tfans.AddVertex(m_visitedVertices[1]); |
241 | 0 | break; |
242 | 0 | case 2: // ops: 00000001 vertices: -1 |
243 | 0 | for(long u = 0; u < degree-1; u++) |
244 | 0 | { |
245 | 0 | m_visitedVertices[m_numVisitedVertices++] = m_vertexCount; |
246 | 0 | m_tfans.AddVertex(m_vertexCount++); |
247 | 0 | } |
248 | 0 | m_tfans.AddVertex(m_visitedVertices[0]); |
249 | 0 | break; |
250 | 0 | case 3: // ops: 00000001 vertices: -2 |
251 | 0 | for(long u=0; u < degree-1; u++) |
252 | 0 | { |
253 | 0 | m_visitedVertices[m_numVisitedVertices++] = m_vertexCount; |
254 | 0 | m_tfans.AddVertex(m_vertexCount++); |
255 | 0 | } |
256 | 0 | m_tfans.AddVertex(m_visitedVertices[1]); |
257 | 0 | break; |
258 | 0 | case 4: // ops: 10000000 vertices: -1 |
259 | 0 | m_tfans.AddVertex(m_visitedVertices[0]); |
260 | 0 | for(long u = 1; u < degree; u++) |
261 | 0 | { |
262 | 0 | m_visitedVertices[m_numVisitedVertices++] = m_vertexCount; |
263 | 0 | m_tfans.AddVertex(m_vertexCount++); |
264 | 0 | } |
265 | 0 | break; |
266 | 0 | case 5: // ops: 10000000 vertices: -2 |
267 | 0 | m_tfans.AddVertex(m_visitedVertices[1]); |
268 | 0 | for(long u = 1; u < degree; u++) |
269 | 0 | { |
270 | 0 | m_visitedVertices[m_numVisitedVertices++] = m_vertexCount; |
271 | 0 | m_tfans.AddVertex(m_vertexCount++); |
272 | 0 | } |
273 | 0 | break; |
274 | 0 | case 6:// ops: 00000000 vertices: |
275 | 0 | for(long u = 0; u < degree; u++) |
276 | 0 | { |
277 | 0 | m_visitedVertices[m_numVisitedVertices++] = m_vertexCount; |
278 | 0 | m_tfans.AddVertex(m_vertexCount++); |
279 | 0 | } |
280 | 0 | break; |
281 | 0 | case 7: // ops: 1000001 vertices: -2 -1 |
282 | 0 | m_tfans.AddVertex(m_visitedVertices[1]); |
283 | 0 | for(long u = 1; u < degree-1; u++) |
284 | 0 | { |
285 | 0 | m_visitedVertices[m_numVisitedVertices++] = m_vertexCount; |
286 | 0 | m_tfans.AddVertex(m_vertexCount++); |
287 | 0 | } |
288 | 0 | m_tfans.AddVertex(m_visitedVertices[0]); |
289 | 0 | break; |
290 | 0 | case 8: // ops: 1xxxxxx1 vertices: -2 x x x x x -1 |
291 | 0 | m_tfans.AddVertex(m_visitedVertices[1]); |
292 | 0 | for(long u = 1; u < degree-1; u++) |
293 | 0 | { |
294 | 0 | op = m_ctfans.ReadOperation(m_itOperation); |
295 | 0 | if (op == 1) |
296 | 0 | { |
297 | 0 | index = m_ctfans.ReadIndex(m_itIndex); |
298 | 0 | if ( index < 0) |
299 | 0 | { |
300 | 0 | m_tfans.AddVertex(m_visitedVertices[-index-1]); |
301 | 0 | } |
302 | 0 | else |
303 | 0 | { |
304 | 0 | m_tfans.AddVertex(index + focusVertex); |
305 | 0 | } |
306 | 0 | } |
307 | 0 | else |
308 | 0 | { |
309 | 0 | m_visitedVertices[m_numVisitedVertices++] = m_vertexCount; |
310 | 0 | m_tfans.AddVertex(m_vertexCount++); |
311 | 0 | } |
312 | 0 | } |
313 | 0 | m_tfans.AddVertex(m_visitedVertices[0]); |
314 | 0 | break; |
315 | 0 | case 9: // general case |
316 | 0 | for(long u = 0; u < degree; u++) |
317 | 0 | { |
318 | 0 | op = m_ctfans.ReadOperation(m_itOperation); |
319 | 0 | if (op == 1) |
320 | 0 | { |
321 | 0 | index = m_ctfans.ReadIndex(m_itIndex); |
322 | 0 | if ( index < 0) |
323 | 0 | { |
324 | 0 | m_tfans.AddVertex(m_visitedVertices[-index-1]); |
325 | 0 | } |
326 | 0 | else |
327 | 0 | { |
328 | 0 | m_tfans.AddVertex(index + focusVertex); |
329 | 0 | } |
330 | 0 | } |
331 | 0 | else |
332 | 0 | { |
333 | 0 | m_visitedVertices[m_numVisitedVertices++] = m_vertexCount; |
334 | 0 | m_tfans.AddVertex(m_vertexCount++); |
335 | 0 | } |
336 | 0 | } |
337 | 0 | break; |
338 | |
|
339 | 0 | } |
340 | | //logger.write_2_log("\t degree=%i \t cas = %i\n", degree, cas); |
341 | 0 | k1 = m_tfans.GetNumVertices(); |
342 | 0 | b = m_tfans.GetVertex(k0+1); |
343 | 0 | for (long k = k0+2; k < k1; k++) |
344 | 0 | { |
345 | 0 | c = m_tfans.GetVertex(k); |
346 | 0 | t = m_triangleCount*3; |
347 | | |
348 | 0 | m_triangles[t++] = (T) focusVertex; |
349 | 0 | m_triangles[t++] = (T) b; |
350 | 0 | m_triangles[t ] = (T) c; |
351 | |
|
352 | 0 | m_vertexToTriangle.AddNeighbor(focusVertex, m_triangleCount); |
353 | 0 | m_vertexToTriangle.AddNeighbor(b , m_triangleCount); |
354 | 0 | m_vertexToTriangle.AddNeighbor(c , m_triangleCount); |
355 | 0 | b=c; |
356 | 0 | m_triangleCount++; |
357 | 0 | } |
358 | 0 | } |
359 | 0 | } |
360 | 0 | return O3DGC_OK; |
361 | 0 | } |
362 | | } |
363 | | #endif //O3DGC_TRIANGLE_LIST_DECODER_INL |
364 | | |