Developer Documentation

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
StripProcessorT.cc
1 /*===========================================================================*\
2 * *
3 * OpenMesh *
4 * Copyright (c) 2001-2015, RWTH-Aachen University *
5 * Department of Computer Graphics and Multimedia *
6 * All rights reserved. *
7 * www.openflipper.org *
8 * *
9 *---------------------------------------------------------------------------*
10 * This file is part of OpenFlipper. *
11 *---------------------------------------------------------------------------*
12 * *
13 * Redistribution and use in source and binary forms, with or without *
14 * modification, are permitted provided that the following conditions *
15 * are met: *
16 * *
17 * 1. Redistributions of source code must retain the above copyright notice, *
18 * this list of conditions and the following disclaimer. *
19 * *
20 * 2. Redistributions in binary form must reproduce the above copyright *
21 * notice, this list of conditions and the following disclaimer in the *
22 * documentation and/or other materials provided with the distribution. *
23 * *
24 * 3. Neither the name of the copyright holder nor the names of its *
25 * contributors may be used to endorse or promote products derived from *
26 * this software without specific prior written permission. *
27 * *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
31 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
33 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
34 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
35 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
36 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
37 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
38 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
39 * *
40 \*===========================================================================*/
41
42 /*===========================================================================*\
43 * *
44 * $Revision$ *
45 * $Date$ *
46 * *
47 \*===========================================================================*/
48
49 //=============================================================================
50 //
51 // CLASS StripProcessorT - IMPLEMENTATION
52 //
53 //=============================================================================
54
55 #define ACG_STRIP_PROCESSOR_C
56
57 //== INCLUDES =================================================================
58
59 #include <list>
60 #include <iostream>
61
62 #include <OpenMesh/Core/Utils/color_cast.hh>
63
64 //== NAMESPACES ===============================================================
65
66
67 namespace ACG {
68 namespace SceneGraph {
69
70 //== IMPLEMENTATION ==========================================================
71
72 template <class Mesh>
73 StripProcessorT<Mesh>::
74 StripProcessorT(Mesh& _mesh) :
75 mesh_(_mesh),
76 stripsValid_(false),
77 updatePerEdgeBuffers_(true),
78 updatePerHalfedgeBuffers_(true),
79 updatePerFaceBuffers_(true),
80 textureIndexPropertyName_("Not Set"),
81 perFaceTextureCoordinatePropertyName_("Not Set")
82 {
83 mesh_.request_face_normals();
84 }
85
86 template <class Mesh>
87 StripProcessorT<Mesh>::
88 ~StripProcessorT() {
89
90 }
91
92 /*template <class Mesh>
93 uint
94 StripProcessorT<Mesh>::getPolyDim() {
95
96 typename Mesh::FaceIter f_it, f_end = mesh_.faces_end();
97 typename Mesh::FaceVertexIter fv_it;
98 uint n = 0;
99
100 for(f_it = mesh_.faces_begin(); f_it != f_end; ++f_it) {
101 uint count = 0;
102 for ( fv_it = mesh_.fv_iter(f_it); fv_it; ++fv_it ) {
103 ++count;
104 }
105
106 if(count > n) n = count;
107 }
108
109 return n;
110 }
111
112 template <class Mesh>
113 uint
114 StripProcessorT<Mesh>::getFaceDimension(FaceHandle _fh) {
115 uint count = 0;
116 for ( typename Mesh::FaceVertexIter fv_it = mesh_.fv_iter(_fh); fv_it; ++fv_it )
117 ++count;
118 return count;
119 }*/
120
121 template <class Mesh>
122 void
123 StripProcessorT<Mesh>::convexityTest(FaceHandle /*_fh*/) {
124 }
125
126 template <class Mesh>
127 unsigned int
128 StripProcessorT<Mesh>::
129 stripify()
130 {
131 if ( stripsValid_)
132 return nStrips();
133
134 // preprocess: add new properties
135 mesh_.add_property( processed_ );
136 mesh_.add_property( used_ );
137 mesh_.request_face_status();
138
139 // build strips
140 clear();
141 buildStrips();
142
143 // postprocess: remove properties
144 mesh_.remove_property(processed_);
145 mesh_.remove_property(used_);
146 mesh_.release_face_status();
147
148 stripsValid_ = true;
149
150 return nStrips();
151 }
152
153
154 //-----------------------------------------------------------------------------
155
156 template <class Mesh>
157 void
158 StripProcessorT<Mesh>::
159 buildStrips()
160 {
161 // init faces to be un-processed and un-used
162 // deleted or hidden faces are marked processed
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;
167 else
168 processed(f_it) = used(f_it) = false;
169 } else {
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;
172 }
173
174 if ( mesh_.is_trimesh() ) {
175 buildStripsTriMesh();
176 } else {
177 buildStripsPolyMesh();
178 }
179
180 // In this case, we have to sort the array to have all strips with the same texture in one block (reduce texture switching)
181 if ( perFaceTextureIndexAvailable() ) {
182 std::sort(strips_.begin(),strips_.end(),&stripTextureCompare);
183 }
184
185 }
186
187 template <class Mesh>
188 void
189 StripProcessorT<Mesh>::
190 buildStripsPolyMesh() {
191
192 // Note: Limiting number of strips to be built to three, even for n-gons.
193
194 std::vector<Strip> experiments; // Three strips to be built. Take longest one after all.
195 std::vector< typename Mesh::HalfedgeHandle > h; // Three halfedges to start from.
196 std::vector< FaceHandles > faces; // Lists of faces.
197 typename FaceHandles::iterator fh_it, fh_end;
198 typename Mesh::FaceIter f_it, f_end=mesh_.faces_end();
199
200 for (f_it=mesh_.faces_begin(); true; ) {
201
202 // find start face
203 for (; f_it != f_end; ++f_it)
204 if (!processed(f_it)) break;
205
206 // stop if all have been processed
207 if (f_it == f_end)
208 break;
209
210 // Number of experiments equals number of edges of the face
211 experiments.clear();
212 experiments.resize( mesh_.valence(f_it) );
213 faces.clear();
214 faces.resize(mesh_.valence(f_it));
215
216 // Store all adjacent halfedges
217 h.clear();
218 for ( typename Mesh::FaceHalfedgeIter fhalfedge_it(mesh_,f_it); fhalfedge_it; ++fhalfedge_it )
219 h.push_back( fhalfedge_it.handle() );
220
221 // build all strips, take best one
222 unsigned int best_length = 0;
223 unsigned int best_idx = 0;
224 for (unsigned int i = 0; i < mesh_.valence(f_it) ; ++i)
225 {
226 buildStripPolyMesh(h[i], experiments[i], faces[i]);
227 const unsigned int length = experiments[i].indexArray.size();
228 if (length > best_length) {
229 best_length = length;
230 best_idx = i;
231 }
232
233 // unset the used flag for the following experiments
234 for (fh_it=faces[i].begin(), fh_end=faces[i].end(); fh_it!=fh_end; ++fh_it)
235 used(*fh_it) = false;
236 }
237
238 // update processed status
239 // The processed flag indicates that the whole face has been rendered
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;
244
245 // add best strip to strip-list
246 strips_.push_back(experiments[best_idx]);
247 }
248 }
249
250 template <class Mesh>
251 void
252 StripProcessorT<Mesh>::
253 buildStripsTriMesh()
254 {
255 Strip experiments[3];
256 typename Mesh::HalfedgeHandle h[3];
257
258 FaceHandles faces[3];
259 typename FaceHandles::iterator fh_it, fh_end;
260 typename Mesh::FaceIter f_it, f_end=mesh_.faces_end();
261
262 for (f_it=mesh_.faces_begin(); true; )
263 {
264 // find start face
265 for (; f_it!=f_end; ++f_it)
266 if (!processed(f_it))
267 break;
268 if (f_it==f_end) break; // stop if all have been processed
269
270
271 // collect starting halfedges
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]);
275
276 // build 3 strips, take best one
277 unsigned int best_length = 0;
278 unsigned int best_idx = 0;
279
280 for (unsigned int i=0; i<3; ++i)
281 {
282 buildStripTriMesh(h[i], experiments[i], faces[i]);
283
284 const unsigned int length = experiments[i].indexArray.size();
285 if ( length > best_length)
286 {
287 best_length = length;
288 best_idx = i;
289 }
290
291 for (fh_it=faces[i].begin(), fh_end=faces[i].end();
292 fh_it!=fh_end; ++fh_it)
293 used(*fh_it) = false;
294 }
295
296
297 // update processed status
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;
302
303 // add best strip to strip-list
304 strips_.push_back(experiments[best_idx]);
305 }
306 }
307
308 //-----------------------------------------------------------------------------
309
310
311 template <class Mesh>
312 void
313 StripProcessorT<Mesh>::
314 buildStripPolyMesh(typename Mesh::HalfedgeHandle _start_hh,
315 Strip& _strip,
316 FaceHandles& _faces) {
317
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; // Keep the hh of the halfedge where we started
322
323 // reset list
324 _faces.clear();
325
326 // Init strip
327 strip.push_back(mesh_.from_vertex_handle(_start_hh).idx());
328 strip.push_back(mesh_.to_vertex_handle(_start_hh).idx());
329
330 // Check if we have to take care of textures
331 // If this property is not available, we do not have texture info and will therefore
332 // skip texture handling in strip generation
333 OpenMesh::FPropHandleT< int > textureIndexProperty;
334 bool textureHandling = false;
335 if ( mesh_.get_property_handle(textureIndexProperty, textureIndexPropertyName_) ) {
336 textureHandling = true;
337 _strip.textureIndex = mesh_.property(textureIndexProperty,mesh_.face_handle(_start_hh));
338 }
339
341
342 // Walk along the strip: 1st direction
343 // We construct the strip by using alternating vertices
344 // of each side.
345 hh_left = hh_right = _start_hh;
346
347 while(true) {
348
349 // Go right
350 hh_right = mesh_.prev_halfedge_handle(hh_right);
351
352 // Add vertex to triangle strip
353 strip.push_back(mesh_.from_vertex_handle(hh_right).idx());
354 faceMap.push_back(mesh_.face_handle(hh_right));
355
356 // Test if we're at the very last halfedge of the polygon
357 if(mesh_.to_vertex_handle(mesh_.next_halfedge_handle(hh_left)) == mesh_.from_vertex_handle(hh_right)) {
358
359 // Mark face as processed and used
360 fh = mesh_.face_handle(hh_left);
361 _faces.push_back(fh);
362 used(fh) = true;
363
364 // Go over to next face via the exit halfedge
365 hh_left = hh_right = mesh_.opposite_halfedge_handle(mesh_.next_halfedge_handle(hh_left));
366
367 // Test if polygon is convex (only for testing purposes a.t.m.)
368 convexityTest(fh);
369
370 if(mesh_.is_boundary(hh_left)) break;
371 fh = mesh_.face_handle(hh_left);
372 if (processed(fh) || used(fh)) break;
373
374 // texture check
375 if ( textureHandling && ( _strip.textureIndex != mesh_.property(textureIndexProperty,fh ) ) ) break;
376
377 // continue;
378 }
379
380 // Go left
381 hh_left = mesh_.next_halfedge_handle(hh_left);
382
383 // Add vertex to triangle strip
384 strip.push_back(mesh_.to_vertex_handle(hh_left).idx());
385 faceMap.push_back(mesh_.face_handle(hh_left));
386
387 // Test if we're at the very last halfedge of the polygon
388 if(mesh_.to_vertex_handle(mesh_.next_halfedge_handle(hh_left)) == mesh_.from_vertex_handle(hh_right)) {
389 // Mark face as processed and used
390 fh = mesh_.face_handle(hh_left);
391 _faces.push_back(fh);
392 used(fh) = true;
393
394 // Go over to next face via the exit halfedge
395 hh_left = hh_right = mesh_.opposite_halfedge_handle(mesh_.next_halfedge_handle(hh_left));
396
397 // Test if polygon is convex (only for testing purposes a.t.m.)
398 convexityTest(fh);
399
400 if(mesh_.is_boundary(hh_left)) break;
401 fh = mesh_.face_handle(hh_left);
402 if (processed(fh) || used(fh)) break;
403
404 // texture check
405 if ( textureHandling && ( _strip.textureIndex != mesh_.property(textureIndexProperty,fh ) ) ) break;
406
407 }
408
409 }
410
411 // Be carefull with the map. As we run in the opposite direction now,
412 // we have to finish the map at the end of the strip
413
414 // Walk along the strip: 2nd direction
415 // We construct the strip by using alternating vertices
416 // of each side.
417 hh_left = hh_right = mesh_.opposite_halfedge_handle(_start_hh);
418
419 bool flip(false);
420 while(true) {
421 // Boundary check as the first might be at the boundary
422 if(mesh_.is_boundary(hh_left)) break;
423
424 // Go right
425 hh_right = mesh_.prev_halfedge_handle(hh_right);
426
427 // Add vertex to triangle strip
428 strip.push_front(mesh_.from_vertex_handle(hh_right).idx());
429 faceMap.push_front(mesh_.face_handle(hh_right));
430 flip = !flip;
431
432 // Test if we're at the very last halfedge of the polygon
433 if(mesh_.to_vertex_handle(mesh_.next_halfedge_handle(hh_left)) == mesh_.from_vertex_handle(hh_right)) {
434
435 // Mark face as processed and used
436 fh = mesh_.face_handle(hh_right);
437 _faces.push_back(fh);
438 used(fh) = true;
439
440 // Go over to next face via the exit halfedge
441 hh_left = hh_right = mesh_.opposite_halfedge_handle(mesh_.next_halfedge_handle(hh_left));
442
443 if(mesh_.is_boundary(hh_left)) break;
444 fh = mesh_.face_handle(hh_left);
445 if (processed(fh) || used(fh)) break;
446
447 // texture check
448 if ( textureHandling && ( _strip.textureIndex != mesh_.property(textureIndexProperty,fh ) ) ) break;
449
450 // Test if polygon is convex (only for testing purposes a.t.m.)
451 convexityTest(fh);
452
453 // continue;
454
455 }
456
457 // Go left
458 hh_left = mesh_.next_halfedge_handle(hh_left);
459
460 // Add vertex to triangle strip
461 strip.push_front( mesh_.to_vertex_handle(hh_left).idx() );
462 faceMap.push_front( mesh_.face_handle(hh_left) );
463 flip = !flip;
464
465 // Test if we're at the very last halfedge of the polygon
466 if(mesh_.to_vertex_handle(mesh_.next_halfedge_handle(hh_left)) == mesh_.from_vertex_handle(hh_right)) {
467
468 // Mark face as processed and used
469 fh = mesh_.face_handle(hh_right);
470 _faces.push_back(fh);
471 used(fh) = true;
472
473 // Go over to next face via the exit halfedge
474 hh_left = hh_right = mesh_.opposite_halfedge_handle(mesh_.next_halfedge_handle(hh_left));
475
476 if(mesh_.is_boundary(hh_left)) break;
477 fh = mesh_.face_handle(hh_left);
478 if (processed(fh) || used(fh)) break;
479
480 // texture check
481 if ( textureHandling && ( _strip.textureIndex != mesh_.property(textureIndexProperty,fh ) ) ) break;
482
483 // Test if polygon is convex (only for testing purposes a.t.m.)
484 convexityTest(fh);
485 }
486
487 }
488
489 if ( flip ) {
490 strip.push_front(strip.front());
491 faceMap.push_front(mesh_.face_handle(0));
492 }
493
494 // Finish the map ( As this is the start of the strip now, this data will be ignored!
495 faceMap.push_front(mesh_.face_handle(0));
496 faceMap.push_front(mesh_.face_handle(0));
497
498 // copy final strip to _strip
499 _strip.indexArray.clear();
500 _strip.indexArray.reserve(strip.size());
501 std::copy(strip.begin(), strip.end(), std::back_inserter(_strip.indexArray));
502
503 _strip.faceMap.clear();
504 _strip.faceMap.reserve(strip.size());
505 std::copy(faceMap.begin(), faceMap.end(), std::back_inserter(_strip.faceMap));
506 }
507
508
509 //-----------------------------------------------------------------------------
510
511
512 template <class Mesh>
513 void
514 StripProcessorT<Mesh>::
515 buildStripTriMesh(typename Mesh::HalfedgeHandle _start_hh,
516 Strip& _strip,
517 FaceHandles& _faces)
518 {
519 std::list<unsigned int> strip;
520 typename Mesh::HalfedgeHandle hh;
521 typename Mesh::FaceHandle fh;
522
523 std::list<typename Mesh::FaceHandle > faceMap;
524
525
526 // reset face list
527 _faces.clear();
528
529
530 // init strip
531 strip.push_back(mesh_.from_vertex_handle(_start_hh).idx());
532 strip.push_back(mesh_.to_vertex_handle(_start_hh).idx());
533
534 // Check if we have to take care of textures
535 // If this property is not available, we do not have texture info and will therefore
536 // skip texture handling in strip generation
537 bool textureHandling = false;
538 OpenMesh::FPropHandleT< int > textureIndexProperty;
539 if ( mesh_.get_property_handle(textureIndexProperty, textureIndexPropertyName_) ) {
540 textureHandling = true;
541 _strip.textureIndex = mesh_.property(textureIndexProperty,mesh_.face_handle(_start_hh));
542 } else {
543 // Set to no texture!
544 // This is not really necessary but cleans up for debugging
545 _strip.textureIndex = 0;
546 }
547
549
550 // walk along the strip: 1st direction
551 hh = mesh_.prev_halfedge_handle(mesh_.opposite_halfedge_handle(_start_hh));
552 while (1)
553 {
554 // go right
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;
561
562 // texture check
563 if ( textureHandling && ( _strip.textureIndex != mesh_.property(textureIndexProperty,fh ) ) ) break;
564
565 _faces.push_back(fh);
566 used(fh) = true;
567 strip.push_back(mesh_.to_vertex_handle(hh).idx());
568 faceMap.push_back(mesh_.face_handle(hh));
569
570 // go left
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;
576
577 // texture check
578 if ( textureHandling && ( _strip.textureIndex != mesh_.property(textureIndexProperty,fh ) ) ) break;
579
580 _faces.push_back(fh);
581 used(fh) = true;
582 strip.push_back(mesh_.to_vertex_handle(hh).idx());
583 faceMap.push_back(mesh_.face_handle(hh));
584 }
585
586
587 // walk along the strip: 2nd direction
588 bool flip(false);
589 hh = mesh_.prev_halfedge_handle(_start_hh);
590 while (1)
591 {
592 // go right
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;
599
600 // texture check
601 if ( textureHandling && ( _strip.textureIndex != mesh_.property(textureIndexProperty,fh ) ) ) break;
602
603 _faces.push_back(fh);
604 used(fh) = true;
605 strip.push_front(mesh_.to_vertex_handle(hh).idx());
606 faceMap.push_front(mesh_.face_handle(hh));
607 flip = true;
608
609 // go left
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;
615
616 // texture check
617 if ( textureHandling && ( _strip.textureIndex != mesh_.property(textureIndexProperty,fh ) ) ) break;
618
619 _faces.push_back(fh);
620 used(fh) = true;
621 strip.push_front(mesh_.to_vertex_handle(hh).idx());
622 faceMap.push_front(mesh_.face_handle(hh));
623 flip = false;
624 }
625
626 if (flip) {
627 strip.push_front(strip.front());
628 faceMap.push_front(mesh_.face_handle(0));
629 }
630
631 // Add two empty faces at the front. They will not be used to render anything as only the third one defines the
632 // face properties in the strip.
633 faceMap.push_front(mesh_.face_handle(0));
634 faceMap.push_front(mesh_.face_handle(0));
635
636 // copy final strip to _strip
637 _strip.indexArray.clear();
638 _strip.indexArray.reserve(strip.size());
639 std::copy(strip.begin(), strip.end(), std::back_inserter(_strip.indexArray));
640
641 _strip.faceMap.clear();
642 _strip.faceMap.reserve(strip.size());
643 std::copy(faceMap.begin(), faceMap.end(), std::back_inserter(_strip.faceMap));
644 }
645
646 template <class Mesh>
647 void
648 StripProcessorT<Mesh>::
649 updatePickingVertices(ACG::GLState& _state, uint _offset) {
650
651 unsigned int idx = 0;
652
653 // Adjust size of the color buffer to the number of vertices in the mesh
654 pickVertexColorBuf_.resize( mesh_.n_vertices() );
655
656 // Get the right picking colors from the gl state and add them per vertex to the color buffer
657 typename Mesh::ConstVertexIter v_it(mesh_.vertices_begin()), v_end(mesh_.vertices_end());
658 for (; v_it!=v_end; ++v_it, ++idx)
659 pickVertexColorBuf_[idx] = _state.pick_get_name_color(idx + _offset);
660 }
661
662 template <class Mesh>
663 void
664 StripProcessorT<Mesh>::
665 updatePickingEdges(ACG::GLState& _state, uint _offset ) {
666
667 updatePerEdgeBuffers();
668
669 pickEdgeColorBuf_.resize(mesh_.n_edges() * 2);
670
671
672 int idx = 0;
673
674 typename Mesh::ConstEdgeIter e_it(mesh_.edges_sbegin()), e_end(mesh_.edges_end());
675 for (; e_it!=e_end; ++e_it) {
676
677 const Vec4uc pickColor = _state.pick_get_name_color (e_it->idx() + _offset);
678
679 pickEdgeColorBuf_[idx] = pickColor;
680 pickEdgeColorBuf_[idx+1] = pickColor;
681
682 idx += 2;
683 }
684 }
685
686 template <class Mesh>
687 void
688 StripProcessorT<Mesh>::
689 updatePickingFaces(ACG::GLState& _state ) {
690
691 // Make sure, the face buffers are up to date before generating the picking data!
692 updatePerFaceBuffers();
693
694 // Get total number of triangles
695 // Each strip has two vertices more than triangles
696 unsigned int n_faces = 0;
697 for(StripsIterator it = strips_.begin(); it != strips_.end(); ++it)
698 n_faces += (*it).indexArray.size() - 2;
699
700 // 3 vertices per face.
701 pickFaceColorBuf_.resize(n_faces * 3);
702
703 // Index to the current buffer position
704 unsigned int bufferIndex = 0;
705
706 // Process all strips
707 for ( unsigned int i = 0 ; i < strips_.size() ; ++i ) {
708
709 // The order of the vertices in the strip is alternating but as the last vertex still defines
710 // points to the associated face, we dont need to swap here!
711
712 // process all faces in the strip
713 // The strip contains 2 faces less then number of vertices in the strip.
714 // As we need seperate faces during rendering, the strips are splitted into triangles
715 // The last vertex of each triangle defines the picking color for the last face.
716 // The handles and indices are collected during the strip generation.
717 for (unsigned int stripIndex = 2 ; stripIndex < strips_[ i ].indexArray.size() ; ++stripIndex) {
718
719 // We have to provide a vertex color for each of the vertices as we need flat shading!
720 const Vec4uc pickColor = _state.pick_get_name_color ( strips_[ i ].faceMap[ stripIndex ].idx() );
721 pickFaceColorBuf_[ bufferIndex + 0 ] = pickColor;
722 pickFaceColorBuf_[ bufferIndex + 1 ] = pickColor;
723 pickFaceColorBuf_[ bufferIndex + 2 ] = pickColor;
724
725 bufferIndex += 3;
726 }
727 }
728
729 }
730
731 template <class Mesh>
732 void
733 StripProcessorT<Mesh>::
734 updatePickingAny(ACG::GLState& _state ) {
735 // Update strip information if necessary
736 stripify();
737
738 updatePickingFaces(_state);
739 updatePickingEdges(_state,mesh_.n_faces());
740 updatePickingVertices(_state,mesh_.n_faces() + mesh_.n_edges());
741 }
742
743 template <class Mesh>
744 void
745 StripProcessorT<Mesh>::
746 updatePerEdgeBuffers() {
747 // Only update buffers if they are invalid
748 if (!updatePerEdgeBuffers_)
749 return;
750
751 perEdgeVertexBuffer_.resize(mesh_.n_edges() * 2);
752
753 if ( mesh_.has_edge_colors() ) {
754 perEdgeColorBuffer_.resize(mesh_.n_edges() * 2);
755 } else
756 perEdgeColorBuffer_.clear();
757
758 unsigned int idx = 0;
759
760 typename Mesh::ConstEdgeIter e_it(mesh_.edges_sbegin()), e_end(mesh_.edges_end());
761 for (; e_it!=e_end; ++e_it) {
762
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)));
765
766 if ( mesh_.has_edge_colors() ) {
767 const Vec4f color = OpenMesh::color_cast<Vec4f>( mesh_.color(e_it) ) ;
768 perEdgeColorBuffer_[ idx ] = color;
769 perEdgeColorBuffer_[ idx + 1 ] = color;
770 }
771
772 idx += 2;
773 }
774
775 updatePerEdgeBuffers_ = false;
776
777 }
778
779 template <class Mesh>
780 ACG::Vec3f *
781 StripProcessorT<Mesh>::
782 perEdgeVertexBuffer() {
783 // Force update of the buffers if required
784 if (updatePerEdgeBuffers_)
785 updatePerEdgeBuffers();
786 return &(perEdgeVertexBuffer_)[0];
787 }
788
789 template <class Mesh>
790 ACG::Vec4f *
791 StripProcessorT<Mesh>::
792 perEdgeColorBuffer() {
793 // Force update of the buffers if required
794 if (updatePerEdgeBuffers_)
795 updatePerEdgeBuffers();
796 return &(perEdgeColorBuffer_)[0];
797 }
798
799
800 template <class Mesh>
801 void
802 StripProcessorT<Mesh>::
803 updatePerHalfedgeBuffers() {
804 // Only update buffers if they are invalid
805 if (!updatePerHalfedgeBuffers_)
806 return;
807
808 perHalfedgeVertexBuffer_.resize(mesh_.n_halfedges() * 2);
809
810 if ( mesh_.has_halfedge_colors() ) {
811 perHalfedgeColorBuffer_.resize(mesh_.n_halfedges() * 2);
812 } else
813 perHalfedgeColorBuffer_.clear();
814
815 unsigned int idx = 0;
816
817 typename Mesh::ConstHalfedgeIter he_it(mesh_.halfedges_sbegin()), he_end(mesh_.halfedges_end());
818 for (; he_it!=he_end; ++he_it) {
819
820 perHalfedgeVertexBuffer_[idx] = halfedge_point(he_it);
821 perHalfedgeVertexBuffer_[idx+1] = halfedge_point(mesh_.prev_halfedge_handle(he_it));
822
823 if ( mesh_.has_halfedge_colors() ) {
824 const Vec4f color = OpenMesh::color_cast<Vec4f>( mesh_.color(he_it) ) ;
825 perHalfedgeColorBuffer_[ idx ] = color;
826 perHalfedgeColorBuffer_[ idx + 1 ] = color;
827 }
828
829 idx += 2;
830 }
831
832 updatePerHalfedgeBuffers_ = false;
833
834 }
835
836 template <class Mesh>
837 typename Mesh::Point
838 StripProcessorT<Mesh>::
839 halfedge_point(const typename Mesh::HalfedgeHandle _heh) {
840
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)));
844
845 // typename Mesh::Point n = (p-pp)%(pn-p);
846 typename Mesh::Point fn;
847 if( !mesh_.is_boundary(_heh))
848 fn = mesh_.normal(mesh_.face_handle(_heh));
849 else
850 fn = mesh_.normal(mesh_.face_handle(mesh_.opposite_halfedge_handle(_heh)));
851
852 typename Mesh::Point upd = ((fn%(pn-p)).normalize() + (fn%(p-pp)).normalize()).normalize();
853
854 upd *= ((pn-p).norm()+(p-pp).norm())*0.08;
855
856 return (p+upd);
857
858 // double alpha = 0.1;
859 // // correct weighting for concave triangles (or at concave boundaries)
860 // if( (fn | n) < 0.0) alpha *=-1.0;
861
862 // return (p*(1.0-2.0*alpha) + pp*alpha + pn*alpha);
863 }
864
865 template <class Mesh>
866 ACG::Vec3f *
867 StripProcessorT<Mesh>::
868 perHalfedgeVertexBuffer() {
869 // Force update of the buffers if required
870 if (updatePerHalfedgeBuffers_)
871 updatePerHalfedgeBuffers();
872 return &(perHalfedgeVertexBuffer_)[0];
873 }
874
875 template <class Mesh>
876 ACG::Vec4f *
877 StripProcessorT<Mesh>::
878 perHalfedgeColorBuffer() {
879 // Force update of the buffers if required
880 if (updatePerHalfedgeBuffers_)
881 updatePerHalfedgeBuffers();
882 return &(perHalfedgeColorBuffer_)[0];
883 }
884
885 template <class Mesh>
886 void
887 StripProcessorT<Mesh>::
888 updatePerFaceBuffers() {
889
890 stripify();
891
892 // Only update buffers if they are invalid
893 if (!updatePerFaceBuffers_)
894 return;
895
896
897 // Get and Recheck property
898 OpenMesh::HPropHandleT< typename Mesh::TexCoord2D > perFaceTextureCoordinateProperty;
899 const bool usePerFaceTextureCoordinateProperty = mesh_.get_property_handle(perFaceTextureCoordinateProperty,perFaceTextureCoordinatePropertyName_);
900
901 const bool usePerFaceTextureIndex = perFaceTextureIndexAvailable();
902
903 unsigned int n_faces = 0;
904
905 // For the polyMeshes we have to count the faces in all strips
906 // Each strip has two vertices more than triangles
907 for(StripsIterator it = strips_.begin(); it != strips_.end(); ++it)
908 n_faces += (*it).indexArray.size() - 2;
909
910 // 3 vertices per face.
911 perFaceVertexBuffer_.resize(n_faces * 3);
912
913 // Index to the current buffer position
914 unsigned int bufferIndex = 0;
915
916 if ( mesh_.has_face_normals() )
917 perFaceNormalBuffer_.resize(n_faces * 3);
918 else
919 perFaceNormalBuffer_.clear();
920
921 if ( mesh_.has_vertex_normals() )
922 perFacePerVertexNormalBuffer_.resize(n_faces * 3);
923 else
924 perFacePerVertexNormalBuffer_.clear();
925
926 if ( mesh_.has_face_colors() )
927 perFaceColorBuffer_.resize(n_faces * 3);
928 else
929 perFaceColorBuffer_.clear();
930
931 if ( usePerFaceTextureCoordinateProperty )
932 perFaceTextureCoordArray_.resize(n_faces * 3);
933 else
934 perFaceTextureCoordArray_.clear();
935
936 textureRenderData_.clear();
937
938 if ( usePerFaceTextureIndex )
939 textureRenderData_.reserve( strips_.size() );
940
941 // Process all strips
942 for ( unsigned int i = 0 ; i < strips_.size() ; ++i ) {
943
944 // Record strip information
945 // Or store a simple strip info with texture 0
946 if ( usePerFaceTextureIndex ) {
947 textureRenderData_.push_back( TextureRenderInfo(strips_[i].textureIndex , strips_[ i ].indexArray.size() -2 ,bufferIndex) );
948 }
949
950 // The order of the vertices in the strip is alternating so we have to alter the directions as well
951 // or we get backfacing triangles although they are frontfacing
952 bool swap = true;
953
954 // process all faces in the strip
955 // The strip contains 2 faces less then number of vertices in the strip.
956 // As we need seperate faces during rendering, the strips are splitted into triangles
957 // The last vertex of each triangle defines the color and the normal for the last face.
958 // Handles and indices are collected during the strip generation.
959 for (unsigned int stripIndex = 2 ; stripIndex < strips_[ i ].indexArray.size() ; ++stripIndex) {
960
961 if ( mesh_.has_face_normals() ) {
962 const Vec3d normal = mesh_.normal( strips_[ i ].faceMap[ stripIndex ] );
963 perFaceNormalBuffer_[ bufferIndex + 0 ] = normal;
964 perFaceNormalBuffer_[ bufferIndex + 1 ] = normal;
965 perFaceNormalBuffer_[ bufferIndex + 2 ] = normal;
966 }
967
968 if ( mesh_.has_face_colors() ) {
969 const Vec4f color = OpenMesh::color_cast<Vec4f>( mesh_.color( strips_[ i ].faceMap[ stripIndex ] ) );
970 perFaceColorBuffer_[ bufferIndex + 0 ] = color;
971 perFaceColorBuffer_[ bufferIndex + 1 ] = color;
972 perFaceColorBuffer_[ bufferIndex + 2 ] = color;
973 }
974
975 if ( swap ) {
976 // Cant render triangle strips as we need one color per face and this means duplicating vertices
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 ] ));
980
981 // Get the normals of all vertices at this face
982 if ( mesh_.has_vertex_normals() ) {
983 perFacePerVertexNormalBuffer_[ bufferIndex + 0 ] = mesh_.normal(mesh_.vertex_handle( strips_[ i ].indexArray[ stripIndex - 2 ] ));
984 perFacePerVertexNormalBuffer_[ bufferIndex + 1 ] = mesh_.normal(mesh_.vertex_handle( strips_[ i ].indexArray[ stripIndex - 1 ] ));
985 perFacePerVertexNormalBuffer_[ bufferIndex + 2 ] = mesh_.normal(mesh_.vertex_handle( strips_[ i ].indexArray[ stripIndex - 0 ] ));
986 }
987
988
989 if ( usePerFaceTextureCoordinateProperty ) {
990 typename Mesh::ConstFaceHalfedgeIter fhe_it(mesh_.cfh_iter(strips_[ i ].faceMap[ stripIndex ]));
991
992 for ( ; fhe_it ; ++fhe_it ) {
993 typename Mesh::VertexHandle cvh = mesh_.to_vertex_handle(fhe_it);
994 Vec2f texcoord = mesh_.property(perFaceTextureCoordinateProperty,fhe_it);
995
996 if ( mesh_.vertex_handle( strips_[ i ].indexArray[ stripIndex - 2 ] ) == cvh ) {
997 perFaceTextureCoordArray_[ bufferIndex + 0 ] = texcoord;
998 continue;
999 } else if ( mesh_.vertex_handle( strips_[ i ].indexArray[ stripIndex - 1 ] ) == cvh ) {
1000 perFaceTextureCoordArray_[ bufferIndex + 1 ] = texcoord;
1001 continue;
1002 } else if ( mesh_.vertex_handle( strips_[ i ].indexArray[ stripIndex - 0 ] ) == cvh ) {
1003 perFaceTextureCoordArray_[ bufferIndex + 2 ] = texcoord;
1004 continue;
1005 }
1006 }
1007
1008 }
1009
1010 swap = false;
1011 } else {
1012 // Cant render triangle strips as we need one color per face and this means duplicating vertices
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 ] ));
1016
1017 // Get the normals of all vertices at this face
1018 if ( mesh_.has_vertex_normals() ) {
1019 perFacePerVertexNormalBuffer_[ bufferIndex + 2 ] = mesh_.normal(mesh_.vertex_handle( strips_[ i ].indexArray[ stripIndex - 2 ] ));
1020 perFacePerVertexNormalBuffer_[ bufferIndex + 1 ] = mesh_.normal(mesh_.vertex_handle( strips_[ i ].indexArray[ stripIndex - 1 ] ));
1021 perFacePerVertexNormalBuffer_[ bufferIndex + 0 ] = mesh_.normal(mesh_.vertex_handle( strips_[ i ].indexArray[ stripIndex - 0 ] ));
1022 }
1023
1024 if ( usePerFaceTextureCoordinateProperty ) {
1025 typename Mesh::ConstFaceHalfedgeIter fhe_it(mesh_.cfh_iter(strips_[ i ].faceMap[ stripIndex ]));
1026
1027 for ( ; fhe_it ; ++fhe_it ) {
1028 typename Mesh::VertexHandle cvh = mesh_.to_vertex_handle(fhe_it);
1029 const Vec2f texcoord = mesh_.property(perFaceTextureCoordinateProperty,fhe_it);
1030
1031 if ( mesh_.vertex_handle( strips_[ i ].indexArray[ stripIndex - 2 ] ) == cvh ) {
1032 perFaceTextureCoordArray_[ bufferIndex + 2 ] = texcoord;
1033 continue;
1034 } else if ( mesh_.vertex_handle( strips_[ i ].indexArray[ stripIndex - 1 ] ) == cvh ) {
1035 perFaceTextureCoordArray_[ bufferIndex + 1 ] = texcoord;
1036 continue;
1037 } else if ( mesh_.vertex_handle( strips_[ i ].indexArray[ stripIndex - 0 ] ) == cvh ) {
1038 perFaceTextureCoordArray_[ bufferIndex + 0 ] = texcoord;
1039 continue;
1040 }
1041 }
1042
1043 }
1044
1045 swap = true;
1046 }
1047
1048 bufferIndex += 3;
1049 }
1050 }
1051
1052 updatePerFaceBuffers_ = false;
1053 }
1054
1055
1056 template <class Mesh>
1057 ACG::Vec3f *
1058 StripProcessorT<Mesh>::
1059 perFaceVertexBuffer() {
1060
1061 // Force update of the buffers if required
1062 if (updatePerFaceBuffers_)
1063 updatePerFaceBuffers();
1064
1065 return &(perFaceVertexBuffer_)[0];
1066 }
1067
1068 template <class Mesh>
1069 ACG::Vec3f *
1070 StripProcessorT<Mesh>::
1071 perFaceNormalBuffer() {
1072 // Force update of the buffers if required
1073 if (updatePerFaceBuffers_)
1074 updatePerFaceBuffers();
1075
1076 return &(perFaceNormalBuffer_)[0];
1077 }
1078
1079 template <class Mesh>
1080 ACG::Vec3f *
1081 StripProcessorT<Mesh>::
1082 perFacePerVertexNormalBuffer() {
1083 // Force update of the buffers if required
1084 if (updatePerFaceBuffers_)
1085 updatePerFaceBuffers();
1086
1087 return &(perFacePerVertexNormalBuffer_)[0];
1088 }
1089
1090 template <class Mesh>
1091 ACG::Vec4f *
1092 StripProcessorT<Mesh>::
1093 perFaceColorBuffer() {
1094 // Force update of the buffers if required
1095 if (updatePerFaceBuffers_)
1096 updatePerFaceBuffers();
1097
1098 return &(perFaceColorBuffer_)[0];
1099 }
1100
1101 template <class Mesh>
1102 void
1103 StripProcessorT<Mesh>::
1104 setPerFaceTextureCoordinatePropertyName( std::string _perFaceTextureCoordinatePropertyName ) {
1105
1106 // Check if the given property exists
1107 OpenMesh::HPropHandleT< typename Mesh::TexCoord2D > perFaceTextureCoordinateProperty;
1108 if ( !mesh_.get_property_handle(perFaceTextureCoordinateProperty,_perFaceTextureCoordinatePropertyName) ) {
1109 std::cerr << "StripProcessor: Unable to get per face texture coordinate property named " << _perFaceTextureCoordinatePropertyName << std::endl;
1110 return;
1111 }
1112
1113 // Remember the property name
1114 perFaceTextureCoordinatePropertyName_ = _perFaceTextureCoordinatePropertyName;
1115
1116 // mark the buffers as invalid as we have a new per face index array
1117 invalidatePerFaceBuffers();
1118 }
1119
1120 template <class Mesh>
1121 bool
1122 StripProcessorT<Mesh>::perFaceTextureCoordinateAvailable() {
1123
1124 // We really have to recheck, as the property might get lost externally (e.g. on restores of the mesh)
1125 OpenMesh::HPropHandleT< typename Mesh::TexCoord2D > perFaceTextureCoordinateProperty;
1126 if ( !mesh_.get_property_handle(perFaceTextureCoordinateProperty, perFaceTextureCoordinatePropertyName_) ) {
1127 return false;
1128 }
1129
1130 // Property available
1131 return true;
1132
1133 }
1134
1135 template <class Mesh>
1136 bool
1137 StripProcessorT<Mesh>::perFaceTextureIndexAvailable() {
1138
1139 // We really have to recheck, as the property might get lost externally (e.g. on restores of the mesh)
1140 OpenMesh::FPropHandleT< int > textureIndexProperty;
1141 if ( !mesh_.get_property_handle(textureIndexProperty, textureIndexPropertyName_) ) {
1142 return false;
1143 }
1144
1145 // Property available
1146 return true;
1147 }
1148
1149 template <class Mesh>
1150 void
1151 StripProcessorT<Mesh>::
1152 setIndexPropertyName( std::string _indexPropertyName ) {
1153
1154 // Check if the given property exists
1155 OpenMesh::FPropHandleT< int > textureIndexProperty;
1156 if ( !mesh_.get_property_handle(textureIndexProperty,_indexPropertyName) ) {
1157 std::cerr << "StripProcessor: Unable to get per face texture Index property named " << _indexPropertyName << std::endl;
1158 return;
1159 }
1160
1161 // Remember the property name
1162 textureIndexPropertyName_ = _indexPropertyName;
1163
1164 // mark strips as invalid ( have to be regenerated to collect texture index information)
1165 stripsValid_ = false;
1166
1167 // mark the buffers as invalid as we have a new per face index array
1168 invalidatePerFaceBuffers();
1169 }
1170
1171 //=============================================================================
1172 } // namespace SceneGraph
1173 } // namespace ACG
1174 //=============================================================================
ACG::SceneGraph::Strip
class for managing a single triangle strip.
Definition: StripProcessorT.hh:84
ACG::SceneGraph::StripProcessorT::perFaceVertexBuffer
ACG::Vec3f * perFaceVertexBuffer()
get a pointer to the per face vertex buffer
Definition: StripProcessorT.cc:1059
ACG::SceneGraph::StripProcessorT::perHalfedgeColorBuffer
ACG::Vec4f * perHalfedgeColorBuffer()
get a pointer to the per edge color buffer
Definition: StripProcessorT.cc:878
ACG::SceneGraph::TextureRenderInfo
Definition: StripProcessorT.hh:104
ACG::SceneGraph::StripProcessorT::~StripProcessorT
~StripProcessorT()
Destructor.
Definition: StripProcessorT.cc:88
ACG
Namespace providing different geometric functions concerning angles.
Definition: DBSCANT.cc:51
ACG::SceneGraph::StripProcessorT::updatePickingVertices
void updatePickingVertices(ACG::GLState &_state, uint _offset=0)
Definition: StripProcessorT.cc:649
ACG::SceneGraph::StripProcessorT::perHalfedgeVertexBuffer
ACG::Vec3f * perHalfedgeVertexBuffer()
get a pointer to the per edge vertex buffer
Definition: StripProcessorT.cc:868
ACG::SceneGraph::StripProcessorT::setPerFaceTextureCoordinatePropertyName
void setPerFaceTextureCoordinatePropertyName(std::string _perFaceTextureCoordinatePropertyName)
set the name of the property used for texture coordinate
Definition: StripProcessorT.cc:1104
OpenMesh::TriMeshT::is_trimesh
static bool is_trimesh()
Determine whether this is a PolyMeshT or TriMeshT ( This function does not check the per face vertex ...
Definition: TriMeshT.hh:110
ACG::SceneGraph::ACG::GLState
Definition: MeshNode2T.cc:220
ACG::SceneGraph::StripProcessorT::FaceHandles
std::vector< typename Mesh::FaceHandle > FaceHandles
This flag shows if the strips have to be regenerated.
Definition: StripProcessorT.hh:189
ACG::SceneGraph::StripProcessorT::buildStripTriMesh
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
Definition: StripProcessorT.cc:515
ACG::SceneGraph::StripProcessorT::updatePerFaceBuffers
void updatePerFaceBuffers()
Update all per face buffers.
Definition: StripProcessorT.cc:888
ACG::SceneGraph::StripProcessorT::perEdgeColorBuffer
ACG::Vec4f * perEdgeColorBuffer()
get a pointer to the per edge color buffer
Definition: StripProcessorT.cc:792
ACG::SceneGraph::Strip::indexArray
std::vector< unsigned int > indexArray
This array cotains the actual triangle strip used for rendering.
Definition: StripProcessorT.hh:92
OpenMesh::PolyMeshT::Point
Kernel::Point Point
Coordinate type.
Definition: PolyMeshT.hh:115
ACG::SceneGraph::Strip::textureIndex
int textureIndex
This contains the texture index used for rendering this strip.
Definition: StripProcessorT.hh:98
ACG::SceneGraph::StripProcessorT::perFaceColorBuffer
ACG::Vec4f * perFaceColorBuffer()
get a pointer to the per face color buffer
Definition: StripProcessorT.cc:1093
ACG::SceneGraph::StripProcessorT::updatePickingFaces
void updatePickingFaces(ACG::GLState &_state)
Call this function to update the color picking array.
Definition: StripProcessorT.cc:689
OpenMesh::TriMesh_ArrayKernelT< CustomTraits >
ACG::SceneGraph::StripProcessorT::stripify
unsigned int stripify()
Compute triangle strips, returns number of strips.
Definition: StripProcessorT.cc:129
ACG::SceneGraph::OpenMesh::FPropHandleT
Definition: MeshNode2T.cc:529
OpenMesh::PolyMeshT::ConstFaceHalfedgeIter
Kernel::ConstFaceHalfedgeIter ConstFaceHalfedgeIter
Circulator.
Definition: PolyMeshT.hh:181
OpenMesh::VectorT
Definition: Vector11T.hh:83
ACG::SceneGraph::stripTextureCompare
bool stripTextureCompare(const Strip &i, const Strip &j)
Compare function for sorting Strips depending on their texture index.
Definition: StripProcessor.cc:68
ACG::SceneGraph::StripProcessorT::perFaceTextureIndexAvailable
bool perFaceTextureIndexAvailable()
Check if textureindicies are available.
Definition: StripProcessorT.cc:1137
ACG::SceneGraph::StripProcessorT::updatePickingEdges
void updatePickingEdges(ACG::GLState &_state, uint _offset=0)
Definition: StripProcessorT.cc:665
OpenMesh::PolyMeshT::VertexHandle
Kernel::VertexHandle VertexHandle
Handle for referencing the corresponding item.
Definition: PolyMeshT.hh:139
ACG::SceneGraph::OpenMesh::HPropHandleT
Definition: MeshNode2T.cc:501
ACG::SceneGraph::StripProcessorT::perEdgeVertexBuffer
ACG::Vec3f * perEdgeVertexBuffer()
get a pointer to the per edge vertex buffer
Definition: StripProcessorT.cc:782
ACG::SceneGraph::ACG::GLState::pick_get_name_color
Vec4uc pick_get_name_color(unsigned int _idx)
ACG::SceneGraph::StripProcessorT::updatePickingAny
void updatePickingAny(ACG::GLState &_state)
Call this function to update the color picking array.
Definition: StripProcessorT.cc:734
ACG::SceneGraph::StripProcessorT::buildStripPolyMesh
void buildStripPolyMesh(typename Mesh::HalfedgeHandle _start_hh, Strip &_strip, FaceHandles &_faces)
build a strip from a given halfedge (in both directions) of a polymesh
Definition: StripProcessorT.cc:314
ACG::SceneGraph::StripProcessorT::updatePerHalfedgeBuffers
void updatePerHalfedgeBuffers()
Update all per edge drawing buffer n The updated buffers are: per edge vertex buffer ( 2 vertices per...
Definition: StripProcessorT.cc:803
ACG::SceneGraph::Strip::faceMap
std::vector< OpenMesh::FaceHandle > faceMap
This map contains for each vertex in the strips a handle to the face it closes.
Definition: StripProcessorT.hh:95
ACG::SceneGraph::StripProcessorT::buildStripsTriMesh
void buildStripsTriMesh()
This method generates strips for triangle meshes.
Definition: StripProcessorT.cc:253
ACG::SceneGraph::StripProcessorT::perFaceNormalBuffer
ACG::Vec3f * perFaceNormalBuffer()
get a pointer to the per face normal buffer
Definition: StripProcessorT.cc:1071
OpenMesh::PolyMeshT::FaceHalfedgeIter
Kernel::FaceHalfedgeIter FaceHalfedgeIter
Circulator.
Definition: PolyMeshT.hh:171
ACG::SceneGraph::StripProcessorT::setIndexPropertyName
void setIndexPropertyName(std::string _indexPropertyName)
set the name of the property used for texture index specification
Definition: StripProcessorT.cc:1152
ACG::SceneGraph::StripProcessorT::StripProcessorT
StripProcessorT(Mesh &_mesh)
Default constructor.
Definition: StripProcessorT.cc:74
ACG::SceneGraph::StripProcessorT::perFaceTextureCoordinateAvailable
bool perFaceTextureCoordinateAvailable()
Check if per Face Texture coordinates are available.
Definition: StripProcessorT.cc:1122
ACG::SceneGraph::StripProcessorT::updatePerEdgeBuffers
void updatePerEdgeBuffers()
Update all per edge drawing buffer n The updated buffers are: per edge vertex buffer ( 2 vertices per...
Definition: StripProcessorT.cc:746
ACG::SceneGraph::StripProcessorT::buildStrips
void buildStrips()
this method does the main work
Definition: StripProcessorT.cc:159
ACG::SceneGraph::StripProcessorT::perFacePerVertexNormalBuffer
ACG::Vec3f * perFacePerVertexNormalBuffer()
get a pointer to the per face per vertex normal buffer
Definition: StripProcessorT.cc:1082
ACG::SceneGraph::StripProcessorT::convexityTest
void convexityTest(FaceHandle _fh)
Test whether face is convex.
Definition: StripProcessorT.cc:123
ACG::SceneGraph::StripProcessorT::halfedge_point
Mesh::Point halfedge_point(const typename Mesh::HalfedgeHandle _heh)
compute halfedge point compute visulization point for halfedge (shifted to interior of face) ...
Definition: StripProcessorT.cc:839
ACG::SceneGraph::StripProcessorT::buildStripsPolyMesh
void buildStripsPolyMesh()
Definition: StripProcessorT.cc:190