From 3eed89288028b5c20008648ced541ca23197127f Mon Sep 17 00:00:00 2001 From: Uwe Date: Wed, 10 Nov 2021 05:08:36 +0100 Subject: [PATCH] [PD] add feature to set direction for pockets This PR adds the functionality of pads to pad along either a custom direction or along an edge to pockets. So with this PR Pad and Pocket are on the same level of functionality. --- src/Mod/PartDesign/App/FeaturePocket.cpp | 82 ++++- src/Mod/PartDesign/App/FeaturePocket.h | 12 +- .../PartDesign/Gui/TaskPocketParameters.cpp | 347 +++++++++++++++++- src/Mod/PartDesign/Gui/TaskPocketParameters.h | 20 + .../PartDesign/Gui/TaskPocketParameters.ui | 182 ++++++++- 5 files changed, 620 insertions(+), 23 deletions(-) diff --git a/src/Mod/PartDesign/App/FeaturePocket.cpp b/src/Mod/PartDesign/App/FeaturePocket.cpp index 3c248d7683..b569dd0c83 100644 --- a/src/Mod/PartDesign/App/FeaturePocket.cpp +++ b/src/Mod/PartDesign/App/FeaturePocket.cpp @@ -67,6 +67,10 @@ Pocket::Pocket() Type.setEnums(TypeEnums); ADD_PROPERTY_TYPE(Length,(100.0),"Pocket",App::Prop_None,"Pocket length"); ADD_PROPERTY_TYPE(Length2,(100.0),"Pocket",App::Prop_None,"P"); + ADD_PROPERTY_TYPE(UseCustomVector, (false), "Pocket", App::Prop_None, "Use custom vector for pocket direction"); + ADD_PROPERTY_TYPE(Direction, (Base::Vector3d(1.0, 1.0, 1.0)), "Pocket", App::Prop_None, "Pocket direction vector"); + ADD_PROPERTY_TYPE(ReferenceAxis, (0), "Pocket", App::Prop_None, "Reference axis of direction"); + ADD_PROPERTY_TYPE(AlongSketchNormal, (true), "Pocket", App::Prop_None, "Measure pocket length along the sketch normal direction"); ADD_PROPERTY_TYPE(UpToFace,(0),"Pocket",App::Prop_None,"Face where pocket will end"); ADD_PROPERTY_TYPE(Offset,(0.0),"Pocket",App::Prop_None,"Offset from face in which pocket will end"); static const App::PropertyQuantityConstraint::Constraints signedLengthConstraint = {-DBL_MAX, DBL_MAX, 1.0}; @@ -84,6 +88,10 @@ short Pocket::mustExecute() const Length.isTouched() || Length2.isTouched() || Offset.isTouched() || + UseCustomVector.isTouched() || + Direction.isTouched() || + ReferenceAxis.isTouched() || + AlongSketchNormal.isTouched() || UpToFace.isTouched()) return 1; return ProfileBased::mustExecute(); @@ -130,6 +138,7 @@ App::DocumentObjectExecReturn *Pocket::execute(void) // get the Sketch plane Base::Placement SketchPos = obj->Placement.getValue(); + // get the normal vector of the sketch Base::Vector3d SketchVector = getProfileNormal(); // turn around for pockets @@ -141,7 +150,78 @@ App::DocumentObjectExecReturn *Pocket::execute(void) base.Move(invObjLoc); - gp_Dir dir(SketchVector.x,SketchVector.y,SketchVector.z); + Base::Vector3d pocketDirection; + + if (!UseCustomVector.getValue()) { + if (!ReferenceAxis.getValue()) { + // use sketch's normal vector for direction + pocketDirection = SketchVector; + AlongSketchNormal.setReadOnly(true); + } + else { + // update Direction from ReferenceAxis + try { + App::DocumentObject* pcReferenceAxis = ReferenceAxis.getValue(); + const std::vector& subReferenceAxis = ReferenceAxis.getSubValues(); + Base::Vector3d base; + Base::Vector3d dir; + getAxis(pcReferenceAxis, subReferenceAxis, base, dir, false); + pocketDirection = dir; + } + catch (const Base::Exception& e) { + return new App::DocumentObjectExecReturn(e.what()); + } + } + } + else { + // use the given vector + // if null vector, use SketchVector + if ((fabs(Direction.getValue().x) < Precision::Confusion()) + && (fabs(Direction.getValue().y) < Precision::Confusion()) + && (fabs(Direction.getValue().z) < Precision::Confusion())) { + Direction.setValue(SketchVector); + } + pocketDirection = Direction.getValue(); + } + + // disable options of UseCustomVector + Direction.setReadOnly(!UseCustomVector.getValue()); + ReferenceAxis.setReadOnly(UseCustomVector.getValue()); + // UseCustomVector allows AlongSketchNormal but !UseCustomVector does not forbid it + if (UseCustomVector.getValue()) + AlongSketchNormal.setReadOnly(false); + + // create vector in pocketing direction with length 1 + gp_Dir dir(pocketDirection.x, pocketDirection.y, pocketDirection.z); + + // store the finally used direction to display it in the dialog + Direction.setValue(dir.X(), dir.Y(), dir.Z()); + + // The length of a gp_Dir is 1 so the resulting pocket would have + // the length L in the direction of dir. But we want to have its height in the + // direction of the normal vector. + // Therefore we must multiply L by the factor that is necessary + // to make dir as long that its projection to the SketchVector + // equals the SketchVector. + // This is the scalar product of both vectors. + // Since the pocket length cannot be negative, the factor must not be negative. + + double factor = fabs(dir * gp_Dir(SketchVector.x, SketchVector.y, SketchVector.z)); + + // factor would be zero if vectors are orthogonal + if (factor < Precision::Confusion()) + return new App::DocumentObjectExecReturn("Pocket: Creation failed because direction is orthogonal to sketch's normal vector"); + + // perform the length correction if not along custom vector + if (AlongSketchNormal.getValue()) { + L = L / factor; + L2 = L2 / factor; + } + + // explicitly set the Direction so that the dialog shows also the used direction + // if the sketch's normal vector was used + Direction.setValue(pocketDirection); + dir.Transform(invObjLoc.Transformation()); if (profileshape.IsNull()) diff --git a/src/Mod/PartDesign/App/FeaturePocket.h b/src/Mod/PartDesign/App/FeaturePocket.h index 36b494d21c..9fb580f4cf 100644 --- a/src/Mod/PartDesign/App/FeaturePocket.h +++ b/src/Mod/PartDesign/App/FeaturePocket.h @@ -37,10 +37,14 @@ class PartDesignExport Pocket : public ProfileBased public: Pocket(); - App::PropertyEnumeration Type; - App::PropertyLength Length; - App::PropertyLength Length2; - App::PropertyLength Offset; + App::PropertyEnumeration Type; + App::PropertyLength Length; + App::PropertyLength Length2; + App::PropertyLength Offset; + App::PropertyBool UseCustomVector; + App::PropertyVector Direction; + App::PropertyBool AlongSketchNormal; + App::PropertyLinkSub ReferenceAxis; /** @name methods override feature */ //@{ diff --git a/src/Mod/PartDesign/Gui/TaskPocketParameters.cpp b/src/Mod/PartDesign/Gui/TaskPocketParameters.cpp index d033225383..a16d614ca1 100644 --- a/src/Mod/PartDesign/Gui/TaskPocketParameters.cpp +++ b/src/Mod/PartDesign/Gui/TaskPocketParameters.cpp @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -76,6 +77,11 @@ TaskPocketParameters::TaskPocketParameters(ViewProviderPocket *PocketView,QWidge Base::Quantity l = pcPocket->Length.getQuantityValue(); Base::Quantity l2 = pcPocket->Length2.getQuantityValue(); Base::Quantity off = pcPocket->Offset.getQuantityValue(); + bool alongNormal = pcPocket->AlongSketchNormal.getValue(); + bool useCustom = pcPocket->UseCustomVector.getValue(); + double xs = pcPocket->Direction.getValue().x; + double ys = pcPocket->Direction.getValue().y; + double zs = pcPocket->Direction.getValue().z; bool midplane = pcPocket->Midplane.getValue(); bool reversed = pcPocket->Reversed.getValue(); int index = pcPocket->Type.getValue(); // must extract value here, clear() kills it! @@ -89,10 +95,30 @@ TaskPocketParameters::TaskPocketParameters(ViewProviderPocket *PocketView,QWidge faceId = std::atoi(&upToFace[4]); } + // set decimals for the direction edits + // do this here before the edits are filed to avoid rounding mistakes + int UserDecimals = Base::UnitsApi::getDecimals(); + ui->XDirectionEdit->setDecimals(UserDecimals); + ui->YDirectionEdit->setDecimals(UserDecimals); + ui->ZDirectionEdit->setDecimals(UserDecimals); + // Fill data into dialog elements + // the direction combobox is later filled in updateUI() ui->lengthEdit->setValue(l); ui->lengthEdit2->setValue(l2); ui->offsetEdit->setValue(off); + ui->checkBoxAlongDirection->setChecked(alongNormal); + ui->checkBoxDirection->setChecked(useCustom); + onDirectionToggled(useCustom); + // disable to change the direction if not custom + if (!useCustom) { + ui->XDirectionEdit->setEnabled(false); + ui->YDirectionEdit->setEnabled(false); + ui->ZDirectionEdit->setEnabled(false); + } + ui->XDirectionEdit->setValue(xs); + ui->YDirectionEdit->setValue(ys); + ui->ZDirectionEdit->setValue(zs); ui->checkBoxMidplane->setChecked(midplane); ui->checkBoxReversed->setChecked(reversed); @@ -127,6 +153,9 @@ TaskPocketParameters::TaskPocketParameters(ViewProviderPocket *PocketView,QWidge ui->lengthEdit->bind(pcPocket->Length); ui->lengthEdit2->bind(pcPocket->Length2); ui->offsetEdit->bind(pcPocket->Offset); + ui->XDirectionEdit->bind(App::ObjectIdentifier::parse(pcPocket, std::string("Direction.x"))); + ui->YDirectionEdit->bind(App::ObjectIdentifier::parse(pcPocket, std::string("Direction.y"))); + ui->ZDirectionEdit->bind(App::ObjectIdentifier::parse(pcPocket, std::string("Direction.z"))); QMetaObject::connectSlotsByName(this); @@ -136,6 +165,18 @@ TaskPocketParameters::TaskPocketParameters(ViewProviderPocket *PocketView,QWidge this, SLOT(onLength2Changed(double))); connect(ui->offsetEdit, SIGNAL(valueChanged(double)), this, SLOT(onOffsetChanged(double))); + connect(ui->directionCB, SIGNAL(activated(int)), + this, SLOT(onDirectionCBChanged(int))); + connect(ui->checkBoxAlongDirection, SIGNAL(toggled(bool)), + this, SLOT(onAlongSketchNormalChanged(bool))); + connect(ui->checkBoxDirection, SIGNAL(toggled(bool)), + this, SLOT(onDirectionToggled(bool))); + connect(ui->XDirectionEdit, SIGNAL(valueChanged(double)), + this, SLOT(onXDirectionEditChanged(double))); + connect(ui->YDirectionEdit, SIGNAL(valueChanged(double)), + this, SLOT(onYDirectionEditChanged(double))); + connect(ui->ZDirectionEdit, SIGNAL(valueChanged(double)), + this, SLOT(onZDirectionEditChanged(double))); connect(ui->checkBoxMidplane, SIGNAL(toggled(bool)), this, SLOT(onMidplaneChanged(bool))); connect(ui->checkBoxReversed, SIGNAL(toggled(bool)), @@ -149,6 +190,8 @@ TaskPocketParameters::TaskPocketParameters(ViewProviderPocket *PocketView,QWidge connect(ui->checkBoxUpdateView, SIGNAL(toggled(bool)), this, SLOT(onUpdateView(bool))); + this->propReferenceAxis = &(pcPocket->ReferenceAxis); + // Due to signals attached after changes took took into effect we should update the UI now. updateUI(index); @@ -166,6 +209,9 @@ TaskPocketParameters::TaskPocketParameters(ViewProviderPocket *PocketView,QWidge void TaskPocketParameters::updateUI(int index) { + // update direction combobox + fillDirectionCombo(); + // disable/hide everything unless we are sure we don't need it bool isLengthEditVisible = false; bool isLengthEdit2Visible = false; @@ -222,6 +268,7 @@ void TaskPocketParameters::updateUI(int index) ui->lengthEdit->setVisible( isLengthEditVisible ); ui->lengthEdit->setEnabled( isLengthEditVisible ); ui->labelLength->setVisible( isLengthEditVisible ); + ui->checkBoxAlongDirection->setVisible(isLengthEditVisible); ui->lengthEdit2->setVisible( isLengthEdit2Visible ); ui->lengthEdit2->setEnabled( isLengthEdit2Visible ); @@ -245,21 +292,36 @@ void TaskPocketParameters::updateUI(int index) void TaskPocketParameters::onSelectionChanged(const Gui::SelectionChanges& msg) { if (msg.Type == Gui::SelectionChanges::AddSelection) { - QString refText = onAddSelection(msg); - if (refText.length() > 0) { - ui->lineFaceName->blockSignals(true); - ui->lineFaceName->setText(refText); - ui->lineFaceName->setProperty("FeatureName", QByteArray(msg.pObjectName)); - ui->lineFaceName->setProperty("FaceName", QByteArray(msg.pSubName)); - ui->lineFaceName->blockSignals(false); - // Turn off reference selection mode - onButtonFace(false); - } else { - ui->lineFaceName->blockSignals(true); - ui->lineFaceName->clear(); - ui->lineFaceName->setProperty("FeatureName", QVariant()); - ui->lineFaceName->setProperty("FaceName", QVariant()); - ui->lineFaceName->blockSignals(false); + // if we have an edge selection for the pocket direction + if (!selectionFace) { + std::vector edge; + App::DocumentObject* selObj; + if (getReferencedSelection(vp->getObject(), msg, selObj, edge) && selObj) { + exitSelectionMode(); + propReferenceAxis->setValue(selObj, edge); + recomputeFeature(); + // update direction combobox + fillDirectionCombo(); + } + } + else { // if we have a selection of a face + QString refText = onAddSelection(msg); + if (refText.length() > 0) { + ui->lineFaceName->blockSignals(true); + ui->lineFaceName->setText(refText); + ui->lineFaceName->setProperty("FeatureName", QByteArray(msg.pObjectName)); + ui->lineFaceName->setProperty("FaceName", QByteArray(msg.pSubName)); + ui->lineFaceName->blockSignals(false); + // Turn off reference selection mode + onButtonFace(false); + } + else { + ui->lineFaceName->blockSignals(true); + ui->lineFaceName->clear(); + ui->lineFaceName->setProperty("FeatureName", QVariant()); + ui->lineFaceName->setProperty("FaceName", QVariant()); + ui->lineFaceName->blockSignals(false); + } } } else if (msg.Type == Gui::SelectionChanges::ClrSelection) { ui->lineFaceName->blockSignals(true); @@ -291,6 +353,193 @@ void TaskPocketParameters::onOffsetChanged(double len) recomputeFeature(); } +void TaskPocketParameters::fillDirectionCombo() +{ + bool oldVal_blockUpdate = blockUpdate; + blockUpdate = true; + + if (axesInList.empty()) { + ui->directionCB->clear(); + // add sketch normal + PartDesign::ProfileBased* pcFeat = static_cast(vp->getObject()); + Part::Part2DObject* pcSketch = dynamic_cast(pcFeat->Profile.getValue()); + if (pcSketch) + addAxisToCombo(pcSketch, "N_Axis", QObject::tr("Sketch normal")); + // add the other entries + addAxisToCombo(0, std::string(), tr("Select reference...")); + // we start with the sketch normal as proposal for the custom direction + if (pcSketch) + addAxisToCombo(pcSketch, "N_Axis", QObject::tr("Custom direction")); + } + + // add current link, if not in list + // first, figure out the item number for current axis + int indexOfCurrent = -1; + App::DocumentObject* ax = propReferenceAxis->getValue(); + const std::vector& subList = propReferenceAxis->getSubValues(); + for (size_t i = 0; i < axesInList.size(); i++) { + if (ax == axesInList[i]->getValue() && subList == axesInList[i]->getSubValues()) { + indexOfCurrent = i; + break; + } + } + // if the axis is not yet listed in the combobox + if (indexOfCurrent == -1 && ax) { + assert(subList.size() <= 1); + std::string sub; + if (!subList.empty()) + sub = subList[0]; + addAxisToCombo(ax, sub, getRefStr(ax, subList)); + indexOfCurrent = axesInList.size() - 1; + // the axis is not the normal, thus enable along direction + ui->checkBoxAlongDirection->setEnabled(true); + // we don't have custom direction thus disable its settings + ui->XDirectionEdit->setEnabled(false); + ui->YDirectionEdit->setEnabled(false); + ui->ZDirectionEdit->setEnabled(false); + } + + // highlight either current index or set custom direction + PartDesign::Pocket* pcPocket = static_cast(vp->getObject()); + bool hasCustom = pcPocket->UseCustomVector.getValue(); + if (indexOfCurrent != -1 && !hasCustom) + ui->directionCB->setCurrentIndex(indexOfCurrent); + if (hasCustom) + ui->directionCB->setCurrentIndex(2); + + blockUpdate = oldVal_blockUpdate; +} + +void TaskPocketParameters::addAxisToCombo(App::DocumentObject* linkObj, + std::string linkSubname, QString itemText) +{ + this->ui->directionCB->addItem(itemText); + this->axesInList.emplace_back(new App::PropertyLinkSub); + App::PropertyLinkSub& lnk = *(axesInList.back()); + lnk.setValue(linkObj, std::vector(1, linkSubname)); +} + +void TaskPocketParameters::onDirectionCBChanged(int num) +{ + PartDesign::Pocket* pcPocket = static_cast(vp->getObject()); + + if (axesInList.empty() || !pcPocket) + return; + + App::PropertyLinkSub& lnk = *(axesInList[num]); + if (lnk.getValue() == 0) { + // enter reference selection mode + this->blockConnection(false); + // to distinguish that this is the direction selection + selectionFace = false; + TaskSketchBasedParameters::onSelectReference(true, true, false, true, true); + return; + } + else { + if (!pcPocket->getDocument()->isIn(lnk.getValue())) { + Base::Console().Error("Object was deleted\n"); + return; + } + propReferenceAxis->Paste(lnk); + // in case user is in selection mode, but changed his mind before selecting anything + exitSelectionMode(); + } + + try { + recomputeFeature(); + } + catch (const Base::Exception& e) { + e.ReportException(); + } + + // disable AlongSketchNormal when the direction is already normal + if (num == 0) + ui->checkBoxAlongDirection->setEnabled(false); + else + ui->checkBoxAlongDirection->setEnabled(true); + // if custom direction is used, show it + if (num == 2) { + ui->checkBoxDirection->setChecked(true); + PartDesign::Pocket* pcPocket = static_cast(vp->getObject()); + pcPocket->UseCustomVector.setValue(true); + } + else { + ui->checkBoxDirection->setChecked(false); + pcPocket->UseCustomVector.setValue(false); + } + // if we dont use custom direction, only allow to show its direction + if (num != 2) { + ui->XDirectionEdit->setEnabled(false); + ui->YDirectionEdit->setEnabled(false); + ui->ZDirectionEdit->setEnabled(false); + } + else { + ui->XDirectionEdit->setEnabled(true); + ui->YDirectionEdit->setEnabled(true); + ui->ZDirectionEdit->setEnabled(true); + } + // recompute and update the direction + recomputeFeature(); + updateDirectionEdits(); +} + +void TaskPocketParameters::onAlongSketchNormalChanged(bool on) +{ + PartDesign::Pocket* pcPocket = static_cast(vp->getObject()); + pcPocket->AlongSketchNormal.setValue(on); + recomputeFeature(); +} + +void TaskPocketParameters::onDirectionToggled(bool on) +{ + if (on) + ui->groupBoxDirection->show(); + else + ui->groupBoxDirection->hide(); +} + +void TaskPocketParameters::onXDirectionEditChanged(double len) +{ + PartDesign::Pocket* pcPocket = static_cast(vp->getObject()); + pcPocket->Direction.setValue(len, pcPocket->Direction.getValue().y, pcPocket->Direction.getValue().z); + recomputeFeature(); + // checking for case of a null vector is done in FeaturePocket.cpp + // if there was a null vector, the normal vector of the sketch is used. + // therefore the vector component edits must be updated + updateDirectionEdits(); +} + +void TaskPocketParameters::onYDirectionEditChanged(double len) +{ + PartDesign::Pocket* pcPocket = static_cast(vp->getObject()); + pcPocket->Direction.setValue(pcPocket->Direction.getValue().x, len, pcPocket->Direction.getValue().z); + recomputeFeature(); + updateDirectionEdits(); +} + +void TaskPocketParameters::onZDirectionEditChanged(double len) +{ + PartDesign::Pocket* pcPocket = static_cast(vp->getObject()); + pcPocket->Direction.setValue(pcPocket->Direction.getValue().x, pcPocket->Direction.getValue().y, len); + recomputeFeature(); + updateDirectionEdits(); +} + +void TaskPocketParameters::updateDirectionEdits(void) +{ + PartDesign::Pocket* pcPocket = static_cast(vp->getObject()); + // we don't want to execute the onChanged edits, but just update their contents + ui->XDirectionEdit->blockSignals(true); + ui->YDirectionEdit->blockSignals(true); + ui->ZDirectionEdit->blockSignals(true); + ui->XDirectionEdit->setValue(pcPocket->Direction.getValue().x); + ui->YDirectionEdit->setValue(pcPocket->Direction.getValue().y); + ui->ZDirectionEdit->setValue(pcPocket->Direction.getValue().z); + ui->XDirectionEdit->blockSignals(false); + ui->YDirectionEdit->blockSignals(false); + ui->ZDirectionEdit->blockSignals(false); +} + void TaskPocketParameters::onMidplaneChanged(bool on) { PartDesign::Pocket* pcPocket = static_cast(vp->getObject()); @@ -394,6 +643,39 @@ double TaskPocketParameters::getOffset(void) const return ui->offsetEdit->value().getValue(); } +bool TaskPocketParameters::getAlongSketchNormal(void) const +{ + return ui->checkBoxAlongDirection->isChecked(); +} + +bool TaskPocketParameters::getCustom(void) const +{ + return ui->checkBoxDirection->isChecked(); +} + +std::string TaskPocketParameters::getReferenceAxis(void) const +{ + std::vector sub; + App::DocumentObject* obj; + getReferenceAxis(obj, sub); + return buildLinkSingleSubPythonStr(obj, sub); +} + +double TaskPocketParameters::getXDirection(void) const +{ + return ui->XDirectionEdit->value(); +} + +double TaskPocketParameters::getYDirection(void) const +{ + return ui->YDirectionEdit->value(); +} + +double TaskPocketParameters::getZDirection(void) const +{ + return ui->ZDirectionEdit->value(); +} + bool TaskPocketParameters::getReversed(void) const { return ui->checkBoxReversed->isChecked(); @@ -433,9 +715,19 @@ void TaskPocketParameters::changeEvent(QEvent *e) ui->lengthEdit->blockSignals(true); ui->lengthEdit2->blockSignals(true); ui->offsetEdit->blockSignals(true); + ui->XDirectionEdit->blockSignals(true); + ui->YDirectionEdit->blockSignals(true); + ui->ZDirectionEdit->blockSignals(true); + ui->directionCB->blockSignals(true); + int index = ui->directionCB->currentIndex(); + ui->directionCB->clear(); + ui->directionCB->addItem(tr("Sketch normal")); + ui->directionCB->addItem(tr("Select reference...")); + ui->directionCB->addItem(tr("Custom direction")); + ui->directionCB->setCurrentIndex(index); ui->lineFaceName->blockSignals(true); ui->changeMode->blockSignals(true); - int index = ui->changeMode->currentIndex(); + index = ui->changeMode->currentIndex(); ui->retranslateUi(proxy); ui->changeMode->clear(); ui->changeMode->addItem(tr("Dimension")); @@ -477,6 +769,29 @@ void TaskPocketParameters::changeEvent(QEvent *e) } } +void TaskPocketParameters::getReferenceAxis(App::DocumentObject*& obj, std::vector& sub) const +{ + if (axesInList.empty()) + throw Base::RuntimeError("Not initialized!"); + + int num = ui->directionCB->currentIndex(); + const App::PropertyLinkSub& lnk = *(axesInList[num]); + if (lnk.getValue() == 0) { + // Note: Is is possible that a face of an object is directly pocketed without defining a profile shape + obj = nullptr; + sub.clear(); + //throw Base::RuntimeError("Still in reference selection mode; reference wasn't selected yet"); + } + else { + PartDesign::ProfileBased* pcDirection = static_cast(vp->getObject()); + if (!pcDirection->getDocument()->isIn(lnk.getValue())) + throw Base::RuntimeError("Object was deleted"); + + obj = lnk.getValue(); + sub = lnk.getSubValues(); + } +} + void TaskPocketParameters::saveHistory(void) { // save the user values to history diff --git a/src/Mod/PartDesign/Gui/TaskPocketParameters.h b/src/Mod/PartDesign/Gui/TaskPocketParameters.h index 397b545d16..09d1344791 100644 --- a/src/Mod/PartDesign/Gui/TaskPocketParameters.h +++ b/src/Mod/PartDesign/Gui/TaskPocketParameters.h @@ -55,10 +55,19 @@ public: virtual void saveHistory() override; virtual void apply() override; + void fillDirectionCombo(); + void addAxisToCombo(App::DocumentObject* linkObj, std::string linkSubname, QString itemText); + private Q_SLOTS: void onLengthChanged(double); void onLength2Changed(double); void onOffsetChanged(double); + void onDirectionCBChanged(int); + void onAlongSketchNormalChanged(bool); + void onDirectionToggled(bool); + void onXDirectionEditChanged(double); + void onYDirectionEditChanged(double); + void onZDirectionEditChanged(double); void onMidplaneChanged(bool); void onReversedChanged(bool); void onButtonFace(const bool pressed = true); @@ -67,11 +76,19 @@ private Q_SLOTS: protected: void changeEvent(QEvent *e) override; + App::PropertyLinkSub* propReferenceAxis; + void getReferenceAxis(App::DocumentObject*& obj, std::vector& sub) const; private: double getLength(void) const; double getLength2(void) const; double getOffset(void) const; + bool getAlongSketchNormal(void) const; + bool getCustom(void) const; + std::string getReferenceAxis(void) const; + double getXDirection(void) const; + double getYDirection(void) const; + double getZDirection(void) const; int getMode(void) const; bool getMidplane(void) const; bool getReversed(void) const; @@ -79,11 +96,14 @@ private: void onSelectionChanged(const Gui::SelectionChanges& msg) override; void updateUI(int index); + void updateDirectionEdits(void); private: QWidget* proxy; std::unique_ptr ui; double oldLength; + bool selectionFace; + std::vector> axesInList; }; /// simulation dialog for the TaskView diff --git a/src/Mod/PartDesign/Gui/TaskPocketParameters.ui b/src/Mod/PartDesign/Gui/TaskPocketParameters.ui index cf487e40eb..322dba0fa5 100644 --- a/src/Mod/PartDesign/Gui/TaskPocketParameters.ui +++ b/src/Mod/PartDesign/Gui/TaskPocketParameters.ui @@ -6,8 +6,8 @@ 0 0 - 193 - 272 + 300 + 436 @@ -65,6 +65,179 @@ + + + + Direction + + + + + + + + Direction/edge: + + + + + + + Set a direction or select an edge +from the model as reference + + + + Sketch normal + + + + + Select reference... + + + + + Custom direction + + + + + + + + + + Show direction + + + + + + + true + + + Use custom vector for pad direction, otherwise +the sketch plane's normal vector will be used + + + false + + + false + + + + + + x-component of direction vector + + + false + + + -100.000000000000000 + + + 100.000000000000000 + + + 0.100000000000000 + + + + + + + + + + z + + + + + + + y-component of direction vector + + + false + + + -100.000000000000000 + + + 100.000000000000000 + + + 0.100000000000000 + + + + + + + + + + y + + + + + + + z-component of direction vector + + + false + + + -100.000000000000000 + + + 100.000000000000000 + + + 0.100000000000000 + + + 1.000000000000000 + + + + + + + + + + x + + + + + + + + + + true + + + If unchecked, the length will be +measured along the specified direction + + + Length along sketch normal + + + + + + @@ -139,6 +312,11 @@ QWidget
Gui/QuantitySpinBox.h
+ + Gui::DoubleSpinBox + QDoubleSpinBox +
Gui/SpinBox.h
+
Gui::PrefQuantitySpinBox Gui::QuantitySpinBox