diff --git a/Packages/Nef_3/TODO b/Packages/Nef_3/TODO index b96ab61c678..fa0909cc076 100644 --- a/Packages/Nef_3/TODO +++ b/Packages/Nef_3/TODO @@ -11,4 +11,5 @@ Nef_3 Package: TODO - Find all intersections between two SNC's. - Binary operations - Extended kernel with infimaximal box - +- Define endpoint of segments used for ray shoting to be in the + infimaximal box. 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 2b7ddc25927..8687dc299f3 100644 --- a/Packages/Nef_3/include/CGAL/Nef_3/SNC_constructor.h +++ b/Packages/Nef_3/include/CGAL/Nef_3/SNC_constructor.h @@ -47,6 +47,8 @@ #define _DEBUG 43 #include +#define IMMN 999999 + CGAL_BEGIN_NAMESPACE template < class Node, class Object, class DClass> @@ -296,84 +298,105 @@ public: volumes. \precond |categorize_facet_cycles_and_creating_facets()| was called before.}*/ - Volume_handle determine_volume( const SFace_handle f, - const std::vector& MinimalVertex, - const Shell_number_hash& Shell ) const { - Vertex_handle v_min = MinimalVertex[Shell[f]]; + Volume_handle determine_volume( SFace_handle sf, + const std::vector< Vertex_handle>& MinimalVertex, + const Shell_number_hash& Shell ) const { + Vertex_handle v_min = MinimalVertex[Shell[sf]]; Halffacet_handle f_below = get_facet_below(v_min); if ( f_below == Halffacet_handle()) // return volumes_begin(); //qualifiers discarded? return Base(*this).volumes_begin(); Volume_handle c = volume(f_below); - if(c != Volume_handle()) + if( c != Volume_handle()) { + TRACE( "Volume " << &*c << " hit "); + TRACEN("(Shell #" << Shell[adjacent_sface(f_below)] << ")"); return c; - SFace_handle sf = sface(f_below); - c = determine_volume(sf, MinimalVertex, Shell); - link_as_inner_shell(sf, c); + } + SFace_handle sf_below = adjacent_sface(f_below); + TRACEN( "Shell not assigned to a volume hit "); + TRACEN( "(Inner shell #" << Shell[sf] << ")"); + c = determine_volume( sf_below, MinimalVertex, Shell); + link_as_inner_shell( sf_below, c); return c; } - Halffacet_handle get_facet_below(const Vertex_handle vi) const { - // Segment_3 s(point(v), point(vertices_begin())), // qualifiers discarded? - Segment_3 s(point(vi), point(Base(*this).vertices_begin())), - so(s.opposite()); - Object_handle closest; - Vertex_handle v; - Halfedge_handle e; - Halffacet_handle f; - CGAL_forall_vertices(v,*sncp()) { - SFace_iterator sf = v->sfaces_begin(); - if (sf != 0 && volume(sf) != Volume_handle() - && contains_internally(s,point(v))) { - shorten(s,point(v)); - closest = Object_handle(v); + Halffacet_handle get_visible_facet( Vertex_handle v, Sphere_point p) const { + TRACEN( "Locating " << p <<" in " << point(v)); + SM_point_locator L(v); + SObject_handle o = L.locate(p); + SFace_const_handle sf; + CGAL_assertion( assign( sf, o)); + assign( sf, o); + SFace_cycle_const_iterator fc; + CGAL_forall_sface_cycles_of( fc, sf) { + SHalfedge_handle se; + if ( assign( se, fc) ) { + TRACEN( "adjacent facet found."); + return facet(twin(se)); } } - CGAL_forall_edges(e,*sncp()) { - Point_3 q; - SFace_handle sf = sface(e); - if (sf != SFace_handle() && volume(sf) != Volume_handle() - && do_intersect(s,e,q) ) { - shorten(s,q); - closest = Object_handle(e); - } - } - CGAL_forall_halffacets(f,*sncp()) { - Point_3 q; - SFace_handle sf = sface(f); - if (sf != SFace_handle() && volume(sf) != Volume_handle() - && do_intersect(s,f,q) ) { - shorten(s,q); - closest = Object_handle(f); - } - } - if( assign(closest, v) ) { - SHalfedge_handle se = v->shalfedges_begin(); - if( se != SHalfedge_handle() ) - return facet(se); - SHalfloop_handle sl = v->shalfloop(); - if( sl != SHalfloop_handle() ) - return facet(sl); - CGAL_assertion_msg(0, "Empty local map."); - } - else if( assign( closest, e ) ) { - SM_decorator SD(vertex(e)); - CGAL_assertion( SD.first_out_edge(e) != SHalfedge_handle() ); - return facet(SD.first_out_edge(e)); - } - else if( assign( closest, f ) ) - return f; - else - TRACEN("no facet below found"); + TRACEN( "no adjacent facet found."); return Halffacet_handle(); } - /* following 4 functions were copied from SNC_point_locator.h */ - void shorten(Segment_3& s, const Point_3& p) const - { s = Segment_3(s.source(),p); } + Halffacet_handle get_facet_below( Vertex_handle vi) const { + Segment_3 s(point(vi), Point_3( 0, 0, -IMMN)); + /* TODO: replace IMMN constant for a real infimaximal number */ + TRACEN( "Shoting ray " << s); + Halffacet_handle f_below; + Vertex_handle v; + CGAL_forall_vertices( v, *sncp()) { + if ( contains_internally( s, point(v))) { + TRACEN("ray hit vertex case"); + Sphere_point sp(point(vi)-point(v)); + Halffacet_handle f_visible = get_visible_facet(v, sp); + if ( f_visible != Halffacet_handle()) { + shorten( s, point(v)); + f_below = f_visible; + } + } + } + Halfedge_handle e; + CGAL_forall_edges( e, *sncp()) { + Point_3 q; + if ( do_intersect( s, e, q) ) { // internally only? + TRACEN("ray hit edge case"); + v = vertex(e); + Sphere_point sp(point(vi)-point(v)); + Halffacet_handle f_visible = get_visible_facet(v, sp); + if ( f_visible != Halffacet_handle()) { + shorten( s, q); + f_below = f_visible; + } + } + } + Halffacet_handle f; + CGAL_forall_halffacets( f, *sncp()) { // internally only? + Point_3 q; + if ( do_intersect( s, f, q) ) { + TRACEN("ray hit facet case"); + Halffacet_cycle_iterator fc(f->facet_cycles_begin()); + CGAL_assertion( fc != f->facet_cycles_end()); + SHalfedge_handle se; + CGAL_assertion( assign( se, fc) ); + v = vertex(se); + Sphere_point sp(point(vi)-point(v)); + Halffacet_handle f_visible = get_visible_facet(v, sp); + if ( f_visible != Halffacet_handle()) { + shorten( s, q); + f_below = f_visible; + } + } + } + return f_below; + } - bool contains_internally(const Segment_3& s, const Point_3& p) const - { if(!s.has_on(p)) + void shorten(Segment_3& s, const Point_3& p) const { + s = Segment_3( s.source(), p); + } + + bool contains_internally(const Segment_3& s, const Point_3& p) const { + if(!s.has_on(p)) return false; Comparison_result r1 = compare_xyz(s.source(),p); Comparison_result r2 = compare_xyz(s.target(),p); @@ -405,23 +428,22 @@ public: const Segment_3& r, Point_3& p) const { - if(s.is_degenerate() || r.is_degenerate()) + if ( s.is_degenerate() || r.is_degenerate()) return false; /* at least one of the segments is degenerate so there is not internal intersection */ - if(orientation(s.source(),s.target(),r.source(),r.target()) != COPLANAR) + if ( orientation(s.source(),s.target(),r.source(),r.target()) != COPLANAR) return false; /* the segments doesn't define a plane */ - if(collinear(s.source(),s.target(),r.source()) && - collinear(s.source(),s.target(),r.target()) ) + if ( collinear(s.source(),s.target(),r.source()) && + collinear(s.source(),s.target(),r.target()) ) return false; /* the segments are collinear */ Line_3 ls(s), lr(r); - if(ls.direction() == lr.direction() || - ls.direction() == -lr.direction() ) + if ( ls.direction() == lr.direction() || + ls.direction() == -lr.direction() ) return false; /* the segments are parallel */ - Oriented_side os1, os2; Vector_3 vs(s.direction()), vr(r.direction()), vt(cross_product(vs, vr)), ws(cross_product(vt, vs)), wr(cross_product(vt, vr)); @@ -439,13 +461,12 @@ public: os2 = hr.oriented_side(s.target()); if(os1 != opposite(os2)) return false; - Object o = intersection(hs, lr); CGAL_assertion(assign(p,o)); /* since line(s) and line(r) are not parallel they intersects in only one point */ assign(p,o); - if( !contains_internally(s, p) || !contains_internally(r, p) ) + if ( !contains_internally(s, p) || !contains_internally(r, p) ) return false; return true; } @@ -455,31 +476,36 @@ public: Halffacet_handle f, Point_3& p) const { Plane_3 h(plane(f)); + // TRACEN("intersecting "<new_volume(); + //link_as_outer_shell( SFace_handle(), outer_volume); // dummy outer shell for (unsigned i = 0; i < MinimalVertex.size(); ++i) { - TRACEN("minimal vertex "<new_volume(); link_as_outer_shell(f, c ); + TRACEN( "Shell #" << i <<" linked as outer shell ("<< + (c == volume(f))<<")"); } } } @@ -837,6 +871,7 @@ create_volumes() const CGAL_forall_sfaces(f,*sncp()) { if ( volume(f) != Volume_handle() ) continue; + TRACEN( "Inner shell #" << Shell[f] <<" visited"); Volume_handle c = determine_volume( f, MinimalVertex, Shell ); link_as_inner_shell( f, c ); } 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 b53cd4af0a8..4b3b42868c0 100644 --- a/Packages/Nef_3/include/CGAL/Nef_3/SNC_decorator.h +++ b/Packages/Nef_3/include/CGAL/Nef_3/SNC_decorator.h @@ -36,6 +36,10 @@ #include #include +#undef _DEBUG +#define _DEBUG 13 +#include + CGAL_BEGIN_NAMESPACE template @@ -96,17 +100,17 @@ public: SNC_decorator(SNC_structure& W) : sncp_(&W) {} SNC_structure* sncp() const { return sncp_; } - Vertex_handle vertex(const Halfedge_handle e) const + Vertex_handle vertex( Halfedge_handle e) const { return e->center_vertex_; } - Halfedge_handle twin(const Halfedge_handle e) const + Halfedge_handle twin( Halfedge_handle e) const { return e->twin_; } - Vertex_handle source(const Halfedge_handle e) const + Vertex_handle source( Halfedge_handle e) const { return e->center_vertex_; } - Vertex_handle target(const Halfedge_handle e) const + Vertex_handle target( Halfedge_handle e) const { return source(twin(e)); } - SFace_handle sface(const Halfedge_handle e) const + SFace_handle sface( Halfedge_handle e) const { return e->incident_sface_; } - SFace_const_handle sface(const Halfedge_const_handle e) const + SFace_const_handle sface( Halfedge_const_handle e) const { return e->incident_sface_; } /* SVertex queries*/ @@ -150,15 +154,15 @@ public: std::string res(os.str()); os.freeze(0); return res; } - SHalfloop_handle twin(const SHalfloop_handle l) const + SHalfloop_handle twin( SHalfloop_handle l) const { return l->twin_; } - Halffacet_handle facet(const SHalfloop_handle l) const + Halffacet_handle facet( SHalfloop_handle l) const { return l->incident_facet_; } - Vertex_handle vertex(const SHalfloop_handle l) const + Vertex_handle vertex( SHalfloop_handle l) const { return l->incident_sface_->center_vertex_; } - SFace_handle sface(const SHalfloop_handle l) const + SFace_handle sface( SHalfloop_handle l) const { return l->incident_sface_; } - SFace_const_handle sface(const SHalfloop_const_handle l) const + SFace_const_handle sface( SHalfloop_const_handle l) const { return l->incident_sface_; } /* SHalfloop queries */ @@ -171,23 +175,24 @@ public: Halffacet_handle twin(Halffacet_handle f) const { return f->twin_; } Volume_handle volume(Halffacet_handle f) const - { return f->volume_; } - SFace_handle sface(Halffacet_handle f) const { - Halffacet_cycle_iterator fc(f->facet_cycles_begin()); - CGAL_assertion( fc != f->facet_cycles_end() ); - SHalfedge_handle e; - SHalfloop_handle l; - if ( assign(e, fc) ) { - SHalfedge_around_facet_circulator se(e); - CGAL_assertion( se != 0 ); - return sface(se); - } else if ( assign(l, fc) ) { - return sface(l); - } else CGAL_assertion_msg(0, "Damn wrong handle."); - return SFace_handle(); // never reached - } + { return f->volume_; } /* Halffacet queries */ + SFace_handle adjacent_sface(Halffacet_handle f) const { + Halffacet_cycle_iterator fc(f->facet_cycles_begin()); + CGAL_assertion( fc != f->facet_cycles_end()); + SHalfedge_handle se; + if ( assign(se, fc) ) { + CGAL_assertion( facet(se) == f); + CGAL_assertion( sface(se) != SFace_handle()); + CGAL_assertion( volume(sface(twin(se))) == volume(f)); + return sface(twin(se)); + } + else + CGAL_assertion_msg( 0, "Facet outer cycle entry point" + "is not an SHalfedge? "); + return SFace_handle(); // never reached + } // attributes:: Point_3& point(Vertex_handle v) const @@ -273,33 +278,41 @@ public: Volume_handle c; Shell_volume_setter(const SNC_decorator& Di, Volume_handle& ci) : D(Di), c(ci) {} - void visit(SFace_handle h) { D.set_volume(h, c); } + void visit(SFace_handle h) { + // TRACEN("volume assigned to SFace "<<&*h); + D.set_volume(h, c); + } void visit(Vertex_handle h) { /* empty */ } void visit(Halfedge_handle h) { /* empty */ } - void visit(Halffacet_handle h ) { D.set_volume(h, c); } + void visit(Halffacet_handle h ) { + // TRACEN("volume assigned to Halffacet "<<&*h); + D.set_volume(h, c); + } void set_volume(Volume_handle ci) { c = ci; } }; void link_as_outer_shell( SFace_handle f, Volume_handle c ) const { CGAL_assertion(c->shell_entry_objects_.size() == 0); Shell_volume_setter Setter(*this, c); + // TRACEN("Setting volume pointer to shell items..."); visit_shell_objects( f, Setter ); + // TRACEN("Done"); + TRACEN("Volume "<<&*c<<", outer shell "<<&*f); store_boundary_object( f, c ); } void link_as_inner_shell( SFace_handle f, Volume_handle c ) const { - // CGAL_assertion(c->shell_entry_objects_.size() > 0); - // the bounding infimaximal box is not yet stored so its entry objects - // list could be empty + //CGAL_assertion(c->shell_entry_objects_.size() > 0); Shell_volume_setter Setter(*this, c); visit_shell_objects( f, Setter ); + TRACEN("Volume "<<&*c<<", inner shell "<<&*f); store_boundary_object( f, c ); } - void set_volume(Halffacet_handle& h, Volume_handle& c) const - { h->volume_ = c; } - void set_volume(SFace_handle& h, Volume_handle& c) const - { h->incident_volume_ = c; } + void set_volume(Halffacet_handle h, Volume_handle c) const + { h->volume_ = c; CGAL_assertion(h->volume_ == c); } + void set_volume(SFace_handle h, Volume_handle c) const + { h->incident_volume_ = c; CGAL_assertion(h->incident_volume_ == c); } template void visit_shell_objects(SFace_handle f, Visitor& V) const; diff --git a/Packages/Nef_3/include/CGAL/Nef_3/SNC_items.h b/Packages/Nef_3/include/CGAL/Nef_3/SNC_items.h index 31da598a0d5..0aac5d42e14 100644 --- a/Packages/Nef_3/include/CGAL/Nef_3/SNC_items.h +++ b/Packages/Nef_3/include/CGAL/Nef_3/SNC_items.h @@ -42,6 +42,7 @@ CGAL_BEGIN_NAMESPACE template class SNC_items; template class SNC_structure; template class SNC_decorator; +template class SNC_constructor; template class SNC_io_parser; template class SNC_SM_decorator; template class SNC_SM_const_decorator; @@ -79,6 +80,7 @@ public: friend class SNC_structure; friend class SNC_decorator; friend class SNC_io_parser; + friend class SNC_constructor; friend class SNC_SM_decorator; friend class SNC_SM_const_decorator; typedef typename Refs::SVertex_iterator SVertex_iterator; @@ -297,6 +299,7 @@ public: friend class SNC_structure; friend class SNC_decorator; friend class SNC_io_parser; + friend class SNC_constructor; friend class SNC_SM_decorator; friend class SNC_SM_const_decorator; typedef typename Refs::Vertex_handle Vertex_handle; @@ -376,6 +379,7 @@ public: friend class SNC_structure; friend class SNC_decorator; friend class SNC_io_parser; + friend class SNC_constructor; friend class SNC_SM_decorator; friend class SNC_SM_const_decorator; friend class SNC_FM_decorator; @@ -451,6 +455,7 @@ public: friend class SNC_structure; friend class SNC_decorator; friend class SNC_io_parser; + friend class SNC_constructor; friend class SNC_SM_decorator; friend class SNC_SM_const_decorator; typedef typename Refs::Object_handle Object_handle; @@ -516,6 +521,7 @@ public: friend class SNC_structure; friend class SNC_decorator; friend class SNC_io_parser; + friend class SNC_constructor; friend class SNC_SM_decorator; friend class SNC_SM_const_decorator; friend class move_shalfedge_around_svertex; @@ -615,6 +621,7 @@ public: friend class SNC_structure; friend class SNC_decorator; friend class SNC_io_parser; + friend class SNC_constructor; friend class SNC_SM_decorator; friend class SNC_SM_const_decorator; friend class Self::Vertex; @@ -682,6 +689,7 @@ public: friend class SNC_structure; friend class SNC_decorator; friend class SNC_io_parser; + friend class SNC_constructor; friend class SNC_SM_decorator; friend class SNC_SM_const_decorator; typedef typename Refs::Vertex_handle Vertex_handle; diff --git a/Packages/Nef_3/include/CGAL/Nef_3/bounded_side_3.h b/Packages/Nef_3/include/CGAL/Nef_3/bounded_side_3.h index 966fd61dabd..815c042fd30 100644 --- a/Packages/Nef_3/include/CGAL/Nef_3/bounded_side_3.h +++ b/Packages/Nef_3/include/CGAL/Nef_3/bounded_side_3.h @@ -34,6 +34,7 @@ #include #include #include +#include CGAL_BEGIN_NAMESPACE @@ -63,6 +64,8 @@ Bounded_side bounded_side_3(ForwardIterator first, typedef typename R::Direction_3 Direction_3; typedef typename R::Plane_3 Plane_3; + CGAL_assertion( !is_empty_range(first, last)); + if(plane == Plane_3()) { ForwardIterator p(first); Point_3 p0(*(p++)); diff --git a/Packages/Nef_3/include/CGAL/Nef_3/polyhedron_3_to_nef_3.h b/Packages/Nef_3/include/CGAL/Nef_3/polyhedron_3_to_nef_3.h index 7481ab68018..f032b096d33 100644 --- a/Packages/Nef_3/include/CGAL/Nef_3/polyhedron_3_to_nef_3.h +++ b/Packages/Nef_3/include/CGAL/Nef_3/polyhedron_3_to_nef_3.h @@ -1,4 +1,4 @@ -#define CGAL_P2NEF3_USE_SM_OVERLAY +//#define CGAL_P2NEF3_USE_SM_OVERLAY // ============================================================================ // // Copyright (c) 1997-2002 The CGAL Consortium