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
47template <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
113template <class VolumeMesh>
114void 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
135template <class VolumeMesh>
136void VolumeMeshBufferManager<VolumeMesh>::addUCharToBuffer( unsigned char _value, unsigned char *&_buffer )
137{
138 *_buffer = _value;
139 ++_buffer;
140}
141
152template <class VolumeMesh>
153void VolumeMeshBufferManager<VolumeMesh>::addPositionToBuffer(ACG::Vec3d _position, unsigned char* _buffer , unsigned int _offset)
155 unsigned char* buffer = _buffer + _offset*mVertexSize;
156 addFloatToBuffer(_position[0], buffer);
157 addFloatToBuffer(_position[1], buffer);
158 addFloatToBuffer(_position[2], buffer);
159}
160
171template <class VolumeMesh>
172void VolumeMeshBufferManager<VolumeMesh>::addColorToBuffer(ACG::Vec4uc _color, unsigned char* _buffer, unsigned int _offset)
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
193template <class VolumeMesh>
194void 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
213template <class VolumeMesh>
214void 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
232template <class VolumeMesh>
233void 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
248template <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);
286
287 mVertexSize = currentOffset;
289
290
295template <class VolumeMesh>
297{
298 if (mNumOfVertices == -1)
299 countNumOfVertices();
300 return mNumOfVertices;
301}
310template <class VolumeMesh>
312{
313 if (mDefaultColor != _defaultColor)
315 invalidateColors();
316 mDefaultColor = _defaultColor;
318}
319
328template <class VolumeMesh>
330{
331 // colors
332 if (_drawMode & (mDrawModes.cellsColoredPerCell))
333 enablePerCellColors();
334 else if (_drawMode & (mDrawModes.cellsColoredPerFace | mDrawModes.facesColoredPerFace | mDrawModes.facesColoredPerFaceFlatShaded))
335 enablePerFaceColors();
336 else if (_drawMode & (mDrawModes.cellsColoredPerHalfface | mDrawModes.halffacesColoredPerHalfface))
337 enablePerHalffaceColors();
338 else if (_drawMode & ( mDrawModes.edgesColoredPerEdge ))
339 enablePerEdgeColors();
340 else if (_drawMode & (mDrawModes.halfedgesColoredPerHalfedge))
341 enablePerHalfedgeColors();
342 else if (_drawMode & (mDrawModes.cellsColoredPerVertex | mDrawModes.facesColoredPerVertex |
343 mDrawModes.halffacesColoredPerVertex | mDrawModes.edgesColoredPerEdge |
344 mDrawModes.verticesColored))
345 enablePerVertexColors();
346 else
347 disableColors();
348
349 //normals
350 if (_drawMode & (mDrawModes.cellsFlatShaded | mDrawModes.halffacesFlatShaded))
351 enablePerHalffaceNormals();
352 else if (_drawMode & (mDrawModes.facesFlatShaded | mDrawModes.facesTexturedShaded | mDrawModes.facesColoredPerFaceFlatShaded))
353 enablePerFaceNormals();
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))
358 enablePerVertexNormals();
359 else
360 disableNormals();
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
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
410
411
418template <class VolumeMesh>
420{
421 cut_planes_.clear();
422 invalidateGeometry();
423 mCellInsidenessValid = false;
424}
425
433template <class VolumeMesh>
435{
436 cut_planes_.push_back(_p);
437 invalidateGeometry();
438 mCellInsidenessValid = false;
439}
440
451template <class VolumeMesh>
453{
454 addCutPlane(ACG::Geometry::Plane(_p, _n, _xsize, _ysize));
455}
456
464template <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
491template <class VolumeMesh>
493{
494 if ( cut_planes_.empty() ) return true;
495 return is_inside(mMesh.vertex(_vh));
496}
497
507template <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
524template <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
541template <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
560template <class VolumeMesh>
562{
563 if ( cut_planes_.empty() ) return true;
564 return is_inside(mMesh.halfface_handle(_fh,0));
565}
566
578template <class VolumeMesh>
580{
581 if (mStatusAttrib[_ch].hidden())
582 return false;
583
584 if (!mCellInsidenessValid)
585 calculateCellInsideness();
586
587 return mCellInsideness[_ch.idx()];
588}
589
590template <class VolumeMesh>
591bool VolumeMeshBufferManager<VolumeMesh>::should_render(const VertexHandle& _vh)
592{
593 if (mStatusAttrib[_vh].hidden())
594 return false;
595 return is_inside(_vh);
596}
597
598template <class VolumeMesh>
599bool VolumeMeshBufferManager<VolumeMesh>::should_render(const HalfEdgeHandle& _heh)
600{
601 if (mStatusAttrib[_heh].hidden())
602 return false;
603 return is_inside(_heh);
604}
605
606template <class VolumeMesh>
608{
609 if (mStatusAttrib[_eh].hidden())
610 return false;
611 return is_inside(_eh);
612}
613
614template <class VolumeMesh>
615bool VolumeMeshBufferManager<VolumeMesh>::should_render(const HalfFaceHandle& _hfh)
616{
617 if (mStatusAttrib[_hfh].hidden())
618 return false;
619 return is_inside(_hfh);
620}
621
622template <class VolumeMesh>
624{
625 if (mStatusAttrib[_fh].hidden())
626 return false;
627 return is_inside(_fh);
628}
629
630template <class VolumeMesh>
632{
633 if (mStatusAttrib[_ch].hidden())
634 return false;
635 return is_inside(_ch);
636}
637
638
645template <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
681template <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
699template <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
725template <class VolumeMesh>
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
747template <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
923template <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
945template <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
964template <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
982template <class VolumeMesh>
984{
985 if (!mCogsValid)
986 calculateCOGs();
987
988 return mCogs[_ch.idx()];
989}
990
998template <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
1030template <class VolumeMesh>
1032{
1033 return (mGeometryChanged) ||
1034 (mVertexSize != mCurrentVertexSize) ||
1035 (mPrimitiveMode != mCurrentPrimitiveMode) ||
1036 (mNumOfVertices != mCurrentNumOfVertices);
1037}
1038
1044template <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
1062template <class VolumeMesh>
1064{
1065 return (mTexCoordsChanged) ||
1066 (mVertexSize != mCurrentVertexSize) ||
1067 (mNumOfVertices != mCurrentNumOfVertices) ||
1068 (mPrimitiveMode != mCurrentPrimitiveMode) ||
1069 (mTexCoordOffset!= mCurrentTexCoordOffset);
1070}
1071
1077template <class VolumeMesh>
1079{
1080 return (mNormalsChanged) ||
1081 (mVertexSize != mCurrentVertexSize) ||
1082 (mPrimitiveMode != mCurrentPrimitiveMode) ||
1083 (mNormalOffset != mCurrentNormalOffset) ||
1084 (mNormalMode != mCurrentNormalMode) ||
1085 (mNumOfVertices != mCurrentNumOfVertices);
1086}
1087
1093template <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
1307template <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
1445template <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
1709template <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
1771template <class VolumeMesh>
1772void 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
1887template <class VolumeMesh>
1889{
1890 if ((mBuffer == 0) || optionsChanged() || mInvalidated)
1891 {
1892
1893 if (mBuffer == 0)
1894 ACG::GLState::genBuffers(1, &mBuffer);
1895
1896 calculateVertexDeclaration();
1897
1898 if (optionsChanged())
1899 mNumOfVertices = -1;
1900
1901 unsigned int numOfVertices = getNumOfVertices();
1902
1903 bool needs_rebuild = positionsNeedRebuild()
1904 || normalsNeedRebuild()
1905 || colorsNeedRebuild()
1906 || texCoordsNeedRebuild();
1907
1908 if (getNumOfVertices() > 0 && needs_rebuild)
1909 {
1910 unsigned int bufferSize = mVertexSize * numOfVertices;
1911
1912 ACG::GLState::bindBuffer(GL_ARRAY_BUFFER, mBuffer);
1913 ACG::GLState::bufferData(GL_ARRAY_BUFFER, bufferSize, 0, GL_STATIC_DRAW);
1914
1915 unsigned char* buffer = (unsigned char *) ACG::GLState::mapBuffer(
1916 GL_ARRAY_BUFFER, GL_WRITE_ONLY);
1917
1918 if (!buffer)
1919 {
1920 std::cerr << "VolumeMeshBufferManager::getBuffer(): error mapping buffer" << std::endl;
1921 return mBuffer;
1922 }
1923
1924 buildVertexBuffer(buffer);
1925 buildNormalBuffer(buffer);
1926 buildColorBuffer(buffer);
1927 buildTexCoordBuffer(buffer);
1928
1929 ACG::GLState::unmapBuffer(GL_ARRAY_BUFFER);
1930 ACG::GLState::bindBuffer(GL_ARRAY_BUFFER, 0);
1931 }
1932
1933 saveOptions();
1934 mInvalidated = false;
1935 mGeometryChanged = false;
1936 mColorsChanged = false;
1937 mNormalsChanged = false;
1938 mTexCoordsChanged = false;
1939
1940 }
1941
1942 return mBuffer;
1943}
1944
1953template <class VolumeMesh>
1955{
1956 if (_offset != mCurrentPickOffset || _state.pick_current_index() != mGlobalPickOffset)
1957 {
1958 invalidateColors();
1959 mGlobalPickOffset = _state.pick_current_index();
1960 }
1961
1962 if ((mBuffer == 0) || optionsChanged() || mInvalidated)
1963 {
1964 if (mBuffer == 0)
1965 ACG::GLState::genBuffers(1, &mBuffer);
1966
1967 calculateVertexDeclaration();
1968
1969 if (optionsChanged())
1970 mNumOfVertices = -1;
1971
1972 unsigned int numOfVertices = getNumOfVertices();
1973
1974 if (getNumOfVertices() > 0 && (positionsNeedRebuild() || colorsNeedRebuild()))
1975 {
1976 unsigned int bufferSize = mVertexSize * numOfVertices;
1977
1978 ACG::GLState::bindBuffer(GL_ARRAY_BUFFER, mBuffer);
1979 ACG::GLState::bufferData(GL_ARRAY_BUFFER, bufferSize, 0, GL_STATIC_DRAW);
1980 unsigned char* buffer = (unsigned char *) ACG::GLState::mapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
1981
1982 if (!buffer)
1983 {
1984 std::cerr << "VolumeMeshBufferManager::getPickBuffer(): error while mapping buffer" << std::endl;
1985 return mBuffer;
1986 }
1987
1988 buildVertexBuffer(buffer);
1989 buildPickColorBuffer(_state, _offset, buffer);
1990
1991 ACG::GLState::unmapBuffer(GL_ARRAY_BUFFER);
1992 ACG::GLState::bindBuffer(GL_ARRAY_BUFFER, 0);
1993 }
1994
1995 mCurrentPickOffset = _offset;
1996 saveOptions();
1997 mInvalidated = false;
1998 mGeometryChanged = false;
1999 mColorsChanged = false;
2000 mTexCoordsChanged = false;
2001
2002 }
2003
2004 return mBuffer;
2005}
2006
2010template <class VolumeMesh>
2012{
2013 invalidateGeometry();
2014 invalidateNormals();
2015 invalidateColors();
2016}
2017
2021template <class VolumeMesh>
2023{
2024 mInvalidated = true;
2025 mNumOfVertices = -1;
2026 mGeometryChanged = true;
2027 mColorsChanged = true;
2028 mTexCoordsChanged = true;
2029 mNormalsChanged = true;
2030 mCogsValid = false;
2031 mCellInsidenessValid = false;
2032}
2033
2037template <class VolumeMesh>
2039{
2040 mInvalidated = true;
2041 mColorsChanged = true;
2042}
2043
2047template <class VolumeMesh>
2049{
2050 mInvalidated = true;
2051 mNormalsChanged = true;
2052}
2053
2057template <class VolumeMesh>
2059{
2060 mInvalidated = true;
2061 mTexCoordsChanged = true;
2062}
2063
2069template <class VolumeMesh>
2071{
2072 if (mBuffer != 0)
2073 ACG::GLState::deleteBuffers(1, &mBuffer);
2074
2075 mBuffer = 0;
2076
2077 invalidate();
2078}
static GLboolean unmapBuffer(GLenum target)
Definition: GLState.cc:2241
Vec4uc pick_get_name_color(size_t _idx)
Definition: GLState.cc:1068
static void genBuffers(GLsizei n, GLuint *buffers)
Definition: GLState.cc:2218
size_t pick_current_index() const
Returns the current color picking index (can be used for caching)
Definition: GLState.cc:1131
static void bufferData(GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage)
Definition: GLState.cc:2227
static void deleteBuffers(GLsizei n, const GLuint *buffers)
Definition: GLState.cc:2232
static GLvoid * mapBuffer(GLenum target, GLenum access)
Definition: GLState.cc:2236
static void bindBuffer(GLenum _target, GLuint _buffer)
replaces glBindBuffer, supports locking
Definition: GLState.cc:1820
static constexpr size_t size()
returns dimension of the vector
Definition: Vector11T.hh:107
This class creates buffers that can be used to render open volume meshs.
void buildNormalBuffer(unsigned char *_buffer)
Adds all normals to the buffer.
void free()
Deletes the buffers on the GPU.
bool texCoordsNeedRebuild()
Checks whether texture coordinates need to be rebuild.
void saveOptions()
State that the current buffer was built with the current options.
void setDefaultColor(ACG::Vec4f _defaultColor)
Sets the default color.
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.
bool positionsNeedRebuild()
Checks whether positions need to be rebuild.
void addPositionToBuffer(ACG::Vec3d _position, unsigned char *_buffer, unsigned int _offset)
Adds a position to the buffer.
bool normalsNeedRebuild()
Checks whether normals need to be rebuild.
void calculateVertexDeclaration()
Constructs a VertexDeclaration, the size and the offsets for the vertices stored in the buffer.
int getNumOfIncidentCells(OpenVolumeMesh::FaceHandle _fh)
Returns the number of cells that are incident to the given face and also inside w....
void buildPickColorBuffer(ACG::GLState &_state, unsigned int _offset, unsigned char *_buffer)
Adds all picking colors to the buffer.
ACG::Vec3d getCOG(OpenVolumeMesh::CellHandle _ch)
Returns the center of gravity of the given cell.
unsigned int getNumOfVertices()
Returns the number of vertices stored in the buffer.
void addCutPlane(const ACG::Geometry::Plane &_p)
Adds a cut plane.
void clearCutPlanes()
Removes all cut planes.
void invalidateColors()
Invalidates colors.
GLuint getBuffer()
Returns the name of the buffer.
void buildTexCoordBuffer(unsigned char *_buffer)
Adds texture coordinates to the buffer.
bool colorsNeedRebuild()
Checks whether colors need to be rebuild.
void addNormalToBuffer(ACG::Vec3d _normal, unsigned char *_buffer, unsigned int _offset)
Adds a normal to the buffer.
void invalidateNormals()
Invalidates normals.
void invalidate()
Invalidates the buffer.
void invalidateTexCoords()
Invalidates texture coordinates.
void addFloatToBuffer(float _value, unsigned char *&_buffer)
Adds a float to the buffer.
void addColorToBuffer(ACG::Vec4uc _color, unsigned char *_buffer, unsigned int _offset)
Adds a color to the buffer.
void calculateCOGs()
Calculates the center of gravity for all cells.
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.
void addTexCoordToBuffer(ACG::Vec2f _texCoord, unsigned char *_buffer, unsigned int _offset)
Adds a texture coordnate to the buffer.
void setOptionsFromDrawMode(ACG::SceneGraph::DrawModes::DrawMode _drawMode)
Configures the buffer manager's options from a DrawMode.
GLuint getPickBuffer(ACG::GLState &_state, unsigned int _offset)
Returns the name of the pick buffer.
bool is_inside(const ACG::Vec3d &_p)
Tests whether the given point is inside w.r.t. all cut planes.
void invalidateGeometry()
Invalidates geometry.
ACG::Vec4f getValenceColorCode(unsigned int _valence, bool _inner) const
Returns a color code for irregular edges.
void buildVertexBuffer(unsigned char *_buffer)
Adds all vertices to the buffer.
void addUCharToBuffer(unsigned char _value, unsigned char *&_buffer)
Adds an unsigned char to the buffer.
Namespace providing different geometric functions concerning angles.
VectorT< float, 4 > Vec4f
Definition: VectorT.hh:138
@ VERTEX_USAGE_NORMAL
"inNormal"
@ VERTEX_USAGE_COLOR
"inColor"
@ VERTEX_USAGE_POSITION
"inPosition"
@ VERTEX_USAGE_TEXCOORD
"inTexCoord"
VectorT< double, 3 > Vec3d
Definition: VectorT.hh:121