From b29d168132c62fe669a6f7a76ec2c635ad85ec7b Mon Sep 17 00:00:00 2001 From: Markus Lampert Date: Mon, 12 Aug 2019 22:19:27 -0700 Subject: [PATCH] Add basic thread milling op --- src/Mod/Path/CMakeLists.txt | 17 + src/Mod/Path/Data/Threads/metric-external.csv | 130 ++ src/Mod/Path/Data/Threads/metric-internal.csv | 82 + src/Mod/Path/Gui/Resources/Path.qrc | 2 + .../Resources/icons/Path_ThreadMilling.svg | 1616 +++++++++++++++++ .../panels/PageOpThreadMillingEdit.ui | 242 +++ src/Mod/Path/InitGui.py | 4 + .../Path/PathScripts/PathCircularHoleBase.py | 17 + src/Mod/Path/PathScripts/PathGuiInit.py | 1 + src/Mod/Path/PathScripts/PathSelection.py | 10 +- src/Mod/Path/PathScripts/PathThreadMilling.py | 121 ++ .../Path/PathScripts/PathThreadMillingGui.py | 167 ++ 12 files changed, 2403 insertions(+), 6 deletions(-) create mode 100644 src/Mod/Path/Data/Threads/metric-external.csv create mode 100644 src/Mod/Path/Data/Threads/metric-internal.csv create mode 100644 src/Mod/Path/Gui/Resources/icons/Path_ThreadMilling.svg create mode 100644 src/Mod/Path/Gui/Resources/panels/PageOpThreadMillingEdit.ui create mode 100644 src/Mod/Path/PathScripts/PathThreadMilling.py create mode 100644 src/Mod/Path/PathScripts/PathThreadMillingGui.py diff --git a/src/Mod/Path/CMakeLists.txt b/src/Mod/Path/CMakeLists.txt index 7046290c7b..9844e431b8 100644 --- a/src/Mod/Path/CMakeLists.txt +++ b/src/Mod/Path/CMakeLists.txt @@ -223,6 +223,15 @@ SET(Path_Images ${PathImages_Tools} ) +SET(PathData_Threads + Data/Threads/metric-external.csv + Data/Threads/metric-internal.csv +) + +SET(Path_Data + ${PathData_Threads} +) + SET(all_files ${PathScripts_SRCS} ${PathScripts_post_SRCS} @@ -230,6 +239,7 @@ SET(all_files ${Tools_Library_SRCS} ${Tools_Shape_SRCS} ${Path_Images} + ${Path_Data} ) ADD_CUSTOM_TARGET(PathScripts ALL @@ -304,3 +314,10 @@ INSTALL( Mod/Path/Images/Tools ) +INSTALL( + FILES + ${PathData_Threads} + DESTINATION + Mod/Path/Data/Threads +) + diff --git a/src/Mod/Path/Data/Threads/metric-external.csv b/src/Mod/Path/Data/Threads/metric-external.csv new file mode 100644 index 0000000000..24232aa7ed --- /dev/null +++ b/src/Mod/Path/Data/Threads/metric-external.csv @@ -0,0 +1,130 @@ +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/metric-internal.csv b/src/Mod/Path/Data/Threads/metric-internal.csv new file mode 100644 index 0000000000..6a821334d5 --- /dev/null +++ b/src/Mod/Path/Data/Threads/metric-internal.csv @@ -0,0 +1,82 @@ +name,pitch,tol,dMinorMin,dMinorMax,dPitchMin,dPitchMax,dMajorMin,dMajorMax +M1.6 x 0.35,0.35,6H,1.221,1.321,1.373,1.458,1.6,1.736 +M2 x 0.4,0.4,6H,1.567,1.679,1.74,1.83,2,2.148 +M2.5 x 0.45,0.45,6H,2.013,2.138,2.208,2.303,2.5,2.66 +M3 x 0.5,0.5,6H,2.459,2.599,2.675,2.775,3,3.172 +M3.5 x 0.6,0.6,6H,2.85,3.01,3.11,3.222,3.5,3.698 +M4 x 0.7,0.7,6H,3.242,3.422,3.545,3.663,4,4.219 +M5 x 0.8,0.8,6H,4.134,4.334,4.48,4.605,5,5.24 +M6 x 1,1,6H,4.917,5.153,5.35,5.5,6,6.294 +M8 x 1,1,6H,6.917,7.153,7.35,7.5,8,8.294 +M8 x 1.25,1.25,6H,6.647,6.912,7.188,7.348,8,8.34 +M10 x 0.75,0.75,6H,9.188,9.378,9.513,9.645,10,10.24 +M10 x 1,1,6H,8.917,9.153,9.35,9.5,10,10.294 +M10 x 1.25,1.25,6H,8.647,8.912,9.188,9.348,10,10.34 +M10 x 1.5,1.5,6H,8.376,8.676,9.026,9.206,10,10.397 +M12 x 1,1,6H,10.917,11.153,11.35,11.51,12,12.304 +M12 x 1.25,1.25,6H,10.647,10.912,11.188,11.368,12,12.36 +M12 x 1.5,1.5,6H,10.376,10.676,11.026,11.216,12,12.407 +M12 x 1.75,1.75,6H,10.106,10.441,10.863,11.063,12,12.452 +M14 x 1.5,1.5,6H,12.376,12.676,13.026,13.216,14,14.407 +M14 x 2,2,6H,11.835,12.21,12.701,12.913,14,14.501 +M15 x 1,1,6H,13.917,14.153,14.35,14.51,15,15.304 +M16 x 1.5,1.5,6H,14.376,14.676,15.026,15.216,16,16.407 +M16 x 2,2,6H,13.835,14.21,14.701,14.913,16,16.501 +M17 x 1,1,6H,15.917,16.153,16.35,16.51,17,17.304 +M18 x 1.5 ,1.5,6H,16.376,16.676,17.026,17.216,18,18.407 +M20 x 1,1,6H,18.917,19.153,19.35,19.51,20,20.304 +M20 x 1.5,1.5,6H,18.376,18.676,19.026,19.216,20,20.407 +M20 x 2.5,2.5,6H,17.294,17.744,18.376,18.6,20,20.585 +M22 x 1.5,1.5,6H,20.376,20.676,21.026,21.216,22,22.407 +M22 x 2.5,2.5,6H,19.294,19.744,20.376,20.6,22,22.585 +M24 x 2,2,6H,21.835,22.21,22.701,22.925,24,24.513 +M24 x 3,3,6H,20.752,21.252,22.051,22.316,24,24.698 +M25 x 1.5,1.5,6H,23.376,23.676,24.026,24.226,25,25.417 +M27 x 2,2,6H,24.835,25.21,25.701,25.925,27,27.513 +M27 x 3,3,6H,23.752,24.252,25.051,25.316,27,27.698 +M30 x 1.5,1.5,6H,28.376,28.676,29.026,29.226,30,30.417 +M30 x 2,2,6H,27.835,28.21,28.701,28.925,30,30.513 +M30 x 3.5,3.5,6H,26.211,26.771,27.727,28.007,30,30.786 +M33 x 2,2,6H,30.835,31.21,31.701,31.925,33,33.513 +M35 x 1.5,1.5,6H,33.376,33.676,34.026,34.226,35,35.417 +M36 x 2,2,6H,33.835,34.21,34.701,34.925,36,36.513 +M36 x 4,4,6H,31.67,32.27,33.402,33.702,36,36.877 +M39 x 2,2,6H,36.835,37.21,37.701,37.925,39,39.513 +M40 x 1.5,1.5,6H,38.376,38.676,39.026,39.226,40,40.417 +M42 x 2,2,6H,39.835,40.21,40.701,40.925,42,42.513 +M42 x 4.5,4.5,6H,37.129,37.799,39.077,39.392,42,42.964 +M45 x 1.5,1.5,6H,43.376,43.676,44.026,44.226,45,45.417 +M48 x 2,2,6H,45.835,46.21,46.701,46.937,48,48.525 +M48 x 5,5,6H,42.587,43.297,44.752,45.087,48,49.056 +M50 x 1.5,1.5,6H,48.376,48.676,49.026,49.238,50,50.429 +M55 x 1.5,1.5,6H,53.376,53.676,54.026,54.238,55,55.429 +M56 x 2,2,6H,53.835,54.21,54.701,54.937,56,56.525 +M56 x 5.5,5.5,6H,50.046,50.796,52.428,52.783,56,57.149 +M60 x 1.5,1.5,6H,58.376,58.676,59.026,59.238,60,60.429 +M64 x 2,2,6H,61.835,62.21,62.701,62.937,64,64.525 +M64 x 6,6,6H,57.505,58.305,60.103,60.478,64,65.241 +M65 x 1.5,1.5,6H,63.376,63.676,64.026,64.238,65,65.429 +M70 x 1.5,1.5,6H,68.376,68.676,69.026,69.238,70,70.429 +M72 x 2,2,6H,69.835,70.21,70.701,70.937,72,72.525 +M72 x 6,6,6H,65.505,66.305,68.103,68.478,72,73.241 +M75 x 1.5,1.5,6H,73.376,73.676,74.026,74.238,75,75.429 +M80 x 1.5,1.5,6H,78.376,78.676,79.026,79.238,80,80.429 +M80 x 2,2,6H,77.835,78.21,78.701,78.937,80,80.525 +M80 x 6,6,6H,73.505,74.305,76.103,76.478,80,81.241 +M85 x 2,2,6H,82.835,83.21,83.701,83.937,85,85.525 +M90 x 2,2,6H,87.835,88.21,88.701,88.937,90,90.525 +M90 x 6,6,6H,83.505,84.305,86.103,86.478,90,91.241 +M95 x 2,2,6H,92.835,93.21,93.701,93.951,95,95.539 +M100 x 2,2,6H,97.835,98.21,98.701,98.951,100,100.539 +M100 x 6,6,6H,93.505,94.305,96.103,96.503,100,101.266 +M105 x 2,2,6H,102.835,103.21,103.701,103.951,105,105.539 +M110 x 2,2,6H,107.835,108.21,108.701,108.951,110,110.539 +M120 x 2,2,6H,117.835,118.21,118.701,118.951,120,120.539 +M130 x 2,2,6H,127.835,128.21,128.701,128.951,130,130.539 +M140 x 2,2,6H,137.835,138.21,138.701,138.951,140,140.539 +M150 x 2,2,6H,147.835,148.21,148.701,148.951,150,150.539 +M160 x 3,3,6H,156.752,157.252,158.051,158.351,160,160.733 +M170 x 3,3,6H,166.752,167.252,168.051,168.351,170,170.733 +M180 x 3,3,6H,176.752,177.252,178.051,178.351,180,180.733 +M190 x 3,3,6H,186.752,187.252,188.051,188.386,190,190.768 +M200 x 3,3,6H,196.752,197.252,198.051,198.386,200,200.768 diff --git a/src/Mod/Path/Gui/Resources/Path.qrc b/src/Mod/Path/Gui/Resources/Path.qrc index f121787924..c1383eb7a5 100644 --- a/src/Mod/Path/Gui/Resources/Path.qrc +++ b/src/Mod/Path/Gui/Resources/Path.qrc @@ -60,6 +60,7 @@ icons/Path_Speed.svg icons/Path_Stock.svg icons/Path_Stop.svg + icons/Path_ThreadMilling.svg icons/Path_ToolBit.svg icons/Path_ToolChange.svg icons/Path_ToolController.svg @@ -114,6 +115,7 @@ panels/PageOpProfileFullEdit.ui panels/PageOpSlotEdit.ui panels/PageOpSurfaceEdit.ui + panels/PageOpThreadMillingEdit.ui panels/PageOpWaterlineEdit.ui panels/PageOpVcarveEdit.ui panels/PathEdit.ui diff --git a/src/Mod/Path/Gui/Resources/icons/Path_ThreadMilling.svg b/src/Mod/Path/Gui/Resources/icons/Path_ThreadMilling.svg new file mode 100644 index 0000000000..6cc8d4653a --- /dev/null +++ b/src/Mod/Path/Gui/Resources/icons/Path_ThreadMilling.svg @@ -0,0 +1,1616 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + [Lorenz Hüdepohl] + + + Path-Helix + 2016-05-10 + http://www.freecadweb.org/wiki/index.php?title=Artwork + + + FreeCAD + + + FreeCAD/src/Mod/Path/Gui/Resources/icons/Path-Helix.svg + + + FreeCAD LGPL2+ + + + https://www.gnu.org/copyleft/lesser.html + + + [agryson] Alexander Gryson + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Mod/Path/Gui/Resources/panels/PageOpThreadMillingEdit.ui b/src/Mod/Path/Gui/Resources/panels/PageOpThreadMillingEdit.ui new file mode 100644 index 0000000000..f1f1ae882b --- /dev/null +++ b/src/Mod/Path/Gui/Resources/panels/PageOpThreadMillingEdit.ui @@ -0,0 +1,242 @@ + + + Form + + + + 0 + 0 + 482 + 736 + + + + Form + + + + + + Thread + + + + + + Orientation + + + + + + + 1 + + + + Left Hand + + + + + Right Hand + + + + + + + + Type + + + + + + + + Custom + + + + + Metric - internal + + + + + SAE - internal + + + + + + + + + + + Fit + + + + + + + 50 + + + Qt::Horizontal + + + + + + + Major Diameter + + + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Minor Diameter + + + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Pitch + + + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + Tool Controller + + + + + + Tool + + + + + + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Flat + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Operation + + + + + + Passes + + + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + 1 + + + + + + + Direction + + + + + + + + Climb + + + + + Conventional + + + + + + + + + + + + Gui::QuantitySpinBox + QDoubleSpinBox +
Gui/QuantitySpinBox.h
+
+
+ + +
diff --git a/src/Mod/Path/InitGui.py b/src/Mod/Path/InitGui.py index 7580f38862..abd207945e 100644 --- a/src/Mod/Path/InitGui.py +++ b/src/Mod/Path/InitGui.py @@ -118,6 +118,7 @@ class PathWorkbench (Workbench): projcmdlist.append("Path_Sanity") prepcmdlist.append("Path_Shape") extracmdlist.extend(["Path_Area", "Path_Area_Workplane"]) + specialcmdlist.append('Path_Thread_Milling') try: import ocl # pylint: disable=unused-variable @@ -145,6 +146,9 @@ class PathWorkbench (Workbench): "Path", "Supplemental Commands")], prepcmdlist) self.appendMenu([QtCore.QT_TRANSLATE_NOOP("Path", "&Path"), QtCore.QT_TRANSLATE_NOOP( "Path", "Path Modification")], modcmdlist) + if specialcmdlist: + self.appendMenu([QtCore.QT_TRANSLATE_NOOP("Path", "&Path"), QtCore.QT_TRANSLATE_NOOP( + "Path", "Specialty Operations")], specialcmdlist) if extracmdlist: self.appendMenu([QtCore.QT_TRANSLATE_NOOP("Path", "&Path")], extracmdlist) diff --git a/src/Mod/Path/PathScripts/PathCircularHoleBase.py b/src/Mod/Path/PathScripts/PathCircularHoleBase.py index c88cdf90d4..c12d6c1075 100644 --- a/src/Mod/Path/PathScripts/PathCircularHoleBase.py +++ b/src/Mod/Path/PathScripts/PathCircularHoleBase.py @@ -765,6 +765,23 @@ class ObjectOp(PathOp.ObjectOp): PathLog.debug(translate("Path", "Rotated to inverse angle.")) return (clnBase, clnStock, angle) + def calculateStartFinalDepths(self, obj, shape, stock): + '''calculateStartFinalDepths(obj, shape, stock) + Calculate correct start and final depths for the shape(face) object provided.''' + finDep = max(obj.FinalDepth.Value, shape.BoundBox.ZMin) + stockTop = stock.Shape.BoundBox.ZMax + if obj.EnableRotation == 'Off': + strDep = obj.StartDepth.Value + if strDep <= finDep: + strDep = stockTop + else: + strDep = min(obj.StartDepth.Value, stockTop) + if strDep <= finDep: + strDep = stockTop + msg = translate('Path', "Start depth <= face depth.\nIncreased to stock top.") + PathLog.error(msg) + return (strDep, finDep) + def sortTuplesByIndex(self, TupleList, tagIdx): '''sortTuplesByIndex(TupleList, tagIdx) sort list of tuples based on tag index provided diff --git a/src/Mod/Path/PathScripts/PathGuiInit.py b/src/Mod/Path/PathScripts/PathGuiInit.py index 6123ddce36..cd48d41309 100644 --- a/src/Mod/Path/PathScripts/PathGuiInit.py +++ b/src/Mod/Path/PathScripts/PathGuiInit.py @@ -73,6 +73,7 @@ def Startup(): from PathScripts import PathSlotGui from PathScripts import PathStop # from PathScripts import PathSurfaceGui # Added in initGui.py due to OCL dependency + from PathScripts import PathThreadMillingGui from PathScripts import PathToolController from PathScripts import PathToolControllerGui from PathScripts import PathToolLibraryManager diff --git a/src/Mod/Path/PathScripts/PathSelection.py b/src/Mod/Path/PathScripts/PathSelection.py index d3b6624214..11a75b31a1 100644 --- a/src/Mod/Path/PathScripts/PathSelection.py +++ b/src/Mod/Path/PathScripts/PathSelection.py @@ -98,19 +98,16 @@ class ENGRAVEGate(PathBaseGate): class CHAMFERGate(PathBaseGate): - def allow(self, doc, obj, sub): # pylint: disable=unused-argument + def allow(self, doc, obj, sub): # pylint: disable=unused-argument try: shape = obj.Shape - except Exception: # pylint: disable=broad-except + except Exception: # pylint: disable=broad-except return False if math.fabs(shape.Volume) < 1e-9 and len(shape.Wires) > 0: return True - if shape.ShapeType == 'Edge': - return True - - if (shape.ShapeType == 'Face' and shape.normalAt(0, 0) == FreeCAD.Vector(0, 0, 1)): + if 'Edge' == shape.ShapeType or 'Face' == shape.ShapeType: return True if sub: @@ -385,6 +382,7 @@ def select(op): opsel['Vcarve'] = vcarveselect opsel['Probe'] = probeselect opsel['Custom'] = customselect + opsel['Thread Milling'] = drillselect opsel['TurnFace'] = turnselect opsel['TurnProfile'] = turnselect opsel['TurnPartoff'] = turnselect diff --git a/src/Mod/Path/PathScripts/PathThreadMilling.py b/src/Mod/Path/PathScripts/PathThreadMilling.py new file mode 100644 index 0000000000..66d277648b --- /dev/null +++ b/src/Mod/Path/PathScripts/PathThreadMilling.py @@ -0,0 +1,121 @@ +# -*- coding: utf-8 -*- + +# *************************************************************************** +# * * +# * Copyright (c) 2019 sliptonic * +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU Lesser General Public License (LGPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * This program is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with this program; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# *************************************************************************** + +from __future__ import print_function + +import FreeCAD +import Path +import PathScripts.PathCircularHoleBase as PathCircularHoleBase +import PathScripts.PathLog as PathLog +import PathScripts.PathOp as PathOp +import PathScripts.PathUtils as PathUtils + +from PySide import QtCore + +__title__ = "Path Thread Milling Operation" +__author__ = "sliptonic (Brad Collette)" +__url__ = "http://www.freecadweb.org" +__doc__ = "Path thread milling operation." + +PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule()) +PathLog.trackModule(PathLog.thisModule()) + + +# Qt translation handling +def translate(context, text, disambig=None): + return QtCore.QCoreApplication.translate(context, text, disambig) + + +class ObjectThreadMilling(PathCircularHoleBase.ObjectOp): + '''Proxy object for thread milling operation.''' + + LeftHand = 'LeftHand' + RightHand = 'RightHand' + ThreadTypeCustom = 'Custom' + ThreadTypeMetricInternal = 'Metric - internal' + DirectionClimb = 'Climb' + + ThreadOrientations = [LeftHand, RightHand] + ThreadTypes = [ThreadTypeCustom, ThreadTypeMetricInternal] + Directions = [DirectionClimb] + + def circularHoleFeatures(self, obj): + return PathOp.FeatureBaseGeometry + + def initCircularHoleOperation(self, obj): + obj.addProperty("App::PropertyEnumeration", "ThreadOrientation", "Thread", QtCore.QT_TRANSLATE_NOOP("App::Property", "Set thread orientation")) + obj.ThreadOrientation = self.ThreadOrientations + obj.addProperty("App::PropertyEnumeration", "ThreadType", "Thread", QtCore.QT_TRANSLATE_NOOP("App::Property", "Currently only internal")) + obj.ThreadType = self.ThreadTypes + 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::PropertyInteger", "ThreadFit", "Thread", QtCore.QT_TRANSLATE_NOOP("App::Property", "Set how many passes are used to cut the thread")) + obj.addProperty("App::PropertyInteger", "Passes", "Mill", QtCore.QT_TRANSLATE_NOOP("App::Property", "Set how many passes are used to cut the thread")) + obj.addProperty("App::PropertyEnumeration", "Direction", "Mill", QtCore.QT_TRANSLATE_NOOP("App::Property", "Direction of thread cutting operation")) + obj.Direction = self.Directions + + + def circularHoleExecute(self, obj, holes): + PathLog.track() + + self.commandlist.append(Path.Command("(Begin Thread Milling)")) + + # rapid to clearance height + self.commandlist.append(Path.Command('G0', {'Z': obj.ClearanceHeight.Value, 'F': self.vertRapid})) + + + def opSetDefaultValues(self, obj, job): + obj.ThreadOrientation = self.RightHand + obj.ThreadType = self.ThreadTypeMetricInternal + obj.ThreadFit = 50 + obj.Pitch = 1 + obj.Passes = 1 + obj.Direction = self.DirectionClimb + + +def SetupProperties(): + setup = [] + setup.append("ThreadOrientation") + setup.append("ThreadType") + setup.append("ThreadName") + setup.append("ThreadFit") + setup.append("MajorDiameter") + setup.append("MinorDiameter") + setup.append("Pitch") + setup.append("Passes") + setup.append("Direction") + return setup + + +def Create(name, obj=None): + '''Create(name) ... Creates and returns a thread milling operation.''' + if obj is None: + obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython", name) + obj.Proxy = ObjectThreadMilling(obj, name) + if obj.Proxy: + obj.Proxy.findAllHoles(obj) + return obj + diff --git a/src/Mod/Path/PathScripts/PathThreadMillingGui.py b/src/Mod/Path/PathScripts/PathThreadMillingGui.py new file mode 100644 index 0000000000..e59f783292 --- /dev/null +++ b/src/Mod/Path/PathScripts/PathThreadMillingGui.py @@ -0,0 +1,167 @@ +# -*- coding: utf-8 -*- + +# *************************************************************************** +# * * +# * Copyright (c) 2019 sliptonic * +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU Lesser General Public License (LGPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * This program is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with this program; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# *************************************************************************** + +import FreeCAD +import FreeCADGui +import PathScripts.PathCircularHoleBaseGui as PathCircularHoleBaseGui +import PathScripts.PathThreadMilling as PathThreadMilling +import PathScripts.PathGui as PathGui +import PathScripts.PathLog as PathLog +import PathScripts.PathOpGui as PathOpGui +import csv + +from PySide import QtCore + +__title__ = "Path Thread Milling Operation UI." +__author__ = "sliptonic (Brad Collette)" +__url__ = "http://www.freecadweb.org" +__doc__ = "UI and Command for Path Thread Milling Operation." + +PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule()) +PathLog.trackModule(PathLog.thisModule()) + +def setupCombo(combo, selections): + combo.clear() + for item in selections: + combo.addItem(item) + +def fillThreads(combo, dataFile): + combo.blockSignals(True) + combo.clear() + with open("{}Mod/Path/Data/Threads/{}.csv".format(FreeCAD.getHomePath(), dataFile)) as fp: + reader = csv.DictReader(fp) + for row in reader: + combo.addItem(row['name'], row) + combo.setEnabled(True) + combo.blockSignals(False) + +class TaskPanelOpPage(PathCircularHoleBaseGui.TaskPanelOpPage): + '''Controller for the thread milling operation's page''' + + def initPage(self, obj): + self.majorDia = PathGui.QuantitySpinBox(self.form.threadMajor, obj, 'MajorDiameter') # pylint: disable=attribute-defined-outside-init + self.minorDia = PathGui.QuantitySpinBox(self.form.threadMinor, obj, 'MinorDiameter') # pylint: disable=attribute-defined-outside-init + self.pitch = PathGui.QuantitySpinBox(self.form.threadPitch, obj, 'Pitch') # pylint: disable=attribute-defined-outside-init + + setupCombo(self.form.threadOrientation, obj.Proxy.ThreadOrientations) + setupCombo(self.form.threadType, obj.Proxy.ThreadTypes) + setupCombo(self.form.opDirection, obj.Proxy.Directions) + + def getForm(self): + '''getForm() ... return UI''' + return FreeCADGui.PySideUic.loadUi(":/panels/PageOpThreadMillingEdit.ui") + + def getFields(self, obj): + '''getFields(obj) ... update obj's properties with values from the UI''' + PathLog.track() + + self.majorDia.updateProperty() + self.minorDia.updateProperty() + self.pitch.updateProperty() + + obj.ThreadOrientation = self.form.threadOrientation.currentText() + obj.ThreadType = self.form.threadType.currentText() + obj.ThreadName = self.form.threadName.currentText() + obj.Direction = self.form.opDirection.currentText() + obj.Passes = self.form.opPasses.value() + + self.updateToolController(obj, self.form.toolController) + + def setFields(self, obj): + '''setFields(obj) ... update UI with obj properties' values''' + PathLog.track() + + self.form.threadOrientation.setCurrentText(obj.ThreadOrientation) + + self.form.threadType.blockSignals(True) + self.form.threadName.blockSignals(True) + self.form.threadType.setCurrentText(obj.ThreadType) + self._updateFromThreadType() + self.form.threadName.setCurrentText(obj.ThreadName) + self.form.threadType.blockSignals(False) + self.form.threadName.blockSignals(False) + + self.form.opPasses.setValue(obj.Passes) + self.form.opDirection.setCurrentText(obj.Direction) + + self.majorDia.updateSpinBox() + self.minorDia.updateSpinBox() + self.pitch.updateSpinBox() + + self.setupToolController(obj, self.form.toolController) + + + + def _updateFromThreadType(self): + if self.form.threadType.currentIndex() == 0: + PathLog.track(self.form.threadType.currentIndex()) + self.form.threadName.setEnabled(False) + self.form.threadFit.setEnabled(False) + self.form.threadFitLabel.setEnabled(False) + else: + PathLog.track(self.form.threadType.currentIndex()) + self.form.threadFit.setEnabled(True) + self.form.threadFitLabel.setEnabled(True) + fillThreads(self.form.threadName, 'metric-internal') + + def _updateFromThreadName(self): + thread = self.form.threadName.currentData() + mamin = float(thread['dMajorMin']) + mamax = float(thread['dMajorMax']) + mimin = float(thread['dMinorMin']) + mimax = float(thread['dMinorMax']) + pitch = float(thread['pitch']) + + self.pitch.updateSpinBox(pitch) + self.majorDia.updateSpinBox((mamin + mamax) / 2) + self.minorDia.updateSpinBox((mimin + mimax) / 2) + + self.setDirty() + + def getSignalsForUpdate(self, obj): + '''getSignalsForUpdate(obj) ... return list of signals which cause the receiver to update the model''' + signals = [] + + signals.append(self.form.threadMajor.editingFinished) + signals.append(self.form.threadMinor.editingFinished) + signals.append(self.form.threadPitch.editingFinished) + + signals.append(self.form.toolController.currentIndexChanged) + + return signals + + def registerSignalHandlers(self, obj): + self.form.threadType.currentIndexChanged.connect(self._updateFromThreadType) + self.form.threadName.currentIndexChanged.connect(self._updateFromThreadName) + + +Command = PathOpGui.SetupOperation('Thread Milling', + PathThreadMilling.Create, + TaskPanelOpPage, + 'Path-ThreadMilling', + QtCore.QT_TRANSLATE_NOOP("PathThreadMilling", "Thread Milling"), + QtCore.QT_TRANSLATE_NOOP("PathThreadMilling", "Creates a Path Thread Milling operation from features of a base object"), + PathThreadMilling.SetupProperties) + +FreeCAD.Console.PrintLog("Loading PathThreadMillingGui ... done\n")