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.facesColoredPerFace | 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 (mStatusAttrib[_ch].hidden())
582  return false;
583 
584  if (!mCellInsidenessValid)
586 
587  return mCellInsideness[_ch.idx()];
588 }
589 
590 template <class VolumeMesh>
592 {
593  if (mStatusAttrib[_vh].hidden())
594  return false;
595  return is_inside(_vh);
596 }
597 
598 template <class VolumeMesh>
600 {
601  if (mStatusAttrib[_heh].hidden())
602  return false;
603  return is_inside(_heh);
604 }
605 
606 template <class VolumeMesh>
608 {
609  if (mStatusAttrib[_eh].hidden())
610  return false;
611  return is_inside(_eh);
612 }
613 
614 template <class VolumeMesh>
616 {
617  if (mStatusAttrib[_hfh].hidden())
618  return false;
619  return is_inside(_hfh);
620 }
621 
622 template <class VolumeMesh>
624 {
625  if (mStatusAttrib[_fh].hidden())
626  return false;
627  return is_inside(_fh);
628 }
629 
630 template <class VolumeMesh>
632 {
633  if (mStatusAttrib[_ch].hidden())
634  return false;
635  return is_inside(_ch);
636 }
637 
638 
645 template <class VolumeMesh>
647 {
648  if (mCellInsideness.size() != mMesh.n_cells())
649  mCellInsideness.resize(mMesh.n_cells());
650 
651  for (unsigned int i = 0; i < mMesh.n_cells(); i++)
652  {
653  CellHandle ch = CellHandle(i);
654  bool inside;
655  ACG::Vec3d cog = getCOG(ch);
656  if ( cut_planes_.empty() )
657  inside = true;
658  else
659  {
660  inside = true;
661  for (OpenVolumeMesh::CellVertexIter cv_it = mMesh.cv_iter(ch); cv_it; ++cv_it)
662  {
663  ACG::Vec3d vertexPos = mScale * mMesh.vertex(*cv_it) + (1-mScale) * cog;
664  if (!is_inside(vertexPos)) inside = false;
665  }
666  }
667  mCellInsideness[i] = inside;
668  }
669 
670  mCellInsidenessValid = true;
671 }
672 
673 
681 template <class VolumeMesh>
683 {
684  return mCurrentPrimitiveMode != mPrimitiveMode ||
685  mCurrentNormalMode != mNormalMode ||
686  mCurrentColorMode != mColorMode ||
687  mCurrentSkipUnselected != mSkipUnselected ||
688  mCurrentShowIrregularInnerEdges != mShowIrregularInnerEdges ||
689  mCurrentShowIrregularOuterValence2Edges != mShowIrregularOuterValence2Edges ||
690  mCurrentSkipRegularEdges != mSkipRegularEdges ||
691  mCurrentBoundaryOnly != mBoundaryOnly;
692 }
693 
699 template <class VolumeMesh>
701 {
702  mCurrentPrimitiveMode = mPrimitiveMode;
703  mCurrentNormalMode = mNormalMode;
704  mCurrentColorMode = mColorMode;
705  mCurrentSkipUnselected = mSkipUnselected;
706  mCurrentShowIrregularInnerEdges = mShowIrregularInnerEdges;
707  mCurrentShowIrregularOuterValence2Edges = mShowIrregularOuterValence2Edges;
708  mCurrentSkipRegularEdges = mSkipRegularEdges;
709  mCurrentBoundaryOnly = mBoundaryOnly;
710  mCurrentVertexSize = mVertexSize;
711  mCurrentNormalOffset = mNormalOffset;
712  mCurrentColorOffset = mColorOffset;
713  mCurrentNumOfVertices = mNumOfVertices;
714 }
715 
716 
725 template <class VolumeMesh>
726 ACG::Vec4f VolumeMeshBufferManager<VolumeMesh>::getValenceColorCode(unsigned int _valence, bool _inner) const {
727 
728  if(_inner && _valence == 3) {
729  return ACG::Vec4f(0.0f, 1.0f, 1.0f, 1.0f);
730  } else if(_inner && _valence == 5) {
731  return ACG::Vec4f(1.0f, 0.0f, 1.0f, 1.0f);
732  } else if(!_inner && _valence > 3) {
733  return ACG::Vec4f(0.0f, 1.0f, 0.0f, 1.0f);
734  } else if(!_inner && _valence == 2) {
735  return ACG::Vec4f(1.0f, 1.0f, 0.0f, 1.0f);
736  } else if(_inner && _valence > 5) {
737  return ACG::Vec4f(0.5f, 1.0f, 0.5f, 1.0f);
738  }
739  return ACG::Vec4f(0.0f, 0.0f, 0.0f, 1.0f);
740 }
741 
747 template <class VolumeMesh>
749 {
750  unsigned int numOfVertices = 0;
751 
752  if (mSkipUnselected) //only count selected
753  {
754  if (mPrimitiveMode == PM_CELLS)
755  {
756  OpenVolumeMesh::CellIter c_begin(mMesh.cells_begin()), c_end(mMesh.cells_end());
757  for (OpenVolumeMesh::CellIter c_it = c_begin; c_it != c_end; ++c_it)
758  {
759  if (mStatusAttrib[*c_it].selected() && should_render(*c_it))
760  {
761  std::vector<HalfFaceHandle> hfs = mMesh.cell(*c_it).halffaces();
762  for (unsigned int i = 0; i < hfs.size(); ++i)
763  numOfVertices += ((mMesh.valence(mMesh.face_handle(hfs[i])))-2)*3;
764  }
765  }
766  }
767  else if (mPrimitiveMode == PM_FACES)
768  {
769  OpenVolumeMesh::FaceIter f_begin(mMesh.faces_begin()), f_end(mMesh.faces_end());
770  for (OpenVolumeMesh::FaceIter f_it = f_begin; f_it != f_end; ++f_it)
771  if (mStatusAttrib[*f_it].selected() && should_render(*f_it) && (!mBoundaryOnly || mMesh.is_boundary(*f_it)))
772  numOfVertices += ((mMesh.valence(*f_it))-2)*3; //additional vertices are added for faces with more than 3 adjacent vertices
773  }
774  else if (mPrimitiveMode == PM_FACES_ON_CELLS)
775  {
776  OpenVolumeMesh::FaceIter f_begin(mMesh.faces_begin()), f_end(mMesh.faces_end());
777  for (OpenVolumeMesh::FaceIter f_it = f_begin; f_it != f_end; ++f_it)
778  if (mStatusAttrib[*f_it].selected())
779  numOfVertices += ((mMesh.valence(*f_it))-2)*3*getNumOfIncidentCells(*f_it); //additional vertices are added for faces with more than 3 adjacent vertices
780  }
781  else if (mPrimitiveMode == PM_HALFFACES)
782  {
783  OpenVolumeMesh::HalfFaceIter hf_begin(mMesh.halffaces_begin()), hf_end(mMesh.halffaces_end());
784  for (OpenVolumeMesh::HalfFaceIter hf_it = hf_begin; hf_it != hf_end; ++hf_it)
785  if (mStatusAttrib[*hf_it].selected() && should_render(*hf_it) && (!mBoundaryOnly || mMesh.is_boundary(*hf_it)))
786  numOfVertices += ((mMesh.valence(mMesh.face_handle(*hf_it)))-2)*3; //additional vertices are added for faces with more than 3 adjacent vertices
787  }
788  else if (mPrimitiveMode == PM_EDGES)
789  {
790  OpenVolumeMesh::EdgeIter e_begin(mMesh.edges_begin()), e_end(mMesh.edges_end());
791  for (OpenVolumeMesh::EdgeIter e_it = e_begin; e_it != e_end; ++e_it)
792  if (mStatusAttrib[*e_it].selected() && should_render(*e_it) && (!mBoundaryOnly || mMesh.is_boundary(*e_it)))
793  numOfVertices += 2;
794  }
795  else if (mPrimitiveMode == PM_EDGES_ON_CELLS)
796  {
797  OpenVolumeMesh::EdgeIter e_begin(mMesh.edges_begin()), e_end(mMesh.edges_end());
798  for (OpenVolumeMesh::EdgeIter e_it = e_begin; e_it != e_end; ++e_it)
799  if (mStatusAttrib[*e_it].selected())
800  numOfVertices += 2*getNumOfIncidentCells(*e_it);
801  }
802  else if (mPrimitiveMode == PM_HALFEDGES)
803  {
804  OpenVolumeMesh::HalfEdgeIter he_begin(mMesh.halfedges_begin()), he_end(mMesh.halfedges_end());
805  for (OpenVolumeMesh::HalfEdgeIter he_it = he_begin; he_it != he_end; ++he_it)
806  if (mStatusAttrib[*he_it].selected() && should_render(*he_it) && (!mBoundaryOnly || mMesh.is_boundary(*he_it)))
807  numOfVertices += 2;
808  }
809  else if (mPrimitiveMode == PM_VERTICES)
810  {
811  OpenVolumeMesh::VertexIter v_begin(mMesh.vertices_begin()), v_end(mMesh.vertices_end());
812  for (OpenVolumeMesh::VertexIter v_it = v_begin; v_it != v_end; ++v_it)
813  if (mStatusAttrib[*v_it].selected() && should_render(*v_it) && (!mBoundaryOnly || mMesh.is_boundary(*v_it)))
814  numOfVertices += 1;
815  }
816  else if (mPrimitiveMode == PM_VERTICES_ON_CELLS)
817  {
818  OpenVolumeMesh::VertexIter v_begin(mMesh.vertices_begin()), v_end(mMesh.vertices_end());
819  for (OpenVolumeMesh::VertexIter v_it = v_begin; v_it != v_end; ++v_it)
820  if (mStatusAttrib[*v_it].selected())
821  numOfVertices += getNumOfIncidentCells(*v_it);
822  }
823  }
824  else
825  {
826  if (mPrimitiveMode == PM_VERTICES_ON_CELLS)
827  {
828  for (unsigned int i = 0; i < mMesh.n_vertices(); i++)
829  numOfVertices += getNumOfIncidentCells(VertexHandle(i));
830  }
831  else if (mPrimitiveMode == PM_VERTICES)
832  {
833  for (unsigned int i = 0; i < mMesh.n_vertices(); i++)
834  if (should_render(VertexHandle(i)) && (!mBoundaryOnly || mMesh.is_boundary(VertexHandle(i))))
835  numOfVertices += 1;
836  }
837  else if (mPrimitiveMode == PM_FACES)
838  {
839  OpenVolumeMesh::FaceIter f_begin(mMesh.faces_begin()), f_end(mMesh.faces_end());
840  for (OpenVolumeMesh::FaceIter f_it = f_begin; f_it != f_end; ++f_it)
841  if (should_render(*f_it) && (!mBoundaryOnly || mMesh.is_boundary(*f_it)))
842  numOfVertices += ((mMesh.valence(*f_it))-2)*3; //additional vertices are added for faces with more than 3 adjacent vertices
843  }
844  else if (mPrimitiveMode == PM_FACES_ON_CELLS)
845  {
846  OpenVolumeMesh::FaceIter f_begin(mMesh.faces_begin()), f_end(mMesh.faces_end());
847  for (OpenVolumeMesh::FaceIter f_it = f_begin; f_it != f_end; ++f_it)
848  numOfVertices += ((mMesh.valence(*f_it))-2)*3*getNumOfIncidentCells(*f_it); //additional vertices are added for faces with more than 3 adjacent vertices
849  }
850  else if (mPrimitiveMode == PM_HALFFACES)
851  {
852  OpenVolumeMesh::HalfFaceIter hf_begin(mMesh.halffaces_begin()), hf_end(mMesh.halffaces_end());
853  for (OpenVolumeMesh::HalfFaceIter hf_it = hf_begin; hf_it != hf_end; ++hf_it)
854  if (should_render(*hf_it) && (!mBoundaryOnly || mMesh.is_boundary(*hf_it)))
855  numOfVertices += ((mMesh.valence(mMesh.face_handle(*hf_it)))-2)*3; //additional vertices are added for faces with more than 3 adjacent vertices
856  }
857  else if (mPrimitiveMode == PM_CELLS)
858  {
859  OpenVolumeMesh::CellIter c_begin(mMesh.cells_begin()), c_end(mMesh.cells_end());
860  for (OpenVolumeMesh::CellIter c_it = c_begin; c_it != c_end; ++c_it)
861  {
862  if (should_render(*c_it))
863  {
864  std::vector<HalfFaceHandle> hfs = mMesh.cell(*c_it).halffaces();
865  for (unsigned int i = 0; i < hfs.size(); ++i)
866  numOfVertices += ((mMesh.valence(mMesh.face_handle(hfs[i])))-2)*3;
867  }
868  }
869  }
870  else if (mPrimitiveMode == PM_EDGES_ON_CELLS)
871  {
872  for (OpenVolumeMesh::EdgeIter e_it = mMesh.edges_begin(); e_it != mMesh.edges_end(); ++e_it)
873  numOfVertices += 2*getNumOfIncidentCells(*e_it);
874  }
875  else if ( mPrimitiveMode == PM_EDGES ) //all edges are drawn, so irregular ones are already included
876  {
877  for (OpenVolumeMesh::EdgeIter e_it = mMesh.edges_begin(); e_it != mMesh.edges_end(); ++e_it)
878  if (should_render(*e_it) && (!mBoundaryOnly || mMesh.is_boundary(*e_it)))
879  numOfVertices += 2;
880  }
881  else if ( mPrimitiveMode == PM_IRREGULAR_EDGES )
882  {
883  for (OpenVolumeMesh::EdgeIter e_it = mMesh.edges_begin(); e_it != mMesh.edges_end(); ++e_it)
884  if (should_render(*e_it) && (!mBoundaryOnly || mMesh.is_boundary(*e_it)))
885  {
886  bool boundary = mMesh.is_boundary(*e_it);
887  unsigned int valence = mMesh.valence(*e_it);
888 
889  // Skip regular edges
890  if(( boundary && valence == 3) || (!boundary && valence == 4)) continue;
891  //skip boundary valence 2 edges if not drawn
892  if ((!(mShowIrregularOuterValence2Edges)) && ( boundary && valence == 2)) continue;
893  //skip irregular inner edges if not drawn
894  if ((!(mShowIrregularInnerEdges)) && (( !boundary && valence != 4) ||
895  ( boundary && valence < 2) ||
896  ( boundary && valence > 3))) continue;
897 
898  numOfVertices += 2;
899  }
900  }
901  else if ( mPrimitiveMode == PM_HALFEDGES )
902  {
903  for (OpenVolumeMesh::HalfEdgeIter he_it = mMesh.halfedges_begin(); he_it != mMesh.halfedges_end(); ++he_it)
904  if (should_render(*he_it) && (!mBoundaryOnly || mMesh.is_boundary(*he_it)))
905  numOfVertices += 2;
906  }
907  else /*if ( mPrimitiveMode == PM_NONE)*/
908  {
909  numOfVertices = 0;
910  }
911  }
912 
913  mNumOfVertices = numOfVertices;
914 }
915 
923 template <class VolumeMesh>
925 {
926  int incidentCells = 0;
927  OpenVolumeMesh::HalfFaceHandle hf0 = mMesh.halfface_handle(_fh, 0);
928  if (mMesh.incident_cell(hf0) != CellHandle(-1))
929  if (should_render(mMesh.incident_cell(hf0)))
930  incidentCells += 1;
931  OpenVolumeMesh::HalfFaceHandle hf1 = mMesh.halfface_handle(_fh, 1);
932  if (mMesh.incident_cell(hf1) != CellHandle(-1))
933  if (should_render(mMesh.incident_cell(hf1)))
934  incidentCells += 1;
935  return incidentCells;
936 }
937 
945 template <class VolumeMesh>
947 {
948  int incidentCells = 0;
949  OpenVolumeMesh::HalfEdgeHandle heh = mMesh.halfedge_handle(_eh, 0);
950  for (OpenVolumeMesh::HalfEdgeCellIter hec_it = OpenVolumeMesh::HalfEdgeCellIter(heh,&mMesh); hec_it.valid(); ++hec_it)
951  if (hec_it->idx() != -1)
952  if (should_render(*hec_it))
953  incidentCells++;
954  return incidentCells;
955 }
956 
964 template <class VolumeMesh>
966 {
967  int incidentCells = 0;
968  for (OpenVolumeMesh::VertexCellIter vc_it = OpenVolumeMesh::VertexCellIter(_vh,&mMesh); vc_it; ++vc_it)
969  if (vc_it->idx() != -1)
970  if (should_render(*vc_it))
971  incidentCells++;
972  return incidentCells;
973 }
974 
982 template <class VolumeMesh>
984 {
985  if (!mCogsValid)
986  calculateCOGs();
987 
988  return mCogs[_ch.idx()];
989 }
990 
998 template <class VolumeMesh>
1000 {
1001  if (mCogs.size() != mMesh.n_cells())
1002  mCogs.resize(mMesh.n_cells());
1003 
1004  OpenVolumeMesh::CellIter c_begin(mMesh.cells_begin()), c_end(mMesh.cells_end());
1005  for (OpenVolumeMesh::CellIter c_it = c_begin; c_it != c_end; ++c_it)
1006  {
1007 
1008  std::vector<HalfFaceHandle> hfs = mMesh.cell(*c_it).halffaces();
1009  ACG::Vec3d cog = ACG::Vec3d(0.0f);
1010  int count = 0;
1011  for (unsigned int i = 0; i < hfs.size(); ++i)
1012  for (OpenVolumeMesh::HalfFaceVertexIter hfv_it = mMesh.hfv_iter(hfs[i]); hfv_it; ++hfv_it)
1013  {
1014  cog += mMesh.vertex(*hfv_it);
1015  count += 1;
1016  }
1017  cog = 1.0/count * cog;
1018 
1019  mCogs[c_it->idx()] = cog;
1020  }
1021 
1022  mCogsValid = true;
1023 }
1024 
1030 template <class VolumeMesh>
1032 {
1033  return (mGeometryChanged) ||
1034  (mVertexSize != mCurrentVertexSize) ||
1035  (mPrimitiveMode != mCurrentPrimitiveMode) ||
1036  (mNumOfVertices != mCurrentNumOfVertices);
1037 }
1038 
1044 template <class VolumeMesh>
1046 {
1047  return (mColorsChanged) ||
1048  (mVertexSize != mCurrentVertexSize) ||
1049  (mNumOfVertices != mCurrentNumOfVertices) ||
1050  (mPrimitiveMode != mCurrentPrimitiveMode) ||
1051  (mColorOffset != mCurrentColorOffset) ||
1052  (mColorMode != mCurrentColorMode) ||
1053  (mShowIrregularInnerEdges != mCurrentShowIrregularInnerEdges) ||
1054  (mShowIrregularOuterValence2Edges != mCurrentShowIrregularOuterValence2Edges);
1055 }
1056 
1062 template <class VolumeMesh>
1064 {
1065  return (mTexCoordsChanged) ||
1066  (mVertexSize != mCurrentVertexSize) ||
1067  (mNumOfVertices != mCurrentNumOfVertices) ||
1068  (mPrimitiveMode != mCurrentPrimitiveMode) ||
1069  (mTexCoordOffset!= mCurrentTexCoordOffset);
1070 }
1071 
1077 template <class VolumeMesh>
1079 {
1080  return (mNormalsChanged) ||
1081  (mVertexSize != mCurrentVertexSize) ||
1082  (mPrimitiveMode != mCurrentPrimitiveMode) ||
1083  (mNormalOffset != mCurrentNormalOffset) ||
1084  (mNormalMode != mCurrentNormalMode) ||
1085  (mNumOfVertices != mCurrentNumOfVertices);
1086 }
1087 
1093 template <class VolumeMesh>
1095 {
1096  unsigned int pos = 0;
1097 
1098  if (mPrimitiveMode == PM_VERTICES)
1099  {
1100  for (unsigned int i = 0; i < mMesh.n_vertices(); ++i) {
1101  if (mSkipUnselected && !mStatusAttrib[VertexHandle(i)].selected()) continue;
1102  if (!should_render(VertexHandle(i))) continue;
1103  if (mBoundaryOnly && !mMesh.is_boundary(VertexHandle(i))) continue;
1104  ACG::Vec3d p = mMesh.vertex(VertexHandle(i));
1105  addPositionToBuffer(p, _buffer, pos++);
1106  }
1107  }
1108  else if (mPrimitiveMode == PM_VERTICES_ON_CELLS)
1109  {
1110  for (unsigned int i = 0; i < mMesh.n_vertices(); ++i) {
1111  if (mSkipUnselected && !mStatusAttrib[VertexHandle(i)].selected()) continue;
1112  ACG::Vec3d p = mMesh.vertex(VertexHandle(i));
1113  for (OpenVolumeMesh::VertexCellIter vc_it = OpenVolumeMesh::VertexCellIter(VertexHandle(i),&mMesh); vc_it; ++vc_it)
1114  {
1115  ACG::Vec3d cog = getCOG(*vc_it);
1116  //ACG::Vec3d newPos = p*mScale + cog*(1-mScale);
1117  if (should_render(*vc_it))
1118  addPositionToBuffer(p*mScale + cog*(1-mScale), _buffer, pos++);
1119  }
1120  }
1121  }
1122  else if (mPrimitiveMode == PM_FACES)
1123  {
1124  std::vector<ACG::Vec3d> vertices;
1125  OpenVolumeMesh::FaceIter f_begin(mMesh.faces_begin()), f_end(mMesh.faces_end());
1126  for (OpenVolumeMesh::FaceIter f_it = f_begin; f_it != f_end; ++f_it)
1127  {
1128  if (mSkipUnselected && !mStatusAttrib[*f_it].selected()) continue;
1129  if (mBoundaryOnly && !mMesh.is_boundary(*f_it)) continue;
1130  if (!should_render(*f_it)) continue;
1131  vertices.clear();
1132  for (OpenVolumeMesh::HalfFaceVertexIter hfv_it = mMesh.hfv_iter(mMesh.halfface_handle(*f_it,0)); hfv_it; ++hfv_it)
1133  vertices.push_back(mMesh.vertex(*hfv_it));
1134 
1135  for (unsigned int i = 0; i < vertices.size()-2; i++)
1136  {
1137  addPositionToBuffer(vertices[0], _buffer, pos++);
1138  addPositionToBuffer(vertices[i+1], _buffer, pos++);
1139  addPositionToBuffer(vertices[i+2], _buffer, pos++);
1140  }
1141  }
1142  }
1143  else if (mPrimitiveMode == PM_FACES_ON_CELLS)
1144  {
1145  std::vector<ACG::Vec3d> vertices;
1146  OpenVolumeMesh::FaceIter f_begin(mMesh.faces_begin()), f_end(mMesh.faces_end());
1147  for (OpenVolumeMesh::FaceIter f_it = f_begin; f_it != f_end; ++f_it)
1148  {
1149  if (mSkipUnselected && !mStatusAttrib[*f_it].selected()) continue;
1150  vertices.clear();
1151  for (OpenVolumeMesh::HalfFaceVertexIter hfv_it = mMesh.hfv_iter(mMesh.halfface_handle(*f_it,0)); hfv_it; ++hfv_it)
1152  vertices.push_back(mMesh.vertex(*hfv_it));
1153 
1154  for (int i = 0; i < 2; i++)
1155  {
1156  OpenVolumeMesh::CellHandle ch = mMesh.incident_cell(mMesh.halfface_handle(*f_it,i));
1157  if (ch != CellHandle(-1))
1158  {
1159  if (!should_render(ch)) continue;
1160  ACG::Vec3d cog = getCOG(ch);
1161  for (unsigned int i = 0; i < vertices.size()-2; i++)
1162  {
1163  //we dont care about the correct facing because we dont cull the back side of faces
1164  addPositionToBuffer(vertices[0]*mScale + cog*(1-mScale), _buffer, pos++);
1165  addPositionToBuffer(vertices[i+1]*mScale + cog*(1-mScale), _buffer, pos++);
1166  addPositionToBuffer(vertices[i+2]*mScale + cog*(1-mScale), _buffer, pos++);
1167  }
1168  }
1169  }
1170 
1171  }
1172  }
1173  else if (mPrimitiveMode == PM_HALFFACES)
1174  {
1175  std::vector<ACG::Vec3d> vertices;
1176  OpenVolumeMesh::HalfFaceIter hf_begin(mMesh.halffaces_begin()), hf_end(mMesh.halffaces_end());
1177  for (OpenVolumeMesh::HalfFaceIter hf_it = hf_begin; hf_it != hf_end; ++hf_it)
1178  {
1179  if (mSkipUnselected && !mStatusAttrib[*hf_it].selected()) continue;
1180  if (mBoundaryOnly && !mMesh.is_boundary(*hf_it)) continue;
1181  if (!should_render(*hf_it)) continue;
1182  vertices.clear();
1183  for (OpenVolumeMesh::HalfFaceVertexIter hfv_it = mMesh.hfv_iter(*hf_it); hfv_it; ++hfv_it)
1184  vertices.push_back(mMesh.vertex(*hfv_it));
1185 
1186  for (unsigned int i = 0; i < vertices.size()-2; i++)
1187  {
1188  addPositionToBuffer(vertices[0], _buffer, pos++);
1189  addPositionToBuffer(vertices[i+1], _buffer, pos++);
1190  addPositionToBuffer(vertices[i+2], _buffer, pos++);
1191  }
1192  }
1193  }
1194  else if (mPrimitiveMode == PM_CELLS)
1195  {
1196  std::vector<ACG::Vec3d> vertices;
1197  OpenVolumeMesh::CellIter c_begin(mMesh.cells_begin()), c_end(mMesh.cells_end());
1198  for (OpenVolumeMesh::CellIter c_it = c_begin; c_it != c_end; ++c_it)
1199  {
1200  if (mSkipUnselected && !mStatusAttrib[*c_it].selected()) continue;
1201  if (!should_render(*c_it)) continue;
1202  std::vector<HalfFaceHandle> hfs = mMesh.cell(*c_it).halffaces();
1203  ACG::Vec3d cog = getCOG(*c_it);
1204  for (unsigned int i = 0; i < hfs.size(); ++i)
1205  {
1206  vertices.clear();
1207  for (OpenVolumeMesh::HalfFaceVertexIter hfv_it = mMesh.hfv_iter(hfs[i]); hfv_it; ++hfv_it)
1208  vertices.push_back(mScale*mMesh.vertex(*hfv_it)+(1-mScale)*cog);
1209 
1210  for (unsigned int i = 0; i < vertices.size()-2; i++)
1211  {
1212  addPositionToBuffer(vertices[0], _buffer, pos++);
1213  addPositionToBuffer(vertices[i+1], _buffer, pos++);
1214  addPositionToBuffer(vertices[i+2], _buffer, pos++);
1215  }
1216  }
1217  }
1218 
1219  }
1220  else if (mPrimitiveMode == PM_EDGES)
1221  {
1222  OpenVolumeMesh::EdgeIter e_begin(mMesh.edges_begin()), e_end(mMesh.edges_end());
1223  for (OpenVolumeMesh::EdgeIter e_it = e_begin; e_it != e_end; ++e_it)
1224  {
1225  if (mSkipUnselected && !mStatusAttrib[*e_it].selected()) continue;
1226  if (mBoundaryOnly && !mMesh.is_boundary(*e_it)) continue;
1227  if (!should_render(*e_it)) continue;
1228 
1229  Edge e(mMesh.edge(*e_it));
1230  addPositionToBuffer(mMesh.vertex(e.from_vertex()), _buffer, pos++);
1231  addPositionToBuffer(mMesh.vertex(e.to_vertex()), _buffer, pos++);
1232  }
1233  }
1234  else if (mPrimitiveMode == PM_EDGES_ON_CELLS)
1235  {
1236  OpenVolumeMesh::EdgeIter e_begin(mMesh.edges_begin()), e_end(mMesh.edges_end());
1237  for (OpenVolumeMesh::EdgeIter e_it = e_begin; e_it != e_end; ++e_it)
1238  {
1239  if (mSkipUnselected && !mStatusAttrib[*e_it].selected()) continue;
1240 
1241  Edge e(mMesh.edge(*e_it));
1242  OpenVolumeMesh::HalfEdgeHandle heh = mMesh.halfedge_handle(*e_it, 0);
1243  for (OpenVolumeMesh::HalfEdgeCellIter hec_it = OpenVolumeMesh::HalfEdgeCellIter(heh,&mMesh); hec_it.valid(); ++hec_it)
1244  {
1245  if (hec_it->idx() != -1)
1246  {
1247  if (!should_render(*hec_it)) continue;
1248  ACG::Vec3d cog = getCOG(*hec_it);
1249  addPositionToBuffer(mMesh.vertex(e.from_vertex())*mScale + cog*(1-mScale), _buffer, pos++);
1250  addPositionToBuffer(mMesh.vertex(e.to_vertex()) *mScale + cog*(1-mScale), _buffer, pos++);
1251  }
1252  }
1253  }
1254  }
1255  else if (mPrimitiveMode == PM_IRREGULAR_EDGES)
1256  {
1257  OpenVolumeMesh::EdgeIter e_begin(mMesh.edges_begin()), e_end(mMesh.edges_end());
1258  for (OpenVolumeMesh::EdgeIter e_it = e_begin; e_it != e_end; ++e_it)
1259  {
1260  if (mSkipUnselected && !mStatusAttrib[*e_it].selected()) continue;
1261  if (mBoundaryOnly && !mMesh.is_boundary(*e_it)) continue;
1262  if (!should_render(*e_it)) continue;
1263 
1264  bool boundary = mMesh.is_boundary(*e_it);
1265  unsigned int valence = mMesh.valence(*e_it);
1266  // Skip regular
1267  if(( boundary && valence == 3) ||
1268  (!boundary && valence == 4)) continue;
1269  //skip boundary valence 2 edges if not drawn
1270  if ((!mShowIrregularOuterValence2Edges) && ( boundary && valence == 2)) continue;
1271  //skip irregular inner edges if not drawn
1272  if ((!mShowIrregularInnerEdges) && (( !boundary && valence != 4) ||
1273  ( boundary && valence < 2) ||
1274  ( boundary && valence > 3))) continue;
1275 
1276  Edge e(mMesh.edge(*e_it));
1277  addPositionToBuffer(mMesh.vertex(e.from_vertex()), _buffer, pos++);
1278  addPositionToBuffer(mMesh.vertex(e.to_vertex()), _buffer, pos++);
1279  }
1280  }
1281  else if (mPrimitiveMode == PM_HALFEDGES)
1282  {
1283  OpenVolumeMesh::HalfEdgeIter he_begin(mMesh.halfedges_begin()), he_end(mMesh.halfedges_end());
1284  for (OpenVolumeMesh::HalfEdgeIter he_it = he_begin; he_it != he_end; ++he_it)
1285  {
1286  if (mSkipUnselected && !mStatusAttrib[*he_it].selected()) continue;
1287  if (mBoundaryOnly && !mMesh.is_boundary(*he_it)) continue;
1288  if (!should_render(*he_it)) continue;
1289 
1290  double lambda = 0.4;
1291  Edge e(mMesh.halfedge(*he_it));
1292  addPositionToBuffer(mMesh.vertex(e.from_vertex()), _buffer, pos++);
1293  addPositionToBuffer((1-lambda)*mMesh.vertex(e.from_vertex()) + lambda*mMesh.vertex(e.to_vertex()), _buffer, pos++);
1294  }
1295  }
1296  else /*if (mPrimitiveMode == PM_NONE)*/
1297  {
1298  //This case should not happen. Do nothing.
1299  }
1300 }
1301 
1307 template <class VolumeMesh>
1309 {
1310  if (mNormalMode == NM_NONE) return;
1311 
1312  unsigned int pos = 0;
1313 
1314  if ((mPrimitiveMode == PM_FACES) && (mNormalMode == NM_FACE))
1315  {
1316  OpenVolumeMesh::FaceIter f_begin(mMesh.faces_begin()), f_end(mMesh.faces_end());
1317  for (OpenVolumeMesh::FaceIter f_it = f_begin; f_it != f_end; ++f_it)
1318  {
1319  if (mBoundaryOnly && !mMesh.is_boundary(*f_it)) continue;
1320  if (!should_render(*f_it)) continue;
1321  ACG::Vec3d normal = mNormalAttrib[*f_it];
1322  unsigned int numOfVerticesInFace = mMesh.valence(*f_it);
1323 
1324  for (unsigned int i = 0; i < numOfVerticesInFace - 2; i++)
1325  {
1326  addNormalToBuffer(normal, _buffer, pos++);
1327  addNormalToBuffer(normal, _buffer, pos++);
1328  addNormalToBuffer(normal, _buffer, pos++);
1329  }
1330  }
1331  }
1332  else if ((mPrimitiveMode == PM_FACES) && (mNormalMode == NM_VERTEX))
1333  {
1334  std::vector<ACG::Vec3d> normals;
1335  OpenVolumeMesh::FaceIter f_begin(mMesh.faces_begin()), f_end(mMesh.faces_end());
1336  for (OpenVolumeMesh::FaceIter f_it = f_begin; f_it != f_end; ++f_it)
1337  {
1338  if (mBoundaryOnly && !mMesh.is_boundary(*f_it)) continue;
1339  if (!should_render(*f_it)) continue;
1340  normals.clear();
1341  for (OpenVolumeMesh::HalfFaceVertexIter hfv_it = mMesh.hfv_iter(mMesh.halfface_handle(*f_it,0)); hfv_it; ++hfv_it)
1342  normals.push_back(mNormalAttrib[*hfv_it]);
1343 
1344  for (unsigned int i = 0; i < normals.size()-2; i++)
1345  {
1346  addNormalToBuffer(normals[0], _buffer, pos++);
1347  addNormalToBuffer(normals[i+1], _buffer, pos++);
1348  addNormalToBuffer(normals[i+2], _buffer, pos++);
1349  }
1350  }
1351  }
1352  else if ((mPrimitiveMode == PM_HALFFACES) && (mNormalMode == NM_HALFFACE))
1353  {
1354  OpenVolumeMesh::HalfFaceIter hf_begin(mMesh.halffaces_begin()), hf_end(mMesh.halffaces_end());
1355  for (OpenVolumeMesh::HalfFaceIter hf_it = hf_begin; hf_it != hf_end; ++hf_it)
1356  {
1357  if (mBoundaryOnly && !mMesh.is_boundary(*hf_it)) continue;
1358  if (!should_render(*hf_it)) continue;
1359  ACG::Vec3d normal = mNormalAttrib[*hf_it];
1360  unsigned int numOfVerticesInCell = 0;
1361  for (OpenVolumeMesh::HalfFaceVertexIter hfv_it = mMesh.hfv_iter(*hf_it); hfv_it; ++hfv_it)
1362  ++numOfVerticesInCell;
1363 
1364  for (unsigned int i = 0; i < numOfVerticesInCell- 2; i++)
1365  {
1366  addNormalToBuffer(normal, _buffer, pos++);
1367  addNormalToBuffer(normal, _buffer, pos++);
1368  addNormalToBuffer(normal, _buffer, pos++);
1369  }
1370  }
1371  }
1372  else if ((mPrimitiveMode == PM_HALFFACES) && (mNormalMode == NM_VERTEX))
1373  {
1374  std::vector<ACG::Vec3d> normals;
1375  OpenVolumeMesh::HalfFaceIter hf_begin(mMesh.halffaces_begin()), hf_end(mMesh.halffaces_end());
1376  for (OpenVolumeMesh::HalfFaceIter hf_it = hf_begin; hf_it != hf_end; ++hf_it)
1377  {
1378  if (mBoundaryOnly && !mMesh.is_boundary(*hf_it)) continue;
1379  if (!should_render(*hf_it)) continue;
1380  normals.clear();
1381  for (OpenVolumeMesh::HalfFaceVertexIter hfv_it = mMesh.hfv_iter(*hf_it); hfv_it; ++hfv_it)
1382  normals.push_back(mNormalAttrib[*hfv_it]);
1383 
1384  for (unsigned int i = 0; i < normals.size()-2; i++)
1385  {
1386  addNormalToBuffer(normals[0], _buffer, pos++);
1387  addNormalToBuffer(normals[i+1], _buffer, pos++);
1388  addNormalToBuffer(normals[i+2], _buffer, pos++);
1389  }
1390  }
1391  }
1392  else if ((mPrimitiveMode == PM_CELLS) && (mNormalMode == NM_HALFFACE))
1393  {
1394  OpenVolumeMesh::CellIter c_begin(mMesh.cells_begin()), c_end(mMesh.cells_end());
1395  for (OpenVolumeMesh::CellIter c_it = c_begin; c_it != c_end; ++c_it)
1396  {
1397  if (!should_render(*c_it)) continue;
1398  std::vector<HalfFaceHandle> hfs = mMesh.cell(*c_it).halffaces();
1399  for (unsigned int i = 0; i < hfs.size(); ++i)
1400  {
1401  ACG::Vec3d normal = -1.0*mNormalAttrib[hfs[i]];
1402  unsigned int numOfVerticesInFace = mMesh.valence(mMesh.face_handle(hfs[i]));
1403 
1404  for (unsigned int i = 0; i < numOfVerticesInFace-2; i++)
1405  {
1406  addNormalToBuffer(normal, _buffer, pos++);
1407  addNormalToBuffer(normal, _buffer, pos++);
1408  addNormalToBuffer(normal, _buffer, pos++);
1409  }
1410  }
1411  }
1412  }
1413  else if ((mPrimitiveMode == PM_CELLS) && (mNormalMode == NM_VERTEX))
1414  {
1415  std::vector<ACG::Vec3d> normals;
1416  OpenVolumeMesh::CellIter c_begin(mMesh.cells_begin()), c_end(mMesh.cells_end());
1417  for (OpenVolumeMesh::CellIter c_it = c_begin; c_it != c_end; ++c_it)
1418  {
1419  if (!should_render(*c_it)) continue;
1420  std::vector<HalfFaceHandle> hfs = mMesh.cell(*c_it).halffaces();
1421 
1422  for (unsigned int i = 0; i < hfs.size(); ++i)
1423  {
1424  normals.clear();
1425  for (OpenVolumeMesh::HalfFaceVertexIter hfv_it = mMesh.hfv_iter(hfs[i]); hfv_it; ++hfv_it)
1426  normals.push_back(mNormalAttrib[*hfv_it]);
1427 
1428  for (unsigned int i = 0; i < normals.size()-2; i++)
1429  {
1430  addNormalToBuffer(normals[0], _buffer, pos++);
1431  addNormalToBuffer(normals[i+1], _buffer, pos++);
1432  addNormalToBuffer(normals[i+2], _buffer, pos++);
1433  }
1434  }
1435  }
1436  }
1437 
1438 }
1439 
1445 template <class VolumeMesh>
1447 {
1448  unsigned int pos = 0;
1449 
1450  if ((mPrimitiveMode == PM_VERTICES) && (mColorMode == CM_VERTEX))
1451  {
1452  for (unsigned int i = 0; i < mMesh.n_vertices(); ++i)
1453  {
1454  if (mBoundaryOnly && !mMesh.is_boundary(VertexHandle(i))) continue;
1455  if (!should_render(VertexHandle(i))) continue;
1456  ACG::Vec4f color = mColorAttrib[VertexHandle(i)];
1457  addColorToBuffer(color, _buffer, pos++);
1458  }
1459  }
1460  else if ((mPrimitiveMode == PM_FACES) && (mColorMode == CM_VERTEX))
1461  {
1462  std::vector<ACG::Vec4f> colors;
1463  OpenVolumeMesh::FaceIter f_begin(mMesh.faces_begin()), f_end(mMesh.faces_end());
1464  for (OpenVolumeMesh::FaceIter f_it = f_begin; f_it != f_end; ++f_it)
1465  {
1466  if (mBoundaryOnly && !mMesh.is_boundary(*f_it)) continue;
1467  if (!should_render(*f_it)) continue;
1468  colors.clear();
1469 
1470  for (OpenVolumeMesh::HalfFaceVertexIter hfv_it = mMesh.hfv_iter(mMesh.halfface_handle(*f_it,0)); 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_FACES) && (mColorMode == CM_FACE))
1482  {
1483  OpenVolumeMesh::FaceIter f_begin(mMesh.faces_begin()), f_end(mMesh.faces_end());
1484  for (OpenVolumeMesh::FaceIter f_it = f_begin; f_it != f_end; ++f_it)
1485  {
1486  if (mBoundaryOnly && !mMesh.is_boundary(*f_it)) continue;
1487  if (!should_render(*f_it)) continue;
1488  ACG::Vec4f color = mColorAttrib[*f_it];
1489 
1490  unsigned int numOfVerticesInFace = mMesh.valence(*f_it);
1491  unsigned int numOfDrawnTriangles = numOfVerticesInFace-2;
1492 
1493  for (unsigned int i = 0; i < numOfDrawnTriangles*3; i++)
1494  addColorToBuffer(color, _buffer, pos++);
1495  }
1496  }
1497  else if ((mPrimitiveMode == PM_HALFFACES) && (mColorMode == CM_HALFFACE))
1498  {
1499  OpenVolumeMesh::HalfFaceIter hf_begin(mMesh.halffaces_begin()), hf_end(mMesh.halffaces_end());
1500  for (OpenVolumeMesh::HalfFaceIter hf_it = hf_begin; hf_it != hf_end; ++hf_it)
1501  {
1502  if (mBoundaryOnly && !mMesh.is_boundary(*hf_it)) continue;
1503  if (!should_render(*hf_it)) continue;
1504  ACG::Vec4f color = mColorAttrib[*hf_it];
1505 
1506  unsigned int numOfVerticesInFace = mMesh.valence(mMesh.face_handle(*hf_it));
1507  unsigned int numOfDrawnTriangles = numOfVerticesInFace-2;
1508 
1509  for (unsigned int i = 0; i < numOfDrawnTriangles*3; i++)
1510  addColorToBuffer(color, _buffer, pos++);
1511  }
1512  }
1513  else if ((mPrimitiveMode == PM_HALFFACES) && (mColorMode == CM_VERTEX))
1514  {
1515  std::vector<ACG::Vec4f> colors;
1516  OpenVolumeMesh::HalfFaceIter hf_begin(mMesh.halffaces_begin()), hf_end(mMesh.halffaces_end());
1517  for (OpenVolumeMesh::HalfFaceIter hf_it = hf_begin; hf_it != hf_end; ++hf_it)
1518  {
1519  if (mBoundaryOnly && !mMesh.is_boundary(*hf_it)) continue;
1520  if (!should_render(*hf_it)) continue;
1521  colors.clear();
1522 
1523  for (OpenVolumeMesh::HalfFaceVertexIter hfv_it = mMesh.hfv_iter(*hf_it); hfv_it; ++hfv_it)
1524  colors.push_back(mColorAttrib[*hfv_it]);
1525 
1526  for (unsigned int i = 0; i < (colors.size()-2); i++)
1527  {
1528  addColorToBuffer(colors[0], _buffer, pos++);
1529  addColorToBuffer(colors[i+1], _buffer, pos++);
1530  addColorToBuffer(colors[i+2], _buffer, pos++);
1531  }
1532  }
1533  }
1534  else if ((mPrimitiveMode == PM_CELLS) && (mColorMode == CM_CELL))
1535  {
1536  OpenVolumeMesh::CellIter c_begin(mMesh.cells_begin()), c_end(mMesh.cells_end());
1537  for (OpenVolumeMesh::CellIter c_it = c_begin; c_it != c_end; ++c_it)
1538  {
1539  if (!should_render(*c_it)) continue;
1540  ACG::Vec4f color = mColorAttrib[*c_it];
1541  std::vector<HalfFaceHandle> hfs = mMesh.cell(*c_it).halffaces();
1542  for (unsigned int i = 0; i < hfs.size(); ++i)
1543  {
1544  unsigned int numOfVerticesInHalfface = 0;
1545  for (OpenVolumeMesh::HalfFaceVertexIter hfv_it = mMesh.hfv_iter(hfs[i]); hfv_it; ++hfv_it)
1546  ++numOfVerticesInHalfface;
1547 
1548  unsigned int numOfDrawnFaces = numOfVerticesInHalfface-2;
1549  for (unsigned int i = 0; i < numOfDrawnFaces*3; i++)
1550  addColorToBuffer(color, _buffer, pos++);
1551  }
1552  }
1553  }
1554  else if ((mPrimitiveMode == PM_CELLS) && (mColorMode == CM_HALFFACE))
1555  {
1556  OpenVolumeMesh::CellIter c_begin(mMesh.cells_begin()), c_end(mMesh.cells_end());
1557  for (OpenVolumeMesh::CellIter c_it = c_begin; c_it != c_end; ++c_it)
1558  {
1559  if (!should_render(*c_it)) continue;
1560  std::vector<HalfFaceHandle> hfs = mMesh.cell(*c_it).halffaces();
1561  for (unsigned int i = 0; i < hfs.size(); ++i)
1562  {
1563  ACG::Vec4f color = mColorAttrib[hfs[i]];
1564  unsigned int numOfVerticesInHalfface = 0;
1565  for (OpenVolumeMesh::HalfFaceVertexIter hfv_it = mMesh.hfv_iter(hfs[i]); hfv_it; ++hfv_it)
1566  ++numOfVerticesInHalfface;
1567 
1568  unsigned int numOfDrawnFaces = numOfVerticesInHalfface-2;
1569  for (unsigned int i = 0; i < numOfDrawnFaces*3; i++)
1570  addColorToBuffer(color, _buffer, pos++);
1571  }
1572  }
1573  }
1574  else if ((mPrimitiveMode == PM_CELLS) && (mColorMode == CM_FACE))
1575  {
1576  OpenVolumeMesh::CellIter c_begin(mMesh.cells_begin()), c_end(mMesh.cells_end());
1577  for (OpenVolumeMesh::CellIter c_it = c_begin; c_it != c_end; ++c_it)
1578  {
1579  if (!should_render(*c_it)) continue;
1580  std::vector<HalfFaceHandle> hfs = mMesh.cell(*c_it).halffaces();
1581  for (unsigned int i = 0; i < hfs.size(); ++i)
1582  {
1583  ACG::Vec4f color = mColorAttrib[mMesh.face_handle(hfs[i])];
1584  unsigned int numOfVerticesInHalfface = 0;
1585  for (OpenVolumeMesh::HalfFaceVertexIter hfv_it = mMesh.hfv_iter(hfs[i]); hfv_it; ++hfv_it)
1586  ++numOfVerticesInHalfface;
1587 
1588  unsigned int numOfDrawnFaces = numOfVerticesInHalfface-2;
1589  for (unsigned int i = 0; i < numOfDrawnFaces*3; i++)
1590  addColorToBuffer(color, _buffer, pos++);
1591  }
1592  }
1593  }
1594  else if ((mPrimitiveMode == PM_CELLS) && (mColorMode == CM_VERTEX))
1595  {
1596  std::vector<ACG::Vec4f> colors;
1597  OpenVolumeMesh::CellIter c_begin(mMesh.cells_begin()), c_end(mMesh.cells_end());
1598  for (OpenVolumeMesh::CellIter c_it = c_begin; c_it != c_end; ++c_it)
1599  {
1600  if (!should_render(*c_it)) continue;
1601  std::vector<HalfFaceHandle> hfs = mMesh.cell(*c_it).halffaces();
1602  for (unsigned int i = 0; i < hfs.size(); ++i)
1603  {
1604  colors.clear();
1605  for (OpenVolumeMesh::HalfFaceVertexIter hfv_it = mMesh.hfv_iter(hfs[i]); hfv_it; ++hfv_it)
1606  colors.push_back(mColorAttrib[*hfv_it]);
1607 
1608  for (unsigned int i = 0; i < colors.size()-2; i++)
1609  {
1610  addColorToBuffer(colors[0], _buffer, pos++);
1611  addColorToBuffer(colors[i+1], _buffer, pos++);
1612  addColorToBuffer(colors[i+2], _buffer, pos++);
1613  }
1614  }
1615  }
1616  }
1617  else if ((mPrimitiveMode == PM_EDGES) && (mColorMode == CM_EDGE))
1618  {
1619  OpenVolumeMesh::EdgeIter e_begin(mMesh.edges_begin()), e_end(mMesh.edges_end());
1620  for (OpenVolumeMesh::EdgeIter e_it = e_begin; e_it != e_end; ++e_it)
1621  {
1622  if (mBoundaryOnly && !mMesh.is_boundary(*e_it)) continue;
1623  if (!should_render(*e_it)) continue;
1624  ACG::Vec4f color = mColorAttrib[*e_it];
1625  addColorToBuffer(color, _buffer, pos++);
1626  addColorToBuffer(color, _buffer, pos++);
1627  }
1628  }
1629  else if ((mPrimitiveMode == PM_EDGES) && (mShowIrregularInnerEdges || mShowIrregularOuterValence2Edges))
1630  {
1631  OpenVolumeMesh::EdgeIter e_begin(mMesh.edges_begin()), e_end(mMesh.edges_end());
1632  for (OpenVolumeMesh::EdgeIter e_it = e_begin; e_it != e_end; ++e_it)
1633  {
1634  if (mBoundaryOnly && !mMesh.is_boundary(*e_it)) continue;
1635  if (!should_render(*e_it)) continue;
1636 
1637  bool boundary = mMesh.is_boundary(*e_it);
1638  unsigned int valence = mMesh.valence(*e_it);
1639 
1640  bool isIrregularInner = ( boundary && valence < 2) || ( boundary && valence > 3) || (!boundary && valence != 4);
1641  bool isIrregularOuterValence2 = ( boundary && valence == 2);
1642 
1643  ACG::Vec4f color;
1644 
1645  if (isIrregularInner && mShowIrregularInnerEdges)
1646  color = getValenceColorCode(valence, !boundary);
1647  else if (isIrregularOuterValence2 && mShowIrregularOuterValence2Edges)
1648  color = getValenceColorCode(valence, !boundary);
1649  else
1650  color = mDefaultColor;
1651 
1652  addColorToBuffer(color, _buffer, pos++);
1653  addColorToBuffer(color, _buffer, pos++);
1654  }
1655  }
1656  else if ( mPrimitiveMode == PM_IRREGULAR_EDGES )
1657  {
1658  OpenVolumeMesh::EdgeIter e_begin(mMesh.edges_begin()), e_end(mMesh.edges_end());
1659  for (OpenVolumeMesh::EdgeIter e_it = e_begin; e_it != e_end; ++e_it)
1660  {
1661  if (mBoundaryOnly && !mMesh.is_boundary(*e_it)) continue;
1662  if (!should_render(*e_it)) continue;
1663 
1664  bool boundary = mMesh.is_boundary(*e_it);
1665  unsigned int valence = mMesh.valence(*e_it);
1666 
1667  bool isRegular = ( boundary && valence == 3) || (!boundary && valence == 4);
1668  bool isIrregularInner = ( boundary && valence < 2) || ( boundary && valence > 3) || (!boundary && valence != 4);
1669  bool isIrregularOuterValence2 = ( boundary && valence == 2);
1670 
1671  if (isRegular) continue;
1672  if (isIrregularInner && !mShowIrregularInnerEdges) continue;
1673  if (isIrregularOuterValence2 && !mShowIrregularOuterValence2Edges) continue;
1674 
1675  ACG::Vec4f color;
1676 
1677  if (isIrregularInner && mShowIrregularInnerEdges)
1678  color = getValenceColorCode(valence, !boundary);
1679  else if (isIrregularOuterValence2 && mShowIrregularOuterValence2Edges)
1680  color = getValenceColorCode(valence, !boundary);
1681  else
1682  color = mDefaultColor;
1683 
1684  addColorToBuffer(color, _buffer, pos++);
1685  addColorToBuffer(color, _buffer, pos++);
1686  }
1687  }
1688  else if ((mPrimitiveMode == PM_HALFEDGES) && (mColorMode == CM_HALFEDGE))
1689  {
1690  OpenVolumeMesh::HalfEdgeIter he_begin(mMesh.halfedges_begin()), he_end(mMesh.halfedges_end());
1691  for (OpenVolumeMesh::HalfEdgeIter he_it = he_begin; he_it != he_end; ++he_it)
1692  {
1693  if (mBoundaryOnly && !mMesh.is_boundary(*he_it)) continue;
1694  if (!should_render(*he_it)) continue;
1695  ACG::Vec4f color = mColorAttrib[*he_it];
1696 
1697  addColorToBuffer(color, _buffer, pos++);
1698  addColorToBuffer(color, _buffer, pos++);
1699  }
1700  }
1701 
1702 }
1703 
1709 template <class VolumeMesh>
1711 {
1712 
1713  unsigned int pos = 0;
1714 
1715  if (mTexCoordMode == TCM_NONE)
1716  return;
1717 
1718  if (mPrimitiveMode == PM_FACES)
1719  {
1720  std::vector<ACG::Vec2f> texCoords;
1721  OpenVolumeMesh::FaceIter f_begin(mMesh.faces_begin()), f_end(mMesh.faces_end());
1722  for (OpenVolumeMesh::FaceIter f_it = f_begin; f_it != f_end; ++f_it)
1723  {
1724  if (mBoundaryOnly && !mMesh.is_boundary(*f_it)) continue;
1725  if (!should_render(*f_it)) continue;
1726  texCoords.clear();
1727 
1728  for (OpenVolumeMesh::HalfFaceVertexIter hfv_it = mMesh.hfv_iter(mMesh.halfface_handle(*f_it,0)); hfv_it; ++hfv_it)
1729  texCoords.push_back(mTexcoordAttrib[*hfv_it]);
1730 
1731  for (unsigned int i = 0; i < (texCoords.size()-2); i++)
1732  {
1733  addTexCoordToBuffer(texCoords[0], _buffer, pos++);
1734  addTexCoordToBuffer(texCoords[i+1], _buffer, pos++);
1735  addTexCoordToBuffer(texCoords[i+2], _buffer, pos++);
1736  }
1737  }
1738  }
1739  else if (mPrimitiveMode == PM_HALFFACES)
1740  {
1741  std::vector<ACG::Vec2f> texCoords;
1742  OpenVolumeMesh::HalfFaceIter hf_begin(mMesh.halffaces_begin()), hf_end(mMesh.halffaces_end());
1743  for (OpenVolumeMesh::HalfFaceIter hf_it = hf_begin; hf_it != hf_end; ++hf_it)
1744  {
1745  if (mBoundaryOnly && !mMesh.is_boundary(*hf_it)) continue;
1746  if (!should_render(*hf_it)) continue;
1747  texCoords.clear();
1748 
1749  for (OpenVolumeMesh::HalfFaceVertexIter hfv_it = mMesh.hfv_iter(*hf_it); hfv_it; ++hfv_it)
1750  texCoords.push_back(mTexcoordAttrib[*hfv_it]);
1751 
1752  for (unsigned int i = 0; i < (texCoords.size()-2); i++)
1753  {
1754  addTexCoordToBuffer(texCoords[0], _buffer, pos++);
1755  addTexCoordToBuffer(texCoords[i+1], _buffer, pos++);
1756  addTexCoordToBuffer(texCoords[i+2], _buffer, pos++);
1757  }
1758  }
1759  }
1760 
1761 }
1762 
1771 template <class VolumeMesh>
1772 void VolumeMeshBufferManager<VolumeMesh>::buildPickColorBuffer(ACG::GLState& _state, unsigned int _offset, unsigned char* _buffer)
1773 {
1774  unsigned int pos = 0;
1775 
1776  if (mPrimitiveMode == PM_VERTICES)
1777  {
1778  for (unsigned int i = 0; i < mMesh.n_vertices(); ++i)
1779  {
1780  if (mBoundaryOnly && !mMesh.is_boundary(VertexHandle(i))) continue;
1781  if (!should_render(VertexHandle(i))) continue;
1782  ACG::Vec4uc color = _state.pick_get_name_color(VertexHandle(i).idx() + _offset);
1783  addColorToBuffer(color, _buffer, pos++);
1784  }
1785  }
1786  if (mPrimitiveMode == PM_VERTICES_ON_CELLS)
1787  {
1788  for (unsigned int i = 0; i < mMesh.n_vertices(); ++i) {
1789  ACG::Vec4uc color = _state.pick_get_name_color(VertexHandle(i).idx() + _offset);
1790  unsigned int numOfIncidentCells = getNumOfIncidentCells(VertexHandle(i));
1791  for (unsigned int j = 0; j < numOfIncidentCells; j++)
1792  addColorToBuffer(color, _buffer, pos++);
1793  }
1794  }
1795  else if (mPrimitiveMode == PM_EDGES)
1796  {
1797  OpenVolumeMesh::EdgeIter e_begin(mMesh.edges_begin()), e_end(mMesh.edges_end());
1798  for (OpenVolumeMesh::EdgeIter e_it = e_begin; e_it != e_end; ++e_it)
1799  {
1800  if (mBoundaryOnly && !mMesh.is_boundary(*e_it)) continue;
1801  if (!should_render(*e_it)) continue;
1802  ACG::Vec4uc color = _state.pick_get_name_color(e_it->idx()+_offset);
1803  addColorToBuffer(color, _buffer, pos++);
1804  addColorToBuffer(color, _buffer, pos++);
1805  }
1806  }
1807  else if (mPrimitiveMode == PM_EDGES_ON_CELLS)
1808  {
1809  OpenVolumeMesh::EdgeIter e_begin(mMesh.edges_begin()), e_end(mMesh.edges_end());
1810  for (OpenVolumeMesh::EdgeIter e_it = e_begin; e_it != e_end; ++e_it)
1811  {
1812  ACG::Vec4uc color = _state.pick_get_name_color(e_it->idx()+_offset);
1813  unsigned int numOfIncidentCells = getNumOfIncidentCells(*e_it);
1814  for (unsigned int i = 0; i < numOfIncidentCells*2;i++)
1815  addColorToBuffer(color, _buffer, pos++);
1816  }
1817  }
1818  else if (mPrimitiveMode == PM_FACES)
1819  {
1820  OpenVolumeMesh::FaceIter f_begin(mMesh.faces_begin()), f_end(mMesh.faces_end());
1821  for (OpenVolumeMesh::FaceIter f_it = f_begin; f_it != f_end; ++f_it)
1822  {
1823  if (mBoundaryOnly && !mMesh.is_boundary(*f_it)) continue;
1824  if (!should_render(*f_it)) continue;
1825  ACG::Vec4uc color = _state.pick_get_name_color(f_it->idx());
1826 
1827  unsigned int numOfVertices = 0;
1828  for (OpenVolumeMesh::HalfFaceVertexIter hfv_it = mMesh.hfv_iter(mMesh.halfface_handle(*f_it,0)); hfv_it; ++hfv_it)
1829  ++numOfVertices;
1830 
1831  for (unsigned int i = 0; i < (numOfVertices-2)*3; i++)
1832  addColorToBuffer(color, _buffer, pos++);
1833  }
1834  }
1835  else if (mPrimitiveMode == PM_FACES_ON_CELLS)
1836  {
1837  OpenVolumeMesh::FaceIter f_begin(mMesh.faces_begin()), f_end(mMesh.faces_end());
1838  for (OpenVolumeMesh::FaceIter f_it = f_begin; f_it != f_end; ++f_it)
1839  {
1840  ACG::Vec4uc color = _state.pick_get_name_color(f_it->idx()+_offset);
1841 
1842  unsigned int numOfVerticesInHalfface = 0;
1843  for (OpenVolumeMesh::HalfFaceVertexIter hfv_it = mMesh.hfv_iter(mMesh.halfface_handle(*f_it,0)); hfv_it; ++hfv_it)
1844  ++numOfVerticesInHalfface;
1845 
1846  for (int i = 0; i < 2; i++)
1847  {
1848  OpenVolumeMesh::CellHandle ch = mMesh.incident_cell(mMesh.halfface_handle(*f_it,i));
1849  if (ch != CellHandle(-1))
1850  {
1851  if (!should_render(ch)) continue;
1852  for (unsigned int i = 0; i < (numOfVerticesInHalfface-2)*3; i++)
1853  addColorToBuffer(color, _buffer, pos++);
1854  }
1855  }
1856  }
1857  }
1858  else if (mPrimitiveMode == PM_CELLS)
1859  {
1860  OpenVolumeMesh::CellIter c_begin(mMesh.cells_begin()), c_end(mMesh.cells_end());
1861  for (OpenVolumeMesh::CellIter c_it = c_begin; c_it != c_end; ++c_it)
1862  {
1863  if (!should_render(*c_it)) continue;
1864  ACG::Vec4uc color = _state.pick_get_name_color(c_it->idx()+_offset);
1865  std::vector<HalfFaceHandle> hfs = mMesh.cell(*c_it).halffaces();
1866  for (unsigned int i = 0; i < hfs.size(); ++i)
1867  {
1868  unsigned int numOfVerticesInHalfface = 0;
1869  for (OpenVolumeMesh::HalfFaceVertexIter hfv_it = mMesh.hfv_iter(hfs[i]); hfv_it; ++hfv_it)
1870  ++numOfVerticesInHalfface;
1871 
1872  unsigned int numOfDrawnFaces = numOfVerticesInHalfface-2;
1873  for (unsigned int i = 0; i < numOfDrawnFaces*3; i++)
1874  addColorToBuffer(color, _buffer, pos++);
1875  }
1876  }
1877  }
1878 }
1879 
1887 template <class VolumeMesh>
1889 {
1890  if ((mBuffer == 0) || optionsChanged() || mInvalidated)
1891  {
1892 
1893  if (mBuffer == 0)
1894  ACG::GLState::genBuffers(1, &mBuffer);
1895 
1897 
1898  if (optionsChanged())
1899  mNumOfVertices = -1;
1900 
1901  unsigned int numOfVertices = getNumOfVertices();
1902 
1903  if (getNumOfVertices() > 0)
1904  {
1905 
1906  unsigned int bufferSize = mVertexSize * numOfVertices;
1907 
1908  ACG::GLState::bindBuffer(GL_ARRAY_BUFFER, mBuffer);
1909  ACG::GLState::bufferData(GL_ARRAY_BUFFER, bufferSize, 0, GL_STATIC_DRAW);
1910 
1911  unsigned char* buffer = (unsigned char *) ACG::GLState::mapBuffer(
1912  GL_ARRAY_BUFFER, GL_READ_WRITE);
1913 
1914  if (buffer)
1915  {
1916 
1917  if (positionsNeedRebuild())
1918  buildVertexBuffer(buffer);
1919  if (normalsNeedRebuild())
1920  buildNormalBuffer(buffer);
1921  if (colorsNeedRebuild())
1922  buildColorBuffer(buffer);
1923  if (texCoordsNeedRebuild())
1924  buildTexCoordBuffer(buffer);
1925 
1926 
1927  ACG::GLState::unmapBuffer(GL_ARRAY_BUFFER);
1928 
1929  ACG::GLState::bindBuffer(GL_ARRAY_BUFFER, 0);
1930 
1931  }
1932  else
1933  {
1934  std::cerr << "error while mapping buffer" << std::endl;
1935  }
1936 
1937  }
1938 
1939  saveOptions();
1940  mInvalidated = false;
1941  mGeometryChanged = false;
1942  mColorsChanged = false;
1943  mNormalsChanged = false;
1944  mTexCoordsChanged = false;
1945 
1946  }
1947 
1948  return mBuffer;
1949 }
1950 
1959 template <class VolumeMesh>
1961 {
1962  if (_offset != mCurrentPickOffset || _state.pick_current_index() != mGlobalPickOffset)
1963  {
1964  invalidateColors();
1965  mGlobalPickOffset = _state.pick_current_index();
1966  }
1967 
1968  if ((mBuffer == 0) || optionsChanged() || mInvalidated)
1969  {
1970  if (mBuffer == 0)
1971  ACG::GLState::genBuffers(1, &mBuffer);
1972 
1974 
1975  if (optionsChanged())
1976  mNumOfVertices = -1;
1977 
1978  unsigned int numOfVertices = getNumOfVertices();
1979 
1980  if (getNumOfVertices() > 0)
1981  {
1982 
1983  unsigned int bufferSize = mVertexSize * numOfVertices;
1984 
1985  ACG::GLState::bindBuffer(GL_ARRAY_BUFFER, mBuffer);
1986  ACG::GLState::bufferData(GL_ARRAY_BUFFER, bufferSize, 0, GL_STATIC_DRAW);
1987 
1988  unsigned char* buffer = (unsigned char *) ACG::GLState::mapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE);
1989 
1990  if (buffer)
1991  {
1992 
1993  if (positionsNeedRebuild())
1994  buildVertexBuffer(buffer);
1995  if (colorsNeedRebuild())
1996  buildPickColorBuffer(_state, _offset, buffer);
1997 
1998  ACG::GLState::unmapBuffer(GL_ARRAY_BUFFER);
1999 
2000  ACG::GLState::bindBuffer(GL_ARRAY_BUFFER, 0);
2001 
2002  }
2003  else
2004  {
2005  std::cerr << "error while mapping buffer" << std::endl;
2006  }
2007 
2008  }
2009 
2010  mCurrentPickOffset = _offset;
2011  saveOptions();
2012  mInvalidated = false;
2013  mGeometryChanged = false;
2014  mColorsChanged = false;
2015  mTexCoordsChanged = false;
2016 
2017  }
2018 
2019  return mBuffer;
2020 }
2021 
2025 template <class VolumeMesh>
2027 {
2030  invalidateColors();
2031 }
2032 
2036 template <class VolumeMesh>
2038 {
2039  mInvalidated = true;
2040  mNumOfVertices = -1;
2041  mGeometryChanged = true;
2042  mColorsChanged = true;
2043  mTexCoordsChanged = true;
2044  mNormalsChanged = true;
2045  mCogsValid = false;
2046  mCellInsidenessValid = false;
2047 }
2048 
2052 template <class VolumeMesh>
2054 {
2055  mInvalidated = true;
2056  mColorsChanged = true;
2057 }
2058 
2062 template <class VolumeMesh>
2064 {
2065  mInvalidated = true;
2066  mNormalsChanged = true;
2067 }
2068 
2072 template <class VolumeMesh>
2074 {
2075  mInvalidated = true;
2076  mTexCoordsChanged = true;
2077 }
2078 
2084 template <class VolumeMesh>
2086 {
2087  if (mBuffer != 0)
2088  ACG::GLState::deleteBuffers(1, &mBuffer);
2089 
2090  mBuffer = 0;
2091 
2092  invalidate();
2093 }
void invalidateGeometry()
Invalidates geometry.
static GLboolean unmapBuffer(GLenum target)
Definition: GLState.cc:2198
bool positionsNeedRebuild()
Checks whether positions need to be rebuild.
void invalidateColors()
Invalidates colors.
void countNumOfVertices()
Counts the number of vertices that need to be stored in the buffer.
void buildColorBuffer(unsigned char *_buffer)
Adds all colors to the buffer.
Namespace providing different geometric functions concerning angles.
void enablePerVertexColors()
Enables per vertex colors.
VectorT< float, 4 > Vec4f
Definition: VectorT.hh:138
void saveOptions()
State that the current buffer was built with the current options.
void buildPickColorBuffer(ACG::GLState &_state, unsigned int _offset, unsigned char *_buffer)
Adds all picking colors to the buffer.
void buildTexCoordBuffer(unsigned char *_buffer)
Adds texture coordinates to the buffer.
size_t pick_current_index() const
Returns the current color picking index (can be used for caching)
Definition: GLState.cc:1131
void clearCutPlanes()
Removes all cut planes.
static void deleteBuffers(GLsizei n, const GLuint *buffers)
Definition: GLState.cc:2189
Vec4uc pick_get_name_color(size_t _idx)
Definition: GLState.cc:1068
void enablePerHalfedgeColors()
Enables per halfedge colors.
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.
void addFloatToBuffer(float _value, unsigned char *&_buffer)
Adds a float to the buffer.
void addUCharToBuffer(unsigned char _value, unsigned char *&_buffer)
Adds an unsigned char to the buffer.
void setOptionsFromDrawMode(ACG::SceneGraph::DrawModes::DrawMode _drawMode)
Configures the buffer manager&#39;s options from a DrawMode.
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 calculateVertexDeclaration()
Constructs a VertexDeclaration, the size and the offsets for the vertices stored in the buffer...
GLuint getPickBuffer(ACG::GLState &_state, unsigned int _offset)
Returns the name of the pick buffer.
void disableNormals()
Disables normals.
void disableColors()
Disables colors.
void addElement(const VertexElement *_pElement)
void invalidateNormals()
Invalidates normals.
void calculateCellInsideness()
Calculates for all cells whether they are inside w.r.t. all cut planes.
void invalidateTexCoords()
Invalidates texture coordinates.
void enablePerCellColors()
Enables per cell colors.
void enablePerHalffaceNormals()
Enables per halfface normals.
void invalidate()
Invalidates the buffer.
void addTexCoordToBuffer(ACG::Vec2f _texCoord, unsigned char *_buffer, unsigned int _offset)
Adds a texture coordnate to the buffer.
void setDefaultColor(ACG::Vec4f _defaultColor)
Sets the default color.
void buildVertexBuffer(unsigned char *_buffer)
Adds all vertices to the buffer.
ACG::Vec4f getValenceColorCode(unsigned int _valence, bool _inner) const
Returns a color code for irregular edges.
static GLvoid * mapBuffer(GLenum target, GLenum access)
Definition: GLState.cc:2193
unsigned int getNumOfVertices()
Returns the number of vertices stored in the buffer.
void free()
Deletes the buffers on the GPU.
This class creates buffers that can be used to render open volume meshs.
bool normalsNeedRebuild()
Checks whether normals need to be rebuild.
void enablePerVertexNormals()
Enables per vertex normals.
void addPositionToBuffer(ACG::Vec3d _position, unsigned char *_buffer, unsigned int _offset)
Adds a position to the buffer.
bool is_inside(const ACG::Vec3d &_p)
Tests whether the given point is inside w.r.t. all cut planes.
bool colorsNeedRebuild()
Checks whether colors need to be rebuild.
void enablePerEdgeColors()
Enables per edge colors.
bool optionsChanged()
Tests whether the options were changed since the last time building the buffer.
static void genBuffers(GLsizei n, GLuint *buffers)
Definition: GLState.cc:2175
static void bufferData(GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage)
Definition: GLState.cc:2184
void calculateCOGs()
Calculates the center of gravity for all cells.
bool texCoordsNeedRebuild()
Checks whether texture coordinates need to be rebuild.
void enablePerFaceColors()
Enables per face colors.
void enablePerHalffaceColors()
Enables per halfface colors.
ACG::Vec3d getCOG(OpenVolumeMesh::CellHandle _ch)
Returns the center of gravity of the given cell.
void buildNormalBuffer(unsigned char *_buffer)
Adds all normals to the buffer.
void enablePerFaceNormals()
Enables per face normals.
void addCutPlane(const ACG::Geometry::Plane &_p)
Adds a cut plane.
static void bindBuffer(GLenum _target, GLuint _buffer)
replaces glBindBuffer, supports locking
Definition: GLState.cc:1820
VectorT< double, 3 > Vec3d
Definition: VectorT.hh:121
GLuint getBuffer()
Returns the name of the buffer.