bool Execute(PointStream< Real > *ps, CMeshO &pm, PoissonParam<Real> &pp, vcg::CallBackPos* cb) { Reset< Real >(); XForm4x4< Real > xForm=XForm4x4< Real >::Identity(); cb(1,"Running Screened Poisson Reconstruction\n" ); double t; double tt=Time(); Real isoValue = 0; Octree< Real > tree; tree.threads = 1; if( pp.MaxSolveDepthVal<0 ) pp.MaxSolveDepthVal = pp.MaxDepthVal; // OctNode< TreeNodeData >::SetAllocator( MEMORY_ALLOCATOR_BLOCK_SIZE ); OctNode< TreeNodeData >::SetAllocator( 0 ); // int kernelDepth = KernelDepth.set ? KernelDepth.value : Depth.value-2; if(pp.KernelDepthVal<0) pp.KernelDepthVal =pp.MaxDepthVal-2; if( pp.KernelDepthVal>pp.MaxDepthVal ) return false; cb(10,"Creating Tree"); double maxMemoryUsage; t=Time(); // tree.maxMemoryUsage=0; typename Octree< Real >::PointInfo* pointInfo = new typename Octree< Real >::PointInfo(); typename Octree< Real >::NormalInfo* normalInfo = new typename Octree< Real >::NormalInfo(); std::vector< Real >* kernelDensityWeights = new std::vector< Real >(); std::vector< Real >* centerWeights = new std::vector< Real >(); // int SetTree( char* fileName , int minDepth , int maxDepth , int fullDepth , int splatDepth , Real samplesPerNode , // Real scaleFactor , bool useConfidence , bool useNormalWeight , Real constraintWeight , int adaptiveExponent , // PointInfo& pointInfo , NormalInfo& normalInfo , std::vector< Real >& kernelDensityWeights , std::vector< Real >& centerWeights , // int boundaryType=BSplineElements< Degree >::NONE , XForm4x4< Real > xForm=XForm4x4< Real >::Identity , bool makeComplete=false ); TreeNodeData::NodeCount=0; int pointCount = tree.template SetTree< Scalarm >( 0, pp.MinDepthVal , pp.MaxDepthVal , pp.FullDepthVal , pp.KernelDepthVal , pp.SamplesPerNodeVal , pp.ScaleVal , pp.ConfidenceFlag , pp.NormalWeightsFlag , pp.PointWeightVal , pp.AdaptiveExponentVal , *pointInfo , *normalInfo , *kernelDensityWeights , *centerWeights , ps, pp.BoundaryTypeVal , xForm , pp.CompleteFlag ); DumpOutput("# Tree set in: %9.1f (s), %9.1f (MB)\n" , Time()-t , tree.maxMemoryUsage ); DumpOutput( "Input Points: %d\n" , pointCount ); DumpOutput( "Leaves/Nodes: %d/%d\n" , tree.tree.leaves() , tree.tree.nodes() ); DumpOutput( "Memory Usage: %.3f MB\n" , float( MemoryInfo::Usage() )/(1<<20) ); maxMemoryUsage = tree.maxMemoryUsage; cb(20,"Settng Constraints"); t=Time() , tree.maxMemoryUsage=0; Pointer( Real ) constraints = tree.SetLaplacianConstraints( *normalInfo ); delete normalInfo; DumpOutput("# Constraints set in: %9.1f (s), %9.1f (MB)\n" , Time()-t , tree.maxMemoryUsage ); DumpOutput( "Memory Usage: %.3f MB\n" , float( MemoryInfo::Usage())/(1<<20) ); maxMemoryUsage = std::max< double >( maxMemoryUsage , tree.maxMemoryUsage ); cb(70,"Solving Linear system"); t=Time() , tree.maxMemoryUsage=0; Pointer( Real ) solution = tree.SolveSystem( *pointInfo , constraints , pp.ShowResidualFlag , pp.ItersVal , pp.MaxSolveDepthVal , pp.CGDepthVal , pp.CSSolverAccuracyVal ); delete pointInfo; FreePointer( constraints ); DumpOutput( "# Linear system solved in: %9.1f (s), %9.1f (MB)\n" , Time()-t , tree.maxMemoryUsage ); DumpOutput( "Memory Usage: %.3f MB\n" , float( MemoryInfo::Usage() )/(1<<20) ); maxMemoryUsage = std::max< double >( maxMemoryUsage , tree.maxMemoryUsage ); CoredFileMeshData< PlyValueVertex< float > > mesh; tree.maxMemoryUsage=0; t=Time(); isoValue = tree.GetIsoValue( solution , *centerWeights ); delete centerWeights; DumpOutput( "Got average in: %f\n" , Time()-t ); DumpOutput( "Iso-Value: %e\n" , isoValue ); cb(80,"Building Isosurface"); t = Time() , tree.maxMemoryUsage = 0; assert(kernelDensityWeights); tree.GetMCIsoSurface( GetPointer( *kernelDensityWeights ) , solution , isoValue , mesh , true , !pp.NonManifoldFlag , false /*PolygonMesh.set*/ ); DumpOutput("# Got triangles in: %9.1f (s), %9.1f (MB)\n" , Time()-t , tree.maxMemoryUsage ); maxMemoryUsage = std::max< double >( maxMemoryUsage , tree.maxMemoryUsage ); DumpOutput( "# Total Solve: %9.1f (s), %9.1f (MB)\n" , Time()-tt , maxMemoryUsage ); DumpOutput( "Vertices / Polygons: %d / %d\n" , mesh.outOfCorePointCount()+mesh.inCorePoints.size() , mesh.polygonCount() ); FreePointer( solution ); cb(90,"Creating Mesh"); mesh.resetIterator(); int vm = mesh.outOfCorePointCount()+mesh.inCorePoints.size(); vcg::tri::Allocator<CMeshO>::AddVertices(pm,vm); int i; for (i=0; i < int(mesh.inCorePoints.size()); i++){ pm.vert[i].P()[0] = mesh.inCorePoints[i].point[0]; pm.vert[i].P()[1] = mesh.inCorePoints[i].point[1]; pm.vert[i].P()[2] = mesh.inCorePoints[i].point[2]; pm.vert[i].Q() = mesh.inCorePoints[i].value; } for (int ii=0; ii < mesh.outOfCorePointCount(); ii++){ PlyValueVertex< float > p; mesh.nextOutOfCorePoint(p); pm.vert[ii+i].P()[0] = p.point[0]; pm.vert[ii+i].P()[1] = p.point[1]; pm.vert[ii+i].P()[2] = p.point[2]; pm.vert[ii+i].Q() = p.value; } std::vector< CoredVertexIndex > polygon; while(mesh.nextPolygon( polygon )) { assert(polygon.size()==3); int indV[3]; for( int i=0 ; i<int(polygon.size()) ; i++ ) { if( polygon[i].inCore ) indV[i] = polygon[i].idx; else indV[i]= polygon[i].idx + int( mesh.inCorePoints.size() ); } vcg::tri::Allocator<CMeshO>::AddFace(pm, &pm.vert[indV[0]], &pm.vert[indV[1]], &pm.vert[indV[2]]); } cb(100,"Done"); return 1; }
int Execute( int argc , char* argv[] ) { Reset< Real >(); int i; int paramNum = sizeof(params)/sizeof(cmdLineReadable*); int commentNum=0; char **comments; comments = new char*[paramNum+7]; for( i=0 ; i<paramNum+7 ; i++ ) comments[i] = new char[1024]; if( Verbose.set ) echoStdout=1; XForm4x4< Real > xForm , iXForm; if( XForm.set ) { FILE* fp = fopen( XForm.value , "r" ); if( !fp ) { fprintf( stderr , "[WARNING] Could not read x-form from: %s\n" , XForm.value ); xForm = XForm4x4< Real >::Identity(); } else { for( int i=0 ; i<4 ; i++ ) for( int j=0 ; j<4 ; j++ ) { float f; fscanf( fp , " %f " , &f ); xForm(i,j) = (Real)f; } fclose( fp ); } } else xForm = XForm4x4< Real >::Identity(); iXForm = xForm.inverse(); DumpOutput2( comments[commentNum++] , "Running Screened Poisson Reconstruction (Version 6.13)\n" ); char str[1024]; for( int i=0 ; i<paramNum ; i++ ) if( params[i]->set ) { params[i]->writeValue( str ); if( strlen( str ) ) DumpOutput2( comments[commentNum++] , "\t--%s %s\n" , params[i]->name , str ); else DumpOutput2( comments[commentNum++] , "\t--%s\n" , params[i]->name ); } double t; double tt=PTime(); Real isoValue = 0; Octree< Real > tree; tree.threads = Threads.value; if( !In.set ) { ShowUsage(argv[0]); return 0; } if( !MaxSolveDepth.set ) MaxSolveDepth.value = Depth.value; OctNode< TreeNodeData >::SetAllocator( MEMORY_ALLOCATOR_BLOCK_SIZE ); t=PTime(); int kernelDepth = KernelDepth.set ? KernelDepth.value : Depth.value-2; if( kernelDepth>Depth.value ) { fprintf( stderr,"[ERROR] %s can't be greater than %s: %d <= %d\n" , KernelDepth.name , Depth.name , KernelDepth.value , Depth.value ); return EXIT_FAILURE; } double maxMemoryUsage; t=PTime() , tree.maxMemoryUsage=0; typename Octree< Real >::PointInfo* pointInfo = new typename Octree< Real >::PointInfo(); typename Octree< Real >::NormalInfo* normalInfo = new typename Octree< Real >::NormalInfo(); std::vector< Real >* kernelDensityWeights = new std::vector< Real >(); std::vector< Real >* centerWeights = new std::vector< Real >(); PointStream< float >* pointStream; char* ext = GetFileExtension( In.value ); if ( !strcasecmp( ext , "bnpts" ) ) pointStream = new BinaryPointStream< float >( In.value ); else if( !strcasecmp( ext , "ply" ) ) pointStream = new PLYPointStream< float >( In.value ); else pointStream = new ASCIIPointStream< float >( In.value ); delete[] ext; int pointCount = tree.template SetTree< float >( pointStream , MinDepth.value , Depth.value , FullDepth.value , kernelDepth , Real(SamplesPerNode.value) , Scale.value , Confidence.set , NormalWeights.set , PointWeight.value , AdaptiveExponent.value , *pointInfo , *normalInfo , *kernelDensityWeights , *centerWeights , BoundaryType.value , xForm , Complete.set ); if( !Density.set ) delete kernelDensityWeights , kernelDensityWeights = NULL; DumpOutput2( comments[commentNum++] , "# Tree set in: %9.1f (s), %9.1f (MB)\n" , PTime()-t , tree.maxMemoryUsage ); DumpOutput( "Input Points: %d\n" , pointCount ); DumpOutput( "Leaves/Nodes: %d/%d\n" , tree.tree.leaves() , tree.tree.nodes() ); DumpOutput( "Memory Usage: %.3f MB\n" , float( MemoryInfo::Usage() )/(1<<20) ); maxMemoryUsage = tree.maxMemoryUsage; t=PTime() , tree.maxMemoryUsage=0; Pointer( Real ) constraints = tree.SetLaplacianConstraints( *normalInfo ); delete normalInfo; DumpOutput2( comments[commentNum++] , "# Constraints set in: %9.1f (s), %9.1f (MB)\n" , PTime()-t , tree.maxMemoryUsage ); DumpOutput( "Memory Usage: %.3f MB\n" , float( MemoryInfo::Usage())/(1<<20) ); maxMemoryUsage = std::max< double >( maxMemoryUsage , tree.maxMemoryUsage ); t=PTime() , tree.maxMemoryUsage=0; Pointer( Real ) solution = tree.SolveSystem( *pointInfo , constraints , ShowResidual.set , Iters.value , MaxSolveDepth.value , CGDepth.value , CSSolverAccuracy.value ); delete pointInfo; FreePointer( constraints ); DumpOutput2( comments[commentNum++] , "# Linear system solved in: %9.1f (s), %9.1f (MB)\n" , PTime()-t , tree.maxMemoryUsage ); DumpOutput( "Memory Usage: %.3f MB\n" , float( MemoryInfo::Usage() )/(1<<20) ); maxMemoryUsage = std::max< double >( maxMemoryUsage , tree.maxMemoryUsage ); CoredFileMeshData< Vertex > mesh; if( Verbose.set ) tree.maxMemoryUsage=0; t=PTime(); isoValue = tree.GetIsoValue( solution , *centerWeights ); delete centerWeights; DumpOutput( "Got average in: %f\n" , PTime()-t ); DumpOutput( "Iso-Value: %e\n" , isoValue ); if( VoxelGrid.set ) { double t = PTime(); FILE* fp = fopen( VoxelGrid.value , "wb" ); if( !fp ) fprintf( stderr , "Failed to open voxel file for writing: %s\n" , VoxelGrid.value ); else { int res; Pointer( Real ) values = tree.Evaluate( solution , res , isoValue , VoxelDepth.value ); fwrite( &res , sizeof(int) , 1 , fp ); if( sizeof(Real)==sizeof(float) ) fwrite( values , sizeof(float) , res*res*res , fp ); else { float *fValues = new float[res*res*res]; for( int i=0 ; i<res*res*res ; i++ ) fValues[i] = float( values[i] ); fwrite( fValues , sizeof(float) , res*res*res , fp ); delete[] fValues; } fclose( fp ); DeletePointer( values ); } DumpOutput( "Got voxel grid in: %f\n" , PTime()-t ); } if( Out.set ) { t = PTime() , tree.maxMemoryUsage = 0; tree.GetMCIsoSurface( kernelDensityWeights ? GetPointer( *kernelDensityWeights ) : NullPointer< Real >() , solution , isoValue , mesh , true , !NonManifold.set , PolygonMesh.set ); if( PolygonMesh.set ) DumpOutput2( comments[commentNum++] , "# Got polygons in: %9.1f (s), %9.1f (MB)\n" , PTime()-t , tree.maxMemoryUsage ); else DumpOutput2( comments[commentNum++] , "# Got triangles in: %9.1f (s), %9.1f (MB)\n" , PTime()-t , tree.maxMemoryUsage ); maxMemoryUsage = std::max< double >( maxMemoryUsage , tree.maxMemoryUsage ); DumpOutput2( comments[commentNum++],"# Total Solve: %9.1f (s), %9.1f (MB)\n" , PTime()-tt , maxMemoryUsage ); if( NoComments.set ) { if( ASCII.set ) PlyWritePolygons( Out.value , &mesh , PLY_ASCII , NULL , 0 , iXForm ); else PlyWritePolygons( Out.value , &mesh , PLY_BINARY_NATIVE , NULL , 0 , iXForm ); } else { if( ASCII.set ) PlyWritePolygons( Out.value , &mesh , PLY_ASCII , comments , commentNum , iXForm ); else PlyWritePolygons( Out.value , &mesh , PLY_BINARY_NATIVE , comments , commentNum , iXForm ); } DumpOutput( "Vertices / Polygons: %d / %d\n" , mesh.outOfCorePointCount()+mesh.inCorePoints.size() , mesh.polygonCount() ); } FreePointer( solution ); return 1; }