diff --git a/.gitattributes b/.gitattributes index 631f8b3163a..a077affd640 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1472,6 +1472,16 @@ Nef_3/doc_tex/Nef_3_ref/fig/snc.eps -text svneol=unset#application/postscript Nef_3/doc_tex/Nef_3_ref/fig/snc.gif -text svneol=unset#image/gif Nef_3/doc_tex/Nef_3_ref/fig/snc.pdf -text svneol=unset#application/pdf Nef_3/examples/Nef_3/complex_construction.cin -text +Nef_3/include/CGAL/Nef_3/Halfedge.h -text +Nef_3/include/CGAL/Nef_3/Halffacet.h -text +Nef_3/include/CGAL/Nef_3/ID_support_handler.h -text +Nef_3/include/CGAL/Nef_3/SFace.h -text +Nef_3/include/CGAL/Nef_3/SHalfedge.h -text +Nef_3/include/CGAL/Nef_3/SHalfloop.h -text +Nef_3/include/CGAL/Nef_3/SNC_external_structure.h -text +Nef_3/include/CGAL/Nef_3/SNC_indexed_items.h -text +Nef_3/include/CGAL/Nef_3/Vertex.h -text +Nef_3/include/CGAL/Nef_3/Volume.h -text Nef_3/performance/Nef_3/cube.nef3 -text svneol=native#application/octet-stream Nef_3/performance/Nef_3/nef3/grid_15_15_15_12345.nef3 -text svneol=native#application/octet-stream Nef_3/performance/Nef_3/nef3/tetrahedra_15_15_15_12345.nef3 -text svneol=native#application/octet-stream diff --git a/Nef_3/include/CGAL/Nef_3/Halfedge.h b/Nef_3/include/CGAL/Nef_3/Halfedge.h new file mode 100644 index 00000000000..b1ee3161d8d --- /dev/null +++ b/Nef_3/include/CGAL/Nef_3/Halfedge.h @@ -0,0 +1,164 @@ +// Copyright (c) 1997-2002 Max-Planck-Institute Saarbruecken (Germany). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you may redistribute it under +// the terms of the Q Public License version 1.0. +// See the file LICENSE.QPL distributed with CGAL. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL: svn+ssh://hachenb@scm.gforge.inria.fr/svn/cgal/branches/Filtered_Nef/Nef_3/include/CGAL/Nef_3/Halfedge.h $ +// $Id: Halfedge.h 35450 2006-12-06 10:43:20Z hachenb $ +// +// +// Author(s) : Michael Seel +// Miguel Granados +// Susan Hert +// Lutz Kettner +// Peter Hachenberger +#ifndef CGAL_NEF_HALFEDGE_H +#define CGAL_NEF_HALFEDGE_H + +#include +#include +#include +#include + +#undef CGAL_NEF_DEBUG +#define CGAL_NEF_DEBUG 83 +#include + +CGAL_BEGIN_NAMESPACE + +template +class Halfedge_base +{ // == Halfedge + typedef void* GenPtr; + typedef typename Refs::Mark Mark; + typedef typename Refs::Vector_3 Vector_3; + typedef typename Refs::Sphere_point Sphere_point; + typedef typename Refs::Vertex_handle Vertex_handle; + typedef typename Refs::Halfedge_handle Halfedge_handle; + typedef typename Refs::SVertex_handle SVertex_handle; + typedef typename Refs::SHalfedge_handle SHalfedge_handle; + typedef typename Refs::SFace_handle SFace_handle; + typedef typename Refs::Vertex_const_handle Vertex_const_handle; + typedef typename Refs::Halfedge_const_handle Halfedge_const_handle; + typedef typename Refs::SVertex_const_handle SVertex_const_handle; + typedef typename Refs::SHalfedge_const_handle SHalfedge_const_handle; + typedef typename Refs::SFace_const_handle SFace_const_handle; + + Vertex_handle center_vertex_; + Mark mark_; + SVertex_handle twin_; + SHalfedge_handle out_sedge_; + SFace_handle incident_sface_; + GenPtr info_; + Sphere_point point_; + + public: + + Halfedge_base() : center_vertex_(), mark_(), twin_(), + out_sedge_(), incident_sface_(), + info_(), point_() {} + + Halfedge_base(Mark m) : center_vertex_(), mark_(m), twin_(), + out_sedge_(), incident_sface_(), + info_(), point_() {} + + ~Halfedge_base() { + CGAL_NEF_TRACEN(" destroying Halfedge item "<<&*this); + } + + Halfedge_base(const Halfedge_base& e) + { center_vertex_ = e.center_vertex_; + point_ = e.point_; + mark_ = e.mark_; + twin_ = e.twin_; + out_sedge_ = e.out_sedge_; + incident_sface_ = e.incident_sface_; + info_ = 0; + } + + Halfedge_base& operator=(const Halfedge_base& e) + { center_vertex_ = e.center_vertex_; + point_ = e.point_; + mark_ = e.mark_; + twin_ = e.twin_; + out_sedge_ = e.out_sedge_; + incident_sface_ = e.incident_sface_; + info_ = 0; + return *this; + } + + Vertex_handle& center_vertex() { return center_vertex_; } + Vertex_const_handle center_vertex() const { return center_vertex_; } + + Vertex_handle& source() { return center_vertex_; } + Vertex_const_handle source() const { return center_vertex_; } + + Vertex_handle& target() { return twin()->source(); } + Vertex_const_handle target() const { return twin()->source(); } + + Mark& mark() { return mark_; } + const Mark& mark() const { return mark_; } + + Vector_3 vector() const { return (point_ - CGAL::ORIGIN); } + Sphere_point& point(){ return point_; } + const Sphere_point& point() const { return point_; } + + SVertex_handle& twin() { return twin_; } + SVertex_const_handle twin() const { return twin_; } + + SHalfedge_handle& out_sedge() { return out_sedge_; } + SHalfedge_const_handle out_sedge() const { return out_sedge_; } + + SFace_handle& incident_sface() { return incident_sface_; } + SFace_const_handle incident_sface() const { return incident_sface_; } + + bool is_isolated() const { return (out_sedge() == SHalfedge_handle()); } + + GenPtr& info() { return info_; } + const GenPtr& info() const { return info_; } + + public: + std::string debug() const + { std::stringstream os; + set_pretty_mode(os); + os<<"sv [ "<::Halfedge_base::is_valid( verb=true, " + "level = " << level << "):" << std::endl; + + bool valid = (center_vertex_ != NULL && center_vertex_ != Vertex_handle()); + valid = valid && (twin_ != NULL && twin_ != SVertex_handle() && + twin_ != SVertex_handle()); + // valid = valid && (out_sedge_ != NULL); + // valid = valid && (incident_sface_ != SFace_handle()); + + // valid = valid &&((out_sedge_ != NULL && incident_sface_ == NULL) || + // (out_sedge_ == NULL && incident_sface_ != NULL)); + + valid = valid && (out_sedge_ != NULL || incident_sface_ != NULL); + + verr << "end of CGAL::SNC_items<...>::Halfedge_base::is_valid(): structure is " + << ( valid ? "valid." : "NOT VALID.") << std::endl; + + return valid; + } + +}; // Halfedge_base + +CGAL_END_NAMESPACE +#endif //CGAL_NEF_HALFEDGE_H diff --git a/Nef_3/include/CGAL/Nef_3/Halffacet.h b/Nef_3/include/CGAL/Nef_3/Halffacet.h new file mode 100644 index 00000000000..533ce6f6ab1 --- /dev/null +++ b/Nef_3/include/CGAL/Nef_3/Halffacet.h @@ -0,0 +1,143 @@ +// Copyright (c) 1997-2002 Max-Planck-Institute Saarbruecken (Germany). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you may redistribute it under +// the terms of the Q Public License version 1.0. +// See the file LICENSE.QPL distributed with CGAL. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL: svn+ssh://hachenb@scm.gforge.inria.fr/svn/cgal/branches/Filtered_Nef/Nef_3/include/CGAL/Nef_3/Halffacet.h $ +// $Id: Halffacet.h 35450 2006-12-06 10:43:20Z hachenb $ +// +// +// Author(s) : Michael Seel +// Miguel Granados +// Susan Hert +// Lutz Kettner +// Peter Hachenberger +#ifndef CGAL_NEF_HALFFACET_H +#define CGAL_NEF_HALFFACET_H + +#include +#include +#include +#include + +#undef CGAL_NEF_DEBUG +#define CGAL_NEF_DEBUG 83 +#include + +CGAL_BEGIN_NAMESPACE + +template +class Halffacet_base { + + typedef void* GenPtr; + typedef typename Refs::Mark Mark; + typedef typename Refs::Plane_3 Plane_3; + typedef typename Refs::Halffacet_handle Halffacet_handle; + typedef typename Refs::Halffacet_const_handle Halffacet_const_handle; + typedef typename Refs::Volume_handle Volume_handle; + typedef typename Refs::Volume_const_handle Volume_const_handle; + typedef typename Refs::Object_list Object_list; + typedef typename Refs::Halffacet_cycle_iterator + Halffacet_cycle_iterator; + typedef typename Refs::Halffacet_cycle_const_iterator + Halffacet_cycle_const_iterator; + + Plane_3 supporting_plane_; + Mark mark_; + Halffacet_handle twin_; + Volume_handle volume_; + Object_list boundary_entry_objects_; // SEdges, SLoops + + public: + + Halffacet_base() : supporting_plane_(), mark_() {} + + Halffacet_base(const Plane_3& h, Mark m) : + supporting_plane_(h), mark_(m) {} + + ~Halffacet_base() { + CGAL_NEF_TRACEN(" destroying Halffacet_base item "<<&*this); + } + + Halffacet_base(const Halffacet_base& f) + { supporting_plane_ = f.supporting_plane_; + mark_ = f.mark_; + twin_ = f.twin_; + CGAL_NEF_TRACEN("VOLUME const"); + volume_ = f.volume_; + boundary_entry_objects_ = f.boundary_entry_objects_; + } + + Halffacet_base& operator=(const Halffacet_base& f) + { if (this == &f) return *this; + supporting_plane_ = f.supporting_plane_; + mark_ = f.mark_; + twin_ = f.twin_; + CGAL_NEF_TRACEN("VOLUME op="); + volume_ = f.volume_; + boundary_entry_objects_ = f.boundary_entry_objects_; + return *this; + } + + Mark& mark() { return mark_; } + const Mark& mark() const { return mark_; } + + Halffacet_handle& twin() { return twin_; } + Halffacet_const_handle twin() const { return twin_; } + + Plane_3& plane() { return supporting_plane_; } + const Plane_3& plane() const { return supporting_plane_; } + + Volume_handle& incident_volume() { return volume_; } + Volume_const_handle incident_volume() const { return volume_; } + + Object_list& boundary_entry_objects() { return boundary_entry_objects_; } + const Object_list& boundary_entry_objects() const { return boundary_entry_objects_; } + + GenPtr& info() { return this->info_; } + const GenPtr& info() const { return this->info_; } + + Halffacet_cycle_iterator facet_cycles_begin() + { return boundary_entry_objects_.begin(); } + Halffacet_cycle_iterator facet_cycles_end() + { return boundary_entry_objects_.end(); } + Halffacet_cycle_const_iterator facet_cycles_begin() const + { return boundary_entry_objects_.begin(); } + Halffacet_cycle_const_iterator facet_cycles_end() const + { return boundary_entry_objects_.end(); } + + bool is_twin() const { return (&*twin_ < this); } + + bool is_valid( bool verb = false, int level = 0) const { + + Verbose_ostream verr(verb); + verr << "begin CGAL::SNC_items<...>::Halffacet_base::is_valid( verb=true, " + "level = " << level << "):" << std::endl; + + bool valid = (twin_ != NULL && twin_ != Halffacet_handle()); + valid = valid && (volume_ != NULL && volume_ != Volume_handle()); + + valid = valid && (supporting_plane_.a() != 0 || + supporting_plane_.b() != 0 || + supporting_plane_.c() != 0); + + valid = valid && (!boundary_entry_objects_.empty()); + + verr << "end of CGAL::SNC_items<...>::Halffacet_base::is_valid(): structure is " + << ( valid ? "valid." : "NOT VALID.") << std::endl; + + return valid; + } + +}; // Halffacet_base + +CGAL_END_NAMESPACE +#endif //CGAL_NEF_HALFFACET_H diff --git a/Nef_3/include/CGAL/Nef_3/ID_support_handler.h b/Nef_3/include/CGAL/Nef_3/ID_support_handler.h new file mode 100644 index 00000000000..e52c9e0d5f9 --- /dev/null +++ b/Nef_3/include/CGAL/Nef_3/ID_support_handler.h @@ -0,0 +1,353 @@ +#ifndef CGAL_ID_SUPPORT_HANDLER +#define CGAL_ID_SUPPORT_HANDLER + +#include +#include + +CGAL_BEGIN_NAMESPACE + +template +class ID_support_handler { + + typedef typename Decorator::SVertex_handle SVertex_handle; + typedef typename Decorator::SHalfedge_handle SHalfedge_handle; + + typedef typename Decorator::SVertex_const_handle SVertex_const_handle; + typedef typename Decorator::SHalfedge_const_handle SHalfedge_const_handle; + typedef typename Decorator::SHalfloop_const_handle SHalfloop_const_handle; + + public: + ID_support_handler() {} + + void handle_support(SVertex_handle sv, + SHalfedge_const_handle se1, + SHalfedge_const_handle se2) {} + + void handle_support(SVertex_handle sv, + SHalfloop_const_handle sl1, + SHalfloop_const_handle sl2) {} + + void handle_support(SVertex_handle sv, + SHalfloop_const_handle sl1, + SHalfedge_const_handle se2) {} + + void handle_support(SVertex_handle sv, + SHalfedge_const_handle se1, + SHalfloop_const_handle sl2) {} + + void handle_support(SVertex_handle sv, + SHalfedge_const_handle se1, + SVertex_const_handle sv2) {} + + void handle_support(SVertex_handle sv, + SVertex_const_handle sv1, + SHalfedge_const_handle se2) {} + + void handle_support(SVertex_handle sv, + SVertex_const_handle sv1, + SVertex_const_handle sv2) {} + + void handle_support(SVertex_handle sv, + SVertex_const_handle sv0) {} + + void handle_support(SVertex_handle sv, + SVertex_const_handle sv1, + SHalfloop_const_handle sl2) {} + + void handle_support(SVertex_handle sv, + SHalfloop_const_handle sl1, + SVertex_const_handle sv2) {} + + void handle_support(SHalfedge_handle se, + SHalfedge_const_handle se1, + SHalfedge_const_handle se2) {} + + void handle_support(SHalfedge_handle se, + SHalfedge_const_handle se1) {} + + void handle_support(SHalfedge_handle se, + SHalfloop_const_handle sl1) {} + + void handle_support(SHalfedge_handle se, + SHalfedge_const_handle se1, + SHalfloop_const_handle sl2) {} + + void handle_support(SHalfedge_handle se, + SHalfloop_const_handle sl1, + SHalfedge_const_handle se2) {} + + void handle_support(SHalfedge_handle se, + SHalfloop_const_handle sl1, + SHalfloop_const_handle sl2) {} +}; + +template +class ID_support_handler { + + typedef typename Decorator::SVertex_handle SVertex_handle; + typedef typename Decorator::SHalfedge_handle SHalfedge_handle; + + typedef typename Decorator::SVertex_const_handle SVertex_const_handle; + typedef typename Decorator::SHalfedge_const_handle SHalfedge_const_handle; + typedef typename Decorator::SHalfloop_const_handle SHalfloop_const_handle; + typedef typename Decorator::Halffacet_const_handle Halffacet_const_handle; + + typedef CGAL::Unique_hash_map F2E; + CGAL::Unique_hash_map f2m; + + public: + ID_support_handler() {} + + void hash_facet_pair(SVertex_handle sv, + Halffacet_const_handle f1, + Halffacet_const_handle f2) { + // std::cerr << "hash_facet_pair " << sv->point() << std::endl + // << " " << f1->plane() << &f1 << std::endl + // << " " << f2->plane() << &f2 << std::endl; + + if(f2m[f1][f2]==0) { + sv->set_index(); + f2m[f1][f2] = sv->get_index(); + // std::cerr << "insert " << sv->point() << &*sv + // << ": " << f2m[f1][f2] << std::endl; + // std::cerr << "not defined, yet" << std::endl; + } + else { + // std::cerr << "access " << sv->point() << &*sv << std::endl; + sv->set_index(f2m[f1][f2]); + // std::cerr << "combine " << sv->point() << "+" << f2e[f2]->point() << std::endl; + } + } + + void handle_support(SVertex_handle sv, + SHalfedge_const_handle se1, + SHalfedge_const_handle se2) { + // std::cerr << "handle support ee " << sv->point() << std::endl; + Halffacet_const_handle f1 = se1->facet(); + if(f1->is_twin()) f1 = f1->twin(); + Halffacet_const_handle f2 = se2->facet(); + if(f2->is_twin()) f2 = f2->twin(); + hash_facet_pair(sv, f1,f2); + } + + void handle_support(SVertex_handle sv, + SHalfloop_const_handle sl1, + SHalfloop_const_handle sl2) { + Halffacet_const_handle f1 = sl1->facet(); + if(f1->is_twin()) f1 = f1->twin(); + Halffacet_const_handle f2 = sl2->facet(); + if(f2->is_twin()) f2 = f2->twin(); + hash_facet_pair(sv, f1,f2); + } + + void handle_support(SVertex_handle sv, + SHalfloop_const_handle sl1, + SHalfedge_const_handle se2, + bool inverse_order = false) { + // std::cerr << "handle support el " << sv->point() << std::endl; + Halffacet_const_handle f1 = sl1->facet(); + if(f1->is_twin()) f1 = f1->twin(); + Halffacet_const_handle f2 = se2->facet(); + if(f2->is_twin()) f2 = f2->twin(); + if(inverse_order) + hash_facet_pair(sv, f2,f1); + else + hash_facet_pair(sv, f1,f2); + } + + void handle_support(SVertex_handle sv, + SHalfedge_const_handle se1, + SHalfloop_const_handle sl2) { + handle_support(sv,sl2,se1,true); + } + + void handle_support(SVertex_handle sv, + SHalfedge_const_handle se1, + SVertex_const_handle sv2) { + // std::cerr << "handle support ev " << sv->point() << std::endl; + sv->set_index(sv2->get_index()); + } + + void handle_support(SVertex_handle sv, + SVertex_const_handle sv1, + SHalfedge_const_handle se2) { + // std::cerr << "handle support ve " << sv->point() << std::endl; + handle_support(sv,se2,sv1); + } + + void handle_support(SVertex_handle sv, + SVertex_const_handle sv1, + SVertex_const_handle sv2) { + // std::cerr << "handle support vv " << sv->point() << std::endl; + // std::cerr << " supported by " << sv1->point() << std::endl; + // std::cerr << " supported by " << sv2->point() << std::endl; + if(sv1->get_index() < sv2->get_index()) + sv->set_index(sv1->get_index()); + else + sv->set_index(sv2->get_index()); + } + + void handle_support(SVertex_handle sv, + SVertex_const_handle sv0) { + // std::cerr << "handle support v " << sv->point() << std::endl; + sv->set_index(sv0->get_index()); + } + + void handle_support(SVertex_handle sv, + SVertex_const_handle sv1, + SHalfloop_const_handle sl2) { + // std::cerr << "handle support vl " << sv->point() << std::endl; + sv->set_index(sv1->get_index()); + } + + void handle_support(SVertex_handle sv, + SHalfloop_const_handle sl1, + SVertex_const_handle sv2) { + // std::cerr << "handle support lv " << sv->point() << std::endl; + handle_support(sv, sv2, sl1); + } + + void handle_support(SHalfedge_handle se, + SHalfedge_const_handle se1) { + CGAL_assertion(se->circle() == se1->circle()); + se->set_index(se1->get_index()); + se->twin()->set_index(se1->twin()->get_index()); + // std::cerr << "se " << se->source()->point() + // << "->" << se->twin()->source()->point() + // << "|" << se->circle() << std::endl; + // std::cerr << "se1 " << se1->get_index() << std::endl; + // std::cerr << "se1->twin() " << se1->twin()->get_index() << std::endl; + // std::cerr << "result " << se->get_index() + // << ", " << se->twin()->get_index() << std::endl; + } + + void handle_support(SHalfedge_handle se, + SHalfloop_const_handle sl1) { + CGAL_assertion(se->circle() == sl1->circle()); + se->set_index(sl1->get_index()); + se->twin()->set_index(sl1->twin()->get_index()); + // std::cerr << "se " << se->source()->point() + // << "->" << se->twin()->source()->point() + // << "|" << se->circle() << std::endl; + // std::cerr << "sl1 " << sl1->get_index() << std::endl; + // std::cerr << "sl1->twin() " << sl1->twin()->get_index() << std::endl; + // std::cerr << "result " << se->get_index() + // << ", " << se->twin()->get_index() << std::endl; + } + + int set_se_index(int index1, int index2, + bool v1, bool v2) { + if(v1) + if(v2) + return index1circle() == se1->circle()); + CGAL_assertion(se->circle() == se2->circle()); + // std::cerr << "se " << se->source()->point() + // << "->" << se->twin()->source()->point() + // << "|" << se->circle() << std::endl; + // std::cerr << vs1 << vs2 << vt1 << vt2 << std::endl; + // std::cerr << "se1 " << se1->get_index() << std::endl; + // std::cerr << "se2 " << se2->get_index() << std::endl; + // std::cerr << "se1->twin() " << se1->twin()->get_index() << std::endl; + // std::cerr << "se2->twin() " << se2->twin()->get_index() << std::endl; + /* + se->set_index(set_se_index(se1->get_index(), + se2->get_index(), + vs1, vs2)); + se->twin()->set_index(set_se_index(se1->twin()->get_index(), + se2->twin()->get_index(), + vt1, vt2)); + */ + if(se1->get_index()get_index()) { + // if(se1->get_index() < hash[se2->get_index()]) + // hash[se2->get_index()] = se1->get_index(); + se->set_index(se1->get_index()); + } else { + // if(se2->get_index() < hash[se1->get_index()]) + // hash[se1->get_index()] = se2->get_index(); + se->set_index(se2->get_index()); + } + if(se1->twin()->get_index()twin()->get_index()) { + // if(se1->twin()->get_index() < hash[se2->twin()->get_index()]) + // hash[se2->twin()->get_index()] = se1->twin()->get_index(); + se->twin()->set_index(se1->twin()->get_index()); + } else { + // if(se2->twin()->get_index() < hash[se1->twin()->get_index()]) + // hash[se1->twin()->get_index()] = se2->twin()->get_index(); + se->twin()->set_index(se2->twin()->get_index()); + } + // std::cerr << "result " << se->get_index() + // << ", " << se->twin()->get_index() << std::endl; + } + + void handle_support(SHalfedge_handle se, + SHalfedge_const_handle se1, + SHalfloop_const_handle sl2) { + CGAL_assertion(se->circle() == se1->circle()); + CGAL_assertion(se->circle() == sl2->circle()); + if(se1->get_index()get_index()) { + // if(se1->get_index() < hash[sl2->get_index()]) + // hash[sl2->get_index()] = se1->get_index(); + se->set_index(se1->get_index()); + } else { + // if(sl2->get_index() < hash[se1->get_index()]) + // hash[se1->get_index()] = sl2->get_index(); + se->set_index(sl2->get_index()); + } + if(se1->twin()->get_index()twin()->get_index()) { + // if(se1->twin()->get_index() < hash[sl2->twin()->get_index()]) + // hash[sl2->twin()->get_index()] = se1->twin()->get_index(); + se->twin()->set_index(se1->twin()->get_index()); + } else { + // if(sl2->twin()->get_index() < hash[se1->twin()->get_index()]) + // hash[se1->twin()->get_index()] = sl2->twin()->get_index(); + se->twin()->set_index(sl2->twin()->get_index()); + } + } + + void handle_support(SHalfedge_handle se, + SHalfloop_const_handle sl1, + SHalfedge_const_handle se2) { + handle_support(se,se2,sl1); + } + + void handle_support(SHalfedge_handle se, + SHalfloop_const_handle sl1, + SHalfloop_const_handle sl2) { + CGAL_assertion(se->circle() == sl1->circle()); + CGAL_assertion(se->circle() == sl2->circle()); + if(sl1->get_index()get_index()) { + // if(sl1->get_index() < hash[sl2->get_index()]) + // hash[sl2->get_index()] = sl1->get_index(); + se->set_index(sl1->get_index()); + } else { + // if(sl2->get_index() < hash[sl1->get_index()]) + // hash[sl1->get_index()] = sl2->get_index(); + se->set_index(sl2->get_index()); + } + if(sl1->twin()->get_index()< sl2->twin()->get_index()) { + // if(sl1->twin()->get_index() < hash[sl2->twin()->get_index()]) + // hash[sl2->twin()->get_index()] = sl1->twin()->get_index(); + se->twin()->set_index(sl1->twin()->get_index()); + } else { + // if(sl2->twin()->get_index() < hash[sl1->twin()->get_index()]) + // hash[sl1->twin()->get_index()] = sl2->twin()->get_index(); + se->twin()->set_index(sl2->twin()->get_index()); + } + } + + // int& hash_index(const int i) { return hash[i]; } +}; + +CGAL_END_NAMESPACE +#endif // CGAL_ID_SUPPORT_HANDLER diff --git a/Nef_3/include/CGAL/Nef_3/SFace.h b/Nef_3/include/CGAL/Nef_3/SFace.h new file mode 100644 index 00000000000..dcc1f6c0acf --- /dev/null +++ b/Nef_3/include/CGAL/Nef_3/SFace.h @@ -0,0 +1,133 @@ +// Copyright (c) 1997-2002 Max-Planck-Institute Saarbruecken (Germany). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you may redistribute it under +// the terms of the Q Public License version 1.0. +// See the file LICENSE.QPL distributed with CGAL. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL: svn+ssh://hachenb@scm.gforge.inria.fr/svn/cgal/branches/Filtered_Nef/Nef_3/include/CGAL/Nef_3/SFace.h $ +// $Id: SFace.h 35450 2006-12-06 10:43:20Z hachenb $ +// +// +// Author(s) : Michael Seel +// Miguel Granados +// Susan Hert +// Lutz Kettner +// Peter Hachenberger +#ifndef CGAL_NEF_SFACE_H +#define CGAL_NEF_SFACE_H + +#include +#include +#include +#include + +#undef CGAL_NEF_DEBUG +#define CGAL_NEF_DEBUG 83 +#include + +CGAL_BEGIN_NAMESPACE + +template +class SFace_base { + typedef void* GenPtr; + typedef typename Refs::Mark Mark; + typedef typename Refs::Vertex_handle Vertex_handle; + typedef typename Refs::Vertex_const_handle Vertex_const_handle; + typedef typename Refs::SFace_handle SFace_handle; + typedef typename Refs::SFace_const_handle SFace_const_handle; + typedef typename Refs::Volume_handle Volume_handle; + typedef typename Refs::Volume_const_handle Volume_const_handle; + typedef typename Refs::Object_list Object_list; + typedef typename Refs::SFace_cycle_iterator SFace_cycle_iterator; + typedef typename Refs::SFace_cycle_const_iterator + SFace_cycle_const_iterator; + Vertex_handle center_vertex_; + Volume_handle volume_; + // Object_list boundary_entry_objects_; // SEdges, SLoops, SVertices + GenPtr info_; + // temporary needed: + Mark mark_; + + public: + Object_list boundary_entry_objects_; // SEdges, SLoops, SVertices + + SFace_base() : center_vertex_(), volume_(), info_(), mark_() {} + + ~SFace_base() { + CGAL_NEF_TRACEN(" destroying SFace_base item "<<&*this); + } + + SFace_base(const SFace_base& f) + { center_vertex_ = f.center_vertex_; + volume_ = f.volume_; + boundary_entry_objects_ = f.boundary_entry_objects_; + info_ = 0; + mark_ = f.mark_; + } + + SFace_base& operator=(const SFace_base& f) + { if (this == &f) return *this; + center_vertex_ = f.center_vertex_; + volume_ = f.volume_; + boundary_entry_objects_ = f.boundary_entry_objects_; + info_ = 0; + mark_ = f.mark_; + return *this; + } + + SFace_cycle_iterator sface_cycles_begin() + { return boundary_entry_objects_.begin(); } + SFace_cycle_iterator sface_cycles_end() + { return boundary_entry_objects_.end(); } + SFace_cycle_const_iterator sface_cycles_begin() const + { return boundary_entry_objects_.begin(); } + SFace_cycle_const_iterator sface_cycles_end() const + { return boundary_entry_objects_.end(); } + + Mark& mark() { return mark_; } + const Mark& mark() const { return mark_; } + + Vertex_handle& center_vertex() { return center_vertex_; } + Vertex_const_handle center_vertex() const { return center_vertex_; } + + Volume_handle& volume() { return volume_; } + Volume_const_handle volume() const { return volume_; } + + Object_list& boundary_entry_objects() { return boundary_entry_objects_; } + const Object_list& boundary_entry_objects() const { return boundary_entry_objects_; } + + GenPtr& info() { return info_; } + const GenPtr& info() const { return info_; } + + bool is_valid( bool verb = false, int level = 0) const { + + Verbose_ostream verr(verb); + verr << "begin CGAL::SNC_items<...>::SFace_base::is_valid( verb=true, " + "level = " << level << "):" << std::endl; + + bool valid =(center_vertex_ != Vertex_handle() && center_vertex_ != NULL); + valid = valid && (volume_ != Volume_handle() && + volume_ != NULL); + + if(boundary_entry_objects_.empty()) { + valid = valid && + (center_vertex_->shalfedges_begin() == center_vertex_->shalfedges_end()); + } + verr << "end of CGAL::SNC_items<...>::SFace_base::is_valid(): structure is " + << ( valid ? "valid." : "NOT VALID.") << std::endl; + + return valid; + } + +}; // SFace_base + + +CGAL_END_NAMESPACE +#endif //CGAL_NEF_SFACE_H diff --git a/Nef_3/include/CGAL/Nef_3/SHalfedge.h b/Nef_3/include/CGAL/Nef_3/SHalfedge.h new file mode 100644 index 00000000000..85c66c4518f --- /dev/null +++ b/Nef_3/include/CGAL/Nef_3/SHalfedge.h @@ -0,0 +1,197 @@ +// Copyright (c) 1997-2002 Max-Planck-Institute Saarbruecken (Germany). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you may redistribute it under +// the terms of the Q Public License version 1.0. +// See the file LICENSE.QPL distributed with CGAL. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL: svn+ssh://hachenb@scm.gforge.inria.fr/svn/cgal/branches/Filtered_Nef/Nef_3/include/CGAL/Nef_3/SHalfedge.h $ +// $Id: SHalfedge.h 35450 2006-12-06 10:43:20Z hachenb $ +// +// +// Author(s) : Michael Seel +// Miguel Granados +// Susan Hert +// Lutz Kettner +// Peter Hachenberger +#ifndef CGAL_NEF_SHALFEDGE_H +#define CGAL_NEF_SHALFEDGE_H + +#include +#include +#include +#include + +#undef CGAL_NEF_DEBUG +#define CGAL_NEF_DEBUG 83 +#include + +CGAL_BEGIN_NAMESPACE + +template +class SHalfedge_base { + typedef void* GenPtr; + typedef typename Refs::Mark Mark; + typedef typename Refs::Sphere_circle Sphere_circle; + + typedef typename Refs::Halfedge_handle Halfedge_handle; + typedef typename Refs::Halfedge_const_handle Halfedge_const_handle; + typedef typename Refs::SVertex_handle SVertex_handle; + typedef typename Refs::SVertex_const_handle SVertex_const_handle; + typedef typename Refs::SHalfedge_handle SHalfedge_handle; + typedef typename Refs::SHalfedge_const_handle SHalfedge_const_handle; + typedef typename Refs::SFace_handle SFace_handle; + typedef typename Refs::SFace_const_handle SFace_const_handle; + typedef typename Refs::Halffacet_handle Halffacet_handle; + typedef typename Refs::Halffacet_const_handle Halffacet_const_handle; + + // Role within local graph: + SVertex_handle source_; + SHalfedge_handle sprev_, snext_; + SFace_handle incident_sface_; + SHalfedge_handle twin_; + // Topology within global Nef structure: + SHalfedge_handle prev_, next_; + Halffacet_handle facet_; + GenPtr info_; + // temporary needed: + Mark mark_; + Sphere_circle circle_; + + public: + + SHalfedge_base() : source_(), sprev_(), snext_(), + incident_sface_(), twin_(), + prev_(), next_(), facet_(), + info_(), mark_(), circle_() {} + + ~SHalfedge_base() { + CGAL_NEF_TRACEN(" destroying SHalfedge_base item "<<&*this); + } + + SHalfedge_base(const SHalfedge_base& e) + { + source_ = e.source_; + sprev_ = e.sprev_; + snext_ = e.snext_; + incident_sface_ = e.incident_sface_; + twin_ = e.twin_; + prev_ = e.prev_; + next_ = e.next_; + facet_ = e.facet_; + info_ = 0; + mark_ = e.mark_; + circle_ = e.circle_; + } + + SHalfedge_base& operator=(const SHalfedge_base& e) + { + source_ = e.source_; + sprev_ = e.sprev_; + snext_ = e.snext_; + incident_sface_ = e.incident_sface_; + twin_ = e.twin_; + prev_ = e.prev_; + next_ = e.next_; + facet_ = e.facet_; + info_ = 0; + mark_ = e.mark_; + circle_ = e.circle_; + return *this; + } + + Mark& mark() { return mark_; } + const Mark& mark() const { return mark_; } + + SHalfedge_handle& twin() { return twin_; } + SHalfedge_const_handle twin() const { return twin_; } + + SVertex_handle& source() { return source_; } + SVertex_const_handle source() const { return source_; } + + SVertex_handle& target() { return twin()->source(); } + SVertex_const_handle target() const { return twin()->source(); } + + SHalfedge_handle& prev() { return prev_; } + SHalfedge_const_handle prev() const { return prev_; } + + SHalfedge_handle& next() { return next_; } + SHalfedge_const_handle next() const { return next_; } + + SHalfedge_handle& sprev() { return sprev_; } + SHalfedge_const_handle sprev() const { return sprev_; } + + SHalfedge_handle& snext() { return snext_; } + SHalfedge_const_handle snext() const { return snext_; } + + SHalfedge_handle& cyclic_adj_succ() + { return sprev()->twin(); } + SHalfedge_const_handle cyclic_adj_succ() const + { return sprev()->twin(); } + + SHalfedge_handle& cyclic_adj_pred(SHalfedge_const_handle e) + { return e->twin()->snext(); } + SHalfedge_const_handle cyclic_adj_pred(SHalfedge_const_handle e) const + { return e->twin()->snext(); } + + Sphere_circle& circle() { return circle_; } + const Sphere_circle& circle() const { return circle_; } + + SFace_handle& incident_sface() { return incident_sface_; } + SFace_const_handle incident_sface() const { return incident_sface_; } + + Halffacet_handle& facet() { return facet_; } + Halffacet_const_handle facet() const { return facet_; } + + GenPtr& info() { return info_; } + const GenPtr& info() const { return info_; } + + public: + std::string debug() const + { std::stringstream os; + set_pretty_mode(os); + os <<"e[ "<debug()<<", " + <source_->debug()<<" "<::SHalfedge_base::is_valid( verb=true, " + "level = " << level << "):" << std::endl; + + bool valid = (source_ != SVertex_handle() && + source_ != NULL && + source_ != Halfedge_handle()); + valid = valid && (twin_ != SHalfedge_handle() && twin_ != NULL); + valid = valid && (sprev_ != SHalfedge_handle() && sprev_ != NULL); + valid = valid && (snext_ != SHalfedge_handle() && snext_ != NULL); + valid = valid && (prev_ != SHalfedge_handle() && prev_ != NULL); + valid = valid && (next_ != SHalfedge_handle() && next_ != NULL); + + valid = valid && (incident_sface_ != SFace_handle() && + incident_sface_ != NULL); + valid = valid && (facet_ != Halffacet_handle() && + facet_ != NULL); + valid = valid && (circle_.d() == 0); + valid = valid && (circle_.a() != 0 || circle_.b() != 0 || circle_.c() !=0); + + verr << "end of CGAL::SNC_items<...>::SHalfedge_base::is_valid(): structure is " + << ( valid ? "valid." : "NOT VALID.") << std::endl; + + return valid; + } + +}; // SHalfedge_base + +CGAL_END_NAMESPACE +#endif //CGAL_NEF_SHALFEDGE_H diff --git a/Nef_3/include/CGAL/Nef_3/SHalfloop.h b/Nef_3/include/CGAL/Nef_3/SHalfloop.h new file mode 100644 index 00000000000..1c4e3f180a2 --- /dev/null +++ b/Nef_3/include/CGAL/Nef_3/SHalfloop.h @@ -0,0 +1,135 @@ +// Copyright (c) 1997-2002 Max-Planck-Institute Saarbruecken (Germany). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you may redistribute it under +// the terms of the Q Public License version 1.0. +// See the file LICENSE.QPL distributed with CGAL. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL: svn+ssh://hachenb@scm.gforge.inria.fr/svn/cgal/branches/Filtered_Nef/Nef_3/include/CGAL/Nef_3/SHalfloop.h $ +// $Id: SHalfloop.h 35450 2006-12-06 10:43:20Z hachenb $ +// +// +// Author(s) : Michael Seel +// Miguel Granados +// Susan Hert +// Lutz Kettner +// Peter Hachenberger +#ifndef CGAL_NEF_SHALFLOOP_H +#define CGAL_NEF_SHALFLOOP_H + +#include +#include +#include +#include + +#undef CGAL_NEF_DEBUG +#define CGAL_NEF_DEBUG 83 +#include + +CGAL_BEGIN_NAMESPACE + +template +class SHalfloop_base { + typedef void* GenPtr; + typedef typename Refs::Mark Mark; + typedef typename Refs::Sphere_circle Sphere_circle; + typedef typename Refs::SHalfloop_handle SHalfloop_handle; + typedef typename Refs::SHalfloop_const_handle SHalfloop_const_handle; + typedef typename Refs::SFace_handle SFace_handle; + typedef typename Refs::SFace_const_handle SFace_const_handle; + typedef typename Refs::Halffacet_handle Halffacet_handle; + typedef typename Refs::Halffacet_const_handle Halffacet_const_handle; + + SHalfloop_handle twin_; + SFace_handle incident_sface_; + Halffacet_handle facet_; + GenPtr info_; + // temporary needed: + Mark mark_; + Sphere_circle circle_; + + public: + + SHalfloop_base() : twin_(), incident_sface_(), facet_(), + info_(), mark_(), circle_() {} + + ~SHalfloop_base() { + CGAL_NEF_TRACEN(" destroying SHalfloop_base item "<<&*this); + } + SHalfloop_base(const SHalfloop_base& l) + { twin_ = l.twin_; + incident_sface_ = l.incident_sface_; + facet_ = l.facet_; + info_ = 0; + mark_ = l.mark_; + circle_ = l.circle_; + } + + SHalfloop_base& operator=(const SHalfloop_base& l) + { twin_ = l.twin_; + incident_sface_ = l.incident_sface_; + facet_ = l.facet_; + info_ = 0; + mark_ = l.mark_; + circle_ = l.circle_; + return *this; + } + + Mark& mark() { return mark_;} + const Mark& mark() const { return mark_; } + + SHalfloop_handle& twin() { return twin_; } + SHalfloop_const_handle twin() const { return twin_; } + + Sphere_circle& circle() { return circle_; } + const Sphere_circle& circle() const { return circle_; } + + SFace_handle& incident_sface() { return incident_sface_; } + SFace_const_handle incident_sface() const { return incident_sface_; } + + Halffacet_handle& facet() { return facet_; } + Halffacet_const_handle facet() const { return facet_; } + + GenPtr& info() { return info_; } + const GenPtr& info() const { return info_; } + + public: + std::string debug() const + { std::stringstream os; + set_pretty_mode(os); + os<<"sl [ "<::SHalfloop_base::is_valid( verb=true, " + "level = " << level << "):" << std::endl; + + bool valid = (twin_ != SHalfloop_handle() && twin_ != NULL); + valid = valid && (incident_sface_ != SFace_handle() && + incident_sface_ != NULL); + valid = valid && (facet_ != Halffacet_handle() && + facet_ != NULL); + valid = valid && (circle_.d() == 0); + valid = valid && (circle_.a() != 0 || circle_.b() != 0 || circle_.c() !=0); + + verr << "end of CGAL::SNC_items<...>::SHalfloop_base::is_valid(): structure is " + << ( valid ? "valid." : "NOT VALID.") << std::endl; + + return valid; + } + +}; // SHalfloop_base + +CGAL_END_NAMESPACE +#endif //CGAL_NEF_SHALFLOOP_H diff --git a/Nef_3/include/CGAL/Nef_3/SNC_external_structure.h b/Nef_3/include/CGAL/Nef_3/SNC_external_structure.h new file mode 100644 index 00000000000..e2498d9b488 --- /dev/null +++ b/Nef_3/include/CGAL/Nef_3/SNC_external_structure.h @@ -0,0 +1,1315 @@ +// Copyright (c) 1997-2002 Max-Planck-Institute Saarbruecken (Germany). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you may redistribute it under +// the terms of the Q Public License version 1.0. +// See the file LICENSE.QPL distributed with CGAL. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL: svn+ssh://hachenb@scm.gforge.inria.fr/svn/cgal/branches/Filtered_Nef/Nef_3/include/CGAL/Nef_3/SNC_external_structure.h $ +// $Id: SNC_external_structure.h 36279 2007-02-15 10:29:45Z hachenb $ +// +// +// Author(s) : Michael Seel +// Miguel Granados +// Susan Hert +// Lutz Kettner +// Peter Hachenberger +#ifndef CGAL_SNC_EXTERNAL_STRUCTURE_H +#define CGAL_SNC_EXTERNAL_STRUCTURE_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#undef CGAL_NEF_DEBUG +#define CGAL_NEF_DEBUG 43 +#include + +CGAL_BEGIN_NAMESPACE + +struct int_lt { + bool operator()(const int& i1, const int& i2) const { return i1 +struct Halfedge_key_lt4 { + + bool operator()(const Edge_handle& e1, const Edge_handle& e2) const { + if(CGAL::sign(e1->point().x()) != 0) + if(e1->source() != e2->source()) + return CGAL::compare_x(e1->source()->point(), e2->source()->point()) < 0; + else + return e1->point().x() < 0; + if(CGAL::sign(e1->point().y()) != 0) + if(e1->source() != e2->source()) + return CGAL::compare_y(e1->source()->point(), e2->source()->point()) < 0; + else + return e1->point().y() < 0; + if(e1->source() != e2->source()) + return CGAL::compare_z(e1->source()->point(), e2->source()->point()) < 0; + return e1->point().z() < 0; + } +}; + +template +struct Halfedge_key_lt3 { + + bool operator()(const Edge_handle& e1, const Edge_handle& e2) const { + if(e1->source() != e2->source()) + return CGAL::lexicographically_xyz_smaller(e1->source()->point(), e2->source()->point()); + if(CGAL::sign(e1->point().x()) != 0) + return e1->point().x() < 0; + if(CGAL::sign(e1->point().y()) != 0) + return e1->point().y() < 0; + return e1->point().z() < 0; + } +}; + +template +struct Halfedge_key { + typedef Halfedge_key Self; + Point p; int i; Edge e; + Decorator& D; + Halfedge_key(Point pi, int ii, Edge ei, Decorator& Di ) : + p(pi), i(ii), e(ei), D(Di) {} + Halfedge_key(const Self& k) : p(k.p), i(k.i), e(k.e), D(k.D) {} + Self& operator=(const Self& k) { p=k.p; i=k.i; e=k.e; return *this; } + bool operator==(const Self& k) const { return p==k.p && i==k.i; } + bool operator!=(const Self& k) const { return !operator==(k); } +}; + +template +struct Halfedge_key_lt { + typedef Halfedge_key Key; + typedef typename Point::R R; + typedef typename R::Vector_3 Vector; + typedef typename R::Direction_3 Direction; + bool operator()( const Key& k1, const Key& k2) const { + if( k1.e->source() == k2.e->source()) + return (k1.i < k2.i); + Direction l(k1.e->vector()); + if( k1.i < 0) l = -l; + return (Direction( k2.p - k1.p) == l); + } +}; + +template +std::ostream& operator<<(std::ostream& os, + const Halfedge_key& k ) +{ os << k.p << " " << k.i; return os; } + +template +int sign_of(const CGAL::Plane_3& h) +{ if ( h.c() != 0 ) return CGAL_NTS sign(h.c()); + if ( h.b() != 0 ) return CGAL_NTS sign(-h.b()); + return CGAL_NTS sign(h.a()); +} + +struct Plane_lt { + template + bool operator()(const CGAL::Plane_3& h1, + const CGAL::Plane_3& h2) const + { + typedef typename R::RT RT; + RT diff = h1.a()-h2.a(); + if ( (diff) != 0 ) return CGAL_NTS sign(diff) < 0; + diff = h1.b()-h2.b(); + if ( (diff) != 0 ) return CGAL_NTS sign(diff) < 0; + diff = h1.c()-h2.c(); + if ( (diff) != 0 ) return CGAL_NTS sign(diff) < 0; + diff = h1.d()-h2.d(); return CGAL_NTS sign(diff) < 0; + } +}; + +struct Plane_RT_lt { + template + bool operator()(const CGAL::Plane_3& h1, + const CGAL::Plane_3& h2) const + { return (&(h1.a())) < (&(h2.a())); } +}; + +// ---------------------------------------------------------------------------- +// SNC_external_structure +// ---------------------------------------------------------------------------- + +template +class SNC_external_structure : public SNC_decorator +{ +public: + typedef SNC_structure_ SNC_structure; + + typedef typename SNC_structure::Infi_box Infi_box; + typedef typename Infi_box::Standard_kernel Standard_kernel; + typedef typename Standard_kernel::Point_3 Standard_point_3; + typedef typename Infi_box::NT NT; + + typedef CGAL::SNC_decorator SNC_decorator; + typedef CGAL::SNC_point_locator SNC_point_locator; + typedef CGAL::SNC_FM_decorator FM_decorator; + typedef CGAL::SNC_simplify SNC_simplify; + + typedef typename SNC_structure::Sphere_map Sphere_map; + typedef CGAL::SM_decorator SM_decorator; + typedef CGAL::SM_const_decorator SM_const_decorator; + typedef CGAL::SM_point_locator SM_point_locator; + + typedef typename SNC_structure::Halfedge_iterator Halfedge_iterator; + typedef typename SNC_structure::Halffacet_iterator Halffacet_iterator; + typedef typename SNC_structure::Volume_iterator Volume_iterator; + + typedef typename SNC_structure::Vertex_handle Vertex_handle; + typedef typename SNC_structure::Halfedge_handle Halfedge_handle; + typedef typename SNC_structure::Halffacet_handle Halffacet_handle; + typedef typename SNC_structure::Volume_handle Volume_handle; + + typedef typename SNC_structure::Halffacet_const_handle Halffacet_const_handle; + typedef typename SNC_structure::SFace_const_handle SFace_const_handle; + + typedef typename SNC_structure::SHalfedge_iterator SHalfedge_iterator; + typedef typename SNC_structure::SFace_iterator SFace_iterator; + typedef typename SNC_structure::SHalfloop_iterator SHalfloop_iterator; + + typedef typename SNC_structure::SVertex_handle SVertex_handle; + typedef typename SNC_structure::SHalfedge_handle SHalfedge_handle; + typedef typename SNC_structure::SFace_handle SFace_handle; + typedef typename SNC_structure::SHalfloop_handle SHalfloop_handle; + + typedef typename SNC_structure::Object_handle Object_handle; + + typedef typename SNC_structure::SHalfedge_around_facet_circulator + SHalfedge_around_facet_circulator; + + typedef typename SNC_structure::Point_3 Point_3; + typedef typename SNC_structure::Direction_3 Direction_3; + typedef typename SNC_structure::Plane_3 Plane_3; + typedef typename SNC_structure::Ray_3 Ray_3; + + typedef typename SNC_structure::Sphere_point Sphere_point; + typedef typename SNC_structure::Sphere_circle Sphere_circle; + + typedef typename SM_decorator::SHalfedge_around_svertex_circulator + SHalfedge_around_svertex_circulator; + + SNC_point_locator* pl; + + typedef CGAL::Unique_hash_map + Sface_shell_hash; + typedef CGAL::Unique_hash_map + Face_shell_hash; + typedef CGAL::Unique_hash_map SFace_visited_hash; + typedef CGAL::Unique_hash_map Shell_closed_hash; + + struct Shell_explorer { + const SNC_decorator& D; + Sface_shell_hash& ShellSf; + Face_shell_hash& ShellF; + // Shell_closed_hash& Closed; + SFace_visited_hash& Done; + SFace_handle sf_min; + int n; + + Shell_explorer(const SNC_decorator& Di, Sface_shell_hash& SSf, + Face_shell_hash& SF, SFace_visited_hash& Vi) + : D(Di), ShellSf(SSf), ShellF(SF), Done(Vi), n(0) {} + + void visit(SFace_handle h) { + CGAL_NEF_TRACEN("visit sf "<center_vertex()->point()); + ShellSf[h]=n; + Done[h]=true; + if ( CGAL::lexicographically_xyz_smaller(h->center_vertex()->point(), + sf_min->center_vertex()->point())) + sf_min = h; + } + + void visit(Vertex_handle h) { + CGAL_NEF_TRACEN("visit v "<point()); + } + + void visit(Halfedge_handle h) { + CGAL_NEF_TRACEN("visit he "<< h->source()->point()); + } + + void visit(Halffacet_handle h) { + CGAL_NEF_TRACEN(h->plane()); + ShellF[h]=n; + } + + void visit(SHalfedge_handle se) {} + void visit(SHalfloop_handle sl) {} + + SFace_handle& minimal_sface() { return sf_min; } + + void increment_shell_number() { + CGAL_NEF_TRACEN("leaving shell "<>>>>pair_up_halfedges"); + typedef Halfedge_key_lt3 + Halfedge_key_lt; + typedef std::list Halfedge_list; + + typedef typename Standard_kernel::Kernel_tag Kernel_tag; + typedef CGAL::Pluecker_line_3 Pluecker_line_3; + typedef CGAL::Pluecker_line_lt Pluecker_line_lt; + typedef std::map< Pluecker_line_3, Halfedge_list, Pluecker_line_lt> + Pluecker_line_map; + + Pluecker_line_map M; + Pluecker_line_map M2; + Pluecker_line_map M3; + Pluecker_line_map M4; + + NT eval(Infi_box::compute_evaluation_constant_for_halfedge_pairup(*this->sncp()));; + + Halfedge_iterator e; + CGAL_forall_halfedges(e,*this->sncp()) { + // progress++; + Point_3 p = e->source()->point(); + Point_3 q = p + e->vector(); + CGAL_NEF_TRACE(" segment("<vector()<<")"); + Standard_point_3 sp = Infi_box::standard_point(p,eval); + Standard_point_3 sq = Infi_box::standard_point(q,eval); + Pluecker_line_3 l( sp, sq); + + int inverted; + l = categorize( l, inverted); + + if(Infi_box::is_edge_on_infibox(e)) + if(Infi_box::is_type4(e)) + M4[l].push_back(e); + else + if(Infi_box::is_type3(e)) + M3[l].push_back(e); + else + M2[l].push_back(e); + else + M[l].push_back(e); + + // the following trace crashes when compiling with optimizations (-O{n}) + //CGAL_NEF_TRACEN(Infi_box::standard_point(point(vertex(e)))+ + + CGAL_NEF_TRACEN(" line("<first); + typename Halfedge_list::iterator itl; + CGAL_forall_iterators(itl,it->second) { + Halfedge_handle e1 = *itl; + ++itl; + CGAL_assertion(itl != it->second.end()); + Halfedge_handle e2 = *itl; + while(normalized(e1->vector()) != normalized(-e2->vector())) { + ++itl; + make_twins(e1,*itl); + e1 = e2; + ++itl; + e2 = *itl; + } + CGAL_NEF_TRACEN(" " << e1->source()->point() + << " -> " << e2->source()->point()); + CGAL_NEF_TRACEN(e1->vector()<<" -> "<<-e2->vector()); + // CGAL_assertion(normalized(e1->vector())==normalized(-e2->vector())); + make_twins(e1,e2); + CGAL_assertion(e1->mark()==e2->mark()); + + // discard temporary sphere_point ? + } + } + + CGAL_forall_iterators(it,M3) { + // progress++; + it->second.sort(Halfedge_key_lt()); + CGAL_NEF_TRACEN("search opposite "<first); + typename Halfedge_list::iterator itl; + CGAL_forall_iterators(itl,it->second) { + Halfedge_handle e1 = *itl; + ++itl; + CGAL_assertion(itl != it->second.end()); + Halfedge_handle e2 = *itl; + while(normalized(e1->vector()) != normalized(-e2->vector())) { + ++itl; + make_twins(e1,*itl); + e1 = e2; + ++itl; + e2 = *itl; + } + CGAL_NEF_TRACEN(" " << e1->source()->point() + << " -> " << e2->source()->point()); + CGAL_NEF_TRACEN(e1->vector()<<" -> "<<-e2->vector()); + // CGAL_assertion(normalized(e1->vector())==normalized(-e2->vector())); + make_twins(e1,e2); + CGAL_assertion(e1->mark()==e2->mark()); + + // discard temporary sphere_point ? + } + } + + CGAL_forall_iterators(it,M2) { + // progress++; + it->second.sort(Halfedge_key_lt()); + CGAL_NEF_TRACEN("search opposite "<first); + typename Halfedge_list::iterator itl; + CGAL_forall_iterators(itl,it->second) { + Halfedge_handle e1 = *itl; + ++itl; + CGAL_assertion(itl != it->second.end()); + Halfedge_handle e2 = *itl; + while(normalized(e1->vector()) != normalized(-e2->vector())) { + ++itl; + make_twins(e1,*itl); + e1 = e2; + ++itl; + e2 = *itl; + } + CGAL_NEF_TRACEN(" " << e1->source()->point() + << " -> " << e2->source()->point()); + CGAL_NEF_TRACEN(e1->vector()<<" -> "<<-e2->vector()); + // CGAL_assertion(normalized(e1->vector())==normalized(-e2->vector())); + make_twins(e1,e2); + CGAL_assertion(e1->mark()==e2->mark()); + + // discard temporary sphere_point ? + } + } + + CGAL_forall_iterators(it,M) { + // progress++; + it->second.sort(Halfedge_key_lt()); + CGAL_NEF_TRACEN("search opposite "<first); + typename Halfedge_list::iterator itl; + CGAL_forall_iterators(itl,it->second) { + Halfedge_handle e1 = *itl; + ++itl; + CGAL_assertion(itl != it->second.end()); + Halfedge_handle e2 = *itl; + while(normalized(e1->vector()) != normalized(-e2->vector())) { + ++itl; + make_twins(e1,*itl); + e1 = e2; + ++itl; + e2 = *itl; + } + CGAL_NEF_TRACEN(" " << e1->source()->point() + << " -> " << e2->source()->point()); + CGAL_NEF_TRACEN(e1->vector()<<" -> "<<-e2->vector()); + // CGAL_assertion(normalized(e1->vector())==normalized(-e2->vector())); + make_twins(e1,e2); + CGAL_assertion(e1->mark()==e2->mark()); + + // discard temporary sphere_point ? + } + } + + } +#else + void pair_up_halfedges() const { + /*{\Mop pairs all halfedge stubs to create the edges in 3-space.}*/ + +// CGAL_NEF_SETDTHREAD(43*61); + CGAL_NEF_TRACEN(">>>>>pair_up_halfedges"); + typedef Halfedge_key< Point_3, Halfedge_handle, SNC_decorator> + Halfedge_key; + typedef Halfedge_key_lt< Point_3, Halfedge_handle, SNC_decorator> + Halfedge_key_lt; + typedef std::list Halfedge_list; + + typedef typename Standard_kernel::Kernel_tag Kernel_tag; + typedef CGAL::Pluecker_line_3 Pluecker_line_3; + typedef CGAL::Pluecker_line_lt Pluecker_line_lt; + typedef std::map< Pluecker_line_3, Halfedge_list, Pluecker_line_lt> + Pluecker_line_map; + + SNC_decorator D(*this); + Pluecker_line_map M; + Pluecker_line_map M2; + Pluecker_line_map M3; + Pluecker_line_map M4; + + NT eval(Infi_box::compute_evaluation_constant_for_halfedge_pairup(*this->sncp()));; + + Halfedge_iterator e; + CGAL_forall_halfedges(e,*this->sncp()) { + // progress++; + Point_3 p = e->source()->point(); + Point_3 q = p + e->vector(); + CGAL_NEF_TRACE(" segment("<vector()<<")"); + Standard_point_3 sp = Infi_box::standard_point(p,eval); + Standard_point_3 sq = Infi_box::standard_point(q,eval); + Pluecker_line_3 l( sp, sq); + + int inverted; + l = categorize( l, inverted); + + if(Infi_box::is_edge_on_infibox(e)) + if(Infi_box::is_type4(e)) + M4[l].push_back(Halfedge_key(p,inverted,e, D)); + else + if(Infi_box::is_type3(e)) + M3[l].push_back(Halfedge_key(p,inverted,e, D)); + else + M2[l].push_back(Halfedge_key(p,inverted,e, D)); + else + M[l].push_back(Halfedge_key(p,inverted,e,D)); + + // the following trace crashes when compiling with optimizations (-O{n}) + //CGAL_NEF_TRACEN(Infi_box::standard_point(point(vertex(e)))+ + + CGAL_NEF_TRACEN(" line("<first); + typename Halfedge_list::iterator itl; + CGAL_forall_iterators(itl,it->second) { + Halfedge_handle e1 = itl->e; + ++itl; + CGAL_assertion(itl != it->second.end()); + Halfedge_handle e2 = itl->e; + CGAL_NEF_TRACEN(" " << e1->source()->point() + << " -> " << e2->source()->point()); + CGAL_NEF_TRACEN(e1->vector()<<" -> "<<-e2->vector()); + // CGAL_assertion(normalized(e1->vector())==normalized(-e2->vector())); + make_twins(e1,e2); + CGAL_assertion(e1->mark()==e2->mark()); + + // discard temporary sphere_point ? + } + } + + CGAL_forall_iterators(it,M3) { + // progress++; + it->second.sort(Halfedge_key_lt()); + CGAL_NEF_TRACEN("search opposite "<first); + typename Halfedge_list::iterator itl; + CGAL_forall_iterators(itl,it->second) { + Halfedge_handle e1 = itl->e; + ++itl; + CGAL_assertion(itl != it->second.end()); + Halfedge_handle e2 = itl->e; + CGAL_NEF_TRACEN(" " << e1->source()->point() + << " -> " << e2->source()->point()); + CGAL_NEF_TRACEN(e1->vector()<<" -> "<<-e2->vector()); + // CGAL_assertion(normalized(e1->vector())==normalized(-e2->vector())); + make_twins(e1,e2); + CGAL_assertion(e1->mark()==e2->mark()); + + // discard temporary sphere_point ? + } + } + + CGAL_forall_iterators(it,M2) { + // progress++; + it->second.sort(Halfedge_key_lt()); + CGAL_NEF_TRACEN("search opposite "<first); + typename Halfedge_list::iterator itl; + CGAL_forall_iterators(itl,it->second) { + Halfedge_handle e1 = itl->e; + ++itl; + CGAL_assertion(itl != it->second.end()); + Halfedge_handle e2 = itl->e; + CGAL_NEF_TRACEN(" " << e1->source()->point() + << " -> " << e2->source()->point()); + CGAL_NEF_TRACEN(e1->vector()<<" -> "<<-e2->vector()); + // CGAL_assertion(normalized(e1->vector())==normalized(-e2->vector())); + make_twins(e1,e2); + CGAL_assertion(e1->mark()==e2->mark()); + + // discard temporary sphere_point ? + } + } + + CGAL_forall_iterators(it,M) { + // progress++; + it->second.sort(Halfedge_key_lt()); + CGAL_NEF_TRACEN("search opposite "<first); + typename Halfedge_list::iterator itl; + CGAL_forall_iterators(itl,it->second) { + Halfedge_handle e1 = itl->e; + ++itl; + CGAL_assertion(itl != it->second.end()); + Halfedge_handle e2 = itl->e; + CGAL_NEF_TRACEN(" " << e1->source()->point() + << " -> " << e2->source()->point()); + CGAL_NEF_TRACEN(e1->vector()<<" -> "<< -e2->vector()); + // CGAL_assertion(normalized(e1->vector())==normalized(-e2->vector())); + CGAL_assertion(e1->source()->point() != e2->source()->point()); + CGAL_assertion(e1->mark()==e2->mark()); + make_twins(e1,e2); + + // discard temporary sphere_point ? + } + } + } +#endif + + void link_shalfedges_to_facet_cycles() const { + /*{\Mop creates all non-trivial facet cycles from sedges. + \precond |pair_up_halfedges()| was called before.}*/ + + // CGAL_NEF_SETDTHREAD(43*31); + CGAL_NEF_TRACEN(">>>>>link_shalfedges_to_facet_cycles"); + +#ifdef CGAL_NEF_EXPLOIT_REFERENCE_COUNTING + Point_3 p1(1,2,7), p2(p1); + bool reference_counted = (&(p1.hx()) == &(p2.hx())); +#endif + + Halfedge_iterator e; + CGAL_forall_edges(e,*this->sncp()) { + // progress++; + CGAL_NEF_TRACEN(""); + CGAL_NEF_TRACEN(PH(e)); + Halfedge_iterator et = e->twin(); + SM_decorator D(&*e->source()), Dt(&*et->source()); + CGAL_NEF_TRACEN(e->source()->point()); + if ( D.is_isolated(e) ) continue; + SHalfedge_around_svertex_circulator ce(D.first_out_edge(e)),cee(ce); + SHalfedge_around_svertex_circulator cet(Dt.first_out_edge(et)),cete(cet); + +#ifdef CGAL_NEF_EXPLOIT_REFERENCE_COUNTING + if(reference_counted) { + CGAL_For_all(cet,cete) + if ( &(cet->circle().a()) == &(ce->circle().opposite().a()) && + cet->source()->twin() == ce->source() ) + break; + } else +#endif + CGAL_For_all(cet,cete) + if ( cet->circle() == ce->circle().opposite() && + cet->source()->twin() == ce->source() ) + break; + + /* + // DEBUG + CGAL_NEF_SETDTHREAD(43); + if( cet->circle() != ce->circle().opposite() ) + CGAL_NEF_TRACEN("assertion failed!"); + + CGAL_NEF_TRACEN("vertices " << e->source()->point() << + " " << et->source()->point()); + + + SHalfedge_around_svertex_circulator sc(D.first_out_edge(e)); + SHalfedge_around_svertex_circulator sct(Dt.first_out_edge(et)); + + CGAL_NEF_TRACEN(""); + CGAL_For_all(sc,cee) + CGAL_NEF_TRACEN("sseg@E addr="<<&*sc<< + " src="<< sc->source()->point()<< + " tgt="<< sc->target()->point()<circle()) == normalized(ce->circle().opposite()) ); + CGAL_assertion( cet->source()->twin() == ce->source()); + CGAL_For_all(ce,cee) { + CGAL_NEF_TRACEN("circles " << cet->circle() << " " << ce->circle() << + " sources " << cet->target()->point() << + " " << ce->target()->point()); + CGAL_assertion( normalized(cet->circle()) == normalized(ce->circle().opposite())); + CGAL_assertion( cet->source()->twin() == ce->source()); + CGAL_assertion(ce->mark()==cet->mark()); + link_as_prev_next_pair(cet->twin(),ce); + link_as_prev_next_pair(ce->twin(),cet); + --cet; // ce moves ccw, cet moves cw + } + } + } + + void categorize_facet_cycles_and_create_facets() const { + /*{\Mop collects all facet cycles incident to a facet and creates + the facets. \precond |link_shalfedges_to_facet_cycles()| was called + before.}*/ + + // CGAL_NEF_SETDTHREAD(43*31); + CGAL_NEF_TRACEN(">>>>>categorize_facet_cycles_and_create_facets"); + + typedef std::list Object_list; +#ifdef CGAL_NEF_EXPLOIT_REFERENCE_COUNTING + typedef std::map + Map_planes; +#else + typedef std::map + Map_planes; +#endif + + Map_planes M; + SHalfedge_iterator e; + CGAL_forall_shalfedges(e,*this->sncp()) { + Sphere_circle c(e->circle()); + Plane_3 h = c.plane_through(e->source()->source()->point()); + CGAL_NEF_TRACEN("\n" << e->source()->twin()->source()->point() <<" - " + << e->source()->source()->point() <<" - "<< + e->twin()->source()->twin()->source()->point() << + " has plane " << h << " has circle " << e->circle() << + " has signum " << sign_of(h)); + if ( sign_of(h)<0 ) continue; + M[normalized(h)].push_back(Object_handle(e->twin())); + CGAL_NEF_TRACEN(" normalized as " << normalized(h)); + } + SHalfloop_iterator l; + CGAL_forall_shalfloops(l,*this->sncp()) { + Sphere_circle c(l->circle()); + Plane_3 h = c.plane_through(l->incident_sface()->center_vertex()->point()); + if ( sign_of(h)<0 ) continue; + // CGAL_assertion( h == normalized(h)); + M[normalized(h)].push_back(Object_handle(l->twin())); + } + +#ifdef CGAL_NEF3_TIMER_PLANE_SWEEPS + number_of_plane_sweeps=0; + timer_plane_sweeps.reset(); +#endif + + typename Map_planes::iterator it; + CGAL_forall_iterators(it,M) { + // progress2++; + // CGAL_NEF_TRACEN(" plane "<first<<" "<<(it->first).point()); + FM_decorator D(*this->sncp()); + D.create_facet_objects(it->first,it->second.begin(),it->second.end()); + } + // CGAL_NEF_SETDTHREAD(1); + } + + void create_volumes() { + /*{\Mop collects all shells incident to a volume and creates the + volumes. \precond |categorize_facet_cycles_and_creating_facets()| was + called before.}*/ + +#ifdef CGAL_NEF3_TIMER_POINT_LOCATION + number_of_ray_shooting_queries=0; + timer_ray_shooting.reset(); +#endif + + // CGAL_NEF_SETDTHREAD(37*43*503*509); + + CGAL_NEF_TRACEN(">>>>>create_volumes"); + Sface_shell_hash ShellSf(0); + Face_shell_hash ShellF(0); + SFace_visited_hash Done(false); + Shell_explorer V(*this,ShellSf,ShellF,Done); + std::vector MinimalSFace; + std::vector EntrySFace; + std::vector Closed; + + SFace_iterator f; + // First, we classify all the Shere Faces per Shell. For each Shell we + // determine its minimum lexicographyly vertex and we check wheter the + // Shell encloses a region (closed surface) or not. + CGAL_forall_sfaces(f,*this->sncp()) { + // progress++; + CGAL_NEF_TRACEN("sface in " << ShellSf[f]); + if ( Done[f] ) + continue; + V.minimal_sface() = f; + visit_shell_objects(f,V); + + CGAL_NEF_TRACEN("minimal vertex " << V.minimal_sface()->center_vertex()->point()); + + MinimalSFace.push_back(V.minimal_sface()); + EntrySFace.push_back(f); + V.increment_shell_number(); + CGAL_NEF_TRACEN("sface out " << ShellSf[f]); + } + + for(unsigned int i=0; itwin()]) { + Closed[ShellF[hf]] = true; + Closed[ShellF[hf->twin()]] = true; + } + + CGAL_assertion( pl != NULL); + +#ifdef CGAL_NEF3_TIMER_INITIALIZE_KDTREE + CGAL::Timer timer_initialize_kdtree; + timer_initialize_kdtree.start(); +#endif + pl->initialize(this->sncp()); // construct the point locator +#ifdef CGAL_NEF3_TIMER_INITIALIZE_KDTREE + timer_initialize_kdtree.stop(); + if(cgal_nef3_timer_on) + std::cout << "Runtime_initialize_kdtree: " + << timer_initialize_kdtree.time() << std::endl; +#endif + + // then, we determine the Shells which correspond to Volumes via a ray + // shootting in the direction (-1,0,0) over the Sphere_map of the minimal + // vertex. The Shell corresponds to a Volume if the object hit belongs + // to another Shell. + + this->sncp()->new_volume(); // outermost volume (nirvana) + if(MinimalSFace.size() == 0) return; + Vertex_handle v_min = MinimalSFace[0]->center_vertex(); + for( unsigned int i = 0; i < MinimalSFace.size(); ++i) { + // progress2++; + Vertex_handle v = MinimalSFace[i]->center_vertex(); + if(CGAL::lexicographically_xyz_smaller(v->point(),v_min->point())) + v_min=v; + CGAL_NEF_TRACEN( "Shell #" << i << " minimal vertex: " << v->point()); + SM_point_locator D((Sphere_map*) &*v); + Object_handle o = D.locate(Sphere_point(-1,0,0)); + SFace_const_handle sfc; + if( !CGAL::assign(sfc, o) || ShellSf[sfc] != i) { + CGAL_NEF_TRACEN("the shell encloses a volume"); + CGAL_NEF_TRACEN("sface hit? "<sncp()->new_volume(); + c->mark() = f->mark(); // TODO test if line is redundant + link_as_inner_shell(f, c ); + CGAL_NEF_TRACE( "Shell #" << i <<" linked as inner shell"); + CGAL_NEF_TRACEN( "(sface" << (CGAL::assign(sfc,o)?"":" not") << " hit case)"); + } + } + } + + // finaly, we go through all the Shells which do not correspond to a Volume + // and we assign them to its enclosing Volume determined via a facet below + // check. + + CGAL_forall_sfaces(f,*this->sncp()) { + // progress3++; + if ( f->volume() != Volume_handle() ) + continue; + CGAL_NEF_TRACEN( "Outer shell #" << ShellSf[f] << " volume?"); + Volume_handle c = determine_volume( MinimalSFace[ShellSf[f]], + MinimalSFace, ShellSf ); + c->mark() = f->mark(); + link_as_outer_shell( f, c ); + } + } + + Halffacet_handle get_facet_below( Vertex_handle vi, + const std::vector< SFace_handle>& MinimalSFace, + const Sface_shell_hash& Shell) const { + // {\Mop determines the facet below a vertex |vi| via ray shooting. } + + Halffacet_handle f_below; + Point_3 p = vi->point(); + if(!Infi_box::is_standard(p)) + return Halffacet_handle(); + + Ray_3 ray = Ray_3(p, Direction_3(-1,0,0)); +#ifdef CGAL_NEF3_TIMER_POINT_LOCATION + number_of_ray_shooting_queries++; + timer_ray_shooting.start(); +#endif + Object_handle o = pl->shoot(ray); +#ifdef CGAL_NEF3_TIMER_POINT_LOCATION + timer_ray_shooting.stop(); +#endif + // The ray here has an special property since it is shooted from the lowest + // vertex in a shell, so it would be expected that the ray goes along the + // interior of a volume before it hits a 2-skeleton element. + // Unfortunatelly, it seems to be possible that several shells are incident + // to this lowest vertex, and in consequence, the ray could also go along + // an edge or a facet belonging to a different shell. + // This fact invalidates the precondition of the get_visible_facet method, + // (the ray must pierce the local view of the hit object in a sface). + // This situation has not been analyzed and has to be verified. Granados. + Vertex_handle v; + Halfedge_handle e; + Halffacet_handle f; + CGAL_NEF_TRACEN("get_facet_below"); + if( CGAL::assign(v, o)) { + CGAL_NEF_TRACEN("facet below from from vertex..."); + f_below = get_visible_facet(v, ray); + if( f_below == Halffacet_handle()) { + CGAL_assertion(v->sfaces_begin() == v->sfaces_last()); + f_below = get_facet_below(MinimalSFace[Shell[v->sfaces_begin()]]->center_vertex(), + MinimalSFace,Shell); + } + } + else if( CGAL::assign(e, o)) { + CGAL_NEF_TRACEN("facet below from from edge..."); + f_below = get_visible_facet(e, ray); + if( f_below == Halffacet_handle()) { + CGAL_assertion(e->source()->sfaces_begin() == e->source()->sfaces_last()); + f_below = get_facet_below(MinimalSFace[Shell[e->source()->sfaces_begin()]]->center_vertex(), + MinimalSFace, Shell); + } + } + else if( CGAL::assign(f, o)) { + CGAL_NEF_TRACEN("facet below from from facet..."); + f_below = get_visible_facet(f, ray); + CGAL_assertion( f_below != Halffacet_handle()); + } + else { CGAL_NEF_TRACEN("no facet below found..."); } + return f_below; + } + + Volume_handle determine_volume( SFace_handle sf, + const std::vector< SFace_handle>& MinimalSFace, + 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.} + + CGAL_NEF_TRACEN("determine volume"); + Vertex_handle v_min = MinimalSFace[Shell[sf]]->center_vertex(); + + Halffacet_handle f_below = get_facet_below(v_min, MinimalSFace, Shell); + if ( f_below == Halffacet_handle()) + return SNC_decorator(*this).volumes_begin(); + Volume_handle c = f_below->incident_volume(); + if( c != Volume_handle()) { + CGAL_NEF_TRACE( "Volume " << &*c << " hit "); + CGAL_NEF_TRACEN("(Shell #" << Shell[adjacent_sface(f_below)] << ")"); + return c; + } + SFace_handle sf_below = adjacent_sface(f_below); + CGAL_NEF_TRACE( "Shell not assigned to a volume hit "); + CGAL_NEF_TRACEN( "(Inner shell #" << Shell[sf_below] << ")"); + c = determine_volume( sf_below, MinimalSFace, Shell); + link_as_inner_shell( sf_below, c); + return c; + } + + void build_external_structure() { +// CGAL_NEF_SETDTHREAD(503*509); + +#ifdef CGAL_NEF3_TIMER_EXTERNAL_STRUCTURE + CGAL::Timer timer_external_structure; + timer_external_structure.start(); +#endif + +#ifdef CGAL_NEF3_TIMER_PLUECKER + CGAL::Timer timer_pluecker; + timer_pluecker.start(); +#endif + // SNC_io_parser O0(std::cerr,*this->sncp()); + // O0.print(); + pair_up_halfedges(); +#ifdef CGAL_NEF3_TIMER_PLUECKER + timer_pluecker.stop(); + if(cgal_nef3_timer_on) + std::cout << "Runtime_pluecker: " + << timer_pluecker.time() << std::endl; +#endif + // SNC_io_parser O0(std::cerr,*this->sncp()); + // O0.print(); + link_shalfedges_to_facet_cycles(); + categorize_facet_cycles_and_create_facets(); + create_volumes(); + +#ifdef CGAL_NEF3_TIMER_EXTERNAL_STRUCTURE + timer_external_structure.stop(); + if(cgal_nef3_timer_on) + std::cout << "Runtime_external_structure: " + << timer_external_structure.time() << std::endl; +#endif + } + + void build_after_binary_operation() { + +#ifdef CGAL_NEF3_TIMER_SIMPLIFICATION + CGAL::Timer timer_simplification; + timer_simplification.start(); +#endif + SNC_simplify simp(*this->sncp()); + simp.vertex_simplification(SNC_simplify::NO_SNC); +#ifdef CGAL_NEF3_TIMER_SIMPLIFICATION + timer_simplification.stop(); + if(cgal_nef3_timer_on) + std::cout << "Runtime_simplification: " + << timer_simplification.time() << std::endl; +#endif + + CGAL_NEF_TRACEN("\nnumber of vertices (so far...) = " + << this->sncp()->number_of_vertices()); + + CGAL_NEF_TRACEN("=> resultant vertices (after simplification): "); + + build_external_structure(); + } + + void clear_external_structure() { + this->sncp()->clear_snc_boundary(); + + while(this->sncp()->volumes_begin()!= this->sncp()->volumes_end()) + this->sncp()->delete_volume(this->sncp()->volumes_begin()); + + while(this->sncp()->halffacets_begin()!= this->sncp()->halffacets_end()) + this->sncp()->delete_halffacet_pair(this->sncp()->halffacets_begin()); + + SHalfedge_iterator se; + CGAL_forall_shalfedges(se,*this) + se->facet() = Halffacet_handle(); + + SFace_iterator sf; + CGAL_forall_sfaces(sf,*this) + sf->volume() = Volume_handle(); + } +}; + +template +class SNC_external_structure + : public SNC_external_structure { + +public: + typedef SNC_structure_ SNC_structure; + typedef SNC_external_structure Base; + + typedef CGAL::SNC_decorator SNC_decorator; + typedef CGAL::SNC_point_locator SNC_point_locator; + typedef CGAL::SNC_FM_decorator FM_decorator; + typedef typename SNC_structure::Sphere_map Sphere_map; + typedef CGAL::SM_decorator SM_decorator; + typedef CGAL::SNC_simplify SNC_simplify; + + typedef typename SNC_structure::Halfedge_iterator Halfedge_iterator; + typedef typename SNC_structure::SHalfedge_iterator SHalfedge_iterator; + typedef typename SNC_structure::SHalfloop_iterator SHalfloop_iterator; + + typedef typename SNC_structure::Halfedge_handle Halfedge_handle; + typedef typename SNC_structure::SHalfedge_handle SHalfedge_handle; + + typedef typename SNC_structure::Object_handle Object_handle; + + typedef typename SNC_structure::SHalfedge_around_facet_circulator + SHalfedge_around_facet_circulator; + typedef typename SM_decorator::SHalfedge_around_svertex_circulator + SHalfedge_around_svertex_circulator; + + typedef typename SNC_structure::Plane_3 Plane_3; + + SNC_external_structure( SNC_structure& W, SNC_point_locator* spl = NULL) + : Base(W, spl) {} + /*{\Mcreate makes |\Mvar| a decorator of |W|.}*/ + + public: + void pair_up_halfedges() const { + typedef Halfedge_key_lt4 Halfedge_key_lt; + typedef std::list Halfedge_list; + typedef std::map index_map; + + CGAL_NEF_TRACEN("pair up by indexes"); + + index_map i2he; + Halfedge_iterator ei; + CGAL_forall_halfedges(ei, *this->sncp()) + i2he[ei->get_index()].push_back(ei); + + typename index_map::iterator it; + CGAL_forall_iterators(it,i2he) { + it->second.sort(Halfedge_key_lt()); + typename Halfedge_list::iterator itl; + CGAL_forall_iterators(itl,it->second) { + Halfedge_handle e1 = *itl; + CGAL_NEF_TRACEN(e1->source()->point() << ", " << e1->vector()); + ++itl; + CGAL_assertion(itl != it->second.end()); + Halfedge_handle e2 = *itl; + CGAL_NEF_TRACEN(" + " << e2->source()->point() << ", " << e2->vector()); + make_twins(e1,e2); + // SNC_io_parser O0(std::cerr,*this->sncp()); + // O0.print(); + CGAL_assertion(e1->mark()==e2->mark()); + } + } + } + + void link_shalfedges_to_facet_cycles() const { + /*{\Mop creates all non-trivial facet cycles from sedges. + \precond |pair_up_halfedges()| was called before.}*/ + + // CGAL_NEF_SETDTHREAD(43*31); + CGAL_NEF_TRACEN(">>>>>link_shalfedges_to_facet_cycles"); + + Halfedge_iterator e; + CGAL_forall_edges(e,*this->sncp()) { + // progress++; + CGAL_NEF_TRACEN(""); + CGAL_NEF_TRACEN(PH(e)); + Halfedge_iterator et = e->twin(); + SM_decorator D(&*e->source()), Dt(&*et->source()); + CGAL_NEF_TRACEN(e->source()->point()); + if ( D.is_isolated(e) ) continue; + SHalfedge_around_svertex_circulator ce(D.first_out_edge(e)),cee(ce); + SHalfedge_around_svertex_circulator cet(Dt.first_out_edge(et)),cete(cet); + + CGAL_For_all(cet,cete) { + // std::cerr << cet->get_index() << ", " << ce->twin()->get_index() << std::endl; + if (cet->get_forward_index() == ce->twin()->get_backward_index()) + // cet->source()->twin() == ce->source()) + break; + } + + /* + CGAL_NEF_TRACEN("vertices " << e->source()->point() << + " " << et->source()->point()); + + + SHalfedge_around_svertex_circulator sc(D.first_out_edge(e)); + SHalfedge_around_svertex_circulator sct(Dt.first_out_edge(et)); + + CGAL_NEF_TRACEN(""); + CGAL_For_all(sc,cee) + CGAL_NEF_TRACEN("sseg@E addr="<<&*sc<< + " src="<< sc->source()->point()<< + " tgt="<< sc->target()->point()<< std::endl << + " circle=" << sc->circle()<< std::endl << + " indexes=" << sc->get_forward_index() << + "," << sc->get_backward_index() << std::endl << + " " << sc->twin()->get_forward_index() << + "," << sc->twin()->get_backward_index()); + + CGAL_NEF_TRACEN(""); + + CGAL_For_all(sct,cete) + CGAL_NEF_TRACEN("sseg@ET addr="<<&*sct<< + " src="<< sct->source()->point()<< + " tgt="<target()->point() <get_backward_index() << std::endl << + " " << sct->twin()->get_forward_index() << + "," << sct->twin()->get_backward_index()); + CGAL_NEF_TRACEN(""); + */ + // CGAL_NEF_SETDTHREAD(1); + + CGAL_assertion( normalized(cet->circle()) == normalized(ce->circle().opposite()) ); + CGAL_assertion( cet->source()->twin() == ce->source()); + CGAL_For_all(ce,cee) { + CGAL_NEF_TRACEN("circles " << cet->circle() << " " << ce->circle() << + " sources " << cet->target()->point() << + " " << ce->target()->point()); + CGAL_assertion( normalized(cet->circle()) == normalized(ce->circle().opposite())); + CGAL_assertion( cet->source()->twin() == ce->source()); + CGAL_assertion(ce->mark()==cet->mark()); + link_as_prev_next_pair(cet->twin(),ce); + link_as_prev_next_pair(ce->twin(),cet); + --cet; // ce moves ccw, cet moves cw + } + } + } + + void categorize_facet_cycles_and_create_facets() const { + /*{\Mop collects all facet cycles incident to a facet and creates + the facets. \precond |link_shalfedges_to_facet_cycles()| was called + before.}*/ + + // CGAL_NEF_SETDTHREAD(43*31); + CGAL_NEF_TRACEN(">>>>>categorize_facet_cycles_and_create_facets"); + + typedef std::list Object_list; + typedef std::map + Map_planes; + + Map_planes M; + SHalfedge_iterator e; + CGAL_forall_shalfedges(e,*this->sncp()) { + if(e->get_index() > e->twin()->get_index()) + continue; + M[e->get_index()].push_back(Object_handle(e)); + } + SHalfloop_iterator l; + CGAL_forall_shalfloops(l,*this->sncp()) { + if(l->get_index() > l->twin()->get_index()) + continue; + M[l->get_index()].push_back(Object_handle(l)); + } + +#ifdef CGAL_NEF3_TIMER_PLANE_SWEEPS + number_of_plane_sweeps=0; + timer_plane_sweeps.reset(); +#endif + + typename Map_planes::iterator it; + CGAL_forall_iterators(it,M) { + // progress2++; + // CGAL_NEF_TRACEN(" plane "<first<<" "<<(it->first).point()); + FM_decorator D(*this->sncp()); + Plane_3 h; + Object_handle o(*it->second.begin()); + if(CGAL::assign(e, o)) + h = e->circle().opposite().plane_through(e->source()->source()->point()); + else if(CGAL::assign(l, o)) + h = l->circle().opposite().plane_through(l->incident_sface()->center_vertex()->point()); + else + CGAL_assertion_msg(false, "wrong handle"); + + D.create_facet_objects(h,it->second.begin(),it->second.end()); + } + // CGAL_NEF_SETDTHREAD(1); + } + + void create_volumes() { + Base::create_volumes(); + } + + void build_external_structure() { +// CGAL_NEF_SETDTHREAD(503*509); + +#ifdef CGAL_NEF3_TIMER_EXTERNAL_STRUCTURE + CGAL::Timer timer_external_structure; + timer_external_structure.start(); +#endif + +#ifdef CGAL_NEF3_TIMER_PLUECKER + CGAL::Timer timer_pluecker; + timer_pluecker.start(); +#endif + // SNC_io_parser O0(std::cerr,*this->sncp()); + // O0.print(); + pair_up_halfedges(); +#ifdef CGAL_NEF3_TIMER_PLUECKER + timer_pluecker.stop(); + if(cgal_nef3_timer_on) + std::cout << "Runtime_pluecker: " + << timer_pluecker.time() << std::endl; +#endif + // SNC_io_parser O0(std::cerr,*this->sncp()); + // O0.print(); + link_shalfedges_to_facet_cycles(); + + std::map hash; + CGAL::Unique_hash_map done(false); + + SHalfedge_iterator sei; + CGAL_forall_shalfedges(sei, *this->sncp()) { + hash[sei->get_forward_index()] = sei->get_forward_index(); + hash[sei->get_backward_index()] = sei->get_backward_index(); + } + + CGAL_forall_shalfedges(sei, *this->sncp()) { + if(done[sei]) + continue; + SHalfedge_around_facet_circulator circ(sei), end(circ); + int index = circ->get_smaller_index(); + ++circ; + CGAL_For_all(circ, end) + if(circ->get_smaller_index() < index) + index = circ->get_smaller_index(); + index = hash[index]; + CGAL_For_all(circ, end) { + hash[circ->get_forward_index()] = index; + hash[circ->get_backward_index()] = index; + circ->set_index(index); + done[circ] = true; + } + } + + SHalfloop_iterator sli; + CGAL_forall_shalfloops(sli, *this->sncp()) + sli->set_index(hash[sli->get_index()]); + + categorize_facet_cycles_and_create_facets(); + create_volumes(); + +#ifdef CGAL_NEF3_TIMER_EXTERNAL_STRUCTURE + timer_external_structure.stop(); + if(cgal_nef3_timer_on) + std::cout << "Runtime_external_structure: " + << timer_external_structure.time() << std::endl; +#endif + } + + void clear_external_structure() { + Base::clear_external_structure(); + } + + void build_after_binary_operation() { + + pair_up_halfedges(); + link_shalfedges_to_facet_cycles(); + + SNC_simplify simp(*this->sncp()); + simp.vertex_simplificationI(); + + std::map hash; + CGAL::Unique_hash_map + done(false); + + SHalfedge_iterator sei; + CGAL_forall_shalfedges(sei, *this->sncp()) { + hash[sei->get_forward_index()] = sei->get_forward_index(); + hash[sei->get_backward_index()] = sei->get_backward_index(); + } + + CGAL_forall_shalfedges(sei, *this->sncp()) { + if(done[sei]) + continue; + SHalfedge_around_facet_circulator circ(sei), end(circ); + int index = circ->get_smaller_index(); + ++circ; + CGAL_For_all(circ, end) + if(circ->get_smaller_index() < index) + index = circ->get_smaller_index(); + index = hash[index]; + CGAL_For_all(circ, end) { + hash[circ->get_forward_index()] = index; + hash[circ->get_backward_index()] = index; + circ->set_index(index); + done[circ] = true; + } + } + + SHalfloop_iterator sli; + CGAL_forall_shalfloops(sli, *this->sncp()) + sli->set_index(hash[sli->get_index()]); + + categorize_facet_cycles_and_create_facets(); + create_volumes(); + } +}; + +CGAL_END_NAMESPACE +#endif //CGAL_SNC_EXTERNAL_STRUCTURE_H diff --git a/Nef_3/include/CGAL/Nef_3/SNC_indexed_items.h b/Nef_3/include/CGAL/Nef_3/SNC_indexed_items.h new file mode 100644 index 00000000000..dcc23981dcb --- /dev/null +++ b/Nef_3/include/CGAL/Nef_3/SNC_indexed_items.h @@ -0,0 +1,95 @@ +#ifndef CGAL_NEF_SNC_ITEMS_H +#define CGAL_NEF_SNC_ITEMS_H +#include +#include +#include +#include +#include +#include +#include + +CGAL_BEGIN_NAMESPACE + +class Index_generator { + + static int unique; + public: + static int get_unique_index() { return unique++; } +}; + +int Index_generator::unique = 0; + +class SNC_indexed_items { + public: + template class Vertex : public Vertex_base {}; + template class Halffacet : public Halffacet_base {}; + template class Volume : public Volume_base {}; + template class SFace : public SFace_base {}; + + template class SHalfloop : public SHalfloop_base { + typedef SHalfloop_base Base; + int index; + public: + SHalfloop() : Base(), index(0) {} + SHalfloop(const SHalfloop& sl) : Base(sl), index(0) {} + SHalfloop& operator=(const SHalfloop& sl) { + (Base) *this = (Base) sl; + index = sl.index; + return *this; + } + + void set_index(int idx = Index_generator::get_unique_index()) + { index = idx; } + int get_index() const { return index; } + }; + + template class SHalfedge : public SHalfedge_base { + typedef SHalfedge_base Base; + int index; + int index2; + public: + SHalfedge() : Base(), index(0), index2(0) {} + SHalfedge(const SHalfedge& se) + : Base(se), index(se.index), index2(se.index2) {} + SHalfedge& operator=(const SHalfedge& se) { + (Base) *this = (Base) se; + index = se.index; + index2 = se.index2; + return *this; + } + + void set_index(int idx = Index_generator::get_unique_index()) + { index = index2 = idx; } + int get_index() const { + // CGAL_assertion(index==index2); + return index; + } + void set_forward_index(int idx) { index = idx;} + void set_backward_index(int idx) { index2 = idx;} + int get_forward_index() const { return index; } + int get_backward_index() const { return index2; } + int get_smaller_index() const { return index < index2 ? index : index2; } + }; + + template class SVertex : public Halfedge_base { + typedef Halfedge_base Base; + typedef typename Refs::Mark Mark; + int index; + public: + SVertex() : Base(), index(0) {} + SVertex(Mark m) : Base(m), index(0) {} + SVertex(const SVertex& sv) : Base(sv) { index = sv.index; } + SVertex& operator=(const SVertex& sv) { + (Base) *this = (Base) sv; + index = sv.index; + return *this; + } + + void set_index(int idx = Index_generator::get_unique_index()) + { index = idx; } + int get_index() const { return index; } + }; +}; + +CGAL_END_NAMESPACE +#endif // CGAL_NEF_SNC_ITEMS_H diff --git a/Nef_3/include/CGAL/Nef_3/Vertex.h b/Nef_3/include/CGAL/Nef_3/Vertex.h new file mode 100644 index 00000000000..2739e4d1751 --- /dev/null +++ b/Nef_3/include/CGAL/Nef_3/Vertex.h @@ -0,0 +1,365 @@ +// Copyright (c) 1997-2002 Max-Planck-Institute Saarbruecken (Germany). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you may redistribute it under +// the terms of the Q Public License version 1.0. +// See the file LICENSE.QPL distributed with CGAL. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL: svn+ssh://hachenb@scm.gforge.inria.fr/svn/cgal/branches/Filtered_Nef/Nef_3/include/CGAL/Nef_3/Vertex.h $ +// $Id: Vertex.h 35450 2006-12-06 10:43:20Z hachenb $ +// +// +// Author(s) : Michael Seel +// Miguel Granados +// Susan Hert +// Lutz Kettner +// Peter Hachenberger +#ifndef CGAL_NEF_VERTEX_H +#define CGAL_NEF_VERTEX_H + +#include +#include +#include +#include + +#undef CGAL_NEF_DEBUG +#define CGAL_NEF_DEBUG 83 +#include + +CGAL_BEGIN_NAMESPACE + +template +class Vertex_base { + + typedef void* GenPtr; + typedef typename Refs::Mark Mark; + typedef typename Refs::Point_3 Point_3; + + typedef typename Refs::Vertex_handle Vertex_handle; + typedef typename Refs::SHalfloop_handle SHalfloop_handle; + + typedef typename Refs::Vertex_iterator Vertex_iterator; + typedef typename Refs::SVertex_iterator SVertex_iterator; + typedef typename Refs::SHalfedge_iterator SHalfedge_iterator; + typedef typename Refs::SHalfloop_iterator SHalfloop_iterator; + typedef typename Refs::SFace_iterator SFace_iterator; + + typedef typename Refs::Vertex_const_iterator Vertex_const_iterator; + typedef typename Refs::SVertex_const_iterator SVertex_const_iterator; + typedef typename Refs::SHalfedge_const_iterator SHalfedge_const_iterator; + typedef typename Refs::SFace_const_iterator SFace_const_iterator; + typedef typename Refs::SHalfloop_const_handle SHalfloop_const_handle; + + typedef typename Refs::Size_type Size_type; + + Point_3 point_at_center_; + Mark mark_; + // local view (surface graph): + public: + Refs* sncp_; + SVertex_iterator svertices_begin_, svertices_last_; + SHalfedge_iterator shalfedges_begin_, shalfedges_last_; + SFace_iterator sfaces_begin_, sfaces_last_; + SHalfloop_iterator shalfloop_; + GenPtr info_; + + public: + + Vertex_base() : point_at_center_(), mark_(), sncp_(), + svertices_begin_(), svertices_last_(), + shalfedges_begin_(), shalfedges_last_(), + sfaces_begin_(), sfaces_last_(), shalfloop_(), + info_() + // , sm_(Vertex_handle((SNC_in_place_list_vertex*) this)) + {} + + Vertex_base(const Point_3& p, Mark m) : + point_at_center_(p), mark_(m), sncp_(), + svertices_begin_(), svertices_last_(), + shalfedges_begin_(), shalfedges_last_(), + sfaces_begin_(), sfaces_last_(), shalfloop_(), + info_() + // , sm_(Vertex_handle((SNC_in_place_list_vertex*) this)) + {} + + Vertex_base(const Vertex_base& v) + // : sm_(Vertex_handle((SNC_in_place_list_vertex*)this)) + { + point_at_center_ = v.point_at_center_; + mark_ = v.mark_; + sncp_ = v.sncp_; + svertices_begin_ = v.svertices_begin_; + svertices_last_ = v.svertices_last_; + shalfedges_begin_ = v.shalfedges_begin_; + shalfedges_last_ = v.shalfedges_last_; + sfaces_begin_ = v.sfaces_begin_; + sfaces_last_ = v.sfaces_last_; + shalfloop_ = v.shalfloop_; + info_ = 0; + } + + Vertex_base& operator=(const Vertex_base& v) + { if (this == &v) return *this; + point_at_center_ = v.point_at_center_; + mark_ = v.mark_; + sncp_ = v.sncp_; + svertices_begin_ = v.svertices_begin_; + svertices_last_ = v.svertices_last_; + shalfedges_begin_ = v.shalfedges_begin_; + shalfedges_last_ = v.shalfedges_last_; + sfaces_begin_ = v.sfaces_begin_; + sfaces_last_ = v.sfaces_last_; + shalfloop_ = v.shalfloop_; + return *this; + } + + Refs* sncp() const { return sncp_; } + Refs*& sncp() { return sncp_; } + + /* all sobjects of the local graph are stored in a global list + where each vertex has a continous range in each list for its + sobjects. All objects of the range [sxxx_begin_,sxxx_last_] + belong to a vertex. This range is empty iff + sxxx_begin_ == sxxx_last_ == sncp()->sxxx_end() + ( the latter being the standard end iterator of the + corresponding list ) + for the past the end iterator we have to increment sxxx_last_ + once iff the range is non-empty. */ + + void init_range(SVertex_iterator it) + { svertices_begin_ = svertices_last_ = it; } + void init_range(SHalfedge_iterator it) + { shalfedges_begin_ = shalfedges_last_ = it; } + void init_range(SFace_iterator it) + { sfaces_begin_ = sfaces_last_ = it; } + + SVertex_iterator& svertices_begin() + { return svertices_begin_; } + SVertex_iterator& svertices_last() + { return svertices_last_; } + SVertex_iterator svertices_end() + { if ( svertices_last_ == sncp()->svertices_end() ) + return svertices_last_; + else + return ++SVertex_iterator(svertices_last_); } + + SHalfedge_iterator& shalfedges_begin() + { return shalfedges_begin_; } + SHalfedge_iterator& shalfedges_last() + { return shalfedges_last_; } + SHalfedge_iterator shalfedges_end() + { if ( shalfedges_last_ == sncp()->shalfedges_end() ) + return shalfedges_last_; + else + return ++SHalfedge_iterator(shalfedges_last_); } + + SFace_iterator& sfaces_begin() + { return sfaces_begin_; } + SFace_iterator& sfaces_last() + { return sfaces_last_; } + SFace_iterator sfaces_end() + { if ( sfaces_last_ == sncp()->sfaces_end() ) + return sfaces_last_; + else + return ++SFace_iterator(sfaces_last_); } + + SVertex_const_iterator svertices_begin() const + { return svertices_begin_; } + SVertex_const_iterator svertices_last() const + { return svertices_last_; } + SVertex_const_iterator svertices_end() const + { if ( svertices_last_ == sncp()->svertices_end() ) + return svertices_last_; + else + return ++SVertex_const_iterator(svertices_last_); } + + SHalfedge_const_iterator shalfedges_begin() const + { return shalfedges_begin_; } + SHalfedge_const_iterator shalfedges_last() const + { return shalfedges_last_; } + SHalfedge_const_iterator shalfedges_end() const + { if ( shalfedges_last_ == sncp()->shalfedges_end() ) + return shalfedges_last_; + else + return ++SHalfedge_const_iterator(shalfedges_last_); } + + SFace_const_iterator sfaces_begin() const + { return sfaces_begin_; } + SFace_const_iterator sfaces_last() const + { return sfaces_last_; } + SFace_const_iterator sfaces_end() const + { if ( sfaces_last_ == sncp()->sfaces_end() ) + return sfaces_last_; + else + return ++SFace_const_iterator(sfaces_last_); } + + SHalfloop_handle& shalfloop() { return shalfloop_; } + SHalfloop_handle shalfloop() const { return shalfloop_; } + + bool has_shalfloop() const { + return shalfloop_ != sncp()->shalfloops_end(); + } + + Size_type number_of_svertices() const + /*{\Mop returns the number of vertices.}*/ + { Size_type n(0); + SVertex_const_iterator vit; + CGAL_forall_svertices(vit, *this) ++n; + return n; } + + Size_type number_of_shalfedges() const + /*{\Mop returns the number of halfedges.}*/ + { Size_type n(0); + SHalfedge_const_iterator eit; + CGAL_forall_shalfedges(eit, *this) ++n; + return n;} + + Size_type number_of_sedges() const + /*{\Mop returns the number of edges.}*/ + { return number_of_shalfedges()/2; } + + Size_type number_of_shalfloops() const + /*{\Mop returns the number of halfloops.}*/ + { return ( has_shalfloop() ? 2 : 0); } + + Size_type number_of_sloops() const + /*{\Mop returns the number of loops.}*/ + { return number_of_shalfloops()/2; } + + Size_type number_of_sfaces() const + /*{\Mop returns the number of faces.}*/ + { Size_type n(0); + SFace_const_iterator fit; + CGAL_forall_sfaces(fit, *this) ++n; + return n; } + + + /*{\Xtext Vertices provide access to their local graphs via + the iterator ranges: + \begin{Mverb} + SVertex_iterator svertices_begin()/svertices_end() + SHalfedge_iterator shalfedges_begin()/shalfedges_end() + SFace_iterator sfaces_begin()/sfaces_end() + SHalfloop_handle shalfloop() + \end{Mverb} + }*/ + + void clear() + /*{\Xop clears the local graph.}*/ { + SFace_iterator fit = sfaces_begin(), + fend = sfaces_end(); + while (fit != fend) { + SFace_iterator fdel = fit++; + /* TO VERIFY: next statement needs access to a private attribute */ + sncp()->reset_sm_object_list(fdel->boundary_entry_objects_); + sncp()->delete_sface_only(fdel); + } + sfaces_begin_ = sfaces_last_ = sncp()->sfaces_end(); + + if ( shalfloop() != sncp()->shalfloops_end() ) { + sncp()->delete_shalfloop_only(shalfloop_->twin()); + sncp()->delete_shalfloop_only(shalfloop_); + shalfloop_ = sncp()->shalfloops_end(); + } + + SHalfedge_iterator eit = shalfedges_begin(), + eend = shalfedges_end(); + while (eit != eend) { + SHalfedge_iterator edel = eit++; + sncp()->delete_shalfedge_only(edel); + } + shalfedges_begin_ = shalfedges_last_ = sncp()->shalfedges_end(); + + SVertex_iterator vit = svertices_begin(), + vend = svertices_end(); + while (vit != vend) { + SVertex_iterator vdel = vit++; + sncp()->delete_halfedge_only(vdel); + } + svertices_begin_ = svertices_last_ = sncp()->halfedges_end(); + } + + Point_3& point() { return point_at_center_; } + const Point_3& point() const { return point_at_center_; } + Mark& mark() { return mark_; } + const Mark& mark() const { return mark_;} + GenPtr& info() { return info_; } + const GenPtr& info() const { return info_; } + + ~Vertex_base() { + CGAL_NEF_TRACEN(" destroying Vertex item "<<&*this); + } + + public: + std::string debug() const + { std::stringstream os; + set_pretty_mode(os); + os<<"{ addr, point, mark, snc, svb, sve, seb, see, sfb, sfe, sl," + <<" info }"<svertices_end()) + CGAL_assertion(svertices_end() == sncp()->svertices_end()); + if(shalfedges_begin_ == sncp()->shalfedges_end()) + CGAL_assertion(shalfedges_end() == sncp()->shalfedges_end()); + if(sfaces_begin_ == sncp()->sfaces_end()) + CGAL_assertion(sfaces_end() == sncp()->sfaces_end()); + */ + return true; + } + + bool is_valid( bool verb = false, int level = 0) const { + + Verbose_ostream verr(verb); + verr << "begin CGAL::SNC_items<...>::Vertex_base::is_valid( verb=true, " + "level = " << level << "):" << std::endl; + + bool valid = (sncp_ != NULL); + valid = valid && (svertices_begin_ != NULL && svertices_begin_ != SVertex_iterator()); + valid = valid && (svertices_last_ != NULL && svertices_last_ != SVertex_iterator()); + valid = valid && (shalfedges_begin_ != NULL && shalfedges_begin_ != SHalfedge_iterator()); + valid = valid && (shalfedges_last_ != NULL && shalfedges_last_ != SHalfedge_iterator()); + valid = valid && (sfaces_begin_ != NULL && sfaces_begin_ != SFace_iterator()); + valid = valid && (sfaces_last_ != NULL && sfaces_last_ != SFace_iterator()); + valid = valid && (shalfloop_ != NULL && shalfloop_ != SHalfloop_iterator()); + + if(shalfedges_begin_ == sncp()->shalfedges_end()) { // point in volume or on plane, which is either isolated or has one outgoing edge + if(shalfloop_ != sncp()->shalfloops_end()) + valid = valid && (++SFace_const_iterator(sfaces_begin_) == sfaces_last_); + else + valid = valid && (sfaces_begin_ == sfaces_last_); + } + + valid = valid && (sfaces_begin_ != sncp()->sfaces_end()); + if(sfaces_begin_ == sfaces_last_) { + valid = valid && (shalfloop_ == sncp()->shalfloops_end()); + } + else + valid = valid && (sfaces_begin_->sface_cycles_begin() != + sfaces_begin_->sface_cycles_end()); + + verr << "end of CGAL::SNC_items<...>::Vertex_base::is_valid(): structure is " + << ( valid ? "valid." : "NOT VALID.") << std::endl; + return valid; + } + +}; // Vertex_base + + +CGAL_END_NAMESPACE +#endif // CGAL_NEF_VERTEX_H diff --git a/Nef_3/include/CGAL/Nef_3/Volume.h b/Nef_3/include/CGAL/Nef_3/Volume.h new file mode 100644 index 00000000000..9bb2ed3671d --- /dev/null +++ b/Nef_3/include/CGAL/Nef_3/Volume.h @@ -0,0 +1,111 @@ +// Copyright (c) 1997-2002 Max-Planck-Institute Saarbruecken (Germany). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you may redistribute it under +// the terms of the Q Public License version 1.0. +// See the file LICENSE.QPL distributed with CGAL. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL: svn+ssh://hachenb@scm.gforge.inria.fr/svn/cgal/branches/Filtered_Nef/Nef_3/include/CGAL/Nef_3/Volume.h $ +// $Id: Volume.h 35450 2006-12-06 10:43:20Z hachenb $ +// +// +// Author(s) : Michael Seel +// Miguel Granados +// Susan Hert +// Lutz Kettner +// Peter Hachenberger +#ifndef CGAL_NEF_VOLUME_H +#define CGAL_NEF_VOLUME_H + +#include +#include +#include +#include + +#undef CGAL_NEF_DEBUG +#define CGAL_NEF_DEBUG 83 +#include + +CGAL_BEGIN_NAMESPACE + +template +class Volume_base { + typedef void* GenPtr; + typedef typename Refs::Mark Mark; + typedef typename Refs::Volume_handle Volume_handle; + typedef typename Refs::Volume_const_handle Volume_const_handle; + typedef typename Refs::Object_list Object_list; + typedef typename Refs::Shell_entry_iterator + Shell_entry_iterator; + typedef typename Refs::Shell_entry_const_iterator + Shell_entry_const_iterator; + + Mark mark_; + Object_list shell_entry_objects_; // SFaces + + public: + + Volume_base() {} + + Volume_base(Mark m) : mark_(m) {} + + ~Volume_base() { + CGAL_NEF_TRACEN(" destroying Volume_base item "<<&*this); + } + + Volume_base(const Volume_base& v) + { mark_ = v.mark_; + shell_entry_objects_ = v.shell_entry_objects_; + } + + Volume_base& operator=(const Volume_base& v) + { if (this == &v) return *this; + mark_ = v.mark_; + shell_entry_objects_ = v.shell_entry_objects_; + return *this; + } + + Mark& mark() { return mark_; } + const Mark& mark() const { return mark_; } + + GenPtr& info() { return this->info_; } + const GenPtr& info() const { return this->info_; } + + Object_list& shell_entry_objects() { return shell_entry_objects_; } + const Object_list& shell_entry_objects() const { + return shell_entry_objects_; + } + + Shell_entry_iterator shells_begin() + { return shell_entry_objects_.begin(); } + Shell_entry_iterator shells_end() + { return shell_entry_objects_.end(); } + Shell_entry_const_iterator shells_begin() const + { return shell_entry_objects_.begin(); } + Shell_entry_const_iterator shells_end() const + { return shell_entry_objects_.end(); } + + bool is_valid( bool verb = false, int level = 0) const { + + Verbose_ostream verr(verb); + verr << "begin CGAL::SNC_items<...>::Volume_base::is_valid( verb=true, " + "level = " << level << "):" << std::endl; + + bool valid = (!shell_entry_objects_.empty()); + + verr << "end of CGAL::SNC_items<...>::Volume_base::is_valid(): structure is " + << ( valid ? "valid." : "NOT VALID.") << std::endl; + + return valid; + } + +}; // Volume_base + +CGAL_END_NAMESPACE +#endif //CGAL_NEF_VOLUME_H