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
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>
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 
109 }
110 
111 //----------------------------------------------------------------------------
112 
113 template <class BSplineCurve>
114 void
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
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;
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
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
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
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>
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
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
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
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
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
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
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
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
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
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
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
790 {
791  create_knot_selection_texture(_state);
792  knotVectorSelectionTexture_valid_ = true;
793 }
794 
795 //----------------------------------------------------------------------------
796 
797 template <class BSplineCurve>
798 void
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
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
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
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
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
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
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
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
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
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 //=============================================================================
vector_type & maximize(const vector_type &_rhs)
maximize values: same as *this = max(*this, _rhs), but faster
Definition: Vector11T.hh:563
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
DrawMode WIREFRAME
draw wireframe
Definition: DrawModes.cc:78
Namespace providing different geometric functions concerning angles.
void clearTextures()
disables texture support and removes all texture types
void setupShaderGenFromDrawmode(const SceneGraph::DrawModes::DrawModeProperties *_props)
Fills out ShaderGenDesc parameters based on Drawmode properties.
void pick_init_texturing()
generate index and setup texture parameters
void create_cp_selection_texture(GLState &_state)
creates texture to put onto nurbs curve for visualization of control point selection ...
void drawTexturedCurve(GLState &_state, GLuint _texture_idx)
renders a textured cuve using the gluNurbsRenderer to vilualize either the control point ot the knot ...
Vec4uc pick_get_name_color(size_t _idx)
Definition: GLState.cc:1068
pick any of the prior targets (should be implemented for all nodes)
Definition: PickTarget.hh:84
void push_back(BaseNode *_node)
Insert _node at the end of the list of children.
void push_modelview_matrix()
push modelview matrix
Definition: GLState.cc:1010
VectorT< float, 3 > Vec3f
Definition: VectorT.hh:119
void updateControlPointSelBuffer()
update control point selection buffer for visualization
static void enable(GLenum _cap, bool _warnRemoved=true)
replaces glEnable, but supports locking
VectorT< float, 4 > Vec4f
Definition: VectorT.hh:138
Pick spline curve or surface (picks u or u,v coords respectively)
Definition: PickTarget.hh:92
void translate(double _x, double _y, double _z, MultiplyFrom _mult_from=MULT_FROM_RIGHT)
translate by (_x, _y, _z)
Definition: GLState.cc:533
void initFromState(GLState *_glState)
Initializes a RenderObject instance.
Definition: RenderObject.cc:61
int viewport_width() const
get viewport width
Definition: GLState.hh:822
void drawFancyControlPolygon(DrawModes::DrawMode _drawMode, GLState &_state)
Renders the control polygon using cylinders and spheres to include shading effects.
size_t pick_current_index() const
Returns the current color picking index (can be used for caching)
Definition: GLState.cc:1131
float point_size() const
get point size
Definition: GLState.hh:970
float line_width() const
get line width
Definition: GLState.hh:975
auto normalize() -> decltype(*this/=std::declval< VectorT< S, DIM >>().norm())
Definition: Vector11T.hh:429
static void disable(GLenum _cap, bool _warnRemoved=true)
replaces glDisable, but supports locking
void drawFancyCurve(GLState &_state)
Renders the spline curve by sampling the curve and rendering cylinders in between the samples...
void boundingBox(Vec3d &_bbMin, Vec3d &_bbMax)
update bounding box
Interface class between scenegraph and renderer.
Definition: RenderObject.hh:98
void drawControlPolygon(DrawModes::DrawMode _drawMode, GLState &_state)
Renders the control polygon.
size_t getNumLayers() const
returns the layer count
Definition: DrawModes.cc:531
void updateCurveBuffer(int _numVertices=50)
update curve line buffer for drawing
void pick_create_texture(GLState &_state)
create texture image
VectorT< float, 2 > Vec2f
Definition: VectorT.hh:102
void setupPointRendering(float _pointSize, const Vec2f &_screenSize)
Setup rendering of circle points.
Vec3d project(const Vec3d &_point) const
project point in world coordinates to window coordinates
Definition: GLState.cc:640
void selection_init_texturing(GLuint &_texture_idx)
generate index and setup texture parameters for selection visualization
VectorT< double, 3 > Vec3d
Definition: VectorT.hh:121
void create_knot_selection_texture(GLState &_state)
creates texture to put onto nurbs curve for visualization of knotvector selection ...
static void shadeModel(GLenum _mode)
replaces glShadeModel, supports locking
const Vec4f & base_color() const
get base color (used when lighting is off)
Definition: GLState.hh:926
GLuint vertexBuffer
VBO, IBO ids, ignored if VAO is provided.
int viewport_height() const
get viewport height
Definition: GLState.hh:824
static void bindTexture(GLenum _target, GLuint _buffer)
replaces glBindTexture, supports locking
void resetLineRendering()
Reset shader template names blocked by line rendering.
virtual void addRenderObject(RenderObject *_renderObject)
Callback for the scenegraph nodes, which send new render objects via this function.
Definition: IRenderer.cc:104
Vec3d viewing_direction() const
get viewing ray
Definition: GLState.hh:848
void drawCurve(GLState &_state)
Renders the spline curve using gluNurbsRenderer.
void setupLineRendering(float _lineWidth, const Vec2f &_screenSize)
Setup rendering of thick lines.
Vec3d eye() const
get eye point
Definition: GLState.cc:886
void updateControlEdgeSelBuffer()
update control edge selection buffer for visualization
ShaderGenDesc shaderDesc
Drawmode and other shader params.
PickTarget
What target to use for picking.
Definition: PickTarget.hh:73
vector_type & minimize(const vector_type &_rhs)
minimize values: same as *this = min(*this, _rhs), but faster
Definition: Vector11T.hh:535
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
void draw(GLState &_state, const DrawModes::DrawMode &_drawMode)
draw lines and normals
GLuint indexBuffer
Use vertex array object.
void pop_modelview_matrix()
pop modelview matrix
Definition: GLState.cc:1026
const DrawModeProperties * getLayer(unsigned int _i) const
returns the property set at layer i
Definition: DrawModes.cc:535
ACG::Vec4f generateHighlightColor(ACG::Vec4f _color)
generates a color to highlight the curve from the given color
void updateControlPointBuffer()
update control point buffer for visualization
DrawModes::DrawMode availableDrawModes() const
return available draw modes
void glColor(const Vec3f &_v)
Wrapper: glColor for Vec3f.
Definition: gl.hh:134
const VertexDeclaration * vertexDecl
Defines the vertex buffer layout, ignored if VAO is provided.
void draw_textured_nurbs(GLState &_state)
draw textured nurbs patch
picks verices (may not be implemented for all nodes)
Definition: PickTarget.hh:82
DrawMode POINTS
draw unlighted points using the default base color
Definition: DrawModes.cc:73
DrawModeProperties stores a set of properties that defines, how to render an object.
Definition: DrawModes.hh:177
bool pick_set_maximum(size_t _idx)
Set the maximal number of primitives/components of your object.
Definition: GLState.cc:1051
void pick_set_name(size_t _idx)
sets the current name/color (like glLoadName(_idx))
Definition: GLState.cc:1061
void pick(GLState &_state, PickTarget _target)
picking