[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [44223] trunk/blender/intern/dualcon/ intern: Remesh modifier: extensive refactoring of the Octree class.

Nicholas Bishop nicholasbishop at gmail.com
Sat Feb 18 12:34:54 CET 2012


Revision: 44223
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=44223
Author:   nicholasbishop
Date:     2012-02-18 11:34:53 +0000 (Sat, 18 Feb 2012)
Log Message:
-----------
Remesh modifier: extensive refactoring of the Octree class.

The changes mostly center around two new structures, InternalNode and
LeafNode. These provide an explicit representation of the Octree
nodes, which formerly were manipulated as opaque byte arrays.

A fair amount of commented out/unused code was also removed. This
includes the "CINDY" code, which may yet be useful, easy to bring back
if so.

There should be no difference in the output of the remesh modifier,
but memory usage may be slightly different. The flood fill bytes are
no longer optional; they will be allocated whether or not the 'remove
disconnect components' flag is set. The leaf node is probably not as
tightly packed due to alignment issues; this could be fixed with the
__attribute__((packed)) flag in gcc (probably there's an MSVC
equivalent), but not sure it's worth it. The internal nodes should
take up less space on 32-bit systems, allocating sizeof(pointer) now
rather than constant eight bytes.

These changes were made in persuit of bug #30158 (remesh crashes on
PowerPC). There's still a fair amount of bitwise stuff in the Octree,
so may still be endian issues and not yet sure if this fixes the bug,
but should be much easier to track down problems now.

Modified Paths:
--------------
    trunk/blender/intern/dualcon/intern/MemoryAllocator.h
    trunk/blender/intern/dualcon/intern/octree.cpp
    trunk/blender/intern/dualcon/intern/octree.h

