static int SearchMaxAreaBoundary( const PointArray& bpts, const IntArray& bpos ) { double maxArea = -1; int pos = -1; for( int i = 0; i < ( int )bpos.size(); i++ ) { int s = 0; for( int j = 0; j < i; j++ ) { s += bpos[j]; } int t = s + bpos[i]; PointArray polygon; std::copy( bpts.begin() + s, bpts.begin() + t, std::back_inserter( polygon ) ); if( pos == -1 ) { pos = i; maxArea = PolygonArea( polygon ); } else { double area = PolygonArea( polygon ); if( area > maxArea ) { pos = i; maxArea = area; } } } return pos; }
void DropPolygonRecursive( node_t *n, polygon_t *p ) { if ( n->child[0] == -1 && n->child[1] == -1 ) { fp_t area; // leaf area = PolygonArea( p ); // printf( " split: %f\n", area ); if ( area > g_best_area ) { g_best_area = area; g_best_leaf = n; } } else { polygon_t *front; polygon_t *back; // node SplitPolygon( p, n->norm, n->dist, &front, &back ); if ( front ) { DropPolygonRecursive( &g_nodes[n->child[0]], front ); FreePolygon( front ); } if ( back ) { DropPolygonRecursive( &g_nodes[n->child[1]], back ); FreePolygon( back ); } } }
void FindLeafForPolygon( polygon_t *p ) { g_best_area = -1.0; g_best_leaf = NULL; DropPolygonRecursive( &g_nodes[0], p ); if ( !g_best_leaf ) Error( "no leaf found\n" ); printf( " %.2f%% of polygon area in one leaf\n", 100.0*g_best_area/PolygonArea(p) ); }
/* ==================== CalcBrushVolume ==================== */ fp_t CalcBrushVolume( cbspbrush_t *in ) { int i; fp_t area, volume, d; polygon_t *p; vec3d_t corner; cplane_t *pl; if ( !in ) return 0.0; p = NULL; for ( i = 0; i < in->surfacenum; i++ ) { p = in->surfaces[i].p; if ( p ) break; } if ( !p ) return 0.0; Vec3dCopy( corner, p->p[0] ); volume = 0; for ( ; i < in->surfacenum; i++ ) { p = in->surfaces[i].p; if ( !p ) continue; pl = in->surfaces[i].pl; d = -(Vec3dDotProduct( corner, pl->norm ) - pl->dist ); area = PolygonArea( p ); volume += d*area; } volume /= 3; return volume; }
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 , <Polygons , >Polygons , <Flags , >Flags , 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; }
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 , <Polygons , >Polygons , <Flags , >Flags , 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; }
int main (int argc, char **argv) { srand(time(NULL)); int i, j, k; float minSize = 10000, maxSize = 1.0, minPeriod = 0.1, minStable = 0.1; PStack im2Regions = NewPStack(100); Image im2 = ReadPGMFile(argv[1]); Image out = ConvertImage1(CopyImage(im2)); fprintf(stderr,"Read in image %s with dimensions %d %d\n",argv[1],im2->rows,im2->cols); FindMSERegions(im2,im2Regions,minSize,maxSize,1,2,FALSE,TRUE); PStack dc = NewPStack(10); for(i=0;i<im2Regions->stacksize;i++) { Region re = im2Regions->items[i]; float area = PolygonArea(re->border); float numberOfSections = area / 44000; if ( numberOfSections >= 1 && numberOfSections < 5 ) { PolygonACD(re->border,0.06,dc); } } Region cc = im2Regions->items[i]; //DrawPolygon(cc->border,out,PIX3(0,255,0)); for(i=0;i<dc->stacksize;i++) { Polygon border = dc->items[i]; int area = PolygonArea(border); if ( area < 44000 || area > 44000 * 1.6 ) continue; PolygonVertexEvolution(border,4); int color = RandomColor(150); for(j=0;j<border->numberOfVertices;j++) { Ellipse e = NewEllipse(border->vertices[j].x,border->vertices[j].y,5,5,0); DrawEllipse(e,out,color); free(e); } DrawPolygon(border,out,color); } WritePPM("sections.ppm",out); //RegionsToSIFTDescriptors(im1Regions,im1Descriptors,4,8,41); //fprintf(stderr,"Created %d descriptors from %d regions in %2.2f seconds\n",im1Descriptors->stacksize,im1Regions->stacksize,CPUTIME-t0); //PrintSIFTDescriptors("csift1",im1Descriptors); /* PStack im2Regions = NewPStack(100); PStack im2Descriptors = NewPStack(100); t0 = CPUTIME; Image im2 = ReadPGMFile(argv[2]); FindMSERegions(im2,im2Regions,minSize,maxSize,minPeriod,minStable); RegionsToSIFTDescriptors(im2Regions,im2Descriptors,4,8,41); fprintf(stderr,"Created %d descriptors from %d regions in %2.2f seconds\n",im2Descriptors->stacksize,im2Regions->stacksize,CPUTIME-t0); PStack matches = NewPStack(100); double **transform = AllocDMatrix(3,3,0,0); FindMatches(im1Descriptors,im2Descriptors,matches,10); fprintf(stderr,"Found %d initial matches.\n",matches->stacksize); ScreenMatches(matches,transform); fprintf(stderr,"A1 = [ "); for(k=0;k<3;k++)fprintf(stderr,"%f %f %f;",transform[k][0],transform[k][1],transform[k][2]); fprintf(stderr,"]\n"); Image im3 = CreateImage(im1->rows,im1->cols); AffineTransformImage(im2,im3,NULL,transform); for (i=0;i<im1->rows;i++) { for (j=0;j<im1->cols;j++) { int rv = MAX(0,im1->pixels[i][j]); int bv = MAX(0,im3->pixels[i][j]); im3->pixels[i][j] = PIX3(rv,0,bv); }} WritePPM("affine.ppm",im3); */ return 0; }