diff --git a/src/Mod/Assembly/Gui/ViewProviderAssembly.cpp b/src/Mod/Assembly/Gui/ViewProviderAssembly.cpp index 1055cd1eb3..4fd58c25d8 100644 --- a/src/Mod/Assembly/Gui/ViewProviderAssembly.cpp +++ b/src/Mod/Assembly/Gui/ViewProviderAssembly.cpp @@ -28,19 +28,29 @@ #include #include #include +#include +#include #include +#include +#include +#include +#include #endif #include #include #include #include + #include #include #include #include +#include #include #include +#include + #include #include #include @@ -177,6 +187,7 @@ bool ViewProviderAssembly::canDragObject(App::DocumentObject* obj) const bool ViewProviderAssembly::setEdit(int ModNum) { Q_UNUSED(ModNum); + // Set the part as 'Activated' ie bold in the tree. Gui::Command::doCommand(Gui::Command::Gui, "Gui.ActiveDocument.ActiveView.setActiveObject('%s', " @@ -185,6 +196,8 @@ bool ViewProviderAssembly::setEdit(int ModNum) this->getObject()->getDocument()->getName(), this->getObject()->getNameInDocument()); + setDragger(); + return true; } @@ -195,6 +208,8 @@ void ViewProviderAssembly::unsetEdit(int ModNum) partMoving = false; docsToMove = {}; + unsetDragger(); + // Check if the view is still active before trying to deactivate the assembly. auto doc = getDocument(); if (!doc) { @@ -213,6 +228,42 @@ void ViewProviderAssembly::unsetEdit(int ModNum) PARTKEY); } +void ViewProviderAssembly::setDragger() +{ + // Create the dragger coin object + assert(!asmDragger); + asmDragger = new Gui::SoFCCSysDragger(); + asmDragger->setAxisColors(Gui::ViewParams::instance()->getAxisXColor(), + Gui::ViewParams::instance()->getAxisYColor(), + Gui::ViewParams::instance()->getAxisZColor()); + asmDragger->draggerSize.setValue(0.05f); + + asmDraggerSwitch = new SoSwitch(SO_SWITCH_NONE); + asmDraggerSwitch->addChild(asmDragger); + + pcRoot->insertChild(asmDraggerSwitch, 0); + asmDraggerSwitch->ref(); + asmDragger->ref(); +} + +void ViewProviderAssembly::unsetDragger() +{ + pcRoot->removeChild(asmDraggerSwitch); + asmDragger->unref(); + asmDragger = nullptr; + asmDraggerSwitch->unref(); + asmDraggerSwitch = nullptr; +} + +void ViewProviderAssembly::setEditViewer(Gui::View3DInventorViewer* viewer, int ModNum) +{ + ViewProviderPart::setEditViewer(viewer, ModNum); + + if (asmDragger && viewer) { + asmDragger->setUpAutoScale(viewer->getSoRenderManager()->getCamera()); + } +} + bool ViewProviderAssembly::isInEditMode() const { App::DocumentObject* activePart = getActivePart(); @@ -240,6 +291,7 @@ App::DocumentObject* ViewProviderAssembly::getActivePart() const bool ViewProviderAssembly::keyPressed(bool pressed, int key) { Q_UNUSED(pressed); + if (key == SoKeyboardEvent::ESCAPE) { if (isInEditMode()) { @@ -383,6 +435,7 @@ bool ViewProviderAssembly::mouseButtonPressed(int Button, { Q_UNUSED(cursorPos); Q_UNUSED(viewer); + // Left Mouse button **************************************************** if (Button == 1) { if (pressed) { @@ -757,6 +810,45 @@ bool ViewProviderAssembly::onDelete(const std::vector& subNames) return ViewProviderPart::onDelete(subNames); } +void ViewProviderAssembly::setDraggerVisibility(bool val) +{ + asmDraggerSwitch->whichChild = val ? SO_SWITCH_ALL : SO_SWITCH_NONE; +} +bool ViewProviderAssembly::getDraggerVisibility() +{ + return asmDraggerSwitch->whichChild.getValue() == SO_SWITCH_ALL; +} + +void ViewProviderAssembly::setDraggerPlacement(Base::Placement plc) +{ + double q0, q1, q2, q3; + plc.getRotation().getValue(q0, q1, q2, q3); + Base::Vector3d pos = plc.getPosition(); + asmDragger->rotation.setValue(q0, q1, q2, q3); + asmDragger->translation.setValue(pos.x, pos.y, pos.z); +} + +Base::Placement ViewProviderAssembly::getDraggerPlacement() +{ + Base::Placement plc; + SbVec3f pos = asmDragger->translation.getValue(); + plc.setPosition(Base::Vector3d(pos[0], pos[1], pos[2])); + + SbVec3f axis; + float angle; + asmDragger->rotation.getValue(axis, angle); + Base::Vector3d axisV = Base::Vector3d(axis[0], axis[1], axis[2]); + Base::Rotation rot(axisV, angle); + plc.setRotation(rot); + + return plc; +} + +Gui::SoFCCSysDragger* ViewProviderAssembly::getDragger() +{ + return asmDragger; +} + PyObject* ViewProviderAssembly::getPyObject() { if (!pyViewObject) { diff --git a/src/Mod/Assembly/Gui/ViewProviderAssembly.h b/src/Mod/Assembly/Gui/ViewProviderAssembly.h index 1ad14ba49b..60d74f45b7 100644 --- a/src/Mod/Assembly/Gui/ViewProviderAssembly.h +++ b/src/Mod/Assembly/Gui/ViewProviderAssembly.h @@ -31,10 +31,16 @@ #include #include +class SoSwitch; +class SoSensor; +class SoDragger; +class SoFieldSensor; + namespace Gui { +class SoFCCSysDragger; class View3DInventorViewer; -} +} // namespace Gui namespace AssemblyGui { @@ -71,6 +77,7 @@ public: //@{ bool setEdit(int ModNum) override; void unsetEdit(int ModNum) override; + void setEditViewer(Gui::View3DInventorViewer*, int ModNum) override; bool isInEditMode() const; /// Ask the view provider if it accepts object deletions while in edit @@ -120,6 +127,15 @@ public: void onSelectionChanged(const Gui::SelectionChanges& msg) override; + // Dragger controls: + void setDragger(); + void unsetDragger(); + void setDraggerVisibility(bool val); + bool getDraggerVisibility(); + void setDraggerPlacement(Base::Placement plc); + Base::Placement getDraggerPlacement(); + Gui::SoFCCSysDragger* getDragger(); + DragMode dragMode; bool canStartDragging; bool partMoving; @@ -136,6 +152,11 @@ public: std::vector> objectMasses; std::vector> docsToMove; + + Gui::SoFCCSysDragger* asmDragger = nullptr; + SoSwitch* asmDraggerSwitch = nullptr; + SoFieldSensor* translationSensor = nullptr; + SoFieldSensor* rotationSensor = nullptr; }; } // namespace AssemblyGui diff --git a/src/Mod/Assembly/Gui/ViewProviderAssemblyPy.xml b/src/Mod/Assembly/Gui/ViewProviderAssemblyPy.xml index 503bf213ab..8d2fac8863 100644 --- a/src/Mod/Assembly/Gui/ViewProviderAssemblyPy.xml +++ b/src/Mod/Assembly/Gui/ViewProviderAssemblyPy.xml @@ -13,11 +13,35 @@ This is the ViewProviderAssembly class + + + + + Return the assembly dragger coin object. + + getDragger() -> SoFCCSysDragger + + Returns: dragger coin object of the assembly + + + Enable moving the parts by clicking and dragging. + + + Show or hide the assembly dragger. + + + + + + Placement of the assembly dragger object. + + + diff --git a/src/Mod/Assembly/Gui/ViewProviderAssemblyPyImp.cpp b/src/Mod/Assembly/Gui/ViewProviderAssemblyPyImp.cpp index 5d6cffe4f1..4e3bd156c2 100644 --- a/src/Mod/Assembly/Gui/ViewProviderAssemblyPyImp.cpp +++ b/src/Mod/Assembly/Gui/ViewProviderAssemblyPyImp.cpp @@ -22,6 +22,10 @@ #include "PreCompiled.h" +#include +#include +#include + // inclusion of the generated files (generated out of ViewProviderAssemblyPy.xml) #include "ViewProviderAssemblyPy.h" #include "ViewProviderAssemblyPy.cpp" @@ -48,6 +52,46 @@ void ViewProviderAssemblyPy::setEnableMovement(Py::Boolean arg) getViewProviderAssemblyPtr()->setEnableMovement(arg); } +Py::Boolean ViewProviderAssemblyPy::getDraggerVisibility() const +{ + return {getViewProviderAssemblyPtr()->getDraggerVisibility()}; +} + +void ViewProviderAssemblyPy::setDraggerVisibility(Py::Boolean arg) +{ + getViewProviderAssemblyPtr()->setDraggerVisibility(arg); +} + +PyObject* ViewProviderAssemblyPy::getDragger(PyObject* args) +{ + if (!PyArg_ParseTuple(args, "")) { + return nullptr; + } + Gui::SoFCCSysDragger* asmDragger = getViewProviderAssemblyPtr()->getDragger(); + + return Base::Interpreter().createSWIGPointerObj("pivy.coin", "SoDragger *", asmDragger, 0); +} + + +Py::Object ViewProviderAssemblyPy::getDraggerPlacement() const +{ + return Py::Placement(getViewProviderAssemblyPtr()->getDraggerPlacement()); +} + +void ViewProviderAssemblyPy::setDraggerPlacement(Py::Object arg) +{ + PyObject* p = arg.ptr(); + if (PyObject_TypeCheck(p, &(Base::PlacementPy::Type))) { + Base::Placement* trf = static_cast(p)->getPlacementPtr(); + getViewProviderAssemblyPtr()->setDraggerPlacement(*trf); + } + else { + std::string error = std::string("type must be 'Placement', not "); + error += p->ob_type->tp_name; + throw Py::TypeError(error); + } +} + PyObject* ViewProviderAssemblyPy::getCustomAttributes(const char* /*attr*/) const { return nullptr;