PartDesign: add interactive gizmos for box, cylinder and sphere operations (#23700)
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -90,6 +90,9 @@ public:
|
||||
return completed;
|
||||
}
|
||||
|
||||
Q_SIGNALS:
|
||||
void placementUpdated();
|
||||
|
||||
private Q_SLOTS:
|
||||
void onAttachmentOffsetChanged(double, int idx);
|
||||
void onAttachmentOffsetXChanged(double);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user