32 #ifndef AdjacencyExtractor_INCLUDE_ONCE 33 #define AdjacencyExtractor_INCLUDE_ONCE 47 A = B = O = 0xFFFFFFFF;
57 return A == 0xFFFFFFFF;
61 return (
u64)A | ( (
u64)B << 32 );
65 return (
u64)B | ( (
u64)A << 32 );
68 bool operator<(
const SEdge& other )
const {
69 return id() < other.id();
73 return id() == other.id();
80 edge[0] = SEdge(a,b,c);
81 edge[1] = SEdge(b,c,a);
82 edge[2] = SEdge(c,a,b);
87 static const int VL_SEdgeMap_SLOTS = 4;
89 struct SEdgeMapSlots {
90 SEdge slot[ VL_SEdgeMap_SLOTS ];
95 std::map<u64, SEdge> edge_map;
96 std::vector<SEdgeMapSlots> cache;
100 size_t memoryUsed()
const {
101 return cache.size() *
sizeof( SEdgeMapSlots ) + edge_map.size() * (
sizeof( SEdge ) +
sizeof(
u64 ) );
104 SEdgeMap(
int size = 104729 ) {
105 cache.resize( size );
110 void put(
u64 uid,
const SEdge& edge) {
113 u64 p = uid % cache.size();
114 for(
int i = 0; i < VL_SEdgeMap_SLOTS; ++i ) {
115 if ( cache[ p ].slot[ i ].isNull() ) {
116 cache[ p ].slot[ i ] = edge;
117 VL_CHECK( ! cache[ p ].slot[ i ].isNull() );
122 edge_map[ uid ] = edge;
125 bool get(
u64 uid, SEdge& edge_out) {
128 u64 p = uid % cache.size();
129 for(
int i = 0; i < VL_SEdgeMap_SLOTS; ++i ) {
130 if ( ! cache[ p ].slot[ i ].isNull() && cache[ p ].slot[ i ].
id() == uid ) {
131 edge_out = cache[ p ].slot[ i ];
136 std::map<u64, SEdge>::iterator it = edge_map.find( uid );
137 if ( it != edge_map.end() ) {
138 edge_out = it->second;
163 std::vector<SEdgeSlot> cache;
164 std::vector<SEdgeSlot> free_slots;
165 SEdgeSlot* free_slots_head;
175 SEdgeMapFast(
int size = 104729 ) {
180 cache.resize( size );
181 free_slots.resize( size );
182 free_slots_head = &free_slots[0];
183 for(
int i = 0; i < free_slots.size() - 1; ++i ) {
184 free_slots[i].next = &free_slots[i + 1];
188 size_t memoryUsed()
const {
189 return cache.size() *
sizeof( SEdgeSlot ) + free_slots.size() *
sizeof( SEdgeSlot );
192 void put(
u64 uid,
const SEdge& edge) {
194 u64 p = uid % cache.size();
197 SEdgeSlot* slot = &cache[ p ];
198 SEdgeSlot* last =
NULL;
199 for( ; slot !=
NULL; last = slot, slot = slot->next )
202 if( slot->edge.isNull() || slot->edge.id() == edge.id() ) {
215 SEdgeSlot* free_slot = free_slots_head;
216 free_slots_head = free_slots_head->next;
217 free_slot->next =
NULL;
218 free_slot->edge = edge;
219 last->next = free_slot;
223 bool get(
u64 uid, SEdge& edge_out) {
225 u64 p = uid % cache.size();
227 for( SEdgeSlot* slot = &cache[ p ]; slot !=
NULL; slot = slot->next ) {
228 if ( ! slot->edge.isNull() && slot->edge.id() == uid ) {
229 edge_out = slot->edge;
248 int total_triangles = 0;
249 for(
int idc = 0; idc < geom->
drawCalls().size(); ++idc ) {
250 int triangle_count = 0;
253 SEdgeMapFast edge_map( indices );
260 Log::error(
"AdjacencyExtractor::extract(): geometry has already adjacency information." );
269 STriangle triangle( a, b, c );
270 edge_map.put( triangle.edge[0].id(), triangle.edge[0] );
271 edge_map.put( triangle.edge[1].id(), triangle.edge[1] );
272 edge_map.put( triangle.edge[2].id(), triangle.edge[2] );
275 total_triangles += triangle_count;
278 geom_adj->drawCalls().push_back( dc_adj.
get() );
279 dc_adj->indexBuffer()->resize( triangle_count * 6 );
280 GLuint* P = dc_adj->indexBuffer()->begin();
297 STriangle triangle( a, b, c );
299 if ( edge_map.get( triangle.edge[0].other(), edge ) ) {
303 if ( edge_map.get( triangle.edge[1].other(), edge ) ) {
307 if ( edge_map.get( triangle.edge[2].other(), edge ) ) {
314 printf(
"EdgeMap: edge-count: %d, cache-hits: %d (%.1f%%), cache MB: %.1f\n",
315 edge_map.edge_count, edge_map.cache_hits, 100.0f * edge_map.cache_hits / edge_map.edge_count,
316 edge_map.memoryUsed() / (1024.0 * 1024.0) );
322 printf(
"Adjacency Time: %.1fs, %.1fKtri/sec (%d)\n", secs, total_triangles / secs / 1000.0f, total_triangles );
bool hasNext()
Returns false if the iterator has reached the end of the triangle list.
unsigned long long u64
64 bits unsigned integer
const ArrayAbstract * vertexArray() const
Conventional vertex array.
static void error(const String &message)
Use this function to provide information about run-time errors: file not found, out of memory...
The Geometry class is a Renderable that implements a polygonal mesh made of polygons, lines and points.
Visualization Library main namespace.
virtual TriangleIterator triangleIterator() const =0
Returns a TriangleIterator used to iterate through the triangles of a DrawCall.
unsigned int u32
32 bits unsigned integer
Iterator used to extract the indices of every single triangle of a DrawCall regardless of the primiti...
u32 countIndices() const
Counts the number of virtual indices of a DrawCall., i.e.
The base class of DrawArrays, DrawElements, MultiDrawElements and DrawRangeElements.
static real currentTime()
Seconds passed from an arbitrary origin QueryPerformanceFrequency should be called only once in the a...
bool operator==(const ref< T1 > &o1, const ref< T2 > &o2)
The ref<> class is used to reference-count an Object.
EPrimitiveType primitiveType() const
Returns the draw call's primitive type.
const ArrayAbstract * normalArray() const
Conventional normal array.
Collection< DrawCall > & drawCalls()
Returns the list of DrawCall objects bound to a Geometry.