Beispiel #1
0
void index_uniqueness_poly(const Polyhedron& g)
{
  std::cerr << "testing Polyhedron\n";
  index_uniqueness(g, edges(g) ,    get(boost::edge_index, g));
  index_uniqueness(g, vertices(g),  get(boost::vertex_index, g));
  index_uniqueness(g, faces(g),     get(boost::face_index, g));
  index_uniqueness(g, halfedges(g), get(boost::halfedge_index, g));

  index_uniqueness(g, edges(g) ,    get(boost::edge_external_index, g));
  index_uniqueness(g, vertices(g),  get(boost::vertex_external_index, g));
  index_uniqueness(g, faces(g),     get(boost::face_external_index, g));
  index_uniqueness(g, halfedges(g), get(boost::halfedge_external_index, g));
}
void 
remove_face_test_1()
{
  CGAL_GRAPH_TRAITS_MEMBERS(T);
  Surface_fixture_1<T> f;

  // find the edge between x and y
  bool found;
  halfedge_descriptor e;
  boost::tie(e, found) = halfedge(f.x, f.y, f.m);
  assert(found);
  assert(face(e, f.m) == f.f3);

  CGAL::Euler::remove_face(e,f.m);

  assert(CGAL::is_valid(f.m));

  assert_EQUAL(degree(f.v, f.m) == 3);
  assert_EQUAL(degree(f.x, f.m) == 2);
  assert_EQUAL(CGAL::internal::exact_num_faces(f.m) == 2);
  assert_EQUAL(CGAL::internal::exact_num_edges(f.m) == 5);
  assert_EQUAL(CGAL::internal::exact_num_vertices(f.m) == 4);
  halfedge_iterator eb, ee;
  int count = 0;
  for(boost::tie(eb, ee) = halfedges(f.m); eb != ee; ++eb) {
    if(face(*eb,f.m) == boost::graph_traits<T>::null_face())
      ++count;
  }
  assert(count == 4);
}
Beispiel #3
0
void index_uniqueness_omesh(const OMesh& g)
{
  std::cerr << "testing OpenMesh\n";
  index_uniqueness(g, edges(g) ,    get(boost::edge_index, g));
  index_uniqueness(g, vertices(g),  get(boost::vertex_index, g));
  index_uniqueness(g, faces(g),     get(boost::face_index, g));
  index_uniqueness(g, halfedges(g), get(boost::halfedge_index, g));
}
Beispiel #4
0
void index_uniqueness_sm(const SM& g)
{
  std::cerr << "testing Surface_mesh\n";
  index_uniqueness(g, edges(g) ,    get(boost::edge_index, g));
  index_uniqueness(g, vertices(g),  get(boost::vertex_index, g));
  index_uniqueness(g, faces(g),     get(boost::face_index, g));
  index_uniqueness(g, halfedges(g), get(boost::halfedge_index, g));
}
Beispiel #5
0
 void 
 gnu()
 {
   SM sm;
   CGAL::make_triangle(Point_3(0,0,0), Point_3(1,0,0), Point_3(1,1,0),sm);
   
   halfedge_descriptor hd = *(halfedges(sm).first);
   hd = next(hd,sm);
   std::cout << hd;
 }
