Gui: Fix transform of link sub-elements

This commit is contained in:
Kacper Donat
2025-09-06 23:23:37 +02:00
committed by Chris Hennes
parent 29c18019ae
commit 707ee60d64
2 changed files with 59 additions and 66 deletions

View File

@@ -21,6 +21,7 @@
***************************************************************************/
#include <memory>
#include <ranges>
#include <string>
#include <QAction>
#include <QMenu>
@@ -29,10 +30,11 @@
#include <Inventor/nodes/SoTransform.h>
#include <App/GeoFeature.h>
#include <App/DocumentObjectGroup.h>
#include <Base/Tools.h>
#include <Base/Placement.h>
#include <Base/Vector3D.h>
#include <Base/Converter.h>
#include "Gui/ViewParams.h"
#include "Application.h"
#include "BitmapFactory.h"
@@ -41,16 +43,15 @@
#include "Inventor/Draggers/SoTransformDragger.h"
#include "Inventor/Draggers/Gizmo.h"
#include "Inventor/SoFCPlacementIndicatorKit.h"
#include "Inventor/So3DAnnotation.h"
#include "SoFCUnifiedSelection.h"
#include "TaskTransform.h"
#include "View3DInventorViewer.h"
#include "ViewProviderDragger.h"
#include "Utilities.h"
#include "ViewParams.h"
#include "ViewProviderLink.h"
#include <ViewProviderLink.h>
#include <App/DocumentObjectGroup.h>
#include <Base/Tools.h>
#include <Inventor/So3DAnnotation.h>
using namespace Gui;
@@ -144,35 +145,50 @@ ViewProvider* ViewProviderDragger::startEditing(int mode)
bool ViewProviderDragger::forwardToLink()
{
// Trying to detect if the editing request is forwarded by a link object,
// usually by doubleClicked(). If so, we route the request back. There shall
// be no risk of infinite recursion, as ViewProviderLink handles
// ViewProvider::Transform request by itself.
ViewProviderDocumentObject* vpParent = nullptr;
std::string subname;
// typically we want to transform the selected object, but if the selected object is in the link,
// we want to transform the link instead.
//
// To achieve that, we use the sub object path and look for the first link in the chain, and
// we forward the request there.
const auto findFirstLinkViewProvider = [this]() -> ViewProvider* {
ViewProviderDocumentObject* vpParent = nullptr;
std::string subname;
auto doc = Application::Instance->editDocument();
if (!doc) {
return false;
auto doc = Application::Instance->editDocument();
if (!doc) {
return nullptr;
}
doc->getInEdit(&vpParent, &subname);
if (!vpParent) {
return nullptr;
}
for (const auto subObjects = vpParent->getObject()->getSubObjectList(subname.c_str());
const auto subObject : std::views::reverse(subObjects)) {
// we don't want to try to edit objects in other documents
if (subObject->getDocument() != getObject()->getDocument()) {
return nullptr;
}
if (auto subObjectViewProvider = Application::Instance->getViewProvider(subObject);
subObjectViewProvider && subObjectViewProvider->isDerivedFrom<ViewProviderLink>()) {
return subObjectViewProvider;
}
}
return nullptr;
};
if (ViewProvider* subObjectViewProvider = findFirstLinkViewProvider();
subObjectViewProvider && subObjectViewProvider != this) {
forwardedViewProvider = subObjectViewProvider->startEditing(Transform);
}
doc->getInEdit(&vpParent, &subname);
if (!vpParent) {
return false;
}
if (vpParent == this) {
return false;
}
if (!vpParent->isDerivedFrom<ViewProviderLink>()) {
return false;
}
forwardedViewProvider = vpParent->startEditing(ViewProvider::Transform);
return forwardedViewProvider != nullptr;
}
App::PropertyPlacement* ViewProviderDragger::getPlacementProperty() const
{
auto object = getObject();
@@ -200,8 +216,8 @@ bool ViewProviderDragger::setEdit(int ModNum)
transformDragger = new SoTransformDragger();
transformDragger->setAxisColors(Gui::ViewParams::instance()->getAxisXColor(),
Gui::ViewParams::instance()->getAxisYColor(),
Gui::ViewParams::instance()->getAxisZColor());
Gui::ViewParams::instance()->getAxisYColor(),
Gui::ViewParams::instance()->getAxisZColor());
transformDragger->draggerSize.setValue(ViewParams::instance()->getDraggerScale());
transformDragger->addStartCallback(dragStartCallback, this);