PartDesign: add interactive gizmos for box, cylinder and sphere operations (#23700)

This commit is contained in:
Captain
2026-02-09 02:06:04 +05:30
committed by GitHub
parent a79a22185d
commit 3237a21580
4 changed files with 109 additions and 1 deletions

View File

@@ -594,6 +594,8 @@ void TaskAttacher::onSelectionChanged(const Gui::SelectionChanges& msg)
if (msg.Type == Gui::SelectionChanges::AddSelection) {
SubAndObjName pair = {msg.pObjectName, msg.pSubName};
addToReference(pair);
Q_EMIT placementUpdated();
}
}
@@ -736,6 +738,8 @@ void TaskAttacher::onAttachmentOffsetChanged(double /*val*/, int idx)
pcAttach->AttachmentOffset.setValue(pl);
updatePreview();
Q_EMIT placementUpdated();
}
void TaskAttacher::onAttachmentOffsetXChanged(double val)
@@ -778,6 +782,8 @@ void TaskAttacher::onCheckFlip(bool on)
= ViewProvider->getObject()->getExtensionByType<Part::AttachExtension>();
pcAttach->MapReversed.setValue(on);
ViewProvider->getObject()->recomputeFeature();
Q_EMIT placementUpdated();
}
void TaskAttacher::onButtonRef(const bool checked, unsigned idx)
@@ -794,6 +800,8 @@ void TaskAttacher::onButtonRef(const bool checked, unsigned idx)
updateRefButton(1);
updateRefButton(2);
updateRefButton(3);
Q_EMIT placementUpdated();
}
void TaskAttacher::onButtonRef1(const bool checked)
@@ -873,6 +881,7 @@ void TaskAttacher::onRefName(const QString& text, unsigned idx)
ui->lineRef4->setText(refstrings[3]);
ui->lineRef4->setProperty("RefName", QByteArray(newrefnames[3].c_str()));
updateReferencesUI();
Q_EMIT placementUpdated();
return;
}
@@ -963,6 +972,8 @@ void TaskAttacher::onRefName(const QString& text, unsigned idx)
selectMapMode(getActiveMapMode());
updateReferencesUI();
Q_EMIT placementUpdated();
}
void TaskAttacher::updateRefButton(int idx)

View File

@@ -90,6 +90,9 @@ public:
return completed;
}
Q_SIGNALS:
void placementUpdated();
private Q_SLOTS:
void onAttachmentOffsetChanged(double, int idx);
void onAttachmentOffsetXChanged(double);

View File

