Gui/ViewProvider.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (c) 2004 Jürgen Riegel <juergen.riegel@web.de>              *
00003  *                                                                         *
00004  *   This file is part of the FreeCAD CAx development system.              *
00005  *                                                                         *
00006  *   This library is free software; you can redistribute it and/or         *
00007  *   modify it under the terms of the GNU Library General Public           *
00008  *   License as published by the Free Software Foundation; either          *
00009  *   version 2 of the License, or (at your option) any later version.      *
00010  *                                                                         *
00011  *   This library  is distributed in the hope that it will be useful,      *
00012  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00013  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00014  *   GNU Library General Public License for more details.                  *
00015  *                                                                         *
00016  *   You should have received a copy of the GNU Library General Public     *
00017  *   License along with this library; see the file COPYING.LIB. If not,    *
00018  *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
00019  *   Suite 330, Boston, MA  02111-1307, USA                                *
00020  *                                                                         *
00021  ***************************************************************************/
00022 
00023 
00024 #include "PreCompiled.h"
00025 
00026 #ifndef _PreComp_
00027 # include <QPixmap>
00028 # include <Inventor/SoPickedPoint.h>
00029 # include <Inventor/nodes/SoSeparator.h>
00030 # include <Inventor/nodes/SoSwitch.h>
00031 # include <Inventor/nodes/SoTransform.h>
00032 # include <Inventor/nodes/SoCamera.h>
00033 # include <Inventor/events/SoMouseButtonEvent.h>
00034 # include <Inventor/events/SoLocation2Event.h>
00035 #endif
00036 
00038 #include <Base/Console.h>
00039 #include <Base/Exception.h>
00040 #include <Base/Matrix.h>
00041 #include <App/PropertyGeo.h>
00042 
00043 #include "ViewProvider.h"
00044 #include "Application.h"
00045 #include "Document.h"
00046 #include "ViewProviderPy.h"
00047 #include "BitmapFactory.h"
00048 #include "View3DInventor.h"
00049 #include "View3DInventorViewer.h"
00050 #include "SoFCDB.h"
00051 
00052 using namespace std;
00053 using namespace Gui;
00054 
00055 
00056 //**************************************************************************
00057 //**************************************************************************
00058 // ViewProvider
00059 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00060 
00061 PROPERTY_SOURCE_ABSTRACT(Gui::ViewProvider, App::PropertyContainer)
00062 
00063 ViewProvider::ViewProvider() 
00064   : pcAnnotation(0), pyViewObject(0), _iActualMode(-1), _iEditMode(-1), _updateData(true)
00065 {
00066     pcRoot = new SoSeparator();
00067     pcRoot->ref();
00068     pcModeSwitch = new SoSwitch();
00069     pcModeSwitch->ref();
00070     pcTransform  = new SoTransform();
00071     pcTransform->ref();
00072     pcRoot->addChild(pcTransform);
00073     pcRoot->addChild(pcModeSwitch);
00074     sPixmap = "px";
00075     pcModeSwitch->whichChild = _iActualMode;
00076 }
00077 
00078 ViewProvider::~ViewProvider()
00079 {
00080     if (pyViewObject) {
00081         pyViewObject->setInvalid();
00082         pyViewObject->DecRef();
00083     }
00084 
00085     pcRoot->unref();
00086     pcTransform->unref();
00087     pcModeSwitch->unref();
00088     if (pcAnnotation)
00089         pcAnnotation->unref();
00090 }
00091 
00092 bool ViewProvider::startEditing(int ModNum)
00093 {
00094     bool ok = setEdit(ModNum);
00095     if (ok) _iEditMode = ModNum;
00096     return ok;
00097 }
00098 
00099 int ViewProvider::getEditingMode() const
00100 {
00101     return _iEditMode;
00102 }
00103 
00104 bool ViewProvider::isEditing() const
00105 {
00106     return getEditingMode() > -1;
00107 }
00108 
00109 void ViewProvider::finishEditing()
00110 {
00111     unsetEdit(_iEditMode);
00112     _iEditMode = -1;
00113 }
00114 
00115 bool ViewProvider::setEdit(int ModNum)
00116 {
00117     return true;
00118 }
00119 
00120 void ViewProvider::unsetEdit(int ModNum)
00121 {
00122 }
00123 
00124 void ViewProvider::setEditViewer(View3DInventorViewer*, int ModNum)
00125 {
00126 }
00127 
00128 void ViewProvider::unsetEditViewer(View3DInventorViewer*)
00129 {
00130 }
00131 
00132 bool ViewProvider::isUpdatesEnabled () const
00133 {
00134     return _updateData;
00135 }
00136 
00137 void ViewProvider::setUpdatesEnabled (bool enable)
00138 {
00139     _updateData = enable;
00140 }
00141 
00142 void ViewProvider::eventCallback(void * ud, SoEventCallback * node)
00143 {
00144     const SoEvent * ev = node->getEvent();
00145     Gui::View3DInventorViewer* view  = reinterpret_cast<Gui::View3DInventorViewer*>(node->getUserData());
00146     ViewProvider *self = reinterpret_cast<ViewProvider*>(ud);
00147     assert(self);
00148 
00149     // Calculate 3d point to the mouse position
00150     SbVec3f point, norm;
00151     point = view->getPointOnScreen(ev->getPosition());
00152     norm = view->getViewDirection();
00153 
00154     // for convenience make a pick ray action to get the (potentially) picked entity in the provider
00155     //SoPickedPoint* Point = self->getPointOnRay(point,norm,*view);
00156     SoSeparator* root = new SoSeparator;
00157     root->ref();
00158     root->addChild(view->getCamera());
00159     root->addChild(self->pcRoot);
00160 
00161     SoRayPickAction rp(view->getViewportRegion());
00162     rp.setPoint(ev->getPosition());
00163     rp.apply(root);
00164     root->unref();
00165 
00166     SoPickedPoint* pp = rp.getPickedPoint();
00167 
00168     try {
00169         // Keyboard events
00170         if (ev->getTypeId().isDerivedFrom(SoKeyboardEvent::getClassTypeId())) {
00171             SoKeyboardEvent * ke = (SoKeyboardEvent *)ev;
00172             const SbBool press = ke->getState() == SoButtonEvent::DOWN ? TRUE : FALSE;
00173             switch (ke->getKey()) {
00174             case SoKeyboardEvent::ESCAPE:
00175                 if (self->keyPressed (press, ke->getKey()))
00176                     node->setHandled();
00177                 else
00178                     Gui::Application::Instance->activeDocument()->resetEdit();
00179                 break;
00180             default:
00181                 // call the virtual method
00182                 if (self->keyPressed (press, ke->getKey()))
00183                     node->setHandled();
00184                 break;
00185             }
00186         }
00187         // switching the mouse buttons
00188         else if (ev->getTypeId().isDerivedFrom(SoMouseButtonEvent::getClassTypeId())) {
00189 
00190             const SoMouseButtonEvent * const event = (const SoMouseButtonEvent *) ev;
00191             const int button = event->getButton();
00192             const SbBool press = event->getState() == SoButtonEvent::DOWN ? TRUE : FALSE;
00193 
00194             // call the virtual method
00195             if (self->mouseButtonPressed(button,press,point,norm,pp))
00196                 node->setHandled();
00197         }
00198         // Mouse Movement handling
00199         else if (ev->getTypeId().isDerivedFrom(SoLocation2Event::getClassTypeId())) {
00200             if (self->mouseMove(point,norm,pp))
00201                 node->setHandled();
00202         }
00203     }
00204     catch (const Base::Exception& e) {
00205         Base::Console().Error("Unhandled exception in ViewProvider::eventCallback: %s\n", e.what());
00206     }
00207     catch (const std::exception& e) {
00208         Base::Console().Error("Unhandled std exception in ViewProvider::eventCallback: %s\n", e.what());
00209     }
00210     catch (...) {
00211         Base::Console().Error("Unhandled unknown C++ exception in ViewProvider::eventCallback");
00212     }
00213 }
00214 
00215 SoSeparator* ViewProvider::getAnnotation(void)
00216 {
00217     if (!pcAnnotation) {
00218         pcAnnotation = new SoSeparator();
00219         pcAnnotation->ref();
00220         pcRoot->addChild(pcAnnotation);
00221     }
00222     return pcAnnotation;
00223 }
00224 
00225 void ViewProvider::update(const App::Property* prop)
00226 {
00227     // Hide the object temporarily to speed up the update
00228     if (!isUpdatesEnabled())
00229         return;
00230     bool vis = ViewProvider::isShow();
00231     if (vis) ViewProvider::hide();
00232     updateData(prop);
00233     if (vis) ViewProvider::show();
00234 }
00235 
00236 QIcon ViewProvider::getIcon(void) const
00237 {
00238     return Gui::BitmapFactory().pixmap(sPixmap);
00239 }
00240 
00241 void ViewProvider::setTransformation(const Base::Matrix4D &rcMatrix)
00242 {
00243     double dMtrx[16];
00244     rcMatrix.getGLMatrix(dMtrx);
00245 
00246     pcTransform->setMatrix(SbMatrix(dMtrx[0], dMtrx[1], dMtrx[2],  dMtrx[3],
00247                                     dMtrx[4], dMtrx[5], dMtrx[6],  dMtrx[7],
00248                                     dMtrx[8], dMtrx[9], dMtrx[10], dMtrx[11],
00249                                     dMtrx[12],dMtrx[13],dMtrx[14], dMtrx[15]));
00250 }
00251 
00252 void ViewProvider::setTransformation(const SbMatrix &rcMatrix)
00253 {
00254     pcTransform->setMatrix(rcMatrix);
00255 }
00256 
00257 SbMatrix ViewProvider::convert(const Base::Matrix4D &rcMatrix) const
00258 {
00259     double dMtrx[16];
00260     rcMatrix.getGLMatrix(dMtrx);
00261     return SbMatrix(dMtrx[0], dMtrx[1], dMtrx[2],  dMtrx[3],
00262                     dMtrx[4], dMtrx[5], dMtrx[6],  dMtrx[7],
00263                     dMtrx[8], dMtrx[9], dMtrx[10], dMtrx[11],
00264                     dMtrx[12],dMtrx[13],dMtrx[14], dMtrx[15]);
00265 }
00266 
00267 void ViewProvider::addDisplayMaskMode( SoNode *node, const char* type )
00268 {
00269     _sDisplayMaskModes[ type ] = pcModeSwitch->getNumChildren();
00270     pcModeSwitch->addChild( node );
00271 }
00272 
00273 void ViewProvider::setDisplayMaskMode( const char* type )
00274 {
00275     std::map<std::string, int>::const_iterator it = _sDisplayMaskModes.find( type );
00276     if (it != _sDisplayMaskModes.end())
00277         pcModeSwitch->whichChild = it->second;
00278     else
00279         pcModeSwitch->whichChild = -1;
00280     _iActualMode = pcModeSwitch->whichChild.getValue();
00281 }
00282 
00283 std::vector<std::string> ViewProvider::getDisplayMaskModes() const
00284 {
00285     std::vector<std::string> types;
00286     for (std::map<std::string, int>::const_iterator it = _sDisplayMaskModes.begin();
00287          it != _sDisplayMaskModes.end(); ++it)
00288         types.push_back( it->first );
00289     return types;
00290 }
00291 
00297 void ViewProvider::setDisplayMode(const char* ModeName)
00298 {
00299     _sCurrentMode = ModeName;
00300 }
00301 
00302 std::string ViewProvider::getActiveDisplayMode(void) const
00303 {
00304     return _sCurrentMode;
00305 }
00306 
00307 void ViewProvider::hide(void)
00308 {
00309     pcModeSwitch->whichChild = -1;
00310 }
00311 
00312 void ViewProvider::show(void)
00313 {
00314     pcModeSwitch->whichChild = _iActualMode;
00315 }
00316 
00317 bool ViewProvider::isShow(void) const
00318 {
00319     return pcModeSwitch->whichChild.getValue() != -1;
00320 }
00321 
00322 void ViewProvider::setVisible(bool s)
00323 {
00324     s ? show() : hide();
00325 }
00326 
00327 bool ViewProvider::isVisible() const
00328 {
00329     return isShow();
00330 }
00331 
00332 void ViewProvider::setDefaultMode(int val)
00333 {
00334     _iActualMode = val;
00335 }
00336 
00337 void ViewProvider::onChanged(const App::Property* prop)
00338 {
00339     Application::Instance->signalChangedObject(*this, *prop);
00340 }
00341 
00342 std::string ViewProvider::toString() const
00343 {
00344     return SoFCDB::writeNodesToString(pcRoot);
00345 }
00346 
00347 PyObject* ViewProvider::getPyObject()
00348 {
00349     if (!pyViewObject)
00350         pyViewObject = new ViewProviderPy(this);
00351     pyViewObject->IncRef();
00352     return pyViewObject;
00353 }
00354 
00355 SoPickedPoint* ViewProvider::getPointOnRay(const SbVec3f& pos,const SbVec3f& dir, const View3DInventorViewer& viewer) const
00356 {
00357     // Note: There seems to be a  bug with setRay() which causes SoRayPickAction
00358     // to fail to get intersections between the ray and a line
00359     SoRayPickAction rp(viewer.getViewportRegion());
00360     rp.setRay(pos,dir);
00361     rp.apply(pcRoot);
00362 
00363     // returns a copy of the point
00364     SoPickedPoint* pick = rp.getPickedPoint();
00365     //return (pick ? pick->copy() : 0); // needs the same instance of CRT under MS Windows
00366     return (pick ? new SoPickedPoint(*pick) : 0);
00367 }

Generated on Wed Nov 23 19:00:57 2011 for FreeCAD by  doxygen 1.6.1