1 /* ========================================================================= *
2  *                                                                           *
3  *                               OpenMesh                                    *
4  *           Copyright (c) 2001-2015, RWTH-Aachen University                 *
5  *           Department of Computer Graphics and Multimedia                  *
6  *                          All rights reserved.                             *
7  *                            www.openmesh.org                               *
8  *                                                                           *
9  *---------------------------------------------------------------------------*
10  * This file is part of OpenMesh.                                            *
11  *---------------------------------------------------------------------------*
12  *                                                                           *
13  * Redistribution and use in source and binary forms, with or without        *
14  * modification, are permitted provided that the following conditions        *
15  * are met:                                                                  *
16  *                                                                           *
17  * 1. Redistributions of source code must retain the above copyright notice, *
18  *    this list of conditions and the following disclaimer.                  *
19  *                                                                           *
20  * 2. Redistributions in binary form must reproduce the above copyright      *
21  *    notice, this list of conditions and the following disclaimer in the    *
22  *    documentation and/or other materials provided with the distribution.   *
23  *                                                                           *
24  * 3. Neither the name of the copyright holder nor the names of its          *
25  *    contributors may be used to endorse or promote products derived from   *
26  *    this software without specific prior written permission.               *
27  *                                                                           *
28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS       *
29  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A           *
31  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,  *
33  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,       *
34  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR        *
35  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF    *
36  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING      *
37  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS        *
38  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              *
39  *                                                                           *
40  * ========================================================================= */
41 
42 
43 
44 #ifndef OPENMESH_ATTRIBKERNEL_HH
45 #define OPENMESH_ATTRIBKERNEL_HH
46 
47 
48 //== INCLUDES =================================================================
49 
50 #include <OpenMesh/Core/Mesh/Attributes.hh>
51 #include <OpenMesh/Core/Utils/GenProg.hh>
52 #include <OpenMesh/Core/Utils/vector_traits.hh>
53 #include <vector>
54 #include <algorithm>
55 
56 //== NAMESPACES ===============================================================
57 
58 namespace OpenMesh {
59 
60 
61 //== CLASS DEFINITION =========================================================
62 
63 /** \class AttribKernelT AttribKernelT.hh <OpenMesh/Mesh/AttribKernelT.hh>
64 
65  The attribute kernel adds all standard properties to the kernel. Therefore
66  the functions/types defined here provide a subset of the kernel
67  interface as described in Concepts::KernelT.
68 
69  \see Concepts::KernelT
70 */
71 template <class MeshItems, class Connectivity>
72 class AttribKernelT : public Connectivity
73 {
74 public:
75 
76   //---------------------------------------------------------------- item types
77 
78   typedef MeshItems MeshItemsT;
79   typedef Connectivity ConnectivityT;
80   typedef typename Connectivity::Vertex     Vertex;
81   typedef typename Connectivity::Halfedge   Halfedge;
82   typedef typename Connectivity::Edge       Edge;
83   typedef typename Connectivity::Face       Face;
84 
85   typedef typename MeshItems::Point         Point;
86   typedef typename MeshItems::Normal        Normal;
87   typedef typename MeshItems::Color         Color;
88   typedef typename MeshItems::TexCoord1D    TexCoord1D;
89   typedef typename MeshItems::TexCoord2D    TexCoord2D;
90   typedef typename MeshItems::TexCoord3D    TexCoord3D;
91   typedef typename MeshItems::Scalar        Scalar;
92   typedef typename MeshItems::TextureIndex  TextureIndex;
93 
94   typedef typename MeshItems::VertexData    VertexData;
95   typedef typename MeshItems::HalfedgeData  HalfedgeData;
96   typedef typename MeshItems::EdgeData      EdgeData;
97   typedef typename MeshItems::FaceData      FaceData;
98 
99   typedef AttribKernelT<MeshItems,Connectivity>  AttribKernel;
100 
101   enum Attribs  {
102     VAttribs = MeshItems::VAttribs,
103     HAttribs = MeshItems::HAttribs,
104     EAttribs = MeshItems::EAttribs,
105     FAttribs = MeshItems::FAttribs
106   };
107 
108   typedef VPropHandleT<VertexData>          DataVPropHandle;
109   typedef HPropHandleT<HalfedgeData>        DataHPropHandle;
110   typedef EPropHandleT<EdgeData>            DataEPropHandle;
111   typedef FPropHandleT<FaceData>            DataFPropHandle;
112 
113   typedef VPropHandleT<Point>               PointsPropertyHandle;
114   typedef VPropHandleT<Normal>              VertexNormalsPropertyHandle;
115   typedef VPropHandleT<Color>               VertexColorsPropertyHandle;
116   typedef VPropHandleT<TexCoord1D>          VertexTexCoords1DPropertyHandle;
117   typedef VPropHandleT<TexCoord2D>          VertexTexCoords2DPropertyHandle;
118   typedef VPropHandleT<TexCoord3D>          VertexTexCoords3DPropertyHandle;
119   typedef HPropHandleT<TexCoord1D>          HalfedgeTexCoords1DPropertyHandle;
120   typedef HPropHandleT<TexCoord2D>          HalfedgeTexCoords2DPropertyHandle;
121   typedef HPropHandleT<TexCoord3D>          HalfedgeTexCoords3DPropertyHandle;
122   typedef EPropHandleT<Color>               EdgeColorsPropertyHandle;
123   typedef HPropHandleT<Normal>              HalfedgeNormalsPropertyHandle;
124   typedef HPropHandleT<Color>               HalfedgeColorsPropertyHandle;
125   typedef FPropHandleT<Normal>              FaceNormalsPropertyHandle;
126   typedef FPropHandleT<Color>               FaceColorsPropertyHandle;
127   typedef FPropHandleT<TextureIndex>        FaceTextureIndexPropertyHandle;
128 
129 public:
130 
131   //-------------------------------------------------- constructor / destructor
132 
AttribKernelT()133   AttribKernelT()
134   : refcount_vnormals_(0),
135     refcount_vcolors_(0),
136     refcount_vtexcoords1D_(0),
137     refcount_vtexcoords2D_(0),
138     refcount_vtexcoords3D_(0),
139     refcount_htexcoords1D_(0),
140     refcount_htexcoords2D_(0),
141     refcount_htexcoords3D_(0),
142     refcount_henormals_(0),
143     refcount_hecolors_(0),
144     refcount_ecolors_(0),
145     refcount_fnormals_(0),
146     refcount_fcolors_(0),
147     refcount_ftextureIndex_(0)
148   {
149     this->add_property( points_, "v:points" );
150 
151     if (VAttribs & Attributes::Normal)
152       request_vertex_normals();
153 
154     if (VAttribs & Attributes::Color)
155       request_vertex_colors();
156 
157     if (VAttribs & Attributes::TexCoord1D)
158       request_vertex_texcoords1D();
159 
160     if (VAttribs & Attributes::TexCoord2D)
161       request_vertex_texcoords2D();
162 
163     if (VAttribs & Attributes::TexCoord3D)
164       request_vertex_texcoords3D();
165 
166     if (HAttribs & Attributes::TexCoord1D)
167       request_halfedge_texcoords1D();
168 
169     if (HAttribs & Attributes::TexCoord2D)
170       request_halfedge_texcoords2D();
171 
172     if (HAttribs & Attributes::TexCoord3D)
173       request_halfedge_texcoords3D();
174 
175     if (HAttribs & Attributes::Color)
176       request_halfedge_colors();
177 
178     if (VAttribs & Attributes::Status)
179       Connectivity::request_vertex_status();
180 
181     if (HAttribs & Attributes::Status)
182       Connectivity::request_halfedge_status();
183 
184     if (HAttribs & Attributes::Normal)
185       request_halfedge_normals();
186 
187     if (EAttribs & Attributes::Status)
188       Connectivity::request_edge_status();
189 
190     if (EAttribs & Attributes::Color)
191       request_edge_colors();
192 
193     if (FAttribs & Attributes::Normal)
194       request_face_normals();
195 
196     if (FAttribs & Attributes::Color)
197       request_face_colors();
198 
199     if (FAttribs & Attributes::Status)
200       Connectivity::request_face_status();
201 
202     if (FAttribs & Attributes::TextureIndex)
203       request_face_texture_index();
204 
205     //FIXME: data properties might actually cost storage even
206     //if there are no data traits??
207     this->add_property(data_vpph_);
208     this->add_property(data_fpph_);
209     this->add_property(data_hpph_);
210     this->add_property(data_epph_);
211   }
212 
~AttribKernelT()213   virtual ~AttribKernelT()
214   {
215     // should remove properties, but this will be done in
216     // BaseKernel's destructor anyway...
217   }
218 
219   /** Assignment from another mesh of \em another type.
220       \note All that's copied is connectivity and vertex positions.
221       All other information (like e.g. attributes or additional
222       elements from traits classes) is not copied.
223       \note If you want to copy all information, including *custom* properties,
224       use PolyMeshT::operator=() instead.
225   */
226   template <class _AttribKernel>
assign(const _AttribKernel & _other,bool copyStandardProperties=false)227   void assign(const _AttribKernel& _other, bool copyStandardProperties = false)
228   {
229     //copy standard properties if necessary
230     if(copyStandardProperties)
231       this->copy_all_kernel_properties(_other);
232 
233     this->assign_connectivity(_other);
234     for (typename Connectivity::VertexIter v_it = Connectivity::vertices_begin();
235          v_it != Connectivity::vertices_end(); ++v_it)
236     {//assumes Point constructor supports cast from _AttribKernel::Point
237       set_point(*v_it, (Point)_other.point(*v_it));
238     }
239 
240     //initialize standard properties if necessary
241     if(copyStandardProperties)
242         initializeStandardProperties();
243   }
244 
245   //-------------------------------------------------------------------- points
246 
points() const247   const Point* points() const
248   { return this->property(points_).data(); }
249 
point(VertexHandle _vh) const250   const Point& point(VertexHandle _vh) const
251   { return this->property(points_, _vh); }
252 
point(VertexHandle _vh)253   Point& point(VertexHandle _vh)
254   { return this->property(points_, _vh); }
255 
set_point(VertexHandle _vh,const Point & _p)256   void set_point(VertexHandle _vh, const Point& _p)
257   { this->property(points_, _vh) = _p; }
258 
points_property_handle() const259   const PointsPropertyHandle& points_property_handle() const
260   { return points_; }
261 
262 
263   //------------------------------------------------------------ vertex normals
264 
vertex_normals() const265   const Normal* vertex_normals() const
266   { return this->property(vertex_normals_).data(); }
267 
normal(VertexHandle _vh) const268   const Normal& normal(VertexHandle _vh) const
269   { return this->property(vertex_normals_, _vh); }
270 
set_normal(VertexHandle _vh,const Normal & _n)271   void set_normal(VertexHandle _vh, const Normal& _n)
272   { this->property(vertex_normals_, _vh) = _n; }
273 
274 
275   //------------------------------------------------------------- vertex colors
276 
vertex_colors() const277   const Color* vertex_colors() const
278   { return this->property(vertex_colors_).data(); }
279 
color(VertexHandle _vh) const280   const Color& color(VertexHandle _vh) const
281   { return this->property(vertex_colors_, _vh); }
282 
set_color(VertexHandle _vh,const Color & _c)283   void set_color(VertexHandle _vh, const Color& _c)
284   { this->property(vertex_colors_, _vh) = _c; }
285 
286 
287   //------------------------------------------------------- vertex 1D texcoords
288 
texcoords1D() const289   const TexCoord1D* texcoords1D() const {
290     return this->property(vertex_texcoords1D_).data();
291   }
292 
texcoord1D(VertexHandle _vh) const293   const TexCoord1D& texcoord1D(VertexHandle _vh) const {
294     return this->property(vertex_texcoords1D_, _vh);
295   }
296 
set_texcoord1D(VertexHandle _vh,const TexCoord1D & _t)297   void set_texcoord1D(VertexHandle _vh, const TexCoord1D& _t) {
298     this->property(vertex_texcoords1D_, _vh) = _t;
299   }
300 
301 
302   //------------------------------------------------------- vertex 2D texcoords
303 
texcoords2D() const304   const TexCoord2D* texcoords2D() const {
305     return this->property(vertex_texcoords2D_).data();
306   }
307 
texcoord2D(VertexHandle _vh) const308   const TexCoord2D& texcoord2D(VertexHandle _vh) const {
309     return this->property(vertex_texcoords2D_, _vh);
310   }
311 
set_texcoord2D(VertexHandle _vh,const TexCoord2D & _t)312   void set_texcoord2D(VertexHandle _vh, const TexCoord2D& _t) {
313     this->property(vertex_texcoords2D_, _vh) = _t;
314   }
315 
316 
317   //------------------------------------------------------- vertex 3D texcoords
318 
texcoords3D() const319   const TexCoord3D* texcoords3D() const {
320     return this->property(vertex_texcoords3D_).data();
321   }
322 
texcoord3D(VertexHandle _vh) const323   const TexCoord3D& texcoord3D(VertexHandle _vh) const {
324     return this->property(vertex_texcoords3D_, _vh);
325   }
326 
set_texcoord3D(VertexHandle _vh,const TexCoord3D & _t)327   void set_texcoord3D(VertexHandle _vh, const TexCoord3D& _t) {
328     this->property(vertex_texcoords3D_, _vh) = _t;
329   }
330 
331   //.------------------------------------------------------ halfedge 1D texcoords
332 
htexcoords1D() const333   const TexCoord1D* htexcoords1D() const {
334     return this->property(halfedge_texcoords1D_).data();
335   }
336 
texcoord1D(HalfedgeHandle _heh) const337   const TexCoord1D& texcoord1D(HalfedgeHandle _heh) const {
338     return this->property(halfedge_texcoords1D_, _heh);
339   }
340 
set_texcoord1D(HalfedgeHandle _heh,const TexCoord1D & _t)341   void set_texcoord1D(HalfedgeHandle _heh, const TexCoord1D& _t) {
342     this->property(halfedge_texcoords1D_, _heh) = _t;
343   }
344 
345 
346   //------------------------------------------------------- halfedge 2D texcoords
347 
htexcoords2D() const348   const TexCoord2D* htexcoords2D() const {
349     return this->property(halfedge_texcoords2D_).data();
350   }
351 
texcoord2D(HalfedgeHandle _heh) const352   const TexCoord2D& texcoord2D(HalfedgeHandle _heh) const {
353     return this->property(halfedge_texcoords2D_, _heh);
354   }
355 
set_texcoord2D(HalfedgeHandle _heh,const TexCoord2D & _t)356   void set_texcoord2D(HalfedgeHandle _heh, const TexCoord2D& _t) {
357     this->property(halfedge_texcoords2D_, _heh) = _t;
358   }
359 
360 
361   //------------------------------------------------------- halfedge 3D texcoords
362 
htexcoords3D() const363   const TexCoord3D* htexcoords3D() const {
364     return this->property(halfedge_texcoords3D_).data();
365   }
366 
texcoord3D(HalfedgeHandle _heh) const367   const TexCoord3D& texcoord3D(HalfedgeHandle _heh) const {
368     return this->property(halfedge_texcoords3D_, _heh);
369   }
370 
set_texcoord3D(HalfedgeHandle _heh,const TexCoord3D & _t)371   void set_texcoord3D(HalfedgeHandle _heh, const TexCoord3D& _t) {
372     this->property(halfedge_texcoords3D_, _heh) = _t;
373   }
374 
375   //------------------------------------------------------------- edge colors
376 
edge_colors() const377   const Color* edge_colors() const
378   { return this->property(edge_colors_).data(); }
379 
color(EdgeHandle _eh) const380   const Color& color(EdgeHandle _eh) const
381   { return this->property(edge_colors_, _eh); }
382 
set_color(EdgeHandle _eh,const Color & _c)383   void set_color(EdgeHandle _eh, const Color& _c)
384   { this->property(edge_colors_, _eh) = _c; }
385 
386 
387   //------------------------------------------------------------- halfedge normals
388 
normal(HalfedgeHandle _heh) const389   const Normal& normal(HalfedgeHandle _heh) const
390   { return this->property(halfedge_normals_, _heh); }
391 
set_normal(HalfedgeHandle _heh,const Normal & _n)392   void set_normal(HalfedgeHandle _heh, const Normal& _n)
393   { this->property(halfedge_normals_, _heh) = _n; }
394 
395 
396   //------------------------------------------------------------- halfedge colors
397 
halfedge_colors() const398   const Color* halfedge_colors() const
399   { return this->property(halfedge_colors_).data(); }
400 
color(HalfedgeHandle _heh) const401   const Color& color(HalfedgeHandle _heh) const
402   { return this->property(halfedge_colors_, _heh); }
403 
set_color(HalfedgeHandle _heh,const Color & _c)404   void set_color(HalfedgeHandle _heh, const Color& _c)
405   { this->property(halfedge_colors_, _heh) = _c; }
406 
407   //-------------------------------------------------------------- face normals
408 
normal(FaceHandle _fh) const409   const Normal& normal(FaceHandle _fh) const
410   { return this->property(face_normals_, _fh); }
411 
set_normal(FaceHandle _fh,const Normal & _n)412   void set_normal(FaceHandle _fh, const Normal& _n)
413   { this->property(face_normals_, _fh) = _n; }
414 
415   //-------------------------------------------------------------- per Face Texture index
416 
texture_index(FaceHandle _fh) const417   const TextureIndex& texture_index(FaceHandle _fh) const
418   { return this->property(face_texture_index_, _fh); }
419 
set_texture_index(FaceHandle _fh,const TextureIndex & _t)420   void set_texture_index(FaceHandle _fh, const TextureIndex& _t)
421   { this->property(face_texture_index_, _fh) = _t; }
422 
423   //--------------------------------------------------------------- face colors
424 
color(FaceHandle _fh) const425   const Color& color(FaceHandle _fh) const
426   { return this->property(face_colors_, _fh); }
427 
set_color(FaceHandle _fh,const Color & _c)428   void set_color(FaceHandle _fh, const Color& _c)
429   { this->property(face_colors_, _fh) = _c; }
430 
431   //------------------------------------------------ request / alloc properties
432 
request_vertex_normals()433   void request_vertex_normals()
434   {
435     if (!refcount_vnormals_++)
436       this->add_property( vertex_normals_, "v:normals" );
437   }
438 
request_vertex_colors()439   void request_vertex_colors()
440   {
441     if (!refcount_vcolors_++)
442       this->add_property( vertex_colors_, "v:colors" );
443   }
444 
request_vertex_texcoords1D()445   void request_vertex_texcoords1D()
446   {
447     if (!refcount_vtexcoords1D_++)
448       this->add_property( vertex_texcoords1D_, "v:texcoords1D" );
449   }
450 
request_vertex_texcoords2D()451   void request_vertex_texcoords2D()
452   {
453     if (!refcount_vtexcoords2D_++)
454       this->add_property( vertex_texcoords2D_, "v:texcoords2D" );
455   }
456 
request_vertex_texcoords3D()457   void request_vertex_texcoords3D()
458   {
459     if (!refcount_vtexcoords3D_++)
460       this->add_property( vertex_texcoords3D_, "v:texcoords3D" );
461   }
462 
request_halfedge_texcoords1D()463   void request_halfedge_texcoords1D()
464   {
465     if (!refcount_htexcoords1D_++)
466       this->add_property( halfedge_texcoords1D_, "h:texcoords1D" );
467   }
468 
request_halfedge_texcoords2D()469   void request_halfedge_texcoords2D()
470   {
471     if (!refcount_htexcoords2D_++)
472       this->add_property( halfedge_texcoords2D_, "h:texcoords2D" );
473   }
474 
request_halfedge_texcoords3D()475   void request_halfedge_texcoords3D()
476   {
477     if (!refcount_htexcoords3D_++)
478       this->add_property( halfedge_texcoords3D_, "h:texcoords3D" );
479   }
480 
request_edge_colors()481   void request_edge_colors()
482   {
483     if (!refcount_ecolors_++)
484       this->add_property( edge_colors_, "e:colors" );
485   }
486 
request_halfedge_normals()487   void request_halfedge_normals()
488   {
489     if (!refcount_henormals_++)
490       this->add_property( halfedge_normals_, "h:normals" );
491   }
492 
request_halfedge_colors()493   void request_halfedge_colors()
494   {
495     if (!refcount_hecolors_++)
496       this->add_property( halfedge_colors_, "h:colors" );
497   }
498 
request_face_normals()499   void request_face_normals()
500   {
501     if (!refcount_fnormals_++)
502       this->add_property( face_normals_, "f:normals" );
503   }
504 
request_face_colors()505   void request_face_colors()
506   {
507     if (!refcount_fcolors_++)
508       this->add_property( face_colors_, "f:colors" );
509   }
510 
request_face_texture_index()511   void request_face_texture_index()
512   {
513     if (!refcount_ftextureIndex_++)
514       this->add_property( face_texture_index_, "f:textureindex" );
515   }
516 
517   //------------------------------------------------- release / free properties
518 
release_vertex_normals()519   void release_vertex_normals()
520   {
521     if ((refcount_vnormals_ > 0) && (! --refcount_vnormals_))
522       this->remove_property(vertex_normals_);
523   }
524 
release_vertex_colors()525   void release_vertex_colors()
526   {
527     if ((refcount_vcolors_ > 0) && (! --refcount_vcolors_))
528       this->remove_property(vertex_colors_);
529   }
530 
release_vertex_texcoords1D()531   void release_vertex_texcoords1D() {
532     if ((refcount_vtexcoords1D_ > 0) && (! --refcount_vtexcoords1D_))
533       this->remove_property(vertex_texcoords1D_);
534   }
535 
release_vertex_texcoords2D()536   void release_vertex_texcoords2D() {
537     if ((refcount_vtexcoords2D_ > 0) && (! --refcount_vtexcoords2D_))
538       this->remove_property(vertex_texcoords2D_);
539   }
540 
release_vertex_texcoords3D()541   void release_vertex_texcoords3D() {
542     if ((refcount_vtexcoords3D_ > 0) && (! --refcount_vtexcoords3D_))
543       this->remove_property(vertex_texcoords3D_);
544   }
545 
release_halfedge_texcoords1D()546   void release_halfedge_texcoords1D() {
547     if ((refcount_htexcoords1D_ > 0) && (! --refcount_htexcoords1D_))
548       this->remove_property(halfedge_texcoords1D_);
549   }
550 
release_halfedge_texcoords2D()551   void release_halfedge_texcoords2D() {
552     if ((refcount_htexcoords2D_ > 0) && (! --refcount_htexcoords2D_))
553       this->remove_property(halfedge_texcoords2D_);
554   }
555 
release_halfedge_texcoords3D()556   void release_halfedge_texcoords3D() {
557     if ((refcount_htexcoords3D_ > 0) && (! --refcount_htexcoords3D_))
558       this->remove_property(halfedge_texcoords3D_);
559   }
560 
release_edge_colors()561   void release_edge_colors()
562   {
563       if ((refcount_ecolors_ > 0) && (! --refcount_ecolors_))
564           this->remove_property(edge_colors_);
565   }
566 
release_halfedge_normals()567   void release_halfedge_normals()
568   {
569       if ((refcount_henormals_ > 0) && (! --refcount_henormals_))
570           this->remove_property(halfedge_normals_);
571   }
572 
release_halfedge_colors()573   void release_halfedge_colors()
574   {
575       if ((refcount_hecolors_ > 0) && (! --refcount_hecolors_))
576           this->remove_property(halfedge_colors_);
577   }
578 
release_face_normals()579   void release_face_normals()
580   {
581     if ((refcount_fnormals_ > 0) && (! --refcount_fnormals_))
582       this->remove_property(face_normals_);
583   }
584 
release_face_colors()585   void release_face_colors()
586   {
587     if ((refcount_fcolors_ > 0) && (! --refcount_fcolors_))
588       this->remove_property(face_colors_);
589   }
590 
release_face_texture_index()591   void release_face_texture_index()
592   {
593     if ((refcount_ftextureIndex_ > 0) && (! --refcount_ftextureIndex_))
594       this->remove_property(face_texture_index_);
595   }
596 
597   //---------------------------------------------- dynamic check for properties
598 
has_vertex_normals() const599   bool has_vertex_normals()       const { return vertex_normals_.is_valid();      }
has_vertex_colors() const600   bool has_vertex_colors()        const { return vertex_colors_.is_valid();       }
has_vertex_texcoords1D() const601   bool has_vertex_texcoords1D()   const { return vertex_texcoords1D_.is_valid();  }
has_vertex_texcoords2D() const602   bool has_vertex_texcoords2D()   const { return vertex_texcoords2D_.is_valid();  }
has_vertex_texcoords3D() const603   bool has_vertex_texcoords3D()   const { return vertex_texcoords3D_.is_valid();  }
has_halfedge_texcoords1D() const604   bool has_halfedge_texcoords1D() const { return halfedge_texcoords1D_.is_valid();}
has_halfedge_texcoords2D() const605   bool has_halfedge_texcoords2D() const { return halfedge_texcoords2D_.is_valid();}
has_halfedge_texcoords3D() const606   bool has_halfedge_texcoords3D() const { return halfedge_texcoords3D_.is_valid();}
has_edge_colors() const607   bool has_edge_colors()          const { return edge_colors_.is_valid();         }
has_halfedge_normals() const608   bool has_halfedge_normals()     const { return halfedge_normals_.is_valid();    }
has_halfedge_colors() const609   bool has_halfedge_colors()      const { return halfedge_colors_.is_valid();     }
has_face_normals() const610   bool has_face_normals()         const { return face_normals_.is_valid();        }
has_face_colors() const611   bool has_face_colors()          const { return face_colors_.is_valid();         }
has_face_texture_index() const612   bool has_face_texture_index()   const { return face_texture_index_.is_valid();  }
613 
614 public:
615   //standard vertex properties
points_pph() const616   PointsPropertyHandle                      points_pph() const
617   { return points_; }
618 
vertex_normals_pph() const619   VertexNormalsPropertyHandle               vertex_normals_pph() const
620   { return vertex_normals_; }
621 
vertex_colors_pph() const622   VertexColorsPropertyHandle                vertex_colors_pph() const
623   { return vertex_colors_; }
624 
vertex_texcoords1D_pph() const625   VertexTexCoords1DPropertyHandle           vertex_texcoords1D_pph() const
626   { return vertex_texcoords1D_; }
627 
vertex_texcoords2D_pph() const628   VertexTexCoords2DPropertyHandle           vertex_texcoords2D_pph() const
629   { return vertex_texcoords2D_; }
630 
vertex_texcoords3D_pph() const631   VertexTexCoords3DPropertyHandle           vertex_texcoords3D_pph() const
632   { return vertex_texcoords3D_; }
633 
634   //standard halfedge properties
halfedge_texcoords1D_pph() const635   HalfedgeTexCoords1DPropertyHandle           halfedge_texcoords1D_pph() const
636   { return halfedge_texcoords1D_; }
637 
halfedge_texcoords2D_pph() const638   HalfedgeTexCoords2DPropertyHandle           halfedge_texcoords2D_pph() const
639   { return halfedge_texcoords2D_; }
640 
halfedge_texcoords3D_pph() const641   HalfedgeTexCoords3DPropertyHandle           halfedge_texcoords3D_pph() const
642   { return halfedge_texcoords3D_; }
643 
644   // standard edge properties
halfedge_normals_pph() const645   HalfedgeNormalsPropertyHandle              halfedge_normals_pph() const
646   { return halfedge_normals_; }
647 
648 
649   // standard edge properties
halfedge_colors_pph() const650   HalfedgeColorsPropertyHandle              halfedge_colors_pph() const
651   { return halfedge_colors_; }
652 
653   // standard edge properties
edge_colors_pph() const654   EdgeColorsPropertyHandle                  edge_colors_pph() const
655   { return edge_colors_; }
656 
657   //standard face properties
face_normals_pph() const658   FaceNormalsPropertyHandle                 face_normals_pph() const
659   { return face_normals_; }
660 
face_colors_pph() const661   FaceColorsPropertyHandle                  face_colors_pph() const
662   { return face_colors_; }
663 
face_texture_index_pph() const664   FaceTextureIndexPropertyHandle            face_texture_index_pph() const
665   { return face_texture_index_; }
666 
data(VertexHandle _vh)667   VertexData&                               data(VertexHandle _vh)
668   { return this->property(data_vpph_, _vh); }
669 
data(VertexHandle _vh) const670   const VertexData&                         data(VertexHandle _vh) const
671   { return this->property(data_vpph_, _vh); }
672 
data(FaceHandle _fh)673   FaceData&                                 data(FaceHandle _fh)
674   { return this->property(data_fpph_, _fh); }
675 
data(FaceHandle _fh) const676   const FaceData&                           data(FaceHandle _fh) const
677   { return this->property(data_fpph_, _fh); }
678 
data(EdgeHandle _eh)679   EdgeData&                                 data(EdgeHandle _eh)
680   { return this->property(data_epph_, _eh); }
681 
data(EdgeHandle _eh) const682   const EdgeData&                           data(EdgeHandle _eh) const
683   { return this->property(data_epph_, _eh); }
684 
data(HalfedgeHandle _heh)685   HalfedgeData&                             data(HalfedgeHandle _heh)
686   { return this->property(data_hpph_, _heh); }
687 
data(HalfedgeHandle _heh) const688   const HalfedgeData&                       data(HalfedgeHandle _heh) const
689   { return this->property(data_hpph_, _heh); }
690 
691 private:
692   //standard vertex properties
693   PointsPropertyHandle                      points_;
694   VertexNormalsPropertyHandle               vertex_normals_;
695   VertexColorsPropertyHandle                vertex_colors_;
696   VertexTexCoords1DPropertyHandle           vertex_texcoords1D_;
697   VertexTexCoords2DPropertyHandle           vertex_texcoords2D_;
698   VertexTexCoords3DPropertyHandle           vertex_texcoords3D_;
699   //standard halfedge properties
700   HalfedgeTexCoords1DPropertyHandle         halfedge_texcoords1D_;
701   HalfedgeTexCoords2DPropertyHandle         halfedge_texcoords2D_;
702   HalfedgeTexCoords3DPropertyHandle         halfedge_texcoords3D_;
703   HalfedgeNormalsPropertyHandle             halfedge_normals_;
704   HalfedgeColorsPropertyHandle              halfedge_colors_;
705   // standard edge properties
706   EdgeColorsPropertyHandle                  edge_colors_;
707   //standard face properties
708   FaceNormalsPropertyHandle                 face_normals_;
709   FaceColorsPropertyHandle                  face_colors_;
710   FaceTextureIndexPropertyHandle            face_texture_index_;
711   //data properties handles
712   DataVPropHandle                           data_vpph_;
713   DataHPropHandle                           data_hpph_;
714   DataEPropHandle                           data_epph_;
715   DataFPropHandle                           data_fpph_;
716 
717   unsigned int                              refcount_vnormals_;
718   unsigned int                              refcount_vcolors_;
719   unsigned int                              refcount_vtexcoords1D_;
720   unsigned int                              refcount_vtexcoords2D_;
721   unsigned int                              refcount_vtexcoords3D_;
722   unsigned int                              refcount_htexcoords1D_;
723   unsigned int                              refcount_htexcoords2D_;
724   unsigned int                              refcount_htexcoords3D_;
725   unsigned int                              refcount_henormals_;
726   unsigned int                              refcount_hecolors_;
727   unsigned int                              refcount_ecolors_;
728   unsigned int                              refcount_fnormals_;
729   unsigned int                              refcount_fcolors_;
730   unsigned int                              refcount_ftextureIndex_;
731 
732   /**
733    * @brief initializeStandardProperties Initializes the standard properties
734    * and sets refcount to 1 if found. (e.g. when the copy constructor was used)
735    */
initializeStandardProperties()736   void initializeStandardProperties()
737   {
738       if(!this->get_property_handle(points_,
739                "v:points"))
740       {
741           //mesh has no points?
742       }
743       refcount_vnormals_ = this->get_property_handle(vertex_normals_,
744           "v:normals") ? 1 : 0 ;
745       refcount_vcolors_ = this->get_property_handle(vertex_colors_,
746           "v:colors") ? 1 : 0 ;
747       refcount_vtexcoords1D_ = this->get_property_handle(vertex_texcoords1D_,
748           "v:texcoords1D") ? 1 : 0 ;
749       refcount_vtexcoords2D_ = this->get_property_handle(vertex_texcoords2D_,
750           "v:texcoords2D") ? 1 : 0 ;
751       refcount_vtexcoords3D_ = this->get_property_handle(vertex_texcoords3D_,
752           "v:texcoords3D") ? 1 : 0 ;
753       refcount_htexcoords1D_ = this->get_property_handle(halfedge_texcoords1D_,
754           "h:texcoords1D") ? 1 : 0 ;
755       refcount_htexcoords2D_ = this->get_property_handle(halfedge_texcoords2D_,
756           "h:texcoords2D") ? 1 : 0 ;
757       refcount_htexcoords3D_ = this->get_property_handle(halfedge_texcoords3D_,
758           "h:texcoords3D") ? 1 : 0 ;
759       refcount_henormals_ = this->get_property_handle(halfedge_normals_,
760           "h:normals") ? 1 : 0 ;
761       refcount_hecolors_ = this->get_property_handle(halfedge_colors_,
762           "h:colors") ? 1 : 0 ;
763       refcount_ecolors_ = this->get_property_handle(edge_colors_,
764           "e:colors") ? 1 : 0 ;
765       refcount_fnormals_ = this->get_property_handle(face_normals_,
766           "f:normals") ? 1 : 0 ;
767       refcount_fcolors_ = this->get_property_handle(face_colors_,
768           "f:colors") ? 1 : 0 ;
769       refcount_ftextureIndex_ = this->get_property_handle(face_texture_index_,
770           "f:textureindex") ? 1 : 0 ;
771   }
772 };
773 
774 //=============================================================================
775 } // namespace OpenMesh
776 //=============================================================================
777 #endif // OPENMESH_ATTRIBKERNEL_HH defined
778 //=============================================================================
779