55 #define ACG_STRIP_PROCESSOR_C 62 #include <OpenMesh/Core/Utils/color_cast.hh> 77 updatePerEdgeBuffers_(true),
78 updatePerHalfedgeBuffers_(true),
79 updatePerFaceBuffers_(true),
80 textureIndexPropertyName_(
"Not Set"),
81 perFaceTextureCoordinatePropertyName_(
"Not Set")
83 mesh_.request_face_normals();
121 template <
class Mesh>
126 template <
class Mesh>
135 mesh_.add_property( processed_ );
136 mesh_.add_property( used_ );
137 mesh_.request_face_status();
144 mesh_.remove_property(processed_);
145 mesh_.remove_property(used_);
146 mesh_.release_face_status();
156 template <
class Mesh>
163 if (mesh_.has_face_status()) {
164 for (
typename Mesh::FaceIter f_it=mesh_.faces_begin(); f_it != mesh_.faces_end(); ++f_it)
165 if (mesh_.status(f_it).hidden() || mesh_.status(f_it).deleted())
166 processed(f_it) = used(f_it) =
true;
168 processed(f_it) = used(f_it) =
false;
170 for (
typename Mesh::FaceIter f_it=mesh_.faces_begin(); f_it != mesh_.faces_end() ; ++f_it)
171 processed(f_it) = used(f_it) =
false;
187 template <
class Mesh>
194 std::vector<Strip> experiments;
195 std::vector< typename Mesh::HalfedgeHandle > h;
196 std::vector< FaceHandles > faces;
197 typename FaceHandles::iterator fh_it, fh_end;
198 typename Mesh::FaceIter f_it, f_end=mesh_.faces_end();
200 for (f_it=mesh_.faces_begin();
true; ) {
203 for (; f_it != f_end; ++f_it)
204 if (!processed(f_it))
break;
212 experiments.resize( mesh_.valence(f_it) );
214 faces.resize(mesh_.valence(f_it));
219 h.push_back( fhalfedge_it.handle() );
222 unsigned int best_length = 0;
223 unsigned int best_idx = 0;
224 for (
unsigned int i = 0; i < mesh_.valence(f_it) ; ++i)
227 const unsigned int length = experiments[i].indexArray.size();
228 if (length > best_length) {
229 best_length = length;
234 for (fh_it=faces[i].
begin(), fh_end=faces[i].
end(); fh_it!=fh_end; ++fh_it)
235 used(*fh_it) =
false;
240 fh_it = faces[best_idx].begin();
241 fh_end = faces[best_idx].end();
242 for (; fh_it!=fh_end; ++fh_it)
243 processed(*fh_it) =
true;
246 strips_.push_back(experiments[best_idx]);
250 template <
class Mesh>
255 Strip experiments[3];
256 typename Mesh::HalfedgeHandle h[3];
259 typename FaceHandles::iterator fh_it, fh_end;
260 typename Mesh::FaceIter f_it, f_end=mesh_.faces_end();
262 for (f_it=mesh_.faces_begin();
true; )
265 for (; f_it!=f_end; ++f_it)
266 if (!processed(f_it))
268 if (f_it==f_end)
break;
272 h[0] = mesh_.halfedge_handle(f_it.handle());
273 h[1] = mesh_.next_halfedge_handle(h[0]);
274 h[2] = mesh_.next_halfedge_handle(h[1]);
277 unsigned int best_length = 0;
278 unsigned int best_idx = 0;
280 for (
unsigned int i=0; i<3; ++i)
284 const unsigned int length = experiments[i].
indexArray.size();
285 if ( length > best_length)
287 best_length = length;
291 for (fh_it=faces[i].
begin(), fh_end=faces[i].
end();
292 fh_it!=fh_end; ++fh_it)
293 used(*fh_it) =
false;
298 fh_it = faces[best_idx].begin();
299 fh_end = faces[best_idx].end();
300 for (; fh_it!=fh_end; ++fh_it)
301 processed(*fh_it) =
true;
304 strips_.push_back(experiments[best_idx]);
311 template <
class Mesh>
318 std::list<unsigned int> strip;
319 std::list<typename Mesh::FaceHandle > faceMap;
320 typename Mesh::FaceHandle fh;
321 typename Mesh::HalfedgeHandle hh_left, hh_right;
327 strip.push_back(mesh_.from_vertex_handle(_start_hh).idx());
328 strip.push_back(mesh_.to_vertex_handle(_start_hh).idx());
334 bool textureHandling =
false;
336 textureHandling =
true;
337 _strip.
textureIndex = mesh_.property(textureIndexProperty,mesh_.face_handle(_start_hh));
345 hh_left = hh_right = _start_hh;
350 hh_right = mesh_.prev_halfedge_handle(hh_right);
353 strip.push_back(mesh_.from_vertex_handle(hh_right).idx());
354 faceMap.push_back(mesh_.face_handle(hh_right));
357 if(mesh_.to_vertex_handle(mesh_.next_halfedge_handle(hh_left)) == mesh_.from_vertex_handle(hh_right)) {
360 fh = mesh_.face_handle(hh_left);
361 _faces.push_back(fh);
365 hh_left = hh_right = mesh_.opposite_halfedge_handle(mesh_.next_halfedge_handle(hh_left));
370 if(mesh_.is_boundary(hh_left))
break;
371 fh = mesh_.face_handle(hh_left);
372 if (processed(fh) || used(fh))
break;
375 if ( textureHandling && ( _strip.
textureIndex != mesh_.property(textureIndexProperty,fh ) ) )
break;
381 hh_left = mesh_.next_halfedge_handle(hh_left);
384 strip.push_back(mesh_.to_vertex_handle(hh_left).idx());
385 faceMap.push_back(mesh_.face_handle(hh_left));
388 if(mesh_.to_vertex_handle(mesh_.next_halfedge_handle(hh_left)) == mesh_.from_vertex_handle(hh_right)) {
390 fh = mesh_.face_handle(hh_left);
391 _faces.push_back(fh);
395 hh_left = hh_right = mesh_.opposite_halfedge_handle(mesh_.next_halfedge_handle(hh_left));
400 if(mesh_.is_boundary(hh_left))
break;
401 fh = mesh_.face_handle(hh_left);
402 if (processed(fh) || used(fh))
break;
405 if ( textureHandling && ( _strip.
textureIndex != mesh_.property(textureIndexProperty,fh ) ) )
break;
417 hh_left = hh_right = mesh_.opposite_halfedge_handle(_start_hh);
422 if(mesh_.is_boundary(hh_left))
break;
425 hh_right = mesh_.prev_halfedge_handle(hh_right);
428 strip.push_front(mesh_.from_vertex_handle(hh_right).idx());
429 faceMap.push_front(mesh_.face_handle(hh_right));
433 if(mesh_.to_vertex_handle(mesh_.next_halfedge_handle(hh_left)) == mesh_.from_vertex_handle(hh_right)) {
436 fh = mesh_.face_handle(hh_right);
437 _faces.push_back(fh);
441 hh_left = hh_right = mesh_.opposite_halfedge_handle(mesh_.next_halfedge_handle(hh_left));
443 if(mesh_.is_boundary(hh_left))
break;
444 fh = mesh_.face_handle(hh_left);
445 if (processed(fh) || used(fh))
break;
448 if ( textureHandling && ( _strip.
textureIndex != mesh_.property(textureIndexProperty,fh ) ) )
break;
458 hh_left = mesh_.next_halfedge_handle(hh_left);
461 strip.push_front( mesh_.to_vertex_handle(hh_left).idx() );
462 faceMap.push_front( mesh_.face_handle(hh_left) );
466 if(mesh_.to_vertex_handle(mesh_.next_halfedge_handle(hh_left)) == mesh_.from_vertex_handle(hh_right)) {
469 fh = mesh_.face_handle(hh_right);
470 _faces.push_back(fh);
474 hh_left = hh_right = mesh_.opposite_halfedge_handle(mesh_.next_halfedge_handle(hh_left));
476 if(mesh_.is_boundary(hh_left))
break;
477 fh = mesh_.face_handle(hh_left);
478 if (processed(fh) || used(fh))
break;
481 if ( textureHandling && ( _strip.
textureIndex != mesh_.property(textureIndexProperty,fh ) ) )
break;
490 strip.push_front(strip.front());
491 faceMap.push_front(mesh_.face_handle(0));
495 faceMap.push_front(mesh_.face_handle(0));
496 faceMap.push_front(mesh_.face_handle(0));
501 std::copy(strip.begin(), strip.end(), std::back_inserter(_strip.
indexArray));
504 _strip.
faceMap.reserve(strip.size());
505 std::copy(faceMap.begin(), faceMap.end(), std::back_inserter(_strip.
faceMap));
512 template <
class Mesh>
519 std::list<unsigned int> strip;
520 typename Mesh::HalfedgeHandle hh;
521 typename Mesh::FaceHandle fh;
523 std::list<typename Mesh::FaceHandle > faceMap;
531 strip.push_back(mesh_.from_vertex_handle(_start_hh).idx());
532 strip.push_back(mesh_.to_vertex_handle(_start_hh).idx());
537 bool textureHandling =
false;
540 textureHandling =
true;
541 _strip.
textureIndex = mesh_.property(textureIndexProperty,mesh_.face_handle(_start_hh));
551 hh = mesh_.prev_halfedge_handle(mesh_.opposite_halfedge_handle(_start_hh));
555 hh = mesh_.next_halfedge_handle(hh);
556 hh = mesh_.opposite_halfedge_handle(hh);
557 hh = mesh_.next_halfedge_handle(hh);
558 if (mesh_.is_boundary(hh))
break;
559 fh = mesh_.face_handle(hh);
560 if (processed(fh) || used(fh))
break;
563 if ( textureHandling && ( _strip.
textureIndex != mesh_.property(textureIndexProperty,fh ) ) )
break;
565 _faces.push_back(fh);
567 strip.push_back(mesh_.to_vertex_handle(hh).idx());
568 faceMap.push_back(mesh_.face_handle(hh));
571 hh = mesh_.opposite_halfedge_handle(hh);
572 hh = mesh_.next_halfedge_handle(hh);
573 if (mesh_.is_boundary(hh))
break;
574 fh = mesh_.face_handle(hh);
575 if (processed(fh) || used(fh))
break;
578 if ( textureHandling && ( _strip.
textureIndex != mesh_.property(textureIndexProperty,fh ) ) )
break;
580 _faces.push_back(fh);
582 strip.push_back(mesh_.to_vertex_handle(hh).idx());
583 faceMap.push_back(mesh_.face_handle(hh));
589 hh = mesh_.prev_halfedge_handle(_start_hh);
593 hh = mesh_.next_halfedge_handle(hh);
594 hh = mesh_.opposite_halfedge_handle(hh);
595 hh = mesh_.next_halfedge_handle(hh);
596 if (mesh_.is_boundary(hh))
break;
597 fh = mesh_.face_handle(hh);
598 if (processed(fh) || used(fh))
break;
601 if ( textureHandling && ( _strip.
textureIndex != mesh_.property(textureIndexProperty,fh ) ) )
break;
603 _faces.push_back(fh);
605 strip.push_front(mesh_.to_vertex_handle(hh).idx());
606 faceMap.push_front(mesh_.face_handle(hh));
610 hh = mesh_.opposite_halfedge_handle(hh);
611 hh = mesh_.next_halfedge_handle(hh);
612 if (mesh_.is_boundary(hh))
break;
613 fh = mesh_.face_handle(hh);
614 if (processed(fh) || used(fh))
break;
617 if ( textureHandling && ( _strip.
textureIndex != mesh_.property(textureIndexProperty,fh ) ) )
break;
619 _faces.push_back(fh);
621 strip.push_front(mesh_.to_vertex_handle(hh).idx());
622 faceMap.push_front(mesh_.face_handle(hh));
627 strip.push_front(strip.front());
628 faceMap.push_front(mesh_.face_handle(0));
633 faceMap.push_front(mesh_.face_handle(0));
634 faceMap.push_front(mesh_.face_handle(0));
639 std::copy(strip.begin(), strip.end(), std::back_inserter(_strip.
indexArray));
642 _strip.
faceMap.reserve(strip.size());
643 std::copy(faceMap.begin(), faceMap.end(), std::back_inserter(_strip.
faceMap));
646 template <
class Mesh>
651 unsigned int idx = 0;
657 typename Mesh::ConstVertexIter v_it(mesh_.vertices_begin()), v_end(mesh_.vertices_end());
658 for (; v_it!=v_end; ++v_it, ++idx)
662 template <
class Mesh>
674 typename Mesh::ConstEdgeIter e_it(mesh_.edges_sbegin()), e_end(mesh_.edges_end());
675 for (; e_it!=e_end; ++e_it) {
686 template <
class Mesh>
696 unsigned int n_faces = 0;
697 for(StripsIterator it = strips_.begin(); it != strips_.end(); ++it)
698 n_faces += (*it).indexArray.size() - 2;
704 unsigned int bufferIndex = 0;
707 for (
unsigned int i = 0 ; i < strips_.size() ; ++i ) {
717 for (
unsigned int stripIndex = 2 ; stripIndex < strips_[ i ].indexArray.size() ; ++stripIndex) {
731 template <
class Mesh>
743 template <
class Mesh>
753 if ( mesh_.has_edge_colors() ) {
758 unsigned int idx = 0;
760 typename Mesh::ConstEdgeIter e_it(mesh_.edges_sbegin()), e_end(mesh_.edges_end());
761 for (; e_it!=e_end; ++e_it) {
763 perEdgeVertexBuffer_[idx] = mesh_.point(mesh_.to_vertex_handle(mesh_.halfedge_handle(e_it, 0)));
764 perEdgeVertexBuffer_[idx+1] = mesh_.point(mesh_.to_vertex_handle(mesh_.halfedge_handle(e_it, 1)));
766 if ( mesh_.has_edge_colors() ) {
767 const Vec4f color = OpenMesh::color_cast<
Vec4f>( mesh_.color(e_it) ) ;
769 perEdgeColorBuffer_[ idx + 1 ] = color;
779 template <
class Mesh>
789 template <
class Mesh>
800 template <
class Mesh>
810 if ( mesh_.has_halfedge_colors() ) {
815 unsigned int idx = 0;
817 typename Mesh::ConstHalfedgeIter he_it(mesh_.halfedges_sbegin()), he_end(mesh_.halfedges_end());
818 for (; he_it!=he_end; ++he_it) {
823 if ( mesh_.has_halfedge_colors() ) {
824 const Vec4f color = OpenMesh::color_cast<
Vec4f>( mesh_.color(he_it) ) ;
826 perHalfedgeColorBuffer_[ idx + 1 ] = color;
836 template <
class Mesh>
841 typename Mesh::Point p = mesh_.point(mesh_.to_vertex_handle (_heh));
842 typename Mesh::Point pp = mesh_.point(mesh_.from_vertex_handle(_heh));
843 typename Mesh::Point pn = mesh_.point(mesh_.to_vertex_handle(mesh_.next_halfedge_handle(_heh)));
847 if( !mesh_.is_boundary(_heh))
848 fn = mesh_.normal(mesh_.face_handle(_heh));
850 fn = mesh_.normal(mesh_.face_handle(mesh_.opposite_halfedge_handle(_heh)));
852 typename Mesh::Point upd = ((fn%(pn-p)).normalize() + (fn%(p-pp)).normalize()).normalize();
854 upd *= ((pn-p).norm()+(p-pp).norm())*0.08;
865 template <
class Mesh>
875 template <
class Mesh>
885 template <
class Mesh>
903 unsigned int n_faces = 0;
907 for(StripsIterator it = strips_.begin(); it != strips_.end(); ++it)
908 n_faces += (*it).indexArray.size() - 2;
914 unsigned int bufferIndex = 0;
916 if ( mesh_.has_face_normals() )
921 if ( mesh_.has_vertex_normals() )
926 if ( mesh_.has_face_colors() )
931 if ( usePerFaceTextureCoordinateProperty )
938 if ( usePerFaceTextureIndex )
942 for (
unsigned int i = 0 ; i < strips_.size() ; ++i ) {
946 if ( usePerFaceTextureIndex ) {
959 for (
unsigned int stripIndex = 2 ; stripIndex < strips_[ i ].indexArray.size() ; ++stripIndex) {
961 if ( mesh_.has_face_normals() ) {
962 const Vec3d normal = mesh_.normal( strips_[ i ].faceMap[ stripIndex ] );
968 if ( mesh_.has_face_colors() ) {
969 const Vec4f color = OpenMesh::color_cast<
Vec4f>( mesh_.color( strips_[ i ].faceMap[ stripIndex ] ) );
971 perFaceColorBuffer_[ bufferIndex + 1 ] = color;
972 perFaceColorBuffer_[ bufferIndex + 2 ] = color;
977 perFaceVertexBuffer_[ bufferIndex + 0 ] = mesh_.point(mesh_.vertex_handle( strips_[ i ].indexArray[ stripIndex - 2 ] ));
978 perFaceVertexBuffer_[ bufferIndex + 1 ] = mesh_.point(mesh_.vertex_handle( strips_[ i ].indexArray[ stripIndex - 1 ] ));
979 perFaceVertexBuffer_[ bufferIndex + 2 ] = mesh_.point(mesh_.vertex_handle( strips_[ i ].indexArray[ stripIndex - 0 ] ));
982 if ( mesh_.has_vertex_normals() ) {
989 if ( usePerFaceTextureCoordinateProperty ) {
992 for ( ; fhe_it ; ++fhe_it ) {
994 Vec2f texcoord = mesh_.property(perFaceTextureCoordinateProperty,fhe_it);
996 if ( mesh_.vertex_handle( strips_[ i ].indexArray[ stripIndex - 2 ] ) == cvh ) {
999 }
else if ( mesh_.vertex_handle( strips_[ i ].indexArray[ stripIndex - 1 ] ) == cvh ) {
1002 }
else if ( mesh_.vertex_handle( strips_[ i ].indexArray[ stripIndex - 0 ] ) == cvh ) {
1013 perFaceVertexBuffer_[ bufferIndex + 2 ] = mesh_.point(mesh_.vertex_handle( strips_[ i ].indexArray[ stripIndex - 2 ] ));
1014 perFaceVertexBuffer_[ bufferIndex + 1 ] = mesh_.point(mesh_.vertex_handle( strips_[ i ].indexArray[ stripIndex - 1 ] ));
1015 perFaceVertexBuffer_[ bufferIndex + 0 ] = mesh_.point(mesh_.vertex_handle( strips_[ i ].indexArray[ stripIndex - 0 ] ));
1018 if ( mesh_.has_vertex_normals() ) {
1024 if ( usePerFaceTextureCoordinateProperty ) {
1027 for ( ; fhe_it ; ++fhe_it ) {
1029 const Vec2f texcoord = mesh_.property(perFaceTextureCoordinateProperty,fhe_it);
1031 if ( mesh_.vertex_handle( strips_[ i ].indexArray[ stripIndex - 2 ] ) == cvh ) {
1034 }
else if ( mesh_.vertex_handle( strips_[ i ].indexArray[ stripIndex - 1 ] ) == cvh ) {
1037 }
else if ( mesh_.vertex_handle( strips_[ i ].indexArray[ stripIndex - 0 ] ) == cvh ) {
1056 template <
class Mesh>
1068 template <
class Mesh>
1079 template <
class Mesh>
1090 template <
class Mesh>
1101 template <
class Mesh>
1108 if ( !mesh_.get_property_handle(perFaceTextureCoordinateProperty,_perFaceTextureCoordinatePropertyName) ) {
1109 std::cerr <<
"StripProcessor: Unable to get per face texture coordinate property named " << _perFaceTextureCoordinatePropertyName << std::endl;
1120 template <
class Mesh>
1135 template <
class Mesh>
1149 template <
class Mesh>
1156 if ( !mesh_.get_property_handle(textureIndexProperty,_indexPropertyName) ) {
1157 std::cerr <<
"StripProcessor: Unable to get per face texture Index property named " << _indexPropertyName << std::endl;
std::vector< ACG::Vec4f > perFaceColorBuffer_
Buffer holding vertices for per face rendering.
std::vector< ACG::Vec3f > perFaceNormalBuffer_
Buffer holding vertices for per face rendering.
bool perFaceTextureCoordinateAvailable()
Check if per Face Texture coordinates are available.
void setIndexPropertyName(std::string _indexPropertyName)
set the name of the property used for texture index specification
void buildStripTriMesh(typename Mesh::HalfedgeHandle _start_hh, Strip &_strip, FaceHandles &_faces)
build a strip from a given halfedge (in both directions) of a triangle mesh
Namespace providing different geometric functions concerning angles.
bool perFaceTextureIndexAvailable()
Check if textureindicies are available.
void updatePickingAny(ACG::GLState &_state)
Call this function to update the color picking array.
std::vector< TextureRenderInfo > textureRenderData_
Property for the per face texture index.
ACG::Vec4f * perHalfedgeColorBuffer()
get a pointer to the per edge color buffer
ACG::Vec4f * perFaceColorBuffer()
get a pointer to the per face color buffer
void updatePerEdgeBuffers()
Update all per edge drawing buffer n The updated buffers are: per edge vertex buffer ( 2 vertices per...
Kernel::Point Point
Coordinate type.
int textureIndex
This contains the texture index used for rendering this strip.
StripsIterator begin() const
Access strips.
ACG::Vec3f * perHalfedgeVertexBuffer()
get a pointer to the per edge vertex buffer
void buildStrips()
this method does the main work
void updatePerHalfedgeBuffers()
Update all per edge drawing buffer n The updated buffers are: per edge vertex buffer ( 2 vertices per...
static constexpr bool is_trimesh()
Determine whether this is a PolyMeshT or TriMeshT (This function does not check the per face vertex c...
std::vector< ACG::Vec3f > perEdgeVertexBuffer_
Per Edge vertex buffer (glLines)
Mesh::Point halfedge_point(const typename Mesh::HalfedgeHandle _heh)
compute halfedge point compute visulization point for halfedge (shifted to interior of face) ...
std::vector< ACG::Vec3f > perFacePerVertexNormalBuffer_
Buffer holding vertices for per face rendering.
void buildStripsTriMesh()
This method generates strips for triangle meshes.
void updatePickingEdges(ACG::GLState &_state, uint _offset=0)
void clear()
delete all strips
void updatePickingVertices(ACG::GLState &_state, uint _offset=0)
std::vector< ACG::Vec4uc > pickVertexColorBuf_
The color buffer used for vertex picking.
std::vector< ACG::Vec4f > perEdgeColorBuffer_
Per Edge color buffer.
std::vector< ACG::Vec4uc > pickFaceColorBuf_
Call this function to update the color picking array.
Kernel::ConstFaceHalfedgeIter ConstFaceHalfedgeIter
Circulator.
void buildStripPolyMesh(typename Mesh::HalfedgeHandle _start_hh, Strip &_strip, FaceHandles &_faces)
build a strip from a given halfedge (in both directions) of a polymesh
StripsIterator end() const
Access strips.
std::vector< ACG::Vec2f > perFaceTextureCoordArray_
Property for the per face texture index.
std::vector< OpenMesh::FaceHandle > faceMap
This map contains for each vertex in the strips a handle to the face it closes.
void buildStripsPolyMesh()
Vec4uc pick_get_name_color(size_t _idx)
std::vector< ACG::Vec3f > perHalfedgeVertexBuffer_
Per Edge vertex buffer (glLines)
ACG::Vec3f * perFaceNormalBuffer()
get a pointer to the per face normal buffer
std::string textureIndexPropertyName_
Property for the per face texture index.
void convexityTest(FaceHandle _fh)
Test whether face is convex.
void updatePickingFaces(ACG::GLState &_state)
Call this function to update the color picking array.
std::vector< typename Mesh::FaceHandle > FaceHandles
This flag shows if the strips have to be regenerated.
bool updatePerFaceBuffers_
This flag controls if an update is really necessary.
StripProcessorT(Mesh &_mesh)
Default constructor.
bool stripTextureCompare(const Strip &i, const Strip &j)
Compare function for sorting Strips depending on their texture index.
bool updatePerEdgeBuffers_
This flag controls if an update is really necessary.
std::string perFaceTextureCoordinatePropertyName_
Property for the per face texture coordinates.
ACG::Vec4f * perEdgeColorBuffer()
get a pointer to the per edge color buffer
ACG::Vec3f * perFaceVertexBuffer()
get a pointer to the per face vertex buffer
Kernel::FaceHalfedgeIter FaceHalfedgeIter
Circulator.
std::vector< unsigned int > indexArray
This array cotains the actual triangle strip used for rendering.
unsigned int stripify()
Compute triangle strips, returns number of strips.
class for managing a single triangle strip.
void setPerFaceTextureCoordinatePropertyName(std::string _perFaceTextureCoordinatePropertyName)
set the name of the property used for texture coordinate
ACG::Vec3f * perEdgeVertexBuffer()
get a pointer to the per edge vertex buffer
~StripProcessorT()
Destructor.
unsigned int nStrips() const
returns number of strips
bool stripsValid_
This flag shows if the strips have to be regenerated.
ACG::Vec3f * perFacePerVertexNormalBuffer()
get a pointer to the per face per vertex normal buffer
bool updatePerHalfedgeBuffers_
This flag controls if an update is really necessary.
void invalidatePerFaceBuffers()
Update of the buffers.
std::vector< ACG::Vec4uc > pickEdgeColorBuf_
std::vector< ACG::Vec3f > perFaceVertexBuffer_
Buffer holding vertices for per face rendering.
std::vector< ACG::Vec4f > perHalfedgeColorBuffer_
Per Edge color buffer.
void updatePerFaceBuffers()
Update all per face buffers.
Kernel::VertexHandle VertexHandle
Handle for referencing the corresponding item.