Skip to Content.
Sympa Menu

cgal-discuss - Re: [cgal-discuss] "Parts" of Polyhedron after a boolean operations.

Subject: CGAL users discussion list

List archive

Re: [cgal-discuss] "Parts" of Polyhedron after a boolean operations.


Chronological Thread 
  • From: Gilles Kneuss <>
  • To:
  • Subject: Re: [cgal-discuss] "Parts" of Polyhedron after a boolean operations.
  • Date: Thu, 3 Dec 2009 08:14:33 +0100
  • Domainkey-signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :content-type; b=LrLcmQTJ85O/VF+VwBQuucqUGtfwAYHC4RPKzcDFobP+3m5b3bCIwAIaIncFz7hxFO DTM69HbvzMi4QPs7EI3gb/EKNifxl+PYo2pq8wREnsoVDkegbNU9A46Pb2odGderZLDZ YO5ylpgA1MfgjsJmxpekOl2HjxvFy02lBKP1E=

Hello Pierre,
 
Thank you very much!
 
-> If can do it more simple, I will tell you...
 
Have a nice day.
 
Gilles

2009/12/3 Pierre Alliez <>
Gilles wote:

> Yes, if you have an examples (using incrémental builder) it would be wonderful !


hi Gilles,

less trivial than I thought but doable - here is the code (.h file attached that makes it) - see usage below.
(we may want to add this to the polyhedron demo - a menu "explode" which generates as many meshes as connected components)
let me know if you can improve this code, ok?

pierre


#include "explode.h"

  std::list<Polyhedron> polyhedra;
  typedef std::back_insert_iterator<std::list<Polyhedron> > OutputIterator;
  Explode_polyhedron<Polyhedron,Kernel,OutputIterator> Explode;

  std::cout << "explode polyhedron...";
  Explode.run(polyhedron,std::back_inserter(polyhedra));
  std::cout << "done (" << polyhedra.size() << " components)" << std::endl;

  // save meshes to off files
  int index = 1;
  std::list<Polyhedron>::iterator it;
  for(it = polyhedra.begin();
      it != polyhedra.end();
      it++, index++)
  {
    char pFilename[256];
    sprintf(pFilename,"mesh%d.off",index);
    std::ofstream stream(pFilename);
    stream << *it;

  }

Pierre Alliez
INRIA Sophia Antipolis - Mediterranee 
Project-team GEOMETRICA 
http://www-sop.inria.fr/members/Pierre.Alliez/
Tel: +33 4 92 38 76 77
Fax: +33 4 97 15 53 95


Gilles Kneuss a écrit :
hi Pierre,
 

 
Thanks.
 
Gilles

2009/12/2 Pierre Alliez <>
hi Gilles,

did you already apply the conversion from the nef polyhedron to the surface polyhedron?

then to do the split I would recommend using the incremental  builder in order to do the split into several polyhedra. let me know if you want some example code to use as starting point for this task.

Pierre Alliez
INRIA Sophia Antipolis - Mediterranee Project-team GEOMETRICA http://www-sop.inria.fr/members/Pierre.Alliez/
Tel: +33 4 92 38 76 77
Fax: +33 4 97 15 53 95



Gilles a écrit :

Hello all,

When I make a boolean op. on 3D Polyhedron and the result is completely parted
(for exemple, I cutted a cylinder into two distinct  parts),

 I would like to identify these two parts (to make two new Polyhedron
afterwards).



Anyone has an answer how can I proceed ?

Thanks for help.

 

--
You are currently subscribed to cgal-discuss.
To unsubscribe or access the archives, go to
https://lists-sop.inria.fr/wws/info/cgal-discuss



#ifndef _EXPLODE_
#define _EXPLODE_

#include <set>
#include <map>
#include <stack>

#include <CGAL/Modifier_base.h>
#include <CGAL/Polyhedron_incremental_builder_3.h>

template<class Handle>
struct less_handle
{
 bool operator()(const Handle& h1,
                 const Handle& h2) const
 {
   return &(*h1) < &(*h2);
 }
};


