00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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
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
00106
00107
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
00177
00178
00179
00180
00181
00182
00183
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
00225
00226 SoNodeSensor* sensor = new SoNodeSensor(sensorCallback, this);
00227
00228 sensor->attach(manip);
00229 manip->setUserData(sensor);
00230 return manip->replaceNode(path);
00231 }
00232 return false;
00233 #else
00234
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
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
00259
00260 SoNodeSensor* sensor = new SoNodeSensor(sensorCallback, this);
00261
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
00282 if (!path)
00283 return;
00284
00285
00286 SoCenterballManip * manip = static_cast<SoCenterballManip*>(path->getTail());
00287 SoNodeSensor* sensor = reinterpret_cast<SoNodeSensor*>(manip->getUserData());
00288
00289
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
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
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
00340
00341
00342
00343
00344
00345
00346
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
00360 if (node && node->getTypeId().isDerivedFrom(RotTransDragger::getClassTypeId())) {
00361
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
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
00372
00373
00374
00375
00376
00377
00378
00379 Base::Placement p;
00380 p.setRotation(Base::Rotation(q0,q1,q2,q3));
00381 Base::Vector3d t(pos[0],pos[1],pos[2]);
00382
00383
00384
00385
00386 p.setPosition(t);
00387 geometry->Placement.setValue(p);
00388 }
00389 } else
00390 if (node && node->getTypeId().isDerivedFrom(SoCenterballDragger::getClassTypeId())) {
00391
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
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
00402
00403
00404
00405
00406
00407
00408
00409 Base::Placement p;
00410 p.setRotation(Base::Rotation(q0,q1,q2,q3));
00411 Base::Vector3d t(pos[0],pos[1],pos[2]);
00412
00413
00414
00415
00416 p.setPosition(t);
00417 geometry->Placement.setValue(p);
00418 }
00419 }
00420 #endif
00421 }
00422
00423 void ViewProviderGeometryObject::dragStartCallback(void *data, SoDragger *)
00424 {
00425
00426 Gui::Application::Instance->activeDocument()->openCommand("Transform");
00427 }
00428
00429 void ViewProviderGeometryObject::dragFinishCallback(void *data, SoDragger *)
00430 {
00431
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
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
00467 SoPickedPoint* pick = rp.getPickedPoint();
00468
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
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
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
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 }