ViewProviderGeometryObject.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (c) 2006 Werner Mayer <wmayer[at]users.sourceforge.net>     *
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 <QAction>
00028 # include <QMenu>
00029 # include <Inventor/actions/SoSearchAction.h>
00030 # include <Inventor/draggers/SoDragger.h>
00031 # include <Inventor/draggers/SoCenterballDragger.h>
00032 # include <Inventor/manips/SoCenterballManip.h>
00033 # include <Inventor/nodes/SoBaseColor.h>
00034 # include <Inventor/nodes/SoCamera.h>
00035 # include <Inventor/nodes/SoDrawStyle.h>
00036 # include <Inventor/nodes/SoMaterial.h>
00037 # include <Inventor/nodes/SoSeparator.h>
00038 # include <Inventor/nodes/SoSwitch.h>
00039 # include <Inventor/nodes/SoDirectionalLight.h>
00040 # include <Inventor/sensors/SoNodeSensor.h> 
00041 # include <Inventor/SoPickedPoint.h>
00042 # include <Inventor/actions/SoRayPickAction.h> 
00043 #endif
00044 
00046 #include "ViewProviderGeometryObject.h"
00047 #include "View3DInventorViewer.h"
00048 #include "SoFCSelection.h"
00049 #include "SoFCBoundingBox.h"
00050 #include "Application.h"
00051 #include "Document.h"
00052 #include "Window.h"
00053 
00054 #include <Base/Placement.h>
00055 #include <App/PropertyGeo.h>
00056 #include <App/GeoFeature.h>
00057 #include <Inventor/draggers/SoCenterballDragger.h>
00058 #if (COIN_MAJOR_VERSION > 2)
00059 #include <Inventor/nodes/SoDepthBuffer.h>
00060 #endif
00061 #include "SoNavigationDragger.h"
00062 #include "SoFCUnifiedSelection.h"
00063 
00064 using namespace Gui;
00065 
00066 
00067 PROPERTY_SOURCE(Gui::ViewProviderGeometryObject, Gui::ViewProviderDocumentObject)
00068 
00069 const App::PropertyIntegerConstraint::Constraints intPercent = {0,100,1};
00070 
00071 ViewProviderGeometryObject::ViewProviderGeometryObject() : pcBoundSwitch(0)
00072 {
00073     ADD_PROPERTY(ShapeColor,(0.8f,0.8f,0.8f));
00074     ADD_PROPERTY(Transparency,(0));
00075     Transparency.setConstraints(&intPercent);
00076     App::Material mat(App::Material::DEFAULT);
00077     ADD_PROPERTY(ShapeMaterial,(mat));
00078     ADD_PROPERTY(BoundingBox,(false));
00079     ADD_PROPERTY(Selectable,(true));
00080 
00081     // Create the selection node
00082     pcHighlight = createFromSettings();
00083     pcHighlight->ref();
00084     if (pcHighlight->selectionMode.getValue() == Gui::SoFCSelection::SEL_OFF)
00085         Selectable.setValue(false);
00086 
00087     pcShapeMaterial = new SoMaterial;
00088     pcShapeMaterial->ref();
00089     ShapeMaterial.touch();
00090 
00091     pcBoundingBox = new Gui::SoFCBoundingBox;
00092     pcBoundingBox->ref();
00093     sPixmap = "Feature";
00094 }
00095 
00096 ViewProviderGeometryObject::~ViewProviderGeometryObject()
00097 {
00098     pcShapeMaterial->unref();
00099     pcHighlight->unref();
00100     pcBoundingBox->unref();
00101 }
00102 
00103 void ViewProviderGeometryObject::onChanged(const App::Property* prop)
00104 {
00105     // Actually, the properties 'ShapeColor' and 'Transparency' are part of the property 'ShapeMaterial'.
00106     // Both redundant properties are kept due to more convenience for the user. But we must keep the values
00107     // consistent of all these properties.
00108     if (prop == &Selectable) {
00109         bool Sel = Selectable.getValue();
00110         setSelectable(Sel);
00111     }
00112     else if (prop == &ShapeColor) {
00113         const App::Color& c = ShapeColor.getValue();
00114         pcShapeMaterial->diffuseColor.setValue(c.r,c.g,c.b);
00115         if (c != ShapeMaterial.getValue().diffuseColor)
00116         ShapeMaterial.setDiffuseColor(c);
00117     }
00118     else if (prop == &Transparency) {
00119         const App::Material& Mat = ShapeMaterial.getValue();
00120         long value = (long)(100*Mat.transparency);
00121         if (value != Transparency.getValue()) {
00122             float trans = Transparency.getValue()/100.0f;
00123             pcShapeMaterial->transparency = trans;
00124             ShapeMaterial.setTransparency(trans);
00125         }
00126     }
00127     else if (prop == &ShapeMaterial) {
00128         const App::Material& Mat = ShapeMaterial.getValue();
00129         long value = (long)(100*Mat.transparency);
00130         if (value != Transparency.getValue())
00131         Transparency.setValue(value);
00132         const App::Color& color = Mat.diffuseColor;
00133         if (color != ShapeColor.getValue())
00134         ShapeColor.setValue(Mat.diffuseColor);
00135         pcShapeMaterial->ambientColor.setValue(Mat.ambientColor.r,Mat.ambientColor.g,Mat.ambientColor.b);
00136         pcShapeMaterial->diffuseColor.setValue(Mat.diffuseColor.r,Mat.diffuseColor.g,Mat.diffuseColor.b);
00137         pcShapeMaterial->specularColor.setValue(Mat.specularColor.r,Mat.specularColor.g,Mat.specularColor.b);
00138         pcShapeMaterial->emissiveColor.setValue(Mat.emissiveColor.r,Mat.emissiveColor.g,Mat.emissiveColor.b);
00139         pcShapeMaterial->shininess.setValue(Mat.shininess);
00140         pcShapeMaterial->transparency.setValue(Mat.transparency);
00141     }
00142     else if (prop == &BoundingBox) {
00143         showBoundingBox( BoundingBox.getValue() );
00144     }
00145 
00146     ViewProviderDocumentObject::onChanged(prop);
00147 }
00148 
00149 void ViewProviderGeometryObject::attach(App::DocumentObject *pcObj)
00150 {
00151     ViewProviderDocumentObject::attach(pcObj);
00152     pcHighlight->objectName = pcObj->getNameInDocument();
00153     pcHighlight->documentName = pcObj->getDocument()->getName();
00154     pcHighlight->subElementName = "Main";
00155 }
00156 
00157 void ViewProviderGeometryObject::updateData(const App::Property* prop)
00158 {
00159     if (prop->isDerivedFrom(App::PropertyComplexGeoData::getClassTypeId())) {
00160         Base::BoundBox3d box = static_cast<const App::PropertyComplexGeoData*>(prop)->getBoundingBox();
00161         pcBoundingBox->minBounds.setValue(box.MinX, box.MinY, box.MinZ);
00162         pcBoundingBox->maxBounds.setValue(box.MaxX, box.MaxY, box.MaxZ);
00163         if (pcBoundSwitch) {
00164             SoGroup* grp = static_cast<SoGroup*>(pcBoundSwitch->getChild(0));
00165             SoTransform* trf = static_cast<SoTransform*>(grp->getChild(2));
00166             SbMatrix m;
00167             m.setTransform(pcTransform->translation.getValue(),
00168                            pcTransform->rotation.getValue(),
00169                            pcTransform->scaleFactor.getValue(),
00170                            pcTransform->scaleOrientation.getValue(),
00171                            pcTransform->center.getValue());
00172             trf->setMatrix(m.inverse());
00173         }
00174     }
00175     else if (prop->isDerivedFrom(App::PropertyPlacement::getClassTypeId())) {
00176         // Note: If R is the rotation, c the rotation center and t the translation
00177         // vector then Inventor applies the following transformation: R*(x-c)+c+t
00178         // In FreeCAD a placement only has a rotation and a translation part but
00179         // no rotation center. This means that the following equation must be ful-
00180         // filled: R * (x-c) + c + t = R * x + t
00181         //    <==> R * x + t - R * c + c = R * x + t
00182         //    <==> (I-R) * c = 0 ==> c = 0
00183         // This means that the center point must be the origin!
00184         Base::Placement p = static_cast<const App::PropertyPlacement*>(prop)->getValue();
00185         float q0 = (float)p.getRotation().getValue()[0];
00186         float q1 = (float)p.getRotation().getValue()[1];
00187         float q2 = (float)p.getRotation().getValue()[2];
00188         float q3 = (float)p.getRotation().getValue()[3];
00189         float px = (float)p.getPosition().x;
00190         float py = (float)p.getPosition().y;
00191         float pz = (float)p.getPosition().z;
00192         pcTransform->rotation.setValue(q0,q1,q2,q3);
00193         pcTransform->translation.setValue(px,py,pz);
00194         pcTransform->center.setValue(0.0f,0.0f,0.0f);
00195     }
00196 }
00197 
00198 bool ViewProviderGeometryObject::doubleClicked(void)
00199 {
00200     Gui::Application::Instance->activeDocument()->setEdit(this, (int)ViewProvider::Default);
00201     return true;
00202 }
00203 
00204 void ViewProviderGeometryObject::setupContextMenu(QMenu* menu, QObject* receiver, const char* member)
00205 {
00206     QAction* act = menu->addAction(QObject::tr("Transform"), receiver, member);
00207     act->setData(QVariant((int)ViewProvider::Transform));
00208 }
00209 
00210 bool ViewProviderGeometryObject::setEdit(int ModNum)
00211 {
00212 #if 1
00213     SoSearchAction sa;
00214     sa.setInterest(SoSearchAction::FIRST);
00215     sa.setSearchingAll(FALSE);
00216     sa.setNode(this->pcTransform);
00217     sa.apply(pcRoot);
00218     SoPath * path = sa.getPath();
00219     if (path) {
00220         SoCenterballManip * manip = new SoCenterballManip;
00221         SoDragger* dragger = manip->getDragger();
00222         dragger->addStartCallback(dragStartCallback, this);
00223         dragger->addFinishCallback(dragFinishCallback, this);
00224         // Attach a sensor to the transform manipulator and set it as its user
00225         // data to delete it when the view provider leaves the edit mode
00226         SoNodeSensor* sensor = new SoNodeSensor(sensorCallback, this);
00227         //sensor->setPriority(0);
00228         sensor->attach(manip);
00229         manip->setUserData(sensor);
00230         return manip->replaceNode(path);
00231     }
00232     return false;
00233 #else
00234         // get the size of this viewprovider
00235         SoGetBoundingBoxAction *boundAction = new SoGetBoundingBoxAction(SbViewportRegion());
00236         boundAction->apply(pcRoot);
00237     SbBox3f bdBox = boundAction->getBoundingBox();
00238         float size = bdBox.getSize().length();
00239         App::GeoFeature* geometry = static_cast<App::GeoFeature*>(pcObject);
00240         const Base::Placement pos = geometry->Placement.getValue();
00241         const Base::Vector3d &vpos = pos.getPosition();
00242         const Base::Rotation &rrot = pos.getRotation();
00243 
00244         // set up manipulator node
00245         SoSeparator * draggSep = new SoSeparator();
00246         SoDepthBuffer *depth = new SoDepthBuffer();
00247         depth->test = true;
00248         depth->function = SoDepthBuffer::ALWAYS;
00249         draggSep->addChild(depth);
00250         SoScale *scale = new SoScale();
00251         scale->scaleFactor = SbVec3f  (size,size,size);
00252         draggSep->addChild(scale);
00253         RotTransDragger *dragger = new RotTransDragger();
00254         dragger->translation = SbVec3f  (vpos.x,vpos.y,vpos.z);
00255         dragger->rotation = SbRotation(rrot[0],rrot[1],rrot[2],rrot[3]);
00256         draggSep->addChild(dragger);
00257 
00258     // Attach a sensor to the transform manipulator and set it as its user
00259     // data to delete it when the view provider leaves the edit mode
00260     SoNodeSensor* sensor = new SoNodeSensor(sensorCallback, this);
00261     //sensor->setPriority(0);
00262     sensor->attach(dragger);
00263 
00264 
00265         pcRoot->insertChild(draggSep,0);
00266         return true;
00267 
00268 #endif 
00269 
00270 }
00271 
00272 void ViewProviderGeometryObject::unsetEdit(int ModNum)
00273 {
00274 # if 1
00275     SoSearchAction sa;
00276     sa.setType(SoCenterballManip::getClassTypeId());
00277     sa.setInterest(SoSearchAction::FIRST);
00278     sa.apply(pcRoot);
00279     SoPath * path = sa.getPath();
00280 
00281     // No transform manipulator found.
00282     if (!path)
00283         return;
00284 
00285     // The manipulator has a sensor as user data and this sensor contains the view provider
00286     SoCenterballManip * manip = static_cast<SoCenterballManip*>(path->getTail());
00287     SoNodeSensor* sensor = reinterpret_cast<SoNodeSensor*>(manip->getUserData());
00288 
00289     // detach sensor
00290     sensor->detach();
00291     delete sensor;
00292 
00293     SoTransform* transform = this->pcTransform;
00294     manip->replaceManip(path, transform);
00295 
00296     if (this->pcObject->getTypeId().isDerivedFrom(App::GeoFeature::getClassTypeId())) {
00297         App::GeoFeature* geometry = static_cast<App::GeoFeature*>(this->pcObject);
00298         this->updateData(&geometry->Placement);
00299     }
00300 #else
00301         pcRoot->removeChild(0);
00302 #endif 
00303 }
00304 
00305 void ViewProviderGeometryObject::setEditViewer(Gui::View3DInventorViewer* viewer, int ModNum)
00306 {
00307     if (ModNum == (int)ViewProvider::Transform) {
00308         SoNode* root = viewer->getSceneGraph();
00309         static_cast<SoFCUnifiedSelection*>(root)->selectionRole.setValue(FALSE);
00310     }
00311 }
00312 
00313 void ViewProviderGeometryObject::unsetEditViewer(Gui::View3DInventorViewer* viewer)
00314 {
00315     int ModNum = this->getEditingMode();
00316     if (ModNum == (int)ViewProvider::Transform) {
00317         SoNode* root = viewer->getSceneGraph();
00318         static_cast<SoFCUnifiedSelection*>(root)->selectionRole.setValue(TRUE);
00319     }
00320 }
00321 
00322 void ViewProviderGeometryObject::sensorCallback(void * data, SoSensor * s)
00323 {
00324     SoNodeSensor* sensor = static_cast<SoNodeSensor*>(s);
00325     SoNode* node = sensor->getAttachedNode();
00326 
00327     if (node && node->getTypeId().isDerivedFrom(SoCenterballManip::getClassTypeId())) {
00328         // apply the transformation data to the placement
00329         SoCenterballManip* manip = static_cast<SoCenterballManip*>(node);
00330         float q0, q1, q2, q3;
00331         SbVec3f move = manip->translation.getValue();
00332         SbVec3f center = manip->center.getValue();
00333         manip->rotation.getValue().getValue(q0, q1, q2, q3);
00334     
00335         // get the placement
00336         ViewProviderGeometryObject* view = reinterpret_cast<ViewProviderGeometryObject*>(data);
00337         if (view && view->pcObject && view->pcObject->getTypeId().isDerivedFrom(App::GeoFeature::getClassTypeId())) {
00338             App::GeoFeature* geometry = static_cast<App::GeoFeature*>(view->pcObject);
00339             // Note: If R is the rotation, c the rotation center and t the translation
00340             // vector then Inventor applies the following transformation: R*(x-c)+c+t
00341             // In FreeCAD a placement only has a rotation and a translation part but
00342             // no rotation center. This means that we must divide the transformation
00343             // in a rotation and translation part.
00344             // R * (x-c) + c + t = R * x - R * c + c + t
00345             // The rotation part is R, the translation part t', however, is:
00346             // t' = t + c - R * c
00347             Base::Placement p;
00348             p.setRotation(Base::Rotation(q0,q1,q2,q3));
00349             Base::Vector3d t(move[0],move[1],move[2]);
00350             Base::Vector3d c(center[0],center[1],center[2]);
00351             t += c;
00352             p.getRotation().multVec(c,c);
00353             t -= c;
00354             p.setPosition(t);
00355             geometry->Placement.setValue(p);
00356         }
00357     }
00358 #if 0
00359         else // RotTransDragger -----------------------------------------------------------      
00360     if (node && node->getTypeId().isDerivedFrom(RotTransDragger::getClassTypeId())) {
00361         // apply the transformation data to the placement
00362         RotTransDragger* dragger = static_cast<RotTransDragger*>(node);
00363         float q0, q1, q2, q3;
00364         SbVec3f pos = dragger->translation.getValue();
00365         dragger->rotation.getValue().getValue(q0, q1, q2, q3);
00366     
00367         // get the placement
00368         ViewProviderGeometryObject* view = reinterpret_cast<ViewProviderGeometryObject*>(data);
00369         if (view && view->pcObject && view->pcObject->getTypeId().isDerivedFrom(App::GeoFeature::getClassTypeId())) {
00370             App::GeoFeature* geometry = static_cast<App::GeoFeature*>(view->pcObject);
00371             // Note: If R is the rotation, c the rotation center and t the translation
00372             // vector then Inventor applies the following transformation: R*(x-c)+c+t
00373             // In FreeCAD a placement only has a rotation and a translation part but
00374             // no rotation center. This means that we must divide the transformation
00375             // in a rotation and translation part.
00376             // R * (x-c) + c + t = R * x - R * c + c + t
00377             // The rotation part is R, the translation part t', however, is:
00378             // t' = t + c - R * c
00379             Base::Placement p;
00380             p.setRotation(Base::Rotation(q0,q1,q2,q3));
00381             Base::Vector3d t(pos[0],pos[1],pos[2]);
00382  /*           Base::Vector3d c(center[0],center[1],center[2]);
00383             t += c;
00384             p.getRotation().multVec(c,c);
00385             t -= c;*/
00386             p.setPosition(t);
00387             geometry->Placement.setValue(p);
00388         }
00389     } else
00390     if (node && node->getTypeId().isDerivedFrom(SoCenterballDragger::getClassTypeId())) {
00391         // apply the transformation data to the placement
00392         SoCenterballDragger* dragger = static_cast<SoCenterballDragger*>(node);
00393         float q0, q1, q2, q3;
00394         SbVec3f pos = dragger->center.getValue();
00395         dragger->rotation.getValue().getValue(q0, q1, q2, q3);
00396     
00397         // get the placement
00398         ViewProviderGeometryObject* view = reinterpret_cast<ViewProviderGeometryObject*>(data);
00399         if (view && view->pcObject && view->pcObject->getTypeId().isDerivedFrom(App::GeoFeature::getClassTypeId())) {
00400             App::GeoFeature* geometry = static_cast<App::GeoFeature*>(view->pcObject);
00401             // Note: If R is the rotation, c the rotation center and t the translation
00402             // vector then Inventor applies the following transformation: R*(x-c)+c+t
00403             // In FreeCAD a placement only has a rotation and a translation part but
00404             // no rotation center. This means that we must divide the transformation
00405             // in a rotation and translation part.
00406             // R * (x-c) + c + t = R * x - R * c + c + t
00407             // The rotation part is R, the translation part t', however, is:
00408             // t' = t + c - R * c
00409             Base::Placement p;
00410             p.setRotation(Base::Rotation(q0,q1,q2,q3));
00411             Base::Vector3d t(pos[0],pos[1],pos[2]);
00412  /*           Base::Vector3d c(center[0],center[1],center[2]);
00413             t += c;
00414             p.getRotation().multVec(c,c);
00415             t -= c;*/
00416             p.setPosition(t);
00417             geometry->Placement.setValue(p);
00418         }
00419     }
00420 #endif
00421 }
00422 
00423 void ViewProviderGeometryObject::dragStartCallback(void *data, SoDragger *)
00424 {
00425     // This is called when a manipulator is about to manipulating
00426     Gui::Application::Instance->activeDocument()->openCommand("Transform");
00427 }
00428 
00429 void ViewProviderGeometryObject::dragFinishCallback(void *data, SoDragger *)
00430 {
00431     // This is called when a manipulator has done manipulating
00432     Gui::Application::Instance->activeDocument()->commitCommand();
00433 }
00434 
00435 SoPickedPointList ViewProviderGeometryObject::getPickedPoints(const SbVec2s& pos, const View3DInventorViewer& viewer,bool pickAll) const
00436 {
00437     SoSeparator* root = new SoSeparator;
00438     root->ref();
00439     root->addChild(viewer.getHeadlight());
00440     root->addChild(viewer.getCamera());
00441     root->addChild(this->pcHighlight);
00442 
00443     SoRayPickAction rp(viewer.getViewportRegion());
00444     rp.setPickAll(pickAll);
00445     rp.setPoint(pos);
00446     rp.apply(root);
00447     root->unref();
00448 
00449     // returns a copy of the list
00450     return rp.getPickedPointList();
00451 }
00452 
00453 SoPickedPoint* ViewProviderGeometryObject::getPickedPoint(const SbVec2s& pos, const View3DInventorViewer& viewer) const
00454 {
00455     SoSeparator* root = new SoSeparator;
00456     root->ref();
00457     root->addChild(viewer.getHeadlight());
00458     root->addChild(viewer.getCamera());
00459     root->addChild(this->pcHighlight);
00460 
00461     SoRayPickAction rp(viewer.getViewportRegion());
00462     rp.setPoint(pos);
00463     rp.apply(root);
00464     root->unref();
00465 
00466     // returns a copy of the point
00467     SoPickedPoint* pick = rp.getPickedPoint();
00468     //return (pick ? pick->copy() : 0); // needs the same instance of CRT under MS Windows
00469     return (pick ? new SoPickedPoint(*pick) : 0);
00470 }
00471 
00472 void ViewProviderGeometryObject::showBoundingBox(bool show)
00473 {
00474     if (!pcBoundSwitch && show) {
00475         pcBoundSwitch = new SoSwitch();
00476         SoSeparator* pBoundingSep = new SoSeparator();
00477         SoDrawStyle* lineStyle = new SoDrawStyle;
00478         lineStyle->lineWidth = 2.0f;
00479         pBoundingSep->addChild(lineStyle);
00480         SoBaseColor* color = new SoBaseColor();
00481         color->rgb.setValue(1.0f, 1.0f, 1.0f);
00482         pBoundingSep->addChild(color);
00483 
00484         pBoundingSep->addChild(new SoTransform());
00485         pBoundingSep->addChild(pcBoundingBox);
00486         pcBoundingBox->coordsOn.setValue(false);
00487         pcBoundingBox->dimensionsOn.setValue(true);
00488 
00489         // add to the highlight node
00490         pcBoundSwitch->addChild(pBoundingSep);
00491         pcRoot->addChild(pcBoundSwitch);
00492     }
00493 
00494     if (pcBoundSwitch) {
00495         pcBoundSwitch->whichChild = (show ? 0 : -1);
00496     }
00497 }
00498 
00499 SoFCSelection* ViewProviderGeometryObject::createFromSettings() const
00500 {
00501     SoFCSelection* sel = new SoFCSelection();
00502 
00503     float transparency;
00504     ParameterGrp::handle hGrp = Gui::WindowParameter::getDefaultParameter()->GetGroup("View");
00505     bool enablePre = hGrp->GetBool("EnablePreselection", true);
00506     bool enableSel = hGrp->GetBool("EnableSelection", true);
00507     if (!enablePre) {
00508         sel->highlightMode = Gui::SoFCSelection::OFF;
00509     }
00510     else {
00511         // Search for a user defined value with the current color as default
00512         SbColor highlightColor = sel->colorHighlight.getValue();
00513         unsigned long highlight = (unsigned long)(highlightColor.getPackedValue());
00514         highlight = hGrp->GetUnsigned("HighlightColor", highlight);
00515         highlightColor.setPackedValue((uint32_t)highlight, transparency);
00516         sel->colorHighlight.setValue(highlightColor);
00517     }
00518     if (!enableSel || !Selectable.getValue()) {
00519         sel->selectionMode = Gui::SoFCSelection::SEL_OFF;
00520     }
00521     else {
00522         // Do the same with the selection color
00523         SbColor selectionColor = sel->colorSelection.getValue();
00524         unsigned long selection = (unsigned long)(selectionColor.getPackedValue());
00525         selection = hGrp->GetUnsigned("SelectionColor", selection);
00526         selectionColor.setPackedValue((uint32_t)selection, transparency);
00527         sel->colorSelection.setValue(selectionColor);
00528     }
00529 
00530     return sel;
00531 }
00532 
00533 void ViewProviderGeometryObject::setSelectable(bool selectable)
00534 {
00535     SoSearchAction sa;
00536     sa.setInterest(SoSearchAction::ALL);
00537     sa.setSearchingAll(TRUE);
00538     sa.setType(Gui::SoFCSelection::getClassTypeId());
00539     sa.apply(pcRoot);
00540 
00541     SoPathList & pathList = sa.getPaths();
00542 
00543     for (int i=0;i<pathList.getLength();i++) {
00544         SoFCSelection *selNode = dynamic_cast<SoFCSelection*>(pathList[i]->getTail());
00545         if (selectable) {
00546             selNode->selectionMode = SoFCSelection::SEL_ON;
00547             selNode->highlightMode = SoFCSelection::AUTO;
00548         }
00549         else {
00550             selNode->selectionMode = SoFCSelection::SEL_OFF;
00551             selNode->highlightMode = SoFCSelection::OFF;
00552             selNode->selected = SoFCSelection::NOTSELECTED;
00553         }
00554     }
00555 }

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