From c11aaafc5424cb95d4370b83ef225d792a887520 Mon Sep 17 00:00:00 2001 From: Markus Lampert Date: Sat, 17 Aug 2019 19:27:11 -0700 Subject: [PATCH] Added support for imperial threads to thread milling --- src/Mod/Path/CMakeLists.txt | 2 +- .../Path/Data/Threads/imperial-internal.csv | 81 +++++++++++ src/Mod/Path/Data/Threads/metric-external.csv | 130 ------------------ src/Mod/Path/Data/Threads/sources.txt | 4 + .../panels/PageOpThreadMillingEdit.ui | 19 ++- src/Mod/Path/PathScripts/PathThreadMilling.py | 23 +++- .../Path/PathScripts/PathThreadMillingGui.py | 55 ++++++-- .../Path/PathTests/TestPathThreadMilling.py | 10 +- 8 files changed, 174 insertions(+), 150 deletions(-) create mode 100644 src/Mod/Path/Data/Threads/imperial-internal.csv delete mode 100644 src/Mod/Path/Data/Threads/metric-external.csv create mode 100644 src/Mod/Path/Data/Threads/sources.txt diff --git a/src/Mod/Path/CMakeLists.txt b/src/Mod/Path/CMakeLists.txt index 9844e431b8..6c9d692156 100644 --- a/src/Mod/Path/CMakeLists.txt +++ b/src/Mod/Path/CMakeLists.txt @@ -224,8 +224,8 @@ SET(Path_Images ) SET(PathData_Threads - Data/Threads/metric-external.csv Data/Threads/metric-internal.csv + Data/Threads/imperial-internal.csv ) SET(Path_Data diff --git a/src/Mod/Path/Data/Threads/imperial-internal.csv b/src/Mod/Path/Data/Threads/imperial-internal.csv new file mode 100644 index 0000000000..9a171490d9 --- /dev/null +++ b/src/Mod/Path/Data/Threads/imperial-internal.csv @@ -0,0 +1,81 @@ +name,tpi,class,dMinorMin,dMinorMax,dPitchMin,dPitchMax,dMajorMin,dMajorMax +0-80,80,2B,0.0465,0.0514,0.0519,0.0542,0.06,0.0633 +0-80,80,3B,0.0465,0.0514,0.0519,0.0536,0.06,0.0626 +1-64,64,2B,0.0561,0.0623,0.0629,0.0655,0.073,0.0768 +1-64,64,3B,0.0561,0.0623,0.0629,0.0648,0.073,0.076 +1-72,72,2B,0.058,0.0635,0.064,0.0665,0.073,0.0766 +1-72,72,3B,0.058,0.0635,0.064,0.0659,0.073,0.0759 +2-56,56,2B,0.0667,0.0737,0.0744,0.0772,0.086,0.0901 +2-56,56,3B,0.0667,0.0737,0.0744,0.0765,0.086,0.0893 +2-64,64,2B,0.0691,0.0753,0.0759,0.0786,0.086,0.0899 +2-64,64,3B,0.0691,0.0753,0.0759,0.0779,0.086,0.0891 +3-48,48,2B,0.0764,0.0845,0.0855,0.0885,0.099,0.1035 +3-48,48,3B,0.0764,0.0845,0.0855,0.0877,0.099,0.1026 +3-56,56,2B,0.0797,0.0865,0.0874,0.0902,0.099,0.1032 +3-56,56,3B,0.0797,0.0865,0.0874,0.0895,0.099,0.1024 +4-40,40,2B,0.0849,0.0939,0.0958,0.0991,0.112,0.1170 +4-40,40,3B,0.0849,0.0939,0.0958,0.0982,0.112,0.116 +4-48,48,2B,0.0894,0.0968,0.0985,0.1016,0.112,0.1167 +4-48,48,3B,0.0894,0.0968,0.0985,0.1008,0.112,0.1158 +5-40,40,2B,0.0979,0.1062,0.1088,0.1121,0.125,0.1301 +5-40,40,3B,0.0979,0.1062,0.1088,0.1113,0.125,0.1292 +5-44,44,2B,0.1004,0.1079,0.1102,0.1134,0.125,0.1299 +5-44,44,3B,0.1004,0.1079,0.1102,0.1126,0.125,0.129 +6-32,32,2B,0.104,0.114,0.1177,0.1214,0.138,0.1438 +6-32,32,3B,0.104,0.114,0.1177,0.1204,0.138,0.1426 +6-40,40,2B,0.111,0.119,0.1218,0.1252,0.138,0.1433 +6-40,40,3B,0.111,0.1186,0.1218,0.1243,0.138,0.1422 +8-32,32,2B,0.13,0.139,0.1437,0.1475,0.164,0.1700 +8-32,32,3B,0.13,0.1389,0.1437,0.1465,0.164,0.1689 +8-36,36,2B,0.134,0.142,0.146,0.1496,0.164,0.1697 +8-36,36,3B,0.134,0.1416,0.146,0.1487,0.164,0.1687 +10-24,24,2B,0.145,0.156,0.1629,0.1672,0.19,0.197 +10-24,24,3B,0.145,0.1555,0.1629,0.1661,0.19,0.1957 +10-32,32,2B,0.156,0.164,0.1697,0.1736,0.19,0.1963 +10-32,32,3B,0.156,0.1641,0.1697,0.1726,0.19,0.1952 +1/4-20,20,2B,0.196,0.207,0.2175,0.2248,0.25,0.261 +1/4-20,20,3B,0.196,0.207,0.2175,0.22,0.25,0.2554 +1/4-28,28,2B,0.211,0.22,0.2268,0.2311,0.25,0.2573 +1/4-28,28,3B,0.211,0.219,0.2268,0.23,0.25,0.2561 +5/16-18,18,2B,0.252,0.265,0.2764,0.2817,0.3125,0.3217 +5/16-18,18,3B,0.252,0.263,0.2764,0.2803,0.3125,0.3201 +5/16-24,24,2B,0.267,0.277,0.2854,0.2902,0.3125,0.3209 +5/16-24,24,3B,0.267,0.2754,0.2854,0.289,0.3125,0.3196 +3/8-16,16,2B,0.307,0.321,0.3344,0.3401,0.375,0.3852 +3/8-16,16,3B,0.307,0.3182,0.3344,0.3387,0.375,0.3836 +3/8-24,24,2B,0.33,0.34,0.3479,0.3528,0.375,0.3841 +3/8-24,24,3B,0.33,0.3372,0.3479,0.3516,0.375,0.3828 +7/16-14,14,2B,0.36,0.376,0.3911,0.3972,0.4375,0.4488 +7/16-14,14,3B,0.36,0.3717,0.3911,0.3957,0.4375,0.4471 +7/16-20,20,2B,0.383,0.395,0.405,0.4104,0.4375,0.4478 +7/16-20,20,3B,0.383,0.3916,0.405,0.4091,0.4375,0.4463 +1/2-13,13,2B,0.417,0.434,0.45,0.4565,0.5,0.5123 +1/2-13,13,3B,0.417,0.4284,0.45,0.4548,0.5,0.5104 +1/2-20,20,2B,0.446,0.457,0.4675,0.4731,0.5,0.5110 +1/2-20,20,3B,0.446,0.4537,0.4675,0.4717,0.5,0.5095 +5/8-11,11,2B,0.527,0.546,0.566,0.5732,0.625,0.6393 +5/8-11,11,3B,0.527,0.5391,0.566,0.5714,0.625,0.6373 +5/8-18,18,2B,0.565,0.578,0.5889,0.5949,0.625,0.6377 +5/8-18,18,3B,0.565,0.573,0.5889,0.5934,0.625,0.6361 +3/4-10,10,2B,0.642,0.663,0.685,0.6927,0.75,0.7660 +3/4-10,10,3B,0.642,0.6545,0.685,0.6907,0.75,0.7638 +3/4-16,16,2B,0.682,0.696,0.7094,0.7159,0.75,0.7644 +3/4-16,16,3B,0.682,0.6908,0.7094,0.7143,0.75,0.7627 +7/8-9,9,2B,0.755,0.778,0.8028,0.811,0.875,0.8928 +7/8-9,9,3B,0.755,0.7681,0.8028,0.8089,0.875,0.8905 +7/8-14,14,2B,0.798,0.814,0.8286,0.8356,0.875,0.8912 +7/8-14,14,3B,0.798,0.8068,0.8286,0.8339,0.875,0.8894 +1-8,8,2B,0.865,0.89,0.9188,0.9276,1,1.0197 +1-8,8,3B,0.865,0.8797,0.9188,0.9254,1,1.0173 +1-12,12,2B,0.91,0.928,0.9459,0.9535,1,1.0181 +1-12,12,3B,0.91,0.9198,0.9459,0.9516,1,1.0161 +11/8-7,7,2B,0.97,0.998,1.0322,1.0416,1.125,1.1466 +11/8-12,12,2B,1.035,1.053,1.0709,1.0787,1.125,1.1445 +11/4-7,7,2B,1.095,1.123,1.1572,1.1668,1.25,1.273 +11/4-12,12,2B,1.16,1.178,1.1959,1.2039,1.25,1.2709 +13/8-6,6,2B,1.195,1.225,1.2667,1.2771,1.375,1.4002 +13/8-12,12,2B,1.285,1.303,1.3209,1.3291,1.375,1.3974 +11/2-6,6,2B,1.32,1.35,1.3917,1.4022,1.5,1.5264 +11/2-12,12,2B,1.41,1.428,1.4459,1.4542,1.5,1.5237 +13/4-5,5,2B,1.534,1.568,1.6201,1.6317,1.75,1.7802 +2-6,6,2B,1.82,1.85,1.8917,1.9028,2,2.0319 diff --git a/src/Mod/Path/Data/Threads/metric-external.csv b/src/Mod/Path/Data/Threads/metric-external.csv deleted file mode 100644 index 24232aa7ed..0000000000 --- a/src/Mod/Path/Data/Threads/metric-external.csv +++ /dev/null @@ -1,130 +0,0 @@ -name,pitch,tol,dMinorMin,dMinorMax,dPitchMin,dPitchMax,dMajorMin,dMajorMax -M1.6 x 0.35,0.35,6g,1.581,1.496,1.354,1.291,1.202,1.075 -M1.6 x 0.35,0.35,6h,1.6,1.515,1.373,1.31,1.221,1.094 -M1.6 x 0.35,0.35,4g6g,1.581,1.496,1.354,1.314,1.202,1.098 -M2 x 0.4,0.4,6g,1.981,1.886,1.721,1.654,1.548,1.408 -M2 x 0.4,0.4,6h,2,1.905,1.74,1.673,1.567,1.427 -M2 x 0.4,0.4,4g6g,1.981,1.886,1.721,1.679,1.548,1.433 -M2.5 x 0.45,0.45,6g,2.48,2.38,2.188,2.117,1.993,1.84 -M2.5 x 0.45,0.45,6h,2.5,2.4,2.208,2.137,2.013,1.86 -M2.5 x 0.45,0.45,4g6g,2.48,2.38,2.188,2.143,1.993,1.866 -M3 x 0.5,0.5,6g,2.98,2.874,2.655,2.58,2.438,2.272 -M3 x 0.5,0.5,6h,3,2.894,2.675,2.6,2.458,2.292 -M3 x 0.5,0.5,4g6g,2.98,2.874,2.655,2.607,2.438,2.299 -M3.5 x 0.6,0.6,6g,3.479,3.354,3.089,3.004,2.829,2.634 -M3.5 x 0.6,0.6,6h,3.5,3.375,3.11,3.025,2.85,2.655 -M3.5 x 0.6,0.6,4g6g,3.479,3.354,3.089,3.036,2.829,2.666 -M4 x 0.7,0.7,6g,3.978,3.838,3.523,3.433,3.22,3.002 -M4 x 0.7,0.7,6h,4,3.86,3.545,3.455,3.242,3.024 -M4 x 0.7,0.7,4g6g,3.978,3.838,3.523,3.467,3.22,3.036 -M5 x 0.8,0.8,6g,4.976,4.826,4.456,4.361,4.11,3.868 -M5 x 0.8,0.8,6h,5,4.85,4.48,4.385,4.134,3.892 -M5 x 0.8,0.8,4g6g,4.976,4.826,4.456,4.396,4.11,3.903 -M6 x 1,1,6g,5.974,5.794,5.324,5.212,4.891,4.596 -M6 x 1,1,6h,6,5.82,5.35,5.238,4.917,4.622 -M6 x 1,1,4g6g,5.974,5.794,5.324,5.253,4.891,4.637 -M8 x 1.25,1.25,6g,7.972,7.76,7.16,7.042,6.619,6.272 -M8 x 1.25,1.25,6h,8,7.788,7.188,7.07,6.647,6.3 -M8 x 1.25,1.25,4g6g,7.972,7.76,7.16,7.085,6.619,6.315 -M8 x 1,1,6g,7.974,7.794,7.324,7.212,6.891,6.596 -M8 x 1,1,6h,8,7.82,7.35,7.238,6.917,6.622 -M8 x 1,1,4g6g,7.974,7.794,7.324,7.253,6.891,6.637 -M10 x 1.5,1.5,6g,9.968,9.732,8.994,8.862,8.344,7.938 -M10 x 1.5,1.5,6h,10,9.764,9.026,8.894,8.376,7.97 -M10 x 1.5,1.5,4g6g,9.968,9.732,8.994,8.909,8.344,7.985 -M10 x 1.25,1.25,6g,9.972,9.76,9.16,9.042,8.619,8.272 -M10 x 1.25,1.25,6h,10,9.788,9.188,9.07,8.647,8.3 -M10 x 1.25,1.25,4g6g,9.972,9.76,9.16,9.085,8.619,8.315 -M10 x 1,1,6g,9.974,9.794,9.324,9.212,8.891,8.596 -M10 x 1,1,6h,10,9.82,9.35,9.238,8.917,8.622 -M10 x 1,1,4g6g,9.974,9.794,9.324,9.253,8.891,8.637 -M10 x 0.75,0.75,6g,9.978,9.838,9.491,9.391,9.166,8.929 -M10 x 0.75,0.75,6h,10,9.86,9.513,9.413,9.188,8.951 -M10 x 0.75,0.75,4g6g,9.978,9.838,9.491,9.428,9.166,8.966 -M12 x 1.75,1.75,6g,11.966,11.701,10.829,10.679,10.071,9.601 -M12 x 1.75,1.75,6h,12,11.735,10.863,10.713,10.105,9.635 -M12 x 1.75,1.75,4g6g,11.966,11.701,10.829,10.734,10.071,9.656 -M12 x 1.5,1.5,6g,11.968,11.732,10.994,10.854,10.344,9.93 -M12 x 1.5,1.5,6h,12,11.764,11.026,10.886,10.376,9.962 -M12 x 1.5,1.5,4g6g,11.968,11.732,10.994,10.904,10.344,9.98 -M12 x 1.25,1.25,6g,11.972,11.76,11.16,11.028,10.619,10.258 -M12 x 1.25,1.25,6h,12,11.788,11.188,11.056,10.647,10.286 -M12 x 1.25,1.25,4g6g,11.972,11.76,11.16,11.075,10.619,10.305 -M12 x 1,1,6g,11.974,11.794,11.324,11.206,10.891,10.59 -M12 x 1,1,6h,12,11.82,11.35,11.232,10.917,10.616 -M12 x 1,1,4g6g,11.974,11.794,11.324,11.249,10.891,10.633 -M14 x 2,2,6g,13.962,13.682,12.663,12.503,11.797,11.271 -M14 x 2,2,6h,14,13.72,12.701,12.541,11.835,11.309 -M14 x 2,2,4g6g,13.962,13.682,12.663,12.563,11.797,11.331 -M14 x 1.5,1.5,6g,13.968,13.732,12.994,12.854,12.344,11.93 -M14 x 1.5,1.5,6h,14,13.764,13.026,12.886,12.376,11.962 -M14 x 1.5,1.5,4g6g,13.968,13.732,12.994,12.904,12.344,11.98 -M15 x 1,1,6g,14.974,14.794,14.324,14.206,13.891,13.59 -M15 x 1,1,6h,15,14.82,14.35,14.232,13.917,13.616 -M15 x 1,1,4g6g,14.974,14.794,14.324,14.249,13.891,13.633 -M16 x 2,2,6g,15.962,15.682,14.663,14.503,13.797,13.271 -M16 x 2,2,6h,16,15.72,14.701,14.541,13.835,13.309 -M16 x 2,2,4g6g,15.962,15.682,14.663,14.563,13.797,13.331 -M16 x 1.5,1.5,6g,15.968,15.732,14.994,14.854,14.344,13.93 -M16 x 1.5,1.5,6h,16,15.764,15.026,14.886,14.376,13.962 -M16 x 1.5,1.5,4g6g,15.968,15.732,14.994,14.904,14.344,13.98 -M17 x 1,1,6g,16.974,16.794,16.324,16.206,15.891,15.59 -M17 x 1,1,6h,17,16.82,16.35,16.232,15.917,15.616 -M17 x 1,1,4g6g,16.974,16.794,16.324,16.249,15.891,15.633 -M18 x 1.5 ,1.5,6g,17.968,17.732,16.994,16.854,16.344,15.93 -M18 x 1.5 ,1.5,6h,18,17.764,17.026,16.886,16.376,15.962 -M18 x 1.5 ,1.5,4g6g,17.968,17.732,16.994,16.904,16.344,15.98 -M20 x 2.5,2.5,6g,19.958,19.623,18.334,18.164,17.251,16.624 -M20 x 2.5,2.5,6h,20,19.665,18.376,18.206,17.293,16.666 -M20 x 2.5,2.5,4g6g,19.958,19.623,18.334,18.228,17.251,16.688 -M20 x 1.5,1.5,6g,19.968,19.732,18.994,18.854,18.344,17.93 -M20 x 1.5,1.5,6h,20,19.764,19.026,18.886,18.376,17.962 -M20 x 1.5,1.5,4g6g,19.968,19.732,18.994,18.904,18.344,17.98 -M20 x 1,1,6g,19.974,19.794,19.324,19.206,18.891,18.59 -M20 x 1,1,6h,20,19.82,19.35,19.232,18.917,18.616 -M20 x 1,1,4g6g,19.974,19.794,19.324,19.249,18.891,18.633 -M22 x 2.5,2.5,6g,21.958,21.623,20.334,20.164,19.251,18.624 -M22 x 2.5,2.5,6h,22,21.665,20.376,20.206,19.293,18.666 -M22 x 1.5,1.5,6g,21.968,21.732,20.994,20.854,20.344,19.93 -M22 x 1.5,1.5,6h,22,21.764,21.026,20.886,20.376,19.962 -M22 x 1.5,1.5,4g6g,21.968,21.732,20.994,20.904,20.344,19.98 -M24 x 3,3,6g,23.952,23.577,22.003,21.803,20.704,19.955 -M24 x 3,3,6h,24,23.625,22.051,21.851,20.752,20.003 -M24 x 3,3,4g6g,23.952,23.577,22.003,21.878,20.704,20.03 -M24 x 2,2,6g,23.962,23.682,22.663,22.493,21.797,21.261 -M24 x 2,2,6h,24,23.72,22.701,22.531,21.835,21.299 -M24 x 2,2,4g6g,23.962,23.682,22.663,22.557,21.797,21.325 -M25 x 1.5,1.5,6g,24.968,24.732,23.994,23.844,23.344,22.92 -M25 x 1.5,1.5,6h,25,24.764,24.026,23.876,23.376,22.952 -M25 x 1.5,1.5,4g6g,24.968,24.732,23.994,23.899,23.344,22.975 -M27 x 3,3,6g,26.952,26.577,25.003,24.803,23.704,22.955 -M27 x 3,3,6h,27,26.625,25.051,24.851,23.752,23.003 -M27 x 2,2,6g,26.962,26.682,25.663,25.493,24.797,24.261 -M27 x 2,2,6h,27,26.72,25.701,25.531,24.835,24.299 -M27 x 2,2,4g6g,26.962,26.682,25.663,25.557,24.797,24.325 -M30 x 3.5,3.5,6g,29.947,29.522,27.674,27.462,26.158,25.306 -M30 x 3.5,3.5,6h,30,29.575,27.727,27.515,26.211,25.359 -M30 x 3.5,3.5,4g6g,29.947,29.522,27.674,27.542,26.158,25.386 -M30 x 2,2,6g,29.962,29.682,28.663,28.493,27.797,27.261 -M30 x 2,2,6h,30,29.72,28.701,28.531,27.835,27.299 -M30 x 2,2,4g6g,29.962,29.682,28.663,28.557,27.797,27.325 -M30 x 1.5,1.5,6g,29.968,29.732,28.994,28.844,28.344,27.92 -M30 x 1.5,1.5,6h,30,29.764,29.026,28.876,28.376,27.952 -M30 x 1.5,1.5,4g6g,29.968,29.732,28.994,28.899,28.344,27.975 -M33 x 2,2,6g,32.962,32.682,31.663,31.493,30.797,30.261 -M33 x 2,2,6h,33,32.72,31.701,31.531,30.835,30.299 -M33 x 2,2,4g6g,32.962,32.682,31.663,31.557,30.797,30.325 -M35 x 1.5,1.5,6g,34.968,34.732,33.994,33.844,33.344,32.92 -M35 x 1.5,1.5,6h,35,34.764,34.026,33.876,33.376,32.952 -M36 x 4,4,6g,35.94,35.465,33.342,33.118,31.61,30.654 -M36 x 4,4,6h,36,35.525,33.402,33.178,31.67,30.714 -M36 x 4,4,4g6g,35.94,35.465,33.342,33.202,31.61,30.738 -M36 x 2,2,6g,35.962,35.682,34.663,34.493,33.797,33.261 -M36 x 2,2,6h,36,35.72,34.701,34.531,33.835,33.299 -M36 x 2,2,4g6g,35.962,35.682,34.663,34.557,33.797,33.325 -M39 x 2,2,6g,38.962,38.682,37.663,37.493,36.797,36.261 -M39 x 2,2,6h,39,38.72,37.701,37.531,36.835,36.299 -M39 x 2,2,4g6g,38.962,38.682,37.663,37.557,36.797,36.325 -M40 x 1.5,1.5,6g,39.968,39.732,38.994,38.844,38.344,37.92 -M40 x 1.5,1.5,6h,40,39.764,39.026,38.876,38.376,37.952 -M40 x 1.5,1.5,4g6g,39.968,39.732,38.994,38.899,38.344,37.975 diff --git a/src/Mod/Path/Data/Threads/sources.txt b/src/Mod/Path/Data/Threads/sources.txt new file mode 100644 index 0000000000..20fb5e92fd --- /dev/null +++ b/src/Mod/Path/Data/Threads/sources.txt @@ -0,0 +1,4 @@ +https://www.amesweb.info/Screws/Internal-Metric-Thread-Dimensions-Chart.aspx +https://www.engineersedge.com/thread_strength/internal_screw_threads_chart.htm + dMajorMax = dMajorMin * 1.01 * (dMinorMax - dMinorMin) + formula empirically derived from metric tolerances diff --git a/src/Mod/Path/Gui/Resources/panels/PageOpThreadMillingEdit.ui b/src/Mod/Path/Gui/Resources/panels/PageOpThreadMillingEdit.ui index 423c9fbabb..f67744b714 100644 --- a/src/Mod/Path/Gui/Resources/panels/PageOpThreadMillingEdit.ui +++ b/src/Mod/Path/Gui/Resources/panels/PageOpThreadMillingEdit.ui @@ -82,6 +82,9 @@ + + 100 + 50 @@ -119,7 +122,7 @@ - + Pitch @@ -132,6 +135,20 @@ + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + TPI + + + diff --git a/src/Mod/Path/PathScripts/PathThreadMilling.py b/src/Mod/Path/PathScripts/PathThreadMilling.py index db226dfeb0..f7d7fdb58b 100644 --- a/src/Mod/Path/PathScripts/PathThreadMilling.py +++ b/src/Mod/Path/PathScripts/PathThreadMilling.py @@ -31,6 +31,7 @@ import PathScripts.PathGeom as PathGeom import PathScripts.PathLog as PathLog import PathScripts.PathOp as PathOp import PathScripts.PathUtils as PathUtils +import math from PySide import QtCore @@ -47,14 +48,20 @@ def translate(context, text, disambig=None): return QtCore.QCoreApplication.translate(context, text, disambig) -def radiiMetricInternal(majorDia, minorDia, toolDia, toolCrest = None): +def radiiInternal(majorDia, minorDia, toolDia, toolCrest = None): '''internlThreadRadius(majorDia, minorDia, toolDia, toolCrest) ... returns the maximum radius for thread.''' PathLog.track(majorDia, minorDia, toolDia, toolCrest) if toolCrest is None: toolCrest = 0.0 - # see https://www.amesweb.info/Screws/Internal-Metric-Thread-Dimensions-Chart.aspx + # As it turns out metric and imperial standard threads follow the same rules. + # The determining factor is the height of the full 60 degree triangle H. + # - The minor diameter is 1/4 * H smaller than the pitch diameter. + # - The major diameter is 3/8 * H bigger than the pitch diameter + # Since we already have the outer diameter it's simpler to just add 1/8 * H + # to get the outer tip of the thread. H = ((majorDia - minorDia) / 2.0 ) * 1.6 # (D - d)/2 = 5/8 * H outerTip = majorDia / 2.0 + H / 8.0 + # Compensate for the crest of the tool toolTip = outerTip - toolCrest * 0.8660254037844386 # math.sqrt(3)/2 ... 60deg triangle height return ((minorDia - toolDia) / 2, toolTip - toolDia / 2) @@ -161,11 +168,12 @@ class ObjectThreadMilling(PathCircularHoleBase.ObjectOp): RightHand = 'RightHand' ThreadTypeCustom = 'Custom' ThreadTypeMetricInternal = 'Metric - internal' + ThreadTypeImperialInternal = 'Imperial - internal' DirectionClimb = 'Climb' DirectionConventional = 'Conventional' ThreadOrientations = [LeftHand, RightHand] - ThreadTypes = [ThreadTypeCustom, ThreadTypeMetricInternal] + ThreadTypes = [ThreadTypeCustom, ThreadTypeMetricInternal, ThreadTypeImperialInternal] Directions = [DirectionClimb, DirectionConventional] def circularHoleFeatures(self, obj): @@ -179,7 +187,8 @@ class ObjectThreadMilling(PathCircularHoleBase.ObjectOp): obj.addProperty("App::PropertyString", "ThreadName", "Thread", QtCore.QT_TRANSLATE_NOOP("App::Property", "Devfines which standard thread was chosen")) obj.addProperty("App::PropertyLength", "MajorDiameter", "Thread", QtCore.QT_TRANSLATE_NOOP("App::Property", "Set thread's major diameter")) obj.addProperty("App::PropertyLength", "MinorDiameter", "Thread", QtCore.QT_TRANSLATE_NOOP("App::Property", "Set thread's minor diameter")) - obj.addProperty("App::PropertyLength", "Pitch", "Thread", QtCore.QT_TRANSLATE_NOOP("App::Property", "Set thread's pitch")) + obj.addProperty("App::PropertyLength", "Pitch", "Thread", QtCore.QT_TRANSLATE_NOOP("App::Property", "Set thread's pitch - used for metric threads")) + obj.addProperty("App::PropertyInteger", "TPI", "Thread", QtCore.QT_TRANSLATE_NOOP("App::Property", "Set thread's tpi - used for imperial threads")) obj.addProperty("App::PropertyInteger", "ThreadFit", "Thread", QtCore.QT_TRANSLATE_NOOP("App::Property", "Set how many passes are used to cut the thread")) obj.addProperty("App::PropertyInteger", "Passes", "Operation", QtCore.QT_TRANSLATE_NOOP("App::Property", "Set how many passes are used to cut the thread")) obj.addProperty("App::PropertyEnumeration", "Direction", "Operation", QtCore.QT_TRANSLATE_NOOP("App::Property", "Direction of thread cutting operation")) @@ -254,7 +263,7 @@ class ObjectThreadMilling(PathCircularHoleBase.ObjectOp): self.commandlist.append(Path.Command('G0', {'Z': obj.ClearanceHeight.Value, 'F': self.vertRapid})) - for radius in threadPasses(obj.Passes, radiiMetricInternal, obj.MajorDiameter.Value, obj.MinorDiameter.Value, self.tool.Diameter, 0): + for radius in threadPasses(obj.Passes, radiiInternal, obj.MajorDiameter.Value, obj.MinorDiameter.Value, self.tool.Diameter, 0): commands = internalThreadCommands(loc, gcode, zStart, zFinal, pitch, radius, obj.LeadInOut) for cmd in commands: p = cmd.Parameters @@ -274,6 +283,8 @@ class ObjectThreadMilling(PathCircularHoleBase.ObjectOp): (cmd, zStart, zFinal) = self.threadSetup(obj) pitch = obj.Pitch.Value + if obj.TPI > 0: + pitch = 25.4 / obj.TPI if pitch <= 0: PathLog.error("Cannot create thread with pitch {}".format(pitch)) return @@ -288,6 +299,7 @@ class ObjectThreadMilling(PathCircularHoleBase.ObjectOp): obj.ThreadType = self.ThreadTypeMetricInternal obj.ThreadFit = 50 obj.Pitch = 1 + obj.TPI = 0 obj.Passes = 1 obj.Direction = self.DirectionClimb obj.LeadInOut = True @@ -302,6 +314,7 @@ def SetupProperties(): setup.append("MajorDiameter") setup.append("MinorDiameter") setup.append("Pitch") + setup.append("TPI") setup.append("Passes") setup.append("Direction") setup.append("LeadInOut") diff --git a/src/Mod/Path/PathScripts/PathThreadMillingGui.py b/src/Mod/Path/PathScripts/PathThreadMillingGui.py index 846a5b6e5f..9a3e55930e 100644 --- a/src/Mod/Path/PathScripts/PathThreadMillingGui.py +++ b/src/Mod/Path/PathScripts/PathThreadMillingGui.py @@ -86,6 +86,7 @@ class TaskPanelOpPage(PathCircularHoleBaseGui.TaskPanelOpPage): obj.Direction = self.form.opDirection.currentText() obj.Passes = self.form.opPasses.value() obj.LeadInOut = self.form.leadInOut.checkState() == QtCore.Qt.Checked + obj.TPI = self.form.threadTPI.value() self.updateToolController(obj, self.form.toolController) @@ -102,6 +103,7 @@ class TaskPanelOpPage(PathCircularHoleBaseGui.TaskPanelOpPage): self.form.threadName.setCurrentText(obj.ThreadName) self.form.threadType.blockSignals(False) self.form.threadName.blockSignals(False) + self.form.threadTPI.setValue(obj.TPI) self.form.opPasses.setValue(obj.Passes) self.form.opDirection.setCurrentText(obj.Direction) @@ -114,30 +116,65 @@ class TaskPanelOpPage(PathCircularHoleBaseGui.TaskPanelOpPage): self.setupToolController(obj, self.form.toolController) + def _isThreadMetric(self): + return self.form.threadType.currentText() == PathThreadMilling.ObjectThreadMilling.ThreadTypeMetricInternal + + def _isThreadImperial(self): + return self.form.threadType.currentText() == PathThreadMilling.ObjectThreadMilling.ThreadTypeImperialInternal def _updateFromThreadType(self): - if self.form.threadType.currentIndex() == 0: - PathLog.track(self.form.threadType.currentIndex()) + + if self.form.threadType.currentText() == PathThreadMilling.ObjectThreadMilling.ThreadTypeCustom: self.form.threadName.setEnabled(False) self.form.threadFit.setEnabled(False) self.form.threadFitLabel.setEnabled(False) - else: - PathLog.track(self.form.threadType.currentIndex()) + self.form.threadPitch.setEnabled(True) + self.form.threadPitchLabel.setEnabled(True) + self.form.threadTPI.setEnabled(True) + self.form.threadTPILabel.setEnabled(True) + + if self._isThreadMetric(): self.form.threadFit.setEnabled(True) self.form.threadFitLabel.setEnabled(True) + self.form.threadPitch.setEnabled(True) + self.form.threadPitchLabel.setEnabled(True) + self.form.threadTPI.setEnabled(False) + self.form.threadTPILabel.setEnabled(False) + self.form.threadTPI.setValue(0) fillThreads(self.form.threadName, 'metric-internal') + if self._isThreadImperial(): + self.form.threadFit.setEnabled(True) + self.form.threadFitLabel.setEnabled(True) + self.form.threadPitch.setEnabled(False) + self.form.threadPitchLabel.setEnabled(False) + self.form.threadTPI.setEnabled(True) + self.form.threadTPILabel.setEnabled(True) + self.pitch.updateSpinBox(0) + fillThreads(self.form.threadName, 'imperial-internal') + def _updateFromThreadName(self): thread = self.form.threadName.currentData() + fit = float(self.form.threadFit.value()) / 100 mamin = float(thread['dMajorMin']) mamax = float(thread['dMajorMax']) + major = mamin + (mamax - mamin) * fit mimin = float(thread['dMinorMin']) mimax = float(thread['dMinorMax']) - pitch = float(thread['pitch']) + minor = mimin + (mimax - mimin) * fit - self.pitch.updateSpinBox(pitch) - self.majorDia.updateSpinBox((mamin + mamax) / 2) - self.minorDia.updateSpinBox((mimin + mimax) / 2) + if self._isThreadMetric(): + pitch = float(thread['pitch']) + self.pitch.updateSpinBox(pitch) + + if self._isThreadImperial(): + tpi = int(thread['tpi']) + self.form.threadTPI.setValue(tpi) + minor = minor * 25.4 + major = major * 25.4 + + self.majorDia.updateSpinBox(major) + self.minorDia.updateSpinBox(minor) self.setDirty() @@ -149,6 +186,7 @@ class TaskPanelOpPage(PathCircularHoleBaseGui.TaskPanelOpPage): signals.append(self.form.threadMinor.editingFinished) signals.append(self.form.threadPitch.editingFinished) signals.append(self.form.threadOrientation.currentIndexChanged) + signals.append(self.form.threadTPI.editingFinished) signals.append(self.form.opDirection.currentIndexChanged) signals.append(self.form.opPasses.editingFinished) signals.append(self.form.leadInOut.stateChanged) @@ -160,6 +198,7 @@ class TaskPanelOpPage(PathCircularHoleBaseGui.TaskPanelOpPage): def registerSignalHandlers(self, obj): self.form.threadType.currentIndexChanged.connect(self._updateFromThreadType) self.form.threadName.currentIndexChanged.connect(self._updateFromThreadName) + self.form.threadFit.valueChanged.connect(self._updateFromThreadName) Command = PathOpGui.SetupOperation('Thread Milling', diff --git a/src/Mod/Path/PathTests/TestPathThreadMilling.py b/src/Mod/Path/PathTests/TestPathThreadMilling.py index 8d62c1bf6f..e8ac9c8a65 100644 --- a/src/Mod/Path/PathTests/TestPathThreadMilling.py +++ b/src/Mod/Path/PathTests/TestPathThreadMilling.py @@ -45,13 +45,13 @@ class TestPathThreadMilling(PathTestBase): self.assertRoughly(have[i], want[i]) def test00(self): - '''Verify metric internal radii.''' - self.assertRadii(PathThreadMilling.radiiMetricInternal(20, 18, 2, 0), (8, 9.2)) - self.assertRadii(PathThreadMilling.radiiMetricInternal(20, 19, 2, 0), (8.5, 9.1)) + '''Verify internal radii.''' + self.assertRadii(PathThreadMilling.radiiInternal(20, 18, 2, 0), (8, 9.2)) + self.assertRadii(PathThreadMilling.radiiInternal(20, 19, 2, 0), (8.5, 9.1)) def test01(self): - '''Verify metric internal radii with tool crest.''' - self.assertRadii(PathThreadMilling.radiiMetricInternal(20, 18, 2, 0.1), (8, 9.113397)) + '''Verify internal radii with tool crest.''' + self.assertRadii(PathThreadMilling.radiiInternal(20, 18, 2, 0.1), (8, 9.113397)) def test10(self): '''Verify thread passes.'''