Skip to Content.
Sympa Menu

cgal-discuss - Re: [cgal-discuss] CGAL difference on Nef_polyhedron produces shape with duplicate vertices

Subject: CGAL users discussion list

List archive

Re: [cgal-discuss] CGAL difference on Nef_polyhedron produces shape with duplicate vertices


Chronological Thread 
  • From: crobar <>
  • To:
  • Subject: Re: [cgal-discuss] CGAL difference on Nef_polyhedron produces shape with duplicate vertices
  • Date: Mon, 1 Sep 2014 01:35:17 -0700 (PDT)

Sebastien Loriot (GeometryFactory) wrote
> What kernel are you using internally to do the computation?
> I guess you export the result into double/float which result in rounding
> of the exact output, which result in points having the same coordinates
> in your case.
>
> Sebastien.

Here is the bulk of the CGAL wrapper:

#include <CGAL/Polyhedron_items_with_id_3.h>
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include<CGAL/Polyhedron_incremental_builder_3.h>
#include<CGAL/Polyhedron_3.h>
#include<CGAL/Nef_polyhedron_3.h>
#include<CGAL/IO/Polyhedron_iostream.h>
#include <CGAL/Iterator_project.h>
#include <CGAL/function_objects.h>


typedef CGAL::Exact_predicates_exact_constructions_kernel Kernel;
typedef CGAL::Polyhedron_3<Kernel> Polyhedron;
typedef Polyhedron::HalfedgeDS HalfedgeDS;
typedef CGAL::Nef_polyhedron_3<Kernel> Nef_polyhedron;

// A modifier creating a triangle with the incremental builder.
template<class HDS>
class polyhedron_builder : public CGAL::Modifier_base<HDS> {
public:
polyhedron t;

polyhedron_builder( const polyhedron &p ){
t = p;
}
void operator()( HDS& hds) {
typedef typename HDS::Vertex Vertex;
typedef typename Vertex::Point Point;


// create a cgal incremental builder
CGAL::Polyhedron_incremental_builder_3<HDS> B( hds, true);
B.begin_surface( t.num_vertices(), t.num_faces() );

// add the polyhedron vertices
for( int i=0; i<t.num_vertices(); i++ ){
double x, y, z;
t.get_vertex( i, x, y, z );
B.add_vertex( Point( x, y, z ) );
}

std::vector&lt;double> coords;
std::vector<int> faces;
t.output_store_in_mesh( coords, faces );

int nverts, tmpi = 0;
while( tmpi < (int)faces.size() ){
nverts = faces[tmpi++];
if( nverts != 3 )
std::cout << "face has " << nverts << " vertices" <<
std::endl;
B.begin_facet();
for( int i=0; i<nverts; i++ ){
B.add_vertex_to_facet( faces[tmpi++] );
}
B.end_facet();
}

// finish up the surface
B.end_surface();
}
};

Nef_polyhedron polyhedron_to_cgal( const polyhedron &amp;p ){
polyhedron tmp = p.triangulate();
Polyhedron P;
polyhedron_builder&lt;HalfedgeDS> builder( tmp );
P.delegate( builder );
if( P.is_closed() )
return Nef_polyhedron( P );
else
std::cout << "input polyhedron is not closed!" << std::endl;

return Nef_polyhedron();
}

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;
}

polyhedron polyhedron_union::operator()( const polyhedron &A, const
polyhedron &B ){
Nef_polyhedron a, b, c;
try {
a = polyhedron_to_cgal( A );
b = polyhedron_to_cgal( B );
c = (a + b).interior().closure();
return cgal_to_polyhedron( c );
} catch( std::exception &e ){
return A;
}
}

polyhedron polyhedron_difference::operator()( const polyhedron &A, const
polyhedron &B ){
Nef_polyhedron a, b, c;
try {
a = polyhedron_to_cgal( A );
b = polyhedron_to_cgal( B );
c = (a - b).interior().closure();
return cgal_to_polyhedron( c );
} catch( std::exception &e ){
return A;
}
}

polyhedron polyhedron_symmetric_difference::operator()( const polyhedron &A,
const polyhedron &B ){
Nef_polyhedron a, b, c;
try {
a = polyhedron_to_cgal( A );
b = polyhedron_to_cgal( B );
c = (a ^ b).interior().closure();
return cgal_to_polyhedron( c );
} catch( std::exception &e ){
return A;
}
}

polyhedron polyhedron_intersection::operator()( const polyhedron &A, const
polyhedron &B ){
Nef_polyhedron a, b, c;
try {
a = polyhedron_to_cgal( A );
b = polyhedron_to_cgal( B );
c = (a * b).interior().closure();
return cgal_to_polyhedron( c );
} catch( std::exception &e ){
return A;
}
}



I'm going to level with you that I did not write this code, and am just
making use of it. I once looked at using CGAL myself, but it was just too
complex and daunting, I could never have justified the time needed to learn
it. Luckily someone else has done the hard work for me in this project.

Therefore I don't know all the details You can see all the CGAL code in
this file:

https://github.com/crobarcro/pyPolyCSG/blob/master/libpolyhcsg/source/polyhedron_binary_op.cpp

As an incentive, consider that having such a simple wrapper available, and
also available in higher level languages like python and Matlab/Octave might
increase the CGAL user base. :-)





--
View this message in context:
http://cgal-discuss.949826.n4.nabble.com/CGAL-difference-on-Nef-polyhedron-produces-shape-with-duplicate-vertices-tp4659760p4659762.html
Sent from the cgal-discuss mailing list archive at Nabble.com.



Archive powered by MHonArc 2.6.18.

Top of Page