1 // Copyright (c) 1997-2002  Max-Planck-Institute Saarbruecken (Germany).
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/Nef_3/include/CGAL/Nef_3/SNC_indexed_items.h $
7 // $Id: SNC_indexed_items.h 2a54687 2021-06-04T13:52:14+02:00 albert-github
8 // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
9 //
10 //
11 // Author(s)     :     Peter Hachenberger  <hachenberger@mpi-sb.mpg.de>
12 
13 #ifndef CGAL_NEF_SNC_INDEXED_ITEMS_H
14 #define CGAL_NEF_SNC_INDEXED_ITEMS_H
15 
16 #include <CGAL/license/Nef_3.h>
17 
18 #include <CGAL/Nef_3/Vertex.h>
19 #include <CGAL/Nef_3/Halfedge.h>
20 #include <CGAL/Nef_3/Halffacet.h>
21 #include <CGAL/Nef_3/Volume.h>
22 #include <CGAL/Nef_3/SHalfedge.h>
23 #include <CGAL/Nef_3/SHalfloop.h>
24 #include <CGAL/Nef_3/SFace.h>
25 
26 #include <atomic>
27 
28 #undef CGAL_NEF_DEBUG
29 #define CGAL_NEF_DEBUG 83
30 #include <CGAL/Nef_2/debug.h>
31 
32 namespace CGAL {
33 
34 class Index_generator {
35 
36  public:
get_unique_index()37   static int get_unique_index()
38   {
39     // initialized with 0
40     // https://en.cppreference.com/w/cpp/language/zero_initialization
41 #ifdef CGAL_NO_ATOMIC
42     static int unique;
43 #else
44     static std::atomic<int> unique;
45 #endif
46     return unique++;
47   }
48 };
49 
50 class SNC_indexed_items {
51  public:
52   template <class Refs> class Vertex :    public Vertex_base<Refs> {};
53   template <class Refs> class Volume :    public Volume_base<Refs> {};
54   template <class Refs> class SFace :     public SFace_base<Refs> {};
55 
56   template <class Refs> class Halffacet : public Halffacet_base<Refs> {
57     typedef Halffacet_base<Refs>    Base;
58     typedef typename Refs::SHalfedge_around_facet_const_circulator
59       SHalfedge_around_facet_const_circulator;
60     typedef typename Refs::SHalfedge_const_handle
61       SHalfedge_const_handle;
62     typedef typename Refs::SHalfloop_const_handle
63       SHalfloop_const_handle;
64     typedef typename Refs::Halffacet_cycle_const_iterator
65       Halffacet_cycle_const_iterator;
66     typedef typename Refs::Plane_3  Plane_3;
67     typedef typename Refs::Mark     Mark;
68 
69   public:
Halffacet()70     Halffacet() : Base() {}
Halffacet(const Plane_3 & h,Mark m)71     Halffacet(const Plane_3& h, Mark m) : Base(h, m) {}
72 
73     bool is_valid( bool verb = false, int level = 0) const {
74       bool valid = Base::is_valid(verb, level);
75 
76       Halffacet_cycle_const_iterator
77         fci(this->facet_cycles_begin());
78       if(!fci.is_shalfedge()) return false;
79       SHalfedge_const_handle set(fci);
80       int index = set->get_index();
81       for(; fci != this->facet_cycles_end(); ++fci) {
82         if(fci.is_shalfedge()) {
83           SHalfedge_const_handle se(fci);
84           SHalfedge_around_facet_const_circulator
85             sfc(se), send(sfc);
86           do {
87             valid = valid && sfc->get_index() == index;
88             ++sfc;
89           } while(sfc != send);
90         } else if(fci.is_shalfloop()) {
91           SHalfloop_const_handle sl(fci);
92           valid = valid && sl->get_index() == index;
93         } else
94           return false;
95       }
96       return valid;
97     }
98   };
99 
100   template <class Refs> class SHalfloop : public SHalfloop_base<Refs> {
101     typedef SHalfloop_base<Refs>                    Base;
102     typedef typename Refs::Halffacet_const_handle Halffacet_const_handle;
103     int index;
104     Halffacet_const_handle ifacet;
105     bool init_ifacet;
106   public:
SHalfloop()107     SHalfloop() : Base(), index(0), init_ifacet(false) {}
SHalfloop(const SHalfloop<Refs> & sl)108     SHalfloop(const SHalfloop<Refs>& sl)
109       : Base(sl), index(0),
110       ifacet(sl.ifacet), init_ifacet(sl.init_ifacet) {}
111     SHalfloop<Refs>& operator=(const SHalfloop<Refs>& sl) {
112       (Base&) *this = (Base) sl;
113       index = sl.index;
114       ifacet = sl.ifacet;
115       init_ifacet = sl.init_ifacet;
116       return *this;
117     }
new_index()118     int new_index()
119     { index = Index_generator::get_unique_index(); return index; }
set_index(int idx)120     void set_index(int idx)
121     { index = idx; }
get_index()122     int get_index() const { return index; }
get_index_facet()123     Halffacet_const_handle get_index_facet() const {
124       if(init_ifacet)
125         return ifacet;
126       return this->facet();
127     }
set_index_facet(Halffacet_const_handle f)128     void set_index_facet(Halffacet_const_handle f) {
129       ifacet = f;
130       init_ifacet = true;
131     }
132   };
133 
134   template <class Refs> class SHalfedge : public SHalfedge_base<Refs> {
135     typedef SHalfedge_base<Refs>                    Base;
136     typedef typename Refs::Halffacet_const_handle Halffacet_const_handle;
137     int index;
138     int index2;
139     Halffacet_const_handle ifacet;
140     bool init_ifacet;
141   public:
SHalfedge()142     SHalfedge() : Base(), index(0), index2(0), init_ifacet(false) {}
SHalfedge(const SHalfedge<Refs> & se)143     SHalfedge(const SHalfedge<Refs>& se)
144       : Base(se), index(se.index), index2(se.index2),
145       ifacet(se.ifacet), init_ifacet(se.init_ifacet) {}
146     SHalfedge<Refs>& operator=(const SHalfedge<Refs>& se) {
147       (Base&) *this = (Base) se;
148       index = se.index;
149       index2 = se.index2;
150       ifacet = se.ifacet;
151       init_ifacet = se.init_ifacet;
152       return *this;
153     }
new_index()154     int new_index()
155     { index = index2 = Index_generator::get_unique_index(); return index; }
set_index(int idx)156     void set_index(int idx)
157     { index = index2 = idx; }
get_index()158     int get_index() const {
159       return index;
160     }
set_forward_index(int idx)161     void set_forward_index(int idx)  { index  = idx;}
set_backward_index(int idx)162     void set_backward_index(int idx) { index2 = idx;}
get_forward_index()163     int get_forward_index() { return index;  }
get_backward_index()164     int get_backward_index() { return index2; }
get_smaller_index()165     int get_smaller_index() { return index < index2 ? index : index2; }
get_index_facet()166     Halffacet_const_handle get_index_facet() const {
167       if(init_ifacet)
168         return ifacet;
169       return this->facet();
170     }
set_index_facet(Halffacet_const_handle f)171     void set_index_facet(Halffacet_const_handle f) {
172       ifacet = f;
173       init_ifacet = true;
174     }
175   };
176 
177   template <class Refs> class SVertex :   public Halfedge_base<Refs> {
178     typedef Halfedge_base<Refs>          Base;
179     typedef typename Refs::Mark          Mark;
180     int index;
181   public:
SVertex()182     SVertex() : Base(), index(0) {}
SVertex(Mark m)183     SVertex(Mark m) : Base(m), index(0) {}
SVertex(const SVertex<Refs> & sv)184     SVertex(const SVertex<Refs>& sv) : Base(sv) { index = sv.index; }
185     SVertex<Refs>& operator=(const SVertex<Refs>& sv) {
186       (Base&) *this = (Base) sv;
187       index = sv.index;
188       return *this;
189     }
new_index()190     int new_index()
191     { index = Index_generator::get_unique_index(); return index; }
set_index(int idx)192     void set_index(int idx)
193     { index = idx; }
get_index()194     int get_index() const { return index; }
195   };
196 };
197 
198 } //namespace CGAL
199 #endif // CGAL_NEF_SNC_INDEXED_ITEMS_H
200