int main(int argc, char* argv[])
{
  const char* filename = (argc > 1) ? argv[1] : "data/mech-holes-shark.off";
  LCC mesh;
  CGAL::read_off(filename, mesh);

  // Incrementally fill the holes
  unsigned int nb_holes = 0;
  for ( halfedge_iterator it=halfedges(mesh).begin();
        it!=halfedges(mesh).end(); ++it)
  {
    halfedge_descriptor h=*it;
    if(is_border(h,mesh))
    {
      std::vector<face_descriptor>  patch_facets;
      std::vector<vertex_descriptor> patch_vertices;
      bool success = CGAL::cpp11::get<0>(
        CGAL::Polygon_mesh_processing::triangulate_refine_and_fair_hole(
                  mesh,
                  h,
                  std::back_inserter(patch_facets),
                  std::back_inserter(patch_vertices),
     CGAL::Polygon_mesh_processing::parameters::vertex_point_map(get(CGAL::vertex_point, mesh)).
                  geom_traits(Kernel())) );

      std::cout << "* Number of facets in constructed patch: " << patch_facets.size() << std::endl;
      std::cout << "  Number of vertices in constructed patch: " << patch_vertices.size() << std::endl;
      std::cout << "  Is fairing successful: " << success << std::endl;
      nb_holes++;
    }
  }

  std::cout << std::endl;
  std::cout << nb_holes << " holes have been filled" << std::endl;
  
  std::ofstream out("filled_LCC.off");
  out.precision(17);
  CGAL::write_off(out, mesh);

  return 0;
}
Beispiel #7
0
void test_edge_hash_and_null(const P& p)
{
  typedef boost::graph_traits<P> GT;
  typedef typename GT::halfedge_descriptor halfedge_descriptor;
  typedef typename GT::vertex_descriptor vertex_descriptor;
  typedef typename GT::face_descriptor face_descriptor;

  BOOST_FOREACH(halfedge_descriptor h, halfedges(p))
  {
    assert(
      hash_value( edge(h,p) ) ==
      hash_value( edge(opposite(h,p),p) ) );
  }
Beispiel #8
0
int
main(int argc, char *argv[])
{
	FILE *fp;
	char comment[80];
	float *verts;
	vertex_t *tris;
	halfedge_t *enext;
	vertex_t *evert;
	halfedge_t *vnext;
	uint16_t *attrs;
	triangle_t ntris;
	halfedge_t nedges;
	vertex_t nverts;
	int i, nrounds, opt;

	nrounds = 5;
	while((opt = getopt(argc, argv, "n:")) != -1){
		switch(opt){
		case 'n':
			nrounds = strtol(optarg, NULL, 10);
			break;
		default:
		caseusage:
			fprintf(stderr, "usage: %s [-n nrounds] path/to/file.stl\n", argv[0]);
			exit(1);
		}
	}
	if(optind == argc)
		goto caseusage;

	for(i = 0; i < nrounds; i++){
		if(argc > 1){
			fp = fopen(argv[optind], "rb");
		} else {
			fp = stdin;
		}
		loadstl(fp, comment, &verts, &nverts, &tris, &attrs, &ntris);
		halfedges(tris, ntris, &enext, &evert, &nedges);
		dualedges(enext, nedges, &vnext);
		fclose(fp);
		free(tris);
		free(verts);
		free(attrs);
		free(enext);
		free(evert);
		free(vnext);
	}

	return 0;
}
Beispiel #9
0
void
test(const char *fname, bool triangle, bool quad, bool tetrahedron, bool hexahedron)
{
  typedef typename boost::graph_traits<Mesh>::halfedge_descriptor halfedge_descriptor;
  std::cerr << "test(" << fname << ")"<< std::endl;
  Mesh m;
  std::ifstream in(fname);
  in >> m;
  halfedge_descriptor hd = *halfedges(m).first;
  assert(CGAL::is_isolated_triangle(hd, m) == triangle);
  assert(CGAL::is_isolated_quad(hd, m) == quad);
  assert(CGAL::is_tetrahedron(hd, m) == tetrahedron);
  assert(CGAL::is_hexahedron(hd, m) == hexahedron);
  }
int main( int argc, char** argv ) 
{
  Surface_mesh surface_mesh; 
  
  std::ifstream is(argv[1]);
  is >> surface_mesh;
  if (!CGAL::is_triangle_mesh(surface_mesh)){
    std::cerr << "Input geometry is not triangulated." << std::endl;
    return EXIT_FAILURE;
  }

  // The items in this polyhedron have an "id()" field 
  // which the default index maps used in the algorithm
  // need to get the index of a vertex/edge.
  // However, the Polyhedron_3 class doesn't assign any value to
  // this id(), so we must do it here:
  int index = 0;
  
  BOOST_FOREACH(halfedge_descriptor hd , halfedges(surface_mesh)){
    hd->id() = index++;
}
  index = 0;
  
  BOOST_FOREACH(vertex_descriptor vd , vertices(surface_mesh)){
    vd->id() = index++;
}
    
  // In this example, the simplification stops when the number of undirected edges
  // drops below 10% of the initial count
  SMS::Count_ratio_stop_predicate<Surface_mesh> stop(0.1);
 
    
  // The index maps are not explicitelty passed as in the previous
  // example because the surface mesh items have a proper id() field.
  // On the other hand, we pass here explicit cost and placement
  // function which differ from the default policies, ommited in
  // the previous example.
  int r = SMS::edge_collapse(surface_mesh, stop);
  
  std::cout << "\nFinished...\n" << r << " edges removed.\n" 
            << (surface_mesh.size_of_halfedges()/2) << " final edges.\n";
        
  std::ofstream os( argc > 2 ? argv[2] : "out.off" );
  os.precision(17);
  os << surface_mesh;
  
  return EXIT_SUCCESS;      
}
Beispiel #11
0
int
main(int,char*[])
{
  Triangulation t;

  t.insert(Point(0.1,0,1));
  t.insert(Point(1,0,1));
  t.insert(Point(0.2,0.2, 2));
  t.insert(Point(0,1,2));
  t.insert(Point(0,2,3));

  vertex_iterator vit, ve;
  // Associate indices to the vertices
  int index = 0;
  // boost::tie assigns the first and second element of the std::pair
  // returned by boost::vertices to the variables vit and ve
  for(boost::tie(vit,ve) = vertices(t); vit!=ve; ++vit ){
    vertex_descriptor  vd = *vit;
    if(! t.is_infinite(vd)){
      vertex_id_map[vd]= index++;
    }
  }

  std::cerr << index << " vertices" << std::endl;
  index = 0;
  face_iterator fit,fe;
  for(boost::tie(fit,fe) = faces(t); fit!= fe; ++fit){
    face_descriptor fd = *fit;
    halfedge_descriptor hd = halfedge(fd,t);
    halfedge_descriptor n = next(hd,t);
    
    halfedge_descriptor nn = next(n,t);
    if(next(nn,t) != hd){
      std::cerr << "the face is not a triangle" << std::endl;
    }
    
    ++index;
  }
  
  std::cerr << index << " faces" << std::endl;
  index = 0;

  edge_iterator eit,ee;
  for(boost::tie(eit,ee) = edges(t); eit!= ee; ++eit){
    edge_descriptor ed = *eit;
    vertex_descriptor vd = source(ed,t);
    CGAL_USE(vd);
    ++index;
  }

  std::cerr << index << " edges" << std::endl;
  index = 0;

  halfedge_iterator hit,he;
  for(boost::tie(hit,he) = halfedges(t); hit!= he; ++hit){
    halfedge_descriptor hd = *hit;
    vertex_descriptor vd = source(hd,t);
    CGAL_USE(vd);
    ++index;
  }
  std::cerr << index << " halfedges" << std::endl;

  std::cerr << num_vertices(t) << " " << num_edges(t) << " " << num_halfedges(t) << " " << num_faces(t) << std::endl;

  typedef boost::property_map<Triangulation, boost::vertex_point_t>::type Ppmap;
  Ppmap ppmap = get(boost::vertex_point, t);
 

  for(vertex_descriptor vd : vertices_around_target(*vertices(t).first, t)){
    std::cout <<  ppmap[vd] << std::endl;
  }


  ppmap[*(++vertices(t).first)] = Point(78,1,2);
  std::cout << " changed point of vertex " << ppmap[*(++vertices(t).first)] << std::endl;

  return 0;
}
int main( int argc, char** argv )
{
  Surface_mesh surface_mesh;

  if (argc!=2){
    std::cerr << "Usage: " << argv[0] << " input.off\n";
    return EXIT_FAILURE;
  }

  std::ifstream is(argv[1]);
  if(!is){
    std::cerr << "Filename provided is invalid\n";
    return EXIT_FAILURE;
  }

  is >> surface_mesh ;
  if (!CGAL::is_triangle_mesh(surface_mesh)){
    std::cerr << "Input geometry is not triangulated." << std::endl;
    return EXIT_FAILURE;
  }

  Surface_mesh::Property_map<halfedge_descriptor,std::pair<Point_3, Point_3> > constrained_halfedges;

  constrained_halfedges = surface_mesh.add_property_map<halfedge_descriptor,std::pair<Point_3, Point_3> >("h:vertices").first;

  std::size_t nb_border_edges=0;
  BOOST_FOREACH(halfedge_descriptor hd, halfedges(surface_mesh)){
    if(CGAL::is_border(hd,surface_mesh)){
      constrained_halfedges[hd] = std::make_pair(surface_mesh.point(source(hd,surface_mesh)),
                                                 surface_mesh.point(target(hd,surface_mesh)));
      ++nb_border_edges;
    }
  }

  // Contract the surface mesh as much as possible
  SMS::Count_stop_predicate<Surface_mesh> stop(0);

  Border_is_constrained_edge_map bem(surface_mesh);
  
  // This the actual call to the simplification algorithm.
  // The surface mesh and stop conditions are mandatory arguments.
  int r = SMS::edge_collapse
            (surface_mesh
            ,stop
             ,CGAL::parameters::edge_is_constrained_map(bem)
                               .get_placement(Placement(bem))
            );

  std::cout << "\nFinished...\n" << r << " edges removed.\n"
            << surface_mesh.number_of_edges() << " final edges.\n";

  std::ofstream os( argc > 2 ? argv[2] : "out.off" );
  os.precision(17);
  os << surface_mesh;

  // now check!
  BOOST_FOREACH(halfedge_descriptor hd, halfedges(surface_mesh)){
    if(CGAL::is_border(hd,surface_mesh)){
      --nb_border_edges;
      if(constrained_halfedges[hd] != std::make_pair(surface_mesh.point(source(hd,surface_mesh)),
                                                     surface_mesh.point(target(hd,surface_mesh)))){
        std::cerr << "oops. send us a bug report\n";
      }

    }
  }
  assert( nb_border_edges==0 );

  return EXIT_SUCCESS;
}
Beispiel #13
0
Surface_mesh::Face
Surface_mesh::
add_face(const std::vector<Vertex>& vertices)
{
    Vertex                   v;
    unsigned int             i, ii, n((int)vertices.size()), id;
    std::vector<Halfedge>    halfedges(n);
    std::vector<bool>        is_new(n), needs_adjust(n, false);
    Halfedge                 inner_next, inner_prev,
    outer_next, outer_prev,
    boundary_next, boundary_prev,
    patch_start, patch_end;

    // cache for set_next_halfedge and vertex' set_halfedge
    typedef std::pair<Halfedge, Halfedge>  NextCacheEntry;
    typedef std::vector<NextCacheEntry>    NextCache;

    NextCache    next_cache;
    next_cache.reserve(3*n);


    // don't allow degenerated faces
    assert (n > 2);


    // test for topological errors
    for (i=0, ii=1; i<n; ++i, ++ii, ii%=n)
    {
        if ( !is_boundary(vertices[i]) )
        {
            std::cerr << "Surface_meshT::add_face: complex vertex\n";
            return Face();
        }

        halfedges[i] = find_halfedge(vertices[i], vertices[ii]);
        is_new[i]    = !halfedges[i].is_valid();

        if (!is_new[i] && !is_boundary(halfedges[i]))
        {
            std::cerr << "Surface_meshT::add_face: complex edge\n";
            return Face();
        }
    }


    // re-link patches if necessary
    for (i=0, ii=1; i<n; ++i, ++ii, ii%=n)
    {
        if (!is_new[i] && !is_new[ii])
        {
            inner_prev = halfedges[i];
            inner_next = halfedges[ii];

            if (next_halfedge(inner_prev) != inner_next)
            {
                // here comes the ugly part... we have to relink a whole patch

                // search a free gap
                // free gap will be between boundary_prev and boundary_next
                outer_prev = opposite_halfedge(inner_next);
                outer_next = opposite_halfedge(inner_prev);
                boundary_prev = outer_prev;
                do
                    boundary_prev = opposite_halfedge(next_halfedge(boundary_prev));
                while (!is_boundary(boundary_prev) || boundary_prev==inner_prev);
                boundary_next = next_halfedge(boundary_prev);
                assert(is_boundary(boundary_prev));
                assert(is_boundary(boundary_next));


                // ok ?
                if (boundary_next == inner_next)
                {
                    std::cerr << "Surface_meshT::add_face: patch re-linking failed\n";
                    return Face();
                }

                // other halfedges' handles
                patch_start = next_halfedge(inner_prev);
                patch_end   = prev_halfedge(inner_next);

                // relink
                next_cache.push_back(NextCacheEntry(boundary_prev, patch_start));
                next_cache.push_back(NextCacheEntry(patch_end, boundary_next));
                next_cache.push_back(NextCacheEntry(inner_prev, inner_next));
            }
        }
    }



    // create missing edges
    for (i=0, ii=1; i<n; ++i, ++ii, ii%=n)
        if (is_new[i])
            halfedges[i] = new_edge(vertices[i], vertices[ii]);



    // create the face
    Face f(new_face());
    set_halfedge(f, halfedges[n-1]);



    // setup halfedges
    for (i=0, ii=1; i<n; ++i, ++ii, ii%=n)
    {
        v          = vertices[ii];
        inner_prev = halfedges[i];
        inner_next = halfedges[ii];

        id = 0;
        if (is_new[i])  id |= 1;
        if (is_new[ii]) id |= 2;

        if (id)
        {
            outer_prev = opposite_halfedge(inner_next);
            outer_next = opposite_halfedge(inner_prev);

            // set outer links
            switch (id)
            {
                case 1: // prev is new, next is old
                    boundary_prev = prev_halfedge(inner_next);
                    next_cache.push_back(NextCacheEntry(boundary_prev, outer_next));
                    set_halfedge(v, outer_next);
                    break;

                case 2: // next is new, prev is old
                    boundary_next = next_halfedge(inner_prev);
                    next_cache.push_back(NextCacheEntry(outer_prev, boundary_next));
                    set_halfedge(v, boundary_next);
                    break;

                case 3: // both are new
                    if (!halfedge(v).is_valid())
                    {
                        set_halfedge(v, outer_next);
                        next_cache.push_back(NextCacheEntry(outer_prev, outer_next));
                    }
                    else
                    {
                        boundary_next = halfedge(v);
                        boundary_prev = prev_halfedge(boundary_next);
                        next_cache.push_back(NextCacheEntry(boundary_prev, outer_next));
                        next_cache.push_back(NextCacheEntry(outer_prev, boundary_next));
                    }
                    break;
            }

            // set inner link
            next_cache.push_back(NextCacheEntry(inner_prev, inner_next));
        }
        else needs_adjust[ii] = (halfedge(v) == inner_next);


        // set face handle
        set_face(halfedges[i], f);
    }



    // process next halfedge cache
    NextCache::const_iterator ncIt(next_cache.begin()), ncEnd(next_cache.end());
    for (; ncIt != ncEnd; ++ncIt)
        set_next_halfedge(ncIt->first, ncIt->second);



    // adjust vertices' halfedge handle
    for (i=0; i<n; ++i)
        if (needs_adjust[i])
            adjust_outgoing_halfedge(vertices[i]);


    return f;
}
Beispiel #14
0
void
Surface_mesh::
remove_edge(Halfedge h)
{
    Halfedge  hn = next_halfedge(h);
    Halfedge  hp = prev_halfedge(h);

    Halfedge  o  = opposite_halfedge(h);
    Halfedge  on = next_halfedge(o);
    Halfedge  op = prev_halfedge(o);

    Face      fh = face(h);
    Face      fo = face(o);

    Vertex    vh = to_vertex(h);
    Vertex    vo = to_vertex(o);



    // halfedge -> vertex
    Halfedge_around_vertex_circulator vh_it, vh_end;
    vh_it = vh_end = halfedges(vo);
    do
    {
        set_vertex(opposite_halfedge(vh_it), vh);
    }
    while (++vh_it != vh_end);


    // halfedge -> halfedge
    set_next_halfedge(hp, hn);
    set_next_halfedge(op, on);


    // face -> halfedge
    if (fh.is_valid())  set_halfedge(fh, hn);
    if (fo.is_valid())  set_halfedge(fo, on);


    // vertex -> halfedge
    if (halfedge(vh) == o)  set_halfedge(vh, hn);
    adjust_outgoing_halfedge(vh);
    set_halfedge(vo, Halfedge());


    // delete stuff
    if (!vdeleted_) vdeleted_ = vertex_property<bool>("v:deleted", false);
    if (!edeleted_) edeleted_ = edge_property<bool>("e:deleted", false);
    vdeleted_[vo]      = true; ++deleted_vertices_;
    edeleted_[edge(h)] = true; ++deleted_edges_;
    garbage_ = true;

    //add
    for(unsigned int j = 0;j < map_2skel.size();j++)
    {
        if(map_2skel[j] == vo.idx())
        {
            //unsigned int tem = map_2skel[j];
            map_2skel[j] = vh.idx();
            //qDebug("vertex:[%d],change %d to %d",j,tem,vh.idx());
        }
    }
    //end
}