From fab235682db031e99bf7d08ca7eaee09aeb1fb04 Mon Sep 17 00:00:00 2001 From: Kacper Donat Date: Thu, 5 Dec 2024 14:42:13 +0100 Subject: [PATCH] Gui: Make ViewProviderLink based on ViewProviderDragger --- src/Gui/TaskCSysDragger.cpp | 30 +++-- src/Gui/ViewProviderDragger.cpp | 22 ++-- src/Gui/ViewProviderDragger.h | 1 + src/Gui/ViewProviderLink.cpp | 190 ++++++------------------------ src/Gui/ViewProviderLink.h | 13 +- src/Gui/ViewProviderLinkPy.xml | 6 - src/Gui/ViewProviderLinkPyImp.cpp | 17 +-- src/Mod/Part/App/Attacher.cpp | 11 +- src/Mod/Part/App/Services.cpp | 5 +- 9 files changed, 88 insertions(+), 207 deletions(-) diff --git a/src/Gui/TaskCSysDragger.cpp b/src/Gui/TaskCSysDragger.cpp index a4e38bcce3..ad9d8e61cf 100644 --- a/src/Gui/TaskCSysDragger.cpp +++ b/src/Gui/TaskCSysDragger.cpp @@ -101,9 +101,7 @@ TaskTransform::TaskTransform(Gui::ViewProviderDragger* vp, vp->resetTransformOrigin(); - if (auto geoFeature = vp->getObject()) { - originalPlacement = geoFeature->Placement.getValue(); - } + originalPlacement = vp->getObjectPlacement(); setupGui(); } @@ -400,23 +398,29 @@ void TaskTransform::onSelectionChanged(const SelectionChanges& msg) return; } + if (!msg.pOriginalMsg) { + // this should not happen! Original should contain unresolved message. + return; + } + auto doc = Application::Instance->getDocument(msg.pDocName); auto obj = doc->getDocument()->getObject(msg.pObjectName); - auto globalPlacement = App::GeoFeature::getGlobalPlacement(obj); + auto orgDoc = Application::Instance->getDocument(msg.pOriginalMsg->pDocName); + auto orgObj = orgDoc->getDocument()->getObject(msg.pOriginalMsg->pObjectName); + + auto globalPlacement = App::GeoFeature::getGlobalPlacement(obj, orgObj, msg.pOriginalMsg->pSubName); auto localPlacement = App::GeoFeature::getPlacementFromProp(obj, "Placement"); auto rootPlacement = App::GeoFeature::getGlobalPlacement(vp->getObject()); + auto attachedPlacement = subObjectPlacementProvider->calculate(msg.Object, localPlacement); - auto selectedObjectPlacement = rootPlacement.inverse() * globalPlacement - * subObjectPlacementProvider->calculate(msg.Object, localPlacement); + auto selectedObjectPlacement = rootPlacement.inverse() * globalPlacement * attachedPlacement; switch (selectionMode) { - case SelectionMode::SelectTransformOrigin: {auto label = msg.pOriginalMsg - ? QStringLiteral("%1#%2.%3") - .arg(QLatin1String(msg.pOriginalMsg->pObjectName), - QLatin1String(msg.pObjectName), - QLatin1String(msg.pSubName)) - : QStringLiteral("%1.%2").arg(QLatin1String(msg.pObjectName), QLatin1String(msg.pSubName)); + case SelectionMode::SelectTransformOrigin: {auto label = QStringLiteral("%1#%2.%3") + .arg(QLatin1String(msg.pOriginalMsg->pObjectName), + QLatin1String(msg.pObjectName), + QLatin1String(msg.pSubName)); ui->referenceLineEdit->setText(label); @@ -491,7 +495,7 @@ void TaskTransform::updateTransformOrigin() return {}; case PlacementMode::Centroid: if (const auto com = centerOfMassProvider->ofDocumentObject(vp->getObject())) { - return Base::Placement {*com, {}}; + return {*com, {}}; } return {}; case PlacementMode::Custom: diff --git a/src/Gui/ViewProviderDragger.cpp b/src/Gui/ViewProviderDragger.cpp index 4e60eab9c1..719c22e6a3 100644 --- a/src/Gui/ViewProviderDragger.cpp +++ b/src/Gui/ViewProviderDragger.cpp @@ -49,6 +49,7 @@ #include "ViewProviderDragger.h" #include "Utilities.h" +#include #include using namespace Gui; @@ -208,9 +209,7 @@ void ViewProviderDragger::setEditViewer(Gui::View3DInventorViewer* viewer, int M csysDragger->setUpAutoScale(viewer->getSoRenderManager()->getCamera()); auto mat = viewer->getDocument()->getEditingTransform(); - if (auto geoFeature = getObject()) { - mat *= geoFeature->Placement.getValue().inverse().toMatrix(); - } + mat *= getObjectPlacement().inverse().toMatrix(); viewer->getDocument()->setEditingTransform(mat); viewer->setupEditingRoot(csysDragger, &mat); @@ -249,13 +248,13 @@ void ViewProviderDragger::dragMotionCallback(void* data, SoDragger* d) void ViewProviderDragger::updatePlacementFromDragger() { - const auto geoFeature = getObject(); + const auto placement = getObject()->getPropertyByName("Placement"); - if (!geoFeature) { + if (!placement) { return; } - geoFeature->Placement.setValue(getDraggerPlacement() * getTransformOrigin().inverse()); + placement->setValue(getDraggerPlacement() * getTransformOrigin().inverse()); } void ViewProviderDragger::updateTransformFromDragger() @@ -266,6 +265,15 @@ void ViewProviderDragger::updateTransformFromDragger() pcTransform->rotation.setValue(Base::convertTo(placement.getRotation())); } +Base::Placement ViewProviderDragger::getObjectPlacement() const +{ + if (auto placement = getObject()->getPropertyByName("Placement")) { + return placement->getValue(); + } + + return {}; +} + Base::Placement ViewProviderDragger::getDraggerPlacement() const { const double translationStep = csysDragger->translationIncrement.getValue(); @@ -314,7 +322,7 @@ void ViewProviderDragger::updateDraggerPosition() return; } - auto placement = getObject()->Placement.getValue() * getTransformOrigin(); + auto placement = getObjectPlacement() * getTransformOrigin(); setDraggerPlacement(placement); } diff --git a/src/Gui/ViewProviderDragger.h b/src/Gui/ViewProviderDragger.h index ce5a6da50c..13d37efb23 100644 --- a/src/Gui/ViewProviderDragger.h +++ b/src/Gui/ViewProviderDragger.h @@ -77,6 +77,7 @@ public: void updatePlacementFromDragger(); void updateTransformFromDragger(); + Base::Placement getObjectPlacement() const; Base::Placement getDraggerPlacement() const; void setDraggerPlacement(const Base::Placement& placement); diff --git a/src/Gui/ViewProviderLink.cpp b/src/Gui/ViewProviderLink.cpp index 6e2fe24d0b..3e0d0b5244 100644 --- a/src/Gui/ViewProviderLink.cpp +++ b/src/Gui/ViewProviderLink.cpp @@ -1624,7 +1624,7 @@ static const char *_LinkElementIcon = "LinkElement"; ViewProviderLink::ViewProviderLink() :linkType(LinkTypeNone),hasSubName(false),hasSubElement(false) - ,useCenterballDragger(false),childVp(nullptr),overlayCacheKey(0) + ,childVp(nullptr),overlayCacheKey(0) { sPixmap = _LinkIcon; @@ -1670,7 +1670,7 @@ ViewProviderLink::~ViewProviderLink() } bool ViewProviderLink::isSelectable() const { - return !pcDragger && Selectable.getValue(); + return Selectable.getValue(); } void ViewProviderLink::attach(App::DocumentObject *pcObj) { @@ -1851,7 +1851,7 @@ void ViewProviderLink::updateDataPrivate(App::LinkBaseExtension *ext, const App: auto propLinkPlacement = ext->getLinkPlacementProperty(); if(!propLinkPlacement || propLinkPlacement == prop) { const auto &pla = static_cast(prop)->getValue(); - ViewProviderGeometryObject::updateTransform(pla, pcTransform); + // ViewProviderGeometryObject::updateTransform(pla, pcTransform); const auto &v = ext->getScaleVector(); if(canScale(v)) pcTransform->scaleFactor.setValue(v.x,v.y,v.z); @@ -2764,25 +2764,28 @@ ViewProvider *ViewProviderLink::startEditing(int mode) { } static thread_local bool _pendingTransform; - static thread_local Base::Matrix4D _editingTransform; + static thread_local Matrix4D _editingTransform; auto doc = Application::Instance->editDocument(); - if(mode==ViewProvider::Transform) { - if(_pendingTransform && doc) + if (mode == ViewProvider::Transform) { + if (_pendingTransform && doc) { doc->setEditingTransform(_editingTransform); + } - if(!initDraggingPlacement()) + if (!initDraggingPlacement()) { return nullptr; - if(useCenterballDragger) - pcDragger = CoinPtr(new SoCenterballDragger); - else - pcDragger = CoinPtr(new SoFCCSysDragger); - updateDraggingPlacement(dragCtx->initialPlacement,true); - pcDragger->addStartCallback(dragStartCallback, this); - pcDragger->addFinishCallback(dragFinishCallback, this); - pcDragger->addMotionCallback(dragMotionCallback, this); - return inherited::startEditing(mode); + } + + if (auto result = inherited::startEditing(mode)) { + csysDragger->addStartCallback(dragStartCallback, this); + csysDragger->addFinishCallback(dragFinishCallback, this); + csysDragger->addMotionCallback(dragMotionCallback, this); + + setDraggerPlacement(dragCtx->initialPlacement); + + return result; + } } if(!linkEdit()) { @@ -2839,6 +2842,7 @@ bool ViewProviderLink::setEdit(int ModNum) Selection().clearSelection(); return true; } + return inherited::setEdit(ModNum); } @@ -2849,125 +2853,21 @@ void ViewProviderLink::setEditViewer(Gui::View3DInventorViewer* viewer, int ModN return; } - if (pcDragger && viewer) - { - auto rootPickStyle = new SoPickStyle(); - rootPickStyle->style = SoPickStyle::UNPICKABLE; - static_cast( - viewer->getSceneGraph())->insertChild(rootPickStyle, 0); - - if(useCenterballDragger) { - auto dragger = static_cast(pcDragger.get()); - auto group = new SoAnnotation; - auto pickStyle = new SoPickStyle; - pickStyle->setOverride(true); - group->addChild(pickStyle); - group->addChild(pcDragger); - - // Because the dragger is not grouped with the actual geometry, - // we use an invisible cube sized by the bounding box obtained from - // initDraggingPlacement() to scale the centerball dragger properly - - auto * ss = static_cast(dragger->getPart("surroundScale", TRUE)); - ss->numNodesUpToContainer = 3; - ss->numNodesUpToReset = 2; - - auto *geoGroup = new SoGroup; - group->addChild(geoGroup); - auto *style = new SoDrawStyle; - style->style.setValue(SoDrawStyle::INVISIBLE); - style->setOverride(TRUE); - geoGroup->addChild(style); - auto *cube = new SoCube; - geoGroup->addChild(cube); - auto length = std::max(std::max(dragCtx->bbox.LengthX(), - dragCtx->bbox.LengthY()), dragCtx->bbox.LengthZ()); - cube->width = length; - cube->height = length; - cube->depth = length; - - viewer->setupEditingRoot(group,&dragCtx->preTransform); - } else { - auto dragger = static_cast(pcDragger.get()); - dragger->draggerSize.setValue(ViewParams::instance()->getDraggerScale()); - dragger->setUpAutoScale(viewer->getSoRenderManager()->getCamera()); - viewer->setupEditingRoot(pcDragger,&dragCtx->preTransform); - - auto task = new TaskCSysDragger(nullptr, dragger); - Gui::Control().showDialog(task); - } - } + ViewProviderDragger::setEditViewer(viewer, ModNum); } void ViewProviderLink::unsetEditViewer(Gui::View3DInventorViewer* viewer) { - SoNode *child = static_cast(viewer->getSceneGraph())->getChild(0); - if (child && child->isOfType(SoPickStyle::getClassTypeId())) - static_cast(viewer->getSceneGraph())->removeChild(child); - pcDragger.reset(); dragCtx.reset(); - Gui::Control().closeDialog(); + + inherited::unsetEditViewer(viewer); } -Base::Placement ViewProviderLink::currentDraggingPlacement() const -{ - // if there isn't an active dragger return a default placement - if (!pcDragger) - return Base::Placement(); - - SbVec3f v; - SbRotation r; - if (useCenterballDragger) { - auto dragger = static_cast(pcDragger.get()); - v = dragger->center.getValue(); - r = dragger->rotation.getValue(); - } - else { - auto dragger = static_cast(pcDragger.get()); - v = dragger->translation.getValue(); - r = dragger->rotation.getValue(); - } - - float q1,q2,q3,q4; - r.getValue(q1,q2,q3,q4); - return Base::Placement(Base::Vector3d(v[0],v[1],v[2]),Base::Rotation(q1,q2,q3,q4)); -} - -void ViewProviderLink::enableCenterballDragger(bool enable) { - if(enable == useCenterballDragger) - return; - if(pcDragger) - LINK_THROW(Base::RuntimeError,"Cannot change dragger during dragging"); - useCenterballDragger = enable; -} - -void ViewProviderLink::updateDraggingPlacement(const Base::Placement &pla, bool force) { - if(pcDragger && (force || currentDraggingPlacement()!=pla)) { - const auto &pos = pla.getPosition(); - const auto &rot = pla.getRotation(); - FC_LOG("updating dragger placement (" << pos.x << ", " << pos.y << ", " << pos.z << ')'); - if(useCenterballDragger) { - auto dragger = static_cast(pcDragger.get()); - SbBool wasenabled = dragger->enableValueChangedCallbacks(FALSE); - SbMatrix matrix; - matrix = convert(pla.toMatrix()); - dragger->center.setValue(SbVec3f(0,0,0)); - dragger->setMotionMatrix(matrix); - if (wasenabled) { - dragger->enableValueChangedCallbacks(TRUE); - dragger->valueChanged(); - } - }else{ - auto dragger = static_cast(pcDragger.get()); - dragger->translation.setValue(SbVec3f(pos.x,pos.y,pos.z)); - dragger->rotation.setValue(rot[0],rot[1],rot[2],rot[3]); - } - } -} - -bool ViewProviderLink::callDraggerProxy(const char *fname, bool update) { - if(!pcDragger) +bool ViewProviderLink::callDraggerProxy(const char* fname) { + if (!csysDragger) { return false; + } + Base::PyGILStateLocker lock; try { auto* proxy = getPropertyByName("Proxy"); @@ -2986,48 +2886,32 @@ bool ViewProviderLink::callDraggerProxy(const char *fname, bool update) { return true; } - if(update) { - auto ext = getLinkExtension(); - if(ext) { - const auto &pla = currentDraggingPlacement(); - auto prop = ext->getLinkPlacementProperty(); - if(!prop) - prop = ext->getPlacementProperty(); - if(prop) { - auto plaNew = pla * Base::Placement(dragCtx->mat); - if(prop->getValue()!=plaNew) - prop->setValue(plaNew); - } - updateDraggingPlacement(pla); - } - } return false; } void ViewProviderLink::dragStartCallback(void *data, SoDragger *) { auto me = static_cast(data); - me->dragCtx->initialPlacement = me->currentDraggingPlacement(); - if(!me->callDraggerProxy("onDragStart",false)) { - me->dragCtx->cmdPending = true; - me->getDocument()->openCommand(QT_TRANSLATE_NOOP("Command", "Link Transform")); - }else - me->dragCtx->cmdPending = false; + + me->dragCtx->initialPlacement = me->getDraggerPlacement(); + me->callDraggerProxy("onDragStart"); } void ViewProviderLink::dragFinishCallback(void *data, SoDragger *) { auto me = static_cast(data); - me->callDraggerProxy("onDragEnd",true); - if(me->dragCtx->cmdPending) { - if(me->currentDraggingPlacement() == me->dragCtx->initialPlacement) + me->callDraggerProxy("onDragEnd"); + + if (me->dragCtx->cmdPending) { + if (me->getDraggerPlacement() == me->dragCtx->initialPlacement) { me->getDocument()->abortCommand(); - else + } else { me->getDocument()->commitCommand(); + } } } void ViewProviderLink::dragMotionCallback(void *data, SoDragger *) { auto me = static_cast(data); - me->callDraggerProxy("onDragMotion",true); + me->callDraggerProxy("onDragMotion"); } void ViewProviderLink::updateLinks(ViewProvider *vp) { diff --git a/src/Gui/ViewProviderLink.h b/src/Gui/ViewProviderLink.h index fc296f2561..79ead6d8cf 100644 --- a/src/Gui/ViewProviderLink.h +++ b/src/Gui/ViewProviderLink.h @@ -184,10 +184,10 @@ protected: Py::Object PythonObject; }; -class GuiExport ViewProviderLink : public ViewProviderDocumentObject +class GuiExport ViewProviderLink : public ViewProviderDragger { PROPERTY_HEADER_WITH_OVERRIDE(Gui::ViewProviderLink); - using inherited = ViewProviderDocumentObject; + using inherited = ViewProviderDragger; public: App::PropertyBool OverrideMaterial; @@ -248,11 +248,6 @@ public: static void updateLinks(ViewProvider *vp); - void updateDraggingPlacement(const Base::Placement &pla, bool force=false); - Base::Placement currentDraggingPlacement() const; - void enableCenterballDragger(bool enable); - bool isUsingCenterballDragger() const { return useCenterballDragger; } - std::map getElementColors(const char *subname=nullptr) const override; void setElementColors(const std::map &colors) override; @@ -311,7 +306,7 @@ protected: ViewProvider *getLinkedView(bool real,const App::LinkBaseExtension *ext=nullptr) const; bool initDraggingPlacement(); - bool callDraggerProxy(const char *fname, bool update); + bool callDraggerProxy(const char* fname); private: static void dragStartCallback(void * data, SoDragger * d); @@ -323,7 +318,6 @@ protected: LinkType linkType; bool hasSubName; bool hasSubElement; - bool useCenterballDragger; struct DraggerContext{ Base::Matrix4D preTransform; @@ -333,7 +327,6 @@ protected: bool cmdPending; }; std::unique_ptr dragCtx; - CoinPtr pcDragger; ViewProviderDocumentObject *childVp; LinkInfoPtr childVpLink; mutable qint64 overlayCacheKey; diff --git a/src/Gui/ViewProviderLinkPy.xml b/src/Gui/ViewProviderLinkPy.xml index 88aaa0747f..09641c2cf8 100644 --- a/src/Gui/ViewProviderLinkPy.xml +++ b/src/Gui/ViewProviderLinkPy.xml @@ -19,12 +19,6 @@ - - - Get/set dragger type - - - Get the associated LinkView object diff --git a/src/Gui/ViewProviderLinkPyImp.cpp b/src/Gui/ViewProviderLinkPyImp.cpp index c1f3588e71..066c87f2e9 100644 --- a/src/Gui/ViewProviderLinkPyImp.cpp +++ b/src/Gui/ViewProviderLinkPyImp.cpp @@ -46,29 +46,16 @@ std::string ViewProviderLinkPy::representation() const Py::Object ViewProviderLinkPy::getDraggingPlacement() const { return Py::asObject(new Base::PlacementPy(new Base::Placement( - getViewProviderLinkPtr()->currentDraggingPlacement()))); + getViewProviderLinkPtr()->getDraggerPlacement()))); } void ViewProviderLinkPy::setDraggingPlacement(Py::Object arg) { if(!PyObject_TypeCheck(arg.ptr(),&Base::PlacementPy::Type)) throw Py::TypeError("expects a placement"); - getViewProviderLinkPtr()->updateDraggingPlacement( + getViewProviderLinkPtr()->setDraggerPlacement( *static_cast(arg.ptr())->getPlacementPtr()); } -Py::Boolean ViewProviderLinkPy::getUseCenterballDragger() const { - return {getViewProviderLinkPtr()->isUsingCenterballDragger()}; -} - -void ViewProviderLinkPy::setUseCenterballDragger(Py::Boolean arg) { - try { - getViewProviderLinkPtr()->enableCenterballDragger(arg); - }catch(const Base::Exception &e){ - e.setPyException(); - throw Py::Exception(); - } -} - Py::Object ViewProviderLinkPy::getLinkView() const { return Py::Object(getViewProviderLinkPtr()->getPyLinkView(),true); } diff --git a/src/Mod/Part/App/Attacher.cpp b/src/Mod/Part/App/Attacher.cpp index 8b9e594f57..84c1c08d2c 100644 --- a/src/Mod/Part/App/Attacher.cpp +++ b/src/Mod/Part/App/Attacher.cpp @@ -1901,6 +1901,11 @@ AttachEngine3D::_calculateAttachedPlacement(const std::vector(objs[0])) { + return plane->Placement.getValue() * attachmentOffset; + } + auto shape = shapes.front(); auto geom = Geometry::fromShape(shape->getShape()); @@ -1929,7 +1934,7 @@ AttachEngine3D::_calculateAttachedPlacement(const std::vectortangent(middle, direction); } - placement.setRotation(Base::Rotation::fromNormalVector(-direction)); + placement.setRotation(Base::Rotation::fromNormalVector(direction)); } } break; @@ -1941,8 +1946,10 @@ AttachEngine3D::_calculateAttachedPlacement(const std::vectorgetLocation()); } else if (auto cone = dynamic_cast(geom.get())) { placement.setPosition(cone->getApex()); + } else if (auto com = shape->centerOfGravity()) { + placement.setPosition(*com); } else { - placement.setPosition(shape->centerOfGravity().value()); + placement.setPosition(shape->getBoundBox().GetCenter()); } if (auto rotation = surface->getRotation()) { diff --git a/src/Mod/Part/App/Services.cpp b/src/Mod/Part/App/Services.cpp index 53eb46b947..65eac11cdb 100644 --- a/src/Mod/Part/App/Services.cpp +++ b/src/Mod/Part/App/Services.cpp @@ -33,7 +33,10 @@ Base::Placement AttacherSubObjectPlacement::calculate(App::SubObjectT object, Base::Placement basePlacement) const { attacher->setReferences({object}); - return basePlacement.inverse() * attacher->calculateAttachedPlacement(basePlacement); + + auto calculatedAttachment = attacher->calculateAttachedPlacement(basePlacement); + + return basePlacement.inverse() * calculatedAttachment; } std::optional PartCenterOfMass::ofDocumentObject(App::DocumentObject* object) const