mirror of https://github.com/CGAL/cgal
constructor for OFF-files is more general, now
- can now handle several surfaces, which also need not to be closed any more - orientation of Off-file does not matter any more; constructor constructs the same polyhedron for both orientations. conversion from Nef_3 to Polyhedron_3 now triangulates all facets to - prevent rounding problems - handle facets with holes
This commit is contained in:
parent
f048a210f6
commit
ae4623ca2b
|
|
@ -187,8 +187,9 @@ void polyhedron_3_to_nef_3(Polyhedron_& P, SNC_structure& S)
|
|||
|
||||
SVertex_handle sv_prev = sv_0;
|
||||
|
||||
bool with_border = false;
|
||||
do {
|
||||
CGAL_assertion(!pe->is_border());
|
||||
// CGAL_assertion(!pe->is_border());
|
||||
CGAL_assertion(pe_prev->face() == pe->opposite()->face());
|
||||
CGAL_assertion(pe_prev->vertex()->point()==pv.point());
|
||||
CGAL_assertion(pe->vertex()->point()==pv.point());
|
||||
|
|
@ -199,9 +200,11 @@ void polyhedron_3_to_nef_3(Polyhedron_& P, SNC_structure& S)
|
|||
SVertex_handle sv = SM.new_svertex(sp);
|
||||
sv->mark() = true;
|
||||
|
||||
CGAL_NEF_TRACEN(pe_prev->facet()->plane());
|
||||
// CGAL_NEF_TRACEN(pe_prev->facet()->plane());
|
||||
CGAL_NEF_TRACEN(pe_target);
|
||||
CGAL_NEF_TRACEN(pe_prev->opposite()->vertex()->point());
|
||||
|
||||
/*
|
||||
if(pe_prev->facet()->plane().is_degenerate()) {
|
||||
typename Polyhedron::Halfedge_around_facet_const_circulator fc(pv.vertex_begin()), fcend(fc);
|
||||
std::cerr << "wrong cycle " << std::endl;
|
||||
|
|
@ -209,34 +212,42 @@ void polyhedron_3_to_nef_3(Polyhedron_& P, SNC_structure& S)
|
|||
std::cerr << " " << fc->vertex()->point() << std::endl;
|
||||
}
|
||||
}
|
||||
CGAL_assertion(!pe_prev->facet()->plane().is_degenerate());
|
||||
CGAL_assertion(pe_prev->facet()->plane().
|
||||
*/
|
||||
CGAL_assertion(pe_prev->is_border() ||
|
||||
!pe_prev->facet()->plane().is_degenerate());
|
||||
CGAL_assertion(pe_prev->is_border() ||
|
||||
pe_prev->facet()->plane().
|
||||
has_on(pe_prev->opposite()->vertex()->point()));
|
||||
CGAL_assertion(pe_prev->facet()->plane().has_on(pe_target));
|
||||
CGAL_assertion(pe_prev->facet()->plane().has_on(pv.point()));
|
||||
CGAL_assertion(pe_prev->is_border() ||
|
||||
pe_prev->facet()->plane().has_on(pe_target));
|
||||
CGAL_assertion(pe_prev->is_border() ||
|
||||
pe_prev->facet()->plane().has_on(pv.point()));
|
||||
|
||||
typename Polyhedron::Facet::Plane_3 ss_plane
|
||||
(CGAL::ORIGIN,
|
||||
pe_prev->facet()->plane().opposite().orthogonal_vector());
|
||||
Sphere_circle ss_circle(ss_plane);
|
||||
|
||||
CGAL_assertion(ss_circle.has_on(sp));
|
||||
CGAL_assertion(ss_circle.has_on(sv_prev->point()));
|
||||
|
||||
SHalfedge_handle e = SM.new_shalfedge_pair(sv_prev, sv);
|
||||
e->circle() = ss_circle;
|
||||
e->twin()->circle() = ss_circle.opposite();
|
||||
e->mark() = e->twin()->mark() = true;
|
||||
|
||||
index_adder.set_hash(pe_prev, e);
|
||||
if(pe_prev->is_border())
|
||||
with_border = true;
|
||||
else {
|
||||
typename Polyhedron::Facet::Plane_3 ss_plane
|
||||
(CGAL::ORIGIN,
|
||||
pe_prev->facet()->plane().opposite().orthogonal_vector());
|
||||
Sphere_circle ss_circle(ss_plane);
|
||||
|
||||
CGAL_assertion(ss_circle.has_on(sp));
|
||||
CGAL_assertion(ss_circle.has_on(sv_prev->point()));
|
||||
|
||||
SHalfedge_handle e = SM.new_shalfedge_pair(sv_prev, sv);
|
||||
e->circle() = ss_circle;
|
||||
e->twin()->circle() = ss_circle.opposite();
|
||||
e->mark() = e->twin()->mark() = true;
|
||||
|
||||
index_adder.set_hash(pe_prev, e);
|
||||
}
|
||||
|
||||
sv_prev = sv;
|
||||
pe_prev = pe;
|
||||
pe++;
|
||||
++pe;
|
||||
}
|
||||
while( pe != pv.vertex_begin() );
|
||||
|
||||
CGAL_assertion(!pe_0->is_border());
|
||||
CGAL_assertion(pe_prev->face() == pe_0->opposite()->face());
|
||||
CGAL_assertion(pe_prev->vertex()->point()==pv.point());
|
||||
CGAL_assertion(pe_0->vertex()->point()==pv.point());
|
||||
|
|
@ -244,37 +255,49 @@ void polyhedron_3_to_nef_3(Polyhedron_& P, SNC_structure& S)
|
|||
CGAL_NEF_TRACEN(pe_prev->facet()->plane());
|
||||
CGAL_NEF_TRACEN(pe_target_0);
|
||||
CGAL_NEF_TRACEN(pe_prev->opposite()->vertex()->point());
|
||||
CGAL_assertion(!pe_prev->facet()->plane().is_degenerate());
|
||||
CGAL_assertion(pe_prev->facet()->plane().
|
||||
CGAL_assertion(pe_prev->is_border() ||
|
||||
!pe_prev->facet()->plane().is_degenerate());
|
||||
CGAL_assertion(pe_prev->is_border() ||
|
||||
pe_prev->facet()->plane().
|
||||
has_on(pe_prev->opposite()->vertex()->point()));
|
||||
CGAL_assertion(pe_prev->facet()->plane().has_on(pe_target_0));
|
||||
CGAL_assertion(pe_prev->facet()->plane().has_on(pv.point()));
|
||||
CGAL_assertion(pe_prev->is_border() ||
|
||||
pe_prev->facet()->plane().has_on(pe_target_0));
|
||||
CGAL_assertion(pe_prev->is_border() ||
|
||||
pe_prev->facet()->plane().has_on(pv.point()));
|
||||
|
||||
typename Polyhedron::Facet::Plane_3 ss_plane
|
||||
(CGAL::ORIGIN,
|
||||
pe_prev->facet()->plane().opposite().orthogonal_vector());
|
||||
Sphere_circle ss_circle(ss_plane);
|
||||
|
||||
CGAL_assertion(ss_plane.has_on(sv_prev->point()));
|
||||
CGAL_assertion(ss_circle.has_on(sp_0));
|
||||
CGAL_assertion(ss_circle.has_on(sv_prev->point()));
|
||||
|
||||
SHalfedge_handle e = SM.new_shalfedge_pair(sv_prev, sv_0);
|
||||
e->circle() = ss_circle;
|
||||
e->twin()->circle() = ss_circle.opposite();
|
||||
e->mark() = e->twin()->mark() = true;
|
||||
|
||||
index_adder.set_hash(pe_prev, e);
|
||||
SHalfedge_handle e;
|
||||
if(pe_prev->is_border()) {
|
||||
with_border = true;
|
||||
e = sv_prev->out_sedge();
|
||||
} else {
|
||||
typename Polyhedron::Facet::Plane_3 ss_plane
|
||||
(CGAL::ORIGIN,
|
||||
pe_prev->facet()->plane().opposite().orthogonal_vector());
|
||||
Sphere_circle ss_circle(ss_plane);
|
||||
|
||||
CGAL_assertion(ss_plane.has_on(sv_prev->point()));
|
||||
CGAL_assertion(ss_circle.has_on(sp_0));
|
||||
CGAL_assertion(ss_circle.has_on(sv_prev->point()));
|
||||
|
||||
e = SM.new_shalfedge_pair(sv_prev, sv_0);
|
||||
e->circle() = ss_circle;
|
||||
e->twin()->circle() = ss_circle.opposite();
|
||||
e->mark() = e->twin()->mark() = true;
|
||||
|
||||
index_adder.set_hash(pe_prev, e);
|
||||
}
|
||||
|
||||
// create faces
|
||||
SFace_handle fint = SM.new_sface();
|
||||
SFace_handle fext = SM.new_sface();
|
||||
SM.link_as_face_cycle(e, fint);
|
||||
SM.link_as_face_cycle(e->twin(), fext);
|
||||
|
||||
// mark faces properly...
|
||||
fint->mark() = true;
|
||||
fext->mark() = false;
|
||||
|
||||
if(!with_border) {
|
||||
SFace_handle fint = SM.new_sface();
|
||||
SM.link_as_face_cycle(e, fint);
|
||||
fint->mark() = false;
|
||||
}
|
||||
|
||||
SM.check_integrity_and_topological_planarity();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@
|
|||
#include <CGAL/Nef_3/SNC_SM_explorer.h>
|
||||
#include <CGAL/Nef_polyhedron_S2.h>
|
||||
#include <CGAL/Modifier_base.h>
|
||||
#include <CGAL/Nef_3/Mark_bounded_volumes.h>
|
||||
|
||||
#ifdef CGAL_NEF3_CGAL_NEF3_SM_VISUALIZOR
|
||||
#include <CGAL/Nef_3/SNC_SM_visualizor.h>
|
||||
|
|
@ -410,16 +411,145 @@ protected:
|
|||
<CGAL::Polyhedron_3<T1,T2,T3,T4>, SNC_structure>( P, snc());
|
||||
build_external_structure();
|
||||
simplify();
|
||||
CGAL::Mark_bounded_volumes<Nef_polyhedron_3> mbv(true);
|
||||
delegate(mbv);
|
||||
set_snc(snc());
|
||||
// CGAL_assertion(orientation() == 1);
|
||||
}
|
||||
|
||||
protected:
|
||||
protected:
|
||||
|
||||
template<typename Kernel>
|
||||
class Triangulation_handler2 {
|
||||
|
||||
typedef typename CGAL::Triangulation_vertex_base_2<Kernel> Vb;
|
||||
typedef typename CGAL::Constrained_triangulation_face_base_2<Kernel> Fb;
|
||||
typedef typename CGAL::Triangulation_data_structure_2<Vb,Fb> TDS;
|
||||
typedef typename CGAL::No_intersection_tag Itag;
|
||||
typedef typename CGAL::Constrained_triangulation_2<Kernel,TDS,Itag> CT;
|
||||
|
||||
typedef typename CT::Face_handle Face_handle;
|
||||
typedef typename CT::Vertex_handle CTVertex_handle;
|
||||
typedef typename CT::Finite_faces_iterator Finite_face_iterator;
|
||||
typedef typename CT::Edge Edge;
|
||||
|
||||
CT ct;
|
||||
CGAL::Unique_hash_map<Face_handle, bool> visited;
|
||||
CGAL::Unique_hash_map<CTVertex_handle, Vertex_const_handle> ctv2v;
|
||||
Finite_face_iterator fi;
|
||||
Plane_3 supporting_plane;
|
||||
|
||||
public:
|
||||
Triangulation_handler2(Halffacet_const_handle f) :
|
||||
visited(false), supporting_plane(f->plane()) {
|
||||
|
||||
Halffacet_cycle_const_iterator fci;
|
||||
for(fci=f->facet_cycles_begin(); fci!=f->facet_cycles_end(); ++fci) {
|
||||
if(fci.is_shalfedge()) {
|
||||
SHalfedge_around_facet_const_circulator sfc(fci), send(sfc);
|
||||
CGAL_For_all(sfc,send) {
|
||||
CGAL_NEF_TRACEN(" insert point" << sfc->source()->source()->point());
|
||||
CTVertex_handle ctv = ct.insert(sfc->source()->source()->point());
|
||||
ctv2v[ctv] = sfc->source()->source();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(fci=f->facet_cycles_begin(); fci!=f->facet_cycles_end(); ++fci) {
|
||||
if(fci.is_shalfedge()) {
|
||||
SHalfedge_around_facet_const_circulator sfc(fci), send(sfc);
|
||||
CGAL_For_all(sfc,send) {
|
||||
CGAL_NEF_TRACEN(" insert constraint" << sfc->source()->source()->point()
|
||||
<< "->" << sfc->source()->twin()->source()->point());
|
||||
ct.insert_constraint(sfc->source()->source()->point(),
|
||||
sfc->source()->twin()->source()->point());
|
||||
}
|
||||
}
|
||||
}
|
||||
CGAL_assertion(ct.is_valid());
|
||||
|
||||
CGAL_NEF_TRACEN("number of finite triangles " << ct.number_of_faces());
|
||||
|
||||
typename CT::Face_handle infinite = ct.infinite_face();
|
||||
typename CT::Vertex_handle ctv = infinite->vertex(1);
|
||||
if(ct.is_infinite(ctv)) ctv = infinite->vertex(2);
|
||||
CGAL_assertion(!ct.is_infinite(ctv));
|
||||
|
||||
typename CT::Face_handle opposite;
|
||||
typename CT::Face_circulator vc(ctv,infinite);
|
||||
do { opposite = vc++;
|
||||
} while(!ct.is_constrained(typename CT::Edge(vc,vc->index(opposite))));
|
||||
typename CT::Face_handle first = vc;
|
||||
|
||||
CGAL_assertion(!ct.is_infinite(first));
|
||||
traverse_triangulation(first, first->index(opposite));
|
||||
|
||||
fi = ct.finite_faces_begin();
|
||||
}
|
||||
|
||||
void traverse_triangulation(Face_handle f, int parent) {
|
||||
visited[f] = true;
|
||||
if(!ct.is_constrained(Edge(f,ct.cw(parent))) && !visited[f->neighbor(ct.cw(parent))]) {
|
||||
Face_handle child(f->neighbor(ct.cw(parent)));
|
||||
traverse_triangulation(child, child->index(f));
|
||||
}
|
||||
if(!ct.is_constrained(Edge(f,ct.ccw(parent))) && !visited[f->neighbor(ct.ccw(parent))]) {
|
||||
Face_handle child(f->neighbor(ct.ccw(parent)));
|
||||
traverse_triangulation(child, child->index(f));
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Triangle_3>
|
||||
bool get_next_triangle(Triangle_3& tr) {
|
||||
while(fi != ct.finite_faces_end() && visited[fi] == false) ++fi;
|
||||
if(fi == ct.finite_faces_end()) return false;
|
||||
tr = Triangle_3(fi->vertex(0)->point(), fi->vertex(1)->point(), fi->vertex(2)->point());
|
||||
++fi;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool same_orientation(Plane_3 p1) const {
|
||||
if(p1.a() != 0)
|
||||
return CGAL::sign(p1.a()) == CGAL::sign(supporting_plane.a());
|
||||
if(p1.b() != 0)
|
||||
return CGAL::sign(p1.b()) == CGAL::sign(supporting_plane.b());
|
||||
return CGAL::sign(p1.c()) == CGAL::sign(supporting_plane.c());
|
||||
}
|
||||
|
||||
template<typename PIB, typename Index>
|
||||
void handle_triangles(PIB& pib, Index& VI) {
|
||||
while(fi != ct.finite_faces_end() && visited[fi] == false) ++fi;
|
||||
while(fi != ct.finite_faces_end()) {
|
||||
Plane_3 plane(fi->vertex(0)->point(),
|
||||
fi->vertex(1)->point(),
|
||||
fi->vertex(2)->point());
|
||||
pib.begin_facet();
|
||||
if(same_orientation(plane)) {
|
||||
pib.add_vertex_to_facet(VI[ctv2v[fi->vertex(0)]]);
|
||||
pib.add_vertex_to_facet(VI[ctv2v[fi->vertex(1)]]);
|
||||
pib.add_vertex_to_facet(VI[ctv2v[fi->vertex(2)]]);
|
||||
} else {
|
||||
pib.add_vertex_to_facet(VI[ctv2v[fi->vertex(0)]]);
|
||||
pib.add_vertex_to_facet(VI[ctv2v[fi->vertex(2)]]);
|
||||
pib.add_vertex_to_facet(VI[ctv2v[fi->vertex(1)]]);
|
||||
}
|
||||
pib.end_facet();
|
||||
do {
|
||||
++fi;
|
||||
} while(fi != ct.finite_faces_end() && visited[fi] == false);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <class HDS>
|
||||
class Build_polyhedron : public CGAL::Modifier_base<HDS> {
|
||||
|
||||
class Visitor {
|
||||
|
||||
typedef typename CGAL::Triangulation_euclidean_traits_xy_3<Kernel> XY;
|
||||
typedef typename CGAL::Triangulation_euclidean_traits_yz_3<Kernel> YZ;
|
||||
typedef typename CGAL::Triangulation_euclidean_traits_xz_3<Kernel> XZ;
|
||||
|
||||
const Object_index<Vertex_const_iterator>& VI;
|
||||
Polyhedron_incremental_builder_3<HDS>& B;
|
||||
SNC_const_decorator& D;
|
||||
|
|
@ -440,17 +570,41 @@ protected:
|
|||
|
||||
Halffacet_const_handle f = opposite_facet->twin();
|
||||
|
||||
B.begin_facet();
|
||||
fc = f->facet_cycles_begin();
|
||||
se = SHalfedge_const_handle(fc);
|
||||
CGAL_assertion(se!=0);
|
||||
SHalfedge_around_facet_const_circulator hc_start(se);
|
||||
SHalfedge_around_facet_const_circulator hc_end(hc_start);
|
||||
CGAL_For_all(hc_start,hc_end) {
|
||||
CGAL_NEF_TRACEN(" add vertex " << hc_start->source()->center_vertex()->point());
|
||||
B.add_vertex_to_facet(VI[hc_start->source()->center_vertex()]);
|
||||
SHalfedge_around_facet_const_circulator
|
||||
sfc1(f->facet_cycles_begin()), sfc2(sfc1);
|
||||
|
||||
if(++f->facet_cycles_begin() != f->facet_cycles_end() ||
|
||||
++(++(++sfc1)) != sfc2) {
|
||||
Vector_3 orth = f->plane().orthogonal_vector();
|
||||
int c = CGAL::abs(orth[0]) > CGAL::abs(orth[1]) ? 0 : 1;
|
||||
c = CGAL::abs(orth[2]) > CGAL::abs(orth[c]) ? 2 : c;
|
||||
|
||||
if(c == 0) {
|
||||
Triangulation_handler2<YZ> th(f);
|
||||
th.handle_triangles(B, VI);
|
||||
} else if(c == 1) {
|
||||
Triangulation_handler2<XZ> th(f);
|
||||
th.handle_triangles(B, VI);
|
||||
} else if(c == 2) {
|
||||
Triangulation_handler2<XY> th(f);
|
||||
th.handle_triangles(B, VI);
|
||||
} else
|
||||
CGAL_assertion_msg(false, "wrong value");
|
||||
|
||||
} else {
|
||||
|
||||
B.begin_facet();
|
||||
fc = f->facet_cycles_begin();
|
||||
se = SHalfedge_const_handle(fc);
|
||||
CGAL_assertion(se!=0);
|
||||
SHalfedge_around_facet_const_circulator hc_start(se);
|
||||
SHalfedge_around_facet_const_circulator hc_end(hc_start);
|
||||
CGAL_For_all(hc_start,hc_end) {
|
||||
CGAL_NEF_TRACEN(" add vertex " << hc_start->source()->center_vertex()->point());
|
||||
B.add_vertex_to_facet(VI[hc_start->source()->center_vertex()]);
|
||||
}
|
||||
B.end_facet();
|
||||
}
|
||||
B.end_facet();
|
||||
}
|
||||
|
||||
void visit(SFace_const_handle) {}
|
||||
|
|
@ -481,8 +635,8 @@ protected:
|
|||
}
|
||||
else {
|
||||
B.begin_surface(scd.number_of_vertices(),
|
||||
scd.number_of_facets(),
|
||||
scd.number_of_edges());
|
||||
2*scd.number_of_vertices()-4,
|
||||
3*scd.number_of_vertices()-6);
|
||||
skip_volumes = 1;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue