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
StatusNodesT.cc
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 * $Revision: 21134 $ *
45 * $Author: moeller $ *
46 * $Date: 2015-08-21 13:22:18 +0200 (Fri, 21 Aug 2015) $ *
47 * *
48 \*===========================================================================*/
49
50
51
52
53 //=============================================================================
54 //
55 // CLASS StatusNodeT - IMPLEMENTATION
56 //
57 //=============================================================================
58
59
60 #define ACG_STATUS_NODES_C
61
62
63 //== INCLUDES =================================================================
64
65
66 #include "StatusNodesT.hh"
67 #include "../GL/gl.hh"
68
69 //== NAMESPACES ===============================================================
70
71
72 namespace ACG {
73 namespace SceneGraph {
74
75
76 //== IMPLEMENTATION ==========================================================
77
78 template <class Mesh, class Mod>
79 StatusNodeT<Mesh, Mod>::
80 StatusNodeT( const Mesh& _mesh,
81 BaseNode* _parent,
82 const std::string& _name )
83 : BaseClass(_parent, _name), mesh_(_mesh),
84 drawMesh_(NULL),
85 bbMin_(FLT_MAX, FLT_MAX, FLT_MAX),
86 bbMax_(-FLT_MAX, -FLT_MAX, -FLT_MAX),
87 invalidGeometry_(true),
88 vertexIndexInvalid_(true),
89 halfedgeCacheInvalid_(true),
90 edgeIndexInvalid_(true),
91 faceIndexInvalid_(true)
92 {
93 this->set_line_width(3);
94 this->set_point_size(5);
95 }
96
97
98 //----------------------------------------------------------------------------
99
100
101 template <class Mesh, class Mod>
102 void
103 StatusNodeT<Mesh, Mod>::
104 boundingBox(Vec3d& _bbMin, Vec3d& _bbMax)
105 {
106 _bbMin.minimize(bbMin_);
107 _bbMax.maximize(bbMax_);
108 }
109
110
111 //----------------------------------------------------------------------------
112
113
114 template <class Mesh, class Mod>
115 DrawModes::DrawMode
116 StatusNodeT<Mesh, Mod>::
117 availableDrawModes() const
118 {
119 return (DrawModes::POINTS |
120 DrawModes::WIREFRAME |
121 DrawModes::EDGES |
122 DrawModes::SOLID_FLAT_SHADED);
123 }
124
125
126 //----------------------------------------------------------------------------
127
128
129 template <class Mesh, class Mod>
130 void
131 StatusNodeT<Mesh, Mod>::
132 update_cache()
133 {
134 if (invalidGeometry_) {
135 bbMin_ = Vec3d(FLT_MAX, FLT_MAX, FLT_MAX);
136 bbMax_ = Vec3d(-FLT_MAX, -FLT_MAX, -FLT_MAX);
137
138 typename Mesh::ConstVertexIter v_it(mesh_.vertices_sbegin()), v_end(mesh_.vertices_end());
139
140 for (; v_it != v_end; ++v_it) {
141 bbMin_.minimize(mesh_.point(*v_it));
142 bbMax_.maximize(mesh_.point(*v_it));
143 }
144
145 invalidGeometry_ = false;
146 }
147
148 /*
149 * Hack: Force rebuild of buffers so that mapVertexToVBOIndex call doesn't SEGFAULT.
150 */
151 if (vertexIndexInvalid_ || edgeIndexInvalid_ || halfedgeCacheInvalid_ || faceIndexInvalid_)
152 if (drawMesh_)
153 drawMesh_->getVBO();
154
155 // Update the indices for selected vertices
156 if (vertexIndexInvalid_) {
157 v_cache_.clear();
158 v_cache_.reserve(mesh_.n_vertices()/4);
159
160 typename Mesh::ConstVertexIter v_it(mesh_.vertices_sbegin()), v_begin(mesh_.vertices_sbegin()), v_end(mesh_.vertices_end());
161 for (v_it = v_begin; v_it != v_end; ++v_it) {
162 if (this->is_vertex_selected(mesh_, *v_it)) {
163 unsigned int vertexIndex = v_it->idx();
164 // use correct index for vbo, if available
165 v_cache_.push_back(drawMesh_ ? drawMesh_->mapVertexToVBOIndex(vertexIndex) : vertexIndex);
166 }
167 }
168 std::vector<unsigned int>(v_cache_.begin(), v_cache_.end()).swap(v_cache_);
169 vertexIndexInvalid_ = false;
170 }
171
172 // Update index list of selected edges
173 if (edgeIndexInvalid_) {
174
175 e_cache_.clear();
176 e_cache_.reserve(mesh_.n_edges()/4);
177
178 typename Mesh::ConstEdgeIter e_it(mesh_.edges_sbegin()), e_begin(mesh_.edges_sbegin()), e_end(mesh_.edges_end());
179 for (e_it = e_begin; e_it != e_end; ++e_it) {
180 if (this->is_edge_selected(mesh_, *e_it)) {
181 typename Mesh::VertexHandle vh = mesh_.to_vertex_handle(mesh_.halfedge_handle(*e_it, 0));
182 unsigned int vidx = vh.idx();
183
184 e_cache_.push_back(drawMesh_ ? drawMesh_->mapVertexToVBOIndex(vidx) : vidx);
185
186 vh = mesh_.to_vertex_handle(mesh_.halfedge_handle(*e_it, 1));
187 vidx = vh.idx();
188
189 e_cache_.push_back(drawMesh_ ? drawMesh_->mapVertexToVBOIndex(vidx) : vidx);
190 }
191 }
192
193 std::vector<unsigned int>(e_cache_.begin(), e_cache_.end()).swap(e_cache_);
194 edgeIndexInvalid_ = false;
195 }
196
197
198 // Update index list of selected halfedges
199 if (halfedgeCacheInvalid_) {
200
201 he_points_.clear();
202 he_points_.reserve(mesh_.n_halfedges()/4);
203 he_normals_.clear();
204 he_normals_.reserve(he_points_.size());
205
206 typename Mesh::ConstHalfedgeIter he_it(mesh_.halfedges_sbegin()), he_begin(mesh_.halfedges_sbegin()), he_end(mesh_.halfedges_end());
207 for (he_it = he_begin; he_it != he_end; ++he_it) {
208 if (this->is_halfedge_selected(mesh_, *he_it)) {
209 // add vertices
210 he_points_.push_back(halfedge_point(*he_it));
211 he_points_.push_back(halfedge_point(mesh_.prev_halfedge_handle(*he_it)));
212
213 // add normals
214 FaceHandle fh;
215 if (!mesh_.is_boundary(*he_it))
216 fh = mesh_.face_handle(*he_it);
217 else
218 fh = mesh_.face_handle(mesh_.opposite_halfedge_handle(*he_it));
219
220 he_normals_.push_back(mesh_.normal(fh));
221 he_normals_.push_back(mesh_.normal(fh));
222 }
223 }
224
225 std::vector<Point>(he_points_.begin(), he_points_.end()).swap(he_points_);
226 std::vector<Normal>(he_normals_.begin(), he_normals_.end()).swap(he_normals_);
227 halfedgeCacheInvalid_ = false;
228 }
229
230
231 // update index list of selected faces
232 if (faceIndexInvalid_) {
233
234 fh_cache_.clear(); //constant time, facehandle is trivially destructible
235 fh_cache_.reserve(mesh_.n_faces()/4);// maximum 2 new allocations will be performed using push_back
236
237 typename Mesh::ConstFaceIter f_it(mesh_.faces_sbegin()), f_begin(mesh_.faces_sbegin()), f_end(mesh_.faces_end());
238 for (f_it = f_begin; f_it != f_end; ++f_it)
239 if (this->is_face_selected(mesh_, *f_it))
240 fh_cache_.push_back(*f_it);
241
242 std::vector<FaceHandle>(fh_cache_.begin(), fh_cache_.end()).swap(fh_cache_);//shrink to fit
243
244 if (mesh_.is_trimesh())
245 {
246 f_cache_.resize(fh_cache_.size()*3);
247 for (size_t i = 0; i < fh_cache_.size(); ++i)
248 {
249 typename Mesh::ConstFaceVertexIter fv_it = mesh_.cfv_iter(fh_cache_[i]);
250 unsigned int vidx = fv_it->idx();
251 f_cache_[i*3] = (drawMesh_ ? drawMesh_->mapVertexToVBOIndex(vidx) : vidx);
252
253 ++fv_it;
254 vidx = fv_it->idx();
255 f_cache_[i*3+1] = (drawMesh_ ? drawMesh_->mapVertexToVBOIndex(vidx) : vidx);
256
257 ++fv_it;
258 vidx = fv_it->idx();
259 f_cache_[i*3+2] = (drawMesh_ ? drawMesh_->mapVertexToVBOIndex(vidx) : vidx);
260 }
261 }
262 else {
263 // triangulate poly-list
264 poly_cache_.clear();
265 poly_cache_.reserve(fh_cache_.size()*4);
266
267 typename std::vector<FaceHandle>::const_iterator fh_it(fh_cache_.begin()), fh_end(fh_cache_.end());
268 for (fh_it = fh_cache_.begin(); fh_it != fh_end; ++fh_it) {
269 typename Mesh::CFVIter fv_it = mesh_.cfv_iter(*fh_it);
270
271 // 1. polygon vertex
272 unsigned int v0 = fv_it->idx();
273
274 // go to next vertex
275 ++fv_it;
276 unsigned int vPrev = fv_it->idx();
277 ++fv_it;
278
279 // create triangle fans pointing towards v0
280 for (; fv_it.is_valid(); ++fv_it) {
281 poly_cache_.push_back(drawMesh_ ? drawMesh_->mapVertexToVBOIndex(v0) : v0);
282 poly_cache_.push_back(drawMesh_ ? drawMesh_->mapVertexToVBOIndex(vPrev) : vPrev);
283
284 vPrev = fv_it->idx();
285 poly_cache_.push_back(drawMesh_ ? drawMesh_->mapVertexToVBOIndex(vPrev) : vPrev);
286 }
287 }
288
289 std::vector<unsigned int>(poly_cache_.begin(), poly_cache_.end()).swap(poly_cache_);//shrink to fit
290 }
291
292
293 faceIndexInvalid_ = false;
294 }
295
296 }
297
298
299 //----------------------------------------------------------------------------
300
301
302 template <class Mesh, class Mod>
303 void
304 StatusNodeT<Mesh, Mod>::
305 draw(GLState& _state, const DrawModes::DrawMode& _drawMode)
306 {
307 // Call updater function before doing anything
308 update_cache();
309
310 // using static bitflags for drawmodes is no longer recommended
311 // read from properties instead:
312
313 bool shaded = false;
314 bool smooth = false;
315 bool
316 wires = ((this->drawMode() == DrawModes::DEFAULT) ||
317 this->drawMode().getLayerIndexByPrimitive(DrawModes::PRIMITIVE_WIREFRAME) >= 0 ||
318 _drawMode.getLayerIndexByPrimitive(DrawModes::PRIMITIVE_WIREFRAME) >= 0),
319 points = ((this->drawMode() == DrawModes::DEFAULT) ||
320 this->drawMode().getLayerIndexByPrimitive(DrawModes::PRIMITIVE_POINT) >= 0 ||
321 _drawMode.getLayerIndexByPrimitive(DrawModes::PRIMITIVE_POINT) >= 0),
322 edges = (this->drawMode() == DrawModes::DEFAULT ||
323 this->drawMode().getLayerIndexByPrimitive(DrawModes::PRIMITIVE_EDGE) >= 0 ||
324 _drawMode.getLayerIndexByPrimitive(DrawModes::PRIMITIVE_EDGE) >= 0),
325 halfedges = ((this->drawMode() == DrawModes::DEFAULT) ||
326 this->drawMode().getLayerIndexByPrimitive(DrawModes::PRIMITIVE_HALFEDGE) >= 0 ||
327 _drawMode.getLayerIndexByPrimitive(DrawModes::PRIMITIVE_HALFEDGE) >= 0),
328 faces = ((this->drawMode() == DrawModes::DEFAULT) ||
329 this->drawMode().getLayerIndexByPrimitive(DrawModes::PRIMITIVE_POLYGON) >= 0 ||
330 _drawMode.getLayerIndexByPrimitive(DrawModes::PRIMITIVE_POLYGON) >= 0);
331
332 for (unsigned int i = 0; i < _drawMode.getNumLayers(); ++i)
333 {
334 const DrawModes::DrawModeProperties* props = _drawMode.getLayer(i);
335
336 if (props->lighting())
337 shaded = true;
338
339 if (props->normalSource() == DrawModes::NORMAL_PER_VERTEX ||
340 props->normalSource() == DrawModes::NORMAL_PER_HALFEDGE)
341 smooth = true;
342 }
343
344 // force shaded selections
345 shaded = true;
346
347
348 GLenum prev_depth = _state.depthFunc();
349
350 ACG::GLState::depthFunc(GL_LEQUAL);
351
352 if (shaded) ACG::GLState::enable(GL_LIGHTING);
353 else ACG::GLState::disable(GL_LIGHTING);
354
355 if (smooth) ACG::GLState::shadeModel(GL_SMOOTH);
356 else ACG::GLState::shadeModel(GL_FLAT);
357
358 if (drawMesh_)
359 {
360 ACG::GLState::bindBuffer(GL_ARRAY_BUFFER, drawMesh_->getVBO());
361 drawMesh_->getVertexDeclaration()->activateFixedFunction();
362
363 // disable unwanted attributes from drawmesh vbo
364 ACG::GLState::disableClientState(GL_COLOR_ARRAY);
365 ACG::GLState::disableClientState(GL_TEXTURE_COORD_ARRAY);
366
367 ACG::GLState::disable(GL_TEXTURE_2D);
368 ACG::GLState::bindTexture(GL_TEXTURE_2D, 0);
369 }
370 else
371 {
372 // use buffers from open mesh
373 if (shaded && mesh_.has_vertex_normals()) {
374 ACG::GLState::enableClientState(GL_NORMAL_ARRAY);
375 ACG::GLState::normalPointer(mesh_.vertex_normals());
376 }
377
378 ACG::GLState::enableClientState(GL_VERTEX_ARRAY);
379 ACG::GLState::vertexPointer(mesh_.points());
380 }
381
382
383 // points
384 if (points)
385 draw_points();
386
387
388 // edges
389 if (edges)
390 draw_edges();
391
392
393 if (shaded && !smooth)
394 ACG::GLState::disableClientState(GL_NORMAL_ARRAY);
395
396
397 // faces
398 if (faces) {
399 if (wires) {
400 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
401 draw_faces(smooth);
402 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
403 } else {
404
405 glPushAttrib( GL_ENABLE_BIT );
406
407 ACG::GLState::enable(GL_POLYGON_OFFSET_FILL);
408
409 glPolygonOffset(0.001f, 0.0f);
410 draw_faces(smooth);
411
412 glPopAttrib();
413 }
414 }
415
416 // disable gpu buffer for halfedges
417 ACG::GLState::bindBuffer(GL_ARRAY_BUFFER, 0);
418 ACG::GLState::disableClientState(GL_NORMAL_ARRAY);
419
420
421 // half edges
422 if (halfedges)
423 draw_halfedges();
424
425 ACG::GLState::disableClientState(GL_NORMAL_ARRAY);
426 ACG::GLState::disableClientState(GL_VERTEX_ARRAY);
427
428 ACG::GLState::depthFunc(prev_depth);
429 }
430
431
432 //----------------------------------------------------------------------------
433
434
435 template <class Mesh, class Mod>
436 void
437 StatusNodeT<Mesh, Mod>::
438 draw_points()
439 {
440 if ( !v_cache_.empty() )
441 glDrawElements(GL_POINTS,
442 int( v_cache_.size() ),
443 GL_UNSIGNED_INT,
444 &v_cache_[0]);
445 }
446
447
448 //----------------------------------------------------------------------------
449
450
451 template <class Mesh, class Mod>
452 void
453 StatusNodeT<Mesh, Mod>::
454 draw_edges()
455 {
456 if ( !e_cache_.empty() )
457 glDrawElements( GL_LINES,
458 int(e_cache_.size()),
459 GL_UNSIGNED_INT,
460 &e_cache_[0]);
461 }
462
463
464 //----------------------------------------------------------------------------
465
466
467 template <class Mesh, class Mod>
468 void
469 StatusNodeT<Mesh, Mod>::
470 draw_halfedges() {
471 if ( !he_points_.empty()) {
472 ACG::GLState::enableClientState(GL_NORMAL_ARRAY);
473
474 ACG::GLState::vertexPointer(&he_points_[0]);
475
476 if ( !he_normals_.empty())
477 ACG::GLState::normalPointer(&he_normals_[0]);
478
479 glDrawArrays(GL_LINES, 0, int(he_points_.size() ) );
480 }
481
482 }
483
484
485 //----------------------------------------------------------------------------
486
487
488 template <class Mesh, class Mod>
489 void
490 StatusNodeT<Mesh, Mod>::
491 draw_faces(bool _per_vertex)
492 {
493 typename std::vector<FaceHandle>::const_iterator fh_it(fh_cache_.begin()),
494 fh_end(fh_cache_.end());
495 typename Mesh::CFVIter fv_it;
496
497
498 // TRIANGLES
499 if (mesh_.is_trimesh()) {
500
501 if (!_per_vertex) {
502 glBegin(GL_TRIANGLES);
503 for (; fh_it!=fh_end; ++fh_it) {
504 glNormal(mesh_.normal(*fh_it));
505 glVertex(mesh_.point(*(fv_it=mesh_.cfv_iter(*fh_it))));
506 glVertex(mesh_.point(*(++fv_it)));
507 glVertex(mesh_.point(*(++fv_it)));
508 }
509
510 glEnd();
511 } else {
512
513 if ( !f_cache_.empty() )
514 glDrawElements(GL_TRIANGLES,
515 int(f_cache_.size()),
516 GL_UNSIGNED_INT,
517 &f_cache_[0]);
518 }
519
520 // POLYGONS
521 } else {
522
523 if (!_per_vertex) {
524
525 for (; fh_it!=fh_end; ++fh_it) {
526 glBegin(GL_POLYGON);
527 glNormal(mesh_.normal(*fh_it));
528 for (fv_it=mesh_.cfv_iter(*fh_it); fv_it.is_valid(); ++fv_it)
529 glVertex(mesh_.point(*fv_it));
530 glEnd();
531 }
532
533 } else {
534
535 for (; fh_it!=fh_end; ++fh_it) {
536 glBegin(GL_POLYGON);
537 for (fv_it=mesh_.cfv_iter(*fh_it); fv_it.is_valid(); ++fv_it) {
538 glNormal(mesh_.normal(*fv_it));
539
540 if (drawMesh_) // map to vbo index
541 glArrayElement(drawMesh_->mapVertexToVBOIndex(fv_it->idx()));
542 else
543 glArrayElement(fv_it->idx());
544 }
545 glEnd();
546 }
547
548 }
549 }
550 }
551
552
553 //----------------------------------------------------------------------------
554
555
556 template <class Mesh, class Mod>
557 typename Mesh::Point
558 StatusNodeT<Mesh, Mod>::
559 halfedge_point(const HalfedgeHandle _heh)
560 {
561 typename Mesh::Point p = mesh_.point(mesh_.to_vertex_handle (_heh));
562 typename Mesh::Point pp = mesh_.point(mesh_.from_vertex_handle(_heh));
563 typename Mesh::Point pn = mesh_.point(mesh_.to_vertex_handle(mesh_.next_halfedge_handle(_heh)));
564
565 // typename Mesh::Point n = (p-pp)%(pn-p);
566 typename Mesh::Point fn;
567 if( !mesh_.is_boundary(_heh))
568 fn = mesh_.normal(mesh_.face_handle(_heh));
569 else
570 fn = mesh_.normal(mesh_.face_handle(mesh_.opposite_halfedge_handle(_heh)));
571
572 typename Mesh::Point upd = ((fn%(pn-p)).normalize() + (fn%(p-pp)).normalize()).normalize();
573
574 upd *= ((pn-p).norm()+(p-pp).norm())*0.08;
575
576
577 return (p+upd);
578
579 // double alpha = 0.1;
580 // // correct weighting for concave triangles (or at concave boundaries)
581 // if( (fn | n) < 0.0) alpha *=-1.0;
582
583 // return (p*(1.0-2.0*alpha) + pp*alpha + pn*alpha);
584 }
585
586 //----------------------------------------------------------------------------
587
588 template <class Mesh, class Mod>
589 void StatusNodeT<Mesh, Mod>::getRenderObjects(IRenderer* _renderer,
590 GLState& _state,
591 const DrawModes::DrawMode& _drawMode,
592 const class Material* _mat)
593 {
594 // Call updater function before doing anything
595 update_cache();
596
597 bool shaded = false,
598 points = ((this->drawMode() == DrawModes::DEFAULT) ||
599 this->drawMode().getLayerIndexByPrimitive(DrawModes::PRIMITIVE_POINT) >= 0 ||
600 _drawMode.getLayerIndexByPrimitive(DrawModes::PRIMITIVE_POINT) >= 0),
601 edges = (this->drawMode() == DrawModes::DEFAULT ||
602 this->drawMode().getLayerIndexByPrimitive(DrawModes::PRIMITIVE_EDGE) >= 0 ||
603 _drawMode.getLayerIndexByPrimitive(DrawModes::PRIMITIVE_EDGE) >= 0),
604 halfedges = ((this->drawMode() == DrawModes::DEFAULT) ||
605 this->drawMode().getLayerIndexByPrimitive(DrawModes::PRIMITIVE_HALFEDGE) >= 0 ||
606 _drawMode.getLayerIndexByPrimitive(DrawModes::PRIMITIVE_HALFEDGE) >= 0),
607 faces = ((this->drawMode() == DrawModes::DEFAULT) ||
608 this->drawMode().getLayerIndexByPrimitive(DrawModes::PRIMITIVE_POLYGON) >= 0 ||
609 _drawMode.getLayerIndexByPrimitive(DrawModes::PRIMITIVE_POLYGON) >= 0);
610
611 RenderObject ro;
612 ro.debugName = "StatusNode";
613 ro.initFromState(&_state);
614
615 ro.depthTest = true;
616 ro.depthFunc = GL_LEQUAL;
617
618 // Use the material from the underlying materialnode
619 ro.setMaterial(&MaterialNode::material());
620
621 pointVertexDecl_.clear();
622 pointVertexDecl_.addElement(GL_DOUBLE, 3, VERTEX_USAGE_POSITION, mesh_.points());
623
624 if (shaded && mesh_.has_vertex_normals())
625 pointVertexDecl_.addElement(GL_DOUBLE, 3, VERTEX_USAGE_NORMAL, mesh_.vertex_normals());
626
627 pointVertexDecl_.setVertexStride(24); // separated buffers, double3: 24 bytes
628
629
630 // draw status later than scene
631 ro.priority = 1;
632
633
634 // enable lighting
635 if (shaded)
636 ro.shaderDesc.shadeMode = SG_SHADE_GOURAUD;
637
638 if (drawMesh_)
639 {
640 ro.vertexBuffer = drawMesh_->getVBO();
641 ro.vertexDecl = drawMesh_->getVertexDeclaration();
642 }
643 else
644 ro.vertexDecl = &pointVertexDecl_;
645
646 // point list
647 if (points && !v_cache_.empty())
648 {
649 // use shaders to simulate line width
650 QString geomTemplate = ShaderProgGenerator::getShaderDir();
651 geomTemplate += "PointSize/geometry.tpl";
652
653 QString fragTemplate = ShaderProgGenerator::getShaderDir();
654 fragTemplate += "PointSize/fragment.tpl";
655
656 ro.shaderDesc.geometryTemplateFile = geomTemplate;
657 ro.shaderDesc.fragmentTemplateFile = fragTemplate;
658
659 ro.setUniform("screenSize", Vec2f((float)_state.viewport_width(), (float)_state.viewport_height()));
660 ro.setUniform("pointSize", MaterialNode::point_size());
661
662 ro.glDrawElements(GL_POINTS, static_cast<GLsizei>(v_cache_.size()), GL_UNSIGNED_INT, &v_cache_[0]);
663 _renderer->addRenderObject(&ro);
664
665 ro.shaderDesc.geometryTemplateFile = "";
666 ro.shaderDesc.fragmentTemplateFile = "";
667 }
668
669 // edge list
670 if (edges && !e_cache_.empty())
671 {
672 // use shaders to simulate line width
673 QString geomTemplate = ShaderProgGenerator::getShaderDir();
674 geomTemplate += "Wireframe/geom_line2quad.tpl";
675
676 ro.shaderDesc.geometryTemplateFile = geomTemplate;
677
678 ro.setUniform("screenSize", Vec2f((float)_state.viewport_width(), (float)_state.viewport_height()));
679 ro.setUniform("lineWidth", MaterialNode::line_width());
680
681 ro.glDrawElements(GL_LINES, static_cast<GLsizei>(e_cache_.size()), GL_UNSIGNED_INT, &e_cache_[0]);
682 _renderer->addRenderObject(&ro);
683
684 ro.shaderDesc.geometryTemplateFile = "";
685 ro.shaderDesc.fragmentTemplateFile = "";
686 }
687
688
689 if (faces)
690 {
691 if (mesh_.is_trimesh() && !f_cache_.empty())
692 {
693 ro.glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(f_cache_.size()), GL_UNSIGNED_INT, &f_cache_[0]);
694 _renderer->addRenderObject(&ro);
695 }
696 else if (!poly_cache_.empty()) //if mesh is not a triangle mesh, poly_cache is always empty
697 {
698 ro.glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(poly_cache_.size()), GL_UNSIGNED_INT, &poly_cache_[0]);
699 _renderer->addRenderObject(&ro);
700 }
701 }
702
703
704 // halfedge list
705 if (halfedges && !he_points_.empty())
706 {
707 ro.shaderDesc.shadeMode = SG_SHADE_UNLIT;
708
709 halfedgeVertexDecl_.clear();
710 halfedgeVertexDecl_.addElement(GL_DOUBLE, 3, VERTEX_USAGE_POSITION, &he_points_[0]);
711
712 ro.vertexBuffer = 0;
713 ro.vertexDecl = &halfedgeVertexDecl_;
714
715 ro.glDrawArrays(GL_LINES, 0, static_cast<GLsizei>(he_points_.size()) );
716 _renderer->addRenderObject(&ro);
717 }
718
719
720 }
721
722
723 //----------------------------------------------------------------------------
724
725 template <class Mesh, class Mod>
726 void StatusNodeT<Mesh, Mod>::updateGeometry() {
727 invalidGeometry_ = true;
728 }
729
730
731 template <class Mesh, class Mod>
732 void StatusNodeT<Mesh, Mod>::updateTopology() {
733 vertexIndexInvalid_ = true;
734 halfedgeCacheInvalid_ = true;
735 edgeIndexInvalid_ = true;
736 faceIndexInvalid_ = true;
737
738 }
739
740 template <class Mesh, class Mod>
741 void StatusNodeT<Mesh, Mod>::updateSelection() {
742 vertexIndexInvalid_ = true;
743 halfedgeCacheInvalid_ = true;
744 edgeIndexInvalid_ = true;
745 faceIndexInvalid_ = true;
746
747 }
748
749 template <class Mesh, class Mod>
750 void StatusNodeT<Mesh, Mod>::setDrawMesh(DrawMeshT<Mesh>* _drawmesh){
751 drawMesh_ = _drawmesh;
752 }
753
754
755 //=============================================================================
756 } // namespace SceneGraph
757 } // namespace ACG
758 //=============================================================================
ACG::SceneGraph::StatusNodeT::setDrawMesh
void setDrawMesh(DrawMeshT< Mesh > *_drawmesh)
Set drawmesh.
Definition: StatusNodesT.cc:750
ACG::DrawMeshT
Mesh Drawing Class.
Definition: DrawMesh.hh:172
ACG::Vec2f
VectorT< float, 2 > Vec2f
Definition: VectorT.hh:108
ACG::RenderObject::shaderDesc
ShaderGenDesc shaderDesc
Drawmode and other shader params.
Definition: RenderObject.hh:232
OpenMesh::PolyMeshT::ConstFaceVertexIter
Kernel::ConstFaceVertexIter ConstFaceVertexIter
Circulator.
Definition: PolyMeshT.hh:180
ACG
Namespace providing different geometric functions concerning angles.
Definition: DBSCANT.cc:51
ACG::SceneGraph::ACG::GLState::enable
static void enable(GLenum _cap)
replaces glEnable, but supports locking
ACG::SceneGraph::ACG::GLState::disableClientState
static void disableClientState(GLenum _cap)
replaces glDisableClientState, supports locking
ACG::SceneGraph::BaseNode
Definition: BaseNode.hh:135
ACG::VERTEX_USAGE_NORMAL
"inNormal"
Definition: VertexDeclaration.hh:72
ACG::SceneGraph::DrawModes::DrawMode::getLayerIndexByPrimitive
int getLayerIndexByPrimitive(DrawModePrimitive _type) const
search for layer with specified primitive
ACG::SceneGraph::DrawModes::DEFAULT
DrawMode DEFAULT
use the default (global) draw mode and not the node's own.
Definition: DrawModes.cc:78
ACG::SceneGraph::ACG::GLState::disable
static void disable(GLenum _cap)
replaces glDisable, but supports locking
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::RenderObject
Interface class between scenegraph and renderer.
Definition: RenderObject.hh:105
ACG::SceneGraph::MaterialNode::point_size
float point_size() const
get point size
Definition: MaterialNode.hh:456
ACG::SceneGraph::ACG::GLState::bindTexture
static void bindTexture(GLenum _target, GLuint _buffer)
replaces glBindTexture, supports locking
ACG::SceneGraph::StatusNodeT::updateGeometry
void updateGeometry()
set geometry invalid, topology and selection is kept
Definition: StatusNodesT.cc:726
ACG::RenderObject::vertexBuffer
GLuint vertexBuffer
VBO, IBO ids, ignored if VAO is provided.
Definition: RenderObject.hh:169
ACG::RenderObject::setUniform
void setUniform(const char *_name, GLint _value)
set values for int uniforms
Definition: RenderObject.cc:396
ACG::SceneGraph::DrawModes::DrawMode::getLayer
const DrawModeProperties * getLayer(unsigned int _i) const
returns the property set at layer i
ACG::SceneGraph::DrawModes::SOLID_FLAT_SHADED
DrawMode SOLID_FLAT_SHADED
draw flat shaded faces (requires face normals)
Definition: DrawModes.cc:87
ACG::RenderObject::depthFunc
GLenum depthFunc
GL_LESS, GL_LEQUAL, GL_GREATER ..
Definition: RenderObject.hh:247
ACG::RenderObject::initFromState
void initFromState(GLState *_glState)
Initializes a RenderObject instance.
Definition: RenderObject.cc:69
OpenMesh::PolyMeshT::Point
Kernel::Point Point
Coordinate type.
Definition: PolyMeshT.hh:115
ACG::SceneGraph::ACG::GLState::shadeModel
static void shadeModel(GLenum _mode)
replaces glShadeModel, supports locking
ACG::Vec3d
VectorT< double, 3 > Vec3d
Definition: VectorT.hh:127
ACG::GLState
Definition: GLState.hh:220
OpenMesh::TriMesh_ArrayKernelT< CustomTraits >
ACG::SceneGraph::StatusNodeT::update_cache
void update_cache()
Definition: StatusNodesT.cc:132
ACG::SceneGraph::ACG::GLState::depthFunc
const GLenum & depthFunc() const
get glDepthFunc() that is supposed to be active
ACG::RenderObject::vertexDecl
const VertexDeclaration * vertexDecl
Defines the vertex buffer layout, ignored if VAO is provided.
Definition: RenderObject.hh:215
ACG::IRenderer
Definition: IRenderer.hh:84
ACG::SceneGraph::DrawModes::DrawMode
Specifies a DrawMode.
Definition: DrawModes.hh:294
ACG::SceneGraph::DrawModes::DrawMode::getNumLayers
size_t getNumLayers() const
returns the layer count
ACG::SceneGraph::ACG::GLState::bindBuffer
static void bindBuffer(GLenum _target, GLuint _buffer)
replaces glBindBuffer, supports locking
ACG::GLState::viewport_width
int viewport_width() const
get viewport width
Definition: GLState.hh:825
ACG::SceneGraph::StatusNodeBaseT< Mesh, Mod,::StatusNodes_ModTraits< Mod >::StaticUsage >
ACG::SceneGraph::StatusNodeT::updateSelection
void updateSelection()
set selection invalid (Only selection changed, rest is kept)
Definition: StatusNodesT.cc:741
ACG::SceneGraph::DrawModes::DrawModeProperties
DrawModeProperties stores a set of properties that defines, how to render an object.
Definition: DrawModes.hh:183
ACG::SceneGraph::MaterialNode::material
ACG::SceneGraph::Material & material()
Get material object reference.
Definition: MaterialNode.hh:543
ACG::SceneGraph::ACG::SceneGraph::DrawModes::DrawMode::getLayerIndexByPrimitive
int getLayerIndexByPrimitive(DrawModePrimitive _type) const
search for layer with specified primitive
Definition: DrawModes.cc:632
OpenMesh::VectorT
Definition: Vector11T.hh:83
ACG::SceneGraph::DrawModes::POINTS
DrawMode POINTS
draw unlighted points using the default base color
Definition: DrawModes.cc:79
ACG::SceneGraph::DrawModes::NORMAL_PER_VERTEX
Definition: DrawModes.hh:168
ACG::VERTEX_USAGE_POSITION
"inPosition"
Definition: VertexDeclaration.hh:71
ACG::SceneGraph::StatusNodeT::updateTopology
void updateTopology()
set topology invalid (updates everything)
Definition: StatusNodesT.cc:732
ACG::glNormal
void glNormal(const Vec3f &_n)
Wrapper: glNormal for Vec3f.
Definition: gl.hh:137
ACG::IRenderer::addRenderObject
virtual void addRenderObject(RenderObject *_renderObject)
Callback for the scenegraph nodes, which send new render objects via this function.
Definition: IRenderer.cc:105
ACG::SceneGraph::ACG::GLState::normalPointer
static void normalPointer(GLenum _type, GLsizei _stride, const GLvoid *_pointer)
replaces glNormalPointer, supports locking
ACG::SceneGraph::ACG::GLState::vertexPointer
static void vertexPointer(GLint _size, GLenum _type, GLsizei _stride, const GLvoid *_pointer)
replaces glVertexPointer, supports locking
ACG::SceneGraph::DrawModes::WIREFRAME
DrawMode WIREFRAME
draw wireframe
Definition: DrawModes.cc:84
ACG::SceneGraph::StatusNodeT::StatusNodeT
StatusNodeT(const Mesh &_mesh, BaseNode *_parent=0, const std::string &_name="<StatusNode>")
constructor
Definition: StatusNodesT.cc:80
OpenMesh::PolyMeshT::VertexHandle
Kernel::VertexHandle VertexHandle
Handle for referencing the corresponding item.
Definition: PolyMeshT.hh:139
ACG::SceneGraph::DrawModes::NORMAL_PER_HALFEDGE
Definition: DrawModes.hh:169
ACG::SceneGraph::StatusNodeT::getRenderObjects
void getRenderObjects(IRenderer *_renderer, GLState &_state, const DrawModes::DrawMode &_drawMode, const class Material *_mat)
support for shader-pipeline
Definition: StatusNodesT.cc:589
ACG::SceneGraph::ACG::GLState::enableClientState
static void enableClientState(GLenum _cap)
replaces glEnableClientState, supports locking
ACG::GLState::depthFunc
const GLenum & depthFunc() const
get glDepthFunc() that is supposed to be active
Definition: GLState.cc:937
ACG::SceneGraph::Material
Definition: MaterialNode.hh:85
ACG::SceneGraph::MaterialNode::line_width
float line_width() const
get line width
Definition: MaterialNode.hh:461
ACG::SceneGraph::DrawModes::DrawModeProperties::lighting
bool lighting() const
Is lighting enabled?
Definition: DrawModes.hh:222
ACG::SceneGraph::DrawModes::EDGES
DrawMode EDGES
draw edges
Definition: DrawModes.cc:82
ACG::RenderObject::priority
int priority
Priority to allow sorting of objects.
Definition: RenderObject.hh:123
ACG::SceneGraph::StatusNodeT
Definition: StatusNodesT.hh:183
ACG::glVertex
void glVertex(const Vec2i &_v)
Wrapper: glVertex for Vec2i.
Definition: gl.hh:97
ACG::ShaderProgGenerator::getShaderDir
static QString getShaderDir()
Definition: ShaderGenerator.cc:2406
ACG::GLState::viewport_height
int viewport_height() const
get viewport height
Definition: GLState.hh:827