Developer Documentation
Loading...
Searching...
No Matches
ViewControlPlugin.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
45#include "ViewControlPlugin.hh"
46#include <OpenFlipper/INIFile/INIFile.hh>
47
48#include <OpenFlipper/ACGHelper/DrawModeConverter.hh>
49#include <ACG/Scenegraph/CoordsysNode.hh>
50
51#include <QWidgetAction>
52#include <QInputDialog>
53#include <QActionGroup>
54#include <QAction>
55
56#define SHOW_SELECTION "Show/Hide Selections"
57#define SHOW_AREAS "Show/Hide All Modeling Areas"
58#define SHOW_AREA "Show/Hide Modeling Area"
59#define SHOW_HANDLE "Show/Hide Handle Area"
60#define SHOW_FEATURES "Show/Hide Feature Selection"
61#define SIZE_SELECTION "Set Selection Width"
62#define SIZE_FEATURES "Set Feature Width"
63#define USEGLOBALDRAWMODE "Use Global DrawMode"
64#define SETSHADERS "Set Shader"
65
66ViewControlPlugin::ViewControlPlugin():
67viewControlMenu_(0),
68lastObjectId_(0),
69shaderWidget_(0),
70toolbar_(0),
71toolbarViewingDirections_(0),
72viewTop_(0),
73viewBottom_(0),
74viewLeft_(0),
75viewRight_(0),
76viewFront_(0),
77viewBack_(0)
78{
79
80}
81
82void ViewControlPlugin::pluginsInitialized() {
83
84 // Disable Context Menu for draw Modes
85 OpenFlipper::Options::drawModesInContextMenu(false);
86
87 // Create a new visualization context menu
88 viewControlMenu_ = new QMenu("Visualization");
89
90 // Set an icon for the menu
91 QIcon icon = QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"drawModes.png");
92 viewControlMenu_->setIcon(icon);
93
94 // Add it as context menu for all registered data types
95 for(std::vector<TypeInfo>::const_iterator it = typesBegin(); it != typesEnd(); ++it) {
96 if(it->name == "Unknown" || it->name == "Group" || it->name == "All") continue;
97 emit addContextMenuItem(viewControlMenu_->menuAction(), it->type, CONTEXTOBJECTMENU );
98 }
99
100 connect( viewControlMenu_, SIGNAL( triggered(QAction*) ), this, SLOT( contextMenuTriggered(QAction*) ));
101
102 setDescriptions();
103
104 // Create toolbar
105 toolbar_ = new QToolBar(tr("Viewing Directions"));
106
107 // Action group for toolbar
108 toolbarViewingDirections_ = new QActionGroup(toolbar_);
109 QString iconPath = OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator();
110
111 // different viewing direction buttons for toolbar
112 viewTop_ = new QAction( QIcon(iconPath + "viewcontrol_top.png"), tr("View from top") , toolbarViewingDirections_);
113 toolbar_->addAction( viewTop_ );
114 viewBottom_ = new QAction( QIcon(iconPath + "viewcontrol_bottom.png"), tr("View from bottom") , toolbarViewingDirections_);
115 toolbar_->addAction( viewBottom_ );
116 viewLeft_ = new QAction( QIcon(iconPath + "viewcontrol_left.png"), tr("View from left") , toolbarViewingDirections_);
117 toolbar_->addAction( viewLeft_ );
118 viewRight_ = new QAction( QIcon(iconPath + "viewcontrol_right.png"), tr("View from right") , toolbarViewingDirections_);
119 toolbar_->addAction( viewRight_ );
120 viewFront_ = new QAction( QIcon(iconPath + "viewcontrol_front.png"), tr("View from front") , toolbarViewingDirections_);
121 toolbar_->addAction( viewFront_ );
122 viewBack_ = new QAction( QIcon(iconPath + "viewcontrol_back.png"), tr("View from back") , toolbarViewingDirections_);
123 toolbar_->addAction( viewBack_ );
124
125 connect( toolbarViewingDirections_, SIGNAL( triggered(QAction*) ), this, SLOT(setView(QAction*)) );
126
127 // Add the generated toolbar to the core
128 emit addToolbar(toolbar_);
129
130
131}
132
133void ViewControlPlugin::updateShaderList() {
134
135 //=======================================================================================
136 // Get Shaders
137 //=======================================================================================
138 shaderList_.clear();
139 QStringList shadersDirs = OpenFlipper::Options::shaderDir().entryList( QDir::Dirs| QDir::NoDotAndDotDot ,QDir::Name);
140
141 for ( int i = 0 ; i < shadersDirs.size(); ++i ) {
142 ShaderInfo info;
143
144 QFileInfo descriptionFile(OpenFlipper::Options::shaderDirStr() +
145 OpenFlipper::Options::dirSeparator() +
146 shadersDirs[i] + OpenFlipper::Options::dirSeparator() + "shader.ini" );
147
148 INIFile ini;
149 if ( !descriptionFile.exists() || !ini.connect( descriptionFile.filePath() ,false ) ) {
150 emit log( LOGWARN, "Unable to open description file for shader " + shadersDirs[i] + " at " + descriptionFile.filePath() );
151
152 info.description = "Unknown";
153 info.version = "Unknown";
154 info.name = shadersDirs[i];
155 info.details = "----------";
156 info.example = "";
157
158 } else {
159
160 QString tmp;
161 if ( ini.get_entry(tmp,"Info","name") )
162 info.name = tmp;
163 else {
164 info.name = shadersDirs[i];
165 emit log( LOGWARN, "Unable to get name from description file for shader " + shadersDirs[i] );
166 }
167
168 if ( ini.get_entry(tmp,"Info","description") )
169 info.description = tmp;
170 else {
171 info.description = "Unknown";
172 emit log( LOGWARN, "Unable to get shader description from description file for shader " + shadersDirs[i] );
173 }
174
175 if ( ini.get_entry(tmp,"Info","details") )
176 info.details = tmp;
177 else {
178 info.details = "----------";
179 emit log( LOGWARN, "Unable to get shader details from description file for shader " + shadersDirs[i] );
180 }
181
182 if ( ini.get_entry(tmp,"Info","version") )
183 info.version = tmp;
184 else {
185 info.version = "Unknown";
186 emit log( LOGWARN, "Unable to get shader version from description file for shader " + shadersDirs[i] );
187 }
188
189 if ( ini.get_entry(tmp,"Info","example") )
190 info.example = OpenFlipper::Options::shaderDirStr() + OpenFlipper::Options::dirSeparator() +
191 shadersDirs[i] + OpenFlipper::Options::dirSeparator() + tmp;
192 else {
193 info.example = "";
194 emit log( LOGWARN, "Unable to get example image from Description file for shader " + shadersDirs[i] );
195 }
196
197 if ( ini.get_entry(tmp,"FragmentShader","file") )
198 info.fragmentShader = tmp;
199 else {
200 info.fragmentShader = "Fragment.glsl";
201 emit log( LOGWARN, "Unable to get fragment shader filename from Description file for shader " + shadersDirs[i] );
202 }
203
204 if ( ini.get_entry(tmp,"VertexShader","file") )
205 info.vertexShader = tmp;
206 else {
207 info.vertexShader = "Vertex.glsl";
208 emit log( LOGWARN, "Unable to get vertex shader filename from Description file for shader " + shadersDirs[i] );
209 }
210
211 if ( ini.get_entry(tmp,"PickVertexShader","file") )
212 info.pickVertexShader = tmp;
213 else
214 info.pickVertexShader = "";
215
216 if ( ini.get_entry(tmp,"PickFragmentShader","file") )
217 info.pickFragmentShader = tmp;
218 else
219 info.pickFragmentShader = "";
220
221 //uniform names
222 std::vector<QString> uniforms;
223 if ( ini.get_entry(uniforms,"Info","uniforms") ) {
224 info.hasUniforms = true;
225 for ( uint uniform = 0 ; uniform < uniforms.size() ; ++uniform)
226 info.uniforms << uniforms[uniform];
227 } else {
228 info.hasUniforms = false;
229 info.uniforms.clear();
230 }
231
232 //unform types
233 uniforms.clear();
234 if ( info.hasUniforms && ini.get_entry(uniforms,"Info","uniformTypes") ) {
235 for ( uint uniform = 0 ; uniform < uniforms.size() ; ++uniform)
236 info.uniformTypes << uniforms[uniform];
237 } else if ( info.hasUniforms ) {
238 info.hasUniforms = false;
239 info.uniforms.clear();
240 info.uniformTypes.clear();
241 emit log( LOGERR, "Uniforms for shader " + shadersDirs[i] + " defined but no type available, disabled uniforms." );
242 }
243
244 //uniform default values
245 uniforms.clear();
246 if ( info.hasUniforms && ini.get_entry(uniforms,"Info","uniformsDefault" ) ) {
247 for ( uint uniform = 0 ; uniform < uniforms.size() ; ++uniform)
248 info.uniformsDefault << uniforms[uniform];
249 } else if ( info.hasUniforms ) {
250 info.hasUniforms = false;
251 info.uniforms.clear();
252 info.uniformTypes.clear();
253 emit log( LOGERR, "Uniforms for shader " + shadersDirs[i] + " defined but no defaults available, disabled uniforms." );
254 }
255 //uniform min values
256 uniforms.clear();
257 if ( info.hasUniforms && ini.get_entry(uniforms,"Info","uniformsMin" ) ) {
258 for ( uint uniform = 0 ; uniform < uniforms.size() ; ++uniform)
259 info.uniformsMin << uniforms[uniform];
260 } else if ( info.hasUniforms )
261 info.uniformsMin = info.uniformsDefault;
262
263 //uniform max values
264 uniforms.clear();
265 if ( info.hasUniforms && ini.get_entry(uniforms,"Info","uniformsMax" ) ) {
266 for ( uint uniform = 0 ; uniform < uniforms.size() ; ++uniform)
267 info.uniformsMax << uniforms[uniform];
268 } else if ( info.hasUniforms )
269 info.uniformsMax = info.uniformsDefault;
270
271 ini.disconnect();
272 }
273
274 info.directory = descriptionFile.path();
275
276 QFileInfo vertexShaderFile( info.directory + OpenFlipper::Options::dirSeparator() + info.vertexShader );
277 if ( !vertexShaderFile.exists() ) {
278 emit log( LOGERR, "Unable to find vertex shader file " + vertexShaderFile.filePath() );
279 continue;
280 }
281
282 QFileInfo fragmentShaderFile( info.directory + OpenFlipper::Options::dirSeparator() + info.fragmentShader );
283 if ( !fragmentShaderFile.exists() ) {
284 emit log( LOGERR, "Unable to find fragment shader file " + fragmentShaderFile.filePath() );
285 continue;
286 }
287
288 shaderList_.push_back(info);
289 }
290
291}
292
293
294void ViewControlPlugin::contextMenuTriggered(QAction* _action){
295 if ( _action->text() == SHOW_SELECTION) {
296
297 QVariant contextObject = _action->data();
298 int objectId = contextObject.toInt();
299
300 if ( objectId == -1)
301 return;
302
303 showSelection( objectId , !selectionVisible( objectId) );
304
305 emit updateView();
306 }
307
308 if ( _action->text() == SIZE_SELECTION) {
309
310 QVariant contextObject = _action->data();
311 int objectId = contextObject.toInt();
312
313 if ( objectId == -1)
314 return;
315
316 BaseObjectData* object = 0;
317 if ( ! PluginFunctions::getObject(objectId,object) )
318 return;
319
320 if ( object->dataType( DATA_TRIANGLE_MESH ) ) {
321 bool ok = true;
322
323 double d = QInputDialog::getDouble(0, tr("Line width for features"),
324 tr("Size:"), 2.0, 1.0, 50.0, 2, &ok,
325 Qt::WindowFlags(), 1);
326 setSelectionLineWidth(objectId,d);
327
328 }
329
330 if ( object->dataType( DATA_POLY_MESH ) ) {
331 bool ok = true;
332 double d = QInputDialog::getDouble(0, tr("Line width for features"),
333 tr("Size:"), 2.0, 1.0, 50.0, 2, &ok,
334 Qt::WindowFlags(), 1);
335 setSelectionLineWidth(objectId,d);
336 }
337
338 emit updateView();
339
340 }
341
342 if ( _action->text() == SHOW_AREAS) {
343
344 QVariant contextObject = _action->data();
345 int objectId = contextObject.toInt();
346
347 if ( objectId == -1)
348 return;
349
350 showModelingAreas( objectId, !modelingAreasVisible(objectId) );
351
352 emit updateView();
353 }
354
355 if ( _action->text() == SHOW_AREA) {
356
357 QVariant contextObject = _action->data();
358 int objectId = contextObject.toInt();
359
360 if ( objectId == -1)
361 return;
362
363 showAreas( AREA, objectId, !areasVisible(AREA,objectId) );
364
365 emit updateView();
366 }
367
368 if ( _action->text() == SHOW_HANDLE) {
369
370 QVariant contextObject = _action->data();
371 int objectId = contextObject.toInt();
372
373 if ( objectId == -1)
374 return;
375
376 showAreas( HANDLEAREA, objectId, !areasVisible(HANDLEAREA,objectId) );
377
378 emit updateView();
379 }
380
381 if ( _action->text() == SHOW_FEATURES) {
382
383 QVariant contextObject = _action->data();
384 int objectId = contextObject.toInt();
385
386 if ( objectId == -1)
387 return;
388
389 BaseObjectData* object = 0;
390 if ( ! PluginFunctions::getObject(objectId,object) )
391 return;
392
393 if ( object->dataType( DATA_TRIANGLE_MESH ) ) {
395 if ( triMeshObject )
397 }
398
399 if ( object->dataType( DATA_POLY_MESH ) ) {
401 if ( polyMeshObject )
403 }
404
405 emit updateView();
406
407 }
408
409 if ( _action->text() == SIZE_FEATURES) {
410
411 QVariant contextObject = _action->data();
412 int objectId = contextObject.toInt();
413
414 if ( objectId == -1)
415 return;
416
417 BaseObjectData* object = 0;
418 if ( ! PluginFunctions::getObject(objectId,object) )
419 return;
420
421 if ( object->dataType( DATA_TRIANGLE_MESH ) ) {
422 bool ok = true;
423
424 double d = QInputDialog::getDouble(0, tr("Line width for features"),
425 tr("Size:"), 2.0, 1.0, 50.0, 2, &ok,
426 Qt::WindowFlags(), 1);
427 setFeatureLineWidth(objectId,d);
428
429 }
430
431 if ( object->dataType( DATA_POLY_MESH ) ) {
432 bool ok = true;
433 double d = QInputDialog::getDouble(0, tr("Line width for features"),
434 tr("Size:"), 2.0, 1.0, 50.0, 2, &ok,
435 Qt::WindowFlags(), 1);
436 setFeatureLineWidth(objectId,d);
437 }
438
439 emit updateView();
440
441 }
442
443
444
445 if ( _action->text() == SETSHADERS ) {
446 if ( shaderWidget_ == 0 ) {
447 shaderWidget_ = new ShaderWidget(0);
448 connect(shaderWidget_->availableShaders,SIGNAL(itemClicked(QListWidgetItem*)),
449 this ,SLOT(slotShaderClicked(QListWidgetItem*)));
450 connect(shaderWidget_->availableShaders,SIGNAL(itemDoubleClicked(QListWidgetItem*)),
451 this ,SLOT(slotShaderDoubleClicked(QListWidgetItem*)));
452
453 connect(shaderWidget_->setShaderButton,SIGNAL(clicked()),this, SLOT(slotSetShader()));
454 connect(shaderWidget_->closeButton,SIGNAL(clicked()),shaderWidget_, SLOT(close()));
455
456 connect(shaderWidget_->uniforms, SIGNAL(itemChanged(QTableWidgetItem*)),
457 this, SLOT(itemChanged(QTableWidgetItem*)) );
458 }
459
460 initShaderWidget();
461
462 shaderWidget_->show();
463
464 emit updateView();
465 }
466
467}
468
470 if ( _id == -1)
471 return false;
472
473 BaseObjectData* object = 0;
474 if ( ! PluginFunctions::getObject(_id,object) )
475 return false;
476
477 if ( object->dataType( DATA_TRIANGLE_MESH ) ) {
478 TriMeshObject* triMeshObject = PluginFunctions::triMeshObject( object );
479 if ( triMeshObject )
480 return triMeshObject->selectionVisible();
481 }
482
483 if ( object->dataType( DATA_POLY_MESH ) ) {
484 PolyMeshObject* polyMeshObject = PluginFunctions::polyMeshObject( object );
485 if ( polyMeshObject )
486 return polyMeshObject->selectionVisible();
487 }
488
489 return false;
490}
491
492bool ViewControlPlugin::areasVisible( StatusBits _bits, int _id ) {
493
494 if ( _id == -1)
495 return false;
496
497 BaseObjectData* object = 0;
498 if ( ! PluginFunctions::getObject(_id,object) )
499 return false;
500
501 if ( object->dataType( DATA_TRIANGLE_MESH ) ) {
502 TriMeshObject* triMeshObject = PluginFunctions::triMeshObject( object );
503 if ( triMeshObject ) {
504 return triMeshObject->areaVisible( _bits );
505 }
506 }
507
508 if ( object->dataType( DATA_POLY_MESH ) ) {
509 PolyMeshObject* polyMeshObject = PluginFunctions::polyMeshObject( object );
510 if ( polyMeshObject )
511 return( polyMeshObject->areaVisible( _bits ) );
512 }
513
514 return false;
515
516}
517
519 return areasVisible(StatusBits(HANDLEAREA | AREA), _id);
520}
521
522void ViewControlPlugin::showAreas( StatusBits _bits, int _id , bool _state ) {
523
524 if ( _id == -1)
525 return;
526
527 BaseObjectData* object = 0;
528 if ( ! PluginFunctions::getObject(_id,object) )
529 return;
530
531 if ( object->dataType( DATA_TRIANGLE_MESH ) ) {
532 TriMeshObject* triMeshObject = PluginFunctions::triMeshObject( object );
533 if ( triMeshObject )
534 triMeshObject->hideArea( _bits, !_state);
535 }
536
537 if ( object->dataType( DATA_POLY_MESH ) ) {
538 PolyMeshObject* polyMeshObject = PluginFunctions::polyMeshObject( object );
539 if ( polyMeshObject )
540 polyMeshObject->hideArea( _bits, !_state);
541 }
542
543}
544
545void ViewControlPlugin::showModelingAreas( int _id , bool _state ) {
546 showAreas(StatusBits(HANDLEAREA | AREA) , _id, _state );
547}
548
549void ViewControlPlugin::setSelectionLineWidth( int _id , double _width ) {
550
551 if ( _id == -1)
552 return;
553
554 BaseObjectData* object = 0;
555 if ( ! PluginFunctions::getObject(_id,object) )
556 return;
557
558 //statusNode()
559 if ( object->dataType( DATA_TRIANGLE_MESH ) ) {
560 TriMeshObject* triMeshObject = PluginFunctions::triMeshObject( object );
561 if ( triMeshObject )
562 triMeshObject->statusNode()->material().lineWidth(_width );
563 }
564
565 if ( object->dataType( DATA_POLY_MESH ) ) {
566 PolyMeshObject* polyMeshObject = PluginFunctions::polyMeshObject( object );
567 if ( polyMeshObject )
568 polyMeshObject->statusNode()->material().lineWidth(_width );
569 }
570
571}
572
573void ViewControlPlugin::setFeatureLineWidth( int _id , double _width ) {
574
575 if ( _id == -1)
576 return;
577
578 BaseObjectData* object = 0;
579 if ( ! PluginFunctions::getObject(_id,object) )
580 return;
581
582 //statusNode()
583 if ( object->dataType( DATA_TRIANGLE_MESH ) ) {
584 TriMeshObject* triMeshObject = PluginFunctions::triMeshObject( object );
585 if ( triMeshObject )
586 triMeshObject->featureNode()->material().lineWidth(_width );
587 }
588
589 if ( object->dataType( DATA_POLY_MESH ) ) {
590 PolyMeshObject* polyMeshObject = PluginFunctions::polyMeshObject( object );
591 if ( polyMeshObject )
592 polyMeshObject->featureNode()->material().lineWidth(_width );
593 }
594
595}
596
597
598void ViewControlPlugin::showSelection( int _id , bool _state ) {
599
600 if ( _id == -1)
601 return;
602
603 BaseObjectData* object = 0;
604 if ( ! PluginFunctions::getObject(_id,object) )
605 return;
606
607 if ( object->dataType( DATA_TRIANGLE_MESH ) ) {
608 TriMeshObject* triMeshObject = PluginFunctions::triMeshObject( object );
609 if ( triMeshObject )
610 triMeshObject->hideSelection( !_state );
611 }
612
613 if ( object->dataType( DATA_POLY_MESH ) ) {
614 PolyMeshObject* polyMeshObject = PluginFunctions::polyMeshObject( object );
615 if ( polyMeshObject )
616 polyMeshObject->hideSelection( !_state );
617 }
618
619}
620
621void ViewControlPlugin::slotUpdateContextMenu( int _objectId ){
622
623 viewControlMenu_->clear();
624
625 lastObjectId_ = _objectId;
626
627 BaseObjectData* object = 0;
628 if ( !PluginFunctions::getObject( _objectId, object ) ) {
629 emit log(LOGERR,"Unable to create Context Menu ... Unable to get Object");
630 return;
631 }
632
633 if (object->dataType( DATA_TRIANGLE_MESH ) || object->dataType( DATA_POLY_MESH ) ) {
634
635 QAction* act;
636 act = viewControlMenu_->addAction( SHOW_SELECTION );
637 act->setCheckable(true);
638
639 act->setStatusTip( "Switch visualization for selection on/off" );
640 act->setToolTip( "Switch visualization for selection on/off" );
641 act->setWhatsThis( "Switch the visualization of your current selections on and off." );
642
643 act->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"selections.png"));
644
645 if ( object->dataType( DATA_TRIANGLE_MESH ) ) {
647 if ( triMeshObject )
648 act->setChecked( triMeshObject->selectionVisible() );
649 }
650
651 if ( object->dataType( DATA_POLY_MESH ) ) {
653 if ( polyMeshObject )
654 act->setChecked( polyMeshObject->selectionVisible() );
655 }
656
657 // ============================================
658 // Action for all modeling areas
659 // ============================================
660 act = viewControlMenu_->addAction( SHOW_AREAS );
661 act->setCheckable(true);
662
663 act->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"areaSelections.png"));
664
665 if ( object->dataType( DATA_TRIANGLE_MESH ) ) {
667 if ( triMeshObject )
668 act->setChecked( triMeshObject->areaVisible( StatusBits(HANDLEAREA | AREA) ) );
669 }
670
671 if ( object->dataType( DATA_POLY_MESH ) ) {
673 if ( polyMeshObject )
674 act->setChecked( polyMeshObject->areaVisible( StatusBits(HANDLEAREA | AREA) ) );
675 }
676
677
678 // ============================================
679 // Action for handle areas
680 // ============================================
681 act = viewControlMenu_->addAction( SHOW_HANDLE );
682 act->setCheckable(true);
683
684 act->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"viewcontrol_handleSelection.png"));
685
686 if ( object->dataType( DATA_TRIANGLE_MESH ) ) {
688 if ( triMeshObject )
689 act->setChecked( triMeshObject->areaVisible( HANDLEAREA ) );
690 }
691
692 if ( object->dataType( DATA_POLY_MESH ) ) {
694 if ( polyMeshObject )
695 act->setChecked( polyMeshObject->areaVisible( HANDLEAREA ) );
696 }
697
698 // ============================================
699 // Action for modeling areas
700 // ============================================
701 act = viewControlMenu_->addAction( SHOW_AREA );
702 act->setCheckable(true);
703
704 act->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"viewcontrol_modelingSelection.png"));
705
706 if ( object->dataType( DATA_TRIANGLE_MESH ) ) {
708 if ( triMeshObject )
709 act->setChecked( triMeshObject->areaVisible( AREA ) );
710 }
711
712 if ( object->dataType( DATA_POLY_MESH ) ) {
714 if ( polyMeshObject )
715 act->setChecked( polyMeshObject->areaVisible( AREA ) );
716 }
717
718 // ============================================
719 // Actions for feature visibility
720 // ============================================
721
722
723 act = viewControlMenu_->addAction( SHOW_FEATURES );
724 act->setCheckable(true);
725
726 act->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"viewcontrol_featureSelections.png"));
727
728 if ( object->dataType( DATA_TRIANGLE_MESH ) ) {
730 if ( triMeshObject )
731 act->setChecked( triMeshObject->featuresVisible() );
732 }
733
734 if ( object->dataType( DATA_POLY_MESH ) ) {
736 if ( polyMeshObject )
737 act->setChecked( polyMeshObject->featuresVisible() );
738 }
739
740 // ============================================
741 // Action for features size
742 // ============================================
743 act = viewControlMenu_->addAction( SIZE_FEATURES );
744
745 act->setCheckable(true);
746
747 act->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"viewcontrol_featureSize.png"));
748
749 // ============================================
750 // Action for selection size
751 // ============================================
752 act = viewControlMenu_->addAction( SIZE_SELECTION );
753
754 act->setCheckable(true);
755
756 act->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"viewcontrol_selectionSize.png"));
757
758 }
759
760 // If this Object has a shader Node, allow settings for the shader
761 if ( object->shaderNode() ) {
762 viewControlMenu_->addSeparator();
763
764 QAction* act = viewControlMenu_->addAction( SETSHADERS );
765 act->setCheckable( false );
766 }
767
768 viewControlMenu_->addSeparator();
769
770 QActionGroup * globalDrawActionsGroup = new QActionGroup( this );
771
772 QAction * action = new QAction( USEGLOBALDRAWMODE , globalDrawActionsGroup );
773 action->setCheckable( false );
774
775 viewControlMenu_->addActions(globalDrawActionsGroup->actions());
776
777 connect( globalDrawActionsGroup, SIGNAL( triggered( QAction * ) ),
778 this , SLOT( slotDrawModeSelected( QAction * ) ) );
779
780 QActionGroup * drawGroup = new QActionGroup( this );
781 drawGroup->setExclusive( false );
782
783 // Collect available draw Modes for this object
785 ACG::SceneGraph::traverse( object->primaryNode() , actionAvailable);
786 availDrawModes_ = actionAvailable.drawModes();
787
788 // Collect available draw Modes for this object
790 ACG::SceneGraph::traverse( object->primaryNode() , actionActive);
791 activeDrawModes_ = actionActive.drawMode();
792
793 std::vector< ACG::SceneGraph::DrawModes::DrawMode > availDrawModeIds;
794 availDrawModeIds = availDrawModes_.getAtomicDrawModes();
795
797
798 const bool containsGlobalDM = activeDrawModes_ == ACG::SceneGraph::DrawModes::DEFAULT;
799
800 activeCheckboxes.clear();
801 for ( unsigned int i = 0; i < availDrawModeIds.size(); ++i )
802 {
803 ACG::SceneGraph::DrawModes::DrawMode id = availDrawModeIds[i];
804 std::string descr = id.description();
805
806 QCheckBox *checkBox = new QCheckBox(QString(descr.c_str()), viewControlMenu_);
807 activeCheckboxes[checkBox] = id;
809 checkBox->setCheckState(Qt::Checked);
810 else if (containsGlobalDM && globalDrawModes.containsAtomicDrawMode(id))
811 checkBox->setCheckState(Qt::PartiallyChecked);
812 else
813 checkBox->setCheckState(Qt::Unchecked);
814 QWidgetAction *checkableAction = new QWidgetAction(drawGroup);
815 checkableAction->setText(descr.c_str());
816 checkableAction->setDefaultWidget(checkBox);
817 connect(checkBox, SIGNAL( stateChanged(int) ), checkableAction, SLOT(trigger() ) );
818 }
819
820 viewControlMenu_->addActions( drawGroup->actions() );
821
822 connect( drawGroup, SIGNAL( triggered( QAction * ) ),
823 this, SLOT( slotDrawModeSelected( QAction * ) ) );
824
825}
826
827void ViewControlPlugin::slotDrawModeSelected( QAction * _action) {
828
829 QWidgetAction * const wdgtAction = dynamic_cast<QWidgetAction*>(_action);
830 QCheckBox * const checkbox = wdgtAction ? dynamic_cast<QCheckBox*>(wdgtAction->defaultWidget()) : 0;
831 const bool activateDrawMode = checkbox ? (checkbox->checkState() != Qt::Unchecked) : false;
832
833 //======================================================================================
834 // Get the mode toggled
835 //======================================================================================
837 std::vector< ACG::SceneGraph::DrawModes::DrawMode > availDrawModeIds;
838 availDrawModeIds = availDrawModes_.getAtomicDrawModes();
839 for ( unsigned int i = 0; i < availDrawModeIds.size(); ++i )
840 {
841 QString descr = QString( availDrawModeIds[i].description().c_str() );
842
843 if ( descr == _action->text() ) {
844 mode = availDrawModeIds[i];
845 break;
846 }
847 }
848
849 //======================================================================================
850 // possibly combine draw modes
851 //======================================================================================
852 bool useGlobalDrawMode = false;
853 bool contextMenuStaysOpen = false;
854 if ( _action->text() != USEGLOBALDRAWMODE ) {
855
856 // extract global draw mode in case we want to combine it with another draw mode
859 activeDrawModes_.combine(widgetDrawMode);
860 }
861
862 // As this is not the global draw mode, filter out default as draw mode or it will interfere with the other modes!
864
865 // If shift is pressed, we combine the modes (and toggle therefore xor)
866 // Otherwise we directly take the new mode
867 if ( qApp->keyboardModifiers() & Qt::ShiftModifier ) {
868 if (activateDrawMode) {
869 activeDrawModes_.combine(mode); // explicit call to combine() states intent more clearly
870 } else {
871 if (activeDrawModes_ == mode) {
873 useGlobalDrawMode = true;
874 } else {
876 }
877 }
878 contextMenuStaysOpen = true;
879 } else {
880 if (activateDrawMode) {
881 activeDrawModes_ = mode ;
882 } else {
884 useGlobalDrawMode = true;
885 }
886 emit hideContextMenu();
887 }
888
890 useGlobalDrawMode = true;
891 }
892
893 } else {
894 // Switch back to global drawmode-> default
896 useGlobalDrawMode = true;
897 }
898
899 if (contextMenuStaysOpen) {
900 typedef std::map<QCheckBox*, ACG::SceneGraph::DrawModes::DrawMode> CBM;
902 for (CBM::iterator it = activeCheckboxes.begin(), it_end = activeCheckboxes.end(); it != it_end; ++it) {
903 it->first->blockSignals(true);
905 it->first->setCheckState(Qt::Checked);
906 } else if (useGlobalDrawMode && globalDrawModes.containsAtomicDrawMode(it->second)) {
907 it->first->setCheckState(Qt::PartiallyChecked);
908 } else {
909 it->first->setCheckState(Qt::Unchecked);
910 }
911 it->first->blockSignals(false);
912 }
913 }
914
915 //======================================================================================
916 // Now do the update in the sceneGraph
917 //======================================================================================
918
919 // Get the associated object
920 BaseObjectData* object = 0;
922
923 // Set draw Modes for this object ( force it when we do not set the global draw mode, to override global draw mode and force the modes on the nodes )
924 ACG::SceneGraph::SetDrawModesAction actionActive( activeDrawModes_ , !useGlobalDrawMode );
925
926
927 if ( object )
928 ACG::SceneGraph::traverse( object->primaryNode() , actionActive);
929 else
931
932 emit updateView();
933}
934
935void ViewControlPlugin::initShaderWidget(){
936
937 //update the shader list
938
939 updateShaderList();
940
941 shaderWidget_->availableShaders->clear();
942
943 for ( uint i = 0 ; i < shaderList_.size(); ++i ) {
944 shaderWidget_->availableShaders->addItem( shaderList_[i].name );
945 }
946
947 shaderWidget_->availableShaders->setCurrentRow(0);
948 slotShaderClicked(shaderWidget_->availableShaders->currentItem());
949
950}
951
952void ViewControlPlugin::slotShaderClicked( QListWidgetItem * _item ){
953 int index = -1;
954 for ( int i = 0 ; i < (int)shaderList_.size(); ++i) {
955 if ( shaderList_[i].name == _item->text() ) {
956 index = i;
957 break;
958 }
959 }
960
961 if ( index == -1 ) {
962 std::cerr << "Strange index Error! " << std::endl;
963 return;
964 }
965
966 shaderWidget_->shaderName->setText( shaderList_[index].name );
967 shaderWidget_->description->setText( shaderList_[index].description );
968 shaderWidget_->details->setText( shaderList_[index].details );
969 shaderWidget_->version->setText( shaderList_[index].version );
970 shaderWidget_->vertexShader->setText( shaderList_[index].vertexShader );
971 shaderWidget_->fragmentShader->setText( shaderList_[index].fragmentShader );
972 shaderWidget_->pickVertexShader->setText( shaderList_[index].pickVertexShader );
973 shaderWidget_->pickFragmentShader->setText( shaderList_[index].pickFragmentShader );
974 shaderWidget_->example->setPixmap( QPixmap(shaderList_[index].example) );
975
976 //get shader paths
977 QStringList shadersDirs = OpenFlipper::Options::shaderDir().entryList( QDir::Dirs| QDir::NoDotAndDotDot ,QDir::Name);
978 QString shaderDir = OpenFlipper::Options::shaderDirStr() + OpenFlipper::Options::dirSeparator();
979
980 QString vertexFile = shaderDir + shadersDirs[ shaderWidget_->availableShaders->currentRow() ] +
981 OpenFlipper::Options::dirSeparator() + shaderWidget_->vertexShader->text();
982 QString fragmentFile = shaderDir + shadersDirs[ shaderWidget_->availableShaders->currentRow() ] +
983 OpenFlipper::Options::dirSeparator() + shaderWidget_->fragmentShader->text();
984
985 //update drawMode checkStates
986 shaderWidget_->drawModes->clear();
987
988 std::vector< ACG::SceneGraph::DrawModes::DrawMode > availDrawModeIds;
989 availDrawModeIds = availDrawModes_.getAtomicDrawModes( );
990
991 for ( unsigned int i = 0; i < availDrawModeIds.size(); ++i )
992 {
993 ACG::SceneGraph::DrawModes::DrawMode id = availDrawModeIds[i];
994
995
996 std::vector< QString > dm = drawModeToDescriptions( id );
997
998 if ( !dm.empty() && dm[0].trimmed() != ""){
999 QListWidgetItem* item = new QListWidgetItem(dm[0]);
1000
1001 item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsUserCheckable | Qt::ItemIsSelectable);
1002
1003 BaseObjectData* object = 0;
1004
1006 if ( object && object->shaderNode() ){
1007 if ( object->shaderNode()->vertexShaderName( id ) == vertexFile.toStdString() &&
1008 object->shaderNode()->fragmentShaderName( id ) == fragmentFile.toStdString() )
1009 item->setCheckState( Qt::Checked );
1010 else
1011 {
1012 //std::cerr << "vertex:" << object->shaderNode()->vertexShaderName( id ) << ", this: " << vertexFile.toStdString() << std::endl;
1013 //std::cerr << "fragment:" << object->shaderNode()->fragmentShaderName( id ) << ", this: " << fragmentFile.toStdString() << std::endl;
1014 item->setCheckState( Qt::Unchecked );
1015 }
1016 }
1017 shaderWidget_->drawModes->addItem(item);
1018 }
1019 }
1020
1021 if ( shaderList_[index].hasUniforms ) {
1022 //set up uniform table
1023 shaderWidget_->uniforms->clear();
1024 shaderWidget_->uniforms->setColumnCount ( 1 );
1025 shaderWidget_->uniforms->setRowCount ( shaderList_[index].uniforms.count() );
1026
1027 shaderWidget_->uniforms->setHorizontalHeaderLabels( QStringList("Value") );
1028 shaderWidget_->uniforms->setVerticalHeaderLabels( shaderList_[index].uniforms );
1029
1030 for (int i=0; i < shaderList_[index].uniforms.count(); i++){
1031 QTableWidgetItem* item = new QTableWidgetItem( shaderList_[index].uniformsDefault[i] );
1032 item->setFlags( Qt::ItemIsEditable | Qt::ItemIsSelectable | Qt::ItemIsEnabled);
1033 shaderWidget_->uniforms->setItem(i,0,item );
1034 }
1035
1036 shaderWidget_->uniformBox->setVisible( true );
1037
1038 }else
1039 shaderWidget_->uniformBox->setVisible( false );
1040
1041 emit updateView();
1042}
1043
1044void ViewControlPlugin::slotShaderDoubleClicked( QListWidgetItem * /*_item*/ ){
1045// slotSetShader();
1046}
1047
1048void ViewControlPlugin::itemChanged(QTableWidgetItem* item){
1049
1050 //get current shader index
1051 int index = -1;
1052 for ( int i = 0 ; i < (int)shaderList_.size(); ++i) {
1053 if ( shaderList_[i].name == shaderWidget_->availableShaders->currentItem()->text() ) {
1054 index = i;
1055 break;
1056 }
1057 }
1058
1059 if ( index == -1 ) {
1060 std::cerr << "Error: Shader Index not found! " << std::endl;
1061 return;
1062 }
1063
1064
1065 int row = item->row();
1066
1067 if ( row > shaderList_[index].uniforms.count() ){
1068 std::cerr << "Error: uniform index out of bounds" << std::endl;
1069 return;
1070 }
1071
1072 //handle different datatypes
1073 if (shaderList_[index].uniformTypes[row] == "float"){
1074 bool ok;
1075
1076 float value = item->text().toFloat(&ok);
1077
1078 if (!ok)
1079 item->setText( shaderList_[index].uniformsDefault[row] );
1080 else if (shaderList_[index].uniformsDefault[row] != shaderList_[index].uniformsMin[row]
1081 && value < shaderList_[index].uniformsMin[row].toFloat())
1082 item->setText( shaderList_[index].uniformsMin[row] );
1083 else if (shaderList_[index].uniformsDefault[row] != shaderList_[index].uniformsMin[row]
1084 && value > shaderList_[index].uniformsMax[row].toFloat())
1085 item->setText( shaderList_[index].uniformsMax[row] );
1086 }
1087
1088}
1089
1090void ViewControlPlugin::slotSetShader()
1091{
1092
1093 //get current shader index
1094 int index = -1;
1095 for (int i = 0; i < (int) shaderList_.size(); ++i) {
1096 if (shaderList_[i].name == shaderWidget_->availableShaders->currentItem()->text()) {
1097 index = i;
1098 break;
1099 }
1100 }
1101
1102 if (index == -1) {
1103 std::cerr << "Error: Shader Index not found! " << std::endl;
1104 return;
1105 }
1106
1107 std::vector<QString> mode;
1108 for (int i = 0; i < shaderWidget_->drawModes->count(); i++) {
1109 if (shaderWidget_->drawModes->item(i)->checkState() == Qt::Checked) {
1110 mode.push_back(shaderWidget_->drawModes->item(i)->text());
1111 setShader(lastObjectId_, descriptionsToDrawMode(mode), shaderList_[index]);
1112 mode.clear();
1113 } else {
1114 mode.push_back(shaderWidget_->drawModes->item(i)->text());
1115 disableShader(lastObjectId_, descriptionsToDrawMode(mode), &shaderList_[index]);
1116 mode.clear();
1117 }
1118 }
1119}
1120
1122 int _objectId,
1124 ShaderInfo* _shader)
1125{
1126
1127 BaseObjectData* object = 0;
1128 PluginFunctions::getObject(_objectId, object);
1129
1130 if (object) {
1131 if (!_shader)
1132 object->shaderNode()->disableShader(_drawMode);
1133 else {
1134 std::string shadeDir = _shader->directory.toStdString() + OpenFlipper::Options::dirSeparator().toStdString();
1135
1136 if (object->shaderNode()->vertexShaderName(_drawMode) == shadeDir + _shader->vertexShader.toStdString()
1137 && object->shaderNode()->fragmentShaderName(_drawMode) == shadeDir + _shader->fragmentShader.toStdString())
1138 object->shaderNode()->disableShader(_drawMode);
1139 }
1140 }
1141
1142 emit updateView();
1143}
1144
1146
1147 if ( OpenFlipper::Options::nogui() )
1148 return;
1149
1150 BaseObjectData* object = 0;
1151 PluginFunctions::getObject( _id, object );
1152
1153 //get shader paths
1154 QFileInfo vertexFile (_shader.name + OpenFlipper::Options::dirSeparator() + _shader.vertexShader);
1155 QFileInfo fragmentFile (_shader.name + OpenFlipper::Options::dirSeparator() + _shader.fragmentShader);
1156 QFileInfo pickVertexFile (_shader.name + OpenFlipper::Options::dirSeparator() + _shader.pickVertexShader);
1157 QFileInfo pickFragmentFile (_shader.name + OpenFlipper::Options::dirSeparator() + _shader.pickFragmentShader);
1158
1159 if ( object && object->shaderNode()
1160 && _shader.vertexShader.length() && _shader.fragmentShader.length()) {
1161
1162 if (vertexFile.absolutePath() != fragmentFile.absolutePath()) {
1163 emit log(LOGERR, "Cannot set shader. Currently shader files have to be in the same folder.");
1164 return;
1165 }
1166
1167 if (_shader.pickVertexShader.length() && _shader.pickFragmentShader.length())
1168 {
1169 if (vertexFile.absolutePath() != pickVertexFile.absolutePath() ||
1170 vertexFile.absolutePath() != pickFragmentFile.absolutePath()) {
1171 emit log(LOGERR, "Cannot set picking shader. Currently shader files have to be in the same folder.");
1172 return;
1173 }
1174
1175 object->shaderNode()->setShaderDir( (_shader.directory + OpenFlipper::Options::dirSeparator()).toStdString() );
1176
1177 object->shaderNode()->setShader(_drawMode,
1178 vertexFile.fileName().toStdString(),
1179 fragmentFile.fileName().toStdString(),
1180 pickVertexFile.fileName().toStdString(),
1181 pickFragmentFile.fileName().toStdString());
1182 }
1183 else
1184 {
1185 object->shaderNode()->setShaderDir( (_shader.directory + OpenFlipper::Options::dirSeparator()).toStdString() );
1186 object->shaderNode()->setShader(_drawMode, vertexFile.fileName().toStdString(), fragmentFile.fileName().toStdString());
1187 }
1188 }
1189
1190
1191 // set uniforms if available
1192 if (_shader.hasUniforms) {
1193 GLSL::PtrProgram shader = object->shaderNode()->getShader( _drawMode );
1194 if ( shader == 0 ) {
1195 std::cerr << "Error: Unable to get shader for shader mode" << std::endl;
1196 } else {
1197 shader->use();
1198
1199 for (int u=0; u < _shader.uniforms.count(); u++) {
1200 //float uniforms
1201 if (_shader.uniformTypes[u] == "float" ) {
1202 shaderWidget_->uniforms->setCurrentCell(u,0);
1203 float value = shaderWidget_->uniforms->currentItem()->text().toFloat();
1204 shader->setUniform(_shader.uniforms[u].toUtf8(), value);
1205 } else
1206 //vec3 uniforms
1207 if (_shader.uniformTypes[u] == "vec3" ) {
1208 shaderWidget_->uniforms->setCurrentCell(u,0);
1209 QStringList vecStr = shaderWidget_->uniforms->currentItem()->text().split(",");
1210 if (vecStr.count() == 3) {
1211 ACG::Vec3f value( vecStr[0].toFloat(), vecStr[1].toFloat(), vecStr[2].toFloat() );
1212 shader->setUniform(_shader.uniforms[u].toUtf8(), value);
1213 }
1214 } else
1215 std::cerr << "Error: handling of uniformType '" << _shader.uniformTypes[u].toStdString() << "' not yet implemented" << std::endl;
1216
1217 }
1218
1219 shader->disable();
1220 }
1221 }
1222
1223 emit updateView();
1224}
1225
1226void ViewControlPlugin::setShader(int _id, QString _drawMode, QString _name ){
1227
1228 if ( OpenFlipper::Options::nogui() )
1229 return;
1230
1231 updateShaderList();
1232
1233 //get current shader index
1234 int index = -1;
1235 for ( int i = 0 ; i < (int)shaderList_.size(); ++i) {
1236 if ( shaderList_[i].name == _name ) {
1237 index = i;
1238 break;
1239 }
1240 }
1241
1242 if ( index == -1 ) {
1243 std::cerr << "Error: Shader not found! " << std::endl;
1244 return;
1245 }
1246
1247 std::vector <QString> mode;
1248 mode.push_back(_drawMode);
1249
1250 setShader(_id, listToDrawMode(mode), shaderList_[index]);
1251}
1252
1253//-----------------------------------------------------------------------------
1254
1255QStringList ViewControlPlugin::getUniforms(QString _shader){
1256 for (uint i=0; i < shaderList_.size(); i++)
1257 if ( shaderList_[i].name == _shader)
1258 return shaderList_[i].uniforms;
1259
1260 return QStringList();
1261}
1262
1263QString ViewControlPlugin::getUniformType(QString _shader, QString _uniform ){
1264
1265 for (uint i=0; i < shaderList_.size(); i++)
1266 if ( shaderList_[i].name == _shader){
1267
1268 for (int u=0; u < shaderList_[i].uniforms.count(); u++)
1269 if ( shaderList_[i].uniforms[u] == _uniform )
1270 return shaderList_[i].uniformTypes[u];
1271 }
1272
1273 return QString();
1274}
1275
1276QString ViewControlPlugin::getUniformDefault(QString _shader, QString _uniform ){
1277
1278 for (uint i=0; i < shaderList_.size(); i++)
1279 if ( shaderList_[i].name == _shader){
1280
1281 for (int u=0; u < shaderList_[i].uniforms.count(); u++)
1282 if ( shaderList_[i].uniforms[u] == _uniform )
1283 return shaderList_[i].uniformsDefault[u];
1284 }
1285
1286 return QString();
1287}
1288
1289QString ViewControlPlugin::getUniformMin(QString _shader, QString _uniform ){
1290
1291 for (uint i=0; i < shaderList_.size(); i++)
1292 if ( shaderList_[i].name == _shader){
1293
1294 for (int u=0; u < shaderList_[i].uniforms.count(); u++)
1295 if ( shaderList_[i].uniforms[u] == _uniform )
1296 return shaderList_[i].uniformsMin[u];
1297 }
1298
1299 return QString();
1300}
1301
1302QString ViewControlPlugin::getUniformMax(QString _shader, QString _uniform ){
1303
1304 for (uint i=0; i < shaderList_.size(); i++)
1305 if ( shaderList_[i].name == _shader){
1306
1307 for (int u=0; u < shaderList_[i].uniforms.count(); u++)
1308 if ( shaderList_[i].uniforms[u] == _uniform )
1309 return shaderList_[i].uniformsMax[u];
1310 }
1311
1312 return QString();
1313}
1314
1315//-----------------------------------------------------------------------------
1316
1318void ViewControlPlugin::setUniform(int _objID, ACG::SceneGraph::DrawModes::DrawMode _drawMode, QString _shader, QString _uniform, QString _value ){
1319
1320 BaseObjectData* object = 0;
1321
1322 PluginFunctions::getObject( _objID, object );
1323 if ( object && object->shaderNode() ){
1324
1325 for (uint i=0; i < shaderList_.size(); i++)
1326 if ( shaderList_[i].name == _shader){
1327
1328 // set uniforms if available
1329 if (shaderList_[i].hasUniforms){
1330 GLSL::PtrProgram shader = object->shaderNode()->getShader( _drawMode );
1331 if ( shader == 0 ) {
1332 std::cerr << "Error: Unable to get shader for shader mode" << std::endl;
1333 } else {
1334 shader->use();
1335
1336 for (int u=0; u < shaderList_[i].uniforms.count(); u++){
1337
1338 //only apply to uniform which was given as param
1339 if ( shaderList_[i].uniforms[u] != _uniform )
1340 continue;
1341
1342 //float uniforms
1343 if (shaderList_[i].uniformTypes[u] == "float" )
1344 shader->setUniform(shaderList_[i].uniforms[u].toUtf8(), _value.toFloat() );
1345
1346 //vec3 uniforms
1347 else if (shaderList_[i].uniformTypes[u] == "vec3" ){
1348 QStringList vecStr = _value.split(",");
1349 if (vecStr.count() == 3){
1350 ACG::Vec3f value( vecStr[0].toFloat(), vecStr[1].toFloat(), vecStr[2].toFloat() );
1351 shader->setUniform(shaderList_[i].uniforms[u].toUtf8(), value);
1352 }
1353 }else
1354 std::cerr << "Error: handling of uniformType '" << shaderList_[i].uniformTypes[u].toStdString() << "' not yet implemented" << std::endl;
1355 }
1356
1357 shader->disable();
1358 }
1359 }
1360 }
1361 }
1362}
1363
1364//-----------------------------------------------------------------------------
1365
1366void ViewControlPlugin::setViewingDirection( Vector _direction, Vector _upvector , int _viewer){
1367 PluginFunctions::viewingDirection(_direction, _upvector, _viewer);
1368}
1369
1370//-----------------------------------------------------------------------------
1371
1372void ViewControlPlugin::setSceneRadius( double _radius , int _viewer){
1373 PluginFunctions::setSceneRadius(_radius, _viewer);
1374}
1375
1376//-----------------------------------------------------------------------------
1377
1378void ViewControlPlugin::rotate( Vector _axis, double _angle, Vector _center , int _viewer) {
1379 PluginFunctions::rotate( _axis, _angle, _center ,_viewer);
1380}
1381
1382//-----------------------------------------------------------------------------
1383
1384void ViewControlPlugin::translate( Vector _vec , int _viewer) {
1385 PluginFunctions::translate( _vec ,_viewer);
1386}
1387
1388
1389void ViewControlPlugin::enableBackfaceCulling( bool _state , int _viewer ) {
1390 if ( _viewer == PluginFunctions::ALL_VIEWERS )
1391 for ( int i = 0 ; i < PluginFunctions::viewers( ); ++i )
1393 else if ( _viewer == PluginFunctions::ACTIVE_VIEWER )
1395 else if ( _viewer >= 0 && _viewer < PluginFunctions::viewers( ) )
1397 else
1398 std::cerr << "Illegal viewer requested! " << std::endl;
1399
1400}
1401
1402
1403//-----------------------------------------------------------------------------
1404
1405void
1406ViewControlPlugin::setDrawMode(QString _mode, int _viewer)
1407{
1408
1409 QStringList list = _mode.split(';');
1410
1411 std::vector< QString > drawModeList;
1412
1413 for ( int i = 0 ; i < list.size() ; ++i )
1414 drawModeList.push_back(list[i]);
1415
1416 ACG::SceneGraph::DrawModes::DrawMode mode = listToDrawMode(drawModeList);
1417
1418 PluginFunctions::setDrawMode( mode , _viewer );
1419 emit updateView();
1420}
1421
1422//-----------------------------------------------------------------------------
1423
1424void
1425ViewControlPlugin::setObjectDrawMode(QString _mode, int _objectID, bool _force)
1426{
1427 BaseObjectData* object = 0;
1428 PluginFunctions::getObject( _objectID, object );
1429
1430 QStringList list = _mode.split(';');
1431
1432 std::vector< QString > drawModeList;
1433
1434 for ( int i = 0 ; i < list.size() ; ++i )
1435 drawModeList.push_back(list[i]);
1436
1437 ACG::SceneGraph::DrawModes::DrawMode mode = listToDrawMode(drawModeList);
1438
1439 // Set draw Modes for this object ( force it when we do not set the global draw mode, to override global draw mode and force the modes on the nodes )
1440 ACG::SceneGraph::SetDrawModesAction actionActive( mode , _force );
1441
1442 if ( object )
1443 ACG::SceneGraph::traverse( object->primaryNode() , actionActive);
1444}
1445
1446//-----------------------------------------------------------------------------
1447
1451
1453 return PluginFunctions::upVector(_viewer);
1454}
1455
1457 return PluginFunctions::eyePos(_viewer);
1458}
1459
1460void ViewControlPlugin::setSceneCenter( Vector _center, int _viewer ) {
1461 PluginFunctions::setScenePos(_center, _viewer);
1462}
1463
1465 return PluginFunctions::sceneCenter(_viewer);
1466}
1467
1468//-----------------------------------------------------------------------------
1469
1470void ViewControlPlugin::setView(int _mode, int _viewer ) {
1471
1472 switch ( _mode ){
1473 case PluginFunctions::VIEW_TOP : //TOP
1474 setViewingDirection( ACG::Vec3d(0.0, -1.0, 0.0), ACG::Vec3d(0.0, 0.0, -1.0), _viewer );
1475 break;
1476 case PluginFunctions::VIEW_BOTTOM : //BOTTOM
1477 setViewingDirection( ACG::Vec3d(0.0, 1.0, 0.0), ACG::Vec3d(0.0, 0.0, -1.0), _viewer );
1478 break;
1479 case PluginFunctions::VIEW_LEFT : //LEFT
1480 setViewingDirection( ACG::Vec3d(1.0, 0.0, 0.0), ACG::Vec3d(0.0, 1.0, 0.0), _viewer );
1481 break;
1482 case PluginFunctions::VIEW_RIGHT : //RIGHT
1483 setViewingDirection( ACG::Vec3d(-1.0, 0.0, 0.0), ACG::Vec3d(0.0, 1.0, 0.0), _viewer );
1484 break;
1485 case PluginFunctions::VIEW_FRONT : //FRONT
1486 setViewingDirection( ACG::Vec3d(0.0, 0.0, -1.0), ACG::Vec3d(0.0, 1.0, 0.0), _viewer );
1487 break;
1488 case PluginFunctions::VIEW_BACK : //BACK
1489 setViewingDirection( ACG::Vec3d(0.0, 0.0, 1.0), ACG::Vec3d(0.0, 1.0, 0.0), _viewer );
1490 break;
1491 default :
1492 emit log(LOGERR, "ViewControl: Unknown view mode: " + QString::number(_mode));
1493 break;
1494 }
1495
1496 updateView();
1497}
1498
1499//-----------------------------------------------------------------------------
1500
1501void ViewControlPlugin::setView(QAction* _action) {
1502
1503 if ( _action == viewTop_) setView (PluginFunctions::VIEW_TOP, PluginFunctions::ACTIVE_VIEWER);
1504 else if ( _action == viewBottom_) setView (PluginFunctions::VIEW_BOTTOM, PluginFunctions::ACTIVE_VIEWER);
1505 else if ( _action == viewLeft_) setView (PluginFunctions::VIEW_LEFT, PluginFunctions::ACTIVE_VIEWER);
1506 else if ( _action == viewRight_) setView (PluginFunctions::VIEW_RIGHT, PluginFunctions::ACTIVE_VIEWER);
1507 else if ( _action == viewFront_) setView (PluginFunctions::VIEW_FRONT, PluginFunctions::ACTIVE_VIEWER);
1508 else if ( _action == viewBack_) setView (PluginFunctions::VIEW_BACK, PluginFunctions::ACTIVE_VIEWER);
1509 else emit log(LOGERR, "ViewControl: Unknown view mode action!");
1510}
1511
1512//-----------------------------------------------------------------------------
1513
1514void ViewControlPlugin::setEyePosition(Vector _eye){
1516 PluginFunctions::sceneCenter(PluginFunctions::ACTIVE_VIEWER),
1517 PluginFunctions::upVector(PluginFunctions::ACTIVE_VIEWER),
1518 PluginFunctions::ACTIVE_VIEWER);
1519}
1520
1521
1525
1527 PluginFunctions::viewAll(_viewer);
1528}
1529
1533
1536}
1537
1541
1545
1546
1550
1554
1555void ViewControlPlugin::setFOVY( double _fovy ) {
1557
1558 emit updateView();
1559}
1560
1562
1563 // Find coordsys node
1564 ACG::SceneGraph::BaseNode* node = 0;
1565 node = PluginFunctions::getSceneGraphRootNode()->find("Core Coordsys Node");
1566 if (node != 0) {
1567 ACG::SceneGraph::CoordsysNode* cnode = dynamic_cast<ACG::SceneGraph::CoordsysNode*> (node);
1568 if (cnode->getProjectionMode() == ACG::SceneGraph::CoordsysNode::PERSPECTIVE_PROJECTION) {
1569 if ( _orthogonal) {
1570 cnode->setProjectionMode(ACG::SceneGraph::CoordsysNode::ORTHOGRAPHIC_PROJECTION);
1571 emit updateView();
1572 }
1573 } else {
1574 if ( !_orthogonal) {
1575 cnode->setProjectionMode(ACG::SceneGraph::CoordsysNode::PERSPECTIVE_PROJECTION);
1576 emit updateView();
1577 }
1578 }
1579
1580 } else {
1581 emit log(LOGERR,tr("setCoordsysProjection(): Could not find coordsys node, thus its projection mode will not be toggled."));
1582 }
1583
1584}
1585
1586void ViewControlPlugin::setTwoSidedLighting(bool _enabled) {
1588}
1589
1592 return state.project(_point);
1593}
1594
1595void ViewControlPlugin::setDescriptions() {
1596 emit setSlotDescription("translate(Vector,int)", "Translate Scene",
1597 QString("TranslationVector,Viewer").split(","),
1598 QString("vector for the translation.,Viewer id (default is all)").split(","));
1599 emit setSlotDescription("translate(Vector)", "Translate Scene in all Viewers",
1600 QString("TranslationVector").split(","),
1601 QString("vector for the translation.").split(","));
1602 emit setSlotDescription("rotate(Vector,double,Vector,int)", "Rotate Scene",
1603 QString("Axis,Angle,Center,Viewer").split(","),
1604 QString("Rotation axis., Rotation Angle., Rotation Center.").split(","));
1605 emit setSlotDescription("rotate(Vector,double,Vector)", "Rotate Scene in all viewers",
1606 QString("Axis,Angle,Center").split(","),
1607 QString("Rotation axis., Rotation Angle., Rotation Center.").split(","));
1608 emit setSlotDescription("setViewingDirection(Vector,Vector,int)", "Set the viewing direction",
1609 QString("direction,upVector,Viewer").split(","),
1610 QString("Viewing direction., Up-Vector.,Viewer id (default is all)").split(","));
1611 emit setSlotDescription("setViewingDirection(Vector,Vector)", "Set the viewing direction in all viewers",
1612 QString("direction,upVector").split(","),
1613 QString("Viewing direction., Up-Vector.").split(","));
1614 emit setSlotDescription("setDrawMode(QString,int)", "Set the drawMode",
1615 QString("DrawMode,Viewer").split(","),
1616 QString("the drawMode ( ; separated list ),Viewer id (default is all)").split(","));
1617 emit setSlotDescription("setDrawMode(QString)", "Set the drawMode for all viewers",
1618
1619 QStringList("DrawMode"), QStringList("the drawMode ( ; separated list )"));
1620
1621 emit setSlotDescription("setObjectDrawMode(QString,int,bool)", "Set the drawMode for an object",
1622 QString("DrawMode,ObjectID,Force").split(","),
1623 QString("the drawMode ( ; separated list ),Object id,Apply without checking support(default is true)").split(","));
1624
1625 emit setSlotDescription("viewAll()", "Change View on all viewers to view whole scene",
1626 QStringList(), QStringList());
1627 emit setSlotDescription("viewAll(int)", "Change View on given viewer to view whole scene",
1628 QStringList("Viewer"), QStringList("Id of the viewer to change"));
1629
1630 emit setSlotDescription("viewHome()", "Change View on all viewers to view home position",
1631 QStringList(), QStringList());
1632 emit setSlotDescription("viewHome(int)", "Change View on given viewer to view home position",
1633 QStringList("Viewer"), QStringList("Id of the viewer to change"));
1634
1635
1636 emit setSlotDescription("orthographicProjection()", "Change Viewer to orthographic projection",
1637 QStringList(), QStringList());
1638 emit setSlotDescription("orthographicProjection(int)", "Change all Viewers to orthographic projection",
1639 QStringList("Viewer"), QStringList("Id of the viewer to change"));
1640
1641
1642 emit setSlotDescription("perspectiveProjection()", "Change Viewer to perspective projection",
1643 QStringList(), QStringList());
1644 emit setSlotDescription("perspectiveProjection(int)", "Change all Viewers to perspective projection",
1645 QStringList("Viewer"), QStringList("Id of the viewer to change"));
1646
1647 emit setSlotDescription("setFOVY(double)", "Set fovy angle of projection for all viewers.",
1648 QStringList("fovy"), QStringList("FOVY angle"));
1649
1650 emit setSlotDescription("setCoordsysProjection(bool)", "Set the projection mode of the coordinate system.",
1651 QStringList("orthogonal"), QStringList("If true, orthogonal projection otherwise perspective projection"));
1652
1653 emit setSlotDescription("upVector()", "Get the current upVector.",
1654 QStringList(), QStringList());
1655
1656 emit setSlotDescription("upVector(int)", "Get the current upVector of a specific viewer.",
1657 QStringList("ViewerId"), QStringList("Id of the viewer"));
1658
1659 emit setSlotDescription("eyePosition()", "Get the current eyePosition.",
1660 QStringList(), QStringList());
1661
1662 emit setSlotDescription("eyePosition(int)", "Get the current eyePosition of a specific viewer.",
1663 QStringList("ViewerId"), QStringList("Id of the viewer"));
1664
1665 emit setSlotDescription("sceneCenter()", "Get the current sceneCenter.",
1666 QStringList(), QStringList());
1667
1668 emit setSlotDescription("sceneCenter(int)", "Get the current sceneCenter of a specific viewer.",
1669 QStringList("ViewerId"), QStringList("Id of the viewer"));
1670
1671 emit setSlotDescription("viewingDirection()", "Get the current viewingDirection.",
1672 QStringList(), QStringList());
1673
1674 emit setSlotDescription("viewingDirection(int)", "Get the current viewingDirection of a specific viewer.",
1675 QStringList("ViewerId"), QStringList("Id of the viewer"));
1676
1677 emit setSlotDescription("setTwoSidedLighting(bool)", "Enable or disable two sided lighting.",
1678 QStringList("enabled"), QStringList("Specifies whether to enable or disable two sided lighting."));
1679
1680}
1681
1682
1683
@ CONTEXTOBJECTMENU
The Menu will be shown when an object was picked.
DLLEXPORT std::vector< TypeInfo >::const_iterator typesEnd()
Get iterator pointing to the last element in the types list.
Definition Types.cc:185
DLLEXPORT std::vector< TypeInfo >::const_iterator typesBegin()
Get iterator pointing to the first element in the types list.
Definition Types.cc:180
@ LOGERR
@ LOGWARN
#define DATA_POLY_MESH
Definition PolyMesh.hh:59
#define DATA_TRIANGLE_MESH
Vec3d project(const Vec3d &_point) const
project point in world coordinates to window coordinates
Definition GLState.cc:640
ChildIter find(BaseNode *_node)
Definition BaseNode.hh:346
DrawModes::DrawMode drawMode() const
Get the collected draw modes.
DrawModes::DrawMode drawModes() const
Get the collected draw modes.
void setProjectionMode(const ProjectionMode _mode)
set mode to either ORTHOGRAPHIC_PROJECTION or PERSPECTIVE_PROJECTION
ProjectionMode getProjectionMode() const
get current projection mode
void combine(DrawMode _mode)
combine with another drawmode
Definition DrawModes.cc:469
void filter(DrawMode _filter)
filter out one drawmode
Definition DrawModes.cc:453
std::vector< DrawMode > getAtomicDrawModes() const
Separates this drawMode into a list of all separate atomic draw modes.
Definition DrawModes.cc:485
bool containsAtomicDrawMode(const DrawMode &_atomicDrawMode) const
Check whether an Atomic DrawMode is active in this draw Mode.
Definition DrawModes.cc:510
virtual ACG::SceneGraph::ShaderNode * shaderNode()
virtual BaseNode * primaryNode()
bool dataType(DataType _type) const
GLSL program class.
void disable()
Resets to standard rendering pipeline.
void use()
Enables the program object for using.
void setUniform(const char *_name, GLint _value)
Set int uniform to specified value.
Class for the handling of simple configuration files.
Definition INIFile.hh:100
bool connect(const QString &name, const bool create)
Connect INIFile object with given filename.
Definition INIFile.cc:70
bool get_entry(QString &_val, const QString &_section, const QString &_key) const
Access to a string entry.
Definition INIFile.cc:433
void disconnect()
Remove connection of this object to a file.
Definition INIFile.cc:122
bool areaVisible(StatusBits _bit)
Return if the selected areas are currently visible.
ACG::SceneGraph::StatusNodeT< MeshT, FeatureNodeMod< MeshT > > * featureNode()
Returns the feature selection node if available, nullptr otherwise.
bool featuresVisible()
return if the feature Node of the object is currently visible
void hideFeatures(bool _hide)
Hide or show the feature Node of the object.
ACG::SceneGraph::SelectionNodeT< MeshT > * statusNode()
bool selectionVisible()
return if the selections are currently visible
void hideSelection(bool _hide)
Hide or show the selection Node of the object.
void hideArea(StatusBits _bit, bool _hide)
Hide or show the area Nodes of the object.
Type for a Meshobject containing a poly mesh.
Definition PolyMesh.hh:65
Type for a MeshObject containing a triangle mesh.
void setSceneCenter(Vector _center, int _viewer=PluginFunctions::ALL_VIEWERS)
Set the scene center.
void showSelection(int _id, bool _state)
Allows to enable/disable visualization of the objects selection for meshes.
void disableShader(int _objectId, ACG::SceneGraph::DrawModes::DrawMode _drawMode, ShaderInfo *_shader=0)
void viewAll()
Change View on all viewers to view whole scene.
void perspectiveProjection()
Change Viewer to perspectiveProjection.
void setViewingDirection(Vector _direction, Vector _upvector, int _viewer=PluginFunctions::ALL_VIEWERS)
Set the viewing direction.
void translate(Vector _vec, int _viewer=PluginFunctions::ALL_VIEWERS)
translate Scene
std::vector< ShaderInfo > shaderList_
void rotate(Vector _axis, double _angle, Vector _center, int _viewer=PluginFunctions::ALL_VIEWERS)
Rotate Scene.
Vector eyePosition(int _viewer=PluginFunctions::ACTIVE_VIEWER)
get a viewers eye Position
void showModelingAreas(int _id, bool _state)
Allows to enable/disable visualization of the objects modeling area for meshes.
Vector upVector(int _viewer=PluginFunctions::ACTIVE_VIEWER)
get a viewers up vector
void showAreas(StatusBits _bits, int _id, bool _state)
Show or hide modeling areas.
void setFOVY(double _fovy)
Set fovy angle of projection.
void viewHome()
Change View on given Viewer to view home position.
bool selectionVisible(int _id)
For meshes returns if the selection for this object is visible.
ACG::SceneGraph::DrawModes::DrawMode availDrawModes_
void setShader(int _id, ACG::SceneGraph::DrawModes::DrawMode _drawMode, ShaderInfo _shader)
ACG::SceneGraph::DrawModes::DrawMode activeDrawModes_
ACG::Vec3d project(ACG::Vec3d _point, int _viewerId=0)
Use the projection matrix of the given viewer to project the point.
void setUniform(int _objID, ACG::SceneGraph::DrawModes::DrawMode _drawMode, QString _shader, QString _uniform, QString _value)
set the value of a uniform in a shader for a specific drawMode
QString description()
Return a description of what the plugin is doing.
void setDrawMode(QString _mode, int _viewer=PluginFunctions::ALL_VIEWERS)
Set the draw mode for a viewer.
Vector viewingDirection(int _viewer=PluginFunctions::ACTIVE_VIEWER)
Get a viewers viewing direction.
bool modelingAreasVisible(int _id)
For meshes returns if the modeling areas for this object is visible.
void setObjectDrawMode(QString _mode, int _objectID, bool _force=true)
Set the draw mode for an object.
void setFeatureLineWidth(int _id, double _width)
Set the line width of the features.
void setCoordsysProjection(bool _orthogonal)
bool areasVisible(StatusBits _bits, int _id)
Return of all of the given modeling areas are visible.
void setSelectionLineWidth(int _id, double _width)
Set the line width of the selections.
void orthographicProjection()
Change Viewer to orthographicProjection.
void setSceneRadius(double _radius, int _viewer=PluginFunctions::ALL_VIEWERS)
Set scene radius.
QString name()
Return a name for the plugin.
void enableBackfaceCulling(bool _state, int _viewer=PluginFunctions::ALL_VIEWERS)
Enable or disable Backface culling.
QStringList getUniforms(QString _shader)
get information about available uniforms for a given shader
Vector sceneCenter(int _viewer=PluginFunctions::ACTIVE_VIEWER)
Get the scene center.
void twoSidedLighting(bool _state)
set 2-sided lighting on/off
bool backFaceCulling()
Get current state of backface culling.
ACG::GLState & glState()
Get the glState of the Viewer.
DrawMode DEFAULT
use the default (global) draw mode and not the node's own.
Definition DrawModes.cc:72
void traverse(BaseNode *_node, Action &_action)
void translate(const ACG::Vec3d &_vector, int _viewer)
Translate viewer pos by given vector.
void perspectiveProjection(int _viewer)
Switch to perspective Projection.
void setSceneRadius(double _radius, int _viewer)
Set the background color of the examiner widget.
ACG::Vec3d eyePos(int _viewer)
Get the current viewer position.
TriMeshObject * triMeshObject(BaseObjectData *_object)
Cast an BaseObject to a TriMeshObject if possible.
Viewer::ViewerProperties & viewerProperties(int _id)
Get the viewer properties Use this functions to get basic viewer properties such as backgroundcolor o...
void viewingDirection(const ACG::Vec3d &_dir, const ACG::Vec3d &_up, int _viewer)
Set the viewing direction.
void viewHome(int _viewer)
Go to home position.
bool getObject(const int _identifier, BaseObject *&_object)
Get the object which has the given identifier.
void orthographicProjection(int _viewer)
Switch to orthographic Projection.
void setScenePos(const ACG::Vec3d &_center, const double _radius, int _viewer)
Set the Scene position.
PolyMeshObject * polyMeshObject(BaseObjectData *_object)
Cast an BaseObject to a PolyMeshObject if possible.
ACG::Vec3d upVector(int _viewer)
Get the current up vector.
void rotate(const ACG::Vec3d &_axis, const double _angle, const ACG::Vec3d &_center, int _viewer)
Rotate Scene around axis.
int viewers()
Get the number of viewers.
ACG::SceneGraph::DrawModes::DrawMode drawMode(int _viewer)
Get the current draw Mode of a Viewer.
void setFOVY(double _fovy)
Set field of view angle.
void setDrawMode(const ACG::SceneGraph::DrawModes::DrawMode &_mode, int _viewer)
Set the draw Mode of a Viewer. .
unsigned int activeExaminer()
Get the id of the examiner which got the last mouse events.
void lookAt(const ACG::Vec3d &_eye, const ACG::Vec3d &_center, const ACG::Vec3d &_up, int _viewer)
Set the look at transformation directly.
ACG::SceneGraph::BaseNode * getSceneGraphRootNode()
get scenegraph root node
const ACG::Vec3d sceneCenter(int _viewer)
Get the current scene center.
void viewAll(int _viewer)
View the whole scene.