[PD] fix UTS clearance holes

This PR is based on PR #4343 and a spin-off of PR #4337. It fixes:

- the bug that we did not use the normed clearance hole diameters for UTS holes
- missing recompute when changing existing hole from Metric to UTS type
This commit is contained in:
donovaly
2021-01-31 22:53:29 +01:00
committed by wmayer
parent 19605200a1
commit c5fe2589d5
3 changed files with 188 additions and 54 deletions

View File

@@ -71,7 +71,8 @@ namespace PartDesign {
const char* Hole::DepthTypeEnums[] = { "Dimension", "ThroughAll", /*, "UpToFirst", */ NULL };
const char* Hole::ThreadTypeEnums[] = { "None", "ISOMetricProfile", "ISOMetricFineProfile", "UNC", "UNF", "UNEF", NULL};
const char* Hole::ThreadFitEnums[] = { "Standard", "Close", "Wide", NULL};
const char* Hole::ClearanceMetricEnums[] = { "Standard", "Close", "Wide", NULL};
const char* Hole::ClearanceUTSEnums[] = { "Normal", "Close", "Loose", NULL };
const char* Hole::DrillPointEnums[] = { "Flat", "Angled", NULL};
/* "None" profile */
@@ -449,6 +450,39 @@ const double Hole::metricHoleDiameters[36][4] =
{ 68.0, 70.0, 77.0, 78.0}
};
const Hole::UTSClearanceDefinition Hole::UTSHoleDiameters[22] =
{
/* UTS clearance hole diameters according to ASME B18.2.8 */
// for information: the norm defines a drill bit number (that is in turn standardized in another ASME norm).
// as result the norm defines a minimal clearance which is the diameter of that drill bit.
// we use here this minimal clearance as the theoretical exact hole diameter as this is also done in the ISO norm.
// {screw class, close, normal, loose}
{ "#0", 1.7, 1.9, 2.4 },
{ "#1", 2.1, 2.3, 2.6 },
{ "#2", 2.4, 2.6, 2.9 },
{ "#3", 2.7, 2.9, 3.3 },
{ "#4", 3.0, 3.3, 3.7 },
{ "#5", 3.6, 4.0, 4.4 },
{ "#6", 3.9, 4.3, 4.7 },
{ "#8", 4.6, 5.0, 5.4 },
{ "#10", 5.2, 5.6, 6.0 },
// "#12" not defined
{ "1/4", 6.8, 7.1, 7.5 },
{ "5/16", 8.3, 8.7, 9.1 },
{ "3/8", 9.9, 10.3, 10.7 },
{ "7/16", 11.5, 11.9, 12.3 },
{ "1/2", 13.5, 14.3, 15.5 },
// "9/16" not defined
{ "5/8", 16.7, 17.5, 18.6 },
{ "3/4", 19.8, 20.6, 23.0 },
{ "7/8", 23.0, 23.8, 26.2 },
{ "1", 26.2, 27.8, 29.4 },
{ "1 1/8", 29.4, 31.0, 33.3 },
{ "1 1/4", 32.5, 34.1, 36.5 },
{ "1 3/8", 36.5, 38.1, 40.9 },
{ "1 1/2", 39.7, 41.3, 44.0 }
};
/* ISO coarse metric enums */
std::vector<std::string> Hole::HoleCutType_ISOmetric_Enums = { "None", "Counterbore", "Countersink", "Cheesehead (deprecated)", "Countersink socket screw (deprecated)", "Cap screw (deprecated)" };
const char* Hole::ThreadSize_ISOmetric_Enums[] = { "M1", "M1.1", "M1.2", "M1.4", "M1.6",
@@ -566,8 +600,8 @@ Hole::Hole()
ADD_PROPERTY_TYPE(ThreadClass, (0L), "Hole", App::Prop_None, "Thread class");
ThreadClass.setEnums(ThreadClass_None_Enums);
ADD_PROPERTY_TYPE(ThreadFit, (0L), "Hole", App::Prop_None, "Thread fit");
ThreadFit.setEnums(ThreadFitEnums);
ADD_PROPERTY_TYPE(ThreadFit, (0L), "Hole", App::Prop_None, "Clearance hole fit");
ThreadFit.setEnums(ClearanceMetricEnums);
ADD_PROPERTY_TYPE(Diameter, (6.0), "Hole", App::Prop_None, "Diameter");
@@ -812,52 +846,130 @@ void Hole::updateDiameterParam()
}
else { // we have a clearance hole
bool found = false;
int MatrixRowSize = sizeof(metricHoleDiameters) / sizeof(metricHoleDiameters[0]);
switch ( ThreadFit.getValue() ) {
case 0: /* standard fit */
// read diameter out of matrix
for (int i = 0; i < MatrixRowSize; i++) {
if (metricHoleDiameters[i][0] == diameter) {
diameter = metricHoleDiameters[i][2];
found = true;
break;
std::string threadType = ThreadType.getValueAsString();
// UTS and metric have a different clearance hole set
if (threadType == "ISOMetricProfile" || threadType == "ISOMetricFineProfile") {
int MatrixRowSizeMetric = sizeof(metricHoleDiameters) / sizeof(metricHoleDiameters[0]);
switch (ThreadFit.getValue()) {
case 0: /* standard fit */
// read diameter out of matrix
for (int i = 0; i < MatrixRowSizeMetric; i++) {
if (metricHoleDiameters[i][0] == diameter) {
diameter = metricHoleDiameters[i][2];
found = true;
break;
}
}
}
// if nothing was found (e.g. if not metric), we must calculate
if (!found) {
diameter = (5 * ((int)((diameter * 110) / 5))) / 100.0;
}
break;
case 1: /* close fit */
// read diameter out of matrix
for (int i = 0; i < MatrixRowSize; i++) {
if (metricHoleDiameters[i][0] == diameter) {
diameter = metricHoleDiameters[i][1];
found = true;
break;
// if nothing is defined (e.g. for M2.2, M9 and M11), we must calculate
// we use the factors defined for M5 in the metricHoleDiameters list
if (!found) {
diameter = diameter * 1.10;
}
}
// if nothing was found, we must calculate
if (!found) {
diameter = (5 * ((int)((diameter * 105) / 5))) / 100.0;
}
break;
case 2: /* wide fit */
// read diameter out of matrix
for (int i = 0; i < MatrixRowSize; i++) {
if (metricHoleDiameters[i][0] == diameter) {
diameter = metricHoleDiameters[i][3];
found = true;
break;
break;
case 1: /* close fit */
// read diameter out of matrix
for (int i = 0; i < MatrixRowSizeMetric; i++) {
if (metricHoleDiameters[i][0] == diameter) {
diameter = metricHoleDiameters[i][1];
found = true;
break;
}
}
// if nothing was found, we must calculate
if (!found) {
diameter = diameter * 1.06;
}
break;
case 2: /* wide fit */
// read diameter out of matrix
for (int i = 0; i < MatrixRowSizeMetric; i++) {
if (metricHoleDiameters[i][0] == diameter) {
diameter = metricHoleDiameters[i][3];
found = true;
break;
}
}
// if nothing was found, we must calculate
if (!found) {
diameter = diameter * 1.16;
}
break;
default:
throw Base::IndexError("Thread fit out of range");
}
// if nothing was found, we must calculate
if (!found) {
diameter = (5 * ((int)((diameter * 115) / 5))) / 100.0;
}
else if (threadType == "UNC" || threadType == "UNF" || threadType == "UNEF") {
std::string ThreadSizeString = ThreadSize.getValueAsString();
int MatrixRowSizeUTS = sizeof(UTSHoleDiameters) / sizeof(UTSHoleDiameters[0]);
switch (ThreadFit.getValue()) {
case 0: /* normal fit */
// read diameter out of matrix
for (int i = 0; i < MatrixRowSizeUTS; i++) {
if (UTSHoleDiameters[i].designation == ThreadSizeString) {
diameter = UTSHoleDiameters[i].normal;
found = true;
break;
}
}
// if nothing was found (if "#12" or "9/16"), we must calculate
// // we use the factors defined for "3/8" in the UTSHoleDiameters list
if (!found) {
diameter = diameter * 1.08;
}
break;
case 1: /* close fit */
// read diameter out of matrix
for (int i = 0; i < MatrixRowSizeUTS; i++) {
if (UTSHoleDiameters[i].designation == ThreadSizeString) {
diameter = UTSHoleDiameters[i].close;
found = true;
break;
}
}
// if nothing was found, we must calculate
if (!found) {
diameter = diameter * 1.04;
}
break;
case 2: /* loose fit */
// read diameter out of matrix
for (int i = 0; i < MatrixRowSizeUTS; i++) {
if (UTSHoleDiameters[i].designation == ThreadSizeString) {
diameter = UTSHoleDiameters[i].loose;
found = true;
break;
}
}
// if nothing was found, we must calculate
if (!found) {
diameter = diameter * 1.12;
}
break;
default:
throw Base::IndexError("Thread fit out of range");
}
}
else {
switch (ThreadFit.getValue()) {
case 0: /* normal fit */
// we must calculate
if (!found) {
diameter = diameter * 1.1;
}
break;
case 1: /* close fit */
if (!found) {
diameter = diameter * 1.05;
}
break;
case 2: /* loose fit */
if (!found) {
diameter = diameter * 1.15;
}
break;
default:
throw Base::IndexError("Thread fit out of range");
}
break;
default:
assert( 0 );
}
}
Diameter.setValue(diameter);
@@ -887,6 +999,7 @@ void Hole::onChanged(const App::Property *prop)
ThreadSize.setEnums(ThreadSize_ISOmetric_Enums);
ThreadClass.setEnums(ThreadClass_ISOmetric_Enums);
HoleCutType.setEnums(HoleCutType_ISOmetric_Enums);
ThreadFit.setEnums(ClearanceMetricEnums);
Threaded.setReadOnly(false);
ThreadSize.setReadOnly(false);
// thread class and direction are only sensible if threaded
@@ -899,6 +1012,7 @@ void Hole::onChanged(const App::Property *prop)
ThreadSize.setEnums(ThreadSize_ISOmetricfine_Enums);
ThreadClass.setEnums(ThreadClass_ISOmetricfine_Enums);
HoleCutType.setEnums(HoleCutType_ISOmetricfine_Enums);
ThreadFit.setEnums(ClearanceMetricEnums);
Threaded.setReadOnly(false);
ThreadSize.setReadOnly(false);
// thread class and direction are only sensible if threaded
@@ -911,6 +1025,7 @@ void Hole::onChanged(const App::Property *prop)
ThreadSize.setEnums(ThreadSize_UNC_Enums);
ThreadClass.setEnums(ThreadClass_UNC_Enums);
HoleCutType.setEnums(HoleCutType_UNC_Enums);
ThreadFit.setEnums(ClearanceUTSEnums);
Threaded.setReadOnly(false);
ThreadSize.setReadOnly(false);
// thread class and direction are only sensible if threaded
@@ -923,6 +1038,7 @@ void Hole::onChanged(const App::Property *prop)
ThreadSize.setEnums(ThreadSize_UNF_Enums);
ThreadClass.setEnums(ThreadClass_UNF_Enums);
HoleCutType.setEnums(HoleCutType_UNF_Enums);
ThreadFit.setEnums(ClearanceUTSEnums);
Threaded.setReadOnly(false);
ThreadSize.setReadOnly(false);
// thread class and direction are only sensible if threaded
@@ -935,6 +1051,7 @@ void Hole::onChanged(const App::Property *prop)
ThreadSize.setEnums(ThreadSize_UNEF_Enums);
ThreadClass.setEnums(ThreadClass_UNEF_Enums);
HoleCutType.setEnums(HoleCutType_UNEF_Enums);
ThreadFit.setEnums(ClearanceUTSEnums);
Threaded.setReadOnly(false);
ThreadSize.setReadOnly(false);
// thread class and direction are only sensible if threaded

View File

@@ -90,6 +90,14 @@ public:
static const double metricHoleDiameters[36][4];
typedef struct {
std::string designation;
double close;
double normal;
double loose;
} UTSClearanceDefinition;
static const UTSClearanceDefinition UTSHoleDiameters[22];
virtual void Restore(Base::XMLReader & reader);
virtual void updateProps();
@@ -99,7 +107,8 @@ protected:
private:
static const char* DepthTypeEnums[];
static const char* ThreadTypeEnums[];
static const char* ThreadFitEnums[];
static const char* ClearanceMetricEnums[];
static const char* ClearanceUTSEnums[];
static const char* DrillPointEnums[];
static const char* ThreadDirectionEnums[];

View File

@@ -440,31 +440,37 @@ void TaskHoleParameters::threadTypeChanged(int index)
// now set the new type, this will reset the comboboxes to item 0
pcHole->ThreadType.setValue(index);
// Size
// 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
// 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);
}
}
// for the UTS types the entries are the same
if (TypeClass == QByteArray("UTS")) {
// the names of the clearance types are different in ISO and UTS
ui->ThreadFit->setItemText(0, QCoreApplication::translate("TaskHoleParameters", "Standard", nullptr));
ui->ThreadFit->setItemText(1, QCoreApplication::translate("TaskHoleParameters", "Close", nullptr));
ui->ThreadFit->setItemText(2, 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, QCoreApplication::translate("TaskHoleParameters", "Normal", nullptr));
ui->ThreadFit->setItemText(1, QCoreApplication::translate("TaskHoleParameters", "Close", nullptr));
ui->ThreadFit->setItemText(2, QCoreApplication::translate("TaskHoleParameters", "Loose", nullptr));
}
// Class and cut type
@@ -475,6 +481,8 @@ void TaskHoleParameters::threadTypeChanged(int index)
int holeCutIndex = ui->HoleCutType->findText(CutTypeString, Qt::MatchContains);
if (holeCutIndex > -1)
ui->HoleCutType->setCurrentIndex(holeCutIndex);
recomputeFeature();
}
void TaskHoleParameters::threadSizeChanged(int index)