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

@@ -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;