From 8444a3ec97ae5d366c6111975d4cf9bd8de1591a Mon Sep 17 00:00:00 2001 From: Alfredo Monclus Date: Fri, 26 Jul 2024 11:40:14 -0300 Subject: [PATCH 01/11] fix(PD): complete ISO-273 --- src/Mod/PartDesign/App/FeatureHole.cpp | 19 +++++++++++++++++-- src/Mod/PartDesign/App/FeatureHole.h | 2 +- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/Mod/PartDesign/App/FeatureHole.cpp b/src/Mod/PartDesign/App/FeatureHole.cpp index cd46abc519..1001efb450 100644 --- a/src/Mod/PartDesign/App/FeatureHole.cpp +++ b/src/Mod/PartDesign/App/FeatureHole.cpp @@ -401,7 +401,7 @@ const Hole::ThreadDescription Hole::threadDescription[][171] = }; -const double Hole::metricHoleDiameters[36][4] = +const double Hole::metricHoleDiameters[51][4] = { /* ISO metric clearance hole diameters according to ISO 273 */ // {screw diameter, close, standard, coarse} @@ -442,7 +442,22 @@ const double Hole::metricHoleDiameters[36][4] = { 56.0, 58.0, 62.0, 66.0}, { 60.0, 62.0, 66.0, 70.0}, { 64.0, 66.0, 70.0, 74.0}, - { 68.0, 70.0, 77.0, 78.0} + { 68.0, 70.0, 74.0, 78.0}, + { 72.0, 74.0, 78.0, 82.0}, + { 76.0, 78.0, 82.0, 86.0}, + { 80.0, 82.0, 86.0, 91.0}, + { 85.0, 87.0, 91.0, 96.0}, + { 90.0, 93.0, 96.0, 101.0}, + { 95.0, 98.0, 101.0, 107.0}, + { 100.0, 104.0, 107.0, 112.0}, + { 105.0, 109.0, 112.0, 117.0}, + { 110.0, 114.0, 117.0, 122.0}, + { 115.0, 119.0, 122.0, 127.0}, + { 120.0, 124.0, 127.0, 132.0}, + { 125.0, 129.0, 132.0, 137.0}, + { 130.0, 134.0, 137.0, 144.0}, + { 140.0, 144.0, 147.0, 155.0}, + { 150.0, 155.0, 158.0, 165.0} }; const Hole::UTSClearanceDefinition Hole::UTSHoleDiameters[22] = diff --git a/src/Mod/PartDesign/App/FeatureHole.h b/src/Mod/PartDesign/App/FeatureHole.h index 662dde2b6c..5a5f9dc0b0 100644 --- a/src/Mod/PartDesign/App/FeatureHole.h +++ b/src/Mod/PartDesign/App/FeatureHole.h @@ -94,7 +94,7 @@ public: }; static const ThreadDescription threadDescription[][171]; - static const double metricHoleDiameters[36][4]; + static const double metricHoleDiameters[51][4]; using UTSClearanceDefinition = struct { std::string designation; From 273295ff0347db6d342e1d5b93c510991d155f71 Mon Sep 17 00:00:00 2001 From: Alfredo Monclus Date: Fri, 26 Jul 2024 19:02:08 -0300 Subject: [PATCH 02/11] feat(PD): BSP - British standard pipe threads --- src/Mod/PartDesign/App/FeatureHole.cpp | 140 ++++++++++++++---- src/Mod/PartDesign/App/FeatureHole.h | 4 + src/Mod/PartDesign/Gui/TaskHoleParameters.cpp | 1 + 3 files changed, 118 insertions(+), 27 deletions(-) diff --git a/src/Mod/PartDesign/App/FeatureHole.cpp b/src/Mod/PartDesign/App/FeatureHole.cpp index 1001efb450..c678818ae0 100644 --- a/src/Mod/PartDesign/App/FeatureHole.cpp +++ b/src/Mod/PartDesign/App/FeatureHole.cpp @@ -37,6 +37,8 @@ # include # include # include +# include +# include # include # include # include @@ -65,7 +67,7 @@ namespace PartDesign { const char* Hole::DepthTypeEnums[] = { "Dimension", "ThroughAll", /*, "UpToFirst", */ nullptr }; const char* Hole::ThreadDepthTypeEnums[] = { "Hole Depth", "Dimension", "Tapped (DIN76)", nullptr }; -const char* Hole::ThreadTypeEnums[] = { "None", "ISOMetricProfile", "ISOMetricFineProfile", "UNC", "UNF", "UNEF", nullptr}; +const char* Hole::ThreadTypeEnums[] = { "None", "ISOMetricProfile", "ISOMetricFineProfile", "UNC", "UNF", "UNEF", "BSP", nullptr}; const char* Hole::ClearanceMetricEnums[] = { "Standard", "Close", "Wide", nullptr}; const char* Hole::ClearanceUTSEnums[] = { "Normal", "Close", "Loose", nullptr }; const char* Hole::DrillPointEnums[] = { "Flat", "Angled", nullptr}; @@ -397,8 +399,36 @@ const Hole::ThreadDescription Hole::threadDescription[][171] = { "1 9/16", 39.688, 1.411, 38.55 }, { "1 5/8", 41.275, 1.411, 40.10 }, { "1 11/16", 42.862, 1.411, 41.60 }, + }, + /* BSP */ + // Parallel - ISO 228-1 + // Tapered - ISO 7-1 + { + { "1/16", 7.723, 0.907, 6.6 }, // G + { "1/8", 9.728, 0.907, 8.8 }, // 11/32 + { "1/4", 13.157, 1.337, 11.8 }, // 29/64 + { "3/8", 16.662, 1.337, 15.25 }, // 19/32 + { "1/2", 20.955, 1.814, 19.00 }, // 3/4 + { "5/8", 22.911, 1.814, 21.00 }, // 53/64 + { "3/4", 26.441, 1.814, 24.50 }, // 31/32 + { "7/8", 30.201, 1.814, 28.25 }, // 1 7/64 + { "1", 33.249, 2.309, 30.75 }, // 1 13/64 + { "1 1/8", 37.897, 2.309, 0.0 }, + { "1 1/4", 41.910, 2.309, 39.50 }, // 1 35/64 + { "1 1/2", 47.803, 2.309, 45.50 }, // 1 25/32 + { "1 3/4", 53.743, 2.309, 51.00 }, // 2 + { "2", 59.614, 2.309, 57.00 }, // 2 1/4 + { "2 1/4", 65.710, 2.309, 0.0 }, + { "2 1/2", 75.184, 2.309, 0.0 }, + { "2 3/4", 81.534, 2.309, 0.0 }, + { "3", 87.884, 2.309, 0.0 }, + { "3 1/2", 100.330, 2.309, 0.0 }, + { "4", 113.030, 2.309, 0.0 }, + { "4 1/2", 125.730, 2.309, 0.0 }, + { "5", 138.430, 2.309, 0.0 }, + { "5 1/2", 151.130, 2.309, 0.0 }, + { "6", 163.830, 2.309, 0.0 }, } - }; const double Hole::metricHoleDiameters[51][4] = @@ -652,6 +682,14 @@ const char* Hole::ThreadSize_UNEF_Enums[] = { "#12", "1/4", "5/16", "3/8", "7/1 "1 5/8", "1 11/16", nullptr }; const char* Hole::ThreadClass_UNEF_Enums[] = { "1B", "2B", "3B", nullptr }; +/* BSP */ +const char* Hole::HoleCutType_BSP_Enums[] = { "None", "Counterbore", "Countersink", "Counterdrill", nullptr}; +const char* Hole::ThreadSize_BSP_Enums[] = { "1/16", "1/8", "1/4", "3/8", "1/2", "5/8", "3/4", "7/8", + "1", "1 1/8", "1 1/4", "1 3/8", "1 1/2", "1 3/4", + "2", "2 1/4", "2 1/2", "2 3/4", + "3", "3 1/2", "4", "4 1/2", + "5", "5 1/2", "6", nullptr }; + const char* Hole::ThreadDirectionEnums[] = { "Right", "Left", nullptr}; PROPERTY_SOURCE(PartDesign::Hole, PartDesign::ProfileBased) @@ -1108,11 +1146,14 @@ std::optional Hole::determineDiameter() const // use normed diameters if possible std::string threadTypeStr = ThreadType.getValueAsString(); - if (threadTypeStr == "ISOMetricProfile" || threadTypeStr == "UNC" - || threadTypeStr == "UNF" || threadTypeStr == "UNEF") { + if (threadDescription[threadType][threadSize].CoreHole > 0) { diameter = threadDescription[threadType][threadSize].CoreHole + clearance; + } // if nothing is available, we must calculate + else if (threadTypeStr == "BSP") { + double thread = 2 * (0.640327 * pitch); + // truncation is allowed by ISO-228 and BS 84 + diameter = diameter - thread * 0.75 + clearance; } - // if nothing available, we must calculate else { // this fits exactly the definition for ISO metric fine diameter = diameter - pitch + clearance; @@ -1373,6 +1414,20 @@ void Hole::onChanged(const App::Property* prop) ThreadDepthType.setReadOnly(!Threaded.getValue()); ThreadDepth.setReadOnly(!Threaded.getValue()); } + else if (type == "BSP") { + ThreadSize.setEnums(ThreadSize_BSP_Enums); + ThreadClass.setEnums(ThreadClass_None_Enums); + HoleCutType.setEnums(HoleCutType_BSP_Enums); + Threaded.setReadOnly(false); + ThreadSize.setReadOnly(false); + ThreadFit.setReadOnly(Threaded.getValue()); + Diameter.setReadOnly(true); + ModelThread.setReadOnly(!Threaded.getValue()); + UseCustomThreadClearance.setReadOnly(!Threaded.getValue() || !ModelThread.getValue()); + CustomThreadClearance.setReadOnly(!Threaded.getValue() || !ModelThread.getValue() || !UseCustomThreadClearance.getValue()); + ThreadDepthType.setReadOnly(!Threaded.getValue()); + ThreadDepth.setReadOnly(!Threaded.getValue()); + } if (holeCutTypeStr == "None") { HoleCutCustomValues.setReadOnly(true); @@ -2100,34 +2155,65 @@ TopoDS_Shape Hole::makeThread(const gp_Vec& xDir, const gp_Vec& zDir, double len // Nomenclature and formulae according to Figure 1 of ISO 68-1 // this is the same for all metric and UTS threads as stated here: // https://en.wikipedia.org/wiki/File:ISO_and_UTS_Thread_Dimensions.svg - // Note that in the ISO standard, Dmaj is called D, which has been followed here. - double Diam = threadDescription[threadType][threadSize].diameter; // major diameter + // Note that in the ISO standard, Dmaj is called D. + double Dmaj = threadDescription[threadType][threadSize].diameter / 2; // major diameter position double Pitch = getThreadPitch(); - double H = sqrt(3) / 2 * Pitch; // height of fundamental triangle double clearance; // clearance to be added on the diameter if (UseCustomThreadClearance.getValue()) - clearance = CustomThreadClearance.getValue(); + clearance = CustomThreadClearance.getValue() / 2; else - clearance = getThreadClassClearance(); - - // construct the cross section going counter-clockwise - // for graphical explanation of geometrical construction of p1-p6 see: - // https://forum.freecad.org/viewtopic.php?f=19&t=54284#p466570 - gp_Pnt p1 = toPnt((Diam / 2 - 5 * H / 8 + clearance / 2) * xDir + Pitch / 8 * zDir); - gp_Pnt p2 = toPnt((Diam / 2 + clearance / 2) * xDir + 7 * Pitch / 16 * zDir); - gp_Pnt p3 = toPnt((Diam / 2 + clearance / 2) * xDir + 9 * Pitch / 16 * zDir); - gp_Pnt p4 = toPnt((Diam / 2 - 5 * H / 8 + clearance / 2) * xDir + 7 * Pitch / 8 * zDir); - gp_Pnt p5 = toPnt(0.9 * (Diam / 2 - 5 * H / 8) * xDir + 7 * Pitch / 8 * zDir); - gp_Pnt p6 = toPnt(0.9 * (Diam / 2 - 5 * H / 8) * xDir + Pitch / 8 * zDir); + clearance = getThreadClassClearance() / 2; BRepBuilderAPI_MakeWire mkThreadWire; - mkThreadWire.Add(BRepBuilderAPI_MakeEdge(p1, p2).Edge()); - mkThreadWire.Add(BRepBuilderAPI_MakeEdge(p2, p3).Edge()); - mkThreadWire.Add(BRepBuilderAPI_MakeEdge(p3, p4).Edge()); - mkThreadWire.Add(BRepBuilderAPI_MakeEdge(p4, p5).Edge()); - mkThreadWire.Add(BRepBuilderAPI_MakeEdge(p5, p6).Edge()); - mkThreadWire.Add(BRepBuilderAPI_MakeEdge(p6, p1).Edge()); + double H; + std::string threadTypeStr = ThreadType.getValueAsString(); + if (threadTypeStr == "BSP") { + H = 0.960491 * Pitch; // Height of Sharp V + double radius = 0.137329 * Pitch; // radius of the crest + double h = 0.640627 * Pitch; // height of the thread + // construct the cross section going counter-clockwise + + gp_Pnt p1 = toPnt((Dmaj - h + clearance) * xDir + Pitch / 8 * zDir); + gp_Pnt p4 = toPnt((Dmaj - h + clearance) * xDir + 7 * Pitch / 8 * zDir); + gp_Pnt p5 = toPnt(0.9 * (Dmaj - h) * xDir + 7 * Pitch / 8 * zDir); + gp_Pnt p6 = toPnt(0.9 * (Dmaj - h) * xDir + Pitch / 8 * zDir); + + // Calculate positions for p2 and p3 based on the arc radius + double p23x = Dmaj + clearance - radius * (1 - std::cos(M_PI / 4)); + + gp_Pnt p2 = toPnt(p23x * xDir + 7 * Pitch / 16 * zDir); + gp_Pnt p3 = toPnt(p23x * xDir + 9 * Pitch / 16 * zDir); + gp_Pnt crest = toPnt((Dmaj + clearance) * xDir + Pitch / 2 * zDir); + + mkThreadWire.Add(BRepBuilderAPI_MakeEdge(p1, p2).Edge()); + Handle(Geom_TrimmedCurve) arc1 = GC_MakeArcOfCircle(p2, crest, p3).Value(); + mkThreadWire.Add(BRepBuilderAPI_MakeEdge(arc1).Edge()); + mkThreadWire.Add(BRepBuilderAPI_MakeEdge(p3, p4).Edge()); + mkThreadWire.Add(BRepBuilderAPI_MakeEdge(p4, p5).Edge()); + mkThreadWire.Add(BRepBuilderAPI_MakeEdge(p5, p6).Edge()); + mkThreadWire.Add(BRepBuilderAPI_MakeEdge(p6, p1).Edge()); + } else { + H = sqrt(3) / 2 * Pitch; // height of fundamental triangle + double h = 5 * H / 8; // height of the thread + // construct the cross section going counter-clockwise + // for graphical explanation of geometrical construction of p1-p6 see: + // https://forum.freecad.org/viewtopic.php?f=19&t=54284#p466570 + gp_Pnt p1 = toPnt((Dmaj - h + clearance) * xDir + Pitch / 8 * zDir); + gp_Pnt p2 = toPnt((Dmaj + clearance) * xDir + 7 * Pitch / 16 * zDir); + gp_Pnt p3 = toPnt((Dmaj + clearance) * xDir + 9 * Pitch / 16 * zDir); + gp_Pnt p4 = toPnt((Dmaj - h + clearance) * xDir + 7 * Pitch / 8 * zDir); + gp_Pnt p5 = toPnt(0.9 * (Dmaj - h) * xDir + 7 * Pitch / 8 * zDir); + gp_Pnt p6 = toPnt(0.9 * (Dmaj - h) * xDir + Pitch / 8 * zDir); + + mkThreadWire.Add(BRepBuilderAPI_MakeEdge(p1, p2).Edge()); + mkThreadWire.Add(BRepBuilderAPI_MakeEdge(p2, p3).Edge()); + mkThreadWire.Add(BRepBuilderAPI_MakeEdge(p3, p4).Edge()); + mkThreadWire.Add(BRepBuilderAPI_MakeEdge(p4, p5).Edge()); + mkThreadWire.Add(BRepBuilderAPI_MakeEdge(p5, p6).Edge()); + mkThreadWire.Add(BRepBuilderAPI_MakeEdge(p6, p1).Edge()); + } + mkThreadWire.Build(); TopoDS_Wire threadWire = mkThreadWire.Wire(); @@ -2162,7 +2248,7 @@ TopoDS_Shape Hole::makeThread(const gp_Vec& xDir, const gp_Vec& zDir, double len helixLength = holeDepth + Pitch / 8; } } - TopoDS_Shape helix = TopoShape().makeLongHelix(Pitch, helixLength, Diam / 2, 0.0, leftHanded); + TopoDS_Shape helix = TopoShape().makeLongHelix(Pitch, helixLength, Dmaj, 0.0, leftHanded); gp_Pnt origo(0.0, 0.0, 0.0); gp_Dir dir_axis1(0.0, 0.0, 1.0); // pointing along the helix axis, as created. diff --git a/src/Mod/PartDesign/App/FeatureHole.h b/src/Mod/PartDesign/App/FeatureHole.h index 5a5f9dc0b0..d77d135433 100644 --- a/src/Mod/PartDesign/App/FeatureHole.h +++ b/src/Mod/PartDesign/App/FeatureHole.h @@ -152,6 +152,10 @@ private: static const char* ThreadSize_UNEF_Enums[]; static const char* ThreadClass_UNEF_Enums[]; + /* BSP profile */ + static const char* HoleCutType_BSP_Enums[]; + static const char* ThreadSize_BSP_Enums[]; + static const double ThreadRunout[ThreadRunout_size][2]; /* Counter-xxx */ diff --git a/src/Mod/PartDesign/Gui/TaskHoleParameters.cpp b/src/Mod/PartDesign/Gui/TaskHoleParameters.cpp index 4d3a493879..1b60b4448a 100644 --- a/src/Mod/PartDesign/Gui/TaskHoleParameters.cpp +++ b/src/Mod/PartDesign/Gui/TaskHoleParameters.cpp @@ -66,6 +66,7 @@ TaskHoleParameters::TaskHoleParameters(ViewProviderHole* HoleView, QWidget* pare ui->ThreadType->addItem(tr("UTS coarse profile"), QByteArray("UTS")); ui->ThreadType->addItem(tr("UTS fine profile"), QByteArray("UTS")); ui->ThreadType->addItem(tr("UTS extra fine profile"), QByteArray("UTS")); + ui->ThreadType->addItem(tr("BSP pipe profile"), QByteArray("BSP")); // read values from the hole properties auto pcHole = getObject(); From ae8b1cfe2a9e95bdd740db2ffa58e69f7ec48b58 Mon Sep 17 00:00:00 2001 From: Alfredo Monclus Date: Sat, 3 Aug 2024 06:58:24 -0300 Subject: [PATCH 03/11] feat(PD): ANSI pipe threads --- src/Mod/PartDesign/App/FeatureHole.cpp | 51 ++++++++++++++++++- src/Mod/PartDesign/App/FeatureHole.h | 4 ++ src/Mod/PartDesign/Gui/TaskHoleParameters.cpp | 1 + 3 files changed, 55 insertions(+), 1 deletion(-) diff --git a/src/Mod/PartDesign/App/FeatureHole.cpp b/src/Mod/PartDesign/App/FeatureHole.cpp index c678818ae0..1e84a16f2e 100644 --- a/src/Mod/PartDesign/App/FeatureHole.cpp +++ b/src/Mod/PartDesign/App/FeatureHole.cpp @@ -67,7 +67,7 @@ namespace PartDesign { const char* Hole::DepthTypeEnums[] = { "Dimension", "ThroughAll", /*, "UpToFirst", */ nullptr }; const char* Hole::ThreadDepthTypeEnums[] = { "Hole Depth", "Dimension", "Tapped (DIN76)", nullptr }; -const char* Hole::ThreadTypeEnums[] = { "None", "ISOMetricProfile", "ISOMetricFineProfile", "UNC", "UNF", "UNEF", "BSP", nullptr}; +const char* Hole::ThreadTypeEnums[] = { "None", "ISOMetricProfile", "ISOMetricFineProfile", "UNC", "UNF", "UNEF", "NPT", "BSP", nullptr}; const char* Hole::ClearanceMetricEnums[] = { "Standard", "Close", "Wide", nullptr}; const char* Hole::ClearanceUTSEnums[] = { "Normal", "Close", "Loose", nullptr }; const char* Hole::DrillPointEnums[] = { "Flat", "Angled", nullptr}; @@ -400,6 +400,29 @@ const Hole::ThreadDescription Hole::threadDescription[][171] = { "1 5/8", 41.275, 1.411, 40.10 }, { "1 11/16", 42.862, 1.411, 41.60 }, }, + /* NPT National pipe threads */ + // Asme B1.20.1 + { + { "1/16", 7.938, 0.941, 0.0 }, + { "1/8", 10.287, 0.941, 0.0 }, + { "1/4", 13.716, 1.411, 0.0 }, + { "3/8", 17.145, 1.411, 0.0 }, + { "1/2", 21.336, 1.814, 0.0 }, + { "3/4", 26.670, 1.814, 0.0 }, + { "1", 33.401, 2.209, 0.0 }, + { "1 1/4", 42.164, 2.209, 0.0 }, + { "1 1/2", 48.260, 2.209, 0.0 }, + { "2", 60.325, 2.209, 0.0 }, + { "2 1/2", 73.025, 3.175, 0.0 }, + { "3", 88.900, 3.175, 0.0 }, + { "3 1/2", 101.600, 3.175, 0.0 }, + { "4", 114.300, 3.175, 0.0 }, + { "5", 141.300, 3.175, 0.0 }, + { "6", 168.275, 3.175, 0.0 }, + { "8", 219.075, 3.175, 0.0 }, + { "10", 273.050, 3.175, 0.0 }, + { "12", 323.850, 3.175, 0.0 }, + }, /* BSP */ // Parallel - ISO 228-1 // Tapered - ISO 7-1 @@ -682,6 +705,14 @@ const char* Hole::ThreadSize_UNEF_Enums[] = { "#12", "1/4", "5/16", "3/8", "7/1 "1 5/8", "1 11/16", nullptr }; const char* Hole::ThreadClass_UNEF_Enums[] = { "1B", "2B", "3B", nullptr }; +/* NPT */ +const char* Hole::HoleCutType_NPT_Enums[] = { "None", "Counterbore", "Countersink", "Counterdrill", nullptr}; +const char* Hole::ThreadSize_NPT_Enums[] = { "1/16", "1/8", "1/4", "3/8", "1/2", "3/4", + "1", "1 1/4", "1 1/2", + "2", "2 1/2", + "3", "3 1/2", + "4", "5", "6", "8", "10", "12", nullptr }; + /* BSP */ const char* Hole::HoleCutType_BSP_Enums[] = { "None", "Counterbore", "Countersink", "Counterdrill", nullptr}; const char* Hole::ThreadSize_BSP_Enums[] = { "1/16", "1/8", "1/4", "3/8", "1/2", "5/8", "3/4", "7/8", @@ -1154,6 +1185,10 @@ std::optional Hole::determineDiameter() const // truncation is allowed by ISO-228 and BS 84 diameter = diameter - thread * 0.75 + clearance; } + else if (threadTypeStr == "NPT") { + double thread = 2 * (0.8 * pitch); + diameter = diameter - thread * 0.75 + clearance; + } else { // this fits exactly the definition for ISO metric fine diameter = diameter - pitch + clearance; @@ -1428,6 +1463,20 @@ void Hole::onChanged(const App::Property* prop) ThreadDepthType.setReadOnly(!Threaded.getValue()); ThreadDepth.setReadOnly(!Threaded.getValue()); } + else if (type == "NPT") { + ThreadSize.setEnums(ThreadSize_NPT_Enums); + ThreadClass.setEnums(ThreadClass_None_Enums); + HoleCutType.setEnums(HoleCutType_NPT_Enums); + Threaded.setReadOnly(false); + ThreadSize.setReadOnly(false); + ThreadFit.setReadOnly(Threaded.getValue()); + Diameter.setReadOnly(true); + ModelThread.setReadOnly(!Threaded.getValue()); + UseCustomThreadClearance.setReadOnly(!Threaded.getValue() || !ModelThread.getValue()); + CustomThreadClearance.setReadOnly(!Threaded.getValue() || !ModelThread.getValue() || !UseCustomThreadClearance.getValue()); + ThreadDepthType.setReadOnly(!Threaded.getValue()); + ThreadDepth.setReadOnly(!Threaded.getValue()); + } if (holeCutTypeStr == "None") { HoleCutCustomValues.setReadOnly(true); diff --git a/src/Mod/PartDesign/App/FeatureHole.h b/src/Mod/PartDesign/App/FeatureHole.h index d77d135433..e1ee95e69d 100644 --- a/src/Mod/PartDesign/App/FeatureHole.h +++ b/src/Mod/PartDesign/App/FeatureHole.h @@ -152,6 +152,10 @@ private: static const char* ThreadSize_UNEF_Enums[]; static const char* ThreadClass_UNEF_Enums[]; + /* NPT profile */ + static const char* HoleCutType_NPT_Enums[]; + static const char* ThreadSize_NPT_Enums[]; + /* BSP profile */ static const char* HoleCutType_BSP_Enums[]; static const char* ThreadSize_BSP_Enums[]; diff --git a/src/Mod/PartDesign/Gui/TaskHoleParameters.cpp b/src/Mod/PartDesign/Gui/TaskHoleParameters.cpp index 1b60b4448a..6be7519f89 100644 --- a/src/Mod/PartDesign/Gui/TaskHoleParameters.cpp +++ b/src/Mod/PartDesign/Gui/TaskHoleParameters.cpp @@ -66,6 +66,7 @@ TaskHoleParameters::TaskHoleParameters(ViewProviderHole* HoleView, QWidget* pare ui->ThreadType->addItem(tr("UTS coarse profile"), QByteArray("UTS")); ui->ThreadType->addItem(tr("UTS fine profile"), QByteArray("UTS")); ui->ThreadType->addItem(tr("UTS extra fine profile"), QByteArray("UTS")); + ui->ThreadType->addItem(tr("ANSI pipe profile"), QByteArray("NPT")); ui->ThreadType->addItem(tr("BSP pipe profile"), QByteArray("BSP")); // read values from the hole properties From 33251daa12146a8c76dc976cbf09da2524809945 Mon Sep 17 00:00:00 2001 From: Alfredo Monclus Date: Sat, 3 Aug 2024 19:18:32 -0300 Subject: [PATCH 04/11] feat(PD): tapered threads support, NPT and BSPT are now possible --- src/Mod/PartDesign/App/FeatureHole.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Mod/PartDesign/App/FeatureHole.cpp b/src/Mod/PartDesign/App/FeatureHole.cpp index 1e84a16f2e..3cafc412cf 100644 --- a/src/Mod/PartDesign/App/FeatureHole.cpp +++ b/src/Mod/PartDesign/App/FeatureHole.cpp @@ -2297,7 +2297,9 @@ TopoDS_Shape Hole::makeThread(const gp_Vec& xDir, const gp_Vec& zDir, double len helixLength = holeDepth + Pitch / 8; } } - TopoDS_Shape helix = TopoShape().makeLongHelix(Pitch, helixLength, Dmaj, 0.0, leftHanded); + double helixAngle = + Tapered.getValue() ? TaperedAngle.getValue() - 90 : 0.0; + TopoDS_Shape helix = TopoShape().makeLongHelix(Pitch, helixLength, Dmaj, helixAngle, leftHanded); gp_Pnt origo(0.0, 0.0, 0.0); gp_Dir dir_axis1(0.0, 0.0, 1.0); // pointing along the helix axis, as created. From 4660dfcfa616bea17abead191b951939eb95fc7c Mon Sep 17 00:00:00 2001 From: Alfredo Monclus Date: Sun, 4 Aug 2024 14:07:57 -0300 Subject: [PATCH 05/11] refactor(PD): change tabs to whitespaces --- src/Mod/PartDesign/App/FeatureHole.cpp | 184 ++++++++++++------------- 1 file changed, 92 insertions(+), 92 deletions(-) diff --git a/src/Mod/PartDesign/App/FeatureHole.cpp b/src/Mod/PartDesign/App/FeatureHole.cpp index 3cafc412cf..79c651dd4f 100644 --- a/src/Mod/PartDesign/App/FeatureHole.cpp +++ b/src/Mod/PartDesign/App/FeatureHole.cpp @@ -88,53 +88,53 @@ const Hole::ThreadDescription Hole::threadDescription[][171] = { /* None */ { - { "---", 6.0, 0.0, 0.0 }, + { "---", 6.0, 0.0, 0.0 }, }, /* ISO metric regular */ /* ISO metric threaded core hole diameters according to ISO 2306 */ // {name, thread diameter, thread pitch, core hole diameter} { - { "M1", 1.0, 0.25, 0.75 }, - { "M1.1", 1.1, 0.25, 0.85 }, - { "M1.2", 1.2, 0.25, 0.95 }, - { "M1.4", 1.4, 0.30, 1.10 }, - { "M1.6", 1.6, 0.35, 1.25 }, - { "M1.8", 1.8, 0.35, 1.45 }, - { "M2", 2.0, 0.40, 1.60 }, - { "M2.2", 2.2, 0.45, 1.75 }, - { "M2.5", 2.5, 0.45, 2.05 }, - { "M3", 3.0, 0.50, 2.50 }, - { "M3.5", 3.5, 0.60, 2.90 }, - { "M4", 4.0, 0.70, 3.30 }, - { "M4.5", 4.5, 0.75, 3.70 }, - { "M5", 5.0, 0.80, 4.20 }, - { "M6", 6.0, 1.00, 5.00 }, - { "M7", 7.0, 1.00, 6.00 }, - { "M8", 8.0, 1.25, 6.80 }, - { "M9", 9.0, 1.25, 7.80 }, - { "M10", 10.0, 1.50, 8.50 }, - { "M11", 11.0, 1.50, 9.50 }, - { "M12", 12.0, 1.75, 10.20 }, - { "M14", 14.0, 2.00, 12.00 }, - { "M16", 16.0, 2.00, 14.00 }, - { "M18", 18.0, 2.50, 15.50 }, - { "M20", 20.0, 2.50, 17.50 }, - { "M22", 22.0, 2.50, 19.50 }, - { "M24", 24.0, 3.00, 21.00 }, - { "M27", 27.0, 3.00, 24.00 }, - { "M30", 30.0, 3.50, 26.50 }, - { "M33", 33.0, 3.50, 29.50 }, - { "M36", 36.0, 4.00, 32.00 }, - { "M39", 39.0, 4.00, 35.00 }, - { "M42", 42.0, 4.50, 37.50 }, - { "M45", 45.0, 4.50, 40.50 }, - { "M48", 48.0, 5.00, 43.00 }, - { "M52", 52.0, 5.00, 47.00 }, - { "M56", 56.0, 5.50, 50.50 }, - { "M60", 60.0, 5.50, 54.50 }, - { "M64", 64.0, 6.00, 58.00 }, - { "M68", 68.0, 6.00, 62.00 }, + { "M1", 1.0, 0.25, 0.75 }, + { "M1.1", 1.1, 0.25, 0.85 }, + { "M1.2", 1.2, 0.25, 0.95 }, + { "M1.4", 1.4, 0.30, 1.10 }, + { "M1.6", 1.6, 0.35, 1.25 }, + { "M1.8", 1.8, 0.35, 1.45 }, + { "M2", 2.0, 0.40, 1.60 }, + { "M2.2", 2.2, 0.45, 1.75 }, + { "M2.5", 2.5, 0.45, 2.05 }, + { "M3", 3.0, 0.50, 2.50 }, + { "M3.5", 3.5, 0.60, 2.90 }, + { "M4", 4.0, 0.70, 3.30 }, + { "M4.5", 4.5, 0.75, 3.70 }, + { "M5", 5.0, 0.80, 4.20 }, + { "M6", 6.0, 1.00, 5.00 }, + { "M7", 7.0, 1.00, 6.00 }, + { "M8", 8.0, 1.25, 6.80 }, + { "M9", 9.0, 1.25, 7.80 }, + { "M10", 10.0, 1.50, 8.50 }, + { "M11", 11.0, 1.50, 9.50 }, + { "M12", 12.0, 1.75, 10.20 }, + { "M14", 14.0, 2.00, 12.00 }, + { "M16", 16.0, 2.00, 14.00 }, + { "M18", 18.0, 2.50, 15.50 }, + { "M20", 20.0, 2.50, 17.50 }, + { "M22", 22.0, 2.50, 19.50 }, + { "M24", 24.0, 3.00, 21.00 }, + { "M27", 27.0, 3.00, 24.00 }, + { "M30", 30.0, 3.50, 26.50 }, + { "M33", 33.0, 3.50, 29.50 }, + { "M36", 36.0, 4.00, 32.00 }, + { "M39", 39.0, 4.00, 35.00 }, + { "M42", 42.0, 4.50, 37.50 }, + { "M45", 45.0, 4.50, 40.50 }, + { "M48", 48.0, 5.00, 43.00 }, + { "M52", 52.0, 5.00, 47.00 }, + { "M56", 56.0, 5.50, 50.50 }, + { "M60", 60.0, 5.50, 54.50 }, + { "M64", 64.0, 6.00, 58.00 }, + { "M68", 68.0, 6.00, 62.00 }, }, /* ISO metric fine (core hole entry is calculated exactly by diameter - pitch) */ { @@ -458,59 +458,59 @@ const double Hole::metricHoleDiameters[51][4] = { /* ISO metric clearance hole diameters according to ISO 273 */ // {screw diameter, close, standard, coarse} - { 1.0, 1.1, 1.2, 1.3}, - { 1.2, 1.3, 1.4, 1.5}, - { 1.4, 1.5, 1.6, 1.8}, - { 1.6, 1.7, 1.8, 2.0}, - { 1.8, 2.0, 2.1, 2.2}, - { 2.0, 2.2, 2.4, 2.6}, - { 2.5, 2.7, 2.9, 3.1}, - { 3.0, 3.2, 3.4, 3.6}, - { 3.5, 3.7, 3.9, 4.2}, - { 4.0, 4.3, 4.5, 4.8}, - { 4.5, 4.8, 5.0, 5.3}, - { 5.0, 5.3, 5.5, 5.8}, - { 6.0, 6.4, 6.6, 7.0}, - { 7.0, 7.4, 7.6, 8.0}, - { 8.0, 8.4, 9.0, 10.0}, + { 1.0, 1.1, 1.2, 1.3}, + { 1.2, 1.3, 1.4, 1.5}, + { 1.4, 1.5, 1.6, 1.8}, + { 1.6, 1.7, 1.8, 2.0}, + { 1.8, 2.0, 2.1, 2.2}, + { 2.0, 2.2, 2.4, 2.6}, + { 2.5, 2.7, 2.9, 3.1}, + { 3.0, 3.2, 3.4, 3.6}, + { 3.5, 3.7, 3.9, 4.2}, + { 4.0, 4.3, 4.5, 4.8}, + { 4.5, 4.8, 5.0, 5.3}, + { 5.0, 5.3, 5.5, 5.8}, + { 6.0, 6.4, 6.6, 7.0}, + { 7.0, 7.4, 7.6, 8.0}, + { 8.0, 8.4, 9.0, 10.0}, // 9.0 undefined - { 10.0, 10.5, 11.0, 12.0}, + { 10.0, 10.5, 11.0, 12.0}, // 11.0 undefined - { 12.0, 13.0, 13.5, 14.5}, - { 14.0, 15.0, 15.5, 16.5}, - { 16.0, 17.0, 17.5, 18.5}, - { 18.0, 19.0, 20.0, 21.0}, - { 20.0, 21.0, 22.0, 24.0}, - { 22.0, 23.0, 24.0, 26.0}, - { 24.0, 25.0, 26.0, 28.0}, - { 27.0, 28.0, 30.0, 32.0}, - { 30.0, 31.0, 33.0, 35.0}, - { 33.0, 34.0, 36.0, 38.0}, - { 36.0, 37.0, 39.0, 42.0}, - { 39.0, 40.0, 42.0, 45.0}, - { 42.0, 43.0, 45.0, 48.0}, - { 45.0, 46.0, 48.0, 52.0}, - { 48.0, 50.0, 52.0, 56.0}, - { 52.0, 54.0, 56.0, 62.0}, - { 56.0, 58.0, 62.0, 66.0}, - { 60.0, 62.0, 66.0, 70.0}, - { 64.0, 66.0, 70.0, 74.0}, - { 68.0, 70.0, 74.0, 78.0}, - { 72.0, 74.0, 78.0, 82.0}, - { 76.0, 78.0, 82.0, 86.0}, - { 80.0, 82.0, 86.0, 91.0}, - { 85.0, 87.0, 91.0, 96.0}, - { 90.0, 93.0, 96.0, 101.0}, - { 95.0, 98.0, 101.0, 107.0}, - { 100.0, 104.0, 107.0, 112.0}, - { 105.0, 109.0, 112.0, 117.0}, - { 110.0, 114.0, 117.0, 122.0}, - { 115.0, 119.0, 122.0, 127.0}, - { 120.0, 124.0, 127.0, 132.0}, - { 125.0, 129.0, 132.0, 137.0}, - { 130.0, 134.0, 137.0, 144.0}, - { 140.0, 144.0, 147.0, 155.0}, - { 150.0, 155.0, 158.0, 165.0} + { 12.0, 13.0, 13.5, 14.5}, + { 14.0, 15.0, 15.5, 16.5}, + { 16.0, 17.0, 17.5, 18.5}, + { 18.0, 19.0, 20.0, 21.0}, + { 20.0, 21.0, 22.0, 24.0}, + { 22.0, 23.0, 24.0, 26.0}, + { 24.0, 25.0, 26.0, 28.0}, + { 27.0, 28.0, 30.0, 32.0}, + { 30.0, 31.0, 33.0, 35.0}, + { 33.0, 34.0, 36.0, 38.0}, + { 36.0, 37.0, 39.0, 42.0}, + { 39.0, 40.0, 42.0, 45.0}, + { 42.0, 43.0, 45.0, 48.0}, + { 45.0, 46.0, 48.0, 52.0}, + { 48.0, 50.0, 52.0, 56.0}, + { 52.0, 54.0, 56.0, 62.0}, + { 56.0, 58.0, 62.0, 66.0}, + { 60.0, 62.0, 66.0, 70.0}, + { 64.0, 66.0, 70.0, 74.0}, + { 68.0, 70.0, 74.0, 78.0}, + { 72.0, 74.0, 78.0, 82.0}, + { 76.0, 78.0, 82.0, 86.0}, + { 80.0, 82.0, 86.0, 91.0}, + { 85.0, 87.0, 91.0, 96.0}, + { 90.0, 93.0, 96.0, 101.0}, + { 95.0, 98.0, 101.0, 107.0}, + { 100.0, 104.0, 107.0, 112.0}, + { 105.0, 109.0, 112.0, 117.0}, + { 110.0, 114.0, 117.0, 122.0}, + { 115.0, 119.0, 122.0, 127.0}, + { 120.0, 124.0, 127.0, 132.0}, + { 125.0, 129.0, 132.0, 137.0}, + { 130.0, 134.0, 137.0, 144.0}, + { 140.0, 144.0, 147.0, 155.0}, + { 150.0, 155.0, 158.0, 165.0} }; const Hole::UTSClearanceDefinition Hole::UTSHoleDiameters[22] = From 32d75519f7c3d594056281bf88a30405f6b4ebf8 Mon Sep 17 00:00:00 2001 From: Alfredo Monclus Date: Mon, 5 Aug 2024 19:16:14 -0300 Subject: [PATCH 06/11] refactor(PD): new cut profile for threads fixes tapered threds removing 2 points increases performance around 10% when doing an M1 in my imprecise testing --- src/Mod/PartDesign/App/FeatureHole.cpp | 81 +++++++++++++++++--------- 1 file changed, 53 insertions(+), 28 deletions(-) diff --git a/src/Mod/PartDesign/App/FeatureHole.cpp b/src/Mod/PartDesign/App/FeatureHole.cpp index 79c651dd4f..180c050585 100644 --- a/src/Mod/PartDesign/App/FeatureHole.cpp +++ b/src/Mod/PartDesign/App/FeatureHole.cpp @@ -2204,8 +2204,8 @@ TopoDS_Shape Hole::makeThread(const gp_Vec& xDir, const gp_Vec& zDir, double len // Nomenclature and formulae according to Figure 1 of ISO 68-1 // this is the same for all metric and UTS threads as stated here: // https://en.wikipedia.org/wiki/File:ISO_and_UTS_Thread_Dimensions.svg - // Note that in the ISO standard, Dmaj is called D. - double Dmaj = threadDescription[threadType][threadSize].diameter / 2; // major diameter position + // Rmaj is half of the major diameter + double Rmaj = threadDescription[threadType][threadSize].diameter / 2; double Pitch = getThreadPitch(); double clearance; // clearance to be added on the diameter @@ -2213,6 +2213,8 @@ TopoDS_Shape Hole::makeThread(const gp_Vec& xDir, const gp_Vec& zDir, double len clearance = CustomThreadClearance.getValue() / 2; else clearance = getThreadClassClearance() / 2; + double RmajC = Rmaj + clearance; + double marginZ = 0.001; BRepBuilderAPI_MakeWire mkThreadWire; double H; @@ -2220,47 +2222,70 @@ TopoDS_Shape Hole::makeThread(const gp_Vec& xDir, const gp_Vec& zDir, double len if (threadTypeStr == "BSP") { H = 0.960491 * Pitch; // Height of Sharp V double radius = 0.137329 * Pitch; // radius of the crest - double h = 0.640627 * Pitch; // height of the thread // construct the cross section going counter-clockwise + // -------------- + // P | p4 + // 5/8P | p3 + // | crest + // 3/8P | p2 + // 0 | p1 + // -------------- + // | base-sharpV Rmaj H - gp_Pnt p1 = toPnt((Dmaj - h + clearance) * xDir + Pitch / 8 * zDir); - gp_Pnt p4 = toPnt((Dmaj - h + clearance) * xDir + 7 * Pitch / 8 * zDir); - gp_Pnt p5 = toPnt(0.9 * (Dmaj - h) * xDir + 7 * Pitch / 8 * zDir); - gp_Pnt p6 = toPnt(0.9 * (Dmaj - h) * xDir + Pitch / 8 * zDir); + // the little adjustment of p1 and p4 is here to prevent coincidencies + double marginX = std::tan(62.5 * M_PI / 180.0) * marginZ; - // Calculate positions for p2 and p3 based on the arc radius - double p23x = Dmaj + clearance - radius * (1 - std::cos(M_PI / 4)); + gp_Pnt p1 = toPnt( + (RmajC - 5 * H / 6 + marginX) * xDir + + marginZ * zDir + ); + gp_Pnt p4 = toPnt( + (RmajC - 5 * H / 6 + marginX) * xDir + + (Pitch - marginZ) * zDir + ); - gp_Pnt p2 = toPnt(p23x * xDir + 7 * Pitch / 16 * zDir); - gp_Pnt p3 = toPnt(p23x * xDir + 9 * Pitch / 16 * zDir); - gp_Pnt crest = toPnt((Dmaj + clearance) * xDir + Pitch / 2 * zDir); + // Calculate positions for p2 and p3 + double p23x = RmajC - radius * 0.58284013094; + + gp_Pnt p2 = toPnt(p23x * xDir + 3 * Pitch / 8 * zDir); + gp_Pnt p3 = toPnt(p23x * xDir + 5 * Pitch / 8 * zDir); + gp_Pnt crest = toPnt((RmajC) * xDir + Pitch / 2 * zDir); mkThreadWire.Add(BRepBuilderAPI_MakeEdge(p1, p2).Edge()); Handle(Geom_TrimmedCurve) arc1 = GC_MakeArcOfCircle(p2, crest, p3).Value(); mkThreadWire.Add(BRepBuilderAPI_MakeEdge(arc1).Edge()); mkThreadWire.Add(BRepBuilderAPI_MakeEdge(p3, p4).Edge()); - mkThreadWire.Add(BRepBuilderAPI_MakeEdge(p4, p5).Edge()); - mkThreadWire.Add(BRepBuilderAPI_MakeEdge(p5, p6).Edge()); - mkThreadWire.Add(BRepBuilderAPI_MakeEdge(p6, p1).Edge()); + mkThreadWire.Add(BRepBuilderAPI_MakeEdge(p4, p1).Edge()); } else { H = sqrt(3) / 2 * Pitch; // height of fundamental triangle - double h = 5 * H / 8; // height of the thread + double h = 7 * H / 8; // distance from Rmaj to the base // construct the cross section going counter-clockwise - // for graphical explanation of geometrical construction of p1-p6 see: - // https://forum.freecad.org/viewtopic.php?f=19&t=54284#p466570 - gp_Pnt p1 = toPnt((Dmaj - h + clearance) * xDir + Pitch / 8 * zDir); - gp_Pnt p2 = toPnt((Dmaj + clearance) * xDir + 7 * Pitch / 16 * zDir); - gp_Pnt p3 = toPnt((Dmaj + clearance) * xDir + 9 * Pitch / 16 * zDir); - gp_Pnt p4 = toPnt((Dmaj - h + clearance) * xDir + 7 * Pitch / 8 * zDir); - gp_Pnt p5 = toPnt(0.9 * (Dmaj - h) * xDir + 7 * Pitch / 8 * zDir); - gp_Pnt p6 = toPnt(0.9 * (Dmaj - h) * xDir + Pitch / 8 * zDir); + // pitch + // -------------- + // P | p4 + // 9/16P | p3 + // 7/16P | p2 + // 0 | p1 + // -------------- + // | base-sharpV Rmaj + + // the little adjustment of p1 and p4 is here to prevent coincidencies + double marginX = std::tan(60.0 * M_PI / 180.0) * marginZ; + gp_Pnt p1 = toPnt( + (RmajC - h + marginX) * xDir + + marginZ * zDir + ); + gp_Pnt p2 = toPnt((RmajC) * xDir + 7 * Pitch / 16 * zDir); + gp_Pnt p3 = toPnt((RmajC) * xDir + 9 * Pitch / 16 * zDir); + gp_Pnt p4 = toPnt( + (RmajC - h + marginX) * xDir + + (Pitch - marginZ) * zDir + ); mkThreadWire.Add(BRepBuilderAPI_MakeEdge(p1, p2).Edge()); mkThreadWire.Add(BRepBuilderAPI_MakeEdge(p2, p3).Edge()); mkThreadWire.Add(BRepBuilderAPI_MakeEdge(p3, p4).Edge()); - mkThreadWire.Add(BRepBuilderAPI_MakeEdge(p4, p5).Edge()); - mkThreadWire.Add(BRepBuilderAPI_MakeEdge(p5, p6).Edge()); - mkThreadWire.Add(BRepBuilderAPI_MakeEdge(p6, p1).Edge()); + mkThreadWire.Add(BRepBuilderAPI_MakeEdge(p4, p1).Edge()); } mkThreadWire.Build(); @@ -2299,7 +2324,7 @@ TopoDS_Shape Hole::makeThread(const gp_Vec& xDir, const gp_Vec& zDir, double len } double helixAngle = Tapered.getValue() ? TaperedAngle.getValue() - 90 : 0.0; - TopoDS_Shape helix = TopoShape().makeLongHelix(Pitch, helixLength, Dmaj, helixAngle, leftHanded); + TopoDS_Shape helix = TopoShape().makeLongHelix(Pitch, helixLength, Rmaj, helixAngle, leftHanded); gp_Pnt origo(0.0, 0.0, 0.0); gp_Dir dir_axis1(0.0, 0.0, 1.0); // pointing along the helix axis, as created. From f1192a12f984d19561d0230d2d5fe03234b9e035 Mon Sep 17 00:00:00 2001 From: Alfredo Monclus Date: Sat, 10 Aug 2024 13:50:16 -0300 Subject: [PATCH 07/11] fix(Test): sketcher external geometry removed test --- .../SketcherTests/TestSketcherSolver.py | 46 ++++++++----------- 1 file changed, 20 insertions(+), 26 deletions(-) diff --git a/src/Mod/Sketcher/SketcherTests/TestSketcherSolver.py b/src/Mod/Sketcher/SketcherTests/TestSketcherSolver.py index 0e92ad22ff..cdb8d6b1c1 100644 --- a/src/Mod/Sketcher/SketcherTests/TestSketcherSolver.py +++ b/src/Mod/Sketcher/SketcherTests/TestSketcherSolver.py @@ -482,31 +482,25 @@ class TestSketcherSolver(unittest.TestCase): def testRemovedExternalGeometryReference(self): body = self.Doc.addObject("PartDesign::Body", "Body") - sketch = self.Doc.addObject("Sketcher::SketchObject", "Sketch") + sketch = body.newObject("Sketcher::SketchObject", "Sketch") CreateRectangleSketch(sketch, (0, 0), (30, 30)) - pad = self.Doc.addObject("PartDesign::Pad", "Pad") + pad = body.newObject("PartDesign::Pad", "Pad") pad.Profile = sketch - sketch1 = self.Doc.addObject("Sketcher::SketchObject", "Sketch1") + sketch1 = body.newObject("Sketcher::SketchObject", "Sketch1") CreateCircleSketch(sketch1, (15, 15), 0.25) - body.addObject(sketch) - body.addObject(pad) - body.addObject(sketch1) self.Doc.recompute() + self.assertEqual(len(pad.Shape.Edges), 12) + hole = self.Doc.addObject("PartDesign::Hole", "Hole") hole.Refine = True + hole.Reversed = True body.addObject(hole) hole.Profile = sketch1 - hole.Diameter = 0.250000 - hole.Depth = 10.000000 hole.DrillPointAngle = 118.000000 - hole.TaperedAngle = 90.000000 hole.Diameter = 6.000000 - hole.Depth = 8.000000 - hole.DrillPointAngle = 118.000000 hole.TaperedAngle = 90.000000 hole.Tapered = 0 hole.Depth = 8.000000 - hole.DrillPointAngle = 118.000000 hole.Threaded = 1 hole.ModelThread = 0 hole.ThreadDepthType = 0 @@ -518,24 +512,24 @@ class TestSketcherSolver(unittest.TestCase): hole.DepthType = 0 hole.DrillPoint = 1 hole.DrillForDepth = 0 - hole.Tapered = 0 self.Doc.recompute() - self.assertEqual(len(hole.Shape.Edges), 12) - hole.Threaded = True - hole.ModelThread = True - # body.addObject(hole) # Commented out as this is a duplicate - # (already performed after hole = self.Doc.addObject("PartDesign::Hole", "Hole")) - # - sketch2 = self.Doc.addObject("Sketcher::SketchObject", "Sketch2") + # 15 edges if it's passthrough-flat 17 if DrillPoint = 1 + self.assertEqual(len(hole.Shape.Edges), 17) + + hole.ModelThread = 1 + sketch2 = body.newObject("Sketcher::SketchObject", "Sketch2") CreateRectangleSketch(sketch2, (0, 0), (3, 3)) - body.addObject(sketch2) self.Doc.recompute() - sketch2.addExternal("Hole", "Edge29") # Edge29 will disappear when we stop modeling threads - self.assertEqual(len(hole.Shape.Edges), 32) - hole.ModelThread = False - hole.Refine = True + self.assertGreater(len(hole.Shape.Edges), 17) + # 77 edges for basic profile + self.assertEqual(len(hole.Shape.Edges), 77) + + # Edges in the thread should disappear when we stop modeling thread + sketch2.addExternal("Hole", "Edge29") + hole.ModelThread = 0 + hole.Refine = 1 self.Doc.recompute() - self.assertEqual(len(hole.Shape.Edges), 12) + self.assertEqual(len(hole.Shape.Edges), 17) self.assertEqual(len(sketch2.ExternalGeometry), 0) def testSaveLoadWithExternalGeometryReference(self): From 8b61b96e18fddab6366c7c643a78bbadf5c3ca87 Mon Sep 17 00:00:00 2001 From: Alfredo Monclus Date: Thu, 8 Aug 2024 15:15:42 -0300 Subject: [PATCH 08/11] feat(PD): BSW threads --- src/Mod/PartDesign/App/FeatureHole.cpp | 93 +++++++++++++++---- src/Mod/PartDesign/App/FeatureHole.h | 6 ++ src/Mod/PartDesign/Gui/TaskHoleParameters.cpp | 1 + 3 files changed, 84 insertions(+), 16 deletions(-) diff --git a/src/Mod/PartDesign/App/FeatureHole.cpp b/src/Mod/PartDesign/App/FeatureHole.cpp index 180c050585..465821c3a3 100644 --- a/src/Mod/PartDesign/App/FeatureHole.cpp +++ b/src/Mod/PartDesign/App/FeatureHole.cpp @@ -67,7 +67,7 @@ namespace PartDesign { const char* Hole::DepthTypeEnums[] = { "Dimension", "ThroughAll", /*, "UpToFirst", */ nullptr }; const char* Hole::ThreadDepthTypeEnums[] = { "Hole Depth", "Dimension", "Tapped (DIN76)", nullptr }; -const char* Hole::ThreadTypeEnums[] = { "None", "ISOMetricProfile", "ISOMetricFineProfile", "UNC", "UNF", "UNEF", "NPT", "BSP", nullptr}; +const char* Hole::ThreadTypeEnums[] = { "None", "ISOMetricProfile", "ISOMetricFineProfile", "UNC", "UNF", "UNEF", "NPT", "BSP", "BSW", nullptr}; const char* Hole::ClearanceMetricEnums[] = { "Standard", "Close", "Wide", nullptr}; const char* Hole::ClearanceUTSEnums[] = { "Normal", "Close", "Loose", nullptr }; const char* Hole::DrillPointEnums[] = { "Flat", "Angled", nullptr}; @@ -427,20 +427,20 @@ const Hole::ThreadDescription Hole::threadDescription[][171] = // Parallel - ISO 228-1 // Tapered - ISO 7-1 { - { "1/16", 7.723, 0.907, 6.6 }, // G - { "1/8", 9.728, 0.907, 8.8 }, // 11/32 - { "1/4", 13.157, 1.337, 11.8 }, // 29/64 - { "3/8", 16.662, 1.337, 15.25 }, // 19/32 - { "1/2", 20.955, 1.814, 19.00 }, // 3/4 - { "5/8", 22.911, 1.814, 21.00 }, // 53/64 - { "3/4", 26.441, 1.814, 24.50 }, // 31/32 - { "7/8", 30.201, 1.814, 28.25 }, // 1 7/64 - { "1", 33.249, 2.309, 30.75 }, // 1 13/64 + { "1/16", 7.723, 0.907, 6.6 }, + { "1/8", 9.728, 0.907, 8.8 }, + { "1/4", 13.157, 1.337, 11.8 }, + { "3/8", 16.662, 1.337, 15.25 }, + { "1/2", 20.955, 1.814, 19.00 }, + { "5/8", 22.911, 1.814, 21.00 }, + { "3/4", 26.441, 1.814, 24.50 }, + { "7/8", 30.201, 1.814, 28.25 }, + { "1", 33.249, 2.309, 30.75 }, { "1 1/8", 37.897, 2.309, 0.0 }, - { "1 1/4", 41.910, 2.309, 39.50 }, // 1 35/64 - { "1 1/2", 47.803, 2.309, 45.50 }, // 1 25/32 - { "1 3/4", 53.743, 2.309, 51.00 }, // 2 - { "2", 59.614, 2.309, 57.00 }, // 2 1/4 + { "1 1/4", 41.910, 2.309, 39.50 }, + { "1 1/2", 47.803, 2.309, 45.50 }, + { "1 3/4", 53.743, 2.309, 51.00 }, + { "2", 59.614, 2.309, 57.00 }, { "2 1/4", 65.710, 2.309, 0.0 }, { "2 1/2", 75.184, 2.309, 0.0 }, { "2 3/4", 81.534, 2.309, 0.0 }, @@ -451,6 +451,40 @@ const Hole::ThreadDescription Hole::threadDescription[][171] = { "5", 138.430, 2.309, 0.0 }, { "5 1/2", 151.130, 2.309, 0.0 }, { "6", 163.830, 2.309, 0.0 }, + }, + /* BSW */ + // BS 84 Basic sizes + { + { "1/8", 3.175, 0.635, 2.55 }, + { "3/16", 4.762, 1.058, 3.70 }, + { "1/4", 6.350, 1.270, 5.10 }, + { "5/16", 7.938, 1.411, 6.50 }, + { "3/8", 9.525, 1.588, 7.90 }, + { "7/16", 11.113, 1.814, 9.30 }, + { "1/2", 12.700, 2.117, 10.50 }, + { "9/16", 14.290, 2.117, 12.10 }, + { "5/8", 15.876, 2.309, 13.50 }, + { "11/16", 17.463, 2.309, 15.00 }, + { "3/4", 19.051, 2.540, 16.25 }, + { "7/8", 22.226, 2.822, 19.25 }, + { "1", 25.400, 3.175, 22.00 }, + { "1 1/8", 28.576, 3.629, 24.75 }, + { "1 1/4", 31.751, 3.629, 28.00 }, + { "1 1/2", 38.100, 4.233, 33.50 }, + { "1 3/4", 44.452, 5.080, 39.00 }, + { "2", 50.802, 5.644, 44.50 }, + { "2 1/4", 57.152, 6.350, 0.0 }, + { "2 1/2", 63.502, 6.350, 0.0 }, + { "2 3/4", 69.853, 7.257, 0.0 }, + { "3", 76.203, 7.257, 0.0 }, + { "3 1/4", 82.553, 7.815, 0.0 }, + { "3 1/2", 88.903, 7.815, 0.0 }, + { "3 3/4", 95.254, 8.467, 0.0 }, + { "4", 101.604, 8.467, 0.0 }, + { "4 1/2", 114.304, 8.835, 0.0 }, + { "5", 127.005, 9.236, 0.0 }, + { "5 1/2", 139.705, 9.676, 0.0 }, + { "6", 152.406, 10.16, 0.0 }, } }; @@ -721,6 +755,16 @@ const char* Hole::ThreadSize_BSP_Enums[] = { "1/16", "1/8", "1/4", "3/8", "1/2 "3", "3 1/2", "4", "4 1/2", "5", "5 1/2", "6", nullptr }; +/* BSW */ +const char* Hole::HoleCutType_BSW_Enums[] = { "None", "Counterbore", "Countersink", "Counterdrill", nullptr}; +const char* Hole::ThreadSize_BSW_Enums[] = { "1/8", "3/16", "1/4", "5/16", "3/8", "7/16", + "1/2", "9/16", "5/8", "11/16", "3/4", "7/8", + "1", "1 1/8", "1 1/4", "1 1/2", "1 3/4", + "2", "2 1/4", "2 1/2", "2 3/4", + "3", "3 1/4", "3 1/2", "3 3/4", + "4", "4 1/2", "5", "5 1/2", "6", nullptr }; +const char* Hole::ThreadClass_BSW_Enums[] = { "Medium", "Normal", nullptr }; + const char* Hole::ThreadDirectionEnums[] = { "Right", "Left", nullptr}; PROPERTY_SOURCE(PartDesign::Hole, PartDesign::ProfileBased) @@ -1180,7 +1224,10 @@ std::optional Hole::determineDiameter() const if (threadDescription[threadType][threadSize].CoreHole > 0) { diameter = threadDescription[threadType][threadSize].CoreHole + clearance; } // if nothing is available, we must calculate - else if (threadTypeStr == "BSP") { + else if ( + threadTypeStr == "BSP" + || threadTypeStr == "BSW" + ) { double thread = 2 * (0.640327 * pitch); // truncation is allowed by ISO-228 and BS 84 diameter = diameter - thread * 0.75 + clearance; @@ -1477,6 +1524,20 @@ void Hole::onChanged(const App::Property* prop) ThreadDepthType.setReadOnly(!Threaded.getValue()); ThreadDepth.setReadOnly(!Threaded.getValue()); } + else if (type == "BSW") { + ThreadSize.setEnums(ThreadSize_BSW_Enums); + ThreadClass.setEnums(ThreadClass_BSW_Enums); + HoleCutType.setEnums(HoleCutType_BSW_Enums); + Threaded.setReadOnly(false); + ThreadSize.setReadOnly(false); + ThreadFit.setReadOnly(Threaded.getValue()); + Diameter.setReadOnly(true); + ModelThread.setReadOnly(!Threaded.getValue()); + UseCustomThreadClearance.setReadOnly(!Threaded.getValue() || !ModelThread.getValue()); + CustomThreadClearance.setReadOnly(!Threaded.getValue() || !ModelThread.getValue() || !UseCustomThreadClearance.getValue()); + ThreadDepthType.setReadOnly(!Threaded.getValue()); + ThreadDepth.setReadOnly(!Threaded.getValue()); + } if (holeCutTypeStr == "None") { HoleCutCustomValues.setReadOnly(true); @@ -2219,7 +2280,7 @@ TopoDS_Shape Hole::makeThread(const gp_Vec& xDir, const gp_Vec& zDir, double len BRepBuilderAPI_MakeWire mkThreadWire; double H; std::string threadTypeStr = ThreadType.getValueAsString(); - if (threadTypeStr == "BSP") { + if (threadTypeStr == "BSP" || threadTypeStr == "BSW") { H = 0.960491 * Pitch; // Height of Sharp V double radius = 0.137329 * Pitch; // radius of the crest // construct the cross section going counter-clockwise diff --git a/src/Mod/PartDesign/App/FeatureHole.h b/src/Mod/PartDesign/App/FeatureHole.h index e1ee95e69d..9390c2d4d4 100644 --- a/src/Mod/PartDesign/App/FeatureHole.h +++ b/src/Mod/PartDesign/App/FeatureHole.h @@ -160,6 +160,12 @@ private: static const char* HoleCutType_BSP_Enums[]; static const char* ThreadSize_BSP_Enums[]; + /* BSW profile */ + static const char* HoleCutType_BSW_Enums[]; + static const char* ThreadSize_BSW_Enums[]; + static const char* ThreadClass_BSW_Enums[]; + + static const double ThreadRunout[ThreadRunout_size][2]; /* Counter-xxx */ diff --git a/src/Mod/PartDesign/Gui/TaskHoleParameters.cpp b/src/Mod/PartDesign/Gui/TaskHoleParameters.cpp index 6be7519f89..33988bb337 100644 --- a/src/Mod/PartDesign/Gui/TaskHoleParameters.cpp +++ b/src/Mod/PartDesign/Gui/TaskHoleParameters.cpp @@ -68,6 +68,7 @@ TaskHoleParameters::TaskHoleParameters(ViewProviderHole* HoleView, QWidget* pare ui->ThreadType->addItem(tr("UTS extra fine profile"), QByteArray("UTS")); ui->ThreadType->addItem(tr("ANSI pipe profile"), QByteArray("NPT")); ui->ThreadType->addItem(tr("BSP pipe profile"), QByteArray("BSP")); + ui->ThreadType->addItem(tr("BSW whitworth profile"), QByteArray("BSW")); // read values from the hole properties auto pcHole = getObject(); From dc3d9522dec8bf94a8a2fef47b3fb6d31f3c8ae7 Mon Sep 17 00:00:00 2001 From: Alfredo Monclus Date: Tue, 13 Aug 2024 14:52:06 -0300 Subject: [PATCH 09/11] feat(PD): BSF threads --- src/Mod/PartDesign/App/FeatureHole.cpp | 64 ++++++++++++++++++- src/Mod/PartDesign/App/FeatureHole.h | 4 ++ src/Mod/PartDesign/Gui/TaskHoleParameters.cpp | 1 + 3 files changed, 67 insertions(+), 2 deletions(-) diff --git a/src/Mod/PartDesign/App/FeatureHole.cpp b/src/Mod/PartDesign/App/FeatureHole.cpp index 465821c3a3..2ea7f705a2 100644 --- a/src/Mod/PartDesign/App/FeatureHole.cpp +++ b/src/Mod/PartDesign/App/FeatureHole.cpp @@ -67,7 +67,7 @@ namespace PartDesign { const char* Hole::DepthTypeEnums[] = { "Dimension", "ThroughAll", /*, "UpToFirst", */ nullptr }; const char* Hole::ThreadDepthTypeEnums[] = { "Hole Depth", "Dimension", "Tapped (DIN76)", nullptr }; -const char* Hole::ThreadTypeEnums[] = { "None", "ISOMetricProfile", "ISOMetricFineProfile", "UNC", "UNF", "UNEF", "NPT", "BSP", "BSW", nullptr}; +const char* Hole::ThreadTypeEnums[] = { "None", "ISOMetricProfile", "ISOMetricFineProfile", "UNC", "UNF", "UNEF", "NPT", "BSP", "BSW", "BSF", nullptr}; const char* Hole::ClearanceMetricEnums[] = { "Standard", "Close", "Wide", nullptr}; const char* Hole::ClearanceUTSEnums[] = { "Normal", "Close", "Loose", nullptr }; const char* Hole::DrillPointEnums[] = { "Flat", "Angled", nullptr}; @@ -485,6 +485,41 @@ const Hole::ThreadDescription Hole::threadDescription[][171] = { "5", 127.005, 9.236, 0.0 }, { "5 1/2", 139.705, 9.676, 0.0 }, { "6", 152.406, 10.16, 0.0 }, + }, + /* BSF */ + // BS 84 Basic sizes + // BS 1157 for drill sizes + { + { "3/16", 4.763, 0.794, 4.00 }, + { "7/32", 5.558, 0.907, 4.60 }, + { "1/4", 6.350, 0.977, 5.30 }, + { "9/32", 7.142, 0.977, 6.10 }, + { "5/16", 7.938, 1.154, 6.80 }, + { "3/8", 9.525, 1.270, 8.30 }, + { "7/16", 11.113, 1.411, 9.70 }, + { "1/2", 12.700, 1.588, 11.10 }, + { "9/16", 14.288, 1.588, 12.70 }, + { "5/8", 15.875, 1.814, 14.00 }, + { "11/16", 17.463, 1.814, 15.50 }, + { "3/4", 19.050, 2.116, 16.75 }, + { "7/8", 22.225, 2.309, 19.75 }, + { "1", 25.400, 2.540, 22.75 }, + { "1 1/8", 28.575, 2.822, 25.50 }, + { "1 1/4", 31.750, 2.822, 28.50 }, + { "1 3/8", 34.925, 3.175, 31.50 }, + { "1 1/2", 38.100, 3.175, 34.50 }, + { "1 5/8", 41.275, 3.175, 0.0 }, + { "1 3/4", 44.450, 3.629, 0.0 }, + { "2", 50.800, 3.629, 0.0 }, + { "2 1/4", 57.150, 4.233, 0.0 }, + { "2 1/2", 63.500, 4.233, 0.0 }, + { "2 3/4", 69.850, 4.233, 0.0 }, + { "3", 76.200, 5.080, 0.0 }, + { "3 1/4", 82.550, 5.080, 0.0 }, + { "3 1/2", 88.900, 5.644, 0.0 }, + { "3 3/4", 95.250, 5.644, 0.0 }, + { "4", 101.600, 5.644, 0.0 }, + { "4 1/4", 107.950, 6.350, 0.0 }, } }; @@ -765,6 +800,16 @@ const char* Hole::ThreadSize_BSW_Enums[] = { "1/8", "3/16", "1/4", "5/16", "3/ "4", "4 1/2", "5", "5 1/2", "6", nullptr }; const char* Hole::ThreadClass_BSW_Enums[] = { "Medium", "Normal", nullptr }; +/* BSF */ +const char* Hole::HoleCutType_BSF_Enums[] = { "None", "Counterbore", "Countersink", "Counterdrill", nullptr}; +const char* Hole::ThreadSize_BSF_Enums[] = { "3/16", "7/32", "1/4", "9/32", "5/16", "3/8", "7/16", + "1/2", "9/16", "5/8", "11/16", "3/4", "7/8", + "1", "1 1/8", "1 1/4", "1 3/8", "1 1/2", "1 5/8", "1 3/4", + "2", "2 1/4", "2 1/2", "2 3/4", + "3", "3 1/4", "3 1/2", "3 3/4", + "4", "4 1/4", nullptr }; +const char* Hole::ThreadClass_BSF_Enums[] = { "Medium", "Normal", nullptr }; + const char* Hole::ThreadDirectionEnums[] = { "Right", "Left", nullptr}; PROPERTY_SOURCE(PartDesign::Hole, PartDesign::ProfileBased) @@ -1227,6 +1272,7 @@ std::optional Hole::determineDiameter() const else if ( threadTypeStr == "BSP" || threadTypeStr == "BSW" + || threadTypeStr == "BSF" ) { double thread = 2 * (0.640327 * pitch); // truncation is allowed by ISO-228 and BS 84 @@ -1538,6 +1584,20 @@ void Hole::onChanged(const App::Property* prop) ThreadDepthType.setReadOnly(!Threaded.getValue()); ThreadDepth.setReadOnly(!Threaded.getValue()); } + else if (type == "BSF") { + ThreadSize.setEnums(ThreadSize_BSF_Enums); + ThreadClass.setEnums(ThreadClass_BSF_Enums); + HoleCutType.setEnums(HoleCutType_BSF_Enums); + Threaded.setReadOnly(false); + ThreadSize.setReadOnly(false); + ThreadFit.setReadOnly(Threaded.getValue()); + Diameter.setReadOnly(true); + ModelThread.setReadOnly(!Threaded.getValue()); + UseCustomThreadClearance.setReadOnly(!Threaded.getValue() || !ModelThread.getValue()); + CustomThreadClearance.setReadOnly(!Threaded.getValue() || !ModelThread.getValue() || !UseCustomThreadClearance.getValue()); + ThreadDepthType.setReadOnly(!Threaded.getValue()); + ThreadDepth.setReadOnly(!Threaded.getValue()); + } if (holeCutTypeStr == "None") { HoleCutCustomValues.setReadOnly(true); @@ -2280,7 +2340,7 @@ TopoDS_Shape Hole::makeThread(const gp_Vec& xDir, const gp_Vec& zDir, double len BRepBuilderAPI_MakeWire mkThreadWire; double H; std::string threadTypeStr = ThreadType.getValueAsString(); - if (threadTypeStr == "BSP" || threadTypeStr == "BSW") { + if (threadTypeStr == "BSP" || threadTypeStr == "BSW" || threadTypeStr == "BSF") { H = 0.960491 * Pitch; // Height of Sharp V double radius = 0.137329 * Pitch; // radius of the crest // construct the cross section going counter-clockwise diff --git a/src/Mod/PartDesign/App/FeatureHole.h b/src/Mod/PartDesign/App/FeatureHole.h index 9390c2d4d4..aaba922623 100644 --- a/src/Mod/PartDesign/App/FeatureHole.h +++ b/src/Mod/PartDesign/App/FeatureHole.h @@ -165,6 +165,10 @@ private: static const char* ThreadSize_BSW_Enums[]; static const char* ThreadClass_BSW_Enums[]; + /* BSF profile */ + static const char* HoleCutType_BSF_Enums[]; + static const char* ThreadSize_BSF_Enums[]; + static const char* ThreadClass_BSF_Enums[]; static const double ThreadRunout[ThreadRunout_size][2]; diff --git a/src/Mod/PartDesign/Gui/TaskHoleParameters.cpp b/src/Mod/PartDesign/Gui/TaskHoleParameters.cpp index 33988bb337..06e55429d5 100644 --- a/src/Mod/PartDesign/Gui/TaskHoleParameters.cpp +++ b/src/Mod/PartDesign/Gui/TaskHoleParameters.cpp @@ -69,6 +69,7 @@ TaskHoleParameters::TaskHoleParameters(ViewProviderHole* HoleView, QWidget* pare ui->ThreadType->addItem(tr("ANSI pipe profile"), QByteArray("NPT")); ui->ThreadType->addItem(tr("BSP pipe profile"), QByteArray("BSP")); ui->ThreadType->addItem(tr("BSW whitworth profile"), QByteArray("BSW")); + ui->ThreadType->addItem(tr("BSF whitworth fine profile"), QByteArray("BSF")); // read values from the hole properties auto pcHole = getObject(); From ab971fba19184867fa27aee9fb49b41c3b091236 Mon Sep 17 00:00:00 2001 From: Alfredo Monclus Date: Wed, 7 Aug 2024 22:37:41 -0300 Subject: [PATCH 10/11] feat(PD): set the proper angle for threads and countersinks apply the recommended thread angle only if the user hasn't set an angle --- src/Mod/PartDesign/App/FeatureHole.cpp | 49 ++++++++++++++++++-------- src/Mod/PartDesign/App/FeatureHole.h | 2 ++ 2 files changed, 37 insertions(+), 14 deletions(-) diff --git a/src/Mod/PartDesign/App/FeatureHole.cpp b/src/Mod/PartDesign/App/FeatureHole.cpp index 2ea7f705a2..06770a4baf 100644 --- a/src/Mod/PartDesign/App/FeatureHole.cpp +++ b/src/Mod/PartDesign/App/FeatureHole.cpp @@ -1084,8 +1084,7 @@ void Hole::updateHoleCutParams() } } - else { // we have an UTS profile or none - + else { // we don't update for these settings but we need to set a value for new holes // furthermore we must assure the hole cut diameter is not <= the hole diameter // if we have a cut but the values are zero, we assume it is a new hole @@ -1103,17 +1102,10 @@ void Hole::updateHoleCutParams() else if (holeCutTypeStr == "Countersink" || holeCutTypeStr == "Counterdrill") { if (HoleCutDiameter.getValue() == 0.0 || HoleCutDiameter.getValue() <= diameterVal) { HoleCutDiameter.setValue(diameterVal * 1.7); - // 82 degrees for UTS, 90 otherwise - if (threadTypeStr != "None") - HoleCutCountersinkAngle.setValue(82.0); - else - HoleCutCountersinkAngle.setValue(90.0); + HoleCutCountersinkAngle.setValue(getCountersinkAngle()); } if (HoleCutCountersinkAngle.getValue() == 0.0) { - if (threadTypeStr != "None") - HoleCutCountersinkAngle.setValue(82.0); - else - HoleCutCountersinkAngle.setValue(90.0); + HoleCutCountersinkAngle.setValue(getCountersinkAngle()); } if (HoleCutDepth.getValue() == 0.0 && holeCutTypeStr == "Counterdrill") { HoleCutDepth.setValue(1.0); @@ -1125,6 +1117,23 @@ void Hole::updateHoleCutParams() } } +double Hole::getCountersinkAngle() const +{ + std::string threadTypeStr = ThreadType.getValueAsString(); + if ( + threadTypeStr == "BSW" + || threadTypeStr == "BSF" + ) + return 100.0; + if ( + threadTypeStr == "UNC" + || threadTypeStr == "UNF" + || threadTypeStr == "UNEF" + ) + return 82.0; + return 90.0; +} + double Hole::getThreadClassClearance() const { double pitch = getThreadPitch(); @@ -1425,6 +1434,12 @@ void Hole::updateDiameterParam() Diameter.setValue(opt.value()); } +double Hole::getThreadProfileAngle() +{ + // Both ISO 7-1 and ASME B1.20.1 define the same angle + return 90 - 1.79; +} + void Hole::onChanged(const App::Property* prop) { if (prop == &ThreadType) { @@ -1657,6 +1672,8 @@ void Hole::onChanged(const App::Property* prop) CustomThreadClearance.setReadOnly(!UseCustomThreadClearance.getValue()); ThreadDepthType.setReadOnly(false); ThreadDepth.setReadOnly(std::string(ThreadDepthType.getValueAsString()) != "Dimension"); + if (Tapered.getValue() && TaperedAngle.getValue() == 90) + TaperedAngle.setValue(getThreadProfileAngle()); } else { ThreadClass.setReadOnly(true); @@ -1691,11 +1708,15 @@ void Hole::onChanged(const App::Property* prop) } } else if (prop == &Tapered) { - if (Tapered.getValue()) + if (Tapered.getValue()) { TaperedAngle.setReadOnly(false); - else + if (Threaded.getValue() && TaperedAngle.getValue() == 90) + TaperedAngle.setValue(getThreadProfileAngle()); + } + else { + TaperedAngle.setValue(90); TaperedAngle.setReadOnly(true); - + } } else if (prop == &ThreadSize) { updateDiameterParam(); diff --git a/src/Mod/PartDesign/App/FeatureHole.h b/src/Mod/PartDesign/App/FeatureHole.h index aaba922623..8164c9a7dc 100644 --- a/src/Mod/PartDesign/App/FeatureHole.h +++ b/src/Mod/PartDesign/App/FeatureHole.h @@ -236,9 +236,11 @@ private: void updateThreadDepthParam(); void readCutDefinitions(); + double getCountersinkAngle() const; double getThreadClassClearance() const; double getThreadRunout(int mode = 1) const; double getThreadPitch() const; + double getThreadProfileAngle(); 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); From 9b0b2c606f10b19ed8a1d7ac5b4036d7b6944986 Mon Sep 17 00:00:00 2001 From: Alfredo Monclus Date: Sat, 14 Dec 2024 09:52:01 -0300 Subject: [PATCH 11/11] refactor(PD): rename CoreHole to TapDrill using a drill and cutting tap is not the only method to create a thread, and this sizes should be optional. i would prefer using the minor diameter of threads, leaving full thread depth and let the user adjust according to their needs using the custom clearance --- src/Mod/PartDesign/App/FeatureHole.cpp | 10 +++++----- src/Mod/PartDesign/App/FeatureHole.h | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Mod/PartDesign/App/FeatureHole.cpp b/src/Mod/PartDesign/App/FeatureHole.cpp index 06770a4baf..d4329b4a31 100644 --- a/src/Mod/PartDesign/App/FeatureHole.cpp +++ b/src/Mod/PartDesign/App/FeatureHole.cpp @@ -92,8 +92,8 @@ const Hole::ThreadDescription Hole::threadDescription[][171] = }, /* ISO metric regular */ - /* ISO metric threaded core hole diameters according to ISO 2306 */ - // {name, thread diameter, thread pitch, core hole diameter} + /* ISO metric threaded Tap-Drill diameters according to ISO 2306 */ + // {name, thread diameter, thread pitch, Tap-Drill diameter} { { "M1", 1.0, 0.25, 0.75 }, { "M1.1", 1.1, 0.25, 0.85 }, @@ -136,7 +136,7 @@ const Hole::ThreadDescription Hole::threadDescription[][171] = { "M64", 64.0, 6.00, 58.00 }, { "M68", 68.0, 6.00, 62.00 }, }, - /* ISO metric fine (core hole entry is calculated exactly by diameter - pitch) */ + /* ISO metric fine (drill = diameter - pitch) */ { { "M1x0.2", 1.0, 0.20, 0.80 }, { "M1.1x0.2", 1.1, 0.20, 0.90 }, @@ -1275,8 +1275,8 @@ std::optional Hole::determineDiameter() const // use normed diameters if possible std::string threadTypeStr = ThreadType.getValueAsString(); - if (threadDescription[threadType][threadSize].CoreHole > 0) { - diameter = threadDescription[threadType][threadSize].CoreHole + clearance; + if (threadDescription[threadType][threadSize].TapDrill > 0) { + diameter = threadDescription[threadType][threadSize].TapDrill + clearance; } // if nothing is available, we must calculate else if ( threadTypeStr == "BSP" diff --git a/src/Mod/PartDesign/App/FeatureHole.h b/src/Mod/PartDesign/App/FeatureHole.h index 8164c9a7dc..b239f44e1b 100644 --- a/src/Mod/PartDesign/App/FeatureHole.h +++ b/src/Mod/PartDesign/App/FeatureHole.h @@ -90,7 +90,7 @@ public: const char * designation; double diameter; double pitch; - double CoreHole; + double TapDrill; }; static const ThreadDescription threadDescription[][171];