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