From 7970c9d2c478636be66becb4ab516b5112263ff8 Mon Sep 17 00:00:00 2001 From: Peter Hachenberger Date: Mon, 15 Sep 2003 09:02:26 +0000 Subject: [PATCH] refactoring --- .../include/CGAL/Nef_3/SNC_constructor.h | 464 ++++++++---------- .../Nef_3/include/CGAL/Nef_3/SNC_decorator.h | 21 +- .../include/CGAL/Nef_3/SNC_intersection.h | 19 +- .../Nef_3/include/CGAL/Nef_3/SNC_structure.h | 272 +++++----- .../include/CGAL/Nef_3/SNC_visualizor_OGL.h | 26 +- 5 files changed, 384 insertions(+), 418 deletions(-) diff --git a/Packages/Nef_3/include/CGAL/Nef_3/SNC_constructor.h b/Packages/Nef_3/include/CGAL/Nef_3/SNC_constructor.h index be50313a52f..0ca2a5cdb74 100644 --- a/Packages/Nef_3/include/CGAL/Nef_3/SNC_constructor.h +++ b/Packages/Nef_3/include/CGAL/Nef_3/SNC_constructor.h @@ -18,12 +18,13 @@ // revision : $Revision$ // revision_date : $Date$ // -// author(s) : Michael Seel -// Miguel Granados -// Susan Hert -// Lutz Kettner -// maintainer : Susan Hert -// Lutz Kettner +// author(s) : Michael Seel +// Miguel Granados +// Susan Hert +// Lutz Kettner +// Peter Hachenberger +// maintainer : Peter Hachenberger +// Lutz Kettner // coordinator : MPI Saarbruecken // // SNC_constructor.h construction of basic SNCs and global construction @@ -264,6 +265,8 @@ public: DECUSING(SHalfedge_around_svertex_circulator); #undef DECUSING + enum{NORMAL, CORNER, DEGENERATE}; + Vertex_handle minVertex; typedef void* GenPtr; @@ -371,68 +374,10 @@ public: volumes. \precond |categorize_facet_cycles_and_creating_facets()| was called before.}*/ + Halffacet_handle get_facet_below( Vertex_handle vi) const; Volume_handle determine_volume( SFace_handle sf, const std::vector< Vertex_handle>& MinimalVertex, - const Sface_shell_hash& Shell ) const - /*{\Mop determines the volume |C| that a shell |S| pointed by |sf| - belongs to. \precondition |S| separates the volume |C| from an enclosed - volume.}*/ { - TRACEN("determine volume"); - Vertex_handle v_min = MinimalVertex[Shell[sf]]; - - Halffacet_handle f_below = get_facet_below(v_min); - if ( f_below == Halffacet_handle()) - return Base(*this).volumes_begin(); - Volume_handle c = volume(f_below); - if( c != Volume_handle()) { - TRACE( "Volume " << &*c << " hit "); - TRACEN("(Shell #" << Shell[adjacent_sface(f_below)] << ")"); - return c; - } - SFace_handle sf_below = adjacent_sface(f_below); - TRACE( "Shell not assigned to a volume hit "); - TRACEN( "(Inner shell #" << Shell[sf_below] << ")"); - c = determine_volume( sf_below, MinimalVertex, Shell); - link_as_inner_shell( sf_below, c); - return c; - } - - Halffacet_handle get_facet_below( Vertex_handle vi) const - // {\Mop determines the facet below a vertex |vi| via ray shooting. } - { - Halffacet_handle f_below; - Point_3 p = point(vi); - if(!Infi_box::is_standard(p)) - return Halffacet_handle(); - - Ray_3 ray = Ray_3(p, Direction_3(-1,0,0)); - - SNC_ray_shooter rs(*sncp()); - Object_handle o = rs.shoot(ray); - Vertex_handle v; - Halfedge_handle e; - Halffacet_handle f; - TRACEN("get_facet_below"); - if( assign(v, o)) { - TRACEN("facet below from from vertex..."); - f_below = get_visible_facet(v, ray); - if( f_below == Halffacet_handle()) - f_below = get_facet_below(v); - } - else if( assign(e, o)) { - TRACEN("facet below from from edge..."); - f_below = get_visible_facet(e, ray); - if( f_below == Halffacet_handle()) - f_below = get_facet_below(vertex(e)); - } - else if( assign(f, o)) { - TRACEN("facet below from from facet..."); - f_below = get_visible_facet(f, ray); - CGAL_nef3_assertion( f_below != Halffacet_handle()); - } - else { TRACEN("no facet below found..."); } - return f_below; - } + const Sface_shell_hash& Shell ) const; void create_vertices_of_box_with_plane(const Plane_3& h, bool b); void create_frame_point(Point_3 p, Point_3 sp1, Point_3 sp2, @@ -443,6 +388,9 @@ public: int min,int max, Plane_3 h, bool boundary)const; + void create_SM_on_infibox(Point_3 center, Sphere_point* SP, int size, + bool boundary, bool fmark0) const; + }; // SNC_constructor @@ -453,7 +401,7 @@ create_vertices_of_box_with_plane(const Plane_3& h, bool b) { // SETDTHREAD(19*43*11); - Point_3 loc(-h.d(),0,0,h.a()); + // Point_3 loc(-h.d(),0,0,h.a()); Vector_3 orth = h.orthogonal_vector(); NT orth_coords[3]; @@ -462,8 +410,10 @@ create_vertices_of_box_with_plane(const Plane_3& h, bool b) { orth_coords[2] = orth.hz()[0]; int add_corners = 0; - while(orth_coords[add_corners] == 0) add_corners++; - CGAL_assertion(add_corners < 3); + while(orth_coords[add_corners] == 0){ + CGAL_assertion(add_corners < 2); + add_corners++; + } std::list points; for(int dir=0; dir<3;++dir) { @@ -499,7 +449,7 @@ create_vertices_of_box_with_plane(const Plane_3& h, bool b) { cross[i][3])); } - for(int i=0;i<2;i++) + for(int i=0;i<3;i++) orth_coords[i] = CGAL_NTS abs(orth_coords[i]); int max = 0; @@ -608,6 +558,11 @@ SNC_constructor:: create_frame_point(Point_3 p, Point_3 sp1, Point_3 sp2, Plane_3 h, bool boundary) const { + if(h.d() == 0) { + CGAL_nef3_assertion(CGAL_NTS abs(p.hy()) != CGAL_NTS abs(p.hx()) || + CGAL_NTS abs(p.hz()) != CGAL_NTS abs(p.hx())); + } + int max = 0; if(CGAL_NTS abs(p.hx()) > CGAL_NTS abs(p.hy())) max = 1; @@ -615,79 +570,31 @@ create_frame_point(Point_3 p, Point_3 sp1, Point_3 sp2, max = 2; TRACEN("create frame point "); - Vertex_handle v=sncp()->new_vertex(p, boundary); - SM_decorator SD(v); TRACEN("create spoints"); Sphere_point SP[4]; switch(max) { - case 0: SP[1] = Sphere_point(1,0,0); break; - case 1: SP[1] = Sphere_point(0,1,0); break; - case 2: SP[1] = Sphere_point(0,0,1); break; + case 0: SP[2] = Sphere_point(1,0,0); break; + case 1: SP[2] = Sphere_point(0,1,0); break; + case 2: SP[2] = Sphere_point(0,0,1); break; default: CGAL_nef3_assertion_msg(0,"wrong value"); } - SP[0]=sp1; - SP[2]=sp2; + SP[1]=sp1; + SP[0]=sp2; if (spherical_orientation(SP[0],SP[1],SP[2]) < 0) { - SP[3] = SP[1]; - SP[1] = -Vector_3(SP[3]); + SP[3] = SP[2]; + SP[2] = -Vector_3(SP[3]); } else - SP[3] = -Vector_3(SP[1]); + SP[3] = -Vector_3(SP[2]); - RT delta = h.a()*SP[1].hx()+h.b()*SP[1].hy()+h.c()*SP[1].hz(); + RT delta = h.a()*SP[2].hx()+h.b()*SP[2].hy()+h.c()*SP[2].hz(); CGAL_nef3_assertion(delta !=0); bool fmark0 = (delta < 0); - TRACEN("create svertices"); - SVertex_handle sv[4]; - for(int i=0; i<4; ++i) { - sv[i] = SD.new_vertex(SP[i]); - mark(sv[i]) = boundary; - } - - TRACEN("create sedges"); - SHalfedge_handle she[5]; - for(int si=0; si<3;++si) { - she[si]=SD.new_edge_pair(sv[si], sv[(si+1)%3]); - SD.circle(she[si])= - Sphere_circle(Plane_3(SP[si],SP[(si+1)%3],Point_3(0,0,0))); - SD.circle(SD.twin(she[si])) = SD.circle(she[si]).opposite(); - SD.mark(she[si]) = boundary; - } - - she[3] = SD.new_edge_pair(SD.twin(she[2]), sv[3],1); - she[4] = SD.new_edge_pair(she[2],sv[3],-1); - - CGAL_nef3_assertion(SD.next(she[0]) == she[1]); - CGAL_nef3_assertion(SD.next(she[1]) == she[2]); - CGAL_nef3_assertion(SD.next(she[2]) == she[0]); - - SD.circle(she[3])= Sphere_circle(Plane_3(SP[0],SP[3],Point_3(0,0,0))); - SD.circle(SD.twin(she[3])) = SD.circle(she[3]).opposite(); - SD.mark(she[3]) = boundary; - // SD.mark(SD.twin(she[3])) = !fmark0; - - SD.circle(she[4])= Sphere_circle(Plane_3(SP[2],SP[3],Point_3(0,0,0))); - SD.circle(SD.twin(she[4])) = SD.circle(she[4]).opposite(); - SD.mark(she[4]) = boundary; - // SD.mark(SD.twin(she[4])) = !fmark0; - - SFace_handle sf[3]; - for(int i=0; i<3; ++i) - sf[i] = SD.new_face(); - SD.mark(sf[0])= fmark0; - SD.mark(sf[1])=!fmark0; - SD.mark(sf[2])= 0; - - SD.link_as_face_cycle(she[0],sf[0]); - SD.link_as_face_cycle(SD.twin(she[2]),sf[1]); - SD.link_as_face_cycle(SD.twin(she[0]),sf[2]); - - SM_point_locator L(v); - L.init_marks_of_halfspheres(); + create_SM_on_infibox(p, SP, 4, boundary, fmark0); } template @@ -696,126 +603,66 @@ SNC_constructor:: create_corner_frame_point(Point_3 p, Point_3 sp1, Point_3 sp2, int max, Plane_3 h, bool boundary) const { + CGAL_nef3_assertion(h.d() == 0); + + Vector_3 vec = h.orthogonal_vector(); + + CGAL_nef3_assertion(CGAL_NTS abs(vec.hx()) != CGAL_NTS abs(vec.hy()) && + CGAL_NTS abs(vec.hy()) != CGAL_NTS abs(vec.hz()) && + CGAL_NTS abs(vec.hx()) != CGAL_NTS abs(vec.hz())); + + CGAL_nef3_assertion(vec.hx() + vec.hy() == vec.hz() || + vec.hx() + vec.hz() == vec.hy() || + vec.hy() + vec.hz() == vec.hx()); + TRACEN("create corner frame point "); - Vertex_handle v=sncp()->new_vertex(p, boundary); - SM_decorator SD(v); RT vp[3]; - vp[0] = -v->point().hx()[1]; - vp[1] = -v->point().hy()[1]; - vp[2] = -v->point().hz()[1]; + vp[0] = -p.hx()[1]; + vp[1] = -p.hy()[1]; + vp[2] = -p.hz()[1]; TRACEN("create spoints"); Sphere_point SP[5]; switch(max) { case 0: - SP[0] = Sphere_point(0,vp[1],0); - SP[3]= Sphere_point(0,0,vp[2]); + SP[3] = Sphere_point(0,vp[1],0); + SP[2]= Sphere_point(0,0,vp[2]); SP[4] = Sphere_point(vp[0],0,0); break; case 1: - SP[0] = Sphere_point(vp[0],0,0); - SP[3]= Sphere_point(0,0,vp[2]); + SP[3] = Sphere_point(vp[0],0,0); + SP[2]= Sphere_point(0,0,vp[2]); SP[4] = Sphere_point(0,vp[1],0); break; case 2: - SP[0] = Sphere_point(vp[0],0,0); - SP[3]= Sphere_point(0,vp[1],0); + SP[3] = Sphere_point(vp[0],0,0); + SP[2]= Sphere_point(0,vp[1],0); SP[4] = Sphere_point(0,0,vp[2]); break; default: CGAL_nef3_assertion_msg(0,"wrong value"); } - if (spherical_orientation(SP[0],Sphere_point(sp1),Sphere_point(sp2)) > 0) { - SP[1] = sp1; - SP[2] = sp2; + if (spherical_orientation(SP[3],Sphere_point(sp1),Sphere_point(sp2)) > 0) { + SP[0] = sp1; + SP[1] = sp2; } else { - SP[1] = sp2; - SP[2] = sp1; + SP[0] = sp2; + SP[1] = sp1; } - if (spherical_orientation(SP[3],SP[0],SP[1]) < 0) { - Sphere_point sx = SP[3]; - SP[3] = SP[0]; - SP[0] = sx; + if (spherical_orientation(SP[2],SP[3],SP[0]) < 0) { + Sphere_point sx = SP[2]; + SP[2] = SP[3]; + SP[3] = sx; } RT delta = h.a()*SP[4].hx()+h.b()*SP[4].hy()+h.c()*SP[4].hz(); CGAL_nef3_assertion(delta !=0); bool fmark0 = (delta > 0); - TRACEN("create svertices"); - SVertex_handle sv[5]; - for(int i=0; i<5; ++i) { - TRACEN("svertex " << SP[i]); - sv[i] = SD.new_vertex(SP[i]); - mark(sv[i]) = boundary; - } - - TRACEN("create sedges"); - SHalfedge_handle she[6]; - for(int si=0; si<4;++si) { - she[si]=SD.new_edge_pair(sv[si], sv[(si+1)%4]); - SD.circle(she[si])= - Sphere_circle(Plane_3(SP[si],SP[(si+1)%4],Point_3(0,0,0))); - SD.circle(SD.twin(she[si])) = SD.circle(she[si]).opposite(); - SD.mark(she[si]) = boundary; - } - - she[4] = SD.new_edge_pair(she[1],sv[4],-1); - - CGAL_nef3_assertion(SD.next(she[0]) == she[1]); - CGAL_nef3_assertion(SD.next(she[1]) == she[2]); - CGAL_nef3_assertion(SD.next(she[2]) == she[3]); - CGAL_nef3_assertion(SD.next(she[3]) == she[0]); - CGAL_nef3_assertion(SD.next(SD.twin(she[1])) == she[4]); - CGAL_nef3_assertion(SD.next(she[4]) == SD.twin(she[4])); - CGAL_nef3_assertion(SD.next(SD.twin(she[4])) == SD.twin(she[0])); - - she[5] = SD.new_edge_pair(sv[4],she[2],-1); - - CGAL_nef3_assertion(SD.next(she[0]) == she[1]); - CGAL_nef3_assertion(SD.next(she[1]) == she[2]); - CGAL_nef3_assertion(SD.next(she[2]) == she[3]); - CGAL_nef3_assertion(SD.next(she[3]) == she[0]); - CGAL_nef3_assertion(SD.next(she[4]) == she[5]); - CGAL_nef3_assertion(SD.next(she[5]) == SD.twin(she[1])); - CGAL_nef3_assertion(SD.next(SD.twin(she[1])) == she[4]); - CGAL_nef3_assertion(SD.next(she[4]) == she[5]); - CGAL_nef3_assertion(spherical_orientation(SP[1],SP[4],SP[2]) > 0); - - SD.circle(she[4])= - Sphere_circle(Plane_3(SP[1],SP[4],Point_3(0,0,0))); - SD.circle(SD.twin(she[4])) = SD.circle(she[4]).opposite(); - SD.mark(she[4]) = boundary; - - SD.circle(she[5])= - Sphere_circle(Plane_3(SP[4],SP[2],Point_3(0,0,0))); - SD.circle(SD.twin(she[5])) = SD.circle(she[5]).opposite(); - SD.mark(she[5]) = 1; - - - TRACEN("create sfaces"); - SFace_handle sf[3]; - for(int i=0; i<3; ++i) - sf[i] = SD.new_face(); - SD.mark(sf[0])=fmark0; - SD.mark(sf[1])=!fmark0; - SD.mark(sf[2])=0; - - TRACEN("link faces"); - SD.link_as_face_cycle(she[0],sf[0]); - SD.link_as_face_cycle(SD.twin(she[1]),sf[1]); - SD.link_as_face_cycle(SD.twin(she[0]),sf[2]); - - TRACEN("fpwc sedges"); - SHalfedge_handle se; - CGAL_nef3_forall_shalfedges(se,SM_decorator(v)) - TRACEN(PH(se)); - - SM_point_locator L(v); - L.init_marks_of_halfspheres(); + create_SM_on_infibox(p, SP, 5, boundary, fmark0); } template @@ -825,78 +672,113 @@ create_degenerate_corner_frame_point(Point_3 p, Point_3 sp1, Point_3 sp2, int min, int max, Plane_3 h, bool boundary) const { - TRACEN("create degenerate corner frame point "); - Vertex_handle v=sncp()->new_vertex(p, boundary); - SM_decorator SD(v); + CGAL_nef3_assertion(h.d() == 0); + + Vector_3 vec = h.orthogonal_vector(); + + CGAL_nef3_assertion( + (CGAL_NTS abs(vec.hx()) == CGAL_NTS abs(vec.hy()) && vec.hz() == 0) || + (CGAL_NTS abs(vec.hy()) == CGAL_NTS abs(vec.hz()) && vec.hx() == 0) || + (CGAL_NTS abs(vec.hx()) == CGAL_NTS abs(vec.hz()) && vec.hy() == 0)); RT vp[3]; vp[0] = -p.hx()[1]; vp[1] = -p.hy()[1]; vp[2] = -p.hz()[1]; + + TRACEN("create degenerate corner frame point "); TRACEN("create spoints"); Sphere_point SP[4]; switch(max) { - case 0: SP[0] = Sphere_point(vp[0],0,0); break; - case 1: SP[0] = Sphere_point(0,vp[1],0); break; - case 2: SP[0] = Sphere_point(0,0,vp[2]); break; + case 0: SP[2] = Sphere_point(vp[0],0,0); break; // plane(x,x,0), plane(x,0,x) + case 1: SP[2] = Sphere_point(0,vp[1],0); break; // plane(0,x,x) default: CGAL_nef3_assertion_msg(0,"wrong value \"max\""); } switch(min+max) { - case 1: SP[3] = Sphere_point(0,0,vp[2]); break; - case 2: SP[3] = Sphere_point(0,vp[1],0); break; - case 3: SP[3] = Sphere_point(vp[0],0,0); break; + case 1: SP[3] = Sphere_point(0,0,vp[2]); break; // plane(0,x,x), plane(x,0,x) + case 2: SP[3] = Sphere_point(0,vp[1],0); break; // plane(x,x,0) default: CGAL_nef3_assertion_msg(0,"wrong value \"min+max\""); } - if (spherical_orientation(SP[0],Sphere_point(sp1),Sphere_point(sp2)) > 0) { - SP[1] = sp1; - SP[2] = sp2; + if (spherical_orientation(SP[2],Sphere_point(sp1),Sphere_point(sp2)) > 0) { + SP[0] = sp1; + SP[1] = sp2; } else { - SP[1] = sp2; - SP[2] = sp1; + SP[0] = sp2; + SP[1] = sp1; } - RT delta = h.a()*SP[0].hx()+h.b()*SP[0].hy()+h.c()*SP[0].hz(); + RT delta = h.a()*SP[2].hx()+h.b()*SP[2].hy()+h.c()*SP[2].hz(); CGAL_nef3_assertion(delta !=0); bool fmark0 = (delta < 0); + create_SM_on_infibox(p, SP, 4, boundary, fmark0); +} + +template +void +SNC_constructor:: +create_SM_on_infibox(Point_3 center, Sphere_point* SP, int size, + bool boundary, bool fmark0) const { + + Vertex_handle v=sncp()->new_vertex(center, boundary); + SM_decorator SD(v); + TRACEN("create svertices"); - SVertex_handle sv[4]; - for(int i=0; i<4; ++i) { + SVertex_handle sv[size]; + for(int i=0; inew_vertex(p , boundary); + TRACEN( point(v)); SM_decorator SD(v); Sphere_point sp[] = { Sphere_point(-x, 0, 0), Sphere_point(0, -y, 0), @@ -1166,6 +1049,77 @@ create_from_edge(Halfedge_handle e, return v; } +template +typename SNC_::Halffacet_handle +SNC_constructor:: +get_facet_below( Vertex_handle vi) const { + // {\Mop determines the facet below a vertex |vi| via ray shooting. } + + Halffacet_handle f_below; + Point_3 p = point(vi); + if(!Infi_box::is_standard(p)) + return Halffacet_handle(); + + Ray_3 ray = Ray_3(p, Direction_3(-1,0,0)); + + SNC_ray_shooter rs(*sncp()); + Object_handle o = rs.shoot(ray); + Vertex_handle v; + Halfedge_handle e; + Halffacet_handle f; + TRACEN("get_facet_below"); + if( assign(v, o)) { + TRACEN("facet below from from vertex..."); + f_below = get_visible_facet(v, ray); + if( f_below == Halffacet_handle()) + f_below = get_facet_below(v); + } + else if( assign(e, o)) { + TRACEN("facet below from from edge..."); + f_below = get_visible_facet(e, ray); + if( f_below == Halffacet_handle()) + f_below = get_facet_below(vertex(e)); + } + else if( assign(f, o)) { + TRACEN("facet below from from facet..."); + f_below = get_visible_facet(f, ray); + CGAL_nef3_assertion( f_below != Halffacet_handle()); + } + else { TRACEN("no facet below found..."); } + return f_below; + } + +template +typename SNC_::Volume_handle +SNC_constructor:: +determine_volume( SFace_handle sf, + const std::vector< Vertex_handle>& MinimalVertex, + const Sface_shell_hash& Shell ) const { + //{\Mop determines the volume |C| that a shell |S| pointed by |sf| + // belongs to. \precondition |S| separates the volume |C| from an enclosed + // volume.} + + TRACEN("determine volume"); + Vertex_handle v_min = MinimalVertex[Shell[sf]]; + + Halffacet_handle f_below = get_facet_below(v_min); + if ( f_below == Halffacet_handle()) + return Base(*this).volumes_begin(); + Volume_handle c = volume(f_below); + if( c != Volume_handle()) { + TRACE( "Volume " << &*c << " hit "); + TRACEN("(Shell #" << Shell[adjacent_sface(f_below)] << ")"); + return c; + } + SFace_handle sf_below = adjacent_sface(f_below); + TRACE( "Shell not assigned to a volume hit "); + TRACEN( "(Inner shell #" << Shell[sf_below] << ")"); + c = determine_volume( sf_below, MinimalVertex, Shell); + link_as_inner_shell( sf_below, c); + return c; + } + + // ---------------------------------------------------------------------------- // pair_up_halfedges() // Starting from all local graphs of all vertices of a nef polyhedron diff --git a/Packages/Nef_3/include/CGAL/Nef_3/SNC_decorator.h b/Packages/Nef_3/include/CGAL/Nef_3/SNC_decorator.h index ee18391963e..ec21e1209a4 100644 --- a/Packages/Nef_3/include/CGAL/Nef_3/SNC_decorator.h +++ b/Packages/Nef_3/include/CGAL/Nef_3/SNC_decorator.h @@ -133,6 +133,8 @@ public: } }; + enum {NO_SNC, WITH_SNC}; + public: typedef void* GenPtr; @@ -726,6 +728,7 @@ public: #endif // CGAL_NEF3_DUMP_SPHERE_MAPS CGAL_assertion( point(v0) == point(v1)); Vertex_handle v01 = rsnc.new_vertex( point(v0), BOP( mark(v0),mark(v1))); + // cerr << "BOP Vertex " << mark(v0) << " " << mark(v1) << std::endl; TRACEN(" binop result on vertex "<<&*v01<<" on "<<&*(v01->sncp())); SM_overlayer O(v01); O.subdivide( v0, v1); @@ -999,10 +1002,10 @@ public: O.print(); #endif // CGAL_NEF3_DUMP_SNC_OPERATORS + /* // remove vertices whose local view is not that of a vertex - Vertex_iterator vi, vin; + Vertex_iterator vi, vin(v1); for( vi = result.vertices_begin(); vi != result.vertices_end(); vi = vin) { - vin = vi; vin++; SM_decorator SD(vi); if( (result.is_part_of_volume(vi) && @@ -1012,11 +1015,13 @@ public: mark(vi) == SD.mark(SD.shalfloop())) || (result.is_part_of_edge(vi) && - mark(vi) == SD.mark(SD.svertices_begin()))) + mark(vi) == SD.mark(SD.svertices_begin()) && + mark(vi) == SD.mark(++(SD.svertices_begin()))) result.delete_vertex(vi); } - - // compute_all_marks_of_halfspaces(); + */ + + result.vertex_simplification(NO_SNC); // synthesis of spatial structure @@ -1027,7 +1032,7 @@ public: C.link_shalfedges_to_facet_cycles(); C.categorize_facet_cycles_and_create_facets(); C.create_volumes(); - result.simplify(); + CGAL_nef3_assertion(!result.simplify()); #ifdef CGAL_NEF3_DUMP_SNC_OPERATORS TRACEN("=> construction completed, result: "); @@ -1068,7 +1073,7 @@ public: std::list Points(false); // durch hashmap ersetzen CGAL_nef3_forall_vertices(vi,*this) { if(!valid) break; - + valid = valid && vi->is_valid(verb, level); valid = valid && (vi->sncp()==sncp()); @@ -1093,7 +1098,7 @@ public: valid = valid && (++count <= max); } - + Points.sort(points_lt()); typename std::list::const_iterator li1, li2; li2 = li1 = Points.begin(); diff --git a/Packages/Nef_3/include/CGAL/Nef_3/SNC_intersection.h b/Packages/Nef_3/include/CGAL/Nef_3/SNC_intersection.h index 664fbcc709c..338b8653197 100644 --- a/Packages/Nef_3/include/CGAL/Nef_3/SNC_intersection.h +++ b/Packages/Nef_3/include/CGAL/Nef_3/SNC_intersection.h @@ -196,24 +196,8 @@ class SNC_intersection : public SNC_const_decorator { if( h.has_on( seg.source())) /* no possible internal intersection */ return false; -#ifdef REDUNDANT_CODE - /* This optimization might be inside of |intersection()| code */ - Oriented_side os1 = h.oriented_side(seg.source()); - Oriented_side os2 = h.oriented_side(seg.target()); - TRACEN( "-> endpoint plane side " << os1 << " " << os2); - CGAL_nef3_assertion( h.has_on(p)); - CGAL_nef3_assertion( seg.has_on(p)); - if (os1 == os2) - return false; -#endif //REDUNDANT_CODE Object o = intersection( h, seg); - Ray_3 s; - if ( assign( s, o) ) { - CGAL_nef3_assertion( s == seg ); - TRACEN( "-> seg belongs to facet's plane." << p ); - return false; - } - else if( !assign( p, o)) + if( !assign( p, o)) return false; TRACEN( "-> intersection point " << p ); TRACEN( "-> point in facet? "< { bool does_intersect_internally( const Segment_3& seg, const Halffacet_const_handle f, Point_3& p) const { + if(plane(f).has_on(seg.target())) return false; return (does_intersect_internally(Ray_3(seg.source(),seg.target()),f,p) && seg.has_on(p)); } diff --git a/Packages/Nef_3/include/CGAL/Nef_3/SNC_structure.h b/Packages/Nef_3/include/CGAL/Nef_3/SNC_structure.h index 106843abae0..ffd6d767ca6 100644 --- a/Packages/Nef_3/include/CGAL/Nef_3/SNC_structure.h +++ b/Packages/Nef_3/include/CGAL/Nef_3/SNC_structure.h @@ -911,63 +911,6 @@ public: put_sface_node(&*h); } - SNC_io_parser *IO; - - typedef typename Union_find< Volume_handle>::handle UFH_volume; - typedef typename Union_find< Halffacet_handle>::handle UFH_facet; - typedef typename Union_find< SFace_handle>::handle UFH_sface; - - void remove_f_including_all_edge_uses_in_its_boundary_cycles - ( Halffacet_handle f, - Unique_hash_map< SFace_handle, UFH_sface>& hash, - Union_find< SFace_handle>& uf ) - /* removes f and its boundary cycles, and merges up the sphere facets - incident to them. */ { - SNC_decorator D; - Halffacet_cycle_iterator fc; - CGAL_nef3_forall_facet_cycles_of(fc, f) { - SHalfedge_handle e; - SHalfloop_handle l; - if( assign(e, fc) ) { - SHalfedge_around_facet_circulator u(e), eend(e); - CGAL_For_all(u, eend) { - SFace_handle fu = D.sface(u), ftu = D.sface(D.twin(u)); - TRACEN("sfUNION of "<index(fu)<<" & "<index(ftu)); - merge_sets( fu, ftu, hash, uf); - SM_decorator SD(D.vertex(u)); - TRACEN("removing "<index(u)<<" & "<index(SD.twin(u))); - Halfedge_handle src(SD.source(u)), tgt(SD.target(u)); - if ( SD.is_closed_at_source(u) ) - SD.set_face( src, fu); - if ( SD.is_closed_at_source( SD.twin(u)) ) - SD.set_face( tgt, fu); - /* TO VERIFY: does is_closed_at_source(u) imply is_isolated(src)? - if it is true, the svertex face update is not necesary. */ - SD.delete_edge_pair(u); - if( SD.is_isolated(src)) - // SD.delete_vertex_only(src); - SD.set_face(src,fu); - SM_decorator SD2(D.vertex(tgt)); - if( SD2.is_isolated(tgt)) - // SD.delete_vertex_only(tgt); - SD2.set_face(tgt,fu); - /* TO VERIFY: can both svertices be isolated at the same time? */ - } - } - else if( assign(l, fc)) { - SFace_handle fu = D.sface(l), ftu = D.sface(D.twin(l)); - TRACEN("UNION of "<index(fu)<<" & "<index(ftu)); - merge_sets( fu, ftu, hash, uf); - SM_decorator SD(D.vertex(l)); - TRACEN("removing "<index(l)<<" & "<index(SD.twin(l))); - SD.delete_loop_only(); - } - } - TRACEN("removing "<index(f)<<" & "<index(D.twin(f))); - delete_halffacet_pair(f); - return; - } - char PSE(SHalfedge_handle h) /* prints a sphere segment */ { SNC_decorator D; @@ -1021,6 +964,66 @@ public: return '.'; } + SNC_io_parser *IO; + + typedef typename Union_find< Volume_handle>::handle UFH_volume; + typedef typename Union_find< Halffacet_handle>::handle UFH_facet; + typedef typename Union_find< SFace_handle>::handle UFH_sface; + + void remove_f_including_all_edge_uses_in_its_boundary_cycles + ( Halffacet_handle f, + Unique_hash_map< SFace_handle, UFH_sface>& hash, + Union_find< SFace_handle>& uf ) + /* removes f and its boundary cycles, and merges up the sphere facets + incident to them. */ { + SNC_decorator D; + Halffacet_cycle_iterator fc; + CGAL_nef3_forall_facet_cycles_of(fc, f) { + SHalfedge_handle e; + SHalfloop_handle l; + if( assign(e, fc) ) { + SHalfedge_around_facet_circulator u(e), eend(e); + CGAL_For_all(u, eend) { + SFace_handle fu = D.sface(u), ftu = D.sface(D.twin(u)); + TRACEN("sfUNION of "<index(fu)<<" & "<index(ftu)); + merge_sets( fu, ftu, hash, uf); + SM_decorator SD(D.vertex(u)); + TRACEN("removing "<index(u)<<" & "<index(SD.twin(u))); + Halfedge_handle src(SD.source(u)), tgt(SD.target(u)); + if ( SD.is_closed_at_source(u) ) + SD.set_face( src, fu); + if ( SD.is_closed_at_source( SD.twin(u)) ) + SD.set_face( tgt, fu); + /* TO VERIFY: does is_closed_at_source(u) imply is_isolated(src)? + if it is true, the svertex face update is not necesary. */ + SD.delete_edge_pair(u); + if( SD.is_isolated(src)) + // SD.delete_vertex_only(src); + SD.set_face(src,fu); + SM_decorator SD2(D.vertex(tgt)); + if( SD2.is_isolated(tgt)) + // SD.delete_vertex_only(tgt); + SD2.set_face(tgt,fu); + /* TO VERIFY: can both svertices be isolated at the same time? */ + } + } + else if( assign(l, fc)) { + // this code is currenlty not used, but it is potentially need + // in the future, e.g for complex marks or a relative interior + // function + SFace_handle fu = D.sface(l), ftu = D.sface(D.twin(l)); + TRACEN("UNION of "<index(fu)<<" & "<index(ftu)); + merge_sets( fu, ftu, hash, uf); + SM_decorator SD(D.vertex(l)); + TRACEN("removing "<index(l)<<" & "<index(SD.twin(l))); + SD.delete_loop_only(); + } + } + TRACEN("removing "<index(f)<<" & "<index(D.twin(f))); + delete_halffacet_pair(f); + return; + } + bool is_part_of_volume(Vertex_handle v) /* determines if a vertex v is part of a volume, cheking if its local graph is trivial (only one sface with no boundary). */ { @@ -1048,38 +1051,83 @@ public: bool is_part_of_edge(Vertex_handle v) { /* determines if a vertex v is part of a edge, checking at its local - graph for two antipodal vertices possible connected by a bundle of - sedges. */ - bool is_part = false; + graph for exactly two antipodal vertices */ + SM_decorator SD(v); - if( !SD.has_loop()) { - TRACE(SNC_decorator(*this).point(v)<<" is in edge interior? "); - SVertex_iterator sv(SD.svertices_begin()); - SVertex_handle p1(sv++), p2(sv++); // TODO: is it dangerous? - if( sv == SD.svertices_end()) { - TRACE("has two svertices? "); - Sphere_point sp1(SD.point(p1)), sp2(SD.point(p2)); - if( sp1 == sp2.antipode()) { - TRACE("are they antipode? "); - SHalfedge_iterator se; - CGAL_nef3_forall_sedges_of( se, v) { - if( (SD.source(se) != p1 && SD.target(se) != p2) && - (SD.source(se) != p2 && SD.target(se) != p1)) - break; - } - is_part = (se == SD.shalfedges_end()) ? true: false; - TRACE("all sedges conect them? "); + if(SD.has_loop()) + return false; + if(SD.svertices_begin() == SD.svertices_end()) + return false; + if(++(SD.svertices_begin()) == SD.svertices_end()) + return false; + + TRACE(SNC_decorator(*this).point(v)<<" is in edge interior? "); + SVertex_iterator sv(SD.svertices_begin()); + SVertex_handle p1(sv++), p2(sv++); + if( sv != SD.svertices_end()) + return false; + + TRACE("has two svertices "); + Sphere_point sp1(SD.point(p1)), sp2(SD.point(p2)); + return (sp1 == sp2.antipode()); + } + + bool vertex_simplification(bool snc_computed = true) { + bool simplified = false; + + SNC_io_parser IO_parser(std::cerr, *this); + IO = &IO_parser; + + SNC_decorator D(*this); + + Vertex_iterator v = (*this).vertices_begin(); + while( v != (*this).vertices_end()) { + SM_decorator SD(v); + Vertex_iterator v_next(v); + v_next++; + if( is_part_of_volume(v)) { + TRACEN("mark("<index(v)<<")="<index(D.volume(SD.sfaces_begin()))<<")="<< + SD.mark(SD.sfaces_begin())); + if(D.mark(v) == SD.mark(SD.sfaces_begin())) { + TRACEN("removing isolated vertex "<index(v)); + delete_vertex(v); + simplified = true; } } + else if( is_part_of_facet(v)) { + if( D.mark(v) == SD.mark(SD.shalfloop())) { + TRACEN("removing "<index(v)<< + " on facet "); + delete_vertex(v); + simplified = true; + } + } + else if( is_part_of_edge(v)) { + SVertex_iterator sv(SD.svertices_begin()); + Halfedge_handle e1(sv++), e2(sv++); + CGAL_nef3_assertion( sv == SD.svertices_end()); + if( D.mark(e1) == D.mark(v) && D.mark(v) == D.mark(e2)) { + TRACEN("merging "<index(e1)<<" & "<index(e2)<< + " in "<index(v)); + if(snc_computed) + merge_halfedge_pairs( e1, e2); + else + delete_vertex(v); + simplified = true; + } + } + v = v_next; } - TRACEN((is_part?"yes":"no")); - return is_part; + return simplified; } - void simplify() { - - // SETDTHREAD(41); + bool simplify() { + bool update_facets = false; + bool update_sfaces = false; + bool update_volumes = false; + TRACEN(">>> simplifying"); SNC_decorator D(*this); SNC_io_parser IO_parser(std::cerr, *this); @@ -1135,6 +1183,7 @@ public: merge_sets( c1, c2, hash_volume, uf_volume); remove_f_including_all_edge_uses_in_its_boundary_cycles (f, hash_sface, uf_sface); + update_sfaces = update_volumes = true; TRACEN("UNION of "<index(c1)<<" & "<index(c2)); } f = f_next; @@ -1163,6 +1212,7 @@ public: if(D.mark(e) == D.mark(D.volume(D.sface(e)))) { TRACEN("removing pair "<index(e)<<' '<index(D.twin(e))); delete_halfedge_pair(e); + update_facets = true; } } else { @@ -1180,6 +1230,7 @@ public: TRACEN("BEFORE "<index(e)); remove_edge_and_merge_facet_cycles(e); + update_facets = true; // TRACEN("AFTER "<index(v)<<")="<index(D.volume(SD.sfaces_begin()))<<")="<< - D.mark(D.volume(SD.sfaces_begin()))); - if(D.mark(v) == D.mark(D.volume(SD.sfaces_begin()))) { - TRACEN("removing isolated vertex "<index(v)); - delete_vertex(v); - } - } - else if( is_part_of_facet(v)) { - CGAL_nef3_assertion( D.facet(SD.shalfloop()) != Halffacet_handle()); - if( D.mark(v) == D.mark(D.facet(SD.shalfloop()))) { - TRACEN("removing "<index(v)<< - " on facet "<index(D.facet(SD.shalfloop()))); - delete_vertex(v); - } - } - else if( is_part_of_edge(v)) { - SVertex_iterator sv(SD.svertices_begin()); - Halfedge_handle e1(sv++), e2(sv++); - CGAL_nef3_assertion( sv == SD.svertices_end()); - if( D.mark(e1) == D.mark(v) && D.mark(v) == D.mark(e2)) { - TRACEN("merging "<index(e1)<<" & "<index(e2)<< - " in "<index(v)); - merge_halfedge_pairs( e1, e2); - } - } - v = v_next; - } - - purge_no_find_objects(hash_volume, hash_facet, hash_sface, uf_volume, - uf_facet, uf_sface); - create_boundary_links_forall_sfaces( hash_sface, uf_sface); - create_boundary_links_forall_facets( hash_facet, uf_facet); - create_boundary_links_forall_volumes( hash_volume, uf_volume); - - TRACEN(">>> simplifying done"); + update_facets = vertex_simplification() || update_facets; SETDTHREAD(1); + + purge_no_find_objects(hash_volume, hash_facet, hash_sface, uf_volume, + uf_facet, uf_sface); + if(update_sfaces || true) create_boundary_links_forall_sfaces( hash_sface, uf_sface); + if(update_facets || true) create_boundary_links_forall_facets( hash_facet, uf_facet); + if(update_volumes|| true) create_boundary_links_forall_volumes( hash_volume, uf_volume); + + TRACEN(">>> simplifying done "); + + return update_sfaces || update_facets || update_volumes; } void remove_edge_and_merge_facet_cycles( Halfedge_handle e) { diff --git a/Packages/Nef_3/include/CGAL/Nef_3/SNC_visualizor_OGL.h b/Packages/Nef_3/include/CGAL/Nef_3/SNC_visualizor_OGL.h index 61a861814ef..dc21cada1d1 100644 --- a/Packages/Nef_3/include/CGAL/Nef_3/SNC_visualizor_OGL.h +++ b/Packages/Nef_3/include/CGAL/Nef_3/SNC_visualizor_OGL.h @@ -842,17 +842,21 @@ public: SNC_visualizor_OGL(const SNC_structure& N) : Base(const_cast(N)) { ppoly_ = & CGAL::OGL::add_polyhedron(); } - OGL::Double_point double_point(const Point_3& p) const - { return OGL::Double_point(CGAL::to_double(p.x()), - CGAL::to_double(p.y()), - CGAL::to_double(p.z())); } + OGL::Double_point double_point(const Point_3& p) const { + double x = CGAL::to_double(p.hx().eval_at(1)); + double y = CGAL::to_double(p.hy().eval_at(1)); + double z = CGAL::to_double(p.hz().eval_at(1)); + double w = CGAL::to_double(p.hw().eval_at(1)); + return OGL::Double_point(x/w,y/w,z/w); + } OGL::Double_segment double_segment(const Segment_3& s) const { return OGL::Double_segment(double_point(s.source()), - double_point(s.target())); } + double_point(s.target())); + } void draw(Vertex_handle v) const - { + { Point_3 bp = Infi_box::box_point(point(v)); TRACEN("vertex " << bp); ppoly_->push_back(double_point(bp), mark(v)); @@ -883,15 +887,17 @@ public: } } Vector_3 v = orthogonal_vector(f); - g.set_normal(CGAL::to_double(v.x()), - CGAL::to_double(v.y()), - CGAL::to_double(v.z()), - mark(f)); + double x = CGAL::to_double(v.hx().eval_at(1)); + double y = CGAL::to_double(v.hy().eval_at(1)); + double z = CGAL::to_double(v.hz().eval_at(1)); + double w = CGAL::to_double(v.hw().eval_at(1)); + g.set_normal(x/w, y/w, z/w, mark(f)); ppoly_->push_back(g); } void draw() const { + // SETDTHREAD(53); Vertex_iterator v; CGAL_nef3_forall_vertices(v,*sncp()) draw(v); ppoly_->bbox() = sncp()->bounded_bbox();