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