template <class HDS, class Polyhedron, class Kernel>
class CModifierExplode : public CGAL::Modifier_base<HDS>
{
private:
 typedef typename Kernel::Triangle_3 Triangle;
 typedef typename HDS::Face_handle Face_handle;
 typedef typename HDS::Vertex_handle Vertex_handle;
 typedef typename HDS::Halfedge_handle Halfedge_handle;
 typedef typename Polyhedron::Halfedge_around_facet_circulator F_circulator;
 typedef typename CGAL::Polyhedron_incremental_builder_3<HDS> builder;

 typedef typename std::set<Face_handle, less_handle<Face_handle> > Faces;
 typedef typename std::set<Vertex_handle, less_handle<Vertex_handle> > Vertices;
 typedef typename std::set<Halfedge_handle, less_handle<Halfedge_handle> > Halfedges;

 Halfedges& m_halfedges;
 Halfedge_handle m_seed_halfedge;

public:

 // life cycle
 CModifierExplode(Halfedge_handle seed_halfedge,
                  Halfedges& halfedges)
   : m_seed_halfedge(seed_halfedge),
     m_halfedges(halfedges)
 {
 }
 ~CModifierExplode() {}

 // make one connected component
 void operator()( HDS& hds)
 {
   Faces faces;
   Vertices vertices;
   std::list<Vertex_handle> ordered_vertices;
   std::map<Vertex_handle,int,less_handle<Vertex_handle> > vertex_map;

   // traverse component and fill sets
   std::stack<Halfedge_handle> stack;
   stack.push(m_seed_halfedge);
   int vertex_index = 0;
   while(!stack.empty())
   {
     // pop halfedge from queue
     Halfedge_handle he = stack.top();
     stack.pop();
     m_halfedges.insert(he);

     // let's see its incident face
     if(!he->is_border())
     {
       Face_handle f = he->facet();
       if(faces.find(f) == faces.end())
         faces.insert(f);
     }

     // let's see its end vertex
     Vertex_handle v = he->vertex();
     if(vertices.find(v) == vertices.end())
     {
       vertices.insert(v);
       ordered_vertices.push_back(v);
       vertex_map[v] = vertex_index++;
     }

     // go and discover component
     Halfedge_handle nhe = he->next();
     Halfedge_handle ohe = he->opposite();
     if(m_halfedges.find(nhe) == m_halfedges.end())
       stack.push(nhe);
     if(m_halfedges.find(ohe) == m_halfedges.end())
       stack.push(ohe);
   }

   builder B(hds,true);
   B.begin_surface(3,1,6);

   // add vertices
   std::list<Vertex_handle>::iterator vit;
   for(vit = ordered_vertices.begin();
       vit != ordered_vertices.end();
       vit++)
   {
     Vertex_handle v = *vit;
     B.add_vertex(v->point());
   }

   // add facets
   Faces::iterator fit;
   for(fit = faces.begin();
     fit != faces.end();
     fit++)
   {
     Face_handle f = *fit;
     B.begin_facet();
     F_circulator he = f->facet_begin();
     F_circulator end = he;
     CGAL_For_all(he,end)
     {
       Vertex_handle v = he->vertex();
       B.add_vertex_to_facet(vertex_map[v]);
     }
     B.end_facet();
   }
   B.end_surface();
 }
};

template <class Polyhedron,
         class Kernel,
         class OutputIterator>
class Explode_polyhedron
{
public:
 typedef typename Polyhedron::HalfedgeDS HalfedgeDS;
 typedef typename Polyhedron::Halfedge_handle Halfedge_handle;
 typedef typename Polyhedron::Halfedge_iterator Halfedge_iterator;

public:
 Explode_polyhedron() {}
 ~Explode_polyhedron() {}

public:
 void run(Polyhedron &polyhedron,
          OutputIterator out)
 {
   std::set<Halfedge_handle,less_handle<Halfedge_handle> > halfedges;
   Polyhedron::Halfedge_iterator he;
   for(he = polyhedron.halfedges_begin();
       he != polyhedron.halfedges_end();
       he++)
   {
     if(halfedges.find(he) == halfedges.end())
     {
       // adds one component as polyhedron
       CModifierExplode<HalfedgeDS,Polyhedron,Kernel> modifier(he,halfedges);
       Polyhedron component;
       component.delegate(modifier);
       *out = component;
       out++;
     }
   }
 }
};

#endif // _EXPLODE_





Archive powered by MHonArc 2.6.16.

Top of Page