1 // Copyright (c) 2005 Rijksuniversiteit Groningen (Netherlands) 2 // All rights reserved. 3 // 4 // This file is part of CGAL (www.cgal.org). 5 // 6 // $URL: https://github.com/CGAL/cgal/blob/v5.3/Skin_surface_3/include/CGAL/subdivide_skin_surface_mesh_3.h $ 7 // $Id: subdivide_skin_surface_mesh_3.h 254d60f 2019-10-19T15:23:19+02:00 Sébastien Loriot 8 // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial 9 // 10 // 11 // Author(s) : Nico Kruithof <Nico@cs.rug.nl> 12 13 #ifndef CGAL_SUBDIVIDE_SKIN_SURFACE_MESH_3_H 14 #define CGAL_SUBDIVIDE_SKIN_SURFACE_MESH_3_H 15 16 #include <CGAL/license/Skin_surface_3.h> 17 18 #include <CGAL/Skin_surface_refinement_policy_3.h> 19 #include <CGAL/Polyhedron_3.h> 20 21 namespace CGAL { 22 23 // This code is based on the Polyhedron tutorial 24 25 template <class SkinSurface_3, 26 class Polyhedron_3, 27 class SubdivisionPolicy_3> 28 class Skin_surface_sqrt3 29 { 30 typedef Polyhedron_3 Polyhedron; 31 typedef SkinSurface_3 Skin_surface_3; 32 // Projects points to the skin surface: 33 typedef SubdivisionPolicy_3 Subdivision_policy; 34 35 typedef typename Polyhedron::Traits Kernel; 36 typedef typename Kernel::Point_3 Point; 37 typedef typename Kernel::Vector_3 Vector; 38 39 typedef typename Polyhedron::Vertex Vertex; 40 typedef typename Polyhedron::Vertex_handle Vertex_handle; 41 typedef typename Polyhedron::Vertex_iterator Vertex_iterator; 42 typedef typename Polyhedron::Edge_iterator Edge_iterator; 43 typedef typename Polyhedron::Halfedge_handle Halfedge_handle; 44 typedef typename Polyhedron::Halfedge_iterator Halfedge_iterator; 45 typedef typename Polyhedron::Halfedge_around_vertex_const_circulator 46 HV_circulator; 47 typedef typename Polyhedron::Halfedge_around_facet_circulator 48 HF_circulator; 49 typedef typename Polyhedron::Facet Facet; 50 typedef typename Polyhedron::Facet_handle Facet_handle; 51 typedef typename Polyhedron::Facet_iterator Facet_iterator; 52 typedef typename Kernel::FT FT; 53 54 public: Skin_surface_sqrt3(const SkinSurface_3 & skin,Polyhedron & P,const SubdivisionPolicy_3 & policy)55 Skin_surface_sqrt3(const SkinSurface_3 &skin, 56 Polyhedron &P, 57 const SubdivisionPolicy_3 &policy) 58 : P(P), ss(skin), policy(policy) { } 59 60 //********************************************* 61 // Subdivision 62 //********************************************* 63 int subdivide(int iter=1) 64 { 65 // check for valid polygon mesh 66 if(P.size_of_facets() == 0) 67 return false; 68 69 // normalize border: there is no border 70 P.normalize_border(); 71 72 while (iter > 0) { 73 do_subdivide(); 74 iter--; 75 } 76 return true; 77 } 78 79 private: 80 81 //********************************************* 82 // Subdivide 83 //********************************************* do_subdivide()84 void do_subdivide() 85 { 86 // We use that new vertices/halfedges/facets are appended at the end. 87 Vertex_iterator last_v = P.vertices_end(); 88 -- last_v; // the last of the old vertices 89 Edge_iterator last_e = P.edges_end(); 90 -- last_e; // the last of the old edges 91 Facet_iterator last_f = P.facets_end(); 92 -- last_f; // the last of the old facets 93 94 // split edges 95 Edge_iterator e = P.edges_begin (); 96 do { 97 split_halfedge(e); 98 } while ( e++ != last_e); 99 100 Vertex_iterator v = P.vertices_begin(); 101 do { 102 Halfedge_handle h_cir, h_start; 103 h_cir = h_start = v->halfedge () ; 104 do { 105 P.split_facet (h_cir->prev(), h_cir->next()); 106 h_cir = h_cir->next()->opposite(); 107 } while (h_cir != h_start); 108 } while (v++ != last_v); 109 110 v = ++last_v; // First new vertex 111 last_v = P.vertices_end(); 112 do { 113 v->point() = policy.to_surface(v); 114 } while (++v != last_v); 115 } 116 117 //********************************************* 118 // Split halfedge 119 //********************************************* split_halfedge(Halfedge_handle e)120 void split_halfedge(Halfedge_handle e) 121 { 122 // Create a new vertices on e. 123 Point p_new = e->vertex()->point(); 124 e = e->prev(); 125 p_new = p_new + .5*(e->vertex()->point()-p_new); 126 127 P.split_vertex( e, e->next()->opposite()); 128 e->next()->vertex()->point() = p_new; 129 } 130 131 Polyhedron &P; 132 const SkinSurface_3 &ss; 133 const Subdivision_policy &policy; 134 }; 135 136 template <class SkinSurface_3, class Polyhedron_3> 137 void subdivide_skin_surface_mesh_3(const SkinSurface_3 &skin, 138 Polyhedron_3 &p, 139 int nSubdiv = 1) { 140 while (nSubdiv > 0) { 141 skin.subdivide_mesh_3(p); 142 nSubdiv--; 143 } 144 } 145 146 } //namespace CGAL 147 148 #endif // CGAL_SUBDIVIDE_SKIN_SURFACE_MESH_3_H 149