Developer Documentation
Loading...
Searching...
No Matches
MeshNodeDeprecatedT_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
44
45
46
47//=============================================================================
48//
49// CLASS MeshNodeDeprecatedT - IMPLEMENTATION
50//
51//=============================================================================
52
53#ifndef DOXY_IGNORE_THIS
54#define ACG_MESHNODE_C
55
56//== INCLUDES =================================================================
57
58
59#include "MeshNodeDeprecatedT.hh"
60#include "ShaderNode.hh"
61#include "DrawModes.hh"
62#include <ACG/GL/gl.hh>
63#include <ACG/GL/GLError.hh>
64#include <ACG/GL/ColorTranslator.hh>
65
67#include <OpenMesh/Core/Utils/Property.hh>
68
69#include <algorithm>
70
71//== NAMESPACES ==============================================================
72
73
74namespace ACG {
75namespace SceneGraph {
76
77
78//== IMPLEMENTATION ==========================================================
79
80
81template<class Mesh>
82MeshNodeDeprecatedT<Mesh>::
83MeshNodeDeprecatedT(const Mesh& _mesh,
84 BaseNode* _parent,
85 std::string _name)
86 : BaseNode(_parent, _name),
87 mesh_(_mesh),
88 enabled_arrays_(0),
89 face_index_buffer_(0),
90 vertex_buffer_(0),
91 normal_buffer_(0),
92 vertexBufferInitialized_(false),
93 normalBufferInitialized_(false),
94 faceIndexBufferInitialized_(false),
95 textureMap_(0),
96 propertyMap_(0),
97 default_halfedge_textcoord_property_("h:texcoords2D"),
98 indexPropertyName_("f:textureindex"),
99 updateFaceList_(true),
100 updateVertexList_(true),
101 updateEdgeList_(true),
102 updateAnyList_(true),
103 faceBaseIndex_(0),
104 vertexBaseIndex_(0),
105 edgeBaseIndex_(0),
106 anyBaseIndex_(0),
107 bbMin_(FLT_MAX, FLT_MAX, FLT_MAX),
108 bbMax_(-FLT_MAX, -FLT_MAX, -FLT_MAX)
109{
110 faceList_ = glGenLists (1);
111 vertexList_ = glGenLists (1);
112 edgeList_ = glGenLists (1);
113 anyList_ = glGenLists (3);
114}
115
116
117//----------------------------------------------------------------------------
118
119
120template<class Mesh>
121MeshNodeDeprecatedT<Mesh>::
122~MeshNodeDeprecatedT()
123{
124 if (vertex_buffer_)
125 glDeleteBuffers(1, (GLuint*) &vertex_buffer_);
126
127 if (normal_buffer_)
128 glDeleteBuffers(1, (GLuint*) &normal_buffer_);
129
130 if (face_index_buffer_)
131 glDeleteBuffers(1, (GLuint*) &face_index_buffer_ );
132
133 if (faceList_)
134 glDeleteLists (faceList_, 1);
135
136 if (vertexList_)
137 glDeleteLists (vertexList_, 1);
138
139 if (edgeList_)
140 glDeleteLists (edgeList_, 1);
141
142 if (anyList_)
143 glDeleteLists (anyList_, 3);
144}
145
146
147//----------------------------------------------------------------------------
148
149
150template<class Mesh>
151void
152MeshNodeDeprecatedT<Mesh>::
153boundingBox(Vec3d& _bbMin, Vec3d& _bbMax)
154{
155 _bbMin.minimize(bbMin_);
156 _bbMax.maximize(bbMax_);
157}
158
159
160//----------------------------------------------------------------------------
161
162
163template<class Mesh>
164DrawModes::DrawMode
165MeshNodeDeprecatedT<Mesh>::
166availableDrawModes() const
167{
168 DrawModes::DrawMode drawModes(DrawModes::NONE);
169
170 drawModes |= DrawModes::POINTS;
171 drawModes |= DrawModes::WIREFRAME;
172 drawModes |= DrawModes::HIDDENLINE;
173 drawModes |= DrawModes::SOLID_SHADER;
174
175 if (mesh_.has_vertex_normals())
176 {
177 drawModes |= DrawModes::POINTS_SHADED;
178 drawModes |= DrawModes::SOLID_SMOOTH_SHADED;
179 drawModes |= DrawModes::SOLID_PHONG_SHADED;
180 }
181
182 if (mesh_.has_vertex_colors())
183 {
184 drawModes |= DrawModes::POINTS_COLORED;
185 drawModes |= DrawModes::SOLID_POINTS_COLORED;
186 }
187
188 if (mesh_.has_face_normals())
189 drawModes |= DrawModes::SOLID_FLAT_SHADED;
190
191 if (mesh_.has_face_colors())
192 {
193 drawModes |= DrawModes::SOLID_FACES_COLORED;
194
195 if( mesh_.has_face_normals() )
196 drawModes |= DrawModes::SOLID_FACES_COLORED_FLAT_SHADED;
197 }
198
199 if (mesh_.has_vertex_texcoords1D())
200 {
201 drawModes |= DrawModes::SOLID_1DTEXTURED;
202
203 if (mesh_.has_vertex_normals())
204 drawModes |= DrawModes::SOLID_1DTEXTURED_SHADED;
205 }
206
207 if (mesh_.has_vertex_texcoords2D())
208 {
209 drawModes |= DrawModes::SOLID_TEXTURED;
210
211 if (mesh_.has_vertex_normals())
212 drawModes |= DrawModes::SOLID_TEXTURED_SHADED;
213 }
214
215 if (mesh_.has_vertex_texcoords3D())
216 {
217 drawModes |= DrawModes::SOLID_3DTEXTURED;
218
219 if (mesh_.has_vertex_normals())
220 drawModes |= DrawModes::SOLID_3DTEXTURED_SHADED;
221 }
222
223 if (mesh_.has_halfedge_texcoords2D())
224 {
225 drawModes |= DrawModes::SOLID_2DTEXTURED_FACE;
226 if (mesh_.has_face_normals())
227 drawModes |= DrawModes::SOLID_2DTEXTURED_FACE_SHADED;
228 }
229
230 return drawModes;
231}
232
233
234//----------------------------------------------------------------------------
235
236
237template<class Mesh>
238void
239MeshNodeDeprecatedT<Mesh>::
240enable_arrays(unsigned int _arrays)
241{
242 // special case: VBO
243 // only use for float data, otherwise it's terribly slow!
244 typedef typename Mesh::Point Point;
245 typedef typename Point::value_type PointScalar;
246 typedef typename Mesh::Normal Normal;
247 typedef typename Normal::value_type NormalScalar;
248
249 bool use_vbo =
250 ((_arrays == VERTEX_ARRAY || _arrays == (VERTEX_ARRAY | NORMAL_ARRAY)) &&
251 (vertexBufferInitialized_ && normalBufferInitialized_) ) ;
252// omlog() << "Use VBO: " << use_vbo << std::endl;
253
254
255
256 // unbind VBO buffers
257 if (!use_vbo && vertex_buffer_)
258 ACG::GLState::bindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
259
260
261
262 if (_arrays & VERTEX_ARRAY)
263 {
264 if (!(enabled_arrays_ & VERTEX_ARRAY))
265 {
266 enabled_arrays_ |= VERTEX_ARRAY;
267 ACG::GLState::enableClientState(GL_VERTEX_ARRAY);
268
269 if (use_vbo )
270 {
271 ACG::GLState::bindBufferARB(GL_ARRAY_BUFFER_ARB, vertex_buffer_);
272
273 // As we ensure that buffers are converted to float before using them, use Float here
274 ACG::GLState::vertexPointer(3, GL_FLOAT, 0, 0);
275 }
276 else
277 {
278 ACG::GLState::vertexPointer(mesh_.points());
279 }
280 }
281 }
282 else if (enabled_arrays_ & VERTEX_ARRAY)
283 {
284 enabled_arrays_ &= ~VERTEX_ARRAY;
285 ACG::GLState::disableClientState(GL_VERTEX_ARRAY);
286 }
287
288
289 if (_arrays & NORMAL_ARRAY)
290 {
291 if (!(enabled_arrays_ & NORMAL_ARRAY))
292 {
293 enabled_arrays_ |= NORMAL_ARRAY;
294 ACG::GLState::enableClientState(GL_NORMAL_ARRAY);
295
296 if (use_vbo)
297 {
298 ACG::GLState::bindBufferARB(GL_ARRAY_BUFFER_ARB, normal_buffer_);
299
300 // As we ensure that buffers are converted to float before using them, use Float here
301 ACG::GLState::normalPointer(GL_FLOAT, 0 , 0);
302 }
303 else
304 {
305 ACG::GLState::normalPointer(mesh_.vertex_normals());
306 }
307 }
308 }
309 else if (enabled_arrays_ & NORMAL_ARRAY)
310 {
311 enabled_arrays_ &= ~NORMAL_ARRAY;
312 ACG::GLState::disableClientState(GL_NORMAL_ARRAY);
313 }
314
315
316 if (_arrays & COLOR_ARRAY)
317 {
318 if (!(enabled_arrays_ & COLOR_ARRAY))
319 {
320 enabled_arrays_ |= COLOR_ARRAY;
321 ACG::GLState::enableClientState(GL_COLOR_ARRAY);
322 ACG::GLState::colorPointer(mesh_.vertex_colors());
323 }
324 }
325 else if (enabled_arrays_ & COLOR_ARRAY)
326 {
327 enabled_arrays_ &= ~COLOR_ARRAY;
328 ACG::GLState::disableClientState(GL_COLOR_ARRAY);
329 }
330
331
332 if (_arrays & TEXTURE_COORD_1D_ARRAY)
333 {
334 if (!(enabled_arrays_ & TEXTURE_COORD_1D_ARRAY))
335 {
336 enabled_arrays_ |= TEXTURE_COORD_1D_ARRAY;
337 ACG::GLState::enableClientState(GL_TEXTURE_COORD_ARRAY);
338 ACG::GLState::texcoordPointer(mesh_.texcoords1D());
339 }
340 }
341 else if (enabled_arrays_ & TEXTURE_COORD_1D_ARRAY)
342 {
343 enabled_arrays_ &= ~TEXTURE_COORD_1D_ARRAY;
344 ACG::GLState::disableClientState(GL_TEXTURE_COORD_ARRAY);
345 }
346
347
348 if (_arrays & TEXTURE_COORD_2D_ARRAY)
349 {
350 if (!(enabled_arrays_ & TEXTURE_COORD_2D_ARRAY))
351 {
352 enabled_arrays_ |= TEXTURE_COORD_2D_ARRAY;
353 ACG::GLState::enableClientState(GL_TEXTURE_COORD_ARRAY);
354 ACG::GLState::texcoordPointer(mesh_.texcoords2D());
355 }
356 }
357 else if (enabled_arrays_ & TEXTURE_COORD_2D_ARRAY)
358 {
359 enabled_arrays_ &= ~TEXTURE_COORD_2D_ARRAY;
360 ACG::GLState::disableClientState(GL_TEXTURE_COORD_ARRAY);
361 }
362
363
364 if (_arrays & TEXTURE_COORD_3D_ARRAY)
365 {
366 if (!(enabled_arrays_ & TEXTURE_COORD_3D_ARRAY))
367 {
368 enabled_arrays_ |= TEXTURE_COORD_3D_ARRAY;
369 ACG::GLState::enableClientState(GL_TEXTURE_COORD_ARRAY);
370 ACG::GLState::texcoordPointer(mesh_.texcoords3D());
371 }
372 }
373 else if (enabled_arrays_ & TEXTURE_COORD_3D_ARRAY)
374 {
375 enabled_arrays_ &= ~TEXTURE_COORD_3D_ARRAY;
376 ACG::GLState::disableClientState(GL_TEXTURE_COORD_ARRAY);
377 }
378
379
381}
382
383
384//----------------------------------------------------------------------------
385
386
387template<class Mesh>
388void
389MeshNodeDeprecatedT<Mesh>::
390update_geometry()
391{
392 updateFaceList_ = true;
393 updateVertexList_ = true;
394 updateEdgeList_ = true;
395 updateAnyList_ = true;
396
397 bbMin_ = Vec3d(FLT_MAX, FLT_MAX, FLT_MAX);
398 bbMax_ = Vec3d(-FLT_MAX, -FLT_MAX, -FLT_MAX);
399 typename Mesh::ConstVertexIter v_it(mesh_.vertices_begin()),
400 v_end(mesh_.vertices_end());
401
402 for (; v_it!=v_end; ++v_it)
403 {
404 bbMin_.minimize(mesh_.point(*v_it));
405 bbMax_.maximize(mesh_.point(*v_it));
406 }
407
408 typedef typename Mesh::Point Point;
409 typedef typename Point::value_type PointScalar;
410 typedef typename Mesh::Normal Normal;
411 typedef typename Normal::value_type NormalScalar;
412
413 //===================================================================
414 // Generate a vertex buffer on the GPU
415 //===================================================================
416
417 if (!vertex_buffer_) glGenBuffers(1, (GLuint*) &vertex_buffer_);
418
419 ACG::GLState::bindBufferARB(GL_ARRAY_BUFFER_ARB, vertex_buffer_);
420 vertexBufferInitialized_ = false;
421
422 //Check if using floats otherwise convert to internal float array
423 if ( sizeof(PointScalar) == 4 ) {
424
425 glBufferData(GL_ARRAY_BUFFER_ARB,
426 3 * mesh_.n_vertices() * sizeof(PointScalar),
427 mesh_.points(),
428 GL_STATIC_DRAW_ARB);
429
430 vertexBufferInitialized_ = true;
431
432 } else {
433
434 vertices_.clear();
435 typename Mesh::ConstVertexIter v_it(mesh_.vertices_begin()),
436 v_end(mesh_.vertices_end());
437
438 for ( ; v_it != v_end ; ++v_it )
439 vertices_.push_back( ACG::Vec3f(mesh_.point(*v_it)) );
440
441 if ( !vertices_.empty() ) {
442
443 glBufferData(GL_ARRAY_BUFFER_ARB,
444 3 * mesh_.n_vertices() * sizeof(float),
445 &vertices_[0],
446 GL_STATIC_DRAW_ARB);
447 vertexBufferInitialized_ = true;
448
449 }
450 }
451
452 //===================================================================
453 // Generate a normal buffer on the GPU
454 //===================================================================
455
456 if (!normal_buffer_) glGenBuffers(1, (GLuint*) &normal_buffer_);
457 ACG::GLState::bindBufferARB(GL_ARRAY_BUFFER_ARB, normal_buffer_);
458 normalBufferInitialized_ = false;
459
460 // Check if using floats otherwise convert to internal float array
461 if ( sizeof(NormalScalar) == 4) {
462
463 glBufferData(GL_ARRAY_BUFFER_ARB,
464 3 * mesh_.n_vertices() * sizeof(NormalScalar),
465 mesh_.vertex_normals(),
466 GL_STATIC_DRAW_ARB);
467
468 normalBufferInitialized_ = true;
469
470 } else {
471 normals_.clear();
472 typename Mesh::ConstVertexIter v_it(mesh_.vertices_begin()),
473 v_end(mesh_.vertices_end());
474
475 for ( ; v_it != v_end ; ++v_it )
476 normals_.push_back( ACG::Vec3f(mesh_.normal(*v_it)) );
477
478 if ( !normals_.empty() ) {
479
480 glBufferData(GL_ARRAY_BUFFER_ARB,
481 3 * mesh_.n_vertices() * sizeof(float),
482 &normals_[0],
483 GL_STATIC_DRAW_ARB);
484 normalBufferInitialized_ = true;
485 }
486
487 }
488
489 // unbind buffers
490 ACG::GLState::bindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
491
492 } else omlog() << "MeshNodeDeprecatedT: VBO not supported on this machine\n";
493}
494
495
496//----------------------------------------------------------------------------
497
498
499template<class Mesh>
500void
501MeshNodeDeprecatedT<Mesh>::
502update_topology()
503{
504 updateFaceList_ = true;
505 updateVertexList_ = true;
506
507 if (mesh_.is_trimesh())
508 {
509 typename Mesh::ConstFaceIter f_it(mesh_.faces_sbegin()),
510 f_end(mesh_.faces_end());
511 typename Mesh::ConstFaceVertexIter fv_it;
512
513 try
514 {
515 indices_.clear();
516 std::vector<unsigned int>().swap(indices_);
517 indices_.reserve(mesh_.n_faces()*3);
518
519 for (; f_it!=f_end; ++f_it)
520 {
521 fv_it = mesh_.cfv_iter( *f_it );
522 indices_.push_back(fv_it->idx()); ++fv_it;
523 indices_.push_back(fv_it->idx()); ++fv_it;
524 indices_.push_back(fv_it->idx());
525 }
526 }
527 catch (...)
528 {
529 indices_.clear();
530 std::vector<unsigned int>().swap(indices_);
531 omerr() << "Topology caching failed\n";
532 }
533
534 //===================================================================
535 // Generate an index buffer on the GPU
536 //===================================================================
537 faceIndexBufferInitialized_ = false;
538
539 if ( !indices_.empty() ) {
540
541 // generate buffer
542 if (!face_index_buffer_) glGenBuffers(1, (GLuint*) &face_index_buffer_);
543
544 // index buffer
545 ACG::GLState::bindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, face_index_buffer_);
546
547 glBufferData(GL_ELEMENT_ARRAY_BUFFER_ARB,
548 indices_.size() * sizeof(unsigned int),
549 &indices_[0],
550 GL_STATIC_DRAW_ARB);
551
552 faceIndexBufferInitialized_ = true;
553
554 // unbind buffer
555 ACG::GLState::bindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
556
557 }
558
559 }
560
561}
562
563
564//----------------------------------------------------------------------------
565
566
567template<class Mesh>
568void
569MeshNodeDeprecatedT<Mesh>::
570draw(GLState& _state, const DrawModes::DrawMode& _drawMode)
571{
572 GLenum prev_depth = _state.depthFunc();
573
574 if (_drawMode & DrawModes::POINTS)
575 {
576 enable_arrays(VERTEX_ARRAY);
577 ACG::GLState::disable(GL_LIGHTING);
579 draw_vertices();
580 }
581
582
583 if ( ( _drawMode & DrawModes::POINTS_COLORED ) && mesh_.has_vertex_colors())
584 {
585 enable_arrays(VERTEX_ARRAY | COLOR_ARRAY);
586 ACG::GLState::disable(GL_LIGHTING);
588 draw_vertices();
589 }
590
591
592 if ( ( _drawMode & DrawModes::POINTS_SHADED ) && mesh_.has_vertex_normals())
593 {
594 enable_arrays(VERTEX_ARRAY | NORMAL_ARRAY);
595 ACG::GLState::enable(GL_LIGHTING);
597 draw_vertices();
598 }
599
600
601 if (_drawMode & DrawModes::WIREFRAME)
602 {
603 glPushAttrib(GL_ENABLE_BIT);
604
605 ACG::GLState::disable( GL_CULL_FACE );
606
607 enable_arrays(VERTEX_ARRAY);
608 ACG::GLState::disable(GL_LIGHTING);
610 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
611 draw_faces(PER_VERTEX);
612 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
613
614 glPopAttrib();
615 }
616
617
618 if (_drawMode & DrawModes::HIDDENLINE)
619 {
620 enable_arrays(VERTEX_ARRAY);
621
622 Vec4f clear_color = _state.clear_color();
623 Vec4f base_color = _state.base_color();
624 clear_color[3] = 1.0;
625
626 ACG::GLState::disable(GL_LIGHTING);
628 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
629 _state.set_base_color(clear_color);
630
631 ACG::GLState::depthRange(0.01, 1.0);
632 draw_faces(PER_VERTEX);
633 ACG::GLState::depthRange(0.0, 1.0);
634
635 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
636 ACG::GLState::depthFunc(GL_LEQUAL);
637 _state.set_base_color(base_color);
638 draw_faces(PER_VERTEX);
639 ACG::GLState::depthFunc(prev_depth);
640 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
641 }
642
643
644 if ( ( _drawMode & DrawModes::SOLID_FLAT_SHADED ) && mesh_.has_face_normals())
645 {
646 ACG::GLState::enable(GL_LIGHTING);
648 ACG::GLState::depthRange(0.01, 1.0);
649 draw_faces(FACE_NORMALS);
650 ACG::GLState::depthRange(0.0, 1.0);
651 }
652
653
654 if ( ( _drawMode & DrawModes::SOLID_SMOOTH_SHADED ) && mesh_.has_vertex_normals())
655 {
656 enable_arrays(VERTEX_ARRAY | NORMAL_ARRAY);
657 ACG::GLState::enable(GL_LIGHTING);
658 ACG::GLState::shadeModel(GL_SMOOTH);
659 ACG::GLState::depthRange(0.01, 1.0);
660 draw_faces(PER_VERTEX);
661 ACG::GLState::depthRange(0.0, 1.0);
662 }
663
664 if ( ( _drawMode & DrawModes::SOLID_PHONG_SHADED ) && mesh_.has_vertex_normals() )
665 {
666// if ( parent() != 0 ) {
667// if ( parent()->className() == "ShaderNode" ) {
668//
669// ShaderNode* node = dynamic_cast< ShaderNode* > ( parent() );
670//
671// GLSL::PtrProgram program = node->getShader( DrawModes::SOLID_PHONG_SHADED );
672//
673// // Enable own Phong shader
674// program->use();
675
676 enable_arrays(VERTEX_ARRAY | NORMAL_ARRAY);
677 ACG::GLState::enable(GL_LIGHTING);
678 ACG::GLState::shadeModel(GL_SMOOTH);
679 ACG::GLState::depthRange(0.01, 1.0);
680 draw_faces(PER_VERTEX);
681 ACG::GLState::depthRange(0.0, 1.0);
682
683 //disable own Phong shader
684// program->disable();
685// }
686// }
687 }
688
689 if ( ( _drawMode & DrawModes::SOLID_ENV_MAPPED ) && mesh_.has_vertex_normals())
690 {
691 enable_arrays(VERTEX_ARRAY | NORMAL_ARRAY);
692 ACG::GLState::enable(GL_LIGHTING);
693 ACG::GLState::shadeModel(GL_SMOOTH);
694 ACG::GLState::depthRange(0.01, 1.0);
695 draw_faces(PER_VERTEX);
696 ACG::GLState::depthRange(0.0, 1.0);
697 }
698
699
700 if ( ( _drawMode & DrawModes::SOLID_FACES_COLORED )&& mesh_.has_face_colors())
701 {
702 Vec4f base_color_backup = _state.base_color();
703
704 ACG::GLState::disable(GL_LIGHTING);
706 ACG::GLState::depthRange(0.01, 1.0);
707 draw_faces(FACE_COLORS);
708 ACG::GLState::depthRange(0.0, 1.0);
709
710 _state.set_base_color(base_color_backup);
711 }
712
713
714 if ( ( _drawMode & DrawModes::SOLID_FACES_COLORED_FLAT_SHADED ) && mesh_.has_face_colors() && mesh_.has_face_normals())
715 {
716 Vec4f base_color_backup = _state.base_color();
717 ACG::GLState::enable(GL_LIGHTING);
718
720 ACG::GLState::depthRange(0.01, 1.0);
721 draw_faces(FACE_NORMALS_COLORS);
722 ACG::GLState::depthRange(0.0, 1.0);
723
724 _state.set_base_color(base_color_backup);
725 }
726
727
728 if ( ( _drawMode & DrawModes::SOLID_POINTS_COLORED ) && mesh_.has_vertex_colors())
729 {
730 Vec4f base_color_backup = _state.base_color();
731
732 enable_arrays(VERTEX_ARRAY | COLOR_ARRAY);
733 ACG::GLState::disable(GL_LIGHTING);
734 ACG::GLState::shadeModel(GL_SMOOTH);
735 ACG::GLState::depthRange(0.01, 1.0);
736 draw_faces(PER_VERTEX);
737 ACG::GLState::depthRange(0.0, 1.0);
738
739 _state.set_base_color(base_color_backup);
740 }
741
742
743 if ( ( _drawMode & DrawModes::SOLID_TEXTURED ) && mesh_.has_vertex_texcoords2D())
744 {
745 enable_arrays(VERTEX_ARRAY | TEXTURE_COORD_2D_ARRAY);
746 ACG::GLState::enable(GL_TEXTURE_2D);
747 ACG::GLState::disable(GL_LIGHTING);
749 ACG::GLState::depthRange(0.01, 1.0);
750 draw_faces(PER_VERTEX);
751 ACG::GLState::depthRange(0.0, 1.0);
752 ACG::GLState::disable(GL_TEXTURE_2D);
753 }
754
755
756 if ( ( _drawMode & DrawModes::SOLID_TEXTURED_SHADED ) && mesh_.has_vertex_texcoords2D() && mesh_.has_vertex_normals())
757 {
758 enable_arrays(VERTEX_ARRAY | NORMAL_ARRAY | TEXTURE_COORD_2D_ARRAY);
759 ACG::GLState::enable(GL_TEXTURE_2D);
760 ACG::GLState::enable(GL_LIGHTING);
761 ACG::GLState::shadeModel(GL_SMOOTH);
762 ACG::GLState::depthRange(0.01, 1.0);
763 draw_faces(PER_VERTEX);
764 ACG::GLState::depthRange(0.0, 1.0);
765 ACG::GLState::disable(GL_TEXTURE_2D);
766 }
767
768
769 if ( ( _drawMode & DrawModes::SOLID_1DTEXTURED ) && mesh_.has_vertex_texcoords1D())
770 {
771 enable_arrays(VERTEX_ARRAY | TEXTURE_COORD_1D_ARRAY);
772 ACG::GLState::enable(GL_TEXTURE_1D);
773 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
774 ACG::GLState::disable(GL_LIGHTING);
775 ACG::GLState::shadeModel(GL_SMOOTH);
776 ACG::GLState::depthRange(0.01, 1.0);
777 draw_faces(PER_VERTEX);
778 ACG::GLState::depthRange(0.0, 1.0);
779 ACG::GLState::disable(GL_TEXTURE_1D);
780 }
781
782
783 if ( ( _drawMode & DrawModes::SOLID_1DTEXTURED_SHADED ) && mesh_.has_vertex_texcoords1D() && mesh_.has_vertex_normals())
784 {
785 // store and change colors
786 const Vec4f ambient = _state.ambient_color();
787 const Vec4f diffuse = _state.diffuse_color();
788 const Vec4f specular = _state.specular_color();
789 _state.set_ambient_color (Vec4f(0.1, 0.1, 0.1, 1.0));
790 _state.set_diffuse_color (Vec4f(0.8, 0.8, 0.8, 1.0));
791 _state.set_specular_color (Vec4f(1.0, 1.0, 1.0, 1.0));
792
793 // store and change texture mode
794 GLint texmode;
795 glGetTexEnviv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &texmode);
796 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
797
798 enable_arrays(VERTEX_ARRAY | NORMAL_ARRAY | TEXTURE_COORD_1D_ARRAY);
799 ACG::GLState::enable(GL_TEXTURE_1D);
800 ACG::GLState::enable(GL_LIGHTING);
801 ACG::GLState::shadeModel(GL_SMOOTH);
802 ACG::GLState::depthRange(0.01, 1.0);
803 draw_faces(PER_VERTEX);
804 ACG::GLState::depthRange(0.0, 1.0);
805 ACG::GLState::disable(GL_TEXTURE_1D);
806
807 // restore colors
808 _state.set_ambient_color(ambient);
809 _state.set_diffuse_color(diffuse);
810 _state.set_specular_color(specular);
811
812 // restore texture mode
813 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, texmode);
814 }
815
816
817
818 if ( ( _drawMode & DrawModes::SOLID_3DTEXTURED ) && mesh_.has_vertex_texcoords3D())
819 {
820 enable_arrays(VERTEX_ARRAY | TEXTURE_COORD_3D_ARRAY);
821 ACG::GLState::enable(GL_TEXTURE_3D);
822 ACG::GLState::disable(GL_LIGHTING);
824 ACG::GLState::depthRange(0.01, 1.0);
825 draw_faces(PER_VERTEX);
826 ACG::GLState::depthRange(0.0, 1.0);
827 ACG::GLState::disable(GL_TEXTURE_3D);
828 }
829
830
831 if ( ( _drawMode & DrawModes::SOLID_3DTEXTURED_SHADED ) && mesh_.has_vertex_texcoords3D() && mesh_.has_vertex_normals())
832 {
833 enable_arrays(VERTEX_ARRAY | NORMAL_ARRAY | TEXTURE_COORD_3D_ARRAY);
834 ACG::GLState::enable(GL_TEXTURE_3D);
835 ACG::GLState::enable(GL_LIGHTING);
836 ACG::GLState::shadeModel(GL_SMOOTH);
837 ACG::GLState::depthRange(0.01, 1.0);
838 draw_faces(PER_VERTEX);
839 ACG::GLState::depthRange(0.0, 1.0);
840 ACG::GLState::disable(GL_TEXTURE_3D);
841 }
842
843 // Textured by using coordinates stored in halfedges
844 // TODO: Check not only mesh_.has_halfedge_texcoords2D but check if custom property is available
845 if ( ( _drawMode & DrawModes::SOLID_2DTEXTURED_FACE ) && mesh_.has_halfedge_texcoords2D())
846 {
847 ACG::GLState::enable(GL_TEXTURE_2D);
848 ACG::GLState::disable(GL_LIGHTING);
850 ACG::GLState::depthRange(0.01, 1.0);
851 draw_faces(FACE_HALFEDGE_TEXTURED);
852 ACG::GLState::depthRange(0.0, 1.0);
853 ACG::GLState::disable(GL_TEXTURE_2D);
854 }
855
856 // Textured by using coordinates stored in halfedges
857 // TODO: Check not only mesh_.has_halfedge_texcoords2D but check if custom property is available
858 if ( ( _drawMode & DrawModes::SOLID_2DTEXTURED_FACE_SHADED ) && mesh_.has_halfedge_texcoords2D() && mesh_.has_face_normals())
859 {
860 ACG::GLState::enable(GL_TEXTURE_2D);
861 ACG::GLState::enable(GL_LIGHTING);
862
864 ACG::GLState::depthRange(0.01, 1.0);
865 draw_faces(FACE_HALFEDGE_TEXTURED);
866 ACG::GLState::depthRange(0.0, 1.0);
867 ACG::GLState::disable(GL_TEXTURE_2D);
868
869 }
870
871 // If in shader mode, just draw, as the shader has to be set by a shadernode above this node
872 if ( (_drawMode & DrawModes::SOLID_SHADER ) ) {
873
874 if ( mesh_.has_face_normals() )
875 enable_arrays( VERTEX_ARRAY | NORMAL_ARRAY);
876 else
877 enable_arrays( VERTEX_ARRAY );
878
879 ACG::GLState::enable(GL_LIGHTING);
880 ACG::GLState::shadeModel(GL_SMOOTH);
881 ACG::GLState::depthRange(0.01, 1.0);
882 draw_faces(PER_VERTEX);
883 ACG::GLState::depthRange(0.0, 1.0);
884 }
885
886
887 enable_arrays(0);
888}
889
890
891//----------------------------------------------------------------------------
892
893
894template<class Mesh>
895void
896MeshNodeDeprecatedT<Mesh>::
897draw_vertices()
898{
899 glDrawArrays(GL_POINTS, 0, mesh_.n_vertices());
900}
901
902
903//----------------------------------------------------------------------------
904
905
906template<class Mesh>
907void
908MeshNodeDeprecatedT<Mesh>::
909draw_faces(FaceMode _mode)
910{
911 typename Mesh::ConstFaceIter f_it(mesh_.faces_sbegin()),
912 f_end(mesh_.faces_end());
913 typename Mesh::ConstFaceVertexIter fv_it;
914 typename Mesh::ConstFaceHalfedgeIter fh_it;
915
916 switch (_mode)
917 {
918 case FACE_NORMALS:
919 {
920 if (mesh_.is_trimesh())
921 {
922 glBegin(GL_TRIANGLES);
923 for (; f_it!=f_end; ++f_it)
924 {
925 glNormal(mesh_.normal(*f_it));
926
927 fv_it=mesh_.cfv_iter(*f_it);
928 glVertex(mesh_.point(*fv_it)); ++fv_it;
929 glVertex(mesh_.point(*fv_it)); ++fv_it;
930 glVertex(mesh_.point(*fv_it));
931 }
932 glEnd();
933 }
934 else
935 {
936 for (; f_it!=f_end; ++f_it)
937 {
938 glBegin(GL_POLYGON);
939 glNormal(mesh_.normal(*f_it));
940 for (fv_it=mesh_.cfv_iter(*f_it); fv_it.is_valid(); ++fv_it)
941 glVertex(mesh_.point(*fv_it));
942 glEnd();
943 }
944 }
945 break;
946 }
947
948
949 case FACE_COLORS:
950 {
951 if (mesh_.is_trimesh())
952 {
953 glBegin(GL_TRIANGLES);
954 for (; f_it!=f_end; ++f_it)
955 {
956 glColor(mesh_.color(*f_it));
957
958 fv_it=mesh_.cfv_iter(*f_it);
959 glVertex(mesh_.point(*fv_it)); ++fv_it;
960 glVertex(mesh_.point(*fv_it)); ++fv_it;
961 glVertex(mesh_.point(*fv_it));
962 }
963 glEnd();
964 }
965 else
966 {
967 for (; f_it!=f_end; ++f_it)
968 {
969 glBegin(GL_POLYGON);
970 glColor(mesh_.color(*f_it));
971 for (fv_it=mesh_.cfv_iter(*f_it); fv_it.is_valid(); ++fv_it)
972 glVertex(mesh_.point(*fv_it));
973 glEnd();
974 }
975 }
976 break;
977 }
978
979
980 case FACE_NORMALS_COLORS:
981 {
982 if (mesh_.is_trimesh())
983 {
984 glBegin(GL_TRIANGLES);
985 for (; f_it!=f_end; ++f_it)
986 {
987 glColor(mesh_.color(*f_it));
988 glNormal(mesh_.normal(*f_it));
989
990 fv_it=mesh_.cfv_iter(*f_it);
991 glVertex(mesh_.point(*fv_it)); ++fv_it;
992 glVertex(mesh_.point(*fv_it)); ++fv_it;
993 glVertex(mesh_.point(*fv_it));
994 }
995 glEnd();
996 }
997 else
998 {
999 for (; f_it!=f_end; ++f_it)
1000 {
1001 glBegin(GL_POLYGON);
1002 glColor(mesh_.color(*f_it));
1003 glNormal(mesh_.normal(*f_it));
1004 for (fv_it=mesh_.cfv_iter(*f_it); fv_it.is_valid(); ++fv_it)
1005 glVertex(mesh_.point(*fv_it));
1006 glEnd();
1007 }
1008 }
1009 break;
1010 }
1011
1012
1013 // propertyMap_ maps between an int index stored in the Mesh describing which texture to use
1014 // and a property name giving 2D Texture coordinates for halfedges ( texcoords for to vertex )
1015
1016 case FACE_HALFEDGE_TEXTURED:
1017 {
1018 if (mesh_.is_trimesh())
1019 {
1020
1021 OpenMesh::FPropHandleT< int > texture_index_property;
1022 if ( !mesh_.get_property_handle(texture_index_property,indexPropertyName_) ) {
1023 if( indexPropertyName_ != "No Texture Index")
1024 std::cerr << "Unable to get per face texture Index property named " << indexPropertyName_ << std::endl;
1025 if ( !mesh_.get_property_handle(texture_index_property,"f:textureindex") ) {
1026 std::cerr << "Unable to get standard per face texture Index property" << std::endl;
1027 texture_index_property.reset();
1028 }
1029 }
1030
1031 // textureMap_ maps between an int index stored in the Mesh describing which texture to use
1032 // and the GluInt bound by the TextureNode. If such a map is not available, assume TextureNode
1033 // has already bound a texture and we use only one texture.
1034 // Additionally if we do not have an texture index property, we do not know which textures
1035 // should be used .. therefore do not switch textures if this property is missing.
1036 if ( !textureMap_ || !texture_index_property.is_valid() ) {
1037
1038 // Get texture coords property
1040 if ( !mesh_.get_property_handle(texture_coord_property,default_halfedge_textcoord_property_) ) {
1041 std::cerr << "Error: Unable to get per face texture coordinate property named "
1042 << default_halfedge_textcoord_property_ << std::endl;
1043 std::cerr << "Unable to texture without texture coordinates" << std::endl;
1044 return;
1045 }
1046
1047 typename Mesh::Point point;
1048 typename Mesh::TexCoord2D tex2d;
1049 glBegin(GL_TRIANGLES);
1050 for (; f_it!=f_end; ++f_it) {
1051 glNormal(mesh_.normal(*f_it));
1052 for (fh_it = mesh_.cfh_iter(*f_it);fh_it.is_valid();++fh_it)
1053 {
1054 point = mesh_.point(mesh_.to_vertex_handle(*fh_it));
1055 tex2d = mesh_.property(texture_coord_property,*fh_it);
1056 glTexCoord2f(tex2d[0], tex2d[1]);
1057 glVertex(point);
1058 }
1059 }
1060 glEnd();
1061 } else {
1062
1064 int last_texture = -1;
1065
1066 typename Mesh::Point point;
1067 typename Mesh::TexCoord2D tex2d;
1068
1069 for (; f_it!=f_end; ++f_it)
1070 {
1071 int texture = mesh_.property(texture_index_property,*f_it);
1072
1073 if (texture == -1)
1074 continue;
1075
1076 if ( last_texture != texture ) {
1077
1078 if ( textureMap_->find(texture) == textureMap_->end() ) {
1079 std::cerr << "Illegal texture index ... trying to access " << texture << std::endl;
1080 last_texture = -1;
1081 continue;
1082 }
1083
1084 // Get texture coords property
1085 if ( !propertyMap_ || !mesh_.get_property_handle(texture_coord_property,(*propertyMap_)[texture]) ) {
1086 if ( propertyMap_)
1087 std::cerr << "Error: Unable to get per face texture coordinate property named "
1088 << (*propertyMap_)[texture] << std::endl;
1089 if ( !mesh_.get_property_handle(texture_coord_property,"h:texcoords2D") ) {
1090 std::cerr << "Fallback: Unable to get standard Property for per halfedge texcoords" << std::endl;
1091 std::cerr << "Unable to texture face without texture coordinates" << std::endl;
1092 last_texture = -1;
1093 continue;
1094 }
1095 }
1096
1097 ACG::GLState::bindTexture( GL_TEXTURE_2D, (*textureMap_)[texture] );
1098
1099 // Remember active texture to skip extra switches
1100 last_texture = texture;
1101
1102 }
1103
1104 glBegin(GL_TRIANGLES);
1105
1106 glNormal(mesh_.normal(*f_it));
1107 glColor(mesh_.color(*f_it));
1108
1109 for (fh_it = mesh_.cfh_iter(*f_it);fh_it.is_valid();++fh_it)
1110 {
1111 point = mesh_.point(mesh_.to_vertex_handle(*fh_it));
1112 tex2d = mesh_.property(texture_coord_property,*fh_it);
1113 glTexCoord2f(tex2d[0], tex2d[1]);
1114 glVertex(point);
1115 }
1116
1117 glEnd();
1118
1119 }
1120 }
1121 }
1122 else
1123 {
1124 // NOT IMPLEMENTED
1125 }
1126 break;
1127 }
1128
1129
1130 case PER_VERTEX:
1131 {
1132 if (mesh_.is_trimesh())
1133 {
1134 // try cached triangle indices
1135 if (!indices_.empty())
1136 {
1137
1138 // If we have an index buffer on the GPU, use it
1139 if ( faceIndexBufferInitialized_ ) {
1140
1141 // As we have a list of all faces on the GPU bind it
1142 ACG::GLState::bindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB,face_index_buffer_);
1143
1144 // Draw it
1145 glDrawElements(GL_TRIANGLES,
1146 indices_.size(),
1147 GL_UNSIGNED_INT,
1148 0);
1149
1150 // And unbind it again
1151 ACG::GLState::bindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB,0);
1152
1153 } else {
1154
1155 glDrawElements(GL_TRIANGLES,
1156 indices_.size(),
1157 GL_UNSIGNED_INT,
1158 &indices_[0]);
1159 }
1160
1161
1162 }
1163
1164 // otherwise use immediate mode
1165 else
1166 {
1167 glBegin(GL_TRIANGLES);
1168 for (; f_it!=f_end; ++f_it)
1169 {
1170
1171 fv_it=mesh_.cfv_iter(*f_it);
1172 glArrayElement(fv_it->idx()); ++fv_it;
1173 glArrayElement(fv_it->idx()); ++fv_it;
1174 glArrayElement(fv_it->idx());
1175 }
1176 glEnd();
1177 }
1178 }
1179 else
1180 {
1181 for (; f_it!=f_end; ++f_it)
1182 {
1183 glBegin(GL_POLYGON);
1184 for (fv_it=mesh_.cfv_iter(*f_it); fv_it.is_valid(); ++fv_it)
1185 glArrayElement(fv_it->idx());
1186 glEnd();
1187 }
1188 }
1189 break;
1190 }
1191 }
1192}
1193
1194
1195//----------------------------------------------------------------------------
1196
1197
1198template<class Mesh>
1199void
1200MeshNodeDeprecatedT<Mesh>::
1201pick(GLState& _state, PickTarget _target)
1202{
1203 switch (_target)
1204 {
1205 case PICK_VERTEX:
1206 {
1207 pick_vertices(_state);
1208 break;
1209 }
1210 case PICK_FRONT_VERTEX:
1211 {
1212 pick_vertices(_state, true);
1213 break;
1214 }
1215
1216 case PICK_ANYTHING:
1217 {
1218 pick_any(_state);
1219 break;
1220 }
1221 case PICK_FACE:
1222 {
1223 pick_faces(_state);
1224 break;
1225 }
1226
1227 case PICK_EDGE:
1228 {
1229 pick_edges(_state);
1230 break;
1231 }
1232
1233 case PICK_FRONT_EDGE:
1234 {
1235 pick_edges(_state, true);
1236 break;
1237 }
1238
1239 default:
1240 break;
1241 }
1242}
1243
1244
1245//----------------------------------------------------------------------------
1246
1247
1248template<class Mesh>
1249void
1250MeshNodeDeprecatedT<Mesh>::
1251pick_vertices(GLState& _state, bool _front)
1252{
1253 GLenum prev_depth = _state.depthFunc();
1254
1255 typename Mesh::ConstVertexIter v_it(mesh_.vertices_begin()),
1256 v_end(mesh_.vertices_end());
1257 GLuint idx(0);
1258
1259 if (!_state.pick_set_maximum (mesh_.n_vertices()))
1260 {
1261 omerr() << "MeshNode::pick_vertices: color range too small, "
1262 << "picking failed\n";
1263 return;
1264 }
1265
1266 if (_front)
1267 {
1268 enable_arrays(VERTEX_ARRAY);
1269
1270 Vec4f clear_color = _state.clear_color();
1271 Vec4f base_color = _state.base_color();
1272 clear_color[3] = 1.0;
1273
1274 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
1275 _state.set_base_color(clear_color);
1276
1277 ACG::GLState::depthRange(0.01, 1.0);
1278 draw_faces(PER_VERTEX);
1279 ACG::GLState::depthRange(0.0, 1.0);
1280
1281 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
1282 ACG::GLState::depthFunc(GL_LEQUAL);
1283 _state.set_base_color(base_color);
1284
1285 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
1286
1287 enable_arrays(0);
1288 }
1289
1290
1291 if (vertexList_ && !updateVertexList_ && _state.pick_current_index () == vertexBaseIndex_)
1292 {
1293 glCallList (vertexList_);
1294 ACG::GLState::depthFunc(prev_depth);
1295 return;
1296 }
1297
1298 if (vertexList_)
1299 {
1300 glNewList (vertexList_, GL_COMPILE);
1301 updateVertexList_ = false;
1302 vertexBaseIndex_ = _state.pick_current_index ();
1303 }
1304
1305 if (_state.color_picking ())
1306 {
1307 update_pick_buffers ();
1308
1309 for (; v_it!=v_end; ++v_it, ++idx)
1310 {
1311 pickColorBuf_[idx] = _state.pick_get_name_color (idx);
1312 pickVertexBuf_[idx] = mesh_.point(*v_it);
1313 }
1314
1315 ACG::GLState::enableClientState(GL_VERTEX_ARRAY);
1316 ACG::GLState::enableClientState(GL_COLOR_ARRAY);
1317
1318 ACG::GLState::vertexPointer (&pickVertexBuf_[0]);
1319 ACG::GLState::colorPointer(&pickColorBuf_[0]);
1320
1321 glDrawArrays(GL_POINTS, 0, mesh_.n_vertices());
1322
1323 ACG::GLState::disableClientState(GL_COLOR_ARRAY);
1324 ACG::GLState::disableClientState(GL_VERTEX_ARRAY);
1325 }
1326 else
1327 {
1328 for (; v_it!=v_end; ++v_it, ++idx)
1329 {
1330 _state.pick_set_name (idx);
1331 glBegin(GL_POINTS);
1332 glVertex(mesh_.point(*v_it));
1333 glEnd();
1334 }
1335 }
1336
1337 if (vertexList_)
1338 {
1339 glEndList ();
1340 glCallList (vertexList_);
1341 }
1342
1343 ACG::GLState::depthFunc(prev_depth);
1344}
1345
1346
1347//----------------------------------------------------------------------------
1348
1349
1350template<class Mesh>
1351void
1352MeshNodeDeprecatedT<Mesh>::
1353pick_faces(GLState& _state)
1354{
1355 typename Mesh::ConstFaceIter f_it(mesh_.faces_sbegin()),
1356 f_end(mesh_.faces_end());
1357 typename Mesh::ConstFaceVertexIter fv_it;
1358
1359
1360 if ( mesh_.n_faces() > 0 )
1361 {
1362 if (!_state.pick_set_maximum (mesh_.n_faces()))
1363 {
1364 omerr() << "MeshNode::pick_faces: color range too small, "
1365 << "picking failed\n";
1366 return;
1367 }
1368 }
1369 else
1370 {
1371 if (!_state.pick_set_maximum (1))
1372 {
1373 omerr() << "Strange pickSetMAximum failed for index 1 in MeshNode\n";
1374 return;
1375 }
1376 }
1377
1378 if (faceList_ && !updateFaceList_ && _state.pick_current_index () == faceBaseIndex_)
1379 {
1380 glCallList (faceList_);
1381 return;
1382 }
1383
1384 if (faceList_)
1385 {
1386 glNewList (faceList_, GL_COMPILE);
1387 updateFaceList_ = false;
1388 faceBaseIndex_ = _state.pick_current_index ();
1389 }
1390
1391 if (_state.color_picking ())
1392 {
1393 update_pick_buffers ();
1394 unsigned int idx = 0;
1395
1396 if (mesh_.is_trimesh())
1397 {
1398 for (; f_it!=f_end; ++f_it)
1399 {
1400 pickColorBuf_[idx] = _state.pick_get_name_color (f_it->idx());
1401 pickColorBuf_[idx+1] = _state.pick_get_name_color (f_it->idx());
1402 pickColorBuf_[idx+2] = _state.pick_get_name_color (f_it->idx());
1403
1404 fv_it=mesh_.cfv_iter(*f_it);
1405 pickVertexBuf_[idx] = mesh_.point(*fv_it); ++fv_it;
1406 pickVertexBuf_[idx+1] = mesh_.point(*fv_it); ++fv_it;
1407 pickVertexBuf_[idx+2] = mesh_.point(*fv_it);
1408 idx += 3;
1409 }
1410
1411 ACG::GLState::enableClientState(GL_VERTEX_ARRAY);
1412 ACG::GLState::enableClientState(GL_COLOR_ARRAY);
1413
1414 ACG::GLState::vertexPointer (&pickVertexBuf_[0]);
1415 ACG::GLState::colorPointer(&pickColorBuf_[0]);
1416
1417 glDrawArrays(GL_TRIANGLES, 0, mesh_.n_faces() * 3);
1418
1419 ACG::GLState::disableClientState(GL_COLOR_ARRAY);
1420 ACG::GLState::disableClientState(GL_VERTEX_ARRAY);
1421
1422 }
1423 else
1424 {
1425 unsigned int face = 0;
1426 std::vector <GLint> first;
1427 std::vector <GLsizei> count;
1428
1429 first.resize (mesh_.n_faces());
1430 count.resize (mesh_.n_faces());
1431
1432 for (; f_it!=f_end; ++f_it, ++face)
1433 {
1434 unsigned int cnt = 0;
1435 first[face] = idx;
1436
1437
1438 for (fv_it=mesh_.cfv_iter(*f_it); fv_it.is_valid(); ++fv_it, ++idx, ++cnt)
1439 {
1440 pickVertexBuf_[idx] = mesh_.point(*fv_it);
1441 pickColorBuf_[idx] = _state.pick_get_name_color (f_it->idx());
1442 }
1443 count[face] = cnt;
1444 }
1445 ACG::GLState::enableClientState(GL_VERTEX_ARRAY);
1446 ACG::GLState::enableClientState(GL_COLOR_ARRAY);
1447
1448 ACG::GLState::vertexPointer (&pickVertexBuf_[0]);
1449 ACG::GLState::colorPointer(&pickColorBuf_[0]);
1450
1451 glMultiDrawArrays(GL_POLYGON, &first[0], &count[0], mesh_.n_faces());
1452
1453 ACG::GLState::disableClientState(GL_COLOR_ARRAY);
1454 ACG::GLState::disableClientState(GL_VERTEX_ARRAY);
1455 }
1456 }
1457 else
1458 {
1459
1460 if (mesh_.is_trimesh())
1461 {
1462 for (; f_it!=f_end; ++f_it)
1463 {
1464 // set index
1465 _state.pick_set_name (f_it->idx());
1466
1467 glBegin(GL_TRIANGLES);
1468
1469 fv_it=mesh_.cfv_iter(*f_it);
1470 glVertex(mesh_.point(*fv_it)); ++fv_it;
1471 glVertex(mesh_.point(*fv_it)); ++fv_it;
1472 glVertex(mesh_.point(*fv_it));
1473 glEnd();
1474 }
1475 }
1476 else
1477 {
1478 for (; f_it!=f_end; ++f_it)
1479 {
1480 // set index
1481 _state.pick_set_name (f_it->idx());
1482
1483 glBegin(GL_POLYGON);
1484
1485 for (fv_it=mesh_.cfv_iter(*f_it); fv_it.is_valid(); ++fv_it)
1486 glVertex(mesh_.point(*fv_it));
1487
1488 glEnd();
1489 }
1490 }
1491 }
1492
1493 if (faceList_)
1494 {
1495 glEndList ();
1496 glCallList (faceList_);
1497 }
1498}
1499
1500//----------------------------------------------------------------------------
1501
1502
1503template<class Mesh>
1504void
1505MeshNodeDeprecatedT<Mesh>::
1506pick_edges(GLState& _state, bool _front)
1507{
1508 typename Mesh::ConstEdgeIter e_it(mesh_.edges_sbegin()),
1509 e_end(mesh_.edges_end());
1510
1511 GLenum prev_depth = _state.depthFunc();
1512
1513 if (!_state.pick_set_maximum (mesh_.n_edges()))
1514 {
1515 omerr() << "MeshNode::pick_edges: color range too small, "
1516 << "picking failed\n";
1517 return;
1518 }
1519
1520 if (_front)
1521 {
1522 enable_arrays(VERTEX_ARRAY);
1523
1524 Vec4f clear_color = _state.clear_color();
1525 Vec4f base_color = _state.base_color();
1526 clear_color[3] = 1.0;
1527
1528 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
1529 _state.set_base_color(clear_color);
1530
1531 ACG::GLState::depthRange(0.01, 1.0);
1532 draw_faces(PER_VERTEX);
1533 ACG::GLState::depthRange(0.0, 1.0);
1534
1535 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
1536 ACG::GLState::depthFunc(GL_LEQUAL);
1537 _state.set_base_color(base_color);
1538
1539 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
1540
1541 enable_arrays(0);
1542 }
1543
1544 if (edgeList_ && !updateEdgeList_ && _state.pick_current_index () == edgeBaseIndex_)
1545 {
1546 glCallList (edgeList_);
1547 ACG::GLState::depthFunc(prev_depth);
1548 return;
1549 }
1550
1551 if (edgeList_)
1552 {
1553 glNewList (edgeList_, GL_COMPILE);
1554 updateEdgeList_ = false;
1555 edgeBaseIndex_ = _state.pick_current_index ();
1556 }
1557
1558 if (_state.color_picking ())
1559 {
1560 unsigned int idx = 0;
1561 update_pick_buffers ();
1562
1563 for (; e_it!=e_end; ++e_it)
1564 {
1565 pickColorBuf_[idx] = _state.pick_get_name_color (e_it->idx());
1566 pickColorBuf_[idx+1] = _state.pick_get_name_color (e_it->idx());
1567 pickVertexBuf_[idx] = mesh_.point(mesh_.to_vertex_handle(mesh_.halfedge_handle(*e_it, 0)));
1568 pickVertexBuf_[idx+1] = mesh_.point(mesh_.to_vertex_handle(mesh_.halfedge_handle(*e_it, 1)));
1569 idx += 2;
1570 }
1571
1572 ACG::GLState::enableClientState(GL_VERTEX_ARRAY);
1573 ACG::GLState::enableClientState(GL_COLOR_ARRAY);
1574
1575 ACG::GLState::vertexPointer (&pickVertexBuf_[0]);
1576 ACG::GLState::colorPointer(&pickColorBuf_[0]);
1577
1578 glDrawArrays(GL_LINES, 0, mesh_.n_edges() * 2);
1579
1580 ACG::GLState::disableClientState(GL_COLOR_ARRAY);
1581 ACG::GLState::disableClientState(GL_VERTEX_ARRAY);
1582 }
1583 else
1584 {
1585 for (; e_it!=e_end; ++e_it)
1586 {
1587 _state.pick_set_name (e_it->idx());
1588 glBegin(GL_LINES);
1589 glVertex(mesh_.point(mesh_.to_vertex_handle(mesh_.halfedge_handle(*e_it, 0))));
1590 glVertex(mesh_.point(mesh_.to_vertex_handle(mesh_.halfedge_handle(*e_it, 1))));
1591 glEnd();
1592 }
1593 }
1594
1595 if (edgeList_)
1596 {
1597 glEndList ();
1598 glCallList (edgeList_);
1599 }
1600
1601 ACG::GLState::depthFunc(prev_depth);
1602}
1603
1604//----------------------------------------------------------------------------
1605
1606
1607template<class Mesh>
1608void
1609MeshNodeDeprecatedT<Mesh>::
1610pick_any(GLState& _state)
1611{
1612 GLenum prev_depth = _state.depthFunc();
1613
1614 unsigned int numElements = mesh_.n_faces() + mesh_.n_edges() + mesh_.n_vertices();
1615
1616 // nothing to pick ?
1617 if (numElements == 0)
1618 return;
1619
1620 if (!_state.pick_set_maximum (numElements))
1621 {
1622 omerr() << "MeshNode::pick_any: color range too small, "
1623 << "picking failed\n";
1624 return;
1625 }
1626
1627 if (anyList_ && !updateAnyList_ && _state.pick_current_index () == anyBaseIndex_)
1628 {
1629 glCallList (anyList_);
1630 glCallList (anyList_+1);
1631 glCallList (anyList_+2);
1632 return;
1633 }
1634
1635 if (anyList_)
1636 {
1637 glNewList (anyList_, GL_COMPILE);
1638 updateAnyList_ = false;
1639 anyBaseIndex_ = _state.pick_current_index ();
1640 }
1641
1642 // faces
1643 typename Mesh::ConstFaceIter f_it(mesh_.faces_sbegin()),
1644 f_end(mesh_.faces_end());
1645 typename Mesh::ConstFaceVertexIter fv_it;
1646
1647 // edges
1648 typename Mesh::ConstEdgeIter e_it(mesh_.edges_sbegin()),
1649 e_end(mesh_.edges_end());
1650
1651 // vertices
1652 typename Mesh::ConstVertexIter v_it(mesh_.vertices_begin()),
1653 v_end(mesh_.vertices_end());
1654 GLuint vidx(mesh_.n_faces() + mesh_.n_edges());
1655
1656
1657
1658 if (_state.color_picking ())
1659 {
1660 update_pick_buffers ();
1661
1662 ACG::GLState::enableClientState(GL_VERTEX_ARRAY);
1663 ACG::GLState::enableClientState(GL_COLOR_ARRAY);
1664
1665 // faces
1666 unsigned int idx = 0;
1667 if (mesh_.is_trimesh())
1668 {
1669 for (; f_it!=f_end; ++f_it)
1670 {
1671 pickColorBuf_[idx] = _state.pick_get_name_color (f_it->idx());
1672 pickColorBuf_[idx+1] = _state.pick_get_name_color (f_it->idx());
1673 pickColorBuf_[idx+2] = _state.pick_get_name_color (f_it->idx());
1674
1675 fv_it=mesh_.cfv_iter(*f_it);
1676 pickVertexBuf_[idx] = mesh_.point(*fv_it); ++fv_it;
1677 pickVertexBuf_[idx+1] = mesh_.point(*fv_it); ++fv_it;
1678 pickVertexBuf_[idx+2] = mesh_.point(*fv_it);
1679 idx += 3;
1680 }
1681
1682 ACG::GLState::vertexPointer (&pickVertexBuf_[0]);
1683 ACG::GLState::colorPointer(&pickColorBuf_[0]);
1684
1685 glDrawArrays(GL_TRIANGLES, 0, mesh_.n_faces() * 3);
1686
1687 }
1688 else
1689 {
1690 unsigned int face = 0;
1691 std::vector <GLint> first;
1692 std::vector <GLsizei> count;
1693
1694 first.resize (mesh_.n_faces());
1695 count.resize (mesh_.n_faces());
1696
1697 for (; f_it!=f_end; ++f_it, ++face)
1698 {
1699 unsigned int cnt = 0;
1700 first[face] = idx;
1701
1702
1703 for (fv_it=mesh_.cfv_iter(*f_it); fv_it.is_valid(); ++fv_it, ++idx, ++cnt)
1704 {
1705 pickVertexBuf_[idx] = mesh_.point(*fv_it);
1706 pickColorBuf_[idx] = _state.pick_get_name_color (f_it->idx());
1707 }
1708 count[face] = cnt;
1709 }
1710
1711 ACG::GLState::vertexPointer (&pickVertexBuf_[0]);
1712 ACG::GLState::colorPointer(&pickColorBuf_[0]);
1713
1714 glMultiDrawArrays(GL_POLYGON, &first[0], &count[0], mesh_.n_faces());
1715
1716 }
1717
1718 if (anyList_)
1719 {
1720 glEndList ();
1721 glNewList (anyList_+1, GL_COMPILE);
1722 }
1723
1724 ACG::GLState::depthFunc(GL_LEQUAL);
1725
1726 // edges
1727 idx = 0;
1728 for (; e_it!=e_end; ++e_it)
1729 {
1730 pickColorBuf_[idx] = _state.pick_get_name_color (mesh_.n_faces() + e_it->idx());
1731 pickColorBuf_[idx+1] = _state.pick_get_name_color (mesh_.n_faces() + e_it->idx());
1732 pickVertexBuf_[idx] = mesh_.point(mesh_.to_vertex_handle(mesh_.halfedge_handle(*e_it, 0)));
1733 pickVertexBuf_[idx+1] = mesh_.point(mesh_.to_vertex_handle(mesh_.halfedge_handle(*e_it, 1)));
1734 idx += 2;
1735 }
1736
1737 ACG::GLState::vertexPointer (&pickVertexBuf_[0]);
1738 ACG::GLState::colorPointer(&pickColorBuf_[0]);
1739
1740 glDrawArrays(GL_LINES, 0, mesh_.n_edges() * 2);
1741
1742 if (anyList_)
1743 {
1744 ACG::GLState::depthFunc(prev_depth);
1745 glEndList ();
1746 glNewList (anyList_+2, GL_COMPILE);
1747 ACG::GLState::depthFunc(GL_LEQUAL);
1748 }
1749
1750 // vertices
1751 idx = 0;
1752 for (; v_it!=v_end; ++v_it, ++idx, ++vidx)
1753 {
1754 pickColorBuf_[idx] = _state.pick_get_name_color (vidx);
1755 pickVertexBuf_[idx] = mesh_.point(*v_it);
1756 }
1757
1758 ACG::GLState::vertexPointer (&pickVertexBuf_[0]);
1759 ACG::GLState::colorPointer(&pickColorBuf_[0]);
1760
1761 glDrawArrays(GL_POINTS, 0, mesh_.n_vertices());
1762
1763 ACG::GLState::disableClientState(GL_COLOR_ARRAY);
1764 ACG::GLState::disableClientState(GL_VERTEX_ARRAY);
1765 }
1766 else
1767 {
1768 // faces
1769 if (mesh_.is_trimesh())
1770 {
1771 for (; f_it!=f_end; ++f_it)
1772 {
1773 // set index
1774 _state.pick_set_name (f_it->idx());
1775
1776 glBegin(GL_TRIANGLES);
1777
1778 fv_it=mesh_.cfv_iter(*f_it);
1779 glVertex(mesh_.point(*fv_it)); ++fv_it;
1780 glVertex(mesh_.point(*fv_it)); ++fv_it;
1781 glVertex(mesh_.point(*fv_it));
1782 glEnd();
1783 }
1784 }
1785 else
1786 {
1787 for (; f_it!=f_end; ++f_it)
1788 {
1789 // set index
1790 _state.pick_set_name (f_it->idx());
1791
1792 glBegin(GL_POLYGON);
1793
1794 for (fv_it=mesh_.cfv_iter(*f_it); fv_it.is_valid(); ++fv_it)
1795 glVertex(mesh_.point(*fv_it));
1796
1797 glEnd();
1798 }
1799 }
1800
1801 if (anyList_)
1802 {
1803 ACG::GLState::depthFunc(prev_depth);
1804 glEndList ();
1805 glNewList (anyList_+1, GL_COMPILE);
1806 }
1807
1808 ACG::GLState::depthFunc(GL_LEQUAL);
1809
1810 // edges
1811 for (; e_it!=e_end; ++e_it)
1812 {
1813 _state.pick_set_name (mesh_.n_faces() + e_it->idx());
1814 glBegin(GL_LINES);
1815 glVertex(mesh_.point(mesh_.to_vertex_handle(mesh_.halfedge_handle(*e_it, 0))));
1816 glVertex(mesh_.point(mesh_.to_vertex_handle(mesh_.halfedge_handle(*e_it, 1))));
1817 glEnd();
1818 }
1819
1820 if (anyList_)
1821 {
1822 ACG::GLState::depthFunc(prev_depth);
1823 glEndList ();
1824 glNewList (anyList_+2, GL_COMPILE);
1825 ACG::GLState::depthFunc(GL_LEQUAL);
1826 }
1827
1828 // vertices
1829 for (; v_it!=v_end; ++v_it, ++vidx)
1830 {
1831 _state.pick_set_name (vidx);
1832 glBegin(GL_POINTS);
1833 glVertex(mesh_.point(*v_it));
1834 glEnd();
1835 }
1836 }
1837
1838 ACG::GLState::depthFunc(prev_depth);
1839
1840 if (anyList_)
1841 {
1842 glEndList ();
1843 glCallList (anyList_);
1844 glCallList (anyList_+1);
1845 glCallList (anyList_+2);
1846 }
1847}
1848
1849//----------------------------------------------------------------------------
1850
1851template<class Mesh>
1852void
1853MeshNodeDeprecatedT<Mesh>::
1854update_pick_buffers ()
1855{
1856 unsigned int nfv = 0;
1857 if (mesh_.is_trimesh())
1858 nfv = mesh_.n_faces() * 3;
1859 else
1860 {
1861 // count number of vertices we need for faces in our buffer
1862 typename Mesh::ConstFaceIter f_it(mesh_.faces_sbegin()),
1863 f_end(mesh_.faces_end());
1864 typename Mesh::ConstFaceVertexIter fv_it;
1865 for (; f_it!=f_end; ++f_it)
1866 {
1867 for (fv_it=mesh_.cfv_iter(*f_it); fv_it.is_valid(); ++fv_it)
1868 nfv++;
1869 }
1870 }
1871
1872 pickVertexBuf_.resize (std::max(mesh_.n_vertices(), std::max(mesh_.n_edges() * 2, size_t(nfv))));
1873 pickColorBuf_.resize (std::max(mesh_.n_vertices(), std::max(mesh_.n_edges() * 2, size_t(nfv))));
1874}
1875
1876//=============================================================================
1877} // namespace SceneGraph
1878} // namespace ACG
1879#endif // DOXY_IGNORE_THIS
1880//=============================================================================
static void disableClientState(GLenum _cap)
replaces glDisableClientState, supports locking
Definition GLState.cc:1584
static void colorPointer(GLint _size, GLenum _type, GLsizei _stride, const GLvoid *_pointer)
replaces glColorPointer, supports locking
Definition GLState.cc:2005
static void vertexPointer(GLint _size, GLenum _type, GLsizei _stride, const GLvoid *_pointer)
replaces glVertexPointer, supports locking
Definition GLState.cc:1961
static void enable(GLenum _cap, bool _warnRemoved=true)
replaces glEnable, but supports locking
Definition GLState.cc:1507
static void bindBufferARB(GLenum _target, GLuint _buffer)
same function as bindBuffer
Definition GLState.hh:579
static void bindTexture(GLenum _target, GLuint _buffer)
replaces glBindTexture, supports locking
Definition GLState.cc:1911
static void normalPointer(GLenum _type, GLsizei _stride, const GLvoid *_pointer)
replaces glNormalPointer, supports locking
Definition GLState.cc:1983
static void enableClientState(GLenum _cap)
replaces glEnableClientState, supports locking
Definition GLState.cc:1570
static void depthRange(GLclampd _zNear, GLclampd _zFar)
replaces glDepthRange, supports locking
Definition GLState.cc:1757
static void texcoordPointer(GLint _size, GLenum _type, GLsizei _stride, const GLvoid *_pointer)
replaces glTexcoordPointer, supports locking
Definition GLState.cc:2027
static void disable(GLenum _cap, bool _warnRemoved=true)
replaces glDisable, but supports locking
Definition GLState.cc:1527
static void shadeModel(GLenum _mode)
replaces glShadeModel, supports locking
Definition GLState.cc:1729
const GLenum & depthFunc() const
get glDepthFunc() that is supposed to be active
Definition GLState.cc:941
bool is_valid() const
The handle is valid iff the index is not negative.
Definition Handles.hh:72
void reset()
reset handle to be invalid
Definition Handles.hh:75
Kernel::ConstFaceIter ConstFaceIter
Scalar type.
Definition PolyMeshT.hh:151
Kernel::ConstFaceHalfedgeIter ConstFaceHalfedgeIter
Circulator.
Definition PolyMeshT.hh:178
Kernel::ConstFaceVertexIter ConstFaceVertexIter
Circulator.
Definition PolyMeshT.hh:177
Kernel::Normal Normal
Normal type.
Definition PolyMeshT.hh:114
Kernel::TexCoord2D TexCoord2D
TexCoord2D type.
Definition PolyMeshT.hh:120
Kernel::ConstEdgeIter ConstEdgeIter
Scalar type.
Definition PolyMeshT.hh:150
Kernel::ConstVertexIter ConstVertexIter
Scalar type.
Definition PolyMeshT.hh:148
Kernel::Point Point
Coordinate type.
Definition PolyMeshT.hh:112
vector_type & maximize(const vector_type &_rhs)
maximize values: same as *this = max(*this, _rhs), but faster
Definition Vector11T.hh:588
vector_type & minimize(const vector_type &_rhs)
minimize values: same as *this = min(*this, _rhs), but faster
Definition Vector11T.hh:560
@ PICK_EDGE
picks edges (may not be implemented for all nodes)
Definition PickTarget.hh:80
@ PICK_ANYTHING
pick any of the prior targets (should be implemented for all nodes)
Definition PickTarget.hh:84
@ PICK_FRONT_VERTEX
picks only visible front verices (may not be implemented for all nodes)
Definition PickTarget.hh:89
@ PICK_FACE
picks faces (should be implemented for all nodes)
Definition PickTarget.hh:78
@ PICK_VERTEX
picks verices (may not be implemented for all nodes)
Definition PickTarget.hh:82
@ PICK_FRONT_EDGE
picks only visible front edges (may not be implemented for all nodes)
Definition PickTarget.hh:87
Namespace providing different geometric functions concerning angles.
void glColor(const Vec3f &_v)
Wrapper: glColor for Vec3f.
Definition gl.hh:144
void glNormal(const Vec3f &_n)
Wrapper: glNormal for Vec3f.
Definition gl.hh:135
void glVertex(const Vec2i &_v)
Wrapper: glVertex for Vec2i.
Definition gl.hh:95
void glCheckErrors()
Definition GLError.hh:96