@@ -29,12 +29,15 @@
#include <App/Document.h>
#include <App/Origin.h>
#include <Base/Console.h>
#include <Base/Converter.h>
#include <Base/UnitsApi.h>
#include <Gui/Application.h>
#include <Gui/Command.h>
#include <Gui/Document.h>
#include <Gui/MainWindow.h>
#include <Gui/ViewProviderCoordinateSystem.h>
#include <Gui/Inventor/Draggers/Gizmo.h>
#include <Gui/Utilities.h>
#include <Mod/PartDesign/App/Body.h>
#include <Mod/PartDesign/App/FeaturePrimitive.h>
@@ -369,6 +372,8 @@ TaskBoxPrimitives::TaskBoxPrimitives(ViewProviderPrimitive* vp, QWidget* parent)
this, &TaskBoxPrimitives::onWedgeZ2maxChanged);
connect(ui->wedgeZ2min, qOverload<double>(&Gui::QuantitySpinBox::valueChanged),
this, &TaskBoxPrimitives::onWedgeZ2minChanged);
setupGizmos();
}
// clang-format on
@@ -810,6 +815,11 @@ void TaskBoxPrimitives::onWedgeZmaxChanged(double v)
}
}
void TaskBoxPrimitives::onPlacementChanged()
{
setGizmoPositions();
}
bool TaskBoxPrimitives::setPrimitive(App::DocumentObject* obj)
{
@@ -998,6 +1008,69 @@ bool TaskBoxPrimitives::setPrimitive(App::DocumentObject* obj)
return true;
}
void TaskBoxPrimitives::setupGizmos()
{
if (!Gui::GizmoContainer::isEnabled()) {
return;
}
switch (getObject<PartDesign::FeaturePrimitive>()->getPrimitiveType()) {
case PartDesign::FeaturePrimitive::Box:
lengthGizmo = new Gui::LinearGizmo(ui->boxLength);
widthGizmo = new Gui::LinearGizmo(ui->boxWidth);
heightGizmo = new Gui::LinearGizmo(ui->boxHeight);
gizmoContainer = Gui::GizmoContainer::create({widthGizmo, heightGizmo, lengthGizmo}, vp);
break;
case PartDesign::FeaturePrimitive::Cylinder:
heightGizmo = new Gui::LinearGizmo(ui->cylinderHeight);
radiusGizmo = new Gui::LinearGizmo(ui->cylinderRadius);
gizmoContainer = Gui::GizmoContainer::create({heightGizmo, radiusGizmo}, vp);
break;
case PartDesign::FeaturePrimitive::Sphere:
radiusGizmo = new Gui::LinearGizmo(ui->sphereRadius);
gizmoContainer = Gui::GizmoContainer::create({radiusGizmo}, vp);
break;
default:
return;
}
setGizmoPositions();
}
void TaskBoxPrimitives::setGizmoPositions()
{
if (!gizmoContainer) {
return;
}
SbVec3f pos = Base::convertTo<SbVec3f>(vp->getObjectPlacement().getPosition());
SbRotation rot = Base::convertTo<SbRotation>(vp->getObjectPlacement().getRotation());
auto getVec = [rot](SbVec3f vec) {
rot.multVec(vec, vec);
return vec;
};
switch (getObject<PartDesign::FeaturePrimitive>()->getPrimitiveType()) {
case PartDesign::FeaturePrimitive::Box:
lengthGizmo->setDraggerPlacement(pos, getVec({1, 0, 0}));
widthGizmo->setDraggerPlacement(pos, getVec({0, 1, 0}));
heightGizmo->setDraggerPlacement(pos, getVec({0, 0, 1}));
break;
case PartDesign::FeaturePrimitive::Cylinder:
heightGizmo->setDraggerPlacement(pos, getVec({0, 0, 1}));
radiusGizmo->setDraggerPlacement(pos, getVec({1, 1, 0}));
break;
case PartDesign::FeaturePrimitive::Sphere:
radiusGizmo->setDraggerPlacement(pos, getVec({1, 1, 0}));
break;
default:
return;
}
}
TaskDlgPrimitiveParameters::TaskDlgPrimitiveParameters(ViewProviderPrimitive* PrimitiveView)
: TaskDlgFeatureParameters(PrimitiveView)
, vp_prm(PrimitiveView)
@@ -1009,6 +1082,13 @@ TaskDlgPrimitiveParameters::TaskDlgPrimitiveParameters(ViewProviderPrimitive* Pr
parameter = new PartGui::TaskAttacher(PrimitiveView, nullptr, QString(), tr("Attachment"));
Content.push_back(parameter);
Content.push_back(preview);
connect(
parameter,
&PartGui::TaskAttacher::placementUpdated,
primitive,
&TaskBoxPrimitives::onPlacementChanged
);
}
TaskDlgPrimitiveParameters::~TaskDlgPrimitiveParameters() = default;

View File

@@ -27,6 +27,8 @@
#define GUI_TASKVIEW_TaskPrimitiveParameters_H
#include <memory>
#include <unordered_map>
#include <Gui/DocumentObserver.h>
#include <Gui/TaskView/TaskDialog.h>
#include <Gui/TaskView/TaskView.h>
@@ -43,7 +45,9 @@ class Property;
namespace Gui
{
class ViewProvider;
}
class GizmoContainer;
class LinearGizmo;
} // namespace Gui
namespace PartDesignGui
{
@@ -102,6 +106,8 @@ public Q_SLOTS:
void onWedgeZ2maxChanged(double);
void onWedgeZ2minChanged(double);
void onPlacementChanged();
private:
/** Notifies when the object is about to be removed. */
void slotDeletedObject(const Gui::ViewProviderDocumentObject& Obj) override;
@@ -121,6 +127,14 @@ private:
QWidget* proxy;
std::unique_ptr<Ui_DlgPrimitives> ui;
ViewProviderPrimitive* vp;
std::unique_ptr<Gui::GizmoContainer> gizmoContainer;
Gui::LinearGizmo* lengthGizmo = nullptr;
Gui::LinearGizmo* heightGizmo = nullptr;
Gui::LinearGizmo* widthGizmo = nullptr;
Gui::LinearGizmo* radiusGizmo = nullptr;
void setupGizmos();
void setGizmoPositions();
};
class TaskDlgPrimitiveParameters: public TaskDlgFeatureParameters