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

📄 vertex_cycle_to_nef_3.h

📁 很多二维 三维几何计算算法 C++ 类库
💻 H
字号:
// Copyright (c) 2005  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.//// Author(s)     : Ralf Osbild <osbild@mpi-sb.mpg.de>#ifndef CGAL_NEF_VERTEX_CYCLE_TO_NEF_3_H#define CGAL_NEF_VERTEX_CYCLE_TO_NEF_3_H#include <iostream>#include <sstream>// triangulation#include <CGAL/Nef_3/Exact_triangulation_euclidean_traits_xy_3.h>#include <CGAL/Nef_3/Exact_triangulation_euclidean_traits_yz_3.h>#include <CGAL/Nef_3/Exact_triangulation_euclidean_traits_xz_3.h>#include <CGAL/Triangulation_data_structure_2.h>#include <CGAL/Constrained_triangulation_2.h>#include <CGAL/Constrained_triangulation_plus_2.h>// Nef polyhedra#include <CGAL/Nef_polyhedron_3.h>#include <CGAL/Nef_3/SNC_structure.h>#include <CGAL/Nef_3/SNC_constructor.h>#include <CGAL/Nef_3/SNC_point_locator.h>CGAL_BEGIN_NAMESPACE// return value reports success ("true" means nef contains result)// note: facets are considered to be compact// CTP - Constrained_triangulation_plustemplate <class CTP, class Nef_3, class II>bool projected_vertex_cycle_to_nef_3 (typename Nef_3::SNC_structure &snc,      II v_first, II v_last, std::ostringstream &ostr){   typedef typename CTP::Vertex           CTP_vertex;   typedef typename CTP::Vertex_handle    CTP_vertex_handle;   typedef typename CTP::Face             CTP_face;   typedef typename CTP::Face_handle      CTP_face_handle;   typedef typename CTP::Face_circulator  CTP_face_circulator;   typedef typename CTP::size_type        CTP_size_type;   typedef typename Nef_3::SNC_structure            SNC_structure;   typedef typename SNC_structure::SM_decorator       SM_decorator;   typedef typename SNC_structure::Vertex_handle      Vertex_handle;   typedef typename SNC_structure::Sphere_point       Sphere_point;   typedef typename SNC_structure::Sphere_circle      Sphere_circle;   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 CGAL::SNC_point_locator_by_spatial_subdivision           <CGAL::SNC_decorator<SNC_structure> >    Point_locator;   typedef typename SNC_structure::Items               Items;   typedef CGAL::SNC_constructor<Items, SNC_structure> SNC_constructor;   // declarations and defaults   II v_it, v_pred_it;   CTP ctp;   bool cond;   CTP_size_type nov;   snc.clear();   for (nov=0, v_it=v_first; v_it!=v_last; ++v_it)   {  if ( *v_it != (ctp.insert (*v_it))->point() )      {  ostr << " -> Different vertices are projected to same location!";	 return false;      }      ++nov;   }   if ( ctp.number_of_vertices() != nov )   {  ostr << " -> Same vertex appears multiple in cycle.";      return false;   }   if ( nov < 3 )   {  ostr << " -> Not at least 3 vertices.";      return false;   }   // construct constrained triangulation   v_it = v_first;   while ( true )   {  // move iterators      v_pred_it = v_it;      ++v_it;      if ( v_it == v_last ) break; // while-end      if ( *v_pred_it == *v_it ) continue ; // no self-loops      ctp.insert_constraint (*v_pred_it, *v_it);      if ( ctp.number_of_vertices() != nov ) break; // constraints intersect   }   if ( v_it == v_last && *v_pred_it != *v_first) // no self-loops   {  ctp.insert_constraint (*v_pred_it, *v_first);   }   // assertion   if ( ctp.number_of_vertices() != nov )   {  ostr << " -> Vertex cycle is not simple; edges intersect.";      return false;   }   CGAL_assertion (ctp.is_valid());   // determine initial positions for the walk-around   CTP_vertex_handle t_vh, t_vh_0;   CTP_face_handle t_fh;   CTP_face_circulator t_fc, t_fc_0;   int idx(0);   {  // search a constrained edge from "outside"      t_fh = ctp.infinite_face ();      cond = t_fh->has_vertex(ctp.infinite_vertex(), idx);      CGAL_assertion ( cond );      idx = ctp.ccw(idx);      t_vh = t_fh->vertex(idx);      // now: *t_vh lies ccw from the infinite vertex      t_fc = t_fc_0 = ctp.incident_faces(t_vh, t_fh);      if(t_fc == CTP_face_circulator())	return false;      do      {  if ((cond=t_fc->is_constrained(ctp.cw(t_fc->index(t_vh))))) break;      } while (--t_fc != t_fc_0)      ; CGAL_assertion ( cond ); // do-while ends with break      t_fh = t_fc->neighbor(ctp.cw(t_fc->index(t_vh)));      // note: if (not sure at this moment!) input is a simple      // polygon, *t_fh lies inside this polygon, *t_vh is a vertex      // of *t_fh and the edge of *t_fh starting clockwise at *t_vh      // is a constraint.   }   // walk along constraints and build sphere maps   t_vh_0 = t_vh;   do   {  // circulate faces beginning with *t_fh around *t_vh      idx = t_fh->index(t_vh);      CTP_vertex_handle t_target_vh = t_fh->vertex(ctp.cw(idx));      // create new vertex in SNC      Vertex_handle p_vh = snc.new_vertex (t_vh->point(), true);      SM_decorator p_dec (&*p_vh); // &*      // create new svertex in SM      Sphere_point dir ( CGAL::ORIGIN+         (t_target_vh->point() - t_vh->point()) ), dir_0 = dir;      SVertex_handle p_svh (p_dec.new_svertex (dir)), p_svh_pred=p_svh;      p_svh->mark() = true;      // consider triangles (implicit edges) that are incident to *t_vh      t_fc = t_fc_0 = ctp.incident_faces(t_vh, t_fh);      do      {  idx = t_fc->index(t_vh);	 t_target_vh = t_fc->vertex(ctp.ccw(idx));	 // assertion	 if ( ctp.is_infinite(t_target_vh) )         {  ostr << " -> Vertex cycle is not simple; edges overlap.";            return false;	 }	 // create new svertex in SM         dir = Sphere_point ( CGAL::ORIGIN+	    (t_target_vh->point() - t_vh->point()) );	 // assertion	 if ( dir == dir_0 )         {  ostr << " -> Vertex cycle is not simple; edges overlap.";            return false;	 }	 p_svh = SVertex_handle (p_dec.new_svertex(dir));	 p_svh->mark() = true;	 // create new sphere edges in SM         SHalfedge_handle p_seh =	    p_dec.new_shalfedge_pair (p_svh_pred, p_svh);         Sphere_circle p_scirc	    (p_seh->source()->point(), p_seh->target()->point());         p_seh->circle() = p_scirc;         p_seh->twin()->circle() = p_scirc.opposite();         p_seh->mark() = p_seh->twin()->mark() = true;	 // constrained edge detected?	 if ((cond = t_fc->is_constrained(ctp.cw(idx))))	 {  // create new sface in SM	    SFace_handle p_fh = p_dec.new_sface ();	    p_fh->mark() = false;	    p_dec.link_as_face_cycle(p_seh,p_fh);	    break;	 }	 p_svh_pred = p_svh;      } while (--t_fc != t_fc_0)      ; CGAL_assertion ( cond ); // do-while ends with break      // check      p_dec.check_integrity_and_topological_planarity();      // prepare next iteration      t_fh = t_fc;      // assertion      --t_fc;      while (--t_fc != t_fc_0)      {  idx = t_fc->index(t_vh);	 if ( t_fc->is_constrained(ctp.ccw(idx)) )         {  ostr << " -> Vertex cycle is not simple; edge contains vertex.";            return false;         }      }      // prepare next iteration      t_vh = t_fh->vertex(ctp.ccw(t_fh->index(t_vh)));   } while (t_vh != t_vh_0)   ; // do-while ends   return true;}// II - input iterator; KN - kernel of normal// return value reports success ("true" means snc contains result)template <class Nef_3, class II, class KN>bool vertex_cycle_to_nef_3 (   typename Nef_3::SNC_structure &snc, II v_first, II v_last,   const CGAL::Vector_3<KN> &normal, bool verb = false){   // Constrained_triangulation_plus with Exact_intersections_tag   typedef typename Nef_3::Kernel          Kernel;   typedef CGAL::Exact_intersections_tag   Tri_itag;   // XY projection + triangulationtypedef CGAL::Exact_triangulation_euclidean_traits_xy_3<Kernel>  XY_kernel;typedef CGAL::Triangulation_vertex_base_2<XY_kernel>             XY_vb;typedef CGAL::Constrained_triangulation_face_base_2<XY_kernel>   XY_fb;typedef CGAL::Triangulation_data_structure_2<XY_vb,XY_fb>        XY_ds;typedef CGAL::Constrained_triangulation_2<XY_kernel, XY_ds, Tri_itag> XY_tri;typedef CGAL::Constrained_triangulation_plus_2<XY_tri>     XY_tri_plus;   // XZ projection + triangulationtypedef CGAL::Exact_triangulation_euclidean_traits_xz_3<Kernel>  XZ_kernel;typedef CGAL::Triangulation_vertex_base_2<XZ_kernel>             XZ_vb;typedef CGAL::Constrained_triangulation_face_base_2<XZ_kernel>   XZ_fb;typedef CGAL::Triangulation_data_structure_2<XZ_vb,XZ_fb>        XZ_ds;typedef CGAL::Constrained_triangulation_2<XZ_kernel, XZ_ds, Tri_itag> XZ_tri;typedef CGAL::Constrained_triangulation_plus_2<XZ_tri>     XZ_tri_plus;   // YZ projection + triangulationtypedef CGAL::Exact_triangulation_euclidean_traits_yz_3<Kernel>  YZ_kernel;typedef CGAL::Triangulation_vertex_base_2<YZ_kernel>             YZ_vb;typedef CGAL::Constrained_triangulation_face_base_2<YZ_kernel>   YZ_fb;typedef CGAL::Triangulation_data_structure_2<YZ_vb,YZ_fb>        YZ_ds;typedef CGAL::Constrained_triangulation_2<YZ_kernel, YZ_ds, Tri_itag> YZ_tri;typedef CGAL::Constrained_triangulation_plus_2<YZ_tri>     YZ_tri_plus;   // defaults   bool is_nef = false;   char direc='?';   snc.clear();   std::ostringstream ostr;   if ( normal == NULL_VECTOR )   {  // report it      ostr << " -> function parameter 'normal' is NULL_VECTOR"	   << " (this can be a symptom of an error).";   }   if ( normal != NULL_VECTOR )   {  // projection depending on normal vector      direc='z';      if ( CGAL::abs(normal.x()) > CGAL::abs(normal.y()) )      {  if ( CGAL::abs(normal.x()) > CGAL::abs(normal.z()) ) direc='x';      }      else      {  if ( CGAL::abs(normal.y()) > CGAL::abs(normal.z()) ) direc='y';      }      // project and triangulate vertices,      // convert result to Nef polyhedron      ostr << " Direction of projection is '" << direc << "'.";      if ( direc == 'x' )      {  is_nef = projected_vertex_cycle_to_nef_3<YZ_tri_plus,Nef_3> (                  snc, v_first, v_last, ostr);      }      else if ( direc == 'y' )      {  is_nef = projected_vertex_cycle_to_nef_3<XZ_tri_plus,Nef_3> (                  snc, v_first, v_last, ostr);      }      else      {  CGAL_assertion ( direc == 'z' );         is_nef = projected_vertex_cycle_to_nef_3<XY_tri_plus,Nef_3> (                  snc, v_first, v_last, ostr);      }   }   if ( !is_nef )   {  // if conversion is unsuccessful so far, try another projection      if ( !is_nef && direc != 'x' )      {  ostr << " Now, direction of projection is 'x'.";	 is_nef = projected_vertex_cycle_to_nef_3<YZ_tri_plus,Nef_3> (                  snc, v_first, v_last, ostr);      }      if ( !is_nef && direc != 'y' )      {  ostr << " Now, direction of projection is 'y'.";         is_nef = projected_vertex_cycle_to_nef_3<XZ_tri_plus,Nef_3> (                  snc, v_first, v_last, ostr);      }      if ( !is_nef && direc != 'z' )      {  ostr << " Now, direction of projection is 'z'.";         is_nef = projected_vertex_cycle_to_nef_3<XY_tri_plus,Nef_3> (                  snc, v_first, v_last, ostr);      }   }   // no successful conversion?   if ( !is_nef && verb )   {  std::cerr << "\nConversion from vertex cycle to Nef_polyhedron_3"	 << " was not successful. Error history:"         << ostr.str().c_str()	 << " Finally, empty Nef_polyhedron_3 was constructed." << std::endl;   }   return is_nef;}CGAL_END_NAMESPACE#endif // CGAL_NEF_VERTEX_CYCLE_TO_NEF_3_H

⌨️ 快捷键说明

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