Developer Documentation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
VolumeMeshBufferManagerT.cc
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 * *
44 * $Revision$ *
45 * $LastChangedBy$ *
46 * $Date$ *
47 * *
48 \*===========================================================================*/
49 
50 #define VOLUMEMESHBUFFERMANAGERT_CC
51 
52 #include "VolumeMeshBufferManager.hh"
53 
54 template <class VolumeMesh>
59  :
60  mDefaultColor(ACG::Vec4f(0.0,0.0,0.0,1.0)),
61  mMesh(mesh_),
62  mStatusAttrib(statusAttrib_),
63  mColorAttrib(colorAttrib_),
64  mNormalAttrib(normalAttrib_),
65  mTexcoordAttrib(texcoordAttrib_),
66  mNumOfVertices(-1),
67  mCurrentNumOfVertices(-1),
68  mVertexSize(0),
69  mVertexDeclaration(),
70  mColorOffset(-1),
71  mNormalOffset(-1),
72  mScale(0.8),
73  mBuffer(0),
74  mCurrentPickOffset(-1),
75  mGlobalPickOffset(0),
76  mInvalidated(true),
77  mGeometryChanged(true),
78  mNormalsChanged(true),
79  mColorsChanged(true),
80  mTexCoordsChanged(true),
81  mDrawModes(),
82  mPrimitiveMode(PM_NONE),
83  mNormalMode(NM_NONE),
84  mColorMode(CM_NO_COLORS),
85  mSkipUnselected(false),
86  mShowIrregularInnerEdges(false),
87  mShowIrregularOuterValence2Edges(false),
88  mSkipRegularEdges(false),
89  mBoundaryOnly(false),
90  mCurrentPrimitiveMode(PM_NONE),
91  mCurrentNormalMode(NM_NONE),
92  mCurrentColorMode(CM_NO_COLORS),
93  mCurrentSkipUnselected(false),
94  mCurrentShowIrregularInnerEdges(false),
95  mCurrentShowIrregularOuterValence2Edges(false),
96  mCurrentSkipRegularEdges(false),
97  mCurrentBoundaryOnly(false),
98  mCurrentVertexSize(0),
99  mCurrentNormalOffset(0),
100  mCurrentColorOffset(0),
101  mCogsValid(false),
102  mCellInsidenessValid(),
103  mTexCoordMode(TCM_NONE),
104  mCurrentTexCoordMode(TCM_NONE),
105  mTexCoordOffset(0),
106  mCurrentTexCoordOffset(0)
107 {
108 
109 }
110 
120 template <class VolumeMesh>
121 void VolumeMeshBufferManager<VolumeMesh>::addFloatToBuffer( float _value, unsigned char *&_buffer )
122 {
123  // get pointer
124  unsigned char *v = (unsigned char *) &_value;
125 
126  // copy over 4 bytes
127  *_buffer++ = *v++;
128  *_buffer++ = *v++;
129  *_buffer++ = *v++;
130  *_buffer++ = *v;
131 }
132 
142 template <class VolumeMesh>
143 void VolumeMeshBufferManager<VolumeMesh>::addUCharToBuffer( unsigned char _value, unsigned char *&_buffer )
144 {
145  *_buffer = _value;
146  ++_buffer;
147 }
148 
159 template <class VolumeMesh>
160 void VolumeMeshBufferManager<VolumeMesh>::addPositionToBuffer(ACG::Vec3d _position, unsigned char* _buffer , unsigned int _offset)
161 {
162  unsigned char* buffer = _buffer + _offset*mVertexSize;
163  addFloatToBuffer(_position[0], buffer);
164  addFloatToBuffer(_position[1], buffer);
165  addFloatToBuffer(_position[2], buffer);
166 }
167 
178 template <class VolumeMesh>
179 void VolumeMeshBufferManager<VolumeMesh>::addColorToBuffer(ACG::Vec4uc _color, unsigned char* _buffer, unsigned int _offset)
180 {
181  unsigned char* buffer = _buffer + _offset*mVertexSize + mColorOffset;
182  addUCharToBuffer(_color[0], buffer);
183  addUCharToBuffer(_color[1], buffer);
184  addUCharToBuffer(_color[2], buffer);
185  addUCharToBuffer(_color[3], buffer);
186 }
187 
200 template <class VolumeMesh>
201 void VolumeMeshBufferManager<VolumeMesh>::addColorToBuffer(ACG::Vec4f _color, unsigned char* _buffer, unsigned int _offset)
202 {
203  unsigned char* buffer = _buffer + _offset*mVertexSize + mColorOffset;
204  addUCharToBuffer(_color[0]*255, buffer);
205  addUCharToBuffer(_color[1]*255, buffer);
206  addUCharToBuffer(_color[2]*255, buffer);
207  addUCharToBuffer(_color[3]*255, buffer);
208 }
209 
220 template <class VolumeMesh>
221 void VolumeMeshBufferManager<VolumeMesh>::addNormalToBuffer(ACG::Vec3d _normal, unsigned char* _buffer, unsigned int _offset)
222 {
223  unsigned char* buffer = _buffer + _offset*mVertexSize + mNormalOffset;
224  addFloatToBuffer(_normal[0], buffer);
225  addFloatToBuffer(_normal[1], buffer);
226  addFloatToBuffer(_normal[2], buffer);
227 }
228 
239 template <class VolumeMesh>
240 void VolumeMeshBufferManager<VolumeMesh>::addTexCoordToBuffer(ACG::Vec2f _texCoord, unsigned char* _buffer, unsigned int _offset)
241 {
242  unsigned char* buffer = _buffer + _offset*mVertexSize + mTexCoordOffset;
243  addFloatToBuffer(_texCoord[0], buffer);
244  addFloatToBuffer(_texCoord[1], buffer);
245 }
246 
247 
255 template <class VolumeMesh>
257 {
258  unsigned int currentOffset = 0;
259  mVertexDeclaration.clear();
260 
261  mNormalOffset = -1;
262  mColorOffset = -1;
263 
264  if (mPrimitiveMode != PM_NONE) //should always be the case
265  {
266  mVertexDeclaration.addElement(GL_FLOAT, 3, ACG::VERTEX_USAGE_POSITION, reinterpret_cast<GLuint*>(currentOffset));
267  currentOffset += 3*sizeof(float);
268  }
269 
270  if (mNormalMode != NM_NONE)
271  {
272  mNormalOffset = currentOffset;
273  mVertexDeclaration.addElement(GL_FLOAT, 3, ACG::VERTEX_USAGE_NORMAL, reinterpret_cast<GLuint*>(currentOffset));
274  currentOffset += 3*sizeof(float);
275  }
276 
277  if ((mColorMode != CM_NO_COLORS) || mShowIrregularInnerEdges || mShowIrregularOuterValence2Edges)
278  {
279  mColorOffset = currentOffset;
280  mVertexDeclaration.addElement(GL_UNSIGNED_BYTE, 4, ACG::VERTEX_USAGE_COLOR, reinterpret_cast<GLuint*>(currentOffset));
281  currentOffset += 4*sizeof(char);
282  }
283 
284  if ((mTexCoordMode != TCM_NONE))
285  {
286  mTexCoordOffset = currentOffset;
287  unsigned char numOfCoords = 0;
288  if (mTexCoordMode == TCM_SINGLE_2D)
289  numOfCoords = 2;
290  mVertexDeclaration.addElement(GL_FLOAT, numOfCoords, ACG::VERTEX_USAGE_TEXCOORD, reinterpret_cast<GLuint*>(currentOffset));
291  currentOffset += numOfCoords * sizeof(float);
292  }
293 
294  mVertexSize = currentOffset;
295 }
296 
297 
302 template <class VolumeMesh>
304 {
305  if (mNumOfVertices == -1)
306  countNumOfVertices();
307  return mNumOfVertices;
308 }
309 
317 template <class VolumeMesh>
319 {
320  if (mDefaultColor != _defaultColor)
321  {
322  invalidateColors();
323  mDefaultColor = _defaultColor;
324  }
325 }
326 
335 template <class VolumeMesh>
337 {
338  // colors
339  if (_drawMode & (mDrawModes.cellsColoredPerCell))
340  enablePerCellColors();
341  else if (_drawMode & (mDrawModes.cellsColoredPerFace | mDrawModes.facesColoredPerFace))
342  enablePerFaceColors();
343  else if (_drawMode & (mDrawModes.cellsColoredPerHalfface | mDrawModes.halffacesColoredPerHalfface))
344  enablePerHalffaceColors();
345  else if (_drawMode & ( mDrawModes.edgesColoredPerEdge ))
346  enablePerEdgeColors();
347  else if (_drawMode & (mDrawModes.halfedgesColoredPerHalfedge))
348  enablePerHalfedgeColors();
349  else if (_drawMode & (mDrawModes.cellsColoredPerVertex | mDrawModes.facesColoredPerVertex |
350  mDrawModes.halffacesColoredPerVertex | mDrawModes.edgesColoredPerEdge |
351  mDrawModes.verticesColored))
352  enablePerVertexColors();
353  else
354  disableColors();
355 
356  //normals
357  if (_drawMode & (mDrawModes.cellsFlatShaded | mDrawModes.halffacesFlatShaded))
358  enablePerHalffaceNormals();
359  else if (_drawMode & (mDrawModes.facesFlatShaded | mDrawModes.facesTexturedShaded))
360  enablePerFaceNormals();
361  else if (_drawMode & (mDrawModes.cellsSmoothShaded | mDrawModes.facesSmoothShaded | mDrawModes.halffacesSmoothShaded |
362  mDrawModes.cellsPhongShaded | mDrawModes.facesPhongShaded | mDrawModes.halffacesPhongShaded))
363  enablePerVertexNormals();
364  else
365  disableNormals();
366 
367  if (_drawMode & (mDrawModes.irregularInnerEdges))
368  mShowIrregularInnerEdges = true;
369  else
370  mShowIrregularInnerEdges = false;
371 
372  if (_drawMode & (mDrawModes.irregularOuterEdges))
373  mShowIrregularOuterValence2Edges = true;
374  else
375  mShowIrregularOuterValence2Edges = false;
376 
377  if (!mShowIrregularInnerEdges && !mShowIrregularOuterValence2Edges)
378  mSkipRegularEdges = false;
379  else
380  mSkipRegularEdges = true;
381 
382 
383  // textures
384  if (_drawMode & (mDrawModes.facesTextured | mDrawModes.facesTexturedShaded))
385  mTexCoordMode = TCM_SINGLE_2D;
386  else
387  mTexCoordMode = TCM_NONE;
388 
389  // primiive mode
390  if (_drawMode & (mDrawModes.cellBasedDrawModes))
391  mPrimitiveMode = PM_CELLS;
392  else if (_drawMode & (mDrawModes.facesOnCells))
393  mPrimitiveMode = PM_FACES_ON_CELLS;
394  else if (_drawMode & (mDrawModes.faceBasedDrawModes | mDrawModes.hiddenLineBackgroundFaces))
395  mPrimitiveMode = PM_FACES;
396  else if (_drawMode & (mDrawModes.halffaceBasedDrawModes))
397  mPrimitiveMode = PM_HALFFACES;
398  else if (_drawMode & (mDrawModes.edgesOnCells))
399  mPrimitiveMode = PM_EDGES_ON_CELLS;
400  else if (_drawMode & ((mDrawModes.edgeBasedDrawModes) & ~(mDrawModes.irregularInnerEdges | mDrawModes.irregularOuterEdges)))
401  mPrimitiveMode = PM_EDGES;
402  else if (_drawMode & (mDrawModes.irregularInnerEdges | mDrawModes.irregularOuterEdges)) // note: this has to be checked after _drawMode & (mDrawModes.edgeBasedDrawModes)
403  mPrimitiveMode = PM_IRREGULAR_EDGES; // if this is true, irregular edges are already included
404  else if (_drawMode & (mDrawModes.halfedgeBasedDrawModes))
405  mPrimitiveMode = PM_HALFEDGES;
406  else if (_drawMode & (mDrawModes.verticesOnCells))
407  mPrimitiveMode = PM_VERTICES_ON_CELLS;
408  else if (_drawMode & (mDrawModes.vertexBasedDrawModes))
409  mPrimitiveMode = PM_VERTICES;
410  else
411  mPrimitiveMode = PM_NONE;
412 
413 
414 }
415 
416 
423 template <class VolumeMesh>
425 {
426  cut_planes_.clear();
427  invalidateGeometry();
428  mCellInsidenessValid = false;
429 }
430 
438 template <class VolumeMesh>
440 {
441  cut_planes_.push_back(_p);
442  invalidateGeometry();
443  mCellInsidenessValid = false;
444 }
445 
456 template <class VolumeMesh>
457 void VolumeMeshBufferManager<VolumeMesh>::addCutPlane(const ACG::Vec3d &_p, const ACG::Vec3d &_n, const ACG::Vec3d &_xsize, const ACG::Vec3d &_ysize)
458 {
459  addCutPlane(Plane(_p, _n, _xsize, _ysize));
460 }
461 
469 template <class VolumeMesh>
471 {
472  for(typename std::vector<Plane>::iterator it = cut_planes_.begin(); it != cut_planes_.end(); ++it) {
473  // get local position
474  ACG::Vec3d pl = _p - it->position;
475  // evaluate dot products
476  double pn = (pl | it->normal);
477  double px = (pl | it->xdirection);
478  double py = (pl | it->ydirection);
479 
480  if (pn < 0.0 && px > -0.5 && px < 0.5 && py > -0.5 && py < 0.5)
481  return false;
482  }
483 
484  return true;
485 }
486 
496 template <class VolumeMesh>
498 {
499  if ( cut_planes_.empty() ) return true;
500  return is_inside(mMesh.vertex(_vh));
501 }
502 
512 template <class VolumeMesh>
514 {
515  if ( cut_planes_.empty() ) return true;
516  Edge e(mMesh.halfedge(_heh));
517  return is_inside(mMesh.vertex(e.from_vertex())) && is_inside(mMesh.vertex(e.to_vertex()));
518 }
519 
529 template <class VolumeMesh>
531 {
532  if ( cut_planes_.empty() ) return true;
533  Edge e(mMesh.edge(_eh));
534  return is_inside(mMesh.vertex(e.from_vertex())) && is_inside(mMesh.vertex(e.to_vertex()));
535 }
536 
546 template <class VolumeMesh>
548 {
549  if ( cut_planes_.empty() ) return true;
550  for (OpenVolumeMesh::HalfFaceVertexIter hfv_it = mMesh.hfv_iter(_hfh); hfv_it; ++hfv_it)
551  if (!is_inside(*hfv_it)) return false;
552 
553  return true;
554 }
555 
565 template <class VolumeMesh>
567 {
568  if ( cut_planes_.empty() ) return true;
569  return is_inside(mMesh.halfface_handle(_fh,0));
570 }
571 
583 template <class VolumeMesh>
585 {
586  if (!mCellInsidenessValid)
587  calculateCellInsideness();
588 
589  return mCellInsideness[_ch.idx()];
590 }
591 
592 
599 template <class VolumeMesh>
601 {
602  if (mCellInsideness.size() != mMesh.n_cells())
603  mCellInsideness.resize(mMesh.n_cells());
604 
605  for (unsigned int i = 0; i < mMesh.n_cells(); i++)
606  {
607  CellHandle ch = CellHandle(i);
608  bool inside;
609  ACG::Vec3d cog = getCOG(ch);
610  if ( cut_planes_.empty() )
611  inside = true;
612  else
613  {
614  inside = true;
615  for (OpenVolumeMesh::CellVertexIter cv_it = mMesh.cv_iter(ch); cv_it; ++cv_it)
616  {
617  ACG::Vec3d vertexPos = mScale * mMesh.vertex(*cv_it) + (1-mScale) * cog;
618  if (!is_inside(vertexPos)) inside = false;
619  }
620  }
621  mCellInsideness[i] = inside;
622  }
623 
624  mCellInsidenessValid = true;
625 }
626 
627 
635 template <class VolumeMesh>
637 {
638  return mCurrentPrimitiveMode != mPrimitiveMode ||
639  mCurrentNormalMode != mNormalMode ||
640  mCurrentColorMode != mColorMode ||
641  mCurrentSkipUnselected != mSkipUnselected ||
642  mCurrentShowIrregularInnerEdges != mShowIrregularInnerEdges ||
643  mCurrentShowIrregularOuterValence2Edges != mShowIrregularOuterValence2Edges ||
644  mCurrentSkipRegularEdges != mSkipRegularEdges ||
645  mCurrentBoundaryOnly != mBoundaryOnly;
646 }
647 
653 template <class VolumeMesh>
655 {
656  mCurrentPrimitiveMode = mPrimitiveMode;
657  mCurrentNormalMode = mNormalMode;
658  mCurrentColorMode = mColorMode;
659  mCurrentSkipUnselected = mSkipUnselected;
660  mCurrentShowIrregularInnerEdges = mShowIrregularInnerEdges;
661  mCurrentShowIrregularOuterValence2Edges = mShowIrregularOuterValence2Edges;
662  mCurrentSkipRegularEdges = mSkipRegularEdges;
663  mCurrentBoundaryOnly = mBoundaryOnly;
664  mCurrentVertexSize = mVertexSize;
665  mCurrentNormalOffset = mNormalOffset;
666  mCurrentColorOffset = mColorOffset;
667  mCurrentNumOfVertices = mNumOfVertices;
668 }
669 
670 
679 template <class VolumeMesh>
680 ACG::Vec4f VolumeMeshBufferManager<VolumeMesh>::getValenceColorCode(unsigned int _valence, bool _inner) const {
681 
682  if(_inner && _valence == 3) {
683  return ACG::Vec4f(0.0f, 1.0f, 1.0f, 1.0f);
684  } else if(_inner && _valence == 5) {
685  return ACG::Vec4f(1.0f, 0.0f, 1.0f, 1.0f);
686  } else if(!_inner && _valence > 3) {
687  return ACG::Vec4f(0.0f, 1.0f, 0.0f, 1.0f);
688  } else if(!_inner && _valence == 2) {
689  return ACG::Vec4f(1.0f, 1.0f, 0.0f, 1.0f);
690  } else if(_inner && _valence > 5) {
691  return ACG::Vec4f(0.5f, 1.0f, 0.5f, 1.0f);
692  }
693  return ACG::Vec4f(0.0f, 0.0f, 0.0f, 1.0f);
694 }
695 
701 template <class VolumeMesh>
703 {
704  unsigned int numOfVertices = 0;
705 
706  if (mSkipUnselected) //only count selected
707  {
708  if (mPrimitiveMode == PM_CELLS)
709  {
710  OpenVolumeMesh::CellIter c_begin(mMesh.cells_begin()), c_end(mMesh.cells_end());
711  for (OpenVolumeMesh::CellIter c_it = c_begin; c_it != c_end; ++c_it)
712  if (mStatusAttrib[*c_it].selected() && is_inside(*c_it))
713  {
714  std::vector<HalfFaceHandle> hfs = mMesh.cell(*c_it).halffaces();
715  for (unsigned int i = 0; i < hfs.size(); ++i)
716  numOfVertices += ((mMesh.valence(mMesh.face_handle(hfs[i])))-2)*3;
717  }
718  }
719  else if (mPrimitiveMode == PM_FACES)
720  {
721  OpenVolumeMesh::FaceIter f_begin(mMesh.faces_begin()), f_end(mMesh.faces_end());
722  for (OpenVolumeMesh::FaceIter f_it = f_begin; f_it != f_end; ++f_it)
723  if (mStatusAttrib[*f_it].selected() && is_inside(*f_it) && (!mBoundaryOnly || mMesh.is_boundary(*f_it)))
724  numOfVertices += ((mMesh.valence(*f_it))-2)*3; //additional vertices are added for faces with more than 3 adjacent vertices
725  }
726  else if (mPrimitiveMode == PM_FACES_ON_CELLS)
727  {
728  OpenVolumeMesh::FaceIter f_begin(mMesh.faces_begin()), f_end(mMesh.faces_end());
729  for (OpenVolumeMesh::FaceIter f_it = f_begin; f_it != f_end; ++f_it)
730  if (mStatusAttrib[*f_it].selected())
731  numOfVertices += ((mMesh.valence(*f_it))-2)*3*getNumOfIncidentCells(*f_it); //additional vertices are added for faces with more than 3 adjacent vertices
732  }
733  else if (mPrimitiveMode == PM_HALFFACES)
734  {
735  OpenVolumeMesh::HalfFaceIter hf_begin(mMesh.halffaces_begin()), hf_end(mMesh.halffaces_end());
736  for (OpenVolumeMesh::HalfFaceIter hf_it = hf_begin; hf_it != hf_end; ++hf_it)
737  if (mStatusAttrib[*hf_it].selected() && is_inside(*hf_it) && (!mBoundaryOnly || mMesh.is_boundary(*hf_it)))
738  numOfVertices += ((mMesh.valence(mMesh.face_handle(*hf_it)))-2)*3; //additional vertices are added for faces with more than 3 adjacent vertices
739  }
740  else if (mPrimitiveMode == PM_EDGES)
741  {
742  OpenVolumeMesh::EdgeIter e_begin(mMesh.edges_begin()), e_end(mMesh.edges_end());
743  for (OpenVolumeMesh::EdgeIter e_it = e_begin; e_it != e_end; ++e_it)
744  if (mStatusAttrib[*e_it].selected() && is_inside(*e_it) && (!mBoundaryOnly || mMesh.is_boundary(*e_it)))
745  numOfVertices += 2;
746  }
747  else if (mPrimitiveMode == PM_EDGES_ON_CELLS)
748  {
749  OpenVolumeMesh::EdgeIter e_begin(mMesh.edges_begin()), e_end(mMesh.edges_end());
750  for (OpenVolumeMesh::EdgeIter e_it = e_begin; e_it != e_end; ++e_it)
751  if (mStatusAttrib[*e_it].selected())
752  numOfVertices += 2*getNumOfIncidentCells(*e_it);
753  }
754  else if (mPrimitiveMode == PM_HALFEDGES)
755  {
756  OpenVolumeMesh::HalfEdgeIter he_begin(mMesh.halfedges_begin()), he_end(mMesh.halfedges_end());
757  for (OpenVolumeMesh::HalfEdgeIter he_it = he_begin; he_it != he_end; ++he_it)
758  if (mStatusAttrib[*he_it].selected() && is_inside(*he_it) && (!mBoundaryOnly || mMesh.is_boundary(*he_it)))
759  numOfVertices += 2;
760  }
761  else if (mPrimitiveMode == PM_VERTICES)
762  {
763  OpenVolumeMesh::VertexIter v_begin(mMesh.vertices_begin()), v_end(mMesh.vertices_end());
764  for (OpenVolumeMesh::VertexIter v_it = v_begin; v_it != v_end; ++v_it)
765  if (mStatusAttrib[*v_it].selected() && is_inside(*v_it) && (!mBoundaryOnly || mMesh.is_boundary(*v_it)))
766  numOfVertices += 1;
767  }
768  else if (mPrimitiveMode == PM_VERTICES_ON_CELLS)
769  {
770  OpenVolumeMesh::VertexIter v_begin(mMesh.vertices_begin()), v_end(mMesh.vertices_end());
771  for (OpenVolumeMesh::VertexIter v_it = v_begin; v_it != v_end; ++v_it)
772  if (mStatusAttrib[*v_it].selected())
773  numOfVertices += getNumOfIncidentCells(*v_it);
774  }
775  }
776  else
777  {
778  if (mPrimitiveMode == PM_VERTICES_ON_CELLS)
779  {
780  for (unsigned int i = 0; i < mMesh.n_vertices(); i++)
781  numOfVertices += getNumOfIncidentCells(VertexHandle(i));
782  }
783  else if (mPrimitiveMode == PM_VERTICES)
784  {
785  for (unsigned int i = 0; i < mMesh.n_vertices(); i++)
786  if (is_inside(VertexHandle(i)) && (!mBoundaryOnly || mMesh.is_boundary(VertexHandle(i))))
787  numOfVertices += 1;
788  }
789  else if (mPrimitiveMode == PM_FACES)
790  {
791  OpenVolumeMesh::FaceIter f_begin(mMesh.faces_begin()), f_end(mMesh.faces_end());
792  for (OpenVolumeMesh::FaceIter f_it = f_begin; f_it != f_end; ++f_it)
793  if (is_inside(*f_it) && (!mBoundaryOnly || mMesh.is_boundary(*f_it)))
794  numOfVertices += ((mMesh.valence(*f_it))-2)*3; //additional vertices are added for faces with more than 3 adjacent vertices
795  }
796  else if (mPrimitiveMode == PM_FACES_ON_CELLS)
797  {
798  OpenVolumeMesh::FaceIter f_begin(mMesh.faces_begin()), f_end(mMesh.faces_end());
799  for (OpenVolumeMesh::FaceIter f_it = f_begin; f_it != f_end; ++f_it)
800  numOfVertices += ((mMesh.valence(*f_it))-2)*3*getNumOfIncidentCells(*f_it); //additional vertices are added for faces with more than 3 adjacent vertices
801  }
802  else if (mPrimitiveMode == PM_HALFFACES)
803  {
804  OpenVolumeMesh::HalfFaceIter hf_begin(mMesh.halffaces_begin()), hf_end(mMesh.halffaces_end());
805  for (OpenVolumeMesh::HalfFaceIter hf_it = hf_begin; hf_it != hf_end; ++hf_it)
806  if (is_inside(*hf_it) && (!mBoundaryOnly || mMesh.is_boundary(*hf_it)))
807  numOfVertices += ((mMesh.valence(mMesh.face_handle(*hf_it)))-2)*3; //additional vertices are added for faces with more than 3 adjacent vertices
808  }
809  else if (mPrimitiveMode == PM_CELLS)
810  {
811  OpenVolumeMesh::CellIter c_begin(mMesh.cells_begin()), c_end(mMesh.cells_end());
812  for (OpenVolumeMesh::CellIter c_it = c_begin; c_it != c_end; ++c_it)
813  {
814  if (is_inside(*c_it))
815  {
816  std::vector<HalfFaceHandle> hfs = mMesh.cell(*c_it).halffaces();
817  for (unsigned int i = 0; i < hfs.size(); ++i)
818  numOfVertices += ((mMesh.valence(mMesh.face_handle(hfs[i])))-2)*3;
819  }
820  }
821  }
822  else if (mPrimitiveMode == PM_EDGES_ON_CELLS)
823  {
824  for (OpenVolumeMesh::EdgeIter e_it = mMesh.edges_begin(); e_it != mMesh.edges_end(); ++e_it)
825  numOfVertices += 2*getNumOfIncidentCells(*e_it);
826  }
827  else if ( mPrimitiveMode == PM_EDGES ) //all edges are drawn, so irregular ones are already included
828  {
829  for (OpenVolumeMesh::EdgeIter e_it = mMesh.edges_begin(); e_it != mMesh.edges_end(); ++e_it)
830  if (is_inside(*e_it) && (!mBoundaryOnly || mMesh.is_boundary(*e_it)))
831  numOfVertices += 2;
832  }
833  else if ( mPrimitiveMode == PM_IRREGULAR_EDGES )
834  {
835  for (OpenVolumeMesh::EdgeIter e_it = mMesh.edges_begin(); e_it != mMesh.edges_end(); ++e_it)
836  if (is_inside(*e_it) && (!mBoundaryOnly || mMesh.is_boundary(*e_it)))
837  {
838  bool boundary = mMesh.is_boundary(*e_it);
839  unsigned int valence = mMesh.valence(*e_it);
840 
841  // Skip regular edges
842  if(( boundary && valence == 3) || (!boundary && valence == 4)) continue;
843  //skip boundary valence 2 edges if not drawn
844  if ((!(mShowIrregularOuterValence2Edges)) && ( boundary && valence == 2)) continue;
845  //skip irregular inner edges if not drawn
846  if ((!(mShowIrregularInnerEdges)) && (( !boundary && valence != 4) ||
847  ( boundary && valence < 2) ||
848  ( boundary && valence > 3))) continue;
849 
850  numOfVertices += 2;
851  }
852  }
853  else if ( mPrimitiveMode == PM_HALFEDGES )
854  {
855  for (OpenVolumeMesh::HalfEdgeIter he_it = mMesh.halfedges_begin(); he_it != mMesh.halfedges_end(); ++he_it)
856  if (is_inside(*he_it) && (!mBoundaryOnly || mMesh.is_boundary(*he_it)))
857  numOfVertices += 2;
858  }
859  else /*if ( mPrimitiveMode == PM_NONE)*/
860  {
861  numOfVertices = 0;
862  }
863  }
864 
865  mNumOfVertices = numOfVertices;
866 }
867 
875 template <class VolumeMesh>
877 {
878  int incidentCells = 0;
879  OpenVolumeMesh::HalfFaceHandle hf0 = mMesh.halfface_handle(_fh, 0);
880  if (mMesh.incident_cell(hf0) != CellHandle(-1))
881  if (is_inside(mMesh.incident_cell(hf0)))
882  incidentCells += 1;
883  OpenVolumeMesh::HalfFaceHandle hf1 = mMesh.halfface_handle(_fh, 1);
884  if (mMesh.incident_cell(hf1) != CellHandle(-1))
885  if (is_inside(mMesh.incident_cell(hf1)))
886  incidentCells += 1;
887  return incidentCells;
888 }
889 
897 template <class VolumeMesh>
899 {
900  int incidentCells = 0;
901  OpenVolumeMesh::HalfEdgeHandle heh = mMesh.halfedge_handle(_eh, 0);
902  for (OpenVolumeMesh::HalfEdgeCellIter hec_it = OpenVolumeMesh::HalfEdgeCellIter(heh,&mMesh); hec_it.valid(); ++hec_it)
903  if (hec_it->idx() != -1)
904  if (is_inside(*hec_it))
905  incidentCells++;
906  return incidentCells;
907 }
908 
916 template <class VolumeMesh>
918 {
919  int incidentCells = 0;
920  for (OpenVolumeMesh::VertexCellIter vc_it = OpenVolumeMesh::VertexCellIter(_vh,&mMesh); vc_it; ++vc_it)
921  if (vc_it->idx() != -1)
922  if (is_inside(*vc_it))
923  incidentCells++;
924  return incidentCells;
925 }
926 
934 template <class VolumeMesh>
936 {
937  if (!mCogsValid)
938  calculateCOGs();
939 
940  return mCogs[_ch.idx()];
941 }
942 
950 template <class VolumeMesh>
952 {
953  if (mCogs.size() != mMesh.n_cells())
954  mCogs.resize(mMesh.n_cells());
955 
956  OpenVolumeMesh::CellIter c_begin(mMesh.cells_begin()), c_end(mMesh.cells_end());
957  for (OpenVolumeMesh::CellIter c_it = c_begin; c_it != c_end; ++c_it)
958  {
959 
960  std::vector<HalfFaceHandle> hfs = mMesh.cell(*c_it).halffaces();
961  ACG::Vec3d cog = ACG::Vec3d(0.0f);
962  int count = 0;
963  for (unsigned int i = 0; i < hfs.size(); ++i)
964  for (OpenVolumeMesh::HalfFaceVertexIter hfv_it = mMesh.hfv_iter(hfs[i]); hfv_it; ++hfv_it)
965  {
966  cog += mMesh.vertex(*hfv_it);
967  count += 1;
968  }
969  cog = 1.0/count * cog;
970 
971  mCogs[c_it->idx()] = cog;
972  }
973 
974  mCogsValid = true;
975 }
976 
982 template <class VolumeMesh>
984 {
985  return (mGeometryChanged) ||
986  (mVertexSize != mCurrentVertexSize) ||
987  (mPrimitiveMode != mCurrentPrimitiveMode) ||
988  (mNumOfVertices != mCurrentNumOfVertices);
989 }
990 
996 template <class VolumeMesh>
998 {
999  return (mColorsChanged) ||
1000  (mVertexSize != mCurrentVertexSize) ||
1001  (mNumOfVertices != mCurrentNumOfVertices) ||
1002  (mPrimitiveMode != mCurrentPrimitiveMode) ||
1003  (mColorOffset != mCurrentColorOffset) ||
1004  (mColorMode != mCurrentColorMode) ||
1005  (mShowIrregularInnerEdges != mCurrentShowIrregularInnerEdges) ||
1006  (mShowIrregularOuterValence2Edges != mCurrentShowIrregularOuterValence2Edges);
1007 }
1008 
1014 template <class VolumeMesh>
1016 {
1017  return (mTexCoordsChanged) ||
1018  (mVertexSize != mCurrentVertexSize) ||
1019  (mNumOfVertices != mCurrentNumOfVertices) ||
1020  (mPrimitiveMode != mCurrentPrimitiveMode) ||
1021  (mTexCoordOffset!= mCurrentTexCoordOffset);
1022 }
1023 
1029 template <class VolumeMesh>
1031 {
1032  return (mNormalsChanged) ||
1033  (mVertexSize != mCurrentVertexSize) ||
1034  (mPrimitiveMode != mCurrentPrimitiveMode) ||
1035  (mNormalOffset != mCurrentNormalOffset) ||
1036  (mNormalMode != mCurrentNormalMode) ||
1037  (mNumOfVertices != mCurrentNumOfVertices);
1038 }
1039 
1045 template <class VolumeMesh>
1047 {
1048  unsigned int pos = 0;
1049 
1050  if (mPrimitiveMode == PM_VERTICES)
1051  {
1052  for (unsigned int i = 0; i < mMesh.n_vertices(); ++i) {
1053  if (mSkipUnselected && !mStatusAttrib[VertexHandle(i)].selected()) continue;
1054  if (!is_inside(VertexHandle(i))) continue;
1055  if (mBoundaryOnly && !mMesh.is_boundary(VertexHandle(i))) continue;
1056  ACG::Vec3d p = mMesh.vertex(VertexHandle(i));
1057  addPositionToBuffer(p, _buffer, pos++);
1058  }
1059  }
1060  else if (mPrimitiveMode == PM_VERTICES_ON_CELLS)
1061  {
1062  for (unsigned int i = 0; i < mMesh.n_vertices(); ++i) {
1063  if (mSkipUnselected && !mStatusAttrib[VertexHandle(i)].selected()) continue;
1064  ACG::Vec3d p = mMesh.vertex(VertexHandle(i));
1065  for (OpenVolumeMesh::VertexCellIter vc_it = OpenVolumeMesh::VertexCellIter(VertexHandle(i),&mMesh); vc_it; ++vc_it)
1066  {
1067  ACG::Vec3d cog = getCOG(*vc_it);
1068  //ACG::Vec3d newPos = p*mScale + cog*(1-mScale);
1069  if (is_inside(*vc_it))
1070  addPositionToBuffer(p*mScale + cog*(1-mScale), _buffer, pos++);
1071  }
1072  }
1073  }
1074  else if (mPrimitiveMode == PM_FACES)
1075  {
1076  std::vector<ACG::Vec3d> vertices;
1077  OpenVolumeMesh::FaceIter f_begin(mMesh.faces_begin()), f_end(mMesh.faces_end());
1078  for (OpenVolumeMesh::FaceIter f_it = f_begin; f_it != f_end; ++f_it)
1079  {
1080  if (mSkipUnselected && !mStatusAttrib[*f_it].selected()) continue;
1081  if (mBoundaryOnly && !mMesh.is_boundary(*f_it)) continue;
1082  if (!is_inside(*f_it)) continue;
1083  vertices.clear();
1084  for (OpenVolumeMesh::HalfFaceVertexIter hfv_it = mMesh.hfv_iter(mMesh.halfface_handle(*f_it,0)); hfv_it; ++hfv_it)
1085  vertices.push_back(mMesh.vertex(*hfv_it));
1086 
1087  for (unsigned int i = 0; i < vertices.size()-2; i++)
1088  {
1089  addPositionToBuffer(vertices[0], _buffer, pos++);
1090  addPositionToBuffer(vertices[i+1], _buffer, pos++);
1091  addPositionToBuffer(vertices[i+2], _buffer, pos++);
1092  }
1093  }
1094  }
1095  else if (mPrimitiveMode == PM_FACES_ON_CELLS)
1096  {
1097  std::vector<ACG::Vec3d> vertices;
1098  OpenVolumeMesh::FaceIter f_begin(mMesh.faces_begin()), f_end(mMesh.faces_end());
1099  for (OpenVolumeMesh::FaceIter f_it = f_begin; f_it != f_end; ++f_it)
1100  {
1101  if (mSkipUnselected && !mStatusAttrib[*f_it].selected()) continue;
1102  vertices.clear();
1103  for (OpenVolumeMesh::HalfFaceVertexIter hfv_it = mMesh.hfv_iter(mMesh.halfface_handle(*f_it,0)); hfv_it; ++hfv_it)
1104  vertices.push_back(mMesh.vertex(*hfv_it));
1105 
1106  for (int i = 0; i < 2; i++)
1107  {
1108  OpenVolumeMesh::CellHandle ch = mMesh.incident_cell(mMesh.halfface_handle(*f_it,i));
1109  if (ch != CellHandle(-1))
1110  {
1111  if (!is_inside(ch)) continue;
1112  ACG::Vec3d cog = getCOG(ch);
1113  for (unsigned int i = 0; i < vertices.size()-2; i++)
1114  {
1115  //we dont care about the correct facing because we dont cull the back side of faces
1116  addPositionToBuffer(vertices[0]*mScale + cog*(1-mScale), _buffer, pos++);
1117  addPositionToBuffer(vertices[i+1]*mScale + cog*(1-mScale), _buffer, pos++);
1118  addPositionToBuffer(vertices[i+2]*mScale + cog*(1-mScale), _buffer, pos++);
1119  }
1120  }
1121  }
1122 
1123  }
1124  }
1125  else if (mPrimitiveMode == PM_HALFFACES)
1126  {
1127  std::vector<ACG::Vec3d> vertices;
1128  OpenVolumeMesh::HalfFaceIter hf_begin(mMesh.halffaces_begin()), hf_end(mMesh.halffaces_end());
1129  for (OpenVolumeMesh::HalfFaceIter hf_it = hf_begin; hf_it != hf_end; ++hf_it)
1130  {
1131  if (mSkipUnselected && !mStatusAttrib[*hf_it].selected()) continue;
1132  if (mBoundaryOnly && !mMesh.is_boundary(*hf_it)) continue;
1133  if (!is_inside(*hf_it)) continue;
1134  vertices.clear();
1135  for (OpenVolumeMesh::HalfFaceVertexIter hfv_it = mMesh.hfv_iter(*hf_it); hfv_it; ++hfv_it)
1136  vertices.push_back(mMesh.vertex(*hfv_it));
1137 
1138  for (unsigned int i = 0; i < vertices.size()-2; i++)
1139  {
1140  addPositionToBuffer(vertices[0], _buffer, pos++);
1141  addPositionToBuffer(vertices[i+1], _buffer, pos++);
1142  addPositionToBuffer(vertices[i+2], _buffer, pos++);
1143  }
1144  }
1145  }
1146  else if (mPrimitiveMode == PM_CELLS)
1147  {
1148  std::vector<ACG::Vec3d> vertices;
1149  OpenVolumeMesh::CellIter c_begin(mMesh.cells_begin()), c_end(mMesh.cells_end());
1150  for (OpenVolumeMesh::CellIter c_it = c_begin; c_it != c_end; ++c_it)
1151  {
1152  if (mSkipUnselected && !mStatusAttrib[*c_it].selected()) continue;
1153  if (!is_inside(*c_it)) continue;
1154  std::vector<HalfFaceHandle> hfs = mMesh.cell(*c_it).halffaces();
1155  ACG::Vec3d cog = getCOG(*c_it);
1156  for (unsigned int i = 0; i < hfs.size(); ++i)
1157  {
1158  vertices.clear();
1159  for (OpenVolumeMesh::HalfFaceVertexIter hfv_it = mMesh.hfv_iter(hfs[i]); hfv_it; ++hfv_it)
1160  vertices.push_back(mScale*mMesh.vertex(*hfv_it)+(1-mScale)*cog);
1161 
1162  for (unsigned int i = 0; i < vertices.size()-2; i++)
1163  {
1164  addPositionToBuffer(vertices[0], _buffer, pos++);
1165  addPositionToBuffer(vertices[i+1], _buffer, pos++);
1166  addPositionToBuffer(vertices[i+2], _buffer, pos++);
1167  }
1168  }
1169  }
1170 
1171  }
1172  else if (mPrimitiveMode == PM_EDGES)
1173  {
1174  OpenVolumeMesh::EdgeIter e_begin(mMesh.edges_begin()), e_end(mMesh.edges_end());
1175  for (OpenVolumeMesh::EdgeIter e_it = e_begin; e_it != e_end; ++e_it)
1176  {
1177  if (mSkipUnselected && !mStatusAttrib[*e_it].selected()) continue;
1178  if (mBoundaryOnly && !mMesh.is_boundary(*e_it)) continue;
1179  if (!is_inside(*e_it)) continue;
1180 
1181  Edge e(mMesh.edge(*e_it));
1182  addPositionToBuffer(mMesh.vertex(e.from_vertex()), _buffer, pos++);
1183  addPositionToBuffer(mMesh.vertex(e.to_vertex()), _buffer, pos++);
1184  }
1185  }
1186  else if (mPrimitiveMode == PM_EDGES_ON_CELLS)
1187  {
1188  OpenVolumeMesh::EdgeIter e_begin(mMesh.edges_begin()), e_end(mMesh.edges_end());
1189  for (OpenVolumeMesh::EdgeIter e_it = e_begin; e_it != e_end; ++e_it)
1190  {
1191  if (mSkipUnselected && !mStatusAttrib[*e_it].selected()) continue;
1192 
1193  Edge e(mMesh.edge(*e_it));
1194  OpenVolumeMesh::HalfEdgeHandle heh = mMesh.halfedge_handle(*e_it, 0);
1195  for (OpenVolumeMesh::HalfEdgeCellIter hec_it = OpenVolumeMesh::HalfEdgeCellIter(heh,&mMesh); hec_it.valid(); ++hec_it)
1196  {
1197  if (hec_it->idx() != -1)
1198  {
1199  if (!is_inside(*hec_it)) continue;
1200  ACG::Vec3d cog = getCOG(*hec_it);
1201  addPositionToBuffer(mMesh.vertex(e.from_vertex())*mScale + cog*(1-mScale), _buffer, pos++);
1202  addPositionToBuffer(mMesh.vertex(e.to_vertex()) *mScale + cog*(1-mScale), _buffer, pos++);
1203  }
1204  }
1205  }
1206  }
1207  else if (mPrimitiveMode == PM_IRREGULAR_EDGES)
1208  {
1209  OpenVolumeMesh::EdgeIter e_begin(mMesh.edges_begin()), e_end(mMesh.edges_end());
1210  for (OpenVolumeMesh::EdgeIter e_it = e_begin; e_it != e_end; ++e_it)
1211  {
1212  if (mSkipUnselected && !mStatusAttrib[*e_it].selected()) continue;
1213  if (mBoundaryOnly && !mMesh.is_boundary(*e_it)) continue;
1214  if (!is_inside(*e_it)) continue;
1215 
1216  bool boundary = mMesh.is_boundary(*e_it);
1217  unsigned int valence = mMesh.valence(*e_it);
1218  // Skip regular
1219  if(( boundary && valence == 3) ||
1220  (!boundary && valence == 4)) continue;
1221  //skip boundary valence 2 edges if not drawn
1222  if ((!mShowIrregularOuterValence2Edges) && ( boundary && valence == 2)) continue;
1223  //skip irregular inner edges if not drawn
1224  if ((!mShowIrregularInnerEdges) && (( !boundary && valence != 4) ||
1225  ( boundary && valence < 2) ||
1226  ( boundary && valence > 3))) continue;
1227 
1228  Edge e(mMesh.edge(*e_it));
1229  addPositionToBuffer(mMesh.vertex(e.from_vertex()), _buffer, pos++);
1230  addPositionToBuffer(mMesh.vertex(e.to_vertex()), _buffer, pos++);
1231  }
1232  }
1233  else if (mPrimitiveMode == PM_HALFEDGES)
1234  {
1235  OpenVolumeMesh::HalfEdgeIter he_begin(mMesh.halfedges_begin()), he_end(mMesh.halfedges_end());
1236  for (OpenVolumeMesh::HalfEdgeIter he_it = he_begin; he_it != he_end; ++he_it)
1237  {
1238  if (mSkipUnselected && !mStatusAttrib[*he_it].selected()) continue;
1239  if (mBoundaryOnly && !mMesh.is_boundary(*he_it)) continue;
1240  if (!is_inside(*he_it)) continue;
1241 
1242  double lambda = 0.4;
1243  Edge e(mMesh.halfedge(*he_it));
1244  addPositionToBuffer(mMesh.vertex(e.from_vertex()), _buffer, pos++);
1245  addPositionToBuffer((1-lambda)*mMesh.vertex(e.from_vertex()) + lambda*mMesh.vertex(e.to_vertex()), _buffer, pos++);
1246  }
1247  }
1248  else /*if (mPrimitiveMode == PM_NONE)*/
1249  {
1250  //This case should not happen. Do nothing.
1251  }
1252 }
1253 
1259 template <class VolumeMesh>
1261 {
1262  if (mNormalMode == NM_NONE) return;
1263 
1264  unsigned int pos = 0;
1265 
1266  if ((mPrimitiveMode == PM_FACES) && (mNormalMode == NM_FACE))
1267  {
1268  OpenVolumeMesh::FaceIter f_begin(mMesh.faces_begin()), f_end(mMesh.faces_end());
1269  for (OpenVolumeMesh::FaceIter f_it = f_begin; f_it != f_end; ++f_it)
1270  {
1271  if (mBoundaryOnly && !mMesh.is_boundary(*f_it)) continue;
1272  if (!is_inside(*f_it)) continue;
1273  ACG::Vec3d normal = mNormalAttrib[*f_it];
1274  unsigned int numOfVerticesInFace = mMesh.valence(*f_it);
1275 
1276  for (unsigned int i = 0; i < numOfVerticesInFace - 2; i++)
1277  {
1278  addNormalToBuffer(normal, _buffer, pos++);
1279  addNormalToBuffer(normal, _buffer, pos++);
1280  addNormalToBuffer(normal, _buffer, pos++);
1281  }
1282  }
1283  }
1284  else if ((mPrimitiveMode == PM_FACES) && (mNormalMode == NM_VERTEX))
1285  {
1286  std::vector<ACG::Vec3d> normals;
1287  OpenVolumeMesh::FaceIter f_begin(mMesh.faces_begin()), f_end(mMesh.faces_end());
1288  for (OpenVolumeMesh::FaceIter f_it = f_begin; f_it != f_end; ++f_it)
1289  {
1290  if (mBoundaryOnly && !mMesh.is_boundary(*f_it)) continue;
1291  if (!is_inside(*f_it)) continue;
1292  normals.clear();
1293  for (OpenVolumeMesh::HalfFaceVertexIter hfv_it = mMesh.hfv_iter(mMesh.halfface_handle(*f_it,0)); hfv_it; ++hfv_it)
1294  normals.push_back(mNormalAttrib[*hfv_it]);
1295 
1296  for (unsigned int i = 0; i < normals.size()-2; i++)
1297  {
1298  addNormalToBuffer(normals[0], _buffer, pos++);
1299  addNormalToBuffer(normals[i+1], _buffer, pos++);
1300  addNormalToBuffer(normals[i+2], _buffer, pos++);
1301  }
1302  }
1303  }
1304  else if ((mPrimitiveMode == PM_HALFFACES) && (mNormalMode == NM_HALFFACE))
1305  {
1306  OpenVolumeMesh::HalfFaceIter hf_begin(mMesh.halffaces_begin()), hf_end(mMesh.halffaces_end());
1307  for (OpenVolumeMesh::HalfFaceIter hf_it = hf_begin; hf_it != hf_end; ++hf_it)
1308  {
1309  if (mBoundaryOnly && !mMesh.is_boundary(*hf_it)) continue;
1310  if (!is_inside(*hf_it)) continue;
1311  ACG::Vec3d normal = mNormalAttrib[*hf_it];
1312  unsigned int numOfVerticesInCell = 0;
1313  for (OpenVolumeMesh::HalfFaceVertexIter hfv_it = mMesh.hfv_iter(*hf_it); hfv_it; ++hfv_it)
1314  ++numOfVerticesInCell;
1315 
1316  for (unsigned int i = 0; i < numOfVerticesInCell- 2; i++)
1317  {
1318  addNormalToBuffer(normal, _buffer, pos++);
1319  addNormalToBuffer(normal, _buffer, pos++);
1320  addNormalToBuffer(normal, _buffer, pos++);
1321  }
1322  }
1323  }
1324  else if ((mPrimitiveMode == PM_HALFFACES) && (mNormalMode == NM_VERTEX))
1325  {
1326  std::vector<ACG::Vec3d> normals;
1327  OpenVolumeMesh::HalfFaceIter hf_begin(mMesh.halffaces_begin()), hf_end(mMesh.halffaces_end());
1328  for (OpenVolumeMesh::HalfFaceIter hf_it = hf_begin; hf_it != hf_end; ++hf_it)
1329  {
1330  if (mBoundaryOnly && !mMesh.is_boundary(*hf_it)) continue;
1331  if (!is_inside(*hf_it)) continue;
1332  normals.clear();
1333  for (OpenVolumeMesh::HalfFaceVertexIter hfv_it = mMesh.hfv_iter(*hf_it); hfv_it; ++hfv_it)
1334  normals.push_back(mNormalAttrib[*hfv_it]);
1335 
1336  for (unsigned int i = 0; i < normals.size()-2; i++)
1337  {
1338  addNormalToBuffer(normals[0], _buffer, pos++);
1339  addNormalToBuffer(normals[i+1], _buffer, pos++);
1340  addNormalToBuffer(normals[i+2], _buffer, pos++);
1341  }
1342  }
1343  }
1344  else if ((mPrimitiveMode == PM_CELLS) && (mNormalMode == NM_HALFFACE))
1345  {
1346  OpenVolumeMesh::CellIter c_begin(mMesh.cells_begin()), c_end(mMesh.cells_end());
1347  for (OpenVolumeMesh::CellIter c_it = c_begin; c_it != c_end; ++c_it)
1348  {
1349  if (!is_inside(*c_it)) continue;
1350  std::vector<HalfFaceHandle> hfs = mMesh.cell(*c_it).halffaces();
1351  for (unsigned int i = 0; i < hfs.size(); ++i)
1352  {
1353  ACG::Vec3d normal = -1.0*mNormalAttrib[hfs[i]];
1354  unsigned int numOfVerticesInFace = mMesh.valence(mMesh.face_handle(hfs[i]));
1355 
1356  for (unsigned int i = 0; i < numOfVerticesInFace-2; i++)
1357  {
1358  addNormalToBuffer(normal, _buffer, pos++);
1359  addNormalToBuffer(normal, _buffer, pos++);
1360  addNormalToBuffer(normal, _buffer, pos++);
1361  }
1362  }
1363  }
1364  }
1365  else if ((mPrimitiveMode == PM_CELLS) && (mNormalMode == NM_VERTEX))
1366  {
1367  std::vector<ACG::Vec3d> normals;
1368  OpenVolumeMesh::CellIter c_begin(mMesh.cells_begin()), c_end(mMesh.cells_end());
1369  for (OpenVolumeMesh::CellIter c_it = c_begin; c_it != c_end; ++c_it)
1370  {
1371  if (!is_inside(*c_it)) continue;
1372  std::vector<HalfFaceHandle> hfs = mMesh.cell(*c_it).halffaces();
1373 
1374  for (unsigned int i = 0; i < hfs.size(); ++i)
1375  {
1376  normals.clear();
1377  for (OpenVolumeMesh::HalfFaceVertexIter hfv_it = mMesh.hfv_iter(hfs[i]); hfv_it; ++hfv_it)
1378  normals.push_back(mNormalAttrib[*hfv_it]);
1379 
1380  for (unsigned int i = 0; i < normals.size()-2; i++)
1381  {
1382  addNormalToBuffer(normals[0], _buffer, pos++);
1383  addNormalToBuffer(normals[i+1], _buffer, pos++);
1384  addNormalToBuffer(normals[i+2], _buffer, pos++);
1385  }
1386  }
1387  }
1388  }
1389 
1390 }
1391 
1397 template <class VolumeMesh>
1399 {
1400  unsigned int pos = 0;
1401 
1402  if ((mPrimitiveMode == PM_VERTICES) && (mColorMode == CM_VERTEX))
1403  {
1404  for (unsigned int i = 0; i < mMesh.n_vertices(); ++i)
1405  {
1406  if (mBoundaryOnly && !mMesh.is_boundary(VertexHandle(i))) continue;
1407  if (!is_inside(VertexHandle(i))) continue;
1408  ACG::Vec4f color = mColorAttrib[VertexHandle(i)];
1409  addColorToBuffer(color, _buffer, pos++);
1410  }
1411  }
1412  else if ((mPrimitiveMode == PM_FACES) && (mColorMode == CM_VERTEX))
1413  {
1414  std::vector<ACG::Vec4f> colors;
1415  OpenVolumeMesh::FaceIter f_begin(mMesh.faces_begin()), f_end(mMesh.faces_end());
1416  for (OpenVolumeMesh::FaceIter f_it = f_begin; f_it != f_end; ++f_it)
1417  {
1418  if (mBoundaryOnly && !mMesh.is_boundary(*f_it)) continue;
1419  if (!is_inside(*f_it)) continue;
1420  colors.clear();
1421 
1422  for (OpenVolumeMesh::HalfFaceVertexIter hfv_it = mMesh.hfv_iter(mMesh.halfface_handle(*f_it,0)); hfv_it; ++hfv_it)
1423  colors.push_back(mColorAttrib[*hfv_it]);
1424 
1425  for (unsigned int i = 0; i < (colors.size()-2); i++)
1426  {
1427  addColorToBuffer(colors[0], _buffer, pos++);
1428  addColorToBuffer(colors[i+1], _buffer, pos++);
1429  addColorToBuffer(colors[i+2], _buffer, pos++);
1430  }
1431  }
1432  }
1433  else if ((mPrimitiveMode == PM_FACES) && (mColorMode == CM_FACE))
1434  {
1435  OpenVolumeMesh::FaceIter f_begin(mMesh.faces_begin()), f_end(mMesh.faces_end());
1436  for (OpenVolumeMesh::FaceIter f_it = f_begin; f_it != f_end; ++f_it)
1437  {
1438  if (mBoundaryOnly && !mMesh.is_boundary(*f_it)) continue;
1439  if (!is_inside(*f_it)) continue;
1440  ACG::Vec4f color = mColorAttrib[*f_it];
1441 
1442  unsigned int numOfVerticesInFace = mMesh.valence(*f_it);
1443  unsigned int numOfDrawnTriangles = numOfVerticesInFace-2;
1444 
1445  for (unsigned int i = 0; i < numOfDrawnTriangles*3; i++)
1446  addColorToBuffer(color, _buffer, pos++);
1447  }
1448  }
1449  else if ((mPrimitiveMode == PM_HALFFACES) && (mColorMode == CM_HALFFACE))
1450  {
1451  OpenVolumeMesh::HalfFaceIter hf_begin(mMesh.halffaces_begin()), hf_end(mMesh.halffaces_end());
1452  for (OpenVolumeMesh::HalfFaceIter hf_it = hf_begin; hf_it != hf_end; ++hf_it)
1453  {
1454  if (mBoundaryOnly && !mMesh.is_boundary(*hf_it)) continue;
1455  if (!is_inside(*hf_it)) continue;
1456  ACG::Vec4f color = mColorAttrib[*hf_it];
1457 
1458  unsigned int numOfVerticesInFace = mMesh.valence(mMesh.face_handle(*hf_it));
1459  unsigned int numOfDrawnTriangles = numOfVerticesInFace-2;
1460 
1461  for (unsigned int i = 0; i < numOfDrawnTriangles*3; i++)
1462  addColorToBuffer(color, _buffer, pos++);
1463  }
1464  }
1465  else if ((mPrimitiveMode == PM_HALFFACES) && (mColorMode == CM_VERTEX))
1466  {
1467  std::vector<ACG::Vec4f> colors;
1468  OpenVolumeMesh::HalfFaceIter hf_begin(mMesh.halffaces_begin()), hf_end(mMesh.halffaces_end());
1469  for (OpenVolumeMesh::HalfFaceIter hf_it = hf_begin; hf_it != hf_end; ++hf_it)
1470  {
1471  if (mBoundaryOnly && !mMesh.is_boundary(*hf_it)) continue;
1472  if (!is_inside(*hf_it)) continue;
1473  colors.clear();
1474 
1475  for (OpenVolumeMesh::HalfFaceVertexIter hfv_it = mMesh.hfv_iter(*hf_it); hfv_it; ++hfv_it)
1476  colors.push_back(mColorAttrib[*hfv_it]);
1477 
1478  for (unsigned int i = 0; i < (colors.size()-2); i++)
1479  {
1480  addColorToBuffer(colors[0], _buffer, pos++);
1481  addColorToBuffer(colors[i+1], _buffer, pos++);
1482  addColorToBuffer(colors[i+2], _buffer, pos++);
1483  }
1484  }
1485  }
1486  else if ((mPrimitiveMode == PM_CELLS) && (mColorMode == CM_CELL))
1487  {
1488  OpenVolumeMesh::CellIter c_begin(mMesh.cells_begin()), c_end(mMesh.cells_end());
1489  for (OpenVolumeMesh::CellIter c_it = c_begin; c_it != c_end; ++c_it)
1490  {
1491  if (!is_inside(*c_it)) continue;
1492  ACG::Vec4f color = mColorAttrib[*c_it];
1493  std::vector<HalfFaceHandle> hfs = mMesh.cell(*c_it).halffaces();
1494  for (unsigned int i = 0; i < hfs.size(); ++i)
1495  {
1496  unsigned int numOfVerticesInHalfface = 0;
1497  for (OpenVolumeMesh::HalfFaceVertexIter hfv_it = mMesh.hfv_iter(hfs[i]); hfv_it; ++hfv_it)
1498  ++numOfVerticesInHalfface;
1499 
1500  unsigned int numOfDrawnFaces = numOfVerticesInHalfface-2;
1501  for (unsigned int i = 0; i < numOfDrawnFaces*3; i++)
1502  addColorToBuffer(color, _buffer, pos++);
1503  }
1504  }
1505  }
1506  else if ((mPrimitiveMode == PM_CELLS) && (mColorMode == CM_HALFFACE))
1507  {
1508  OpenVolumeMesh::CellIter c_begin(mMesh.cells_begin()), c_end(mMesh.cells_end());
1509  for (OpenVolumeMesh::CellIter c_it = c_begin; c_it != c_end; ++c_it)
1510  {
1511  if (!is_inside(*c_it)) continue;
1512  std::vector<HalfFaceHandle> hfs = mMesh.cell(*c_it).halffaces();
1513  for (unsigned int i = 0; i < hfs.size(); ++i)
1514  {
1515  ACG::Vec4f color = mColorAttrib[hfs[i]];
1516  unsigned int numOfVerticesInHalfface = 0;
1517  for (OpenVolumeMesh::HalfFaceVertexIter hfv_it = mMesh.hfv_iter(hfs[i]); hfv_it; ++hfv_it)
1518  ++numOfVerticesInHalfface;
1519 
1520  unsigned int numOfDrawnFaces = numOfVerticesInHalfface-2;
1521  for (unsigned int i = 0; i < numOfDrawnFaces*3; i++)
1522  addColorToBuffer(color, _buffer, pos++);
1523  }
1524  }
1525  }
1526  else if ((mPrimitiveMode == PM_CELLS) && (mColorMode == CM_FACE))
1527  {
1528  OpenVolumeMesh::CellIter c_begin(mMesh.cells_begin()), c_end(mMesh.cells_end());
1529  for (OpenVolumeMesh::CellIter c_it = c_begin; c_it != c_end; ++c_it)
1530  {
1531  if (!is_inside(*c_it)) continue;
1532  std::vector<HalfFaceHandle> hfs = mMesh.cell(*c_it).halffaces();
1533  for (unsigned int i = 0; i < hfs.size(); ++i)
1534  {
1535  ACG::Vec4f color = mColorAttrib[mMesh.face_handle(hfs[i])];
1536  unsigned int numOfVerticesInHalfface = 0;
1537  for (OpenVolumeMesh::HalfFaceVertexIter hfv_it = mMesh.hfv_iter(hfs[i]); hfv_it; ++hfv_it)
1538  ++numOfVerticesInHalfface;
1539 
1540  unsigned int numOfDrawnFaces = numOfVerticesInHalfface-2;
1541  for (unsigned int i = 0; i < numOfDrawnFaces*3; i++)
1542  addColorToBuffer(color, _buffer, pos++);
1543  }
1544  }
1545  }
1546  else if ((mPrimitiveMode == PM_CELLS) && (mColorMode == CM_VERTEX))
1547  {
1548  std::vector<ACG::Vec4f> colors;
1549  OpenVolumeMesh::CellIter c_begin(mMesh.cells_begin()), c_end(mMesh.cells_end());
1550  for (OpenVolumeMesh::CellIter c_it = c_begin; c_it != c_end; ++c_it)
1551  {
1552  if (!is_inside(*c_it)) continue;
1553  std::vector<HalfFaceHandle> hfs = mMesh.cell(*c_it).halffaces();
1554  for (unsigned int i = 0; i < hfs.size(); ++i)
1555  {
1556  colors.clear();
1557  for (OpenVolumeMesh::HalfFaceVertexIter hfv_it = mMesh.hfv_iter(hfs[i]); hfv_it; ++hfv_it)
1558  colors.push_back(mColorAttrib[*hfv_it]);
1559 
1560  for (unsigned int i = 0; i < colors.size()-2; i++)
1561  {
1562  addColorToBuffer(colors[0], _buffer, pos++);
1563  addColorToBuffer(colors[i+1], _buffer, pos++);
1564  addColorToBuffer(colors[i+2], _buffer, pos++);
1565  }
1566  }
1567  }
1568  }
1569  else if ((mPrimitiveMode == PM_EDGES) && (mColorMode == CM_EDGE))
1570  {
1571  OpenVolumeMesh::EdgeIter e_begin(mMesh.edges_begin()), e_end(mMesh.edges_end());
1572  for (OpenVolumeMesh::EdgeIter e_it = e_begin; e_it != e_end; ++e_it)
1573  {
1574  if (mBoundaryOnly && !mMesh.is_boundary(*e_it)) continue;
1575  if (!is_inside(*e_it)) continue;
1576  ACG::Vec4f color = mColorAttrib[*e_it];
1577  addColorToBuffer(color, _buffer, pos++);
1578  addColorToBuffer(color, _buffer, pos++);
1579  }
1580  }
1581  else if ((mPrimitiveMode == PM_EDGES) && (mShowIrregularInnerEdges || mShowIrregularOuterValence2Edges))
1582  {
1583  OpenVolumeMesh::EdgeIter e_begin(mMesh.edges_begin()), e_end(mMesh.edges_end());
1584  for (OpenVolumeMesh::EdgeIter e_it = e_begin; e_it != e_end; ++e_it)
1585  {
1586  if (mBoundaryOnly && !mMesh.is_boundary(*e_it)) continue;
1587  if (!is_inside(*e_it)) continue;
1588 
1589  bool boundary = mMesh.is_boundary(*e_it);
1590  unsigned int valence = mMesh.valence(*e_it);
1591 
1592  bool isIrregularInner = ( boundary && valence < 2) || ( boundary && valence > 3) || (!boundary && valence != 4);
1593  bool isIrregularOuterValence2 = ( boundary && valence == 2);
1594 
1595  ACG::Vec4f color;
1596 
1597  if (isIrregularInner && mShowIrregularInnerEdges)
1598  color = getValenceColorCode(valence, !boundary);
1599  else if (isIrregularOuterValence2 && mShowIrregularOuterValence2Edges)
1600  color = getValenceColorCode(valence, !boundary);
1601  else
1602  color = mDefaultColor;
1603 
1604  addColorToBuffer(color, _buffer, pos++);
1605  addColorToBuffer(color, _buffer, pos++);
1606  }
1607  }
1608  else if ( mPrimitiveMode == PM_IRREGULAR_EDGES )
1609  {
1610  OpenVolumeMesh::EdgeIter e_begin(mMesh.edges_begin()), e_end(mMesh.edges_end());
1611  for (OpenVolumeMesh::EdgeIter e_it = e_begin; e_it != e_end; ++e_it)
1612  {
1613  if (mBoundaryOnly && !mMesh.is_boundary(*e_it)) continue;
1614  if (!is_inside(*e_it)) continue;
1615 
1616  bool boundary = mMesh.is_boundary(*e_it);
1617  unsigned int valence = mMesh.valence(*e_it);
1618 
1619  bool isRegular = ( boundary && valence == 3) || (!boundary && valence == 4);
1620  bool isIrregularInner = ( boundary && valence < 2) || ( boundary && valence > 3) || (!boundary && valence != 4);
1621  bool isIrregularOuterValence2 = ( boundary && valence == 2);
1622 
1623  if (isRegular) continue;
1624  if (isIrregularInner && !mShowIrregularInnerEdges) continue;
1625  if (isIrregularOuterValence2 && !mShowIrregularOuterValence2Edges) continue;
1626 
1627  ACG::Vec4f color;
1628 
1629  if (isIrregularInner && mShowIrregularInnerEdges)
1630  color = getValenceColorCode(valence, !boundary);
1631  else if (isIrregularOuterValence2 && mShowIrregularOuterValence2Edges)
1632  color = getValenceColorCode(valence, !boundary);
1633  else
1634  color = mDefaultColor;
1635 
1636  addColorToBuffer(color, _buffer, pos++);
1637  addColorToBuffer(color, _buffer, pos++);
1638  }
1639  }
1640  else if ((mPrimitiveMode == PM_HALFEDGES) && (mColorMode == CM_HALFEDGE))
1641  {
1642  OpenVolumeMesh::HalfEdgeIter he_begin(mMesh.halfedges_begin()), he_end(mMesh.halfedges_end());
1643  for (OpenVolumeMesh::HalfEdgeIter he_it = he_begin; he_it != he_end; ++he_it)
1644  {
1645  if (mBoundaryOnly && !mMesh.is_boundary(*he_it)) continue;
1646  if (!is_inside(*he_it)) continue;
1647  ACG::Vec4f color = mColorAttrib[*he_it];
1648 
1649  addColorToBuffer(color, _buffer, pos++);
1650  addColorToBuffer(color, _buffer, pos++);
1651  }
1652  }
1653 
1654 }
1655 
1661 template <class VolumeMesh>
1663 {
1664 
1665  unsigned int pos = 0;
1666 
1667  if (mTexCoordMode == TCM_NONE)
1668  return;
1669 
1670  if (mPrimitiveMode == PM_FACES)
1671  {
1672  std::vector<ACG::Vec2f> texCoords;
1673  OpenVolumeMesh::FaceIter f_begin(mMesh.faces_begin()), f_end(mMesh.faces_end());
1674  for (OpenVolumeMesh::FaceIter f_it = f_begin; f_it != f_end; ++f_it)
1675  {
1676  if (mBoundaryOnly && !mMesh.is_boundary(*f_it)) continue;
1677  if (!is_inside(*f_it)) continue;
1678  texCoords.clear();
1679 
1680  for (OpenVolumeMesh::HalfFaceVertexIter hfv_it = mMesh.hfv_iter(mMesh.halfface_handle(*f_it,0)); hfv_it; ++hfv_it)
1681  texCoords.push_back(mTexcoordAttrib[*hfv_it]);
1682 
1683  for (unsigned int i = 0; i < (texCoords.size()-2); i++)
1684  {
1685  addTexCoordToBuffer(texCoords[0], _buffer, pos++);
1686  addTexCoordToBuffer(texCoords[i+1], _buffer, pos++);
1687  addTexCoordToBuffer(texCoords[i+2], _buffer, pos++);
1688  }
1689  }
1690  }
1691  else if (mPrimitiveMode == PM_HALFFACES)
1692  {
1693  std::vector<ACG::Vec2f> texCoords;
1694  OpenVolumeMesh::HalfFaceIter hf_begin(mMesh.halffaces_begin()), hf_end(mMesh.halffaces_end());
1695  for (OpenVolumeMesh::HalfFaceIter hf_it = hf_begin; hf_it != hf_end; ++hf_it)
1696  {
1697  if (mBoundaryOnly && !mMesh.is_boundary(*hf_it)) continue;
1698  if (!is_inside(*hf_it)) continue;
1699  texCoords.clear();
1700 
1701  for (OpenVolumeMesh::HalfFaceVertexIter hfv_it = mMesh.hfv_iter(*hf_it); hfv_it; ++hfv_it)
1702  texCoords.push_back(mTexcoordAttrib[*hfv_it]);
1703 
1704  for (unsigned int i = 0; i < (texCoords.size()-2); i++)
1705  {
1706  addTexCoordToBuffer(texCoords[0], _buffer, pos++);
1707  addTexCoordToBuffer(texCoords[i+1], _buffer, pos++);
1708  addTexCoordToBuffer(texCoords[i+2], _buffer, pos++);
1709  }
1710  }
1711  }
1712 
1713 }
1714 
1723 template <class VolumeMesh>
1724 void VolumeMeshBufferManager<VolumeMesh>::buildPickColorBuffer(ACG::GLState& _state, unsigned int _offset, unsigned char* _buffer)
1725 {
1726  unsigned int pos = 0;
1727 
1728  if (mPrimitiveMode == PM_VERTICES)
1729  {
1730  for (unsigned int i = 0; i < mMesh.n_vertices(); ++i)
1731  {
1732  if (mBoundaryOnly && !mMesh.is_boundary(VertexHandle(i))) continue;
1733  if (!is_inside(VertexHandle(i))) continue;
1734  ACG::Vec4uc color = _state.pick_get_name_color(VertexHandle(i).idx() + _offset);
1735  addColorToBuffer(color, _buffer, pos++);
1736  }
1737  }
1738  if (mPrimitiveMode == PM_VERTICES_ON_CELLS)
1739  {
1740  for (unsigned int i = 0; i < mMesh.n_vertices(); ++i) {
1741  ACG::Vec4uc color = _state.pick_get_name_color(VertexHandle(i).idx() + _offset);
1742  unsigned int numOfIncidentCells = getNumOfIncidentCells(VertexHandle(i));
1743  for (unsigned int j = 0; j < numOfIncidentCells; j++)
1744  addColorToBuffer(color, _buffer, pos++);
1745  }
1746  }
1747  else if (mPrimitiveMode == PM_EDGES)
1748  {
1749  OpenVolumeMesh::EdgeIter e_begin(mMesh.edges_begin()), e_end(mMesh.edges_end());
1750  for (OpenVolumeMesh::EdgeIter e_it = e_begin; e_it != e_end; ++e_it)
1751  {
1752  if (mBoundaryOnly && !mMesh.is_boundary(*e_it)) continue;
1753  if (!is_inside(*e_it)) continue;
1754  ACG::Vec4uc color = _state.pick_get_name_color(e_it->idx()+_offset);
1755  addColorToBuffer(color, _buffer, pos++);
1756  addColorToBuffer(color, _buffer, pos++);
1757  }
1758  }
1759  else if (mPrimitiveMode == PM_EDGES_ON_CELLS)
1760  {
1761  OpenVolumeMesh::EdgeIter e_begin(mMesh.edges_begin()), e_end(mMesh.edges_end());
1762  for (OpenVolumeMesh::EdgeIter e_it = e_begin; e_it != e_end; ++e_it)
1763  {
1764  ACG::Vec4uc color = _state.pick_get_name_color(e_it->idx()+_offset);
1765  unsigned int numOfIncidentCells = getNumOfIncidentCells(*e_it);
1766  for (unsigned int i = 0; i < numOfIncidentCells*2;i++)
1767  addColorToBuffer(color, _buffer, pos++);
1768  }
1769  }
1770  else if (mPrimitiveMode == PM_FACES)
1771  {
1772  OpenVolumeMesh::FaceIter f_begin(mMesh.faces_begin()), f_end(mMesh.faces_end());
1773  for (OpenVolumeMesh::FaceIter f_it = f_begin; f_it != f_end; ++f_it)
1774  {
1775  if (mBoundaryOnly && !mMesh.is_boundary(*f_it)) continue;
1776  if (!is_inside(*f_it)) continue;
1777  ACG::Vec4uc color = _state.pick_get_name_color(f_it->idx());
1778 
1779  unsigned int numOfVertices = 0;
1780  for (OpenVolumeMesh::HalfFaceVertexIter hfv_it = mMesh.hfv_iter(mMesh.halfface_handle(*f_it,0)); hfv_it; ++hfv_it)
1781  ++numOfVertices;
1782 
1783  for (unsigned int i = 0; i < (numOfVertices-2)*3; i++)
1784  addColorToBuffer(color, _buffer, pos++);
1785  }
1786  }
1787  else if (mPrimitiveMode == PM_FACES_ON_CELLS)
1788  {
1789  OpenVolumeMesh::FaceIter f_begin(mMesh.faces_begin()), f_end(mMesh.faces_end());
1790  for (OpenVolumeMesh::FaceIter f_it = f_begin; f_it != f_end; ++f_it)
1791  {
1792  ACG::Vec4uc color = _state.pick_get_name_color(f_it->idx()+_offset);
1793 
1794  unsigned int numOfVerticesInHalfface = 0;
1795  for (OpenVolumeMesh::HalfFaceVertexIter hfv_it = mMesh.hfv_iter(mMesh.halfface_handle(*f_it,0)); hfv_it; ++hfv_it)
1796  ++numOfVerticesInHalfface;
1797 
1798  for (int i = 0; i < 2; i++)
1799  {
1800  OpenVolumeMesh::CellHandle ch = mMesh.incident_cell(mMesh.halfface_handle(*f_it,i));
1801  if (ch != CellHandle(-1))
1802  {
1803  if (!is_inside(ch)) continue;
1804  for (unsigned int i = 0; i < (numOfVerticesInHalfface-2)*3; i++)
1805  addColorToBuffer(color, _buffer, pos++);
1806  }
1807  }
1808  }
1809  }
1810  else if (mPrimitiveMode == PM_CELLS)
1811  {
1812  OpenVolumeMesh::CellIter c_begin(mMesh.cells_begin()), c_end(mMesh.cells_end());
1813  for (OpenVolumeMesh::CellIter c_it = c_begin; c_it != c_end; ++c_it)
1814  {
1815  if (!is_inside(*c_it)) continue;
1816  ACG::Vec4uc color = _state.pick_get_name_color(c_it->idx()+_offset);
1817  std::vector<HalfFaceHandle> hfs = mMesh.cell(*c_it).halffaces();
1818  for (unsigned int i = 0; i < hfs.size(); ++i)
1819  {
1820  unsigned int numOfVerticesInHalfface = 0;
1821  for (OpenVolumeMesh::HalfFaceVertexIter hfv_it = mMesh.hfv_iter(hfs[i]); hfv_it; ++hfv_it)
1822  ++numOfVerticesInHalfface;
1823 
1824  unsigned int numOfDrawnFaces = numOfVerticesInHalfface-2;
1825  for (unsigned int i = 0; i < numOfDrawnFaces*3; i++)
1826  addColorToBuffer(color, _buffer, pos++);
1827  }
1828  }
1829  }
1830 }
1831 
1839 template <class VolumeMesh>
1841 {
1842  if ((mBuffer == 0) || optionsChanged() || mInvalidated)
1843  {
1844 
1845  if (mBuffer == 0)
1846  ACG::GLState::genBuffers(1, &mBuffer);
1847 
1848  calculateVertexDeclaration();
1849 
1850  if (optionsChanged())
1851  mNumOfVertices = -1;
1852 
1853  unsigned int numOfVertices = getNumOfVertices();
1854 
1855  if (getNumOfVertices() > 0)
1856  {
1857 
1858  unsigned int bufferSize = mVertexSize * numOfVertices;
1859 
1860  ACG::GLState::bindBuffer(GL_ARRAY_BUFFER, mBuffer);
1861  ACG::GLState::bufferData(GL_ARRAY_BUFFER, bufferSize, 0, GL_STATIC_DRAW);
1862 
1863  unsigned char* buffer = (unsigned char *) ACG::GLState::mapBuffer(
1864  GL_ARRAY_BUFFER, GL_READ_WRITE);
1865 
1866  if (buffer)
1867  {
1868 
1869  if (positionsNeedRebuild())
1870  buildVertexBuffer(buffer);
1871  if (normalsNeedRebuild())
1872  buildNormalBuffer(buffer);
1873  if (colorsNeedRebuild())
1874  buildColorBuffer(buffer);
1875  if (texCoordsNeedRebuild())
1876  buildTexCoordBuffer(buffer);
1877 
1878 
1879  ACG::GLState::unmapBuffer(GL_ARRAY_BUFFER);
1880 
1881  ACG::GLState::bindBuffer(GL_ARRAY_BUFFER, 0);
1882 
1883  }
1884  else
1885  {
1886  std::cerr << "error while mapping buffer" << std::endl;
1887  }
1888 
1889  }
1890 
1891  saveOptions();
1892  mInvalidated = false;
1893  mGeometryChanged = false;
1894  mColorsChanged = false;
1895  mNormalsChanged = false;
1896  mTexCoordsChanged = false;
1897 
1898  }
1899 
1900  return mBuffer;
1901 }
1902 
1911 template <class VolumeMesh>
1913 {
1914  if (_offset != mCurrentPickOffset || _state.pick_current_index() != mGlobalPickOffset)
1915  {
1916  invalidateColors();
1917  mGlobalPickOffset = _state.pick_current_index();
1918  }
1919 
1920  if ((mBuffer == 0) || optionsChanged() || mInvalidated)
1921  {
1922  if (mBuffer == 0)
1923  ACG::GLState::genBuffers(1, &mBuffer);
1924 
1925  calculateVertexDeclaration();
1926 
1927  if (optionsChanged())
1928  mNumOfVertices = -1;
1929 
1930  unsigned int numOfVertices = getNumOfVertices();
1931 
1932  if (getNumOfVertices() > 0)
1933  {
1934 
1935  unsigned int bufferSize = mVertexSize * numOfVertices;
1936 
1937  ACG::GLState::bindBuffer(GL_ARRAY_BUFFER, mBuffer);
1938  ACG::GLState::bufferData(GL_ARRAY_BUFFER, bufferSize, 0, GL_STATIC_DRAW);
1939 
1940  unsigned char* buffer = (unsigned char *) ACG::GLState::mapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE);
1941 
1942  if (buffer)
1943  {
1944 
1945  if (positionsNeedRebuild())
1946  buildVertexBuffer(buffer);
1947  if (colorsNeedRebuild())
1948  buildPickColorBuffer(_state, _offset, buffer);
1949 
1950  ACG::GLState::unmapBuffer(GL_ARRAY_BUFFER);
1951 
1952  ACG::GLState::bindBuffer(GL_ARRAY_BUFFER, 0);
1953 
1954  }
1955  else
1956  {
1957  std::cerr << "error while mapping buffer" << std::endl;
1958  }
1959 
1960  }
1961 
1962  mCurrentPickOffset = _offset;
1963  saveOptions();
1964  mInvalidated = false;
1965  mGeometryChanged = false;
1966  mColorsChanged = false;
1967  mTexCoordsChanged = false;
1968 
1969  }
1970 
1971  return mBuffer;
1972 }
1973 
1977 template <class VolumeMesh>
1979 {
1980  invalidateGeometry();
1981  invalidateNormals();
1982  invalidateColors();
1983 }
1984 
1988 template <class VolumeMesh>
1990 {
1991  mInvalidated = true;
1992  mNumOfVertices = -1;
1993  mGeometryChanged = true;
1994  mColorsChanged = true;
1995  mTexCoordsChanged = true;
1996  mNormalsChanged = true;
1997  mCogsValid = false;
1998  mCellInsidenessValid = false;
1999 }
2000 
2004 template <class VolumeMesh>
2006 {
2007  mInvalidated = true;
2008  mColorsChanged = true;
2009 }
2010 
2014 template <class VolumeMesh>
2016 {
2017  mInvalidated = true;
2018  mNormalsChanged = true;
2019 }
2020 
2024 template <class VolumeMesh>
2026 {
2027  mInvalidated = true;
2028  mTexCoordsChanged = true;
2029 }
2030 
2036 template <class VolumeMesh>
2038 {
2039  if (mBuffer != 0)
2040  ACG::GLState::deleteBuffers(1, &mBuffer);
2041 
2042  mBuffer = 0;
2043 
2044  invalidate();
2045 }
ACG::Vec4f getValenceColorCode(unsigned int _valence, bool _inner) const
Returns a color code for irregular edges.
void setOptionsFromDrawMode(ACG::SceneGraph::DrawModes::DrawMode _drawMode)
Configures the buffer manager's options from a DrawMode.
void calculateCOGs()
Calculates the center of gravity for all cells.
Namespace providing different geometric functions concerning angles.
Definition: DBSCANT.cc:51
static void bindBuffer(GLenum _target, GLuint _buffer)
replaces glBindBuffer, supports locking
Definition: GLState.cc:1764
void invalidate()
Invalidates the buffer.
void clearCutPlanes()
Removes all cut planes.
void invalidateColors()
Invalidates colors.
void invalidateNormals()
Invalidates normals.
void buildColorBuffer(unsigned char *_buffer)
Adds all colors to the buffer.
Vec4uc pick_get_name_color(unsigned int _idx)
Definition: GLState.cc:1064
bool texCoordsNeedRebuild()
Checks whether texture coordinates need to be rebuild.
void free()
Deletes the buffers on the GPU.
void addPositionToBuffer(ACG::Vec3d _position, unsigned char *_buffer, unsigned int _offset)
Adds a position to the buffer.
VectorT< float, 4 > Vec4f
Definition: VectorT.hh:144
static GLboolean unmapBuffer(GLenum target)
Definition: GLState.cc:2114
void addUCharToBuffer(unsigned char _value, unsigned char *&_buffer)
Adds an unsigned char to the buffer.
VectorT< double, 3 > Vec3d
Definition: VectorT.hh:127
bool positionsNeedRebuild()
Checks whether positions need to be rebuild.
static GLvoid * mapBuffer(GLenum target, GLenum access)
Definition: GLState.cc:2109
This class creates buffers that can be used to render open volume meshs.
void addCutPlane(const typename VolumeMeshBufferManager< VolumeMesh >::Plane &_p)
Adds a cut plane.
GLuint getBuffer()
Returns the name of the buffer.
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 buildPickColorBuffer(ACG::GLState &_state, unsigned int _offset, unsigned char *_buffer)
Adds all picking colors to the buffer.
void setDefaultColor(ACG::Vec4f _defaultColor)
Sets the default color.
GLuint getPickBuffer(ACG::GLState &_state, unsigned int _offset)
Returns the name of the pick buffer.
void calculateVertexDeclaration()
Constructs a VertexDeclaration, the size and the offsets for the vertices stored in the buffer...
void addNormalToBuffer(ACG::Vec3d _normal, unsigned char *_buffer, unsigned int _offset)
Adds a normal to the buffer.
void addColorToBuffer(ACG::Vec4uc _color, unsigned char *_buffer, unsigned int _offset)
Adds a color to the buffer.
unsigned int pick_current_index() const
Returns the current color picking index (can be used for caching)
Definition: GLState.cc:1114
void buildVertexBuffer(unsigned char *_buffer)
Adds all vertices to the buffer.
void saveOptions()
State that the current buffer was built with the current options.
void countNumOfVertices()
Counts the number of vertices that need to be stored in the buffer.
void calculateCellInsideness()
Calculates for all cells whether they are inside w.r.t. all cut planes.
bool optionsChanged()
Tests whether the options were changed since the last time building the buffer.
void buildTexCoordBuffer(unsigned char *_buffer)
Adds texture coordinates to the buffer.
void addTexCoordToBuffer(ACG::Vec2f _texCoord, unsigned char *_buffer, unsigned int _offset)
Adds a texture coordnate to the buffer.
unsigned int getNumOfVertices()
Returns the number of vertices stored in the buffer.
void invalidateTexCoords()
Invalidates texture coordinates.
static void deleteBuffers(GLsizei n, const GLuint *buffers)
Definition: GLState.cc:2105
static void bufferData(GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage)
Definition: GLState.cc:2100
void addFloatToBuffer(float _value, unsigned char *&_buffer)
Adds a float to the buffer.
void invalidateGeometry()
Invalidates geometry.
static void genBuffers(GLsizei n, GLuint *buffers)
Definition: GLState.cc:2091
bool colorsNeedRebuild()
Checks whether colors need to be rebuild.
bool normalsNeedRebuild()
Checks whether normals need to be rebuild.
bool is_inside(const ACG::Vec3d &_p)
Tests whether the given point is inside w.r.t. all cut planes.
void buildNormalBuffer(unsigned char *_buffer)
Adds all normals to the buffer.
ACG::Vec3d getCOG(OpenVolumeMesh::CellHandle _ch)
Returns the center of gravity of the given cell.