diff --git a/src/Base/Rotation.cpp b/src/Base/Rotation.cpp index 118a7c6563..646731561d 100644 --- a/src/Base/Rotation.cpp +++ b/src/Base/Rotation.cpp @@ -673,13 +673,13 @@ void Rotation::getYawPitchRoll(double& y, double& p, double& r) const double qd2 = 2.0*(q13-q02); // handle gimbal lock - if (fabs(qd2-1.0) <= DBL_EPSILON) { + if (fabs(qd2-1.0) <= 16 * DBL_EPSILON) { // Tolerance copied from OCC "gp_Quaternion.cxx" // north pole y = 0.0; p = D_PI/2.0; r = 2.0 * atan2(quat[0],quat[3]); } - else if (fabs(qd2+1.0) <= DBL_EPSILON) { + else if (fabs(qd2+1.0) <= 16 * DBL_EPSILON) { // Tolerance copied from OCC "gp_Quaternion.cxx" // south pole y = 0.0; p = -D_PI/2.0; diff --git a/src/Gui/Application.cpp b/src/Gui/Application.cpp index 6af9e09da9..be017ae1cc 100644 --- a/src/Gui/Application.cpp +++ b/src/Gui/Application.cpp @@ -2080,6 +2080,12 @@ void Application::runApplication(void) WheelEventFilter* filter = new WheelEventFilter(&mainApp); mainApp.installEventFilter(filter); } + + //filter keyboard events to substitute decimal separator + if (hGrp->GetBool("SubstituteDecimalSeparator", false)) { + KeyboardFilter* filter = new KeyboardFilter(&mainApp); + mainApp.installEventFilter(filter); + } #if defined(HAVE_QT5_OPENGL) { diff --git a/src/Gui/GuiApplication.cpp b/src/Gui/GuiApplication.cpp index 2431a5f76d..b254658000 100644 --- a/src/Gui/GuiApplication.cpp +++ b/src/Gui/GuiApplication.cpp @@ -26,12 +26,14 @@ #ifndef _PreComp_ # include # include +# include # include # include # include # include # include # include +# include # include # include #endif @@ -323,5 +325,29 @@ bool WheelEventFilter::eventFilter(QObject* obj, QEvent* ev) return false; } +KeyboardFilter::KeyboardFilter(QObject* parent) + : QObject(parent) +{ +} + +bool KeyboardFilter::eventFilter(QObject* obj, QEvent* ev) +{ + if (ev->type() == QEvent::KeyPress || ev->type() == QEvent::KeyRelease) { + QKeyEvent *kev = static_cast(ev); + QAbstractSpinBox *target = dynamic_cast(obj); + if (kev->key() == Qt::Key_Period && target) + { + QChar decimalPoint = QLocale().decimalPoint(); + QChar groupSeparator = QLocale().groupSeparator(); + if (decimalPoint != Qt::Key_Period && (groupSeparator != Qt::Key_Period || (kev->modifiers() & Qt::KeypadModifier))) { + QKeyEvent modifiedKeyEvent(kev->type(), decimalPoint.digitValue(), kev->modifiers(), QString(decimalPoint), kev->isAutoRepeat(), kev->count()); + qApp->sendEvent(obj, &modifiedKeyEvent); + return true; + } + } + } + return false; +} + #include "moc_GuiApplication.cpp" diff --git a/src/Gui/GuiApplication.h b/src/Gui/GuiApplication.h index 191148e216..85b7f2cf31 100644 --- a/src/Gui/GuiApplication.h +++ b/src/Gui/GuiApplication.h @@ -92,6 +92,15 @@ public: bool eventFilter(QObject* obj, QEvent* ev); }; +class KeyboardFilter : public QObject +{ + Q_OBJECT + +public: + KeyboardFilter(QObject* parent); + bool eventFilter(QObject* obj, QEvent* ev); +}; + } #endif // GUI_APPLICATION_H diff --git a/src/Mod/PartDesign/App/FeaturePad.cpp b/src/Mod/PartDesign/App/FeaturePad.cpp index 7558595d58..35755a212a 100644 --- a/src/Mod/PartDesign/App/FeaturePad.cpp +++ b/src/Mod/PartDesign/App/FeaturePad.cpp @@ -70,6 +70,7 @@ Pad::Pad() ADD_PROPERTY_TYPE(Length2, (100.0), "Pad", App::Prop_None,"Second Pad length"); ADD_PROPERTY_TYPE(UseCustomVector, (false), "Pad", App::Prop_None, "Use custom vector for pad direction"); ADD_PROPERTY_TYPE(Direction, (Base::Vector3d(1.0, 1.0, 1.0)), "Pad", App::Prop_None, "Pad direction vector"); + ADD_PROPERTY_TYPE(ReferenceAxis, (0), "Pad", App::Prop_None, "Reference axis of direction"); ADD_PROPERTY_TYPE(AlongSketchNormal, (true), "Pad", App::Prop_None, "Measure pad length along the sketch normal direction"); ADD_PROPERTY_TYPE(UpToFace, (0), "Pad", App::Prop_None, "Face where pad will end"); ADD_PROPERTY_TYPE(Offset, (0.0), "Pad", App::Prop_None, "Offset from face in which pad will end"); @@ -79,10 +80,6 @@ Pad::Pad() // Remove the constraints and keep the type to allow to accept negative values // https://forum.freecadweb.org/viewtopic.php?f=3&t=52075&p=448410#p447636 Length2.setConstraints(nullptr); - - // for new pads UseCustomVector is false, thus disable Direction and AlongSketchNormal - AlongSketchNormal.setReadOnly(true); - Direction.setReadOnly(true); } short Pad::mustExecute() const @@ -93,6 +90,7 @@ short Pad::mustExecute() const Length2.isTouched() || UseCustomVector.isTouched() || Direction.isTouched() || + ReferenceAxis.isTouched() || AlongSketchNormal.isTouched() || Offset.isTouched() || UpToFace.isTouched()) @@ -121,7 +119,8 @@ App::DocumentObjectExecReturn *Pad::execute(void) try { obj = getVerifiedObject(); sketchshape = getVerifiedFace(); - } catch (const Base::Exception& e) { + } + catch (const Base::Exception& e) { return new App::DocumentObjectExecReturn(e.what()); } @@ -129,7 +128,8 @@ App::DocumentObjectExecReturn *Pad::execute(void) TopoDS_Shape base; try { base = getBaseShape(); - } catch (const Base::Exception&) { + } + catch (const Base::Exception&) { base = TopoDS_Shape(); } @@ -147,29 +147,50 @@ App::DocumentObjectExecReturn *Pad::execute(void) Base::Vector3d paddingDirection; if (!UseCustomVector.getValue()) { - // use sketch's normal vector for direction - paddingDirection = SketchVector; + if (ReferenceAxis.getValue() == nullptr) { + // use sketch's normal vector for direction + paddingDirection = 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); + paddingDirection = 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()) ) - { + && (fabs(Direction.getValue().z) < Precision::Confusion()) ) { Direction.setValue(SketchVector); } - paddingDirection = Direction.getValue(); } // disable options of UseCustomVector - AlongSketchNormal.setReadOnly(!UseCustomVector.getValue()); 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 padding direction with length 1 gp_Dir dir(paddingDirection.x, paddingDirection.y, paddingDirection.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 pad would have // the length L in the direction of dir. But we want to have its height in the // direction of the normal vector. @@ -384,4 +405,3 @@ App::DocumentObjectExecReturn *Pad::execute(void) return new App::DocumentObjectExecReturn(e.what()); } } - diff --git a/src/Mod/PartDesign/App/FeaturePad.h b/src/Mod/PartDesign/App/FeaturePad.h index 6d38b0fedd..775102f1b4 100644 --- a/src/Mod/PartDesign/App/FeaturePad.h +++ b/src/Mod/PartDesign/App/FeaturePad.h @@ -47,6 +47,7 @@ public: App::PropertyVector Direction; App::PropertyBool AlongSketchNormal; App::PropertyLength Offset; + App::PropertyLinkSub ReferenceAxis; /** @name methods override feature */ //@{ diff --git a/src/Mod/PartDesign/App/FeatureSketchBased.cpp b/src/Mod/PartDesign/App/FeatureSketchBased.cpp index 05a7fc77b3..497f3ea6be 100644 --- a/src/Mod/PartDesign/App/FeatureSketchBased.cpp +++ b/src/Mod/PartDesign/App/FeatureSketchBased.cpp @@ -1070,6 +1070,10 @@ void ProfileBased::getAxis(const App::DocumentObject *pcReferenceAxis, const std hasValidAxis = true; axis = sketch->getAxis(Part::Part2DObject::H_Axis); } + else if (subReferenceAxis[0] == "N_Axis") { + hasValidAxis = true; + axis = sketch->getAxis(Part::Part2DObject::N_Axis); + } else if (subReferenceAxis[0].size() > 4 && subReferenceAxis[0].substr(0, 4) == "Axis") { int AxId = std::atoi(subReferenceAxis[0].substr(4, 4000).c_str()); if (AxId >= 0 && AxId < sketch->getAxisCount()) { diff --git a/src/Mod/PartDesign/Gui/Command.cpp b/src/Mod/PartDesign/Gui/Command.cpp index 77a65c45a2..83b13b9874 100644 --- a/src/Mod/PartDesign/Gui/Command.cpp +++ b/src/Mod/PartDesign/Gui/Command.cpp @@ -1256,6 +1256,9 @@ void CmdPartDesignPad::activated(int iMsg) Gui::Command::updateActive(); Part::Part2DObject* sketch = dynamic_cast(profile); + + FCMD_OBJ_CMD(Feat, "ReferenceAxis = (" << getObjectCmd(sketch) << ",['N_Axis'])"); + finishProfileBased(cmd, sketch, Feat); cmd->adjustCameraPosition(); }; diff --git a/src/Mod/PartDesign/Gui/TaskHelixParameters.cpp b/src/Mod/PartDesign/Gui/TaskHelixParameters.cpp index eeb1e6bb83..029a63c661 100644 --- a/src/Mod/PartDesign/Gui/TaskHelixParameters.cpp +++ b/src/Mod/PartDesign/Gui/TaskHelixParameters.cpp @@ -235,8 +235,10 @@ void TaskHelixParameters::fillAxisCombo(bool forceRefill) 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()) + if (ax == axesInList[i]->getValue() && subList == axesInList[i]->getSubValues()) { indexOfCurrent = i; + break; + } } if (indexOfCurrent == -1 && ax) { assert(subList.size() <= 1); @@ -260,7 +262,7 @@ void TaskHelixParameters::addAxisToCombo(App::DocumentObject* linkObj, { this->ui->axis->addItem(itemText); this->axesInList.emplace_back(new App::PropertyLinkSub); - App::PropertyLinkSub &lnk = *(axesInList[axesInList.size()-1]); + App::PropertyLinkSub &lnk = *(axesInList.back()); lnk.setValue(linkObj,std::vector(1,linkSubname)); } diff --git a/src/Mod/PartDesign/Gui/TaskPadParameters.cpp b/src/Mod/PartDesign/Gui/TaskPadParameters.cpp index 326010aef9..941b600781 100644 --- a/src/Mod/PartDesign/Gui/TaskPadParameters.cpp +++ b/src/Mod/PartDesign/Gui/TaskPadParameters.cpp @@ -34,6 +34,7 @@ #include "TaskPadParameters.h" #include #include +#include #include #include #include @@ -43,6 +44,7 @@ #include #include #include +#include #include #include #include "TaskSketchBasedParameters.h" @@ -75,7 +77,7 @@ TaskPadParameters::TaskPadParameters(ViewProviderPad *PadView, QWidget *parent, PartDesign::Pad* pcPad = static_cast(vp->getObject()); Base::Quantity l = pcPad->Length.getQuantityValue(); Base::Quantity l2 = pcPad->Length2.getQuantityValue(); - bool alongCustom = pcPad->AlongSketchNormal.getValue(); + bool alongNormal = pcPad->AlongSketchNormal.getValue(); bool useCustom = pcPad->UseCustomVector.getValue(); double xs = pcPad->Direction.getValue().x; double ys = pcPad->Direction.getValue().y; @@ -104,9 +106,14 @@ TaskPadParameters::TaskPadParameters(ViewProviderPad *PadView, QWidget *parent, // Fill data into dialog elements ui->lengthEdit->setValue(l); ui->lengthEdit2->setValue(l2); + // the direction combobox is filled later in updateUI() ui->checkBoxDirection->setChecked(useCustom); onDirectionToggled(useCustom); - ui->checkBoxAlongDirection->setChecked(alongCustom); + ui->checkBoxAlongDirection->setChecked(alongNormal); + // dis/enable length and direction + ui->directionCB->setEnabled(!useCustom); + if (useCustom) + ui->checkBoxAlongDirection->setEnabled(useCustom); ui->XDirectionEdit->setValue(xs); ui->YDirectionEdit->setValue(ys); ui->ZDirectionEdit->setValue(zs); @@ -157,6 +164,8 @@ TaskPadParameters::TaskPadParameters(ViewProviderPad *PadView, QWidget *parent, this, SLOT(onLengthChanged(double))); connect(ui->lengthEdit2, SIGNAL(valueChanged(double)), this, SLOT(onLength2Changed(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)), @@ -182,12 +191,14 @@ TaskPadParameters::TaskPadParameters(ViewProviderPad *PadView, QWidget *parent, connect(ui->checkBoxUpdateView, SIGNAL(toggled(bool)), this, SLOT(onUpdateView(bool))); + this->propReferenceAxis = &(pcPad->ReferenceAxis); + // Due to signals attached after changes took took into effect we should update the UI now. updateUI(index); // if it is a newly created object use the last value of the history // TODO: newObj doesn't supplied normally by any caller (2015-07-24, Fat-Zer) - if(newObj){ + if (newObj) { ui->lengthEdit->setToLastUsedValue(); ui->lengthEdit->selectNumber(); ui->lengthEdit2->setToLastUsedValue(); @@ -199,6 +210,9 @@ TaskPadParameters::TaskPadParameters(ViewProviderPad *PadView, QWidget *parent, void TaskPadParameters::updateUI(int index) { + // update direction combobox + fillDirectionCombo(); + // disable/hide everything unless we are sure we don't need it // exception: the direction parameters are in any case visible bool isLengthEditVisible = false; @@ -280,23 +294,38 @@ void TaskPadParameters::updateUI(int index) void TaskPadParameters::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 pad 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 (msg.Type == Gui::SelectionChanges::ClrSelection) { + 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 && selectionFace) { ui->lineFaceName->blockSignals(true); ui->lineFaceName->clear(); ui->lineFaceName->setProperty("FeatureName", QVariant()); @@ -319,6 +348,119 @@ void TaskPadParameters::onLength2Changed(double len) recomputeFeature(); } +void TaskPadParameters::fillDirectionCombo() +{ + bool oldVal_blockUpdate = blockUpdate; + blockUpdate = true; + + if (axesInList.empty()) { + ui->directionCB->clear(); + this->axesInList.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 "Select reference" + addAxisToCombo(0, std::string(), tr("Select reference...")); + } + + // 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 (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; + } + + // highlight current index + if (indexOfCurrent != -1) + ui->directionCB->setCurrentIndex(indexOfCurrent); + + // disable AlongSketchNormal when the direction is already normal + if (ui->directionCB->currentIndex() == 0) + ui->checkBoxAlongDirection->setEnabled(false); + else + ui->checkBoxAlongDirection->setEnabled(true); + + blockUpdate = oldVal_blockUpdate; +} + +void TaskPadParameters::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 TaskPadParameters::onDirectionCBChanged(int num) +{ + PartDesign::Pad* pcPad = static_cast(vp->getObject()); + + if (axesInList.empty() || !pcPad) + return; + + App::DocumentObject* oldRefAxis = propReferenceAxis->getValue(); + std::vector oldSubRefAxis = propReferenceAxis->getSubValues(); + std::string oldRefName; + if (!oldSubRefAxis.empty()) + oldRefName = oldSubRefAxis.front(); + + 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 (!pcPad->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 { + App::DocumentObject* newRefAxis = propReferenceAxis->getValue(); + const std::vector& newSubRefAxis = propReferenceAxis->getSubValues(); + std::string newRefName; + if (!newSubRefAxis.empty()) + newRefName = newSubRefAxis.front(); + + 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); + // update the direction + updateDirectionEdits(); +} + void TaskPadParameters::onAlongSketchNormalChanged(bool on) { PartDesign::Pad* pcPad = static_cast(vp->getObject()); @@ -334,7 +476,8 @@ void TaskPadParameters::onDirectionToggled(bool on) ui->checkBoxAlongDirection->setEnabled(on); if (on) { ui->groupBoxDirection->show(); - } else { + } + else { ui->checkBoxAlongDirection->setChecked(!on); ui->groupBoxDirection->hide(); } @@ -410,6 +553,8 @@ void TaskPadParameters::onReversedChanged(bool on) // midplane is not sensible when reversed ui->checkBoxMidplane->setEnabled(!on); recomputeFeature(); + // update the direction + updateDirectionEdits(); } void TaskPadParameters::onModeChanged(int index) @@ -437,6 +582,9 @@ void TaskPadParameters::onButtonFace(const bool pressed) { this->blockConnection(!pressed); + // to distinguish that this is the direction selection + selectionFace = true; + // only faces are allowed TaskSketchBasedParameters::onSelectReference(pressed, false, true, false); @@ -489,6 +637,14 @@ bool TaskPadParameters::getCustom(void) const return ui->checkBoxDirection->isChecked(); } +std::string TaskPadParameters::getReferenceAxis(void) const +{ + std::vector sub; + App::DocumentObject* obj; + getReferenceAxis(obj, sub); + return buildLinkSingleSubPythonStr(obj, sub); +} + double TaskPadParameters::getXDirection(void) const { return ui->XDirectionEdit->value(); @@ -550,10 +706,16 @@ void TaskPadParameters::changeEvent(QEvent *e) ui->XDirectionEdit->blockSignals(true); ui->YDirectionEdit->blockSignals(true); ui->ZDirectionEdit->blockSignals(true); + ui->directionCB->blockSignals(true); + int index = ui->directionCB->currentIndex(); + ui->directionCB->addItem(tr("Sketch normal")); + ui->directionCB->addItem(tr("Select reference...")); + ui->directionCB->clear(); + ui->directionCB->setCurrentIndex(index); ui->offsetEdit->blockSignals(true); 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")); @@ -563,9 +725,7 @@ void TaskPadParameters::changeEvent(QEvent *e) ui->changeMode->addItem(tr("Two dimensions")); ui->changeMode->setCurrentIndex(index); -#if QT_VERSION >= 0x040700 ui->lineFaceName->setPlaceholderText(tr("No face selected")); -#endif QVariant featureName = ui->lineFaceName->property("FeatureName"); if (featureName.isValid()) { QStringList parts = ui->lineFaceName->text().split(QChar::fromLatin1(':')); @@ -592,12 +752,33 @@ void TaskPadParameters::changeEvent(QEvent *e) ui->XDirectionEdit->blockSignals(false); ui->YDirectionEdit->blockSignals(false); ui->ZDirectionEdit->blockSignals(false); + ui->directionCB->blockSignals(false); ui->offsetEdit->blockSignals(false); ui->lineFaceName->blockSignals(false); ui->changeMode->blockSignals(false); } } +void TaskPadParameters::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) { + 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 TaskPadParameters::saveHistory(void) { // save the user values to history @@ -615,6 +796,7 @@ void TaskPadParameters::apply() FCMD_OBJ_CMD(obj, "UseCustomVector = " << (getCustom() ? 1 : 0)); FCMD_OBJ_CMD(obj, "Direction = (" << getXDirection() << ", " << getYDirection() << ", " << getZDirection() << ")"); + FCMD_OBJ_CMD(obj, "ReferenceAxis = " << getReferenceAxis()); FCMD_OBJ_CMD(obj, "AlongSketchNormal = " << (getAlongSketchNormal() ? 1 : 0)); FCMD_OBJ_CMD(obj,"Type = " << getMode()); QString facename = getFaceName(); diff --git a/src/Mod/PartDesign/Gui/TaskPadParameters.h b/src/Mod/PartDesign/Gui/TaskPadParameters.h index f5e9846efa..1a30d0d932 100644 --- a/src/Mod/PartDesign/Gui/TaskPadParameters.h +++ b/src/Mod/PartDesign/Gui/TaskPadParameters.h @@ -55,9 +55,13 @@ 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 onDirectionCBChanged(int); void onAlongSketchNormalChanged(bool); void onDirectionToggled(bool); void onXDirectionEditChanged(double); @@ -72,12 +76,15 @@ 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; 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; @@ -93,6 +100,8 @@ private: private: QWidget* proxy; std::unique_ptr ui; + bool selectionFace; + std::vector> axesInList; }; /// simulation dialog for the TaskView diff --git a/src/Mod/PartDesign/Gui/TaskPadParameters.ui b/src/Mod/PartDesign/Gui/TaskPadParameters.ui index b0a680b51c..dbc9c341a6 100644 --- a/src/Mod/PartDesign/Gui/TaskPadParameters.ui +++ b/src/Mod/PartDesign/Gui/TaskPadParameters.ui @@ -6,14 +6,14 @@ 0 0 - 280 - 497 + 300 + 436 Form - + @@ -52,116 +52,157 @@ - - - Use custom direction + + + Direction - - - - - - true - - - Use custom vector for pad direction otherwise -the sketch plane's normal vector will be used - - - false - - + - - - x - - - - - - - x-component of direction vector - - - false - - - -100.000000000000000 - - - 100.000000000000000 - - - 0.100000000000000 - - - - - + + + + + Direction/edge: + + + + + + + Either along the sketch normal +or select an edge as reference + + + + Sketch normal + + + + + Select reference... + + + + + - + - y - - - - - - - y-component of direction vector - - - false - - - -100.000000000000000 - - - 100.000000000000000 - - - 0.100000000000000 - - - + Use custom direction - - - z + + + true - - - - - z-component of direction vector + Use custom vector for pad direction, otherwise +the sketch plane's normal vector will be used - + false - - -100.000000000000000 - - - 100.000000000000000 - - - 0.100000000000000 - - - 1.000000000000000 - - - + + 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 @@ -173,9 +214,6 @@ measured along the specified direction Length along sketch normal - - true - @@ -244,15 +282,15 @@ measured along the specified direction - - + + Face - +