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;
}
int Execute( int argc , char* argv[] )
{
	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++ ) fscanf( fp , " %f " , &xForm( i , j ) );
			fclose( fp );
		}
	}
	else xForm = XForm4x4< Real >::Identity();
	iXForm = xForm.inverse();

	DumpOutput2( comments[commentNum++] , "Running Screened Poisson Reconstruction (Version 5.5)\n" , Degree );
	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=Time();
	Real isoValue = 0;

	POctree< Degree , OutputDensity > tree;
	tree.threads = Threads.value;
	if( !In.set )
	{
		ShowUsage(argv[0]);
		return 0;
	}
	if( !MaxSolveDepth.set ) MaxSolveDepth.value = Depth.value;
	if( SolverDivide.value<MinDepth.value )
	{
		fprintf( stderr , "[WARNING] %s must be at least as large as %s: %d>=%d\n" , SolverDivide.name , MinDepth.name , SolverDivide.value , MinDepth.value );
		SolverDivide.value = MinDepth.value;
	}
	if( IsoDivide.value<MinDepth.value )
	{
		fprintf( stderr , "[WARNING] %s must be at least as large as %s: %d>=%d\n" , IsoDivide.name , MinDepth.name , IsoDivide.value , IsoDivide.value );
		IsoDivide.value = MinDepth.value;
	}
	
	OctNode< TreeNodeData< OutputDensity > , Real >::SetAllocator( MEMORY_ALLOCATOR_BLOCK_SIZE );

	t=Time();
	int kernelDepth = KernelDepth.set ?  KernelDepth.value : Depth.value-2;

	tree.setBSplineData( Depth.value , BoundaryType.value );
	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=Time() , tree.maxMemoryUsage=0;
	int pointCount = tree.setTree( In.value , Depth.value , MinDepth.value , kernelDepth , Real(SamplesPerNode.value) , Scale.value , Confidence.set , PointWeight.value , AdaptiveExponent.value , xForm );
	tree.ClipTree();
	tree.finalize( IsoDivide.value );

	DumpOutput2( comments[commentNum++] , "#             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;
	t=Time() , tree.maxMemoryUsage=0;
	tree.SetLaplacianConstraints();
	DumpOutput2( comments[commentNum++] , "#      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 );

	t=Time() , tree.maxMemoryUsage=0;
	tree.LaplacianMatrixIteration( SolverDivide.value, ShowResidual.set , MinIters.value , SolverAccuracy.value , MaxSolveDepth.value , FixedIters.value );
	DumpOutput2( comments[commentNum++] , "# 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< Vertex > mesh;

	if( Verbose.set ) tree.maxMemoryUsage=0;
	t=Time();
	isoValue = tree.GetIsoValue();
	DumpOutput( "Got average in: %f\n" , Time()-t );
	DumpOutput( "Iso-Value: %e\n" , isoValue );

	if( VoxelGrid.set )
	{
		double t = Time();
		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.GetSolutionGrid( 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" , Time()-t );
	}

	if( Out.set )
	{
		t = Time() , tree.maxMemoryUsage = 0;
		tree.GetMCIsoTriangles( isoValue , IsoDivide.value , &mesh , 0 , 1 , !NonManifold.set , PolygonMesh.set );
		if( PolygonMesh.set ) DumpOutput2( comments[commentNum++] , "#         Got polygons in: %9.1f (s), %9.1f (MB)\n" , Time()-t , tree.maxMemoryUsage );
		else                  DumpOutput2( comments[commentNum++] , "#        Got triangles in: %9.1f (s), %9.1f (MB)\n" , Time()-t , tree.maxMemoryUsage );
		maxMemoryUsage = std::max< double >( maxMemoryUsage , tree.maxMemoryUsage );
		DumpOutput2( comments[commentNum++],"#             Total Solve: %9.1f (s), %9.1f (MB)\n" , Time()-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 );
		}
	}

	return 1;
}
Exemple #3
0
int Execute(int argc,char* argv[])
{
	int i;
	cmdLineString In,Out;
	cmdLineReadable Binary,Verbose,NoResetSamples,NoClipTree,Confidence,Manifold,PolygonMesh;
	cmdLineInt Depth(8),SolverDivide(8),IsoDivide(8),Refine(3);
	cmdLineInt KernelDepth;
	cmdLineFloat SamplesPerNode(1.0f),Scale(1.1f);
	char* paramNames[]=
	{
		"in","depth","out","refine","noResetSamples","noClipTree",
		"binary","solverDivide","isoDivide","scale","verbose",
		"kernelDepth","samplesPerNode","confidence","manifold","polygonMesh"
	};
	cmdLineReadable* params[]=
	{
		&In,&Depth,&Out,&Refine,&NoResetSamples,&NoClipTree,
		&Binary,&SolverDivide,&IsoDivide,&Scale,&Verbose,
		&KernelDepth,&SamplesPerNode,&Confidence,&Manifold,&PolygonMesh
	};
	int paramNum=sizeof(paramNames)/sizeof(char*);
	int commentNum=0;
	char **comments;

	comments=new char*[paramNum+7];
	for(i=0;i<paramNum+7;i++){comments[i]=new char[1024];}

	const char* Rev = "Rev: V2 ";
	const char* Date = "Date: 2006-11-09 (Thur, 09 Nov 2006) ";

	cmdLineParse(argc-1,&argv[1],paramNames,paramNum,params,0);

	if(Verbose.set){echoStdout=1;}

	DumpOutput2(comments[commentNum++],"Running Multi-Grid Octree Surface Reconstructor (degree %d). Version 3\n", Degree);
	if(In.set)				{DumpOutput2(comments[commentNum++],"\t--in %s\n",In.value);}
	if(Out.set)				{DumpOutput2(comments[commentNum++],"\t--out %s\n",Out.value);}
	if(Binary.set)			{DumpOutput2(comments[commentNum++],"\t--binary\n");}
	if(Depth.set)			{DumpOutput2(comments[commentNum++],"\t--depth %d\n",Depth.value);}
	if(SolverDivide.set)	{DumpOutput2(comments[commentNum++],"\t--solverDivide %d\n",SolverDivide.value);}
	if(IsoDivide.set)		{DumpOutput2(comments[commentNum++],"\t--isoDivide %d\n",IsoDivide.value);}
	if(Refine.set)			{DumpOutput2(comments[commentNum++],"\t--refine %d\n",Refine.value);}
	if(Scale.set)			{DumpOutput2(comments[commentNum++],"\t--scale %f\n",Scale.value);}
	if(KernelDepth.set)		{DumpOutput2(comments[commentNum++],"\t--kernelDepth %d\n",KernelDepth.value);}
	if(SamplesPerNode.set)	{DumpOutput2(comments[commentNum++],"\t--samplesPerNode %f\n",SamplesPerNode.value);}
	if(NoResetSamples.set)	{DumpOutput2(comments[commentNum++],"\t--noResetSamples\n");}
	if(NoClipTree.set)		{DumpOutput2(comments[commentNum++],"\t--noClipTree\n");}
	if(Confidence.set)		{DumpOutput2(comments[commentNum++],"\t--confidence\n");}
	if(Manifold.set)		{DumpOutput2(comments[commentNum++],"\t--manifold\n");}
	if(PolygonMesh.set)		{DumpOutput2(comments[commentNum++],"\t--polygonMesh\n");}

	double t;
	double tt=Time();
	Point3D<float> center;
	Real scale=1.0;
	Real isoValue=0;
	//////////////////////////////////
	// Fix courtesy of David Gallup //
	TreeNodeData::UseIndex = 1;     //
	//////////////////////////////////
	Octree<Degree> tree;
	PPolynomial<Degree> ReconstructionFunction=PPolynomial<Degree>::GaussianApproximation();

	center.coords[0]=center.coords[1]=center.coords[2]=0;
	if(!In.set || !Out.set)
	{
		ShowUsage(argv[0]);
		return 0;
	}
	
	TreeOctNode::SetAllocator(MEMORY_ALLOCATOR_BLOCK_SIZE);

	t=Time();
	int kernelDepth=Depth.value-2;
	if(KernelDepth.set){kernelDepth=KernelDepth.value;}

	tree.setFunctionData(ReconstructionFunction,Depth.value,0,Real(1.0)/(1<<Depth.value));
	DumpOutput("Function Data Set In: %lg\n",Time()-t);
	DumpOutput("Memory Usage: %.3f MB\n",float(MemoryInfo::Usage())/(1<<20));
	if(kernelDepth>Depth.value){
		fprintf(stderr,"KernelDepth can't be greater than Depth: %d <= %d\n",kernelDepth,Depth.value);
		return EXIT_FAILURE;
	}


	t=Time();
#if 1
	tree.setTree(In.value,Depth.value,Binary.set,kernelDepth,Real(SamplesPerNode.value),Scale.value,center,scale,!NoResetSamples.set,Confidence.set);
#else
if(Confidence.set){
	tree.setTree(In.value,Depth.value,Binary.set,kernelDepth,Real(SamplesPerNode.value),Scale.value,center,scale,!NoResetSamples.set,0,1);
}
else{
	tree.setTree(In.value,Depth.value,Binary.set,kernelDepth,Real(SamplesPerNode.value),Scale.value,center,scale,!NoResetSamples.set,0,0);
}
#endif
	DumpOutput2(comments[commentNum++],"#             Tree set in: %9.1f (s), %9.1f (MB)\n",Time()-t,tree.maxMemoryUsage);
	DumpOutput("Leaves/Nodes: %d/%d\n",tree.tree.leaves(),tree.tree.nodes());
	DumpOutput("   Tree Size: %.3f MB\n",float(sizeof(TreeOctNode)*tree.tree.nodes())/(1<<20));
	DumpOutput("Memory Usage: %.3f MB\n",float(MemoryInfo::Usage())/(1<<20));

	if(!NoClipTree.set){
		t=Time();
		tree.ClipTree();
		DumpOutput("Tree Clipped In: %lg\n",Time()-t);
		DumpOutput("Leaves/Nodes: %d/%d\n",tree.tree.leaves(),tree.tree.nodes());
		DumpOutput("   Tree Size: %.3f MB\n",float(sizeof(TreeOctNode)*tree.tree.nodes())/(1<<20));
	}

	t=Time();
	tree.finalize1(Refine.value);
	DumpOutput("Finalized 1 In: %lg\n",Time()-t);
	DumpOutput("Leaves/Nodes: %d/%d\n",tree.tree.leaves(),tree.tree.nodes());
	DumpOutput("Memory Usage: %.3f MB\n",float(MemoryInfo::Usage())/(1<<20));

	t=Time();
	tree.maxMemoryUsage=0;
	tree.SetLaplacianWeights();
	DumpOutput2(comments[commentNum++],"#Laplacian Weights Set In: %9.1f (s), %9.1f (MB)\n",Time()-t,tree.maxMemoryUsage);
	DumpOutput("Memory Usage: %.3f MB\n",float(MemoryInfo::Usage())/(1<<20));

	t=Time();
	tree.finalize2(Refine.value);
	DumpOutput("Finalized 2 In: %lg\n",Time()-t);
	DumpOutput("Leaves/Nodes: %d/%d\n",tree.tree.leaves(),tree.tree.nodes());
	DumpOutput("Memory Usage: %.3f MB\n",float(MemoryInfo::Usage())/(1<<20));

	tree.maxMemoryUsage=0;
	t=Time();
	tree.LaplacianMatrixIteration(SolverDivide.value);
	DumpOutput2(comments[commentNum++],"# 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));

	CoredVectorMeshData mesh;
	tree.maxMemoryUsage=0;
	t=Time();
	isoValue=tree.GetIsoValue();
	DumpOutput("Got average in: %f\n",Time()-t);
	DumpOutput("Iso-Value: %e\n",isoValue);
	DumpOutput("Memory Usage: %.3f MB\n",float(tree.MemoryUsage()));

	t=Time();
	if(IsoDivide.value) tree.GetMCIsoTriangles( isoValue , IsoDivide.value , &mesh , 0 , 1 , Manifold.set , PolygonMesh.set );
	else                tree.GetMCIsoTriangles( isoValue ,                   &mesh , 0 , 1 , Manifold.set , PolygonMesh.set );
	if( PolygonMesh.set ) DumpOutput2(comments[commentNum++],"#         Got Polygons in: %9.1f (s), %9.1f (MB)\n",Time()-t,tree.maxMemoryUsage);
	else                  DumpOutput2(comments[commentNum++],"#        Got Triangles in: %9.1f (s), %9.1f (MB)\n",Time()-t,tree.maxMemoryUsage);
	DumpOutput2(comments[commentNum++],"#              Total Time: %9.1f (s)\n",Time()-tt);
	PlyWritePolygons(Out.value,&mesh,PLY_BINARY_NATIVE,center,scale,comments,commentNum);

	return 1;
}
Exemple #4
0
int main( int argc , char* argv[] )
{
	int paramNum = sizeof(params)/sizeof(cmdLineReadable*);
	cmdLineParse( argc-1 , &argv[1] , paramNum , params , 0 );

#if FOR_RELEASE
	if( !In.set || !Trim.set )
	{
		ShowUsage( argv[0] );
		return EXIT_FAILURE;
	}
#else // !FOR_RELEASE
	if( !In.set )
	{
		ShowUsage( argv[0] );
		return EXIT_FAILURE;
	}
#endif // FOR_RELEASE
	float min , max;
	std::vector< PlyValueVertex< float > > vertices;
	std::vector< std::vector< int > > polygons;

	int ft , commentNum = paramNum+2;
	char** comments;
	bool readFlags[ PlyValueVertex< float >::Components ];
	PlyReadPolygons( In.value , vertices , polygons , PlyValueVertex< float >::Properties , PlyValueVertex< float >::Components , ft , &comments , &commentNum , readFlags );
	if( !readFlags[3] ){ fprintf( stderr , "[ERROR] vertices do not have value flag\n" ) ; return EXIT_FAILURE; }
#if 0
	if( Trim.set ) for( int i=0 ; i<Smooth.value ; i++ ) SmoothValues( vertices , polygons , Trim.value-0.5f , Trim.value+0.5f );
	else           for( int i=0 ; i<Smooth.value ; i++ ) SmoothValues( vertices , polygons );
#else
	for( int i=0 ; i<Smooth.value ; i++ ) SmoothValues( vertices , polygons );
#endif 
	min = max = vertices[0].value;
	for( size_t i=0 ; i<vertices.size() ; i++ ) min = std::min< float >( min , vertices[i].value ) , max = std::max< float >( max , vertices[i].value );
	printf( "Value Range: [%f,%f]\n" , min , max );


	if( Trim.set )
	{
		hash_map< long long , int > vertexTable;
		std::vector< std::vector< int > > ltPolygons , gtPolygons;
		std::vector< bool > ltFlags , gtFlags;

		for( int i=0 ; i<paramNum+2 ; i++ ) comments[i+commentNum]=new char[1024];
		sprintf( comments[commentNum++] , "Running Surface Trimmer (V5)" );
		if(              In.set ) sprintf(comments[commentNum++],"\t--%s %s" , In.name , In.value );
		if(             Out.set ) sprintf(comments[commentNum++],"\t--%s %s" , Out.name , Out.value );
		if(            Trim.set ) sprintf(comments[commentNum++],"\t--%s %f" , Trim.name , Trim.value );
		if(          Smooth.set ) sprintf(comments[commentNum++],"\t--%s %d" , Smooth.name , Smooth.value );
		if( IslandAreaRatio.set ) sprintf(comments[commentNum++],"\t--%s %f" , IslandAreaRatio.name , IslandAreaRatio.value );
		if(     PolygonMesh.set ) sprintf(comments[commentNum++],"\t--%s" , PolygonMesh.name );

		double t=Time();
		for( size_t i=0 ; i<polygons.size() ; i++ ) SplitPolygon( polygons[i] , vertices , &ltPolygons , &gtPolygons , &ltFlags , &gtFlags , vertexTable , Trim.value );
		if( IslandAreaRatio.value>0 )
		{
			std::vector< std::vector< int > > _ltPolygons , _gtPolygons;
			std::vector< std::vector< int > > ltComponents , gtComponents;
			SetConnectedComponents( ltPolygons , ltComponents );
			SetConnectedComponents( gtPolygons , gtComponents );
			std::vector< double > ltAreas( ltComponents.size() , 0. ) , gtAreas( gtComponents.size() , 0. );
			std::vector< bool > ltComponentFlags( ltComponents.size() , false ) , gtComponentFlags( gtComponents.size() , false );
			double area = 0.;
			for( size_t i=0 ; i<ltComponents.size() ; i++ )
			{
				for( size_t j=0 ; j<ltComponents[i].size() ; j++ )
				{
					ltAreas[i] += PolygonArea( vertices , ltPolygons[ ltComponents[i][j] ] );
					ltComponentFlags[i] = ( ltComponentFlags[i] || ltFlags[ ltComponents[i][j] ] );
				}
				area += ltAreas[i];
			}
			for( size_t i=0 ; i<gtComponents.size() ; i++ )
			{
				for( size_t j=0 ; j<gtComponents[i].size() ; j++ )
				{
					gtAreas[i] += PolygonArea( vertices , gtPolygons[ gtComponents[i][j] ] );
					gtComponentFlags[i] = ( gtComponentFlags[i] || gtFlags[ gtComponents[i][j] ] );
				}
				area += gtAreas[i];
			}
			for( size_t i=0 ; i<ltComponents.size() ; i++ )
			{
				if( ltAreas[i]<area*IslandAreaRatio.value && ltComponentFlags[i] ) for( size_t j=0 ; j<ltComponents[i].size() ; j++ ) _gtPolygons.push_back( ltPolygons[ ltComponents[i][j] ] );
				else                                                               for( size_t j=0 ; j<ltComponents[i].size() ; j++ ) _ltPolygons.push_back( ltPolygons[ ltComponents[i][j] ] );
			}
			for( size_t i=0 ; i<gtComponents.size() ; i++ )
			{
				if( gtAreas[i]<area*IslandAreaRatio.value && gtComponentFlags[i] ) for( size_t j=0 ; j<gtComponents[i].size() ; j++ ) _ltPolygons.push_back( gtPolygons[ gtComponents[i][j] ] );
				else                                                               for( size_t j=0 ; j<gtComponents[i].size() ; j++ ) _gtPolygons.push_back( gtPolygons[ gtComponents[i][j] ] );
			}
			ltPolygons = _ltPolygons , gtPolygons = _gtPolygons;
		}
		if( !PolygonMesh.set )
		{
			{
				std::vector< std::vector< int > > polys = ltPolygons;
				Triangulate( vertices , ltPolygons , polys ) , ltPolygons = polys;
			}
			{
				std::vector< std::vector< int > > polys = gtPolygons;
				Triangulate( vertices , gtPolygons , polys ) , gtPolygons = polys;
			}
		}

		RemoveHangingVertices( vertices , gtPolygons );
		sprintf( comments[commentNum++] , "#Trimmed In: %9.1f (s)" , Time()-t );
		if( Out.set ) PlyWritePolygons( Out.value , vertices , gtPolygons , PlyValueVertex< float >::Properties , PlyValueVertex< float >::Components , ft , comments , commentNum );
	}
	else
	{
		if( ColorRange.set ) min = ColorRange.values[0] , max = ColorRange.values[1];
		std::vector< PlyColorVertex< float > > outVertices;
		ColorVertices( vertices , outVertices , min , max );
		if( Out.set ) PlyWritePolygons( Out.value , outVertices , polygons , PlyColorVertex< float >::Properties , PlyColorVertex< float >::Components , ft , comments , commentNum );
	}

	return EXIT_SUCCESS;
}