Developer Documentation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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
278 BSplineCurveNodeT<BSplineCurve>::
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
683 BSplineCurveNodeT<BSplineCurve>::
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
732 BSplineCurveNodeT<BSplineCurve>::
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
748 BSplineCurveNodeT<BSplineCurve>::
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
780 BSplineCurveNodeT<BSplineCurve>::
781 updateControlPointSelectionTexture(GLState& _state)
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
794 BSplineCurveNodeT<BSplineCurve>::
795 updateKnotVectorSelectionTexture(GLState& _state)
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 //=============================================================================
Pick spline curve or surface (picks u or u,v coords respectively)
Definition: BaseNode.hh:118
VectorT< float, 2 > Vec2f
Definition: VectorT.hh:108
GLuint indexBuffer
Use vertex array object.
ShaderGenDesc shaderDesc
Drawmode and other shader params.
void updateControlPointSelBuffer()
update control point selection buffer for visualization
void selection_init_texturing(GLuint &_texture_idx)
generate index and setup texture parameters for selection visualization
Namespace providing different geometric functions concerning angles.
Definition: DBSCANT.cc:51
static void enable(GLenum _cap)
replaces glEnable, but supports locking
void pick_set_name(unsigned int _idx)
sets the current name/color (like glLoadName(_idx))
Definition: GLState.cc:1057
void create_cp_selection_texture(GLState &_state)
creates texture to put onto nurbs curve for visualization of control point selection ...
PickTarget
What target to use for picking.
Definition: BaseNode.hh:99
static void disable(GLenum _cap)
replaces glDisable, but supports locking
void drawFancyCurve(GLState &_state)
Renders the spline curve by sampling the curve and rendering cylinders in between the samples...
bool pick_set_maximum(unsigned int _idx)
Set the maximal number of primitives/components of your object.
Definition: GLState.cc:1047
Vec4uc pick_get_name_color(unsigned int _idx)
Definition: GLState.cc:1064
pick any of the prior targets (should be implemented for all nodes)
Definition: BaseNode.hh:110
Interface class between scenegraph and renderer.
void setupPointRendering(float _pointSize, const Vec2f &_screenSize)
Setup rendering of circle points.
void resetLineRendering()
Reset shader template names blocked by line rendering.
static void bindTexture(GLenum _target, GLuint _buffer)
replaces glBindTexture, supports locking
GLuint vertexBuffer
VBO, IBO ids, ignored if VAO is provided.
const DrawModeProperties * getLayer(unsigned int _i) const
returns the property set at layer i
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
void updateCurveBuffer(int _numVertices=50)
update curve line buffer for drawing
void initFromState(GLState *_glState)
Initializes a RenderObject instance.
Definition: RenderObject.cc:69
VectorT< float, 4 > Vec4f
Definition: VectorT.hh:144
void push_back(BaseNode *_node)
Insert _node at the end of the list of children.
Definition: MeshNode2T.cc:294
void drawTexturedCurve(GLState &_state, GLuint _texture_idx)
renders a textured cuve using the gluNurbsRenderer to vilualize either the control point ot the knot ...
static void shadeModel(GLenum _mode)
replaces glShadeModel, supports locking
VectorT< double, 3 > Vec3d
Definition: VectorT.hh:127
DrawModes::DrawMode availableDrawModes() const
return available draw modes
void draw_textured_nurbs(GLState &_state)
draw textured nurbs patch
void glColor(const Vec3f &_v)
Wrapper: glColor for Vec3f.
Definition: gl.hh:146
picks verices (may not be implemented for all nodes)
Definition: BaseNode.hh:108
void pick(GLState &_state, PickTarget _target)
picking
void create_knot_selection_texture(GLState &_state)
creates texture to put onto nurbs curve for visualization of knotvector selection ...
void pick_create_texture(GLState &_state)
create texture image
const VertexDeclaration * vertexDecl
Defines the vertex buffer layout, ignored if VAO is provided.
size_t getNumLayers() const
returns the layer count
int viewport_width() const
get viewport width
Definition: GLState.hh:825
DrawModeProperties stores a set of properties that defines, how to render an object.
Definition: DrawModes.hh:183
float line_width() const
get line width
Definition: GLState.hh:978
VectorT< float, 3 > Vec3f
Definition: VectorT.hh:125
float point_size() const
get point size
Definition: GLState.hh:973
void drawControlPolygon(DrawModes::DrawMode _drawMode, GLState &_state)
Renders the control polygon.
DrawMode POINTS
draw unlighted points using the default base color
Definition: DrawModes.cc:79
void clearTextures()
disables texture support and removes all texture types
virtual void addRenderObject(RenderObject *_renderObject)
Callback for the scenegraph nodes, which send new render objects via this function.
Definition: IRenderer.cc:105
Vec3d viewing_direction() const
get viewing ray
Definition: GLState.hh:851
void drawFancyControlPolygon(DrawModes::DrawMode _drawMode, GLState &_state)
Renders the control polygon using cylinders and spheres to include shading effects.
ACG::Vec4f generateHighlightColor(ACG::Vec4f _color)
generates a color to highlight the curve from the given color
DrawMode WIREFRAME
draw wireframe
Definition: DrawModes.cc:84
void boundingBox(Vec3d &_bbMin, Vec3d &_bbMax)
update bounding box
void setupShaderGenFromDrawmode(const SceneGraph::DrawModes::DrawModeProperties *_props)
Fills out ShaderGenDesc parameters based on Drawmode properties.
void drawCurve(GLState &_state)
Renders the spline curve using gluNurbsRenderer.
void draw(GLState &_state, const DrawModes::DrawMode &_drawMode)
draw lines and normals
Vec3d eye() const
get eye point
Definition: GLState.cc:882
void pick_init_texturing()
generate index and setup texture parameters
void updateControlEdgeSelBuffer()
update control edge selection buffer for visualization
const Vec4f & base_color() const
get base color (used when lighting is off)
Definition: GLState.hh:929
Vec3d project(const Vec3d &_point) const
project point in world coordinates to window coordinates
Definition: GLState.cc:638
void updateControlPointBuffer()
update control point buffer for visualization
int viewport_height() const
get viewport height
Definition: GLState.hh:827
void setupLineRendering(float _lineWidth, const Vec2f &_screenSize)
Setup rendering of thick lines.