⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 k3_tree.h

📁 很多二维 三维几何计算算法 C++ 类库
💻 H
📖 第 1 页 / 共 3 页
字号:
  }  template<typename Depth>  void add_edge(Halfedge_handle e, Depth depth) {    if(left_node == 0) {      object_list.push_back(Object_handle(e));      return;    }    Side_of_plane sop;    Oriented_side side = sop(splitting_plane.point(), e, depth);    if( side == ON_NEGATIVE_SIDE || side == ON_ORIENTED_BOUNDARY)      left_node->add_edge(e, depth+1);    if( side == ON_POSITIVE_SIDE || side == ON_ORIENTED_BOUNDARY)      right_node->add_edge(e, depth+1);  }  template<typename Depth>  void add_vertex(Vertex_handle v, Depth depth) {    if(left_node == 0) {      object_list.push_back(Object_handle(v));      return;    }    Side_of_plane sop;    Oriented_side side = sop(splitting_plane.point(), v, depth);    if( side == ON_NEGATIVE_SIDE || side == ON_ORIENTED_BOUNDARY)      left_node->add_vertex(v, depth+1);    if( side == ON_POSITIVE_SIDE || side == ON_ORIENTED_BOUNDARY)      right_node->add_vertex(v, depth+1);  }  friend std::ostream& operator<<  (std::ostream& os, const Node* node) {  CGAL_assertion( node != 0);  if( node->is_leaf())    os <<  node->objects().size();  else {    os << " ( ";    if( !node->left()) os << '-';    else os << node->left();    os << " , ";    if( !node->right()) os << '-';    else os << node->right();    os << " ) ";  }  return os;}  ~Node() {  CGAL_NEF_TRACEN("~Node: deleting node...");  if( !is_leaf()) {    delete left_node;    delete right_node;  }}private:  Node* parent_node;  Node* left_node;  Node* right_node;  Plane_3 splitting_plane;  Point_3 point_on_plane;  Object_list object_list;};public:  class Objects_around_segment   {   public:    class Iterator;  protected:    Traits traits;    Node *root_node;    Segment_3 segment;    bool initialized;  public:    Objects_around_segment() : initialized(false) {}    Objects_around_segment( const K3_tree& k, const Segment_3& s) :       root_node(k.root), segment(s), initialized(true) {      CGAL_NEF_TRACEN("Objects_around_segment: input segment: "<<segment);    }    void initialize( const K3_tree& k, const Segment_3& s) {      root_node = k.root;      segment = s;      initialized = true;      CGAL_NEF_TRACEN("Objects_around_segment: input segment: "<<s<<" (initialize)");    }  public:    Iterator begin() const {      CGAL_assertion( initialized == true);      return Iterator( root_node, segment);    }    Iterator end() const {      return Iterator();    }    class Iterator    {      friend class K3_tree;      typedef Iterator Self;      typedef std::pair< const Node*, Segment_3> Candidate;    protected:      std::list<Candidate> S;      const Node* node;      Traits traits;      CGAL_assertion_code( Segment_3 prev_segment);      CGAL_assertion_code( bool first_segment);    public:      Iterator() : node(0) {}      Iterator( const Node* root, const Segment_3& s) {        CGAL_assertion_code( first_segment = true);        S.push_front( Candidate( root, s));        ++(*this); // place the interator in the first intersected cell      }      Iterator( const Self& i) : S(i.S), node(i.node) {}      const Object_list& operator*() const {         CGAL_assertion( node != 0);        return node->objects();      }      Self& operator++() {        if( S.empty())  node = 0; // end of the iteratorelse {  while( !S.empty()) {    const Node* n = S.front().first;    Segment_3 s = S.front().second;    S.pop_front();    if( n->is_leaf()) {#ifndef NDEBUG      CGAL_assertion_code(      if( first_segment) {        first_segment = false;        CGAL_NEF_TRACEN("operator++: prev_segment=(none), segment="<<s);      }      else {        CGAL_assertion( prev_segment.target() == s.source());        CGAL_assertion( prev_segment.direction() == s.direction());        CGAL_NEF_TRACEN("operator++: prev_segment="<<prev_segment<<", segment="<<s);      }      prev_segment = s);#endif      node = n;      break;    }    else {      CGAL_NEF_TRACEN("find next intersected cell: segment: "<<s);      CGAL_NEF_TRACEN("find next intersected cell: node plane: "<<n->plane() <<             ", point: "<<n->plane().point());      Oriented_side src_side = n->plane().oriented_side(s.source());      Oriented_side tgt_side = n->plane().oriented_side(s.target());      if( src_side == ON_ORIENTED_BOUNDARY && tgt_side == ON_ORIENTED_BOUNDARY)        src_side = tgt_side = ON_NEGATIVE_SIDE;      else if( src_side == ON_ORIENTED_BOUNDARY)        src_side = tgt_side;      else if( tgt_side == ON_ORIENTED_BOUNDARY)        tgt_side = src_side;      if( src_side == tgt_side)        S.push_front( Candidate( get_child_by_side( n, src_side), s));      else {        Segment_3 s1, s2;        divide_segment_by_plane( s, n->plane(), s1, s2);        S.push_front( Candidate( get_child_by_side( n, tgt_side), s2)); // cell on target pushed first        S.push_front( Candidate( get_child_by_side( n, src_side), s1));      }    }  }}        return *this;      }      bool operator==(const Self& i) const {         return (node == i.node);       }      bool operator!=(const Self& i) const {         return !(*this == i);       }    private:      const Node* get_node() const {         CGAL_assertion( node != 0);        return node;      }      inline const Node* get_child_by_side( const Node* node, Oriented_side side) {  CGAL_assertion( node != NULL);  CGAL_assertion( side != ON_ORIENTED_BOUNDARY);  if( side == ON_NEGATIVE_SIDE) {    return node->left();  }  CGAL_assertion( side == ON_POSITIVE_SIDE);  return node->right();}void divide_segment_by_plane( Segment_3 s, Plane_3 pl,                               Segment_3& s1, Segment_3& s2) {  Object o = traits.intersect_object()( pl, s);  Point_3 ip;  CGAL_assertion( CGAL::assign( ip, o));  CGAL::assign( ip, o);  ip = normalized(ip);  s1 = Segment_3( s.source(), ip);  s2 = Segment_3( ip, s.target());  CGAL_assertion( s1.target() == s2.source());  CGAL_assertion( s1.direction() == s.direction());  CGAL_assertion( s2.direction() == s.direction());}    };  };  class Objects_along_ray : public Objects_around_segment  {    typedef Objects_around_segment Base;  protected:    Traits traits;	  public:    Objects_along_ray( const K3_tree& k, const Ray_3& r) {      CGAL_NEF_TRACEN("Objects_along_ray: input ray: "<<r);      Vector_3 vec(r.to_vector());      // First of all, we need to find out wheather we are working over an extended kernel or on a standard kernel. As precondition we have that ray is oriented in the minus x axis direction.  When having an extended kernel, the ray can be subtituted by a segment with the endpoint on the 'intersection' between the ray and the bounding infimaximal box.  In the presence of a standard kernel, the intersection is computed with the bounding box with the vertices of the Nef polyhedron.      Point_3 p(r.source()), q;      Bounding_box_3 b = k.bounding_box;      int c = (CGAL::abs(vec[0]) > CGAL::abs(vec[1]) ? 0 : 1);       c = (CGAL::abs(vec[2]) > CGAL::abs(vec[c]) ? 2 : c);       Point_3 pt_on_minus_x_plane = vec[c] < 0 ? 	Point_3(FT(b.min_coord(0)), FT(b.min_coord(1)),FT(b.min_coord(2))) :	Point_3(FT(b.max_coord(0)), FT(b.max_coord(1)),FT(b.max_coord(2)));      // We compute the intersection between a plane with normal vector in       // the minus x direction and located at the minimum point of the bounding box, and the input ray.  When the ray does not intersect the bounding volume, there won't be any object hit, so it is safe to construct a segment that simply lay in the unbounded side of the bounding box.  This approach is taken instead of somehow (efficiently) report that there was no hit object, in order to mantain a clear interface with the Iterator class.      Plane_3 pl_on_minus_x;            if(c==0)	pl_on_minus_x = Plane_3(pt_on_minus_x_plane, Vector_3( 1, 0, 0));      else if(c==1)	pl_on_minus_x = Plane_3(pt_on_minus_x_plane, Vector_3( 0, 1, 0));      else {	CGAL_assertion_msg(c==2, "wrong value"); 	pl_on_minus_x = Plane_3(pt_on_minus_x_plane, Vector_3( 0, 0, 1));      }      Object o = traits.intersect_object()( pl_on_minus_x, r);      if( !CGAL::assign( q, o) || pl_on_minus_x.has_on(p))	q = r.source() + vec;      else	q = normalized(q);      Base::initialize( k, Segment_3( p, q));    }  };private:#ifdef CGAL_NEF_EXPLOIT_REFERENCE_COUNTING  bool reference_counted;#endif  Traits traits;  Node* root;  int max_depth;  Bounding_box_3 bounding_box;public:  template<typename SNC_structure>  K3_tree(SNC_structure* W) #ifdef CGAL_NEF_EXPLOIT_REFERENCE_COUNTING    : reference_counted(false) #endif    {    typedef typename SNC_structure::Vertex_iterator Vertex_iterator;    typedef typename SNC_structure::Halfedge_iterator Halfedge_iterator;    typedef typename SNC_structure::Halffacet_iterator Halffacet_iterator;    typedef typename SNC_structure::Halffacet_cycle_iterator                                    Halffacet_cycle_iterator;    typedef typename SNC_structure::SHalfedge_around_facet_circulator                                    SHalfedge_around_facet_circulator;    CGAL_assertion( W != NULL);    Object_list objects;    Vertex_iterator v;    Halfedge_iterator e;    Halffacet_iterator f;    CGAL_forall_vertices( v, *W)      objects.push_back(Object_handle(Vertex_handle(v)));    typename Object_list::difference_type v_end = objects.size();    CGAL_forall_edges( e, *W)      objects.push_back(Object_handle(Halfedge_handle(e)));    CGAL_forall_facets( f, *W) {#ifdef CGAL_NEF3_TRIANGULATE_FACETS         Halffacet_cycle_iterator fci = f->facet_cycles_begin();      CGAL_assertion(fci.is_shalfedge());      SHalfedge_around_facet_circulator safc(fci);      if(circulator_size(safc) > 10) {      typedef typename CGAL::Triangulation_euclidean_traits_xy_3<Kernel>       XY;      typedef typename CGAL::Triangulation_euclidean_traits_yz_3<Kernel>       YZ;      typedef typename CGAL::Triangulation_euclidean_traits_xz_3<Kernel>       XZ;      Triangle_3 tr;      Vector_3 orth = f->plane().orthogonal_vector();      int c = CGAL::abs(orth[0]) > CGAL::abs(orth[1]) ? 0 : 1;      c = CGAL::abs(orth[2]) > CGAL::abs(orth[c]) ? 2 : c;      std::list<Triangle_3> triangles;      if(c == 0) {        Triangulation_handler<SNC_structure, YZ> th(f);        while(th.get_next_triangle(tr)) {	  triangles.push_front(tr);          Halffacet_triangle_handle th( f, *triangles.begin());          objects.push_back(Object_handle(th));        }      } else if(c == 1) {        Triangulation_handler<SNC_structure, XZ> th(f);        while(th.get_next_triangle(tr)) {	  triangles.push_front(tr);          Halffacet_triangle_handle th( f, *triangles.begin());          objects.push_back(Object_handle(th));        }      } else if(c == 2) {        Triangulation_handler<SNC_structure, XY> th(f);        while(th.get_next_triangle(tr)) {	  triangles.push_front(tr);          Halffacet_triangle_handle th( f, *triangles.begin());          objects.push_back(Object_handle(th));        }      } else       	CGAL_assertion_msg(false, "wrong value");      } else        objects.push_back(Object_handle(Halffacet_handle(f)));#else      objects.push_back(Object_handle(Halffacet_handle(f)));#endif // CGAL_NEF3_TRIANGULATE_FACETS    }    Object_iterator oli=objects.begin()+v_end;    root = build_kdtree( objects, oli, 0);  }  K3_tree(Object_list& objects, Object_iterator& v_end) {    typename Object_list::difference_type n_vertices = std::distance(objects.begin(),v_end); CGAL_NEF_TRACEN("K3_tree(): n_vertices = " << std::distance(objects.begin(),v_end)); std::frexp( (double) n_vertices, &max_depth); // TODO: in the presence of a infimaximal bounding box, the bounding box does not have to be computed Objects_bbox objects_bbox = traits.objects_bbox_object(); bounding_box = objects_bbox(objects); //CGAL_NEF_TRACEN("bounding box:"<<objects_bbox); #ifdef CGAL_NEF_EXPLOIT_REFERENCE_COUNTING        Point_3 p1(1,2,7), p2(p1);    reference_counted = (&(p1.hx()) == &(p2.hx()));    CGAL_NEF_TRACEN("reference counted " << reference_counted);#endif    root = build_kdtree( objects, v_end, 0);  }  const Object_list& objects_around_point( const Point_3& p) const {    return locate( p, root);  }  Objects_along_ray objects_along_ray( const Ray_3& r) const {    return Objects_along_ray( *this, r);  }  Object_list objects_around_segment( const Segment_3& s) const {    Object_list O;        Objects_around_segment objects( *this, s);    Unique_hash_map< Vertex_handle, bool> v_mark(false);    Unique_hash_map< Halfedge_handle, bool> e_mark(false);    Unique_hash_map< Halffacet_handle, bool> f_mark(false);    std::map< Triangle_3, bool, Compare_triangle_3<Triangle_3> > t_mark;    for( typename Objects_around_segment::Iterator oar = objects.begin(); 	 oar != objects.end(); ++oar) {      for( typename Object_list::const_iterator o = (*oar).begin();	   o != (*oar).end(); ++o) { // TODO: implement operator->(...)	Vertex_handle v;	Halfedge_handle e;	Halffacet_handle f;#ifdef CGAL_NEF3_TRIANGULATE_FACETS	Halffacet_triangle_handle t;#endif#ifdef CGAL_NEF3_FACET_WITH_BOX	Partial_facet pf;#endif	if( CGAL::assign( v, *o)) {	  if( !v_mark[v]) {	    O.push_back(*o);	    v_mark[v] = true;	  }	}	else if( CGAL::assign( e, *o)) {	  if( !e_mark [e]) {	    O.push_back(*o);	    e_mark[e] = true;	  }	}	else if( CGAL::assign( f, *o)) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -