@ -17,42 +17,44 @@
# include <stack>
# include <stack>
using namespace std ;
# ifndef DOXYGEN_GENERATING_OUTPUT
# ifndef DOXYGEN_GENERATING_OUTPUT
namespace Magnum { namespace MeshTools { namespace Implementation {
namespace Magnum { namespace MeshTools { namespace Implementation {
void Tipsify : : operator ( ) ( size_t cacheSize ) {
void Tipsify : : operator ( ) ( size_t cacheSize ) {
/* Neighboring triangles for each vertex, per-vertex live triangle count */
/* Neighboring triangles for each vertex, per-vertex live triangle count */
std : : vector < unsigned in t > liveTriangleCount , neighborPosition , neighbors ;
std : : vector < uint32_ t > liveTriangleCount , neighborPosition , neighbors ;
buildAdjacency ( liveTriangleCount , neighborPosition , neighbors ) ;
buildAdjacency ( liveTriangleCount , neighborPosition , neighbors ) ;
/* Global time, per-vertex caching timestamps, per-triangle emmited flag */
/* Global time, per-vertex caching timestamps, per-triangle emmited flag */
unsigned in t time = cacheSize + 1 ;
uint32_ t time = cacheSize + 1 ;
std : : vector < unsigned in t > timestamp ( vertexCount ) ;
std : : vector < uint32_ t > timestamp ( vertexCount ) ;
std : : vector < bool > emitted ( indices . size ( ) / 3 ) ;
std : : vector < bool > emitted ( indices . size ( ) / 3 ) ;
/* Dead-end vertex stack */
/* Dead-end vertex stack */
std : : stack < unsigned in t > deadEndStack ;
std : : stack < uint32_ t > deadEndStack ;
/* Output index buffer */
/* Output index buffer */
std : : vector < unsigned in t > outputIndices ;
std : : vector < uint32_ t > outputIndices ;
outputIndices . reserve ( indices . size ( ) ) ;
outputIndices . reserve ( indices . size ( ) ) ;
/* Starting vertex for fanning, cursor */
/* Starting vertex for fanning, cursor */
unsigned in t fanningVertex = 0 ;
uint32_ t fanningVertex = 0 ;
unsigned in t i = 0 ;
uint32_ t i = 0 ;
while ( fanningVertex ! = 0xFFFFFFFFu ) {
while ( fanningVertex ! = 0xFFFFFFFFu ) {
/* Array with candidates for next fanning vertex (in 1-ring around
/* Array with candidates for next fanning vertex (in 1-ring around
fanning vertex ) */
fanning vertex ) */
std : : vector < unsigned in t > candidates ;
std : : vector < uint32_ t > candidates ;
/* For all neighbors of fanning vertex */
/* For all neighbors of fanning vertex */
for ( unsigned in t ti = neighborPosition [ fanningVertex ] , t = neighbors [ ti ] ; ti ! = neighborPosition [ fanningVertex + 1 ] ; t = neighbors [ + + ti ] ) {
for ( uint32_ t ti = neighborPosition [ fanningVertex ] , t = neighbors [ ti ] ; ti ! = neighborPosition [ fanningVertex + 1 ] ; t = neighbors [ + + ti ] ) {
/* Continue if already emitted */
/* Continue if already emitted */
if ( emitted [ t ] ) continue ;
if ( emitted [ t ] ) continue ;
emitted [ t ] = true ;
emitted [ t ] = true ;
/* Write all vertices of the triangle to output buffer */
/* Write all vertices of the triangle to output buffer */
for ( unsigned in t vi = 0 , v = indices [ t * 3 ] ; vi ! = 3 ; v = indices [ + + vi + t * 3 ] ) {
for ( uint32_ t vi = 0 , v = indices [ t * 3 ] ; vi ! = 3 ; v = indices [ + + vi + t * 3 ] ) {
outputIndices . push_back ( v ) ;
outputIndices . push_back ( v ) ;
/* Add to dead end stack and candidates array */
/* Add to dead end stack and candidates array */
@ -73,15 +75,15 @@ void Tipsify::operator()(size_t cacheSize) {
fanningVertex = 0xFFFFFFFFu ;
fanningVertex = 0xFFFFFFFFu ;
/* Go through candidates in 1-ring around fanning vertex */
/* Go through candidates in 1-ring around fanning vertex */
int candidatePriority = - 1 ;
int32_t candidatePriority = - 1 ;
for ( unsigned in t v : candidates ) {
for ( uint32_ t v : candidates ) {
/* Skip if it doesn't have any live triangles */
/* Skip if it doesn't have any live triangles */
if ( ! liveTriangleCount [ v ] ) continue ;
if ( ! liveTriangleCount [ v ] ) continue ;
/* Get most fresh candidate which will still be in cache even
/* Get most fresh candidate which will still be in cache even
after fanning . Every fanned triangle will generate at most
after fanning . Every fanned triangle will generate at most
two cache misses , thus 2 * liveTriangleCount */
two cache misses , thus 2 * liveTriangleCount */
int priority = 0 ;
int32_t priority = 0 ;
if ( time - timestamp [ v ] + 2 * liveTriangleCount [ v ] < = cacheSize )
if ( time - timestamp [ v ] + 2 * liveTriangleCount [ v ] < = cacheSize )
priority = time - timestamp [ v ] ;
priority = time - timestamp [ v ] ;
if ( priority > candidatePriority ) {
if ( priority > candidatePriority ) {
@ -117,12 +119,12 @@ void Tipsify::operator()(size_t cacheSize) {
std : : swap ( indices , outputIndices ) ;
std : : swap ( indices , outputIndices ) ;
}
}
void Tipsify : : buildAdjacency ( std : : vector < unsigned in t > & liveTriangleCount , std : : vector < unsigned in t > & neighborOffset , std : : vector < unsigned in t > & neighbors ) const {
void Tipsify : : buildAdjacency ( std : : vector < uint32_ t > & liveTriangleCount , std : : vector < uint32_ t > & neighborOffset , std : : vector < uint32_ t > & neighbors ) const {
/* How many times is each vertex referenced == count of neighboring
/* How many times is each vertex referenced == count of neighboring
triangles for each vertex */
triangles for each vertex */
liveTriangleCount . clear ( ) ;
liveTriangleCount . clear ( ) ;
liveTriangleCount . resize ( vertexCount ) ;
liveTriangleCount . resize ( vertexCount ) ;
for ( unsigned in t i = 0 ; i ! = indices . size ( ) ; + + i )
for ( size_ t i = 0 ; i ! = indices . size ( ) ; + + i )
+ + liveTriangleCount [ indices [ i ] ] ;
+ + liveTriangleCount [ indices [ i ] ] ;
/* Building offset array from counts. Neighbors for i-th vertex will at
/* Building offset array from counts. Neighbors for i-th vertex will at
@ -132,8 +134,8 @@ void Tipsify::buildAdjacency(std::vector<unsigned int>& liveTriangleCount, std::
neighborOffset . clear ( ) ;
neighborOffset . clear ( ) ;
neighborOffset . reserve ( vertexCount + 1 ) ;
neighborOffset . reserve ( vertexCount + 1 ) ;
neighborOffset . push_back ( 0 ) ;
neighborOffset . push_back ( 0 ) ;
unsigned in t sum = 0 ;
uint32_ t sum = 0 ;
for ( unsigned in t i = 0 ; i ! = vertexCount ; + + i ) {
for ( size_ t i = 0 ; i ! = vertexCount ; + + i ) {
neighborOffset . push_back ( sum ) ;
neighborOffset . push_back ( sum ) ;
sum + = liveTriangleCount [ i ] ;
sum + = liveTriangleCount [ i ] ;
}
}
@ -142,7 +144,7 @@ void Tipsify::buildAdjacency(std::vector<unsigned int>& liveTriangleCount, std::
positioning */
positioning */
neighbors . clear ( ) ;
neighbors . clear ( ) ;
neighbors . resize ( sum ) ;
neighbors . resize ( sum ) ;
for ( unsigned in t i = 0 ; i ! = indices . size ( ) ; + + i )
for ( size_ t i = 0 ; i ! = indices . size ( ) ; + + i )
neighbors [ neighborOffset [ indices [ i ] + 1 ] + + ] = i / 3 ;
neighbors [ neighborOffset [ indices [ i ] + 1 ] + + ] = i / 3 ;
}
}