diff --git a/src/Mod/PartDesign/App/FeatureHole.cpp b/src/Mod/PartDesign/App/FeatureHole.cpp index 5a4b8cee3b..baed9aa286 100644 --- a/src/Mod/PartDesign/App/FeatureHole.cpp +++ b/src/Mod/PartDesign/App/FeatureHole.cpp @@ -759,6 +759,9 @@ Hole::Hole() ADD_PROPERTY_TYPE(Diameter, (6.0), "Hole", App::Prop_None, "Diameter"); Diameter.setConstraints(&diameterRange); + ADD_PROPERTY_TYPE(ThreadDiameter, (0.0), "Hole", App::Prop_None, "Thread major diameter"); + ThreadDiameter.setReadOnly(true); + ADD_PROPERTY_TYPE(ThreadDirection, (0L), "Hole", App::Prop_None, "Thread direction"); ThreadDirection.setEnums(ThreadDirectionEnums); ThreadDirection.setReadOnly(true); @@ -1346,6 +1349,12 @@ std::optional Hole::determineDiameter() const void Hole::updateDiameterParam() { + int threadType = ThreadType.getValue(); + int threadSize = ThreadSize.getValue(); + if (threadType > 0 && threadSize > 0) + ThreadDiameter.setValue( + threadDescription[threadType][threadSize].diameter + ); if (auto opt = determineDiameter()) Diameter.setValue(opt.value()); } @@ -1356,6 +1365,32 @@ double Hole::getThreadProfileAngle() return 90 - 1.79; } +void Hole::findClosestDesignation() +{ + // Intended for thread type changes + // finds the closest diameter of the new thread type + int threadType = ThreadType.getValue(); + int closestSize = 0; + double diameter = ThreadDiameter.getValue(); + if (diameter == 0) + diameter = Diameter.getValue(); + double closestDifference = std::numeric_limits::infinity(); + double difference; + + for (size_t i = 0; i < threadDescription[threadType].size(); i++) { + difference = threadDescription[threadType][i].diameter - diameter; + if (difference == 0) { + closestSize = i; + break; + } + if (std::abs(difference) < closestDifference) { + closestSize = i; + closestDifference = std::abs(difference); + } + } + ThreadSize.setValue(closestSize); +} + void Hole::onChanged(const App::Property* prop) { if (prop == &ThreadType) { @@ -1363,7 +1398,10 @@ void Hole::onChanged(const App::Property* prop) if (ThreadType.isValid()) { type = ThreadType.getValueAsString(); ThreadSize.setEnums(getThreadDesignations(ThreadType.getValue())); + if (type != "None") + findClosestDesignation(); } + if (HoleCutType.isValid()) holeCutTypeStr = HoleCutType.getValueAsString(); @@ -1639,6 +1677,11 @@ void Hole::onChanged(const App::Property* prop) // a changed diameter means we also need to check the hole cut // because the hole cut diameter must not be <= than the diameter updateHoleCutParams(); + if (ThreadType.getValue() == 0) { + // Profile is None but this is needed to find the closest + // designation if the user switch to threaded + ThreadDiameter.setValue(Diameter.getValue()); + } } else if (prop == &HoleCutType) { ProfileBased::onChanged(&HoleCutDiameter); diff --git a/src/Mod/PartDesign/App/FeatureHole.h b/src/Mod/PartDesign/App/FeatureHole.h index 6b50107e03..f817e164cb 100644 --- a/src/Mod/PartDesign/App/FeatureHole.h +++ b/src/Mod/PartDesign/App/FeatureHole.h @@ -56,6 +56,7 @@ public: App::PropertyEnumeration ThreadClass; App::PropertyEnumeration ThreadFit; App::PropertyLength Diameter; + App::PropertyLength ThreadDiameter; App::PropertyEnumeration ThreadDirection; App::PropertyEnumeration HoleCutType; App::PropertyBool HoleCutCustomValues; @@ -231,6 +232,7 @@ private: double getThreadRunout(int mode = 1) const; double getThreadPitch() const; double getThreadProfileAngle(); + void findClosestDesignation(); void rotateToNormal(const gp_Dir& helixAxis, const gp_Dir& normalAxis, TopoDS_Shape& helixShape) const; gp_Vec computePerpendicular(const gp_Vec&) const; TopoDS_Shape makeThread(const gp_Vec&, const gp_Vec&, double); diff --git a/src/Mod/PartDesign/Gui/TaskHoleParameters.cpp b/src/Mod/PartDesign/Gui/TaskHoleParameters.cpp index c68917ac7d..0865583a9d 100644 --- a/src/Mod/PartDesign/Gui/TaskHoleParameters.cpp +++ b/src/Mod/PartDesign/Gui/TaskHoleParameters.cpp @@ -632,23 +632,7 @@ void TaskHoleParameters::threadTypeChanged(int index) ui->labelSize->setHidden(isNone); ui->ClearanceWidget->setHidden(isNone || isThreaded); - // size and clearance if (TypeClass == QByteArray("ISO")) { - // the size for ISO type has either the form "M3x0.35" or just "M3" - // so we need to check if the size contains a 'x'. If yes, check if the string - // up to the 'x' is exists in the new list - if (ThreadSizeString.indexOf(QString::fromLatin1("x")) > -1) { - // we have an ISO fine size - // cut of the part behind the 'x' - ThreadSizeString = - ThreadSizeString.left(ThreadSizeString.indexOf(QString::fromLatin1("x"))); - } - // search if the string exists in the combobox - int threadSizeIndex = ui->ThreadSize->findText(ThreadSizeString, Qt::MatchContains); - if (threadSizeIndex > -1) { - // we can set it - ui->ThreadSize->setCurrentIndex(threadSizeIndex); - } // the names of the clearance types are different in ISO and UTS ui->ThreadFit->setItemText( 0, @@ -661,11 +645,6 @@ void TaskHoleParameters::threadTypeChanged(int index) QCoreApplication::translate("TaskHoleParameters", "Wide", nullptr)); } else if (TypeClass == QByteArray("UTS")) { - // for all UTS types the size entries are the same - int threadSizeIndex = ui->ThreadSize->findText(ThreadSizeString, Qt::MatchContains); - if (threadSizeIndex > -1) { - ui->ThreadSize->setCurrentIndex(threadSizeIndex); - } // the names of the clearance types are different in ISO and UTS ui->ThreadFit->setItemText( 0,