Skip to Content.
Sympa Menu

cgal-discuss - Re: [cgal-discuss] Mesh simplification and generation with constraints

Subject: CGAL users discussion list

List archive

Re: [cgal-discuss] Mesh simplification and generation with constraints


Chronological Thread 
  • From: Fernando Cacciola <>
  • To:
  • Subject: Re: [cgal-discuss] Mesh simplification and generation with constraints
  • Date: Wed, 29 Apr 2009 14:39:23 -0300

Hello Amir,

Hello,


Is there a (simple) way to use CGAL mesh simplification and mesh generation with constraints? For both, the constraints mean that certain vertices and edge must exist in the mesh (not be simplified\be part of the generated mesh).

Attached there is a file "edge_collapse_constrained_polyhedron.cpp"

It contains a complete example showing how to mark edges as non-removable.

The trick is to supply a custom "edge_is_border" map which returns true for edges which, even if they are not borders, should not be simplified.

That example will be added into the documentation.

Best

Fernando Cacciola
www.geometryfactory.com
#include <iostream>
#include <fstream>

#include <CGAL/Simple_cartesian.h>
#include <CGAL/Polyhedron_3.h>
#include <CGAL/IO/Polyhedron_iostream.h>

// Adaptor for Polyhedron_3
#include <CGAL/Surface_mesh_simplification/HalfedgeGraph_Polyhedron_3.h>

// Simplification function
#include <CGAL/Surface_mesh_simplification/edge_collapse.h>

// Stop-condition policy
#include <CGAL/Surface_mesh_simplification/Policies/Edge_collapse/Count_stop_predicate.h>

#include <CGAL/Unique_hash_map.h>

typedef CGAL::Simple_cartesian<double> Kernel;
typedef CGAL::Polyhedron_3<Kernel> Surface; 

namespace SMS = CGAL::Surface_mesh_simplification ;

template<class PolyhedronT>
class Polyhedron_edge_is_constrained_or_border_map : public boost::put_get_helper<bool, Polyhedron_edge_is_constrained_or_border_map<PolyhedronT> >
{
private:

  typedef PolyhedronT Polyhedron ;
  
public:

  typedef boost::readable_property_map_tag                                category;
  typedef bool                                                            value_type;
  typedef bool                                                            reference;
  typedef typename boost::graph_traits<Polyhedron const>::edge_descriptor key_type;

  Polyhedron_edge_is_constrained_or_border_map( Polyhedron const& ) : mConstrains(false) {}

  reference operator[](key_type const& e) const { return e->is_border() || is_constrained(e) ; }
  
  void set_is_constrained ( key_type const& e, bool is )  { mConstrains[e]=is; }
  
  bool is_constrained( key_type const& e ) const { return mConstrains.is_defined(e) ? mConstrains[e] : false ; }      
  
private:
  
  typedef CGAL::Unique_hash_map<key_type,bool> Constrains_map ;
  
  Constrains_map mConstrains ;
  
};

int main( int argc, char** argv ) 
{
  Surface surface; 
  
  std::ifstream is(argv[1]) ; is >> surface ;

  // This is a stop predicate (defines when the algorithm terminates).
  // In this example, the simplification stops when the number of undirected edges
  // left in the surface drops below the specified number (1000)
  SMS::Count_stop_predicate<Surface> stop(10);
     
  typedef Polyhedron_edge_is_constrained_or_border_map<Surface> Constrains_map ;
     
  Constrains_map constrains_map(surface) ;
     
  for( Surface::Halfedge_iterator eb = surface.halfedges_begin()
     , ee = surface.halfedges_end()
     ; eb != ee
     ; ++ eb
     ) 
    constrains_map.set_is_constrained(eb,true);
     
  // This the actual call to the simplification algorithm.
  // The surface and stop conditions are mandatory arguments.
  // The index maps are needed because the vertices and edges
  // of this surface lack an "id()" field.
  int r = SMS::edge_collapse
            (surface
            ,stop
            ,CGAL::vertex_index_map(boost::get(CGAL::vertex_external_index,surface)) 
                  .edge_index_map  (boost::get(CGAL::edge_external_index  ,surface)) 
                  .edge_is_border_map(constrains_map)
            );
  
  std::cout << "\nFinished...\n" << r << " edges removed.\n" 
            << (surface.size_of_halfedges()/2) << " final edges.\n" ;
        
  std::ofstream os( argc > 2 ? argv[2] : "out.off" ) ; os << surface ;
  
  return 0 ;      
}

// EOF //



Archive powered by MHonArc 2.6.16.

Top of Page