From ae4623ca2bed3ec94d881fae22fda0c2364883cf Mon Sep 17 00:00:00 2001 From: Peter Hachenberger Date: Tue, 31 Jul 2007 11:41:47 +0000 Subject: [PATCH] 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 --- .../CGAL/Nef_3/polyhedron_3_to_nef_3.h | 115 ++++++----- Nef_3/include/CGAL/Nef_polyhedron_3.h | 180 ++++++++++++++++-- 2 files changed, 236 insertions(+), 59 deletions(-) diff --git a/Nef_3/include/CGAL/Nef_3/polyhedron_3_to_nef_3.h b/Nef_3/include/CGAL/Nef_3/polyhedron_3_to_nef_3.h index 005a8225bf4..bca30198f70 100644 --- a/Nef_3/include/CGAL/Nef_3/polyhedron_3_to_nef_3.h +++ b/Nef_3/include/CGAL/Nef_3/polyhedron_3_to_nef_3.h @@ -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(); } diff --git a/Nef_3/include/CGAL/Nef_polyhedron_3.h b/Nef_3/include/CGAL/Nef_polyhedron_3.h index 0c78b15a54d..49436d55905 100644 --- a/Nef_3/include/CGAL/Nef_polyhedron_3.h +++ b/Nef_3/include/CGAL/Nef_polyhedron_3.h @@ -42,6 +42,7 @@ #include #include #include +#include #ifdef CGAL_NEF3_CGAL_NEF3_SM_VISUALIZOR #include @@ -410,16 +411,145 @@ protected: , SNC_structure>( P, snc()); build_external_structure(); simplify(); + CGAL::Mark_bounded_volumes mbv(true); + delegate(mbv); set_snc(snc()); // CGAL_assertion(orientation() == 1); } - protected: + protected: + + template + class Triangulation_handler2 { + + typedef typename CGAL::Triangulation_vertex_base_2 Vb; + typedef typename CGAL::Constrained_triangulation_face_base_2 Fb; + typedef typename CGAL::Triangulation_data_structure_2 TDS; + typedef typename CGAL::No_intersection_tag Itag; + typedef typename CGAL::Constrained_triangulation_2 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 visited; + CGAL::Unique_hash_map 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 + 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 + 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 Build_polyhedron : public CGAL::Modifier_base { class Visitor { + typedef typename CGAL::Triangulation_euclidean_traits_xy_3 XY; + typedef typename CGAL::Triangulation_euclidean_traits_yz_3 YZ; + typedef typename CGAL::Triangulation_euclidean_traits_xz_3 XZ; + const Object_index& VI; Polyhedron_incremental_builder_3& 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 th(f); + th.handle_triangles(B, VI); + } else if(c == 1) { + Triangulation_handler2 th(f); + th.handle_triangles(B, VI); + } else if(c == 2) { + Triangulation_handler2 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; }