MagicDGP::LightMesh3D* PoissonReconstruction::SurfaceTrimmer(int argc , char* argv[], std::vector< PlyValueVertex< float > >& vertices, std::vector< std::vector< int > >& polygons)
    {
        cmdLineString In( "in" ) , Out( "out" );
        cmdLineInt Smooth( "smooth" , 5 );
        cmdLineFloat Trim( "trim" ) , IslandAreaRatio( "aRatio" , 0.001f );
        cmdLineFloatArray< 2 > ColorRange( "color" );
        cmdLineReadable PolygonMesh( "polygonMesh" );

        cmdLineReadable* params[] =
        {
            &In , &Out , &Trim , &PolygonMesh , &ColorRange , &Smooth , &IslandAreaRatio
        };

        int paramNum = sizeof(params)/sizeof(cmdLineReadable*);
        cmdLineParse( argc , argv, paramNum , params , 0 );

        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; }

        for( int i=0 ; i<Smooth.value ; i++ ) SmoothValues( vertices , polygons );

        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 );

            MagicDGP::LightMesh3D* pExportMesh = new MagicDGP::LightMesh3D;
            for (int pIndex = 0; pIndex < vertices.size(); pIndex++)
            {
                PlyValueVertex< float > vert = vertices.at(pIndex);
                MagicMath::Vector3 vertPos(vert.point[0], vert.point[1], vert.point[2]);
                pExportMesh->InsertVertex(vertPos);
            }
            for (int pIndex = 0; pIndex < gtPolygons.size(); pIndex++)
            {
                MagicDGP::FaceIndex faceIdx;
                for (int k = 0; k < 3; k++)
                {
                    faceIdx.mIndex[k] = gtPolygons.at(pIndex).at(k);
                }
                pExportMesh->InsertFace(faceIdx);
            }
            pExportMesh->UpdateNormal();
            
            return pExportMesh;
        }
        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 );
            //if( Out.set ) PlyWritePolygons( Out.value , outVertices , polygons , PlyColorVertex< float >::Properties , PlyColorVertex< float >::Components , 1 , NULL , 0 );
        }

        return NULL;
    }
示例#2
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;
}