summaryrefslogtreecommitdiff
path: root/libs/assimp/contrib/Open3DGC/o3dgcTriangleListDecoder.inl
diff options
context:
space:
mode:
Diffstat (limited to 'libs/assimp/contrib/Open3DGC/o3dgcTriangleListDecoder.inl')
-rw-r--r--libs/assimp/contrib/Open3DGC/o3dgcTriangleListDecoder.inl364
1 files changed, 364 insertions, 0 deletions
diff --git a/libs/assimp/contrib/Open3DGC/o3dgcTriangleListDecoder.inl b/libs/assimp/contrib/Open3DGC/o3dgcTriangleListDecoder.inl
new file mode 100644
index 0000000..dd3af4a
--- /dev/null
+++ b/libs/assimp/contrib/Open3DGC/o3dgcTriangleListDecoder.inl
@@ -0,0 +1,364 @@
+/*
+Copyright (c) 2013 Khaled Mammou - Advanced Micro Devices, Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+#pragma once
+#ifndef O3DGC_TRIANGLE_LIST_DECODER_INL
+#define O3DGC_TRIANGLE_LIST_DECODER_INL
+
+namespace o3dgc
+{
+ template<class T>
+ O3DGCErrorCode TriangleListDecoder<T>::Init(T * const triangles,
+ const long numTriangles,
+ const long numVertices,
+ const long maxSizeV2T)
+ {
+ assert(numVertices > 0);
+ assert(numTriangles > 0);
+ m_numTriangles = numTriangles;
+ m_numVertices = numVertices;
+ m_triangles = triangles;
+ m_vertexCount = 0;
+ m_triangleCount = 0;
+ m_itNumTFans = 0;
+ m_itDegree = 0;
+ m_itConfig = 0;
+ m_itOperation = 0;
+ m_itIndex = 0;
+ if (m_numVertices > m_maxNumVertices)
+ {
+ m_maxNumVertices = m_numVertices;
+ delete [] m_visitedVerticesValence;
+ delete [] m_visitedVertices;
+ m_visitedVerticesValence = new long [m_numVertices];
+ m_visitedVertices = new long [m_numVertices];
+ }
+
+ if (m_decodeTrianglesOrder && m_tempTrianglesSize < m_numTriangles)
+ {
+ delete [] m_tempTriangles;
+ m_tempTrianglesSize = m_numTriangles;
+ m_tempTriangles = new T [3*m_tempTrianglesSize];
+ }
+
+ m_ctfans.SetStreamType(m_streamType);
+ m_ctfans.Allocate(m_numVertices, m_numTriangles);
+ m_tfans.Allocate(2 * m_numVertices, 8 * m_numVertices);
+
+ // compute vertex-to-triangle adjacency information
+ m_vertexToTriangle.AllocateNumNeighborsArray(numVertices);
+ long * numNeighbors = m_vertexToTriangle.GetNumNeighborsBuffer();
+ for(long i = 0; i < numVertices; ++i)
+ {
+ numNeighbors[i] = maxSizeV2T;
+ }
+ m_vertexToTriangle.AllocateNeighborsArray();
+ m_vertexToTriangle.ClearNeighborsArray();
+ return O3DGC_OK;
+ }
+ template<class T>
+ O3DGCErrorCode TriangleListDecoder<T>::Decompress()
+ {
+ for(long focusVertex = 0; focusVertex < m_numVertices; ++focusVertex)
+ {
+ if (focusVertex == m_vertexCount)
+ {
+ m_vertexCount++; // insert focusVertex
+ }
+ CompueLocalConnectivityInfo(focusVertex);
+ DecompressTFAN(focusVertex);
+ }
+ return O3DGC_OK;
+ }
+ template<class T>
+ O3DGCErrorCode TriangleListDecoder<T>::Reorder()
+ {
+ if (m_decodeTrianglesOrder)
+ {
+ unsigned long itTriangleIndex = 0;
+ long prevTriangleIndex = 0;
+ long t;
+ memcpy(m_tempTriangles, m_triangles, m_numTriangles * 3 * sizeof(T));
+ for(long i = 0; i < m_numTriangles; ++i)
+ {
+ t = m_ctfans.ReadTriangleIndex(itTriangleIndex) + prevTriangleIndex;
+ assert( t >= 0 && t < m_numTriangles);
+ memcpy(m_triangles + 3 * t, m_tempTriangles + 3 * i, sizeof(T) * 3);
+ prevTriangleIndex = t + 1;
+ }
+ }
+ return O3DGC_OK;
+ }
+ template<class T>
+ O3DGCErrorCode TriangleListDecoder<T>::CompueLocalConnectivityInfo(const long focusVertex)
+ {
+ long t = 0;
+ long p, v;
+ m_numConqueredTriangles = 0;
+ m_numVisitedVertices = 0;
+ for(long i = m_vertexToTriangle.Begin(focusVertex); (t >= 0) && (i < m_vertexToTriangle.End(focusVertex)); ++i)
+ {
+ t = m_vertexToTriangle.GetNeighbor(i);
+ if ( t >= 0)
+ {
+ ++m_numConqueredTriangles;
+ p = 3*t;
+ // extract visited vertices
+ for(long k = 0; k < 3; ++k)
+ {
+ v = m_triangles[p+k];
+ if (v > focusVertex) // vertices are insertices by increasing traversal order
+ {
+ bool foundOrInserted = false;
+ for (long j = 0; j < m_numVisitedVertices; ++j)
+ {
+ if (v == m_visitedVertices[j])
+ {
+ m_visitedVerticesValence[j]++;
+ foundOrInserted = true;
+ break;
+ }
+ else if (v < m_visitedVertices[j])
+ {
+ ++m_numVisitedVertices;
+ for (long h = m_numVisitedVertices-1; h > j; --h)
+ {
+ m_visitedVertices[h] = m_visitedVertices[h-1];
+ m_visitedVerticesValence[h] = m_visitedVerticesValence[h-1];
+ }
+ m_visitedVertices[j] = v;
+ m_visitedVerticesValence[j] = 1;
+ foundOrInserted = true;
+ break;
+ }
+ }
+ if (!foundOrInserted)
+ {
+ m_visitedVertices[m_numVisitedVertices] = v;
+ m_visitedVerticesValence[m_numVisitedVertices] = 1;
+ m_numVisitedVertices++;
+ }
+ }
+ }
+ }
+ }
+ // re-order visited vertices by taking into account their valence (i.e., # of conquered triangles incident to each vertex)
+ // in order to avoid config. 9
+ if (m_numVisitedVertices > 2)
+ {
+ long y;
+ for(long x = 1; x < m_numVisitedVertices; ++x)
+ {
+
+ if (m_visitedVerticesValence[x] == 1)
+ {
+ y = x;
+ while( (y > 0) && (m_visitedVerticesValence[y] < m_visitedVerticesValence[y-1]) )
+ {
+ swap(m_visitedVerticesValence[y], m_visitedVerticesValence[y-1]);
+ swap(m_visitedVertices[y], m_visitedVertices[y-1]);
+ --y;
+ }
+ }
+ }
+ }
+ return O3DGC_OK;
+ }
+ template<class T>
+ O3DGCErrorCode TriangleListDecoder<T>::DecompressTFAN(const long focusVertex)
+ {
+ long ntfans;
+ long degree, config;
+ long op;
+ long index;
+ long k0, k1;
+ long b, c, t;
+
+ ntfans = m_ctfans.ReadNumTFans(m_itNumTFans);
+ if (ntfans > 0)
+ {
+ for(long f = 0; f != ntfans; f++)
+ {
+ m_tfans.AddTFAN();
+ degree = m_ctfans.ReadDegree(m_itDegree) +2 - m_numConqueredTriangles;
+ config = m_ctfans.ReadConfig(m_itConfig);
+ k0 = m_tfans.GetNumVertices();
+ m_tfans.AddVertex(focusVertex);
+ switch(config)
+ {
+ case 0:// ops: 1000001 vertices: -1 -2
+ m_tfans.AddVertex(m_visitedVertices[0]);
+ for(long u = 1; u < degree-1; u++)
+ {
+ m_visitedVertices[m_numVisitedVertices++] = m_vertexCount;
+ m_tfans.AddVertex(m_vertexCount++);
+ }
+ m_tfans.AddVertex(m_visitedVertices[1]);
+ break;
+ case 1: // ops: 1xxxxxx1 vertices: -1 x x x x x -2
+ m_tfans.AddVertex(m_visitedVertices[0]);
+ for(long u = 1; u < degree-1; u++)
+ {
+ op = m_ctfans.ReadOperation(m_itOperation);
+ if (op == 1)
+ {
+ index = m_ctfans.ReadIndex(m_itIndex);
+ if ( index < 0)
+ {
+ m_tfans.AddVertex(m_visitedVertices[-index-1]);
+ }
+ else
+ {
+ m_tfans.AddVertex(index + focusVertex);
+ }
+ }
+ else
+ {
+ m_visitedVertices[m_numVisitedVertices++] = m_vertexCount;
+ m_tfans.AddVertex(m_vertexCount++);
+ }
+ }
+ m_tfans.AddVertex(m_visitedVertices[1]);
+ break;
+ case 2: // ops: 00000001 vertices: -1
+ for(long u = 0; u < degree-1; u++)
+ {
+ m_visitedVertices[m_numVisitedVertices++] = m_vertexCount;
+ m_tfans.AddVertex(m_vertexCount++);
+ }
+ m_tfans.AddVertex(m_visitedVertices[0]);
+ break;
+ case 3: // ops: 00000001 vertices: -2
+ for(long u=0; u < degree-1; u++)
+ {
+ m_visitedVertices[m_numVisitedVertices++] = m_vertexCount;
+ m_tfans.AddVertex(m_vertexCount++);
+ }
+ m_tfans.AddVertex(m_visitedVertices[1]);
+ break;
+ case 4: // ops: 10000000 vertices: -1
+ m_tfans.AddVertex(m_visitedVertices[0]);
+ for(long u = 1; u < degree; u++)
+ {
+ m_visitedVertices[m_numVisitedVertices++] = m_vertexCount;
+ m_tfans.AddVertex(m_vertexCount++);
+ }
+ break;
+ case 5: // ops: 10000000 vertices: -2
+ m_tfans.AddVertex(m_visitedVertices[1]);
+ for(long u = 1; u < degree; u++)
+ {
+ m_visitedVertices[m_numVisitedVertices++] = m_vertexCount;
+ m_tfans.AddVertex(m_vertexCount++);
+ }
+ break;
+ case 6:// ops: 00000000 vertices:
+ for(long u = 0; u < degree; u++)
+ {
+ m_visitedVertices[m_numVisitedVertices++] = m_vertexCount;
+ m_tfans.AddVertex(m_vertexCount++);
+ }
+ break;
+ case 7: // ops: 1000001 vertices: -2 -1
+ m_tfans.AddVertex(m_visitedVertices[1]);
+ for(long u = 1; u < degree-1; u++)
+ {
+ m_visitedVertices[m_numVisitedVertices++] = m_vertexCount;
+ m_tfans.AddVertex(m_vertexCount++);
+ }
+ m_tfans.AddVertex(m_visitedVertices[0]);
+ break;
+ case 8: // ops: 1xxxxxx1 vertices: -2 x x x x x -1
+ m_tfans.AddVertex(m_visitedVertices[1]);
+ for(long u = 1; u < degree-1; u++)
+ {
+ op = m_ctfans.ReadOperation(m_itOperation);
+ if (op == 1)
+ {
+ index = m_ctfans.ReadIndex(m_itIndex);
+ if ( index < 0)
+ {
+ m_tfans.AddVertex(m_visitedVertices[-index-1]);
+ }
+ else
+ {
+ m_tfans.AddVertex(index + focusVertex);
+ }
+ }
+ else
+ {
+ m_visitedVertices[m_numVisitedVertices++] = m_vertexCount;
+ m_tfans.AddVertex(m_vertexCount++);
+ }
+ }
+ m_tfans.AddVertex(m_visitedVertices[0]);
+ break;
+ case 9: // general case
+ for(long u = 0; u < degree; u++)
+ {
+ op = m_ctfans.ReadOperation(m_itOperation);
+ if (op == 1)
+ {
+ index = m_ctfans.ReadIndex(m_itIndex);
+ if ( index < 0)
+ {
+ m_tfans.AddVertex(m_visitedVertices[-index-1]);
+ }
+ else
+ {
+ m_tfans.AddVertex(index + focusVertex);
+ }
+ }
+ else
+ {
+ m_visitedVertices[m_numVisitedVertices++] = m_vertexCount;
+ m_tfans.AddVertex(m_vertexCount++);
+ }
+ }
+ break;
+
+ }
+ //logger.write_2_log("\t degree=%i \t cas = %i\n", degree, cas);
+ k1 = m_tfans.GetNumVertices();
+ b = m_tfans.GetVertex(k0+1);
+ for (long k = k0+2; k < k1; k++)
+ {
+ c = m_tfans.GetVertex(k);
+ t = m_triangleCount*3;
+
+ m_triangles[t++] = (T) focusVertex;
+ m_triangles[t++] = (T) b;
+ m_triangles[t ] = (T) c;
+
+ m_vertexToTriangle.AddNeighbor(focusVertex, m_triangleCount);
+ m_vertexToTriangle.AddNeighbor(b , m_triangleCount);
+ m_vertexToTriangle.AddNeighbor(c , m_triangleCount);
+ b=c;
+ m_triangleCount++;
+ }
+ }
+ }
+ return O3DGC_OK;
+ }
+}
+#endif //O3DGC_TRIANGLE_LIST_DECODER_INL
+