Developer Documentation
VolumeMeshBufferManagerT_impl.hh
1 /*===========================================================================*\
2  * *
3  * OpenFlipper *
4  * Copyright (c) 2001-2015, RWTH-Aachen University *
5  * Department of Computer Graphics and Multimedia *
6  * All rights reserved. *
7  * www.openflipper.org *
8  * *
9  *---------------------------------------------------------------------------*
10  * This file is part of OpenFlipper. *
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 #define VOLUMEMESHBUFFERMANAGERT_CC
44 
45 #include "VolumeMeshBufferManager.hh"
46 
47 template <class VolumeMesh>
52  :
53  mDefaultColor(ACG::Vec4f(0.0,0.0,0.0,1.0)),
54  mMesh(mesh_),
55  mStatusAttrib(statusAttrib_),
56  mColorAttrib(colorAttrib_),
57  mNormalAttrib(normalAttrib_),
58  mTexcoordAttrib(texcoordAttrib_),
59  mNumOfVertices(-1),
60  mCurrentNumOfVertices(-1),
61  mVertexSize(0),
62  mVertexDeclaration(),
63  mColorOffset(-1),
64  mNormalOffset(-1),
65  mScale(0.8),
66  mBuffer(0),
67  mCurrentPickOffset(-1),
68  mGlobalPickOffset(0),
69  mInvalidated(true),
70  mGeometryChanged(true),
71  mNormalsChanged(true),
72  mColorsChanged(true),
73  mTexCoordsChanged(true),
74  mDrawModes(),
75  mPrimitiveMode(PM_NONE),
76  mNormalMode(NM_NONE),
77  mColorMode(CM_NO_COLORS),
78  mSkipUnselected(false),
79  mShowIrregularInnerEdges(false),
80  mShowIrregularOuterValence2Edges(false),
81  mSkipRegularEdges(false),
82  mBoundaryOnly(false),
83  mCurrentPrimitiveMode(PM_NONE),
84  mCurrentNormalMode(NM_NONE),
85  mCurrentColorMode(CM_NO_COLORS),
86  mCurrentSkipUnselected(false),
87  mCurrentShowIrregularInnerEdges(false),
88  mCurrentShowIrregularOuterValence2Edges(false),
89  mCurrentSkipRegularEdges(false),
90  mCurrentBoundaryOnly(false),
91  mCurrentVertexSize(0),
92  mCurrentNormalOffset(0),
93  mCurrentColorOffset(0),
94  mCogsValid(false),
95  mCellInsidenessValid(),
96  mTexCoordMode(TCM_NONE),
97  mCurrentTexCoordMode(TCM_NONE),
98  mTexCoordOffset(0),
99  mCurrentTexCoordOffset(0)
100 {
101 
102 }
103 
113 template <class VolumeMesh>
114 void VolumeMeshBufferManager<VolumeMesh>::addFloatToBuffer( float _value, unsigned char *&_buffer )
115 {
116  // get pointer
117  unsigned char *v = (unsigned char *) &_value;
118 
119  // copy over 4 bytes
120  *_buffer++ = *v++;
121  *_buffer++ = *v++;
122  *_buffer++ = *v++;
123  *_buffer++ = *v;
124 }
125 
135 template <class VolumeMesh>
136 void VolumeMeshBufferManager<VolumeMesh>::addUCharToBuffer( unsigned char _value, unsigned char *&_buffer )
137 {
138  *_buffer = _value;
139  ++_buffer;
140 }
141 
152 template <class VolumeMesh>
153 void VolumeMeshBufferManager<VolumeMesh>::addPositionToBuffer(ACG::Vec3d _position, unsigned char* _buffer , unsigned int _offset)
154 {
155  unsigned char* buffer = _buffer + _offset*mVertexSize;
156  addFloatToBuffer(_position[0], buffer);
157  addFloatToBuffer(_position[1], buffer);
158  addFloatToBuffer(_position[2], buffer);
159 }
160 
171 template <class VolumeMesh>
172 void VolumeMeshBufferManager<VolumeMesh>::addColorToBuffer(ACG::Vec4uc _color, unsigned char* _buffer, unsigned int _offset)
173 {
174  unsigned char* buffer = _buffer + _offset*mVertexSize + mColorOffset;
175  addUCharToBuffer(_color[0], buffer);
176  addUCharToBuffer(_color[1], buffer);
177  addUCharToBuffer(_color[2], buffer);
178  addUCharToBuffer(_color[3], buffer);
179 }
180 
193 template <class VolumeMesh>
194 void VolumeMeshBufferManager<VolumeMesh>::addColorToBuffer(ACG::Vec4f _color, unsigned char* _buffer, unsigned int _offset)
195 {
196  unsigned char* buffer = _buffer + _offset*mVertexSize + mColorOffset;
197  addUCharToBuffer(_color[0]*255, buffer);
198  addUCharToBuffer(_color[1]*255, buffer);
199  addUCharToBuffer(_color[2]*255, buffer);
200  addUCharToBuffer(_color[3]*255, buffer);
201 }
202 
213 template <class VolumeMesh>
214 void VolumeMeshBufferManager<VolumeMesh>::addNormalToBuffer(ACG::Vec3d _normal, unsigned char* _buffer, unsigned int _offset)
215 {
216  unsigned char* buffer = _buffer + _offset*mVertexSize + mNormalOffset;
217  addFloatToBuffer(_normal[0], buffer);
218  addFloatToBuffer(_normal[1], buffer);
219  addFloatToBuffer(_normal[2], buffer);
220 }
221 
232 template <class VolumeMesh>
233 void VolumeMeshBufferManager<VolumeMesh>::addTexCoordToBuffer(ACG::Vec2f _texCoord, unsigned char* _buffer, unsigned int _offset)
234 {
235  unsigned char* buffer = _buffer + _offset*mVertexSize + mTexCoordOffset;
236  addFloatToBuffer(_texCoord[0], buffer);
237  addFloatToBuffer(_texCoord[1], buffer);
238 }
239 
240 
248 template <class VolumeMesh>
250 {
251  unsigned int currentOffset = 0;
252  mVertexDeclaration.clear();
253 
254  mNormalOffset = -1;
255  mColorOffset = -1;
256 
257  if (mPrimitiveMode != PM_NONE) //should always be the case
258  {
259  mVertexDeclaration.addElement(GL_FLOAT, 3, ACG::VERTEX_USAGE_POSITION, reinterpret_cast<GLuint*>(currentOffset),0, 0, mBuffer);
260  currentOffset += 3*sizeof(float);
261  }
262 
263  if (mNormalMode != NM_NONE)
264  {
265  mNormalOffset = currentOffset;
266  mVertexDeclaration.addElement(GL_FLOAT, 3, ACG::VERTEX_USAGE_NORMAL, reinterpret_cast<GLuint*>(currentOffset),0, 0, mBuffer);
267  currentOffset += 3*sizeof(float);
268  }
269 
270  if ((mColorMode != CM_NO_COLORS) || mShowIrregularInnerEdges || mShowIrregularOuterValence2Edges)
271  {
272  mColorOffset = currentOffset;
273  mVertexDeclaration.addElement(GL_UNSIGNED_BYTE, 4, ACG::VERTEX_USAGE_COLOR, reinterpret_cast<GLuint*>(currentOffset),0, 0, mBuffer);
274  currentOffset += 4*sizeof(char);
275  }
276 
277  if ((mTexCoordMode != TCM_NONE))
278  {
279  mTexCoordOffset = currentOffset;
280  unsigned char numOfCoords = 0;
281  if (mTexCoordMode == TCM_SINGLE_2D)
282  numOfCoords = 2;
283  mVertexDeclaration.addElement(GL_FLOAT, numOfCoords, ACG::VERTEX_USAGE_TEXCOORD, reinterpret_cast<GLuint*>(currentOffset),0, 0, mBuffer);
284  currentOffset += numOfCoords * sizeof(float);
285  }
286 
287  mVertexSize = currentOffset;
288 }
289 
290 
295 template <class VolumeMesh>
297 {
298  if (mNumOfVertices == -1)
300  return mNumOfVertices;
301 }
302 
310 template <class VolumeMesh>
312 {
313  if (mDefaultColor != _defaultColor)
314  {
316  mDefaultColor = _defaultColor;
317  }
318 }
319 
328 template <class VolumeMesh>
330 {
331  // colors
332  if (_drawMode & (mDrawModes.cellsColoredPerCell))
334  else if (_drawMode & (mDrawModes.cellsColoredPerFace | mDrawModes.facesColoredPerFace | mDrawModes.facesColoredPerFaceFlatShaded))
336  else if (_drawMode & (mDrawModes.cellsColoredPerHalfface | mDrawModes.halffacesColoredPerHalfface))
338  else if (_drawMode & ( mDrawModes.edgesColoredPerEdge ))
340  else if (_drawMode & (mDrawModes.halfedgesColoredPerHalfedge))
342  else if (_drawMode & (mDrawModes.cellsColoredPerVertex | mDrawModes.facesColoredPerVertex |
343  mDrawModes.halffacesColoredPerVertex | mDrawModes.edgesColoredPerEdge |
344  mDrawModes.verticesColored))
346  else
347  disableColors();
348 
349  //normals
350  if (_drawMode & (mDrawModes.cellsFlatShaded | mDrawModes.halffacesFlatShaded))
352  else if (_drawMode & (mDrawModes.facesFlatShaded | mDrawModes.facesTexturedShaded | mDrawModes.facesColoredPerFaceFlatShaded))
354  else if (_drawMode & (mDrawModes.cellsSmoothShaded | mDrawModes.facesSmoothShaded | mDrawModes.halffacesSmoothShaded |
355  mDrawModes.cellsPhongShaded | mDrawModes.facesPhongShaded | mDrawModes.halffacesPhongShaded |
356  mDrawModes.cellsColoredPerCell | mDrawModes.cellsColoredPerFace | mDrawModes.cellsColoredPerHalfface |
357  mDrawModes.cellsColoredPerVertex | mDrawModes.cellsTransparent))
359  else
360  disableNormals();
361 
362  if (_drawMode & (mDrawModes.irregularInnerEdges))
363  mShowIrregularInnerEdges = true;
364  else
365  mShowIrregularInnerEdges = false;
366 
367  if (_drawMode & (mDrawModes.irregularOuterEdges))
368  mShowIrregularOuterValence2Edges = true;
369  else
370  mShowIrregularOuterValence2Edges = false;
371 
372  if (!mShowIrregularInnerEdges && !mShowIrregularOuterValence2Edges)
373  mSkipRegularEdges = false;
374  else
375  mSkipRegularEdges = true;
376 
377 
378  // textures
379  if (_drawMode & (mDrawModes.facesTextured | mDrawModes.facesTexturedShaded))
380  mTexCoordMode = TCM_SINGLE_2D;
381  else
382  mTexCoordMode = TCM_NONE;
383 
384  // primiive mode
385  if (_drawMode & (mDrawModes.cellBasedDrawModes))
386  mPrimitiveMode = PM_CELLS;
387  else if (_drawMode & (mDrawModes.facesOnCells))
388  mPrimitiveMode = PM_FACES_ON_CELLS;
389  else if (_drawMode & (mDrawModes.faceBasedDrawModes | mDrawModes.hiddenLineBackgroundFaces))
390  mPrimitiveMode = PM_FACES;
391  else if (_drawMode & (mDrawModes.halffaceBasedDrawModes))
392  mPrimitiveMode = PM_HALFFACES;
393  else if (_drawMode & (mDrawModes.edgesOnCells))
394  mPrimitiveMode = PM_EDGES_ON_CELLS;
395  else if (_drawMode & ((mDrawModes.edgeBasedDrawModes) & ~(mDrawModes.irregularInnerEdges | mDrawModes.irregularOuterEdges)))
396  mPrimitiveMode = PM_EDGES;
397  else if (_drawMode & (mDrawModes.irregularInnerEdges | mDrawModes.irregularOuterEdges)) // note: this has to be checked after _drawMode & (mDrawModes.edgeBasedDrawModes)
398  mPrimitiveMode = PM_IRREGULAR_EDGES; // if this is true, irregular edges are already included
399  else if (_drawMode & (mDrawModes.halfedgeBasedDrawModes))
400  mPrimitiveMode = PM_HALFEDGES;
401  else if (_drawMode & (mDrawModes.verticesOnCells))
402  mPrimitiveMode = PM_VERTICES_ON_CELLS;
403  else if (_drawMode & (mDrawModes.vertexBasedDrawModes))
404  mPrimitiveMode = PM_VERTICES;
405  else
406  mPrimitiveMode = PM_NONE;
407 
408 
409 }
410 
411 
418 template <class VolumeMesh>
420 {
421  cut_planes_.clear();
423  mCellInsidenessValid = false;
424 }
425 
433 template <class VolumeMesh>
435 {
436  cut_planes_.push_back(_p);
438  mCellInsidenessValid = false;
439 }
440 
451 template <class VolumeMesh>
452 void VolumeMeshBufferManager<VolumeMesh>::addCutPlane(const ACG::Vec3d &_p, const ACG::Vec3d &_n, const ACG::Vec3d &_xsize, const ACG::Vec3d &_ysize)
453 {
454  addCutPlane(ACG::Geometry::Plane(_p, _n, _xsize, _ysize));
455 }
456 
464 template <class VolumeMesh>
466 {
467  for(typename std::vector<Plane>::iterator it = cut_planes_.begin(); it != cut_planes_.end(); ++it) {
468  // get local position
469  ACG::Vec3d pl = _p - it->position;
470  // evaluate dot products
471  double pn = (pl | it->normal);
472  double px = (pl | it->xDirection);
473  double py = (pl | it->yDirection);
474 
475  if (pn < 0.0 && px > -0.5 && px < 0.5 && py > -0.5 && py < 0.5)
476  return false;
477  }
478 
479  return true;
480 }
481 
491 template <class VolumeMesh>
493 {
494  if ( cut_planes_.empty() ) return true;
495  return is_inside(mMesh.vertex(_vh));
496 }
497 
507 template <class VolumeMesh>
509 {
510  if ( cut_planes_.empty() ) return true;
511  Edge e(mMesh.halfedge(_heh));
512  return is_inside(mMesh.vertex(e.from_vertex())) && is_inside(mMesh.vertex(e.to_vertex()));
513 }
514 
524 template <class VolumeMesh>
526 {
527  if ( cut_planes_.empty() ) return true;
528  Edge e(mMesh.edge(_eh));
529  return is_inside(mMesh.vertex(e.from_vertex())) && is_inside(mMesh.vertex(e.to_vertex()));
530 }
531 
541 template <class VolumeMesh>
543 {
544  if ( cut_planes_.empty() ) return true;
545  for (OpenVolumeMesh::HalfFaceVertexIter hfv_it = mMesh.hfv_iter(_hfh); hfv_it; ++hfv_it)
546  if (!is_inside(*hfv_it)) return false;
547 
548  return true;
549 }
550 
560 template <class VolumeMesh>
562 {
563  if ( cut_planes_.empty() ) return true;
564  return is_inside(mMesh.halfface_handle(_fh,0));
565 }
566 
578 template <class VolumeMesh>
580 {
581  if (!mCellInsidenessValid)
583 
584  return mCellInsideness[_ch.idx()];
585 }
586 
587 
594 template <class VolumeMesh>
596 {
597  if (mCellInsideness.size() != mMesh.n_cells())
598  mCellInsideness.resize(mMesh.n_cells());
599 
600  for (unsigned int i = 0; i < mMesh.n_cells(); i++)
601  {
602  CellHandle ch = CellHandle(i);
603  bool inside;
604  ACG::Vec3d cog = getCOG(ch);
605  if ( cut_planes_.empty() )
606  inside = true;
607  else
608  {
609  inside = true;
610  for (OpenVolumeMesh::CellVertexIter cv_it = mMesh.cv_iter(ch); cv_it; ++cv_it)
611  {
612  ACG::Vec3d vertexPos = mScale * mMesh.vertex(*cv_it) + (1-mScale) * cog;
613  if (!is_inside(vertexPos)) inside = false;
614  }
615  }
616  mCellInsideness[i] = inside;
617  }
618 
619  mCellInsidenessValid = true;
620 }
621 
622 
630 template <class VolumeMesh>
632 {
633  return mCurrentPrimitiveMode != mPrimitiveMode ||
634  mCurrentNormalMode != mNormalMode ||
635  mCurrentColorMode != mColorMode ||
636  mCurrentSkipUnselected != mSkipUnselected ||
637  mCurrentShowIrregularInnerEdges != mShowIrregularInnerEdges ||
638  mCurrentShowIrregularOuterValence2Edges != mShowIrregularOuterValence2Edges ||
639  mCurrentSkipRegularEdges != mSkipRegularEdges ||
640  mCurrentBoundaryOnly != mBoundaryOnly;
641 }
642 
648 template <class VolumeMesh>
650 {
651  mCurrentPrimitiveMode = mPrimitiveMode;
652  mCurrentNormalMode = mNormalMode;
653  mCurrentColorMode = mColorMode;
654  mCurrentSkipUnselected = mSkipUnselected;
655  mCurrentShowIrregularInnerEdges = mShowIrregularInnerEdges;
656  mCurrentShowIrregularOuterValence2Edges = mShowIrregularOuterValence2Edges;
657  mCurrentSkipRegularEdges = mSkipRegularEdges;
658  mCurrentBoundaryOnly = mBoundaryOnly;
659  mCurrentVertexSize = mVertexSize;
660  mCurrentNormalOffset = mNormalOffset;
661  mCurrentColorOffset = mColorOffset;
662  mCurrentNumOfVertices = mNumOfVertices;
663 }
664 
665 
674 template <class VolumeMesh>
675 ACG::Vec4f VolumeMeshBufferManager<VolumeMesh>::getValenceColorCode(unsigned int _valence, bool _inner) const {
676 
677  if(_inner && _valence == 3) {
678  return ACG::Vec4f(0.0f, 1.0f, 1.0f, 1.0f);
679  } else if(_inner && _valence == 5) {
680  return ACG::Vec4f(1.0f, 0.0f, 1.0f, 1.0f);
681  } else if(!_inner && _valence > 3) {
682  return ACG::Vec4f(0.0f, 1.0f, 0.0f, 1.0f);
683  } else if(!_inner && _valence == 2) {
684  return ACG::Vec4f(1.0f, 1.0f, 0.0f, 1.0f);
685  } else if(_inner && _valence > 5) {
686  return ACG::Vec4f(0.5f, 1.0f, 0.5f, 1.0f);
687  }
688  return ACG::Vec4f(0.0f, 0.0f, 0.0f, 1.0f);
689 }
690 
696 template <class VolumeMesh>
698 {
699  unsigned int numOfVertices = 0;
700 
701  if (mSkipUnselected) //only count selected
702  {
703  if (mPrimitiveMode == PM_CELLS)
704  {
705  OpenVolumeMesh::CellIter c_begin(mMesh.cells_begin()), c_end(mMesh.cells_end());
706  for (OpenVolumeMesh::CellIter c_it = c_begin; c_it != c_end; ++c_it)
707  if (mStatusAttrib[*c_it].selected() && is_inside(*c_it))
708  {
709  std::vector<HalfFaceHandle> hfs = mMesh.cell(*c_it).halffaces();
710  for (unsigned int i = 0; i < hfs.size(); ++i)
711  numOfVertices += ((mMesh.valence(mMesh.face_handle(hfs[i])))-2)*3;
712  }
713  }
714  else if (mPrimitiveMode == PM_FACES)
715  {
716  OpenVolumeMesh::FaceIter f_begin(mMesh.faces_begin()), f_end(mMesh.faces_end());
717  for (OpenVolumeMesh::FaceIter f_it = f_begin; f_it != f_end; ++f_it)
718  if (mStatusAttrib[*f_it].selected() && is_inside(*f_it) && (!mBoundaryOnly || mMesh.is_boundary(*f_it)))
719  numOfVertices += ((mMesh.valence(*f_it))-2)*3; //additional vertices are added for faces with more than 3 adjacent vertices
720  }
721  else if (mPrimitiveMode == PM_FACES_ON_CELLS)
722  {
723  OpenVolumeMesh::FaceIter f_begin(mMesh.faces_begin()), f_end(mMesh.faces_end());
724  for (OpenVolumeMesh::FaceIter f_it = f_begin; f_it != f_end; ++f_it)
725  if (mStatusAttrib[*f_it].selected())
726  numOfVertices += ((mMesh.valence(*f_it))-2)*3*getNumOfIncidentCells(*f_it); //additional vertices are added for faces with more than 3 adjacent vertices
727  }
728  else if (mPrimitiveMode == PM_HALFFACES)
729  {
730  OpenVolumeMesh::HalfFaceIter hf_begin(mMesh.halffaces_begin()), hf_end(mMesh.halffaces_end());
731  for (OpenVolumeMesh::HalfFaceIter hf_it = hf_begin; hf_it != hf_end; ++hf_it)
732  if (mStatusAttrib[*hf_it].selected() && is_inside(*hf_it) && (!mBoundaryOnly || mMesh.is_boundary(*hf_it)))
733  numOfVertices += ((mMesh.valence(mMesh.face_handle(*hf_it)))-2)*3; //additional vertices are added for faces with more than 3 adjacent vertices
734  }
735  else if (mPrimitiveMode == PM_EDGES)
736  {
737  OpenVolumeMesh::EdgeIter e_begin(mMesh.edges_begin()), e_end(mMesh.edges_end());
738  for (OpenVolumeMesh::EdgeIter e_it = e_begin; e_it != e_end; ++e_it)
739  if (mStatusAttrib[*e_it].selected() && is_inside(*e_it) && (!mBoundaryOnly || mMesh.is_boundary(*e_it)))
740  numOfVertices += 2;
741  }
742  else if (mPrimitiveMode == PM_EDGES_ON_CELLS)
743  {
744  OpenVolumeMesh::EdgeIter e_begin(mMesh.edges_begin()), e_end(mMesh.edges_end());
745  for (OpenVolumeMesh::EdgeIter e_it = e_begin; e_it != e_end; ++e_it)
746  if (mStatusAttrib[*e_it].selected())
747  numOfVertices += 2*getNumOfIncidentCells(*e_it);
748  }
749  else if (mPrimitiveMode == PM_HALFEDGES)
750  {
751  OpenVolumeMesh::HalfEdgeIter he_begin(mMesh.halfedges_begin()), he_end(mMesh.halfedges_end());
752  for (OpenVolumeMesh::HalfEdgeIter he_it = he_begin; he_it != he_end; ++he_it)
753  if (mStatusAttrib[*he_it].selected() && is_inside(*he_it) && (!mBoundaryOnly || mMesh.is_boundary(*he_it)))
754  numOfVertices += 2;
755  }
756  else if (mPrimitiveMode == PM_VERTICES)
757  {
758  OpenVolumeMesh::VertexIter v_begin(mMesh.vertices_begin()), v_end(mMesh.vertices_end());
759  for (OpenVolumeMesh::VertexIter v_it = v_begin; v_it != v_end; ++v_it)
760  if (mStatusAttrib[*v_it].selected() && is_inside(*v_it) && (!mBoundaryOnly || mMesh.is_boundary(*v_it)))
761  numOfVertices += 1;
762  }
763  else if (mPrimitiveMode == PM_VERTICES_ON_CELLS)
764  {
765  OpenVolumeMesh::VertexIter v_begin(mMesh.vertices_begin()), v_end(mMesh.vertices_end());
766  for (OpenVolumeMesh::VertexIter v_it = v_begin; v_it != v_end; ++v_it)
767  if (mStatusAttrib[*v_it].selected())
768  numOfVertices += getNumOfIncidentCells(*v_it);
769  }
770  }
771  else
772  {
773  if (mPrimitiveMode == PM_VERTICES_ON_CELLS)
774  {
775  for (unsigned int i = 0; i < mMesh.n_vertices(); i++)
776  numOfVertices += getNumOfIncidentCells(VertexHandle(i));
777  }
778  else if (mPrimitiveMode == PM_VERTICES)
779  {
780  for (unsigned int i = 0; i < mMesh.n_vertices(); i++)
781  if (is_inside(VertexHandle(i)) && (!mBoundaryOnly || mMesh.is_boundary(VertexHandle(i))))
782  numOfVertices += 1;
783  }
784  else if (mPrimitiveMode == PM_FACES)
785  {
786  OpenVolumeMesh::FaceIter f_begin(mMesh.faces_begin()), f_end(mMesh.faces_end());
787  for (OpenVolumeMesh::FaceIter f_it = f_begin; f_it != f_end; ++f_it)
788  if (is_inside(*f_it) && (!mBoundaryOnly || mMesh.is_boundary(*f_it)))
789  numOfVertices += ((mMesh.valence(*f_it))-2)*3; //additional vertices are added for faces with more than 3 adjacent vertices
790  }
791  else if (mPrimitiveMode == PM_FACES_ON_CELLS)
792  {
793  OpenVolumeMesh::FaceIter f_begin(mMesh.faces_begin()), f_end(mMesh.faces_end());
794  for (OpenVolumeMesh::FaceIter f_it = f_begin; f_it != f_end; ++f_it)
795  numOfVertices += ((mMesh.valence(*f_it))-2)*3*getNumOfIncidentCells(*f_it); //additional vertices are added for faces with more than 3 adjacent vertices
796  }
797  else if (mPrimitiveMode == PM_HALFFACES)
798  {
799  OpenVolumeMesh::HalfFaceIter hf_begin(mMesh.halffaces_begin()), hf_end(mMesh.halffaces_end());
800  for (OpenVolumeMesh::HalfFaceIter hf_it = hf_begin; hf_it != hf_end; ++hf_it)
801  if (is_inside(*hf_it) && (!mBoundaryOnly || mMesh.is_boundary(*hf_it)))
802  numOfVertices += ((mMesh.valence(mMesh.face_handle(*hf_it)))-2)*3; //additional vertices are added for faces with more than 3 adjacent vertices
803  }
804  else if (mPrimitiveMode == PM_CELLS)
805  {
806  OpenVolumeMesh::CellIter c_begin(mMesh.cells_begin()), c_end(mMesh.cells_end());
807  for (OpenVolumeMesh::CellIter c_it = c_begin; c_it != c_end; ++c_it)
808  {
809  if (is_inside(*c_it))
810  {
811  std::vector<HalfFaceHandle> hfs = mMesh.cell(*c_it).halffaces();
812  for (unsigned int i = 0; i < hfs.size(); ++i)
813  numOfVertices += ((mMesh.valence(mMesh.face_handle(hfs[i])))-2)*3;
814  }
815  }
816  }
817  else if (mPrimitiveMode == PM_EDGES_ON_CELLS)
818  {
819  for (OpenVolumeMesh::EdgeIter e_it = mMesh.edges_begin(); e_it != mMesh.edges_end(); ++e_it)
820  numOfVertices += 2*getNumOfIncidentCells(*e_it);
821  }
822  else if ( mPrimitiveMode == PM_EDGES ) //all edges are drawn, so irregular ones are already included
823  {
824  for (OpenVolumeMesh::EdgeIter e_it = mMesh.edges_begin(); e_it != mMesh.edges_end(); ++e_it)
825  if (is_inside(*e_it) && (!mBoundaryOnly || mMesh.is_boundary(*e_it)))
826  numOfVertices += 2;
827  }
828  else if ( mPrimitiveMode == PM_IRREGULAR_EDGES )
829  {
830  for (OpenVolumeMesh::EdgeIter e_it = mMesh.edges_begin(); e_it != mMesh.edges_end(); ++e_it)
831  if (is_inside(*e_it) && (!mBoundaryOnly || mMesh.is_boundary(*e_it)))
832  {
833  bool boundary = mMesh.is_boundary(*e_it);
834  unsigned int valence = mMesh.valence(*e_it);
835 
836  // Skip regular edges
837  if(( boundary && valence == 3) || (!boundary && valence == 4)) continue;
838  //skip boundary valence 2 edges if not drawn
839  if ((!(mShowIrregularOuterValence2Edges)) && ( boundary && valence == 2)) continue;
840  //skip irregular inner edges if not drawn
841  if ((!(mShowIrregularInnerEdges)) && (( !boundary && valence != 4) ||
842  ( boundary && valence < 2) ||
843  ( boundary && valence > 3))) continue;
844 
845  numOfVertices += 2;
846  }
847  }
848  else if ( mPrimitiveMode == PM_HALFEDGES )
849  {
850  for (OpenVolumeMesh::HalfEdgeIter he_it = mMesh.halfedges_begin(); he_it != mMesh.halfedges_end(); ++he_it)
851  if (is_inside(*he_it) && (!mBoundaryOnly || mMesh.is_boundary(*he_it)))
852  numOfVertices += 2;
853  }
854  else /*if ( mPrimitiveMode == PM_NONE)*/
855  {
856  numOfVertices = 0;
857  }
858  }
859 
860  mNumOfVertices = numOfVertices;
861 }
862 
870 template <class VolumeMesh>
872 {
873  int incidentCells = 0;
874  OpenVolumeMesh::HalfFaceHandle hf0 = mMesh.halfface_handle(_fh, 0);
875  if (mMesh.incident_cell(hf0) != CellHandle(-1))
876  if (is_inside(mMesh.incident_cell(hf0)))
877  incidentCells += 1;
878  OpenVolumeMesh::HalfFaceHandle hf1 = mMesh.halfface_handle(_fh, 1);
879  if (mMesh.incident_cell(hf1) != CellHandle(-1))
880  if (is_inside(mMesh.incident_cell(hf1)))
881  incidentCells += 1;
882  return incidentCells;
883 }
884 
892 template <class VolumeMesh>
894 {
895  int incidentCells = 0;
896  OpenVolumeMesh::HalfEdgeHandle heh = mMesh.halfedge_handle(_eh, 0);
897  for (OpenVolumeMesh::HalfEdgeCellIter hec_it = OpenVolumeMesh::HalfEdgeCellIter(heh,&mMesh); hec_it.valid(); ++hec_it)
898  if (hec_it->idx() != -1)
899  if (is_inside(*hec_it))
900  incidentCells++;
901  return incidentCells;
902 }
903 
911 template <class VolumeMesh>
913 {
914  int incidentCells = 0;
915  for (OpenVolumeMesh::VertexCellIter vc_it = OpenVolumeMesh::VertexCellIter(_vh,&mMesh); vc_it; ++vc_it)
916  if (vc_it->idx() != -1)
917  if (is_inside(*vc_it))
918  incidentCells++;
919  return incidentCells;
920 }
921 
929 template <class VolumeMesh>
931 {
932  if (!mCogsValid)
933  calculateCOGs();
934 
935  return mCogs[_ch.idx()];
936 }
937 
945 template <class VolumeMesh>
947 {
948  if (mCogs.size() != mMesh.n_cells())
949  mCogs.resize(mMesh.n_cells());
950 
951  OpenVolumeMesh::CellIter c_begin(mMesh.cells_begin()), c_end(mMesh.cells_end());
952  for (OpenVolumeMesh::CellIter c_it = c_begin; c_it != c_end; ++c_it)
953  {
954 
955  std::vector<HalfFaceHandle> hfs = mMesh.cell(*c_it).halffaces();
956  ACG::Vec3d cog = ACG::Vec3d(0.0f);
957  int count = 0;
958  for (unsigned int i = 0; i < hfs.size(); ++i)
959  for (OpenVolumeMesh::HalfFaceVertexIter hfv_it = mMesh.hfv_iter(hfs[i]); hfv_it; ++hfv_it)
960  {
961  cog += mMesh.vertex(*hfv_it);
962  count += 1;
963  }
964  cog = 1.0/count * cog;
965 
966  mCogs[c_it->idx()] = cog;
967  }
968 
969  mCogsValid = true;
970 }
971 
977 template <class VolumeMesh>
979 {
980  return (mGeometryChanged) ||
981  (mVertexSize != mCurrentVertexSize) ||
982  (mPrimitiveMode != mCurrentPrimitiveMode) ||
983  (mNumOfVertices != mCurrentNumOfVertices);
984 }
985 
991 template <class VolumeMesh>
993 {
994  return (mColorsChanged) ||
995  (mVertexSize != mCurrentVertexSize) ||
996  (mNumOfVertices != mCurrentNumOfVertices) ||
997  (mPrimitiveMode != mCurrentPrimitiveMode) ||
998  (mColorOffset != mCurrentColorOffset) ||
999  (mColorMode != mCurrentColorMode) ||
1000  (mShowIrregularInnerEdges != mCurrentShowIrregularInnerEdges) ||
1001  (mShowIrregularOuterValence2Edges != mCurrentShowIrregularOuterValence2Edges);
1002 }
1003 
1009 template <class VolumeMesh>
1011 {
1012  return (mTexCoordsChanged) ||
1013  (mVertexSize != mCurrentVertexSize) ||
1014  (mNumOfVertices != mCurrentNumOfVertices) ||
1015  (mPrimitiveMode != mCurrentPrimitiveMode) ||
1016  (mTexCoordOffset!= mCurrentTexCoordOffset);
1017 }
1018 
1024 template <class VolumeMesh>
1026 {
1027  return (mNormalsChanged) ||
1028  (mVertexSize != mCurrentVertexSize) ||
1029  (mPrimitiveMode != mCurrentPrimitiveMode) ||
1030  (mNormalOffset != mCurrentNormalOffset) ||
1031  (mNormalMode != mCurrentNormalMode) ||
1032  (mNumOfVertices != mCurrentNumOfVertices);
1033 }
1034 
1040 template <class VolumeMesh>
1042 {
1043  unsigned int pos = 0;
1044 
1045  if (mPrimitiveMode == PM_VERTICES)
1046  {
1047  for (unsigned int i = 0; i < mMesh.n_vertices(); ++i) {
1048  if (mSkipUnselected && !mStatusAttrib[VertexHandle(i)].selected()) continue;
1049  if (!is_inside(VertexHandle(i))) continue;
1050  if (mBoundaryOnly && !mMesh.is_boundary(VertexHandle(i))) continue;
1051  ACG::Vec3d p = mMesh.vertex(VertexHandle(i));
1052  addPositionToBuffer(p, _buffer, pos++);
1053  }
1054  }
1055  else if (mPrimitiveMode == PM_VERTICES_ON_CELLS)
1056  {
1057  for (unsigned int i = 0; i < mMesh.n_vertices(); ++i) {
1058  if (mSkipUnselected && !mStatusAttrib[VertexHandle(i)].selected()) continue;
1059  ACG::Vec3d p = mMesh.vertex(VertexHandle(i));
1060  for (OpenVolumeMesh::VertexCellIter vc_it = OpenVolumeMesh::VertexCellIter(VertexHandle(i),&mMesh); vc_it; ++vc_it)
1061  {
1062  ACG::Vec3d cog = getCOG(*vc_it);
1063  //ACG::Vec3d newPos = p*mScale + cog*(1-mScale);
1064  if (is_inside(*vc_it))
1065  addPositionToBuffer(p*mScale + cog*(1-mScale), _buffer, pos++);
1066  }
1067  }
1068  }
1069  else if (mPrimitiveMode == PM_FACES)
1070  {
1071  std::vector<ACG::Vec3d> vertices;
1072  OpenVolumeMesh::FaceIter f_begin(mMesh.faces_begin()), f_end(mMesh.faces_end());
1073  for (OpenVolumeMesh::FaceIter f_it = f_begin; f_it != f_end; ++f_it)
1074  {
1075  if (mSkipUnselected && !mStatusAttrib[*f_it].selected()) continue;
1076  if (mBoundaryOnly && !mMesh.is_boundary(*f_it)) continue;
1077  if (!is_inside(*f_it)) continue;
1078  vertices.clear();
1079  for (OpenVolumeMesh::HalfFaceVertexIter hfv_it = mMesh.hfv_iter(mMesh.halfface_handle(*f_it,0)); hfv_it; ++hfv_it)
1080  vertices.push_back(mMesh.vertex(*hfv_it));
1081 
1082  for (unsigned int i = 0; i < vertices.size()-2; i++)
1083  {
1084  addPositionToBuffer(vertices[0], _buffer, pos++);
1085  addPositionToBuffer(vertices[i+1], _buffer, pos++);
1086  addPositionToBuffer(vertices[i+2], _buffer, pos++);
1087  }
1088  }
1089  }
1090  else if (mPrimitiveMode == PM_FACES_ON_CELLS)
1091  {
1092  std::vector<ACG::Vec3d> vertices;
1093  OpenVolumeMesh::FaceIter f_begin(mMesh.faces_begin()), f_end(mMesh.faces_end());
1094  for (OpenVolumeMesh::FaceIter f_it = f_begin; f_it != f_end; ++f_it)
1095  {
1096  if (mSkipUnselected && !mStatusAttrib[*f_it].selected()) continue;
1097  vertices.clear();
1098  for (OpenVolumeMesh::HalfFaceVertexIter hfv_it = mMesh.hfv_iter(mMesh.halfface_handle(*f_it,0)); hfv_it; ++hfv_it)
1099  vertices.push_back(mMesh.vertex(*hfv_it));
1100 
1101  for (int i = 0; i < 2; i++)
1102  {
1103  OpenVolumeMesh::CellHandle ch = mMesh.incident_cell(mMesh.halfface_handle(*f_it,i));
1104  if (ch != CellHandle(-1))
1105  {
1106  if (!is_inside(ch)) continue;
1107  ACG::Vec3d cog = getCOG(ch);
1108  for (unsigned int i = 0; i < vertices.size()-2; i++)
1109  {
1110  //we dont care about the correct facing because we dont cull the back side of faces
1111  addPositionToBuffer(vertices[0]*mScale + cog*(1-mScale), _buffer, pos++);
1112  addPositionToBuffer(vertices[i+1]*mScale + cog*(1-mScale), _buffer, pos++);
1113  addPositionToBuffer(vertices[i+2]*mScale + cog*(1-mScale), _buffer, pos++);
1114  }
1115  }
1116  }
1117 
1118  }
1119  }
1120  else if (mPrimitiveMode == PM_HALFFACES)
1121  {
1122  std::vector<ACG::Vec3d> vertices;
1123  OpenVolumeMesh::HalfFaceIter hf_begin(mMesh.halffaces_begin()), hf_end(mMesh.halffaces_end());
1124  for (OpenVolumeMesh::HalfFaceIter hf_it = hf_begin; hf_it != hf_end; ++hf_it)
1125  {
1126  if (mSkipUnselected && !mStatusAttrib[*hf_it].selected()) continue;
1127  if (mBoundaryOnly && !mMesh.is_boundary(*hf_it)) continue;
1128  if (!is_inside(*hf_it)) continue;
1129  vertices.clear();
1130  for (OpenVolumeMesh::HalfFaceVertexIter hfv_it = mMesh.hfv_iter(*hf_it); hfv_it; ++hfv_it)
1131  vertices.push_back(mMesh.vertex(*hfv_it));
1132 
1133  for (unsigned int i = 0; i < vertices.size()-2; i++)
1134  {
1135  addPositionToBuffer(vertices[0], _buffer, pos++);
1136  addPositionToBuffer(vertices[i+1], _buffer, pos++);
1137  addPositionToBuffer(vertices[i+2], _buffer, pos++);
1138  }
1139  }
1140  }
1141  else if (mPrimitiveMode == PM_CELLS)
1142  {
1143  std::vector<ACG::Vec3d> vertices;
1144  OpenVolumeMesh::CellIter c_begin(mMesh.cells_begin()), c_end(mMesh.cells_end());
1145  for (OpenVolumeMesh::CellIter c_it = c_begin; c_it != c_end; ++c_it)
1146  {
1147  if (mSkipUnselected && !mStatusAttrib[*c_it].selected()) continue;
1148  if (!is_inside(*c_it)) continue;
1149  std::vector<HalfFaceHandle> hfs = mMesh.cell(*c_it).halffaces();
1150  ACG::Vec3d cog = getCOG(*c_it);
1151  for (unsigned int i = 0; i < hfs.size(); ++i)
1152  {
1153  vertices.clear();
1154  for (OpenVolumeMesh::HalfFaceVertexIter hfv_it = mMesh.hfv_iter(hfs[i]); hfv_it; ++hfv_it)
1155  vertices.push_back(mScale*mMesh.vertex(*hfv_it)+(1-mScale)*cog);
1156 
1157  for (unsigned int i = 0; i < vertices.size()-2; i++)
1158  {
1159  addPositionToBuffer(vertices[0], _buffer, pos++);
1160  addPositionToBuffer(vertices[i+1], _buffer, pos++);
1161  addPositionToBuffer(vertices[i+2], _buffer, pos++);
1162  }
1163  }
1164  }
1165 
1166  }
1167  else if (mPrimitiveMode == PM_EDGES)
1168  {
1169  OpenVolumeMesh::EdgeIter e_begin(mMesh.edges_begin()), e_end(mMesh.edges_end());
1170  for (OpenVolumeMesh::EdgeIter e_it = e_begin; e_it != e_end; ++e_it)
1171  {
1172  if (mSkipUnselected && !mStatusAttrib[*e_it].selected()) continue;
1173  if (mBoundaryOnly && !mMesh.is_boundary(*e_it)) continue;
1174  if (!is_inside(*e_it)) continue;
1175 
1176  Edge e(mMesh.edge(*e_it));
1177  addPositionToBuffer(mMesh.vertex(e.from_vertex()), _buffer, pos++);
1178  addPositionToBuffer(mMesh.vertex(e.to_vertex()), _buffer, pos++);
1179  }
1180  }
1181  else if (mPrimitiveMode == PM_EDGES_ON_CELLS)
1182  {
1183  OpenVolumeMesh::EdgeIter e_begin(mMesh.edges_begin()), e_end(mMesh.edges_end());
1184  for (OpenVolumeMesh::EdgeIter e_it = e_begin; e_it != e_end; ++e_it)
1185  {
1186  if (mSkipUnselected && !mStatusAttrib[*e_it].selected()) continue;
1187 
1188  Edge e(mMesh.edge(*e_it));
1189  OpenVolumeMesh::HalfEdgeHandle heh = mMesh.halfedge_handle(*e_it, 0);
1190  for (OpenVolumeMesh::HalfEdgeCellIter hec_it = OpenVolumeMesh::HalfEdgeCellIter(heh,&mMesh); hec_it.valid(); ++hec_it)
1191  {
1192  if (hec_it->idx() != -1)
1193  {
1194  if (!is_inside(*hec_it)) continue;
1195  ACG::Vec3d cog = getCOG(*hec_it);
1196  addPositionToBuffer(mMesh.vertex(e.from_vertex())*mScale + cog*(1-mScale), _buffer, pos++);
1197  addPositionToBuffer(mMesh.vertex(e.to_vertex()) *mScale + cog*(1-mScale), _buffer, pos++);
1198  }
1199  }
1200  }
1201  }
1202  else if (mPrimitiveMode == PM_IRREGULAR_EDGES)
1203  {
1204  OpenVolumeMesh::EdgeIter e_begin(mMesh.edges_begin()), e_end(mMesh.edges_end());
1205  for (OpenVolumeMesh::EdgeIter e_it = e_begin; e_it != e_end; ++e_it)
1206  {
1207  if (mSkipUnselected && !mStatusAttrib[*e_it].selected()) continue;
1208  if (mBoundaryOnly && !mMesh.is_boundary(*e_it)) continue;
1209  if (!is_inside(*e_it)) continue;
1210 
1211  bool boundary = mMesh.is_boundary(*e_it);
1212  unsigned int valence = mMesh.valence(*e_it);
1213  // Skip regular
1214  if(( boundary && valence == 3) ||
1215  (!boundary && valence == 4)) continue;
1216  //skip boundary valence 2 edges if not drawn
1217  if ((!mShowIrregularOuterValence2Edges) && ( boundary && valence == 2)) continue;
1218  //skip irregular inner edges if not drawn
1219  if ((!mShowIrregularInnerEdges) && (( !boundary && valence != 4) ||
1220  ( boundary && valence < 2) ||
1221  ( boundary && valence > 3))) continue;
1222 
1223  Edge e(mMesh.edge(*e_it));
1224  addPositionToBuffer(mMesh.vertex(e.from_vertex()), _buffer, pos++);
1225  addPositionToBuffer(mMesh.vertex(e.to_vertex()), _buffer, pos++);
1226  }
1227  }
1228  else if (mPrimitiveMode == PM_HALFEDGES)
1229  {
1230  OpenVolumeMesh::HalfEdgeIter he_begin(mMesh.halfedges_begin()), he_end(mMesh.halfedges_end());
1231  for (OpenVolumeMesh::HalfEdgeIter he_it = he_begin; he_it != he_end; ++he_it)
1232  {
1233  if (mSkipUnselected && !mStatusAttrib[*he_it].selected()) continue;
1234  if (mBoundaryOnly && !mMesh.is_boundary(*he_it)) continue;
1235  if (!is_inside(*he_it)) continue;
1236 
1237  double lambda = 0.4;
1238  Edge e(mMesh.halfedge(*he_it));
1239  addPositionToBuffer(mMesh.vertex(e.from_vertex()), _buffer, pos++);
1240  addPositionToBuffer((1-lambda)*mMesh.vertex(e.from_vertex()) + lambda*mMesh.vertex(e.to_vertex()), _buffer, pos++);
1241  }
1242  }
1243  else /*if (mPrimitiveMode == PM_NONE)*/
1244  {
1245  //This case should not happen. Do nothing.
1246  }
1247 }
1248 
1254 template <class VolumeMesh>
1256 {
1257  if (mNormalMode == NM_NONE) return;
1258 
1259  unsigned int pos = 0;
1260 
1261  if ((mPrimitiveMode == PM_FACES) && (mNormalMode == NM_FACE))
1262  {
1263  OpenVolumeMesh::FaceIter f_begin(mMesh.faces_begin()), f_end(mMesh.faces_end());
1264  for (OpenVolumeMesh::FaceIter f_it = f_begin; f_it != f_end; ++f_it)
1265  {
1266  if (mBoundaryOnly && !mMesh.is_boundary(*f_it)) continue;
1267  if (!is_inside(*f_it)) continue;
1268  ACG::Vec3d normal = mNormalAttrib[*f_it];
1269  unsigned int numOfVerticesInFace = mMesh.valence(*f_it);
1270 
1271  for (unsigned int i = 0; i < numOfVerticesInFace - 2; i++)
1272  {
1273  addNormalToBuffer(normal, _buffer, pos++);
1274  addNormalToBuffer(normal, _buffer, pos++);
1275  addNormalToBuffer(normal, _buffer, pos++);
1276  }
1277  }
1278  }
1279  else if ((mPrimitiveMode == PM_FACES) && (mNormalMode == NM_VERTEX))
1280  {
1281  std::vector<ACG::Vec3d> normals;
1282  OpenVolumeMesh::FaceIter f_begin(mMesh.faces_begin()), f_end(mMesh.faces_end());
1283  for (OpenVolumeMesh::FaceIter f_it = f_begin; f_it != f_end; ++f_it)
1284  {
1285  if (mBoundaryOnly && !mMesh.is_boundary(*f_it)) continue;
1286  if (!is_inside(*f_it)) continue;
1287  normals.clear();
1288  for (OpenVolumeMesh::HalfFaceVertexIter hfv_it = mMesh.hfv_iter(mMesh.halfface_handle(*f_it,0)); hfv_it; ++hfv_it)
1289  normals.push_back(mNormalAttrib[*hfv_it]);
1290 
1291  for (unsigned int i = 0; i < normals.size()-2; i++)
1292  {
1293  addNormalToBuffer(normals[0], _buffer, pos++);
1294  addNormalToBuffer(normals[i+1], _buffer, pos++);
1295  addNormalToBuffer(normals[i+2], _buffer, pos++);
1296  }
1297  }
1298  }
1299  else if ((mPrimitiveMode == PM_HALFFACES) && (mNormalMode == NM_HALFFACE))
1300  {
1301  OpenVolumeMesh::HalfFaceIter hf_begin(mMesh.halffaces_begin()), hf_end(mMesh.halffaces_end());
1302  for (OpenVolumeMesh::HalfFaceIter hf_it = hf_begin; hf_it != hf_end; ++hf_it)
1303  {
1304  if (mBoundaryOnly && !mMesh.is_boundary(*hf_it)) continue;
1305  if (!is_inside(*hf_it)) continue;
1306  ACG::Vec3d normal = mNormalAttrib[*hf_it];
1307  unsigned int numOfVerticesInCell = 0;
1308  for (OpenVolumeMesh::HalfFaceVertexIter hfv_it = mMesh.hfv_iter(*hf_it); hfv_it; ++hfv_it)
1309  ++numOfVerticesInCell;
1310 
1311  for (unsigned int i = 0; i < numOfVerticesInCell- 2; i++)
1312  {
1313  addNormalToBuffer(normal, _buffer, pos++);
1314  addNormalToBuffer(normal, _buffer, pos++);
1315  addNormalToBuffer(normal, _buffer, pos++);
1316  }
1317  }
1318  }
1319  else if ((mPrimitiveMode == PM_HALFFACES) && (mNormalMode == NM_VERTEX))
1320  {
1321  std::vector<ACG::Vec3d> normals;
1322  OpenVolumeMesh::HalfFaceIter hf_begin(mMesh.halffaces_begin()), hf_end(mMesh.halffaces_end());
1323  for (OpenVolumeMesh::HalfFaceIter hf_it = hf_begin; hf_it != hf_end; ++hf_it)
1324  {
1325  if (mBoundaryOnly && !mMesh.is_boundary(*hf_it)) continue;
1326  if (!is_inside(*hf_it)) continue;
1327  normals.clear();
1328  for (OpenVolumeMesh::HalfFaceVertexIter hfv_it = mMesh.hfv_iter(*hf_it); hfv_it; ++hfv_it)
1329  normals.push_back(mNormalAttrib[*hfv_it]);
1330 
1331  for (unsigned int i = 0; i < normals.size()-2; i++)
1332  {
1333  addNormalToBuffer(normals[0], _buffer, pos++);
1334  addNormalToBuffer(normals[i+1], _buffer, pos++);
1335  addNormalToBuffer(normals[i+2], _buffer, pos++);
1336  }
1337  }
1338  }
1339  else if ((mPrimitiveMode == PM_CELLS) && (mNormalMode == NM_HALFFACE))
1340  {
1341  OpenVolumeMesh::CellIter c_begin(mMesh.cells_begin()), c_end(mMesh.cells_end());
1342  for (OpenVolumeMesh::CellIter c_it = c_begin; c_it != c_end; ++c_it)
1343  {
1344  if (!is_inside(*c_it)) continue;
1345  std::vector<HalfFaceHandle> hfs = mMesh.cell(*c_it).halffaces();
1346  for (unsigned int i = 0; i < hfs.size(); ++i)
1347  {
1348  ACG::Vec3d normal = -1.0*mNormalAttrib[hfs[i]];
1349  unsigned int numOfVerticesInFace = mMesh.valence(mMesh.face_handle(hfs[i]));
1350 
1351  for (unsigned int i = 0; i < numOfVerticesInFace-2; i++)
1352  {
1353  addNormalToBuffer(normal, _buffer, pos++);
1354  addNormalToBuffer(normal, _buffer, pos++);
1355  addNormalToBuffer(normal, _buffer, pos++);
1356  }
1357  }
1358  }
1359  }
1360  else if ((mPrimitiveMode == PM_CELLS) && (mNormalMode == NM_VERTEX))
1361  {
1362  std::vector<ACG::Vec3d> normals;
1363  OpenVolumeMesh::CellIter c_begin(mMesh.cells_begin()), c_end(mMesh.cells_end());
1364  for (OpenVolumeMesh::CellIter c_it = c_begin; c_it != c_end; ++c_it)
1365  {
1366  if (!is_inside(*c_it)) continue;
1367  std::vector<HalfFaceHandle> hfs = mMesh.cell(*c_it).halffaces();
1368 
1369  for (unsigned int i = 0; i < hfs.size(); ++i)
1370  {
1371  normals.clear();
1372  for (OpenVolumeMesh::HalfFaceVertexIter hfv_it = mMesh.hfv_iter(hfs[i]); hfv_it; ++hfv_it)
1373  normals.push_back(mNormalAttrib[*hfv_it]);
1374 
1375  for (unsigned int i = 0; i < normals.size()-2; i++)
1376  {
1377  addNormalToBuffer(normals[0], _buffer, pos++);
1378  addNormalToBuffer(normals[i+1], _buffer, pos++);
1379  addNormalToBuffer(normals[i+2], _buffer, pos++);
1380  }
1381  }
1382  }
1383  }
1384 
1385 }
1386 
1392 template <class VolumeMesh>
1394 {
1395  unsigned int pos = 0;
1396 
1397  if ((mPrimitiveMode == PM_VERTICES) && (mColorMode == CM_VERTEX))
1398  {
1399  for (unsigned int i = 0; i < mMesh.n_vertices(); ++i)
1400  {
1401  if (mBoundaryOnly && !mMesh.is_boundary(VertexHandle(i))) continue;
1402  if (!is_inside(VertexHandle(i))) continue;
1403  ACG::Vec4f color = mColorAttrib[VertexHandle(i)];
1404  addColorToBuffer(color, _buffer, pos++);
1405  }
1406  }
1407  else if ((mPrimitiveMode == PM_FACES) && (mColorMode == CM_VERTEX))
1408  {
1409  std::vector<ACG::Vec4f> colors;
1410  OpenVolumeMesh::FaceIter f_begin(mMesh.faces_begin()), f_end(mMesh.faces_end());
1411  for (OpenVolumeMesh::FaceIter f_it = f_begin; f_it != f_end; ++f_it)
1412  {
1413  if (mBoundaryOnly && !mMesh.is_boundary(*f_it)) continue;
1414  if (!is_inside(*f_it)) continue;
1415  colors.clear();
1416 
1417  for (OpenVolumeMesh::HalfFaceVertexIter hfv_it = mMesh.hfv_iter(mMesh.halfface_handle(*f_it,0)); hfv_it; ++hfv_it)
1418  colors.push_back(mColorAttrib[*hfv_it]);
1419 
1420  for (unsigned int i = 0; i < (colors.size()-2); i++)
1421  {
1422  addColorToBuffer(colors[0], _buffer, pos++);
1423  addColorToBuffer(colors[i+1], _buffer, pos++);
1424  addColorToBuffer(colors[i+2], _buffer, pos++);
1425  }
1426  }
1427  }
1428  else if ((mPrimitiveMode == PM_FACES) && (mColorMode == CM_FACE))
1429  {
1430  OpenVolumeMesh::FaceIter f_begin(mMesh.faces_begin()), f_end(mMesh.faces_end());
1431  for (OpenVolumeMesh::FaceIter f_it = f_begin; f_it != f_end; ++f_it)
1432  {
1433  if (mBoundaryOnly && !mMesh.is_boundary(*f_it)) continue;
1434  if (!is_inside(*f_it)) continue;
1435  ACG::Vec4f color = mColorAttrib[*f_it];
1436 
1437  unsigned int numOfVerticesInFace = mMesh.valence(*f_it);
1438  unsigned int numOfDrawnTriangles = numOfVerticesInFace-2;
1439 
1440  for (unsigned int i = 0; i < numOfDrawnTriangles*3; i++)
1441  addColorToBuffer(color, _buffer, pos++);
1442  }
1443  }
1444  else if ((mPrimitiveMode == PM_HALFFACES) && (mColorMode == CM_HALFFACE))
1445  {
1446  OpenVolumeMesh::HalfFaceIter hf_begin(mMesh.halffaces_begin()), hf_end(mMesh.halffaces_end());
1447  for (OpenVolumeMesh::HalfFaceIter hf_it = hf_begin; hf_it != hf_end; ++hf_it)
1448  {
1449  if (mBoundaryOnly && !mMesh.is_boundary(*hf_it)) continue;
1450  if (!is_inside(*hf_it)) continue;
1451  ACG::Vec4f color = mColorAttrib[*hf_it];
1452 
1453  unsigned int numOfVerticesInFace = mMesh.valence(mMesh.face_handle(*hf_it));
1454  unsigned int numOfDrawnTriangles = numOfVerticesInFace-2;
1455 
1456  for (unsigned int i = 0; i < numOfDrawnTriangles*3; i++)
1457  addColorToBuffer(color, _buffer, pos++);
1458  }
1459  }
1460  else if ((mPrimitiveMode == PM_HALFFACES) && (mColorMode == CM_VERTEX))
1461  {
1462  std::vector<ACG::Vec4f> colors;
1463  OpenVolumeMesh::HalfFaceIter hf_begin(mMesh.halffaces_begin()), hf_end(mMesh.halffaces_end());
1464  for (OpenVolumeMesh::HalfFaceIter hf_it = hf_begin; hf_it != hf_end; ++hf_it)
1465  {
1466  if (mBoundaryOnly && !mMesh.is_boundary(*hf_it)) continue;
1467  if (!is_inside(*hf_it)) continue;
1468  colors.clear();
1469 
1470  for (OpenVolumeMesh::HalfFaceVertexIter hfv_it = mMesh.hfv_iter(*hf_it); hfv_it; ++hfv_it)
1471  colors.push_back(mColorAttrib[*hfv_it]);
1472 
1473  for (unsigned int i = 0; i < (colors.size()-2); i++)
1474  {
1475  addColorToBuffer(colors[0], _buffer, pos++);
1476  addColorToBuffer(colors[i+1], _buffer, pos++);
1477  addColorToBuffer(colors[i+2], _buffer, pos++);
1478  }
1479  }
1480  }
1481  else if ((mPrimitiveMode == PM_CELLS) && (mColorMode == CM_CELL))
1482  {
1483  OpenVolumeMesh::CellIter c_begin(mMesh.cells_begin()), c_end(mMesh.cells_end());
1484  for (OpenVolumeMesh::CellIter c_it = c_begin; c_it != c_end; ++c_it)
1485  {
1486  if (!is_inside(*c_it)) continue;
1487  ACG::Vec4f color = mColorAttrib[*c_it];
1488  std::vector<HalfFaceHandle> hfs = mMesh.cell(*c_it).halffaces();
1489  for (unsigned int i = 0; i < hfs.size(); ++i)
1490  {
1491  unsigned int numOfVerticesInHalfface = 0;
1492  for (OpenVolumeMesh::HalfFaceVertexIter hfv_it = mMesh.hfv_iter(hfs[i]); hfv_it; ++hfv_it)
1493  ++numOfVerticesInHalfface;
1494 
1495  unsigned int numOfDrawnFaces = numOfVerticesInHalfface-2;
1496  for (unsigned int i = 0; i < numOfDrawnFaces*3; i++)
1497  addColorToBuffer(color, _buffer, pos++);
1498  }
1499  }
1500  }
1501  else if ((mPrimitiveMode == PM_CELLS) && (mColorMode == CM_HALFFACE))
1502  {
1503  OpenVolumeMesh::CellIter c_begin(mMesh.cells_begin()), c_end(mMesh.cells_end());
1504  for (OpenVolumeMesh::CellIter c_it = c_begin; c_it != c_end; ++c_it)
1505  {
1506  if (!is_inside(*c_it)) continue;
1507  std::vector<HalfFaceHandle> hfs = mMesh.cell(*c_it).halffaces();
1508  for (unsigned int i = 0; i < hfs.size(); ++i)
1509  {
1510  ACG::Vec4f color = mColorAttrib[hfs[i]];
1511  unsigned int numOfVerticesInHalfface = 0;
1512  for (OpenVolumeMesh::HalfFaceVertexIter hfv_it = mMesh.hfv_iter(hfs[i]); hfv_it; ++hfv_it)
1513  ++numOfVerticesInHalfface;
1514 
1515  unsigned int numOfDrawnFaces = numOfVerticesInHalfface-2;
1516  for (unsigned int i = 0; i < numOfDrawnFaces*3; i++)
1517  addColorToBuffer(color, _buffer, pos++);
1518  }
1519  }
1520  }
1521  else if ((mPrimitiveMode == PM_CELLS) && (mColorMode == CM_FACE))
1522  {
1523  OpenVolumeMesh::CellIter c_begin(mMesh.cells_begin()), c_end(mMesh.cells_end());
1524  for (OpenVolumeMesh::CellIter c_it = c_begin; c_it != c_end; ++c_it)
1525  {
1526  if (!is_inside(*c_it)) continue;
1527  std::vector<HalfFaceHandle> hfs = mMesh.cell(*c_it).halffaces();
1528  for (unsigned int i = 0; i < hfs.size(); ++i)
1529  {
1530  ACG::Vec4f color = mColorAttrib[mMesh.face_handle(hfs[i])];
1531  unsigned int numOfVerticesInHalfface = 0;
1532  for (OpenVolumeMesh::HalfFaceVertexIter hfv_it = mMesh.hfv_iter(hfs[i]); hfv_it; ++hfv_it)
1533  ++numOfVerticesInHalfface;
1534 
1535  unsigned int numOfDrawnFaces = numOfVerticesInHalfface-2;
1536  for (unsigned int i = 0; i < numOfDrawnFaces*3; i++)
1537  addColorToBuffer(color, _buffer, pos++);
1538  }
1539  }
1540  }
1541  else if ((mPrimitiveMode == PM_CELLS) && (mColorMode == CM_VERTEX))
1542  {
1543  std::vector<ACG::Vec4f> colors;
1544  OpenVolumeMesh::CellIter c_begin(mMesh.cells_begin()), c_end(mMesh.cells_end());
1545  for (OpenVolumeMesh::CellIter c_it = c_begin; c_it != c_end; ++c_it)
1546  {
1547  if (!is_inside(*c_it)) continue;
1548  std::vector<HalfFaceHandle> hfs = mMesh.cell(*c_it).halffaces();
1549  for (unsigned int i = 0; i < hfs.size(); ++i)
1550  {
1551  colors.clear();
1552  for (OpenVolumeMesh::HalfFaceVertexIter hfv_it = mMesh.hfv_iter(hfs[i]); hfv_it; ++hfv_it)
1553  colors.push_back(mColorAttrib[*hfv_it]);
1554 
1555  for (unsigned int i = 0; i < colors.size()-2; i++)
1556  {
1557  addColorToBuffer(colors[0], _buffer, pos++);
1558  addColorToBuffer(colors[i+1], _buffer, pos++);
1559  addColorToBuffer(colors[i+2], _buffer, pos++);
1560  }
1561  }
1562  }
1563  }
1564  else if ((mPrimitiveMode == PM_EDGES) && (mColorMode == CM_EDGE))
1565  {
1566  OpenVolumeMesh::EdgeIter e_begin(mMesh.edges_begin()), e_end(mMesh.edges_end());
1567  for (OpenVolumeMesh::EdgeIter e_it = e_begin; e_it != e_end; ++e_it)
1568  {
1569  if (mBoundaryOnly && !mMesh.is_boundary(*e_it)) continue;
1570  if (!is_inside(*e_it)) continue;
1571  ACG::Vec4f color = mColorAttrib[*e_it];
1572  addColorToBuffer(color, _buffer, pos++);
1573  addColorToBuffer(color, _buffer, pos++);
1574  }
1575  }
1576  else if ((mPrimitiveMode == PM_EDGES) && (mShowIrregularInnerEdges || mShowIrregularOuterValence2Edges))
1577  {
1578  OpenVolumeMesh::EdgeIter e_begin(mMesh.edges_begin()), e_end(mMesh.edges_end());
1579  for (OpenVolumeMesh::EdgeIter e_it = e_begin; e_it != e_end; ++e_it)
1580  {
1581  if (mBoundaryOnly && !mMesh.is_boundary(*e_it)) continue;
1582  if (!is_inside(*e_it)) continue;
1583 
1584  bool boundary = mMesh.is_boundary(*e_it);
1585  unsigned int valence = mMesh.valence(*e_it);
1586 
1587  bool isIrregularInner = ( boundary && valence < 2) || ( boundary && valence > 3) || (!boundary && valence != 4);
1588  bool isIrregularOuterValence2 = ( boundary && valence == 2);
1589 
1590  ACG::Vec4f color;
1591 
1592  if (isIrregularInner && mShowIrregularInnerEdges)
1593  color = getValenceColorCode(valence, !boundary);
1594  else if (isIrregularOuterValence2 && mShowIrregularOuterValence2Edges)
1595  color = getValenceColorCode(valence, !boundary);
1596  else
1597  color = mDefaultColor;
1598 
1599  addColorToBuffer(color, _buffer, pos++);
1600  addColorToBuffer(color, _buffer, pos++);
1601  }
1602  }
1603  else if ( mPrimitiveMode == PM_IRREGULAR_EDGES )
1604  {
1605  OpenVolumeMesh::EdgeIter e_begin(mMesh.edges_begin()), e_end(mMesh.edges_end());
1606  for (OpenVolumeMesh::EdgeIter e_it = e_begin; e_it != e_end; ++e_it)
1607  {
1608  if (mBoundaryOnly && !mMesh.is_boundary(*e_it)) continue;
1609  if (!is_inside(*e_it)) continue;
1610 
1611  bool boundary = mMesh.is_boundary(*e_it);
1612  unsigned int valence = mMesh.valence(*e_it);
1613 
1614  bool isRegular = ( boundary && valence == 3) || (!boundary && valence == 4);
1615  bool isIrregularInner = ( boundary && valence < 2) || ( boundary && valence > 3) || (!boundary && valence != 4);
1616  bool isIrregularOuterValence2 = ( boundary && valence == 2);
1617 
1618  if (isRegular) continue;
1619  if (isIrregularInner && !mShowIrregularInnerEdges) continue;
1620  if (isIrregularOuterValence2 && !mShowIrregularOuterValence2Edges) continue;
1621 
1622  ACG::Vec4f color;
1623 
1624  if (isIrregularInner && mShowIrregularInnerEdges)
1625  color = getValenceColorCode(valence, !boundary);
1626  else if (isIrregularOuterValence2 && mShowIrregularOuterValence2Edges)
1627  color = getValenceColorCode(valence, !boundary);
1628  else
1629  color = mDefaultColor;
1630 
1631  addColorToBuffer(color, _buffer, pos++);
1632  addColorToBuffer(color, _buffer, pos++);
1633  }
1634  }
1635  else if ((mPrimitiveMode == PM_HALFEDGES) && (mColorMode == CM_HALFEDGE))
1636  {
1637  OpenVolumeMesh::HalfEdgeIter he_begin(mMesh.halfedges_begin()), he_end(mMesh.halfedges_end());
1638  for (OpenVolumeMesh::HalfEdgeIter he_it = he_begin; he_it != he_end; ++he_it)
1639  {
1640  if (mBoundaryOnly && !mMesh.is_boundary(*he_it)) continue;
1641  if (!is_inside(*he_it)) continue;
1642  ACG::Vec4f color = mColorAttrib[*he_it];
1643 
1644  addColorToBuffer(color, _buffer, pos++);
1645  addColorToBuffer(color, _buffer, pos++);
1646  }
1647  }
1648 
1649 }
1650 
1656 template <class VolumeMesh>
1658 {
1659 
1660  unsigned int pos = 0;
1661 
1662  if (mTexCoordMode == TCM_NONE)
1663  return;
1664 
1665  if (mPrimitiveMode == PM_FACES)
1666  {
1667  std::vector<ACG::Vec2f> texCoords;
1668  OpenVolumeMesh::FaceIter f_begin(mMesh.faces_begin()), f_end(mMesh.faces_end());
1669  for (OpenVolumeMesh::FaceIter f_it = f_begin; f_it != f_end; ++f_it)
1670  {
1671  if (mBoundaryOnly && !mMesh.is_boundary(*f_it)) continue;
1672  if (!is_inside(*f_it)) continue;
1673  texCoords.clear();
1674 
1675  for (OpenVolumeMesh::HalfFaceVertexIter hfv_it = mMesh.hfv_iter(mMesh.halfface_handle(*f_it,0)); hfv_it; ++hfv_it)
1676  texCoords.push_back(mTexcoordAttrib[*hfv_it]);
1677 
1678  for (unsigned int i = 0; i < (texCoords.size()-2); i++)
1679  {
1680  addTexCoordToBuffer(texCoords[0], _buffer, pos++);
1681  addTexCoordToBuffer(texCoords[i+1], _buffer, pos++);
1682  addTexCoordToBuffer(texCoords[i+2], _buffer, pos++);
1683  }
1684  }
1685  }
1686  else if (mPrimitiveMode == PM_HALFFACES)
1687  {
1688  std::vector<ACG::Vec2f> texCoords;
1689  OpenVolumeMesh::HalfFaceIter hf_begin(mMesh.halffaces_begin()), hf_end(mMesh.halffaces_end());
1690  for (OpenVolumeMesh::HalfFaceIter hf_it = hf_begin; hf_it != hf_end; ++hf_it)
1691  {
1692  if (mBoundaryOnly && !mMesh.is_boundary(*hf_it)) continue;
1693  if (!is_inside(*hf_it)) continue;
1694  texCoords.clear();
1695 
1696  for (OpenVolumeMesh::HalfFaceVertexIter hfv_it = mMesh.hfv_iter(*hf_it); hfv_it; ++hfv_it)
1697  texCoords.push_back(mTexcoordAttrib[*hfv_it]);
1698 
1699  for (unsigned int i = 0; i < (texCoords.size()-2); i++)
1700  {
1701  addTexCoordToBuffer(texCoords[0], _buffer, pos++);
1702  addTexCoordToBuffer(texCoords[i+1], _buffer, pos++);
1703  addTexCoordToBuffer(texCoords[i+2], _buffer, pos++);
1704  }
1705  }
1706  }
1707 
1708 }
1709 
1718 template <class VolumeMesh>
1719 void VolumeMeshBufferManager<VolumeMesh>::buildPickColorBuffer(ACG::GLState& _state, unsigned int _offset, unsigned char* _buffer)
1720 {
1721  unsigned int pos = 0;
1722 
1723  if (mPrimitiveMode == PM_VERTICES)
1724  {
1725  for (unsigned int i = 0; i < mMesh.n_vertices(); ++i)
1726  {
1727  if (mBoundaryOnly && !mMesh.is_boundary(VertexHandle(i))) continue;
1728  if (!is_inside(VertexHandle(i))) continue;
1729  ACG::Vec4uc color = _state.pick_get_name_color(VertexHandle(i).idx() + _offset);
1730  addColorToBuffer(color, _buffer, pos++);
1731  }
1732  }
1733  if (mPrimitiveMode == PM_VERTICES_ON_CELLS)
1734  {
1735  for (unsigned int i = 0; i < mMesh.n_vertices(); ++i) {
1736  ACG::Vec4uc color = _state.pick_get_name_color(VertexHandle(i).idx() + _offset);
1737  unsigned int numOfIncidentCells = getNumOfIncidentCells(VertexHandle(i));
1738  for (unsigned int j = 0; j < numOfIncidentCells; j++)
1739  addColorToBuffer(color, _buffer, pos++);
1740  }
1741  }
1742  else if (mPrimitiveMode == PM_EDGES)
1743  {
1744  OpenVolumeMesh::EdgeIter e_begin(mMesh.edges_begin()), e_end(mMesh.edges_end());
1745  for (OpenVolumeMesh::EdgeIter e_it = e_begin; e_it != e_end; ++e_it)
1746  {
1747  if (mBoundaryOnly && !mMesh.is_boundary(*e_it)) continue;
1748  if (!is_inside(*e_it)) continue;
1749  ACG::Vec4uc color = _state.pick_get_name_color(e_it->idx()+_offset);
1750  addColorToBuffer(color, _buffer, pos++);
1751  addColorToBuffer(color, _buffer, pos++);
1752  }
1753  }
1754  else if (mPrimitiveMode == PM_EDGES_ON_CELLS)
1755  {
1756  OpenVolumeMesh::EdgeIter e_begin(mMesh.edges_begin()), e_end(mMesh.edges_end());
1757  for (OpenVolumeMesh::EdgeIter e_it = e_begin; e_it != e_end; ++e_it)
1758  {
1759  ACG::Vec4uc color = _state.pick_get_name_color(e_it->idx()+_offset);
1760  unsigned int numOfIncidentCells = getNumOfIncidentCells(*e_it);
1761  for (unsigned int i = 0; i < numOfIncidentCells*2;i++)
1762  addColorToBuffer(color, _buffer, pos++);
1763  }
1764  }
1765  else if (mPrimitiveMode == PM_FACES)
1766  {
1767  OpenVolumeMesh::FaceIter f_begin(mMesh.faces_begin()), f_end(mMesh.faces_end());
1768  for (OpenVolumeMesh::FaceIter f_it = f_begin; f_it != f_end; ++f_it)
1769  {
1770  if (mBoundaryOnly && !mMesh.is_boundary(*f_it)) continue;
1771  if (!is_inside(*f_it)) continue;
1772  ACG::Vec4uc color = _state.pick_get_name_color(f_it->idx());
1773 
1774  unsigned int numOfVertices = 0;
1775  for (OpenVolumeMesh::HalfFaceVertexIter hfv_it = mMesh.hfv_iter(mMesh.halfface_handle(*f_it,0)); hfv_it; ++hfv_it)
1776  ++numOfVertices;
1777 
1778  for (unsigned int i = 0; i < (numOfVertices-2)*3; i++)
1779  addColorToBuffer(color, _buffer, pos++);
1780  }
1781  }
1782  else if (mPrimitiveMode == PM_FACES_ON_CELLS)
1783  {
1784  OpenVolumeMesh::FaceIter f_begin(mMesh.faces_begin()), f_end(mMesh.faces_end());
1785  for (OpenVolumeMesh::FaceIter f_it = f_begin; f_it != f_end; ++f_it)
1786  {
1787  ACG::Vec4uc color = _state.pick_get_name_color(f_it->idx()+_offset);
1788 
1789  unsigned int numOfVerticesInHalfface = 0;
1790  for (OpenVolumeMesh::HalfFaceVertexIter hfv_it = mMesh.hfv_iter(mMesh.halfface_handle(*f_it,0)); hfv_it; ++hfv_it)
1791  ++numOfVerticesInHalfface;
1792 
1793  for (int i = 0; i < 2; i++)
1794  {
1795  OpenVolumeMesh::CellHandle ch = mMesh.incident_cell(mMesh.halfface_handle(*f_it,i));
1796  if (ch != CellHandle(-1))
1797  {
1798  if (!is_inside(ch)) continue;
1799  for (unsigned int i = 0; i < (numOfVerticesInHalfface-2)*3; i++)
1800  addColorToBuffer(color, _buffer, pos++);
1801  }
1802  }
1803  }
1804  }
1805  else if (mPrimitiveMode == PM_CELLS)
1806  {
1807  OpenVolumeMesh::CellIter c_begin(mMesh.cells_begin()), c_end(mMesh.cells_end());
1808  for (OpenVolumeMesh::CellIter c_it = c_begin; c_it != c_end; ++c_it)
1809  {
1810  if (!is_inside(*c_it)) continue;
1811  ACG::Vec4uc color = _state.pick_get_name_color(c_it->idx()+_offset);
1812  std::vector<HalfFaceHandle> hfs = mMesh.cell(*c_it).halffaces();
1813  for (unsigned int i = 0; i < hfs.size(); ++i)
1814  {
1815  unsigned int numOfVerticesInHalfface = 0;
1816  for (OpenVolumeMesh::HalfFaceVertexIter hfv_it = mMesh.hfv_iter(hfs[i]); hfv_it; ++hfv_it)
1817  ++numOfVerticesInHalfface;
1818 
1819  unsigned int numOfDrawnFaces = numOfVerticesInHalfface-2;
1820  for (unsigned int i = 0; i < numOfDrawnFaces*3; i++)
1821  addColorToBuffer(color, _buffer, pos++);
1822  }
1823  }
1824  }
1825 }
1826 
1834 template <class VolumeMesh>
1836 {
1837  if ((mBuffer == 0) || optionsChanged() || mInvalidated)
1838  {
1839 
1840  if (mBuffer == 0)
1841  ACG::GLState::genBuffers(1, &mBuffer);
1842 
1844 
1845  if (optionsChanged())
1846  mNumOfVertices = -1;
1847 
1848  unsigned int numOfVertices = getNumOfVertices();
1849 
1850  if (getNumOfVertices() > 0)
1851  {
1852 
1853  unsigned int bufferSize = mVertexSize * numOfVertices;
1854 
1855  ACG::GLState::bindBuffer(GL_ARRAY_BUFFER, mBuffer);
1856  ACG::GLState::bufferData(GL_ARRAY_BUFFER, bufferSize, 0, GL_STATIC_DRAW);
1857 
1858  unsigned char* buffer = (unsigned char *) ACG::GLState::mapBuffer(
1859  GL_ARRAY_BUFFER, GL_READ_WRITE);
1860 
1861  if (buffer)
1862  {
1863 
1864  if (positionsNeedRebuild())
1865  buildVertexBuffer(buffer);
1866  if (normalsNeedRebuild())
1867  buildNormalBuffer(buffer);
1868  if (colorsNeedRebuild())
1869  buildColorBuffer(buffer);
1870  if (texCoordsNeedRebuild())
1871  buildTexCoordBuffer(buffer);
1872 
1873 
1874  ACG::GLState::unmapBuffer(GL_ARRAY_BUFFER);
1875 
1876  ACG::GLState::bindBuffer(GL_ARRAY_BUFFER, 0);
1877 
1878  }
1879  else
1880  {
1881  std::cerr << "error while mapping buffer" << std::endl;
1882  }
1883 
1884  }
1885 
1886  saveOptions();
1887  mInvalidated = false;
1888  mGeometryChanged = false;
1889  mColorsChanged = false;
1890  mNormalsChanged = false;
1891  mTexCoordsChanged = false;
1892 
1893  }
1894 
1895  return mBuffer;
1896 }
1897 
1906 template <class VolumeMesh>
1908 {
1909  if (_offset != mCurrentPickOffset || _state.pick_current_index() != mGlobalPickOffset)
1910  {
1911  invalidateColors();
1912  mGlobalPickOffset = _state.pick_current_index();
1913  }
1914 
1915  if ((mBuffer == 0) || optionsChanged() || mInvalidated)
1916  {
1917  if (mBuffer == 0)
1918  ACG::GLState::genBuffers(1, &mBuffer);
1919 
1921 
1922  if (optionsChanged())
1923  mNumOfVertices = -1;
1924 
1925  unsigned int numOfVertices = getNumOfVertices();
1926 
1927  if (getNumOfVertices() > 0)
1928  {
1929 
1930  unsigned int bufferSize = mVertexSize * numOfVertices;
1931 
1932  ACG::GLState::bindBuffer(GL_ARRAY_BUFFER, mBuffer);
1933  ACG::GLState::bufferData(GL_ARRAY_BUFFER, bufferSize, 0, GL_STATIC_DRAW);
1934 
1935  unsigned char* buffer = (unsigned char *) ACG::GLState::mapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE);
1936 
1937  if (buffer)
1938  {
1939 
1940  if (positionsNeedRebuild())
1941  buildVertexBuffer(buffer);
1942  if (colorsNeedRebuild())
1943  buildPickColorBuffer(_state, _offset, buffer);
1944 
1945  ACG::GLState::unmapBuffer(GL_ARRAY_BUFFER);
1946 
1947  ACG::GLState::bindBuffer(GL_ARRAY_BUFFER, 0);
1948 
1949  }
1950  else
1951  {
1952  std::cerr << "error while mapping buffer" << std::endl;
1953  }
1954 
1955  }
1956 
1957  mCurrentPickOffset = _offset;
1958  saveOptions();
1959  mInvalidated = false;
1960  mGeometryChanged = false;
1961  mColorsChanged = false;
1962  mTexCoordsChanged = false;
1963 
1964  }
1965 
1966  return mBuffer;
1967 }
1968 
1972 template <class VolumeMesh>
1974 {
1977  invalidateColors();
1978 }
1979 
1983 template <class VolumeMesh>
1985 {
1986  mInvalidated = true;
1987  mNumOfVertices = -1;
1988  mGeometryChanged = true;
1989  mColorsChanged = true;
1990  mTexCoordsChanged = true;
1991  mNormalsChanged = true;
1992  mCogsValid = false;
1993  mCellInsidenessValid = false;
1994 }
1995 
1999 template <class VolumeMesh>
2001 {
2002  mInvalidated = true;
2003  mColorsChanged = true;
2004 }
2005 
2009 template <class VolumeMesh>
2011 {
2012  mInvalidated = true;
2013  mNormalsChanged = true;
2014 }
2015 
2019 template <class VolumeMesh>
2021 {
2022  mInvalidated = true;
2023  mTexCoordsChanged = true;
2024 }
2025 
2031 template <class VolumeMesh>
2033 {
2034  if (mBuffer != 0)
2035  ACG::GLState::deleteBuffers(1, &mBuffer);
2036 
2037  mBuffer = 0;
2038 
2039  invalidate();
2040 }
void saveOptions()
State that the current buffer was built with the current options.
Namespace providing different geometric functions concerning angles.
void addPositionToBuffer(ACG::Vec3d _position, unsigned char *_buffer, unsigned int _offset)
Adds a position to the buffer.
void calculateCellInsideness()
Calculates for all cells whether they are inside w.r.t. all cut planes.
void enablePerCellColors()
Enables per cell colors.
Vec4uc pick_get_name_color(size_t _idx)
Definition: GLState.cc:1068
static void deleteBuffers(GLsizei n, const GLuint *buffers)
Definition: GLState.cc:2189
bool is_inside(const ACG::Vec3d &_p)
Tests whether the given point is inside w.r.t. all cut planes.
ACG::Vec4f getValenceColorCode(unsigned int _valence, bool _inner) const
Returns a color code for irregular edges.
GLuint getPickBuffer(ACG::GLState &_state, unsigned int _offset)
Returns the name of the pick buffer.
void buildTexCoordBuffer(unsigned char *_buffer)
Adds texture coordinates to the buffer.
void disableColors()
Disables colors.
void enablePerFaceNormals()
Enables per face normals.
VectorT< float, 4 > Vec4f
Definition: VectorT.hh:138
void invalidateTexCoords()
Invalidates texture coordinates.
size_t pick_current_index() const
Returns the current color picking index (can be used for caching)
Definition: GLState.cc:1131
void addNormalToBuffer(ACG::Vec3d _normal, unsigned char *_buffer, unsigned int _offset)
Adds a normal to the buffer.
void clearCutPlanes()
Removes all cut planes.
static void bufferData(GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage)
Definition: GLState.cc:2184
void setDefaultColor(ACG::Vec4f _defaultColor)
Sets the default color.
void invalidate()
Invalidates the buffer.
void enablePerHalffaceNormals()
Enables per halfface normals.
static GLvoid * mapBuffer(GLenum target, GLenum access)
Definition: GLState.cc:2193
This class creates buffers that can be used to render open volume meshs.
void addFloatToBuffer(float _value, unsigned char *&_buffer)
Adds a float to the buffer.
void enablePerVertexNormals()
Enables per vertex normals.
bool texCoordsNeedRebuild()
Checks whether texture coordinates need to be rebuild.
unsigned int getNumOfVertices()
Returns the number of vertices stored in the buffer.
void free()
Deletes the buffers on the GPU.
void buildVertexBuffer(unsigned char *_buffer)
Adds all vertices to the buffer.
void disableNormals()
Disables normals.
static void genBuffers(GLsizei n, GLuint *buffers)
Definition: GLState.cc:2175
void addElement(const VertexElement *_pElement)
bool colorsNeedRebuild()
Checks whether colors need to be rebuild.
VectorT< double, 3 > Vec3d
Definition: VectorT.hh:121
void enablePerEdgeColors()
Enables per edge colors.
void enablePerHalfedgeColors()
Enables per halfedge colors.
void addUCharToBuffer(unsigned char _value, unsigned char *&_buffer)
Adds an unsigned char to the buffer.
void enablePerHalffaceColors()
Enables per halfface colors.
bool optionsChanged()
Tests whether the options were changed since the last time building the buffer.
void buildColorBuffer(unsigned char *_buffer)
Adds all colors to the buffer.
void addTexCoordToBuffer(ACG::Vec2f _texCoord, unsigned char *_buffer, unsigned int _offset)
Adds a texture coordnate to the buffer.
void enablePerFaceColors()
Enables per face colors.
void invalidateNormals()
Invalidates normals.
void setOptionsFromDrawMode(ACG::SceneGraph::DrawModes::DrawMode _drawMode)
Configures the buffer manager&#39;s options from a DrawMode.
void countNumOfVertices()
Counts the number of vertices that need to be stored in the buffer.
void addColorToBuffer(ACG::Vec4uc _color, unsigned char *_buffer, unsigned int _offset)
Adds a color to the buffer.
static void bindBuffer(GLenum _target, GLuint _buffer)
replaces glBindBuffer, supports locking
Definition: GLState.cc:1820
static GLboolean unmapBuffer(GLenum target)
Definition: GLState.cc:2198
bool positionsNeedRebuild()
Checks whether positions need to be rebuild.
void invalidateGeometry()
Invalidates geometry.
int getNumOfIncidentCells(OpenVolumeMesh::FaceHandle _fh)
Returns the number of cells that are incident to the given face and also inside w.r.t. all cut planes.
void buildNormalBuffer(unsigned char *_buffer)
Adds all normals to the buffer.
bool normalsNeedRebuild()
Checks whether normals need to be rebuild.
ACG::Vec3d getCOG(OpenVolumeMesh::CellHandle _ch)
Returns the center of gravity of the given cell.
void addCutPlane(const ACG::Geometry::Plane &_p)
Adds a cut plane.
void calculateVertexDeclaration()
Constructs a VertexDeclaration, the size and the offsets for the vertices stored in the buffer...
void invalidateColors()
Invalidates colors.
void enablePerVertexColors()
Enables per vertex colors.
GLuint getBuffer()
Returns the name of the buffer.
void calculateCOGs()
Calculates the center of gravity for all cells.
void buildPickColorBuffer(ACG::GLState &_state, unsigned int _offset, unsigned char *_buffer)
Adds all picking colors to the buffer.