Developer Documentation

BSplineCurveNodeT_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 // CLASS BSplineCurveNodeT - IMPLEMENTATION
48 // Author: Ellen Dekkers <dekkers@cs.rwth-aachen.de>
49 //
50 //=============================================================================
51
52 #define ACG_BSPLINECURVENODET_C
53
54 //== INCLUDES =================================================================
55
56 #include "BSplineCurveNodeT.hh"
57 #include <ACG/GL/gl.hh>
58 #include <ACG/GL/GLError.hh>
59 #include <ACG/GL/IRenderer.hh>
60 #include <ACG/Utils/VSToolsT.hh>
61 #include <vector>
62 #include <OpenMesh/Core/Utils/vector_cast.hh>
63
64
65 //== NAMESPACES ===============================================================
66
67 namespace ACG {
68 namespace SceneGraph {
69
70 //== IMPLEMENTATION ==========================================================
71
72 //----------------------------------------------------------------------------
73
74 template <class BSplineCurve>
75 void
76 BSplineCurveNodeT<BSplineCurve>::
77 boundingBox(Vec3d& _bbMin, Vec3d& _bbMax)
78 {
79 for (unsigned int i = 0; i < bsplineCurve_.n_control_points(); ++i)
80 {
81 _bbMin.minimize(bsplineCurve_.get_control_point(i));
82 _bbMax.maximize(bsplineCurve_.get_control_point(i));
83 }
84 }
85
86 //----------------------------------------------------------------------------
87
88 template <class BSplineCurve>
89 DrawModes::DrawMode
90 BSplineCurveNodeT<BSplineCurve>::
91 availableDrawModes() const
92 {
93 /*
94 DrawModes::DrawMode drawModes(0);
95
96 drawModes |= DrawModes::POINTS;
97 drawModes |= DrawModes::WIREFRAME;
98 drawModes |= DrawModes::HIDDENLINE;
99 drawModes |= DrawModes::SOLID_SMOOTH_SHADED;
100 drawModes |= DrawModes::SOLID_FLAT_SHADED;
101 drawModes |= DrawModes::SOLID_PHONG_SHADED;
102 drawModes |= DrawModes::SOLID_SHADER;
103 drawModes |= DrawModes::SOLID_TEXTURED;
104 drawModes |= DrawModes::SOLID_1DTEXTURED;
105
106 return drawModes;*/
107
108 return (DrawModes::WIREFRAME | DrawModes::POINTS);
109 }
110
111 //----------------------------------------------------------------------------
112
113 template <class BSplineCurve>
114 void
115 BSplineCurveNodeT<BSplineCurve>::
116 draw(GLState& _state, const DrawModes::DrawMode& _drawMode)
117 {
118 glPushAttrib(GL_ENABLE_BIT);
119
120 // check if textures are still valid
121 if ( bspline_selection_draw_mode_ == CONTROLPOINT
122 && controlPointSelectionTexture_valid_ == false)
123 updateControlPointSelectionTexture(_state);
124
125 if ( bspline_selection_draw_mode_ == KNOTVECTOR
126 && knotVectorSelectionTexture_valid_ == false)
127 updateKnotVectorSelectionTexture(_state);
128
129
130 if (_drawMode & DrawModes::WIREFRAME)
131 {
132 ACG::GLState::disable( GL_CULL_FACE );
133
134 if (bspline_draw_mode_ == NORMAL)
135 {
136 ACG::GLState::disable(GL_LIGHTING);
137 }
138 else if (bspline_draw_mode_ == FANCY)
139 {
140 // ACG::GLState::enable(GL_AUTO_NORMAL);
141 // ACG::GLState::enable(GL_NORMALIZE);
142 glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
143 ACG::GLState::enable( GL_COLOR_MATERIAL );
144 ACG::GLState::enable(GL_LIGHTING);
145 ACG::GLState::shadeModel(GL_SMOOTH);
146 }
147
148 render( _state, false, _drawMode);
149 }
150 else if (_drawMode & DrawModes::POINTS)
151 {
152 ACG::GLState::disable(GL_LIGHTING);
153 ACG::GLState::shadeModel(GL_FLAT);
154
155 render( _state, false, _drawMode);
156 }
157
158
159 glPopAttrib();
160 }
161
162 //----------------------------------------------------------------------------
163
164 template <class BSplineCurve>
165 void
166 BSplineCurveNodeT<BSplineCurve>::
167 getRenderObjects( IRenderer* _renderer, GLState& _state , const DrawModes::DrawMode& _drawMode , const Material* _mat )
168 {
169 // check if textures are still valid
170 if ( bspline_selection_draw_mode_ == CONTROLPOINT
171 && controlPointSelectionTexture_valid_ == false)
172 updateControlPointSelectionTexture(_state);
173
174 if ( bspline_selection_draw_mode_ == KNOTVECTOR
175 && knotVectorSelectionTexture_valid_ == false)
176 updateKnotVectorSelectionTexture(_state);
177
178 // update vbo
179 updateCurveBuffer();
180
181 // init base object
182 RenderObject ro;
183 ro.initFromState(&_state);
184 ro.depthTest = true;
185
186 ro.vertexBuffer = curveLineVBO_.id();
187 ro.vertexDecl = &curveLineDecl_;
188
189
190 // create object for each layer
191 for (size_t i = 0; i < _drawMode.getNumLayers(); ++i)
192 {
193 const DrawModes::DrawModeProperties* props = _drawMode.getLayer(i);
194
195 ro.setupShaderGenFromDrawmode(props);
196
197 if (props->primitive() == DrawModes::PRIMITIVE_POINT)
198 {
199 ro.glDrawArrays(GL_POINTS, 0, curveLineVertices_);
200 _renderer->addRenderObject(&ro);
201 }
202 else if (props->primitive() == DrawModes::PRIMITIVE_WIREFRAME)
203 {
204 ro.glDrawArrays(GL_LINE_STRIP, 0, curveLineVertices_);
205 _renderer->addRenderObject(&ro);
206 }
207 }
208
209 // create objects for the control polygon (includes selection on the polygon)
210 if (render_control_polygon_)
211 {
212 updateControlPointBuffer();
213 updateControlPointSelBuffer();
214 updateControlEdgeSelBuffer();
215
216 ro.vertexBuffer = controlPointVBO_.id();
217 ro.vertexDecl = &controlPointDecl_;
218
219 ro.shaderDesc.shadeMode = SG_SHADE_UNLIT;
220 ro.shaderDesc.clearTextures();
221 ro.shaderDesc.vertexColors = false;
222
223
224 Vec3f highlightColor = OpenMesh::vector_cast<Vec3f, Vec4f>(generateHighlightColor(polygon_color_));
225 Vec3f polygonColor = OpenMesh::vector_cast<Vec3f, Vec4f>(polygon_color_);
226
227
228 Vec2f screenSize = Vec2f(_state.viewport_width(), _state.viewport_height());
229
230 // edge-selection
231 if (controlEdgeSelCount_)
232 {
233 ro.emissive = highlightColor;
234 ro.setupLineRendering(2.0f * _state.line_width(), screenSize);
235
236 ro.indexBuffer = controlEdgeSelIBO_.id();
237 ro.glDrawElements(GL_LINES, 2 * controlEdgeSelCount_, GL_UNSIGNED_INT, 0);
238 _renderer->addRenderObject(&ro);
239 }
240
241 // all line segments
242 ro.emissive = polygonColor;
243 ro.setupLineRendering(_state.line_width(), screenSize);
244 ro.glDrawArrays(GL_LINE_STRIP, 0, bsplineCurve_.n_control_points());
245 _renderer->addRenderObject(&ro);
246
247 ro.resetLineRendering();
248
249 // point selection
250 if (controlPointSelCount_)
251 {
252 ro.emissive = highlightColor;
253 ro.setupPointRendering(10.0f, screenSize);
254
255 ro.indexBuffer = controlPointSelIBO_.id();
256 ro.glDrawElements(GL_POINTS, controlPointSelCount_, GL_UNSIGNED_INT, 0);
257 _renderer->addRenderObject(&ro);
258 }
259
260 // all points
261 ro.emissive = polygonColor;
262 ro.setupPointRendering(_state.point_size() + 4.0f, screenSize);
263 ro.glDrawElements(GL_POINTS, bsplineCurve_.n_control_points(), GL_UNSIGNED_INT, 0);
264 _renderer->addRenderObject(&ro);
265 }
266 }
267
268 //----------------------------------------------------------------------------
269
270 template <class BSplineCurve>
271 void
272 BSplineCurveNodeT<BSplineCurve>::
273 render(GLState& _state, bool /*_fill*/, DrawModes::DrawMode _drawMode)
274 {
275 // draw the control polygon (includes selection on the polygon)
276 if (render_control_polygon_)
277 {
278 if (bspline_draw_mode_ == NORMAL)
279 drawControlPolygon(_drawMode, _state);
280 else if (bspline_draw_mode_ == FANCY)
281 drawFancyControlPolygon(_drawMode, _state);
282 }
283
284
285 // draw the spline curve itself, depending on the type of visualization
286 if ((_drawMode & DrawModes::WIREFRAME) && render_bspline_curve_)
287 {
288 if (bspline_selection_draw_mode_ == NONE)
289 {
290 if (bspline_draw_mode_ == NORMAL)
291 drawCurve(_state);
292 else
293 drawFancyCurve(_state);
294 }
295 else
296 {
297 if (bspline_selection_draw_mode_ == CONTROLPOINT) {
298 drawTexturedCurve(_state, cp_selection_texture_idx_);
299 }
300 else if (bspline_selection_draw_mode_ == KNOTVECTOR) {
301 drawTexturedCurve(_state, knot_selection_texture_idx_);
302 }
303 }
304 }
305 }
306
307 //----------------------------------------------------------------------------
308
309 template <class BSplineCurve>
310 void
311 BSplineCurveNodeT<BSplineCurve>::
312 drawCurve(GLState& /*_state*/)
313 {
314 updateCurveBuffer();
315
316 curveLineVBO_.bind();
317 curveLineDecl_.activateFixedFunction();
318
319 glDrawArrays(GL_LINE_STRIP, 0, curveLineVertices_);
320
321 curveLineDecl_.deactivateFixedFunction();
322 curveLineVBO_.unbind();
323 }
324
325 //----------------------------------------------------------------------------
326
327 template <class BSplineCurve>
328 void
329 BSplineCurveNodeT<BSplineCurve>::
330 drawFancyCurve(GLState& _state)
331 {
332 // draw the curve
333 // double cylinderRadius = _state.line_width() * 0.05;
334 double cylinderRadius = _state.line_width() * 0.2;
335
336 for (int i = 0; i < (int)curve_samples_.size() - 1; ++i)
337 {
338 Vec3d p = curve_samples_[i].first;
339 Vec3d p_next = curve_samples_[i+1].first;
340 draw_cylinder(p, p_next - p, cylinderRadius, _state);
341 }
342 }
343
344 //----------------------------------------------------------------------------
345
346 template <class BSplineCurve>
347 ACG::Vec4f
348 BSplineCurveNodeT<BSplineCurve>::
349 generateHighlightColor(ACG::Vec4f _color)
350 {
351 float c1 = _color[0]*1.5;
352 c1 = c1 > 1.0 ? 1.0 : c1;
353
354 float c2 = _color[1]*1.5;
355 c2 = c2 > 1.0 ? 1.0 : c2;
356
357 float c3 = _color[2]*1.5;
358 c3 = c3 > 1.0 ? 1.0 : c3;
359
360 return Vec4f( c1, c2, c3, _color[3]);
361 }
362
363 //----------------------------------------------------------------------------
364
365 template <class BSplineCurve>
366 void
367 BSplineCurveNodeT<BSplineCurve>::
368 drawControlPolygon(DrawModes::DrawMode _drawMode, GLState& _state)
369 {
370 updateControlPointBuffer();
371 updateControlPointSelBuffer();
372 updateControlEdgeSelBuffer();
373
374 // remember current base color
375 Vec4f base_color_old = _state.base_color();
376
377 controlPointVBO_.bind();
378 controlPointDecl_.activateFixedFunction();
379
380 // draw line segments
381 if (_drawMode & DrawModes::WIREFRAME)
382 {
383 // draw selection
384 if( bsplineCurve_.edge_selections_available())
385 {
386 // save old values
387 float line_width_old = _state.line_width();
388
389 glColor(generateHighlightColor(polygon_color_));
390 glLineWidth(2*line_width_old);
391
392 controlEdgeSelIBO_.bind();
393 glDrawElements(GL_LINES, 2 * controlEdgeSelCount_, GL_UNSIGNED_INT, 0);
394 controlEdgeSelIBO_.unbind();
395
396 glLineWidth(line_width_old);
397 }
398
399 // draw all line segments
400 glColor(polygon_color_);
401
402 // float line_width_old = _state.line_width();
403 // glLineWidth(line_width_old+2.0);
404
405
406 // draw bspline control polygon
407 glDrawArrays(GL_LINE_STRIP, 0, bsplineCurve_.n_control_points());
408
409 // glLineWidth(line_width_old);
410 }
411
412
413 // draw points
414 if ((_drawMode & DrawModes::POINTS) && render_control_polygon_)
415 {
416 // draw selection
417 if (controlPointSelCount_)
418 {
419 // save old values
420 float point_size_old = _state.point_size();
421
422 glColor(generateHighlightColor(polygon_color_));
423 glPointSize(10);
424
425 controlPointSelIBO_.bind();
426 glDrawElements(GL_POINTS, controlPointSelCount_, GL_UNSIGNED_INT, 0);
427 controlPointSelIBO_.unbind();
428
429 glPointSize(point_size_old);
430 }
431
432 // draw all points
433 glColor(polygon_color_);
434 float point_size_old = _state.point_size();
435 glPointSize(point_size_old + 4);
436
437 glDrawArrays(GL_POINTS, 0, bsplineCurve_.n_control_points());
438
439 glPointSize(point_size_old);
440 }
441
442
443 controlPointDecl_.deactivateFixedFunction();
444 controlPointVBO_.unbind();
445
446 // reset olf color
447 glColor( base_color_old );
448 }
449
450 //----------------------------------------------------------------------------
451
452 template <class BSplineCurve>
453 void
454 BSplineCurveNodeT<BSplineCurve>::
455 drawFancyControlPolygon(DrawModes::DrawMode _drawMode, GLState& _state)
456 {
457 // save old base color
458 Vec4f base_color_old = _state.base_color();
459
460 // draw line segments
461 if (_drawMode & DrawModes::WIREFRAME)
462 {
463 // double cylinderRadius = _state.line_width() * 0.05;
464 double cylinderRadius = _state.line_width() * 0.2;
465
466 // draw selection
467 if( bsplineCurve_.edge_selections_available())
468 {
469 glColor(generateHighlightColor(polygon_color_));
470
471 // draw bspline control polygon
472 for (int i = 0; i < (int)bsplineCurve_.n_control_points()-1; ++i) // #edges
473 {
474 if (bsplineCurve_.edge_selection(i))
475 {
476 Point p = bsplineCurve_.get_control_point(i);
477 Point axis = bsplineCurve_.get_control_point(i+1) - bsplineCurve_.get_control_point(i);
478 draw_cylinder(p, axis, cylinderRadius, _state);
479 }
480 }
481 }
482
483 // draw all line segments
484 glColor(polygon_color_);
485
486 // draw bspline control polygon
487 for (unsigned int i = 0; i < bsplineCurve_.n_control_points() - 1; ++i)
488 {
489 Point p = bsplineCurve_.get_control_point(i);
490 Point axis = bsplineCurve_.get_control_point(i+1) - bsplineCurve_.get_control_point(i);
491 draw_cylinder(p, axis, cylinderRadius, _state);
492 }
493 } // end of if wireframe
494
495
496 // draw points
497 if ((_drawMode & DrawModes::POINTS) && render_control_polygon_)
498 {
499 if (bsplineCurve_.n_control_points() == 0)
500 return;
501
502 // radius of sphere
503 // double sphereRadius = _state.point_size() * 0.05;
504 double sphereRadius = _state.point_size() * 0.25;
505
506 // draw selection
507 if( bsplineCurve_.controlpoint_selections_available())
508 {
509 glColor(generateHighlightColor(polygon_color_));
510
511 // draw control polygon
512 for (unsigned int i = 0; i < bsplineCurve_.n_control_points(); ++i)
513 if (bsplineCurve_.controlpoint_selection(i))
514 draw_sphere(bsplineCurve_.get_control_point(i), sphereRadius, _state, fancySphere_);
515 }
516
517 // draw all points
518 glColor(polygon_color_);
519
520 for (unsigned int i = 0; i < bsplineCurve_.n_control_points(); ++i)
521 draw_sphere(bsplineCurve_.get_control_point(i), sphereRadius, _state, fancySphere_);
522 }
523
524 // reset color
525 glColor( base_color_old );
526 }
527
528 //----------------------------------------------------------------------------
529
530 template <class BSplineCurve>
531 void
532 BSplineCurveNodeT<BSplineCurve>::
533 drawTexturedCurve(GLState& _state, GLuint _texture_idx)
534 {
535 glPushAttrib(GL_ALL_ATTRIB_BITS);
536 ACG::GLState::enable( GL_COLOR_MATERIAL );
537 glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
538
539 ACG::GLState::enable(GL_TEXTURE_2D);
540
541 ACG::GLState::bindTexture( GL_TEXTURE_2D, _texture_idx);
542
543 // blend colors (otherwise lighting does not affect the texture)
544 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
545 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
546 // avoid aliasing at patch boundaries
547 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
548 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
549 // GL_MODULATE to include lighting effects
550 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
551
552 float line_width_old = _state.line_width();
553 draw_textured_nurbs( _state);
554 glLineWidth(line_width_old);
555
556 ACG::GLState::bindTexture( GL_TEXTURE_2D, 0);
557 ACG::GLState::disable(GL_TEXTURE_2D);
558 ACG::GLState::disable( GL_COLOR_MATERIAL );
559 glPopAttrib( );
560 }
561
562 //----------------------------------------------------------------------------
563
564 template <class BSplineCurve>
565 void
566 BSplineCurveNodeT<BSplineCurve>::
567 updateGeometry()
568 {
569 invalidateCurveLine_ = true;
570 invalidateControlPointVBO_ = true;
571
572 curve_samples_.clear();
573
574 std::pair< Vec3d, Vec4f > sample;
575
576 int d = bsplineCurve_.degree();
577 int k = bsplineCurve_.n_knots();
578
579 for ( int l = d; l < k - d - 1; ++l )
580 {
581 for ( int s = 0; s <= resolution_; ++s )
582 {
583 double step = s / (float) resolution_ ;
584 double u = bsplineCurve_.get_knot( l ) + step * ( bsplineCurve_.get_knot( l+1 ) - bsplineCurve_.get_knot( l ) );
585
586 // check if highlighted
587 if ( bsplineCurve_.get_knotvector_ref()->selections_available() )
588 {
589 if ( bsplineCurve_.get_knotvector_ref()->selection(l)
590 && bsplineCurve_.get_knotvector_ref()->selection(l+1))
591 sample.second = curve_highlight_color_;
592 else
593 sample.second = curve_color_;
594 }
595 else
596 sample.second = curve_color_;
597
598 sample.first = bsplineCurve_.curvePoint(u);
599
600 curve_samples_.push_back(sample);
601 } // end of resolution iter
602 }
603 }
604
605 //----------------------------------------------------------------------------
606
607 template <class BSplineCurve>
608 void
609 BSplineCurveNodeT<BSplineCurve>::
610 pick(GLState& _state, PickTarget _target)
611 {
612 switch (_target)
613 {
614 case PICK_VERTEX:
615 {
616 _state.pick_set_maximum (bsplineCurve_.n_control_points());
617 pick_vertices(_state);
618 break;
619 }
620
621 case PICK_SPLINE:
622 {
623 _state.pick_set_maximum (pick_texture_res_ );
624 pick_spline(_state, 0);
625 break;
626 }
627
628
629 case PICK_ANYTHING:
630 {
631 _state.pick_set_maximum (bsplineCurve_.n_control_points() + pick_texture_res_);
632 pick_vertices(_state);
633 pick_spline(_state, bsplineCurve_.n_control_points());
634 break;
635 }
636
637 default:
638 _state.pick_set_maximum(1);
639 _state.pick_set_name(0);
640 break;
641 }
642 }
643
644 //----------------------------------------------------------------------------
645
646 template <class BSplineCurve>
647 void
648 BSplineCurveNodeT<BSplineCurve>::
649 pick_vertices( GLState& _state )
650 {
651 // radius in pixels
652 int psize = 7;
653
654 // _state.pick_set_name (0);
655
656 for (unsigned int i = 0; i < bsplineCurve_.n_control_points(); ++i)
657 {
658 _state.pick_set_name (i);
659
660 // compute 3d radius of sphere
661 Vec3d window_pos = _state.project( (Vec3d) bsplineCurve_.get_control_point(i));
662 int px = round( window_pos[0]);
663 int py = round( window_pos[1]);
664 double angle = acos(_state.viewing_direction(px, py).normalize()|_state.viewing_direction(px+psize, py).normalize());
665 double l = (_state.eye() - (Vec3d)bsplineCurve_.get_control_point(i)).norm();
666 double r = l*tan(angle);
667
668 // draw 3d sphere
669 draw_sphere(bsplineCurve_.get_control_point(i), r, _state, sphere_);
670 }
671 }
672
673 //----------------------------------------------------------------------------
674
675 template <class BSplineCurve >
676 void
677 BSplineCurveNodeT<BSplineCurve>::
678 pick_spline( GLState& _state, unsigned int _offset )
679 {
680 glPushAttrib(GL_ALL_ATTRIB_BITS);
681
682 ACG::GLState::enable(GL_TEXTURE_2D);
683 // ACG::GLState::enable(GL_TEXTURE_1D);
684 // ACG::GLState::enable(GL_MAP1_TEXTURE_COORD_1);
685
686
687 if( _state.pick_current_index () + _offset != pick_texture_baseidx_)
688 {
689 pick_texture_baseidx_ = _state.pick_current_index() + _offset;
690 pick_create_texture( _state);
691 }
692 else
693 {
694 // do not blend colors (else color picking breaks!)
695 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
696 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
697 // avoid aliasing at patch boundaries
698 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
699 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
700 // GL_REPLACE to avoid smearing colors (else color picking breaks!)
701 glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
702
703 ACG::GLState::bindTexture( GL_TEXTURE_2D, pick_texture_idx_);
704 // ACG::GLState::bindTexture( GL_TEXTURE_1D, pick_texture_idx_);
705 }
706
707 float line_width_old = _state.line_width();
708 glLineWidth(10);
709 draw_textured_nurbs( _state);
710 glLineWidth(line_width_old);
711
712 // ACG::GLState::bindTexture( GL_TEXTURE_1D, 0);
713 // ACG::GLState::disable(GL_TEXTURE_1D);
714 // ACG::GLState::disable(GL_MAP1_TEXTURE_COORD_1);
715
716 ACG::GLState::bindTexture( GL_TEXTURE_2D, 0);
717 ACG::GLState::disable(GL_TEXTURE_2D);
718
719 glPopAttrib( );
720 }
721
722 //----------------------------------------------------------------------------
723
724 template <class BSplineCurve>
725 void
726 BSplineCurveNodeT<BSplineCurve>::
727 draw_sphere( const Point& _p0, double _r, GLState& _state, GLSphere* _sphere)
728 {
729 // draw 3d sphere
730 _state.push_modelview_matrix();
731 _state.translate( _p0[0], _p0[1], _p0[2]);
732
733 _sphere->draw(_state,_r);
734
735 _state.pop_modelview_matrix();
736 }
737
738 //----------------------------------------------------------------------------
739
740 template <class BSplineCurve>
741 void
742 BSplineCurveNodeT<BSplineCurve>::
743 draw_cylinder( const Point& _p0, const Point& _axis, double _r, GLState& _state)
744 {
745 _state.push_modelview_matrix();
746 _state.translate(_p0[0], _p0[1], _p0[2]);
747
748 Point direction = _axis;
749 Point z_axis(0,0,1);
750 Point rot_normal;
751 double rot_angle;
752
753 direction.normalize();
754 rot_angle = acos((z_axis | direction))*180/M_PI;
755 rot_normal = ((z_axis % direction).normalize());
756
757
758 if( fabs( rot_angle ) > 0.0001 && fabs( 180 - rot_angle ) > 0.0001)
759 _state.rotate(rot_angle,rot_normal[0], rot_normal[1], rot_normal[2]);
760 else
761 _state.rotate(rot_angle,1,0,0);
762
763 cylinder_->setBottomRadius(_r);
764 cylinder_->setTopRadius(_r);
765 cylinder_->draw(_state,_axis.norm());
766
767 _state.pop_modelview_matrix();
768 }
769
770 //----------------------------------------------------------------------------
771
772 template <class BSplineCurve>
773 void
774 BSplineCurveNodeT<BSplineCurve>::
775 updateControlPointSelectionTexture(GLState& _state)
776 {
777 create_cp_selection_texture(_state);
778 controlPointSelectionTexture_valid_ = true;
779
780 // vbo containing the control points needs updating
781 invalidateControlPointSelIBO_ = true;
782 }
783
784 //----------------------------------------------------------------------------
785
786 template <class BSplineCurve>
787 void
788 BSplineCurveNodeT<BSplineCurve>::
789 updateKnotVectorSelectionTexture(GLState& _state)
790 {
791 create_knot_selection_texture(_state);
792 knotVectorSelectionTexture_valid_ = true;
793 }
794
795 //----------------------------------------------------------------------------
796
797 template <class BSplineCurve>
798 void
799 BSplineCurveNodeT<BSplineCurve>::
800 selection_init_texturing(GLuint & _texture_idx)
801 {
802 // generate texture index
803 glGenTextures( 1, &_texture_idx );
804 // bind texture as current
805 ACG::GLState::bindTexture( GL_TEXTURE_2D, _texture_idx );
806 // blend colors (otherwise lighting does not affect the texture)
807 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
808 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
809 // avoid aliasing at patch boundaries
810 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
811 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
812 // GL_MODULATE to include lighting effects
813 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
814 // unbind current texture
815 ACG::GLState::bindTexture( GL_TEXTURE_2D, 0);
816 }
817
818 //----------------------------------------------------------------------------
819
820 template <class BSplineCurve>
821 void
822 BSplineCurveNodeT<BSplineCurve>::
823 create_cp_selection_texture(GLState& /*_state*/)
824 {
825 if (bsplineCurve_.n_knots() == 0)
826 return;
827
828 if(cp_selection_texture_idx_ == 0)
829 selection_init_texturing(cp_selection_texture_idx_);
830
831 QImage b(cp_selection_texture_res_, 2, QImage::Format_ARGB32);
832
833 int degree = bsplineCurve_.degree();
834 int numKnots = bsplineCurve_.n_knots();
835
836 double minu = bsplineCurve_.get_knot( degree );
837 double maxu = bsplineCurve_.get_knot( numKnots - degree -1 );
838 double diffu = maxu - minu;
839 if (diffu == 0.0) return;
840
841 // get the colors to create the texture
842 // Vec4f curveColor = _state.base_color();
843 // Vec4f highlightColor = generateHighlightColor(curveColor);
844 Vec4f curveColor = curve_color_;
845 Vec4f highlightColor = curve_highlight_color_;
846
847
848 int texelIdx = 0;
849 for ( int m = 0; m < cp_selection_texture_res_; ++m)
850 {
851 double step_m = (double)m / (double)cp_selection_texture_res_;
852 double u = step_m * diffu;
853
854 // get the span and check which knots are selected
855 ACG::Vec2i span = bsplineCurve_.span(u);
856 // check for incomple spline
857 if (span[0] < 0 || span[1] < 0)
858 return;
859
860 float alpha = 0.0; // blends between curve and highlight colors
861 for (int i = 0; i < degree+1; ++i) // degree+1 basis functions (those in the span) contribute
862 {
863 int idx = span[0] + i;
864
865 // basis functions sum up to 1. hence, we only have to sum up those with selected control point to get the blending weight
866 if (bsplineCurve_.controlpoint_selected(idx))
867 alpha += bsplineCurve_.basisFunction(idx, degree, u);
868 }
869
870 // compute color
871 Vec4f color = curveColor * (1.0 - alpha) + highlightColor * alpha;
872
873 // fill texture
874 b.setPixel (texelIdx, 0, qRgba((int)(color[0]*255.0), (int)(color[1]*255.0), (int)(color[2]*255.0), 255));
875 b.setPixel (texelIdx, 1, qRgba((int)(color[0]*255.0), (int)(color[1]*255.0), (int)(color[2]*255.0), 255));
876
877 ++texelIdx;
878 }
879
880 // debug, output image
881 //b.save("curveCPSelectionTexture.png", "PNG");
882
883 cp_selection_texture_image_ = QGLWidget::convertToGLFormat( b );
884
885 // bind texture
886 ACG::GLState::bindTexture( GL_TEXTURE_2D, cp_selection_texture_idx_ );
887 glTexImage2D( GL_TEXTURE_2D,
888 0, GL_RGBA, cp_selection_texture_image_.width(), cp_selection_texture_image_.height(),
889 0, GL_RGBA, GL_UNSIGNED_BYTE, cp_selection_texture_image_.bits() );
890 }
891
892 //----------------------------------------------------------------------------
893
894 template <class BSplineCurve>
895 void
896 BSplineCurveNodeT<BSplineCurve>::
897 create_knot_selection_texture(GLState& /*_state*/)
898 {
899 if (bsplineCurve_.n_knots() == 0)
900 return;
901
902 if(knot_selection_texture_idx_ == 0)
903 selection_init_texturing(knot_selection_texture_idx_);
904
905 QImage b(knot_selection_texture_res_, 2, QImage::Format_ARGB32);
906
907 int degree = bsplineCurve_.degree();
908 int numKnots = bsplineCurve_.n_knots();
909
910 double minu = bsplineCurve_.get_knot( degree );
911 double maxu = bsplineCurve_.get_knot( numKnots - degree -1 );
912 double diffu = maxu - minu;
913 if (diffu == 0.0) return;
914
915 int texelIdx = 0;
916
917 // if a knot is selected, select all knots in the span of this knot, too
918 std::vector<bool> selectedKnotSpans(numKnots, false);
919 for (int i = 0; i < numKnots; ++i)
920 {
921 if (bsplineCurve_.get_knotvector_ref()->selection(i))
922 {
923 // get the span and check which knots are selected
924 ACG::Vec2i span = bsplineCurve_.span(bsplineCurve_.get_knot(i));
925 // check for incomple spline
926 if (span[0] < 0 || span[1] < 0)
927 return;
928
929 for(int j = span[0]; j <= span[1]+degree; ++j)
930 selectedKnotSpans[j] = true;
931 }
932 }
933
934 // Vec4f curveColor = _state.base_color();
935 // Vec4f highlightColor = generateHighlightColor(curveColor);
936 Vec4f curveColor = curve_color_;
937 Vec4f highlightColor = curve_highlight_color_;
938
939 for ( int m = 0; m < knot_selection_texture_res_; ++m)
940 {
941 double step_m = (double)m / (double)knot_selection_texture_res_;
942 double u = step_m * diffu;
943
944 Vec4f color;
945 Vec2i interval = bsplineCurve_.interval(u);
946 // check if highlighted
947 if (selectedKnotSpans[interval[0]] && selectedKnotSpans[interval[1]])
948 color = highlightColor;
949 else
950 color = curveColor;
951
952 // fill texture
953 b.setPixel (texelIdx, 0, qRgba((int)(color[0]*255.0), (int)(color[1]*255.0), (int)(color[2]*255.0), 255));
954 b.setPixel (texelIdx, 1, qRgba((int)(color[0]*255.0), (int)(color[1]*255.0), (int)(color[2]*255.0), 255));
955
956 ++texelIdx;
957 }
958
959 // debug, output image
960 //b.save("curveKnotSelectionTexture.png", "PNG");
961
962 knot_selection_texture_image_ = QGLWidget::convertToGLFormat( b );
963
964 // bind texture
965 ACG::GLState::bindTexture( GL_TEXTURE_2D, knot_selection_texture_idx_ );
966 glTexImage2D( GL_TEXTURE_2D,
967 0, GL_RGBA, knot_selection_texture_image_.width(), knot_selection_texture_image_.height(),
968 0, GL_RGBA, GL_UNSIGNED_BYTE, knot_selection_texture_image_.bits() );
969 }
970
971 //----------------------------------------------------------------------------
972
973 template <class BSplineCurve>
974 void
975 BSplineCurveNodeT<BSplineCurve>::
976 pick_init_texturing( )
977 {
978 pick_texture_res_ = 256;
979 pick_texture_baseidx_ = 0;
980
981 // generate texture index
982 glGenTextures( 1, &pick_texture_idx_ );
983 // bind texture as current
984 ACG::GLState::bindTexture( GL_TEXTURE_2D, pick_texture_idx_ );
985 // do not blend colors (else color picking breaks!)
986 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
987 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
988 // avoid aliasing at patch boundaries
989 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
990 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
991 // GL_REPLACE to avoid smearing colors (else color picking breaks!)
992 glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
993 // unbind current texture
994 ACG::GLState::bindTexture( GL_TEXTURE_2D, 0);
995 }
996
997 //----------------------------------------------------------------------------
998
999 template <class BSplineCurve>
1000 void
1001 BSplineCurveNodeT<BSplineCurve>::
1002 pick_create_texture( GLState& _state)
1003 {
1004 if(pick_texture_idx_ == 0)
1005 pick_init_texturing();
1006
1007 QImage b(pick_texture_res_, 2, QImage::Format_ARGB32);
1008
1009 // fill with colors
1010 int cur_idx=0;
1011 for( int i = 0; i < pick_texture_res_; ++i)
1012 {
1013 Vec4uc cur_col( _state.pick_get_name_color (cur_idx) );
1014 b.setPixel (i, 0, qRgba((int)cur_col[0], (int)cur_col[1], (int)cur_col[2], (int)cur_col[3]));
1015 b.setPixel (i, 1, qRgba((int)cur_col[0], (int)cur_col[1], (int)cur_col[2], (int)cur_col[3]));
1016 cur_idx++;
1017 }
1018
1019 /*
1020 // create stripe or checkerboard texture
1021 bool odd_row = true;
1022 bool odd_col = true;
1023 bool green = true;
1024 for( int i = 0; i < pick_texture_res_; ++i)
1025 {
1026 if (i % 20 == 0)
1027 odd_row = !odd_row;
1028
1029 odd_col = true;
1030 for( int j = 0; j < pick_texture_res_; ++j)
1031 {
1032 if (j % 20 == 0)
1033 odd_col = !odd_col;
1034
1035 // green = (odd_row && odd_col) || (!odd_row && !odd_col); // checkerboard texture
1036 green = odd_row; // stripe texture
1037 if (green)
1038 b.setPixel (i, j, qRgba(0, 255, 0, 255));
1039 else
1040 b.setPixel (i, j, qRgba(255, 0, 255, 255));
1041 }
1042 }
1043 */
1044
1045 // debug, output image
1046 // b.save("curveTexture.png", "PNG");
1047
1048 pick_texture_image_ = QGLWidget::convertToGLFormat( b );
1049
1050 // bind texture
1051 ACG::GLState::bindTexture( GL_TEXTURE_2D, pick_texture_idx_ );
1052 glTexImage2D( GL_TEXTURE_2D,
1053 0, GL_RGBA, pick_texture_image_.width(), pick_texture_image_.height(),
1054 0, GL_RGBA, GL_UNSIGNED_BYTE, pick_texture_image_.bits() );
1055 }
1056
1057 //----------------------------------------------------------------------------
1058
1059 template <class BSplineCurve>
1060 void
1061 BSplineCurveNodeT<BSplineCurve>::
1062 draw_textured_nurbs( GLState& /*_state*/)
1063 {
1064 updateCurveBuffer();
1065
1066 curveLineVBO_.bind();
1067 curveLineDecl_.activateFixedFunction();
1068
1069 glDrawArrays(GL_LINE_STRIP, 0, curveLineVertices_);
1070
1071 curveLineDecl_.deactivateFixedFunction();
1072 curveLineVBO_.unbind();
1073 }
1074
1075 //----------------------------------------------------------------------------
1076
1077 template <class BSplineCurve>
1078 void
1079 BSplineCurveNodeT<BSplineCurve>::
1080 updateCurveBuffer(int _numVertices)
1081 {
1082 if (!invalidateCurveLine_)
1083 return;
1084
1085 // create vertex declaration if uninitialized
1086 if (!curveLineDecl_.getNumElements())
1087 {
1088 curveLineDecl_.addElement(GL_FLOAT, 3, VERTEX_USAGE_POSITION);
1089 curveLineDecl_.addElement(GL_FLOAT, 1, VERTEX_USAGE_TEXCOORD);
1090 }
1091
1092 // vbo memory:
1093 // float3 pos
1094 // float texcoord
1095 std::vector<float> vboData(_numVertices * 4);
1096
1097 for (int i = 0; i < _numVertices; ++i)
1098 {
1099 // param in [0, 1]
1100 typename BSplineCurve::Scalar u01 = typename BSplineCurve::Scalar(i) / typename BSplineCurve::Scalar(_numVertices - 1);
1101
1102 // map to actual range
1103 typename BSplineCurve::Scalar u = (1 - u01) * bsplineCurve_.lower() + u01 * bsplineCurve_.upper();
1104
1105 // evaluate curve point
1106 typename BSplineCurve::Point pos = bsplineCurve_.curvePoint(u);
1107
1108 // store pos
1109 for (int k = 0; k < 3; ++k)
1110 vboData[i*4 + k] = pos[k];
1111
1112 // store texcoord
1113 vboData[i*4 + 3] = u01;
1114 }
1115
1116
1117 curveLineVBO_.del();
1118 if (_numVertices)
1119 curveLineVBO_.upload(vboData.size() * 4, &vboData[0], GL_STATIC_DRAW);
1120
1121
1122 curveLineVertices_ = _numVertices;
1123
1124 invalidateCurveLine_ = false;
1125 }
1126
1127 //----------------------------------------------------------------------------
1128
1129 template <class BSplineCurve>
1130 void
1131 BSplineCurveNodeT<BSplineCurve>::
1132 updateControlPointBuffer()
1133 {
1134 if (!invalidateControlPointVBO_)
1135 return;
1136
1137 // create vertex declaration if uninitialized
1138 if (!controlPointDecl_.getNumElements())
1139 controlPointDecl_.addElement(GL_FLOAT, 3, VERTEX_USAGE_POSITION);
1140
1141 int numCP = bsplineCurve_.n_control_points();
1142
1143 // vbo memory:
1144 // float3 pos
1145 std::vector<float> vboData(numCP * 3);
1146
1147 for (int i = 0; i < numCP; ++i)
1148 {
1149 typename BSplineCurve::Point pos = bsplineCurve_.get_control_point(i);
1150 for (int k = 0; k < 3; ++k)
1151 vboData[i*3 + k] = pos[k];
1152 }
1153
1154 controlPointVBO_.del();
1155 if (numCP)
1156 controlPointVBO_.upload(vboData.size() * 4, &vboData[0], GL_STATIC_DRAW);
1157
1158 invalidateControlPointVBO_ = false;
1159 }
1160
1161 //----------------------------------------------------------------------------
1162
1163 template <class BSplineCurve>
1164 void
1165 BSplineCurveNodeT<BSplineCurve>::
1166 updateControlPointSelBuffer()
1167 {
1168 if (!invalidateControlPointSelIBO_)
1169 return;
1170
1171 controlPointSelIBO_.del();
1172
1173 if (bsplineCurve_.controlpoint_selections_available())
1174 {
1175 int numCP = bsplineCurve_.n_control_points();
1176
1177 // count # selected points
1178 int numSel = 0;
1179 for (int i = 0; i < numCP; ++i)
1180 {
1181 if (bsplineCurve_.controlpoint_selection(i))
1182 ++numSel;
1183 }
1184
1185 // save count for draw call
1186 controlPointSelCount_ = numSel;
1187
1188
1189 if (numSel)
1190 {
1191 // create array
1192 std::vector<int> iboData(numSel);
1193 numSel = 0;
1194 for (int i = 0; i < numCP; ++i)
1195 {
1196 if (bsplineCurve_.controlpoint_selection(i))
1197 iboData[numSel++] = i;
1198 }
1199
1200 controlPointSelIBO_.upload(numSel * 4, &iboData[0], GL_STATIC_DRAW);
1201 }
1202 }
1203
1204 invalidateControlPointSelIBO_ = false;
1205 }
1206
1207 //----------------------------------------------------------------------------
1208
1209 template <class BSplineCurve>
1210 void
1211 BSplineCurveNodeT<BSplineCurve>::
1212 updateControlEdgeSelBuffer()
1213 {
1214 if (!invalidateControlEdgeSelIBO_)
1215 return;
1216
1217 controlEdgeSelIBO_.del();
1218
1219 if (bsplineCurve_.edge_selections_available())
1220 {
1221 int numCP = bsplineCurve_.n_control_points();
1222 int numE = numCP - 1;
1223
1224 // count # selected edges
1225 int numSel = 0;
1226 for (int i = 0; i < numE; ++i)
1227 {
1228 if (bsplineCurve_.edge_selection(i))
1229 ++numSel;
1230 }
1231
1232 // save count for draw call
1233 controlEdgeSelCount_ = numSel;
1234
1235 if (numSel)
1236 {
1237 // create array
1238 std::vector<int> iboData(numSel * 2);
1239 numSel = 0;
1240 for (int i = 0; i < numE; ++i)
1241 {
1242 if (bsplineCurve_.edge_selection(i))
1243 {
1244 iboData[numSel++] = i;
1245 iboData[numSel++] = (i+1)%numCP;
1246 }
1247 }
1248
1249 controlEdgeSelIBO_.upload(numSel * 4, &iboData[0], GL_STATIC_DRAW);
1250 }
1251 }
1252
1253 invalidateControlEdgeSelIBO_ = false;
1254 }
1255
1256 //----------------------------------------------------------------------------
1257
1258 /*
1259 template <class BSplineCurve>
1260 void
1261 BSplineCurveNodeT<BSplineCurve>::
1262 pick_init_texturing( )
1263 {
1264 pick_texture_res_ = 256;
1265 pick_texture_baseidx_ = 0;
1266
1267 // generate texture index
1268 glGenTextures( 1, &pick_texture_idx_ );
1269 // bind texture as current
1270 ACG::GLState::bindTexture( GL_TEXTURE_1D, pick_texture_idx_ );
1271 // do not blend colors (else color picking breaks!)
1272 glTexParameterf( GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
1273 glTexParameterf( GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
1274 // avoid aliasing at patch boundaries
1275 glTexParameterf( GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
1276 // GL_REPLACE to avoid smearing colors (else color picking breaks!)
1277 glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
1278 // unbind current texture
1279 ACG::GLState::bindTexture( GL_TEXTURE_1D, 0);
1280 }
1281
1282 //----------------------------------------------------------------------------
1283
1284 template <class BSplineCurve>
1285 void
1286 BSplineCurveNodeT<BSplineCurve>::
1287 pick_create_texture( GLState& _state)
1288 {
1289 std::cout << "[BSplineCurveNodeT] pick_create_texture" << std::endl;
1290
1291 // QImage b(pick_texture_res_, pick_texture_res_, QImage::Format_ARGB32);
1292 QImage b(pick_texture_res_, 1, QImage::Format_ARGB32);
1293
1294 std::cout << "texture of size " << b.width() << " x " << b.height() << std::endl;
1295
1296 // fill with colors
1297 int cur_idx = 0;
1298 bool green = false;
1299 for( int i = 0; i < pick_texture_res_; ++i)
1300 {
1301 Vec4uc cur_col( _state.pick_get_name_color (cur_idx) );
1302 // b.setPixel (i, 0, qRgba((int)cur_col[0], (int)cur_col[1], (int)cur_col[2], (int)cur_col[3]));
1303
1304 if (i % 10 == 0)
1305 green = !green;
1306
1307 if (green)
1308 b.setPixel (i, 0, qRgba(0, 255, 0, 255));
1309 else
1310 b.setPixel (i, 0, qRgba(255, 0, 255, 255));
1311
1312 cur_idx++;
1313 }
1314
1315 // debug, output image (usually does not look as expected :\ )
1316 b.save("1Dcurvetexture.png", "PNG");
1317
1318 pick_texture_image_ = QGLWidget::convertToGLFormat( b );
1319
1320 // bind texture
1321 ACG::GLState::bindTexture( GL_TEXTURE_1D, pick_texture_idx_ );
1322 glTexImage1D( GL_TEXTURE_1D,
1323 0, GL_RGBA, pick_texture_image_.width(),
1324 0, GL_RGBA, GL_UNSIGNED_BYTE,
1325 pick_texture_image_.bits() );
1326
1327 }
1328
1329 //----------------------------------------------------------------------------
1330
1331 template <class BSplineCurve>
1332 void
1333 BSplineCurveNodeT<BSplineCurve>::
1334 pick_draw_textured_nurbs( GLState& _state)
1335 {
1336 std::cout << "[BSplineCurveNodeT] pick_draw_textured_nurbs" << std::endl;
1337
1338 int numKnots = bsplineCurve_.n_knots();
1339 const int numCPs = bsplineCurve_.n_control_points();
1340 int order = bsplineCurve_.degree() + 1;
1341
1342 // get kntvector
1343 std::cout << "knots: " << std::flush;
1344 GLfloat *knots = new GLfloat[numKnots];
1345 for (int i = 0; i < numKnots; ++i)
1346 {
1347 knots[i] = bsplineCurve_.get_knot(i);
1348 std::cout << bsplineCurve_.get_knot(i) << ", " << std::flush;
1349 }
1350 std::cout << std::endl;
1351
1352 // get control points
1353 GLfloat *ctlpoints = new GLfloat[numCPs * 3];
1354 for (int i = 0; i < numCPs; ++i)
1355 {
1356 Vec3d p = bsplineCurve_.get_control_point(i);
1357 ctlpoints[i * 3 + 0] = (GLfloat)p[0];
1358 ctlpoints[i * 3 + 1] = (GLfloat)p[1];
1359 ctlpoints[i * 3 + 2] = (GLfloat)p[2];
1360 }
1361
1362
1363 glLineWidth(5);
1364
1365 GLUnurbsObj *theNurb;
1366 theNurb = gluNewNurbsRenderer();
1367
1368 #ifdef WIN32
1369 gluNurbsCallback(theNurb, GLU_ERROR, (void (__stdcall *)(void))(&nurbsErrorCallback) );
1370 #else
1371 gluNurbsCallback(theNurb, GLU_ERROR, (GLvoid (*)()) (&nurbsErrorCallback) );
1372 #endif
1373
1374 // draw filled
1375 gluNurbsProperty(theNurb, GLU_DISPLAY_MODE, GLU_FILL);
1376
1377 #ifdef GLU_OBJECT_PARAMETRIC_ERROR
1378 // object space -> fixed (non-adaptive) sampling
1379 gluNurbsProperty(theNurb, GLU_SAMPLING_METHOD, GLU_OBJECT_PARAMETRIC_ERROR);
1380 #else
1381 gluNurbsProperty(theNurb, GLU_SAMPLING_METHOD, GLU_PARAMETRIC_ERROR);
1382 #endif
1383
1384 gluNurbsProperty(theNurb, GLU_PARAMETRIC_TOLERANCE, 0.2);
1385
1386 // get min/max knots of domain defining patch (partition of unity)
1387 float minu( knots[bsplineCurve_.degree()]);
1388 float maxu( knots[numKnots - order]);
1389 std::cout << "minu = " << minu << ", maxu = " << maxu << std::endl;
1390
1391 // control points of 1d texture (0, 1)
1392 GLfloat tcoords[2] = {0.0, 1.0};
1393
1394 // knots of domain, over which tcoords shall be linearly interpolated
1395 // GLfloat tknots[2] = {minu, maxu};
1396 GLfloat tknots[4] = {minu, minu, maxu, maxu};
1397 // GLfloat tknots[4] = {minu/(maxu - minu), minu/(maxu - minu), maxu/(maxu - minu), maxu/(maxu - minu)};
1398
1399 // begin drawing nurbs
1400 gluBeginCurve(theNurb);
1401
1402 // first enable texture coordinate mapping
1403 gluNurbsCurve(theNurb, 4, tknots, 1, tcoords, 2, GL_MAP1_TEXTURE_COORD_1);
1404 // gluNurbsCurve(theNurb, 4, tknots, 1, &tcoords[0], 2, GL_MAP1_TEXTURE_COORD_1);
1405 // gluNurbsCurve(theNurb, numKnots, knots, 3, ctlpoints, order, GL_MAP1_TEXTURE_COORD_1);
1406
1407 // draw surface
1408 gluNurbsCurve(theNurb, numKnots, knots, 3, ctlpoints, order, GL_MAP1_VERTEX_3);
1409 gluEndCurve(theNurb);
1410
1411 gluDeleteNurbsRenderer(theNurb);
1412
1413 delete[] knots;
1414 delete[] ctlpoints;
1415 }
1416 */
1417
1418 //----------------------------------------------------------------------------
1419
1420 /*
1421 template <class BSplineCurve>
1422 void
1423 BSplineCurveNodeT<BSplineCurve>::
1424 drawDirectMode(DrawModes::DrawMode _drawMode, GLState& _state)
1425 {
1426 // draw the curve
1427 if ((_drawMode & DrawModes::WIREFRAME) && render_bspline_curve_)
1428 {
1429 // float line_width_old = _state.line_width();
1430 // glLineWidth(line_width_old + 2.0);
1431
1432 glBegin(GL_LINE_STRIP);
1433 for (unsigned int i = 0; i < curve_samples_.size(); ++i)
1434 {
1435 Vec3d pos = curve_samples_[i].first;
1436 Vec4f col = curve_samples_[i].second;
1437
1438 glColor(col);
1439 glVertex3f(pos[0], pos[1], pos[2]);
1440 }
1441 glEnd();
1442
1443 // glLineWidth(line_width_old);
1444 }
1445 }
1446 */
1447
1448 //----------------------------------------------------------------------------
1449
1450 //=============================================================================
1451 } // namespace SceneGraph
1452 } // namespace ACG
1453 //=============================================================================
ACG::SceneGraph::BSplineCurveNodeT::draw_textured_nurbs
void draw_textured_nurbs(GLState &_state)
draw textured nurbs patch
Definition: BSplineCurveNodeT_impl.hh:1062
ACG::SceneGraph::BSplineCurveNodeT::updateControlPointSelBuffer
void updateControlPointSelBuffer()
update control point selection buffer for visualization
Definition: BSplineCurveNodeT_impl.hh:1166
ACG::glColor
void glColor(const Vec3f &_v)
Wrapper: glColor for Vec3f.
Definition: gl.hh:144
ACG::RenderObject::initFromState
void initFromState(GLState *_glState)
Initializes a RenderObject instance.
Definition: RenderObject.cc:61
OpenMesh::vector_cast
void vector_cast(const src_t &_src, dst_t &_dst, GenProg::Int2Type< n >)
Cast vector type to another vector type by copying the vector elements.
Definition: vector_cast.hh:81
ACG::GLState::viewing_direction
Vec3d viewing_direction() const
get viewing ray
Definition: GLState.hh:848
ACG::GLState::pop_modelview_matrix
void pop_modelview_matrix()
pop modelview matrix
Definition: GLState.cc:1026
ACG::GLState
Definition: GLState.hh:213
ACG::GLState::point_size
float point_size() const
get point size
Definition: GLState.hh:970
ACG::SceneGraph::BSplineCurveNodeT::boundingBox
void boundingBox(Vec3d &_bbMin, Vec3d &_bbMax) override
update bounding box
Definition: BSplineCurveNodeT_impl.hh:77
ACG::GLState::viewport_width
int viewport_width() const
get viewport width
Definition: GLState.hh:822
ACG::Vec2f
VectorT< float, 2 > Vec2f
Definition: VectorT.hh:102
ACG::RenderObject::resetLineRendering
void resetLineRendering()
Reset shader template names blocked by line rendering.
Definition: RenderObject.cc:479
ACG
Namespace providing different geometric functions concerning angles.
Definition: BaseObjectData.hh:68
ACG::SceneGraph::BSplineCurveNodeT::create_cp_selection_texture
void create_cp_selection_texture(GLState &_state)
creates texture to put onto nurbs curve for visualization of control point selection ...
Definition: BSplineCurveNodeT_impl.hh:823
pybind11
Definition: PythonTypeConversions.hh:49
ACG::GLState::project
Vec3d project(const Vec3d &_point) const
project point in world coordinates to window coordinates
Definition: GLState.cc:640
ACG::Vec4f
VectorT< float, 4 > Vec4f
Definition: VectorT.hh:138
ACG::SceneGraph::BSplineCurveNodeT::drawFancyCurve
void drawFancyCurve(GLState &_state)
Renders the spline curve by sampling the curve and rendering cylinders in between the samples...
Definition: BSplineCurveNodeT_impl.hh:330
ACG::SceneGraph::ACG::GLState::disable
static void disable(GLenum _cap, bool _warnRemoved=true)
replaces glDisable, but supports locking
ACG::GLState::base_color
const Vec4f & base_color() const
get base color (used when lighting is off)
Definition: GLState.hh:926
ACG::RenderObject::shaderDesc
ShaderGenDesc shaderDesc
Drawmode and other shader params.
Definition: RenderObject.hh:225
ACG::GLState::pick_current_index
size_t pick_current_index() const
Returns the current color picking index (can be used for caching)
Definition: GLState.cc:1131
ACG::ShaderGenDesc::clearTextures
void clearTextures()
disables texture support and removes all texture types
Definition: ShaderGenerator.hh:223
OpenMesh::VectorT
Definition: Vector11T.hh:83
ACG::SceneGraph::BSplineCurveNodeT::availableDrawModes
DrawModes::DrawMode availableDrawModes() const override
return available draw modes
Definition: BSplineCurveNodeT_impl.hh:91
OpenMesh::VectorT::maximize
vector_type & maximize(const vector_type &_rhs)
maximize values: same as *this = max(*this, _rhs), but faster
Definition: Vector11T.hh:568
ACG::RenderObject::vertexBuffer
GLuint vertexBuffer
VBO, IBO ids, ignored if VAO is provided.
Definition: RenderObject.hh:162
ACG::SceneGraph::BSplineCurveNodeT::pick
void pick(GLState &_state, PickTarget _target) override
picking
Definition: BSplineCurveNodeT_impl.hh:610
ACG::GLState::pick_get_name_color
Vec4uc pick_get_name_color(size_t _idx)
Definition: GLState.cc:1068
ACG::IRenderer
Definition: IRenderer.hh:78
ACG::RenderObject::setupLineRendering
void setupLineRendering(float _lineWidth, const Vec2f &_screenSize)
Setup rendering of thick lines.
Definition: RenderObject.cc:464
SceneGraph
Definition: QtPrincipalAxisDialog.hh:67
ACG::SceneGraph::ACG::SceneGraph::BaseNode::push_back
void push_back(BaseNode *_node)
Insert _node at the end of the list of children.
Definition: MeshNode2T_impl.hh:318
ACG::VERTEX_USAGE_TEXCOORD
"inTexCoord"
Definition: VertexDeclaration.hh:67
ACG::SceneGraph::BSplineCurveNodeT::create_knot_selection_texture
void create_knot_selection_texture(GLState &_state)
creates texture to put onto nurbs curve for visualization of knotvector selection ...
Definition: BSplineCurveNodeT_impl.hh:897
ACG::SceneGraph::PickTarget
PickTarget
What target to use for picking.
Definition: PickTarget.hh:73
ACG::GLState::push_modelview_matrix
void push_modelview_matrix()
push modelview matrix
Definition: GLState.cc:1010
ACG::SceneGraph::BSplineCurveNodeT::pick_create_texture
void pick_create_texture(GLState &_state)
create texture image
Definition: BSplineCurveNodeT_impl.hh:1002
ACG::Vec3f
VectorT< float, 3 > Vec3f
Definition: VectorT.hh:119
ACG::SceneGraph::BSplineCurveNodeT::updateControlPointBuffer
void updateControlPointBuffer()
update control point buffer for visualization
Definition: BSplineCurveNodeT_impl.hh:1132
ACG::VERTEX_USAGE_POSITION
"inPosition"
Definition: VertexDeclaration.hh:65
ACG::RenderObject::setupPointRendering
void setupPointRendering(float _pointSize, const Vec2f &_screenSize)
Setup rendering of circle points.
Definition: RenderObject.cc:484
ACG::SceneGraph::PICK_ANYTHING
pick any of the prior targets (should be implemented for all nodes)
Definition: PickTarget.hh:84
ACG::GLState::pick_set_maximum
bool pick_set_maximum(size_t _idx)
Set the maximal number of primitives/components of your object.
Definition: GLState.cc:1051
ACG::SceneGraph::BSplineCurveNodeT::drawCurve
void drawCurve(GLState &_state)
Renders the spline curve using gluNurbsRenderer.
Definition: BSplineCurveNodeT_impl.hh:312
ACG::SceneGraph::PICK_VERTEX
picks verices (may not be implemented for all nodes)
Definition: PickTarget.hh:82
ACG::RenderObject::indexBuffer
GLuint indexBuffer
Use vertex array object.
Definition: RenderObject.hh:162
ACG::GLState::viewport_height
int viewport_height() const
get viewport height
Definition: GLState.hh:824
OpenMesh::VectorT::minimize
vector_type & minimize(const vector_type &_rhs)
minimize values: same as *this = min(*this, _rhs), but faster
Definition: Vector11T.hh:540
ACG::RenderObject::vertexDecl
const VertexDeclaration * vertexDecl
Defines the vertex buffer layout, ignored if VAO is provided.
Definition: RenderObject.hh:208
ACG::SceneGraph::BSplineCurveNodeT::draw
void draw(GLState &_state, const DrawModes::DrawMode &_drawMode) override
draw lines and normals
Definition: BSplineCurveNodeT_impl.hh:116
ACG::GLSphere
Definition: GLPrimitives.hh:139
ACG::SceneGraph::DrawModes::POINTS
DrawMode POINTS
draw unlighted points using the default base color
Definition: DrawModes.cc:73
ACG::SceneGraph::BSplineCurveNodeT::updateCurveBuffer
void updateCurveBuffer(int _numVertices=50)
update curve line buffer for drawing
Definition: BSplineCurveNodeT_impl.hh:1080
ACG::SceneGraph::DrawModes::DrawModeProperties
DrawModeProperties stores a set of properties that defines, how to render an object.
Definition: DrawModes.hh:177
ACG::GLState::rotate
void rotate(double _angle, double _x, double _y, double _z, MultiplyFrom _mult_from=MULT_FROM_RIGHT)
rotate around axis (_x, _y, _z) by _angle
Definition: GLState.cc:564
ACG::IRenderer::addRenderObject
virtual void addRenderObject(RenderObject *_renderObject)
Callback for the scenegraph nodes, which send new render objects via this function.
Definition: IRenderer.cc:104
ACG::SceneGraph::BSplineCurveNodeT::drawTexturedCurve
void drawTexturedCurve(GLState &_state, GLuint _texture_idx)
renders a textured cuve using the gluNurbsRenderer to vilualize either the control point ot the knot ...
Definition: BSplineCurveNodeT_impl.hh:533
ACG::SceneGraph::BSplineCurveNodeT::pick_init_texturing
void pick_init_texturing()
generate index and setup texture parameters
Definition: BSplineCurveNodeT_impl.hh:976
ACG::SceneGraph::DrawModes::DrawMode
Specifies a DrawMode.
Definition: DrawModes.hh:288
ACG::SceneGraph::DrawModes::WIREFRAME
DrawMode WIREFRAME
draw wireframe
Definition: DrawModes.cc:78
ACG::GLState::pick_set_name
void pick_set_name(size_t _idx)
sets the current name/color (like glLoadName(_idx))
Definition: GLState.cc:1061
ACG::SceneGraph::BSplineCurveNodeT::selection_init_texturing
void selection_init_texturing(GLuint &_texture_idx)
generate index and setup texture parameters for selection visualization
Definition: BSplineCurveNodeT_impl.hh:800
ACG::SceneGraph::ACG::GLState::enable
static void enable(GLenum _cap, bool _warnRemoved=true)
replaces glEnable, but supports locking
ACG::SceneGraph::PICK_SPLINE
Pick spline curve or surface (picks u or u,v coords respectively)
Definition: PickTarget.hh:92
ACG::SceneGraph::BSplineCurveNodeT::updateControlEdgeSelBuffer
void updateControlEdgeSelBuffer()
update control edge selection buffer for visualization
Definition: BSplineCurveNodeT_impl.hh:1212
ACG::RenderObject::setupShaderGenFromDrawmode
void setupShaderGenFromDrawmode(const SceneGraph::DrawModes::DrawModeProperties *_props)
Fills out ShaderGenDesc parameters based on Drawmode properties.
Definition: RenderObject.cc:137
ACG::SceneGraph::BSplineCurveNodeT::generateHighlightColor
ACG::Vec4f generateHighlightColor(ACG::Vec4f _color)
generates a color to highlight the curve from the given color
Definition: BSplineCurveNodeT_impl.hh:349
ACG::GLState::line_width
float line_width() const
get line width
Definition: GLState.hh:975
ACG::SceneGraph::DrawModes::DrawMode::getLayer
const DrawModeProperties * getLayer(unsigned int _i) const
returns the property set at layer i
Definition: DrawModes.cc:535
ACG::SceneGraph::BSplineCurveNodeT
Definition: BSplineCurveNodeT.hh:88
ACG::SceneGraph::BSplineCurveNodeT::drawFancyControlPolygon
void drawFancyControlPolygon(DrawModes::DrawMode _drawMode, GLState &_state)
Renders the control polygon using cylinders and spheres to include shading effects.
Definition: BSplineCurveNodeT_impl.hh:455
OpenMesh::VectorT::normalize
auto normalize() -> decltype(*this/=std::declval< VectorT< S, DIM >>().norm())
Definition: Vector11T.hh:434
ACG::RenderObject
Interface class between scenegraph and renderer.
Definition: RenderObject.hh:98
ACG::SceneGraph::ACG::GLState::bindTexture
static void bindTexture(GLenum _target, GLuint _buffer)
replaces glBindTexture, supports locking
ACG::SceneGraph::DrawModes::DrawMode::getNumLayers
size_t getNumLayers() const
returns the layer count
Definition: DrawModes.cc:531
ACG::SceneGraph::BSplineCurveNodeT::drawControlPolygon
void drawControlPolygon(DrawModes::DrawMode _drawMode, GLState &_state)
Renders the control polygon.
Definition: BSplineCurveNodeT_impl.hh:368
ACG::SceneGraph::ACG::GLState::shadeModel
static void shadeModel(GLenum _mode)
replaces glShadeModel, supports locking
ACG::SceneGraph::Material
Definition: MaterialNode.hh:79
ACG::GLState::eye
Vec3d eye() const
get eye point
Definition: GLState.cc:886
ACG::GLState::translate
void translate(double _x, double _y, double _z, MultiplyFrom _mult_from=MULT_FROM_RIGHT)
translate by (_x, _y, _z)
Definition: GLState.cc:533
ACG::Vec3d
VectorT< double, 3 > Vec3d
Definition: VectorT.hh:121