Пример #1
0
polyhedron cgal_to_polyhedron( const Nef_polyhedron &NP ){
    Polyhedron P;
    polyhedron ret;
    
    if( NP.is_simple() ){
        NP.convert_to_polyhedron(P);
        std::vector<double> coords;
        std::vector<int> tris;
        int next_id = 0;
        std::map< Polyhedron::Vertex*, int > vid;
        for( Polyhedron::Vertex_iterator iter=P.vertices_begin(); iter!=P.vertices_end(); iter++ ){
            coords.push_back( CGAL::to_double( (*iter).point().x() ) );
            coords.push_back( CGAL::to_double( (*iter).point().y() ) );
            coords.push_back( CGAL::to_double( (*iter).point().z() ) );
            vid[ &(*iter) ] = next_id++;
        }
        
        for( Polyhedron::Facet_iterator iter=P.facets_begin(); iter!=P.facets_end(); iter++ ){
            Polyhedron::Halfedge_around_facet_circulator j = iter->facet_begin();
            tris.push_back( CGAL::circulator_size(j) );
            do {
                tris.push_back( std::distance(P.vertices_begin(), j->vertex()) );
            } while ( ++j != iter->facet_begin());
        }
        
        ret.initialize_load_from_mesh( coords, tris );
    } else {
        std::cout << "resulting polyhedron is not simple!" << std::endl;
    }
    return ret;
}
Пример #2
0
void smoothMesh( Polyhedron & poly, unsigned int nTimes )
{
    int nV = poly.size_of_vertices();
    const double lambda = SMOOTHING_LAMBDA;
    const double mu	= SMOOTHING_MU;

    vector< Point3 > shrink  ( nV );
    vector< Point3 > expand  ( nV );

    for ( unsigned int k = 0; k < nTimes; ++k ) {
	// copy the vertex coordinates
	for ( Vertex_iterator vi = poly.vertices_begin(); vi != poly.vertices_end(); ++vi ) {
	    shrink  [ vi->id() ] = vi->point();
	}
	// shrinking stage
	for ( Vertex_iterator vi = poly.vertices_begin(); vi != poly.vertices_end(); ++vi ) {
	    moveVertex( vi, shrink[ vi->id() ], lambda );
	}
	// copy back the vertex coordinates
	for ( Vertex_iterator vi = poly.vertices_begin(); vi != poly.vertices_end(); ++vi ) {
	    vi->point()		= shrink[ vi->id() ];
	    expand[ vi->id() ]	= shrink[ vi->id() ];
	}
	// expanding stage
	for ( Vertex_iterator vi = poly.vertices_begin(); vi != poly.vertices_end(); ++vi ) {
	    moveVertex( vi, expand[ vi->id() ], mu );
	}
	// copy back the vertex coordinates
	for ( Vertex_iterator vi = poly.vertices_begin(); vi != poly.vertices_end(); ++vi ) {
	    vi->point()		= expand[ vi->id() ];
	}
    }
}
Пример #3
0
void geometryUtils::subdivide(Polyhedron& P) {
    if (P.size_of_facets() == 0)
        return;
    // We use that new vertices/halfedges/facets are appended at the end.
    std::size_t nv = P.size_of_vertices();
    Vertex_iterator last_v = P.vertices_end();
    --last_v; // the last of the old vertices
    Edge_iterator last_e = P.edges_end();
    --last_e; // the last of the old edges
    Facet_iterator last_f = P.facets_end();
    --last_f; // the last of the old facets
    Facet_iterator f = P.facets_begin(); // create new center vertices
    do {
        geometryUtils::subdivide_create_center_vertex(P, f);
    } while (f++ != last_f);
    std::vector<Point_3> pts; // smooth the old vertices
    pts.reserve(nv); // get intermediate space for the new points
    ++last_v; // make it the past-the-end position again
    std::transform(P.vertices_begin(), last_v, std::back_inserter(pts),
            Smooth_old_vertex());
    std::copy(pts.begin(), pts.end(), P.points_begin());
    Edge_iterator e = P.edges_begin(); // flip the old edges
    ++last_e; // make it the past-the-end position again
    while (e != last_e) {
        Halfedge_handle h = e;
        ++e; // careful, incr. before flip since flip destroys current edge
        geometryUtils::subdivide_flip_edge(P, h);
    };
    CGAL_postcondition(P.is_valid());
};
Пример #4
0
void renewAttrs( Polyhedron & poly )
{
    // assign IDs to vertices
    for ( Vertex_iterator vi = poly.vertices_begin(); vi != poly.vertices_end(); ++vi ) {
	vi->nCuts()	= 0;
    }

    // assign IDs to faces: the dual vertex and the dual coordinates-the center coordinates
    for ( Facet_iterator fi = poly.facets_begin(); fi != poly.facets_end(); ++fi ) {
	fi->piece()	= NO_INDEX;
	Vector3 sum( 0.0, 0.0, 0.0 );
	Halfedge_facet_circulator hfc = fi->facet_begin();
	do {
	    sum = sum + ( hfc->vertex()->point() - CGAL::ORIGIN );
	} while ( ++hfc != fi->facet_begin() );
	sum = sum / ( double )CGAL::circulator_size( hfc );
	fi->center() = CGAL::ORIGIN + sum;
    }

    // assign the same IDs to the identical/ opposite halfedges
    for ( Halfedge_iterator hi = poly.halfedges_begin(); hi != poly.halfedges_end(); ++hi ) {
	hi->label()		= DEFAULT_LABEL;
	hi->match()		= DEFAULT_LABEL;
	hi->cycle()		= NO_INDEX;
	hi->connect()		= true;
	hi->visit()		= false;
	hi->path()		= NO_INDEX;
	hi->orient()		= true;
	// We individually handle hi->fixed
    }
}
Пример #5
0
void transformMesh( Polyhedron & poly, Transformation3 & map )
{
    for ( Vertex_iterator vi = poly.vertices_begin(); vi != poly.vertices_end(); ++vi ) {
	Point3 store = vi->point().transform( map );
	vi->point() = store;
    }
}
Пример #6
0
//------------------------------------------------------------------------------
//	Initialize the dual center 
//------------------------------------------------------------------------------
void initAttrs( Polyhedron & poly )
{
    // assign IDs to vertices
    int vID = 0;
    for ( Vertex_iterator vi = poly.vertices_begin(); vi != poly.vertices_end(); ++vi ) {
	vi->id()	= vID++;
	vi->label()	= DEFAULT_LABEL;
	vi->nCuts()	= 0;
    }
    cerr << "Total number of vertices = " << vID << endl;

    // assign IDs to faces: the dual vertex and the dual coordinates-the center coordinates
    int fID = 0;
    for ( Facet_iterator fi = poly.facets_begin(); fi != poly.facets_end(); ++fi ) {
	fi->id()	= fID++;
	// fi->label()	= DEFAULT_LABEL;
	fi->piece()	= NO_INDEX;
	Vector3 sum( 0.0, 0.0, 0.0 );
	Halfedge_facet_circulator hfc = fi->facet_begin();
	do {
	    sum = sum + ( hfc->vertex()->point() - CGAL::ORIGIN );
	} while ( ++hfc != fi->facet_begin() );
	sum = sum / ( double )CGAL::circulator_size( hfc );
	fi->center() = CGAL::ORIGIN + sum;
	// cerr << " Barycenter No. " << fid-1 << " : " << bary[ fid-1 ] << endl;
    }
    cerr << "Total number of facets = " << fID << endl;

    // initialize the halfedge IDs
    for ( Halfedge_iterator hi = poly.halfedges_begin(); hi != poly.halfedges_end(); ++hi ) {
	hi->id() = NO_INDEX;
    }

    // assign the same IDs to the identical/ opposite halfedges
    int eID = 0;
    for ( Halfedge_iterator hi = poly.halfedges_begin(); hi != poly.halfedges_end(); ++hi ) {
	if ( hi->id() == NO_INDEX ) {
	    assert( hi->opposite()->id() == NO_INDEX );
	    hi->id() = eID;
	    hi->opposite()->id() = eID;
	    eID++;
	    hi->label()		= hi->opposite()->label()	= DEFAULT_LABEL;
	    hi->match()		= hi->opposite()->match()	= DEFAULT_LABEL;
	    hi->cycle()		= hi->opposite()->cycle()	= NO_INDEX;
	    hi->weight()	= hi->opposite()->weight()	= 0.0;
	    hi->connect()	= hi->opposite()->connect()	= true;
	    hi->visit()		= hi->opposite()->visit()	= false;
	    // We individually handle hi->fixed
	}
    }
    cerr << "Total number of edges = " << eID << endl;
}
int main()
{
  std::stringstream ss;
  ss << "\
OFF\n6 4 0\n\
0 1 0\n\
0 0 0\n\
1 0 0\n\
1 1 0\n\
2 1 0\n\
2 0 0\n\
3 0 1 2\n\
3 0 2 3\n\
3 2 5 3\n\
3 5 4 3\n";

  Polyhedron P;
  ss >> P;

  assert( P.size_of_vertices() == 6);
  assert( P.size_of_facets() == 4);
  assert( P.is_valid() );

  //consider vertex 3 and set its halfedge to be on the border
  Polyhedron::Vertex_iterator vit=P.vertices_begin();
  std::advance(vit, 3);
  assert( vit->point() == K::Point_3(1, 1, 0) );
  Polyhedron::Halfedge_handle h=vit->halfedge();
  while ( !h->is_border() )
    h=h->next()->opposite();
  vit->VBase::set_halfedge(h);
  assert( vit->halfedge()->vertex() == vit );

  //consider vertex 4 and set its halfedge to be on the border
  ++vit;
  assert( vit->point() == K::Point_3(2, 1, 0) );
  h=vit->halfedge();
  while ( !h->is_border() )
    h=h->next()->opposite();
  vit->VBase::set_halfedge(h);
  assert( vit->halfedge()->vertex() == vit );

  //try to append a facet
  Appender modifier;
  P.delegate(modifier);

  assert( P.size_of_vertices() == 7);
  assert( P.size_of_facets() == 5);
  assert( P.is_valid() );
}
Пример #8
0
//------------------------------------------------------------------------------
//	Normalize the 3D triangulated mesh with the display window
//------------------------------------------------------------------------------
void normalizeMesh( Polyhedron & poly, vector< Segment3 > & bone )
{
    Vector3 sum, ave;

    for ( Vertex_iterator vi = poly.vertices_begin(); vi != poly.vertices_end(); ++vi ) {
	sum = sum + ( vi->point() - CGAL::ORIGIN );
    }
    ave = sum / ( double )poly.size_of_vertices();

    for ( Vertex_iterator vi = poly.vertices_begin(); vi != poly.vertices_end(); ++vi ) {
	vi->point() = vi->point() - ave;
    }
    
    cerr << " ave = " << ave << endl;
    Transformation3 translate( CGAL::TRANSLATION, -ave );

    // fabs:absolute values-no negative values
    double sideMax = 0.0;
    for ( Vertex_iterator vi = poly.vertices_begin(); vi != poly.vertices_end(); ++vi ) {
	if ( fabs( vi->point().x() ) > sideMax ) sideMax = fabs( vi->point().x() );
	if ( fabs( vi->point().y() ) > sideMax ) sideMax = fabs( vi->point().y() );
	if ( fabs( vi->point().z() ) > sideMax ) sideMax = fabs( vi->point().z() );
    }
    
	// sideMax: the largest number
    for ( Vertex_iterator vi = poly.vertices_begin(); vi != poly.vertices_end(); ++vi ) {
	vi->point() = CGAL::ORIGIN + ( vi->point() - CGAL::ORIGIN ) / sideMax;
    }

    Transformation3 scale( CGAL::SCALING, 1.0/sideMax );

    Transformation3 composite = scale * translate;
	    
    for ( unsigned int k = 0; k < bone.size(); ++k ) {
	bone[ k ] = bone[ k ].transform( composite );
    }
}
Пример #9
0
void modify_vertex_position()
{
	Polyhedron P;
    Halfedge_handle h = P.make_tetrahedron();
    if ( P.is_tetrahedron(h))
	{
		int i(0);
		for(Vertex_iterator vi = P.vertices_begin(); vi != P.vertices_end(); ++vi,++i)
		{
		  std::cout << "before changing vertex " << i << ": " << vi->point().x() << vi->point().y() << vi->point().z() << endl;
		  Point_3 pt(1, 0, 0);
		  vi->point() = pt;
		  std::cout << "after changing vertex " << i << ": " << vi->point().x() << vi->point().y() << vi->point().z() << endl;
		}
	}
}
IGL_INLINE void igl::copyleft::cgal::polyhedron_to_mesh(
  const Polyhedron & poly,
  Eigen::MatrixXd & V,
  Eigen::MatrixXi & F)
{
  using namespace std;
  V.resize(poly.size_of_vertices(),3);
  F.resize(poly.size_of_facets(),3);
  typedef typename Polyhedron::Vertex_const_iterator Vertex_iterator;
  std::map<Vertex_iterator,size_t> vertex_to_index;
  {
    size_t v = 0;
    for(
      typename Polyhedron::Vertex_const_iterator p = poly.vertices_begin();
      p != poly.vertices_end();
      p++)
    {
      V(v,0) = p->point().x();
      V(v,1) = p->point().y();
      V(v,2) = p->point().z();
      vertex_to_index[p] = v;
      v++;
    }
  }
  {
    size_t f = 0;
    for(
      typename Polyhedron::Facet_const_iterator facet = poly.facets_begin();
      facet != poly.facets_end();
      ++facet)
    {
      typename Polyhedron::Halfedge_around_facet_const_circulator he = 
        facet->facet_begin();
      // Facets in polyhedral surfaces are at least triangles.
      assert(CGAL::circulator_size(he) == 3 && "Facets should be triangles");
      size_t c = 0;
      do {
        //// This is stooopidly slow
        // F(f,c) = std::distance(poly.vertices_begin(), he->vertex());
        F(f,c) = vertex_to_index[he->vertex()];
        c++;
      } while ( ++he != facet->facet_begin());
      f++;
    }
  }
}
scalarField calcCurvature(const triSurface& surf)
{
    scalarField k(surf.points().size(), 0);

    Polyhedron P;

    buildCGALPolyhedron convert(surf);
    P.delegate(convert);

    // Info<< "Created CGAL Polyhedron with " << label(P.size_of_vertices())
    //     << " vertices and " << label(P.size_of_facets())
    //     << " facets. " << endl;

    // The rest of this function adapted from
    //     CGAL-3.7/examples/Jet_fitting_3/Mesh_estimation.cpp

     //Vertex property map, with std::map
    typedef std::map<Vertex*, int> Vertex2int_map_type;
    typedef boost::associative_property_map< Vertex2int_map_type >
        Vertex_PM_type;
    typedef T_PolyhedralSurf_rings<Polyhedron, Vertex_PM_type > Poly_rings;

    typedef CGAL::Monge_via_jet_fitting<Kernel>         Monge_via_jet_fitting;
    typedef Monge_via_jet_fitting::Monge_form           Monge_form;

    std::vector<Point_3> in_points;  //container for data points

    // default parameter values and global variables
    unsigned int d_fitting = 2;
    unsigned int d_monge = 2;
    unsigned int min_nb_points = (d_fitting + 1)*(d_fitting + 2)/2;

    //initialize the tag of all vertices to -1
    Vertex_iterator vitb = P.vertices_begin();
    Vertex_iterator vite = P.vertices_end();

    Vertex2int_map_type vertex2props;
    Vertex_PM_type vpm(vertex2props);

    CGAL_For_all(vitb, vite)
    {
        put(vpm, &(*vitb), -1);
    }
Пример #12
0
 int main(int argc, const char **argv )
 {
   std::vector<Point> points;
   CGAL::Random_points_on_sphere_3<Point> g;

   size_t N = 0;
   if (argc > 1)
     N = atof(argv[1]);
   N = std::max(size_t(100), N);

   for (size_t i = 0; i < N; ++i)
     points.push_back(rescale(*g++));

   for (size_t n = 0; n < 100; ++n)
     {
       std::cerr << "step " << n << ":\n\t";
       lloyd_step(points);
     }

   Polyhedron P;
   CGAL::convex_hull_3(points.begin(), points.end(), P);

   CGAL::set_ascii_mode( std::cout);
   std::cout << "OFF" << std::endl << P.size_of_vertices() << ' '
	     << P.size_of_facets() << " 0" << std::endl;
   std::copy( P.points_begin(), P.points_end(),
	      std::ostream_iterator<Point>( std::cout, "\n"));
   for (  Facet_iterator i = P.facets_begin(); i != P.facets_end(); ++i) {
     Halfedge_facet_circulator j = i->facet_begin();
     // Facets in polyhedral surfaces are at least triangles.
     CGAL_assertion( CGAL::circulator_size(j) >= 3);
     std::cout << CGAL::circulator_size(j) << ' ';
     do {
       std::cout << ' ' << std::distance(P.vertices_begin(), j->vertex());
     } while ( ++j != i->facet_begin());
     std::cout << std::endl;
   }

   std::ofstream os ("test.cloud");
   std::copy(points.begin(), points.end(),
	     std::ostream_iterator<Point>(os, "\n"));
}
Пример #13
0
//**********************************************************************************
//returns min coordinates
Vector3r MinCoord(const shared_ptr<Shape>& cm1,const State& state1){
	const Se3r& se3=state1.se3; 
	Polyhedra* A = static_cast<Polyhedra*>(cm1.get());

	//move and rotate CGAL structure Polyhedron
	Matrix3r rot_mat = (se3.orientation).toRotationMatrix();
	Vector3r trans_vec = se3.position;
	Transformation t_rot_trans(rot_mat(0,0),rot_mat(0,1),rot_mat(0,2), trans_vec[0],rot_mat(1,0),rot_mat(1,1),rot_mat(1,2),trans_vec[1],rot_mat(2,0),rot_mat(2,1),rot_mat(2,2),trans_vec[2],1.);
	Polyhedron PA = A->GetPolyhedron();
	std::transform( PA.points_begin(), PA.points_end(), PA.points_begin(), t_rot_trans);
	
	Vector3r minccord = trans_vec;
	for(Polyhedron::Vertex_iterator vi = PA.vertices_begin(); vi != PA.vertices_end(); ++vi){	
		if (vi->point()[0]<minccord[0]) minccord[0]=vi->point()[0];
		if (vi->point()[1]<minccord[1]) minccord[1]=vi->point()[1];
		if (vi->point()[2]<minccord[2]) minccord[2]=vi->point()[2];
	}
	
	return minccord;
}
Пример #14
0
ofMesh & ofxCGALSkinSurface::makeSkinSurfaceMesh() {
    std::list<Weighted_point> l;
    FT shrinkfactor = shrinkFactor;
    
    for(int i=0; i<points.size(); i++) {
        float px = points[i].point.x;
        float py = points[i].point.y;
        float pz = points[i].point.z;
        float radius = points[i].radius;
        
        l.push_front(Weighted_point(Bare_point(px, py, pz), radius * radius));
    }
    
    Skin_surface_3 skin_surface(l.begin(), l.end(), shrinkfactor);
    
    Polyhedron p;
    CGAL::mesh_skin_surface_3(skin_surface, p);
    
    if(bSubdiv == true) {
        CGAL::subdivide_skin_surface_mesh_3(skin_surface, p);
    }
    
    mesh.clear();
    
    map<Point_3, int> point_indices;
    int count = 0;
    
    for (auto it=p.vertices_begin(); it!=p.vertices_end(); ++it) {
        auto& p = it->point();
        mesh.addVertex(ofVec3f(p.x(), p.y(), p.z()));
        point_indices[p] = count++;
    }
    for (auto it=p.facets_begin(); it!=p.facets_end(); ++it) {
        mesh.addIndex(point_indices[it->halfedge()->vertex()->point()]);
        mesh.addIndex(point_indices[it->halfedge()->next()->vertex()->point()]);
        mesh.addIndex(point_indices[it->halfedge()->prev()->vertex()->point()]);
    }
}
Пример #15
0
void alignMesh( Polyhedron & poly )
{
    int num = poly.size_of_vertices();

    // initialization here is very important!!
    Point3 ave( 0.0, 0.0, 0.0 );
    for ( Vertex_iterator vi = poly.vertices_begin(); vi != poly.vertices_end(); ++vi ) {
	ave = ave + ( vi->point() - CGAL::ORIGIN );
    }
    ave = CGAL::ORIGIN + ( ave - CGAL::ORIGIN )/( double )num;

    unsigned int dim	= 3;
    double * data	= new double [ num*dim ];

    int nPoints = 0;
    for ( Vertex_iterator vi = poly.vertices_begin(); vi != poly.vertices_end(); ++vi ) {
	data[ nPoints * dim + 0 ] = vi->point().x() - ave.x();
	data[ nPoints * dim + 1 ] = vi->point().y() - ave.y();
	data[ nPoints * dim + 2 ] = vi->point().z() - ave.z();
	nPoints++;
    }

    assert( nPoints == ( int )num );

    /*****************************************
      analyze the engenstructure of X^T X
     *****************************************/
    /* define the matrix X */
    gsl_matrix_view X = gsl_matrix_view_array( data, num, dim );

    /* memory reallocation */
    // proj = ( double * )realloc( proj, sizeof( double ) * PDIM * num );

    /* calculate the covariance matrix B */
    gsl_matrix * B              = gsl_matrix_alloc( dim, dim );
    gsl_blas_dgemm( CblasTrans, CblasNoTrans, 1.0,
                    &(X.matrix),
                    &(X.matrix), 0.0,
                    B );
       
    /* divided by the number of samples */
    gsl_matrix_scale( B, 1.0/(double)num );

    gsl_vector * eVal       = gsl_vector_alloc( dim );
    gsl_matrix * eVec       = gsl_matrix_alloc( dim, dim );
    gsl_eigen_symmv_workspace * w
                                = gsl_eigen_symmv_alloc( dim );

    // eigenanalysis of the matrix B
    gsl_eigen_symmv( B, eVal, eVec, w );
    // release the memory of w
    gsl_eigen_symmv_free( w );
    // sort eigenvalues in a descending order
    gsl_eigen_symmv_sort( eVal, eVec, GSL_EIGEN_SORT_VAL_DESC );

    // #ifdef MYDEBUG
    for ( unsigned int i = 0; i < dim; ++i ) {
	cerr << "Eigenvalue No. " << i << " = " << gsl_vector_get( eVal, i ) << endl;
	cerr << "Eigenvector No. " << i << endl;
	double length = 0.0;
	for ( unsigned int j = 0; j < dim; ++j ) {
	    cerr << gsl_matrix_get( eVec, i, j ) << " ";
	    length += gsl_matrix_get( eVec, i, j )*gsl_matrix_get( eVec, i, j );
	}
	cerr << " length = " << length << endl;
    }
    // #endif	// MYDEBUG

    // 0 1 2, 0 2 1, 
    

    Transformation3 map;
    map = 
	Transformation3( gsl_matrix_get(eVec,1,0), gsl_matrix_get(eVec,0,0), gsl_matrix_get(eVec,2,0),
			 gsl_matrix_get(eVec,1,1), gsl_matrix_get(eVec,0,1), gsl_matrix_get(eVec,2,1),
			 gsl_matrix_get(eVec,1,2), gsl_matrix_get(eVec,0,2), gsl_matrix_get(eVec,2,2) );
    if ( map.is_odd() ) {
	cerr << " Transformation matrix reflected" << endl;
	map = 
	    Transformation3( gsl_matrix_get(eVec,1,0), gsl_matrix_get(eVec,0,0), -gsl_matrix_get(eVec,2,0),
			     gsl_matrix_get(eVec,1,1), gsl_matrix_get(eVec,0,1), -gsl_matrix_get(eVec,2,1),
			     gsl_matrix_get(eVec,1,2), gsl_matrix_get(eVec,0,2), -gsl_matrix_get(eVec,2,2) );
    }

    for ( unsigned int i = 0; i < dim; ++i ) {
	cerr << "| ";
	for ( unsigned int j = 0; j < dim; ++j ) {
	    cerr << map.cartesian( i, j ) << " ";
	}
	cerr << "|" << endl;
    }

    transformMesh( poly, map );

    return;
}
Пример #16
0
//------------------------------------------------------------------------------
//	Align the mesh
//------------------------------------------------------------------------------
Vector3 principalAxis( Polyhedron & poly )
{
    int num = poly.size_of_vertices();

    // initialization here is very important!!
    Point3 ave( 0.0, 0.0, 0.0 );
    for ( Vertex_iterator vi = poly.vertices_begin(); vi != poly.vertices_end(); ++vi ) {
	ave = ave + ( vi->point() - CGAL::ORIGIN );
    }
    ave = CGAL::ORIGIN + ( ave - CGAL::ORIGIN )/( double )num;

    unsigned int dim	= 3;
    double * data	= new double [ num*dim ];

    int nPoints = 0;
    for ( Vertex_iterator vi = poly.vertices_begin(); vi != poly.vertices_end(); ++vi ) {
	data[ nPoints * dim + 0 ] = vi->point().x() - ave.x();
	data[ nPoints * dim + 1 ] = vi->point().y() - ave.y();
	data[ nPoints * dim + 2 ] = vi->point().z() - ave.z();
	nPoints++;
    }

    assert( nPoints == ( int )num );

    /*****************************************
      analyze the engenstructure of X^T X
     *****************************************/
    /* define the matrix X */
    gsl_matrix_view X = gsl_matrix_view_array( data, num, dim );

    /* memory reallocation */
    // proj = ( double * )realloc( proj, sizeof( double ) * PDIM * num );

    /* calculate the covariance matrix B */
    gsl_matrix * B              = gsl_matrix_alloc( dim, dim );
    gsl_blas_dgemm( CblasTrans, CblasNoTrans, 1.0,
                    &(X.matrix),
                    &(X.matrix), 0.0,
                    B );
       
    /* divided by the number of samples */
    gsl_matrix_scale( B, 1.0/(double)num );

    gsl_vector * eVal       = gsl_vector_alloc( dim );
    gsl_matrix * eVec       = gsl_matrix_alloc( dim, dim );
    gsl_eigen_symmv_workspace * w
                                = gsl_eigen_symmv_alloc( dim );

    // eigenanalysis of the matrix B
    gsl_eigen_symmv( B, eVal, eVec, w );
    // release the memory of w
    gsl_eigen_symmv_free( w );
    // sort eigenvalues in a descending order
    gsl_eigen_symmv_sort( eVal, eVec, GSL_EIGEN_SORT_VAL_DESC );

#ifdef MYDEBUG
    for ( unsigned int i = 0; i < dim; ++i ) {
	cerr << "Eigenvalue No. " << i << " = " << gsl_vector_get( eVal, i ) << endl;
	cerr << "Eigenvector No. " << i << endl;
	for ( unsigned int j = 0; j < dim; ++j ) {
	    length += gsl_matrix_get( eVec, i, j )*gsl_matrix_get( eVec, i, j );
	}
	cerr << " length = " << length << endl;
    }
#endif	// MYDEBUG

    Vector3 ref( gsl_matrix_get( eVec, 0, 0 ),
		 gsl_matrix_get( eVec, 0, 1 ),
		 gsl_matrix_get( eVec, 0, 2 ) );
    return ref;

#ifdef DEBUG
    gsl_vector_view eachVec = gsl_matrix_column( eigenVec, 0 );
    double cosRot = gsl_matrix_get( eigenVec, 0, 1 );
    double sinRot = gsl_matrix_get( eigenVec, 1, 1 );
#ifdef DEBUG
    cerr << " 2nd axis : " << cosRot << " , " << sinRot << endl;
#endif	// DEBUG

    Transformation2 rotate( CGAL::ROTATION, -sinRot, cosRot );
    for ( unsigned int i = 0; i < subpatch.size(); ++i ) {
	subpatch[ i ]->triangle() = subpatch[ i ]->triangle().transform( rotate );
    }
#endif	// DEBUG
}
Пример #17
0
int main(int argc, char * argv[])
{
    std::cerr << "PARAMETERIZATION" << std::endl;
    std::cerr << "  Floater parameterization" << std::endl;
    std::cerr << "  Circle border" << std::endl;
    std::cerr << "  Eigen solver" << std::endl;

    //***************************************
    // decode parameters
    //***************************************

    if (argc-1 != 1)
    {
        std::cerr << "Usage: " << argv[0] << " input_file.off" << std::endl;
        return(EXIT_FAILURE);
    }

    // File name is:
    const char* input_filename  = argv[1];

    //***************************************
    // Read the mesh
    //***************************************

    // Read the mesh
    std::ifstream stream(input_filename);
    Polyhedron mesh;
    stream >> mesh;
    if(!stream || !mesh.is_valid() || mesh.empty())
    {
        std::cerr << "Error: cannot read OFF file " << input_filename << std::endl;
        return EXIT_FAILURE;
    }

    //***************************************
    // Create Polyhedron adaptor
    // Note: no cutting => we support only
    // meshes that are topological disks
    //***************************************

    typedef CGAL::Parameterization_polyhedron_adaptor_3<Polyhedron>
                                            Parameterization_polyhedron_adaptor;
    Timer t;
    t.start();
    Parameterization_polyhedron_adaptor mesh_adaptor(mesh);

    //***************************************
    // Floater Mean Value Coordinates parameterization
    // (circular border) with Eigen solver
    //***************************************

    // Circular border parameterizer (the default)
    typedef CGAL::Circular_border_arc_length_parameterizer_3<Parameterization_polyhedron_adaptor>
                                                        Border_parameterizer;
    // Eigen solver
    typedef CGAL::Eigen_solver_traits<Eigen::BiCGSTAB<CGAL::Eigen_sparse_matrix<double>::EigenType, Eigen::IncompleteLUT< double > > >                Solver;

    // Floater Mean Value Coordinates parameterization
    // (circular border) with Eigen solver
    typedef CGAL::Mean_value_coordinates_parameterizer_3<Parameterization_polyhedron_adaptor,
                                                         Border_parameterizer,
      Solver>
                                                        Parameterizer;

    Parameterizer::Error_code err = CGAL::parameterize(mesh_adaptor, Parameterizer());
    t.stop();

    switch(err) {
    case Parameterizer::OK: // Success
        break;
    case Parameterizer::ERROR_EMPTY_MESH: // Input mesh not supported
    case Parameterizer::ERROR_NON_TRIANGULAR_MESH:   
    case Parameterizer::ERROR_NO_TOPOLOGICAL_DISC:     
    case Parameterizer::ERROR_BORDER_TOO_SHORT:    
        std::cerr << "Input mesh not supported: " << Parameterizer::get_error_message(err) << std::endl;
        return EXIT_FAILURE;
        break;
    default: // Error
        std::cerr << "Error: " << Parameterizer::get_error_message(err) << std::endl;
        return EXIT_FAILURE;
        break;
    };

    //***************************************
    // Output
    //***************************************

    // Raw output: dump (u,v) pairs
    Polyhedron::Vertex_const_iterator pVertex;
    for (pVertex = mesh.vertices_begin();
        pVertex != mesh.vertices_end();
        pVertex++)
    {
        // (u,v) pair is stored in any halfedge
        double u = mesh_adaptor.info(pVertex->halfedge())->uv().x();
        double v = mesh_adaptor.info(pVertex->halfedge())->uv().y();
        std::cout << "(u,v) = (" << u << "," << v << ")" << std::endl;
    }
    std::cerr << t.time() << "sec." << std::endl; 
    return EXIT_SUCCESS;
}
Пример #18
0
void MainWindow::parameterize(const Parameterization_method method)
{
  QApplication::setOverrideCursor(Qt::WaitCursor);

  // get active polyhedron
  int index = getSelectedSceneItemIndex();
  Polyhedron* pMesh = scene->polyhedron(index);
  if(pMesh == NULL)
  {
    QApplication::restoreOverrideCursor();
    return;
  }

  // parameterize
  QTime time;
  time.start();
  typedef CGAL::Parameterization_polyhedron_adaptor_3<Polyhedron> Adaptor;
  Adaptor adaptor(*pMesh);  

  bool success = false;
  switch(method)
  {
  case PARAM_MVC:
    {
      std::cout << "Parameterize (MVC)...";
      typedef CGAL::Mean_value_coordinates_parameterizer_3<Adaptor> Parameterizer;
      Parameterizer::Error_code err = CGAL::parameterize(adaptor,Parameterizer());
      success = err == Parameterizer::OK;
      break;
    }
  case PARAM_DCP:
    {
      std::cout << "Parameterize (DCP)...";
      typedef CGAL::Discrete_conformal_map_parameterizer_3<Adaptor> Parameterizer;
      Parameterizer::Error_code err = CGAL::parameterize(adaptor,Parameterizer());
      success = err == Parameterizer::OK;
    }
  }

  if(success)
    std::cout << "ok (" << time.elapsed() << " ms)" << std::endl;
  else
  {
    std::cout << "failure" << std::endl;
    QApplication::restoreOverrideCursor();
    return;
  }

  // add textured polyhedon to the scene
  Textured_polyhedron *pTex_polyhedron = new Textured_polyhedron();
  Textured_polyhedron_builder<Polyhedron,Textured_polyhedron,Kernel> builder;
  builder.run(*pMesh,*pTex_polyhedron);
  pTex_polyhedron->compute_normals();

  Polyhedron::Vertex_iterator it1;
  Textured_polyhedron::Vertex_iterator it2;
  for(it1 = pMesh->vertices_begin(), 
    it2 = pTex_polyhedron->vertices_begin();
    it1 != pMesh->vertices_end(),
    it2 != pTex_polyhedron->vertices_end();
  it1++, it2++)
  {
    // (u,v) pair is stored per halfedge
    FT u = adaptor.info(it1->halfedge())->uv().x();
    FT v = adaptor.info(it1->halfedge())->uv().y();
    it2->u() = u;
    it2->v() = v;
  }

  scene->addTexPolyhedron(pTex_polyhedron,
    tr("%1 (parameterized)").arg(scene->polyhedronName(index)),
    Qt::white,
    scene->isPolyhedronVisible(index),
    scene->polyhedronRenderingMode(index));

  QApplication::restoreOverrideCursor();
}
Пример #19
0
void ComputeGaussCurvature(Polyhedron &P)
{
  Polyhedron::Vertex_iterator vit;
  for(vit=P.vertices_begin(); vit!=P.vertices_end(); vit++)
    ComputeGaussCurvature(vit);
}
Пример #20
0
void ElPoly::DefineSkin(int NSample){
  std::list<Weighted_point> l;
  FT shrinkfactor = 0.5;
  double *Plot  = new double[pNType()*CUBE(NSample)];
  double *Count = new double[CUBE(NSample)];
  double Thre = 10.;
  double Radius = pEdge(0)/(double)NSample;
  for(int p=0;p<pNPart();p++){
    int t = pType(p);
    int vx = (int)(pPos(p,0)/pEdge(0)*NSample);
    int vy = (int)(pPos(p,1)/pEdge(1)*NSample);
    int vz = (int)(pPos(p,2)/pEdge(2)*NSample);
    int vTot = (vz*NSample+vy)*NSample+vx;
    Plot[vTot*pNType()+t] += 1.;
  }
  double *Norm = (double *)calloc(pNType(),sizeof(double));
  for(int t=0;t<pNType();t++){
    for(int v=0;v<CUBE(NSample);v++){
      if(Norm[t] < Plot[v*pNType()+t])
	Norm[t] = Plot[v*pNType()+t];
    }
    Norm[t] = Norm[t] <= 0. ? 1. : Norm[t];
  }
  for(int vx=0;vx<NSample;vx++){
    double x = vx*pEdge(0)/(double)NSample;
    for(int vy=0;vy<NSample;vy++){
      double y = vy*pEdge(1)/(double)NSample;
      for(int vz=0;vz<NSample;vz++){
	double z = vz*pEdge(2)/(double)NSample;
	int vTot = (vz*NSample+vy)*NSample+vx;
	if(Plot[vTot*pNType()] > Thre){
	  l.push_front(Weighted_point(Bare_point(x,y,z),Radius));
	}
      }
    }
  }

  Polyhedron Polyhe;

  Skin_surface_3 skin_surface(l.begin(), l.end(), shrinkfactor);
  CGAL::mesh_skin_surface_3(skin_surface, Polyhe);

  //  CGAL::subdivide_skin_surface_mesh_3(skin_surface, Polyhe);

  // std::ofstream out("mesh.off");
  // out << Polyhe;

  glDeleteLists(Dr->Particles,1);
  Dr->Particles = glGenLists(1);
  glNewList(Dr->Particles,GL_COMPILE);

  // Polyhedron::Facet_iterator fcUp = Polyhe.facets_begin();
  // for(;fcUp != Polyhe.facets_end(); ++fcUp){
  //   Polyhedron::Supports_facet_halfedge = fcUp.halfedge();
  //   //Halfedge_around_facet_circulator heUp = fcUp.halfedge();
  // }

  // for (Vertex_iterator vit = Polyhe.vertices_begin();vit != Polyhe.vertices_end(); vit++){
  //   // Vector n = policy.normal(vit);
  //   // n = n/sqrt(n*n);
  //   cout << vit->point() << std::endl;
  //   Halfedge_iterator heUp = Polyhe.halfedges_begin();
  //   for(;heUp != Polyhe.halfedges_end(); ++heUp){
  //     //Polyhedron::Halfedge_handle Half = *heUp;
  //     Vertex_handle veUp = heUp->vertex();
  //     K::Point_3 pf1 = vit->point();
  //   }
  // }
  CGAL::Inverse_index<Vertex_handle> index(Polyhe.vertices_begin(),
  					   Polyhe.vertices_end());

  for(Facet_iterator fi = Polyhe.facets_begin();fi != Polyhe.facets_end(); ++fi) {
    HFC hc = fi->facet_begin();
    HFC hc_end = hc;
    Polyhedron::Vertex_handle vf1 = (*hc).vertex();
    hc++;
    Polyhedron::Vertex_handle vf2 = (*hc).vertex();
    hc++;
    Polyhedron::Vertex_handle vf3 = (*hc).vertex();
    hc++;
    K::Point_3 pf1 = vf1->point();
    K::Point_3 pf2 = vf2->point();
    K::Point_3 pf3 = vf3->point();
    Vettore v1(pf1.x(),pf1.y(),pf1.z());
    Vettore v2(pf2.x(),pf2.y(),pf2.z());
    Vettore v3(pf3.x(),pf3.y(),pf3.z());
    Vettore vN(3);
    v1.Mult(InvScaleUn);
    v2.Mult(InvScaleUn);
    v3.Mult(InvScaleUn);
    vN = (v1-v2) ^ (v3-v2);
    //if(vN.Norm() > 2.*AreaMean) continue;
    double Sfumatura = .3*Mat->Casuale();
    glColor4f(0.1,.4+Sfumatura,0.2,1.);
    //glColor4f(HueUp[p].r,HueUp[p].g,HueUp[p].b,HueUp[p].a);
    DrTria(&v1,&v2,&v3,&vN);
    glColor4f(1.,.0,0.,1.);
    DrTriaContour(&v1,&v2,&v3);


    // glPushMatrix();//Particle
    // glBegin(GL_LINES);
    // do {
    //   Polyhedron::Vertex_handle vh = (*hc).vertex();
    //   K::Point_3 pf1 = vh->point();
    //   glVertex3d(pf1.x(),pf1.y(),pf1.z());
    // } while (++hc != hc_end);
    // glEnd();
    // glPopMatrix();//Particle
  }
  
  glEndList();
  
  // Tr tr;     // 3D-Delaunay triangulation
  // C2t3 c2t3 (tr);   // 2D-complex in 3D-Delaunay triangulation

  // Surface_3 surface(sphere_function,Sphere_3(CGAL::ORIGIN, 2.)); 
  // Surface_mesh_default_criteria_3<Tr> criteria(30., 0.1,0.1); 
  // // meshing surface
  // make_surface_mesh(c2t3, surface, criteria, CGAL::Non_manifold_tag());

  // std::cout << "Final number of points: " << tr.number_of_vertices() << "\n";

  // DT dt;
  // for(int c=0;c<Gen->NChain;c++){
  //   if(CHAIN_IF_TYPE(Ch[c].Type,CHAIN_UP) )continue;
  //   Point_3<K> ChPos(pPos(c,CLat1),pPos(c,CLat2),pPos(c,CNorm));
  //   dt.insert(ChPos);
  // }
  // Face_iterator fcTr = dt.finite_faces_begin();
  // glDeleteLists(Dr->Particles,1);
  // Dr->Particles = glGenLists(1);
  // glNewList(Dr->Particles,GL_COMPILE);
  // for(;fcTr != dt.faces_end(); ++fcTr){
  //   Vertex_handle vf1 = fcTr->vertex(0),
  //     vf2 = fcTr->vertex(1),vf3 = fcTr->vertex(2);
  //   Point pf1 = vf1->point();
  //   Point pf2 = vf2->point();
  //   Point pf3 = vf3->point();
  //   Vettore v1(pf1.x() - pf2.x(),pf1.y() - pf2.y(),pf1.z()-pf2.z());
  //   Vettore v2(pf3.x() - pf2.x(),pf3.y() - pf2.y(),pf1.z()-pf2.z());
  //   Vettore vN(3);
  //   vN = v1 ^ v2;
  //   DrTira(v1,v2,v3,vN);
    
  // }
  // glEndList();
   }
Пример #21
0
int main(int argc, char * argv[])
{
    std::cerr << "PARAMETERIZATION" << std::endl;
    std::cerr << "  Floater parameterization" << std::endl;
    std::cerr << "  Circle border" << std::endl;
    std::cerr << "  OpenNL solver" << std::endl;
    std::cerr << "  Very simple cut if model is not a topological disk" << std::endl;

    //***************************************
    // decode parameters
    //***************************************

    if (argc-1 != 1)
    {
        std::cerr << "Usage: " << argv[0] << " input_file.off" << std::endl;
        return(EXIT_FAILURE);
    }

    // File name is:
    const char* input_filename  = argv[1];

    //***************************************
    // Read the mesh
    //***************************************

    // Read the mesh
    std::ifstream stream(input_filename);
    Polyhedron mesh;
    stream >> mesh;
    if(!stream || !mesh.is_valid() || mesh.empty())
    {
        std::cerr << "Error: cannot read OFF file " << input_filename << std::endl;
        return EXIT_FAILURE;
    }

    //***************************************
    // Create Polyhedron adaptor
    //***************************************

    Parameterization_polyhedron_adaptor mesh_adaptor(mesh);

    //***************************************
    // Virtually cut mesh
    //***************************************

    // The parameterization methods support only meshes that
    // are topological disks => we need to compute a "cutting" of the mesh
    // that makes it homeomorphic to a disk
    Seam seam = cut_mesh(mesh_adaptor);
    if (seam.empty())
    {
        std::cerr << "Input mesh not supported: the example cutting algorithm is too simple to cut this shape" << std::endl;
        return EXIT_FAILURE;
    }

    // Create a second adaptor that virtually "cuts" the mesh following the 'seam' path
    typedef CGAL::Parameterization_mesh_patch_3<Parameterization_polyhedron_adaptor>
                                            Mesh_patch_polyhedron;
    Mesh_patch_polyhedron   mesh_patch(mesh_adaptor, seam.begin(), seam.end());
    if (!mesh_patch.is_valid())
    {
        std::cerr << "Input mesh not supported: non manifold shape or invalid cutting" << std::endl;
        return EXIT_FAILURE;
    }

    //***************************************
    // Floater Mean Value Coordinates parameterization
    //***************************************

    typedef CGAL::Parameterizer_traits_3<Mesh_patch_polyhedron>
                                            Parameterizer; // Type that defines the error codes

    Parameterizer::Error_code err = CGAL::parameterize(mesh_patch);
    switch(err) {
    case Parameterizer::OK: // Success
        break;
    case Parameterizer::ERROR_EMPTY_MESH: // Input mesh not supported
    case Parameterizer::ERROR_NON_TRIANGULAR_MESH:
    case Parameterizer::ERROR_NO_TOPOLOGICAL_DISC:
    case Parameterizer::ERROR_BORDER_TOO_SHORT:
        std::cerr << "Input mesh not supported: " << Parameterizer::get_error_message(err) << std::endl;
        return EXIT_FAILURE;
        break;
    default: // Error
        std::cerr << "Error: " << Parameterizer::get_error_message(err) << std::endl;
        return EXIT_FAILURE;
        break;
    };

    //***************************************
    // Output
    //***************************************

    // Raw output: dump (u,v) pairs
    Polyhedron::Vertex_const_iterator pVertex;
    for (pVertex = mesh.vertices_begin();
        pVertex != mesh.vertices_end();
        pVertex++)
    {
        // (u,v) pair is stored in any halfedge
        double u = mesh_adaptor.info(pVertex->halfedge())->uv().x();
        double v = mesh_adaptor.info(pVertex->halfedge())->uv().y();
        std::cout << "(u,v) = (" << u << "," << v << ")" << std::endl;
    }

    return EXIT_SUCCESS;
}
Пример #22
0
/*
 * mexFunction(): entry point for the mex function
 */
void mexFunction(int nlhs, mxArray *plhs[], 
		 int nrhs, const mxArray *prhs[]) {

  // interface to deal with input arguments from Matlab
  enum InputIndexType {IN_TRI, IN_X, IN_METHOD, IN_ITER, InputIndexType_MAX};
  MatlabImportFilter::Pointer matlabImport = MatlabImportFilter::New();
  matlabImport->ConnectToMatlabFunctionInput(nrhs, prhs);

  // check that we have all input arguments
  matlabImport->CheckNumberOfArguments(2, InputIndexType_MAX);

  // register the inputs for this function at the import filter
  MatlabInputPointer inTRI =        matlabImport->RegisterInput(IN_TRI, "TRI");
  MatlabInputPointer inX =          matlabImport->RegisterInput(IN_X, "X");
  MatlabInputPointer inMETHOD =     matlabImport->RegisterInput(IN_METHOD, "METHOD");
  MatlabInputPointer inITER =       matlabImport->RegisterInput(IN_ITER, "ITER");

  // interface to deal with outputs to Matlab
  enum OutputIndexType {OUT_TRI, OUT_N, OutputIndexType_MAX};
  MatlabExportFilter::Pointer matlabExport = MatlabExportFilter::New();
  matlabExport->ConnectToMatlabFunctionOutput(nlhs, plhs);

  // check number of outputs the user is asking for
  matlabExport->CheckNumberOfArguments(0, OutputIndexType_MAX);

  // register the outputs for this function at the export filter
  typedef MatlabExportFilter::MatlabOutputPointer MatlabOutputPointer;
  MatlabOutputPointer outTRI = matlabExport->RegisterOutput(OUT_TRI, "TRI");
  MatlabOutputPointer outN = matlabExport->RegisterOutput(OUT_N, "N");

  // if any of the inputs is empty, the output is empty too
  if (mxIsEmpty(prhs[IN_TRI]) || mxIsEmpty(prhs[IN_X])) {
    matlabExport->CopyEmptyArrayToMatlab(outTRI);
    matlabExport->CopyEmptyArrayToMatlab(outN);
    return;
  }

  // polyhedron to contain the input mesh
  Polyhedron mesh;
  PolyhedronBuilder<Polyhedron> builder(matlabImport, inTRI, inX);
  mesh.delegate(builder);

  // get size of input matrix with the points
  mwSize nrowsTri = mxGetM(inTRI->pm);
  mwSize nrowsX = mxGetM(inX->pm);

#ifdef DEBUG  
  std::cout << "Number of facets read = " << mesh.size_of_facets() << std::endl;
  std::cout << "Number of vertices read = " << mesh.size_of_vertices() << std::endl;
#endif

  if (nrowsTri != mesh.size_of_facets()) {
    mexErrMsgTxt(("Input " + inTRI->name + ": Number of triangles read into mesh different from triangles provided at the input").c_str());
  }
  if (nrowsX != mesh.size_of_vertices()) {
    mexErrMsgTxt(("Input " + inX->name + ": Number of vertices read into mesh different from vertices provided at the input").c_str());
  }

  // sort halfedges such that the non-border edges precede the
  // border edges. We need to do this before any halfedge iterator
  // operations are valid
  mesh.normalize_border();
  
#ifdef DEBUG
  std::cout << "Number of border halfedges = " << mesh.size_of_border_halfedges() << std::endl;
#endif
  
  // number of holes we have filled
  mwIndex n = 0;

  // a closed mesh with no holes will have no border edges. What we do
  // is grab a border halfedge and close the associated hole. This
  // makes the rest of the iterators invalid, so we have to normalize
  // the mesh again. Then we iterate, looking for a new border
  // halfedge, filling the hole, etc.
  //
  // Note that confusingly, mesh.border_halfedges_begin() gives a
  // pointer to the halfedge that is NOT a border in a border
  // edge. The border halfedge is instead
  // mesh.border_halfedges_begin()->opposite()
  while (!mesh.is_closed()) {
    
    // exit if user pressed Ctrl+C
    ctrlcCheckPoint(__FILE__, __LINE__);

    // get the first hole we can find, and close it
    mesh.fill_hole(mesh.border_halfedges_begin()->opposite());

    // increase the counter of number of holes we have filled
    n++;

    // renormalize mesh so that halfedge iterators are again valid
    mesh.normalize_border();

  }

  // split all facets to triangles
  CGAL::triangulate_polyhedron<Polyhedron>(mesh);

  // copy output with number of holes filled
  std::vector<double> nout(1, n);
  matlabExport->CopyVectorOfScalarsToMatlab<double, std::vector<double> >(outN, nout, 1);

  // allocate memory for Matlab outputs
  double *tri = matlabExport->AllocateMatrixInMatlab<double>(outTRI, mesh.size_of_facets(), 3);

   // extract the triangles of the solution
  // snippet adapted from CgalMeshSegmentation.cpp

  // vertices coordinates. Assign indices to the vertices by defining
  // a map between their handles and the index
  std::map<Vertex_handle, int> V;
  int inum = 0;
  for(Vertex_iterator vit = mesh.vertices_begin(); vit != mesh.vertices_end(); ++vit) {

    // save to internal list of vertices
    V[vit] = inum++;

  }  

  // triangles given as (i,j,k), where each index corresponds to a vertex in x
  mwIndex row = 0;
  for (Facet_iterator fit = mesh.facets_begin(); fit != mesh.facets_end(); ++fit, ++row) {

    if (fit->facet_degree() != 3) {
      std::cerr << "Facet has " << fit->facet_degree() << " edges" << std::endl;
      mexErrMsgTxt("Facet does not have 3 edges");
    }

    // go around the half-edges of the facet, to extract the vertices
    Halfedge_around_facet_circulator heit = fit->facet_begin();
    int idx = 0;
    do {
      
      // extract triangle indices and save to Matlab output
      // note that Matlab indices go like 1, 2, 3..., while C++ indices go like 0, 1, 2...
      tri[row + idx * mesh.size_of_facets()] = 1 + V[heit->vertex()];
      idx++;

    } while (++heit != fit->facet_begin());
    
  }
}
void Polyhedron_demo_jet_fitting_plugin::on_actionEstimateCurvature_triggered()
{
  // get active polyhedron
  const Scene_interface::Item_id index = scene->mainSelectionIndex();
  Scene_polyhedron_item* poly_item = 
    qobject_cast<Scene_polyhedron_item*>(scene->item(index));
  if(!poly_item)
    return;

  // wait cursor
  QApplication::setOverrideCursor(Qt::WaitCursor);

  Polyhedron* pMesh = poly_item->polyhedron();

  // types
  typedef CGAL::Monge_via_jet_fitting<Kernel> Fitting;
  typedef Fitting::Monge_form Monge_form;

  typedef Kernel::Point_3 Point;

  Scene_polylines_item* max_curv = new Scene_polylines_item;
  max_curv->setColor(Qt::red);
  max_curv->setName(tr("%1 (max curvatures)").arg(poly_item->name()));
  Scene_polylines_item* min_curv = new Scene_polylines_item;
  min_curv->setColor(Qt::green);
  min_curv->setName(tr("%1 (min curvatures)").arg(poly_item->name()));

  Polyhedron::Vertex_iterator v;
  for(v = pMesh->vertices_begin();
      v != pMesh->vertices_end();
      v++)
  {
    std::vector<Point> points;

    // pick central point
    const Point& central_point = v->point();
    points.push_back(central_point);

    // compute min edge len around central vertex
    // to scale the ribbons used to display the directions

    typedef Kernel::FT FT;

    FT min_edge_len = std::numeric_limits<FT>::infinity();
    Polyhedron::Halfedge_around_vertex_circulator he = v->vertex_begin();
    Polyhedron::Halfedge_around_vertex_circulator end = he;
    CGAL_For_all(he,end)
    {
      const Point& p = he->opposite()->vertex()->point();
      points.push_back(p);
      FT edge_len = std::sqrt(CGAL::squared_distance(central_point,p));
      min_edge_len = edge_len < min_edge_len ? edge_len : min_edge_len; // avoids #undef min
    }

    if(points.size() > 5)
    {
      // estimate curvature by fitting
      Fitting monge_fit;
      const int dim_monge = 2;
      const int dim_fitting = 2;
      Monge_form monge_form = monge_fit(points.begin(),points.end(),dim_fitting,dim_monge);

      // make monge form comply with vertex normal (to get correct
      // orientation)
      typedef Kernel::Vector_3 Vector;
      Vector n = CGAL::Polygon_mesh_processing::compute_vertex_normal(v, *pMesh);
      monge_form.comply_wrt_given_normal(n);

      Vector umin = min_edge_len * monge_form.minimal_principal_direction();
      Vector umax = min_edge_len * monge_form.maximal_principal_direction();

      Scene_polylines_item::Polyline max_segment(2), min_segment(2);

      const double du = 0.2;

      max_segment[0] = central_point + du * umax;
      max_segment[1] = central_point - du * umax;
      min_segment[0] = central_point + du * umin;
      min_segment[1] = central_point - du * umin;

      max_curv->polylines.push_back(max_segment);
      min_curv->polylines.push_back(min_segment);
    }
  }

  scene->addItem(max_curv);
  scene->addItem(min_curv);
  max_curv->changed();
  min_curv->changed();
  
  // default cursor
  QApplication::restoreOverrideCursor();
}
void PoissonSurfaceReconstruction::reconstruct(std::vector<Eigen::Vector3d> &points, std::vector<Eigen::Vector3d> &normals, TriangleMesh &mesh){

	assert(points.size() == normals.size());

  std::cout << "creating points with normal..." << std::endl;
  std::vector<Point_with_normal> points_with_normal;
  points_with_normal.resize((int)points.size());
  for(int i=0; i<(int)points.size(); i++){
    Vector vec(normals[i][0], normals[i][1], normals[i][2]);
    //Point_with_normal pwn(points[i][0], points[i][1], points[i][2], vec);
    //points_with_normal[i]  = pwn;
    points_with_normal[i] = Point_with_normal(points[i][0], points[i][1], points[i][2], vec);
  }

  std::cout << "constructing poisson reconstruction function..." << std::endl;
  Poisson_reconstruction_function function(points_with_normal.begin(), points_with_normal.end(),
                                           CGAL::make_normal_of_point_with_normal_pmap(PointList::value_type()));

  std::cout << "computing implicit function..." << std::endl;
  if( ! function.compute_implicit_function() ) {
  	std::cout << "compute implicit function is failure" << std::endl;
  	return;
  }
  	//return EXIT_FAILURE;

  // Computes average spacing
  std::cout << "compute average spacing..." << std::endl;
  FT average_spacing = CGAL::compute_average_spacing(points_with_normal.begin(), points_with_normal.end(),
                                                       6 /* knn = 1 ring */);
  // Gets one point inside the implicit surface
  // and computes implicit function bounding sphere radius.
  Point inner_point = function.get_inner_point();
  Sphere bsphere = function.bounding_sphere();
  FT radius = std::sqrt(bsphere.squared_radius());

  // Defines the implicit surface: requires defining a
  // conservative bounding sphere centered at inner point.
  FT sm_sphere_radius = 5.0 * radius;
  FT sm_dichotomy_error = distance_criteria*average_spacing/1000.0; // Dichotomy error must be << sm_distance
  //FT sm_dichotomy_error = distance_criteria*average_spacing/10.0; // Dichotomy error must be << sm_distance
  std::cout << "reconstructed surface" << std::endl;
  Surface_3 reconstructed_surface(function,
                    Sphere(inner_point,sm_sphere_radius*sm_sphere_radius),
                    sm_dichotomy_error/sm_sphere_radius);

  // Defines surface mesh generation criteria    
  CGAL::Surface_mesh_default_criteria_3<STr> criteria(angle_criteria,  // Min triangle angle (degrees)
                                                        radius_criteria*average_spacing,  // Max triangle size
                                                        distance_criteria*average_spacing); // Approximation error
  
  std::cout << "generating surface mesh..." << std::endl;
  // Generates surface mesh with manifold option
  STr tr; // 3D Delaunay triangulation for surface mesh generation
  C2t3 c2t3(tr); // 2D complex in 3D Delaunay triangulation
  CGAL::make_surface_mesh(c2t3,                                 // reconstructed mesh
                            reconstructed_surface,                              // implicit surface
                            criteria,                             // meshing criteria
                            CGAL::Manifold_tag());  // require manifold mesh

  if(tr.number_of_vertices() == 0){
  	std::cout << "surface mesh generation is failed" << std::endl;
  	return;
  }

  Polyhedron surface;
  CGAL::output_surface_facets_to_polyhedron(c2t3, surface);

  // convert CGAL::surface to TriangleMesh //
  std::cout << "converting CGA::surface to TriangleMesh..." << std::endl;
	std::vector<Eigen::Vector3d> pts;
	std::vector<std::vector<int> > faces;
	pts.resize(surface.size_of_vertices());
	faces.resize(surface.size_of_facets());

	Polyhedron::Point_iterator pit;
	int index = 0;
	for(pit=surface.points_begin(); pit!=surface.points_end(); ++pit){
		pts[index][0] = pit->x();
		pts[index][1] = pit->y();
		pts[index][2] = pit->z();				
		index ++;
	}
	index = 0;
	Polyhedron::Face_iterator fit;
	for(fit=surface.facets_begin(); fit!=surface.facets_end(); ++fit){
		std::vector<int > face(3);
		Halfedge_facet_circulator j = fit->facet_begin();
		int f_index = 0;
		do {
			face[f_index] = std::distance(surface.vertices_begin(), j->vertex());
			f_index++;
    } while ( ++j != fit->facet_begin());    

    faces[index] = face;
		index++;
	}

	mesh.createFromFaceVertex(pts, faces);  
}
Пример #25
0
int main() {

	
	//std::cout<<CGBench::BendBench::Run(CGBench::VMag::M1)<<std::endl;
	//CGBench::BenchLanuch(CGBench::VMag::M3,CGBench::VMag::M3);

	/*std::ofstream of("C:\\123.off");

	std::vector <Point_3> arr;
	arr.push_back(Point_3 (2,0,2));
	arr.push_back(Point_3 (6,0,3));
	arr.push_back(Point_3 (8,0,4));
	arr.push_back(Point_3 (3,0,5));
	arr.push_back(Point_3 (5,0,6));
	arr.push_back(Point_3 (8,0,7));

	arr.push_back(Point_3 (0,1.75,8));
	arr.push_back(Point_3 (0,1.50,8));
	arr.push_back(Point_3 (0,1.25,8));

	arr.push_back(Point_3 (0,1,8));
	arr.push_back(Point_3 (0,1,7));
	arr.push_back(Point_3 (0,1,6));
	arr.push_back(Point_3 (0,1,5));
	arr.push_back(Point_3 (0,1,4));
	arr.push_back(Point_3 (0,1,3));

	arr.push_back(Point_3 (0,1.25,3));
	arr.push_back(Point_3 (0,1.50,3));
	arr.push_back(Point_3 (0,1.75,3));

	
	Point_3* Center = new Point_3(0,0,0);*/

	//Arc_2 s(30,270,30,true);
	//Circle_2 s(4,20);
	//Ellipse_2 s(6,4,30);
	//Plane_3 s(30,30,10,10);
	//Rectangle_2 s(20,10);

	//Box_3 s(20,20,20,15,15,15);
	//Capsule_3 s(30,200,10,10);
	//ChamferCyl_3 s(60,100,30,10,5,5,15);
	//Cone_3 s(2,5,10,3,3,3);
	//Cylinder_3 s(3,20,20,9,30);
	//Lathe_3 s(arr,Center,Z_ax,20,360);
	//Pyramid_3 s(100,200,200,4,4,4);
	//Sphere_3 s(20,50);
	//Spindle_3 s(10,30,20,10,5,15);
	//Spring_3 s(20,2.5,200,10,10,40);
	//Torus_3 s(20,5,0,0,30,40);
	//Tube_3 s(14,13,15,20,20,10);

	//Polyhedron P;
	//P = s.Draw();
	//Traingulate trg;
	//P=s.Draw();
	//std::transform(P.facets_begin(), P.facets_end(), P.planes_begin(), Normal_vector());
	/*Eigen::Transform3d T;
	Eigen::Vector3d Original(0,0,10);
	T.setIdentity();
	T.pretranslate (-Original);
	trg.ApplyTransformToPolyhedron(P,T);*/


	//Traingulate tr;
	//tr.Do(P);

	//Bevel Be(400,-4,1.25);
	//Be.Do(P);

	//Bridge Br(18,20);
	//Br.Do(P);

	//Extrude Ex(45,15);
	//Ex.Do(P);
	
	//Outline Ou(45,1.5);
	//Ou.Do(P);


	//Bend Ben(90,s.Center,Y_ax,false,20,-20);
	//Ben.Do(P);

	//Bulge Bu(40,s.Center,Z_ax,BRadial,false,45,-45);
	//Bu.Do(P);

	//Cylindrical_Wave CylWa(2,8,12,s.Center,Z_ax);
	//CylWa.Do(P);

	//Linear_Wave LiWaX(1,10,0,s.Center,Z_ax,X_ax);
	//LiWaX.Do(P);
	//Linear_Wave LiWaY(2,10,0,s.Center,Z_ax,Y_ax);
	//LiWaY.Do(P);

	/*ChamferCyl_3 n(1,50,5,10,10,10,40);
	Spindle_3 p(5,30,5,10,20,40);
	Polyhedron P;
	Polyhedron E;
	E = p.Draw();
	P = n.Draw();
	Morph Mor(E,50);
	Mor.Do(P);*/

	//Noise No(5,0.3,0,s.Center,Z_ax);
	//No.Do(P);

	//Skew Sk(30,s.Center,Z_ax,false,20,-20);
	//Sk.Do(P);

	//Smooth Sm(1);
	//Sm.Do(P);

	//Spherify Sph(50);
	//Sph.Do(P);

	//Squeeze Sq(-30,s.Center,Z_ax,false,10,0);
	//Sq.Do(P);

	//Stretch St(-20,s.Center,Z_ax,true,50,-50);
	//St.Do(P);
	
	//Taper Ta(3,s.Center,X_ax,false,20,-20);
	//Ta.Do(P);

	//Twist Tw(270,s.Center,Z_ax,true,-5,15);
	//Tw.Do(P);

	/*Box_3 B(20, 30, 60, 20, 30, 30); 
	Polyhedron P = B.Draw();
	Twist Tw1(270, B.Center, Z_ax, true, 30, 10);
	Twist Tw2(-270, B.Center, Z_ax, true, -10, -30);
	Stretch St(30, B.Center, Z_ax, true, 20,-20);
	Squeeze Sq(15, B.Center, Z_ax);
	Tw1.Do(P);
	Tw2.Do(P);
	Sq.Do(P);
	St.Do(P);*/

	std::ofstream of("C:\\123.off");

	Box_3 B(20, 30, 60, 20, 30, 30); 
Polyhedron P = B.Draw();
Twist Tw1(270, B.Center, Z_ax, true, 30, 10);
Twist Tw2(-270, B.Center, Z_ax, true, -10, -30);
Stretch St(30, B.Center, Z_ax, true, 20,-20);
Squeeze Sq(15, B.Center, Z_ax);
Tw1.Do(P);
Tw2.Do(P);
Sq.Do(P);
St.Do(P);



	//// Write polyhedron in Object File Format (OFF).
	CGAL::set_ascii_mode( of );
	of << "OFF" << std::endl << P.size_of_vertices() << ' ' << P.size_of_facets() << " 0" << std::endl;
	std::copy( P.points_begin(), P.points_end(), std::ostream_iterator<Point_3>( of, "\n"));

	for (  Facet_iterator i = P.facets_begin(); i != P.facets_end(); ++i) 
	{
		Halfedge_facet_circulator j = i->facet_begin();
		// Facets in polyhedral surfaces are at least triangles.
		CGAL_assertion( CGAL::circulator_size(j) >= 3);
		of << CGAL::circulator_size(j) << ' ';
		
		do 
		{
			of << ' ' << std::distance(P.vertices_begin(), j->vertex());
		} while ( ++j != i->facet_begin());
		
		of << std::endl;
	}

	/* Write polyhedron in (OBJ).
	CGAL::set_ascii_mode( oof );
	oof << "# " << P.size_of_vertices() << ' ' << std::endl <<"# "<< P.size_of_facets() << std::endl;
	oof<<"v ";
	std::copy( P.points_begin(), P.points_end(), std::ostream_iterator<Point_3>( oof, "\nv "));
	oof<<"_ _ _\n";
	for (  Facet_iterator i = P.facets_begin(); i != P.facets_end(); ++i)
	{
		Halfedge_facet_circulator j = i->facet_begin();
		// Facets in polyhedral surfaces are at least triangles.
		//CGAL_assertion( CGAL::circulator_size(j) >= 3);
       
		oof << 'f' << ' ';
       
		do
		{
			oof << ' ' << std::distance(P.vertices_begin(), j->vertex())+1;
		} while ( ++j != i->facet_begin());
       
		oof << std::endl;
	}
	*/

	return 0;
}
// a helper method for running different iterators
void running_iterators( Polyhedron& P) {
    if ( P.size_of_facets() == 0)
        return;

    std::size_t nv = P.size_of_vertices();

    std::cout << "The number of vertices in the Polyhedron: " << nv << std::endl;
    std::cout << "The number of facets in the Polyhedron: " << P.size_of_facets() << std::endl;
    std::cout << "The number of half edges in the Polyhedron: " << P.size_of_halfedges() << std::endl;

    std::cout << std:: endl;

    Polyhedron::Vertex_iterator last_v = P.vertices_end();
    -- last_v;  // the last of the old vertices

    Polyhedron::Edge_iterator last_e = P.edges_end();
    -- last_e;  // the last of the old edges

    Polyhedron::Facet_iterator last_f = P.facets_end();
    -- last_f;  // the last of the old facets

    int k = 0;
    Polyhedron::Facet_iterator f = P.facets_begin();

    do {
    	std::cout << "Printing a facet index: " << k++ <<  std::endl;

    	f->halfedge();

    } while ( f++ != last_f);

    std::cout  << std::endl;

    // -------------------------------------------------
    // traverse the vertices
    // -------------------------------------------------

    std::cout << "Printing the vertex indices: " << std::endl;

     int n=0;
     for (Polyhedron::Vertex_iterator vi = P.vertices_begin(); vi != P.vertices_end(); ++vi)
     {
    	 Kernel::Point_3 p;
    	 p = vi->point();
    	 std::cout << "Vertex index: "  << n++ << std::endl;
    	 std::cout << "p.x() = "  << p.x() << std::endl;
    	 std::cout << "p.y() = "  << p.y() << std::endl;
    	 std::cout << "p.z() = "  << p.z() << std::endl;

     }

     std::cout  << std::endl;

     // -------------------------------------------------
     // traverse the edges
     // -------------------------------------------------

     std::cout << "Iterating over the edges.... " << std::endl;

     n=0;
     for (Polyhedron::Edge_iterator ei = P.edges_begin(); ei != P.edges_end(); ++ei)
     {
    	 ei->next();
    	 Kernel::Point_3 p;
    	 p =  ei->vertex()->point();
    	 std::cout << "For edge index: " << n++ << std::endl;
    	 std::cout << "p.x() = "  << p.x() << std::endl;
		 std::cout << "p.y() = "  << p.y() << std::endl;
		 std::cout << "p.z() = "  << p.z() << std::endl;

     }
     std::cout  << std::endl;

	 // -----------------------------------------------
	 // Do something else with the edge iterators
	 // -----------------------------------------------

    Polyhedron::Edge_iterator e = P.edges_begin();
    ++ last_e; // make it the past-the-end position again

    while ( e != last_e) {
    	Polyhedron::Halfedge_handle h = e;
        ++e;
    };

    CGAL_postcondition( P.is_valid());
}