From 1c58c3b677ce82d193583e57f0c94a7eee42fbb1 Mon Sep 17 00:00:00 2001 From: donovaly Date: Mon, 1 Feb 2021 06:11:40 +0100 Subject: [PATCH] [PD] hole fix custom cut handling This PR is based on PR #4344 and a spin-off of PR #4337. It fixes: We have normed screw head cuts. These values can be overridden but we must store the info about the overriding. Why? - because when you have e.g. made a custom change to a normed countersink and then change to another countersink norm, you would either not get the values defined in the norm or you get these values but loose e.g. your depth settings --- src/Mod/PartDesign/App/FeatureHole.cpp | 125 +++++++++++++----- src/Mod/PartDesign/App/FeatureHole.h | 1 + src/Mod/PartDesign/Gui/TaskHoleParameters.cpp | 104 +++++++++++---- src/Mod/PartDesign/Gui/TaskHoleParameters.h | 2 + src/Mod/PartDesign/Gui/TaskHoleParameters.ui | 53 +++++--- 5 files changed, 211 insertions(+), 74 deletions(-) diff --git a/src/Mod/PartDesign/App/FeatureHole.cpp b/src/Mod/PartDesign/App/FeatureHole.cpp index 884ce8a5ca..eb4914bec3 100644 --- a/src/Mod/PartDesign/App/FeatureHole.cpp +++ b/src/Mod/PartDesign/App/FeatureHole.cpp @@ -612,6 +612,8 @@ Hole::Hole() ADD_PROPERTY_TYPE(HoleCutType, (0L), "Hole", App::Prop_None, "Head cut type"); HoleCutType.setEnums(HoleCutType_None_Enums); + ADD_PROPERTY_TYPE(HoleCutCustomValues, (false), "Hole", App::Prop_None, "Custom cut values"); + ADD_PROPERTY_TYPE(HoleCutDiameter, (0.0), "Hole", App::Prop_None, "Head cut diameter"); ADD_PROPERTY_TYPE(HoleCutDepth, (0.0), "Hole", App::Prop_None, "Head cut deth"); @@ -684,6 +686,8 @@ void Hole::updateHoleCutParams() } if (HoleCutDepth.getValue() == 0.0) HoleCutDepth.setValue(dimen.depth); + HoleCutDiameter.setReadOnly(false); + HoleCutDepth.setReadOnly(false); HoleCutCountersinkAngle.setReadOnly(true); } else if (holeCutType == "Countersink") { @@ -702,6 +706,8 @@ void Hole::updateHoleCutParams() if (HoleCutCountersinkAngle.getValue() == 0.0) { HoleCutCountersinkAngle.setValue(counter.angle); } + HoleCutDiameter.setReadOnly(false); + HoleCutDepth.setReadOnly(false); HoleCutCountersinkAngle.setReadOnly(false); } @@ -718,9 +724,31 @@ void Hole::updateHoleCutParams() // valid values for visual feedback HoleCutDiameter.setValue(Diameter.getValue() + 0.1); HoleCutDepth.setValue(0.1); + // we force custom values since there are no normed ones + HoleCutCustomValues.setReadOnly(true); + // important to set only if not already true, to avoid loop call of updateHoleCutParams() + if (!HoleCutCustomValues.getValue()) { + HoleCutCustomValues.setValue(true); + HoleCutDiameter.setReadOnly(false); + HoleCutDepth.setReadOnly(false); + } } else { - HoleCutDiameter.setValue(dimen.diameter); - HoleCutDepth.setValue(dimen.depth); + // set normed values if not overwritten or if previously there + // were no normed values available and thus HoleCutCustomValues is checked and read-only + if (!HoleCutCustomValues.getValue() + || (HoleCutCustomValues.getValue() && HoleCutCustomValues.isReadOnly())) { + HoleCutDiameter.setValue(dimen.diameter); + HoleCutDepth.setValue(dimen.depth); + HoleCutDiameter.setReadOnly(true); + HoleCutDepth.setReadOnly(true); + if (HoleCutCustomValues.getValue() && HoleCutCustomValues.isReadOnly()) + HoleCutCustomValues.setValue(false); + } + else { + HoleCutDiameter.setReadOnly(false); + HoleCutDepth.setReadOnly(false); + } + HoleCutCustomValues.setReadOnly(false); } } else if (counter.cut_type == CutDimensionSet::Countersink) { const CounterSinkDimension &dimen = counter.get_sink(threadSize); @@ -728,12 +756,37 @@ void Hole::updateHoleCutParams() // valid values for visual feedback HoleCutDiameter.setValue(Diameter.getValue() + 0.1); // there might be an angle of zero (if no norm exists for the size) - if (HoleCutCountersinkAngle.getValue() == 0.0) { + if (HoleCutCountersinkAngle.getValue() == 0.0) { HoleCutCountersinkAngle.setValue(counter.angle); } + // we force custom values since there are no normed ones + HoleCutCustomValues.setReadOnly(true); + // important to set only if not already true, to avoid loop call of updateHoleCutParams() + if (!HoleCutCustomValues.getValue()) { + HoleCutCustomValues.setValue(true); + HoleCutDiameter.setReadOnly(false); + HoleCutDepth.setReadOnly(false); + HoleCutCountersinkAngle.setReadOnly(false); + } } else { - HoleCutDiameter.setValue(dimen.diameter); - HoleCutCountersinkAngle.setValue(counter.angle); + // set normed values if not overwritten or if previously there + // were no normed values available and thus HoleCutCustomValues is checked and read-only + if (!HoleCutCustomValues.getValue() + || (HoleCutCustomValues.getValue() && HoleCutCustomValues.isReadOnly())) { + HoleCutDiameter.setValue(dimen.diameter); + HoleCutDiameter.setReadOnly(true); + HoleCutDepth.setReadOnly(true); + HoleCutCountersinkAngle.setValue(counter.angle); + HoleCutCountersinkAngle.setReadOnly(true); + if (HoleCutCustomValues.getValue() && HoleCutCustomValues.isReadOnly()) + HoleCutCustomValues.setValue(false); + } + else { + HoleCutDiameter.setReadOnly(false); + HoleCutDepth.setReadOnly(false); + HoleCutCountersinkAngle.setReadOnly(false); + } + HoleCutCustomValues.setReadOnly(false); } } } @@ -745,6 +798,8 @@ void Hole::updateHoleCutParams() else if (holeCutType == "Cheesehead (deprecated)") { HoleCutDiameter.setValue(diameterVal * 1.6); HoleCutDepth.setValue(diameterVal * 0.6); + HoleCutDiameter.setReadOnly(false); + HoleCutDepth.setReadOnly(false); } else if (holeCutType == "Countersink socket screw (deprecated)") { HoleCutDiameter.setValue(diameterVal * 2.0); @@ -752,10 +807,15 @@ void Hole::updateHoleCutParams() if (HoleCutCountersinkAngle.getValue() == 0.0) { HoleCutCountersinkAngle.setValue(90.0); } + HoleCutDiameter.setReadOnly(false); + HoleCutDepth.setReadOnly(false); + HoleCutCountersinkAngle.setReadOnly(false); } else if (holeCutType == "Cap screw (deprecated)") { HoleCutDiameter.setValue(diameterVal * 1.5); HoleCutDepth.setValue(diameterVal * 1.25); + HoleCutDiameter.setReadOnly(false); + HoleCutDepth.setReadOnly(false); } } else { // we have an UTS profile or none @@ -771,6 +831,8 @@ void Hole::updateHoleCutParams() } if (HoleCutDepth.getValue() == 0.0) HoleCutDepth.setValue(diameterVal * 0.9); + HoleCutDiameter.setReadOnly(false); + HoleCutDepth.setReadOnly(false); } else if (holeCutType == "Countersink") { if (HoleCutDiameter.getValue() == 0.0 || HoleCutDiameter.getValue() <= diameterVal) { @@ -787,6 +849,9 @@ void Hole::updateHoleCutParams() else HoleCutCountersinkAngle.setValue(90.0); } + HoleCutDiameter.setReadOnly(false); + HoleCutDepth.setReadOnly(false); + HoleCutCountersinkAngle.setReadOnly(false); } } } @@ -1062,24 +1127,37 @@ void Hole::onChanged(const App::Property *prop) } if (holeCutType == "None") { + HoleCutCustomValues.setReadOnly(true); HoleCutDiameter.setReadOnly(true); HoleCutDepth.setReadOnly(true); HoleCutCountersinkAngle.setReadOnly(true); } else if (holeCutType == "Counterbore") { + HoleCutCustomValues.setReadOnly(true); HoleCutDiameter.setReadOnly(false); HoleCutDepth.setReadOnly(false); HoleCutCountersinkAngle.setReadOnly(true); } else if (holeCutType == "Countersink") { + HoleCutCustomValues.setReadOnly(true); HoleCutDiameter.setReadOnly(false); HoleCutDepth.setReadOnly(false); HoleCutCountersinkAngle.setReadOnly(false); } else { // screw definition - HoleCutDiameter.setReadOnly(false); - HoleCutDepth.setReadOnly(false); - HoleCutCountersinkAngle.setReadOnly(false); + HoleCutCustomValues.setReadOnly(false); + if (HoleCutCustomValues.getValue()) { + HoleCutDiameter.setReadOnly(false); + HoleCutDepth.setReadOnly(false); + // we must not set HoleCutCountersinkAngle here because the info if this can + // be enabled is first available in updateHoleCutParams and thus handled there + updateHoleCutParams(); + } + else { + HoleCutDiameter.setReadOnly(true); + HoleCutDepth.setReadOnly(true); + HoleCutCountersinkAngle.setReadOnly(true); + } } // Signal changes to these @@ -1161,32 +1239,17 @@ void Hole::onChanged(const App::Property *prop) updateHoleCutParams(); } else if (prop == &HoleCutType) { - std::string holeCutType; - if (HoleCutType.isValid()) - holeCutType = HoleCutType.getValueAsString(); - if (holeCutType == "None") { - HoleCutDiameter.setReadOnly(true); - HoleCutDepth.setReadOnly(true); - HoleCutCountersinkAngle.setReadOnly(true); - } - else if (holeCutType == "Counterbore") { - HoleCutDiameter.setReadOnly(false); - HoleCutDepth.setReadOnly(false); - HoleCutCountersinkAngle.setReadOnly(true); - } - else if (holeCutType == "Countersink") { - HoleCutDiameter.setReadOnly(false); - HoleCutDepth.setReadOnly(false); - HoleCutCountersinkAngle.setReadOnly(false); - } - else { // screw definition - HoleCutDiameter.setReadOnly(false); - HoleCutDepth.setReadOnly(false); - HoleCutCountersinkAngle.setReadOnly(false); - } ProfileBased::onChanged(&HoleCutDiameter); ProfileBased::onChanged(&HoleCutDepth); ProfileBased::onChanged(&HoleCutCountersinkAngle); + + // the read-only states are set in updateHoleCutParams() + updateHoleCutParams(); + } + else if (prop == &HoleCutCustomValues) { + // when going back to standardized values, we must recalculate + // also to find out if HoleCutCountersinkAngle can be ReadOnly + // both an also the read-only states is done in updateHoleCutParams() updateHoleCutParams(); } else if (prop == &DepthType) { diff --git a/src/Mod/PartDesign/App/FeatureHole.h b/src/Mod/PartDesign/App/FeatureHole.h index 9ec22ccd3f..c28ef80465 100644 --- a/src/Mod/PartDesign/App/FeatureHole.h +++ b/src/Mod/PartDesign/App/FeatureHole.h @@ -57,6 +57,7 @@ public: App::PropertyLength Diameter; App::PropertyEnumeration ThreadDirection; App::PropertyEnumeration HoleCutType; + App::PropertyBool HoleCutCustomValues; App::PropertyLength HoleCutDiameter; App::PropertyLength HoleCutDepth; App::PropertyAngle HoleCutCountersinkAngle; diff --git a/src/Mod/PartDesign/Gui/TaskHoleParameters.cpp b/src/Mod/PartDesign/Gui/TaskHoleParameters.cpp index fd35108360..c1648446f7 100644 --- a/src/Mod/PartDesign/Gui/TaskHoleParameters.cpp +++ b/src/Mod/PartDesign/Gui/TaskHoleParameters.cpp @@ -115,34 +115,16 @@ TaskHoleParameters::TaskHoleParameters(ViewProviderHole *HoleView, QWidget *pare ++cursor; } ui->HoleCutType->setCurrentIndex(pcHole->HoleCutType.getValue()); + ui->HoleCutCustomValues->setChecked(pcHole->HoleCutCustomValues.getValue()); + ui->HoleCutCustomValues->setDisabled(pcHole->HoleCutCustomValues.isReadOnly()); + // HoleCutDiameter must not be smaller or equal than the Diameter + ui->HoleCutDiameter->setMinimum(pcHole->Diameter.getValue() + 0.1); ui->HoleCutDiameter->setValue(pcHole->HoleCutDiameter.getValue()); + ui->HoleCutDiameter->setDisabled(pcHole->HoleCutDiameter.isReadOnly()); ui->HoleCutDepth->setValue(pcHole->HoleCutDepth.getValue()); + ui->HoleCutDepth->setDisabled(pcHole->HoleCutDepth.isReadOnly()); ui->HoleCutCountersinkAngle->setValue(pcHole->HoleCutCountersinkAngle.getValue()); - - std::string holeCutType; - if (pcHole->HoleCutType.isValid()) - holeCutType = pcHole->HoleCutType.getValueAsString(); - - if (holeCutType == "None") { - ui->HoleCutDiameter->setEnabled(false); - ui->HoleCutDepth->setEnabled(false); - ui->HoleCutCountersinkAngle->setEnabled(false); - } - else if (holeCutType == "Counterbore") { - ui->HoleCutDiameter->setEnabled(true); - ui->HoleCutDepth->setEnabled(true); - ui->HoleCutCountersinkAngle->setEnabled(false); - } - else if (holeCutType == "Countersink") { - ui->HoleCutDiameter->setEnabled(true); - ui->HoleCutDepth->setEnabled(true); - ui->HoleCutCountersinkAngle->setEnabled(true); - } - else { // screw definition - ui->HoleCutDiameter->setEnabled(true); - ui->HoleCutDepth->setEnabled(true); - ui->HoleCutCountersinkAngle->setEnabled(true); - } + ui->HoleCutCountersinkAngle->setDisabled(pcHole->HoleCutCountersinkAngle.isReadOnly()); ui->DepthType->setCurrentIndex(pcHole->DepthType.getValue()); ui->Depth->setValue(pcHole->Depth.getValue()); @@ -189,6 +171,7 @@ TaskHoleParameters::TaskHoleParameters(ViewProviderHole *HoleView, QWidget *pare connect(ui->directionRightHand, SIGNAL(clicked(bool)), this, SLOT(threadDirectionChanged())); connect(ui->directionLeftHand, SIGNAL(clicked(bool)), this, SLOT(threadDirectionChanged())); connect(ui->HoleCutType, SIGNAL(currentIndexChanged(int)), this, SLOT(holeCutTypeChanged(int))); + connect(ui->HoleCutCustomValues, SIGNAL(clicked(bool)), this, SLOT(holeCutCustomValuesChanged())); connect(ui->HoleCutDiameter, SIGNAL(valueChanged(double)), this, SLOT(holeCutDiameterChanged(double))); connect(ui->HoleCutDepth, SIGNAL(valueChanged(double)), this, SLOT(holeCutDepthChanged(double))); connect(ui->HoleCutCountersinkAngle, SIGNAL(valueChanged(double)), this, SLOT(holeCutCountersinkAngleChanged(double))); @@ -282,8 +265,65 @@ void TaskHoleParameters::holeCutTypeChanged(int index) // therefore reset it, it will be reset to sensible values by setting the new HoleCutType pcHole->HoleCutDepth.setValue(0.0); + // when holeCutType was changed, reset HoleCutCustomValues to false because it should + // be a purpose decision to overwrite the normed values + // we will handle the case that there is no normed value later in this routine + ui->HoleCutCustomValues->setChecked(false); + pcHole->HoleCutCustomValues.setValue(false); + pcHole->HoleCutType.setValue(index); + + // recompute to get the info about the HoleCutType properties recomputeFeature(); + + // apply the result to the widgets + ui->HoleCutCustomValues->setDisabled(pcHole->HoleCutCustomValues.isReadOnly()); + ui->HoleCutCustomValues->setChecked(pcHole->HoleCutCustomValues.getValue()); + + // HoleCutCustomValues is only enabled for screw definitions + // we must do this after recomputeFeature() because this gives us the info if + // the type is a countersink and thus if HoleCutCountersinkAngle can be enabled + std::string HoleCutTypeString = pcHole->HoleCutType.getValueAsString(); + if (HoleCutTypeString == "None" || HoleCutTypeString == "Counterbore" + || HoleCutTypeString == "Countersink") { + ui->HoleCutCustomValues->setEnabled(false); + } + else { // screw definition + // we can have the case that we have no normed values + // in this case HoleCutCustomValues is read-only AND true + if (ui->HoleCutCustomValues->isChecked()) { + ui->HoleCutDiameter->setEnabled(true); + ui->HoleCutDepth->setEnabled(true); + if (!pcHole->HoleCutCountersinkAngle.isReadOnly()) + ui->HoleCutCountersinkAngle->setEnabled(true); + } + else { + ui->HoleCutDiameter->setEnabled(false); + ui->HoleCutDepth->setEnabled(false); + ui->HoleCutCountersinkAngle->setEnabled(false); + } + } +} + +void TaskHoleParameters::holeCutCustomValuesChanged() +{ + PartDesign::Hole* pcHole = static_cast(vp->getObject()); + + pcHole->HoleCutCustomValues.setValue(ui->HoleCutCustomValues->isChecked()); + + if (ui->HoleCutCustomValues->isChecked()) { + ui->HoleCutDiameter->setEnabled(true); + ui->HoleCutDepth->setEnabled(true); + if (!pcHole->HoleCutCountersinkAngle.isReadOnly()) + ui->HoleCutCountersinkAngle->setEnabled(true); + } + else { + ui->HoleCutDiameter->setEnabled(false); + ui->HoleCutDepth->setEnabled(false); + ui->HoleCutCountersinkAngle->setEnabled(false); + } + + recomputeFeature(); } void TaskHoleParameters::holeCutDiameterChanged(double value) @@ -482,6 +522,9 @@ void TaskHoleParameters::threadTypeChanged(int index) if (holeCutIndex > -1) ui->HoleCutType->setCurrentIndex(holeCutIndex); + // we must set the read-only state according to the new HoleCutType + holeCutTypeChanged(ui->HoleCutType->currentIndex()); + recomputeFeature(); } @@ -512,6 +555,10 @@ void TaskHoleParameters::threadDiameterChanged(double value) PartDesign::Hole* pcHole = static_cast(vp->getObject()); pcHole->Diameter.setValue(value); + + // HoleCutDiameter must not be smaller or equal than the Diameter + ui->HoleCutDiameter->setMinimum(value + 0.1); + recomputeFeature(); } @@ -824,6 +871,11 @@ long TaskHoleParameters::getHoleCutType() const return ui->HoleCutType->currentIndex(); } +bool TaskHoleParameters::getHoleCutCustomValues() const +{ + return ui->HoleCutCustomValues->isChecked(); +} + Base::Quantity TaskHoleParameters::getHoleCutDiameter() const { return ui->HoleCutDiameter->value(); @@ -910,6 +962,8 @@ void TaskHoleParameters::apply() FCMD_OBJ_CMD(obj,"ThreadDirection = " << getThreadDirection()); if (!pcHole->HoleCutType.isReadOnly()) FCMD_OBJ_CMD(obj,"HoleCutType = " << getHoleCutType()); + if (!pcHole->HoleCutCustomValues.isReadOnly()) + FCMD_OBJ_CMD(obj, "HoleCutCustomValues = " << (getHoleCutCustomValues() ? 1 : 0)); if (!pcHole->DepthType.isReadOnly()) FCMD_OBJ_CMD(obj,"DepthType = " << getDepthType()); if (!pcHole->DrillPoint.isReadOnly()) diff --git a/src/Mod/PartDesign/Gui/TaskHoleParameters.h b/src/Mod/PartDesign/Gui/TaskHoleParameters.h index 894c4314a6..2ec266cac8 100644 --- a/src/Mod/PartDesign/Gui/TaskHoleParameters.h +++ b/src/Mod/PartDesign/Gui/TaskHoleParameters.h @@ -69,6 +69,7 @@ public: Base::Quantity getDiameter() const; long getThreadDirection() const; long getHoleCutType() const; + bool getHoleCutCustomValues() const; Base::Quantity getHoleCutDiameter() const; Base::Quantity getHoleCutDepth() const; Base::Quantity getHoleCutCountersinkAngle() const; @@ -94,6 +95,7 @@ private Q_SLOTS: void threadDiameterChanged(double value); void threadDirectionChanged(); void holeCutTypeChanged(int index); + void holeCutCustomValuesChanged(); void holeCutDiameterChanged(double value); void holeCutDepthChanged(double value); void holeCutCountersinkAngleChanged(double value); diff --git a/src/Mod/PartDesign/Gui/TaskHoleParameters.ui b/src/Mod/PartDesign/Gui/TaskHoleParameters.ui index 27a6b7ac60..acb1d821e9 100644 --- a/src/Mod/PartDesign/Gui/TaskHoleParameters.ui +++ b/src/Mod/PartDesign/Gui/TaskHoleParameters.ui @@ -6,8 +6,8 @@ 0 0 - 335 - 463 + 342 + 486 @@ -362,6 +362,22 @@ Only available for holes without thread + + + + 0 + 0 + + + + Check to override the values predefined by the 'Type' + + + Custom values + + + + @@ -374,7 +390,7 @@ Only available for holes without thread - + @@ -402,7 +418,7 @@ Only available for holes without thread - + @@ -415,7 +431,7 @@ Only available for holes without thread - + @@ -440,7 +456,7 @@ Only available for holes without thread - + @@ -453,7 +469,7 @@ Only available for holes without thread - + @@ -475,7 +491,7 @@ Only available for holes without thread - + @@ -491,7 +507,7 @@ Only available for holes without thread - + @@ -507,7 +523,7 @@ Only available for holes without thread - + @@ -523,7 +539,7 @@ Only available for holes without thread - + @@ -539,7 +555,7 @@ Only available for holes without thread - + @@ -555,7 +571,7 @@ Only available for holes without thread - + @@ -572,14 +588,14 @@ account for the depth of blind holes - + <b>Misc</b> - + @@ -592,7 +608,7 @@ account for the depth of blind holes - + @@ -614,7 +630,7 @@ over 90: larger hole radius at the bottom - + @@ -630,7 +646,7 @@ over 90: larger hole radius at the bottom - + @@ -656,6 +672,7 @@ over 90: larger hole radius at the bottom DepthType Depth HoleCutType + HoleCutCustomValues HoleCutDiameter HoleCutDepth HoleCutCountersinkAngle