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