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