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