Modified: trunk/blender/intern/dualcon/intern/MemoryAllocator.h
===================================================================
--- trunk/blender/intern/dualcon/intern/MemoryAllocator.h	2012-02-18 11:26:11 UTC (rev 44222)
+++ trunk/blender/intern/dualcon/intern/MemoryAllocator.h	2012-02-18 11:34:53 UTC (rev 44223)
@@ -43,8 +43,8 @@
 class VirtualMemoryAllocator
 {
 public:
-	virtual UCHAR * allocate( ) = 0 ;
-	virtual void deallocate( UCHAR * obj ) = 0 ;
+	virtual void * allocate( ) = 0 ;
+	virtual void deallocate( void * obj ) = 0 ;
 	virtual void destroy( ) = 0 ;
 	virtual void printInfo( ) = 0 ;
 
@@ -161,7 +161,7 @@
 	/**
 	 * Allocation method
 	 */
-	UCHAR * allocate ( )
+	void * allocate ( )
 	{
 		if ( available == 0 )
 		{
@@ -170,13 +170,13 @@
 
 		// printf("Allocating %d\n", header[ allocated ]) ;
 		available -- ;
-		return stack[ available >> HEAP_BASE ][ available & HEAP_MASK ] ;
+		return (void*)stack[ available >> HEAP_BASE ][ available & HEAP_MASK ] ;
 	}
 
 	/**
 	 * De-allocation method
 	 */
-	void deallocate ( UCHAR * obj )
+	void deallocate ( void * obj )
 	{
 		if ( available == stacksize )
 		{
@@ -184,7 +184,7 @@
 		}
 
 		// printf("De-allocating %d\n", ( obj - data ) / N ) ;
-		stack[ available >> HEAP_BASE ][ available & HEAP_MASK ] = obj ;
+		stack[ available >> HEAP_BASE ][ available & HEAP_MASK ] = (UCHAR*)obj ;
 		available ++ ;
 		// printf("%d %d\n", allocated, header[ allocated ]) ;
 	}

Modified: trunk/blender/intern/dualcon/intern/octree.cpp
===================================================================
--- trunk/blender/intern/dualcon/intern/octree.cpp	2012-02-18 11:26:11 UTC (rev 44222)
+++ trunk/blender/intern/dualcon/intern/octree.cpp	2012-02-18 11:34:53 UTC (rev 44223)
@@ -15,7 +15,7 @@
  * along with this program; if not, write to the Free Software Foundation,
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  *
- * Contributor(s): Tao Ju
+ * Contributor(s): Tao Ju, Nicholas Bishop
  *
  * ***** END GPL LICENSE BLOCK *****
  */
@@ -42,12 +42,12 @@
 #define dc_printf(...) do {} while(0)
 #endif
 
-Octree::Octree( ModelReader* mr,
+Octree::Octree(ModelReader* mr,
 				DualConAllocOutput alloc_output_func,
 				DualConAddVert add_vert_func,
 				DualConAddQuad add_quad_func,
 				DualConFlags flags, DualConMode dualcon_mode, int depth,
-				float threshold, float sharpness )
+				float threshold, float sharpness)
 	: use_flood_fill(flags & DUALCON_FLOOD_FILL),
 	  /* note on `use_manifold':
 		 
@@ -72,956 +72,574 @@
 	  add_vert(add_vert_func),
 	  add_quad(add_quad_func)
 {
-	this->thresh = threshold ;
-	this->reader = mr ;
-	this->dimen = 1 << GRID_DIMENSION ;
-	this->range = reader->getBoundingBox( this->origin ) ;
-	this->nodeCount = this->nodeSpace = 0;
-	this->maxDepth = depth ;
-	this->mindimen = ( dimen >> maxDepth ) ;
-	this->minshift = ( GRID_DIMENSION - maxDepth ) ;
-	this->buildTable( ) ;
+	thresh = threshold;
+	reader = mr;
+	dimen = 1 << GRID_DIMENSION;
+	range = reader->getBoundingBox(origin);
+	nodeCount = nodeSpace = 0;
+	maxDepth = depth;
+	mindimen =(dimen >> maxDepth);
+	minshift =(GRID_DIMENSION - maxDepth);
+	buildTable();
 
-	flood_bytes = use_flood_fill ? FLOOD_FILL_BYTES : 0;
-	leaf_extra_bytes = flood_bytes + CINDY_BYTES;
+	maxTrianglePerCell = 0;
 
-#ifdef USE_HERMIT
-	leaf_node_bytes = 7 + leaf_extra_bytes;
-#else
-	leaf_node_bytes = 3 + leaf_extra_bytes;
-#endif
-
-#ifdef QIANYI
-	dc_printf("Origin: (%f %f %f), Dimension: %f\n", origin[0], origin[1], origin[2], range) ;
-#endif
-
-	this->maxTrianglePerCell = 0 ;
-
 	// Initialize memory
 #ifdef IN_VERBOSE_MODE
-	dc_printf("Range: %f origin: %f, %f,%f \n", range, origin[0], origin[1], origin[2] ) ;
-	dc_printf("Initialize memory...\n") ;
+	dc_printf("Range: %f origin: %f, %f,%f \n", range, origin[0], origin[1], origin[2]);
+	dc_printf("Initialize memory...\n");
 #endif
-	initMemory( ) ;
-	this->root = createInternal( 0 ) ;
+	initMemory();
+	root = (Node*)createInternal(0);
 
 	// Read MC table
 #ifdef IN_VERBOSE_MODE
-	dc_printf("Reading contour table...\n") ;
+	dc_printf("Reading contour table...\n");
 #endif
-	this->cubes = new Cubes();
+	cubes = new Cubes();
 
 }
 
-Octree::~Octree( )
+Octree::~Octree()
 {
-	freeMemory( ) ;
+	freeMemory();
 }
 
 void Octree::scanConvert()
 {
 	// Scan triangles
 #if DC_DEBUG
-	clock_t start, finish ;
-	start = clock( ) ;
+	clock_t start, finish;
+	start = clock();
 #endif
 	
-	this->addTrian( ) ;
-	this->resetMinimalEdges( ) ;
-	this->preparePrimalEdgesMask( this->root ) ;
+	addTrian();
+	resetMinimalEdges();
+	preparePrimalEdgesMask(&root->internal);
 
 #if DC_DEBUG
-	finish = clock( ) ;
+	finish = clock();
 	dc_printf("Time taken: %f seconds                   \n", 
-		(double)(finish - start) / CLOCKS_PER_SEC ) ;
+		(double)(finish - start) / CLOCKS_PER_SEC);
 #endif
 
 	// Generate signs
 	// Find holes
 #if DC_DEBUG
-	dc_printf("Patching...\n") ;
-	start = clock( ) ;
+	dc_printf("Patching...\n");
+	start = clock();
 #endif
-	this->trace( ) ;
+	trace();
 #if DC_DEBUG
-	finish = clock( ) ;
-	dc_printf("Time taken: %f seconds \n",	(double)(finish - start) / CLOCKS_PER_SEC ) ;
+	finish = clock();
+	dc_printf("Time taken: %f seconds \n",	(double)(finish - start) / CLOCKS_PER_SEC);
 #ifdef IN_VERBOSE_MODE
-	dc_printf("Holes: %d Average Length: %f Max Length: %d \n", numRings, (float)totRingLengths / (float) numRings, maxRingLength ) ;
+	dc_printf("Holes: %d Average Length: %f Max Length: %d \n", numRings,(float)totRingLengths /(float) numRings, maxRingLength);
 #endif
 #endif
 	
 	// Check again
-	int tnumRings = numRings ;
-	this->trace( ) ;
+	int tnumRings = numRings;
+	trace();
 #ifdef IN_VERBOSE_MODE
-	dc_printf("Holes after patching: %d \n", numRings) ;
+	dc_printf("Holes after patching: %d \n", numRings);
 #endif	
-	numRings = tnumRings ;
+	numRings = tnumRings;
 
 #if DC_DEBUG
-	dc_printf("Building signs...\n") ;
-	start = clock( ) ;
+	dc_printf("Building signs...\n");
+	start = clock();
 #endif
-	this->buildSigns( ) ;
+	buildSigns();
 #if DC_DEBUG
-	finish = clock( ) ;
-	dc_printf("Time taken: %f seconds \n",	(double)(finish - start) / CLOCKS_PER_SEC ) ;
+	finish = clock();
+	dc_printf("Time taken: %f seconds \n",	(double)(finish - start) / CLOCKS_PER_SEC);
 #endif
 
 	if(use_flood_fill) {
 		/*
-		  start = clock( ) ;
-		  this->floodFill( ) ;
+		  start = clock();
+		  floodFill();
 		  // Check again
-		  tnumRings = numRings ;
-		  this->trace( ) ;
-		  dc_printf("Holes after filling: %d \n", numRings) ;
-		  numRings = tnumRings ;
-		  this->buildSigns( ) ;
-		  finish = clock( ) ;
-		  dc_printf("Time taken: %f seconds \n",	(double)(finish - start) / CLOCKS_PER_SEC ) ;
+		  tnumRings = numRings;
+		  trace();
+		  dc_printf("Holes after filling: %d \n", numRings);
+		  numRings = tnumRings;
+		  buildSigns();
+		  finish = clock();
+		  dc_printf("Time taken: %f seconds \n",	(double)(finish - start) / CLOCKS_PER_SEC);
 		*/
 #if DC_DEBUG
-		start = clock( ) ;
+		start = clock();
 		dc_printf("Removing components...\n");
 #endif
-		this->floodFill( ) ;
-		this->buildSigns( ) ;
+		floodFill();
+		buildSigns();
 		//	dc_printf("Checking...\n");
-		//	this->floodFill( ) ;
+		//	floodFill();
 #if DC_DEBUG
-		finish = clock( ) ;
-		dc_printf("Time taken: %f seconds \n", (double)(finish - start) / CLOCKS_PER_SEC ) ;
+		finish = clock();
+		dc_printf("Time taken: %f seconds \n",(double)(finish - start) / CLOCKS_PER_SEC);
 #endif
 	}
 
 	// Output
-#ifdef OUTPUT_REPAIRED
 #if DC_DEBUG
-	start = clock( ) ;
+	start = clock();
 #endif
 	writeOut();
 #if DC_DEBUG
-	finish = clock( ) ;
+	finish = clock();
 #endif
-	// dc_printf("Time taken: %f seconds \n",	(double)(finish - start) / CLOCKS_PER_SEC ) ;
-#ifdef CINDY
-	this->writeTags( "tags.txt" ) ;
-	dc_printf("Tags output to tags.txt\n") ;
-#endif
+	// dc_printf("Time taken: %f seconds \n",	(double)(finish - start) / CLOCKS_PER_SEC);
 
-#endif
-
 	// Print info
 #ifdef IN_VERBOSE_MODE
-	printMemUsage( ) ;
+	printMemUsage();
 #endif
 }
 
