SofaViewer.h
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #ifndef SOFA_VIEWER_H
00028 #define SOFA_VIEWER_H
00029
00030 #include <qstring.h>
00031 #include <qwidget.h>
00032
00033
00034
00035 #ifdef SOFA_QT4
00036 #include <QEvent>
00037 #include <QMouseEvent>
00038 #include <QKeyEvent>
00039 #else
00040 #include <qevent.h>
00041 #endif
00042
00043
00044 #include <sofa/helper/gl/Capture.h>
00045 #include <sofa/core/objectmodel/KeypressedEvent.h>
00046 #include <sofa/core/objectmodel/KeyreleasedEvent.h>
00047 #include <sofa/core/objectmodel/MouseEvent.h>
00048 #include <sofa/component/collision/RayPickInteractor.h>
00049
00050
00051 #include <sofa/component/controller/Controller.h>
00052 #include <sofa/defaulttype/LaparoscopicRigidTypes.h>
00053
00054 #include <sofa/simulation/common/MechanicalVisitor.h>
00055 #include <sofa/simulation/common/UpdateMappingVisitor.h>
00056 #include <sofa/simulation/tree/Simulation.h>
00057 #ifdef SOFA_QT4
00058 #include <QEvent>
00059 #include <QMouseEvent>
00060 #include <QKeyEvent>
00061 #else
00062 #include <qevent.h>
00063 #endif
00064
00065 namespace sofa
00066 {
00067
00068 namespace gui
00069 {
00070
00071 namespace qt
00072 {
00073
00074 namespace viewer
00075 {
00076
00077 using namespace sofa::defaulttype;
00078 enum {
00079 BTLEFT_MODE = 101,
00080 BTRIGHT_MODE = 102,
00081 BTMIDDLE_MODE = 103,
00082 };
00083
00084 enum {CAMERA_PERSPECTIVE, CAMERA_ORTHOGRAPHIC};
00085
00086 class SofaViewer
00087
00088
00089 {
00090
00091 public:
00092 SofaViewer ()
00093 : groot(NULL), m_isControlPressed(false), _video(false), _shadow(false), _gl_shadow(false), _axis(false), camera_type(CAMERA_PERSPECTIVE)
00094 {}
00095 virtual ~SofaViewer(){}
00096
00097 virtual QWidget* getQWidget()=0;
00098
00099 virtual sofa::simulation::tree::GNode* getScene() { return groot;}
00100 virtual const std::string& getSceneFileName(){ return sceneFileName;}
00101 virtual void setSceneFileName(const std::string &f){sceneFileName = f;};
00102
00103 virtual void setup() {}
00104 virtual void setScene(sofa::simulation::tree::GNode* scene, const char* filename=NULL, bool =false)
00105 {
00106
00107
00108 scene->getContext()->get( interactor);
00109 std::ostringstream ofilename;
00110 std::string screenshot_prefix;
00111
00112 sceneFileName = (filename==NULL)?"":filename;
00113 if (!sceneFileName.empty())
00114 {
00115 const char* begin = sceneFileName.c_str();
00116 const char* end = strrchr(begin,'.');
00117 if (!end) end = begin + sceneFileName.length();
00118 ofilename << std::string(begin, end);
00119 ofilename << "_";
00120
00121 screenshot_prefix = ofilename.str();
00122
00123 std::string::size_type position_scene = screenshot_prefix.rfind("scenes/");
00124
00125 if (position_scene != std::string::npos && position_scene < screenshot_prefix.size()-7)
00126 {
00127 screenshot_prefix.replace(position_scene, 7, "share/screenshots/");
00128 }
00129 }
00130 else
00131 screenshot_prefix = "scene_";
00132 capture.setPrefix(screenshot_prefix);
00133
00134 groot = scene;
00135 initTexturesDone = false;
00136 sceneBBoxIsValid = true;
00137
00138 }
00139
00140
00141 virtual void resetView()=0;
00142 virtual QString helpString()=0;
00143 virtual bool ready() { return true; }
00144 virtual void wait() {}
00145
00146
00147 virtual const std::string screenshotName(){ return capture.findFilename().c_str();};
00148 virtual void setPrefix(const std::string filename){capture.setPrefix(filename);};
00149 virtual void screenshot(const std::string filename, int compression_level = -1)
00150 {
00151 capture.saveScreen(filename, compression_level);
00152 }
00153
00154 protected:
00155
00156
00157
00158
00159 void keyPressEvent ( QKeyEvent * e )
00160 {
00161 switch(e->key())
00162 {
00163 case Qt::Key_B:
00164
00165 {
00166 _background = (_background+1)%3;
00167 break;
00168 }
00169 case Qt::Key_L:
00170
00171 {
00172 if (_gl_shadow) _shadow = !_shadow;
00173 break;
00174 }
00175 case Qt::Key_R:
00176
00177 {
00178 _axis = !_axis;
00179 break;
00180 }
00181 case Qt::Key_S:
00182 {
00183 screenshot(capture.findFilename());
00184 break;
00185 }
00186 case Qt::Key_T:
00187 {
00188 if (camera_type == CAMERA_PERSPECTIVE)
00189 camera_type = CAMERA_ORTHOGRAPHIC;
00190 else
00191 camera_type = CAMERA_PERSPECTIVE;
00192 break;
00193 }
00194 case Qt::Key_V:
00195
00196 {
00197 _video = !_video;
00198 capture.setCounter();
00199 break;
00200 }
00201 case Qt::Key_W:
00202
00203 {
00204 saveView();
00205 break;
00206 }
00207 case Qt::Key_Control:
00208 {
00209 m_isControlPressed = true;
00210
00211 break;
00212 }
00213 default:
00214 {
00215 e->ignore();
00216 }
00217 }
00218 }
00219
00220
00221 void keyReleaseEvent ( QKeyEvent * e )
00222 {
00223
00224 switch(e->key())
00225 {
00226 case Qt::Key_Control:
00227 {
00228 m_isControlPressed = false;
00229
00230
00231 sofa::core::objectmodel::MouseEvent mouseEvent(sofa::core::objectmodel::MouseEvent::Reset);
00232 if (groot)
00233 groot->propagateEvent(&mouseEvent);
00234 }
00235 default:
00236 {
00237 e->ignore();
00238 }
00239 }
00240
00241 if( isControlPressed() )
00242 {
00243 sofa::core::objectmodel::KeyreleasedEvent keyEvent(e->key());
00244 if (groot)
00245 groot->propagateEvent(&keyEvent);
00246 }
00247 }
00248
00249
00250
00251
00252 bool isControlPressed() const {
00253 return m_isControlPressed;
00254 }
00255
00256
00257
00258
00259
00260 void mouseEvent( QMouseEvent *e)
00261 {
00262 if (e->state()&Qt::ShiftButton)
00263 {
00264
00265 if (interactor==NULL)
00266 {
00267 interactor = new sofa::component::collision::RayPickInteractor();
00268 interactor->setName("mouse");
00269 if (groot)
00270 {
00271 simulation::tree::GNode* child = new simulation::tree::GNode("mouse");
00272 groot->addChild(child);
00273 child->addObject(interactor);
00274 }
00275 interactor->init();
00276 }
00277 interactor->newEvent("show");
00278 switch (e->type())
00279 {
00280 case QEvent::MouseButtonPress:
00281 if (e->button() == Qt::LeftButton)
00282 {
00283 interactor->newEvent("pick");
00284 }
00285 else if (e->button() == Qt::RightButton)
00286 {
00287 interactor->newEvent("pick2");
00288 }
00289 else if (e->button() == Qt::MidButton)
00290 {
00291 interactor->newEvent("pick3");
00292 }
00293 break;
00294 case QEvent::MouseButtonRelease:
00295
00296 {
00297 interactor->newEvent("release");
00298 }
00299 break;
00300 default: break;
00301 }
00302 moveRayPickInteractor(e->x(), e->y());
00303 }
00304
00305 }
00306
00307
00308
00309 void moveLaparoscopic( QMouseEvent *e)
00310 {
00311 int index_instrument = simulation::tree::getSimulation()->instrumentInUse.getValue();
00312 if (index_instrument < 0 || index_instrument > (int)simulation::tree::getSimulation()->instruments.size()) return;
00313
00314 simulation::Node *instrument = simulation::tree::getSimulation()->instruments[index_instrument];
00315 if (instrument == NULL) return;
00316
00317 int eventX = e->x();
00318 int eventY = e->y();
00319
00320 std::vector< sofa::core::componentmodel::behavior::MechanicalState<sofa::defaulttype::LaparoscopicRigidTypes>* > instruments;
00321 instrument->getTreeObjects<sofa::core::componentmodel::behavior::MechanicalState<sofa::defaulttype::LaparoscopicRigidTypes>, std::vector< sofa::core::componentmodel::behavior::MechanicalState<sofa::defaulttype::LaparoscopicRigidTypes>* > >(&instruments);
00322
00323 if (!instruments.empty())
00324 {
00325 sofa::core::componentmodel::behavior::MechanicalState<sofa::defaulttype::LaparoscopicRigidTypes>* instrument = instruments[0];
00326 switch (e->type())
00327 {
00328 case QEvent::MouseButtonPress:
00329
00330 if (e->button() == Qt::LeftButton)
00331 {
00332 _navigationMode = BTLEFT_MODE;
00333 _mouseInteractorMoving = true;
00334 _mouseInteractorSavedPosX = eventX;
00335 _mouseInteractorSavedPosY = eventY;
00336 }
00337
00338 else if (e->button() == Qt::RightButton)
00339 {
00340 _navigationMode = BTRIGHT_MODE;
00341 _mouseInteractorMoving = true;
00342 _mouseInteractorSavedPosX = eventX;
00343 _mouseInteractorSavedPosY = eventY;
00344 }
00345
00346 else if (e->button() == Qt::MidButton)
00347 {
00348 _navigationMode = BTMIDDLE_MODE;
00349 _mouseInteractorMoving = true;
00350 _mouseInteractorSavedPosX = eventX;
00351 _mouseInteractorSavedPosY = eventY;
00352 }
00353 break;
00354
00355 case QEvent::MouseMove:
00356
00357 break;
00358
00359 case QEvent::MouseButtonRelease:
00360
00361 if (e->button() == Qt::LeftButton)
00362 {
00363 if (_mouseInteractorMoving)
00364 {
00365 _mouseInteractorMoving = false;
00366 }
00367 }
00368
00369 else if (e->button() == Qt::RightButton)
00370 {
00371 if (_mouseInteractorMoving)
00372 {
00373 _mouseInteractorMoving = false;
00374 }
00375 }
00376
00377 else if (e->button() == Qt::MidButton)
00378 {
00379 if (_mouseInteractorMoving)
00380 {
00381 _mouseInteractorMoving = false;
00382
00383 }
00384 }
00385 break;
00386
00387 default:
00388 break;
00389 }
00390
00391 if (_mouseInteractorMoving && _navigationMode == BTLEFT_MODE)
00392 {
00393 int dx = eventX - _mouseInteractorSavedPosX;
00394 int dy = eventY - _mouseInteractorSavedPosY;
00395 if (dx || dy)
00396 {
00397 (*instrument->getX())[0].getOrientation() = (*instrument->getX())[0].getOrientation() * Quat(Vector3(0,1,0),dx*0.001) * Quat(Vector3(0,0,1),dy*0.001);
00398 _mouseInteractorSavedPosX = eventX;
00399 _mouseInteractorSavedPosY = eventY;
00400 }
00401 }
00402 else if (_mouseInteractorMoving && _navigationMode == BTMIDDLE_MODE)
00403 {
00404 int dx = eventX - _mouseInteractorSavedPosX;
00405 int dy = eventY - _mouseInteractorSavedPosY;
00406 if (dx || dy)
00407 {
00408 _mouseInteractorSavedPosX = eventX;
00409 _mouseInteractorSavedPosY = eventY;
00410 }
00411 }
00412 else if (_mouseInteractorMoving && _navigationMode == BTRIGHT_MODE)
00413 {
00414 int dx = eventX - _mouseInteractorSavedPosX;
00415 int dy = eventY - _mouseInteractorSavedPosY;
00416 if (dx || dy)
00417 {
00418 (*instrument->getX())[0].getTranslation() += (dy)*0.01;
00419 (*instrument->getX())[0].getOrientation() = (*instrument->getX())[0].getOrientation() * Quat(Vector3(1,0,0),dx*0.001);
00420 _mouseInteractorSavedPosX = eventX;
00421 _mouseInteractorSavedPosY = eventY;
00422 }
00423 }
00424
00425 static_cast<sofa::simulation::tree::GNode*>(instrument->getContext())->execute<sofa::simulation::MechanicalPropagatePositionAndVelocityVisitor>();
00426 static_cast<sofa::simulation::tree::GNode*>(instrument->getContext())->execute<sofa::simulation::UpdateMappingVisitor>();
00427 getQWidget()->update();
00428 }
00429 else
00430 {
00431 std::vector< component::controller::Controller* > bc;
00432 instrument->getTreeObjects<component::controller::Controller, std::vector< component::controller::Controller* > >(&bc);
00433
00434 if (!bc.empty())
00435 {
00436 switch (e->type())
00437 {
00438 case QEvent::MouseButtonPress:
00439
00440 if (e->button() == Qt::LeftButton)
00441 {
00442 sofa::core::objectmodel::MouseEvent mouseEvent(sofa::core::objectmodel::MouseEvent::LeftPressed, eventX, eventY);
00443 if (groot)
00444 groot->propagateEvent(&mouseEvent);
00445 }
00446
00447 else if (e->button() == Qt::RightButton)
00448 {
00449 sofa::core::objectmodel::MouseEvent mouseEvent(sofa::core::objectmodel::MouseEvent::RightPressed, eventX, eventY);
00450 if (groot)
00451 groot->propagateEvent(&mouseEvent);
00452 }
00453
00454 else if (e->button() == Qt::MidButton)
00455 {
00456
00457 }
00458 break;
00459
00460 case QEvent::MouseMove:
00461 {
00462 if (e->state()&(Qt::LeftButton|Qt::RightButton))
00463 {
00464 sofa::core::objectmodel::MouseEvent mouseEvent(sofa::core::objectmodel::MouseEvent::Move, eventX, eventY);
00465 if (groot)
00466 groot->propagateEvent(&mouseEvent);
00467 }
00468 }
00469 break;
00470
00471 case QEvent::MouseButtonRelease:
00472
00473 if (e->button() == Qt::LeftButton)
00474 {
00475 sofa::core::objectmodel::MouseEvent mouseEvent(sofa::core::objectmodel::MouseEvent::LeftReleased, eventX, eventY);
00476 if (groot)
00477 groot->propagateEvent(&mouseEvent);
00478 }
00479
00480 else if (e->button() == Qt::RightButton)
00481 {
00482 sofa::core::objectmodel::MouseEvent mouseEvent(sofa::core::objectmodel::MouseEvent::RightReleased, eventX, eventY);
00483 if (groot)
00484 groot->propagateEvent(&mouseEvent);
00485 }
00486
00487 else if (e->button() == Qt::MidButton)
00488 {
00489
00490 }
00491 break;
00492
00493 default:
00494 break;
00495 }
00496
00497 getQWidget()->update();
00498 }
00499 }
00500 }
00501
00502 void moveLaparoscopic(QWheelEvent *e)
00503 {
00504 int index_instrument = simulation::tree::getSimulation()->instrumentInUse.getValue();
00505 if (index_instrument < 0 || index_instrument > (int)simulation::tree::getSimulation()->instruments.size()) return;
00506
00507 simulation::Node *instrument = simulation::tree::getSimulation()->instruments[index_instrument];
00508 if (instrument == NULL) return;
00509
00510 std::vector< component::controller::Controller* > bc;
00511 instrument->getTreeObjects<component::controller::Controller, std::vector< component::controller::Controller* > >(&bc);
00512
00513 if (!bc.empty())
00514 {
00515 sofa::core::objectmodel::MouseEvent mouseEvent(sofa::core::objectmodel::MouseEvent::Wheel, e->delta());
00516 if (groot)
00517 groot->propagateEvent(&mouseEvent);
00518 getQWidget()->update();
00519 }
00520 }
00521
00522 virtual void moveRayPickInteractor(int , int ){};
00523
00524 sofa::helper::gl::Capture capture;
00525 sofa::simulation::tree::GNode* groot;
00526 std::string sceneFileName;
00527
00528 bool m_isControlPressed;
00529 bool _video;
00530 bool _shadow;
00531 bool _gl_shadow;
00532 bool _axis;
00533 int camera_type;
00534 int _background;
00535 bool initTexturesDone;
00536 bool sceneBBoxIsValid;
00537 sofa::component::collision::RayPickInteractor* interactor;
00538
00539
00540 int _navigationMode;
00541 bool _mouseInteractorMoving;
00542 int _mouseInteractorSavedPosX;
00543 int _mouseInteractorSavedPosY;
00544
00545
00546
00547
00548
00549 virtual void saveView()=0;
00550 virtual void setSizeW(int)=0;
00551 virtual void setSizeH(int)=0;
00552
00553
00554
00555 virtual void redrawn()=0;
00556 virtual void resizeW( int )=0;
00557 virtual void resizeH( int )=0;
00558
00559 };
00560 }
00561 }
00562 }
00563 }
00564
00565 #endif