-#if 0
-void Octree::writeOut( char* fname )
+void Octree::initMemory()
 {
-	dc_printf( "\n" ) ;
-	if ( strstr( fname, ".ply" ) != NULL )
-	{
-		dc_printf("Writing PLY file format.\n") ;
-		this->outType = 1 ;
-		writePLY( fname ) ;
-	} 
-	else if ( strstr( fname, ".off" ) != NULL )
-	{
-		dc_printf("Writing OFF file format.\n") ;
-		this->outType = 0 ;
-		writeOFF( fname ) ;
-	}
-	else if ( strstr( fname, ".sof" ) != NULL )
-	{
-		dc_printf("Writing Signed Octree File format.\n") ;
-		this->outType = 2 ;
-		writeOctree( fname ) ;
-	}
-	else if ( strstr( fname, ".dcf" ) != NULL )
-	{
-#ifdef USE_HERMIT
-		dc_printf("Writing Dual Contouring File format.\n") ;
-		this->outType = 3 ;
-		writeDCF( fname ) ;
-#else
-		dc_printf("Can not write Dual Contouring File format in non-DC mode.\n") ;
-#endif
-	}
-#ifdef USE_HERMIT
-	else if ( strstr( fname, ".sog" ) != NULL )
-	{
-		dc_printf("Writing signed octree with geometry.\n") ;
-		this->outType = 4 ;
-		writeOctreeGeom( fname ) ;
-	}
-#endif
-	/*
-	else if ( strstr( fname, ".sof" ) != NULL )
-	{
-		dc_printf("Writing SOF file format.\n") ;
-		this->outType = 2 ;
-		writeOctree( fname ) ;
-	}
-	*/
-	else
-	{
-		dc_printf("Unknown output format.\n") ;
-	}
+	leafalloc[0] = new MemoryAllocator<sizeof(LeafNode)>();
+	leafalloc[1] = new MemoryAllocator<sizeof(LeafNode) + sizeof(float) * EDGE_FLOATS>();
+	leafalloc[2] = new MemoryAllocator<sizeof(LeafNode) + sizeof(float) * EDGE_FLOATS * 2>();
+	leafalloc[3] = new MemoryAllocator<sizeof(LeafNode) + sizeof(float) * EDGE_FLOATS * 3>();
 
+	alloc[0] = new MemoryAllocator<sizeof(InternalNode)>();
+	alloc[1] = new MemoryAllocator<sizeof(InternalNode) + sizeof(Node*)>();
+	alloc[2] = new MemoryAllocator<sizeof(InternalNode) + sizeof(Node*) * 2>();
+	alloc[3] = new MemoryAllocator<sizeof(InternalNode) + sizeof(Node*) * 3>();
+	alloc[4] = new MemoryAllocator<sizeof(InternalNode) + sizeof(Node*) * 4>();
+	alloc[5] = new MemoryAllocator<sizeof(InternalNode) + sizeof(Node*) * 5>();
+	alloc[6] = new MemoryAllocator<sizeof(InternalNode) + sizeof(Node*) * 6>();
+	alloc[7] = new MemoryAllocator<sizeof(InternalNode) + sizeof(Node*) * 7>();
+	alloc[8] = new MemoryAllocator<sizeof(InternalNode) + sizeof(Node*) * 8>();
 }
-#endif
 
-void Octree::initMemory( )
+void Octree::freeMemory()
 {
-#ifdef USE_HERMIT
-	const int leaf_node_bytes = 7;
-#else
-	const int leaf_node_bytes = 3;
-#endif
-
-	if(use_flood_fill) {
-		const int bytes = leaf_node_bytes + CINDY_BYTES + FLOOD_FILL_BYTES;
-		this->leafalloc[ 0 ] = new MemoryAllocator< bytes > ( ) ;

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list