From 4c06752c39f5b7926b84784bdf7d923c48c15b05 Mon Sep 17 00:00:00 2001 From: Jeremy Mack Wright Date: Sun, 23 Jul 2017 00:22:57 -0400 Subject: [PATCH 01/19] Implemented build and parameter search CQGI functionality, and updated the CadQuery library. --- Gui/Command.py | 45 ++++++-- Libs/cadquery-lib/.coverage | 2 +- Libs/cadquery-lib/.travis.yml | 11 +- Libs/cadquery-lib/README.md | 39 ++++++- Libs/cadquery-lib/cadquery/cq.py | 2 +- Libs/cadquery-lib/cadquery/cqgi.py | 12 +-- .../cadquery/freecad_impl/__init__.py | 1 + .../cadquery/freecad_impl/shapes.py | 8 +- Libs/cadquery-lib/cadquery/selectors.py | 36 +++---- Libs/cadquery-lib/doc/apireference.rst | 1 + Libs/cadquery-lib/doc/classreference.rst | 1 + Libs/cadquery-lib/doc/installation.rst | 5 - Libs/cadquery-lib/doc/roadmap.rst | 12 --- Libs/cadquery-lib/doc/selectors.rst | 100 ++++++++++-------- Libs/cadquery-lib/requirements-dev.txt | 7 +- Libs/cadquery-lib/tests/TestCQSelectors.py | 44 ++++++++ 16 files changed, 216 insertions(+), 110 deletions(-) diff --git a/Gui/Command.py b/Gui/Command.py index f977db2..31ef1e3 100644 --- a/Gui/Command.py +++ b/Gui/Command.py @@ -9,6 +9,8 @@ import ExportCQ, ImportCQ import module_locator import Settings import Shared +from cadquery import cqgi +from Helpers import show # Distinguish python built-in open function from the one declared here if open.__module__ == '__builtin__': @@ -122,17 +124,42 @@ class CadQueryExecuteScript: # Clear the old render before re-rendering Shared.clearActiveDocument() - # Save our code to a tempfile and render it - tempFile = tempfile.NamedTemporaryFile(delete=False) - tempFile.write(cqCodePane.toPlainText().encode('utf-8')) - tempFile.close() + # Check to see if we are executig a CQGI compliant script + scriptText = cqCodePane.toPlainText().encode('utf-8') + if "build_object(" in scriptText and "# build_object(" not in scriptText and "#build_boject(" not in scriptText: + FreeCAD.Console.PrintMessage("Executing CQGI-compliant script.\r\n") - # Set some environment variables that may help the user - os.environ["MYSCRIPT_FULL_PATH"] = cqCodePane.file.path - os.environ["MYSCRIPT_DIR"] = os.path.dirname(os.path.abspath(cqCodePane.file.path)) + # A repreentation of the CQ script with all the metadata attached + cqModel = cqgi.parse(scriptText) - # We import this way because using execfile() causes non-standard script execution in some situations - imp.load_source('temp_module', tempFile.name) + # Allows us to present parameters to users later that they can alter + parameters = cqModel.metadata.parameters + + FreeCAD.Console.PrintMessage("Script Variables:\r\n") + for key, value in parameters.iteritems(): + FreeCAD.Console.PrintMessage("variable name: " + key + ", variable value: " + str(value.default_value) + "\r\n") + + build_result = cqgi.parse(scriptText).build() + + # Make sure that the build was successful + if build_result.success: + # Display all the results that the user requested + for result in build_result.results: + show(result) + else: + FreeCAD.Console.PrintError("Error executing CQGI-compliant script.\r\n") + else: + # Save our code to a tempfile and render it + tempFile = tempfile.NamedTemporaryFile(delete=False) + tempFile.write(scriptText) + tempFile.close() + + # Set some environment variables that may help the user + os.environ["MYSCRIPT_FULL_PATH"] = cqCodePane.file.path + os.environ["MYSCRIPT_DIR"] = os.path.dirname(os.path.abspath(cqCodePane.file.path)) + + # We import this way because using execfile() causes non-standard script execution in some situations + imp.load_source('temp_module', tempFile.name) msg = QtGui.QApplication.translate( "cqCodeWidget", diff --git a/Libs/cadquery-lib/.coverage b/Libs/cadquery-lib/.coverage index 09e0f75..349220a 100644 --- a/Libs/cadquery-lib/.coverage +++ b/Libs/cadquery-lib/.coverage @@ -1 +1 @@ -!coverage.py: This is a private format, don't read it directly!{"lines": {"/home/jwright/Downloads/cadquery/cadquery/cq_directive.py": [], "/home/jwright/Downloads/cadquery/cadquery/cq.py": [2049, 2052, 2053, 2054, 2056, 2057, 2058, 2060, 18, 20, 21, 22, 23, 24, 27, 2076, 2078, 33, 34, 35, 36, 2085, 2086, 39, 40, 2089, 43, 2093, 49, 51, 2102, 2103, 2104, 58, 59, 60, 2109, 62, 2111, 65, 2126, 2127, 2128, 81, 2130, 2131, 84, 2133, 2134, 2140, 2141, 2142, 2143, 96, 2145, 2147, 2149, 102, 2151, 104, 106, 107, 108, 110, 112, 2166, 2168, 2170, 2171, 2172, 2173, 2174, 2178, 363, 2180, 133, 2182, 2183, 136, 2185, 138, 2187, 140, 141, 2255, 143, 145, 149, 150, 151, 153, 154, 156, 2207, 368, 2211, 2213, 2215, 2217, 2218, 2220, 174, 175, 176, 178, 182, 184, 185, 2235, 188, 189, 190, 2239, 192, 193, 195, 374, 2246, 2247, 2249, 2251, 2252, 205, 2254, 207, 2257, 211, 213, 222, 224, 2427, 2276, 2277, 2279, 2282, 2087, 238, 239, 240, 2088, 243, 244, 246, 383, 253, 255, 2307, 2308, 2309, 2310, 2433, 2312, 265, 2314, 2316, 2318, 2333, 2336, 2339, 2340, 2341, 2342, 2344, 2346, 306, 2075, 308, 309, 310, 311, 2361, 314, 2363, 2364, 2366, 2368, 322, 329, 330, 332, 333, 335, 337, 341, 344, 345, 349, 350, 353, 355, 356, 357, 360, 361, 2411, 364, 365, 2414, 2415, 2416, 2417, 2418, 2419, 2420, 2422, 375, 2424, 378, 379, 2428, 382, 2431, 384, 385, 2434, 388, 390, 396, 398, 404, 406, 411, 413, 2471, 2472, 2474, 427, 428, 432, 2482, 2483, 2485, 2486, 2488, 2489, 2491, 2494, 2497, 2498, 2500, 454, 455, 456, 457, 458, 461, 462, 464, 466, 78, 79, 2524, 479, 80, 482, 483, 485, 486, 488, 490, 1447, 82, 2132, 519, 521, 2480, 551, 553, 582, 97, 584, 605, 607, 103, 839, 631, 633, 651, 653, 669, 671, 2502, 681, 683, 692, 694, 720, 722, 723, 724, 725, 727, 729, 2070, 742, 743, 745, 758, 2071, 766, 769, 131, 2072, 2523, 805, 807, 808, 811, 812, 813, 815, 137, 2527, 836, 838, 481, 842, 843, 844, 846, 369, 874, 876, 877, 880, 882, 883, 886, 910, 912, 914, 936, 937, 938, 939, 943, 947, 948, 949, 951, 952, 953, 955, 968, 969, 971, 972, 974, 975, 976, 977, 979, 981, 994, 995, 996, 997, 998, 999, 1001, 1022, 1024, 1025, 1026, 1027, 1031, 1032, 172, 1034, 1036, 1050, 1053, 1054, 1055, 1056, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1067, 1069, 1089, 1090, 1091, 1092, 1094, 1096, 1123, 1124, 1125, 1127, 2236, 2237, 1137, 1139, 1141, 1143, 1144, 1146, 1149, 2241, 1160, 1161, 1163, 1170, 1172, 1179, 1181, 1191, 1192, 1194, 1204, 1205, 1208, 2359, 1223, 1224, 1227, 2253, 1242, 1243, 1244, 1246, 2259, 1278, 1279, 1281, 1282, 1284, 1286, 1287, 1289, 1291, 1307, 1308, 1309, 1311, 1313, 1314, 1316, 1318, 1338, 1341, 1343, 1345, 1346, 1347, 1350, 1352, 1354, 2091, 1372, 1373, 1374, 1376, 1390, 1391, 1392, 1394, 1401, 1403, 1404, 1406, 1421, 1423, 1433, 1434, 1435, 1439, 1446, 241, 1448, 1449, 1451, 1472, 1475, 1476, 1478, 1480, 1481, 1482, 1486, 1487, 1488, 1490, 1492, 1524, 1525, 1527, 1529, 1530, 1532, 1534, 1535, 1536, 1538, 1540, 1542, 1560, 1561, 1564, 1567, 1568, 1570, 1572, 263, 2313, 1598, 1601, 1602, 1603, 1604, 1605, 1607, 1608, 1609, 1610, 1612, 1613, 1616, 1619, 1648, 1649, 1650, 1651, 1653, 1655, 1666, 1668, 1669, 1670, 1671, 1672, 1673, 1675, 1677, 1692, 1695, 1698, 1699, 1701, 1704, 1706, 1707, 1709, 1711, 1725, 1728, 1730, 1732, 1741, 1742, 1743, 1745, 1747, 1757, 1758, 1762, 1763, 1764, 1765, 1767, 1769, 1770, 1773, 1803, 1804, 1806, 1812, 1814, 1817, 1818, 1819, 1821, 1825, 2107, 2356, 2357, 1856, 1857, 1859, 1862, 1865, 1866, 1867, 1868, 1869, 1870, 1872, 1876, 2362, 63, 1902, 1903, 1905, 1911, 1913, 1914, 1916, 1919, 320, 1940, 1942, 1945, 1954, 1955, 1956, 1957, 1958, 1959, 1963, 1964, 1966, 1967, 1968, 1970, 1995, 1997, 1998, 2000, 2001, 2002, 2004, 2027, 2030, 2034, 2035, 2037, 2041, 2044, 2045, 2047], "/home/jwright/Downloads/cadquery/cadquery/freecad_impl/__init__.py": [18, 19, 22, 24, 25, 29, 34, 36, 37, 38, 39, 40, 41, 42, 44, 45, 101, 102, 103, 104, 105, 106, 107, 108, 109], "/home/jwright/Downloads/cadquery/cadquery/freecad_impl/shapes.py": [1024, 514, 1027, 517, 519, 428, 523, 547, 526, 528, 88, 857, 537, 539, 90, 717, 603, 549, 550, 945, 552, 605, 49, 50, 51, 52, 565, 55, 568, 569, 571, 572, 61, 693, 352, 68, 69, 582, 71, 584, 74, 587, 588, 590, 79, 592, 580, 82, 83, 84, 85, 87, 600, 89, 602, 91, 604, 93, 94, 95, 96, 609, 98, 699, 104, 105, 618, 619, 621, 110, 623, 624, 113, 114, 627, 116, 617, 72, 636, 819, 640, 643, 134, 961, 567, 862, 651, 654, 655, 659, 662, 664, 669, 160, 673, 795, 677, 909, 682, 455, 172, 173, 175, 807, 178, 181, 694, 184, 628, 187, 188, 701, 702, 191, 799, 708, 710, 711, 204, 825, 206, 719, 720, 209, 210, 211, 212, 213, 729, 219, 794, 806, 208, 741, 742, 977, 233, 561, 809, 750, 752, 59, 243, 244, 245, 189, 247, 680, 249, 762, 931, 255, 256, 769, 258, 260, 897, 812, 898, 813, 276, 279, 280, 793, 282, 283, 796, 285, 286, 901, 288, 289, 802, 291, 292, 294, 295, 808, 297, 298, 300, 301, 303, 816, 904, 306, 307, 309, 822, 823, 564, 991, 317, 318, 821, 320, 321, 323, 324, 325, 327, 329, 330, 761, 332, 333, 335, 1017, 340, 343, 856, 241, 859, 860, 349, 350, 351, 864, 353, 500, 355, 486, 97, 487, 483, 368, 369, 370, 372, 373, 376, 890, 379, 892, 381, 800, 895, 385, 386, 387, 388, 389, 906, 392, 818, 394, 395, 908, 397, 401, 404, 921, 407, 920, 409, 855, 413, 926, 928, 240, 930, 419, 420, 933, 753, 424, 426, 427, 940, 429, 942, 925, 944, 433, 947, 949, 951, 952, 441, 954, 801, 444, 562, 672, 962, 331, 964, 803, 417, 456, 457, 459, 972, 418, 974, 975, 465, 466, 979, 468, 469, 471, 472, 475, 817, 442, 992, 995, 485, 998, 81, 1000, 489, 1004, 594, 1007, 1009, 499, 595, 1012, 501, 503, 596, 1018, 1019, 767, 1021, 511], "/home/jwright/Downloads/cadquery/cadquery/__init__.py": [2, 3, 4, 5, 10, 11, 15, 16, 17, 18, 21], "/home/jwright/Downloads/cadquery/cadquery/selectors.py": [18, 20, 21, 22, 25, 30, 31, 41, 43, 44, 46, 47, 49, 50, 52, 53, 55, 71, 72, 73, 74, 76, 77, 83, 85, 98, 99, 100, 101, 102, 104, 106, 107, 108, 110, 113, 114, 115, 117, 118, 119, 120, 121, 122, 124, 125, 127, 129, 133, 134, 135, 136, 138, 142, 148, 149, 152, 154, 156, 157, 158, 160, 161, 162, 164, 166, 184, 186, 187, 189, 207, 209, 210, 212, 230, 232, 233, 234, 235, 238, 257, 258, 259, 261, 262, 263, 264, 265, 266, 268, 293, 294, 295, 296, 297, 298, 299, 301, 302, 310, 311, 313, 316, 318, 322, 323, 324, 325, 327, 328, 329, 331, 334, 337, 338, 340, 342, 345, 346, 348, 350, 354, 355, 356, 358, 362, 363, 364, 366, 368, 370, 405, 406, 408, 409, 410, 411, 412, 413, 414, 417, 418, 419, 420, 421, 422, 423, 425, 426, 427, 429, 430, 431, 432, 434, 439, 442, 443, 447, 448, 452, 454, 455, 457, 458, 459, 460, 461, 462, 463, 464, 465, 469, 474], "/home/jwright/Downloads/cadquery/cadquery/cqgi.py": [4, 5, 6, 7, 8, 10, 12, 23, 24, 27, 36, 38, 43, 44, 45, 46, 51, 53, 64, 66, 67, 68, 70, 71, 72, 74, 83, 95, 96, 98, 99, 101, 102, 103, 104, 105, 106, 107, 110, 111, 112, 113, 114, 116, 117, 118, 119, 120, 121, 122, 124, 125, 126, 128, 129, 131, 132, 133, 135, 136, 139, 149, 150, 151, 152, 153, 154, 155, 156, 158, 159, 160, 162, 163, 165, 166, 167, 168, 171, 175, 176, 177, 179, 180, 182, 183, 184, 185, 188, 189, 192, 193, 196, 197, 200, 201, 204, 214, 215, 218, 221, 224, 227, 230, 232, 234, 235, 237, 238, 240, 241, 242, 243, 244, 245, 246, 247, 249, 251, 256, 257, 258, 259, 260, 261, 262, 263, 265, 266, 267, 268, 271, 275, 280, 285, 286, 287, 288, 290, 295, 297, 301, 303, 309, 315, 316, 318, 323, 324, 325, 326, 328, 332, 333, 336, 340, 341, 344, 349, 351, 362, 365, 368, 372, 377, 378, 379, 381, 382, 384, 385, 386, 388, 389, 390, 391, 393, 394, 395, 397, 398, 400, 403, 404, 405, 407, 411, 412, 416, 417, 418, 420, 421, 422, 423, 425, 428, 430, 431, 433, 434, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 453, 455, 456, 459, 462, 463, 464, 466, 467, 472], "/home/jwright/Downloads/cadquery/cadquery/freecad_impl/importers.py": [2, 3, 5, 6, 7, 8, 9, 10, 12, 13, 15, 16, 17, 20, 28, 29, 33, 39, 41, 44, 45, 46, 48, 53], "/home/jwright/Downloads/cadquery/cadquery/freecad_impl/exporters.py": [1, 3, 4, 6, 9, 10, 15, 16, 17, 18, 19, 20, 23, 24, 25, 28, 34, 46, 47, 49, 51, 53, 55, 56, 59, 60, 61, 62, 63, 64, 65, 66, 71, 74, 76, 77, 78, 79, 83, 84, 86, 91, 92, 93, 95, 96, 99, 103, 105, 107, 108, 111, 115, 116, 118, 121, 122, 124, 125, 127, 128, 130, 131, 132, 133, 136, 137, 138, 139, 140, 141, 142, 143, 144, 147, 148, 149, 150, 151, 152, 153, 154, 157, 164, 165, 167, 168, 169, 170, 172, 173, 174, 177, 179, 180, 186, 187, 188, 189, 190, 191, 195, 210, 211, 212, 214, 215, 216, 217, 218, 220, 221, 223, 225, 226, 227, 232, 237, 239, 243, 245, 246, 247, 248, 251, 252, 254, 257, 258, 259, 260, 263, 266, 269, 270, 271, 273, 274, 275, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 294, 297, 304, 305, 306, 307, 353, 389, 391], "/home/jwright/Downloads/cadquery/cadquery/freecad_impl/geom.py": [515, 516, 517, 522, 523, 524, 529, 18, 20, 21, 22, 23, 26, 540, 542, 544, 546, 547, 548, 550, 632, 42, 44, 45, 46, 47, 560, 49, 50, 563, 564, 565, 567, 568, 569, 58, 572, 573, 575, 581, 70, 583, 72, 73, 74, 75, 76, 77, 78, 79, 592, 593, 594, 595, 597, 87, 89, 91, 93, 95, 608, 97, 99, 101, 614, 103, 616, 105, 618, 107, 109, 110, 113, 114, 116, 117, 630, 119, 120, 633, 122, 123, 125, 638, 127, 128, 130, 635, 132, 645, 134, 136, 144, 146, 147, 149, 152, 155, 158, 161, 162, 164, 167, 170, 173, 174, 177, 181, 182, 183, 184, 188, 189, 191, 192, 195, 586, 631, 206, 208, 209, 463, 634, 570, 238, 637, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 254, 255, 260, 261, 262, 263, 264, 266, 267, 268, 269, 270, 272, 273, 643, 278, 279, 280, 281, 282, 284, 285, 133, 48, 290, 291, 296, 297, 302, 303, 51, 308, 309, 52, 314, 315, 590, 629, 53, 320, 321, 326, 327, 55, 332, 345, 346, 348, 349, 350, 352, 354, 356, 358, 360, 362, 364, 365, 367, 609, 389, 391, 495, 69, 418, 419, 582, 423, 424, 71, 428, 430, 584, 611, 585, 445, 446, 587, 454, 588, 461, 462, 589, 464, 466, 467, 469, 591, 483, 485, 488, 489, 490, 491, 494, 613, 497, 499], "/home/jwright/Downloads/cadquery/cadquery/plugins/__init__.py": [18], "/home/jwright/Downloads/cadquery/cadquery/contrib/__init__.py": []}} \ No newline at end of file +!coverage.py: This is a private format, don't read it directly!{"lines": {"/home/jwright/Downloads/cadquery/cadquery/cq_directive.py": [], "/home/jwright/Downloads/cadquery/cadquery/cq.py": [2049, 2052, 2053, 2054, 2056, 2057, 2058, 2060, 18, 20, 21, 22, 23, 24, 27, 2076, 2078, 33, 34, 35, 36, 2085, 2086, 39, 40, 2089, 43, 2093, 49, 51, 2102, 2103, 2104, 58, 59, 60, 2109, 62, 2111, 65, 2126, 2127, 2128, 81, 2130, 2131, 84, 2133, 2134, 2140, 2141, 2142, 2143, 96, 2145, 2147, 2149, 102, 2151, 104, 106, 107, 108, 110, 112, 2166, 2168, 2170, 2171, 2172, 2173, 2174, 2178, 363, 2180, 133, 2182, 2183, 136, 2185, 138, 2187, 140, 141, 2255, 143, 145, 149, 150, 151, 153, 154, 156, 2207, 368, 2211, 2213, 2215, 2217, 2218, 2220, 174, 175, 176, 178, 182, 184, 185, 2235, 188, 189, 190, 2239, 192, 193, 195, 374, 2246, 2247, 2249, 2251, 2252, 205, 2254, 207, 2257, 211, 213, 222, 224, 2427, 2276, 2277, 2279, 2282, 2087, 238, 239, 240, 2088, 243, 244, 246, 383, 253, 255, 2307, 2308, 2309, 2310, 2433, 2312, 265, 2314, 2316, 2318, 2333, 2336, 2339, 2340, 2341, 2342, 2344, 2346, 306, 2075, 308, 309, 310, 311, 2361, 314, 2363, 2364, 2366, 2368, 322, 329, 330, 332, 333, 335, 337, 341, 344, 345, 349, 350, 353, 355, 356, 357, 360, 361, 2411, 364, 365, 2414, 2415, 2416, 2417, 2418, 2419, 2420, 2422, 375, 2424, 378, 379, 2428, 382, 2431, 384, 385, 2434, 388, 390, 396, 398, 404, 406, 411, 413, 2471, 2472, 2474, 427, 428, 432, 2482, 2483, 2485, 2486, 2488, 2489, 2491, 2494, 2497, 2498, 2500, 454, 455, 456, 457, 458, 461, 462, 464, 466, 78, 79, 2524, 479, 80, 482, 483, 485, 486, 488, 490, 1447, 82, 2132, 519, 521, 2480, 551, 553, 582, 97, 584, 605, 607, 103, 839, 631, 633, 651, 653, 669, 671, 2502, 681, 683, 692, 694, 720, 722, 723, 724, 725, 727, 729, 2070, 742, 743, 745, 758, 2071, 766, 769, 131, 2072, 2523, 805, 807, 808, 811, 812, 813, 815, 137, 2527, 836, 838, 481, 842, 843, 844, 846, 369, 874, 876, 877, 880, 882, 883, 886, 910, 912, 914, 936, 937, 938, 939, 943, 947, 948, 949, 951, 952, 953, 955, 968, 969, 971, 972, 974, 975, 976, 977, 979, 981, 994, 995, 996, 997, 998, 999, 1001, 1022, 1024, 1025, 1026, 1027, 1031, 1032, 172, 1034, 1036, 1050, 1053, 1054, 1055, 1056, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1067, 1069, 1089, 1090, 1091, 1092, 1094, 1096, 1123, 1124, 1125, 1127, 2236, 2237, 1137, 1139, 1141, 1143, 1144, 1146, 1149, 2241, 1160, 1161, 1163, 1170, 1172, 1179, 1181, 1191, 1192, 1194, 1204, 1205, 1208, 2359, 1223, 1224, 1227, 2253, 1242, 1243, 1244, 1246, 2259, 1278, 1279, 1281, 1282, 1284, 1286, 1287, 1289, 1291, 1307, 1308, 1309, 1311, 1313, 1314, 1316, 1318, 1338, 1341, 1343, 1345, 1346, 1347, 1350, 1352, 1354, 2091, 1372, 1373, 1374, 1376, 1390, 1391, 1392, 1394, 1401, 1403, 1404, 1406, 1421, 1423, 1433, 1434, 1435, 1439, 1446, 241, 1448, 1449, 1451, 1472, 1475, 1476, 1478, 1480, 1481, 1482, 1486, 1487, 1488, 1490, 1492, 1524, 1525, 1527, 1529, 1530, 1532, 1534, 1535, 1536, 1538, 1540, 1542, 1560, 1561, 1564, 1567, 1568, 1570, 1572, 263, 2313, 1598, 1601, 1602, 1603, 1604, 1605, 1607, 1608, 1609, 1610, 1612, 1613, 1616, 1619, 1648, 1649, 1650, 1651, 1653, 1655, 1666, 1668, 1669, 1670, 1671, 1672, 1673, 1675, 1677, 1692, 1695, 1698, 1699, 1701, 1704, 1706, 1707, 1709, 1711, 1725, 1728, 1730, 1732, 1741, 1742, 1743, 1745, 1747, 1757, 1758, 1762, 1763, 1764, 1765, 1767, 1769, 1770, 1773, 1803, 1804, 1806, 1812, 1814, 1817, 1818, 1819, 1821, 1825, 2107, 2356, 2357, 1856, 1857, 1859, 1862, 1865, 1866, 1867, 1868, 1869, 1870, 1872, 1876, 2362, 63, 1902, 1903, 1905, 1911, 1913, 1914, 1916, 1919, 320, 1940, 1942, 1945, 1954, 1955, 1956, 1957, 1958, 1959, 1963, 1964, 1966, 1967, 1968, 1970, 1995, 1997, 1998, 2000, 2001, 2002, 2004, 2027, 2030, 2034, 2035, 2037, 2041, 2044, 2045, 2047], "/home/jwright/Downloads/cadquery/cadquery/freecad_impl/__init__.py": [18, 19, 20, 23, 26, 27, 30, 32, 33, 34, 35, 36, 37, 38, 39, 41, 42, 101, 102, 103, 104, 105, 106], "/home/jwright/Downloads/cadquery/cadquery/freecad_impl/shapes.py": [1026, 1027, 1028, 1030, 521, 599, 524, 930, 526, 88, 530, 259, 533, 535, 810, 461, 802, 602, 1033, 544, 546, 603, 518, 554, 556, 557, 559, 49, 50, 51, 52, 986, 55, 568, 104, 571, 572, 61, 574, 575, 576, 578, 579, 68, 69, 71, 72, 1036, 74, 587, 866, 591, 81, 594, 595, 84, 85, 87, 355, 89, 90, 91, 93, 94, 607, 96, 609, 610, 611, 612, 808, 616, 105, 110, 873, 624, 113, 626, 116, 446, 630, 631, 632, 633, 634, 703, 636, 637, 645, 134, 961, 649, 652, 937, 660, 663, 664, 668, 601, 160, 673, 678, 625, 681, 682, 172, 173, 686, 175, 689, 178, 691, 181, 184, 628, 187, 188, 189, 702, 191, 971, 708, 710, 711, 493, 204, 717, 206, 719, 720, 209, 210, 211, 212, 213, 726, 728, 729, 219, 220, 221, 223, 224, 208, 738, 114, 234, 809, 750, 751, 830, 241, 242, 244, 245, 246, 297, 248, 761, 250, 322, 256, 257, 770, 771, 97, 261, 262, 811, 776, 812, 778, 983, 281, 815, 284, 285, 803, 287, 288, 290, 291, 804, 293, 294, 817, 296, 988, 95, 299, 300, 818, 302, 303, 816, 305, 306, 308, 821, 822, 311, 312, 825, 314, 827, 828, 906, 868, 831, 832, 834, 323, 325, 326, 328, 329, 330, 332, 334, 335, 336, 337, 338, 340, 569, 345, 348, 826, 864, 506, 354, 59, 356, 357, 358, 871, 360, 762, 805, 373, 374, 375, 377, 378, 381, 865, 384, 386, 899, 406, 390, 391, 392, 393, 394, 907, 397, 910, 399, 400, 913, 402, 915, 917, 918, 409, 98, 412, 414, 929, 418, 422, 423, 424, 425, 939, 940, 429, 942, 431, 432, 433, 434, 949, 438, 951, 901, 953, 954, 671, 956, 492, 958, 447, 960, 449, 963, 904, 970, 759, 460, 973, 462, 589, 464, 981, 470, 471, 984, 473, 474, 79, 476, 477, 478, 479, 480, 482, 934, 1000, 1001, 490, 935, 1004, 82, 494, 1007, 496, 1009, 83, 1013, 869, 1016, 1018, 507, 508, 1021, 510, 597], "/home/jwright/Downloads/cadquery/cadquery/__init__.py": [2, 3, 4, 5, 10, 11, 15, 16, 17, 18, 21], "/home/jwright/Downloads/cadquery/cadquery/selectors.py": [51, 514, 515, 516, 518, 519, 521, 522, 523, 525, 526, 319, 528, 18, 531, 20, 21, 22, 23, 24, 538, 29, 542, 543, 544, 34, 35, 548, 553, 555, 45, 47, 48, 50, 563, 564, 53, 54, 567, 56, 57, 570, 59, 573, 574, 575, 577, 578, 579, 581, 582, 583, 585, 586, 75, 76, 77, 78, 591, 592, 593, 594, 596, 598, 87, 600, 89, 102, 103, 104, 105, 106, 108, 530, 110, 111, 112, 114, 117, 118, 119, 532, 122, 123, 124, 125, 126, 128, 129, 131, 133, 137, 138, 139, 140, 142, 655, 656, 657, 146, 659, 663, 152, 153, 156, 158, 160, 161, 162, 164, 165, 166, 568, 168, 170, 188, 190, 191, 193, 535, 546, 211, 213, 214, 121, 216, 536, 234, 236, 237, 238, 239, 242, 261, 262, 263, 265, 266, 267, 268, 269, 270, 301, 272, 293, 294, 295, 296, 297, 298, 299, 562, 302, 305, 307, 309, 310, 649, 313, 314, 316, 650, 565, 321, 329, 330, 331, 332, 333, 334, 335, 337, 339, 654, 342, 345, 349, 350, 351, 354, 355, 358, 360, 364, 365, 366, 367, 369, 370, 371, 373, 376, 379, 380, 382, 384, 387, 388, 390, 392, 396, 397, 398, 400, 80, 404, 405, 406, 408, 410, 413, 81, 419, 420, 421, 422, 423, 426, 427, 428, 429, 430, 433, 434, 437, 438, 439, 442, 445, 448, 449, 450, 587, 452, 455, 458, 463, 464, 466, 468, 590, 472, 473, 476, 477, 478, 479, 480, 481, 482, 485, 486, 487, 488, 489, 490, 491, 494, 495, 496, 497, 498, 501, 502, 503, 504, 505, 507, 508, 510, 341], "/home/jwright/Downloads/cadquery/cadquery/cqgi.py": [4, 5, 6, 7, 8, 10, 12, 23, 24, 27, 36, 38, 43, 44, 45, 46, 51, 53, 64, 66, 67, 68, 70, 71, 72, 74, 83, 95, 96, 98, 99, 101, 102, 103, 104, 105, 106, 107, 110, 111, 112, 113, 114, 116, 117, 118, 119, 120, 121, 122, 124, 125, 126, 128, 129, 131, 132, 133, 135, 136, 139, 149, 150, 151, 152, 153, 154, 155, 156, 158, 159, 160, 162, 163, 165, 166, 167, 168, 171, 175, 176, 177, 179, 180, 182, 183, 184, 185, 188, 189, 192, 193, 196, 197, 200, 201, 204, 214, 215, 218, 221, 224, 227, 230, 232, 234, 235, 237, 238, 240, 241, 242, 243, 244, 245, 246, 247, 249, 251, 256, 257, 258, 259, 260, 261, 262, 263, 265, 266, 267, 268, 271, 275, 280, 285, 286, 287, 288, 290, 295, 297, 301, 303, 309, 315, 316, 318, 323, 324, 325, 326, 328, 332, 333, 336, 340, 341, 344, 349, 351, 362, 365, 368, 372, 377, 378, 379, 381, 382, 384, 385, 386, 388, 389, 390, 391, 393, 394, 395, 397, 398, 400, 403, 404, 405, 407, 411, 412, 416, 417, 418, 420, 421, 422, 423, 425, 428, 430, 431, 433, 434, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 453, 455, 456, 459, 462, 463, 464, 466, 467, 472], "/home/jwright/Downloads/cadquery/cadquery/freecad_impl/importers.py": [2, 3, 5, 6, 7, 8, 9, 10, 12, 13, 15, 16, 17, 20, 28, 29, 33, 39, 41, 44, 45, 46, 48, 53], "/home/jwright/Downloads/cadquery/cadquery/freecad_impl/exporters.py": [1, 3, 4, 6, 9, 10, 15, 16, 17, 18, 19, 20, 23, 24, 25, 28, 34, 46, 47, 49, 51, 53, 55, 56, 59, 60, 61, 62, 63, 64, 65, 66, 71, 74, 76, 77, 78, 79, 83, 84, 86, 91, 92, 93, 95, 96, 99, 103, 105, 107, 108, 111, 115, 116, 118, 121, 122, 124, 125, 127, 128, 130, 131, 132, 133, 136, 137, 138, 139, 140, 141, 142, 143, 144, 147, 148, 149, 150, 151, 152, 153, 154, 157, 164, 165, 167, 168, 169, 170, 172, 173, 174, 177, 179, 180, 186, 187, 188, 189, 190, 191, 195, 210, 211, 212, 214, 215, 216, 217, 218, 220, 221, 223, 225, 226, 227, 232, 237, 239, 243, 245, 246, 247, 248, 251, 252, 254, 257, 258, 259, 260, 263, 266, 269, 270, 271, 273, 274, 275, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 294, 297, 304, 305, 306, 307, 353, 389, 391], "/home/jwright/Downloads/cadquery/cadquery/freecad_impl/geom.py": [515, 516, 517, 522, 523, 524, 529, 18, 20, 21, 22, 23, 26, 540, 542, 544, 546, 547, 548, 550, 632, 42, 44, 45, 46, 47, 560, 49, 50, 563, 564, 565, 567, 568, 569, 58, 572, 573, 575, 581, 70, 583, 72, 73, 74, 75, 76, 77, 78, 79, 592, 593, 594, 595, 597, 87, 89, 91, 93, 95, 608, 97, 99, 101, 614, 103, 616, 105, 618, 107, 109, 110, 113, 114, 116, 117, 630, 119, 120, 633, 122, 123, 125, 638, 127, 128, 130, 635, 132, 645, 134, 136, 144, 146, 147, 149, 152, 155, 158, 161, 162, 164, 167, 170, 173, 174, 177, 181, 182, 183, 184, 188, 189, 191, 192, 195, 586, 631, 206, 208, 209, 463, 634, 570, 238, 637, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 254, 255, 260, 261, 262, 263, 264, 266, 267, 268, 269, 270, 272, 273, 643, 278, 279, 280, 281, 282, 284, 285, 133, 48, 290, 291, 296, 297, 302, 303, 51, 308, 309, 52, 314, 315, 590, 629, 53, 320, 321, 326, 327, 55, 332, 345, 346, 348, 349, 350, 352, 354, 356, 358, 360, 362, 364, 365, 367, 609, 389, 391, 495, 69, 418, 419, 582, 423, 424, 71, 428, 430, 584, 611, 585, 445, 446, 587, 454, 588, 461, 462, 589, 464, 466, 467, 469, 591, 483, 485, 488, 489, 490, 491, 494, 613, 497, 499], "/home/jwright/Downloads/cadquery/cadquery/plugins/__init__.py": [18], "/home/jwright/Downloads/cadquery/cadquery/contrib/__init__.py": []}} \ No newline at end of file diff --git a/Libs/cadquery-lib/.travis.yml b/Libs/cadquery-lib/.travis.yml index 3537f48..aa8160b 100644 --- a/Libs/cadquery-lib/.travis.yml +++ b/Libs/cadquery-lib/.travis.yml @@ -7,22 +7,23 @@ install: - gcc --version - g++ --version - python ./setup.py install -- pip install coverage -- pip install coveralls -- pip install Sphinx==1.3.2 +- pip install -r requirements-dev.txt - pip install travis-sphinx -- pip install pyparsing + script: - coverage run --source=cadquery ./runtests.py - travis-sphinx --nowarn --source=doc build + after_success: - coveralls - travis-sphinx deploy + branches: except: - pythonocc - 2_0_branch -deploy: + + deploy: provider: pypi user: dcowden password: diff --git a/Libs/cadquery-lib/README.md b/Libs/cadquery-lib/README.md index 60fc9d4..8cc0b03 100644 --- a/Libs/cadquery-lib/README.md +++ b/Libs/cadquery-lib/README.md @@ -10,9 +10,9 @@ CadQuery is an intuitive, easy-to-use python based language for building paramet CadQuery has several goals: -* Build models with scripts that are as close as possible to how you'd describe the object to a human. +* Build lD models with scripts that are as close as possible to how you'd describe the object to a human. * Create parametric models that can be very easily customized by end users -* Output high quality CAD formats like STEP and AMF in addition to traditional STL +* Output high quality (loss-less) CAD formats like STEP and AMF in addition to traditional STL * Provide a non-proprietary, plain text model format that can be edited and executed with only a web browser Using CadQuery, you can write short, simple scripts that produce high quality CAD models. It is easy to make many different objects using a single script that can be customized. @@ -21,7 +21,6 @@ Full Documentation ============================ You can find the full cadquery documentation at http://dcowden.github.io/cadquery - Getting Started With CadQuery ======================================== @@ -113,6 +112,40 @@ The cadquery script is surprisingly short, and allows easily customizing any of Thanks go to cadquery contributor hyOzd ( Altu Technology ) for the example! +Projects Using CadQuery +========================= + +KiCad uses cadquery to build high quality models of electrictronic components. ( https://github.com/KiCad/packages3D ) + +

+ +

+ +This Prusa i3 extruder support uses cadquery to build the model (https://github.com/adam-urbanczyk/cadquery-models) : + +

+ +

+ +The mach30 project used cadquery to develop a tool that will create a rocket thruster directly from the appropriate equations (https://opendesignengine.net/projects/yavin-thruster/wiki): +

+ +

+ +This example uses Jupyter notebook to produce a really cool web-based scripting environment ( https://github.com/RustyVermeer/avnb/blob/master/readme.md ) : + +

+ +

+ + + + + +We would love to link to your cadquery based project. Just let us know and we'll add it here. + + + Why CadQuery instead of OpenSCAD? ======================================== diff --git a/Libs/cadquery-lib/cadquery/cq.py b/Libs/cadquery-lib/cadquery/cq.py index b2d3a50..97f135b 100644 --- a/Libs/cadquery-lib/cadquery/cq.py +++ b/Libs/cadquery-lib/cadquery/cq.py @@ -1047,7 +1047,7 @@ class Workplane(CQ): false, the lower left corner will be at the center of the work plane """ - if xSpacing < 1 or ySpacing < 1 or xCount < 1 or yCount < 1: + if xSpacing <= 0 or ySpacing <= 0 or xCount < 1 or yCount < 1: raise ValueError("Spacing and count must be > 0 ") lpoints = [] # coordinates relative to bottom left point diff --git a/Libs/cadquery-lib/cadquery/cqgi.py b/Libs/cadquery-lib/cadquery/cqgi.py index 01701db..329074b 100644 --- a/Libs/cadquery-lib/cadquery/cqgi.py +++ b/Libs/cadquery-lib/cadquery/cqgi.py @@ -115,11 +115,11 @@ class CQModel(object): else: raise NoOutputError("Script did not call build_object-- no output available.") except Exception, ex: - print "Error Executing Script:" + #print "Error Executing Script:" result.set_failure_result(ex) - traceback.print_exc() - print "Full Text of Script:" - print self.script_source + #traceback.print_exc() + #print "Full Text of Script:" + #print self.script_source end = time.clock() result.buildTime = end - start @@ -180,7 +180,7 @@ class ScriptMetadata(object): self.parameters[p.name] = p def add_parameter_description(self,name,description): - print 'Adding Parameter name=%s, desc=%s' % ( name, description ) + #print 'Adding Parameter name=%s, desc=%s' % ( name, description ) p = self.parameters[name] p.desc = description @@ -418,7 +418,7 @@ class ParameterDescriptionFinder(ast.NodeTransformer): self.cqModel.add_parameter_description(varname,desc) except: - print "Unable to handle function call" + #print "Unable to handle function call" pass return node diff --git a/Libs/cadquery-lib/cadquery/freecad_impl/__init__.py b/Libs/cadquery-lib/cadquery/freecad_impl/__init__.py index 05ed957..3a82a2f 100644 --- a/Libs/cadquery-lib/cadquery/freecad_impl/__init__.py +++ b/Libs/cadquery-lib/cadquery/freecad_impl/__init__.py @@ -35,6 +35,7 @@ def _fc_path(): "/usr/lib/freecad/lib", "/opt/freecad/lib/", "/usr/bin/freecad/lib", + "/usr/lib/freecad-daily/lib", "/usr/lib/freecad", "/usr/lib64/freecad/lib", ]: diff --git a/Libs/cadquery-lib/cadquery/freecad_impl/shapes.py b/Libs/cadquery-lib/cadquery/freecad_impl/shapes.py index 12567e9..6f65ccc 100644 --- a/Libs/cadquery-lib/cadquery/freecad_impl/shapes.py +++ b/Libs/cadquery-lib/cadquery/freecad_impl/shapes.py @@ -420,11 +420,17 @@ class Edge(Shape): # self.endPoint = None self.edgetypes = { - FreeCADPart.Line: 'LINE', FreeCADPart.ArcOfCircle: 'ARC', FreeCADPart.Circle: 'CIRCLE' } + if hasattr(FreeCADPart,"LineSegment"): + #FreeCAD <= 0.16 + self.edgetypes[FreeCADPart.LineSegment] = 'LINE' + else: + #FreeCAD >= 0.17 + self.edgetypes[FreeCADPart.Line] = 'LINE' + # Helps identify this solid through the use of an ID self.label = "" diff --git a/Libs/cadquery-lib/cadquery/selectors.py b/Libs/cadquery-lib/cadquery/selectors.py index 72174e1..a2d476e 100644 --- a/Libs/cadquery-lib/cadquery/selectors.py +++ b/Libs/cadquery-lib/cadquery/selectors.py @@ -20,6 +20,7 @@ import re import math from cadquery import Vector,Edge,Vertex,Face,Solid,Shell,Compound +from collections import defaultdict from pyparsing import Literal,Word,nums,Optional,Combine,oneOf,upcaseTokens,\ CaselessLiteral,Group,infixNotation,opAssoc,Forward,\ ZeroOrMore,Keyword @@ -299,11 +300,6 @@ class DirectionMinMaxSelector(Selector): def distance(tShape): return tShape.Center().dot(self.vector) - #if tShape.ShapeType == 'Vertex': - # pnt = tShape.Point - #else: - # pnt = tShape.Center() - #return pnt.dot(self.vector) # import OrderedDict from collections import OrderedDict @@ -336,34 +332,30 @@ class DirectionNthSelector(ParallelDirSelector): self.max = max self.directionMax = directionMax self.TOLERANCE = tolerance - if directionMax: - self.N = n #do we want indexing from 0 or from 1? - else: - self.N = -n - + self.N = n + def filter(self,objectList): #select first the objects that are normal/parallel to a given dir objectList = super(DirectionNthSelector,self).filter(objectList) def distance(tShape): return tShape.Center().dot(self.direction) - #if tShape.ShapeType == 'Vertex': - # pnt = tShape.Point - #else: - # pnt = tShape.Center() - #return pnt.dot(self.vector) - - #make and distance to object dict - objectDict = {distance(el) : el for el in objectList} + #calculate how many digits of precision do we need digits = int(1/self.TOLERANCE) - # create a rounded distance to original distance mapping (implicitly perfroms unique operation) - dist_round_dist = {round(d,digits) : d for d in objectDict.keys()} + + #make a distance to object dict + #this is one to many mapping so I am using a default dict with list + objectDict = defaultdict(list) + for el in objectList: + objectDict[round(distance(el),digits)].append(el) + # choose the Nth unique rounded distance - nth_d = dist_round_dist[sorted(dist_round_dist.keys())[self.N]] + nth_distance = sorted(objectDict.keys(), + reverse=not self.directionMax)[self.N] # map back to original objects and return - return [objectDict[d] for d in objectDict.keys() if abs(d-nth_d) < self.TOLERANCE] + return objectDict[nth_distance] class BinarySelector(Selector): """ diff --git a/Libs/cadquery-lib/doc/apireference.rst b/Libs/cadquery-lib/doc/apireference.rst index 55aea7d..59b04c6 100644 --- a/Libs/cadquery-lib/doc/apireference.rst +++ b/Libs/cadquery-lib/doc/apireference.rst @@ -157,6 +157,7 @@ as a basis for futher operations. BaseDirSelector ParallelDirSelector DirectionSelector + DirectionNthSelector PerpendicularDirSelector TypeSelector DirectionMinMaxSelector diff --git a/Libs/cadquery-lib/doc/classreference.rst b/Libs/cadquery-lib/doc/classreference.rst index b072b39..ce88a2a 100644 --- a/Libs/cadquery-lib/doc/classreference.rst +++ b/Libs/cadquery-lib/doc/classreference.rst @@ -52,6 +52,7 @@ Selector Classes BaseDirSelector ParallelDirSelector DirectionSelector + DirectionNthSelector PerpendicularDirSelector TypeSelector DirectionMinMaxSelector diff --git a/Libs/cadquery-lib/doc/installation.rst b/Libs/cadquery-lib/doc/installation.rst index 8633a9d..b5160b0 100644 --- a/Libs/cadquery-lib/doc/installation.rst +++ b/Libs/cadquery-lib/doc/installation.rst @@ -47,11 +47,6 @@ If you prefer to have a GUI available, your best option is to use Simply extract cadquery-freecad-module into your FreeCAD installation. You'll end up with a cadquery workbench that allows you to interactively run scripts, and then see the results in the FreeCAD GUI -If you are using Ubuntu, you can also install it via this ppa: - -https://code.launchpad.net/~freecad-community/+archive/ubuntu/ppa/+packages - - Zero Step Install ------------------------------------------------- diff --git a/Libs/cadquery-lib/doc/roadmap.rst b/Libs/cadquery-lib/doc/roadmap.rst index 3337ff2..a5b7e28 100644 --- a/Libs/cadquery-lib/doc/roadmap.rst +++ b/Libs/cadquery-lib/doc/roadmap.rst @@ -29,18 +29,6 @@ face.outerWire Selectors -------------------- -Chained Selectors - Space delimited selectors should be unioned to allow multiple selections. For example ">Z >X" - -Ad-hoc axes - for example, >(1,2,1) would select a face with normal in the 1,2,1 direction - -logic inversion - ! or not to invert logic, such as "!(>Z)" to select faces _other_ than the most z facing - -closest to point - support faces, points, or edges closest to a provided point - tagged entities support tagging entities when they are created, so they can be selected later on using that tag. ideally, tags are propagated to features that are created from these features ( ie, an edge tagged with 'foo' diff --git a/Libs/cadquery-lib/doc/selectors.rst b/Libs/cadquery-lib/doc/selectors.rst index b14a02a..c40c547 100644 --- a/Libs/cadquery-lib/doc/selectors.rst +++ b/Libs/cadquery-lib/doc/selectors.rst @@ -28,26 +28,28 @@ string patterns in, CadQuery will automatically use the associated selector obje Combining Selectors ========================== -Selectors can be combined arithmetically and logically, so that it is possible to do intersection, union, and other -combinations. For example:: +Selectors can be combined logically, currently defined operators include **and**, **or**, **not** and **exc[ept]** (set difference). For example: - box = cadquery.Workplane("XY").box(10,10,10) +.. cq_plot:: - s = selectors.StringSyntaxSelector + result = cq.Workplane("XY").box(2, 2, 2) \ + .edges("|Z and >Y") \ + .chamfer(0.2) + + build_object(result) - ### select all edges on right and left faces - #box = box.edges((s("|Z") + s("|Y"))).fillet(1) +Much more complex expressions are possible as well: - ### select all edges on top and bottom - #box = box.edges(-s("|Z")).fillet(1) - #box = box.edges(s('|X')+s('Y')).fillet(1) - box = box.faces(s('>Z')+s('Z')+s('Z") \ + .shell(-0.2) \ + .faces(">Z") \ + .edges("not(X or Y)") \ + .chamfer(0.1) + + build_object(result) .. _filteringfaces: @@ -64,17 +66,19 @@ of the face. The axis used in the listing below are for illustration: any axis would work similarly in each case. -========= ====================================== ======================================================= ========================== -Selector Selects Selector Class # objects returned -========= ====================================== ======================================================= ========================== -+Z Faces with normal in +z direction :py:class:`cadquery.DirectionSelector` 0 or 1 -\|Z Faces parallel to xy plane :py:class:`cadquery.ParallelDirSelector` 0..many --X Faces with normal in neg x direction :py:class:`cadquery.DirectionSelector` 0..many -#Z Faces perpendicular to z direction :py:class:`cadquery.PerpendicularDirSelector` 0..many -%Plane Faces of type plane :py:class:`cadquery.TypeSelector` 0..many ->Y Face farthest in the positive y dir :py:class:`cadquery.DirectionMinMaxSelector` 0 or 1 -Y Face farthest in the positive y dir :py:class:`cadquery.DirectionMinMaxSelector` 0..many +Y[-2] 2nd Face farthest in the positive y dir :py:class:`cadquery.DirectionMinMaxSelector` 0..many +Y Edges farthest in the positive y dir :py:class:`cadquery.DirectionMinMaxSelector` 0 or 1 -Y Edges farthest in the positive y dir :py:class:`cadquery.DirectionMinMaxSelector` 0..many +Y[1] 2nd closest edge in the positive y dir :py:class:`cadquery.DirectionMinMaxSelector` 0..many +Y Vertices farthest in the positive y dir :py:class:`cadquery.DirectionMinMaxSelector` 0 or 1 -Y Vertices farthest in the positive y dir :py:class:`cadquery.DirectionMinMaxSelector` 0..many +(-1,1,0)').chamfer(1) + + build_object(result) diff --git a/Libs/cadquery-lib/requirements-dev.txt b/Libs/cadquery-lib/requirements-dev.txt index 872a66d..14429e3 100644 --- a/Libs/cadquery-lib/requirements-dev.txt +++ b/Libs/cadquery-lib/requirements-dev.txt @@ -1,3 +1,6 @@ sphinx-rtd-theme==0.1.9 -travis-sphinx==1.1.0 -Sphinx==1.3.1 +travis-sphinx +Sphinx==1.3.2 +coverage +coveralls +pyparsing diff --git a/Libs/cadquery-lib/tests/TestCQSelectors.py b/Libs/cadquery-lib/tests/TestCQSelectors.py index 9b5e12f..1bc411b 100644 --- a/Libs/cadquery-lib/tests/TestCQSelectors.py +++ b/Libs/cadquery-lib/tests/TestCQSelectors.py @@ -194,10 +194,14 @@ class TestCQSelectors(BaseTest): #2nd face val = c.faces('>(1,0,0)[1]').val() self.assertAlmostEqual(val.Center().x,-1.5) + val = c.faces('>X[1]').val() + self.assertAlmostEqual(val.Center().x,-1.5) #2nd face with inversed selection vector val = c.faces('>(-1,0,0)[1]').val() self.assertAlmostEqual(val.Center().x,1.5) + val = c.faces('X[-2]').val() @@ -210,6 +214,46 @@ class TestCQSelectors(BaseTest): #check if the selected face if normal to the specified Vector self.assertAlmostEqual(val.normalAt().cross(Vector(1,0,0)).Length,0.0) + #test selection of multiple faces with the same distance + c = Workplane('XY')\ + .box(1,4,1,centered=(False,True,False)).faces('Z')\ + .box(1,1,1,centered=(True,True,False)) + + #select 2nd from the bottom (NB python indexing is 0-based) + vals = c.faces('>Z[1]').vals() + self.assertEqual(len(vals),2) + + val = c.faces('>Z[1]').val() + self.assertAlmostEqual(val.Center().z,1) + + #do the same but by selecting 3rd from the top + vals = c.faces('Z[-1] is equivalent to >Z + val1 = c.faces('>Z[-1]').val() + val2 = c.faces('>Z').val() + self.assertTupleAlmostEquals(val1.Center().toTuple(), + val2.Center().toTuple(), + 3) def testNearestTo(self): c = CQ(makeUnitCube()) From ecefa3d707cda3285af25862679c5d740248ee32 Mon Sep 17 00:00:00 2001 From: Jeremy Mack Wright Date: Mon, 24 Jul 2017 16:51:18 -0400 Subject: [PATCH 02/19] Added a toggle for the variable editor and started stubbing in that and a script validation function. --- Gui/Command.py | 78 ++++++++++++++++++++++++++++-- InitGui.py | 4 +- Libs/cadquery-lib/cadquery/cqgi.py | 2 +- 3 files changed, 79 insertions(+), 5 deletions(-) diff --git a/Gui/Command.py b/Gui/Command.py index 31ef1e3..e0db8a1 100644 --- a/Gui/Command.py +++ b/Gui/Command.py @@ -4,7 +4,7 @@ import imp, os, sys, tempfile import FreeCAD, FreeCADGui -from PySide import QtGui +from PySide import QtGui, QtCore import ExportCQ, ImportCQ import module_locator import Settings @@ -22,7 +22,9 @@ class CadQueryClearOutput: def GetResources(self): return {"MenuText": "Clear Output", - "ToolTip": "Clears the script output from the Reports view"} + "Accel": "Shift+Alt+C", + "ToolTip": "Clears the script output from the Reports view", + "Pixmap": ":/icons/button_invalid.svg"} def IsActive(self): return True @@ -42,7 +44,8 @@ class CadQueryCloseScript: def GetResources(self): return {"MenuText": "Close Script", - "ToolTip": "Closes the CadQuery script"} + "ToolTip": "Closes the CadQuery script", + "Pixmap": ":/icons/edit_Cancel.svg"} def IsActive(self): return True @@ -311,3 +314,72 @@ class CadQuerySaveAsScript: # Save the file before closing the original and the re-rendering the new one ExportCQ.save(filename[0]) CadQueryExecuteScript().Activated() + + +class ToggleVariablesEditor: + """If the user is running a CQGI-compliant script, they can edit variables through this edistor""" + + def GetResources(self): + return {"MenuText": "Toggle Variables Editor", + "Accel": "Shift+Alt+E", + "ToolTip": "Opens a live variables editor editor", + "Pixmap": ":/icons/edit-edit.svg"} + + def IsActive(self): + return True + + def Activated(self): + mw = FreeCADGui.getMainWindow() + + # Tracks whether or not we have already added the variables editor + isPresent = False + + # If the widget is open, we need to close it + dockWidgets = mw.findChildren(QtGui.QDockWidget) + for widget in dockWidgets: + if widget.objectName() == "cqVarsEditor": + # Toggle the visibility of the widget + if widget.visibleRegion().isEmpty(): + widget.setVisible(True) + else: + widget.setVisible(False) + + isPresent = True + + if not isPresent: + cqVariablesEditor = QtGui.QDockWidget("CadQuery Variables Editor") + cqVariablesEditor.setObjectName("cqVarsEditor") + mw.addDockWidget(QtCore.Qt.LeftDockWidgetArea, cqVariablesEditor) + + +class CadQueryValidateScript: + """Checks the script for the user without executing it and populates the variable editor, if needed""" + + def GetResources(self): + return {"MenuText": "Validate Script", + "Accel": "F4", + "ToolTip": "Validates a CadQuery script", + "Pixmap": ":/icons/edit_OK.svg"} + + def IsActive(self): + return True + + def Activated(self): + mw = FreeCADGui.getMainWindow() + + # Tracks whether or not we have already added the variables editor + isPresent = False + + # If the widget is open, we need to close it + dockWidgets = mw.findChildren(QtGui.QDockWidget) + for widget in dockWidgets: + if widget.objectName() == "cqVarsEditor": + # TODO: Clear and then populate the controls in the widget based on the variables + + # Toggle the visibility of the widget + # if widget.visibleRegion().isEmpty(): + # widget.setVisible(True) + # else: + # widget.setVisible(False) + + isPresent = True \ No newline at end of file diff --git a/InitGui.py b/InitGui.py index 87d012c..14c0616 100644 --- a/InitGui.py +++ b/InitGui.py @@ -34,7 +34,7 @@ class CadQueryWorkbench (Workbench): self.appendMenu('CadQuery', ['CadQueryNewScript', 'CadQueryOpenScript', 'CadQuerySaveScript', 'CadQuerySaveAsScript', 'CadQueryCloseScript']) self.appendMenu(['CadQuery', 'Examples'], submenu) - self.appendMenu('CadQuery', ['Separator', 'CadQueryExecuteScript', 'CadQueryClearOutput']) + self.appendMenu('CadQuery', ['Separator', 'CadQueryExecuteScript', 'CadQueryValidateScript', 'ToggleVariablesEditor', 'CadQueryClearOutput']) def Activated(self): import os @@ -111,7 +111,9 @@ FreeCADGui.addCommand('CadQueryOpenScript', CadQueryOpenScript()) FreeCADGui.addCommand('CadQuerySaveScript', CadQuerySaveScript()) FreeCADGui.addCommand('CadQuerySaveAsScript', CadQuerySaveAsScript()) FreeCADGui.addCommand('CadQueryExecuteScript', CadQueryExecuteScript()) +FreeCADGui.addCommand('CadQueryValidateScript', CadQueryValidateScript()) FreeCADGui.addCommand('CadQueryCloseScript', CadQueryCloseScript()) +FreeCADGui.addCommand('ToggleVariablesEditor', ToggleVariablesEditor()) FreeCADGui.addCommand('CadQueryClearOutput', CadQueryClearOutput()) # Step through and add an Examples submenu item for each example diff --git a/Libs/cadquery-lib/cadquery/cqgi.py b/Libs/cadquery-lib/cadquery/cqgi.py index 329074b..8fa7b0c 100644 --- a/Libs/cadquery-lib/cadquery/cqgi.py +++ b/Libs/cadquery-lib/cadquery/cqgi.py @@ -48,7 +48,7 @@ class CQModel(object): # TODO: pick up other scirpt metadata: # describe # pick up validation methods - self._find_descriptions() + self._find_descriptions() def _find_vars(self): """ From 896bcca7c97b33709096e52d8d13681a3fa05966 Mon Sep 17 00:00:00 2001 From: Jeremy Mack Wright Date: Sat, 29 Jul 2017 08:20:53 -0400 Subject: [PATCH 03/19] Worked through script validation and started to implement the logic to populate the parameters editor. --- Gui/Command.py | 47 +++++++++++++++++++++++++---------------------- InitGui.py | 2 +- Shared.py | 34 ++++++++++++++++++++++++++++++++-- 3 files changed, 58 insertions(+), 25 deletions(-) diff --git a/Gui/Command.py b/Gui/Command.py index e0db8a1..338ddb6 100644 --- a/Gui/Command.py +++ b/Gui/Command.py @@ -127,8 +127,9 @@ class CadQueryExecuteScript: # Clear the old render before re-rendering Shared.clearActiveDocument() - # Check to see if we are executig a CQGI compliant script scriptText = cqCodePane.toPlainText().encode('utf-8') + + # Check to see if we are executig a CQGI compliant script if "build_object(" in scriptText and "# build_object(" not in scriptText and "#build_boject(" not in scriptText: FreeCAD.Console.PrintMessage("Executing CQGI-compliant script.\r\n") @@ -138,11 +139,7 @@ class CadQueryExecuteScript: # Allows us to present parameters to users later that they can alter parameters = cqModel.metadata.parameters - FreeCAD.Console.PrintMessage("Script Variables:\r\n") - for key, value in parameters.iteritems(): - FreeCAD.Console.PrintMessage("variable name: " + key + ", variable value: " + str(value.default_value) + "\r\n") - - build_result = cqgi.parse(scriptText).build() + build_result = cqModel.build() # Make sure that the build was successful if build_result.success: @@ -316,11 +313,11 @@ class CadQuerySaveAsScript: CadQueryExecuteScript().Activated() -class ToggleVariablesEditor: +class ToggleParametersEditor: """If the user is running a CQGI-compliant script, they can edit variables through this edistor""" def GetResources(self): - return {"MenuText": "Toggle Variables Editor", + return {"MenuText": "Toggle Parameters Editor", "Accel": "Shift+Alt+E", "ToolTip": "Opens a live variables editor editor", "Pixmap": ":/icons/edit-edit.svg"} @@ -365,21 +362,27 @@ class CadQueryValidateScript: return True def Activated(self): - mw = FreeCADGui.getMainWindow() + # Grab our code editor so we can interact with it + cqCodePane = Shared.getActiveCodePane() - # Tracks whether or not we have already added the variables editor - isPresent = False + # If there is no script to check, ignore this command + if cqCodePane is None: + FreeCAD.Console.PrintMessage("There is no script to validate.") + return - # If the widget is open, we need to close it - dockWidgets = mw.findChildren(QtGui.QDockWidget) - for widget in dockWidgets: - if widget.objectName() == "cqVarsEditor": - # TODO: Clear and then populate the controls in the widget based on the variables + # Clear the old render before re-rendering + Shared.clearActiveDocument() - # Toggle the visibility of the widget - # if widget.visibleRegion().isEmpty(): - # widget.setVisible(True) - # else: - # widget.setVisible(False) + scriptText = cqCodePane.toPlainText().encode('utf-8') - isPresent = True \ No newline at end of file + if "build_object(" not in scriptText or "# build_object(" in scriptText or "#build_boject(" in scriptText: + FreeCAD.Console.PrintError("Script did not call build_object, no output available. Script must be CQGI compliant to get build output, variable editing and validation.\r\n") + return + + # A repreentation of the CQ script with all the metadata attached + cqModel = cqgi.parse(scriptText) + + # Allows us to present parameters to users later that they can alter + parameters = cqModel.metadata.parameters + + Shared.populateParameterEditor(parameters) \ No newline at end of file diff --git a/InitGui.py b/InitGui.py index 14c0616..705843d 100644 --- a/InitGui.py +++ b/InitGui.py @@ -113,7 +113,7 @@ FreeCADGui.addCommand('CadQuerySaveAsScript', CadQuerySaveAsScript()) FreeCADGui.addCommand('CadQueryExecuteScript', CadQueryExecuteScript()) FreeCADGui.addCommand('CadQueryValidateScript', CadQueryValidateScript()) FreeCADGui.addCommand('CadQueryCloseScript', CadQueryCloseScript()) -FreeCADGui.addCommand('ToggleVariablesEditor', ToggleVariablesEditor()) +FreeCADGui.addCommand('ToggleVariablesEditor', ToggleParametersEditor()) FreeCADGui.addCommand('CadQueryClearOutput', CadQueryClearOutput()) # Step through and add an Examples submenu item for each example diff --git a/Shared.py b/Shared.py index 24b5ca9..7354c54 100644 --- a/Shared.py +++ b/Shared.py @@ -9,7 +9,10 @@ def clearActiveDocument(): # Grab our code editor so we can interact with it mw = FreeCADGui.getMainWindow() mdi = mw.findChild(QtGui.QMdiArea) - winName = mdi.currentSubWindow().windowTitle().split(" ")[0].split('.')[0] + currentWin = mdi.currentSubWindow() + if currentWin == None: + return + winName = currentWin.windowTitle().split(" ")[0].split('.')[0] try: doc = FreeCAD.getDocument(winName) @@ -84,4 +87,31 @@ def setActiveWindowTitle(title): mdiWin.setWindowTitle(title) cqCodePane = mdiWin.findChild(QtGui.QPlainTextEdit) - cqCodePane.setObjectName("cqCodePane_" + title.split('.')[0]) \ No newline at end of file + cqCodePane.setObjectName("cqCodePane_" + title.split('.')[0]) + + +def populateParameterEditor(parameters): + """Puts the proper controls in the script variable editor pane based on the parameters found""" + + FreeCAD.Console.PrintMessage("Script Variables:\r\n") + for key, value in parameters.iteritems(): + FreeCAD.Console.PrintMessage("variable name: " + key + ", variable value: " + str(value.default_value) + "\r\n") + + mw = FreeCADGui.getMainWindow() + + # Tracks whether or not we have already added the variables editor + isPresent = False + + # If the widget is open, we need to close it + dockWidgets = mw.findChildren(QtGui.QDockWidget) + for widget in dockWidgets: + if widget.objectName() == "cqVarsEditor": + # TODO: Clear and then populate the controls in the widget based on the variables + + # Toggle the visibility of the widget + # if widget.visibleRegion().isEmpty(): + # widget.setVisible(True) + # else: + # widget.setVisible(False) + + isPresent = True \ No newline at end of file From 81d1f4e8508616739c5f67ceafb0cc2669eafe0d Mon Sep 17 00:00:00 2001 From: Jeremy Mack Wright Date: Sun, 13 Aug 2017 08:46:29 -0400 Subject: [PATCH 04/19] Got the variables editor to populate with controls for each of the variables in the script. --- Gui/Command.py | 6 +++++- Shared.py | 26 +++++++++++++++++++++++--- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/Gui/Command.py b/Gui/Command.py index 338ddb6..a81699a 100644 --- a/Gui/Command.py +++ b/Gui/Command.py @@ -346,6 +346,10 @@ class ToggleParametersEditor: if not isPresent: cqVariablesEditor = QtGui.QDockWidget("CadQuery Variables Editor") cqVariablesEditor.setObjectName("cqVarsEditor") + # cqVariablesEditor.setAutoFillBackground(True) + # p = cqVariablesEditor.palette() + # p.setColor(cqVariablesEditor.backgroundRole(), '#FF0000') + # cqVariablesEditor.setPalette(p) mw.addDockWidget(QtCore.Qt.LeftDockWidgetArea, cqVariablesEditor) @@ -378,7 +382,7 @@ class CadQueryValidateScript: if "build_object(" not in scriptText or "# build_object(" in scriptText or "#build_boject(" in scriptText: FreeCAD.Console.PrintError("Script did not call build_object, no output available. Script must be CQGI compliant to get build output, variable editing and validation.\r\n") return - + # A repreentation of the CQ script with all the metadata attached cqModel = cqgi.parse(scriptText) diff --git a/Shared.py b/Shared.py index 7354c54..a6ff2e7 100644 --- a/Shared.py +++ b/Shared.py @@ -94,19 +94,39 @@ def populateParameterEditor(parameters): """Puts the proper controls in the script variable editor pane based on the parameters found""" FreeCAD.Console.PrintMessage("Script Variables:\r\n") - for key, value in parameters.iteritems(): - FreeCAD.Console.PrintMessage("variable name: " + key + ", variable value: " + str(value.default_value) + "\r\n") mw = FreeCADGui.getMainWindow() # Tracks whether or not we have already added the variables editor isPresent = False + # TODO: Clear and then populate the controls in the widget based on the variables + # https://stackoverflow.com/questions/3940409/how-to-clear-all-the-widgets-in-parent-widgets + # If the widget is open, we need to close it dockWidgets = mw.findChildren(QtGui.QDockWidget) for widget in dockWidgets: if widget.objectName() == "cqVarsEditor": - # TODO: Clear and then populate the controls in the widget based on the variables + gridLayout = QtGui.QGridLayout() + + line = 1 + for pKey, pVal in parameters.iteritems(): + FreeCAD.Console.PrintMessage("variable name: " + pKey + ", variable value: " + str(pVal.default_value) + "\r\n") + label = QtGui.QLabel(pKey) + value = QtGui.QLineEdit() + value.setText(str(pVal.default_value)) + btn = QtGui.QPushButton("OK") + gridLayout.addWidget(label, line, 0) + gridLayout.addWidget(value, line, 1) + gridLayout.addWidget(btn, line, 2) + + line += 1 + + # Create a widget we can put the layout in + newWidget = QtGui.QWidget() + newWidget.setLayout(gridLayout) + + widget.setWidget(newWidget) # Toggle the visibility of the widget # if widget.visibleRegion().isEmpty(): From 84c0a9b24911989ce6d3408759e0554b971094d6 Mon Sep 17 00:00:00 2001 From: Jeremy Mack Wright Date: Thu, 17 Aug 2017 11:20:50 -0400 Subject: [PATCH 05/19] Added a scroll bar to the variables editor and made sure that the widget was being replaced each time validation is complete. --- Shared.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Shared.py b/Shared.py index a6ff2e7..ae490bc 100644 --- a/Shared.py +++ b/Shared.py @@ -100,9 +100,6 @@ def populateParameterEditor(parameters): # Tracks whether or not we have already added the variables editor isPresent = False - # TODO: Clear and then populate the controls in the widget based on the variables - # https://stackoverflow.com/questions/3940409/how-to-clear-all-the-widgets-in-parent-widgets - # If the widget is open, we need to close it dockWidgets = mw.findChildren(QtGui.QDockWidget) for widget in dockWidgets: @@ -122,11 +119,15 @@ def populateParameterEditor(parameters): line += 1 - # Create a widget we can put the layout in + # Create a widget we can put the layout in and add a scrollbar newWidget = QtGui.QWidget() newWidget.setLayout(gridLayout) + scrollArea = QtGui.QScrollArea() + scrollArea.setBackgroundRole(QtGui.QPalette.Light) + scrollArea.setStyleSheet("QLabel { color : black; }"); + scrollArea.setWidget(newWidget) - widget.setWidget(newWidget) + widget.setWidget(scrollArea) # Toggle the visibility of the widget # if widget.visibleRegion().isEmpty(): From 68907ba9d7c9477e9a10f4349000ad2efd2b349b Mon Sep 17 00:00:00 2001 From: Jeremy Mack Wright Date: Sat, 19 Aug 2017 17:22:20 -0400 Subject: [PATCH 06/19] Got the parameters editor working so that it can modify the model, but it still needs a lot of clean-up. --- Gui/Command.py | 36 +++++++++++++++++++++++++++++++----- Shared.py | 5 +++-- 2 files changed, 34 insertions(+), 7 deletions(-) diff --git a/Gui/Command.py b/Gui/Command.py index a81699a..868a298 100644 --- a/Gui/Command.py +++ b/Gui/Command.py @@ -138,8 +138,34 @@ class CadQueryExecuteScript: # Allows us to present parameters to users later that they can alter parameters = cqModel.metadata.parameters + build_parameters = {} - build_result = cqModel.build() + # Collect the build parameters from the Parameters Editor view, if they exist + mw = FreeCADGui.getMainWindow() + + # Tracks whether or not we have already added the variables editor + isPresent = False + + # If the widget is open, we need to close it + dockWidgets = mw.findChildren(QtGui.QDockWidget) + for widget in dockWidgets: + if widget.objectName() == "cqVarsEditor": + # Toggle the visibility of the widget + if not widget.visibleRegion().isEmpty(): + # build_parameters = {'param': 2} + + # Find all of the controls that will have parameter values in them + valueControls = mw.findChildren(QtGui.QLineEdit) + for valueControl in valueControls: + objectName = valueControl.objectName() + FreeCAD.Console.PrintMessage(objectName + "\r\n") + if objectName != None and objectName != '' and objectName[0] == 'p': + FreeCAD.Console.PrintMessage(objectName.split('_')[1] + "\r\n") + build_parameters[objectName.split('_')[1]] = valueControl.text() + + FreeCAD.Console.PrintMessage(build_parameters[objectName.split('_')[1]] + "\r\n") + + build_result = cqModel.build(build_parameters=build_parameters) # Make sure that the build was successful if build_result.success: @@ -346,12 +372,12 @@ class ToggleParametersEditor: if not isPresent: cqVariablesEditor = QtGui.QDockWidget("CadQuery Variables Editor") cqVariablesEditor.setObjectName("cqVarsEditor") - # cqVariablesEditor.setAutoFillBackground(True) - # p = cqVariablesEditor.palette() - # p.setColor(cqVariablesEditor.backgroundRole(), '#FF0000') - # cqVariablesEditor.setPalette(p) + mw.addDockWidget(QtCore.Qt.LeftDockWidgetArea, cqVariablesEditor) + # Go ahead and populate the view if there are variables in the script + CadQueryValidateScript().Activated() + class CadQueryValidateScript: """Checks the script for the user without executing it and populates the variable editor, if needed""" diff --git a/Shared.py b/Shared.py index ae490bc..9726cca 100644 --- a/Shared.py +++ b/Shared.py @@ -112,10 +112,11 @@ def populateParameterEditor(parameters): label = QtGui.QLabel(pKey) value = QtGui.QLineEdit() value.setText(str(pVal.default_value)) - btn = QtGui.QPushButton("OK") + value.setObjectName("p_" + pKey) + # btn = QtGui.QPushButton("OK") gridLayout.addWidget(label, line, 0) gridLayout.addWidget(value, line, 1) - gridLayout.addWidget(btn, line, 2) + # gridLayout.addWidget(btn, line, 2) line += 1 From 44e8533f26b89487cb6aa10b0a14e9cbc10f8032 Mon Sep 17 00:00:00 2001 From: Jeremy Mack Wright Date: Sat, 19 Aug 2017 23:12:14 -0400 Subject: [PATCH 07/19] Cleaned up the CQGI execution code and made it a little more robust. --- Gui/Command.py | 11 ++++------- Shared.py | 19 +++++++++---------- 2 files changed, 13 insertions(+), 17 deletions(-) diff --git a/Gui/Command.py b/Gui/Command.py index 868a298..6b12fba 100644 --- a/Gui/Command.py +++ b/Gui/Command.py @@ -152,18 +152,15 @@ class CadQueryExecuteScript: if widget.objectName() == "cqVarsEditor": # Toggle the visibility of the widget if not widget.visibleRegion().isEmpty(): - # build_parameters = {'param': 2} - # Find all of the controls that will have parameter values in them valueControls = mw.findChildren(QtGui.QLineEdit) for valueControl in valueControls: objectName = valueControl.objectName() - FreeCAD.Console.PrintMessage(objectName + "\r\n") - if objectName != None and objectName != '' and objectName[0] == 'p': - FreeCAD.Console.PrintMessage(objectName.split('_')[1] + "\r\n") - build_parameters[objectName.split('_')[1]] = valueControl.text() - FreeCAD.Console.PrintMessage(build_parameters[objectName.split('_')[1]] + "\r\n") + # We only want text fields that will have parameter values in them + if objectName != None and objectName != '' and objectName.find('pcontrol_') >= 0: + # Associate the value in the text field with the variable name in the script + build_parameters[objectName.replace('pcontrol_', '')] = valueControl.text() build_result = cqModel.build(build_parameters=build_parameters) diff --git a/Shared.py b/Shared.py index 9726cca..ed271ea 100644 --- a/Shared.py +++ b/Shared.py @@ -107,22 +107,27 @@ def populateParameterEditor(parameters): gridLayout = QtGui.QGridLayout() line = 1 + + # Add controls for all the parameters so that they can be edited from the GUI for pKey, pVal in parameters.iteritems(): - FreeCAD.Console.PrintMessage("variable name: " + pKey + ", variable value: " + str(pVal.default_value) + "\r\n") label = QtGui.QLabel(pKey) + + # We want to keep track of this parameter value field so that we can pull its value later when executing value = QtGui.QLineEdit() value.setText(str(pVal.default_value)) - value.setObjectName("p_" + pKey) - # btn = QtGui.QPushButton("OK") + value.setObjectName("pcontrol_" + pKey) + + # Add the parameter control sets, one set per line gridLayout.addWidget(label, line, 0) gridLayout.addWidget(value, line, 1) - # gridLayout.addWidget(btn, line, 2) line += 1 # Create a widget we can put the layout in and add a scrollbar newWidget = QtGui.QWidget() newWidget.setLayout(gridLayout) + + # Add a scroll bar in case there are a lot of variables in the script scrollArea = QtGui.QScrollArea() scrollArea.setBackgroundRole(QtGui.QPalette.Light) scrollArea.setStyleSheet("QLabel { color : black; }"); @@ -130,10 +135,4 @@ def populateParameterEditor(parameters): widget.setWidget(scrollArea) - # Toggle the visibility of the widget - # if widget.visibleRegion().isEmpty(): - # widget.setVisible(True) - # else: - # widget.setVisible(False) - isPresent = True \ No newline at end of file From 9cb1e58f3f0c2cdf03c498f25831246460ab7cc1 Mon Sep 17 00:00:00 2001 From: Jeremy Mack Wright Date: Fri, 1 Sep 2017 16:33:32 -0400 Subject: [PATCH 08/19] Made the variables area scrollable. --- Shared.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/Shared.py b/Shared.py index ed271ea..96fb214 100644 --- a/Shared.py +++ b/Shared.py @@ -97,9 +97,6 @@ def populateParameterEditor(parameters): mw = FreeCADGui.getMainWindow() - # Tracks whether or not we have already added the variables editor - isPresent = False - # If the widget is open, we need to close it dockWidgets = mw.findChildren(QtGui.QDockWidget) for widget in dockWidgets: @@ -133,6 +130,4 @@ def populateParameterEditor(parameters): scrollArea.setStyleSheet("QLabel { color : black; }"); scrollArea.setWidget(newWidget) - widget.setWidget(scrollArea) - - isPresent = True \ No newline at end of file + widget.setWidget(scrollArea) \ No newline at end of file From 9689664aa189a09001d76034b077e97fcad396f0 Mon Sep 17 00:00:00 2001 From: Jeremy Mack Wright Date: Sat, 2 Sep 2017 00:03:00 -0400 Subject: [PATCH 09/19] Removed deprecated UTF8 QTApplication references. --- Gui/Command.py | 3 +-- Gui/ExportCQ.py | 3 +-- Gui/ImportCQ.py | 6 ++---- InitGui.py | 3 +-- 4 files changed, 5 insertions(+), 10 deletions(-) diff --git a/Gui/Command.py b/Gui/Command.py index 6b12fba..959432a 100644 --- a/Gui/Command.py +++ b/Gui/Command.py @@ -187,8 +187,7 @@ class CadQueryExecuteScript: msg = QtGui.QApplication.translate( "cqCodeWidget", "Executed ", - None, - QtGui.QApplication.UnicodeUTF8) + None) FreeCAD.Console.PrintMessage(msg + cqCodePane.file.path + "\r\n") diff --git a/Gui/ExportCQ.py b/Gui/ExportCQ.py index cba98f8..ca73d16 100644 --- a/Gui/ExportCQ.py +++ b/Gui/ExportCQ.py @@ -26,6 +26,5 @@ def save(filename=None): msg = QtGui.QApplication.translate( "cqCodeWidget", "Saved ", - None, - QtGui.QApplication.UnicodeUTF8) + None) FreeCAD.Console.PrintMessage(msg + cqCodePane.file.path + "\r\n") diff --git a/Gui/ImportCQ.py b/Gui/ImportCQ.py index 00625c9..10a53d4 100644 --- a/Gui/ImportCQ.py +++ b/Gui/ImportCQ.py @@ -36,8 +36,7 @@ def open(filename): msg = QtGui.QApplication.translate( "cqCodeWidget", "Please install Python 2.7", - None, - QtGui.QApplication.UnicodeUTF8) + None) FreeCAD.Console.PrintError(msg + "\r\n") # The extra version numbers won't work on Windows @@ -98,8 +97,7 @@ def open(filename): msg = QtGui.QApplication.translate( "cqCodeWidget", "Opened ", - None, - QtGui.QApplication.UnicodeUTF8) + None) FreeCAD.Console.PrintMessage(msg + filename + "\r\n") return diff --git a/InitGui.py b/InitGui.py index 705843d..25425b9 100644 --- a/InitGui.py +++ b/InitGui.py @@ -57,8 +57,7 @@ class CadQueryWorkbench (Workbench): "Author: David Cowden\r\n" "License: Apache-2.0\r\n" "Website: https://github.com/dcowden/cadquery\r\n", - None, - QtGui.QApplication.UnicodeUTF8) + None) FreeCAD.Console.PrintMessage(msg) #Getting the main window will allow us to start setting things up the way we want From 2cdd504888b9ac0925a8d5c2dcb9e813d494ae5b Mon Sep 17 00:00:00 2001 From: Jeremy Mack Wright Date: Sun, 3 Sep 2017 18:01:39 -0400 Subject: [PATCH 10/19] Added options handling to build_object function. --- Gui/Command.py | 8 +- Libs/cadquery-lib/.coverage | 1 - Libs/cadquery-lib/.gitignore | 7 - Libs/cadquery-lib/.travis.yml | 32 ---- Libs/cadquery-lib/README.md | 8 +- Libs/cadquery-lib/cadquery.egg-info/PKG-INFO | 154 ++++++++++++++++++ .../cadquery.egg-info/SOURCES.txt | 29 ++++ .../cadquery.egg-info/dependency_links.txt | 1 + .../cadquery.egg-info/not-zip-safe | 1 + .../cadquery.egg-info/top_level.txt | 2 + Libs/cadquery-lib/cadquery/cqgi.py | 40 +++-- Libs/cadquery-lib/doc/cqgi.rst | 5 +- Libs/cadquery-lib/tests/TestCQGI.py | 25 +-- 13 files changed, 239 insertions(+), 74 deletions(-) delete mode 100644 Libs/cadquery-lib/.coverage delete mode 100644 Libs/cadquery-lib/.gitignore delete mode 100644 Libs/cadquery-lib/.travis.yml create mode 100644 Libs/cadquery-lib/cadquery.egg-info/PKG-INFO create mode 100644 Libs/cadquery-lib/cadquery.egg-info/SOURCES.txt create mode 100644 Libs/cadquery-lib/cadquery.egg-info/dependency_links.txt create mode 100644 Libs/cadquery-lib/cadquery.egg-info/not-zip-safe create mode 100644 Libs/cadquery-lib/cadquery.egg-info/top_level.txt diff --git a/Gui/Command.py b/Gui/Command.py index 959432a..329496b 100644 --- a/Gui/Command.py +++ b/Gui/Command.py @@ -168,9 +168,13 @@ class CadQueryExecuteScript: if build_result.success: # Display all the results that the user requested for result in build_result.results: - show(result) + # Apply options to the show function if any were provided + if result.options and result.options["rgba"]: + show(result.shape, result.options["rgba"]) + else: + show(result.shape) else: - FreeCAD.Console.PrintError("Error executing CQGI-compliant script.\r\n") + FreeCAD.Console.PrintError("Error executing CQGI-compliant script. " + str(build_result.exception) + "\r\n") else: # Save our code to a tempfile and render it tempFile = tempfile.NamedTemporaryFile(delete=False) diff --git a/Libs/cadquery-lib/.coverage b/Libs/cadquery-lib/.coverage deleted file mode 100644 index 349220a..0000000 --- a/Libs/cadquery-lib/.coverage +++ /dev/null @@ -1 +0,0 @@ -!coverage.py: This is a private format, don't read it directly!{"lines": {"/home/jwright/Downloads/cadquery/cadquery/cq_directive.py": [], "/home/jwright/Downloads/cadquery/cadquery/cq.py": [2049, 2052, 2053, 2054, 2056, 2057, 2058, 2060, 18, 20, 21, 22, 23, 24, 27, 2076, 2078, 33, 34, 35, 36, 2085, 2086, 39, 40, 2089, 43, 2093, 49, 51, 2102, 2103, 2104, 58, 59, 60, 2109, 62, 2111, 65, 2126, 2127, 2128, 81, 2130, 2131, 84, 2133, 2134, 2140, 2141, 2142, 2143, 96, 2145, 2147, 2149, 102, 2151, 104, 106, 107, 108, 110, 112, 2166, 2168, 2170, 2171, 2172, 2173, 2174, 2178, 363, 2180, 133, 2182, 2183, 136, 2185, 138, 2187, 140, 141, 2255, 143, 145, 149, 150, 151, 153, 154, 156, 2207, 368, 2211, 2213, 2215, 2217, 2218, 2220, 174, 175, 176, 178, 182, 184, 185, 2235, 188, 189, 190, 2239, 192, 193, 195, 374, 2246, 2247, 2249, 2251, 2252, 205, 2254, 207, 2257, 211, 213, 222, 224, 2427, 2276, 2277, 2279, 2282, 2087, 238, 239, 240, 2088, 243, 244, 246, 383, 253, 255, 2307, 2308, 2309, 2310, 2433, 2312, 265, 2314, 2316, 2318, 2333, 2336, 2339, 2340, 2341, 2342, 2344, 2346, 306, 2075, 308, 309, 310, 311, 2361, 314, 2363, 2364, 2366, 2368, 322, 329, 330, 332, 333, 335, 337, 341, 344, 345, 349, 350, 353, 355, 356, 357, 360, 361, 2411, 364, 365, 2414, 2415, 2416, 2417, 2418, 2419, 2420, 2422, 375, 2424, 378, 379, 2428, 382, 2431, 384, 385, 2434, 388, 390, 396, 398, 404, 406, 411, 413, 2471, 2472, 2474, 427, 428, 432, 2482, 2483, 2485, 2486, 2488, 2489, 2491, 2494, 2497, 2498, 2500, 454, 455, 456, 457, 458, 461, 462, 464, 466, 78, 79, 2524, 479, 80, 482, 483, 485, 486, 488, 490, 1447, 82, 2132, 519, 521, 2480, 551, 553, 582, 97, 584, 605, 607, 103, 839, 631, 633, 651, 653, 669, 671, 2502, 681, 683, 692, 694, 720, 722, 723, 724, 725, 727, 729, 2070, 742, 743, 745, 758, 2071, 766, 769, 131, 2072, 2523, 805, 807, 808, 811, 812, 813, 815, 137, 2527, 836, 838, 481, 842, 843, 844, 846, 369, 874, 876, 877, 880, 882, 883, 886, 910, 912, 914, 936, 937, 938, 939, 943, 947, 948, 949, 951, 952, 953, 955, 968, 969, 971, 972, 974, 975, 976, 977, 979, 981, 994, 995, 996, 997, 998, 999, 1001, 1022, 1024, 1025, 1026, 1027, 1031, 1032, 172, 1034, 1036, 1050, 1053, 1054, 1055, 1056, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1067, 1069, 1089, 1090, 1091, 1092, 1094, 1096, 1123, 1124, 1125, 1127, 2236, 2237, 1137, 1139, 1141, 1143, 1144, 1146, 1149, 2241, 1160, 1161, 1163, 1170, 1172, 1179, 1181, 1191, 1192, 1194, 1204, 1205, 1208, 2359, 1223, 1224, 1227, 2253, 1242, 1243, 1244, 1246, 2259, 1278, 1279, 1281, 1282, 1284, 1286, 1287, 1289, 1291, 1307, 1308, 1309, 1311, 1313, 1314, 1316, 1318, 1338, 1341, 1343, 1345, 1346, 1347, 1350, 1352, 1354, 2091, 1372, 1373, 1374, 1376, 1390, 1391, 1392, 1394, 1401, 1403, 1404, 1406, 1421, 1423, 1433, 1434, 1435, 1439, 1446, 241, 1448, 1449, 1451, 1472, 1475, 1476, 1478, 1480, 1481, 1482, 1486, 1487, 1488, 1490, 1492, 1524, 1525, 1527, 1529, 1530, 1532, 1534, 1535, 1536, 1538, 1540, 1542, 1560, 1561, 1564, 1567, 1568, 1570, 1572, 263, 2313, 1598, 1601, 1602, 1603, 1604, 1605, 1607, 1608, 1609, 1610, 1612, 1613, 1616, 1619, 1648, 1649, 1650, 1651, 1653, 1655, 1666, 1668, 1669, 1670, 1671, 1672, 1673, 1675, 1677, 1692, 1695, 1698, 1699, 1701, 1704, 1706, 1707, 1709, 1711, 1725, 1728, 1730, 1732, 1741, 1742, 1743, 1745, 1747, 1757, 1758, 1762, 1763, 1764, 1765, 1767, 1769, 1770, 1773, 1803, 1804, 1806, 1812, 1814, 1817, 1818, 1819, 1821, 1825, 2107, 2356, 2357, 1856, 1857, 1859, 1862, 1865, 1866, 1867, 1868, 1869, 1870, 1872, 1876, 2362, 63, 1902, 1903, 1905, 1911, 1913, 1914, 1916, 1919, 320, 1940, 1942, 1945, 1954, 1955, 1956, 1957, 1958, 1959, 1963, 1964, 1966, 1967, 1968, 1970, 1995, 1997, 1998, 2000, 2001, 2002, 2004, 2027, 2030, 2034, 2035, 2037, 2041, 2044, 2045, 2047], "/home/jwright/Downloads/cadquery/cadquery/freecad_impl/__init__.py": [18, 19, 20, 23, 26, 27, 30, 32, 33, 34, 35, 36, 37, 38, 39, 41, 42, 101, 102, 103, 104, 105, 106], "/home/jwright/Downloads/cadquery/cadquery/freecad_impl/shapes.py": [1026, 1027, 1028, 1030, 521, 599, 524, 930, 526, 88, 530, 259, 533, 535, 810, 461, 802, 602, 1033, 544, 546, 603, 518, 554, 556, 557, 559, 49, 50, 51, 52, 986, 55, 568, 104, 571, 572, 61, 574, 575, 576, 578, 579, 68, 69, 71, 72, 1036, 74, 587, 866, 591, 81, 594, 595, 84, 85, 87, 355, 89, 90, 91, 93, 94, 607, 96, 609, 610, 611, 612, 808, 616, 105, 110, 873, 624, 113, 626, 116, 446, 630, 631, 632, 633, 634, 703, 636, 637, 645, 134, 961, 649, 652, 937, 660, 663, 664, 668, 601, 160, 673, 678, 625, 681, 682, 172, 173, 686, 175, 689, 178, 691, 181, 184, 628, 187, 188, 189, 702, 191, 971, 708, 710, 711, 493, 204, 717, 206, 719, 720, 209, 210, 211, 212, 213, 726, 728, 729, 219, 220, 221, 223, 224, 208, 738, 114, 234, 809, 750, 751, 830, 241, 242, 244, 245, 246, 297, 248, 761, 250, 322, 256, 257, 770, 771, 97, 261, 262, 811, 776, 812, 778, 983, 281, 815, 284, 285, 803, 287, 288, 290, 291, 804, 293, 294, 817, 296, 988, 95, 299, 300, 818, 302, 303, 816, 305, 306, 308, 821, 822, 311, 312, 825, 314, 827, 828, 906, 868, 831, 832, 834, 323, 325, 326, 328, 329, 330, 332, 334, 335, 336, 337, 338, 340, 569, 345, 348, 826, 864, 506, 354, 59, 356, 357, 358, 871, 360, 762, 805, 373, 374, 375, 377, 378, 381, 865, 384, 386, 899, 406, 390, 391, 392, 393, 394, 907, 397, 910, 399, 400, 913, 402, 915, 917, 918, 409, 98, 412, 414, 929, 418, 422, 423, 424, 425, 939, 940, 429, 942, 431, 432, 433, 434, 949, 438, 951, 901, 953, 954, 671, 956, 492, 958, 447, 960, 449, 963, 904, 970, 759, 460, 973, 462, 589, 464, 981, 470, 471, 984, 473, 474, 79, 476, 477, 478, 479, 480, 482, 934, 1000, 1001, 490, 935, 1004, 82, 494, 1007, 496, 1009, 83, 1013, 869, 1016, 1018, 507, 508, 1021, 510, 597], "/home/jwright/Downloads/cadquery/cadquery/__init__.py": [2, 3, 4, 5, 10, 11, 15, 16, 17, 18, 21], "/home/jwright/Downloads/cadquery/cadquery/selectors.py": [51, 514, 515, 516, 518, 519, 521, 522, 523, 525, 526, 319, 528, 18, 531, 20, 21, 22, 23, 24, 538, 29, 542, 543, 544, 34, 35, 548, 553, 555, 45, 47, 48, 50, 563, 564, 53, 54, 567, 56, 57, 570, 59, 573, 574, 575, 577, 578, 579, 581, 582, 583, 585, 586, 75, 76, 77, 78, 591, 592, 593, 594, 596, 598, 87, 600, 89, 102, 103, 104, 105, 106, 108, 530, 110, 111, 112, 114, 117, 118, 119, 532, 122, 123, 124, 125, 126, 128, 129, 131, 133, 137, 138, 139, 140, 142, 655, 656, 657, 146, 659, 663, 152, 153, 156, 158, 160, 161, 162, 164, 165, 166, 568, 168, 170, 188, 190, 191, 193, 535, 546, 211, 213, 214, 121, 216, 536, 234, 236, 237, 238, 239, 242, 261, 262, 263, 265, 266, 267, 268, 269, 270, 301, 272, 293, 294, 295, 296, 297, 298, 299, 562, 302, 305, 307, 309, 310, 649, 313, 314, 316, 650, 565, 321, 329, 330, 331, 332, 333, 334, 335, 337, 339, 654, 342, 345, 349, 350, 351, 354, 355, 358, 360, 364, 365, 366, 367, 369, 370, 371, 373, 376, 379, 380, 382, 384, 387, 388, 390, 392, 396, 397, 398, 400, 80, 404, 405, 406, 408, 410, 413, 81, 419, 420, 421, 422, 423, 426, 427, 428, 429, 430, 433, 434, 437, 438, 439, 442, 445, 448, 449, 450, 587, 452, 455, 458, 463, 464, 466, 468, 590, 472, 473, 476, 477, 478, 479, 480, 481, 482, 485, 486, 487, 488, 489, 490, 491, 494, 495, 496, 497, 498, 501, 502, 503, 504, 505, 507, 508, 510, 341], "/home/jwright/Downloads/cadquery/cadquery/cqgi.py": [4, 5, 6, 7, 8, 10, 12, 23, 24, 27, 36, 38, 43, 44, 45, 46, 51, 53, 64, 66, 67, 68, 70, 71, 72, 74, 83, 95, 96, 98, 99, 101, 102, 103, 104, 105, 106, 107, 110, 111, 112, 113, 114, 116, 117, 118, 119, 120, 121, 122, 124, 125, 126, 128, 129, 131, 132, 133, 135, 136, 139, 149, 150, 151, 152, 153, 154, 155, 156, 158, 159, 160, 162, 163, 165, 166, 167, 168, 171, 175, 176, 177, 179, 180, 182, 183, 184, 185, 188, 189, 192, 193, 196, 197, 200, 201, 204, 214, 215, 218, 221, 224, 227, 230, 232, 234, 235, 237, 238, 240, 241, 242, 243, 244, 245, 246, 247, 249, 251, 256, 257, 258, 259, 260, 261, 262, 263, 265, 266, 267, 268, 271, 275, 280, 285, 286, 287, 288, 290, 295, 297, 301, 303, 309, 315, 316, 318, 323, 324, 325, 326, 328, 332, 333, 336, 340, 341, 344, 349, 351, 362, 365, 368, 372, 377, 378, 379, 381, 382, 384, 385, 386, 388, 389, 390, 391, 393, 394, 395, 397, 398, 400, 403, 404, 405, 407, 411, 412, 416, 417, 418, 420, 421, 422, 423, 425, 428, 430, 431, 433, 434, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 453, 455, 456, 459, 462, 463, 464, 466, 467, 472], "/home/jwright/Downloads/cadquery/cadquery/freecad_impl/importers.py": [2, 3, 5, 6, 7, 8, 9, 10, 12, 13, 15, 16, 17, 20, 28, 29, 33, 39, 41, 44, 45, 46, 48, 53], "/home/jwright/Downloads/cadquery/cadquery/freecad_impl/exporters.py": [1, 3, 4, 6, 9, 10, 15, 16, 17, 18, 19, 20, 23, 24, 25, 28, 34, 46, 47, 49, 51, 53, 55, 56, 59, 60, 61, 62, 63, 64, 65, 66, 71, 74, 76, 77, 78, 79, 83, 84, 86, 91, 92, 93, 95, 96, 99, 103, 105, 107, 108, 111, 115, 116, 118, 121, 122, 124, 125, 127, 128, 130, 131, 132, 133, 136, 137, 138, 139, 140, 141, 142, 143, 144, 147, 148, 149, 150, 151, 152, 153, 154, 157, 164, 165, 167, 168, 169, 170, 172, 173, 174, 177, 179, 180, 186, 187, 188, 189, 190, 191, 195, 210, 211, 212, 214, 215, 216, 217, 218, 220, 221, 223, 225, 226, 227, 232, 237, 239, 243, 245, 246, 247, 248, 251, 252, 254, 257, 258, 259, 260, 263, 266, 269, 270, 271, 273, 274, 275, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 294, 297, 304, 305, 306, 307, 353, 389, 391], "/home/jwright/Downloads/cadquery/cadquery/freecad_impl/geom.py": [515, 516, 517, 522, 523, 524, 529, 18, 20, 21, 22, 23, 26, 540, 542, 544, 546, 547, 548, 550, 632, 42, 44, 45, 46, 47, 560, 49, 50, 563, 564, 565, 567, 568, 569, 58, 572, 573, 575, 581, 70, 583, 72, 73, 74, 75, 76, 77, 78, 79, 592, 593, 594, 595, 597, 87, 89, 91, 93, 95, 608, 97, 99, 101, 614, 103, 616, 105, 618, 107, 109, 110, 113, 114, 116, 117, 630, 119, 120, 633, 122, 123, 125, 638, 127, 128, 130, 635, 132, 645, 134, 136, 144, 146, 147, 149, 152, 155, 158, 161, 162, 164, 167, 170, 173, 174, 177, 181, 182, 183, 184, 188, 189, 191, 192, 195, 586, 631, 206, 208, 209, 463, 634, 570, 238, 637, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 254, 255, 260, 261, 262, 263, 264, 266, 267, 268, 269, 270, 272, 273, 643, 278, 279, 280, 281, 282, 284, 285, 133, 48, 290, 291, 296, 297, 302, 303, 51, 308, 309, 52, 314, 315, 590, 629, 53, 320, 321, 326, 327, 55, 332, 345, 346, 348, 349, 350, 352, 354, 356, 358, 360, 362, 364, 365, 367, 609, 389, 391, 495, 69, 418, 419, 582, 423, 424, 71, 428, 430, 584, 611, 585, 445, 446, 587, 454, 588, 461, 462, 589, 464, 466, 467, 469, 591, 483, 485, 488, 489, 490, 491, 494, 613, 497, 499], "/home/jwright/Downloads/cadquery/cadquery/plugins/__init__.py": [18], "/home/jwright/Downloads/cadquery/cadquery/contrib/__init__.py": []}} \ No newline at end of file diff --git a/Libs/cadquery-lib/.gitignore b/Libs/cadquery-lib/.gitignore deleted file mode 100644 index e7df8cf..0000000 --- a/Libs/cadquery-lib/.gitignore +++ /dev/null @@ -1,7 +0,0 @@ -build/ -*.pyc -doc/_build/* -dist/* -.idea/* -cadquery.egg-info -target/* diff --git a/Libs/cadquery-lib/.travis.yml b/Libs/cadquery-lib/.travis.yml deleted file mode 100644 index aa8160b..0000000 --- a/Libs/cadquery-lib/.travis.yml +++ /dev/null @@ -1,32 +0,0 @@ -language: python -before_install: -- sudo add-apt-repository -y ppa:freecad-maintainers/freecad-stable -- sudo apt-get update -qq -install: -- sudo apt-get install -y freecad freecad-doc -- gcc --version -- g++ --version -- python ./setup.py install -- pip install -r requirements-dev.txt -- pip install travis-sphinx - -script: -- coverage run --source=cadquery ./runtests.py -- travis-sphinx --nowarn --source=doc build - -after_success: -- coveralls -- travis-sphinx deploy - -branches: - except: - - pythonocc - - 2_0_branch - - deploy: - provider: pypi - user: dcowden - password: - secure: aP02wBbry1j3hYG/w++siF1lk26teuRQlPAx1c+ec8fxUw+bECa2HbPQHcIvSXB5N6nc6P3L9LjHt9ktm+Dn6FLJu3qWYNGAZx9PTn24ug0iAmB+JyNrsET3nK6WUKR1XpBqvjKgdpukd1Hknh2FSzYoyUvFWH9/CovITCFN3jo= - on: - tags: true \ No newline at end of file diff --git a/Libs/cadquery-lib/README.md b/Libs/cadquery-lib/README.md index 8cc0b03..d041e0f 100644 --- a/Libs/cadquery-lib/README.md +++ b/Libs/cadquery-lib/README.md @@ -223,7 +223,11 @@ Use these steps if you would like to write CadQuery scripts as a python API. In ```bash pip install cadquery ``` -3. test your installation:: +4. installing cadquery should install pyparsing as well, but if not:: +```bash + pip install pyparsing +``` +5. test your installation:: ```python from cadquery import * box = Workplane("XY").box(1,2,3) @@ -234,7 +238,7 @@ You're up and running! Installing -- Using CadQuery from Inside FreeCAD ================================================= -Use the Excellent CadQuery-FreeCAD plugin here: +Use the CadQuery module for FreeCAD here: https://github.com/jmwright/cadquery-freecad-module It includes a distribution of the latest version of cadquery. diff --git a/Libs/cadquery-lib/cadquery.egg-info/PKG-INFO b/Libs/cadquery-lib/cadquery.egg-info/PKG-INFO new file mode 100644 index 0000000..823c3bd --- /dev/null +++ b/Libs/cadquery-lib/cadquery.egg-info/PKG-INFO @@ -0,0 +1,154 @@ +Metadata-Version: 1.1 +Name: cadquery +Version: 1.0.0 +Summary: CadQuery is a parametric scripting language for creating and traversing CAD models +Home-page: https://github.com/dcowden/cadquery +Author: David Cowden +Author-email: dave.cowden@gmail.com +License: Apache Public License 2.0 +Description: What is a CadQuery? + ======================================== + + [![Travis Build Status](https://travis-ci.org/dcowden/cadquery.svg)](https://travis-ci.org/dcowden/cadquery) + [![Coverage Status](https://coveralls.io/repos/dcowden/cadquery/badge.svg)](https://coveralls.io/r/dcowden/cadquery) + [![GitHub version](https://badge.fury.io/gh/dcowden%2Fcadquery.svg)](https://github.com/dcowden/cadquery/releases/tag/v0.3.0) + [![License](https://img.shields.io/badge/license-LGPL-lightgrey.svg)](https://github.com/dcowden/cadquery/blob/master/LICENSE) + + CadQuery is an intuitive, easy-to-use python based language for building parametric 3D CAD models. CadQuery is for 3D CAD what jQuery is for javascript. Imagine selecting Faces of a 3d object the same way you select DOM objects with JQuery! + + CadQuery has several goals: + + * Build models with scripts that are as close as possible to how you'd describe the object to a human. + * Create parametric models that can be very easily customized by end users + * Output high quality CAD formats like STEP and AMF in addition to traditional STL + * Provide a non-proprietary, plain text model format that can be edited and executed with only a web browser + + Using CadQuery, you can write short, simple scripts that produce high quality CAD models. It is easy to make many different objects using a single script that can be customized. + + Full Documentation + ============================ + You can find the full cadquery documentation at http://dcowden.github.io/cadquery + + + Getting Started With CadQuery + ======================================== + + The easiest way to get started with CadQuery is to Install FreeCAD (version 14+) (http://www.freecadweb.org/), and then to use our great CadQuery-FreeCAD plugin here: https://github.com/jmwright/cadquery-freecad-module + + + It includes the latest version of cadquery alreadby bundled, and has super-easy installation on Mac, Windows, and Unix. + + It has tons of awesome features like integration with FreeCAD so you can see your objects, code-autocompletion, an examples bundle, and script saving/loading. Its definitely the best way to kick the tires! + + We also have a Google Group to make it easy to get help from other CadQuery users. Please join the group and introduce yourself, and we would also love to hear what you are doing with CadQuery. https://groups.google.com/forum/#!forum/cadquery + + + + Why CadQuery instead of OpenSCAD? + ======================================== + + CadQuery is based on OpenCasCade. CadQuery shares many features with OpenSCAD, another open source, script based, parametric model generator. + + The primary advantage of OpenSCAD is the large number of already existing model libaries that exist already. So why not simply use OpenSCAD? + + CadQuery scripts have several key advantages over OpenSCAD: + + 1. **The scripts use a standard programming language**, python, and thus can benefit from the associated infrastructure. + This includes many standard libraries and IDEs + + 2. **More powerful CAD kernel** OpenCascade is much more powerful than CGAL. Features supported natively + by OCC include NURBS, splines, surface sewing, STL repair, STEP import/export, and other complex operations, + in addition to the standard CSG operations supported by CGAL + + 3. **Ability to import/export STEP** We think the ability to begin with a STEP model, created in a CAD package, + and then add parametric features is key. This is possible in OpenSCAD using STL, but STL is a lossy format + + 4. **Less Code and easier scripting** CadQuery scripts require less code to create most objects, because it is possible to locate + features based on the position of other features, workplanes, vertices, etc. + + 5. **Better Performance** CadQuery scripts can build STL, STEP, and AMF faster than OpenSCAD. + + License + ======== + + CadQuery is licensed under the terms of the Apache Public License, version 2.0. + A copy of the license can be found at http://www.apache.org/licenses/LICENSE-2.0 + + Where is the GUI? + ================== + + If you would like IDE support, you can use CadQuery inside of FreeCAD. There's an excellent plugin module here https://github.com/jmwright/cadquery-freecad-module + + CadQuery also provides the backbone of http://parametricparts.com, so the easiest way to see it in action is to review the samples and objects there. + + Installing -- FreeStanding Installation + ======================================== + + Use these steps if you would like to write CadQuery scripts as a python API. In this case, FreeCAD is used only as a CAD kernel. + + 1. install FreeCAD, version 0.12 or greater for your platform. http://sourceforge.net/projects/free-cad/. + + 2. adjust your path if necessary. FreeCAD bundles a python interpreter, but you'll probably want to use your own, + preferably one that has virtualenv available. To use FreeCAD from any python interpreter, just append the FreeCAD + lib directory to your path. On (*Nix):: + + import sys + sys.path.append('/usr/lib/freecad/lib') + + or on Windows:: + + import sys + sys.path.append('/c/apps/FreeCAD/bin') + + *NOTE* FreeCAD on Windows will not work with python 2.7-- you must use pthon 2.6.X!!!! + + 3. install cadquery:: + + pip install cadquery + + 3. test your installation:: + + from cadquery import * + box = Workplane("XY").box(1,2,3) + exporters.toString(box,'STL') + + You're up and running! + + Installing -- Using CadQuery from Inside FreeCAD + ================================================= + + Use the Excellent CadQuery-FreeCAD plugin here: + https://github.com/jmwright/cadquery-freecad-module + + It includes a distribution of the latest version of cadquery. + + Where does the name CadQuery come from? + ======================================== + + CadQuery is inspired by ( `jQuery `_ ), a popular framework that + revolutionized web development involving javascript. + + If you are familiar with how jQuery, you will probably recognize several jQuery features that CadQuery uses: + + * A fluent api to create clean, easy to read code + * Language features that make selection and iteration incredibly easy + * + * Ability to use the library along side other python libraries + * Clear and complete documentation, with plenty of samples. + + +Platform: any +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: Intended Audience :: End Users/Desktop +Classifier: Intended Audience :: Information Technology +Classifier: Intended Audience :: Science/Research +Classifier: Intended Audience :: System Administrators +Classifier: License :: OSI Approved :: Apache Software License +Classifier: Operating System :: POSIX +Classifier: Operating System :: MacOS +Classifier: Operating System :: Unix +Classifier: Programming Language :: Python +Classifier: Topic :: Software Development :: Libraries :: Python Modules +Classifier: Topic :: Internet +Classifier: Topic :: Scientific/Engineering diff --git a/Libs/cadquery-lib/cadquery.egg-info/SOURCES.txt b/Libs/cadquery-lib/cadquery.egg-info/SOURCES.txt new file mode 100644 index 0000000..0507b5e --- /dev/null +++ b/Libs/cadquery-lib/cadquery.egg-info/SOURCES.txt @@ -0,0 +1,29 @@ +MANIFEST.in +README.txt +setup.cfg +setup.py +cadquery/__init__.py +cadquery/cq.py +cadquery/cq_directive.py +cadquery/cqgi.py +cadquery/selectors.py +cadquery.egg-info/PKG-INFO +cadquery.egg-info/SOURCES.txt +cadquery.egg-info/dependency_links.txt +cadquery.egg-info/not-zip-safe +cadquery.egg-info/top_level.txt +cadquery/contrib/__init__.py +cadquery/freecad_impl/__init__.py +cadquery/freecad_impl/exporters.py +cadquery/freecad_impl/geom.py +cadquery/freecad_impl/importers.py +cadquery/freecad_impl/shapes.py +cadquery/plugins/__init__.py +tests/TestCQGI.py +tests/TestCQSelectors.py +tests/TestCadObjects.py +tests/TestCadQuery.py +tests/TestExporters.py +tests/TestImporters.py +tests/TestWorkplanes.py +tests/__init__.py \ No newline at end of file diff --git a/Libs/cadquery-lib/cadquery.egg-info/dependency_links.txt b/Libs/cadquery-lib/cadquery.egg-info/dependency_links.txt new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/Libs/cadquery-lib/cadquery.egg-info/dependency_links.txt @@ -0,0 +1 @@ + diff --git a/Libs/cadquery-lib/cadquery.egg-info/not-zip-safe b/Libs/cadquery-lib/cadquery.egg-info/not-zip-safe new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/Libs/cadquery-lib/cadquery.egg-info/not-zip-safe @@ -0,0 +1 @@ + diff --git a/Libs/cadquery-lib/cadquery.egg-info/top_level.txt b/Libs/cadquery-lib/cadquery.egg-info/top_level.txt new file mode 100644 index 0000000..2bbe7fc --- /dev/null +++ b/Libs/cadquery-lib/cadquery.egg-info/top_level.txt @@ -0,0 +1,2 @@ +cadquery +tests diff --git a/Libs/cadquery-lib/cadquery/cqgi.py b/Libs/cadquery-lib/cadquery/cqgi.py index 8fa7b0c..d0777a8 100644 --- a/Libs/cadquery-lib/cadquery/cqgi.py +++ b/Libs/cadquery-lib/cadquery/cqgi.py @@ -34,7 +34,6 @@ class CQModel(object): the build method can be used to generate a 3d model """ - def __init__(self, script_source): """ Create an object by parsing the supplied python script. @@ -48,7 +47,7 @@ class CQModel(object): # TODO: pick up other scirpt metadata: # describe # pick up validation methods - self._find_descriptions() + self._find_descriptions() def _find_vars(self): """ @@ -136,6 +135,14 @@ class CQModel(object): p.set_value(v) +class ShapeResult(object): + """ + An object created by a build, including the user parameters provided + """ + def __init__(self): + self.shape = None + self.options = None + class BuildResult(object): """ The result of executing a CadQuery script. @@ -149,8 +156,8 @@ class BuildResult(object): """ def __init__(self): self.buildTime = None - self.results = [] - self.debugObjects = [] + self.results = [] #list of ShapeResult + self.debugObjects = [] #list of ShapeResult self.first_result = None self.success = False self.exception = None @@ -287,18 +294,25 @@ class ScriptCallback(object): self.outputObjects = [] self.debugObjects = [] - def build_object(self, shape): + def build_object(self, shape,options={}): """ - return an object to the executing environment + return an object to the executing environment, with options :param shape: a cadquery object + :param options: a dictionary of options that will be made available to the executing envrionment """ - self.outputObjects.append(shape) + o = ShapeResult() + o.options=options + o.shape = shape + self.outputObjects.append(o) def debug(self,obj,args={}): """ Debug print/output an object, with optional arguments. """ - self.debugObjects.append(DebugObject(obj,args)) + s = ShapeResult() + s.shape = obj + s.options = args + self.debugObjects.append(s) def describe_parameter(self,var_data ): """ @@ -315,15 +329,7 @@ class ScriptCallback(object): def has_results(self): return len(self.outputObjects) > 0 -class DebugObject(object): - """ - Represents a request to debug an object - Object is the type of object we want to debug - args are parameters for use during debuging ( for example, color, tranparency ) - """ - def __init__(self,object,args): - self.args = args - self.object = object + class InvalidParameterError(Exception): """ diff --git a/Libs/cadquery-lib/doc/cqgi.rst b/Libs/cadquery-lib/doc/cqgi.rst index 310f7d2..84a3602 100644 --- a/Libs/cadquery-lib/doc/cqgi.rst +++ b/Libs/cadquery-lib/doc/cqgi.rst @@ -37,6 +37,9 @@ CQGI compliant containers provide an execution environment for scripts. The envi Scripts must call build_output at least once. Invoking build_object more than once will send multiple objects to the container. An error will occur if the script does not return an object using the build_object() method. +An optional options dictionary can be provided to the build_object method. If provided, it is passed onto the executing environment, and is used to render the object. Typically, this will be colors, transparency, and other visual affects. + + This CQGI compliant script produces a cube with a circle on top, and displays a workplane as well as an intermediate circle as debug output:: base_cube = cq.Workplane('XY').rect(1.0,1.0).extrude(1.0) @@ -47,7 +50,7 @@ This CQGI compliant script produces a cube with a circle on top, and displays a circle=top_of_cube_plane.circle(0.5) debug(circle, { 'color': 'red' } ) - build_object( circle.extrude(1.0) ) + build_object( circle.extrude(1.0),{"color": "#aaaaaa" ) Note that importing cadquery is not required. At the end of this script, one object will be displayed, in addition to a workplane, a point, and a circle diff --git a/Libs/cadquery-lib/tests/TestCQGI.py b/Libs/cadquery-lib/tests/TestCQGI.py index 7cc967f..08c63dc 100644 --- a/Libs/cadquery-lib/tests/TestCQGI.py +++ b/Libs/cadquery-lib/tests/TestCQGI.py @@ -48,10 +48,11 @@ class TestCQGI(BaseTest): result = model.build() debugItems = result.debugObjects self.assertTrue(len(debugItems) == 2) - self.assertTrue( debugItems[0].object == "bar" ) - self.assertTrue( debugItems[0].args == { "color":'yellow' } ) - self.assertTrue( debugItems[1].object == 2.0 ) - self.assertTrue( debugItems[1].args == {} ) + + self.assertTrue( debugItems[0].shape == "bar" ) + self.assertTrue( debugItems[0].options == { "color":'yellow' } ) + self.assertTrue( debugItems[1].shape == 2.0 ) + self.assertTrue( debugItems[1].options == {} ) def test_build_with_empty_params(self): model = cqgi.CQModel(TESTSCRIPT) @@ -59,12 +60,12 @@ class TestCQGI(BaseTest): self.assertTrue(result.success) self.assertTrue(len(result.results) == 1) - self.assertTrue(result.results[0] == "2.0|3.0|bar|1.0") + self.assertTrue(result.results[0].shape == "2.0|3.0|bar|1.0") def test_build_with_different_params(self): model = cqgi.CQModel(TESTSCRIPT) result = model.build({'height': 3.0}) - self.assertTrue(result.results[0] == "3.0|3.0|bar|1.0") + self.assertTrue(result.results[0].shape == "3.0|3.0|bar|1.0") def test_describe_parameters(self): script = textwrap.dedent( @@ -128,8 +129,8 @@ class TestCQGI(BaseTest): model = cqgi.CQModel(script) result = model.build({}) self.assertEquals(2, len(result.results)) - self.assertEquals(1, result.results[0]) - self.assertEquals(2, result.results[1]) + self.assertEquals(1, result.results[0].shape) + self.assertEquals(2, result.results[1].shape) def test_that_assinging_number_to_string_works(self): script = textwrap.dedent( @@ -139,7 +140,7 @@ class TestCQGI(BaseTest): """ ) result = cqgi.parse(script).build( {'h': 33.33}) - self.assertEquals(result.results[0], "33.33") + self.assertEquals(result.results[0].shape, "33.33") def test_that_assigning_string_to_number_fails(self): script = textwrap.dedent( @@ -181,7 +182,7 @@ class TestCQGI(BaseTest): result = cqgi.parse(script).build() self.assertTrue(result.success) - self.assertIsNotNone(result.first_result) + self.assertIsNotNone(result.first_result.shape) def test_setting_boolean_variable(self): script = textwrap.dedent( @@ -195,7 +196,7 @@ class TestCQGI(BaseTest): result = cqgi.parse(script).build({'h': False}) self.assertTrue(result.success) - self.assertEquals(result.first_result,'*False*') + self.assertEquals(result.first_result.shape,'*False*') def test_that_only_top_level_vars_are_detected(self): script = textwrap.dedent( @@ -213,4 +214,4 @@ class TestCQGI(BaseTest): model = cqgi.parse(script) - self.assertEquals(2, len(model.metadata.parameters)) \ No newline at end of file + self.assertEquals(2, len(model.metadata.parameters)) From 21200cc10d137cef0be50f41046d528226255b5e Mon Sep 17 00:00:00 2001 From: Jeremy Mack Wright Date: Mon, 11 Sep 2017 21:49:14 -0400 Subject: [PATCH 11/19] Added CQGI debug objects. --- Gui/Command.py | 13 ++++++- Libs/cadquery-lib/cadquery/cq.py | 46 ++++++++++++++++++++++--- Libs/cadquery-lib/cadquery/cqgi.py | 9 +++-- Libs/cadquery-lib/tests/TestCadQuery.py | 27 ++++++++++----- 4 files changed, 77 insertions(+), 18 deletions(-) diff --git a/Gui/Command.py b/Gui/Command.py index 329496b..bb5254f 100644 --- a/Gui/Command.py +++ b/Gui/Command.py @@ -9,6 +9,7 @@ import ExportCQ, ImportCQ import module_locator import Settings import Shared +from random import random from cadquery import cqgi from Helpers import show @@ -130,7 +131,7 @@ class CadQueryExecuteScript: scriptText = cqCodePane.toPlainText().encode('utf-8') # Check to see if we are executig a CQGI compliant script - if "build_object(" in scriptText and "# build_object(" not in scriptText and "#build_boject(" not in scriptText: + if ("build_object(" in scriptText and "# build_object(" not in scriptText and "#build_boject(" not in scriptText) or ("debug(" in scriptText and "# debug(" not in scriptText and "#debug(" not in scriptText): FreeCAD.Console.PrintMessage("Executing CQGI-compliant script.\r\n") # A repreentation of the CQ script with all the metadata attached @@ -173,6 +174,16 @@ class CadQueryExecuteScript: show(result.shape, result.options["rgba"]) else: show(result.shape) + + for debugObj in build_result.debugObjects: + # Mark this as a debug object + debugObj.shape.val().label = "Debug" + str(random()) + + # Apply options to the show function if any were provided + if debugObj.options and debugObj.options["rgba"]: + show(debugObj.shape, debugObj.options["rgba"]) + else: + show(debugObj.shape, (255, 0, 0, 0.80)) else: FreeCAD.Console.PrintError("Error executing CQGI-compliant script. " + str(build_result.exception) + "\r\n") else: diff --git a/Libs/cadquery-lib/cadquery/cq.py b/Libs/cadquery-lib/cadquery/cq.py index 97f135b..dc685c9 100644 --- a/Libs/cadquery-lib/cadquery/cq.py +++ b/Libs/cadquery-lib/cadquery/cq.py @@ -341,7 +341,7 @@ class CQ(object): if not all(_isCoPlanar(self.objects[0], f) for f in self.objects[1:]): raise ValueError("Selected faces must be co-planar.") - if centerOption == 'CenterOfMass': + if centerOption == 'CenterOfMass': center = Shape.CombinedCenter(self.objects) elif centerOption == 'CenterOfBoundBox': center = Shape.CombinedCenterOfBoundBox(self.objects) @@ -1991,9 +1991,9 @@ class Workplane(CQ): Support for non-prismatic extrusion ( IE, sweeping along a profile, not just perpendicular to the plane extrude to surface. this is quite tricky since the surface selected may not be planar - """ + """ r = self._extrude(distance,both=both) # returns a Solid (or a compound if there were multiple) - + if combine: newS = self._combineWithBase(r) else: @@ -2184,6 +2184,44 @@ class Workplane(CQ): return self.newObject([newS]) + def intersect(self, toIntersect, combine=True, clean=True): + """ + Intersects the provided solid from the current solid. + + if combine=True, the result and the original are updated to point to the new object + if combine=False, the result will be on the stack, but the original is unmodified + + :param toIntersect: object to intersect + :type toIntersect: a solid object, or a CQ object having a solid, + :param boolean clean: call :py:meth:`clean` afterwards to have a clean shape + :raises: ValueError if there is no solid to intersect with in the chain + :return: a CQ object with the resulting object selected + """ + + # look for parents to intersect with + solidRef = self.findSolid(searchStack=True, searchParents=True) + + if solidRef is None: + raise ValueError("Cannot find solid to intersect with") + solidToIntersect = None + + if isinstance(toIntersect, CQ): + solidToIntersect = toIntersect.val() + elif isinstance(toIntersect, Solid): + solidToIntersect = toIntersect + else: + raise ValueError("Cannot intersect type '{}'".format(type(toIntersect))) + + newS = solidRef.intersect(solidToIntersect) + + if clean: newS = newS.clean() + + if combine: + solidRef.wrapped = newS.wrapped + + return self.newObject([newS]) + + def cutBlind(self, distanceToCut, clean=True): """ Use all un-extruded wires in the parent chain to create a prismatic cut from existing solid. @@ -2308,7 +2346,7 @@ class Workplane(CQ): for ws in wireSets: thisObj = Solid.extrudeLinear(ws[0], ws[1:], eDir) toFuse.append(thisObj) - + if both: thisObj = Solid.extrudeLinear(ws[0], ws[1:], eDir.multiply(-1.)) toFuse.append(thisObj) diff --git a/Libs/cadquery-lib/cadquery/cqgi.py b/Libs/cadquery-lib/cadquery/cqgi.py index d0777a8..d654d72 100644 --- a/Libs/cadquery-lib/cadquery/cqgi.py +++ b/Libs/cadquery-lib/cadquery/cqgi.py @@ -109,10 +109,8 @@ class CQModel(object): c = compile(self.ast_tree, CQSCRIPT, 'exec') exec (c, env) result.set_debug(collector.debugObjects ) - if collector.has_results(): - result.set_success_result(collector.outputObjects) - else: - raise NoOutputError("Script did not call build_object-- no output available.") + result.set_success_result(collector.outputObjects) + except Exception, ex: #print "Error Executing Script:" result.set_failure_result(ex) @@ -171,7 +169,8 @@ class BuildResult(object): def set_success_result(self, results): self.results = results - self.first_result = self.results[0] + if len(self.results) > 0: + self.first_result = self.results[0] self.success = True diff --git a/Libs/cadquery-lib/tests/TestCadQuery.py b/Libs/cadquery-lib/tests/TestCadQuery.py index f12165a..12f41b7 100644 --- a/Libs/cadquery-lib/tests/TestCadQuery.py +++ b/Libs/cadquery-lib/tests/TestCadQuery.py @@ -604,6 +604,20 @@ class TestCadQuery(BaseTest): self.assertEqual(10,currentS.faces().size()) + def testIntersect(self): + """ + Tests the intersect function. + """ + s = Workplane(Plane.XY()) + currentS = s.rect(2.0, 2.0).extrude(0.5) + toIntersect = s.rect(1.0, 1.0).extrude(1) + + currentS.intersect(toIntersect.val()) + + self.assertEqual(6, currentS.faces().size()) + bb = currentS.val().BoundingBox() + self.assertListEqual([bb.xlen, bb.ylen, bb.zlen], [1, 1, 0.5]) + def testBoundingBox(self): """ Tests the boudingbox center of a model @@ -1387,7 +1401,7 @@ class TestCadQuery(BaseTest): result =topOfLid.union(bottom) self.saveModel(result) - + def testExtrude(self): """ Test symmetric extrude @@ -1395,19 +1409,16 @@ class TestCadQuery(BaseTest): r = 1. h = 1. decimal_places = 9. - + #extrude symmetrically s = Workplane("XY").circle(r).extrude(h,both=True) - + top_face = s.faces(">Z") bottom_face = s.faces(" Date: Tue, 12 Sep 2017 15:02:10 -0400 Subject: [PATCH 12/19] Added menu icons to examples. --- Gui/Command.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Gui/Command.py b/Gui/Command.py index bb5254f..f679ced 100644 --- a/Gui/Command.py +++ b/Gui/Command.py @@ -90,7 +90,8 @@ class CadQueryExecuteExample: self.exFile = str(exFile) def GetResources(self): - return {"MenuText": str(self.exFile)} + return {"MenuText": str(self.exFile), + "Pixmap": ":/icons/accessories-text-editor.svg"} def Activated(self): FreeCAD.Console.PrintMessage(self.exFile + "\r\n") From 24a77b727e60b48bb797ebaf8b9a16f55c08ff0b Mon Sep 17 00:00:00 2001 From: Jeremy Mack Wright Date: Wed, 13 Sep 2017 14:40:21 -0400 Subject: [PATCH 13/19] Cleaned up, commented and converted the first five examples to be CQGI-compliant. --- Examples/Ex000_Introduction.py | 20 --------- Examples/Ex001_Simple_Block.py | 28 ++++++------ .../Ex002_Block_With_Bored_Center_Hole.py | 29 +++++++------ ...03_Pillow_Block_With_Counterbored_Holes.py | 43 ++++++++++++------- Examples/Ex004_Extruded_Cylindrical_Plate.py | 41 +++++++++++------- Examples/Ex005_Extruded_Lines_and_Arcs.py | 41 ++++++++++++------ 6 files changed, 113 insertions(+), 89 deletions(-) delete mode 100644 Examples/Ex000_Introduction.py diff --git a/Examples/Ex000_Introduction.py b/Examples/Ex000_Introduction.py deleted file mode 100644 index a11fb7f..0000000 --- a/Examples/Ex000_Introduction.py +++ /dev/null @@ -1,20 +0,0 @@ -# This example is meant to be used from within the CadQuery module of FreeCAD. -# From within FreeCAD, you can make changes to this script and then click -# CadQuery > Execute Script, or you can press F2. -# There are more examples in the Examples directory included with this module. -# Ex026_Lego_Brick.py is highly recommended as a great example of what CadQuery -# can do. -import cadquery -from Helpers import show - -# The dimensions of the box. These can be modified rather than changing the -# object's code directly. -length = 2.0 -height = 1.0 -thickness = 1.0 - -# Create a 3D box based on the dimension variables above -result = cadquery.Workplane("XY").box(length, height, thickness) - -# Render the solid -show(result) diff --git a/Examples/Ex001_Simple_Block.py b/Examples/Ex001_Simple_Block.py index a95b064..12c0ae5 100644 --- a/Examples/Ex001_Simple_Block.py +++ b/Examples/Ex001_Simple_Block.py @@ -1,15 +1,19 @@ -# This example is meant to be used from within the CadQuery module of FreeCAD. -import cadquery -from Helpers import show +import cadquery as cq -# The dimensions of the box. These can be modified rather than changing the -# object's code directly. -length = 80.0 -height = 60.0 -thickness = 10.0 +# These can be modified rather than hardcoding values for each dimension. +length = 80.0 # Length of the block +height = 60.0 # Height of the block +thickness = 10.0 # Thickness of the block -# Create a 3D box based on the dimension variables above -result = cadquery.Workplane("XY").box(length, height, thickness) +# Create a 3D block based on the dimension variables above. +# 1. Establishes a workplane that an object can be built on. +# 1a. Uses the X and Y origins to define the workplane, meaning that the +# positive Z direction is "up", and the negative Z direction is "down". +result = cq.Workplane("XY").box(length, height, thickness) -# Render the solid -show(result) +# The following method is now outdated, but can still be used to display the +# results of the script if you want +# from Helpers import show +# show(result) # Render the result of this script + +build_object(result) diff --git a/Examples/Ex002_Block_With_Bored_Center_Hole.py b/Examples/Ex002_Block_With_Bored_Center_Hole.py index 6203204..a1dda36 100644 --- a/Examples/Ex002_Block_With_Bored_Center_Hole.py +++ b/Examples/Ex002_Block_With_Bored_Center_Hole.py @@ -1,17 +1,20 @@ -# This example is meant to be used from within the CadQuery module of FreeCAD. -import cadquery -from Helpers import show +import cadquery as cq -# The dimensions of the box. These can be modified rather than changing the -# object's code directly. -length = 80.0 -height = 60.0 -thickness = 10.0 -center_hole_dia = 22.0 +# These can be modified rather than hardcoding values for each dimension. +length = 80.0 # Length of the block +height = 60.0 # Height of the block +thickness = 10.0 # Thickness of the block +center_hole_dia = 22.0 # Diameter of center hole in block -# Create a box based on the dimensions above and add a 22mm center hole -result = cadquery.Workplane("XY").box(length, height, thickness) \ +# Create a block based on the dimensions above and add a 22mm center hole. +# 1. Establishes a workplane that an object can be built on. +# 1a. Uses the X and Y origins to define the workplane, meaning that the +# positive Z direction is "up", and the negative Z direction is "down". +# 2. The highest (max) Z face is selected and a new workplane is created on it. +# 3. The new workplane is used to drill a hole through the block. +# 3a. The hole is automatically centered in the workplane. +result = cq.Workplane("XY").box(length, height, thickness) \ .faces(">Z").workplane().hole(center_hole_dia) -# Render the solid -show(result) +# Displays the result of this script +build_object(result) diff --git a/Examples/Ex003_Pillow_Block_With_Counterbored_Holes.py b/Examples/Ex003_Pillow_Block_With_Counterbored_Holes.py index 74c1d84..981b5c1 100644 --- a/Examples/Ex003_Pillow_Block_With_Counterbored_Holes.py +++ b/Examples/Ex003_Pillow_Block_With_Counterbored_Holes.py @@ -1,23 +1,34 @@ -# This example is meant to be used from within the CadQuery module of FreeCAD. -import cadquery -from Helpers import show +import cadquery as cq -# The dimensions of the box. These can be modified rather than changing the -# object's code directly. -length = 80.0 -height = 60.0 -thickness = 10.0 -center_hole_dia = 22.0 -cbore_hole_diameter = 2.4 -cbore_diameter = 4.4 -cbore_depth = 2.1 +# These can be modified rather than hardcoding values for each dimension. +length = 80.0 # Length of the block +height = 60.0 # Height of the block +thickness = 10.0 # Thickness of the block +center_hole_dia = 22.0 # Diameter of center hole in block +cbore_hole_diameter = 2.4 # Bolt shank/threads clearance hole diameter +cbore_diameter = 4.4 # Bolt head pocket hole diameter +cbore_depth = 2.1 # Bolt head pocket hole depth -# Create a 3D box based on the dimensions above and add 4 counterbored holes -result = cadquery.Workplane("XY").box(length, height, thickness) \ +# Create a 3D block based on the dimensions above and add a 22mm center hold +# and 4 counterbored holes for bolts +# 1. Establishes a workplane that an object can be built on. +# 1a. Uses the X and Y origins to define the workplane, meaning that the +# positive Z direction is "up", and the negative Z direction is "down". +# 2. The highest(max) Z face is selected and a new workplane is created on it. +# 3. The new workplane is used to drill a hole through the block. +# 3a. The hole is automatically centered in the workplane. +# 4. The highest(max) Z face is selected and a new workplane is created on it. +# 5. A for-construction rectangle is created on the workplane based on the +# block's overall dimensions. +# 5a. For-construction objects are used only to place other geometry, they +# do not show up in the final displayed geometry. +# 6. The vertices of the rectangle (corners) are selected, and a counter-bored +# hole is placed at each of the vertices (all 4 of them at once). +result = cq.Workplane("XY").box(length, height, thickness) \ .faces(">Z").workplane().hole(center_hole_dia) \ .faces(">Z").workplane() \ .rect(length - 8.0, height - 8.0, forConstruction=True) \ .vertices().cboreHole(cbore_hole_diameter, cbore_diameter, cbore_depth) -# Render the solid -show(result) +# Displays the result of this script +build_object(result) diff --git a/Examples/Ex004_Extruded_Cylindrical_Plate.py b/Examples/Ex004_Extruded_Cylindrical_Plate.py index 0de305a..4ab483d 100644 --- a/Examples/Ex004_Extruded_Cylindrical_Plate.py +++ b/Examples/Ex004_Extruded_Cylindrical_Plate.py @@ -1,18 +1,29 @@ -# This example is meant to be used from within the CadQuery module of FreeCAD. -import cadquery -from Helpers import show +import cadquery as cq -# The dimensions of the model. These can be modified rather than changing the -# object's code directly. -circle_radius = 50.0 -rectangle_width = 13.0 -rectangle_length = 19.0 -thickness = 13.0 +# These can be modified rather than hardcoding values for each dimension. +circle_radius = 50.0 # Radius of the plate +thickness = 13.0 # Thickness of the plate +rectangle_width = 13.0 # Width of rectangular hole in cylindrical plate +rectangle_length = 19.0 # Length of rectangular hole in cylindrical plate -# Extrude a cylindrical plate with a rectangular hole in the middle of it -result = cadquery.Workplane("front").circle(circle_radius) \ - .rect(rectangle_width, rectangle_length) \ - .extrude(thickness) +# Extrude a cylindrical plate with a rectangular hole in the middle of it. +# 1. Establishes a workplane that an object can be built on. +# 1a. Uses the named plane orientation "front" to define the workplane, meaning +# that the positive Z direction is "up", and the negative Z direction +# is "down". +# 2. The 2D geometry for the outer circle is created at the same time as the +# rectangle that will create the hole in the center. +# 2a. The circle and the rectangle will be automatically centered on the +# workplane. +# 2b. Unlike some other functions like the hole(), circle() takes +# a radius and not a diameter. +# 3. The circle and rectangle are extruded together, creating a cylindrical +# plate with a rectangular hole in the center. +# 3a. circle() and rect() could be changed to any other shape to completely +# change the resulting plate and/or the hole in it. +result = cq.Workplane("front").circle(circle_radius) \ + .rect(rectangle_width, rectangle_length) \ + .extrude(thickness) -# Render the solid -show(result) +# Displays the result of this script +build_object(result) diff --git a/Examples/Ex005_Extruded_Lines_and_Arcs.py b/Examples/Ex005_Extruded_Lines_and_Arcs.py index 34e3a1b..cc67cbf 100644 --- a/Examples/Ex005_Extruded_Lines_and_Arcs.py +++ b/Examples/Ex005_Extruded_Lines_and_Arcs.py @@ -1,17 +1,32 @@ -# This example is meant to be used from within the CadQuery module of FreeCAD. -import cadquery -from Helpers import show +import cadquery as cq -# The dimensions of the model. These can be modified rather than changing the -# object's code directly. -width = 2.0 -thickness = 0.25 +# These can be modified rather than hardcoding values for each dimension. +width = 2.0 # Overall width of the plate +thickness = 0.25 # Thickness of the plate # Extrude a plate outline made of lines and an arc -result = cadquery.Workplane("front").lineTo(width, 0) \ - .lineTo(width, 1.0) \ - .threePointArc((1.0, 1.5), (0.0, 1.0)) \ - .close().extrude(thickness) +# 1. Establishes a workplane that an object can be built on. +# 1a. Uses the named plane orientation "front" to define the workplane, meaning +# that the positive Z direction is "up", and the negative Z direction +# is "down". +# 2. Draws a line from the origin to an X position of the plate's width. +# 2a. The starting point of a 2D drawing like this will be at the center of the +# workplane (0, 0) unless the moveTo() function moves the starting point. +# 3. A line is drawn from the last position straight up in the Y direction +# 1.0 millimeters. +# 4. An arc is drawn from the last point, through point (1.0, 1.5) which is +# half-way back to the origin in the X direction and 0.5 mm above where +# the last line ended at. The arc then ends at (0.0, 1.0), which is 1.0 mm +# above (in the Y direction) where our first line started from. +# 5. close() is called to automatically draw the last line for us and close +# the sketch so that it can be extruded. +# 5a. Without the close(), the 2D sketch will be left open and the extrude +# operation will provide unpredictable results. +# 6. The 2D sketch is extruded into a solid object of the specified thickness. +result = cq.Workplane("front").lineTo(width, 0) \ + .lineTo(width, 1.0) \ + .threePointArc((1.0, 1.5), (0.0, 1.0)) \ + .close().extrude(thickness) -# Render the solid -show(result) +# Displays the result of this script +build_object(result) From a54a7a21a6662b04da68555de6298365f58846d9 Mon Sep 17 00:00:00 2001 From: Jeremy Mack Wright Date: Fri, 15 Sep 2017 14:22:34 -0400 Subject: [PATCH 14/19] Converted more examples and switched to CadQuery being a submodule rather than a subtree. --- .gitmodules | 3 + .../Ex006_Moving_the_Current_Working_Point.py | 45 +- Examples/Ex007_Using_Point_Lists.py | 41 +- Examples/Ex008_Polygon_Creation.py | 45 +- Init.py | 2 +- Libs/cadquery | 1 + Libs/cadquery-lib/AUTHORS.md | 4 - Libs/cadquery-lib/LICENSE | 208 -- Libs/cadquery-lib/MANIFEST | 24 - Libs/cadquery-lib/MANIFEST.in | 1 - Libs/cadquery-lib/README.md | 272 -- Libs/cadquery-lib/README.txt | 125 - Libs/cadquery-lib/build-docs.sh | 2 - Libs/cadquery-lib/cadquery.egg-info/PKG-INFO | 154 - .../cadquery.egg-info/SOURCES.txt | 29 - .../cadquery.egg-info/dependency_links.txt | 1 - .../cadquery.egg-info/not-zip-safe | 1 - .../cadquery.egg-info/top_level.txt | 2 - Libs/cadquery-lib/cadquery/README.txt | 8 - Libs/cadquery-lib/cadquery/__init__.py | 21 - .../cadquery-lib/cadquery/contrib/__init__.py | 18 - Libs/cadquery-lib/cadquery/cq.py | 2565 ----------------- Libs/cadquery-lib/cadquery/cq_directive.py | 85 - Libs/cadquery-lib/cadquery/cqgi.py | 477 --- .../cadquery/freecad_impl/README.txt | 3 - .../cadquery/freecad_impl/__init__.py | 107 - .../cadquery/freecad_impl/exporters.py | 392 --- .../cadquery/freecad_impl/geom.py | 647 ----- .../cadquery/freecad_impl/importers.py | 71 - .../cadquery/freecad_impl/shapes.py | 1044 ------- .../cadquery-lib/cadquery/plugins/__init__.py | 18 - Libs/cadquery-lib/cadquery/selectors.py | 663 ----- Libs/cadquery-lib/changes.md | 100 - Libs/cadquery-lib/doc/README | 2 - .../doc/_static/ParametricPulley.PNG | Bin 59186 -> 0 bytes Libs/cadquery-lib/doc/_static/block.png | Bin 9385 -> 0 bytes .../doc/_static/cadquery_cheatsheet.html | 404 --- Libs/cadquery-lib/doc/_static/cqlogo.png | Bin 3136 -> 0 bytes .../doc/_static/hyOzd-cablefix.png | Bin 27301 -> 0 bytes .../doc/_static/hyOzd-finished.jpg | Bin 149415 -> 0 bytes Libs/cadquery-lib/doc/_static/new_badge.png | Bin 3163 -> 0 bytes .../doc/_static/parametric-cup-screencap.PNG | Bin 66208 -> 0 bytes .../parametric-pillowblock-screencap.png | Bin 59428 -> 0 bytes Libs/cadquery-lib/doc/_static/pillowblock.png | Bin 17582 -> 0 bytes .../cadquery-lib/doc/_static/quickstart-1.png | Bin 6162 -> 0 bytes .../cadquery-lib/doc/_static/quickstart-2.png | Bin 6162 -> 0 bytes .../cadquery-lib/doc/_static/quickstart-3.png | Bin 7084 -> 0 bytes .../cadquery-lib/doc/_static/quickstart-4.png | Bin 7095 -> 0 bytes .../cadquery-lib/doc/_static/quickstart-5.png | Bin 11703 -> 0 bytes Libs/cadquery-lib/doc/_static/quickstart.png | Bin 17947 -> 0 bytes .../doc/_static/quickstart/000.png | Bin 11963 -> 0 bytes .../doc/_static/quickstart/001.png | Bin 56946 -> 0 bytes .../doc/_static/quickstart/002.png | Bin 120334 -> 0 bytes .../doc/_static/quickstart/003.png | Bin 123947 -> 0 bytes .../doc/_static/quickstart/004.png | Bin 124307 -> 0 bytes .../doc/_static/quickstart/005.png | Bin 136681 -> 0 bytes Libs/cadquery-lib/doc/_static/simpleblock.png | Bin 8698 -> 0 bytes Libs/cadquery-lib/doc/apireference.rst | 169 -- Libs/cadquery-lib/doc/classreference.rst | 71 - Libs/cadquery-lib/doc/conf.py | 276 -- Libs/cadquery-lib/doc/cqgi.rst | 167 -- Libs/cadquery-lib/doc/designprinciples.rst | 74 - Libs/cadquery-lib/doc/examples.rst | 1096 ------- Libs/cadquery-lib/doc/extending.rst | 180 -- Libs/cadquery-lib/doc/fileformat.rst | 24 - Libs/cadquery-lib/doc/index.rst | 58 - Libs/cadquery-lib/doc/installation.rst | 58 - Libs/cadquery-lib/doc/intro.rst | 95 - Libs/cadquery-lib/doc/primer.rst | 153 - Libs/cadquery-lib/doc/quickstart.rst | 242 -- Libs/cadquery-lib/doc/roadmap.rst | 154 - Libs/cadquery-lib/doc/selectors.rst | 140 - .../examples/FreeCAD/Ex001_Simple_Block.py | 32 - .../Ex002_Block_With_Bored_Center_Hole.py | 33 - ...03_Pillow_Block_With_Counterbored_Holes.py | 40 - .../Ex004_Extruded_Cylindrical_Plate.py | 34 - .../FreeCAD/Ex005_Extruded_Lines_and_Arcs.py | 33 - .../Ex006_Moving_the_Current_Working_Point.py | 38 - .../FreeCAD/Ex007_Using_Point_Lists.py | 36 - .../FreeCAD/Ex008_Polygon_Creation.py | 36 - .../examples/FreeCAD/Ex009_Polylines.py | 44 - .../Ex010_Defining_an_Edge_with_a_Spline.py | 45 - .../Ex011_Mirroring_Symmetric_Geometry.py | 34 - .../Ex012_Creating_Workplanes_on_Faces.py | 31 - .../Ex013_Locating_a_Workplane_on_a_Vertex.py | 34 - .../FreeCAD/Ex014_Offset_Workplanes.py | 34 - .../FreeCAD/Ex015_Rotated_Workplanes.py | 32 - .../Ex016_Using_Construction_Geometry.py | 29 - .../Ex017_Shelling_to_Create_Thin_Features.py | 28 - .../examples/FreeCAD/Ex018_Making_Lofts.py | 29 - .../FreeCAD/Ex019_Counter_Sunk_Holes.py | 30 - .../Ex020_Rounding_Corners_with_Fillets.py | 28 - .../FreeCAD/Ex021_Splitting_an_Object.py | 31 - .../FreeCAD/Ex022_Classic_OCC_Bottle.py | 40 - .../FreeCAD/Ex023_Parametric_Enclosure.py | 102 - ...x024_Using_FreeCAD_Solids_as_CQ_Objects.py | 41 - .../examples/FreeCAD/Ex025_Revolution.py | 41 - Libs/cadquery-lib/registering.txt | 11 - Libs/cadquery-lib/requirements-dev.txt | 6 - Libs/cadquery-lib/requirements.txt | 1 - Libs/cadquery-lib/runtests.py | 18 - Libs/cadquery-lib/setup.cfg | 0 Libs/cadquery-lib/setup.py | 58 - Libs/cadquery-lib/tests/README.txt | 1 - Libs/cadquery-lib/tests/TestCQGI.py | 217 -- Libs/cadquery-lib/tests/TestCQSelectors.py | 503 ---- Libs/cadquery-lib/tests/TestCadObjects.py | 104 - Libs/cadquery-lib/tests/TestCadQuery.py | 1424 --------- Libs/cadquery-lib/tests/TestExporters.py | 43 - Libs/cadquery-lib/tests/TestImporters.py | 54 - Libs/cadquery-lib/tests/TestWorkplanes.py | 125 - Libs/cadquery-lib/tests/__init__.py | 54 - 112 files changed, 92 insertions(+), 14004 deletions(-) create mode 100644 .gitmodules create mode 160000 Libs/cadquery delete mode 100644 Libs/cadquery-lib/AUTHORS.md delete mode 100644 Libs/cadquery-lib/LICENSE delete mode 100644 Libs/cadquery-lib/MANIFEST delete mode 100644 Libs/cadquery-lib/MANIFEST.in delete mode 100644 Libs/cadquery-lib/README.md delete mode 100644 Libs/cadquery-lib/README.txt delete mode 100755 Libs/cadquery-lib/build-docs.sh delete mode 100644 Libs/cadquery-lib/cadquery.egg-info/PKG-INFO delete mode 100644 Libs/cadquery-lib/cadquery.egg-info/SOURCES.txt delete mode 100644 Libs/cadquery-lib/cadquery.egg-info/dependency_links.txt delete mode 100644 Libs/cadquery-lib/cadquery.egg-info/not-zip-safe delete mode 100644 Libs/cadquery-lib/cadquery.egg-info/top_level.txt delete mode 100644 Libs/cadquery-lib/cadquery/README.txt delete mode 100644 Libs/cadquery-lib/cadquery/__init__.py delete mode 100644 Libs/cadquery-lib/cadquery/contrib/__init__.py delete mode 100644 Libs/cadquery-lib/cadquery/cq.py delete mode 100644 Libs/cadquery-lib/cadquery/cq_directive.py delete mode 100644 Libs/cadquery-lib/cadquery/cqgi.py delete mode 100644 Libs/cadquery-lib/cadquery/freecad_impl/README.txt delete mode 100644 Libs/cadquery-lib/cadquery/freecad_impl/__init__.py delete mode 100644 Libs/cadquery-lib/cadquery/freecad_impl/exporters.py delete mode 100644 Libs/cadquery-lib/cadquery/freecad_impl/geom.py delete mode 100644 Libs/cadquery-lib/cadquery/freecad_impl/importers.py delete mode 100644 Libs/cadquery-lib/cadquery/freecad_impl/shapes.py delete mode 100644 Libs/cadquery-lib/cadquery/plugins/__init__.py delete mode 100644 Libs/cadquery-lib/cadquery/selectors.py delete mode 100644 Libs/cadquery-lib/changes.md delete mode 100644 Libs/cadquery-lib/doc/README delete mode 100644 Libs/cadquery-lib/doc/_static/ParametricPulley.PNG delete mode 100644 Libs/cadquery-lib/doc/_static/block.png delete mode 100644 Libs/cadquery-lib/doc/_static/cadquery_cheatsheet.html delete mode 100644 Libs/cadquery-lib/doc/_static/cqlogo.png delete mode 100644 Libs/cadquery-lib/doc/_static/hyOzd-cablefix.png delete mode 100644 Libs/cadquery-lib/doc/_static/hyOzd-finished.jpg delete mode 100644 Libs/cadquery-lib/doc/_static/new_badge.png delete mode 100644 Libs/cadquery-lib/doc/_static/parametric-cup-screencap.PNG delete mode 100644 Libs/cadquery-lib/doc/_static/parametric-pillowblock-screencap.png delete mode 100644 Libs/cadquery-lib/doc/_static/pillowblock.png delete mode 100644 Libs/cadquery-lib/doc/_static/quickstart-1.png delete mode 100644 Libs/cadquery-lib/doc/_static/quickstart-2.png delete mode 100644 Libs/cadquery-lib/doc/_static/quickstart-3.png delete mode 100644 Libs/cadquery-lib/doc/_static/quickstart-4.png delete mode 100644 Libs/cadquery-lib/doc/_static/quickstart-5.png delete mode 100644 Libs/cadquery-lib/doc/_static/quickstart.png delete mode 100644 Libs/cadquery-lib/doc/_static/quickstart/000.png delete mode 100644 Libs/cadquery-lib/doc/_static/quickstart/001.png delete mode 100644 Libs/cadquery-lib/doc/_static/quickstart/002.png delete mode 100644 Libs/cadquery-lib/doc/_static/quickstart/003.png delete mode 100644 Libs/cadquery-lib/doc/_static/quickstart/004.png delete mode 100644 Libs/cadquery-lib/doc/_static/quickstart/005.png delete mode 100644 Libs/cadquery-lib/doc/_static/simpleblock.png delete mode 100644 Libs/cadquery-lib/doc/apireference.rst delete mode 100644 Libs/cadquery-lib/doc/classreference.rst delete mode 100644 Libs/cadquery-lib/doc/conf.py delete mode 100644 Libs/cadquery-lib/doc/cqgi.rst delete mode 100644 Libs/cadquery-lib/doc/designprinciples.rst delete mode 100644 Libs/cadquery-lib/doc/examples.rst delete mode 100644 Libs/cadquery-lib/doc/extending.rst delete mode 100644 Libs/cadquery-lib/doc/fileformat.rst delete mode 100644 Libs/cadquery-lib/doc/index.rst delete mode 100644 Libs/cadquery-lib/doc/installation.rst delete mode 100644 Libs/cadquery-lib/doc/intro.rst delete mode 100644 Libs/cadquery-lib/doc/primer.rst delete mode 100644 Libs/cadquery-lib/doc/quickstart.rst delete mode 100644 Libs/cadquery-lib/doc/roadmap.rst delete mode 100644 Libs/cadquery-lib/doc/selectors.rst delete mode 100644 Libs/cadquery-lib/examples/FreeCAD/Ex001_Simple_Block.py delete mode 100644 Libs/cadquery-lib/examples/FreeCAD/Ex002_Block_With_Bored_Center_Hole.py delete mode 100644 Libs/cadquery-lib/examples/FreeCAD/Ex003_Pillow_Block_With_Counterbored_Holes.py delete mode 100644 Libs/cadquery-lib/examples/FreeCAD/Ex004_Extruded_Cylindrical_Plate.py delete mode 100644 Libs/cadquery-lib/examples/FreeCAD/Ex005_Extruded_Lines_and_Arcs.py delete mode 100644 Libs/cadquery-lib/examples/FreeCAD/Ex006_Moving_the_Current_Working_Point.py delete mode 100644 Libs/cadquery-lib/examples/FreeCAD/Ex007_Using_Point_Lists.py delete mode 100644 Libs/cadquery-lib/examples/FreeCAD/Ex008_Polygon_Creation.py delete mode 100644 Libs/cadquery-lib/examples/FreeCAD/Ex009_Polylines.py delete mode 100644 Libs/cadquery-lib/examples/FreeCAD/Ex010_Defining_an_Edge_with_a_Spline.py delete mode 100644 Libs/cadquery-lib/examples/FreeCAD/Ex011_Mirroring_Symmetric_Geometry.py delete mode 100644 Libs/cadquery-lib/examples/FreeCAD/Ex012_Creating_Workplanes_on_Faces.py delete mode 100644 Libs/cadquery-lib/examples/FreeCAD/Ex013_Locating_a_Workplane_on_a_Vertex.py delete mode 100644 Libs/cadquery-lib/examples/FreeCAD/Ex014_Offset_Workplanes.py delete mode 100644 Libs/cadquery-lib/examples/FreeCAD/Ex015_Rotated_Workplanes.py delete mode 100644 Libs/cadquery-lib/examples/FreeCAD/Ex016_Using_Construction_Geometry.py delete mode 100644 Libs/cadquery-lib/examples/FreeCAD/Ex017_Shelling_to_Create_Thin_Features.py delete mode 100644 Libs/cadquery-lib/examples/FreeCAD/Ex018_Making_Lofts.py delete mode 100644 Libs/cadquery-lib/examples/FreeCAD/Ex019_Counter_Sunk_Holes.py delete mode 100644 Libs/cadquery-lib/examples/FreeCAD/Ex020_Rounding_Corners_with_Fillets.py delete mode 100644 Libs/cadquery-lib/examples/FreeCAD/Ex021_Splitting_an_Object.py delete mode 100644 Libs/cadquery-lib/examples/FreeCAD/Ex022_Classic_OCC_Bottle.py delete mode 100644 Libs/cadquery-lib/examples/FreeCAD/Ex023_Parametric_Enclosure.py delete mode 100644 Libs/cadquery-lib/examples/FreeCAD/Ex024_Using_FreeCAD_Solids_as_CQ_Objects.py delete mode 100644 Libs/cadquery-lib/examples/FreeCAD/Ex025_Revolution.py delete mode 100644 Libs/cadquery-lib/registering.txt delete mode 100644 Libs/cadquery-lib/requirements-dev.txt delete mode 100644 Libs/cadquery-lib/requirements.txt delete mode 100644 Libs/cadquery-lib/runtests.py delete mode 100644 Libs/cadquery-lib/setup.cfg delete mode 100644 Libs/cadquery-lib/setup.py delete mode 100644 Libs/cadquery-lib/tests/README.txt delete mode 100644 Libs/cadquery-lib/tests/TestCQGI.py delete mode 100644 Libs/cadquery-lib/tests/TestCQSelectors.py delete mode 100644 Libs/cadquery-lib/tests/TestCadObjects.py delete mode 100644 Libs/cadquery-lib/tests/TestCadQuery.py delete mode 100644 Libs/cadquery-lib/tests/TestExporters.py delete mode 100644 Libs/cadquery-lib/tests/TestImporters.py delete mode 100644 Libs/cadquery-lib/tests/TestWorkplanes.py delete mode 100644 Libs/cadquery-lib/tests/__init__.py diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..fb62e70 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "Libs/cadquery"] + path = Libs/cadquery + url = https://github.com/dcowden/cadquery.git diff --git a/Examples/Ex006_Moving_the_Current_Working_Point.py b/Examples/Ex006_Moving_the_Current_Working_Point.py index fbb463c..166fe9f 100644 --- a/Examples/Ex006_Moving_the_Current_Working_Point.py +++ b/Examples/Ex006_Moving_the_Current_Working_Point.py @@ -1,22 +1,35 @@ -# This example is meant to be used from within the CadQuery module of FreeCAD. -import cadquery -from Helpers import show +import cadquery as cq -# The dimensions of the model. These can be modified rather than changing the -# object's code directly. -circle_radius = 3.0 -thickness = 0.25 +# These can be modified rather than hardcoding values for each dimension. +circle_radius = 3.0 # The outside radius of the plate +thickness = 0.25 # The thickness of the plate -# Make the plate with two cutouts in it -# Current point is the center of the circle, at (0,0) -result = cadquery.Workplane("front").circle(circle_radius) -result = result.center(1.5, 0.0).rect(0.5, 0.5) # New work center is (1.5,0.0) +# Make a plate with two cutouts in it by moving the workplane center point +# 1. Establishes a workplane that an object can be built on. +# 1a. Uses the named plane orientation "front" to define the workplane, meaning +# that the positive Z direction is "up", and the negative Z direction +# is "down". +# 1b. The initial workplane center point is the center of the circle, at (0,0). +# 2. A circle is created at the center of the workplane +# 2a. Notice that circle() takes a radius and not a diameter +result = cq.Workplane("front").circle(circle_radius) -result = result.center(-1.5, 1.5).circle(0.25) # New work center is ( 0.0,1.5) -# The new center is specified relative to the previous center, -# not global coordinates! +# 3. The work center is movide to (1.5, 0.0) by calling center(). +# 3a. The new center is specified relative to the previous center,not +# relative to global coordinates. +# 4. A 0.5mm x 0.5mm 2D square is drawn inside the circle. +# 4a. The plate has not been extruded yet, only 2D geometry is being created. +result = result.center(1.5, 0.0).rect(0.5, 0.5) +# 5. The work center is moved again, this time to (-1.5, 1.5). +# 6. A 2D circle is created at that new center with a radius of 0.25mm. +result = result.center(-1.5, 1.5).circle(0.25) + +# 7. All 2D geometry is extruded to the specified thickness of the plate. +# 7a. The small circle and the square are enclosed in the outer circle of the +# plate and so it is assumed that we want them to be cut out of the plate. +# A separate cut operation is not needed. result = result.extrude(thickness) -# Render the solid -show(result) +# Displays the result of this script +build_object(result) diff --git a/Examples/Ex007_Using_Point_Lists.py b/Examples/Ex007_Using_Point_Lists.py index effd879..7a1bb84 100644 --- a/Examples/Ex007_Using_Point_Lists.py +++ b/Examples/Ex007_Using_Point_Lists.py @@ -1,21 +1,32 @@ -# This example is meant to be used from within the CadQuery module of FreeCAD. -import cadquery -from Helpers import show +import cadquery as cq -# The dimensions of the model. These can be modified rather than changing the -# object's code directly. -plate_radius = 2.0 -hole_pattern_radius = 0.25 -thickness = 0.125 +# These can be modified rather than hardcoding values for each dimension. +plate_radius = 2.0 # The radius of the plate that will be extruded +hole_pattern_radius = 0.25 # Radius of circle where the holes will be placed +thickness = 0.125 # The thickness of the plate that will be extruded -# Make the plate with 4 holes in it at various points -# Make the base -r = cadquery.Workplane("front").circle(plate_radius) -# Now four points are on the stack +# Make a plate with 4 holes in it at various points in a polar arrangement from +# the center of the workplane. +# 1. Establishes a workplane that an object can be built on. +# 1a. Uses the named plane orientation "front" to define the workplane, meaning +# that the positive Z direction is "up", and the negative Z direction +# is "down". +# 2. A 2D circle is drawn that will become though outer profile of the plate. +r = cq.Workplane("front").circle(plate_radius) + +# 3. Push 4 points on the stack that will be used as the center points of the +# holes. r = r.pushPoints([(1.5, 0), (0, 1.5), (-1.5, 0), (0, -1.5)]) -# Circle will operate on all four points + +# 4. This circle() call will operate on all four points, putting a circle at +# each one. r = r.circle(hole_pattern_radius) + +# 5. All 2D geometry is extruded to the specified thickness of the plate. +# 5a. The small hole circles are enclosed in the outer circle of the plate and +# so it is assumed that we want them to be cut out of the plate. A +# separate cut operation is not needed. result = r.extrude(thickness) -# Render the solid -show(result) +# Displays the result of this script +build_object(result) diff --git a/Examples/Ex008_Polygon_Creation.py b/Examples/Ex008_Polygon_Creation.py index b3f3469..c9d37c9 100644 --- a/Examples/Ex008_Polygon_Creation.py +++ b/Examples/Ex008_Polygon_Creation.py @@ -1,20 +1,39 @@ -# This example is meant to be used from within the CadQuery module of FreeCAD. -import cadquery -from Helpers import show +import cadquery as cq -# The dimensions of the model. These can be modified rather than changing the -# object's code directly. -width = 3.0 -height = 4.0 -thickness = 0.25 -polygon_sides = 6 -polygon_dia = 1.0 +# These can be modified rather than hardcoding values for each dimension. +width = 3.0 # The width of the plate +height = 4.0 # The height of the plate +thickness = 0.25 # The thickness of the plate +polygon_sides = 6 # The number of sides that the polygonal holes should have +polygon_dia = 1.0 # The diameter of the circle enclosing the polygon points # Create a plate with two polygons cut through it -result = cadquery.Workplane("front").box(width, height, thickness) \ +# 1. Establishes a workplane that an object can be built on. +# 1a. Uses the named plane orientation "front" to define the workplane, meaning +# that the positive Z direction is "up", and the negative Z direction +# is "down". +# 2. A 3D box is created in one box() operation to represent the plate. +# 2a. The box is centered around the origin, which creates a result that may +# be unituitive when the polygon cuts are made. +# 3. 2 points are pushed onto the stack and will be used as centers for the +# polygonal holes. +# 4. The two polygons are created, on for each point, with one call to +# polygon() using the number of sides and the circle that bounds the +# polygon. +# 5. The polygons are cut thru all objects that are in the line of extrusion. +# 5a. A face was not selected, and so the polygons are created on the +# workplane. Since the box was centered around the origin, the polygons end +# up being in the center of the box. This makes them cut from the center to +# the outside along the normal (positive direction). +# 6. The polygons are cut through all objects, starting at the center of the +# box/plate and going "downward" (opposite of normal) direction. Functions +# like cutBlind() assume a positive cut direction, but cutThruAll() assumes +# instead that the cut is made from a max direction and cuts downward from +# that max through all objects. +result = cq.Workplane("front").box(width, height, thickness) \ .pushPoints([(0, 0.75), (0, -0.75)]) \ .polygon(polygon_sides, polygon_dia) \ .cutThruAll() -# Render the solid -show(result) +# Displays the result of this script +build_object(result) diff --git a/Init.py b/Init.py index bb2a5f8..120b0d7 100644 --- a/Init.py +++ b/Init.py @@ -14,7 +14,7 @@ libs_dir_path = os.path.join(module_base_path, 'Libs') sys.path.insert(0, libs_dir_path) # Tack on our CadQuery library git subtree -cq_lib_path = os.path.join(libs_dir_path, 'cadquery-lib') +cq_lib_path = os.path.join(libs_dir_path, 'cadquery') sys.path.insert(1, cq_lib_path) # Make sure we get the right libs under the FreeCAD installation diff --git a/Libs/cadquery b/Libs/cadquery new file mode 160000 index 0000000..0c40258 --- /dev/null +++ b/Libs/cadquery @@ -0,0 +1 @@ +Subproject commit 0c40258e28c0fad08b699430bce34ea2613d8d1e diff --git a/Libs/cadquery-lib/AUTHORS.md b/Libs/cadquery-lib/AUTHORS.md deleted file mode 100644 index 31b30e8..0000000 --- a/Libs/cadquery-lib/AUTHORS.md +++ /dev/null @@ -1,4 +0,0 @@ -# Core CQ Developers - -* [Dave Cowden](https://github.com/dcowden), Creator - Lead Developer -* [Jeremy Wright](https://github.com/jmwright) (a.k.a [innovationstech](https://github.com/innovationstech)) diff --git a/Libs/cadquery-lib/LICENSE b/Libs/cadquery-lib/LICENSE deleted file mode 100644 index d4fa4f1..0000000 --- a/Libs/cadquery-lib/LICENSE +++ /dev/null @@ -1,208 +0,0 @@ -CadQuery -Copyright (C) 2015 Parametric Products Intellectual Holdings, LLC - -This library is free software; you can redistribute it and/or -modify it under the terms of the Apache Public License, v 2.0 - - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [Parametric Products Intellectual Holdings, LLC] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/Libs/cadquery-lib/MANIFEST b/Libs/cadquery-lib/MANIFEST deleted file mode 100644 index ce5c215..0000000 --- a/Libs/cadquery-lib/MANIFEST +++ /dev/null @@ -1,24 +0,0 @@ -README.txt -README.md -setup.cfg -setup.py -cadquery\cq.py -cadquery\__init__.py -cadquery\cq_directive.py -cadquery\selectors.py -cadquery\cqgi.py -cadquery\contrib\__init__.py -cadquery\freecad_impl\__init__.py -cadquery\freecad_impl\exporters.py -cadquery\freecad_impl\importers.py -cadquery\freecad_impl\geom.py -cadquery\freecad_impl\shapes.py -cadquery\plugins\__init__.py -tests\TestCQSelectors.py -tests\TestCadObjects.py -tests\TestCadQuery.py -tests\TestExporters.py -tests\TestImporters.py -tests\TestWorkplanes.py -tests\TestCQGI.py -tests\__init__.py diff --git a/Libs/cadquery-lib/MANIFEST.in b/Libs/cadquery-lib/MANIFEST.in deleted file mode 100644 index bb3ec5f..0000000 --- a/Libs/cadquery-lib/MANIFEST.in +++ /dev/null @@ -1 +0,0 @@ -include README.md diff --git a/Libs/cadquery-lib/README.md b/Libs/cadquery-lib/README.md deleted file mode 100644 index d041e0f..0000000 --- a/Libs/cadquery-lib/README.md +++ /dev/null @@ -1,272 +0,0 @@ -What is a CadQuery? -======================================== - -[![Travis Build Status](https://travis-ci.org/dcowden/cadquery.svg?branch=master)](https://travis-ci.org/dcowden/cadquery?branch=master) -[![Coverage Status](https://coveralls.io/repos/dcowden/cadquery/badge.svg)](https://coveralls.io/r/dcowden/cadquery) -[![GitHub version](https://badge.fury.io/gh/dcowden%2Fcadquery.svg)](https://github.com/dcowden/cadquery/releases/tag/v0.3.0) -[![License](https://img.shields.io/badge/license-Apache2-blue.svg)](https://github.com/dcowden/cadquery/blob/master/LICENSE) - -CadQuery is an intuitive, easy-to-use python based language for building parametric 3D CAD models. CadQuery is for 3D CAD what jQuery is for javascript. Imagine selecting Faces of a 3d object the same way you select DOM objects with JQuery! - -CadQuery has several goals: - -* Build lD models with scripts that are as close as possible to how you'd describe the object to a human. -* Create parametric models that can be very easily customized by end users -* Output high quality (loss-less) CAD formats like STEP and AMF in addition to traditional STL -* Provide a non-proprietary, plain text model format that can be edited and executed with only a web browser - -Using CadQuery, you can write short, simple scripts that produce high quality CAD models. It is easy to make many different objects using a single script that can be customized. - -Full Documentation -============================ -You can find the full cadquery documentation at http://dcowden.github.io/cadquery - -Getting Started With CadQuery -======================================== - -The easiest way to get started with CadQuery is to Install FreeCAD (version 14+) (http://www.freecadweb.org/), and then to use our great CadQuery-FreeCAD plugin here: https://github.com/jmwright/cadquery-freecad-module - - -It includes the latest version of cadquery alreadby bundled, and has super-easy installation on Mac, Windows, and Unix. - -It has tons of awesome features like integration with FreeCAD so you can see your objects, code-autocompletion, an examples bundle, and script saving/loading. Its definitely the best way to kick the tires! - -We also have a Google Group to make it easy to get help from other CadQuery users. Please join the group and introduce yourself, and we would also love to hear what you are doing with CadQuery. https://groups.google.com/forum/#!forum/cadquery - -Examples -====================== - -This resin mold was modeled using cadquery and then created on a CNC machine: - -

- - -

- -The cadquery script is surprisingly short, and allows easily customizing any of the variables:: - -```python - import cadquery as cq - from Helpers import show - BS = cq.selectors.BoxSelector - - # PARAMETERS - mount_holes = True - - # mold size - mw = 40 - mh = 13 - ml = 120 - - # wire and fix size - wd = 6 # wire diameter - rt = 7 # resin thickness - rl = 50 # resin length - rwpl = 10 # resin to wire pass length - - # pocket fillet - pf = 18 - - # mount holes - mhd = 7 # hole diameter - mht = 3 # hole distance from edge - - # filling hole - fhd = 6 - - # DRAWING - - # draw base - base = cq.Workplane("XY").box(ml, mw, mh, (True, True, False)) - - # draw wire - pocket = cq.Workplane("XY", (0, 0, mh)).moveTo(-ml/2., 0).line(0, wd/2.)\ - .line((ml-rl)/2.-rwpl, 0).line(rwpl, rt).line(rl, 0)\ - .line(rwpl, -rt).line((ml-rl)/2.-rwpl, 0)\ - .line(0, -(wd/2.)).close().revolve(axisEnd=(1, 0))\ - .edges(BS((-rl/2.-rwpl-.1, -100, -100), (rl/2.+rwpl+.1, 100, 100)))\ - .fillet(pf) - - r = base.cut(pocket) - - # mount holes - if mount_holes: - px = ml/2.-mht-mhd/2. - py = mw/2.-mht-mhd/2 - r = r.faces(" - -

- -This Prusa i3 extruder support uses cadquery to build the model (https://github.com/adam-urbanczyk/cadquery-models) : - -

- -

- -The mach30 project used cadquery to develop a tool that will create a rocket thruster directly from the appropriate equations (https://opendesignengine.net/projects/yavin-thruster/wiki): -

- -

- -This example uses Jupyter notebook to produce a really cool web-based scripting environment ( https://github.com/RustyVermeer/avnb/blob/master/readme.md ) : - -

- -

- - - - - -We would love to link to your cadquery based project. Just let us know and we'll add it here. - - - - -Why CadQuery instead of OpenSCAD? -======================================== - -CadQuery is based on OpenCasCade. CadQuery shares many features with OpenSCAD, another open source, script based, parametric model generator. - -The primary advantage of OpenSCAD is the large number of already existing model libaries that exist already. So why not simply use OpenSCAD? - -CadQuery scripts have several key advantages over OpenSCAD: - -1. **The scripts use a standard programming language**, python, and thus can benefit from the associated infrastructure. - This includes many standard libraries and IDEs - -2. **More powerful CAD kernel** OpenCascade is much more powerful than CGAL. Features supported natively - by OCC include NURBS, splines, surface sewing, STL repair, STEP import/export, and other complex operations, - in addition to the standard CSG operations supported by CGAL - -3. **Ability to import/export STEP** We think the ability to begin with a STEP model, created in a CAD package, - and then add parametric features is key. This is possible in OpenSCAD using STL, but STL is a lossy format - -4. **Less Code and easier scripting** CadQuery scripts require less code to create most objects, because it is possible to locate - features based on the position of other features, workplanes, vertices, etc. - -5. **Better Performance** CadQuery scripts can build STL, STEP, and AMF faster than OpenSCAD. - -License -======== - -CadQuery is licensed under the terms of the Apache Public License, version 2.0. -A copy of the license can be found at http://www.apache.org/licenses/LICENSE-2.0 - -CadQuery GUI Interfaces -======================= - -There are currently several known CadQuery GUIs: - -### CadQuery FreeCAD Module -You can use CadQuery inside of FreeCAD. There's an excellent plugin module here https://github.com/jmwright/cadquery-freecad-module - -### CadQuery GUI (under active development) -Work is underway on a stand-alone gui here: https://github.com/jmwright/cadquery-gui - -### ParametricParts.com -If you are impatient and want to see a working example with no installation, have a look at this lego brick example http://parametricparts.com/parts/vqb5dy69/. - -The script that generates the model is on the 'modelscript' tab. - - -Installing -- FreeStanding Installation -======================================== - -Use these steps if you would like to write CadQuery scripts as a python API. In this case, FreeCAD is used only as a CAD kernel. - -1. install FreeCAD, version 0.15 or greater for your platform. https://github.com/FreeCAD/FreeCAD/releases. - -2. adjust your path if necessary. FreeCAD bundles a python interpreter, but you'll probably want to use your own, - preferably one that has virtualenv available. To use FreeCAD from any python interpreter, just append the FreeCAD - lib directory to your path. On (*Nix):: - -```python - import sys - sys.path.append('/usr/lib/freecad/lib') -``` - - or on Windows:: - -```python - import sys - sys.path.append('/c/apps/FreeCAD/bin') -``` - - *NOTE* FreeCAD on Windows will not work with python 2.7-- you must use pthon 2.6.X!!!! - -3. install cadquery:: -```bash - pip install cadquery -``` -4. installing cadquery should install pyparsing as well, but if not:: -```bash - pip install pyparsing -``` -5. test your installation:: -```python - from cadquery import * - box = Workplane("XY").box(1,2,3) - exporters.toString(box,'STL') -``` -You're up and running! - -Installing -- Using CadQuery from Inside FreeCAD -================================================= - -Use the CadQuery module for FreeCAD here: - https://github.com/jmwright/cadquery-freecad-module - -It includes a distribution of the latest version of cadquery. - -Roadmap/Future Work -======================= - -Work has begun on Cadquery 2.0, which will feature: - - 1. Feature trees, for more powerful selection - 2. Direct use of OpenCascade Community Edition(OCE), so that it is no longer required to install FreeCAD - 3. https://github.com/jmwright/cadquery-gui, which will allow visualization of workplanes - -The project page can be found here: https://github.com/dcowden/cadquery/projects/1 - -A more detailed description of the plan for CQ 2.0 is here: https://docs.google.com/document/d/1cXuxBkVeYmGOo34MGRdG7E3ILypQqkrJ26oVf3CUSPQ - -Where does the name CadQuery come from? -======================================== - -CadQuery is inspired by jQuery, a popular framework that -revolutionized web development involving javascript. - -If you are familiar with how jQuery, you will probably recognize several jQuery features that CadQuery uses: - -* A fluent api to create clean, easy to read code -* Language features that make selection and iteration incredibly easy -* -* Ability to use the library along side other python libraries -* Clear and complete documentation, with plenty of samples. - diff --git a/Libs/cadquery-lib/README.txt b/Libs/cadquery-lib/README.txt deleted file mode 100644 index a356b5b..0000000 --- a/Libs/cadquery-lib/README.txt +++ /dev/null @@ -1,125 +0,0 @@ -What is a CadQuery? -======================================== - -CadQuery is an intuitive, easy-to-use python based language for building parametric 3D CAD models. CadQuery is for 3D CAD what jQuery is for javascript. Imagine selecting Faces of a 3d object the same way you select DOM objects with JQuery! - -CadQuery has several goals: - -* Build models with scripts that are as close as possible to how you'd describe the object to a human. -* Create parametric models that can be very easily customized by end users -* Output high quality CAD formats like STEP and AMF in addition to traditional STL -* Provide a non-proprietary, plain text model format that can be edited and executed with only a web browser - -Using CadQuery, you can write short, simple scripts that produce high quality CAD models. It is easy to make many different objects using a single script that can be customized. - -Getting Started With CadQuery -======================================== - -The easiest way to get started with CadQuery is to Install FreeCAD ( version 14 recommended ) (http://www.freecadweb.org/) , and then to use our CadQuery-FreeCAD plugin here: - -https://github.com/jmwright/cadquery-freecad-module - - -It includes the latest version of cadquery alreadby bundled, and has super-easy installation on Mac, Windows, and Unix. - -It has tons of awesome features like integration with FreeCAD so you can see your objects, code-autocompletion, an examples bundle, and script saving/loading. Its definitely the best way to kick the tires! - - -Recently Added Features -======================================== - -* 12/5/14 -- New FreeCAD/CadQuery Module! https://github.com/jmwright/cadquery-freecad-module -* 10/25/14 -- Added Revolution Feature ( thanks Jeremy ! ) - - -Why CadQuery instead of OpenSCAD? -======================================== - -CadQuery is based on OpenCasCade. CadQuery shares many features with OpenSCAD, another open source, script based, parametric model generator. - -The primary advantage of OpenSCAD is the large number of already existing model libaries that exist already. So why not simply use OpenSCAD? - -CadQuery scripts have several key advantages over OpenSCAD: - -1. **The scripts use a standard programming language**, python, and thus can benefit from the associated infrastructure. - This includes many standard libraries and IDEs - -2. **More powerful CAD kernel** OpenCascade is much more powerful than CGAL. Features supported natively - by OCC include NURBS, splines, surface sewing, STL repair, STEP import/export, and other complex operations, - in addition to the standard CSG operations supported by CGAL - -3. **Ability to import/export STEP** We think the ability to begin with a STEP model, created in a CAD package, - and then add parametric features is key. This is possible in OpenSCAD using STL, but STL is a lossy format - -4. **Less Code and easier scripting** CadQuery scripts require less code to create most objects, because it is possible to locate - features based on the position of other features, workplanes, vertices, etc. - -5. **Better Performance** CadQuery scripts can build STL, STEP, and AMF faster than OpenSCAD. - -License -======== - -CadQuery is licensed under the terms of the LGPLv3. http://www.gnu.org/copyleft/lesser.html - -Where is the GUI? -================== - -If you would like IDE support, you can use CadQuery inside of FreeCAD. There's an excellent plugin module here https://github.com/jmwright/cadquery-freecad-module - -CadQuery also provides the backbone of http://parametricparts.com, so the easiest way to see it in action is to review the samples and objects there. - -Installing -- FreeStanding Installation -======================================== - -Use these steps if you would like to write CadQuery scripts as a python API. In this case, FreeCAD is used only as a CAD kernel. - -1. install FreeCAD, version 0.14 or greater for your platform. http://sourceforge.net/projects/free-cad/. - -2. adjust your path if necessary. FreeCAD bundles a python interpreter, but you'll probably want to use your own, - preferably one that has virtualenv available. To use FreeCAD from any python interpreter, just append the FreeCAD - lib directory to your path. On (*Nix):: - - import sys - sys.path.append('/usr/lib/freecad/lib') - - or on Windows:: - - import sys - sys.path.append('/c/apps/FreeCAD/bin') - - *NOTE* FreeCAD on Windows will not work with python 2.7-- you must use pthon 2.6.X!!!! - -3. install cadquery:: - - pip install cadquery - -3. test your installation:: - - from cadquery import * - box = Workplane("XY").box(1,2,3) - exporters.toString(box,'STL') - -You're up and running! - -Installing -- Using CadQuery from Inside FreeCAD -================================================= - -Use the Excellent CadQuery-FreeCAD plugin here: - https://github.com/jmwright/cadquery-freecad-module - -It includes a distribution of the latest version of cadquery. - -Where does the name CadQuery come from? -======================================== - -CadQuery is inspired by ( `jQuery `_ ), a popular framework that -revolutionized web development involving javascript. - -If you are familiar with how jQuery, you will probably recognize several jQuery features that CadQuery uses: - -* A fluent api to create clean, easy to read code -* Language features that make selection and iteration incredibly easy -* -* Ability to use the library along side other python libraries -* Clear and complete documentation, with plenty of samples. - diff --git a/Libs/cadquery-lib/build-docs.sh b/Libs/cadquery-lib/build-docs.sh deleted file mode 100755 index bef2f78..0000000 --- a/Libs/cadquery-lib/build-docs.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -sphinx-build -b html doc target/docs \ No newline at end of file diff --git a/Libs/cadquery-lib/cadquery.egg-info/PKG-INFO b/Libs/cadquery-lib/cadquery.egg-info/PKG-INFO deleted file mode 100644 index 823c3bd..0000000 --- a/Libs/cadquery-lib/cadquery.egg-info/PKG-INFO +++ /dev/null @@ -1,154 +0,0 @@ -Metadata-Version: 1.1 -Name: cadquery -Version: 1.0.0 -Summary: CadQuery is a parametric scripting language for creating and traversing CAD models -Home-page: https://github.com/dcowden/cadquery -Author: David Cowden -Author-email: dave.cowden@gmail.com -License: Apache Public License 2.0 -Description: What is a CadQuery? - ======================================== - - [![Travis Build Status](https://travis-ci.org/dcowden/cadquery.svg)](https://travis-ci.org/dcowden/cadquery) - [![Coverage Status](https://coveralls.io/repos/dcowden/cadquery/badge.svg)](https://coveralls.io/r/dcowden/cadquery) - [![GitHub version](https://badge.fury.io/gh/dcowden%2Fcadquery.svg)](https://github.com/dcowden/cadquery/releases/tag/v0.3.0) - [![License](https://img.shields.io/badge/license-LGPL-lightgrey.svg)](https://github.com/dcowden/cadquery/blob/master/LICENSE) - - CadQuery is an intuitive, easy-to-use python based language for building parametric 3D CAD models. CadQuery is for 3D CAD what jQuery is for javascript. Imagine selecting Faces of a 3d object the same way you select DOM objects with JQuery! - - CadQuery has several goals: - - * Build models with scripts that are as close as possible to how you'd describe the object to a human. - * Create parametric models that can be very easily customized by end users - * Output high quality CAD formats like STEP and AMF in addition to traditional STL - * Provide a non-proprietary, plain text model format that can be edited and executed with only a web browser - - Using CadQuery, you can write short, simple scripts that produce high quality CAD models. It is easy to make many different objects using a single script that can be customized. - - Full Documentation - ============================ - You can find the full cadquery documentation at http://dcowden.github.io/cadquery - - - Getting Started With CadQuery - ======================================== - - The easiest way to get started with CadQuery is to Install FreeCAD (version 14+) (http://www.freecadweb.org/), and then to use our great CadQuery-FreeCAD plugin here: https://github.com/jmwright/cadquery-freecad-module - - - It includes the latest version of cadquery alreadby bundled, and has super-easy installation on Mac, Windows, and Unix. - - It has tons of awesome features like integration with FreeCAD so you can see your objects, code-autocompletion, an examples bundle, and script saving/loading. Its definitely the best way to kick the tires! - - We also have a Google Group to make it easy to get help from other CadQuery users. Please join the group and introduce yourself, and we would also love to hear what you are doing with CadQuery. https://groups.google.com/forum/#!forum/cadquery - - - - Why CadQuery instead of OpenSCAD? - ======================================== - - CadQuery is based on OpenCasCade. CadQuery shares many features with OpenSCAD, another open source, script based, parametric model generator. - - The primary advantage of OpenSCAD is the large number of already existing model libaries that exist already. So why not simply use OpenSCAD? - - CadQuery scripts have several key advantages over OpenSCAD: - - 1. **The scripts use a standard programming language**, python, and thus can benefit from the associated infrastructure. - This includes many standard libraries and IDEs - - 2. **More powerful CAD kernel** OpenCascade is much more powerful than CGAL. Features supported natively - by OCC include NURBS, splines, surface sewing, STL repair, STEP import/export, and other complex operations, - in addition to the standard CSG operations supported by CGAL - - 3. **Ability to import/export STEP** We think the ability to begin with a STEP model, created in a CAD package, - and then add parametric features is key. This is possible in OpenSCAD using STL, but STL is a lossy format - - 4. **Less Code and easier scripting** CadQuery scripts require less code to create most objects, because it is possible to locate - features based on the position of other features, workplanes, vertices, etc. - - 5. **Better Performance** CadQuery scripts can build STL, STEP, and AMF faster than OpenSCAD. - - License - ======== - - CadQuery is licensed under the terms of the Apache Public License, version 2.0. - A copy of the license can be found at http://www.apache.org/licenses/LICENSE-2.0 - - Where is the GUI? - ================== - - If you would like IDE support, you can use CadQuery inside of FreeCAD. There's an excellent plugin module here https://github.com/jmwright/cadquery-freecad-module - - CadQuery also provides the backbone of http://parametricparts.com, so the easiest way to see it in action is to review the samples and objects there. - - Installing -- FreeStanding Installation - ======================================== - - Use these steps if you would like to write CadQuery scripts as a python API. In this case, FreeCAD is used only as a CAD kernel. - - 1. install FreeCAD, version 0.12 or greater for your platform. http://sourceforge.net/projects/free-cad/. - - 2. adjust your path if necessary. FreeCAD bundles a python interpreter, but you'll probably want to use your own, - preferably one that has virtualenv available. To use FreeCAD from any python interpreter, just append the FreeCAD - lib directory to your path. On (*Nix):: - - import sys - sys.path.append('/usr/lib/freecad/lib') - - or on Windows:: - - import sys - sys.path.append('/c/apps/FreeCAD/bin') - - *NOTE* FreeCAD on Windows will not work with python 2.7-- you must use pthon 2.6.X!!!! - - 3. install cadquery:: - - pip install cadquery - - 3. test your installation:: - - from cadquery import * - box = Workplane("XY").box(1,2,3) - exporters.toString(box,'STL') - - You're up and running! - - Installing -- Using CadQuery from Inside FreeCAD - ================================================= - - Use the Excellent CadQuery-FreeCAD plugin here: - https://github.com/jmwright/cadquery-freecad-module - - It includes a distribution of the latest version of cadquery. - - Where does the name CadQuery come from? - ======================================== - - CadQuery is inspired by ( `jQuery `_ ), a popular framework that - revolutionized web development involving javascript. - - If you are familiar with how jQuery, you will probably recognize several jQuery features that CadQuery uses: - - * A fluent api to create clean, easy to read code - * Language features that make selection and iteration incredibly easy - * - * Ability to use the library along side other python libraries - * Clear and complete documentation, with plenty of samples. - - -Platform: any -Classifier: Development Status :: 5 - Production/Stable -Classifier: Intended Audience :: Developers -Classifier: Intended Audience :: End Users/Desktop -Classifier: Intended Audience :: Information Technology -Classifier: Intended Audience :: Science/Research -Classifier: Intended Audience :: System Administrators -Classifier: License :: OSI Approved :: Apache Software License -Classifier: Operating System :: POSIX -Classifier: Operating System :: MacOS -Classifier: Operating System :: Unix -Classifier: Programming Language :: Python -Classifier: Topic :: Software Development :: Libraries :: Python Modules -Classifier: Topic :: Internet -Classifier: Topic :: Scientific/Engineering diff --git a/Libs/cadquery-lib/cadquery.egg-info/SOURCES.txt b/Libs/cadquery-lib/cadquery.egg-info/SOURCES.txt deleted file mode 100644 index 0507b5e..0000000 --- a/Libs/cadquery-lib/cadquery.egg-info/SOURCES.txt +++ /dev/null @@ -1,29 +0,0 @@ -MANIFEST.in -README.txt -setup.cfg -setup.py -cadquery/__init__.py -cadquery/cq.py -cadquery/cq_directive.py -cadquery/cqgi.py -cadquery/selectors.py -cadquery.egg-info/PKG-INFO -cadquery.egg-info/SOURCES.txt -cadquery.egg-info/dependency_links.txt -cadquery.egg-info/not-zip-safe -cadquery.egg-info/top_level.txt -cadquery/contrib/__init__.py -cadquery/freecad_impl/__init__.py -cadquery/freecad_impl/exporters.py -cadquery/freecad_impl/geom.py -cadquery/freecad_impl/importers.py -cadquery/freecad_impl/shapes.py -cadquery/plugins/__init__.py -tests/TestCQGI.py -tests/TestCQSelectors.py -tests/TestCadObjects.py -tests/TestCadQuery.py -tests/TestExporters.py -tests/TestImporters.py -tests/TestWorkplanes.py -tests/__init__.py \ No newline at end of file diff --git a/Libs/cadquery-lib/cadquery.egg-info/dependency_links.txt b/Libs/cadquery-lib/cadquery.egg-info/dependency_links.txt deleted file mode 100644 index 8b13789..0000000 --- a/Libs/cadquery-lib/cadquery.egg-info/dependency_links.txt +++ /dev/null @@ -1 +0,0 @@ - diff --git a/Libs/cadquery-lib/cadquery.egg-info/not-zip-safe b/Libs/cadquery-lib/cadquery.egg-info/not-zip-safe deleted file mode 100644 index 8b13789..0000000 --- a/Libs/cadquery-lib/cadquery.egg-info/not-zip-safe +++ /dev/null @@ -1 +0,0 @@ - diff --git a/Libs/cadquery-lib/cadquery.egg-info/top_level.txt b/Libs/cadquery-lib/cadquery.egg-info/top_level.txt deleted file mode 100644 index 2bbe7fc..0000000 --- a/Libs/cadquery-lib/cadquery.egg-info/top_level.txt +++ /dev/null @@ -1,2 +0,0 @@ -cadquery -tests diff --git a/Libs/cadquery-lib/cadquery/README.txt b/Libs/cadquery-lib/cadquery/README.txt deleted file mode 100644 index ab8dc7e..0000000 --- a/Libs/cadquery-lib/cadquery/README.txt +++ /dev/null @@ -1,8 +0,0 @@ -*** -Core CadQuery implementation. - -No files should depend on or import FreeCAD , pythonOCC, or other CAD Kernel libraries!!! -Dependencies should be on the classes provided by implementation packages, which in turn -can depend on CAD libraries. - -*** \ No newline at end of file diff --git a/Libs/cadquery-lib/cadquery/__init__.py b/Libs/cadquery-lib/cadquery/__init__.py deleted file mode 100644 index a9b77e4..0000000 --- a/Libs/cadquery-lib/cadquery/__init__.py +++ /dev/null @@ -1,21 +0,0 @@ -#these items point to the freecad implementation -from .freecad_impl.geom import Plane,BoundBox,Vector,Matrix,sortWiresByBuildOrder -from .freecad_impl.shapes import Shape,Vertex,Edge,Face,Wire,Solid,Shell,Compound -from .freecad_impl import exporters -from .freecad_impl import importers - -#these items are the common implementation - -#the order of these matter -from .selectors import * -from .cq import * - - -__all__ = [ - 'CQ','Workplane','plugins','selectors','Plane','BoundBox','Matrix','Vector','sortWiresByBuildOrder', - 'Shape','Vertex','Edge','Wire','Face','Solid','Shell','Compound','exporters', 'importers', - 'NearestToPointSelector','ParallelDirSelector','DirectionSelector','PerpendicularDirSelector', - 'TypeSelector','DirectionMinMaxSelector','StringSyntaxSelector','Selector','plugins' -] - -__version__ = "1.0.0" diff --git a/Libs/cadquery-lib/cadquery/contrib/__init__.py b/Libs/cadquery-lib/cadquery/contrib/__init__.py deleted file mode 100644 index 67c7b68..0000000 --- a/Libs/cadquery-lib/cadquery/contrib/__init__.py +++ /dev/null @@ -1,18 +0,0 @@ -""" - Copyright (C) 2011-2015 Parametric Products Intellectual Holdings, LLC - - This file is part of CadQuery. - - CadQuery is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - CadQuery 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; If not, see -""" diff --git a/Libs/cadquery-lib/cadquery/cq.py b/Libs/cadquery-lib/cadquery/cq.py deleted file mode 100644 index dc685c9..0000000 --- a/Libs/cadquery-lib/cadquery/cq.py +++ /dev/null @@ -1,2565 +0,0 @@ -""" - Copyright (C) 2011-2015 Parametric Products Intellectual Holdings, LLC - - This file is part of CadQuery. - - CadQuery is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - CadQuery 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; If not, see -""" - -import time -import math -from cadquery import * -from cadquery import selectors -from cadquery import exporters - - -class CQContext(object): - """ - A shared context for modeling. - - All objects in the same CQ chain share a reference to this same object instance - which allows for shared state when needed, - """ - def __init__(self): - self.pendingWires = [] # a list of wires that have been created and need to be extruded - self.pendingEdges = [] # a list of created pending edges that need to be joined into wires - # a reference to the first point for a set of edges. - # Used to determine how to behave when close() is called - self.firstPoint = None - self.tolerance = 0.0001 # user specified tolerance - - -class CQ(object): - """ - Provides enhanced functionality for a wrapped CAD primitive. - - Examples include feature selection, feature creation, 2d drawing - using work planes, and 3d operations like fillets, shells, and splitting - """ - - def __init__(self, obj): - """ - Construct a new CadQuery (CQ) object that wraps a CAD primitive. - - :param obj: Object to Wrap. - :type obj: A CAD Primitive ( wire,vertex,face,solid,edge ) - """ - self.objects = [] - self.ctx = CQContext() - self.parent = None - - if obj: # guarded because sometimes None for internal use - self.objects.append(obj) - - def newObject(self, objlist): - """ - Make a new CQ object. - - :param objlist: The stack of objects to use - :type objlist: a list of CAD primitives ( wire,face,edge,solid,vertex,etc ) - - The parent of the new object will be set to the current object, - to preserve the chain correctly. - - Custom plugins and subclasses should use this method to create new CQ objects - correctly. - """ - r = CQ(None) # create a completely blank one - r.parent = self - r.ctx = self.ctx # context solid remains the same - r.objects = list(objlist) - return r - - def _collectProperty(self, propName): - """ - Collects all of the values for propName, - for all items on the stack. - FreeCAD objects do not implement id correctly, - so hashCode is used to ensure we don't add the same - object multiple times. - - One weird use case is that the stack could have a solid reference object - on it. This is meant to be a reference to the most recently modified version - of the context solid, whatever it is. - """ - all = {} - for o in self.objects: - - # tricky-- if an object is a compound of solids, - # do not return all of the solids underneath-- typically - # then we'll keep joining to ourself - if propName == 'Solids' and isinstance(o, Solid) and o.ShapeType() == 'Compound': - for i in getattr(o, 'Compounds')(): - all[i.hashCode()] = i - else: - if hasattr(o, propName): - for i in getattr(o, propName)(): - all[i.hashCode()] = i - - return list(all.values()) - - def split(self, keepTop=False, keepBottom=False): - """ - Splits a solid on the stack into two parts, optionally keeping the separate parts. - - :param boolean keepTop: True to keep the top, False or None to discard it - :param boolean keepBottom: True to keep the bottom, False or None to discard it - :raises: ValueError if keepTop and keepBottom are both false. - :raises: ValueError if there is not a solid in the current stack or the parent chain - :returns: CQ object with the desired objects on the stack. - - The most common operation splits a solid and keeps one half. This sample creates - split bushing:: - - #drill a hole in the side - c = Workplane().box(1,1,1).faces(">Z").workplane().circle(0.25).cutThruAll()F - #now cut it in half sideways - c.faces(">Y").workplane(-0.5).split(keepTop=True) - """ - - solid = self.findSolid() - - if (not keepTop) and (not keepBottom): - raise ValueError("You have to keep at least one half") - - maxDim = solid.BoundingBox().DiagonalLength * 10.0 - topCutBox = self.rect(maxDim, maxDim)._extrude(maxDim) - bottomCutBox = self.rect(maxDim, maxDim)._extrude(-maxDim) - - top = solid.cut(bottomCutBox) - bottom = solid.cut(topCutBox) - - if keepTop and keepBottom: - # Put both on the stack, leave original unchanged. - return self.newObject([top, bottom]) - else: - # Put the one we are keeping on the stack, and also update the - # context solidto the one we kept. - if keepTop: - solid.wrapped = top.wrapped - return self.newObject([top]) - else: - solid.wrapped = bottom.wrapped - return self.newObject([bottom]) - - def combineSolids(self, otherCQToCombine=None): - """ - !!!DEPRECATED!!! use union() - Combines all solids on the current stack, and any context object, together - into a single object. - - After the operation, the returned solid is also the context solid. - - :param otherCQToCombine: another CadQuery to combine. - :return: a cQ object with the resulting combined solid on the stack. - - Most of the time, both objects will contain a single solid, which is - combined and returned on the stack of the new object. - """ - #loop through current stack objects, and combine them - #TODO: combine other types of objects as well, like edges and wires - toCombine = self.solids().vals() - - if otherCQToCombine: - for obj in otherCQToCombine.solids().vals(): - toCombine.append(obj) - - if len(toCombine) < 1: - raise ValueError("Cannot Combine: at least one solid required!") - - #get context solid and we don't want to find our own objects - ctxSolid = self.findSolid(searchStack=False, searchParents=True) - - if ctxSolid is None: - ctxSolid = toCombine.pop(0) - - #now combine them all. make sure to save a reference to the ctxSolid pointer! - s = ctxSolid - for tc in toCombine: - s = s.fuse(tc) - - ctxSolid.wrapped = s.wrapped - return self.newObject([s]) - - def all(self): - """ - Return a list of all CQ objects on the stack. - - useful when you need to operate on the elements - individually. - - Contrast with vals, which returns the underlying - objects for all of the items on the stack - """ - return [self.newObject([o]) for o in self.objects] - - def size(self): - """ - Return the number of objects currently on the stack - """ - return len(self.objects) - - def vals(self): - """ - get the values in the current list - - :rtype: list of FreeCAD objects - :returns: the values of the objects on the stack. - - Contrast with :py:meth:`all`, which returns CQ objects for all of the items on the stack - """ - return self.objects - - def add(self, obj): - """ - Adds an object or a list of objects to the stack - - :param obj: an object to add - :type obj: a CQ object, CAD primitive, or list of CAD primitives - :return: a CQ object with the requested operation performed - - If an CQ object, the values of that object's stack are added. If a list of cad primitives, - they are all added. If a single CAD primitive it is added - - Used in rare cases when you need to combine the results of several CQ results - into a single CQ object. Shelling is one common example - """ - if type(obj) == list: - self.objects.extend(obj) - elif type(obj) == CQ or type(obj) == Workplane: - self.objects.extend(obj.objects) - else: - self.objects.append(obj) - return self - - def val(self): - """ - Return the first value on the stack - - :return: the first value on the stack. - :rtype: A FreeCAD object or a SolidReference - """ - return self.objects[0] - - def toFreecad(self): - """ - Directly returns the wrapped FreeCAD object to cut down on the amount of boiler plate code - needed when rendering a model in FreeCAD's 3D view. - :return: The wrapped FreeCAD object - :rtype A FreeCAD object or a SolidReference - """ - - return self.objects[0].wrapped - - def workplane(self, offset=0.0, invert=False, centerOption='CenterOfMass'): - """ - Creates a new 2-D workplane, located relative to the first face on the stack. - - :param offset: offset for the work plane in the Z direction. Default - :param invert: invert the Z direction from that of the face. - :type offset: float or None=0.0 - :type invert: boolean or None=False - :rtype: Workplane object ( which is a subclass of CQ ) - - The first element on the stack must be a face, a set of - co-planar faces or a vertex. If a vertex, then the parent - item on the chain immediately before the vertex must be a - face. - - The result will be a 2-d working plane - with a new coordinate system set up as follows: - - * The origin will be located in the *center* of the - face/faces, if a face/faces was selected. If a vertex was - selected, the origin will be at the vertex, and located - on the face. - * The Z direction will be normal to the plane of the face,computed - at the center point. - * The X direction will be parallel to the x-y plane. If the workplane is parallel to - the global x-y plane, the x direction of the workplane will co-incide with the - global x direction. - - Most commonly, the selected face will be planar, and the workplane lies in the same plane - of the face ( IE, offset=0). Occasionally, it is useful to define a face offset from - an existing surface, and even more rarely to define a workplane based on a face that is - not planar. - - To create a workplane without first having a face, use the Workplane() method. - - Future Enhancements: - * Allow creating workplane from planar wires - * Allow creating workplane based on an arbitrary point on a face, not just the center. - For now you can work around by creating a workplane and then offsetting the center - afterwards. - """ - def _isCoPlanar(f0, f1): - """Test if two faces are on the same plane.""" - p0 = f0.Center() - p1 = f1.Center() - n0 = f0.normalAt() - n1 = f1.normalAt() - - # test normals (direction of planes) - if not ((abs(n0.x-n1.x) < self.ctx.tolerance) or - (abs(n0.y-n1.y) < self.ctx.tolerance) or - (abs(n0.z-n1.z) < self.ctx.tolerance)): - return False - - # test if p1 is on the plane of f0 (offset of planes) - return abs(n0.dot(p0.sub(p1)) < self.ctx.tolerance) - - def _computeXdir(normal): - """ - Figures out the X direction based on the given normal. - :param :normal The direction that's normal to the plane. - :type :normal A Vector - :return A vector representing the X direction. - """ - xd = Vector(0, 0, 1).cross(normal) - if xd.Length < self.ctx.tolerance: - #this face is parallel with the x-y plane, so choose x to be in global coordinates - xd = Vector(1, 0, 0) - return xd - - if len(self.objects) > 1: - # are all objects 'PLANE'? - if not all(o.geomType() == 'PLANE' for o in self.objects): - raise ValueError("If multiple objects selected, they all must be planar faces.") - - # are all faces co-planar with each other? - if not all(_isCoPlanar(self.objects[0], f) for f in self.objects[1:]): - raise ValueError("Selected faces must be co-planar.") - - if centerOption == 'CenterOfMass': - center = Shape.CombinedCenter(self.objects) - elif centerOption == 'CenterOfBoundBox': - center = Shape.CombinedCenterOfBoundBox(self.objects) - - normal = self.objects[0].normalAt() - xDir = _computeXdir(normal) - - else: - obj = self.objects[0] - - if isinstance(obj, Face): - if centerOption == 'CenterOfMass': - center = obj.Center() - elif centerOption == 'CenterOfBoundBox': - center = obj.CenterOfBoundBox() - normal = obj.normalAt(center) - xDir = _computeXdir(normal) - else: - if hasattr(obj, 'Center'): - if centerOption == 'CenterOfMass': - center = obj.Center() - elif centerOption == 'CenterOfBoundBox': - center = obj.CenterOfBoundBox() - normal = self.plane.zDir - xDir = self.plane.xDir - else: - raise ValueError("Needs a face or a vertex or point on a work plane") - - #invert if requested - if invert: - normal = normal.multiply(-1.0) - - #offset origin if desired - offsetVector = normal.normalized().multiply(offset) - offsetCenter = center.add(offsetVector) - - #make the new workplane - plane = Plane(offsetCenter, xDir, normal) - s = Workplane(plane) - s.parent = self - s.ctx = self.ctx - - #a new workplane has the center of the workplane on the stack - return s - - def first(self): - """ - Return the first item on the stack - :returns: the first item on the stack. - :rtype: a CQ object - """ - return self.newObject(self.objects[0:1]) - - def item(self, i): - """ - - Return the ith item on the stack. - :rtype: a CQ object - """ - return self.newObject([self.objects[i]]) - - def last(self): - """ - Return the last item on the stack. - :rtype: a CQ object - """ - return self.newObject([self.objects[-1]]) - - def end(self): - """ - Return the parent of this CQ element - :rtype: a CQ object - :raises: ValueError if there are no more parents in the chain. - - For example:: - - CQ(obj).faces("+Z").vertices().end() - - will return the same as:: - - CQ(obj).faces("+Z") - """ - if self.parent: - return self.parent - else: - raise ValueError("Cannot End the chain-- no parents!") - - def findSolid(self, searchStack=True, searchParents=True): - """ - Finds the first solid object in the chain, searching from the current node - backwards through parents until one is found. - - :param searchStack: should objects on the stack be searched first. - :param searchParents: should parents be searched? - :raises: ValueError if no solid is found in the current object or its parents, - and errorOnEmpty is True - - This function is very important for chains that are modifying a single parent object, - most often a solid. - - Most of the time, a chain defines or selects a solid, and then modifies it using workplanes - or other operations. - - Plugin Developers should make use of this method to find the solid that should be modified, - if the plugin implements a unary operation, or if the operation will automatically merge its - results with an object already on the stack. - """ - #notfound = ValueError("Cannot find a Valid Solid to Operate on!") - - if searchStack: - for s in self.objects: - if isinstance(s, Solid): - return s - elif isinstance(s, Compound): - return s.Solids() - - if searchParents and self.parent is not None: - return self.parent.findSolid(searchStack=True, searchParents=searchParents) - - return None - - def _selectObjects(self, objType, selector=None): - """ - Filters objects of the selected type with the specified selector,and returns results - - :param objType: the type of object we are searching for - :type objType: string: (Vertex|Edge|Wire|Solid|Shell|Compound|CompSolid) - :return: a CQ object with the selected objects on the stack. - - **Implementation Note**: This is the base implementation of the vertices,edges,faces, - solids,shells, and other similar selector methods. It is a useful extension point for - plugin developers to make other selector methods. - """ - # A single list of all faces from all objects on the stack - toReturn = self._collectProperty(objType) - - if selector is not None: - if isinstance(selector, str) or isinstance(selector, unicode): - selectorObj = selectors.StringSyntaxSelector(selector) - else: - selectorObj = selector - toReturn = selectorObj.filter(toReturn) - - return self.newObject(toReturn) - - def vertices(self, selector=None): - """ - Select the vertices of objects on the stack, optionally filtering the selection. If there - are multiple objects on the stack, the vertices of all objects are collected and a list of - all the distinct vertices is returned. - - :param selector: - :type selector: None, a Selector object, or a string selector expression. - :return: a CQ object who's stack contains the *distinct* vertices of *all* objects on the - current stack, after being filtered by the selector, if provided - - If there are no vertices for any objects on the current stack, an empty CQ object - is returned - - The typical use is to select the vertices of a single object on the stack. For example:: - - Workplane().box(1,1,1).faces("+Z").vertices().size() - - returns 4, because the topmost face of cube will contain four vertices. While this:: - - Workplane().box(1,1,1).faces().vertices().size() - - returns 8, because a cube has a total of 8 vertices - - **Note** Circles are peculiar, they have a single vertex at the center! - - :py:class:`StringSyntaxSelector` - - """ - return self._selectObjects('Vertices', selector) - - def faces(self, selector=None): - """ - Select the faces of objects on the stack, optionally filtering the selection. If there are - multiple objects on the stack, the faces of all objects are collected and a list of all the - distinct faces is returned. - - :param selector: A selector - :type selector: None, a Selector object, or a string selector expression. - :return: a CQ object who's stack contains all of the *distinct* faces of *all* objects on - the current stack, filtered by the provided selector. - - If there are no vertices for any objects on the current stack, an empty CQ object - is returned. - - The typical use is to select the faces of a single object on the stack. For example:: - - CQ(aCube).faces("+Z").size() - - returns 1, because a cube has one face with a normal in the +Z direction. Similarly:: - - CQ(aCube).faces().size() - - returns 6, because a cube has a total of 6 faces, And:: - - CQ(aCube).faces("|Z").size() - - returns 2, because a cube has 2 faces having normals parallel to the z direction - - See more about selectors HERE - """ - return self._selectObjects('Faces', selector) - - def edges(self, selector=None): - """ - Select the edges of objects on the stack, optionally filtering the selection. If there are - multiple objects on the stack, the edges of all objects are collected and a list of all the - distinct edges is returned. - - :param selector: A selector - :type selector: None, a Selector object, or a string selector expression. - :return: a CQ object who's stack contains all of the *distinct* edges of *all* objects on - the current stack, filtered by the provided selector. - - If there are no edges for any objects on the current stack, an empty CQ object is returned - - The typical use is to select the edges of a single object on the stack. For example:: - - CQ(aCube).faces("+Z").edges().size() - - returns 4, because a cube has one face with a normal in the +Z direction. Similarly:: - - CQ(aCube).edges().size() - - returns 12, because a cube has a total of 12 edges, And:: - - CQ(aCube).edges("|Z").size() - - returns 4, because a cube has 4 edges parallel to the z direction - - See more about selectors HERE - """ - return self._selectObjects('Edges', selector) - - def wires(self, selector=None): - """ - Select the wires of objects on the stack, optionally filtering the selection. If there are - multiple objects on the stack, the wires of all objects are collected and a list of all the - distinct wires is returned. - - :param selector: A selector - :type selector: None, a Selector object, or a string selector expression. - :return: a CQ object who's stack contains all of the *distinct* wires of *all* objects on - the current stack, filtered by the provided selector. - - If there are no wires for any objects on the current stack, an empty CQ object is returned - - The typical use is to select the wires of a single object on the stack. For example:: - - CQ(aCube).faces("+Z").wires().size() - - returns 1, because a face typically only has one outer wire - - See more about selectors HERE - """ - return self._selectObjects('Wires', selector) - - def solids(self, selector=None): - """ - Select the solids of objects on the stack, optionally filtering the selection. If there are - multiple objects on the stack, the solids of all objects are collected and a list of all the - distinct solids is returned. - - :param selector: A selector - :type selector: None, a Selector object, or a string selector expression. - :return: a CQ object who's stack contains all of the *distinct* solids of *all* objects on - the current stack, filtered by the provided selector. - - If there are no solids for any objects on the current stack, an empty CQ object is returned - - The typical use is to select the a single object on the stack. For example:: - - CQ(aCube).solids().size() - - returns 1, because a cube consists of one solid. - - It is possible for single CQ object ( or even a single CAD primitive ) to contain - multiple solids. - - See more about selectors HERE - """ - return self._selectObjects('Solids', selector) - - def shells(self, selector=None): - """ - Select the shells of objects on the stack, optionally filtering the selection. If there are - multiple objects on the stack, the shells of all objects are collected and a list of all the - distinct shells is returned. - - :param selector: A selector - :type selector: None, a Selector object, or a string selector expression. - :return: a CQ object who's stack contains all of the *distinct* solids of *all* objects on - the current stack, filtered by the provided selector. - - If there are no shells for any objects on the current stack, an empty CQ object is returned - - Most solids will have a single shell, which represents the outer surface. A shell will - typically be composed of multiple faces. - - See more about selectors HERE - """ - return self._selectObjects('Shells', selector) - - def compounds(self, selector=None): - """ - Select compounds on the stack, optionally filtering the selection. If there are multiple - objects on the stack, they are collected and a list of all the distinct compounds - is returned. - - :param selector: A selector - :type selector: None, a Selector object, or a string selector expression. - :return: a CQ object who's stack contains all of the *distinct* solids of *all* objects on - the current stack, filtered by the provided selector. - - A compound contains multiple CAD primitives that resulted from a single operation, such as - a union, cut, split, or fillet. Compounds can contain multiple edges, wires, or solids. - - See more about selectors HERE - """ - return self._selectObjects('Compounds', selector) - - def toSvg(self, opts=None): - """ - Returns svg text that represents the first item on the stack. - - for testing purposes. - - :param opts: svg formatting options - :type opts: dictionary, width and height - :return: a string that contains SVG that represents this item. - """ - return exporters.getSVG(self.val().wrapped, opts) - - def exportSvg(self, fileName): - """ - Exports the first item on the stack as an SVG file - - For testing purposes mainly. - - :param fileName: the filename to export - :type fileName: String, absolute path to the file - """ - exporters.exportSVG(self, fileName) - - def rotateAboutCenter(self, axisEndPoint, angleDegrees): - """ - Rotates all items on the stack by the specified angle, about the specified axis - - The center of rotation is a vector starting at the center of the object on the stack, - and ended at the specified point. - - :param axisEndPoint: the second point of axis of rotation - :type axisEndPoint: a three-tuple in global coordinates - :param angleDegrees: the rotation angle, in degrees - :type angleDegrees: float - :returns: a CQ object, with all items rotated. - - WARNING: This version returns the same cq object instead of a new one-- the - old object is not accessible. - - Future Enhancements: - * A version of this method that returns a transformed copy, rather than modifying - the originals - * This method doesnt expose a very good interface, because the axis of rotation - could be inconsistent between multiple objects. This is because the beginning - of the axis is variable, while the end is fixed. This is fine when operating on - one object, but is not cool for multiple. - """ - - #center point is the first point in the vector - endVec = Vector(axisEndPoint) - - def _rot(obj): - startPt = obj.Center() - endPt = startPt + endVec - return obj.rotate(startPt, endPt, angleDegrees) - - return self.each(_rot, False) - - def rotate(self, axisStartPoint, axisEndPoint, angleDegrees): - """ - Returns a copy of all of the items on the stack rotated through and angle around the axis - of rotation. - - :param axisStartPoint: The first point of the axis of rotation - :type axisStartPoint: a 3-tuple of floats - :type axisEndPoint: The second point of the axis of rotation - :type axisEndPoint: a 3-tuple of floats - :param angleDegrees: the rotation angle, in degrees - :type angleDegrees: float - :returns: a CQ object - """ - return self.newObject([o.rotate(axisStartPoint, axisEndPoint, angleDegrees) - for o in self.objects]) - - def mirror(self, mirrorPlane="XY", basePointVector=(0, 0, 0)): - """ - Mirror a single CQ object. This operation is the same as in the FreeCAD PartWB's mirroring - - :param mirrorPlane: the plane to mirror about - :type mirrorPlane: string, one of "XY", "YX", "XZ", "ZX", "YZ", "ZY" the planes - :param basePointVector: the base point to mirror about - :type basePointVector: tuple - """ - newS = self.newObject([self.objects[0].mirror(mirrorPlane, basePointVector)]) - return newS.first() - - - def translate(self, vec): - """ - Returns a copy of all of the items on the stack moved by the specified translation vector. - - :param tupleDistance: distance to move, in global coordinates - :type tupleDistance: a 3-tuple of float - :returns: a CQ object - """ - return self.newObject([o.translate(vec) for o in self.objects]) - - - def shell(self, thickness): - """ - Remove the selected faces to create a shell of the specified thickness. - - To shell, first create a solid, and *in the same chain* select the faces you wish to remove. - - :param thickness: a positive float, representing the thickness of the desired shell. - Negative values shell inwards, positive values shell outwards. - :raises: ValueError if the current stack contains objects that are not faces of a solid - further up in the chain. - :returns: a CQ object with the resulting shelled solid selected. - - This example will create a hollowed out unit cube, where the top most face is open, - and all other walls are 0.2 units thick:: - - Workplane().box(1,1,1).faces("+Z").shell(0.2) - - Shelling is one of the cases where you may need to use the add method to select several - faces. For example, this example creates a 3-walled corner, by removing three faces - of a cube:: - - s = Workplane().box(1,1,1) - s1 = s.faces("+Z") - s1.add(s.faces("+Y")).add(s.faces("+X")) - self.saveModel(s1.shell(0.2)) - - This fairly yucky syntax for selecting multiple faces is planned for improvement - - **Note**: When sharp edges are shelled inwards, they remain sharp corners, but **outward** - shells are automatically filleted, because an outward offset from a corner generates - a radius. - - - Future Enhancements: - Better selectors to make it easier to select multiple faces - """ - solidRef = self.findSolid() - - for f in self.objects: - if type(f) != Face: - raise ValueError("Shelling requires that faces be selected") - - s = solidRef.shell(self.objects, thickness) - solidRef.wrapped = s.wrapped - return self.newObject([s]) - - def fillet(self, radius): - """ - Fillets a solid on the selected edges. - - The edges on the stack are filleted. The solid to which the edges belong must be in the - parent chain of the selected edges. - - :param radius: the radius of the fillet, must be > zero - :type radius: positive float - :raises: ValueError if at least one edge is not selected - :raises: ValueError if the solid containing the edge is not in the chain - :returns: cq object with the resulting solid selected. - - This example will create a unit cube, with the top edges filleted:: - - s = Workplane().box(1,1,1).faces("+Z").edges().fillet(0.1) - """ - # TODO: we will need much better edge selectors for this to work - # TODO: ensure that edges selected actually belong to the solid in the chain, otherwise, - # TODO: we segfault - - solid = self.findSolid() - - edgeList = self.edges().vals() - if len(edgeList) < 1: - raise ValueError("Fillets requires that edges be selected") - - s = solid.fillet(radius, edgeList) - solid.wrapped = s.wrapped - return self.newObject([s]) - - def chamfer(self, length, length2=None): - """ - Chamfers a solid on the selected edges. - - The edges on the stack are chamfered. The solid to which the - edges belong must be in the parent chain of the selected - edges. - - Optional parameter `length2` can be supplied with a different - value than `length` for a chamfer that is shorter on one side - longer on the other side. - - :param length: the length of the fillet, must be greater than zero - :param length2: optional parameter for asymmetrical chamfer - :type length: positive float - :type length2: positive float - :raises: ValueError if at least one edge is not selected - :raises: ValueError if the solid containing the edge is not in the chain - :returns: cq object with the resulting solid selected. - - This example will create a unit cube, with the top edges chamfered:: - - s = Workplane("XY").box(1,1,1).faces("+Z").chamfer(0.1) - - This example will create chamfers longer on the sides:: - - s = Workplane("XY").box(1,1,1).faces("+Z").chamfer(0.2, 0.1) - """ - solid = self.findSolid() - - edgeList = self.edges().vals() - if len(edgeList) < 1: - raise ValueError("Chamfer requires that edges be selected") - - s = solid.chamfer(length, length2, edgeList) - - solid.wrapped = s.wrapped - return self.newObject([s]) - - -class Workplane(CQ): - """ - Defines a coordinate system in space, in which 2-d coordinates can be used. - - :param plane: the plane in which the workplane will be done - :type plane: a Plane object, or a string in (XY|YZ|XZ|front|back|top|bottom|left|right) - :param origin: the desired origin of the new workplane - :type origin: a 3-tuple in global coordinates, or None to default to the origin - :param obj: an object to use initially for the stack - :type obj: a CAD primitive, or None to use the centerpoint of the plane as the initial - stack value. - :raises: ValueError if the provided plane is not a plane, a valid named workplane - :return: A Workplane object, with coordinate system matching the supplied plane. - - The most common use is:: - - s = Workplane("XY") - - After creation, the stack contains a single point, the origin of the underlying plane, - and the *current point* is on the origin. - - .. note:: - You can also create workplanes on the surface of existing faces using - :py:meth:`CQ.workplane` - """ - - FOR_CONSTRUCTION = 'ForConstruction' - - def __init__(self, inPlane, origin=(0, 0, 0), obj=None): - """ - make a workplane from a particular plane - - :param inPlane: the plane in which the workplane will be done - :type inPlane: a Plane object, or a string in (XY|YZ|XZ|front|back|top|bottom|left|right) - :param origin: the desired origin of the new workplane - :type origin: a 3-tuple in global coordinates, or None to default to the origin - :param obj: an object to use initially for the stack - :type obj: a CAD primitive, or None to use the centerpoint of the plane as the initial - stack value. - :raises: ValueError if the provided plane is not a plane, or one of XY|YZ|XZ - :return: A Workplane object, with coordinate system matching the supplied plane. - - The most common use is:: - - s = Workplane("XY") - - After creation, the stack contains a single point, the origin of the underlying plane, and - the *current point* is on the origin. - """ - - if inPlane.__class__.__name__ == 'Plane': - tmpPlane = inPlane - elif isinstance(inPlane, str) or isinstance(inPlane, unicode): - tmpPlane = Plane.named(inPlane, origin) - else: - tmpPlane = None - - if tmpPlane is None: - raise ValueError( - 'Provided value {} is not a valid work plane'.format(inPlane)) - - self.obj = obj - self.plane = tmpPlane - self.firstPoint = None - # Changed so that workplane has the center as the first item on the stack - self.objects = [self.plane.origin] - self.parent = None - self.ctx = CQContext() - - def transformed(self, rotate=(0, 0, 0), offset=(0, 0, 0)): - """ - Create a new workplane based on the current one. - The origin of the new plane is located at the existing origin+offset vector, where offset is - given in coordinates local to the current plane - The new plane is rotated through the angles specified by the components of the rotation - vector. - :param rotate: 3-tuple of angles to rotate, in degrees relative to work plane coordinates - :param offset: 3-tuple to offset the new plane, in local work plane coordinates - :return: a new work plane, transformed as requested - """ - - #old api accepted a vector, so we'll check for that. - if rotate.__class__.__name__ == 'Vector': - rotate = rotate.toTuple() - - if offset.__class__.__name__ == 'Vector': - offset = offset.toTuple() - - p = self.plane.rotated(rotate) - p.origin = self.plane.toWorldCoords(offset) - ns = self.newObject([p.origin]) - ns.plane = p - - return ns - - def newObject(self, objlist): - """ - Create a new workplane object from this one. - - Overrides CQ.newObject, and should be used by extensions, plugins, and - subclasses to create new objects. - - :param objlist: new objects to put on the stack - :type objlist: a list of CAD primitives - :return: a new Workplane object with the current workplane as a parent. - """ - - #copy the current state to the new object - ns = Workplane("XY") - ns.plane = self.plane - ns.parent = self - ns.objects = list(objlist) - ns.ctx = self.ctx - return ns - - def _findFromPoint(self, useLocalCoords=False): - """ - Finds the start point for an operation when an existing point - is implied. Examples include 2d operations such as lineTo, - which allows specifying the end point, and implicitly use the - end of the previous line as the starting point - - :return: a Vector representing the point to use, or none if - such a point is not available. - - :param useLocalCoords: selects whether the point is returned - in local coordinates or global coordinates. - - The algorithm is this: - * If an Edge is on the stack, its end point is used.yp - * if a vector is on the stack, it is used - - WARNING: only the last object on the stack is used. - - NOTE: - """ - obj = self.objects[-1] - - if isinstance(obj, Edge): - p = obj.endPoint() - elif isinstance(obj, Vector): - p = obj - else: - raise RuntimeError("Cannot convert object type '%s' to vector " % type(obj)) - - if useLocalCoords: - return self.plane.toLocalCoords(p) - else: - return p - - def rarray(self, xSpacing, ySpacing, xCount, yCount, center=True): - """ - Creates an array of points and pushes them onto the stack. - If you want to position the array at another point, create another workplane - that is shifted to the position you would like to use as a reference - - :param xSpacing: spacing between points in the x direction ( must be > 0) - :param ySpacing: spacing between points in the y direction ( must be > 0) - :param xCount: number of points ( > 0 ) - :param yCount: number of points ( > 0 ) - :param center: if true, the array will be centered at the center of the workplane. if - false, the lower left corner will be at the center of the work plane - """ - - if xSpacing <= 0 or ySpacing <= 0 or xCount < 1 or yCount < 1: - raise ValueError("Spacing and count must be > 0 ") - - lpoints = [] # coordinates relative to bottom left point - for x in range(xCount): - for y in range(yCount): - lpoints.append((xSpacing * x, ySpacing * y)) - - #shift points down and left relative to origin if requested - if center: - xc = xSpacing*(xCount-1) * 0.5 - yc = ySpacing*(yCount-1) * 0.5 - cpoints = [] - for p in lpoints: - cpoints.append((p[0] - xc, p[1] - yc)) - lpoints = list(cpoints) - - return self.pushPoints(lpoints) - - def pushPoints(self, pntList): - """ - Pushes a list of points onto the stack as vertices. - The points are in the 2-d coordinate space of the workplane face - - :param pntList: a list of points to push onto the stack - :type pntList: list of 2-tuples, in *local* coordinates - :return: a new workplane with the desired points on the stack. - - A common use is to provide a list of points for a subsequent operation, such as creating - circles or holes. This example creates a cube, and then drills three holes through it, - based on three points:: - - s = Workplane().box(1,1,1).faces(">Z").workplane().\ - pushPoints([(-0.3,0.3),(0.3,0.3),(0,0)]) - body = s.circle(0.05).cutThruAll() - - Here the circle function operates on all three points, and is then extruded to create three - holes. See :py:meth:`circle` for how it works. - """ - vecs = [] - for pnt in pntList: - vec = self.plane.toWorldCoords(pnt) - vecs.append(vec) - - return self.newObject(vecs) - - def center(self, x, y): - """ - Shift local coordinates to the specified location. - - The location is specified in terms of local coordinates. - - :param float x: the new x location - :param float y: the new y location - :returns: the workplane object, with the center adjusted. - - The current point is set to the new center. - This method is useful to adjust the center point after it has been created automatically on - a face, but not where you'd like it to be. - - In this example, we adjust the workplane center to be at the corner of a cube, instead of - the center of a face, which is the default:: - - #this workplane is centered at x=0.5,y=0.5, the center of the upper face - s = Workplane().box(1,1,1).faces(">Z").workplane() - - s.center(-0.5,-0.5) # move the center to the corner - t = s.circle(0.25).extrude(0.2) - assert ( t.faces().size() == 9 ) # a cube with a cylindrical nub at the top right corner - - The result is a cube with a round boss on the corner - """ - "Shift local coordinates to the specified location, according to current coordinates" - self.plane.setOrigin2d(x, y) - n = self.newObject([self.plane.origin]) - return n - - def lineTo(self, x, y, forConstruction=False): - """ - Make a line from the current point to the provided point - - :param float x: the x point, in workplane plane coordinates - :param float y: the y point, in workplane plane coordinates - :return: the Workplane object with the current point at the end of the new line - - see :py:meth:`line` if you want to use relative dimensions to make a line instead. - """ - startPoint = self._findFromPoint(False) - - endPoint = self.plane.toWorldCoords((x, y)) - - p = Edge.makeLine(startPoint, endPoint) - - if not forConstruction: - self._addPendingEdge(p) - - return self.newObject([p]) - - # line a specified incremental amount from current point - def line(self, xDist, yDist, forConstruction=False): - """ - Make a line from the current point to the provided point, using - dimensions relative to the current point - - :param float xDist: x distance from current point - :param float yDist: y distance from current point - :return: the workplane object with the current point at the end of the new line - - see :py:meth:`lineTo` if you want to use absolute coordinates to make a line instead. - """ - p = self._findFromPoint(True) # return local coordinates - return self.lineTo(p.x + xDist, yDist + p.y, forConstruction) - - def vLine(self, distance, forConstruction=False): - """ - Make a vertical line from the current point the provided distance - - :param float distance: (y) distance from current point - :return: the workplane object with the current point at the end of the new line - """ - return self.line(0, distance, forConstruction) - - def hLine(self, distance, forConstruction=False): - """ - Make a horizontal line from the current point the provided distance - - :param float distance: (x) distance from current point - :return: the Workplane object with the current point at the end of the new line - """ - return self.line(distance, 0, forConstruction) - - def vLineTo(self, yCoord, forConstruction=False): - """ - Make a vertical line from the current point to the provided y coordinate. - - Useful if it is more convenient to specify the end location rather than distance, - as in :py:meth:`vLine` - - :param float yCoord: y coordinate for the end of the line - :return: the Workplane object with the current point at the end of the new line - """ - p = self._findFromPoint(True) - return self.lineTo(p.x, yCoord, forConstruction) - - def hLineTo(self, xCoord, forConstruction=False): - """ - Make a horizontal line from the current point to the provided x coordinate. - - Useful if it is more convenient to specify the end location rather than distance, - as in :py:meth:`hLine` - - :param float xCoord: x coordinate for the end of the line - :return: the Workplane object with the current point at the end of the new line - """ - p = self._findFromPoint(True) - return self.lineTo(xCoord, p.y, forConstruction) - - #absolute move in current plane, not drawing - def moveTo(self, x=0, y=0): - """ - Move to the specified point, without drawing. - - :param x: desired x location, in local coordinates - :type x: float, or none for zero - :param y: desired y location, in local coordinates - :type y: float, or none for zero. - - Not to be confused with :py:meth:`center`, which moves the center of the entire - workplane, this method only moves the current point ( and therefore does not affect objects - already drawn ). - - See :py:meth:`move` to do the same thing but using relative dimensions - """ - newCenter = Vector(x, y, 0) - return self.newObject([self.plane.toWorldCoords(newCenter)]) - - #relative move in current plane, not drawing - def move(self, xDist=0, yDist=0): - """ - Move the specified distance from the current point, without drawing. - - :param xDist: desired x distance, in local coordinates - :type xDist: float, or none for zero - :param yDist: desired y distance, in local coordinates - :type yDist: float, or none for zero. - - Not to be confused with :py:meth:`center`, which moves the center of the entire - workplane, this method only moves the current point ( and therefore does not affect objects - already drawn ). - - See :py:meth:`moveTo` to do the same thing but using absolute coordinates - """ - p = self._findFromPoint(True) - newCenter = p + Vector(xDist, yDist, 0) - return self.newObject([self.plane.toWorldCoords(newCenter)]) - - def spline(self, listOfXYTuple, forConstruction=False): - """ - Create a spline interpolated through the provided points. - - :param listOfXYTuple: points to interpolate through - :type listOfXYTuple: list of 2-tuple - :return: a Workplane object with the current point at the end of the spline - - The spline will begin at the current point, and - end with the last point in the XY tuple list - - This example creates a block with a spline for one side:: - - s = Workplane(Plane.XY()) - sPnts = [ - (2.75,1.5), - (2.5,1.75), - (2.0,1.5), - (1.5,1.0), - (1.0,1.25), - (0.5,1.0), - (0,1.0) - ] - r = s.lineTo(3.0,0).lineTo(3.0,1.0).spline(sPnts).close() - r = r.extrude(0.5) - - *WARNING* It is fairly easy to create a list of points - that cannot be correctly interpreted as a spline. - - Future Enhancements: - * provide access to control points - """ - gstartPoint = self._findFromPoint(False) - gEndPoint = self.plane.toWorldCoords(listOfXYTuple[-1]) - - vecs = [self.plane.toWorldCoords(p) for p in listOfXYTuple] - allPoints = [gstartPoint] + vecs - - e = Edge.makeSpline(allPoints) - - if not forConstruction: - self._addPendingEdge(e) - - return self.newObject([e]) - - def threePointArc(self, point1, point2, forConstruction=False): - """ - Draw an arc from the current point, through point1, and ending at point2 - - :param point1: point to draw through - :type point1: 2-tuple, in workplane coordinates - :param point2: end point for the arc - :type point2: 2-tuple, in workplane coordinates - :return: a workplane with the current point at the end of the arc - - Future Enhancements: - provide a version that allows an arc using relative measures - provide a centerpoint arc - provide tangent arcs - """ - - gstartPoint = self._findFromPoint(False) - gpoint1 = self.plane.toWorldCoords(point1) - gpoint2 = self.plane.toWorldCoords(point2) - - arc = Edge.makeThreePointArc(gstartPoint, gpoint1, gpoint2) - - if not forConstruction: - self._addPendingEdge(arc) - - return self.newObject([arc]) - - def rotateAndCopy(self, matrix): - """ - Makes a copy of all edges on the stack, rotates them according to the - provided matrix, and then attempts to consolidate them into a single wire. - - :param matrix: a 4xr transformation matrix, in global coordinates - :type matrix: a FreeCAD Base.Matrix object - :return: a CadQuery object with consolidated wires, and any originals on the stack. - - The most common use case is to create a set of open edges, and then mirror them - around either the X or Y axis to complete a closed shape. - - see :py:meth:`mirrorX` and :py:meth:`mirrorY` to mirror about the global X and Y axes - see :py:meth:`mirrorX` and for an example - - Future Enhancements: - faster implementation: this one transforms 3 times to accomplish the result - """ - - #convert edges to a wire, if there are pending edges - n = self.wire(forConstruction=False) - - #attempt to consolidate wires together. - consolidated = n.consolidateWires() - - rotatedWires = self.plane.rotateShapes(consolidated.wires().vals(), matrix) - - for w in rotatedWires: - consolidated.objects.append(w) - consolidated._addPendingWire(w) - - #attempt again to consolidate all of the wires - c = consolidated.consolidateWires() - - return c - - def mirrorY(self): - """ - Mirror entities around the y axis of the workplane plane. - - :return: a new object with any free edges consolidated into as few wires as possible. - - All free edges are collected into a wire, and then the wire is mirrored, - and finally joined into a new wire - - Typically used to make creating wires with symmetry easier. This line of code:: - - s = Workplane().lineTo(2,2).threePointArc((3,1),(2,0)).mirrorX().extrude(0.25) - - Produces a flat, heart shaped object - - Future Enhancements: - mirrorX().mirrorY() should work but doesnt, due to some FreeCAD weirdness - """ - tm = Matrix() - tm.rotateY(math.pi) - return self.rotateAndCopy(tm) - - def mirrorX(self): - """ - Mirror entities around the x axis of the workplane plane. - - :return: a new object with any free edges consolidated into as few wires as possible. - - All free edges are collected into a wire, and then the wire is mirrored, - and finally joined into a new wire - - Typically used to make creating wires with symmetry easier. - - Future Enhancements: - mirrorX().mirrorY() should work but doesnt, due to some FreeCAD weirdness - """ - tm = Matrix() - tm.rotateX(math.pi) - return self.rotateAndCopy(tm) - - def _addPendingEdge(self, edge): - """ - Queues an edge for later combination into a wire. - - :param edge: - :return: - """ - self.ctx.pendingEdges.append(edge) - - if self.ctx.firstPoint is None: - self.ctx.firstPoint = self.plane.toLocalCoords(edge.startPoint()) - - def _addPendingWire(self, wire): - """ - Queue a Wire for later extrusion - - Internal Processing Note. In FreeCAD, edges-->wires-->faces-->solids. - - but users do not normally care about these distinctions. Users 'think' in terms - of edges, and solids. - - CadQuery tracks edges as they are drawn, and automatically combines them into wires - when the user does an operation that needs it. - - Similarly, cadQuery tracks pending wires, and automatically combines them into faces - when necessary to make a solid. - """ - self.ctx.pendingWires.append(wire) - - def consolidateWires(self): - """ - Attempt to consolidate wires on the stack into a single. - If possible, a new object with the results are returned. - if not possible, the wires remain separated - - FreeCAD has a bug in Part.Wire([]) which does not create wires/edges properly sometimes - Additionally, it has a bug where a profile composed of two wires ( rather than one ) - also does not work properly. Together these are a real problem. - """ - wires = self.wires().vals() - if len(wires) < 2: - return self - - #TODO: this makes the assumption that either all wires could be combined, or none. - #in reality trying each combination of wires is probably not reasonable anyway - w = Wire.combine(wires) - - #ok this is a little tricky. if we consolidate wires, we have to actually - #modify the pendingWires collection to remove the original ones, and replace them - #with the consolidate done - #since we are already assuming that all wires could be consolidated, its easy, we just - #clear the pending wire list - r = self.newObject([w]) - r.ctx.pendingWires = [] - r._addPendingWire(w) - return r - - def wire(self, forConstruction=False): - """ - Returns a CQ object with all pending edges connected into a wire. - - All edges on the stack that can be combined will be combined into a single wire object, - and other objects will remain on the stack unmodified - - :param forConstruction: whether the wire should be used to make a solid, or if it is just - for reference - :type forConstruction: boolean. true if the object is only for reference - - This method is primarily of use to plugin developers making utilities for 2-d construction. - This method should be called when a user operation implies that 2-d construction is - finished, and we are ready to begin working in 3d - - SEE '2-d construction concepts' for a more detailed explanation of how CadQuery handles - edges, wires, etc - - Any non edges will still remain. - """ - - edges = self.ctx.pendingEdges - - #do not consolidate if there are no free edges - if len(edges) == 0: - return self - - self.ctx.pendingEdges = [] - - others = [] - for e in self.objects: - if type(e) != Edge: - others.append(e) - - - w = Wire.assembleEdges(edges) - if not forConstruction: - self._addPendingWire(w) - - return self.newObject(others + [w]) - - def each(self, callBackFunction, useLocalCoordinates=False): - """ - Runs the provided function on each value in the stack, and collects the return values into - a new CQ object. - - Special note: a newly created workplane always has its center point as its only stack item - - :param callBackFunction: the function to call for each item on the current stack. - :param useLocalCoordinates: should values be converted from local coordinates first? - :type useLocalCoordinates: boolean - - The callback function must accept one argument, which is the item on the stack, and return - one object, which is collected. If the function returns None, nothing is added to the stack. - The object passed into the callBackFunction is potentially transformed to local coordinates, - if useLocalCoordinates is true - - useLocalCoordinates is very useful for plugin developers. - - If false, the callback function is assumed to be working in global coordinates. Objects - created are added as-is, and objects passed into the function are sent in using global - coordinates - - If true, the calling function is assumed to be working in local coordinates. Objects are - transformed to local coordinates before they are passed into the callback method, and result - objects are transformed to global coordinates after they are returned. - - This allows plugin developers to create objects in local coordinates, without worrying - about the fact that the working plane is different than the global coordinate system. - - - TODO: wrapper object for Wire will clean up forConstruction flag everywhere - """ - results = [] - for obj in self.objects: - - if useLocalCoordinates: - #TODO: this needs to work for all types of objects, not just vectors! - r = callBackFunction(self.plane.toLocalCoords(obj)) - r = r.transformShape(self.plane.rG) - else: - r = callBackFunction(obj) - - if type(r) == Wire: - if not r.forConstruction: - self._addPendingWire(r) - - results.append(r) - - return self.newObject(results) - - def eachpoint(self, callbackFunction, useLocalCoordinates=False): - """ - Same as each(), except each item on the stack is converted into a point before it - is passed into the callback function. - - :return: CadQuery object which contains a list of vectors (points ) on its stack. - - :param useLocalCoordinates: should points be in local or global coordinates - :type useLocalCoordinates: boolean - - The resulting object has a point on the stack for each object on the original stack. - Vertices and points remain a point. Faces, Wires, Solids, Edges, and Shells are converted - to a point by using their center of mass. - - If the stack has zero length, a single point is returned, which is the center of the current - workplane/coordinate system - """ - #convert stack to a list of points - pnts = [] - if len(self.objects) == 0: - #nothing on the stack. here, we'll assume we should operate with the - #origin as the context point - pnts.append(self.plane.origin) - else: - - for v in self.objects: - pnts.append(v.Center()) - - return self.newObject(pnts).each(callbackFunction, useLocalCoordinates) - - def rect(self, xLen, yLen, centered=True, forConstruction=False): - """ - Make a rectangle for each item on the stack. - - :param xLen: length in xDirection ( in workplane coordinates ) - :type xLen: float > 0 - :param yLen: length in yDirection ( in workplane coordinates ) - :type yLen: float > 0 - :param boolean centered: true if the rect is centered on the reference point, false if the - lower-left is on the reference point - :param forConstruction: should the new wires be reference geometry only? - :type forConstruction: true if the wires are for reference, false if they are creating part - geometry - :return: a new CQ object with the created wires on the stack - - A common use case is to use a for-construction rectangle to define the centers of a hole - pattern:: - - s = Workplane().rect(4.0,4.0,forConstruction=True).vertices().circle(0.25) - - Creates 4 circles at the corners of a square centered on the origin. - - Future Enhancements: - better way to handle forConstruction - project points not in the workplane plane onto the workplane plane - """ - def makeRectangleWire(pnt): - # Here pnt is in local coordinates due to useLocalCoords=True - # (xc,yc,zc) = pnt.toTuple() - if centered: - p1 = pnt.add(Vector(xLen/-2.0, yLen/-2.0, 0)) - p2 = pnt.add(Vector(xLen/2.0, yLen/-2.0, 0)) - p3 = pnt.add(Vector(xLen/2.0, yLen/2.0, 0)) - p4 = pnt.add(Vector(xLen/-2.0, yLen/2.0, 0)) - else: - p1 = pnt - p2 = pnt.add(Vector(xLen, 0, 0)) - p3 = pnt.add(Vector(xLen, yLen, 0)) - p4 = pnt.add(Vector(0, yLen, 0)) - - w = Wire.makePolygon([p1, p2, p3, p4, p1], forConstruction) - return w - #return Part.makePolygon([p1,p2,p3,p4,p1]) - - return self.eachpoint(makeRectangleWire, True) - - #circle from current point - def circle(self, radius, forConstruction=False): - """ - Make a circle for each item on the stack. - - :param radius: radius of the circle - :type radius: float > 0 - :param forConstruction: should the new wires be reference geometry only? - :type forConstruction: true if the wires are for reference, false if they are creating - part geometry - :return: a new CQ object with the created wires on the stack - - A common use case is to use a for-construction rectangle to define the centers of a - hole pattern:: - - s = Workplane().rect(4.0,4.0,forConstruction=True).vertices().circle(0.25) - - Creates 4 circles at the corners of a square centered on the origin. Another common case is - to use successive circle() calls to create concentric circles. This works because the - center of a circle is its reference point:: - - s = Workplane().circle(2.0).circle(1.0) - - Creates two concentric circles, which when extruded will form a ring. - - Future Enhancements: - better way to handle forConstruction - project points not in the workplane plane onto the workplane plane - - """ - def makeCircleWire(obj): - cir = Wire.makeCircle(radius, obj, Vector(0, 0, 1)) - cir.forConstruction = forConstruction - return cir - - return self.eachpoint(makeCircleWire, useLocalCoordinates=True) - - def polygon(self, nSides, diameter, forConstruction=False): - """ - Creates a polygon inscribed in a circle of the specified diameter for each point on - the stack - - The first vertex is always oriented in the x direction. - - :param nSides: number of sides, must be > 3 - :param diameter: the size of the circle the polygon is inscribed into - :return: a polygon wire - """ - def _makePolygon(center): - #pnt is a vector in local coordinates - angle = 2.0 * math.pi / nSides - pnts = [] - for i in range(nSides+1): - pnts.append(center + Vector((diameter / 2.0 * math.cos(angle*i)), - (diameter / 2.0 * math.sin(angle*i)), 0)) - return Wire.makePolygon(pnts, forConstruction) - - return self.eachpoint(_makePolygon, True) - - def polyline(self, listOfXYTuple, forConstruction=False): - """ - Create a polyline from a list of points - - :param listOfXYTuple: a list of points in Workplane coordinates - :type listOfXYTuple: list of 2-tuples - :param forConstruction: whether or not the edges are used for reference - :type forConstruction: true if the edges are for reference, false if they are for creating geometry - part geometry - :return: a new CQ object with a list of edges on the stack - - *NOTE* most commonly, the resulting wire should be closed. - """ - - # Our list of new edges that will go into a new CQ object - edges = [] - - # The very first startPoint comes from our original object, but not after that - startPoint = self._findFromPoint(False) - - # Draw a line for each set of points, starting from the from-point of the original CQ object - for curTuple in listOfXYTuple: - endPoint = self.plane.toWorldCoords(curTuple) - - edges.append(Edge.makeLine(startPoint, endPoint)) - - # We need to move the start point for the next line that we draw or we get stuck at the same startPoint - startPoint = endPoint - - if not forConstruction: - self._addPendingEdge(edges[-1]) - - return self.newObject(edges) - - def close(self): - """ - End 2-d construction, and attempt to build a closed wire. - - :return: a CQ object with a completed wire on the stack, if possible. - - After 2-d drafting with lineTo,threePointArc, and polyline, it is necessary - to convert the edges produced by these into one or more wires. - - When a set of edges is closed, cadQuery assumes it is safe to build the group of edges - into a wire. This example builds a simple triangular prism:: - - s = Workplane().lineTo(1,0).lineTo(1,1).close().extrude(0.2) - """ - self.lineTo(self.ctx.firstPoint.x, self.ctx.firstPoint.y) - - # Need to reset the first point after closing a wire - self.ctx.firstPoint=None - - return self.wire() - - def largestDimension(self): - """ - Finds the largest dimension in the stack. - Used internally to create thru features, this is how you can compute - how long or wide a feature must be to make sure to cut through all of the material - :return: A value representing the largest dimension of the first solid on the stack - """ - #TODO: this implementation is naive and returns the dims of the first solid... most of - #TODO: the time this works. but a stronger implementation would be to search all solids. - s = self.findSolid() - if s: - return s.BoundingBox().DiagonalLength * 5.0 - else: - return -1 - - def cutEach(self, fcn, useLocalCoords=False, clean=True): - """ - Evaluates the provided function at each point on the stack (ie, eachpoint) - and then cuts the result from the context solid. - :param fcn: a function suitable for use in the eachpoint method: ie, that accepts a vector - :param useLocalCoords: same as for :py:meth:`eachpoint` - :param boolean clean: call :py:meth:`clean` afterwards to have a clean shape - :return: a CQ object that contains the resulting solid - :raises: an error if there is not a context solid to cut from - """ - ctxSolid = self.findSolid() - if ctxSolid is None: - raise ValueError("Must have a solid in the chain to cut from!") - - #will contain all of the counterbores as a single compound - results = self.eachpoint(fcn, useLocalCoords).vals() - s = ctxSolid - for cb in results: - s = s.cut(cb) - - if clean: s = s.clean() - - ctxSolid.wrapped = s.wrapped - return self.newObject([s]) - - #but parameter list is different so a simple function pointer wont work - def cboreHole(self, diameter, cboreDiameter, cboreDepth, depth=None, clean=True): - """ - Makes a counterbored hole for each item on the stack. - - :param diameter: the diameter of the hole - :type diameter: float > 0 - :param cboreDiameter: the diameter of the cbore - :type cboreDiameter: float > 0 and > diameter - :param cboreDepth: depth of the counterbore - :type cboreDepth: float > 0 - :param depth: the depth of the hole - :type depth: float > 0 or None to drill thru the entire part. - :param boolean clean: call :py:meth:`clean` afterwards to have a clean shape - - The surface of the hole is at the current workplane plane. - - One hole is created for each item on the stack. A very common use case is to use a - construction rectangle to define the centers of a set of holes, like so:: - - s = Workplane(Plane.XY()).box(2,4,0.5).faces(">Z").workplane()\ - .rect(1.5,3.5,forConstruction=True)\ - .vertices().cboreHole(0.125, 0.25,0.125,depth=None) - - This sample creates a plate with a set of holes at the corners. - - **Plugin Note**: this is one example of the power of plugins. Counterbored holes are quite - time consuming to create, but are quite easily defined by users. - - see :py:meth:`cskHole` to make countersinks instead of counterbores - """ - if depth is None: - depth = self.largestDimension() - - def _makeCbore(center): - """ - Makes a single hole with counterbore at the supplied point - returns a solid suitable for subtraction - pnt is in local coordinates - """ - boreDir = Vector(0, 0, -1) - #first make the hole - hole = Solid.makeCylinder(diameter/2.0, depth, center, boreDir) # local coordianates! - - #add the counter bore - cbore = Solid.makeCylinder(cboreDiameter / 2.0, cboreDepth, center, boreDir) - r = hole.fuse(cbore) - return r - - return self.cutEach(_makeCbore, True, clean) - - #TODO: almost all code duplicated! - #but parameter list is different so a simple function pointer wont work - def cskHole(self, diameter, cskDiameter, cskAngle, depth=None, clean=True): - """ - Makes a countersunk hole for each item on the stack. - - :param diameter: the diameter of the hole - :type diameter: float > 0 - :param cskDiameter: the diameter of the countersink - :type cskDiameter: float > 0 and > diameter - :param cskAngle: angle of the countersink, in degrees ( 82 is common ) - :type cskAngle: float > 0 - :param depth: the depth of the hole - :type depth: float > 0 or None to drill thru the entire part. - :param boolean clean: call :py:meth:`clean` afterwards to have a clean shape - - The surface of the hole is at the current workplane. - - One hole is created for each item on the stack. A very common use case is to use a - construction rectangle to define the centers of a set of holes, like so:: - - s = Workplane(Plane.XY()).box(2,4,0.5).faces(">Z").workplane()\ - .rect(1.5,3.5,forConstruction=True)\ - .vertices().cskHole(0.125, 0.25,82,depth=None) - - This sample creates a plate with a set of holes at the corners. - - **Plugin Note**: this is one example of the power of plugins. CounterSunk holes are quite - time consuming to create, but are quite easily defined by users. - - see :py:meth:`cboreHole` to make counterbores instead of countersinks - """ - - if depth is None: - depth = self.largestDimension() - - def _makeCsk(center): - #center is in local coordinates - - boreDir = Vector(0, 0, -1) - - #first make the hole - hole = Solid.makeCylinder(diameter/2.0, depth, center, boreDir) # local coords! - r = cskDiameter / 2.0 - h = r / math.tan(math.radians(cskAngle / 2.0)) - csk = Solid.makeCone(r, 0.0, h, center, boreDir) - r = hole.fuse(csk) - return r - - return self.cutEach(_makeCsk, True, clean) - - #TODO: almost all code duplicated! - #but parameter list is different so a simple function pointer wont work - def hole(self, diameter, depth=None, clean=True): - """ - Makes a hole for each item on the stack. - - :param diameter: the diameter of the hole - :type diameter: float > 0 - :param depth: the depth of the hole - :type depth: float > 0 or None to drill thru the entire part. - :param boolean clean: call :py:meth:`clean` afterwards to have a clean shape - - The surface of the hole is at the current workplane. - - One hole is created for each item on the stack. A very common use case is to use a - construction rectangle to define the centers of a set of holes, like so:: - - s = Workplane(Plane.XY()).box(2,4,0.5).faces(">Z").workplane()\ - .rect(1.5,3.5,forConstruction=True)\ - .vertices().hole(0.125, 0.25,82,depth=None) - - This sample creates a plate with a set of holes at the corners. - - **Plugin Note**: this is one example of the power of plugins. CounterSunk holes are quite - time consuming to create, but are quite easily defined by users. - - see :py:meth:`cboreHole` and :py:meth:`cskHole` to make counterbores or countersinks - """ - if depth is None: - depth = self.largestDimension() - - def _makeHole(center): - """ - Makes a single hole with counterbore at the supplied point - returns a solid suitable for subtraction - pnt is in local coordinates - """ - boreDir = Vector(0, 0, -1) - #first make the hole - hole = Solid.makeCylinder(diameter / 2.0, depth, center, boreDir) # local coordinates! - return hole - - return self.cutEach(_makeHole, True, clean) - - #TODO: duplicated code with _extrude and extrude - def twistExtrude(self, distance, angleDegrees, combine=True, clean=True): - """ - Extrudes a wire in the direction normal to the plane, but also twists by the specified - angle over the length of the extrusion - - The center point of the rotation will be the center of the workplane - - See extrude for more details, since this method is the same except for the the addition - of the angle. In fact, if angle=0, the result is the same as a linear extrude. - - **NOTE** This method can create complex calculations, so be careful using it with - complex geometries - - :param distance: the distance to extrude normal to the workplane - :param angle: angline ( in degrees) to rotate through the extrusion - :param boolean combine: True to combine the resulting solid with parent solids if found. - :param boolean clean: call :py:meth:`clean` afterwards to have a clean shape - :return: a CQ object with the resulting solid selected. - """ - #group wires together into faces based on which ones are inside the others - #result is a list of lists - wireSets = sortWiresByBuildOrder(list(self.ctx.pendingWires), self.plane, []) - - self.ctx.pendingWires = [] # now all of the wires have been used to create an extrusion - - #compute extrusion vector and extrude - eDir = self.plane.zDir.multiply(distance) - - #one would think that fusing faces into a compound and then extruding would work, - #but it doesnt-- the resulting compound appears to look right, ( right number of faces, etc) - #but then cutting it from the main solid fails with BRep_NotDone. - #the work around is to extrude each and then join the resulting solids, which seems to work - - #underlying cad kernel can only handle simple bosses-- we'll aggregate them if there - # are multiple sets - r = None - for ws in wireSets: - thisObj = Solid.extrudeLinearWithRotation(ws[0], ws[1:], self.plane.origin, - eDir, angleDegrees) - if r is None: - r = thisObj - else: - r = r.fuse(thisObj) - - if combine: - newS = self._combineWithBase(r) - else: - newS = self.newObject([r]) - if clean: newS = newS.clean() - return newS - - def extrude(self, distance, combine=True, clean=True, both=False): - """ - Use all un-extruded wires in the parent chain to create a prismatic solid. - - :param distance: the distance to extrude, normal to the workplane plane - :type distance: float, negative means opposite the normal direction - :param boolean combine: True to combine the resulting solid with parent solids if found. - :param boolean clean: call :py:meth:`clean` afterwards to have a clean shape - :param boolean both: extrude in both directions symmetrically - :return: a CQ object with the resulting solid selected. - - extrude always *adds* material to a part. - - The returned object is always a CQ object, and depends on wither combine is True, and - whether a context solid is already defined: - - * if combine is False, the new value is pushed onto the stack. - * if combine is true, the value is combined with the context solid if it exists, - and the resulting solid becomes the new context solid. - - FutureEnhancement: - Support for non-prismatic extrusion ( IE, sweeping along a profile, not just - perpendicular to the plane extrude to surface. this is quite tricky since the surface - selected may not be planar - """ - r = self._extrude(distance,both=both) # returns a Solid (or a compound if there were multiple) - - if combine: - newS = self._combineWithBase(r) - else: - newS = self.newObject([r]) - if clean: newS = newS.clean() - return newS - - def revolve(self, angleDegrees=360.0, axisStart=None, axisEnd=None, combine=True, clean=True): - """ - Use all un-revolved wires in the parent chain to create a solid. - - :param angleDegrees: the angle to revolve through. - :type angleDegrees: float, anything less than 360 degrees will leave the shape open - :param axisStart: the start point of the axis of rotation - :type axisStart: tuple, a two tuple - :param axisEnd: the end point of the axis of rotation - :type axisEnd: tuple, a two tuple - :param combine: True to combine the resulting solid with parent solids if found. - :type combine: boolean, combine with parent solid - :param boolean clean: call :py:meth:`clean` afterwards to have a clean shape - :return: a CQ object with the resulting solid selected. - - The returned object is always a CQ object, and depends on wither combine is True, and - whether a context solid is already defined: - - * if combine is False, the new value is pushed onto the stack. - * if combine is true, the value is combined with the context solid if it exists, - and the resulting solid becomes the new context solid. - """ - #Make sure we account for users specifying angles larger than 360 degrees - angleDegrees %= 360.0 - - #Compensate for FreeCAD not assuming that a 0 degree revolve means a 360 degree revolve - angleDegrees = 360.0 if angleDegrees == 0 else angleDegrees - - # The default start point of the vector defining the axis of rotation will be the origin - # of the workplane - if axisStart is None: - axisStart = self.plane.toWorldCoords((0, 0)).toTuple() - else: - axisStart = self.plane.toWorldCoords(axisStart).toTuple() - - # The default end point of the vector defining the axis of rotation should be along the - # normal from the plane - if axisEnd is None: - # Make sure we match the user's assumed axis of rotation if they specified an start - # but not an end - if axisStart[1] != 0: - axisEnd = self.plane.toWorldCoords((0, axisStart[1])).toTuple() - else: - axisEnd = self.plane.toWorldCoords((0, 1)).toTuple() - else: - axisEnd = self.plane.toWorldCoords(axisEnd).toTuple() - - # returns a Solid (or a compound if there were multiple) - r = self._revolve(angleDegrees, axisStart, axisEnd) - if combine: - newS = self._combineWithBase(r) - else: - newS = self.newObject([r]) - if clean: newS = newS.clean() - return newS - - def sweep(self, path, makeSolid=True, isFrenet=False, combine=True, clean=True): - """ - Use all un-extruded wires in the parent chain to create a swept solid. - - :param path: A wire along which the pending wires will be swept - :param boolean combine: True to combine the resulting solid with parent solids if found. - :param boolean clean: call :py:meth:`clean` afterwards to have a clean shape - :return: a CQ object with the resulting solid selected. - """ - - r = self._sweep(path.wire(), makeSolid, isFrenet) # returns a Solid (or a compound if there were multiple) - if combine: - newS = self._combineWithBase(r) - else: - newS = self.newObject([r]) - if clean: newS = newS.clean() - return newS - - def _combineWithBase(self, obj): - """ - Combines the provided object with the base solid, if one can be found. - :param obj: - :return: a new object that represents the result of combining the base object with obj, - or obj if one could not be found - """ - baseSolid = self.findSolid(searchParents=True) - r = obj - if baseSolid is not None: - r = baseSolid.fuse(obj) - baseSolid.wrapped = r.wrapped - - return self.newObject([r]) - - def combine(self, clean=True): - """ - Attempts to combine all of the items on the stack into a single item. - WARNING: all of the items must be of the same type! - - :param boolean clean: call :py:meth:`clean` afterwards to have a clean shape - :raises: ValueError if there are no items on the stack, or if they cannot be combined - :return: a CQ object with the resulting object selected - """ - items = list(self.objects) - s = items.pop(0) - for ss in items: - s = s.fuse(ss) - - if clean: s = s.clean() - - return self.newObject([s]) - - def union(self, toUnion=None, combine=True, clean=True): - """ - Unions all of the items on the stack of toUnion with the current solid. - If there is no current solid, the items in toUnion are unioned together. - if combine=True, the result and the original are updated to point to the new object - if combine=False, the result will be on the stack, but the original is unmodified - - :param toUnion: - :type toUnion: a solid object, or a CQ object having a solid, - :param boolean clean: call :py:meth:`clean` afterwards to have a clean shape - :raises: ValueError if there is no solid to add to in the chain - :return: a CQ object with the resulting object selected - """ - - #first collect all of the items together - if type(toUnion) == CQ or type(toUnion) == Workplane: - solids = toUnion.solids().vals() - if len(solids) < 1: - raise ValueError("CQ object must have at least one solid on the stack to union!") - newS = solids.pop(0) - for s in solids: - newS = newS.fuse(s) - elif type(toUnion) == Solid: - newS = toUnion - else: - raise ValueError("Cannot union type '{}'".format(type(toUnion))) - - #now combine with existing solid, if there is one - # look for parents to cut from - solidRef = self.findSolid(searchStack=True, searchParents=True) - if combine and solidRef is not None: - r = solidRef.fuse(newS) - solidRef.wrapped = newS.wrapped - else: - r = newS - - if clean: r = r.clean() - - return self.newObject([r]) - - def cut(self, toCut, combine=True, clean=True): - """ - Cuts the provided solid from the current solid, IE, perform a solid subtraction - - if combine=True, the result and the original are updated to point to the new object - if combine=False, the result will be on the stack, but the original is unmodified - - :param toCut: object to cut - :type toCut: a solid object, or a CQ object having a solid, - :param boolean clean: call :py:meth:`clean` afterwards to have a clean shape - :raises: ValueError if there is no solid to subtract from in the chain - :return: a CQ object with the resulting object selected - """ - - # look for parents to cut from - solidRef = self.findSolid(searchStack=True, searchParents=True) - - if solidRef is None: - raise ValueError("Cannot find solid to cut from") - solidToCut = None - if type(toCut) == CQ or type(toCut) == Workplane: - solidToCut = toCut.val() - elif type(toCut) == Solid: - solidToCut = toCut - else: - raise ValueError("Cannot cut type '{}'".format(type(toCut))) - - newS = solidRef.cut(solidToCut) - - if clean: newS = newS.clean() - - if combine: - solidRef.wrapped = newS.wrapped - - return self.newObject([newS]) - - def intersect(self, toIntersect, combine=True, clean=True): - """ - Intersects the provided solid from the current solid. - - if combine=True, the result and the original are updated to point to the new object - if combine=False, the result will be on the stack, but the original is unmodified - - :param toIntersect: object to intersect - :type toIntersect: a solid object, or a CQ object having a solid, - :param boolean clean: call :py:meth:`clean` afterwards to have a clean shape - :raises: ValueError if there is no solid to intersect with in the chain - :return: a CQ object with the resulting object selected - """ - - # look for parents to intersect with - solidRef = self.findSolid(searchStack=True, searchParents=True) - - if solidRef is None: - raise ValueError("Cannot find solid to intersect with") - solidToIntersect = None - - if isinstance(toIntersect, CQ): - solidToIntersect = toIntersect.val() - elif isinstance(toIntersect, Solid): - solidToIntersect = toIntersect - else: - raise ValueError("Cannot intersect type '{}'".format(type(toIntersect))) - - newS = solidRef.intersect(solidToIntersect) - - if clean: newS = newS.clean() - - if combine: - solidRef.wrapped = newS.wrapped - - return self.newObject([newS]) - - - def cutBlind(self, distanceToCut, clean=True): - """ - Use all un-extruded wires in the parent chain to create a prismatic cut from existing solid. - - Similar to extrude, except that a solid in the parent chain is required to remove material - from. cutBlind always removes material from a part. - - :param distanceToCut: distance to extrude before cutting - :type distanceToCut: float, >0 means in the positive direction of the workplane normal, - <0 means in the negative direction - :param boolean clean: call :py:meth:`clean` afterwards to have a clean shape - :raises: ValueError if there is no solid to subtract from in the chain - :return: a CQ object with the resulting object selected - - see :py:meth:`cutThruAll` to cut material from the entire part - - Future Enhancements: - Cut Up to Surface - """ - #first, make the object - toCut = self._extrude(distanceToCut) - - #now find a solid in the chain - - solidRef = self.findSolid() - - s = solidRef.cut(toCut) - - if clean: s = s.clean() - - solidRef.wrapped = s.wrapped - return self.newObject([s]) - - def cutThruAll(self, positive=False, clean=True): - """ - Use all un-extruded wires in the parent chain to create a prismatic cut from existing solid. - - Similar to extrude, except that a solid in the parent chain is required to remove material - from. cutThruAll always removes material from a part. - - :param boolean positive: True to cut in the positive direction, false to cut in the - negative direction - :param boolean clean: call :py:meth:`clean` afterwards to have a clean shape - :raises: ValueError if there is no solid to subtract from in the chain - :return: a CQ object with the resulting object selected - - see :py:meth:`cutBlind` to cut material to a limited depth - """ - maxDim = self.largestDimension() - if not positive: - maxDim *= (-1.0) - - return self.cutBlind(maxDim, clean) - - def loft(self, filled=True, ruled=False, combine=True): - """ - Make a lofted solid, through the set of wires. - :return: a CQ object containing the created loft - """ - wiresToLoft = self.ctx.pendingWires - self.ctx.pendingWires = [] - - r = Solid.makeLoft(wiresToLoft, ruled) - - if combine: - parentSolid = self.findSolid(searchStack=False, searchParents=True) - if parentSolid is not None: - r = parentSolid.fuse(r) - parentSolid.wrapped = r.wrapped - - return self.newObject([r]) - - def _extrude(self, distance, both=False): - """ - Make a prismatic solid from the existing set of pending wires. - - :param distance: distance to extrude - :param boolean both: extrude in both directions symmetrically - :return: a FreeCAD solid, suitable for boolean operations. - - This method is a utility method, primarily for plugin and internal use. - It is the basis for cutBlind,extrude,cutThruAll, and all similar methods. - - Future Enhancements: - extrude along a profile (sweep) - """ - - #group wires together into faces based on which ones are inside the others - #result is a list of lists - s = time.time() - wireSets = sortWiresByBuildOrder(list(self.ctx.pendingWires), self.plane, []) - #print "sorted wires in %d sec" % ( time.time() - s ) - self.ctx.pendingWires = [] # now all of the wires have been used to create an extrusion - - #compute extrusion vector and extrude - eDir = self.plane.zDir.multiply(distance) - - - #one would think that fusing faces into a compound and then extruding would work, - #but it doesnt-- the resulting compound appears to look right, ( right number of faces, etc) - #but then cutting it from the main solid fails with BRep_NotDone. - #the work around is to extrude each and then join the resulting solids, which seems to work - - # underlying cad kernel can only handle simple bosses-- we'll aggregate them if there are - # multiple sets - - # IMPORTANT NOTE: OCC is slow slow slow in boolean operations. So you do NOT want to fuse - # each item to another and save the result-- instead, you want to combine all of the new - # items into a compound, and fuse them together!!! - # r = None - # for ws in wireSets: - # thisObj = Solid.extrudeLinear(ws[0], ws[1:], eDir) - # if r is None: - # r = thisObj - # else: - # s = time.time() - # r = r.fuse(thisObj) - # print "Fused in %0.3f sec" % ( time.time() - s ) - # return r - - toFuse = [] - for ws in wireSets: - thisObj = Solid.extrudeLinear(ws[0], ws[1:], eDir) - toFuse.append(thisObj) - - if both: - thisObj = Solid.extrudeLinear(ws[0], ws[1:], eDir.multiply(-1.)) - toFuse.append(thisObj) - - return Compound.makeCompound(toFuse) - - def _revolve(self, angleDegrees, axisStart, axisEnd): - """ - Make a solid from the existing set of pending wires. - - :param angleDegrees: the angle to revolve through. - :type angleDegrees: float, anything less than 360 degrees will leave the shape open - :param axisStart: the start point of the axis of rotation - :type axisStart: tuple, a two tuple - :param axisEnd: the end point of the axis of rotation - :type axisEnd: tuple, a two tuple - :return: a FreeCAD solid, suitable for boolean operations. - - This method is a utility method, primarily for plugin and internal use. - """ - #We have to gather the wires to be revolved - wireSets = sortWiresByBuildOrder(list(self.ctx.pendingWires), self.plane, []) - - #Mark that all of the wires have been used to create a revolution - self.ctx.pendingWires = [] - - #Revolve the wires, make a compound out of them and then fuse them - toFuse = [] - for ws in wireSets: - thisObj = Solid.revolve(ws[0], ws[1:], angleDegrees, axisStart, axisEnd) - toFuse.append(thisObj) - - return Compound.makeCompound(toFuse) - - def _sweep(self, path, makeSolid=True, isFrenet=False): - """ - Makes a swept solid from an existing set of pending wires. - - :param path: A wire along which the pending wires will be swept - :return:a FreeCAD solid, suitable for boolean operations - """ - - # group wires together into faces based on which ones are inside the others - # result is a list of lists - s = time.time() - wireSets = sortWiresByBuildOrder(list(self.ctx.pendingWires), self.plane, []) - # print "sorted wires in %d sec" % ( time.time() - s ) - self.ctx.pendingWires = [] # now all of the wires have been used to create an extrusion - - toFuse = [] - for ws in wireSets: - thisObj = Solid.sweep(ws[0], ws[1:], path.val(), makeSolid, isFrenet) - toFuse.append(thisObj) - - return Compound.makeCompound(toFuse) - - def box(self, length, width, height, centered=(True, True, True), combine=True, clean=True): - """ - Return a 3d box with specified dimensions for each object on the stack. - - :param length: box size in X direction - :type length: float > 0 - :param width: box size in Y direction - :type width: float > 0 - :param height: box size in Z direction - :type height: float > 0 - :param centered: should the box be centered, or should reference point be at the lower - bound of the range? - :param combine: should the results be combined with other solids on the stack - (and each other)? - :type combine: true to combine shapes, false otherwise. - :param boolean clean: call :py:meth:`clean` afterwards to have a clean shape - - Centered is a tuple that describes whether the box should be centered on the x,y, and - z axes. If true, the box is centered on the respective axis relative to the workplane - origin, if false, the workplane center will represent the lower bound of the resulting box - - one box is created for each item on the current stack. If no items are on the stack, one box - using the current workplane center is created. - - If combine is true, the result will be a single object on the stack: - if a solid was found in the chain, the result is that solid with all boxes produced - fused onto it otherwise, the result is the combination of all the produced boxes - - if combine is false, the result will be a list of the boxes produced - - Most often boxes form the basis for a part:: - - #make a single box with lower left corner at origin - s = Workplane().box(1,2,3,centered=(False,False,False) - - But sometimes it is useful to create an array of them: - - #create 4 small square bumps on a larger base plate: - s = Workplane().box(4,4,0.5).faces(">Z").workplane()\ - .rect(3,3,forConstruction=True).vertices().box(0.25,0.25,0.25,combine=True) - - """ - - def _makebox(pnt): - - #(xp,yp,zp) = self.plane.toLocalCoords(pnt) - (xp, yp, zp) = pnt.toTuple() - if centered[0]: - xp -= (length / 2.0) - if centered[1]: - yp -= (width / 2.0) - if centered[2]: - zp -= (height / 2.0) - - return Solid.makeBox(length, width, height, Vector(xp, yp, zp)) - - boxes = self.eachpoint(_makebox, True) - - #if combination is not desired, just return the created boxes - if not combine: - return boxes - else: - #combine everything - return self.union(boxes, clean=clean) - - def sphere(self, radius, direct=(0, 0, 1), angle1=-90, angle2=90, angle3=360, - centered=(True, True, True), combine=True, clean=True): - """ - Returns a 3D sphere with the specified radius for each point on the stack - - :param radius: The radius of the sphere - :type radius: float > 0 - :param direct: The direction axis for the creation of the sphere - :type direct: A three-tuple - :param angle1: The first angle to sweep the sphere arc through - :type angle1: float > 0 - :param angle2: The second angle to sweep the sphere arc through - :type angle2: float > 0 - :param angle3: The third angle to sweep the sphere arc through - :type angle3: float > 0 - :param centered: A three-tuple of booleans that determines whether the sphere is centered - on each axis origin - :param combine: Whether the results should be combined with other solids on the stack - (and each other) - :type combine: true to combine shapes, false otherwise - :return: A sphere object for each point on the stack - - Centered is a tuple that describes whether the sphere should be centered on the x,y, and - z axes. If true, the sphere is centered on the respective axis relative to the workplane - origin, if false, the workplane center will represent the lower bound of the resulting - sphere. - - One sphere is created for each item on the current stack. If no items are on the stack, one - box using the current workplane center is created. - - If combine is true, the result will be a single object on the stack: - If a solid was found in the chain, the result is that solid with all spheres produced - fused onto it otherwise, the result is the combination of all the produced boxes - - If combine is false, the result will be a list of the spheres produced - """ - - # Convert the direction tuple to a vector, if needed - if isinstance(direct, tuple): - direct = Vector(direct) - - def _makesphere(pnt): - """ - Inner function that is used to create a sphere for each point/object on the workplane - :param pnt: The center point for the sphere - :return: A CQ Solid object representing a sphere - """ - (xp, yp, zp) = pnt.toTuple() - - if not centered[0]: - xp += radius - - if not centered[1]: - yp += radius - - if not centered[2]: - zp += radius - - return Solid.makeSphere(radius, Vector(xp, yp, zp), direct, angle1, angle2, angle3) - - # We want a sphere for each point on the workplane - spheres = self.eachpoint(_makesphere, True) - - # If we don't need to combine everything, just return the created spheres - if not combine: - return spheres - else: - return self.union(spheres, clean=clean) - - def clean(self): - """ - Cleans the current solid by removing unwanted edges from the - faces. - - Normally you don't have to call this function. It is - automatically called after each related operation. You can - disable this behavior with `clean=False` parameter if method - has any. In some cases this can improve performance - drastically but is generally dis-advised since it may break - some operations such as fillet. - - Note that in some cases where lots of solid operations are - chained, `clean()` may actually improve performance since - the shape is 'simplified' at each step and thus next operation - is easier. - - Also note that, due to limitation of the underlying engine, - `clean` may fail to produce a clean output in some cases such as - spherical faces. - """ - try: - cleanObjects = [obj.clean() for obj in self.objects] - except AttributeError: - raise AttributeError("%s object doesn't support `clean()` method!" % obj.ShapeType()) - return self.newObject(cleanObjects) diff --git a/Libs/cadquery-lib/cadquery/cq_directive.py b/Libs/cadquery-lib/cadquery/cq_directive.py deleted file mode 100644 index 0dc5fae..0000000 --- a/Libs/cadquery-lib/cadquery/cq_directive.py +++ /dev/null @@ -1,85 +0,0 @@ -""" -A special directive for including a cq object. - -""" - -import traceback -from cadquery import * -from cadquery import cqgi -import StringIO -from docutils.parsers.rst import directives - -template = """ - -.. raw:: html - -
- %(out_svg)s -
-
-
- -""" -template_content_indent = ' ' - - -def cq_directive(name, arguments, options, content, lineno, - content_offset, block_text, state, state_machine): - # only consider inline snippets - plot_code = '\n'.join(content) - - # Since we don't have a filename, use a hash based on the content - # the script must define a variable called 'out', which is expected to - # be a CQ object - out_svg = "Your Script Did not assign call build_output() function!" - - try: - _s = StringIO.StringIO() - result = cqgi.parse(plot_code).build() - - if result.success: - exporters.exportShape(result.first_result, "SVG", _s) - out_svg = _s.getvalue() - else: - raise result.exception - - except Exception: - traceback.print_exc() - out_svg = traceback.format_exc() - - # now out - # Now start generating the lines of output - lines = [] - - # get rid of new lines - out_svg = out_svg.replace('\n', '') - - txt_align = "left" - if "align" in options: - txt_align = options['align'] - - lines.extend((template % locals()).split('\n')) - - lines.extend(['::', '']) - lines.extend([' %s' % row.rstrip() - for row in plot_code.split('\n')]) - lines.append('') - - if len(lines): - state_machine.insert_input( - lines, state_machine.input_lines.source(0)) - - return [] - - -def setup(app): - setup.app = app - setup.config = app.config - setup.confdir = app.confdir - - options = {'height': directives.length_or_unitless, - 'width': directives.length_or_percentage_or_unitless, - 'align': directives.unchanged - } - - app.add_directive('cq_plot', cq_directive, True, (0, 2, 0), **options) diff --git a/Libs/cadquery-lib/cadquery/cqgi.py b/Libs/cadquery-lib/cadquery/cqgi.py deleted file mode 100644 index d654d72..0000000 --- a/Libs/cadquery-lib/cadquery/cqgi.py +++ /dev/null @@ -1,477 +0,0 @@ -""" -The CadQuery Gateway Interface. -Provides classes and tools for executing CadQuery scripts -""" -import ast -import traceback -import time -import cadquery - -CQSCRIPT = "" - -def parse(script_source): - """ - Parses the script as a model, and returns a model. - - If you would prefer to access the underlying model without building it, - for example, to inspect its available parameters, construct a CQModel object. - - :param script_source: the script to run. Must be a valid cadquery script - :return: a CQModel object that defines the script and allows execution - - """ - model = CQModel(script_source) - return model - - -class CQModel(object): - """ - Represents a Cadquery Script. - - After construction, the metadata property contains - a ScriptMetaData object, which describes the model in more detail, - and can be used to retrive the parameters defined by the model. - - the build method can be used to generate a 3d model - """ - def __init__(self, script_source): - """ - Create an object by parsing the supplied python script. - :param script_source: a python script to parse - """ - self.metadata = ScriptMetadata() - self.ast_tree = ast.parse(script_source, CQSCRIPT) - self.script_source = script_source - self._find_vars() - - # TODO: pick up other scirpt metadata: - # describe - # pick up validation methods - self._find_descriptions() - - def _find_vars(self): - """ - Parse the script, and populate variables that appear to be - overridable. - """ - #assumption here: we assume that variable declarations - #are only at the top level of the script. IE, we'll ignore any - #variable definitions at lower levels of the script - - #we dont want to use the visit interface because here we excplicitly - #want to walk only the top level of the tree. - assignment_finder = ConstantAssignmentFinder(self.metadata) - - for node in self.ast_tree.body: - if isinstance(node, ast.Assign): - assignment_finder.visit_Assign(node) - - def _find_descriptions(self): - description_finder = ParameterDescriptionFinder(self.metadata) - description_finder.visit(self.ast_tree) - - def validate(self, params): - """ - Determine if the supplied parameters are valid. - NOT IMPLEMENTED YET-- raises NotImplementedError - :param params: a dictionary of parameters - - """ - raise NotImplementedError("not yet implemented") - - def build(self, build_parameters=None, build_options=None): - """ - Executes the script, using the optional parameters to override those in the model - :param build_parameters: a dictionary of variables. The variables must be - assignable to the underlying variable type. These variables override default values in the script - :param build_options: build options for how to build the model. Build options include things like - timeouts, tesselation tolerances, etc - :raises: Nothing. If there is an exception, it will be on the exception property of the result. - This is the interface so that we can return other information on the result, such as the build time - :return: a BuildResult object, which includes the status of the result, and either - a resulting shape or an exception - """ - if not build_parameters: - build_parameters = {} - - start = time.clock() - result = BuildResult() - - try: - self.set_param_values(build_parameters) - collector = ScriptCallback() - env = EnvironmentBuilder().with_real_builtins().with_cadquery_objects() \ - .add_entry("build_object", collector.build_object) \ - .add_entry("debug", collector.debug) \ - .add_entry("describe_parameter",collector.describe_parameter) \ - .build() - - c = compile(self.ast_tree, CQSCRIPT, 'exec') - exec (c, env) - result.set_debug(collector.debugObjects ) - result.set_success_result(collector.outputObjects) - - except Exception, ex: - #print "Error Executing Script:" - result.set_failure_result(ex) - #traceback.print_exc() - #print "Full Text of Script:" - #print self.script_source - - end = time.clock() - result.buildTime = end - start - return result - - def set_param_values(self, params): - model_parameters = self.metadata.parameters - - for k, v in params.iteritems(): - if k not in model_parameters: - raise InvalidParameterError("Cannot set value '%s': not a parameter of the model." % k) - - p = model_parameters[k] - p.set_value(v) - - -class ShapeResult(object): - """ - An object created by a build, including the user parameters provided - """ - def __init__(self): - self.shape = None - self.options = None - -class BuildResult(object): - """ - The result of executing a CadQuery script. - The success property contains whether the exeuction was successful. - - If successful, the results property contains a list of all results, - and the first_result property contains the first result. - - If unsuccessful, the exception property contains a reference to - the stack trace that occurred. - """ - def __init__(self): - self.buildTime = None - self.results = [] #list of ShapeResult - self.debugObjects = [] #list of ShapeResult - self.first_result = None - self.success = False - self.exception = None - - def set_failure_result(self, ex): - self.exception = ex - self.success = False - - def set_debug(self, debugObjects): - self.debugObjects = debugObjects - - def set_success_result(self, results): - self.results = results - if len(self.results) > 0: - self.first_result = self.results[0] - self.success = True - - -class ScriptMetadata(object): - """ - Defines the metadata for a parsed CQ Script. - the parameters property is a dict of InputParameter objects. - """ - def __init__(self): - self.parameters = {} - - def add_script_parameter(self, p): - self.parameters[p.name] = p - - def add_parameter_description(self,name,description): - #print 'Adding Parameter name=%s, desc=%s' % ( name, description ) - p = self.parameters[name] - p.desc = description - - -class ParameterType(object): - pass - - -class NumberParameterType(ParameterType): - pass - - -class StringParameterType(ParameterType): - pass - - -class BooleanParameterType(ParameterType): - pass - - -class InputParameter: - """ - Defines a parameter that can be supplied when the model is executed. - - Name, varType, and default_value are always available, because they are computed - from a variable assignment line of code: - - The others are only available if the script has used define_parameter() to - provide additional metadata - - """ - def __init__(self): - - #: the default value for the variable. - self.default_value = None - - #: the name of the parameter. - self.name = None - - #: type of the variable: BooleanParameter, StringParameter, NumericParameter - self.varType = None - - #: help text describing the variable. Only available if the script used describe_parameter() - self.desc = None - - #: valid values for the variable. Only available if the script used describe_parameter() - self.valid_values = [] - - self.ast_node = None - - @staticmethod - def create(ast_node, var_name, var_type, default_value, valid_values=None, desc=None): - - if valid_values is None: - valid_values = [] - - p = InputParameter() - p.ast_node = ast_node - p.default_value = default_value - p.name = var_name - p.desc = desc - p.varType = var_type - p.valid_values = valid_values - return p - - def set_value(self, new_value): - - if len(self.valid_values) > 0 and new_value not in self.valid_values: - raise InvalidParameterError( - "Cannot set value '{0:s}' for parameter '{1:s}': not a valid value. Valid values are {2:s} " - .format(str(new_value), self.name, str(self.valid_values))) - - if self.varType == NumberParameterType: - try: - f = float(new_value) - self.ast_node.n = f - except ValueError: - raise InvalidParameterError( - "Cannot set value '{0:s}' for parameter '{1:s}': parameter must be numeric." - .format(str(new_value), self.name)) - - elif self.varType == StringParameterType: - self.ast_node.s = str(new_value) - elif self.varType == BooleanParameterType: - if new_value: - self.ast_node.id = 'True' - else: - self.ast_node.id = 'False' - else: - raise ValueError("Unknown Type of var: ", str(self.varType)) - - def __str__(self): - return "InputParameter: {name=%s, type=%s, defaultValue=%s" % ( - self.name, str(self.varType), str(self.default_value)) - - -class ScriptCallback(object): - """ - Allows a script to communicate with the container - the build_object() method is exposed to CQ scripts, to allow them - to return objects to the execution environment - """ - def __init__(self): - self.outputObjects = [] - self.debugObjects = [] - - def build_object(self, shape,options={}): - """ - return an object to the executing environment, with options - :param shape: a cadquery object - :param options: a dictionary of options that will be made available to the executing envrionment - """ - o = ShapeResult() - o.options=options - o.shape = shape - self.outputObjects.append(o) - - def debug(self,obj,args={}): - """ - Debug print/output an object, with optional arguments. - """ - s = ShapeResult() - s.shape = obj - s.options = args - self.debugObjects.append(s) - - def describe_parameter(self,var_data ): - """ - Do Nothing-- we parsed the ast ahead of exection to get what we need. - """ - pass - - def add_error(self, param, field_list): - """ - Not implemented yet: allows scripts to indicate that there are problems with inputs - """ - pass - - def has_results(self): - return len(self.outputObjects) > 0 - - - -class InvalidParameterError(Exception): - """ - Raised when an attempt is made to provide a new parameter value - that cannot be assigned to the model - """ - pass - - -class NoOutputError(Exception): - """ - Raised when the script does not execute the build_object() method to - return a solid - """ - pass - - -class ScriptExecutionError(Exception): - """ - Represents a script syntax error. - Useful for helping clients pinpoint issues with the script - interactively - """ - - def __init__(self, line=None, message=None): - if line is None: - self.line = 0 - else: - self.line = line - - if message is None: - self.message = "Unknown Script Error" - else: - self.message = message - - def full_message(self): - return self.__repr__() - - def __str__(self): - return self.__repr__() - - def __repr__(self): - return "ScriptError [Line %s]: %s" % (self.line, self.message) - - -class EnvironmentBuilder(object): - """ - Builds an execution environment for a cadquery script. - The environment includes the builtins, as well as - the other methods the script will need. - """ - def __init__(self): - self.env = {} - - def with_real_builtins(self): - return self.with_builtins(__builtins__) - - def with_builtins(self, env_dict): - self.env['__builtins__'] = env_dict - return self - - def with_cadquery_objects(self): - self.env['cadquery'] = cadquery - self.env['cq'] = cadquery - return self - - def add_entry(self, name, value): - self.env[name] = value - return self - - def build(self): - return self.env - -class ParameterDescriptionFinder(ast.NodeTransformer): - """ - Visits a parse tree, looking for function calls to describe_parameter(var, description ) - """ - def __init__(self, cq_model): - self.cqModel = cq_model - - def visit_Call(self,node): - """ - Called when we see a function call. Is it describe_parameter? - """ - try: - if node.func.id == 'describe_parameter': - #looks like we have a call to our function. - #first parameter is the variable, - #second is the description - varname = node.args[0].id - desc = node.args[1].s - self.cqModel.add_parameter_description(varname,desc) - - except: - #print "Unable to handle function call" - pass - return node - -class ConstantAssignmentFinder(ast.NodeTransformer): - """ - Visits a parse tree, and adds script parameters to the cqModel - """ - - def __init__(self, cq_model): - self.cqModel = cq_model - - def handle_assignment(self, var_name, value_node): - try: - - if type(value_node) == ast.Num: - self.cqModel.add_script_parameter( - InputParameter.create(value_node, var_name, NumberParameterType, value_node.n)) - elif type(value_node) == ast.Str: - self.cqModel.add_script_parameter( - InputParameter.create(value_node, var_name, StringParameterType, value_node.s)) - elif type(value_node == ast.Name): - if value_node.id == 'True': - self.cqModel.add_script_parameter( - InputParameter.create(value_node, var_name, BooleanParameterType, True)) - elif value_node.id == 'False': - self.cqModel.add_script_parameter( - InputParameter.create(value_node, var_name, BooleanParameterType, True)) - except: - print "Unable to handle assignment for variable '%s'" % var_name - pass - - def visit_Assign(self, node): - - try: - left_side = node.targets[0] - - #do not handle attribute assignments - if isinstance(left_side,ast.Attribute): - return - - if type(node.value) in [ast.Num, ast.Str, ast.Name]: - self.handle_assignment(left_side.id, node.value) - elif type(node.value) == ast.Tuple: - # we have a multi-value assignment - for n, v in zip(left_side.elts, node.value.elts): - self.handle_assignment(n.id, v) - except: - traceback.print_exc() - print "Unable to handle assignment for node '%s'" % ast.dump(left_side) - - return node diff --git a/Libs/cadquery-lib/cadquery/freecad_impl/README.txt b/Libs/cadquery-lib/cadquery/freecad_impl/README.txt deleted file mode 100644 index 34ea788..0000000 --- a/Libs/cadquery-lib/cadquery/freecad_impl/README.txt +++ /dev/null @@ -1,3 +0,0 @@ -It is ok for files in this directory to import FreeCAD, FreeCAD.Base, and FreeCAD.Part. - -Other modules should _not_ depend on FreeCAD \ No newline at end of file diff --git a/Libs/cadquery-lib/cadquery/freecad_impl/__init__.py b/Libs/cadquery-lib/cadquery/freecad_impl/__init__.py deleted file mode 100644 index 3a82a2f..0000000 --- a/Libs/cadquery-lib/cadquery/freecad_impl/__init__.py +++ /dev/null @@ -1,107 +0,0 @@ -""" - Copyright (C) 2011-2015 Parametric Products Intellectual Holdings, LLC - - This file is part of CadQuery. - - CadQuery is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - CadQuery 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; If not, see -""" -import os -import sys - - -def _fc_path(): - """Find FreeCAD""" - # Look for FREECAD_LIB env variable - _PATH = os.environ.get('FREECAD_LIB', '') - if _PATH and os.path.exists(_PATH): - return _PATH - - if sys.platform.startswith('linux'): - # Make some dangerous assumptions... - for _PATH in [ - os.path.join(os.path.expanduser("~"), "lib/freecad/lib"), - "/usr/local/lib/freecad/lib", - "/usr/lib/freecad/lib", - "/opt/freecad/lib/", - "/usr/bin/freecad/lib", - "/usr/lib/freecad-daily/lib", - "/usr/lib/freecad", - "/usr/lib64/freecad/lib", - ]: - if os.path.exists(_PATH): - return _PATH - - elif sys.platform.startswith('win'): - # Try all the usual suspects - for _PATH in [ - "c:/Program Files/FreeCAD0.12/bin", - "c:/Program Files/FreeCAD0.13/bin", - "c:/Program Files/FreeCAD0.14/bin", - "c:/Program Files/FreeCAD0.15/bin", - "c:/Program Files/FreeCAD0.16/bin", - "c:/Program Files/FreeCAD0.17/bin", - "c:/Program Files (x86)/FreeCAD0.12/bin", - "c:/Program Files (x86)/FreeCAD0.13/bin", - "c:/Program Files (x86)/FreeCAD0.14/bin", - "c:/Program Files (x86)/FreeCAD0.15/bin", - "c:/Program Files (x86)/FreeCAD0.16/bin", - "c:/Program Files (x86)/FreeCAD0.17/bin", - "c:/apps/FreeCAD0.12/bin", - "c:/apps/FreeCAD0.13/bin", - "c:/apps/FreeCAD0.14/bin", - "c:/apps/FreeCAD0.15/bin", - "c:/apps/FreeCAD0.16/bin", - "c:/apps/FreeCAD0.17/bin", - "c:/Program Files/FreeCAD 0.12/bin", - "c:/Program Files/FreeCAD 0.13/bin", - "c:/Program Files/FreeCAD 0.14/bin", - "c:/Program Files/FreeCAD 0.15/bin", - "c:/Program Files/FreeCAD 0.16/bin", - "c:/Program Files/FreeCAD 0.17/bin", - "c:/Program Files (x86)/FreeCAD 0.12/bin", - "c:/Program Files (x86)/FreeCAD 0.13/bin", - "c:/Program Files (x86)/FreeCAD 0.14/bin", - "c:/Program Files (x86)/FreeCAD 0.15/bin", - "c:/Program Files (x86)/FreeCAD 0.16/bin", - "c:/Program Files (x86)/FreeCAD 0.17/bin", - "c:/apps/FreeCAD 0.12/bin", - "c:/apps/FreeCAD 0.13/bin", - "c:/apps/FreeCAD 0.14/bin", - "c:/apps/FreeCAD 0.15/bin", - "c:/apps/FreeCAD 0.16/bin", - "c:/apps/FreeCAD 0.17/bin", - ]: - if os.path.exists(_PATH): - return _PATH - - elif sys.platform.startswith('darwin'): - # Assume we're dealing with a Mac - for _PATH in [ - "/Applications/FreeCAD.app/Contents/lib", - os.path.join(os.path.expanduser("~"), - "Library/Application Support/FreeCAD/lib"), - ]: - if os.path.exists(_PATH): - return _PATH - - raise ImportError('cadquery was unable to determine freecad library path') - - -# Make sure that the correct FreeCAD path shows up in Python's system path -try: - import FreeCAD -except ImportError: - path = _fc_path() - sys.path.insert(0, path) - import FreeCAD diff --git a/Libs/cadquery-lib/cadquery/freecad_impl/exporters.py b/Libs/cadquery-lib/cadquery/freecad_impl/exporters.py deleted file mode 100644 index c4b097a..0000000 --- a/Libs/cadquery-lib/cadquery/freecad_impl/exporters.py +++ /dev/null @@ -1,392 +0,0 @@ -import cadquery - -import FreeCAD -import Drawing - -import tempfile, os, StringIO - - -try: - import xml.etree.cElementTree as ET -except ImportError: - import xml.etree.ElementTree as ET - - -class ExportTypes: - STL = "STL" - STEP = "STEP" - AMF = "AMF" - SVG = "SVG" - TJS = "TJS" - - -class UNITS: - MM = "mm" - IN = "in" - - -def toString(shape, exportType, tolerance=0.1): - s = StringIO.StringIO() - exportShape(shape, exportType, s, tolerance) - return s.getvalue() - - -def exportShape(shape,exportType,fileLike,tolerance=0.1): - """ - :param shape: the shape to export. it can be a shape object, or a cadquery object. If a cadquery - object, the first value is exported - :param exportFormat: the exportFormat to use - :param tolerance: the tolerance, in model units - :param fileLike: a file like object to which the content will be written. - The object should be already open and ready to write. The caller is responsible - for closing the object - """ - - - if isinstance(shape,cadquery.CQ): - shape = shape.val() - - if exportType == ExportTypes.TJS: - #tessellate the model - tess = shape.tessellate(tolerance) - - mesher = JsonMesh() #warning: needs to be changed to remove buildTime and exportTime!!! - #add vertices - for vec in tess[0]: - mesher.addVertex(vec.x, vec.y, vec.z) - - #add faces - for f in tess[1]: - mesher.addTriangleFace(f[0],f[1], f[2]) - fileLike.write( mesher.toJson()) - elif exportType == ExportTypes.SVG: - fileLike.write(getSVG(shape.wrapped)) - elif exportType == ExportTypes.AMF: - tess = shape.tessellate(tolerance) - aw = AmfWriter(tess).writeAmf(fileLike) - else: - - #all these types required writing to a file and then - #re-reading. this is due to the fact that FreeCAD writes these - (h, outFileName) = tempfile.mkstemp() - #weird, but we need to close this file. the next step is going to write to - #it from c code, so it needs to be closed. - os.close(h) - - if exportType == ExportTypes.STEP: - shape.exportStep(outFileName) - elif exportType == ExportTypes.STL: - shape.wrapped.exportStl(outFileName) - else: - raise ValueError("No idea how i got here") - - res = readAndDeleteFile(outFileName) - fileLike.write(res) - -def readAndDeleteFile(fileName): - """ - read data from file provided, and delete it when done - return the contents as a string - """ - res = "" - with open(fileName,'r') as f: - res = f.read() - - os.remove(fileName) - return res - - -def guessUnitOfMeasure(shape): - """ - Guess the unit of measure of a shape. - """ - bb = shape.BoundBox - - dimList = [ bb.XLength, bb.YLength,bb.ZLength ] - #no real part would likely be bigger than 10 inches on any side - if max(dimList) > 10: - return UNITS.MM - - #no real part would likely be smaller than 0.1 mm on all dimensions - if min(dimList) < 0.1: - return UNITS.IN - - #no real part would have the sum of its dimensions less than about 5mm - if sum(dimList) < 10: - return UNITS.IN - - return UNITS.MM - - -class AmfWriter(object): - def __init__(self,tessellation): - - self.units = "mm" - self.tessellation = tessellation - - def writeAmf(self,outFile): - amf = ET.Element('amf',units=self.units) - #TODO: if result is a compound, we need to loop through them - object = ET.SubElement(amf,'object',id="0") - mesh = ET.SubElement(object,'mesh') - vertices = ET.SubElement(mesh,'vertices') - volume = ET.SubElement(mesh,'volume') - - #add vertices - for v in self.tessellation[0]: - vtx = ET.SubElement(vertices,'vertex') - coord = ET.SubElement(vtx,'coordinates') - x = ET.SubElement(coord,'x') - x.text = str(v.x) - y = ET.SubElement(coord,'y') - y.text = str(v.y) - z = ET.SubElement(coord,'z') - z.text = str(v.z) - - #add triangles - for t in self.tessellation[1]: - triangle = ET.SubElement(volume,'triangle') - v1 = ET.SubElement(triangle,'v1') - v1.text = str(t[0]) - v2 = ET.SubElement(triangle,'v2') - v2.text = str(t[1]) - v3 = ET.SubElement(triangle,'v3') - v3.text = str(t[2]) - - - ET.ElementTree(amf).write(outFile,encoding='ISO-8859-1') - -""" - Objects that represent - three.js JSON object notation - https://github.com/mrdoob/three.js/wiki/JSON-Model-format-3.0 -""" -class JsonMesh(object): - def __init__(self): - - self.vertices = []; - self.faces = []; - self.nVertices = 0; - self.nFaces = 0; - - def addVertex(self,x,y,z): - self.nVertices += 1; - self.vertices.extend([x,y,z]); - - #add triangle composed of the three provided vertex indices - def addTriangleFace(self, i,j,k): - #first position means justa simple triangle - self.nFaces += 1; - self.faces.extend([0,int(i),int(j),int(k)]); - - """ - Get a json model from this model. - For now we'll forget about colors, vertex normals, and all that stuff - """ - def toJson(self): - return JSON_TEMPLATE % { - 'vertices' : str(self.vertices), - 'faces' : str(self.faces), - 'nVertices': self.nVertices, - 'nFaces' : self.nFaces - }; - - -def getPaths(freeCadSVG): - """ - freeCad svg is worthless-- except for paths, which are fairly useful - this method accepts svg from fReeCAD and returns a list of strings suitable for inclusion in a path element - returns two lists-- one list of visible lines, and one list of hidden lines - - HACK ALERT!!!!! - FreeCAD does not give a way to determine which lines are hidden and which are not - the only way to tell is that hidden lines are in a with 0.15 stroke and visible are 0.35 stroke. - so we actually look for that as a way to parse. - - to make it worse, elementTree xpath attribute selectors do not work in python 2.6, and we - cannot use python 2.7 due to freecad. So its necessary to look for the pure strings! ick! - """ - - hiddenPaths = [] - visiblePaths = [] - if len(freeCadSVG) > 0: - #yuk, freecad returns svg fragments. stupid stupid - fullDoc = "%s" % freeCadSVG - e = ET.ElementTree(ET.fromstring(fullDoc)) - segments = e.findall(".//g") - for s in segments: - paths = s.findall("path") - - if s.get("stroke-width") == "0.15": #hidden line HACK HACK HACK - mylist = hiddenPaths - else: - mylist = visiblePaths - - for p in paths: - mylist.append(p.get("d")) - return (hiddenPaths,visiblePaths) - else: - return ([],[]) - - -def getSVG(shape,opts=None): - """ - Export a shape to SVG - """ - - d = {'width':800,'height':240,'marginLeft':200,'marginTop':20} - - if opts: - d.update(opts) - - #need to guess the scale and the coordinate center - uom = guessUnitOfMeasure(shape) - - width=float(d['width']) - height=float(d['height']) - marginLeft=float(d['marginLeft']) - marginTop=float(d['marginTop']) - - #TODO: provide option to give 3 views - viewVector = FreeCAD.Base.Vector(-1.75,1.1,5) - (visibleG0,visibleG1,hiddenG0,hiddenG1) = Drawing.project(shape,viewVector) - - (hiddenPaths,visiblePaths) = getPaths(Drawing.projectToSVG(shape,viewVector,"ShowHiddenLines")) #this param is totally undocumented! - - #get bounding box -- these are all in 2-d space - bb = visibleG0.BoundBox - bb.add(visibleG1.BoundBox) - bb.add(hiddenG0.BoundBox) - bb.add(hiddenG1.BoundBox) - - #width pixels for x, height pixesl for y - unitScale = min( width / bb.XLength * 0.75 , height / bb.YLength * 0.75 ) - - #compute amount to translate-- move the top left into view - (xTranslate,yTranslate) = ( (0 - bb.XMin) + marginLeft/unitScale ,(0- bb.YMax) - marginTop/unitScale) - - #compute paths ( again -- had to strip out freecad crap ) - hiddenContent = "" - for p in hiddenPaths: - hiddenContent += PATHTEMPLATE % p - - visibleContent = "" - for p in visiblePaths: - visibleContent += PATHTEMPLATE % p - - svg = SVG_TEMPLATE % ( - { - "unitScale" : str(unitScale), - "strokeWidth" : str(1.0/unitScale), - "hiddenContent" : hiddenContent , - "visibleContent" :visibleContent, - "xTranslate" : str(xTranslate), - "yTranslate" : str(yTranslate), - "width" : str(width), - "height" : str(height), - "textboxY" :str(height - 30), - "uom" : str(uom) - } - ) - #svg = SVG_TEMPLATE % ( - # {"content": projectedContent} - #) - return svg - - -def exportSVG(shape, fileName): - """ - accept a cadquery shape, and export it to the provided file - TODO: should use file-like objects, not a fileName, and/or be able to return a string instead - export a view of a part to svg - """ - - svg = getSVG(shape.val().wrapped) - f = open(fileName,'w') - f.write(svg) - f.close() - - - -JSON_TEMPLATE= """\ -{ - "metadata" : - { - "formatVersion" : 3, - "generatedBy" : "ParametricParts", - "vertices" : %(nVertices)d, - "faces" : %(nFaces)d, - "normals" : 0, - "colors" : 0, - "uvs" : 0, - "materials" : 1, - "morphTargets" : 0 - }, - - "scale" : 1.0, - - "materials": [ { - "DbgColor" : 15658734, - "DbgIndex" : 0, - "DbgName" : "Material", - "colorAmbient" : [0.0, 0.0, 0.0], - "colorDiffuse" : [0.6400000190734865, 0.10179081114814892, 0.126246120426746], - "colorSpecular" : [0.5, 0.5, 0.5], - "shading" : "Lambert", - "specularCoef" : 50, - "transparency" : 1.0, - "vertexColors" : false - }], - - "vertices": %(vertices)s, - - "morphTargets": [], - - "normals": [], - - "colors": [], - - "uvs": [[]], - - "faces": %(faces)s -} -""" - -SVG_TEMPLATE = """ - - - - -%(hiddenContent)s - - - - -%(visibleContent)s - - - - - X - - - Y - - - Z - - - -""" - -PATHTEMPLATE="\t\t\t\n" - diff --git a/Libs/cadquery-lib/cadquery/freecad_impl/geom.py b/Libs/cadquery-lib/cadquery/freecad_impl/geom.py deleted file mode 100644 index 2bd8c3a..0000000 --- a/Libs/cadquery-lib/cadquery/freecad_impl/geom.py +++ /dev/null @@ -1,647 +0,0 @@ -""" - Copyright (C) 2011-2015 Parametric Products Intellectual Holdings, LLC - - This file is part of CadQuery. - - CadQuery is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - CadQuery 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; If not, see -""" - -import math -import cadquery -import FreeCAD -import Part as FreeCADPart - - -def sortWiresByBuildOrder(wireList, plane, result=[]): - """Tries to determine how wires should be combined into faces. - - Assume: - The wires make up one or more faces, which could have 'holes' - Outer wires are listed ahead of inner wires - there are no wires inside wires inside wires - ( IE, islands -- we can deal with that later on ) - none of the wires are construction wires - - Compute: - one or more sets of wires, with the outer wire listed first, and inner - ones - - Returns, list of lists. - """ - result = [] - - remainingWires = list(wireList) - while remainingWires: - outerWire = remainingWires.pop(0) - group = [outerWire] - otherWires = list(remainingWires) - for w in otherWires: - if plane.isWireInside(outerWire, w): - group.append(w) - remainingWires.remove(w) - result.append(group) - - return result - - -class Vector(object): - """Create a 3-dimensional vector - - :param args: a 3-d vector, with x-y-z parts. - - you can either provide: - * nothing (in which case the null vector is return) - * a FreeCAD vector - * a vector ( in which case it is copied ) - * a 3-tuple - * three float values, x, y, and z - """ - def __init__(self, *args): - if len(args) == 3: - fV = FreeCAD.Base.Vector(args[0], args[1], args[2]) - elif len(args) == 1: - if isinstance(args[0], Vector): - fV = args[0].wrapped - elif isinstance(args[0], tuple): - fV = FreeCAD.Base.Vector(args[0][0], args[0][1], args[0][2]) - elif isinstance(args[0], FreeCAD.Base.Vector): - fV = args[0] - else: - fV = args[0] - elif len(args) == 0: - fV = FreeCAD.Base.Vector(0, 0, 0) - else: - raise ValueError("Expected three floats, FreeCAD Vector, or 3-tuple") - - self._wrapped = fV - - @property - def x(self): - return self.wrapped.x - - @property - def y(self): - return self.wrapped.y - - @property - def z(self): - return self.wrapped.z - - @property - def Length(self): - return self.wrapped.Length - - @property - def wrapped(self): - return self._wrapped - - def toTuple(self): - return (self.x, self.y, self.z) - - # TODO: is it possible to create a dynamic proxy without all this code? - def cross(self, v): - return Vector(self.wrapped.cross(v.wrapped)) - - def dot(self, v): - return self.wrapped.dot(v.wrapped) - - def sub(self, v): - return Vector(self.wrapped.sub(v.wrapped)) - - def add(self, v): - return Vector(self.wrapped.add(v.wrapped)) - - def multiply(self, scale): - """Return a copy multiplied by the provided scalar""" - tmp_fc_vector = FreeCAD.Base.Vector(self.wrapped) - return Vector(tmp_fc_vector.multiply(scale)) - - def normalized(self): - """Return a normalized version of this vector""" - tmp_fc_vector = FreeCAD.Base.Vector(self.wrapped) - tmp_fc_vector.normalize() - return Vector(tmp_fc_vector) - - def Center(self): - """Return the vector itself - - The center of myself is myself. - Provided so that vectors, vertexes, and other shapes all support a - common interface, when Center() is requested for all objects on the - stack. - """ - return self - - def getAngle(self, v): - return self.wrapped.getAngle(v.wrapped) - - def distanceToLine(self): - raise NotImplementedError("Have not needed this yet, but FreeCAD supports it!") - - def projectToLine(self): - raise NotImplementedError("Have not needed this yet, but FreeCAD supports it!") - - def distanceToPlane(self): - raise NotImplementedError("Have not needed this yet, but FreeCAD supports it!") - - def projectToPlane(self): - raise NotImplementedError("Have not needed this yet, but FreeCAD supports it!") - - def __add__(self, v): - return self.add(v) - - def __repr__(self): - return self.wrapped.__repr__() - - def __str__(self): - return self.wrapped.__str__() - - def __ne__(self, other): - return self.wrapped.__ne__(other) - - def __eq__(self, other): - return self.wrapped.__eq__(other) - - -class Matrix: - """A 3d , 4x4 transformation matrix. - - Used to move geometry in space. - """ - def __init__(self, matrix=None): - if matrix is None: - self.wrapped = FreeCAD.Base.Matrix() - else: - self.wrapped = matrix - - def rotateX(self, angle): - self.wrapped.rotateX(angle) - - def rotateY(self, angle): - self.wrapped.rotateY(angle) - - -class Plane(object): - """A 2D coordinate system in space - - A 2D coordinate system in space, with the x-y axes on the plane, and a - particular point as the origin. - - A plane allows the use of 2-d coordinates, which are later converted to - global, 3d coordinates when the operations are complete. - - Frequently, it is not necessary to create work planes, as they can be - created automatically from faces. - """ - - @classmethod - def named(cls, stdName, origin=(0, 0, 0)): - """Create a predefined Plane based on the conventional names. - - :param stdName: one of (XY|YZ|ZX|XZ|YX|ZY|front|back|left|right|top|bottom) - :type stdName: string - :param origin: the desired origin, specified in global coordinates - :type origin: 3-tuple of the origin of the new plane, in global coorindates. - - Available named planes are as follows. Direction references refer to - the global directions. - - =========== ======= ======= ====== - Name xDir yDir zDir - =========== ======= ======= ====== - XY +x +y +z - YZ +y +z +x - ZX +z +x +y - XZ +x +z -y - YX +y +x -z - ZY +z +y -x - front +x +y +z - back -x +y -z - left +z +y -x - right -z +y +x - top +x -z +y - bottom +x +z -y - =========== ======= ======= ====== - """ - - namedPlanes = { - # origin, xDir, normal - 'XY': Plane(origin, (1, 0, 0), (0, 0, 1)), - 'YZ': Plane(origin, (0, 1, 0), (1, 0, 0)), - 'ZX': Plane(origin, (0, 0, 1), (0, 1, 0)), - 'XZ': Plane(origin, (1, 0, 0), (0, -1, 0)), - 'YX': Plane(origin, (0, 1, 0), (0, 0, -1)), - 'ZY': Plane(origin, (0, 0, 1), (-1, 0, 0)), - 'front': Plane(origin, (1, 0, 0), (0, 0, 1)), - 'back': Plane(origin, (-1, 0, 0), (0, 0, -1)), - 'left': Plane(origin, (0, 0, 1), (-1, 0, 0)), - 'right': Plane(origin, (0, 0, -1), (1, 0, 0)), - 'top': Plane(origin, (1, 0, 0), (0, 1, 0)), - 'bottom': Plane(origin, (1, 0, 0), (0, -1, 0)) - } - - try: - return namedPlanes[stdName] - except KeyError: - raise ValueError('Supported names are {}'.format( - namedPlanes.keys())) - - @classmethod - def XY(cls, origin=(0, 0, 0), xDir=Vector(1, 0, 0)): - plane = Plane.named('XY', origin) - plane._setPlaneDir(xDir) - return plane - - @classmethod - def YZ(cls, origin=(0, 0, 0), xDir=Vector(0, 1, 0)): - plane = Plane.named('YZ', origin) - plane._setPlaneDir(xDir) - return plane - - @classmethod - def ZX(cls, origin=(0, 0, 0), xDir=Vector(0, 0, 1)): - plane = Plane.named('ZX', origin) - plane._setPlaneDir(xDir) - return plane - - @classmethod - def XZ(cls, origin=(0, 0, 0), xDir=Vector(1, 0, 0)): - plane = Plane.named('XZ', origin) - plane._setPlaneDir(xDir) - return plane - - @classmethod - def YX(cls, origin=(0, 0, 0), xDir=Vector(0, 1, 0)): - plane = Plane.named('YX', origin) - plane._setPlaneDir(xDir) - return plane - - @classmethod - def ZY(cls, origin=(0, 0, 0), xDir=Vector(0, 0, 1)): - plane = Plane.named('ZY', origin) - plane._setPlaneDir(xDir) - return plane - - @classmethod - def front(cls, origin=(0, 0, 0), xDir=Vector(1, 0, 0)): - plane = Plane.named('front', origin) - plane._setPlaneDir(xDir) - return plane - - @classmethod - def back(cls, origin=(0, 0, 0), xDir=Vector(-1, 0, 0)): - plane = Plane.named('back', origin) - plane._setPlaneDir(xDir) - return plane - - @classmethod - def left(cls, origin=(0, 0, 0), xDir=Vector(0, 0, 1)): - plane = Plane.named('left', origin) - plane._setPlaneDir(xDir) - return plane - - @classmethod - def right(cls, origin=(0, 0, 0), xDir=Vector(0, 0, -1)): - plane = Plane.named('right', origin) - plane._setPlaneDir(xDir) - return plane - - @classmethod - def top(cls, origin=(0, 0, 0), xDir=Vector(1, 0, 0)): - plane = Plane.named('top', origin) - plane._setPlaneDir(xDir) - return plane - - @classmethod - def bottom(cls, origin=(0, 0, 0), xDir=Vector(1, 0, 0)): - plane = Plane.named('bottom', origin) - plane._setPlaneDir(xDir) - return plane - - def __init__(self, origin, xDir, normal): - """Create a Plane with an arbitrary orientation - - TODO: project x and y vectors so they work even if not orthogonal - :param origin: the origin - :type origin: a three-tuple of the origin, in global coordinates - :param xDir: a vector representing the xDirection. - :type xDir: a three-tuple representing a vector, or a FreeCAD Vector - :param normal: the normal direction for the new plane - :type normal: a FreeCAD Vector - :raises: ValueError if the specified xDir is not orthogonal to the provided normal. - :return: a plane in the global space, with the xDirection of the plane in the specified direction. - """ - normal = Vector(normal) - if (normal.Length == 0.0): - raise ValueError('normal should be non null') - self.zDir = normal.normalized() - xDir = Vector(xDir) - if (xDir.Length == 0.0): - raise ValueError('xDir should be non null') - self._setPlaneDir(xDir) - - self.invZDir = self.zDir.multiply(-1.0) - - self.origin = origin - - @property - def origin(self): - return self._origin - - @origin.setter - def origin(self, value): - self._origin = Vector(value) - self._calcTransforms() - - def setOrigin2d(self, x, y): - """ - Set a new origin in the plane itself - - Set a new origin in the plane itself. The plane's orientation and - xDrection are unaffected. - - :param float x: offset in the x direction - :param float y: offset in the y direction - :return: void - - The new coordinates are specified in terms of the current 2-d system. - As an example: - - p = Plane.XY() - p.setOrigin2d(2, 2) - p.setOrigin2d(2, 2) - - results in a plane with its origin at (x, y) = (4, 4) in global - coordinates. Both operations were relative to local coordinates of the - plane. - """ - self.origin = self.toWorldCoords((x, y)) - - def isWireInside(self, baseWire, testWire): - """Determine if testWire is inside baseWire - - Determine if testWire is inside baseWire, after both wires are projected - into the current plane. - - :param baseWire: a reference wire - :type baseWire: a FreeCAD wire - :param testWire: another wire - :type testWire: a FreeCAD wire - :return: True if testWire is inside baseWire, otherwise False - - If either wire does not lie in the current plane, it is projected into - the plane first. - - *WARNING*: This method is not 100% reliable. It uses bounding box - tests, but needs more work to check for cases when curves are complex. - - Future Enhancements: - * Discretizing points along each curve to provide a more reliable - test. - """ - # TODO: also use a set of points along the wire to test as well. - # TODO: would it be more efficient to create objects in the local - # coordinate system, and then transform to global - # coordinates upon extrusion? - - tBaseWire = baseWire.transformGeometry(self.fG) - tTestWire = testWire.transformGeometry(self.fG) - - # These bounding boxes will have z=0, since we transformed them into the - # space of the plane. - bb = tBaseWire.BoundingBox() - tb = tTestWire.BoundingBox() - - # findOutsideBox actually inspects both ways, here we only want to - # know if one is inside the other - return bb == BoundBox.findOutsideBox2D(bb, tb) - - def toLocalCoords(self, obj): - """Project the provided coordinates onto this plane - - :param obj: an object or vector to convert - :type vector: a vector or shape - :return: an object of the same type, but converted to local coordinates - - - Most of the time, the z-coordinate returned will be zero, because most - operations based on a plane are all 2-d. Occasionally, though, 3-d - points outside of the current plane are transformed. One such example is - :py:meth:`Workplane.box`, where 3-d corners of a box are transformed to - orient the box in space correctly. - - """ - if isinstance(obj, Vector): - return Vector(self.fG.multiply(obj.wrapped)) - elif isinstance(obj, cadquery.Shape): - return obj.transformShape(self.rG) - else: - raise ValueError( - "Don't know how to convert type {} to local coordinates".format( - type(obj))) - - def toWorldCoords(self, tuplePoint): - """Convert a point in local coordinates to global coordinates - - :param tuplePoint: point in local coordinates to convert. - :type tuplePoint: a 2 or three tuple of float. The third value is taken to be zero if not supplied. - :return: a Vector in global coordinates - """ - if isinstance(tuplePoint, Vector): - v = tuplePoint - elif len(tuplePoint) == 2: - v = Vector(tuplePoint[0], tuplePoint[1], 0) - else: - v = Vector(tuplePoint) - return Vector(self.rG.multiply(v.wrapped)) - - def rotated(self, rotate=(0, 0, 0)): - """Returns a copy of this plane, rotated about the specified axes - - Since the z axis is always normal the plane, rotating around Z will - always produce a plane that is parallel to this one. - - The origin of the workplane is unaffected by the rotation. - - Rotations are done in order x, y, z. If you need a different order, - manually chain together multiple rotate() commands. - - :param rotate: Vector [xDegrees, yDegrees, zDegrees] - :return: a copy of this plane rotated as requested. - """ - rotate = Vector(rotate) - # Convert to radians. - rotate = rotate.multiply(math.pi / 180.0) - - # Compute rotation matrix. - m = FreeCAD.Base.Matrix() - m.rotateX(rotate.x) - m.rotateY(rotate.y) - m.rotateZ(rotate.z) - - # Compute the new plane. - newXdir = Vector(m.multiply(self.xDir.wrapped)) - newZdir = Vector(m.multiply(self.zDir.wrapped)) - - return Plane(self.origin, newXdir, newZdir) - - def rotateShapes(self, listOfShapes, rotationMatrix): - """Rotate the listOfShapes by the supplied rotationMatrix - - @param listOfShapes is a list of shape objects - @param rotationMatrix is a geom.Matrix object. - returns a list of shape objects rotated according to the rotationMatrix. - """ - # Compute rotation matrix (global --> local --> rotate --> global). - # rm = self.plane.fG.multiply(matrix).multiply(self.plane.rG) - # rm = self.computeTransform(rotationMatrix) - - # There might be a better way, but to do this rotation takes 3 steps: - # - transform geometry to local coordinates - # - then rotate about x - # - then transform back to global coordinates. - - resultWires = [] - for w in listOfShapes: - mirrored = w.transformGeometry(rotationMatrix.wrapped) - - # If the first vertex of the second wire is not coincident with the - # first or last vertices of the first wire we have to fix the wire - # so that it will mirror correctly. - if ((mirrored.wrapped.Vertexes[0].X == w.wrapped.Vertexes[0].X and - mirrored.wrapped.Vertexes[0].Y == w.wrapped.Vertexes[0].Y and - mirrored.wrapped.Vertexes[0].Z == w.wrapped.Vertexes[0].Z) or - (mirrored.wrapped.Vertexes[0].X == w.wrapped.Vertexes[-1].X and - mirrored.wrapped.Vertexes[0].Y == w.wrapped.Vertexes[-1].Y and - mirrored.wrapped.Vertexes[0].Z == w.wrapped.Vertexes[-1].Z)): - - resultWires.append(mirrored) - else: - # Make sure that our mirrored edges meet up and are ordered - # properly. - aEdges = w.wrapped.Edges - aEdges.extend(mirrored.wrapped.Edges) - comp = FreeCADPart.Compound(aEdges) - mirroredWire = comp.connectEdgesToWires(False).Wires[0] - - resultWires.append(cadquery.Shape.cast(mirroredWire)) - - return resultWires - - def _setPlaneDir(self, xDir): - """Set the vectors parallel to the plane, i.e. xDir and yDir""" - if (self.zDir.dot(xDir) > 1e-5): - raise ValueError('xDir must be parralel to the plane') - xDir = Vector(xDir) - self.xDir = xDir.normalized() - self.yDir = self.zDir.cross(self.xDir).normalized() - - def _calcTransforms(self): - """Computes transformation matrices to convert between coordinates - - Computes transformation matrices to convert between local and global - coordinates. - """ - # r is the forward transformation matrix from world to local coordinates - # ok i will be really honest, i cannot understand exactly why this works - # something bout the order of the translation and the rotation. - # the double-inverting is strange, and I don't understand it. - r = FreeCAD.Base.Matrix() - - # Forward transform must rotate and adjust for origin. - (r.A11, r.A12, r.A13) = (self.xDir.x, self.xDir.y, self.xDir.z) - (r.A21, r.A22, r.A23) = (self.yDir.x, self.yDir.y, self.yDir.z) - (r.A31, r.A32, r.A33) = (self.zDir.x, self.zDir.y, self.zDir.z) - - invR = r.inverse() - invR.A14 = self.origin.x - invR.A24 = self.origin.y - invR.A34 = self.origin.z - - self.rG = invR - self.fG = invR.inverse() - - def computeTransform(self, tMatrix): - """Computes the 2-d projection of the supplied matrix""" - - return Matrix(self.fG.multiply(tMatrix.wrapped).multiply(self.rG)) - - -class BoundBox(object): - """A BoundingBox for an object or set of objects. Wraps the FreeCAD one""" - def __init__(self, bb): - self.wrapped = bb - self.xmin = bb.XMin - self.xmax = bb.XMax - self.xlen = bb.XLength - self.ymin = bb.YMin - self.ymax = bb.YMax - self.ylen = bb.YLength - self.zmin = bb.ZMin - self.zmax = bb.ZMax - self.zlen = bb.ZLength - self.center = Vector(bb.Center) - self.DiagonalLength = bb.DiagonalLength - - def add(self, obj): - """Returns a modified (expanded) bounding box - - obj can be one of several things: - 1. a 3-tuple corresponding to x,y, and z amounts to add - 2. a vector, containing the x,y,z values to add - 3. another bounding box, where a new box will be created that - encloses both. - - This bounding box is not changed. - """ - tmp = FreeCAD.Base.BoundBox(self.wrapped) - if isinstance(obj, tuple): - tmp.add(obj[0], obj[1], obj[2]) - elif isinstance(obj, Vector): - tmp.add(obj.fV) - elif isinstance(obj, BoundBox): - tmp.add(obj.wrapped) - - return BoundBox(tmp) - - @classmethod - def findOutsideBox2D(cls, b1, b2): - """Compares bounding boxes - - Compares bounding boxes. Returns none if neither is inside the other. - Returns the outer one if either is outside the other. - - BoundBox.isInside works in 3d, but this is a 2d bounding box, so it - doesn't work correctly plus, there was all kinds of rounding error in - the built-in implementation i do not understand. - """ - fc_bb1 = b1.wrapped - fc_bb2 = b2.wrapped - if (fc_bb1.XMin < fc_bb2.XMin and - fc_bb1.XMax > fc_bb2.XMax and - fc_bb1.YMin < fc_bb2.YMin and - fc_bb1.YMax > fc_bb2.YMax): - return b1 - - if (fc_bb2.XMin < fc_bb1.XMin and - fc_bb2.XMax > fc_bb1.XMax and - fc_bb2.YMin < fc_bb1.YMin and - fc_bb2.YMax > fc_bb1.YMax): - return b2 - - return None - - def isInside(self, anotherBox): - """Is the provided bounding box inside this one?""" - return self.wrapped.isInside(anotherBox.wrapped) diff --git a/Libs/cadquery-lib/cadquery/freecad_impl/importers.py b/Libs/cadquery-lib/cadquery/freecad_impl/importers.py deleted file mode 100644 index 7d4f0a9..0000000 --- a/Libs/cadquery-lib/cadquery/freecad_impl/importers.py +++ /dev/null @@ -1,71 +0,0 @@ - -import cadquery -from .shapes import Shape - -import FreeCAD -import Part -import sys -import os -import urllib as urlreader -import tempfile - -class ImportTypes: - STEP = "STEP" - -class UNITS: - MM = "mm" - IN = "in" - - -def importShape(importType, fileName): - """ - Imports a file based on the type (STEP, STL, etc) - :param importType: The type of file that we're importing - :param fileName: THe name of the file that we're importing - """ - - #Check to see what type of file we're working with - if importType == ImportTypes.STEP: - return importStep(fileName) - - -#Loads a STEP file into a CQ.Workplane object -def importStep(fileName): - """ - Accepts a file name and loads the STEP file into a cadquery shape - :param fileName: The path and name of the STEP file to be imported - """ - #Now read and return the shape - try: - #print fileName - rshape = Part.read(fileName) - - #Make sure that we extract all the solids - solids = [] - for solid in rshape.Solids: - solids.append(Shape.cast(solid)) - - return cadquery.Workplane("XY").newObject(solids) - except: - raise ValueError("STEP File Could not be loaded") - -#Loads a STEP file from an URL into a CQ.Workplane object -def importStepFromURL(url): - #Now read and return the shape - try: - webFile = urlreader.urlopen(url) - tempFile = tempfile.NamedTemporaryFile(suffix='.step', delete=False) - tempFile.write(webFile.read()) - webFile.close() - tempFile.close() - - rshape = Part.read(tempFile.name) - - #Make sure that we extract all the solids - solids = [] - for solid in rshape.Solids: - solids.append(Shape.cast(solid)) - - return cadquery.Workplane("XY").newObject(solids) - except: - raise ValueError("STEP File from the URL: " + url + " Could not be loaded") diff --git a/Libs/cadquery-lib/cadquery/freecad_impl/shapes.py b/Libs/cadquery-lib/cadquery/freecad_impl/shapes.py deleted file mode 100644 index 6f65ccc..0000000 --- a/Libs/cadquery-lib/cadquery/freecad_impl/shapes.py +++ /dev/null @@ -1,1044 +0,0 @@ -""" - Copyright (C) 2011-2015 Parametric Products Intellectual Holdings, LLC - - This file is part of CadQuery. - - CadQuery is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - CadQuery 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; If not, see - - Wrapper Classes for FreeCAD - These classes provide a stable interface for 3d objects, - independent of the FreeCAD interface. - - Future work might include use of pythonOCC, OCC, or even - another CAD kernel directly, so this interface layer is quite important. - - Funny, in java this is one of those few areas where i'd actually spend the time - to make an interface and an implementation, but for new these are just rolled together - - This interface layer provides three distinct values: - - 1. It allows us to avoid changing key api points if we change underlying implementations. - It would be a disaster if script and plugin authors had to change models because we - changed implementations - - 2. Allow better documentation. One of the reasons FreeCAD is no more popular is because - its docs are terrible. This allows us to provide good documentation via docstrings - for each wrapper - - 3. Work around bugs. there are a quite a feb bugs in free this layer allows fixing them - - 4. allows for enhanced functionality. Many objects are missing features we need. For example - we need a 'forConstruction' flag on the Wire object. this allows adding those kinds of things - - 5. allow changing interfaces when we'd like. there are few cases where the FreeCAD api is not - very user friendly: we like to change those when necessary. As an example, in the FreeCAD api, - all factory methods are on the 'Part' object, but it is very useful to know what kind of - object each one returns, so these are better grouped by the type of object they return. - (who would know that Part.makeCircle() returns an Edge, but Part.makePolygon() returns a Wire ? -""" -from cadquery import Vector, BoundBox -import FreeCAD -import Part as FreeCADPart - - -class Shape(object): - """ - Represents a shape in the system. - Wrappers the FreeCAD api - """ - - def __init__(self, obj): - self.wrapped = obj - self.forConstruction = False - - # Helps identify this solid through the use of an ID - self.label = "" - - @classmethod - def cast(cls, obj, forConstruction=False): - "Returns the right type of wrapper, given a FreeCAD object" - s = obj.ShapeType - if type(obj) == FreeCAD.Base.Vector: - return Vector(obj) - tr = None - - # TODO: there is a clever way to do this i'm sure with a lookup - # but it is not a perfect mapping, because we are trying to hide - # a bit of the complexity of Compounds in FreeCAD. - if s == 'Vertex': - tr = Vertex(obj) - elif s == 'Edge': - tr = Edge(obj) - elif s == 'Wire': - tr = Wire(obj) - elif s == 'Face': - tr = Face(obj) - elif s == 'Shell': - tr = Shell(obj) - elif s == 'Solid': - tr = Solid(obj) - elif s == 'Compound': - #compound of solids, lets return a solid instead - if len(obj.Solids) > 1: - tr = Solid(obj) - elif len(obj.Solids) == 1: - tr = Solid(obj.Solids[0]) - elif len(obj.Wires) > 0: - tr = Wire(obj) - else: - tr = Compound(obj) - else: - raise ValueError("cast:unknown shape type %s" % s) - - tr.forConstruction = forConstruction - return tr - - # TODO: all these should move into the exporters folder. - # we dont need a bunch of exporting code stored in here! - # - def exportStl(self, fileName): - self.wrapped.exportStl(fileName) - - def exportStep(self, fileName): - self.wrapped.exportStep(fileName) - - def exportShape(self, fileName, fileFormat): - if fileFormat == ExportFormats.STL: - self.wrapped.exportStl(fileName) - elif fileFormat == ExportFormats.BREP: - self.wrapped.exportBrep(fileName) - elif fileFormat == ExportFormats.STEP: - self.wrapped.exportStep(fileName) - elif fileFormat == ExportFormats.AMF: - # not built into FreeCAD - #TODO: user selected tolerance - tess = self.wrapped.tessellate(0.1) - aw = amfUtils.AMFWriter(tess) - aw.writeAmf(fileName) - elif fileFormat == ExportFormats.IGES: - self.wrapped.exportIges(fileName) - else: - raise ValueError("Unknown export format: %s" % format) - - def geomType(self): - """ - Gets the underlying geometry type - :return: a string according to the geometry type. - - Implementations can return any values desired, but the - values the user uses in type filters should correspond to these. - - As an example, if a user does:: - - CQ(object).faces("%mytype") - - The expectation is that the geomType attribute will return 'mytype' - - The return values depend on the type of the shape: - - Vertex: always 'Vertex' - Edge: LINE, ARC, CIRCLE, SPLINE - Face: PLANE, SPHERE, CONE - Solid: 'Solid' - Shell: 'Shell' - Compound: 'Compound' - Wire: 'Wire' - """ - return self.wrapped.ShapeType - - def isType(self, obj, strType): - """ - Returns True if the shape is the specified type, false otherwise - - contrast with ShapeType, which will raise an exception - if the provide object is not a shape at all - """ - if hasattr(obj, 'ShapeType'): - return obj.ShapeType == strType - else: - return False - - def hashCode(self): - return self.wrapped.hashCode() - - def isNull(self): - return self.wrapped.isNull() - - def isSame(self, other): - return self.wrapped.isSame(other.wrapped) - - def isEqual(self, other): - return self.wrapped.isEqual(other.wrapped) - - def isValid(self): - return self.wrapped.isValid() - - def BoundingBox(self, tolerance=0.1): - self.wrapped.tessellate(tolerance) - return BoundBox(self.wrapped.BoundBox) - - def mirror(self, mirrorPlane="XY", basePointVector=(0, 0, 0)): - if mirrorPlane == "XY" or mirrorPlane== "YX": - mirrorPlaneNormalVector = FreeCAD.Base.Vector(0, 0, 1) - elif mirrorPlane == "XZ" or mirrorPlane == "ZX": - mirrorPlaneNormalVector = FreeCAD.Base.Vector(0, 1, 0) - elif mirrorPlane == "YZ" or mirrorPlane == "ZY": - mirrorPlaneNormalVector = FreeCAD.Base.Vector(1, 0, 0) - - if type(basePointVector) == tuple: - basePointVector = Vector(basePointVector) - - return Shape.cast(self.wrapped.mirror(basePointVector.wrapped, mirrorPlaneNormalVector)) - - def Center(self): - # A Part.Shape object doesn't have the CenterOfMass function, but it's wrapped Solid(s) does - if isinstance(self.wrapped, FreeCADPart.Shape): - # If there are no Solids, we're probably dealing with a Face or something similar - if len(self.Solids()) == 0: - return Vector(self.wrapped.CenterOfMass) - elif len(self.Solids()) == 1: - return Vector(self.Solids()[0].wrapped.CenterOfMass) - elif len(self.Solids()) > 1: - return self.CombinedCenter(self.Solids()) - elif isinstance(self.wrapped, FreeCADPart.Solid): - return Vector(self.wrapped.CenterOfMass) - else: - raise ValueError("Cannot find the center of %s object type" % str(type(self.Solids()[0].wrapped))) - - def CenterOfBoundBox(self, tolerance = 0.1): - self.wrapped.tessellate(tolerance) - if isinstance(self.wrapped, FreeCADPart.Shape): - # If there are no Solids, we're probably dealing with a Face or something similar - if len(self.Solids()) == 0: - return Vector(self.wrapped.BoundBox.Center) - elif len(self.Solids()) == 1: - return Vector(self.Solids()[0].wrapped.BoundBox.Center) - elif len(self.Solids()) > 1: - return self.CombinedCenterOfBoundBox(self.Solids()) - elif isinstance(self.wrapped, FreeCADPart.Solid): - return Vector(self.wrapped.BoundBox.Center) - else: - raise ValueError("Cannot find the center(BoundBox's) of %s object type" % str(type(self.Solids()[0].wrapped))) - - @staticmethod - def CombinedCenter(objects): - """ - Calculates the center of mass of multiple objects. - - :param objects: a list of objects with mass - """ - total_mass = sum(Shape.computeMass(o) for o in objects) - weighted_centers = [o.wrapped.CenterOfMass.multiply(Shape.computeMass(o)) for o in objects] - - sum_wc = weighted_centers[0] - for wc in weighted_centers[1:] : - sum_wc = sum_wc.add(wc) - - return Vector(sum_wc.multiply(1./total_mass)) - - @staticmethod - def computeMass(object): - """ - Calculates the 'mass' of an object. in FreeCAD < 15, all objects had a mass. - in FreeCAD >=15, faces no longer have mass, but instead have area. - """ - if object.wrapped.ShapeType == 'Face': - return object.wrapped.Area - else: - return object.wrapped.Mass - - @staticmethod - def CombinedCenterOfBoundBox(objects, tolerance = 0.1): - """ - Calculates the center of BoundBox of multiple objects. - - :param objects: a list of objects with mass 1 - """ - total_mass = len(objects) - - weighted_centers = [] - for o in objects: - o.wrapped.tessellate(tolerance) - weighted_centers.append(o.wrapped.BoundBox.Center.multiply(1.0)) - - sum_wc = weighted_centers[0] - for wc in weighted_centers[1:] : - sum_wc = sum_wc.add(wc) - - return Vector(sum_wc.multiply(1./total_mass)) - - def Closed(self): - return self.wrapped.Closed - - def ShapeType(self): - return self.wrapped.ShapeType - - def Vertices(self): - return [Vertex(i) for i in self.wrapped.Vertexes] - - def Edges(self): - return [Edge(i) for i in self.wrapped.Edges] - - def Compounds(self): - return [Compound(i) for i in self.wrapped.Compounds] - - def Wires(self): - return [Wire(i) for i in self.wrapped.Wires] - - def Faces(self): - return [Face(i) for i in self.wrapped.Faces] - - def Shells(self): - return [Shell(i) for i in self.wrapped.Shells] - - def Solids(self): - return [Solid(i) for i in self.wrapped.Solids] - - def Area(self): - return self.wrapped.Area - - def Length(self): - return self.wrapped.Length - - def rotate(self, startVector, endVector, angleDegrees): - """ - Rotates a shape around an axis - :param startVector: start point of rotation axis either a 3-tuple or a Vector - :param endVector: end point of rotation axis, either a 3-tuple or a Vector - :param angleDegrees: angle to rotate, in degrees - :return: a copy of the shape, rotated - """ - if type(startVector) == tuple: - startVector = Vector(startVector) - - if type(endVector) == tuple: - endVector = Vector(endVector) - - tmp = self.wrapped.copy() - tmp.rotate(startVector.wrapped, endVector.wrapped, angleDegrees) - return Shape.cast(tmp) - - def translate(self, vector): - - if type(vector) == tuple: - vector = Vector(vector) - tmp = self.wrapped.copy() - tmp.translate(vector.wrapped) - return Shape.cast(tmp) - - def scale(self, factor): - tmp = self.wrapped.copy() - tmp.scale(factor) - return Shape.cast(tmp) - - def copy(self): - return Shape.cast(self.wrapped.copy()) - - def transformShape(self, tMatrix): - """ - tMatrix is a matrix object. - returns a copy of the ojbect, transformed by the provided matrix, - with all objects keeping their type - """ - tmp = self.wrapped.copy() - tmp.transformShape(tMatrix) - r = Shape.cast(tmp) - r.forConstruction = self.forConstruction - return r - - def transformGeometry(self, tMatrix): - """ - tMatrix is a matrix object. - - returns a copy of the object, but with geometry transformed insetad of just - rotated. - - WARNING: transformGeometry will sometimes convert lines and circles to splines, - but it also has the ability to handle skew and stretching transformations. - - If your transformation is only translation and rotation, it is safer to use transformShape, - which doesnt change the underlying type of the geometry, but cannot handle skew transformations - """ - tmp = self.wrapped.copy() - tmp = tmp.transformGeometry(tMatrix) - return Shape.cast(tmp) - - def __hash__(self): - return self.wrapped.hashCode() - - -class Vertex(Shape): - """ - A Single Point in Space - """ - - def __init__(self, obj, forConstruction=False): - """ - Create a vertex from a FreeCAD Vertex - """ - self.wrapped = obj - self.forConstruction = forConstruction - self.X = obj.X - self.Y = obj.Y - self.Z = obj.Z - - # Helps identify this solid through the use of an ID - self.label = "" - - def toTuple(self): - return (self.X, self.Y, self.Z) - - def Center(self): - """ - The center of a vertex is itself! - """ - return Vector(self.wrapped.Point) - - -class Edge(Shape): - """ - A trimmed curve that represents the border of a face - """ - - def __init__(self, obj): - """ - An Edge - """ - self.wrapped = obj - # self.startPoint = None - # self.endPoint = None - - self.edgetypes = { - FreeCADPart.ArcOfCircle: 'ARC', - FreeCADPart.Circle: 'CIRCLE' - } - - if hasattr(FreeCADPart,"LineSegment"): - #FreeCAD <= 0.16 - self.edgetypes[FreeCADPart.LineSegment] = 'LINE' - else: - #FreeCAD >= 0.17 - self.edgetypes[FreeCADPart.Line] = 'LINE' - - # Helps identify this solid through the use of an ID - self.label = "" - - def geomType(self): - t = type(self.wrapped.Curve) - if self.edgetypes.has_key(t): - return self.edgetypes[t] - else: - return "Unknown Edge Curve Type: %s" % str(t) - - def startPoint(self): - """ - - :return: a vector representing the start poing of this edge - - Note, circles may have the start and end points the same - """ - # work around freecad bug where valueAt is unreliable - curve = self.wrapped.Curve - return Vector(curve.value(self.wrapped.ParameterRange[0])) - - def endPoint(self): - """ - - :return: a vector representing the end point of this edge. - - Note, circles may have the start and end points the same - - """ - # warning: easier syntax in freecad of .valueAt(.ParameterRange[1]) has - # a bug with curves other than arcs, but using the underlying curve directly seems to work - # that's the solution i'm using below - curve = self.wrapped.Curve - v = Vector(curve.value(self.wrapped.ParameterRange[1])) - return v - - def tangentAt(self, locationVector=None): - """ - Compute tangent vector at the specified location. - :param locationVector: location to use. Use the center point if None - :return: tangent vector - """ - if locationVector is None: - locationVector = self.Center() - - p = self.wrapped.Curve.parameter(locationVector.wrapped) - return Vector(self.wrapped.tangentAt(p)) - - @classmethod - def makeCircle(cls, radius, pnt=(0, 0, 0), dir=(0, 0, 1), angle1=360.0, angle2=360): - center = Vector(pnt) - normal = Vector(dir) - return Edge(FreeCADPart.makeCircle(radius, center.wrapped, normal.wrapped, angle1, angle2)) - - @classmethod - def makeSpline(cls, listOfVector): - """ - Interpolate a spline through the provided points. - :param cls: - :param listOfVector: a list of Vectors that represent the points - :return: an Edge - """ - vecs = [v.wrapped for v in listOfVector] - - spline = FreeCADPart.BSplineCurve() - spline.interpolate(vecs, False) - return Edge(spline.toShape()) - - @classmethod - def makeThreePointArc(cls, v1, v2, v3): - """ - Makes a three point arc through the provided points - :param cls: - :param v1: start vector - :param v2: middle vector - :param v3: end vector - :return: an edge object through the three points - """ - arc = FreeCADPart.Arc(v1.wrapped, v2.wrapped, v3.wrapped) - e = Edge(arc.toShape()) - return e # arcane and undocumented, this creates an Edge object - - @classmethod - def makeLine(cls, v1, v2): - """ - Create a line between two points - :param v1: Vector that represents the first point - :param v2: Vector that represents the second point - :return: A linear edge between the two provided points - """ - return Edge(FreeCADPart.makeLine(v1.toTuple(), v2.toTuple())) - - -class Wire(Shape): - """ - A series of connected, ordered Edges, that typically bounds a Face - """ - - def __init__(self, obj): - """ - A Wire - """ - self.wrapped = obj - - # Helps identify this solid through the use of an ID - self.label = "" - - @classmethod - def combine(cls, listOfWires): - """ - Attempt to combine a list of wires into a new wire. - the wires are returned in a list. - :param cls: - :param listOfWires: - :return: - """ - return Shape.cast(FreeCADPart.Wire([w.wrapped for w in listOfWires])) - - @classmethod - def assembleEdges(cls, listOfEdges): - """ - Attempts to build a wire that consists of the edges in the provided list - :param cls: - :param listOfEdges: a list of Edge objects - :return: a wire with the edges assembled - """ - fCEdges = [a.wrapped for a in listOfEdges] - - wa = Wire(FreeCADPart.Wire(fCEdges)) - return wa - - @classmethod - def makeCircle(cls, radius, center, normal): - """ - Makes a Circle centered at the provided point, having normal in the provided direction - :param radius: floating point radius of the circle, must be > 0 - :param center: vector representing the center of the circle - :param normal: vector representing the direction of the plane the circle should lie in - :return: - """ - w = Wire(FreeCADPart.Wire([FreeCADPart.makeCircle(radius, center.wrapped, normal.wrapped)])) - return w - - @classmethod - def makePolygon(cls, listOfVertices, forConstruction=False): - # convert list of tuples into Vectors. - w = Wire(FreeCADPart.makePolygon([i.wrapped for i in listOfVertices])) - w.forConstruction = forConstruction - return w - - @classmethod - def makeHelix(cls, pitch, height, radius, angle=360.0): - """ - Make a helix with a given pitch, height and radius - By default a cylindrical surface is used to create the helix. If - the fourth parameter is set (the apex given in degree) a conical surface is used instead' - """ - return Wire(FreeCADPart.makeHelix(pitch, height, radius, angle)) - - def clean(self): - """This method is not implemented yet.""" - return self - -class Face(Shape): - """ - a bounded surface that represents part of the boundary of a solid - """ - def __init__(self, obj): - - self.wrapped = obj - - self.facetypes = { - # TODO: bezier,bspline etc - FreeCADPart.Plane: 'PLANE', - FreeCADPart.Sphere: 'SPHERE', - FreeCADPart.Cone: 'CONE' - } - - # Helps identify this solid through the use of an ID - self.label = "" - - def geomType(self): - t = type(self.wrapped.Surface) - if self.facetypes.has_key(t): - return self.facetypes[t] - else: - return "Unknown Face Surface Type: %s" % str(t) - - def normalAt(self, locationVector=None): - """ - Computes the normal vector at the desired location on the face. - - :returns: a vector representing the direction - :param locationVector: the location to compute the normal at. If none, the center of the face is used. - :type locationVector: a vector that lies on the surface. - """ - if locationVector == None: - locationVector = self.Center() - (u, v) = self.wrapped.Surface.parameter(locationVector.wrapped) - - return Vector(self.wrapped.normalAt(u, v).normalize()) - - @classmethod - def makePlane(cls, length, width, basePnt=(0, 0, 0), dir=(0, 0, 1)): - basePnt = Vector(basePnt) - dir = Vector(dir) - return Face(FreeCADPart.makePlane(length, width, basePnt.wrapped, dir.wrapped)) - - @classmethod - def makeRuledSurface(cls, edgeOrWire1, edgeOrWire2, dist=None): - """ - 'makeRuledSurface(Edge|Wire,Edge|Wire) -- Make a ruled surface - Create a ruled surface out of two edges or wires. If wires are used then - these must have the same - """ - return Shape.cast(FreeCADPart.makeRuledSurface(edgeOrWire1.obj, edgeOrWire2.obj, dist)) - - def cut(self, faceToCut): - "Remove a face from another one" - return Shape.cast(self.obj.cut(faceToCut.obj)) - - def fuse(self, faceToJoin): - return Shape.cast(self.obj.fuse(faceToJoin.obj)) - - def intersect(self, faceToIntersect): - """ - computes the intersection between the face and the supplied one. - The result could be a face or a compound of faces - """ - return Shape.cast(self.obj.common(faceToIntersect.obj)) - - -class Shell(Shape): - """ - the outer boundary of a surface - """ - def __init__(self, wrapped): - """ - A Shell - """ - self.wrapped = wrapped - - # Helps identify this solid through the use of an ID - self.label = "" - - @classmethod - def makeShell(cls, listOfFaces): - return Shell(FreeCADPart.makeShell([i.obj for i in listOfFaces])) - - -class Solid(Shape): - """ - a single solid - """ - def __init__(self, obj): - """ - A Solid - """ - self.wrapped = obj - - # Helps identify this solid through the use of an ID - self.label = "" - - @classmethod - def isSolid(cls, obj): - """ - Returns true if the object is a FreeCAD solid, false otherwise - """ - if hasattr(obj, 'ShapeType'): - if obj.ShapeType == 'Solid' or \ - (obj.ShapeType == 'Compound' and len(obj.Solids) > 0): - return True - return False - - @classmethod - def makeBox(cls, length, width, height, pnt=Vector(0, 0, 0), dir=Vector(0, 0, 1)): - """ - makeBox(length,width,height,[pnt,dir]) -- Make a box located in pnt with the dimensions (length,width,height) - By default pnt=Vector(0,0,0) and dir=Vector(0,0,1)' - """ - return Shape.cast(FreeCADPart.makeBox(length, width, height, pnt.wrapped, dir.wrapped)) - - @classmethod - def makeCone(cls, radius1, radius2, height, pnt=Vector(0, 0, 0), dir=Vector(0, 0, 1), angleDegrees=360): - """ - Make a cone with given radii and height - By default pnt=Vector(0,0,0), - dir=Vector(0,0,1) and angle=360' - """ - return Shape.cast(FreeCADPart.makeCone(radius1, radius2, height, pnt.wrapped, dir.wrapped, angleDegrees)) - - @classmethod - def makeCylinder(cls, radius, height, pnt=Vector(0, 0, 0), dir=Vector(0, 0, 1), angleDegrees=360): - """ - makeCylinder(radius,height,[pnt,dir,angle]) -- - Make a cylinder with a given radius and height - By default pnt=Vector(0,0,0),dir=Vector(0,0,1) and angle=360' - """ - return Shape.cast(FreeCADPart.makeCylinder(radius, height, pnt.wrapped, dir.wrapped, angleDegrees)) - - @classmethod - def makeTorus(cls, radius1, radius2, pnt=None, dir=None, angleDegrees1=None, angleDegrees2=None): - """ - makeTorus(radius1,radius2,[pnt,dir,angle1,angle2,angle]) -- - Make a torus with agiven radii and angles - By default pnt=Vector(0,0,0),dir=Vector(0,0,1),angle1=0 - ,angle1=360 and angle=360' - """ - return Shape.cast(FreeCADPart.makeTorus(radius1, radius2, pnt, dir, angleDegrees1, angleDegrees2)) - - @classmethod - def sweep(cls, profileWire, pathWire): - """ - make a solid by sweeping the profileWire along the specified path - :param cls: - :param profileWire: - :param pathWire: - :return: - """ - # needs to use freecad wire.makePipe or makePipeShell - # needs to allow free-space wires ( those not made from a workplane ) - - @classmethod - def makeLoft(cls, listOfWire, ruled=False): - """ - makes a loft from a list of wires - The wires will be converted into faces when possible-- it is presumed that nobody ever actually - wants to make an infinitely thin shell for a real FreeCADPart. - """ - # the True flag requests building a solid instead of a shell. - - return Shape.cast(FreeCADPart.makeLoft([i.wrapped for i in listOfWire], True, ruled)) - - @classmethod - def makeWedge(cls, xmin, ymin, zmin, z2min, x2min, xmax, ymax, zmax, z2max, x2max, pnt=None, dir=None): - """ - Make a wedge located in pnt - By default pnt=Vector(0,0,0) and dir=Vector(0,0,1) - """ - return Shape.cast( - FreeCADPart.makeWedge(xmin, ymin, zmin, z2min, x2min, xmax, ymax, zmax, z2max, x2max, pnt, dir)) - - @classmethod - def makeSphere(cls, radius, pnt=None, dir=None, angleDegrees1=None, angleDegrees2=None, angleDegrees3=None): - """ - Make a sphere with a given radius - By default pnt=Vector(0,0,0), dir=Vector(0,0,1), angle1=0, angle2=90 and angle3=360 - """ - return Shape.cast(FreeCADPart.makeSphere(radius, pnt.wrapped, dir.wrapped, angleDegrees1, angleDegrees2, angleDegrees3)) - - @classmethod - def extrudeLinearWithRotation(cls, outerWire, innerWires, vecCenter, vecNormal, angleDegrees): - """ - Creates a 'twisted prism' by extruding, while simultaneously rotating around the extrusion vector. - - Though the signature may appear to be similar enough to extrudeLinear to merit combining them, the - construction methods used here are different enough that they should be separate. - - At a high level, the steps followed are: - (1) accept a set of wires - (2) create another set of wires like this one, but which are transformed and rotated - (3) create a ruledSurface between the sets of wires - (4) create a shell and compute the resulting object - - :param outerWire: the outermost wire, a cad.Wire - :param innerWires: a list of inner wires, a list of cad.Wire - :param vecCenter: the center point about which to rotate. the axis of rotation is defined by - vecNormal, located at vecCenter. ( a cad.Vector ) - :param vecNormal: a vector along which to extrude the wires ( a cad.Vector ) - :param angleDegrees: the angle to rotate through while extruding - :return: a cad.Solid object - """ - - # from this point down we are dealing with FreeCAD wires not cad.wires - startWires = [outerWire.wrapped] + [i.wrapped for i in innerWires] - endWires = [] - p1 = vecCenter.wrapped - p2 = vecCenter.add(vecNormal).wrapped - - # make translated and rotated copy of each wire - for w in startWires: - w2 = w.copy() - w2.translate(vecNormal.wrapped) - w2.rotate(p1, p2, angleDegrees) - endWires.append(w2) - - # make a ruled surface for each set of wires - sides = [] - for w1, w2 in zip(startWires, endWires): - rs = FreeCADPart.makeRuledSurface(w1, w2) - sides.append(rs) - - #make faces for the top and bottom - startFace = FreeCADPart.Face(startWires) - endFace = FreeCADPart.Face(endWires) - - #collect all the faces from the sides - faceList = [startFace] - for s in sides: - faceList.extend(s.Faces) - faceList.append(endFace) - - shell = FreeCADPart.makeShell(faceList) - solid = FreeCADPart.makeSolid(shell) - return Shape.cast(solid) - - @classmethod - def extrudeLinear(cls, outerWire, innerWires, vecNormal): - """ - Attempt to extrude the list of wires into a prismatic solid in the provided direction - - :param outerWire: the outermost wire - :param innerWires: a list of inner wires - :param vecNormal: a vector along which to extrude the wires - :return: a Solid object - - The wires must not intersect - - Extruding wires is very non-trivial. Nested wires imply very different geometry, and - there are many geometries that are invalid. In general, the following conditions must be met: - - * all wires must be closed - * there cannot be any intersecting or self-intersecting wires - * wires must be listed from outside in - * more than one levels of nesting is not supported reliably - - This method will attempt to sort the wires, but there is much work remaining to make this method - reliable. - """ - - # one would think that fusing faces into a compound and then extruding would work, - # but it doesnt-- the resulting compound appears to look right, ( right number of faces, etc), - # but then cutting it from the main solid fails with BRep_NotDone. - #the work around is to extrude each and then join the resulting solids, which seems to work - - #FreeCAD allows this in one operation, but others might not - freeCADWires = [outerWire.wrapped] - for w in innerWires: - freeCADWires.append(w.wrapped) - - f = FreeCADPart.Face(freeCADWires) - result = f.extrude(vecNormal.wrapped) - - return Shape.cast(result) - - @classmethod - def revolve(cls, outerWire, innerWires, angleDegrees, axisStart, axisEnd): - """ - Attempt to revolve the list of wires into a solid in the provided direction - - :param outerWire: the outermost wire - :param innerWires: a list of inner wires - :param angleDegrees: the angle to revolve through. - :type angleDegrees: float, anything less than 360 degrees will leave the shape open - :param axisStart: the start point of the axis of rotation - :type axisStart: tuple, a two tuple - :param axisEnd: the end point of the axis of rotation - :type axisEnd: tuple, a two tuple - :return: a Solid object - - The wires must not intersect - - * all wires must be closed - * there cannot be any intersecting or self-intersecting wires - * wires must be listed from outside in - * more than one levels of nesting is not supported reliably - * the wire(s) that you're revolving cannot be centered - - This method will attempt to sort the wires, but there is much work remaining to make this method - reliable. - """ - freeCADWires = [outerWire.wrapped] - - for w in innerWires: - freeCADWires.append(w.wrapped) - - f = FreeCADPart.Face(freeCADWires) - - rotateCenter = FreeCAD.Base.Vector(axisStart) - rotateAxis = FreeCAD.Base.Vector(axisEnd) - - #Convert our axis end vector into to something FreeCAD will understand (an axis specification vector) - rotateAxis = rotateCenter.sub(rotateAxis) - - #FreeCAD wants a rotation center and then an axis to rotate around rather than an axis of rotation - result = f.revolve(rotateCenter, rotateAxis, angleDegrees) - - return Shape.cast(result) - - @classmethod - def sweep(cls, outerWire, innerWires, path, makeSolid=True, isFrenet=False): - """ - Attempt to sweep the list of wires into a prismatic solid along the provided path - - :param outerWire: the outermost wire - :param innerWires: a list of inner wires - :param path: The wire to sweep the face resulting from the wires over - :return: a Solid object - """ - - # FreeCAD allows this in one operation, but others might not - freeCADWires = [outerWire.wrapped] - for w in innerWires: - freeCADWires.append(w.wrapped) - - # f = FreeCADPart.Face(freeCADWires) - wire = FreeCADPart.Wire([path.wrapped]) - result = wire.makePipeShell(freeCADWires, makeSolid, isFrenet) - - return Shape.cast(result) - - def tessellate(self, tolerance): - return self.wrapped.tessellate(tolerance) - - def intersect(self, toIntersect): - """ - computes the intersection between this solid and the supplied one - The result could be a face or a compound of faces - """ - return Shape.cast(self.wrapped.common(toIntersect.wrapped)) - - def cut(self, solidToCut): - "Remove a solid from another one" - return Shape.cast(self.wrapped.cut(solidToCut.wrapped)) - - def fuse(self, solidToJoin): - return Shape.cast(self.wrapped.fuse(solidToJoin.wrapped)) - - def clean(self): - """Clean faces by removing splitter edges.""" - r = self.wrapped.removeSplitter() - # removeSplitter() returns a generic Shape type, cast to actual type of object - r = FreeCADPart.cast_to_shape(r) - return Shape.cast(r) - - def fillet(self, radius, edgeList): - """ - Fillets the specified edges of this solid. - :param radius: float > 0, the radius of the fillet - :param edgeList: a list of Edge objects, which must belong to this solid - :return: Filleted solid - """ - nativeEdges = [e.wrapped for e in edgeList] - return Shape.cast(self.wrapped.makeFillet(radius, nativeEdges)) - - def chamfer(self, length, length2, edgeList): - """ - Chamfers the specified edges of this solid. - :param length: length > 0, the length (length) of the chamfer - :param length2: length2 > 0, optional parameter for asymmetrical chamfer. Should be `None` if not required. - :param edgeList: a list of Edge objects, which must belong to this solid - :return: Chamfered solid - """ - nativeEdges = [e.wrapped for e in edgeList] - # note: we prefer 'length' word to 'radius' as opposed to FreeCAD's API - if length2: - return Shape.cast(self.wrapped.makeChamfer(length, length2, nativeEdges)) - else: - return Shape.cast(self.wrapped.makeChamfer(length, nativeEdges)) - - def shell(self, faceList, thickness, tolerance=0.0001): - """ - make a shelled solid of given by removing the list of faces - - :param faceList: list of face objects, which must be part of the solid. - :param thickness: floating point thickness. positive shells outwards, negative shells inwards - :param tolerance: modelling tolerance of the method, default=0.0001 - :return: a shelled solid - - **WARNING** The underlying FreeCAD implementation can very frequently have problems - with shelling complex geometries! - """ - nativeFaces = [f.wrapped for f in faceList] - return Shape.cast(self.wrapped.makeThickness(nativeFaces, thickness, tolerance)) - - -class Compound(Shape): - """ - a collection of disconnected solids - """ - - def __init__(self, obj): - """ - An Edge - """ - self.wrapped = obj - - # Helps identify this solid through the use of an ID - self.label = "" - - def Center(self): - return self.Center() - - @classmethod - def makeCompound(cls, listOfShapes): - """ - Create a compound out of a list of shapes - """ - solids = [s.wrapped for s in listOfShapes] - c = FreeCADPart.Compound(solids) - return Shape.cast(c) - - def fuse(self, toJoin): - return Shape.cast(self.wrapped.fuse(toJoin.wrapped)) - - def tessellate(self, tolerance): - return self.wrapped.tessellate(tolerance) - - def clean(self): - """This method is not implemented yet.""" - return self diff --git a/Libs/cadquery-lib/cadquery/plugins/__init__.py b/Libs/cadquery-lib/cadquery/plugins/__init__.py deleted file mode 100644 index 3697b9f..0000000 --- a/Libs/cadquery-lib/cadquery/plugins/__init__.py +++ /dev/null @@ -1,18 +0,0 @@ -""" - CadQuery - Copyright (C) 2015 Parametric Products Intellectual Holdings, LLC - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -""" diff --git a/Libs/cadquery-lib/cadquery/selectors.py b/Libs/cadquery-lib/cadquery/selectors.py deleted file mode 100644 index a2d476e..0000000 --- a/Libs/cadquery-lib/cadquery/selectors.py +++ /dev/null @@ -1,663 +0,0 @@ -""" - Copyright (C) 2011-2015 Parametric Products Intellectual Holdings, LLC - - This file is part of CadQuery. - - CadQuery is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - CadQuery 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; If not, see -""" - -import re -import math -from cadquery import Vector,Edge,Vertex,Face,Solid,Shell,Compound -from collections import defaultdict -from pyparsing import Literal,Word,nums,Optional,Combine,oneOf,upcaseTokens,\ - CaselessLiteral,Group,infixNotation,opAssoc,Forward,\ - ZeroOrMore,Keyword - - -class Selector(object): - """ - Filters a list of objects - - Filters must provide a single method that filters objects. - """ - def filter(self,objectList): - """ - Filter the provided list - :param objectList: list to filter - :type objectList: list of FreeCAD primatives - :return: filtered list - - The default implementation returns the original list unfiltered - - """ - return objectList - - def __and__(self, other): - return AndSelector(self, other) - - def __add__(self, other): - return SumSelector(self, other) - - def __sub__(self, other): - return SubtractSelector(self, other) - - def __neg__(self): - return InverseSelector(self) - -class NearestToPointSelector(Selector): - """ - Selects object nearest the provided point. - - If the object is a vertex or point, the distance - is used. For other kinds of shapes, the center of mass - is used to to compute which is closest. - - Applicability: All Types of Shapes - - Example:: - - CQ(aCube).vertices(NearestToPointSelector((0,1,0)) - - returns the vertex of the unit cube closest to the point x=0,y=1,z=0 - - """ - def __init__(self,pnt ): - self.pnt = pnt - def filter(self,objectList): - - def dist(tShape): - return tShape.Center().sub(Vector(*self.pnt)).Length - #if tShape.ShapeType == 'Vertex': - # return tShape.Point.sub(toVector(self.pnt)).Length - #else: - # return tShape.CenterOfMass.sub(toVector(self.pnt)).Length - - return [ min(objectList,key=dist) ] - -class BoxSelector(Selector): - """ - Selects objects inside the 3D box defined by 2 points. - - If `boundingbox` is True only the objects that have their bounding - box inside the given box is selected. Otherwise only center point - of the object is tested. - - Applicability: all types of shapes - - Example:: - - CQ(aCube).edges(BoxSelector((0,1,0), (1,2,1)) - """ - def __init__(self, point0, point1, boundingbox=False): - self.p0 = Vector(*point0) - self.p1 = Vector(*point1) - self.test_boundingbox = boundingbox - - def filter(self, objectList): - - result = [] - x0, y0, z0 = self.p0.toTuple() - x1, y1, z1 = self.p1.toTuple() - - def isInsideBox(p): - # using XOR for checking if x/y/z is in between regardless - # of order of x/y/z0 and x/y/z1 - return ((p.x < x0) ^ (p.x < x1)) and \ - ((p.y < y0) ^ (p.y < y1)) and \ - ((p.z < z0) ^ (p.z < z1)) - - for o in objectList: - if self.test_boundingbox: - bb = o.BoundingBox() - if isInsideBox(Vector(bb.xmin, bb.ymin, bb.zmin)) and \ - isInsideBox(Vector(bb.xmax, bb.ymax, bb.zmax)): - result.append(o) - else: - if isInsideBox(o.Center()): - result.append(o) - - return result - -class BaseDirSelector(Selector): - """ - A selector that handles selection on the basis of a single - direction vector - """ - def __init__(self,vector,tolerance=0.0001 ): - self.direction = vector - self.TOLERANCE = tolerance - - def test(self,vec): - "Test a specified vector. Subclasses override to provide other implementations" - return True - - def filter(self,objectList): - """ - There are lots of kinds of filters, but - for planes they are always based on the normal of the plane, - and for edges on the tangent vector along the edge - """ - r = [] - for o in objectList: - #no really good way to avoid a switch here, edges and faces are simply different! - - if type(o) == Face: - # a face is only parallell to a direction if it is a plane, and its normal is parallel to the dir - normal = o.normalAt(None) - - if self.test(normal): - r.append(o) - elif type(o) == Edge and o.geomType() == 'LINE': - #an edge is parallel to a direction if it is a line, and the line is parallel to the dir - tangent = o.tangentAt(None) - if self.test(tangent): - r.append(o) - - return r - -class ParallelDirSelector(BaseDirSelector): - """ - Selects objects parallel with the provided direction - - Applicability: - Linear Edges - Planar Faces - - Use the string syntax shortcut \|(X|Y|Z) if you want to select - based on a cardinal direction. - - Example:: - - CQ(aCube).faces(ParallelDirSelector((0,0,1)) - - selects faces with a normals in the z direction, and is equivalent to:: - - CQ(aCube).faces("|Z") - """ - - def test(self,vec): - return self.direction.cross(vec).Length < self.TOLERANCE - -class DirectionSelector(BaseDirSelector): - """ - Selects objects aligned with the provided direction - - Applicability: - Linear Edges - Planar Faces - - Use the string syntax shortcut +/-(X|Y|Z) if you want to select - based on a cardinal direction. - - Example:: - - CQ(aCube).faces(DirectionSelector((0,0,1)) - - selects faces with a normals in the z direction, and is equivalent to:: - - CQ(aCube).faces("+Z") - """ - - def test(self,vec): - return abs(self.direction.getAngle(vec) < self.TOLERANCE) - -class PerpendicularDirSelector(BaseDirSelector): - """ - Selects objects perpendicular with the provided direction - - Applicability: - Linear Edges - Planar Faces - - Use the string syntax shortcut #(X|Y|Z) if you want to select - based on a cardinal direction. - - Example:: - - CQ(aCube).faces(PerpendicularDirSelector((0,0,1)) - - selects faces with a normals perpendicular to the z direction, and is equivalent to:: - - CQ(aCube).faces("#Z") - """ - - def test(self,vec): - angle = self.direction.getAngle(vec) - r = (abs(angle) < self.TOLERANCE) or (abs(angle - math.pi) < self.TOLERANCE ) - return not r - - -class TypeSelector(Selector): - """ - Selects objects of the prescribed topological type. - - Applicability: - Faces: Plane,Cylinder,Sphere - Edges: Line,Circle,Arc - - You can use the shortcut selector %(PLANE|SPHERE|CONE) for faces, - and %(LINE|ARC|CIRCLE) for edges. - - For example this:: - - CQ(aCube).faces ( TypeSelector("PLANE") ) - - will select 6 faces, and is equivalent to:: - - CQ(aCube).faces( "%PLANE" ) - - """ - def __init__(self,typeString): - self.typeString = typeString.upper() - - def filter(self,objectList): - r = [] - for o in objectList: - if o.geomType() == self.typeString: - r.append(o) - return r - -class DirectionMinMaxSelector(Selector): - """ - Selects objects closest or farthest in the specified direction - Used for faces, points, and edges - - Applicability: - All object types. for a vertex, its point is used. for all other kinds - of objects, the center of mass of the object is used. - - You can use the string shortcuts >(X|Y|Z) or <(X|Y|Z) if you want to - select based on a cardinal direction. - - For example this:: - - CQ(aCube).faces ( DirectionMinMaxSelector((0,0,1),True ) - - Means to select the face having the center of mass farthest in the positive z direction, - and is the same as: - - CQ(aCube).faces( ">Z" ) - - """ - def __init__(self, vector, directionMax=True, tolerance=0.0001): - self.vector = vector - self.max = max - self.directionMax = directionMax - self.TOLERANCE = tolerance - def filter(self,objectList): - - def distance(tShape): - return tShape.Center().dot(self.vector) - - # import OrderedDict - from collections import OrderedDict - #make and distance to object dict - objectDict = {distance(el) : el for el in objectList} - #transform it into an ordered dict - objectDict = OrderedDict(sorted(objectDict.items(), - key=lambda x: x[0])) - - # find out the max/min distance - if self.directionMax: - d = objectDict.keys()[-1] - else: - d = objectDict.keys()[0] - - # return all objects at the max/min distance (within a tolerance) - return filter(lambda o: abs(d - distance(o)) < self.TOLERANCE, objectList) - -class DirectionNthSelector(ParallelDirSelector): - """ - Selects nth object parallel (or normal) to the specified direction - Used for faces and edges - - Applicability: - Linear Edges - Planar Faces - """ - def __init__(self, vector, n, directionMax=True, tolerance=0.0001): - self.direction = vector - self.max = max - self.directionMax = directionMax - self.TOLERANCE = tolerance - self.N = n - - def filter(self,objectList): - #select first the objects that are normal/parallel to a given dir - objectList = super(DirectionNthSelector,self).filter(objectList) - - def distance(tShape): - return tShape.Center().dot(self.direction) - - #calculate how many digits of precision do we need - digits = int(1/self.TOLERANCE) - - #make a distance to object dict - #this is one to many mapping so I am using a default dict with list - objectDict = defaultdict(list) - for el in objectList: - objectDict[round(distance(el),digits)].append(el) - - # choose the Nth unique rounded distance - nth_distance = sorted(objectDict.keys(), - reverse=not self.directionMax)[self.N] - - # map back to original objects and return - return objectDict[nth_distance] - -class BinarySelector(Selector): - """ - Base class for selectors that operates with two other - selectors. Subclass must implement the :filterResults(): method. - """ - def __init__(self, left, right): - self.left = left - self.right = right - - def filter(self, objectList): - return self.filterResults(self.left.filter(objectList), - self.right.filter(objectList)) - - def filterResults(self, r_left, r_right): - raise NotImplementedError - -class AndSelector(BinarySelector): - """ - Intersection selector. Returns objects that is selected by both selectors. - """ - def filterResults(self, r_left, r_right): - # return intersection of lists - return list(set(r_left) & set(r_right)) - -class SumSelector(BinarySelector): - """ - Union selector. Returns the sum of two selectors results. - """ - def filterResults(self, r_left, r_right): - # return the union (no duplicates) of lists - return list(set(r_left + r_right)) - -class SubtractSelector(BinarySelector): - """ - Difference selector. Substract results of a selector from another - selectors results. - """ - def filterResults(self, r_left, r_right): - return list(set(r_left) - set(r_right)) - -class InverseSelector(Selector): - """ - Inverts the selection of given selector. In other words, selects - all objects that is not selected by given selector. - """ - def __init__(self, selector): - self.selector = selector - - def filter(self, objectList): - # note that Selector() selects everything - return SubtractSelector(Selector(), self.selector).filter(objectList) - - -def _makeGrammar(): - """ - Define the simple string selector grammar using PyParsing - """ - - #float definition - point = Literal('.') - plusmin = Literal('+') | Literal('-') - number = Word(nums) - integer = Combine(Optional(plusmin) + number) - floatn = Combine(integer + Optional(point + Optional(number))) - - #vector definition - lbracket = Literal('(') - rbracket = Literal(')') - comma = Literal(',') - vector = Combine(lbracket + floatn('x') + comma + \ - floatn('y') + comma + floatn('z') + rbracket) - - #direction definition - simple_dir = oneOf(['X','Y','Z','XY','XZ','YZ']) - direction = simple_dir('simple_dir') | vector('vector_dir') - - #CQ type definition - cqtype = oneOf(['Plane','Cylinder','Sphere','Cone','Line','Circle','Arc'], - caseless=True) - cqtype = cqtype.setParseAction(upcaseTokens) - - #type operator - type_op = Literal('%') - - #direction operator - direction_op = oneOf(['>','<']) - - #index definition - ix_number = Group(Optional('-')+Word(nums)) - lsqbracket = Literal('[').suppress() - rsqbracket = Literal(']').suppress() - - index = lsqbracket + ix_number('index') + rsqbracket - - #other operators - other_op = oneOf(['|','#','+','-']) - - #named view - named_view = oneOf(['front','back','left','right','top','bottom']) - - return direction('only_dir') | \ - (type_op('type_op') + cqtype('cq_type')) | \ - (direction_op('dir_op') + direction('dir') + Optional(index)) | \ - (other_op('other_op') + direction('dir')) | \ - named_view('named_view') - -_grammar = _makeGrammar() #make a grammar instance - -class _SimpleStringSyntaxSelector(Selector): - """ - This is a private class that converts a parseResults object into a simple - selector object - """ - def __init__(self,parseResults): - - #define all token to object mappings - self.axes = { - 'X': Vector(1,0,0), - 'Y': Vector(0,1,0), - 'Z': Vector(0,0,1), - 'XY': Vector(1,1,0), - 'YZ': Vector(0,1,1), - 'XZ': Vector(1,0,1) - } - - self.namedViews = { - 'front' : (Vector(0,0,1),True), - 'back' : (Vector(0,0,1),False), - 'left' : (Vector(1,0,0),False), - 'right' : (Vector(1,0,0),True), - 'top' : (Vector(0,1,0),True), - 'bottom': (Vector(0,1,0),False) - } - - self.operatorMinMax = { - '>' : True, - '<' : False, - '+' : True, - '-' : False - } - - self.operator = { - '+' : DirectionSelector, - '-' : DirectionSelector, - '#' : PerpendicularDirSelector, - '|' : ParallelDirSelector} - - self.parseResults = parseResults - self.mySelector = self._chooseSelector(parseResults) - - def _chooseSelector(self,pr): - """ - Sets up the underlying filters accordingly - """ - if 'only_dir' in pr: - vec = self._getVector(pr) - return DirectionSelector(vec) - - elif 'type_op' in pr: - return TypeSelector(pr.cq_type) - - elif 'dir_op' in pr: - vec = self._getVector(pr) - minmax = self.operatorMinMax[pr.dir_op] - - if 'index' in pr: - return DirectionNthSelector(vec,int(''.join(pr.index.asList())),minmax) - else: - return DirectionMinMaxSelector(vec,minmax) - - elif 'other_op' in pr: - vec = self._getVector(pr) - return self.operator[pr.other_op](vec) - - else: - args = self.namedViews[pr.named_view] - return DirectionMinMaxSelector(*args) - - def _getVector(self,pr): - """ - Translate parsed vector string into a CQ Vector - """ - if 'vector_dir' in pr: - vec = pr.vector_dir - return Vector(float(vec.x),float(vec.y),float(vec.z)) - else: - return self.axes[pr.simple_dir] - - def filter(self,objectList): - """ - selects minimum, maximum, positive or negative values relative to a direction - [+\|-\|<\|>\|] \ - """ - return self.mySelector.filter(objectList) - -def _makeExpressionGrammar(atom): - """ - Define the complex string selector grammar using PyParsing (which supports - logical operations and nesting) - """ - - #define operators - and_op = Literal('and') - or_op = Literal('or') - delta_op = oneOf(['exc','except']) - not_op = Literal('not') - - def atom_callback(res): - return _SimpleStringSyntaxSelector(res) - - atom.setParseAction(atom_callback) #construct a simple selector from every matched - - #define callback functions for all operations - def and_callback(res): - items = res.asList()[0][::2] #take every secend items, i.e. all operands - return reduce(AndSelector,items) - - def or_callback(res): - items = res.asList()[0][::2] #take every secend items, i.e. all operands - return reduce(SumSelector,items) - - def exc_callback(res): - items = res.asList()[0][::2] #take every secend items, i.e. all operands - return reduce(SubtractSelector,items) - - def not_callback(res): - right = res.asList()[0][1] #take second item, i.e. the operand - return InverseSelector(right) - - #construct the final grammar and set all the callbacks - expr = infixNotation(atom, - [(and_op,2,opAssoc.LEFT,and_callback), - (or_op,2,opAssoc.LEFT,or_callback), - (delta_op,2,opAssoc.LEFT,exc_callback), - (not_op,1,opAssoc.RIGHT,not_callback)]) - - return expr - -_expression_grammar = _makeExpressionGrammar(_grammar) - -class StringSyntaxSelector(Selector): - """ - Filter lists objects using a simple string syntax. All of the filters available in the string syntax - are also available ( usually with more functionality ) through the creation of full-fledged - selector objects. see :py:class:`Selector` and its subclasses - - Filtering works differently depending on the type of object list being filtered. - - :param selectorString: A two-part selector string, [selector][axis] - - :return: objects that match the specified selector - - ***Modfiers*** are ``('|','+','-','<','>','%')`` - - :\|: - parallel to ( same as :py:class:`ParallelDirSelector` ). Can return multiple objects. - :#: - perpendicular to (same as :py:class:`PerpendicularDirSelector` ) - :+: - positive direction (same as :py:class:`DirectionSelector` ) - :-: - negative direction (same as :py:class:`DirectionSelector` ) - :>: - maximize (same as :py:class:`DirectionMinMaxSelector` with directionMax=True) - :<: - minimize (same as :py:class:`DirectionMinMaxSelector` with directionMax=False ) - :%: - curve/surface type (same as :py:class:`TypeSelector`) - - ***axisStrings*** are: ``X,Y,Z,XY,YZ,XZ`` or ``(x,y,z)`` which defines an arbitrary direction - - It is possible to combine simple selectors together using logical operations. - The following operations are suuported - - :and: - Logical AND, e.g. >X and >Y - :or: - Logical OR, e.g. |X or |Y - :not: - Logical NOT, e.g. not #XY - :exc(ept): - Set difference (equivalent to AND NOT): |X exc >Z - - Finally, it is also possible to use even more complex expressions with nesting - and arbitrary number of terms, e.g. - - (not >X[0] and #XY) or >XY[0] - - Selectors are a complex topic: see :ref:`selector_reference` for more information - """ - def __init__(self,selectorString): - """ - Feed the input string through the parser and construct an relevant complex selector object - """ - self.selectorString = selectorString - parse_result = _expression_grammar.parseString(selectorString, - parseAll=True) - self.mySelector = parse_result.asList()[0] - - def filter(self,objectList): - """ - Filter give object list through th already constructed complex selector object - """ - return self.mySelector.filter(objectList) \ No newline at end of file diff --git a/Libs/cadquery-lib/changes.md b/Libs/cadquery-lib/changes.md deleted file mode 100644 index 24d08ab..0000000 --- a/Libs/cadquery-lib/changes.md +++ /dev/null @@ -1,100 +0,0 @@ -Changes -======= - - -v0.1 ------ - * Initial Version - -v0.1.6 ------ - * Added STEP import and supporting tests - -v0.1.7 ------ - * Added revolve operation and supporting tests - * Fixed minor documentation errors - -v0.1.8 ------ - * Added toFreecad() function as a convenience for val().wrapped - * Converted all examples to use toFreecad() - * Updated all version numbers that were missed before - * Fixed import issues in Windows caused by fc_import - * Added/fixed Mac OS support - * Improved STEP import - * Fixed bug in rotateAboutCenter that negated its effect on solids - * Added Travis config (thanks @krasin) - * Removed redundant workplane.py file left over from the PParts.com migration - * Fixed toWorldCoordinates bug in moveTo (thanks @xix-xeaon) - * Added new tests for 2D drawing functions - * Integrated Coveralls.io, with a badge in README.md - * Integrated version badge in README.md - -v0.2.0 ------ - * Fixed versioning to match the semantic versioning scheme - * Added license badge in changes.md - * Fixed Solid.makeSphere implementation - * Added CQ.sphere operation that mirrors CQ.box - * Updated copyright dates - * Cleaned up spelling and misc errors in docstrings - * Fixed FreeCAD import error on Arch Linux (thanks @moeb) - * Made FreeCAD import report import error instead of silently failing (thanks @moeb) - * Added ruled option for the loft operation (thanks @hyOzd) - * Fixed close() not working in planes other than XY (thanks @hyOzd) - * Added box selector with bounding box option (thanks @hyOzd) - * CQ.translate and CQ.rotate documentation fixes (thanks @hyOzd) - * Fixed centering of a sphere - * Increased test coverage - * Added a clean function to keep some operations from failing on solids that need simplified (thanks @hyOzd) - * Added a mention of the new Google Group to the readme - -v0.3.0 ------ - * Fixed a bug where clean() could not be called on appropriate objects other than solids (thanks @hyOzd) #108 - * Implemented new selectors that allow existing selectors to be combined with arithmetic/boolean operations (thanks @hyOzd) #110 - * Fixed a bug where only 1 random edge was returned with multiple min/max selector matches (thanks @hyOzd) #111 - * Implemented the creation of a workplane from multiple co-planar faces (thanks @hyOzd) #113 - * Fixed the operation of Center() when called on a compound with multiple solids - * Add the named planes ZX YX ZY to define different normals (thanks @galou) #115 - * Code cleanup in accordance with PEP 8 (thanks @galou) - * Fixed a bug with the close function not resetting the first point of the context correctly (thanks @huskier) - * Fixed the findSolid function so that it handles compounds #107 - * Changed the polyline function so that it adds edges to the stack instead of a wire #102 - * Add the ability to find the center of the bounding box, rather than the center of mass (thanks @huskier) #122 - * Changed normalize function to normalized to match OCC/PythonOCC nomenclature #124 - * Added a label attribute to all freecad_impl.shapes so that they can have IDs attached to them #124 - -v0.4.0 ------- - * Added Documentation, which is available on dcowden.github.io/cadquery - * Added CQGI, an adapter API that standardizes use of cadquery from within structured execution environments - * Added ability to import STEP files from a web URL (thanks @huskier ) #128 - -v0.4.1 ------- - * Minor CQGI updates - -v0.5.0-stable ------- - * Configuring Travis to push to PyPI on version releases. - -v0.5.1 ------- - * Mirroring fixes (thanks @huskier) - * Added a mirroring example (thanks @huskier) - -v0.5.2 ------- - * Added the sweep operation #33 - -v1.0.0 ------- - * Added an option to do symmetric extrusion about the workplane (thanks @adam-urbanczyk) - * Extended selector syntax to include Nth selector and re-implemented selectors using pyparsing (thanks @adam-urbanczyk) - * Added logical operations to string selectors (thanks @adam-urbanczyk) - * Cleanup of README.md and changes.md (thanks @baoboa) - * Fixed bugs with toVector and Face 'Not Defined' errors (thanks @huskier) - * Refactor of the initialization code for PEP8 compliance and Python 3 compatibility (thanks @Peque) - * Making sure that the new pyparsing library dependency is handled properly (thanks @Peque) diff --git a/Libs/cadquery-lib/doc/README b/Libs/cadquery-lib/doc/README deleted file mode 100644 index b89ab3d..0000000 --- a/Libs/cadquery-lib/doc/README +++ /dev/null @@ -1,2 +0,0 @@ -This documentation should be generated with sphinxdoc. -see ../build-docs.sh diff --git a/Libs/cadquery-lib/doc/_static/ParametricPulley.PNG b/Libs/cadquery-lib/doc/_static/ParametricPulley.PNG deleted file mode 100644 index c5e6e873038fd3beb443fa8bfd146c649578e126..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 59186 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 T>-QPnJwjboR>u}98VCF@W7%6e diff --git a/Libs/cadquery-lib/doc/_static/cadquery_cheatsheet.html b/Libs/cadquery-lib/doc/_static/cadquery_cheatsheet.html deleted file mode 100644 index bb58252..0000000 --- a/Libs/cadquery-lib/doc/_static/cadquery_cheatsheet.html +++ /dev/null @@ -1,404 +0,0 @@ - - - - CadQuery Cheatsheet - - - - - -

- -
-

BREP Terminology


- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
vertexA single point in space
edgeA connection between two or more vertices along a particular path (called a curve)
wireA collection of edges that are connected together
faceA set of edges or wires that enclose a surface
shellA collection of faces that are connected together along some of their edges
solidA shell that has a closed interior
compoundA collection of solids
-
-
-

Named Planes


- Available named planes are as follows. Direction references refer to the global directions. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NamexDiryDirzDir
XY+x+y+z
YZ+y+z+x
XZ+x+z-y
front+x+y+z
back-x+y-z
left+z+y-x
right-z+y+x
top+x-z+y
bottom+x+z-y
-
-
-

Core Classes


- - - - - - - - - - - - - - - - - -
ClassDescription
CQ(obj)Provides enhanced functionality for a wrapped CAD primitive.
Plane(origin, xDir, normal)A 2d coordinate system in space, with the x-y axes on the a plane, and a particular point as the origin.
Workplane(inPlane[origin, obj])Defines a coordinate system in space, in which 2-d coordinates can be used.
-
-
-
-
-

Selector Methods


- CadQuery selector strings allow filtering various types of object lists. - Most commonly, Edges, Faces, and Vertices are used, but all objects types can be filtered.
- - - - - - - - - - - - - - - - - - - - - - - - -
Selector MethodDescription
CQ.faces(selector=None)Select the faces of objects on the stack, optionally filtering the selection.
CQ.edges(selector=None)Select the edges of objects on the stack, optionally filtering the selection.
CQ.vertices(selector=None)Select the vertices of objects on the stack, optionally filtering the selection.
CQ.solids(selector=None)Select the solids of objects on the stack, optionally filtering the selection.
CQ.shells(selector=None)Select the shells of objects on the stack, optionally filtering the selection.
-
-
-

Selector Classes


- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ClassDescription
NearestToPointSelector(pnt)Selects object nearest the provided point.
ParallelDirSelector(vector[tolerance])Selects objects parallel with the provided direction.
DirectionSelector(vector[tolerance])Selects objects aligned with the provided direction.
PerpendicularDirSelector(vector[tolerance])Selects objects perpendicular with the provided direction.
TypeSelector(typeString)Selects objects of the prescribed topological type.
DirectionMinMaxSelector(vector[directionMax])Selects objects closest or farthest in the specified direction.
StringSyntaxSelector(selectorString)Filter lists objects using a simple string syntax.
-
-
-

Selector String Modifiers


- Selectors are a complex topic: see CadQuery String Selectors for more information.
- Axis Strings are: X, Y, Z, XY, YZ, XZ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ModifierDescription
|Parallel to (same as ParallelDirSelector). Can return multiple objects.
#Perpendicular to (same as PerpendicularDirSelector)
+Positive direction (same as DirectionSelector)
-Negative direction (same as DirectionSelector)
>Maximize (same as DirectionMinMaxSelector with directionMax=True)
<Minimize (same as DirectionMinMaxSelector with directionMax=False)
%Curve/surface type (same as TypeSelector)
-
-
-

Examples of Filtering Faces


- All types of filters work on faces. In most cases, the selector refers to the direction of the normal vector of the face. - If a face is not planar, selectors are evaluated at the center of mass of the face. This can lead to results that are quite unexpected. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SelectorSelector ClassSelects# Objects Returned
+ZDirectionSelectorFaces with normal in +z direction0 or 1
|ZParallelDirSelectorFaces parallel to xy plane0..many
-XDirectionSelectorFaces with normal in neg x direction0..many
#ZPerpendicularDirSelectorFaces perpendicular to z direction0..many
%PlaneTypeSelectorFaces of type plane0..many
>YDirectionMinMaxSelectorFace farthest in the positive y dir0 or 1
<YDirectionMinMaxSelectorFace farthest in the negative y dir0 or 1
-
-
-

Examples of Filtering Edges


- Some filter types are not supported for edges. The selector usually refers to the direction of the edge. - Non-linear edges are not selected for any selectors except type (%). Non-linear edges are never returned when these filters are applied. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SelectorSelector ClassSelects# Objects Returned
+ZDirectionSelectorEdges aligned in the Z direction0..many
|ZParallelDirSelectorEdges parallel to z direction0..many
-XDirectionSelectorEdges aligned in neg x direction0..many
#ZPerpendicularDirSelectorEdges perpendicular to z direction0..many
%PlaneTypeSelectorEdges type line0..many
>YDirectionMinMaxSelectorEdges farthest in the positive y dir0 or 1
<YDirectionMinMaxSelectorEdges farthest in the negative y dir0 or 1
-
-
-

Examples of Filtering Vertices


- Only a few of the filter types apply to vertices. The location of the vertex is the subject of the filter. - - - - - - - - - - - - - - - - - - - -
SelectorSelector ClassSelects# Objects Returned
>YDirectionMinMaxSelectorVertices farthest in the positive y dir0 or 1
<YDirectionMinMaxSelectorVertices farthest in the negative y dir0 or 1
-
-
- - diff --git a/Libs/cadquery-lib/doc/_static/cqlogo.png b/Libs/cadquery-lib/doc/_static/cqlogo.png deleted file mode 100644 index 529ffef0475da5485b9004b5d05e6975b29cb5e2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3136 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 Jd!p+Y`9HaY$iM&q diff --git a/Libs/cadquery-lib/doc/_static/hyOzd-finished.jpg b/Libs/cadquery-lib/doc/_static/hyOzd-finished.jpg deleted file mode 100644 index ec5656773f8e8c06fb505155c113805f1d6197b5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 149415 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≫b{*KN9$LQ8Y_zd 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%0ABeGQ#22eMA=_`azMb6nt@ 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 diff --git a/Libs/cadquery-lib/doc/_static/quickstart-2.png b/Libs/cadquery-lib/doc/_static/quickstart-2.png deleted file mode 100644 index 6dd6e9a7e1003d48c472660078dddf2eb3848155..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6162 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 diff --git a/Libs/cadquery-lib/doc/_static/quickstart-3.png b/Libs/cadquery-lib/doc/_static/quickstart-3.png deleted file mode 100644 index e4997f0c91fd549e4d21df207873798022befb20..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7084 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 diff --git a/Libs/cadquery-lib/doc/_static/quickstart.png b/Libs/cadquery-lib/doc/_static/quickstart.png deleted file mode 100644 index 467b9c75fce2dd0518ab2cde418e4aa36c1b6d00..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17947 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�Y%{ZlN{}Nmtx)1)lC-a&YdI30P?kJUT3|MM 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 diff --git a/Libs/cadquery-lib/doc/_static/quickstart/002.png b/Libs/cadquery-lib/doc/_static/quickstart/002.png deleted file mode 100644 index 8b8ab367bbe1d95659835e5b1090d9abc69b7df8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 120334 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

$EfdIJv@@tWWw@-n_S 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 diff --git a/Libs/cadquery-lib/doc/_static/quickstart/003.png b/Libs/cadquery-lib/doc/_static/quickstart/003.png deleted file mode 100644 index 8aaa128ce5c867e2fd080be5f199181275d91098..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 123947 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 diff --git a/Libs/cadquery-lib/doc/_static/quickstart/005.png b/Libs/cadquery-lib/doc/_static/quickstart/005.png deleted file mode 100644 index 0dbbb12a0ac343d85ec9a85b01f3b44491aad9c3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 136681 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 z

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

#mqi0H>x}H2ntjyV$8I>GA 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

V+)~o>>}Xda#&v3S%FN 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 diff --git a/Libs/cadquery-lib/doc/_static/simpleblock.png b/Libs/cadquery-lib/doc/_static/simpleblock.png deleted file mode 100644 index 5ac69058e109c08890973ba5ed70e12ac0f73609..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8698 zcmds7_dAvG-#?X6Mn?9`3CTECR%RR{5lONlBV_NDm3a`-NfJ_|=-4yan=%rPy&@Ee z%!r=%{eAv{=enL>p6luA%3WROzCZWp{eHjJ=fvt?)1;x$ zE}T94Ed5C{Rr<$up?fXyAFrumHV)*LUYw|@k!j5P`}gr(Z#%uCG^6YTV{B;=<#RQ??uZhW~aYSkQ0y1unl z@%=v223{YRS7~TuBt2^DBt7yj+RW6{)D0i(zPYiHfApc$CnYsi?d_n|+GNdWt)D29 zsKvun%Me!UQWuTTv5eTfZYnahoOEX^D;^383VmZ^Tv=J!0h_%Idtqv7>dhHF_zwvQ ziO13JLVtiJJJQz&hyJAarY5QzVwZh59r*{H}owyCMfh!ESG)^&P$dq1$#awX85Fie!^ z)gNhiuG_<<@GQegP)Mlt_qR`_9`hPHSxTJ08V)eF5^2Lu)?WPdw3*jN^3q6Y)<(X2 zC$NPEuivMkp)qT`dpS=;PI-BMd&Pfu%5S5SJM>O_9Halvn0=w?nRLlyMnglxi;h$~ z&AoTTE;{A>grMn2~je*abqC&Ds%iuTR`8I z)@O%{y3e`IwkyY+i>hm?+-8m%7~pRN0-T%& zK1YPkc-C4_aRehzh z)R*aW_`uu4qjY;B;Pr52OYy6JhU}(uw?<~FtE*+O=<7Kv1U9eJl$7OPvs4F50BPjDRmx`5MZD%OSSW&!6@BZefW5s zDQjpFp6ZnO!QL%i@12<387aK6aEDNFUAV`5hgJ7uKHS5HZL4GD;=%jgvX`n3Lpyv# zlyV8W(q{faBQJvX`!pJl|Fb`1`m5xP~>MksEG^P34~PM3CRd3Tc_7PRMX zmP+<=uKm1^)L1lA7701|$hd9IUYi7bN|+aoK7M~^wYgvU-^1$ZKuS6~I^+64sY|}A z4#}G`b{kh*EM+S8crRY8Ac~t{luAYT?a`F%a-O`=r#a&)okq|Y%;_6%behSzgY>6X zpO@{uUbNxI=TEbv6yNW?cC^8}q{CwhRM5$H7JJg3$$FrfgpI=*f)9*j%);XJ@~m|F zutp5Dv|*x+f9atg&R@$=srCISEBc&G9oLLqipv+|=GqIyN?@rKi_fXjc8wAm90ri6p8!4QJZsa8Z?)-fDMkibcZq zWOjD;*<>wRZf+VBEC3bu!+Ujk`DDH!1!{eFmmIaQu+U^H!K0|ishvyT(9j_5f4-$< zK?mDwCz0m z$)C+Hp5Ci<<;nwdjHbCcN1OGhqpnM`vS$SaDI&;eG#niTeSeOV;=64JMjR+3pJm7` z>hS8Pq@(~&ERU9+vz0Kx$A~^}X>C1GT3Y&fWxK1pySX=AhR|8cO$rS=-DduOGkiGoX_7)-}N zj;6=nx>bf!Fk7|TjK;NVr>V$Jyf(Oyk(oJAZm$Q0XzA=EkByD>RU|~f*0UK}SS0pk z%HPrpE@uE@f;X^ki97|csi<_gbz^UT|LfuIOlQ&UTBz5{0f%*f;+F32Q*Moi(yFSe z?(nS0m>8R`M?B$IQ=cMbpx%cM&@nQS-nw-wK6A4z_Kg2hrXTXr{gq;y)@bTSpT1Qp z`N1bxE;`Tx2}aN;?V*0v?{Wd-mH@p`aVfBzAfsyfF-)MNr?)QMcTRwX{z%EpOnCoZ z7T(r)A&8HU&wrzxSv=&gf8F8Egsj&h6;QE}y-iV>!vMO#vXP4{;uz|szJQq9w1Rnk zAY+o^4vV#o%|@@xjPYv?9$ITpJA^nZO zXF`)kEbdbSLba6lD^09!B0JID-R-lsyS3E@u=XfDJ^s(;lFWfmWEgCT<4t}2Ftcjc z=BcTA^`$FUt~6KN8!YkrWw8ZYr@rI}HAKw<`}-(q^5d;mh=rpK!SYqEQ{&kq<$TD} zQ)+AFFL^J2&h~frJ2s0zt)x^=Ow%| zUU&rncQYfF1jgi@x*8i0h^o3e>2$ynC#4bT-k(2n(1ZzrYuW1Yv`kFVu!Uz86ehEM zjM-t66tRTiuM6FHcXxLO;zoOW`!nTGC27~m(N(V@b-@(Xw}VnYYSz}){DF`+KXj$Wlvtg35%l{?e1hbNp}G0wY%{uO`x__470u%fO@-{s4fmnUl^4Gatl43a8=P6yNgVBWnglp2QD z1!j8yKg_D~{(1czmx_#zmj3=M`JARwMVbEcf9@Pu-!NU%wmk+VcoBLO@QKM#4fJDn zPENWv=(*rWPoLW5#uXqV$%Rh+1ga^OpZk`HNvz`iojag$jPib1I6l?R)fY_By@UZ? zO~u?U)7B*-6IZFNtLyTcIuc`1cQV&tY+-TCSoz;yNg&bjg?Sj#cfY8ojQ+D?ESheA z>w838TpT~A-~QIUwzf9oe8Jh;Uk$BZ{fZ+6HhlC~(w~>|v@J|7s0+*lZBirm)YI!X zEv6MUtD=If$Hm39yuN}LHsDRJuMODbXP{8WuW|YP`F)ol^<-tFc)lfyvRAvWsXjh~ zE#b`-Nk!*;AXZjZ*5#4ntir4L#D&GxZ{MOAg^W}LQ_#}VI}MF>$UA}{$;-=YdZBn< z*i;}{5xSM#b-HfswT+?RO}r>kim1sQ9GQRPE%3<275_pb%6vn|xpxJcxbB+nRh8_I_15N9mW@K<6 z+N;-sqG;Ih)!_HpZ{P0DeJtq2bY!Tb>5Pgkr~$ytYdlHeb0<)%lQm~XiY;RZ1R=P! z&4z01YMK_WY7&>C`=8(6G`Qy%7Hl`ZjW^XllJfa6WEW~^Sm+B*~L+Yi8M?J*z9n`>}k$gxu0X|&3P z{b+BVM%es)$=H&Xu5RVHdwk`nx@Xbv{?MZ{fE(|9f3ksXO2*?)r0H}F=?v*W!>@za z*&Wn$1osiHom)1#vIOJ(vwEgu#4>a$d*kbTXHt&aOal{vAT_EBYkP2lJX-*Ffgf~Z8xdsKMl^@aSbc*kw@qmP2c-ZP>SvWaelJ9=Gd-pD) zfi)62Vr6E6%GH-H1^njivGYo&yyu&eaqKK;KTdgH68B$t+Q^+n+&J3a-d^EwYf#qb zhhe?V$LrUxclGwFySloTTMC^&Pk!puDP);XF}KH8Hx2(Rrn{|!GpyWGDC}K(EE)DA zUjfKp1QU%rvUG3|fW^S(I8OaqUdF+gevRP{aUlMIYR2vD`RioJ(n0?@4RqQbQ?an% zs&XC+2VgE#Un(W7z1oMhRRrMy08vv@BOoH8e)sM-wf=y)DCUxY%|-sq>WT`6!8f|C zFeD`*hkH4ODatf@gtD`-0CW3IQ7%e13nU(}a`gOXe!Y1KBM3>(VBAVx%#={b=Owc5)i@oXM_jjD*Gm0xg zrCu)w+&AtgS!a_xcYq#!6lOzv4n3!>_4>LA3jdPi(nrmma#J;_j z>AwBrCWo9SiDl46RQuZf>i{=ES9iwB?z%`wooLbN6FJ)Yi3oRis7kf#l<;*Ly5Z*D zUTT}p#CDKy?z?NZ^9%)f&!4yX+7@eEYE4Q;%@zq-;rM&MbAVtN9#K)62r}xHXW}*` zj>Ce4Nel1kx`6e~%~tRs)*D{cOg#KcOfpN#|Nitp&5OXXT>x|}^dLx%63=hi z54n}O)M8FYWo21zE4l+=-AUn_zDX>$Oo9fPg)Vg4AXPUji?97cmn??W)NBQHC@06N z7ERUs_s{0W@GZ-^>X{Iy6f++{6xMiVQA8ybdY*Vg^C)-@=?`)1BCyZRGxU0(H1->h|0I46y_B zWoIHME-^7$^;J_h{yZHUo8yDHs0Y9UrtM&O5iz$qUP%ecv^h!nXtaRer#VQWPl3`rGC; zd}W%Tc5w*_?O$@Qz8YCcPELOC_ixaXr%ziz`{x^?&z?p79IuSPxv;k}zxVxZ777J0p{Av!wXKBjj^w-gR3&EsF%fuv-Lji$SX(Pqoj&J2 zDeqs?oH-f^;iiQhW99ax_Wdt@1ZM^BuqypsSAzl1xa9LO`X+sHZpxD<=ehawYUO zWtp5zRWq?l>M0(7Bl7^%Bd(x87&r>hYrgw@78XctI%rdu-vKSp3vrc^Q(xi09kZ4@ zVlN8{R$q-Vlai7?Q@k$?&jP0r{p=Y_fkizV7^%_5P~}7px$w&oWR=$D#w4_gE$ER0zX}`HN=~IgUd14#Hd2z`#q8AB6)fjHK7a z=DC!9T9|AIzKu0~8n6c*ilJ}bx|^BpJ_X_xWH zV<*VY%FDAOcQi0~tUfJ7H}>K-|I)^MXHH(;Nx0L8UmifC0x8-83~@#-B_bY6eVoFU z4IDtDG*hF?pq)FR2#KJLFjyW(wH`Z3*yR8A_f`^VFGp5*=wrdk%`PlNPEMLHeEVhv zu=%LlwhF@<78NZ;M#T~aYnTNl9!~o1ed)=QC$rllmYsl-6IeBNNjs{Jhpac2LZ)LA zyL@3M;WylTD^Rh`TKwauPdv$5`VjPj?gCbMUt4=lS(zK;2k<;#Klks=O*#&ahu}d- zNJw77`-Fsqh_NMrojgfJ1?>|JdQ3xu?1T4r>+(m&?dV=P2?_efqkW;rczp7cCy}6f zPN0SyrI3sW0$Z!OmZ-fI%YPJ_nwPK9@?;wsnBhf)gdz+D)j?bMcx~_OAody3PuI!! z4pMGSD0rRL{(hRkdM+3*0a4Ky)54;V1`*?m8~nVyv(Vprze4}TgMxr%QKG_NcX|2w zt-*yEm)V{|97FoQVk}m~Mj}n$#N-s}vt#8WEnbKe+`YVNi);1|4(7)zogkReFfw9- zfDLJG@1Nt05G1G=8?%75rsd$EDj%bQ7{$%a4QWb9V?aPcq!I%wR#j6whB|ia7z$-+ zX^9F;O=U)MRz6<(Q(#f98yla5lzXDut#x>q5i)G`C708L0$L6zDA=|b-E`@j|E!Ly zz@s~oxRWgE1Lv9^oFMw&Lp!43k?>JSl^7TqUu9<>2N|JiV!{f1a^2kgA%KHwuE89H z1n<3;PM_wy6j|%{>ni}Hz=aFVpdelje%II6N6k*Fd&5>k8lj3w%>iKntJZ{MmyU%6 z2mRIr8(SZ^9iEg#1Cb{W*e9T>_a8n0ue6Mfu|jDO=eRxdzP`Smj*IIwxQB@5Fz}cv z#Us^@)JA3vB24k(cRw=N+S=av_Ay0YfMNImvTJegWqm5nOAPt>`9#47%gF}i-9~(k zFdTr1<_$rtxw*MoSFfspMoZ+BkA}uvooVD2Orf}N;Q|Q5Lf105ZmQ3+iNzj=K7dRf zi^VoU3j&gFi?;N?ygbm>FHtB)sZ%W1{;pOg-%w%q^b!sRo7g|o12@1^+2T| zf$Hk%ajqPx+OL;fPsKsR0Ev@YXjt+TUZ#fOLxB7 z-qFzl2R%@F$hG{|CQJ97s>TzN6ciOV=3=-J-FxHhwZbE*c924#xEnNdW@wF@Y9DL-x z`<$u|JsFCeoLq~S9?>n(x?nUT-@ZK$&X@ugPQ@-w1*QO(loXSm&JKOfgYW(f=TEZo z^5?|FXcH3?0b3y8uTz;Jkw~KgRQUYe8_|gWN$VyHFWX9|_ZrFHSA=F34?PMB`ggdS zXA%w;5z$p(@0te(2bpq{RS<*)>ug-*Y=TeRge)h4T}IfK?(Ms7?OX%c;wH%3AsB_} z?SP*DT;pYrELJm-qZw3|2ZWrk>4+PEH6acV_#`crwKMy{G202>* z0-{H~G5g4%O_8)vJh_QU{F^>d^G|GQzL-z->?ntDu{iXi+#iq|&8O{-B zKdZQO8@(MIo`CaH;&bYe*49>{+ZaE|SOx*of2-c-Qi#!md0U&Pwr;2Bc`ijD&Lb`! zPK-tZrhzDJ?d{DfjLKdhuMBlMNkh{KDkU5+l6Vj#z0{EpGvr5A_44IQVkb43T7)hU z`kx}|Yr`+I4}rg~pIiRa0(!)_Tdr=@lGA9v0Hmm>xPzB*A&6Z-F9 zX5;rKQRRz014j6AjhuT#_XlInuJGr74l*T%b9AMa1ntUeuE<;)ukkt$j7WnruJPnU z)TL93Mj@|=2sP-&yn=!@plmv3=3Djs#NHan0!)}2;GD4>6Etk@b9E<2S9MZd0Bj;o38X1FX2fNKIx;ShOHE0Ua-v9$ zh)^qk<9_NJ|1Vyua4xT^NSJg0NmV$6++6H+?(xOKxeEmT{)=h$B|(2Ykq`mm($0v0 zoQjGHlXyA~PEIG6HvszJ+SNviZacYDID;bb&CD45@&!4gfg}si0!ey^e94Re4b+nM zeOO2!wlmv+b$IE!)$%KgNX)$EKN^IZqqbg@G7gL;xLuiA+cKLK8mR9eH-5&)-i7BxK-Tk zL^)B5y1iHTJ!t7F`H*Y|H-2fl{sm4eY!t3ZaNsZhr and

headings. - headerlinkcolor (CSS color): Color for the backreference link in headings. - textalign (CSS text-align value): Text alignment for the body, default is justify. -""" -# Add any paths that contain custom themes here, relative to this directory. -#html_theme_path = [] - -# The name for this set of Sphinx documents. If None, it defaults to -# " v documentation". -html_title = "CadQuery Documentation" - -# A shorter title for the navigation bar. Default is the same as html_title. -#html_short_title = None - -# The name of an image file (relative to this directory) to place at the top -# of the sidebar. -html_logo = "_static/cqlogo.png" - -# The name of an image file (within the static path) to use as favicon of the -# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 -# pixels large. -#html_favicon = None - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] - -# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, -# using the given strftime format. -#html_last_updated_fmt = '%b %d, %Y' - -# If true, SmartyPants will be used to convert quotes and dashes to -# typographically correct entities. -#html_use_smartypants = True - -# Custom sidebar templates, maps document names to template names. -#html_sidebars = {} - -# Additional templates that should be rendered to pages, maps page names to -# template names. -#html_additional_pages = {} - -# If false, no module index is generated. -#html_domain_indices = True - -# If false, no index is generated. -#html_use_index = True - -# If true, the index is split into individual pages for each letter. -#html_split_index = False - -# If true, links to the reST sources are added to the pages. -html_show_sourcelink = False - -# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. -html_show_sphinx = False - -# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. -#html_show_copyright = True - -# If true, an OpenSearch description file will be output, and all pages will -# contain a tag referring to it. The value of this option must be the -# base URL from which the finished HTML is served. -#html_use_opensearch = '' - -# This is the file name suffix for HTML files (e.g. ".xhtml"). -#html_file_suffix = None - -# Output file base name for HTML help builder. -htmlhelp_basename = 'CadQuerydoc' - - -# -- Options for LaTeX output -------------------------------------------------- - -latex_elements = { -# The paper size ('letterpaper' or 'a4paper'). -#'papersize': 'letterpaper', - -# The font size ('10pt', '11pt' or '12pt'). -#'pointsize': '10pt', - -# Additional stuff for the LaTeX preamble. -#'preamble': '', -} - -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, author, documentclass [howto/manual]). -latex_documents = [ - ('index', 'CadQuery.tex', u'CadQuery Documentation', - u'David Cowden', 'manual'), -] - -# The name of an image file (relative to this directory) to place at the top of -# the title page. -#latex_logo = None - -# For "manual" documents, if this is true, then toplevel headings are parts, -# not chapters. -#latex_use_parts = False - -# If true, show page references after internal links. -#latex_show_pagerefs = False - -# If true, show URL addresses after external links. -#latex_show_urls = False - -# Documents to append as an appendix to all manuals. -#latex_appendices = [] - -# If false, no module index is generated. -#latex_domain_indices = True - - -# -- Options for manual page output -------------------------------------------- - -# One entry per manual page. List of tuples -# (source start file, name, description, authors, manual section). -man_pages = [ - ('index', 'cadquery', u'CadQuery Documentation', - [u'David Cowden'], 1) -] - -# If true, show URL addresses after external links. -#man_show_urls = False - - -# -- Options for Texinfo output ------------------------------------------------ - -# Grouping the document tree into Texinfo files. List of tuples -# (source start file, target name, title, author, -# dir menu entry, description, category) -texinfo_documents = [ - ('index', 'CadQuery', u'CadQuery Documentation', - u'David Cowden', 'CadQuery', 'A Fluent CAD api', - 'Miscellaneous'), -] - -# Documents to append as an appendix to all manuals. -#texinfo_appendices = [] - -# If false, no module index is generated. -#texinfo_domain_indices = True - -# How to display URL addresses: 'footnote', 'no', or 'inline'. -#texinfo_show_urls = 'footnote' diff --git a/Libs/cadquery-lib/doc/cqgi.rst b/Libs/cadquery-lib/doc/cqgi.rst deleted file mode 100644 index 84a3602..0000000 --- a/Libs/cadquery-lib/doc/cqgi.rst +++ /dev/null @@ -1,167 +0,0 @@ -.. _cqgi: - -The CadQuery Gateway Interface -==================================== - - -CadQuery is first and foremost designed as a library, which can be used as a part of any project. -In this context, there is no need for a standard script format or gateway api. - -Though the embedded use case is the most common, several tools have been created which run -cadquery scripts on behalf of the user, and then render the result of the script visually. - -These execution environments (EE) generally accept a script and user input values for -script parameters, and then display the resulting objects visually to the user. - -Today, three execution environments exist: - - * `The CadQuery Freecad Module `_, which runs scripts - inside of the FreeCAD IDE, and displays objects in the display window - * the cq-directive, which is used to execute scripts inside of sphinx-doc, - producing documented examples that include both a script and an SVG representation of the object that results - * `ParametricParts.com `_, which provides a web-based way to prompt user input for - variables, and then display the result output in a web page. - -The CQGI is distributed with cadquery, and standardizes the interface between execution environments and cadquery scripts. - - -The Script Side ------------------ - -CQGI compliant containers provide an execution environment for scripts. The environment includes: - - * the cadquery library is automatically imported as 'cq'. - * the :py:meth:`cadquery.cqgi.ScriptCallback.build_object()` method is defined that should be used to export a shape to the execution environment - * the :py:meth:`cadquery.cqgi.ScriptCallBack.debug()` method is defined, which can be used by scripts to debug model output during execution. - -Scripts must call build_output at least once. Invoking build_object more than once will send multiple objects to -the container. An error will occur if the script does not return an object using the build_object() method. - -An optional options dictionary can be provided to the build_object method. If provided, it is passed onto the executing environment, and is used to render the object. Typically, this will be colors, transparency, and other visual affects. - - -This CQGI compliant script produces a cube with a circle on top, and displays a workplane as well as an intermediate circle as debug output:: - - base_cube = cq.Workplane('XY').rect(1.0,1.0).extrude(1.0) - top_of_cube_plane = base_cube.faces(">Z").workplane() - debug(top_of_cube_plane, { 'color': 'yellow', } ) - debug(top_of_cube_plane.center, { 'color' : 'blue' } ) - - circle=top_of_cube_plane.circle(0.5) - debug(circle, { 'color': 'red' } ) - - build_object( circle.extrude(1.0),{"color": "#aaaaaa" ) - -Note that importing cadquery is not required. -At the end of this script, one object will be displayed, in addition to a workplane, a point, and a circle - -Future enhancements will include several other methods, used to provide more metadata for the execution environment: - * :py:meth:`cadquery.cqgi.ScriptCallback.add_error()`, indicates an error with an input parameter - * :py:meth:`cadquery.cqgi.ScriptCallback.describe_parameter()`, provides extra information about a parameter in the script, - - -The execution environment side -------------------------------- - -CQGI makes it easy to run cadquery scripts in a standard way. To run a script from an execution environment, -run code like this:: - - from cadquery import cqgi - - user_script = ... - build_result = cqgi.parse(user_script).build() - -The :py:meth:`cadquery.cqgi.parse()` method returns a :py:class:`cadquery.cqgi.CQModel` object. - -The `metadata`p property of the object contains a `cadquery.cqgi.ScriptMetaData` object, which can be used to discover the -user parameters available. This is useful if the execution environment would like to present a GUI to allow the user to change the -model parameters. Typically, after collecting new values, the environment will supply them in the build() method. - -This code will return a dictionary of parameter values in the model text SCRIPT:: - - parameters = cqgi.parse(SCRIPT).metadata.parameters - -The dictionary you get back is a map where key is the parameter name, and value is an InputParameter object, -which has a name, type, and default value. - -The type is an object which extends ParameterType-- you can use this to determine what kind of widget to render ( checkbox for boolean, for example ). - -The parameter object also has a description, valid values, minimum, and maximum values, if the user has provided them using the -describe_parameter() method. - - - -Calling :py:meth:`cadquery.cqgi.CQModel.build()` returns a :py:class:`cadquery.cqgi.BuildResult` object, -,which includes the script execution time, and a success flag. - -If the script was successful, the results property will include a list of results returned by the script, -as well as any debug the script produced - -If the script failed, the exception property contains the exception object. - -If you have a way to get inputs from a user, you can override any of the constants defined in the user script -with new values:: - - from cadquery import cqgi - - user_script = ... - build_result = cqgi.parse(user_script).build(build_parameters={ 'param': 2 }, build_options={} ) - -If a parameter called 'param' is defined in the model, it will be assigned the value 2 before the script runs. -An error will occur if a value is provided that is not defined in the model, or if the value provided cannot -be assigned to a variable with the given name. - -build_options is used to set server-side settings like timeouts, tesselation tolerances, and other details about -how the model should be built. - - -More about script variables ------------------------------ - -CQGI uses the following rules to find input variables for a script: - - * only top-level statements are considered - * only assignments of constant values to a local name are considered. - -For example, in the following script:: - - h = 1.0 - w = 2.0 - foo = 'bar' - - def some_function(): - x = 1 - -h, w, and foo will be overridable script variables, but x is not. - -You can list the variables defined in the model by using the return value of the parse method:: - - model = cqgi.parse(user_script) - - //a dictionary of InputParameter objects - parameters = model.metadata.parameters - -The key of the dictionary is a string , and the value is a :py:class:`cadquery.cqgi.InputParameter` object -See the CQGI API docs for more details. - -Future enhancments will include a safer sandbox to prevent malicious scripts. - -Important CQGI Methods -------------------------- - -These are the most important Methods and classes of the CQGI - -.. currentmodule:: cadquery.cqgi - -.. autosummary:: - parse - CQModel.build - BuildResult - ScriptCallback.build_object - -Complete CQGI api ------------------ - -.. automodule:: cadquery.cqgi - :members: - diff --git a/Libs/cadquery-lib/doc/designprinciples.rst b/Libs/cadquery-lib/doc/designprinciples.rst deleted file mode 100644 index a74c8c3..0000000 --- a/Libs/cadquery-lib/doc/designprinciples.rst +++ /dev/null @@ -1,74 +0,0 @@ -.. _designprinciples: - - -=========================== -CadQuery Design Principles -=========================== - - -Principle 1: Intuitive Construction -==================================== - -CadQuery aims to make building models using python scripting easy and intuitive. -CadQuery strives to allow scripts to read roughly as a human would describe an object verbally. - -For example, consider this object: - -.. image:: _static/quickstart.png - -A human would describe this as: - - "A block 80mm square x 30mm thick , with countersunk holes for M2 socket head cap screws - at the corners, and a circular pocket 22mm in diameter in the middle for a bearing" - -The goal is to have the CadQuery script that produces this object be as close as possible to the english phrase -a human would use. - - -Principle 2: Capture Design Intent -==================================== - -The features that are **not** part of the part description above are just as important as those that are. For example, most -humans will assume that: - - * The countersunk holes are spaced a uniform distance from the edges - * The circular pocket is in the center of the block, no matter how big the block is - -If you have experience with 3D CAD systems, you also know that there is a key design intent built into this object. -After the base block is created, how the hole is located is key. If it is located from one edge, changing the block -size will have a different affect than if the hole is located from the center. - -Many scripting langauges do not provide a way to capture design intent-- because they require that you always work in -global coordinates. CadQuery is different-- you can locate features relative to others in a relative way-- preserving -the design intent just like a human would when creating a drawing or building an object. - -In fact, though many people know how to use 3D CAD systems, few understand how important the way that an object is built -impact its maintainability and resiliency to design changes. - - -Principle 3: Plugins as first class citizens -============================================ - -Any system for building 3D models will evolve to contain an immense number of libraries and feature builders. It is -important that these can be seamlessly included into the core and used alongside the built in libraries. Plugins -should be easy to install and familiar to use. - - -Principle 4: CAD models as source code makes sense -================================================================== - -It is surprising that the world of 3D CAD is primarily dominated by systems that create opaque binary files. -Just like the world of software, CAD models are very complex. - -CAD models have many things in common with software, and would benefit greatly from the use of tools that are standard -in the software industry, such as: - - 1. Easily re-using features between objects - 2. Storing objects using version control systems - 3. Computing the differences between objects by using source control tools - 4. Share objects on the internet - 5. Automate testing and generation by allowing objects to be built from within libraries - -CadQuery is designed to make 3D content creation easy enough that the above benefits can be attained without more work -than using existing 'opaque', 'point and click' solutions. - diff --git a/Libs/cadquery-lib/doc/examples.rst b/Libs/cadquery-lib/doc/examples.rst deleted file mode 100644 index 06c79aa..0000000 --- a/Libs/cadquery-lib/doc/examples.rst +++ /dev/null @@ -1,1096 +0,0 @@ -.. _examples: - -********************************* -CadQuery Examples -********************************* - - - -The examples on this page can help you learn how to build objects with CadQuery. - -They are organized from simple to complex, so working through them in order is the best way to absorb them. - -Each example lists the api elements used in the example for easy reference. -Items introduced in the example are marked with a **!** - -.. note:: - - You may want to work through these examples by pasting the text into a scratchpad on the live website. - If you do, make sure to take these steps so that they work: - - 1. paste the content into the build() method, properly intented, and - 2. add the line 'return result' at the end. The samples below are autogenerated, but they use a different - syntax than the models on the website need to be. - -.. note:: - - We strongly recommend installing FreeCAD, and the `cadquery-freecad-module `_, - so that you can work along with these examples interactively. See :ref:`installation` for more info. - -.. warning:: - - * You have to have an svg capable browser to view these! - -.. contents:: List of Examples - :backlinks: entry - - -Simple Rectangular Plate ------------------------- - -Just about the simplest possible example, a rectangular box - -.. cq_plot:: - - result = cadquery.Workplane("front").box(2.0, 2.0, 0.5) - build_object(result) - -.. topic:: Api References - - .. hlist:: - :columns: 2 - - * :py:meth:`Workplane` **!** - * :py:meth:`Workplane.box` **!** - -Plate with Hole ------------------------- - -A rectangular box, but with a hole added. - -"\>Z" selects the top most face of the resulting box. The hole is located in the center because the default origin -of a working plane is at the center of the face. The default hole depth is through the entire part. - -.. cq_plot:: - - # The dimensions of the box. These can be modified rather than changing the - # object's code directly. - length = 80.0 - height = 60.0 - thickness = 10.0 - center_hole_dia = 22.0 - - # Create a box based on the dimensions above and add a 22mm center hole - result = cq.Workplane("XY").box(length, height, thickness) \ - .faces(">Z").workplane().hole(center_hole_dia) - - build_object(result) - -.. topic:: Api References - - .. hlist:: - :columns: 2 - - * :py:meth:`Workplane.hole` **!** - * :py:meth:`Workplane.box` - * :py:meth:`Workplane.box` - -An extruded prismatic solid -------------------------------- - -Build a prismatic solid using extrusion. After a drawing operation, the center of the previous object -is placed on the stack, and is the reference for the next operation. So in this case, the rect() is drawn -centered on the previously draw circle. - -By default, rectangles and circles are centered around the previous working point. - -.. cq_plot:: - - result = cq.Workplane("front").circle(2.0).rect(0.5, 0.75).extrude(0.5) - build_object(result) - -.. topic:: Api References - - .. hlist:: - :columns: 2 - - * :py:meth:`Workplane.circle` **!** - * :py:meth:`Workplane.rect` **!** - * :py:meth:`Workplane.extrude` **!** - * :py:meth:`Workplane` - -Building Profiles using lines and arcs --------------------------------------- - -Sometimes you need to build complex profiles using lines and arcs. This example builds a prismatic -solid from 2-d operations. - -2-d operations maintain a current point, which is initially at the origin. Use close() to finish a -closed curve. - - -.. cq_plot:: - - result = cq.Workplane("front").lineTo(2.0, 0).lineTo(2.0, 1.0).threePointArc((1.0, 1.5),(0.0, 1.0))\ - .close().extrude(0.25) - build_object(result) - - -.. topic:: Api References - - .. hlist:: - :columns: 2 - - * :py:meth:`Workplane.threePointArc` **!** - * :py:meth:`Workplane.lineTo` **!** - * :py:meth:`Workplane.extrude` - * :py:meth:`Workplane` - -Moving The Current working point ---------------------------------- - -In this example, a closed profile is required, with some interior features as well. - -This example also demonstrates using multiple lines of code instead of longer chained commands, -though of course in this case it was possible to do it in one long line as well. - -A new work plane center can be established at any point. - -.. cq_plot:: - - result = cq.Workplane("front").circle(3.0) #current point is the center of the circle, at (0,0) - result = result.center(1.5, 0.0).rect(0.5, 0.5) # new work center is (1.5, 0.0) - - result = result.center(-1.5, 1.5).circle(0.25) # new work center is ( 0.0, 1.5). - #the new center is specified relative to the previous center, not global coordinates! - - result = result.extrude(0.25) - build_object(result) - - -.. topic:: Api References - - .. hlist:: - :columns: 2 - - * :py:meth:`Workplane.center` **!** - * :py:meth:`Workplane` - * :py:meth:`Workplane.circle` - * :py:meth:`Workplane.rect` - * :py:meth:`Workplane.extrude` - -Using Point Lists ---------------------------- - -Sometimes you need to create a number of features at various locations, and using :py:meth:`Workplane.center` -is too cumbersome. - -You can use a list of points to construct multiple objects at once. Most construction methods, -like :py:meth:`Workplane.circle` and :py:meth:`Workplane.rect`, will operate on multiple points if they are on the stack - -.. cq_plot:: - - r = cq.Workplane("front").circle(2.0) # make base - r = r.pushPoints( [ (1.5, 0),(0, 1.5),(-1.5, 0),(0, -1.5) ] ) # now four points are on the stack - r = r.circle( 0.25 ) # circle will operate on all four points - result = r.extrude(0.125 ) # make prism - build_object(result) - -.. topic:: Api References - - .. hlist:: - :columns: 2 - - * :py:meth:`Workplane.points` **!** - * :py:meth:`Workplane` - * :py:meth:`Workplane.circle` - * :py:meth:`Workplane.extrude` - -Polygons -------------------------- - -You can create polygons for each stack point if you would like. Useful in 3d printers whos firmware does not -correct for small hole sizes. - -.. cq_plot:: - - result = cq.Workplane("front").box(3.0, 4.0, 0.25).pushPoints ( [ ( 0,0.75 ),(0, -0.75) ]) \ - .polygon(6, 1.0).cutThruAll() - build_object(result) - -.. topic:: Api References - - .. hlist:: - :columns: 2 - - * :py:meth:`Workplane.polygon` **!** - * :py:meth:`Workplane.pushPoints` - * :py:meth:`Workplane.box` - -Polylines -------------------------- - -:py:meth:`Workplane.polyline` allows creating a shape from a large number of chained points connected by lines. - -This example uses a polyline to create one half of an i-beam shape, which is mirrored to create the final profile. - -.. cq_plot:: - - (L,H,W,t) = ( 100.0, 20.0, 20.0, 1.0) - pts = [ - (0,H/2.0), - (W/2.0,H/2.0), - (W/2.0,(H/2.0 - t)), - (t/2.0,(H/2.0-t)), - (t/2.0,(t - H/2.0)), - (W/2.0,(t -H/2.0)), - (W/2.0,H/-2.0), - (0,H/-2.0) - ] - result = cq.Workplane("front").polyline(pts).mirrorY().extrude(L) - build_object(result) - -.. topic:: Api References - - .. hlist:: - :columns: 2 - - * :py:meth:`Workplane.polyline` **!** - * :py:meth:`Workplane` - * :py:meth:`Workplane.mirrorY` - * :py:meth:`Workplane.extrude` - - - -Defining an Edge with a Spline ------------------------------- - -This example defines a side using a spline curve through a collection of points. Useful when you have an edge that -needs a complex profile - -.. cq_plot:: - - s = cq.Workplane("XY") - sPnts = [ - (2.75, 1.5), - (2.5, 1.75), - (2.0, 1.5), - (1.5, 1.0), - (1.0, 1.25), - (0.5, 1.0), - (0, 1.0) - ] - r = s.lineTo(3.0, 0).lineTo(3.0, 1.0).spline(sPnts).close() - result = r.extrude(0.5) - build_object(result) - -.. topic:: Api References - - .. hlist:: - :columns: 2 - - * :py:meth:`Workplane.spline` **!** - * :py:meth:`Workplane` - * :py:meth:`Workplane.close` - * :py:meth:`Workplane.lineTo` - * :py:meth:`Workplane.extrude` - -Mirroring Symmetric Geometry ------------------------------ - -You can mirror 2-d geometry when your shape is symmetric. In this example we also -introduce horizontal and vertical lines, which make for slightly easier coding. - - -.. cq_plot:: - - r = cq.Workplane("front").hLine(1.0) # 1.0 is the distance, not coordinate - r = r.vLine(0.5).hLine(-0.25).vLine(-0.25).hLineTo(0.0) # hLineTo allows using xCoordinate not distance - result =r.mirrorY().extrude(0.25 ) # mirror the geometry and extrude - build_object(result) - -.. topic:: Api References - - .. hlist:: - :columns: 2 - - * :py:meth:`Workplane.hLine` **!** - * :py:meth:`Workplane.vLine` **!** - * :py:meth:`Workplane.hLineTo` **!** - * :py:meth:`Workplane.mirrorY` **!** - * :py:meth:`Workplane.mirrorX` **!** - * :py:meth:`Workplane` - * :py:meth:`Workplane.extrude` - -Mirroring 3D Objects ------------------------------ - -.. cq_plot:: - - result0 = (cadquery.Workplane("XY") - .moveTo(10,0) - .lineTo(5,0) - .threePointArc((3.9393,0.4393),(3.5,1.5)) - .threePointArc((3.0607,2.5607),(2,3)) - .lineTo(1.5,3) - .threePointArc((0.4393,3.4393),(0,4.5)) - .lineTo(0,13.5) - .threePointArc((0.4393,14.5607),(1.5,15)) - .lineTo(28,15) - .lineTo(28,13.5) - .lineTo(24,13.5) - .lineTo(24,11.5) - .lineTo(27,11.5) - .lineTo(27,10) - .lineTo(22,10) - .lineTo(22,13.2) - .lineTo(14.5,13.2) - .lineTo(14.5,10) - .lineTo(12.5,10 ) - .lineTo(12.5,13.2) - .lineTo(5.5,13.2) - .lineTo(5.5,2) - .threePointArc((5.793,1.293),(6.5,1)) - .lineTo(10,1) - .close()) - result = result0.extrude(100) - - result = result.rotate((0, 0, 0),(1, 0, 0), 90) - - result = result.translate(result.val().BoundingBox().center.multiply(-1)) - - mirXY_neg = result.mirror(mirrorPlane="XY", basePointVector=(0, 0, -30)) - mirXY_pos = result.mirror(mirrorPlane="XY", basePointVector=(0, 0, 30)) - mirZY_neg = result.mirror(mirrorPlane="ZY", basePointVector=(-30,0,0)) - mirZY_pos = result.mirror(mirrorPlane="ZY", basePointVector=(30,0,0)) - - result = result.union(mirXY_neg).union(mirXY_pos).union(mirZY_neg).union(mirZY_pos) - - build_object(result) - -.. topic:: Api References - - .. hlist:: - :columns: 2 - - * :py:meth:`Workplane.moveTo` - * :py:meth:`Workplane.lineTo` - * :py:meth:`Workplane.threePointArc` - * :py:meth:`Workplane.extrude` - * :py:meth:`Workplane.mirror` - * :py:meth:`Workplane.union` - * :py:meth:`CQ.rotate` - -Creating Workplanes on Faces ------------------------------ - -This example shows how to locate a new workplane on the face of a previously created feature. - -.. note:: - Using workplanes in this way are a key feature of CadQuery. Unlike typical 3d scripting language, - using work planes frees you from tracking the position of various features in variables, and - allows the model to adjust itself with removing redundant dimensions - -The :py:meth:`Workplane.faces()` method allows you to select the faces of a resulting solid. It accepts -a selector string or object, that allows you to target a single face, and make a workplane oriented on that -face. - -Keep in mind that the origin of new workplanes are located at the center of a face by default. - -.. cq_plot:: - - result = cq.Workplane("front").box(2,3, 0.5) #make a basic prism - result = result.faces(">Z").workplane().hole(0.5) #find the top-most face and make a hole - build_object(result) - -.. topic:: Api References - - .. hlist:: - :columns: 2 - - * :py:meth:`Workplane.faces` **!** - * :py:meth:`StringSyntaxSelector` **!** - * :ref:`selector_reference` **!** - * :py:meth:`Workplane.workplane` - * :py:meth:`Workplane.box` - * :py:meth:`Workplane` - -Locating a Workplane on a vertex ---------------------------------- - -Normally, the :py:meth:`Workplane.workplane` method requires a face to be selected. But if a vertex is selected -**immediately after a face**, :py:meth:`Workplane.workplane` will locate the workplane on the face, with the origin at the vertex instead -of at the center of the face - -The example also introduces :py:meth:`Workplane.cutThruAll`, which makes a cut through the entire part, no matter -how deep the part is - -.. cq_plot:: - - result = cq.Workplane("front").box(3,2, 0.5) #make a basic prism - result = result.faces(">Z").vertices("Z").workplane() \ - .transformed(offset=cq.Vector(0, -1.5, 1.0),rotate=cq.Vector(60, 0, 0)) \ - .rect(1.5,1.5,forConstruction=True).vertices().hole(0.25) - build_object(result) - -.. topic:: Api References - - .. hlist:: - :columns: 2 - - * :py:meth:`Workplane.transformed` **!** - * :py:meth:`Workplane.box` - * :py:meth:`Workplane.rect` - * :py:meth:`Workplane.faces` - -Using construction Geometry ---------------------------- - -You can draw shapes to use the vertices as points to locate other features. Features that are used to -locate other features, rather than to create them, are called ``Construction Geometry`` - -In the example below, a rectangle is drawn, and its vertices are used to locate a set of holes. - -.. cq_plot:: - - result = cq.Workplane("front").box(2, 2, 0.5).faces(">Z").workplane() \ - .rect(1.5, 1.5, forConstruction=True).vertices().hole(0.125 ) - build_object(result) - -.. topic:: Api References - - .. hlist:: - :columns: 2 - - * :py:meth:`Workplane.rect` (forConstruction=True) - * :ref:`selector_reference` - * :py:meth:`Workplane.workplane` - * :py:meth:`Workplane.box` - * :py:meth:`Workplane.hole` - * :py:meth:`Workplane` - -Shelling To Create Thin features --------------------------------- - -Shelling converts a solid object into a shell of uniform thickness. To shell an object, one or more faces -are removed, and then the inside of the solid is 'hollowed out' to make the shell. - - -.. cq_plot:: - - result = cq.Workplane("front").box(2, 2, 2).faces("+Z").shell(0.05) - build_object(result) - -.. topic:: Api References - - .. hlist:: - :columns: 2 - - * :py:meth:`Workplane.shell` **!** - * :py:meth:`Workplane.box` - * :py:meth:`Workplane.faces` - * :py:meth:`Workplane` - -Making Lofts --------------------------------------------- - -A loft is a solid swept through a set of wires. This example creates lofted section between a rectangle -and a circular section. - -.. cq_plot:: - - result = cq.Workplane("front").box(4.0, 4.0, 0.25).faces(">Z").circle(1.5) \ - .workplane(offset=3.0).rect(0.75, 0.5).loft(combine=True) - - build_object(result) - -.. topic:: Api References - - .. hlist:: - :columns: 2 - - * :py:meth:`Workplane.loft` **!** - * :py:meth:`Workplane.box` - * :py:meth:`Workplane.faces` - * :py:meth:`Workplane.circle` - * :py:meth:`Workplane.rect` - -Making Counter-bored and counter-sunk holes ----------------------------------------------- - -Counterbored and countersunk holes are so common that CadQuery creates macros to create them in a single step. - -Similar to :py:meth:`Workplane.hole` , these functions operate on a list of points as well as a single point. - -.. cq_plot:: - - result = cq.Workplane(cq.Plane.XY()).box(4,2, 0.5).faces(">Z").workplane().rect(3.5, 1.5, forConstruction=True)\ - .vertices().cboreHole(0.125, 0.25, 0.125, depth=None) - - build_object(result) - -.. topic:: Api References - - .. hlist:: - :columns: 2 - - * :py:meth:`Workplane.cboreHole` **!** - * :py:meth:`Workplane.cskHole` **!** - * :py:meth:`Workplane.box` - * :py:meth:`Workplane.rect` - * :py:meth:`Workplane.workplane` - * :py:meth:`Workplane.vertices` - * :py:meth:`Workplane.faces` - * :py:meth:`Workplane` - -Rounding Corners with Fillet ------------------------------ - -Filleting is done by selecting the edges of a solid, and using the fillet function. - -Here we fillet all of the edges of a simple plate. - -.. cq_plot:: - - result = cq.Workplane("XY" ).box(3, 3, 0.5).edges("|Z").fillet(0.125) - build_object(result) - -.. topic:: Api References - - .. hlist:: - :columns: 2 - - * :py:meth:`Workplane.fillet` **!** - * :py:meth:`Workplane.box` - * :py:meth:`Workplane.edges` - * :py:meth:`Workplane` - -A Parametric Bearing Pillow Block ------------------------------------- - -Combining a few basic functions, its possible to make a very good parametric bearing pillow block, -with just a few lines of code. - -.. cq_plot:: - - (length,height,bearing_diam, thickness,padding) = ( 30.0, 40.0, 22.0, 10.0, 8.0) - - result = cq.Workplane("XY").box(length,height,thickness).faces(">Z").workplane().hole(bearing_diam) \ - .faces(">Z").workplane() \ - .rect(length-padding,height-padding,forConstruction=True) \ - .vertices().cboreHole(2.4, 4.4, 2.1) - - build_object(result) - - -Splitting an Object ---------------------- - -You can split an object using a workplane, and retain either or both halves - -.. cq_plot:: - - c = cq.Workplane("XY").box(1,1,1).faces(">Z").workplane().circle(0.25).cutThruAll() - - #now cut it in half sideways - result = c.faces(">Y").workplane(-0.5).split(keepTop=True) - build_object(result) - -.. topic:: Api References - - .. hlist:: - :columns: 2 - - * :py:meth:`Workplane.split` **!** - * :py:meth:`Workplane.box` - * :py:meth:`Workplane.circle` - * :py:meth:`Workplane.cutThruAll` - * :py:meth:`Workplane.workplane` - * :py:meth:`Workplane` - -The Classic OCC Bottle ----------------------- - -CadQuery is based on the OpenCascade.org (OCC) modeling Kernel. Those who are familiar with OCC know about the -famous 'bottle' example. http://www.opencascade.org/org/gettingstarted/appli/ - -A pythonOCC version is listed here - http://code.google.com/p/pythonocc/source/browse/trunk/src/examples/Tools/InteractiveViewer/scripts/Bottle.py?r=1046 - -Of course one difference between this sample and the OCC version is the length. This sample is one of the longer -ones at 13 lines, but that's very short compared to the pythonOCC version, which is 10x longer! - - -.. cq_plot:: - - (L,w,t) = (20.0, 6.0, 3.0) - s = cq.Workplane("XY") - - #draw half the profile of the bottle and extrude it - p = s.center(-L/2.0, 0).vLine(w/2.0) \ - .threePointArc((L/2.0, w/2.0 + t),(L, w/2.0)).vLine(-w/2.0) \ - .mirrorX().extrude(30.0,True) - - #make the neck - p.faces(">Z").workplane().circle(3.0).extrude(2.0,True) - - #make a shell - result = p.faces(">Z").shell(0.3) - build_object(result) - -.. topic:: Api References - - .. hlist:: - :columns: 2 - - * :py:meth:`Workplane.extrude` - * :py:meth:`Workplane.mirrorX` - * :py:meth:`Workplane.threePointArc` - * :py:meth:`Workplane.workplane` - * :py:meth:`Workplane.vertices` - * :py:meth:`Workplane.vLine` - * :py:meth:`Workplane.faces` - * :py:meth:`Workplane` - -A Parametric Enclosure ------------------------ - -.. cq_plot:: - :height: 400 - - #parameter definitions - p_outerWidth = 100.0 #Outer width of box enclosure - p_outerLength = 150.0 #Outer length of box enclosure - p_outerHeight = 50.0 #Outer height of box enclosure - - p_thickness = 3.0 #Thickness of the box walls - p_sideRadius = 10.0 #Radius for the curves around the sides of the bo - p_topAndBottomRadius = 2.0 #Radius for the curves on the top and bottom edges of the box - - p_screwpostInset = 12.0 #How far in from the edges the screwposts should be place. - p_screwpostID = 4.0 #nner Diameter of the screwpost holes, should be roughly screw diameter not including threads - p_screwpostOD = 10.0 #Outer Diameter of the screwposts.\nDetermines overall thickness of the posts - - p_boreDiameter = 8.0 #Diameter of the counterbore hole, if any - p_boreDepth = 1.0 #Depth of the counterbore hole, if - p_countersinkDiameter = 0.0 #Outer diameter of countersink. Should roughly match the outer diameter of the screw head - p_countersinkAngle = 90.0 #Countersink angle (complete angle between opposite sides, not from center to one side) - p_flipLid = True #Whether to place the lid with the top facing down or not. - p_lipHeight = 1.0 #Height of lip on the underside of the lid.\nSits inside the box body for a snug fit. - - #outer shell - oshell = cq.Workplane("XY").rect(p_outerWidth,p_outerLength).extrude(p_outerHeight + p_lipHeight) - - #weird geometry happens if we make the fillets in the wrong order - if p_sideRadius > p_topAndBottomRadius: - oshell.edges("|Z").fillet(p_sideRadius) - oshell.edges("#Z").fillet(p_topAndBottomRadius) - else: - oshell.edges("#Z").fillet(p_topAndBottomRadius) - oshell.edges("|Z").fillet(p_sideRadius) - - #inner shell - ishell = oshell.faces("Z").workplane(-p_thickness)\ - .rect(POSTWIDTH,POSTLENGTH,forConstruction=True)\ - .vertices() - - for v in postCenters.all(): - v.circle(p_screwpostOD/2.0).circle(p_screwpostID/2.0)\ - .extrude((-1.0)*(p_outerHeight + p_lipHeight -p_thickness ),True) - - #split lid into top and bottom parts - (lid,bottom) = box.faces(">Z").workplane(-p_thickness -p_lipHeight ).split(keepTop=True,keepBottom=True).all() #splits into two solids - - #translate the lid, and subtract the bottom from it to produce the lid inset - lowerLid = lid.translate((0,0,-p_lipHeight)) - cutlip = lowerLid.cut(bottom).translate((p_outerWidth + p_thickness ,0,p_thickness - p_outerHeight + p_lipHeight)) - - #compute centers for counterbore/countersink or counterbore - topOfLidCenters = cutlip.faces(">Z").workplane().rect(POSTWIDTH,POSTLENGTH,forConstruction=True).vertices() - - #add holes of the desired type - if p_boreDiameter > 0 and p_boreDepth > 0: - topOfLid = topOfLidCenters.cboreHole(p_screwpostID,p_boreDiameter,p_boreDepth,(2.0)*p_thickness) - elif p_countersinkDiameter > 0 and p_countersinkAngle > 0: - topOfLid = topOfLidCenters.cskHole(p_screwpostID,p_countersinkDiameter,p_countersinkAngle,(2.0)*p_thickness) - else: - topOfLid= topOfLidCenters.hole(p_screwpostID,(2.0)*p_thickness) - - #flip lid upside down if desired - if p_flipLid: - topOfLid.rotateAboutCenter((1,0,0),180) - - #return the combined result - result =topOfLid.combineSolids(bottom) - - build_object(result) - -.. topic:: Api References - - .. hlist:: - :columns: 3 - - * :py:meth:`Workplane.circle` - * :py:meth:`Workplane.rect` - * :py:meth:`Workplane.extrude` - * :py:meth:`Workplane.box` - * :py:meth:`CQ.all` - * :py:meth:`CQ.faces` - * :py:meth:`CQ.vertices` - * :py:meth:`CQ.edges` - * :py:meth:`CQ.workplane` - * :py:meth:`Workplane.fillet` - * :py:meth:`Workplane.cut` - * :py:meth:`Workplane.combineSolids` - * :py:meth:`Workplane.rotateAboutCenter` - * :py:meth:`Workplane.cboreHole` - * :py:meth:`Workplane.cskHole` - * :py:meth:`Workplane.hole` - -Lego Brick -------------------- - -This script will produce any size regular rectangular Lego(TM) brick. Its only tricky because of the logic -regarding the underside of the brick. - -.. cq_plot:: - :height: 400 - - ##### - # Inputs - ###### - lbumps = 6 # number of bumps long - wbumps = 2 # number of bumps wide - thin = True # True for thin, False for thick - - # - # Lego Brick Constants-- these make a lego brick a lego :) - # - pitch = 8.0 - clearance = 0.1 - bumpDiam = 4.8 - bumpHeight = 1.8 - if thin: - height = 3.2 - else: - height = 9.6 - - t = (pitch - (2 * clearance) - bumpDiam) / 2.0 - postDiam = pitch - t # works out to 6.5 - total_length = lbumps*pitch - 2.0*clearance - total_width = wbumps*pitch - 2.0*clearance - - # make the base - s = cq.Workplane("XY").box(total_length, total_width, height) - - # shell inwards not outwards - s = s.faces("Z").workplane(). \ - rarray(pitch, pitch, lbumps, wbumps, True).circle(bumpDiam / 2.0) \ - .extrude(bumpHeight) - - # add posts on the bottom. posts are different diameter depending on geometry - # solid studs for 1 bump, tubes for multiple, none for 1x1 - tmp = s.faces(" 1 and wbumps > 1: - tmp = tmp.rarray(pitch, pitch, lbumps - 1, wbumps - 1, center=True). \ - circle(postDiam / 2.0).circle(bumpDiam / 2.0).extrude(height - t) - elif lbumps > 1: - tmp = tmp.rarray(pitch, pitch, lbumps - 1, 1, center=True). \ - circle(t).extrude(height - t) - elif wbumps > 1: - tmp = tmp.rarray(pitch, pitch, 1, wbumps - 1, center=True). \ - circle(t).extrude(height - t) - else: - tmp = s - - # Render the solid - build_object(tmp) - - -Braille Example ---------------------- - -.. cq_plot:: - :height: 400 - - from __future__ import unicode_literals, division - from collections import namedtuple - - - # text_lines is a list of text lines. - # FreeCAD in braille (converted with braille-converter: - # https://github.com/jpaugh/braille-converter.git). - text_lines = ['⠠ ⠋ ⠗ ⠑ ⠑ ⠠ ⠉ ⠠ ⠁ ⠠ ⠙'] - # See http://www.tiresias.org/research/reports/braille_cell.htm for examples - # of braille cell geometry. - horizontal_interdot = 2.5 - vertical_interdot = 2.5 - horizontal_intercell = 6 - vertical_interline = 10 - dot_height = 0.5 - dot_diameter = 1.3 - - base_thickness = 1.5 - - # End of configuration. - BrailleCellGeometry = namedtuple('BrailleCellGeometry', - ('horizontal_interdot', - 'vertical_interdot', - 'intercell', - 'interline', - 'dot_height', - 'dot_diameter')) - - - class Point(object): - def __init__(self, x, y): - self.x = x - self.y = y - - def __add__(self, other): - return Point(self.x + other.x, self.y + other.y) - - def __len__(self): - return 2 - - def __getitem__(self, index): - return (self.x, self.y)[index] - - def __str__(self): - return '({}, {})'.format(self.x, self.y) - - - def brailleToPoints(text, cell_geometry): - # Unicode bit pattern (cf. https://en.wikipedia.org/wiki/Braille_Patterns). - mask1 = 0b00000001 - mask2 = 0b00000010 - mask3 = 0b00000100 - mask4 = 0b00001000 - mask5 = 0b00010000 - mask6 = 0b00100000 - mask7 = 0b01000000 - mask8 = 0b10000000 - masks = (mask1, mask2, mask3, mask4, mask5, mask6, mask7, mask8) - - # Corresponding dot position - w = cell_geometry.horizontal_interdot - h = cell_geometry.vertical_interdot - pos1 = Point(0, 2 * h) - pos2 = Point(0, h) - pos3 = Point(0, 0) - pos4 = Point(w, 2 * h) - pos5 = Point(w, h) - pos6 = Point(w, 0) - pos7 = Point(0, -h) - pos8 = Point(w, -h) - pos = (pos1, pos2, pos3, pos4, pos5, pos6, pos7, pos8) - - # Braille blank pattern (u'\u2800'). - blank = '⠀' - points = [] - # Position of dot1 along the x-axis (horizontal). - character_origin = 0 - for c in text: - for m, p in zip(masks, pos): - delta_to_blank = ord(c) - ord(blank) - if (m & delta_to_blank): - points.append(p + Point(character_origin, 0)) - character_origin += cell_geometry.intercell - return points - - - def get_plate_height(text_lines, cell_geometry): - # cell_geometry.vertical_interdot is also used as space between base - # borders and characters. - return (2 * cell_geometry.vertical_interdot + - 2 * cell_geometry.vertical_interdot + - (len(text_lines) - 1) * cell_geometry.interline) - - - def get_plate_width(text_lines, cell_geometry): - # cell_geometry.horizontal_interdot is also used as space between base - # borders and characters. - max_len = max([len(t) for t in text_lines]) - return (2 * cell_geometry.horizontal_interdot + - cell_geometry.horizontal_interdot + - (max_len - 1) * cell_geometry.intercell) - - - def get_cylinder_radius(cell_geometry): - """Return the radius the cylinder should have - The cylinder have the same radius as the half-sphere make the dots (the - hidden and the shown part of the dots). - The radius is such that the spherical cap with diameter - cell_geometry.dot_diameter has a height of cell_geometry.dot_height. - """ - h = cell_geometry.dot_height - r = cell_geometry.dot_diameter / 2 - return (r ** 2 + h ** 2) / 2 / h - - - def get_base_plate_thickness(plate_thickness, cell_geometry): - """Return the height on which the half spheres will sit""" - return (plate_thickness + - get_cylinder_radius(cell_geometry) - - cell_geometry.dot_height) - - - def make_base(text_lines, cell_geometry, plate_thickness): - base_width = get_plate_width(text_lines, cell_geometry) - base_height = get_plate_height(text_lines, cell_geometry) - base_thickness = get_base_plate_thickness(plate_thickness, cell_geometry) - base = cq.Workplane('XY').box(base_width, base_height, base_thickness, - centered=(False, False, False)) - return base - - - def make_embossed_plate(text_lines, cell_geometry): - """Make an embossed plate with dots as spherical caps - Method: - - make a thin plate on which sit cylinders - - fillet the upper edge of the cylinders so to get pseudo half-spheres - - make the union with a thicker plate so that only the sphere caps stay - "visible". - """ - base = make_base(text_lines, cell_geometry, base_thickness) - - dot_pos = [] - base_width = get_plate_width(text_lines, cell_geometry) - base_height = get_plate_height(text_lines, cell_geometry) - y = base_height - 3 * cell_geometry.vertical_interdot - line_start_pos = Point(cell_geometry.horizontal_interdot, y) - for text in text_lines: - dots = brailleToPoints(text, cell_geometry) - dots = [p + line_start_pos for p in dots] - dot_pos += dots - line_start_pos += Point(0, -cell_geometry.interline) - - r = get_cylinder_radius(cell_geometry) - base = base.faces('>Z').vertices('Z').edges() \ - .fillet(r - 0.001) - hidding_box = cq.Workplane('XY').box( - base_width, base_height, base_thickness, centered=(False, False, False)) - result = hidding_box.union(base) - return result - - _cell_geometry = BrailleCellGeometry( - horizontal_interdot, - vertical_interdot, - horizontal_intercell, - vertical_interline, - dot_height, - dot_diameter) - - if base_thickness < get_cylinder_radius(_cell_geometry): - raise ValueError('Base thickness should be at least {}'.format(dot_height)) - - build_object(make_embossed_plate(text_lines, _cell_geometry)) - -Panel With Various Connector Holes ------------------------------------ - -.. cq_plot:: - :height: 400 - - # The dimensions of the model. These can be modified rather than changing the - # object's code directly. - width = 400 - height = 500 - thickness = 2 - - # Create a plate with two polygons cut through it - result = cq.Workplane("front").box(width, height, thickness) - - h_sep = 60 - for idx in range(4): - result = result.workplane(offset=1, centerOption='CenterOfBoundBox').center(157,210-idx*h_sep).moveTo(-23.5,0).circle(1.6).moveTo(23.5,0).circle(1.6).moveTo(-17.038896,-5.7).threePointArc((-19.44306,-4.70416),(-20.438896,-2.3)).lineTo(-21.25,2.3).threePointArc((-20.25416,4.70416),(-17.85,5.7)).lineTo(17.85,5.7).threePointArc((20.25416,4.70416),(21.25,2.3)).lineTo(20.438896,-2.3).threePointArc((19.44306,-4.70416),(17.038896,-5.7)).close().cutThruAll() - - for idx in range(4): - result = result.workplane(offset=1, centerOption='CenterOfBoundBox').center(157,-30-idx*h_sep).moveTo(-16.65,0).circle(1.6).moveTo(16.65,0).circle(1.6).moveTo(-10.1889,-5.7).threePointArc((-12.59306,-4.70416),(-13.5889,-2.3)).lineTo(-14.4,2.3).threePointArc((-13.40416,4.70416),(-11,5.7)).lineTo(11,5.7).threePointArc((13.40416,4.70416),(14.4,2.3)).lineTo(13.5889,-2.3).threePointArc((12.59306,-4.70416),(10.1889,-5.7)).close().cutThruAll() - - h_sep4DB9 = 30 - for idx in range(8): - result = result.workplane(offset=1, centerOption='CenterOfBoundBox').center(91,225-idx*h_sep4DB9).moveTo(-12.5,0).circle(1.6).moveTo(12.5,0).circle(1.6).moveTo(-6.038896,-5.7).threePointArc((-8.44306,-4.70416),(-9.438896,-2.3)).lineTo(-10.25,2.3).threePointArc((-9.25416,4.70416),(-6.85,5.7)).lineTo(6.85,5.7).threePointArc((9.25416,4.70416),(10.25,2.3)).lineTo(9.438896,-2.3).threePointArc((8.44306,-4.70416),(6.038896,-5.7)).close().cutThruAll() - - for idx in range(4): - result = result.workplane(offset=1, centerOption='CenterOfBoundBox').center(25,210-idx*h_sep).moveTo(-23.5,0).circle(1.6).moveTo(23.5,0).circle(1.6).moveTo(-17.038896,-5.7).threePointArc((-19.44306,-4.70416),(-20.438896,-2.3)).lineTo(-21.25,2.3).threePointArc((-20.25416,4.70416),(-17.85,5.7)).lineTo(17.85,5.7).threePointArc((20.25416,4.70416),(21.25,2.3)).lineTo(20.438896,-2.3).threePointArc((19.44306,-4.70416),(17.038896,-5.7)).close().cutThruAll() - - for idx in range(4): - result = result.workplane(offset=1, centerOption='CenterOfBoundBox').center(25,-30-idx*h_sep).moveTo(-16.65,0).circle(1.6).moveTo(16.65,0).circle(1.6).moveTo(-10.1889,-5.7).threePointArc((-12.59306,-4.70416),(-13.5889,-2.3)).lineTo(-14.4,2.3).threePointArc((-13.40416,4.70416),(-11,5.7)).lineTo(11,5.7).threePointArc((13.40416,4.70416),(14.4,2.3)).lineTo(13.5889,-2.3).threePointArc((12.59306,-4.70416),(10.1889,-5.7)).close().cutThruAll() - - for idx in range(8): - result = result.workplane(offset=1, centerOption='CenterOfBoundBox').center(-41,225-idx*h_sep4DB9).moveTo(-12.5,0).circle(1.6).moveTo(12.5,0).circle(1.6).moveTo(-6.038896,-5.7).threePointArc((-8.44306,-4.70416),(-9.438896,-2.3)).lineTo(-10.25,2.3).threePointArc((-9.25416,4.70416),(-6.85,5.7)).lineTo(6.85,5.7).threePointArc((9.25416,4.70416),(10.25,2.3)).lineTo(9.438896,-2.3).threePointArc((8.44306,-4.70416),(6.038896,-5.7)).close().cutThruAll() - - for idx in range(4): - result = result.workplane(offset=1, centerOption='CenterOfBoundBox').center(-107,210-idx*h_sep).moveTo(-23.5,0).circle(1.6).moveTo(23.5,0).circle(1.6).moveTo(-17.038896,-5.7).threePointArc((-19.44306,-4.70416),(-20.438896,-2.3)).lineTo(-21.25,2.3).threePointArc((-20.25416,4.70416),(-17.85,5.7)).lineTo(17.85,5.7).threePointArc((20.25416,4.70416),(21.25,2.3)).lineTo(20.438896,-2.3).threePointArc((19.44306,-4.70416),(17.038896,-5.7)).close().cutThruAll() - - for idx in range(4): - result = result.workplane(offset=1, centerOption='CenterOfBoundBox').center(-107,-30-idx*h_sep).circle(14).rect(24.7487,24.7487, forConstruction=True).vertices().hole(3.2).cutThruAll() - - for idx in range(8): - result = result.workplane(offset=1, centerOption='CenterOfBoundBox').center(-173,225-idx*h_sep4DB9).moveTo(-12.5,0).circle(1.6).moveTo(12.5,0).circle(1.6).moveTo(-6.038896,-5.7).threePointArc((-8.44306,-4.70416),(-9.438896,-2.3)).lineTo(-10.25,2.3).threePointArc((-9.25416,4.70416),(-6.85,5.7)).lineTo(6.85,5.7).threePointArc((9.25416,4.70416),(10.25,2.3)).lineTo(9.438896,-2.3).threePointArc((8.44306,-4.70416),(6.038896,-5.7)).close().cutThruAll() - - for idx in range(4): - result = result.workplane(offset=1, centerOption='CenterOfBoundBox').center(-173,-30-idx*h_sep).moveTo(-2.9176,-5.3).threePointArc((-6.05,0),(-2.9176,5.3)).lineTo(2.9176,5.3).threePointArc((6.05,0),(2.9176,-5.3)).close().cutThruAll() - - # Render the solid - build_object(result) diff --git a/Libs/cadquery-lib/doc/extending.rst b/Libs/cadquery-lib/doc/extending.rst deleted file mode 100644 index 8138b18..0000000 --- a/Libs/cadquery-lib/doc/extending.rst +++ /dev/null @@ -1,180 +0,0 @@ -.. _extending: - -Extending CadQuery -====================== - - -If you find that CadQuery doesnt suit your needs, you can easily extend it. CadQuery provides several extension -methods: - - * You can load plugins others have developed. This is by far the easiest way to access other code - * you can define your own plugins. - * you can use FreeCAD script directly - - -Using FreeCAD Script ------------------------ - -The easiest way to extend CadQuery is to simply use FreeCAD script inside of your build method. Just about -any valid FreeCAD script will execute just fine. For example, this simple CadQuery script:: - - return cq.Workplane("XY").box(1.0,2.0,3.0).val() - -is actually equivalent to:: - - return Part.makeBox(1.0,2.0,3.0) - -As long as you return a valid FreeCAD Shape, you can use any FreeCAD methods you like. You can even mix and match the -two. For example, consider this script, which creates a FreeCAD box, but then uses cadquery to select its faces:: - - box = Part.makeBox(1.0,2.0,3.0) - cq = CQ(box).faces(">Z").size() # returns 6 - - -Extending CadQuery: Plugins ----------------------------- - -Though you can get a lot done with FreeCAD, the code gets pretty nasty in a hurry. CadQuery shields you from -a lot of the complexity of the FreeCAD api. - -You can get the best of both worlds by wrapping your freecad script into a CadQuery plugin. - -A CadQuery plugin is simply a function that is attached to the CadQuery :py:meth:`cadquery.CQ` or :py:meth:`cadquery.Workplane` class. -When connected, your plugin can be used in the chain just like the built-in functions. - -There are a few key concepts important to understand when building a plugin - - -The Stack -------------------- - -Every CadQuery object has a local stack, which contains a list of items. The items on the stack will be -one of these types: - - * **A CadQuery SolidReference object**, which holds a reference to a FreeCAD solid - * **A FreeCAD object**, a Vertex, Edge, Wire, Face, Shell, Solid, or Compound - -The stack is available by using self.objects, and will always contain at least one object. - -.. note:: - - Objects and points on the stack are **always** in global coordinates. Similarly, any objects you - create must be created in terms of global coordinates as well! - - -Preserving the Chain ------------------------ - -CadQuery's fluent api relies on the ability to chain calls together one after another. For this to work, -you must return a valid CadQuery object as a return value. If you choose not to return a CadQuery object, -then your plugin will end the chain. Sometimes this is desired for example :py:meth:`cadquery.CQ.size` - -There are two ways you can safely continue the chain: - - 1. **return self** If you simply wish to modify the stack contents, you can simply return a reference to - self. This approach is destructive, because the contents of the stack are modified, but it is also the - simplest. - 2. :py:meth:`cadquery.CQ.newObject` Most of the time, you will want to return a new object. Using newObject will - return a new CQ or Workplane object having the stack you specify, and will link this object to the - previous one. This preserves the original object and its stack. - - -Helper Methods ------------------------ - -When you implement a CadQuery plugin, you are extending CadQuery's base objects. As a result, you can call any -CadQuery or Workplane methods from inside of your extension. You can also call a number of internal methods that -are designed to aid in plugin creation: - - - * :py:meth:`cadquery.Workplane._makeWireAtPoints` will invoke a factory function you supply for all points on the stack, - and return a properly constructed cadquery object. This function takes care of registering wires for you - and everything like that - - * :py:meth:`cadquery.Workplane.newObject` returns a new Workplane object with the provided stack, and with its parent set - to the current object. The preferred way to continue the chain - - * :py:meth:`cadquery.CQ.findSolid` returns the first Solid found in the chain, working from the current object upwards - in the chain. commonly used when your plugin will modify an existing solid, or needs to create objects and - then combine them onto the 'main' part that is in progress - - * :py:meth:`cadquery.Workplane._addPendingWire` must be called if you add a wire. This allows the base class to track all the wires - that are created, so that they can be managed when extrusion occurs. - - * :py:meth:`cadquery.Workplane.wire` gathers up all of the edges that have been drawn ( eg, by line, vline, etc ), and - attempts to combine them into a single wire, which is returned. This should be used when your plugin creates - 2-d edges, and you know it is time to collect them into a single wire. - - * :py:meth:`cadquery.Workplane.plane` provides a reference to the workplane, which allows you to convert between workplane - coordinates and global coordinates: - * :py:meth:`cadquery.freecad_impl.geom.Plane.toWorldCoords` will convert local coordinates to global ones - * :py:meth:`cadquery.freecad_impl.geom.Plane.toLocalCoords` will convet from global coordinates to local coordinates - -Coordinate Systems ------------------------ - -Keep in mind that the user may be using a work plane that has created a local coordinate system. Consequently, -the orientation of shapes that you create are often implicitly defined by the user's workplane. - -Any objects that you create must be fully defined in *global coordinates*, even though some or all of the users' -inputs may be defined in terms of local coordinates. - - -Linking in your plugin ------------------------ - -Your plugin is a single method, which is attached to the main Workplane or CadQuery object. - -Your plugin method's first parameter should be 'self', which will provide a reference to base class functionality. -You can also accept other arguments. - -To install it, simply attach it to the CadQuery or Workplane object, like this:: - - def _yourFunction(self,arg1,arg): - do stuff - return whatever_you_want - - cq.Workplane.yourPlugin = _yourFunction - -That's it! - -CadQueryExample Plugins ------------------------ -Some core cadquery code is intentionally written exactly like a plugin. -If you are writing your own plugins, have a look at these methods for inspiration: - - * :py:meth:`cadquery.Workplane.polygon` - * :py:meth:`cadquery.Workplane.cboreHole` - - -Plugin Example ------------------------ - -This ultra simple plugin makes cubes of the specified size for each stack point. - -(The cubes are off-center because the boxes have their lower left corner at the reference points.) - -.. cq_plot:: - - def makeCubes(self,length): - #self refers to the CQ or Workplane object - - #inner method that creates a cube - def _singleCube(pnt): - #pnt is a location in local coordinates - #since we're using eachpoint with useLocalCoordinates=True - return cq.Solid.makeBox(length,length,length,pnt) - - #use CQ utility method to iterate over the stack, call our - #method, and convert to/from local coordinates. - return self.eachpoint(_singleCube,True) - - #link the plugin into cadQuery - cq.Workplane.makeCubes = makeCubes - - #use the plugin - result = cq.Workplane("XY").box(6.0,8.0,0.5).faces(">Z")\ - .rect(4.0,4.0,forConstruction=True).vertices() \ - .makeCubes(1.0).combineSolids() - build_object(result) - diff --git a/Libs/cadquery-lib/doc/fileformat.rst b/Libs/cadquery-lib/doc/fileformat.rst deleted file mode 100644 index e34afa5..0000000 --- a/Libs/cadquery-lib/doc/fileformat.rst +++ /dev/null @@ -1,24 +0,0 @@ -.. _cadquery_reference: - -CadQuery Scripts and Object Output -====================================== - -CadQuery scripts are pure python scripts, that may follow a few conventions. - -If you are using cadquery as a library, there are no constraints. - -If you are using cadquery scripts inside of a cadquery execution environment, -like `The CadQuery Freecad Module `_ or -`parametricParts.com `_, there are a few conventions you need to be aware of: - - * cadquery is already imported as 'cq' - * to return an object to the container, you need to call the build_object() method. - -Each script generally has three sections: - - * Variable Assignments and metadata definitions - * cadquery and other python code - * object exports, via the export_object() function - - -see the :ref:`cqgi` section for more details. \ No newline at end of file diff --git a/Libs/cadquery-lib/doc/index.rst b/Libs/cadquery-lib/doc/index.rst deleted file mode 100644 index 41e3ce4..0000000 --- a/Libs/cadquery-lib/doc/index.rst +++ /dev/null @@ -1,58 +0,0 @@ - - -CadQuery Documentation -=================================== - -CadQuery is an intuitive, easy-to-use python library for building parametric 3D CAD models. It has several goals: - - * Build models with scripts that are as close as possible to how you'd describe the object to a human, - using a standard, already established programming language - - * Create parametric models that can be very easily customized by end users - - * Output high quality CAD formats like STEP and AMF in addition to traditional STL - - * Provide a non-proprietary, plain text model format that can be edited and executed with only a web browser - -See CadQuery in Action -------------------------- - -This `Getting Started Video `_ will show you what CadQuery can do. - - -Quick Links ------------------- - - * :ref:`quickstart` - * `CadQuery CheatSheet <_static/cadquery_cheatsheet.html>`_ - * :ref:`apireference` - -Table Of Contents -------------------- - -.. toctree:: - :maxdepth: 2 - - intro.rst - installation.rst - quickstart.rst - designprinciples.rst - primer.rst - fileformat.rst - examples.rst - apireference.rst - selectors.rst - classreference.rst - cqgi.rst - extending.rst - roadmap.rst - - - -Indices and tables -------------------- - -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` - diff --git a/Libs/cadquery-lib/doc/installation.rst b/Libs/cadquery-lib/doc/installation.rst deleted file mode 100644 index b5160b0..0000000 --- a/Libs/cadquery-lib/doc/installation.rst +++ /dev/null @@ -1,58 +0,0 @@ -.. _installation: - -Installing CadQuery -=================================== - -CadQuery is based on `FreeCAD `_, -which is turn based on the open-source `OpenCascade `_ modelling kernel. - -Prerequisites--FreeCAD and Python 2.6 or 2.7 ----------------------------------------------- -CadQuery requires FreeCAD and Python version 2.6.x or 2.7.x *Python 3.x is NOT supported* - -Ubuntu Command Line Installation ------------------------------------------- - -On Ubuntu, you can type:: - - sudo apt-get install -y freecad freecad-doc - pip install cadquery - -This `Unix Installation Video `_ will walk you through the installation - - -Installation: Other Platforms ------------------------------------------- - - 1. Install FreeCAD using the appropriate installer for your platform, on `www.freecadweb.org `_ - 2. pip install cadquery - -This `Windows Installation video `_ will walk you through the installation on Windows - -Test Your Installation ------------------------- - -If all has gone well, you can open a command line/prompt, and type:: - - $python - $import cadquery - $cadquery.Workplane('XY').box(1,2,3).toSvg() - -Adding a Nicer GUI via the cadquery-freecad-module --------------------------------------------------------- - -If you prefer to have a GUI available, your best option is to use -`The CadQuery Freecad Module `_. - -Simply extract cadquery-freecad-module into your FreeCAD installation. You'll end up -with a cadquery workbench that allows you to interactively run scripts, and then see the results in the FreeCAD GUI - -Zero Step Install -------------------------------------------------- - -If you would like to use cadquery with no installation all, you can -use `ParametricParts.com `_, a web-based platform that runs cadquery scripts - -It is free, and allows running and viewing cadquery scripts in your web browser or mobile phone - - diff --git a/Libs/cadquery-lib/doc/intro.rst b/Libs/cadquery-lib/doc/intro.rst deleted file mode 100644 index b2d64fd..0000000 --- a/Libs/cadquery-lib/doc/intro.rst +++ /dev/null @@ -1,95 +0,0 @@ -.. _what_is_cadquery: - -********************* -Introduction -********************* - -What is CadQuery -======================================== - -CadQuery is an intuitive, easy-to-use python library for building parametric 3D CAD models. It has several goals: - - * Build models with scripts that are as close as possible to how you'd describe the object to a human, - using a standard, already established programming language - - * Create parametric models that can be very easily customized by end users - - * Output high quality CAD formats like STEP and AMF in addition to traditional STL - - * Provide a non-proprietary, plain text model format that can be edited and executed with only a web browser - -CadQuery is based on -`FreeCAD `_, -which is turn based on the open-source `OpenCascade `_ modelling kernel. - -Using CadQuery, you can build fully parametric models with a very small amount of code. For example, this simple script -produces a flat plate with a hole in the middle:: - - thickness = 0.5 - width=2.0 - result = Workplane("front").box(width,width,thickness).faces(">Z").hole(thickness) - -.. image:: _static/simpleblock.png - -That's a bit of a dixie-cup example. But it is pretty similar to a more useful part: a parametric pillow block for a -standard 608-size ball bearing:: - - (length,height,diam, thickness,padding) = ( 30.0,40.0,22.0,10.0,8.0) - - result = Workplane("XY").box(length,height,thickness).faces(">Z").workplane().hole(diam)\ - .faces(">Z").workplane() \ - .rect(length-padding,height-padding,forConstruction=True) \ - .vertices().cboreHole(2.4,4.4,2.1) - -.. image:: _static/pillowblock.png - -Lots more examples are available in the :ref:`examples` - -CadQuery is a library, GUIs are separate -============================================== - -CadQuery is a library, that's intentionally designed to be usable as a GUI-less library. This enables -its use in a variety of engineering and scientific applications that create 3d models programmatically. - -If you'd like a GUI, you have a couple of options: - - * Install cadquery as a part of `The CadQuery Freecad Module `_ - * Use `ParametricParts.com `_, a web-based platform that runs cadQuery scripts - - -Why CadQuery instead of OpenSCAD? -============================================ - -Like OpenSCAD, CadQuery is an open-source, script based, parametric model generator. But CadQuery has several key advantages: - - 1. **The scripts use a standard programming language**, python, and thus can benefit from the associated infrastructure. - This includes many standard libraries and IDEs - - 2. **More powerful CAD kernel** OpenCascade is much more powerful than CGAL. Features supported natively - by OCC include NURBS, splines, surface sewing, STL repair, STEP import/export, and other complex operations, - in addition to the standard CSG operations supported by CGAL - - 3. **Ability to import/export STEP** We think the ability to begin with a STEP model, created in a CAD package, - and then add parametric features is key. This is possible in OpenSCAD using STL, but STL is a lossy format - - 4. **Less Code and easier scripting** CadQuery scripts require less code to create most objects, because it is possible to locate - features based on the position of other features, workplanes, vertices, etc. - - 5. **Better Performance** CadQuery scripts can build STL, STEP, and AMF faster than OpenSCAD. - -Where does the name CadQuery come from? -======================================== - -CadQuery is inspired by `jQuery `_ , a popular framework that -revolutionized web development involving javascript. - -CadQuery is for 3D CAD what jQuery is for javascript. -If you are familiar with how jQuery works, you will probably recognize several jQuery features that CadQuery uses: - - * A fluent api to create clean, easy to read code - - * Ability to use the library along side other python libraries - - * Clear and complete documentation, with plenty of samples. - - diff --git a/Libs/cadquery-lib/doc/primer.rst b/Libs/cadquery-lib/doc/primer.rst deleted file mode 100644 index b69af5a..0000000 --- a/Libs/cadquery-lib/doc/primer.rst +++ /dev/null @@ -1,153 +0,0 @@ -.. _3d_cad_primer: - - -CadQuery Concepts -=================================== - - -3D BREP Topology Concepts ---------------------------- -Before talking about CadQuery, it makes sense to talk a little about 3D CAD Topology. CadQuery is based upon the -OpenCascade kernel, which is uses Boundary Representations ( BREP ) for objects. This just means that objects -are defined by their enclosing surfaces. - -When working in a BREP system, these fundamental constructs exist to define a shape ( working up the food chain): - - :vertex: a single point in space - :edge: a connection between two or more vertices along a particular path ( called a curve ) - :wire: a collection of edges that are connected together. - :face: a set of edges or wires that enclose a surface - :shell: a collection of faces that are connected together along some of their edges - :solid: a shell that has a closed interior - :compound: a collection of solids - -When using CadQuery, all of these objects are created, hopefully with the least possible work. In the actual CAD -kernel, there are another set of Geometrical constructs involved as well. For example, an arc-shaped edge will -hold a reference to an underlying curve that is a full cricle, and each linear edge holds underneath it the equation -for a line. CadQuery shields you from these constructs. - - -CQ, the CadQuery Object ---------------------------- - -The CadQuery object wraps a BREP feature, and provides functionality around it. Typical examples include rotating, -transforming, combining objects, and creating workplanes. - -See :ref:`apireference` to learn more. - - -Workplanes ---------------------------- - -Workplanes represent a plane in space, from which other features can be located. They have a center point and a local -coordinate system. - -The most common way to create a workplane is to locate one on the face of a solid. You can also create new workplanes -in space, or relative to other planes using offsets or rotations. - -The most powerful feature of workplanes is that they allow you to work in 2D space in the coordinate system of the -workplane, and then build 3D features based on local coordinates. This makes scripts much easier to create and maintain. - -See :py:class:`cadquery.Workplane` to learn more - - -2D Construction ---------------------------- - -Once you create a workplane, you can work in 2D, and then later use the features you create to make 3D objects. -You'll find all of the 2D constructs you expect-- circles, lines, arcs, mirroring, points, etc. - -See :ref:`2dOperations` to learn more. - - -3D Construction ---------------------------- - -You can construct 3D primatives such as boxes, spheres, wedges, and cylinders directly. You can also sweep, extrude, -and loft 2D geometry to form 3D features. Of course the basic primitive operations are also available. - -See :ref:`3doperations` to learn more. - - - -Selectors ---------------------------- - -Selectors allow you to select one or more features, for use to define new features. As an example, you might -extrude a box, and then select the top face as the location for a new feture. Or, you might extrude a box, and -then select all of the vertical edges so that you can apply a fillet to them. - -You can select Vertices, Edges, Faces, Solids, and Wires using selectors. - -Think of selectors as the equivalent of your hand and mouse, were you to build an object using a conventional CAD system. - -You can learn more about selectors :ref:`selectors` - - -Construction Geometry ---------------------------- -Construction geometry are features that are not part of the object, but are only defined to aid in building the object. -A common example might be to define a rectangle, and then use the corners to define a the location of a set of holes. - -Most CadQuery construction methods provide a forConstruction keyword, which creates a feature that will only be used -to locate other features - - -The Stack ---------------------------- - -As you work in CadQuery, each operation returns a new CadQuery object with the result of that operations. Each CadQuery -object has a list of objects, and a reference to its parent. - -You can always go backwards to older operations by removing the current object from the stack. For example:: - - CQ(someObject).faces(">Z").first().vertices() - -returns a CadQuery object that contains all of the vertices on highest face of someObject. But you can always move -backwards in the stack to get the face as well:: - - CQ(someObject).faces(">Z").first().vertices().end() #returns the same as CQ(someObject).faces(">Z").first() - -You can browse stack access methods here :ref:`stackMethods` - - -Chaining ---------------------------- - -All CadQuery methods return another CadQuery object, so that you can chain the methods together fluently. Use -the core CQ methods to get at the objects that were created. - - -The Context Solid ---------------------------- - -Most of the time, you are building a single object, and adding features to that single object. CadQuery watches -your operations, and defines the first solid object created as the 'context solid'. After that, any features -you create are automatically combined ( unless you specify otherwise) with that solid. This happens even if the -solid was created a long way up in the stack. For example:: - - Workplane('XY').box(1,2,3).faces(">Z").circle(0.25).extrude() - -Will create a 1x2x3 box, with a cylindrical boss extending from the top face. It was not necessary to manually -combine the cylinder created by extruding the circle with the box, because the default behavior for extrude is -to combine the result with the context solid. The hole() method works similarly-- CadQuery presumes that you want -to subtract the hole from the context solid. - -If you want to avoid this, you can specified combine=False, and CadQuery will create the solid separately. - - -Iteration ---------------------------- - -CAD models often have repeated geometry, and its really annoying to resort to for loops to construct features. -Many CadQuery methods operate automatically on each element on the stack, so that you don't have to write loops. -For example, this:: - - Workplane('XY').box(1,2,3).faces(">Z").vertices().circle(0.5) - -Will actually create 4 circles, because vertices() selects 4 vertices of a rectangular face, and the circle() method -iterates on each member of the stack. - -This is really useful to remember when you author your own plugins. :py:meth:`cadquery.CQ.Workplane.each` is useful for this purpose. - - diff --git a/Libs/cadquery-lib/doc/quickstart.rst b/Libs/cadquery-lib/doc/quickstart.rst deleted file mode 100644 index 6701942..0000000 --- a/Libs/cadquery-lib/doc/quickstart.rst +++ /dev/null @@ -1,242 +0,0 @@ -.. _quickstart: - -*********************** -CadQuery QuickStart -*********************** - -.. module:: cadquery - -Want a quick glimpse of what CadQuery can do? This quickstart will demonstrate the basics of cadQuery using a simple example - -Prerequisites: FreeCAD + cadQuery-freeCAD-module in FreeCAD -============================================================== - -If you have not already done so, follow the :ref:`installation`, and to install cadquery, FreeCAD, -and the cadquery-freecad-module - -After installation, open the CadQuery workbench: - -.. image:: _static/quickstart/001.png - -You'll see that we start out with a single block. Find the cadquery Code Window, at the bottom left. - -If you want check out a couple of the examples in the CadQuery->Examples menu. - -What we'll accomplish -======================== - -We will build a fully parametric bearing pillow block in this quickstart. Our finished object will look like this: - -.. image:: _static/quickstart/000.png - -**We would like our block to have these features:** - - 1. It should be sized to hold a single 608 ( 'skate' ) bearing, in the center of the block. - 2. It should have counter sunk holes for M2 socket head cap screws at the corners - 3. The length and width of the block should be configurable by the user to any reasonable size. - -A human would describe this as: - - "A rectangular block 80mm x 60mm x 30mm , with countersunk holes for M2 socket head cap screws - at the corners, and a circular pocket 22mm in diameter in the middle for a bearing" - -Human descriptions are very elegant, right? -Hopefully our finished script will not be too much more complex than this human-oriented description. - -Let's see how we do. - -Start With A single, simple Plate -====================================== - -Lets start with a simple model that makes nothing but a rectangular block, but -with place-holders for the dimensions. Paste this into the CodeWindow: - -.. code-block:: python - :linenos: - - height = 60.0 - width = 80.0 - thickness = 10.0 - - # make the base - result = cq.Workplane("XY").box(height, width, thickness) - - # Render the solid - build_object(result) - -Press F2 to run the script. You should see Our basic base. - -.. image:: _static/quickstart/002.png - -Nothing special, but its a start! - -Add the Holes -================ - -Our pillow block needs to have a 22mm diameter hole in the center of this block to hold the bearing. - -This modification will do the trick: - -.. code-block:: python - :linenos: - :emphasize-lines: 4,8 - - height = 60.0 - width = 80.0 - thickness = 10.0 - diameter = 22.0 - - # make the base - result = cq.Workplane("XY").box(height, width, thickness)\ - .faces(">Z").workplane().hole(diameter) - - # Render the solid - build_object(result) - -Rebuild your model by pressing F2. Your block should look like this: - -.. image:: _static/quickstart/003.png - - -The code is pretty compact, lets step through it. - -**Line 4** adds a new parameter, diameter, for the diamter of the hole - -**Line 8**, we're adding the hole. -:py:meth:`cadquery.CQ.faces` selects the top-most face in the Z direction, and then -:py:meth:`cadquery.CQ.workplane` begins a new workplane located on this face. The center of this workplane -is located at the geometric center of the shape, which in this case is the center of the plate. -Finally, :py:meth:`cadquery.Workplane.hole` drills a hole through the part 22mm in diamter - -.. note:: - - Don't worry about the CadQuery syntax now.. you can learn all about it in the :ref:`apireference` later. - -More Holes -============ - -Ok, that hole was not too hard, but what about the counter-bored holes in the corners? - -An M2 Socket head cap screw has these dimensions: - - * **Head Diameter** : 3.8 mm - * **Head height** : 2.0 mm - * **Clearance Hole** : 2.4 mm - * **CounterBore diameter** : 4.4 mm - -The centers of these holes should be 4mm from the edges of the block. And, -we want the block to work correctly even when the block is re-sized by the user. - -**Don't tell me** we'll have to repeat the steps above 8 times to get counter-bored holes? -Good news!-- we can get the job done with just two lines of code. Here's the code we need: - -.. code-block:: python - :linenos: - :emphasize-lines: 5,10-13 - - height = 60.0 - width = 80.0 - thickness = 10.0 - diameter = 22.0 - padding = 12.0 - - # make the base - result = cq.Workplane("XY").box(height, width, thickness)\ - .faces(">Z").workplane().hole(diameter)\ - .faces(">Z").workplane() \ - .rect(height - padding,width - padding,forConstruction=True)\ - .vertices()\ - .cboreHole(2.4, 4.4, 2.1) - - # Render the solid - build_object(result) - - -After pressing F2 to re-execute the model, you should see something like this: - - .. image:: _static/quickstart/004.png - - -There is quite a bit going on here, so lets break it down a bit. - -**Line 5** creates a new padding parameter that decides how far the holes are from the edges of the plate. - -**Line 10** selects the top-most face of the block, and creates a workplane on the top of that face, which we'll use to -define the centers of the holes in the corners. - -There are a couple of things to note about this line: - - 1. The :py:meth:`cadquery.Workplane.rect` function draws a rectangle. **forConstruction=True** - tells CadQuery that this rectangle will not form a part of the solid, - but we are just using it to help define some other geometry. - 2. The center point of a workplane on a face is always at the center of the face, which works well here - 3. Unless you specifiy otherwise, a rectangle is drawn with its center on the current workplane center-- in - this case, the center of the top face of the block. So this rectangle will be centered on the face - - -**Line 11** draws a rectangle 8mm smaller than the overall length and width of the block,which we will use to -locate the corner holes. We'll use the vertices ( corners ) of this rectangle to locate the holes. The rectangle's -center is at the center of the workplane, which in this case co-incides with the center of the bearing hole. - -**Line 12** selects the vertices of the rectangle, which we will use for the centers of the holes. -The :py:meth:`cadquery.CQ.vertices` function selects the corners of the rectangle - -**Line 13** uses the cboreHole function to draw the holes. -The :py:meth:`cadquery.Workplane.cboreHole` function is a handy CadQuery function that makes a counterbored hole, -like most other CadQuery functions, operate on the values on the stack. In this case, since we -selected the four vertices before calling the function, the function operates on each of the four points-- -which results in a counterbore hole at the corners. - - -Filleting -=========== - -Almost done. Let's just round the corners of the block a bit. That's easy, we just need to select the edges -and then fillet them: - -We can do that using the preset dictionaries in the parameter definition: - -.. code-block:: python - :linenos: - :emphasize-lines: 13 - - height = 60.0 - width = 80.0 - thickness = 10.0 - diameter = 22.0 - padding = 12.0 - - # make the base - result = cq.Workplane("XY").box(height, width, thickness)\ - .faces(">Z").workplane().hole(diameter)\ - .faces(">Z").workplane() \ - .rect(height - padding, width - padding, forConstruction=True)\ - .vertices().cboreHole(2.4, 4.4, 2.1)\ - .edges("|Z").fillet(2.0) - - # Render the solid - build_object(result) - -**Line 13** fillets the edges using the :py:meth:`cadquery.CQ.fillet` method. - -To grab the right edges, the :py:meth:`cadquery.CQ.edges` selects all of the -edges that are parallel to the Z axis ("\|Z"), - -The finished product looks like this: - - .. image:: _static/quickstart/005.png - - -Done! -============ - -You just made a parametric, model that can generate pretty much any bearing pillow block -with < 20 lines of code. - -Want to learn more? -==================== - - * Use the CadQuery->Examples menu of the cadquery workbench to explore a lot of other examples. - * The :ref:`examples` contains lots of examples demonstrating cadquery features - * The :ref:`apireference` is a good overview of language features grouped by function - * The :ref:`classreference` is the hard-core listing of all functions available. \ No newline at end of file diff --git a/Libs/cadquery-lib/doc/roadmap.rst b/Libs/cadquery-lib/doc/roadmap.rst deleted file mode 100644 index a5b7e28..0000000 --- a/Libs/cadquery-lib/doc/roadmap.rst +++ /dev/null @@ -1,154 +0,0 @@ -.. _roadmap: - - -RoadMap: Planned Features -============================== - -**CadQuery is not even close to finished!!!** - -Many features are planned for later versions. This page tracks them. If you find that you need features -not listed here, let us know! - -Core --------------------- - -end(n) - allows moving backwards a fixed number of parents in the chain, eg end(3) is same as end().end().end() - -FreeCAD object wrappers - return CQ wrappers for FreeCAD shapes instead of the native FreeCAD objects. - -Improved iteration tools for plugin developers - make it easier to iterate over points and wires for plugins - -More parameter types (String? ) - -face.outerWire - allow selecting the outerWire of a face, so that it can be used for reference geometry or offsets - -Selectors --------------------- - -tagged entities - support tagging entities when they are created, so they can be selected later on using that tag. - ideally, tags are propagated to features that are created from these features ( ie, an edge tagged with 'foo' - that is later extruded into a face means that face would be tagged with 'foo' as well ) - - -Workplanes --------------------- - -rotated workplanes - support creation of workplanes at an angle to another plane or face - -workplane local rotations - rotate the coordinate system of a workplane by an angle. - -make a workplane from a wire - useful to select outer wire and then operate from there, to allow offsets - -2-d operations -------------------- - -offsets - offset profiles, including circles, rects, and other profiles. - -ellipses - create elipses and portions of elipses - -regular polygons - several construction methods: - * number of sides and side length - * number of sides inscribed in circle - * number of sides circumscribed by circle - -arc construction using relative measures - instead of forcing use of absolute workplane coordinates - -tangent arcs - after a line - -centerpoint arcs - including portions of arcs as well as with end points specified - -trimming - ability to use construction geometry to trim other entities - -construction lines - especially centerlines - -2-d fillets - for a rectangle, or for consecutive selected lines - -2-d chamfers - based on rectangles, polygons, polylines, or adjacent selected lines - -mirror around centerline - using centerline construction geometry - -rectangular array - automate creation of equally spread points - -polar array - create equally spaced copies of a feature around a circle - perhaps based on a construction circle? - -midpoint selection - select midpoints of lines, arcs - -face center - explicit selection of face center - -manipulate spline control points - so that the shape of a spline can be more accurately controlled - -feature snap - project geometry in the rest of the part into the work plane, so that - they can be selected and used as references for other features. - -polyline edges - allow polyline to be combined with other edges/curves - -create text - ideally, in various fonts. - -3-d operations ---------------------- - -rotation/transform that return a copy - The current rotateAboutCenter and translate method modify the object, rather than returning a copy - -primitive creation - Need primitive creation for: - * cone - * sphere - * cylinder - * torus - * wedge - -extrude/cut up to surface - allow a cut or extrude to terminate at another surface, rather than either through all or a fixed distance - -extrude along a path - rather than just normal to the plane. This would include - -STEP import - allow embedding and importing step solids created in other tools, which - can then be further manipulated parametrically - -Dome - very difficult to do otherwise - -primitive boolean operations - * intersect - * union - * subtract - - -Algorithms ---------------------- - -Wire Discretization - Sample wires at point interval to improve closet wire computations - - diff --git a/Libs/cadquery-lib/doc/selectors.rst b/Libs/cadquery-lib/doc/selectors.rst deleted file mode 100644 index c40c547..0000000 --- a/Libs/cadquery-lib/doc/selectors.rst +++ /dev/null @@ -1,140 +0,0 @@ -.. _selector_reference: - -String Selectors Reference -============================= - - -CadQuery selector strings allow filtering various types of object lists. Most commonly, Edges, Faces, and Vertices are -used, but all objects types can be filtered. - -String selectors are simply shortcuts for using the full object equivalents. If you pass one of the -string patterns in, CadQuery will automatically use the associated selector object. - - * :py:meth:`cadquery.CQ.faces` - * :py:meth:`cadquery.CQ.edges` - * :py:meth:`cadquery.CQ.vertices` - * :py:meth:`cadquery.CQ.solids` - * :py:meth:`cadquery.CQ.shells` - -.. note:: - - String selectors are shortcuts to concrete selector classes, which you can use or extend. See - :ref:`classreference` for more details - - If you find that the built-in selectors are not sufficient, you can easily plug in your own. - See :ref:`extending` to see how. - - -Combining Selectors -========================== - -Selectors can be combined logically, currently defined operators include **and**, **or**, **not** and **exc[ept]** (set difference). For example: - -.. cq_plot:: - - result = cq.Workplane("XY").box(2, 2, 2) \ - .edges("|Z and >Y") \ - .chamfer(0.2) - - build_object(result) - -Much more complex expressions are possible as well: - -.. cq_plot:: - - result = cq.Workplane("XY").box(2, 2, 2) \ - .faces(">Z") \ - .shell(-0.2) \ - .faces(">Z") \ - .edges("not(X or Y)") \ - .chamfer(0.1) - - build_object(result) - -.. _filteringfaces: - -Filtering Faces ----------------- - -All types of filters work on faces. In most cases, the selector refers to the direction of the **normal vector** -of the face. - -.. warning:: - - If a face is not planar, selectors are evaluated at the center of mass of the face. This can lead - to results that are quite unexpected. - -The axis used in the listing below are for illustration: any axis would work similarly in each case. - -========= ======================================= ======================================================= ========================== -Selector Selects Selector Class # objects returned -========= ======================================= ======================================================= ========================== -+Z Faces with normal in +z direction :py:class:`cadquery.DirectionSelector` 0..many -\|Z Faces parallel to xy plane :py:class:`cadquery.ParallelDirSelector` 0..many --X Faces with normal in neg x direction :py:class:`cadquery.DirectionSelector` 0..many -#Z Faces perpendicular to z direction :py:class:`cadquery.PerpendicularDirSelector` 0..many -%Plane Faces of type plane :py:class:`cadquery.TypeSelector` 0..many ->Y Face farthest in the positive y dir :py:class:`cadquery.DirectionMinMaxSelector` 0..many -Y[-2] 2nd Face farthest in the positive y dir :py:class:`cadquery.DirectionMinMaxSelector` 0..many -Y Edges farthest in the positive y dir :py:class:`cadquery.DirectionMinMaxSelector` 0..many -Y[1] 2nd closest edge in the positive y dir :py:class:`cadquery.DirectionMinMaxSelector` 0..many -Y Vertices farthest in the positive y dir :py:class:`cadquery.DirectionMinMaxSelector` 0..many -(-1,1,0)').chamfer(1) - - build_object(result) diff --git a/Libs/cadquery-lib/examples/FreeCAD/Ex001_Simple_Block.py b/Libs/cadquery-lib/examples/FreeCAD/Ex001_Simple_Block.py deleted file mode 100644 index 8e1609c..0000000 --- a/Libs/cadquery-lib/examples/FreeCAD/Ex001_Simple_Block.py +++ /dev/null @@ -1,32 +0,0 @@ -#File: Ex001_Simple_Block.py -#To use this example file, you need to first follow the "Using CadQuery From Inside FreeCAD" -#instructions here: https://github.com/dcowden/cadquery#installing----using-cadquery-from-inside-freecad - -#You run this example by typing the following in the FreeCAD python console, making sure to change -#the path to this example, and the name of the example appropriately. -#import sys -#sys.path.append('/home/user/Downloads/cadquery/examples/FreeCAD') -#import Ex001_Simple_Block - -#If you need to reload the part after making a change, you can use the following lines within the FreeCAD console. -#reload(Ex001_Simple_Block) - -#You'll need to delete the original shape that was created, and the new shape should be named sequentially -# (Shape001, etc). - -#You can also tie these blocks of code to macros, buttons, and keybindings in FreeCAD for quicker access. -#You can get a more in-depth explanation of this example at http://parametricparts.com/docs/quickstart.html - -import cadquery -import Part - -#The dimensions of the box. These can be modified rather than changing the box's code directly. -length = 80.0 -height = 60.0 -thickness = 10.0 - -#Create a 3D box based on the dimension variables above -result = cadquery.Workplane("XY").box(length, height, thickness) - -#Boiler plate code to render our solid in FreeCAD's GUI -Part.show(result.toFreecad()) \ No newline at end of file diff --git a/Libs/cadquery-lib/examples/FreeCAD/Ex002_Block_With_Bored_Center_Hole.py b/Libs/cadquery-lib/examples/FreeCAD/Ex002_Block_With_Bored_Center_Hole.py deleted file mode 100644 index ea405f5..0000000 --- a/Libs/cadquery-lib/examples/FreeCAD/Ex002_Block_With_Bored_Center_Hole.py +++ /dev/null @@ -1,33 +0,0 @@ -#File: Ex002_Block_With_Bored_Center_Hole.py -#To use this example file, you need to first follow the "Using CadQuery From Inside FreeCAD" -#instructions here: https://github.com/dcowden/cadquery#installing----using-cadquery-from-inside-freecad - -#You run this example by typing the following in the FreeCAD python console, making sure to change -#the path to this example, and the name of the example appropriately. -#import sys -#sys.path.append('/home/user/Downloads/cadquery/examples/FreeCAD') -#import Ex002_Block_With_Bored_Center_Hole - -#If you need to reload the part after making a change, you can use the following lines within the FreeCAD console. -#reload(Ex002_Block_With_Bored_Center_Hole) - -#You'll need to delete the original shape that was created, and the new shape should be named sequentially (Shape001, etc). - -#You can also tie these blocks of code to macros, buttons, and keybindings in FreeCAD for quicker access. -#You can get a more in-depth explantion of this example at http://parametricparts.com/docs/quickstart.html - -import cadquery -import Part - -#The dimensions of the box. These can be modified rather than changing the box's code directly. -length = 80.0 -height = 60.0 -thickness = 10.0 -center_hole_dia = 22.0 - -#Create a 3D box based on the dimension variables above and add a 22mm center hole -result = cadquery.Workplane("XY").box(length, height, thickness) \ - .faces(">Z").workplane().hole(center_hole_dia) - -#Boiler plate code to render our solid in FreeCAD's GUI -Part.show(result.toFreecad()) \ No newline at end of file diff --git a/Libs/cadquery-lib/examples/FreeCAD/Ex003_Pillow_Block_With_Counterbored_Holes.py b/Libs/cadquery-lib/examples/FreeCAD/Ex003_Pillow_Block_With_Counterbored_Holes.py deleted file mode 100644 index 382f03e..0000000 --- a/Libs/cadquery-lib/examples/FreeCAD/Ex003_Pillow_Block_With_Counterbored_Holes.py +++ /dev/null @@ -1,40 +0,0 @@ -#File: Ex003_Pillow_Block_With_Counterbored_Holes.py -#To use this example file, you need to first follow the "Using CadQuery From Inside FreeCAD" -#instructions here: https://github.com/dcowden/cadquery#installing----using-cadquery-from-inside-freecad - -#You run this example by typing the following in the FreeCAD python console, making sure to change -#the path to this example, and the name of the example appropriately. -#import sys -#sys.path.append('/home/user/Downloads/cadquery/examples/FreeCAD') -#import Ex003_Pillow_Block_With_Counterbored_Holes - -#If you need to reload the part after making a change, you can use the following lines within the FreeCAD console. -#reload(Ex003_Pillow_Block_With_Counterbored_Holes) - -#You'll need to delete the original shape that was created, and the new shape should be named sequentially -# (Shape001, etc). - -#You can also tie these blocks of code to macros, buttons, and keybindings in FreeCAD for quicker access. -#You can get a more in-depth explanation of this example at http://parametricparts.com/docs/quickstart.html - -import cadquery -import Part - -#The dimensions of the box. These can be modified rather than changing the box's code directly. -length = 80.0 -height = 60.0 -thickness = 10.0 -center_hole_dia = 22.0 -cbore_hole_diameter = 2.4 -cbore_diameter = 4.4 -cbore_depth = 2.1 - -#Create a 3D box based on the dimension variables above and add 4 counterbored holes -result = cadquery.Workplane("XY").box(length, height, thickness) \ - .faces(">Z").workplane().hole(center_hole_dia) \ - .faces(">Z").workplane() \ - .rect(length - 8.0, height - 8.0, forConstruction = True) \ - .vertices().cboreHole(cbore_hole_diameter, cbore_diameter, cbore_depth) - -#Boiler plate code to render our solid in FreeCAD's GUI -Part.show(result.toFreecad()) \ No newline at end of file diff --git a/Libs/cadquery-lib/examples/FreeCAD/Ex004_Extruded_Cylindrical_Plate.py b/Libs/cadquery-lib/examples/FreeCAD/Ex004_Extruded_Cylindrical_Plate.py deleted file mode 100644 index 8b631ce..0000000 --- a/Libs/cadquery-lib/examples/FreeCAD/Ex004_Extruded_Cylindrical_Plate.py +++ /dev/null @@ -1,34 +0,0 @@ -#File: Ex004_Extruded_Cylindrical_Plate.py -#To use this example file, you need to first follow the "Using CadQuery From Inside FreeCAD" -#instructions here: https://github.com/dcowden/cadquery#installing----using-cadquery-from-inside-freecad - -#You run this example by typing the following in the FreeCAD python console, making sure to change -#the path to this example, and the name of the example appropriately. -#import sys -#sys.path.append('/home/user/Downloads/cadquery/examples/FreeCAD') -#import Ex004_Extruded_Cylindrical_Plate - -#If you need to reload the part after making a change, you can use the following lines within the FreeCAD console. -#reload(Ex004_Extruded_Cylindrical_Plate) - -#You'll need to delete the original shape that was created, and the new shape should be named sequentially -# (Shape001, etc). - -#You can also tie these blocks of code to macros, buttons, and keybindings in FreeCAD for quicker access. -#You can get a more information on this example at -# http://parametricparts.com/docs/examples.html#an-extruded-prismatic-solid - -import cadquery -import Part - -#The dimensions of the model. These can be modified rather than changing the box's code directly. -circle_radius = 50.0 -rectangle_width = 13.0 -rectangle_length = 19.0 -thickness = 13.0 - -#Extrude a cylindrical plate with a rectangular hole in the middle of it -result = cadquery.Workplane("front").circle(circle_radius).rect(rectangle_width, rectangle_length).extrude(thickness) - -#Boiler plate code to render our solid in FreeCAD's GUI -Part.show(result.toFreecad()) \ No newline at end of file diff --git a/Libs/cadquery-lib/examples/FreeCAD/Ex005_Extruded_Lines_and_Arcs.py b/Libs/cadquery-lib/examples/FreeCAD/Ex005_Extruded_Lines_and_Arcs.py deleted file mode 100644 index 9994434..0000000 --- a/Libs/cadquery-lib/examples/FreeCAD/Ex005_Extruded_Lines_and_Arcs.py +++ /dev/null @@ -1,33 +0,0 @@ -#File: Ex005_Extruded_Lines_and_Arcs.py -#To use this example file, you need to first follow the "Using CadQuery From Inside FreeCAD" -#instructions here: https://github.com/dcowden/cadquery#installing----using-cadquery-from-inside-freecad - -#You run this example by typing the following in the FreeCAD python console, making sure to change -#the path to this example, and the name of the example appropriately. -#import sys -#sys.path.append('/home/user/Downloads/cadquery/examples/FreeCAD') -#import Ex005_Extruded_Lines_and_Arcs - -#If you need to reload the part after making a change, you can use the following lines within the FreeCAD console. -#reload(Ex005_Extruded_Lines_and_Arcs) - -#You'll need to delete the original shape that was created, and the new shape should be named sequentially -#(Shape001, etc). - -#You can also tie these blocks of code to macros, buttons, and keybindings in FreeCAD for quicker access. -#You can get a more information on this example at -# http://parametricparts.com/docs/examples.html#an-extruded-prismatic-solid - -import cadquery -import Part - -#The dimensions of the model. These can be modified rather than changing the box's code directly. -width = 2.0 -thickness = 0.25 - -#Extrude a plate outline made of lines and an arc -result = cadquery.Workplane("front").lineTo(width, 0).lineTo(width, 1.0).threePointArc((1.0, 1.5),(0.0, 1.0)) \ - .close().extrude(thickness) - -#Boiler plate code to render our solid in FreeCAD's GUI -Part.show(result.toFreecad()) \ No newline at end of file diff --git a/Libs/cadquery-lib/examples/FreeCAD/Ex006_Moving_the_Current_Working_Point.py b/Libs/cadquery-lib/examples/FreeCAD/Ex006_Moving_the_Current_Working_Point.py deleted file mode 100644 index 892396c..0000000 --- a/Libs/cadquery-lib/examples/FreeCAD/Ex006_Moving_the_Current_Working_Point.py +++ /dev/null @@ -1,38 +0,0 @@ -#File: Ex006_Moving_the_Current_Working_Point.py -#To use this example file, you need to first follow the "Using CadQuery From Inside FreeCAD" -#instructions here: https://github.com/dcowden/cadquery#installing----using-cadquery-from-inside-freecad - -#You run this example by typing the following in the FreeCAD python console, making sure to change -#the path to this example, and the name of the example appropriately. -#import sys -#sys.path.append('/home/user/Downloads/cadquery/examples/FreeCAD') -#import Ex006_Moving_the_Current_Working_Point - -#If you need to reload the part after making a change, you can use the following lines within the FreeCAD console. -#reload(Ex006_Moving_the_Current_Working_Point) - -#You'll need to delete the original shape that was created, and the new shape should be named sequentially -# (Shape001, etc). - -#You can also tie these blocks of code to macros, buttons, and keybindings in FreeCAD for quicker access. -#You can get a more information on this example at -# http://parametricparts.com/docs/examples.html#an-extruded-prismatic-solid - -import cadquery -import Part - -#The dimensions of the model. These can be modified rather than changing the box's code directly. -circle_radius = 3.0 -thickness = 0.25 - -#Make the plate with two cutouts in it -result = cadquery.Workplane("front").circle(circle_radius) # Current point is the center of the circle, at (0,0) -result = result.center(1.5,0.0).rect(0.5,0.5) # New work center is (1.5,0.0) - -result = result.center(-1.5,1.5).circle(0.25) # New work center is ( 0.0,1.5). -#The new center is specified relative to the previous center, not global coordinates! - -result = result.extrude(thickness) - -#Boiler plate code to render our solid in FreeCAD's GUI -Part.show(result.toFreecad()) \ No newline at end of file diff --git a/Libs/cadquery-lib/examples/FreeCAD/Ex007_Using_Point_Lists.py b/Libs/cadquery-lib/examples/FreeCAD/Ex007_Using_Point_Lists.py deleted file mode 100644 index 2609d84..0000000 --- a/Libs/cadquery-lib/examples/FreeCAD/Ex007_Using_Point_Lists.py +++ /dev/null @@ -1,36 +0,0 @@ -#File: Ex007_Using_Point_Lists.py -#To use this example file, you need to first follow the "Using CadQuery From Inside FreeCAD" -#instructions here: https://github.com/dcowden/cadquery#installing----using-cadquery-from-inside-freecad - -#You run this example by typing the following in the FreeCAD python console, making sure to change -#the path to this example, and the name of the example appropriately. -#import sys -#sys.path.append('/home/user/Downloads/cadquery/examples/FreeCAD') -#import Ex007_Using_Point_Lists - -#If you need to reload the part after making a change, you can use the following lines within the FreeCAD console. -#reload(Ex007_Using_Point_Lists) - -#You'll need to delete the original shape that was created, and the new shape should be named sequentially -# (Shape001, etc). - -#You can also tie these blocks of code to macros, buttons, and keybindings in FreeCAD for quicker access. -#You can get a more information on this example at -# http://parametricparts.com/docs/examples.html#an-extruded-prismatic-solid - -import cadquery -import Part - -#The dimensions of the model. These can be modified rather than changing the box's code directly. -plate_radius = 2.0 -hole_pattern_radius = 0.25 -thickness = 0.125 - -#Make the plate with 4 holes in it at various points -r = cadquery.Workplane("front").circle(plate_radius) # Make the base -r = r.pushPoints([(1.5, 0), (0, 1.5), (-1.5, 0), (0, -1.5)]) # Now four points are on the stack -r = r.circle(hole_pattern_radius) # Circle will operate on all four points -result = r.extrude(thickness) - -#Boiler plate code to render our solid in FreeCAD's GUI -Part.show(result.toFreecad()) \ No newline at end of file diff --git a/Libs/cadquery-lib/examples/FreeCAD/Ex008_Polygon_Creation.py b/Libs/cadquery-lib/examples/FreeCAD/Ex008_Polygon_Creation.py deleted file mode 100644 index 6eefe13..0000000 --- a/Libs/cadquery-lib/examples/FreeCAD/Ex008_Polygon_Creation.py +++ /dev/null @@ -1,36 +0,0 @@ -#File: Ex008_Polygon_Creation.py -#To use this example file, you need to first follow the "Using CadQuery From Inside FreeCAD" -#instructions here: https://github.com/dcowden/cadquery#installing----using-cadquery-from-inside-freecad - -#You run this example by typing the following in the FreeCAD python console, making sure to change -#the path to this example, and the name of the example appropriately. -#import sys -#sys.path.append('/home/user/Downloads/cadquery/examples/FreeCAD') -#import Ex008_Polygon_Creation - -#If you need to reload the part after making a change, you can use the following lines within the FreeCAD console. -#reload(Ex008_Polygon_Creation) - -#You'll need to delete the original shape that was created, and the new shape should be named sequentially -# (Shape001, etc). - -#You can also tie these blocks of code to macros, buttons, and keybindings in FreeCAD for quicker access. -#You can get a more information on this example at -# http://parametricparts.com/docs/examples.html#an-extruded-prismatic-solid - -import cadquery -import Part - -#The dimensions of the model. These can be modified rather than changing the box's code directly. -width = 3.0 -height = 4.0 -thickness = 0.25 -polygon_sides = 6 -polygon_dia = 1.0 - -#Create a plate with two polygons cut through it -result = cadquery.Workplane("front").box(width, height, thickness).pushPoints([(0, 0.75), (0, -0.75)]) \ - .polygon(polygon_sides, polygon_dia).cutThruAll() - -#Boiler plate code to render our solid in FreeCAD's GUI -Part.show(result.toFreecad()) \ No newline at end of file diff --git a/Libs/cadquery-lib/examples/FreeCAD/Ex009_Polylines.py b/Libs/cadquery-lib/examples/FreeCAD/Ex009_Polylines.py deleted file mode 100644 index 73f9259..0000000 --- a/Libs/cadquery-lib/examples/FreeCAD/Ex009_Polylines.py +++ /dev/null @@ -1,44 +0,0 @@ -#File: Ex009_Polylines.py -#To use this example file, you need to first follow the "Using CadQuery From Inside FreeCAD" -#instructions here: https://github.com/dcowden/cadquery#installing----using-cadquery-from-inside-freecad - -#You run this example by typing the following in the FreeCAD python console, making sure to change -#the path to this example, and the name of the example appropriately. -#import sys -#sys.path.append('/home/user/Downloads/cadquery/examples/FreeCAD') -#import Ex009_Polylines - -#If you need to reload the part after making a change, you can use the following lines within the FreeCAD console. -#reload(Ex009_Polylines) - -#You'll need to delete the original shape that was created, and the new shape should be named sequentially -# (Shape001, etc). - -#You can also tie these blocks of code to macros, buttons, and keybindings in FreeCAD for quicker access. -#You can get a more information on this example at -# http://parametricparts.com/docs/examples.html#an-extruded-prismatic-solid - -import cadquery -import Part - -#Set up our Length, Height, Width, and thickness that will be used to define the locations that the polyline -#is drawn to/thru -(L, H, W, t) = (100.0, 20.0, 20.0, 1.0) - -#Define the locations that the polyline will be drawn to/thru -pts = [ - (0, H/2.0), - (W/2.0, H/2.0), - (W/2.0, (H/2.0 - t)), - (t/2.0, (H/2.0-t)), - (t/2.0, (t - H/2.0)), - (W/2.0, (t - H/2.0)), - (W/2.0, H/-2.0), - (0, H/-2.0) -] - -#We generate half of the I-beam outline and then mirror it to create the full I-beam -result = cadquery.Workplane("front").polyline(pts).mirrorY().extrude(L) - -#Boiler plate code to render our solid in FreeCAD's GUI -Part.show(result.toFreecad()) \ No newline at end of file diff --git a/Libs/cadquery-lib/examples/FreeCAD/Ex010_Defining_an_Edge_with_a_Spline.py b/Libs/cadquery-lib/examples/FreeCAD/Ex010_Defining_an_Edge_with_a_Spline.py deleted file mode 100644 index 7a9534a..0000000 --- a/Libs/cadquery-lib/examples/FreeCAD/Ex010_Defining_an_Edge_with_a_Spline.py +++ /dev/null @@ -1,45 +0,0 @@ -#File: Ex010_Defining_an_Edge_with_a_Spline.py -#To use this example file, you need to first follow the "Using CadQuery From Inside FreeCAD" -#instructions here: https://github.com/dcowden/cadquery#installing----using-cadquery-from-inside-freecad - -#You run this example by typing the following in the FreeCAD python console, making sure to change -#the path to this example, and the name of the example appropriately. -#import sys -#sys.path.append('/home/user/Downloads/cadquery/examples/FreeCAD') -#import Ex010_Defining_an_Edge_with_a_Spline - -#If you need to reload the part after making a change, you can use the following lines within the FreeCAD console. -#reload(Ex010_Defining_an_Edge_with_a_Spline) - -#You'll need to delete the original shape that was created, and the new shape should be named sequentially -# (Shape001, etc). - -#You can also tie these blocks of code to macros, buttons, and keybindings in FreeCAD for quicker access. -#You can get a more information on this example at -# http://parametricparts.com/docs/examples.html#an-extruded-prismatic-solid - -import cadquery -import Part - -#The workplane we want to create the spline on to extrude -s = cadquery.Workplane("XY") - -#The points that the spline will pass through -sPnts = [ - (2.75, 1.5), - (2.5, 1.75), - (2.0, 1.5), - (1.5, 1.0), - (1.0, 1.25), - (0.5, 1.0), - (0, 1.0) -] - -#Generate our plate with the spline feature and make sure it's a closed entity -r = s.lineTo(3.0, 0).lineTo(3.0, 1.0).spline(sPnts).close() - -#Extrude to turn the wire into a plate -result = r.extrude(0.5) - -#Boiler plate code to render our solid in FreeCAD's GUI -Part.show(result.toFreecad()) \ No newline at end of file diff --git a/Libs/cadquery-lib/examples/FreeCAD/Ex011_Mirroring_Symmetric_Geometry.py b/Libs/cadquery-lib/examples/FreeCAD/Ex011_Mirroring_Symmetric_Geometry.py deleted file mode 100644 index 54a02b6..0000000 --- a/Libs/cadquery-lib/examples/FreeCAD/Ex011_Mirroring_Symmetric_Geometry.py +++ /dev/null @@ -1,34 +0,0 @@ -#File: Ex011_Mirroring_Symmetric_Geometry.py -#To use this example file, you need to first follow the "Using CadQuery From Inside FreeCAD" -#instructions here: https://github.com/dcowden/cadquery#installing----using-cadquery-from-inside-freecad - -#You run this example by typing the following in the FreeCAD python console, making sure to change -#the path to this example, and the name of the example appropriately. -#import sys -#sys.path.append('/home/user/Downloads/cadquery/examples/FreeCAD') -#import Ex011_Mirroring_Symmetric_Geometry - -#If you need to reload the part after making a change, you can use the following lines within the FreeCAD console. -#reload(Ex011_Mirroring_Symmetric_Geometry) - -#You'll need to delete the original shape that was created, and the new shape should be named sequentially -# (Shape001, etc). - -#You can also tie these blocks of code to macros, buttons, and keybindings in FreeCAD for quicker access. -#You can get a more information on this example at -# http://parametricparts.com/docs/examples.html#an-extruded-prismatic-solid - -import cadquery -import Part - -#1.0 is the distance, not coordinate -r = cadquery.Workplane("front").hLine(1.0) - -#hLineTo allows using xCoordinate not distance -r = r.vLine(0.5).hLine(-0.25).vLine(-0.25).hLineTo(0.0) - -#Mirror the geometry and extrude -result = r.mirrorY().extrude(0.25) - -#Boiler plate code to render our solid in FreeCAD's GUI -Part.show(result.toFreecad()) diff --git a/Libs/cadquery-lib/examples/FreeCAD/Ex012_Creating_Workplanes_on_Faces.py b/Libs/cadquery-lib/examples/FreeCAD/Ex012_Creating_Workplanes_on_Faces.py deleted file mode 100644 index 50a8ba3..0000000 --- a/Libs/cadquery-lib/examples/FreeCAD/Ex012_Creating_Workplanes_on_Faces.py +++ /dev/null @@ -1,31 +0,0 @@ -#File: Ex012_Creating_Workplanes_on_Faces.py -#To use this example file, you need to first follow the "Using CadQuery From Inside FreeCAD" -#instructions here: https://github.com/dcowden/cadquery#installing----using-cadquery-from-inside-freecad - -#You run this example by typing the following in the FreeCAD python console, making sure to change -#the path to this example, and the name of the example appropriately. -#import sys -#sys.path.append('/home/user/Downloads/cadquery/examples/FreeCAD') -#import Ex012_Creating_Workplanes_on_Faces - -#If you need to reload the part after making a change, you can use the following lines within the FreeCAD console. -#reload(Ex012_Creating_Workplanes_on_Faces) - -#You'll need to delete the original shape that was created, and the new shape should be named sequentially -# (Shape001, etc). - -#You can also tie these blocks of code to macros, buttons, and keybindings in FreeCAD for quicker access. -#You can get a more information on this example at -# http://parametricparts.com/docs/examples.html#an-extruded-prismatic-solid - -import cadquery -import Part - -#Make a basic prism -result = cadquery.Workplane("front").box(2,3,0.5) - -#Find the top-most face and make a hole -result = result.faces(">Z").workplane().hole(0.5) - -#Boiler plate code to render our solid in FreeCAD's GUI -Part.show(result.toFreecad()) diff --git a/Libs/cadquery-lib/examples/FreeCAD/Ex013_Locating_a_Workplane_on_a_Vertex.py b/Libs/cadquery-lib/examples/FreeCAD/Ex013_Locating_a_Workplane_on_a_Vertex.py deleted file mode 100644 index a50f74f..0000000 --- a/Libs/cadquery-lib/examples/FreeCAD/Ex013_Locating_a_Workplane_on_a_Vertex.py +++ /dev/null @@ -1,34 +0,0 @@ -#File: Ex013_Locating_a_Workplane_on_a_Vertex.py -#To use this example file, you need to first follow the "Using CadQuery From Inside FreeCAD" -#instructions here: https://github.com/dcowden/cadquery#installing----using-cadquery-from-inside-freecad - -#You run this example by typing the following in the FreeCAD python console, making sure to change -#the path to this example, and the name of the example appropriately. -#import sys -#sys.path.append('/home/user/Downloads/cadquery/examples/FreeCAD') -#import Ex013_Locating_a_Workplane_on_a_Vertex - -#If you need to reload the part after making a change, you can use the following lines within the FreeCAD console. -#reload(Ex013_Locating_a_Workplane_on_a_Vertex) - -#You'll need to delete the original shape that was created, and the new shape should be named sequentially -# (Shape001, etc). - -#You can also tie these blocks of code to macros, buttons, and keybindings in FreeCAD for quicker access. -#You can get a more information on this example at -# http://parametricparts.com/docs/examples.html#an-extruded-prismatic-solid - -import cadquery -import Part - -#Make a basic prism -result = cadquery.Workplane("front").box(3, 2, 0.5) - -#Select the lower left vertex and make a workplane -result = result.faces(">Z").vertices("Z").workplane() \ - .transformed(offset=Vector(0, -1.5, 1.0), rotate=Vector(60, 0, 0)) \ - .rect(1.5, 1.5, forConstruction=True).vertices().hole(0.25) - -#Boiler plate code to render our solid in FreeCAD's GUI -Part.show(result.toFreecad()) diff --git a/Libs/cadquery-lib/examples/FreeCAD/Ex016_Using_Construction_Geometry.py b/Libs/cadquery-lib/examples/FreeCAD/Ex016_Using_Construction_Geometry.py deleted file mode 100644 index 69ba013..0000000 --- a/Libs/cadquery-lib/examples/FreeCAD/Ex016_Using_Construction_Geometry.py +++ /dev/null @@ -1,29 +0,0 @@ -#File: Ex016_Using_Construction_Geometry.py -#To use this example file, you need to first follow the "Using CadQuery From Inside FreeCAD" -#instructions here: https://github.com/dcowden/cadquery#installing----using-cadquery-from-inside-freecad - -#You run this example by typing the following in the FreeCAD python console, making sure to change -#the path to this example, and the name of the example appropriately. -#import sys -#sys.path.append('/home/user/Downloads/cadquery/examples/FreeCAD') -#import Ex016_Using_Construction_Geometry - -#If you need to reload the part after making a change, you can use the following lines within the FreeCAD console. -#reload(Ex016_Using_Construction_Geometry) - -#You'll need to delete the original shape that was created, and the new shape should be named sequentially -# (Shape001, etc). - -#You can also tie these blocks of code to macros, buttons, and keybindings in FreeCAD for quicker access. -#You can get a more information on this example at -# http://parametricparts.com/docs/examples.html#an-extruded-prismatic-solid - -import cadquery -import Part - -#Create a block with holes in each corner of a rectangle on that workplane -result = cadquery.Workplane("front").box(2, 2, 0.5).faces(">Z").workplane() \ - .rect(1.5, 1.5, forConstruction=True).vertices().hole(0.125) - -#Boiler plate code to render our solid in FreeCAD's GUI -Part.show(result.toFreecad()) diff --git a/Libs/cadquery-lib/examples/FreeCAD/Ex017_Shelling_to_Create_Thin_Features.py b/Libs/cadquery-lib/examples/FreeCAD/Ex017_Shelling_to_Create_Thin_Features.py deleted file mode 100644 index 7965c44..0000000 --- a/Libs/cadquery-lib/examples/FreeCAD/Ex017_Shelling_to_Create_Thin_Features.py +++ /dev/null @@ -1,28 +0,0 @@ -#File: Ex017_Shelling_to_Create_Thin_Features.py -#To use this example file, you need to first follow the "Using CadQuery From Inside FreeCAD" -#instructions here: https://github.com/dcowden/cadquery#installing----using-cadquery-from-inside-freecad - -#You run this example by typing the following in the FreeCAD python console, making sure to change -#the path to this example, and the name of the example appropriately. -#import sys -#sys.path.append('/home/user/Downloads/cadquery/examples/FreeCAD') -#import Ex017_Shelling_to_Create_Thin_Features - -#If you need to reload the part after making a change, you can use the following lines within the FreeCAD console. -#reload(Ex017_Shelling_to_Create_Thin_Features) - -#You'll need to delete the original shape that was created, and the new shape should be named sequentially -# (Shape001, etc). - -#You can also tie these blocks of code to macros, buttons, and keybindings in FreeCAD for quicker access. -#You can get a more information on this example at -# http://parametricparts.com/docs/examples.html#an-extruded-prismatic-solid - -import cadquery -import Part - -#Create a hollow box that's open on both ends with a thin wall -result = cadquery.Workplane("front").box(2, 2, 2).faces("+Z").shell(0.05) - -#Boiler plate code to render our solid in FreeCAD's GUI -Part.show(result.toFreecad()) diff --git a/Libs/cadquery-lib/examples/FreeCAD/Ex018_Making_Lofts.py b/Libs/cadquery-lib/examples/FreeCAD/Ex018_Making_Lofts.py deleted file mode 100644 index 847285a..0000000 --- a/Libs/cadquery-lib/examples/FreeCAD/Ex018_Making_Lofts.py +++ /dev/null @@ -1,29 +0,0 @@ -#File: Ex018_Making_Lofts.py -#To use this example file, you need to first follow the "Using CadQuery From Inside FreeCAD" -#instructions here: https://github.com/dcowden/cadquery#installing----using-cadquery-from-inside-freecad - -#You run this example by typing the following in the FreeCAD python console, making sure to change -#the path to this example, and the name of the example appropriately. -#import sys -#sys.path.append('/home/user/Downloads/cadquery/examples/FreeCAD') -#import Ex018_Making_Lofts - -#If you need to reload the part after making a change, you can use the following lines within the FreeCAD console. -#reload(Ex018_Making_Lofts) - -#You'll need to delete the original shape that was created, and the new shape should be named sequentially -# (Shape001, etc). - -#You can also tie these blocks of code to macros, buttons, and keybindings in FreeCAD for quicker access. -#You can get a more information on this example at -# http://parametricparts.com/docs/examples.html#an-extruded-prismatic-solid - -import cadquery -import Part - -#Create a lofted section between a rectangle and a circular section -result = cadquery.Workplane("front").box(4.0, 4.0, 0.25).faces(">Z").circle(1.5) \ - .workplane(offset=3.0).rect(0.75, 0.5).loft(combine=True) - -#Boiler plate code to render our solid in FreeCAD's GUI -Part.show(result.toFreecad()) diff --git a/Libs/cadquery-lib/examples/FreeCAD/Ex019_Counter_Sunk_Holes.py b/Libs/cadquery-lib/examples/FreeCAD/Ex019_Counter_Sunk_Holes.py deleted file mode 100644 index 4a2590d..0000000 --- a/Libs/cadquery-lib/examples/FreeCAD/Ex019_Counter_Sunk_Holes.py +++ /dev/null @@ -1,30 +0,0 @@ -#File: Ex019_Counter_Sunk_Holes.py -#To use this example file, you need to first follow the "Using CadQuery From Inside FreeCAD" -#instructions here: https://github.com/dcowden/cadquery#installing----using-cadquery-from-inside-freecad - -#You run this example by typing the following in the FreeCAD python console, making sure to change -#the path to this example, and the name of the example appropriately. -#import sys -#sys.path.append('/home/user/Downloads/cadquery/examples/FreeCAD') -#import Ex019_Counter_Sunk_Holes - -#If you need to reload the part after making a change, you can use the following lines within the FreeCAD console. -#reload(Ex019_Counter_Sunk_Holes) - -#You'll need to delete the original shape that was created, and the new shape should be named sequentially -# (Shape001, etc). - -#You can also tie these blocks of code to macros, buttons, and keybindings in FreeCAD for quicker access. -#You can get a more information on this example at -# http://parametricparts.com/docs/examples.html#an-extruded-prismatic-solid - -import cadquery -import Part - -#Create a plate with 4 counter-sunk holes in it -result = cadquery.Workplane(cadquery.Plane.XY()).box(4, 2, 0.5).faces(">Z").workplane() \ - .rect(3.5, 1.5, forConstruction=True)\ - .vertices().cskHole(0.125, 0.25, 82.0, depth=None) - -#Boiler plate code to render our solid in FreeCAD's GUI -Part.show(result.toFreecad()) diff --git a/Libs/cadquery-lib/examples/FreeCAD/Ex020_Rounding_Corners_with_Fillets.py b/Libs/cadquery-lib/examples/FreeCAD/Ex020_Rounding_Corners_with_Fillets.py deleted file mode 100644 index 2d71322..0000000 --- a/Libs/cadquery-lib/examples/FreeCAD/Ex020_Rounding_Corners_with_Fillets.py +++ /dev/null @@ -1,28 +0,0 @@ -#File: Ex020_Rounding_Corners_with_Fillets.py -#To use this example file, you need to first follow the "Using CadQuery From Inside FreeCAD" -#instructions here: https://github.com/dcowden/cadquery#installing----using-cadquery-from-inside-freecad - -#You run this example by typing the following in the FreeCAD python console, making sure to change -#the path to this example, and the name of the example appropriately. -#import sys -#sys.path.append('/home/user/Downloads/cadquery/examples/FreeCAD') -#import Ex020_Rounding_Corners_with_Fillets - -#If you need to reload the part after making a change, you can use the following lines within the FreeCAD console. -#reload(Ex020_Rounding_Corners_with_Fillets) - -#You'll need to delete the original shape that was created, and the new shape should be named sequentially -# (Shape001, etc). - -#You can also tie these blocks of code to macros, buttons, and keybindings in FreeCAD for quicker access. -#You can get a more information on this example at -# http://parametricparts.com/docs/examples.html#an-extruded-prismatic-solid - -import cadquery -import Part - -#Create a plate with 4 rounded corners in the Z-axis -result = cadquery.Workplane("XY").box(3, 3, 0.5).edges("|Z").fillet(0.125) - -#Boiler plate code to render our solid in FreeCAD's GUI -Part.show(result.toFreecad()) diff --git a/Libs/cadquery-lib/examples/FreeCAD/Ex021_Splitting_an_Object.py b/Libs/cadquery-lib/examples/FreeCAD/Ex021_Splitting_an_Object.py deleted file mode 100644 index 133104a..0000000 --- a/Libs/cadquery-lib/examples/FreeCAD/Ex021_Splitting_an_Object.py +++ /dev/null @@ -1,31 +0,0 @@ -#File: Ex021_Splitting_an_Object.py -#To use this example file, you need to first follow the "Using CadQuery From Inside FreeCAD" -#instructions here: https://github.com/dcowden/cadquery#installing----using-cadquery-from-inside-freecad - -#You run this example by typing the following in the FreeCAD python console, making sure to change -#the path to this example, and the name of the example appropriately. -#import sys -#sys.path.append('/home/user/Downloads/cadquery/examples/FreeCAD') -#import Ex021_Splitting_an_Object - -#If you need to reload the part after making a change, you can use the following lines within the FreeCAD console. -#reload(Ex021_Splitting_an_Object) - -#You'll need to delete the original shape that was created, and the new shape should be named sequentially -# (Shape001, etc). - -#You can also tie these blocks of code to macros, buttons, and keybindings in FreeCAD for quicker access. -#You can get a more information on this example at -# http://parametricparts.com/docs/examples.html#an-extruded-prismatic-solid - -import cadquery -import Part - -#Create a simple block with a hole through it that we can split -c = cadquery.Workplane("XY").box(1, 1, 1).faces(">Z").workplane().circle(0.25).cutThruAll() - -#Cut the block in half sideways -result = c.faces(">Y").workplane(-0.5).split(keepTop=True) - -#Boiler plate code to render our solid in FreeCAD's GUI -Part.show(result.toFreecad()) diff --git a/Libs/cadquery-lib/examples/FreeCAD/Ex022_Classic_OCC_Bottle.py b/Libs/cadquery-lib/examples/FreeCAD/Ex022_Classic_OCC_Bottle.py deleted file mode 100644 index 8ea52c5..0000000 --- a/Libs/cadquery-lib/examples/FreeCAD/Ex022_Classic_OCC_Bottle.py +++ /dev/null @@ -1,40 +0,0 @@ -#File: Ex022_Classic_OCC_Bottle.py -#To use this example file, you need to first follow the "Using CadQuery From Inside FreeCAD" -#instructions here: https://github.com/dcowden/cadquery#installing----using-cadquery-from-inside-freecad - -#You run this example by typing the following in the FreeCAD python console, making sure to change -#the path to this example, and the name of the example appropriately. -#import sys -#sys.path.append('/home/user/Downloads/cadquery/examples/FreeCAD') -#import Ex022_Classic_OCC_Bottle - -#If you need to reload the part after making a change, you can use the following lines within the FreeCAD console. -#reload(Ex022_Classic_OCC_Bottle) - -#You'll need to delete the original shape that was created, and the new shape should be named sequentially -# (Shape001, etc). - -#You can also tie these blocks of code to macros, buttons, and keybindings in FreeCAD for quicker access. -#You can get a more information on this example at -# http://parametricparts.com/docs/examples.html#an-extruded-prismatic-solid - -import cadquery -import Part - -#Set up the length, width, and thickness -(L,w,t) = (20.0, 6.0, 3.0) -s = cadquery.Workplane("XY") - -#Draw half the profile of the bottle and extrude it -p = s.center(-L / 2.0, 0).vLine(w / 2.0) \ - .threePointArc((L / 2.0, w / 2.0 + t),(L, w / 2.0)).vLine(-w / 2.0) \ - .mirrorX().extrude(30.0, True) - -#Make the neck -p.faces(">Z").workplane().circle(3.0).extrude(2.0, True) - -#Make a shell -result = p.faces(">Z").shell(0.3) - -#Boiler plate code to render our solid in FreeCAD's GUI -Part.show(result.toFreecad()) diff --git a/Libs/cadquery-lib/examples/FreeCAD/Ex023_Parametric_Enclosure.py b/Libs/cadquery-lib/examples/FreeCAD/Ex023_Parametric_Enclosure.py deleted file mode 100644 index ef3308f..0000000 --- a/Libs/cadquery-lib/examples/FreeCAD/Ex023_Parametric_Enclosure.py +++ /dev/null @@ -1,102 +0,0 @@ -#File: Ex023_Parametric_Enclosure.py -#To use this example file, you need to first follow the "Using CadQuery From Inside FreeCAD" -#instructions here: https://github.com/dcowden/cadquery#installing----using-cadquery-from-inside-freecad - -#You run this example by typing the following in the FreeCAD python console, making sure to change -#the path to this example, and the name of the example appropriately. -#import sys -#sys.path.append('/home/user/Downloads/cadquery/examples/FreeCAD') -#import Ex023_Parametric_Enclosure - -#If you need to reload the part after making a change, you can use the following lines within the FreeCAD console. -#reload(Ex023_Parametric_Enclosure) - -#You'll need to delete the original shape that was created, and the new shape should be named sequentially -# (Shape001, etc). - -#You can also tie these blocks of code to macros, buttons, and keybindings in FreeCAD for quicker access. -#You can get a more information on this example at -# http://parametricparts.com/docs/examples.html#an-extruded-prismatic-solid - -import cadquery -import Part - -#Parameter definitions -p_outerWidth = 100.0 # Outer width of box enclosure -p_outerLength = 150.0 # Outer length of box enclosure -p_outerHeight = 50.0 # Outer height of box enclosure - -p_thickness = 3.0 # Thickness of the box walls -p_sideRadius = 10.0 # Radius for the curves around the sides of the bo -p_topAndBottomRadius = 2.0 # Radius for the curves on the top and bottom edges of the box - -p_screwpostInset = 12.0 # How far in from the edges the screwposts should be placed -p_screwpostID = 4.0 # Inner diameter of the screwpost holes, should be roughly screw diameter not including threads -p_screwpostOD = 10.0 # Outer diameter of the screwposts. Determines overall thickness of the posts - -p_boreDiameter = 8.0 # Diameter of the counterbore hole, if any -p_boreDepth = 1.0 # Depth of the counterbore hole, if -p_countersinkDiameter = 0.0 # Outer diameter of countersink. Should roughly match the outer diameter of the screw head -p_countersinkAngle = 90.0 # Countersink angle (complete angle between opposite sides, not from center to one side) -p_flipLid = True # Whether to place the lid with the top facing down or not. -p_lipHeight = 1.0 # Height of lip on the underside of the lid. Sits inside the box body for a snug fit. - -#Outer shell -oshell = cadquery.Workplane("XY").rect(p_outerWidth, p_outerLength).extrude(p_outerHeight + p_lipHeight) - -#Weird geometry happens if we make the fillets in the wrong order -if p_sideRadius > p_topAndBottomRadius: - oshell.edges("|Z").fillet(p_sideRadius) - oshell.edges("#Z").fillet(p_topAndBottomRadius) -else: - oshell.edges("#Z").fillet(p_topAndBottomRadius) - oshell.edges("|Z").fillet(p_sideRadius) - -#Inner shell -ishell = oshell.faces("Z").workplane(-p_thickness)\ - .rect(POSTWIDTH, POSTLENGTH, forConstruction=True)\ - .vertices() - -for v in postCenters.all(): - v.circle(p_screwpostOD / 2.0).circle(p_screwpostID / 2.0)\ - .extrude((-1.0) * ((p_outerHeight + p_lipHeight) - (2.0 * p_thickness)), True) - -#Split lid into top and bottom parts -(lid, bottom) = box.faces(">Z").workplane(-p_thickness - p_lipHeight).split(keepTop=True, keepBottom=True).all() - -#Translate the lid, and subtract the bottom from it to produce the lid inset -lowerLid = lid.translate((0, 0, -p_lipHeight)) -cutlip = lowerLid.cut(bottom).translate((p_outerWidth + p_thickness, 0, p_thickness - p_outerHeight + p_lipHeight)) - -#Compute centers for counterbore/countersink or counterbore -topOfLidCenters = cutlip.faces(">Z").workplane().rect(POSTWIDTH, POSTLENGTH, forConstruction=True).vertices() - -#Add holes of the desired type -if p_boreDiameter > 0 and p_boreDepth > 0: - topOfLid = topOfLidCenters.cboreHole(p_screwpostID, p_boreDiameter, p_boreDepth, (2.0) * p_thickness) -elif p_countersinkDiameter > 0 and p_countersinkAngle > 0: - topOfLid = topOfLidCenters.cskHole(p_screwpostID, p_countersinkDiameter, p_countersinkAngle, (2.0) * p_thickness) -else: - topOfLid= topOfLidCenters.hole(p_screwpostID, 2.0 * p_thickness) - -#Flip lid upside down if desired -if p_flipLid: - topOfLid.rotateAboutCenter((1, 0, 0), 180) - -#Return the combined result -result = topOfLid.combineSolids(bottom) - -#Boiler plate code to render our solid in FreeCAD's GUI -Part.show(result.toFreecad()) diff --git a/Libs/cadquery-lib/examples/FreeCAD/Ex024_Using_FreeCAD_Solids_as_CQ_Objects.py b/Libs/cadquery-lib/examples/FreeCAD/Ex024_Using_FreeCAD_Solids_as_CQ_Objects.py deleted file mode 100644 index 7a8088f..0000000 --- a/Libs/cadquery-lib/examples/FreeCAD/Ex024_Using_FreeCAD_Solids_as_CQ_Objects.py +++ /dev/null @@ -1,41 +0,0 @@ -#File: Ex024_Using_FreeCAD_Solids_as_CQ_Objects.py -#To use this example file, you need to first follow the "Using CadQuery From Inside FreeCAD" -#instructions here: https://github.com/dcowden/cadquery#installing----using-cadquery-from-inside-freecad - -#You run this example by typing the following in the FreeCAD python console, making sure to change -#the path to this example, and the name of the example appropriately. -#import sys -#sys.path.append('/home/user/Downloads/cadquery/examples/FreeCAD') -#import Ex024_Using_FreeCAD_Solids_as_CQ_Objects - -#If you need to reload the part after making a change, you can use the following lines within the FreeCAD console. -#reload(Ex024_Using_FreeCAD_Solids_as_CQ_Objects) - -#You'll need to delete the original shape that was created, and the new shape should be named sequentially -# (Shape001, etc). - -#You can also tie these blocks of code to macros, buttons, and keybindings in FreeCAD for quicker access. -#You can get a more information on this example at -# http://parametricparts.com/docs/examples.html#an-extruded-prismatic-solid - -import cadquery, FreeCAD, Part - -#Create a new document that we can draw our model on -newDoc = FreeCAD.newDocument() - -#shows a 1x1x1 FreeCAD cube in the display -initialBox = newDoc.addObject("Part::Box","initialBox") -newDoc.recompute() - -#Make a CQ object -cqBox = cadquery.CQ(cadquery.Solid(initialBox.Shape)) - -#Extrude a peg -newThing = cqBox.faces(">Z").workplane().circle(0.5).extrude(0.25) - -#Add a FreeCAD object to the tree and then store a CQ object in it -nextShape = newDoc.addObject("Part::Feature", "nextShape") -nextShape.Shape = newThing.val().wrapped - -#Rerender the doc to see what the new solid looks like -newDoc.recompute() diff --git a/Libs/cadquery-lib/examples/FreeCAD/Ex025_Revolution.py b/Libs/cadquery-lib/examples/FreeCAD/Ex025_Revolution.py deleted file mode 100644 index e0f9364..0000000 --- a/Libs/cadquery-lib/examples/FreeCAD/Ex025_Revolution.py +++ /dev/null @@ -1,41 +0,0 @@ -#File: Ex025_Revolution.py -#To use this example file, you need to first follow the "Using CadQuery From Inside FreeCAD" -#instructions here: https://github.com/dcowden/cadquery#installing----using-cadquery-from-inside-freecad - -#You run this example by typing the following in the FreeCAD python console, making sure to change -#the path to this example, and the name of the example appropriately. -#import sys -#sys.path.append('/home/user/Downloads/cadquery/examples/FreeCAD') -#import Ex025_Revolution - -#If you need to reload the part after making a change, you can use the following lines within the FreeCAD console. -#reload(Ex025_Revolution) - -#You'll need to delete the original shape that was created, and the new shape should be named sequentially -# (Shape001, etc). - -#You can also tie these blocks of code to macros, buttons, and keybindings in FreeCAD for quicker access. -#You can get a more information on this example at -# http://parametricparts.com/docs/examples.html#an-extruded-prismatic-solid - -import cadquery -import Part - -#The dimensions of the model. These can be modified rather than changing the shape's code directly. -rectangle_width = 10.0 -rectangle_length = 10.0 -angle_degrees = 360.0 - -#Revolve a cylinder from a rectangle -#Switch comments around in this section to try the revolve operation with different parameters -result = cadquery.Workplane("XY").rect(rectangle_width, rectangle_length, False).revolve() -#result = cadquery.Workplane("XY").rect(rectangle_width, rectangle_length, False).revolve(angle_degrees) -#result = cadquery.Workplane("XY").rect(rectangle_width, rectangle_length).revolve(angle_degrees,(-5,-5)) -#result = cadquery.Workplane("XY").rect(rectangle_width, rectangle_length).revolve(angle_degrees,(-5, -5),(-5, 5)) -#result = cadquery.Workplane("XY").rect(rectangle_width, rectangle_length).revolve(angle_degrees,(-5,-5),(-5,5), False) - -#Revolve a donut with square walls -#result = cadquery.Workplane("XY").rect(rectangle_width, rectangle_length, True).revolve(angle_degrees, (20, 0), (20, 10)) - -#Boiler plate code to render our solid in FreeCAD's GUI -Part.show(result.toFreecad()) diff --git a/Libs/cadquery-lib/registering.txt b/Libs/cadquery-lib/registering.txt deleted file mode 100644 index 0be612c..0000000 --- a/Libs/cadquery-lib/registering.txt +++ /dev/null @@ -1,11 +0,0 @@ -# -# Registering with Pypy -# -To register with pypy: - - (1) make sure you have python 2.6.x with setuptools installed, - ( source a virtual env ) - - (2) change version number in setup.py if you need - (3) python setup.py register - (4) python setup.py sdist upload \ No newline at end of file diff --git a/Libs/cadquery-lib/requirements-dev.txt b/Libs/cadquery-lib/requirements-dev.txt deleted file mode 100644 index 14429e3..0000000 --- a/Libs/cadquery-lib/requirements-dev.txt +++ /dev/null @@ -1,6 +0,0 @@ -sphinx-rtd-theme==0.1.9 -travis-sphinx -Sphinx==1.3.2 -coverage -coveralls -pyparsing diff --git a/Libs/cadquery-lib/requirements.txt b/Libs/cadquery-lib/requirements.txt deleted file mode 100644 index d6e1198..0000000 --- a/Libs/cadquery-lib/requirements.txt +++ /dev/null @@ -1 +0,0 @@ --e . diff --git a/Libs/cadquery-lib/runtests.py b/Libs/cadquery-lib/runtests.py deleted file mode 100644 index ee90ce4..0000000 --- a/Libs/cadquery-lib/runtests.py +++ /dev/null @@ -1,18 +0,0 @@ -import sys -from tests import * -import cadquery -import unittest - -#if you are on python 2.7, you can use -m uniitest discover. -#but this is required for python 2.6.6 on windows. FreeCAD0.12 will not load -#on py 2.7.x on win -suite = unittest.TestSuite() - -suite.addTests(unittest.TestLoader().loadTestsFromTestCase(TestCQGI.TestCQGI)) -suite.addTests(unittest.TestLoader().loadTestsFromTestCase(TestCadObjects.TestCadObjects)) -suite.addTests(unittest.TestLoader().loadTestsFromTestCase(TestWorkplanes.TestWorkplanes)) -suite.addTests(unittest.TestLoader().loadTestsFromTestCase(TestCQSelectors.TestCQSelectors)) -suite.addTests(unittest.TestLoader().loadTestsFromTestCase(TestCadQuery.TestCadQuery)) -suite.addTests(unittest.TestLoader().loadTestsFromTestCase(TestExporters.TestExporters)) -suite.addTests(unittest.TestLoader().loadTestsFromTestCase(TestImporters.TestImporters)) -unittest.TextTestRunner().run(suite) diff --git a/Libs/cadquery-lib/setup.cfg b/Libs/cadquery-lib/setup.cfg deleted file mode 100644 index e69de29..0000000 diff --git a/Libs/cadquery-lib/setup.py b/Libs/cadquery-lib/setup.py deleted file mode 100644 index 2e7018b..0000000 --- a/Libs/cadquery-lib/setup.py +++ /dev/null @@ -1,58 +0,0 @@ -# Copyright 2015 Parametric Products Intellectual Holdings, LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -import os -from setuptools import setup - - -#if we are building in travis, use the build number as the sub-minor version -version = '0.5-SNAPSHOT' -if 'TRAVIS_TAG' in os.environ.keys(): - version= os.environ['TRAVIS_TAG'] - - -setup( - name='cadquery', - version=version, - url='https://github.com/dcowden/cadquery', - license='Apache Public License 2.0', - author='David Cowden', - author_email='dave.cowden@gmail.com', - description='CadQuery is a parametric scripting language for creating and traversing CAD models', - long_description=open('README.md').read(), - packages=['cadquery','cadquery.contrib','cadquery.freecad_impl','cadquery.plugins','tests'], - install_requires=['pyparsing'], - include_package_data=True, - zip_safe=False, - platforms='any', - test_suite='tests', - - classifiers=[ - 'Development Status :: 5 - Production/Stable', - #'Development Status :: 6 - Mature', - #'Development Status :: 7 - Inactive', - 'Intended Audience :: Developers', - 'Intended Audience :: End Users/Desktop', - 'Intended Audience :: Information Technology', - 'Intended Audience :: Science/Research', - 'Intended Audience :: System Administrators', - 'License :: OSI Approved :: Apache Software License', - 'Operating System :: POSIX', - 'Operating System :: MacOS', - 'Operating System :: Unix', - 'Programming Language :: Python', - 'Topic :: Software Development :: Libraries :: Python Modules', - 'Topic :: Internet', - 'Topic :: Scientific/Engineering' - ] -) diff --git a/Libs/cadquery-lib/tests/README.txt b/Libs/cadquery-lib/tests/README.txt deleted file mode 100644 index 99c6a4f..0000000 --- a/Libs/cadquery-lib/tests/README.txt +++ /dev/null @@ -1 +0,0 @@ -It is OK for tests to import implementations like FreeCAD directly. \ No newline at end of file diff --git a/Libs/cadquery-lib/tests/TestCQGI.py b/Libs/cadquery-lib/tests/TestCQGI.py deleted file mode 100644 index 08c63dc..0000000 --- a/Libs/cadquery-lib/tests/TestCQGI.py +++ /dev/null @@ -1,217 +0,0 @@ -""" - Tests CQGI functionality - - Currently, this includes: - Parsing a script, and detecting its available variables - Altering the values at runtime - defining a build_object function to return results -""" - -from cadquery import cqgi -from tests import BaseTest -import textwrap - -TESTSCRIPT = textwrap.dedent( - """ - height=2.0 - width=3.0 - (a,b) = (1.0,1.0) - foo="bar" - - result = "%s|%s|%s|%s" % ( str(height) , str(width) , foo , str(a) ) - build_object(result) - """ -) - -TEST_DEBUG_SCRIPT = textwrap.dedent( - """ - height=2.0 - width=3.0 - (a,b) = (1.0,1.0) - foo="bar" - debug(foo, { "color": 'yellow' } ) - result = "%s|%s|%s|%s" % ( str(height) , str(width) , foo , str(a) ) - build_object(result) - debug(height ) - """ -) - -class TestCQGI(BaseTest): - def test_parser(self): - model = cqgi.CQModel(TESTSCRIPT) - metadata = model.metadata - - self.assertEquals(set(metadata.parameters.keys()), {'height', 'width', 'a', 'b', 'foo'}) - - def test_build_with_debug(self): - model = cqgi.CQModel(TEST_DEBUG_SCRIPT) - result = model.build() - debugItems = result.debugObjects - self.assertTrue(len(debugItems) == 2) - - self.assertTrue( debugItems[0].shape == "bar" ) - self.assertTrue( debugItems[0].options == { "color":'yellow' } ) - self.assertTrue( debugItems[1].shape == 2.0 ) - self.assertTrue( debugItems[1].options == {} ) - - def test_build_with_empty_params(self): - model = cqgi.CQModel(TESTSCRIPT) - result = model.build() - - self.assertTrue(result.success) - self.assertTrue(len(result.results) == 1) - self.assertTrue(result.results[0].shape == "2.0|3.0|bar|1.0") - - def test_build_with_different_params(self): - model = cqgi.CQModel(TESTSCRIPT) - result = model.build({'height': 3.0}) - self.assertTrue(result.results[0].shape == "3.0|3.0|bar|1.0") - - def test_describe_parameters(self): - script = textwrap.dedent( - """ - a = 2.0 - describe_parameter(a,'FirstLetter') - """ - ) - model = cqgi.CQModel(script) - a_param = model.metadata.parameters['a'] - self.assertTrue(a_param.default_value == 2.0) - self.assertTrue(a_param.desc == 'FirstLetter') - self.assertTrue(a_param.varType == cqgi.NumberParameterType ) - - def test_describe_parameter_invalid_doesnt_fail_script(self): - script = textwrap.dedent( - """ - a = 2.0 - describe_parameter(a, 2 - 1 ) - """ - ) - model = cqgi.CQModel(script) - a_param = model.metadata.parameters['a'] - self.assertTrue(a_param.name == 'a' ) - - def test_build_with_exception(self): - badscript = textwrap.dedent( - """ - raise ValueError("ERROR") - """ - ) - - model = cqgi.CQModel(badscript) - result = model.build({}) - self.assertFalse(result.success) - self.assertIsNotNone(result.exception) - self.assertTrue(result.exception.message == "ERROR") - - def test_that_invalid_syntax_in_script_fails_immediately(self): - badscript = textwrap.dedent( - """ - this doesnt even compile - """ - ) - - with self.assertRaises(Exception) as context: - model = cqgi.CQModel(badscript) - - self.assertTrue('invalid syntax' in context.exception) - - def test_that_two_results_are_returned(self): - script = textwrap.dedent( - """ - h = 1 - build_object(h) - h = 2 - build_object(h) - """ - ) - - model = cqgi.CQModel(script) - result = model.build({}) - self.assertEquals(2, len(result.results)) - self.assertEquals(1, result.results[0].shape) - self.assertEquals(2, result.results[1].shape) - - def test_that_assinging_number_to_string_works(self): - script = textwrap.dedent( - """ - h = "this is a string" - build_object(h) - """ - ) - result = cqgi.parse(script).build( {'h': 33.33}) - self.assertEquals(result.results[0].shape, "33.33") - - def test_that_assigning_string_to_number_fails(self): - script = textwrap.dedent( - """ - h = 20.0 - build_object(h) - """ - ) - result = cqgi.parse(script).build( {'h': "a string"}) - self.assertTrue(isinstance(result.exception, cqgi.InvalidParameterError)) - - def test_that_assigning_unknown_var_fails(self): - script = textwrap.dedent( - """ - h = 20.0 - build_object(h) - """ - ) - - result = cqgi.parse(script).build( {'w': "var is not there"}) - self.assertTrue(isinstance(result.exception, cqgi.InvalidParameterError)) - - def test_that_not_calling_build_object_raises_error(self): - script = textwrap.dedent( - """ - h = 20.0 - """ - ) - result = cqgi.parse(script).build() - self.assertTrue(isinstance(result.exception, cqgi.NoOutputError)) - - def test_that_cq_objects_are_visible(self): - script = textwrap.dedent( - """ - r = cadquery.Workplane('XY').box(1,2,3) - build_object(r) - """ - ) - - result = cqgi.parse(script).build() - self.assertTrue(result.success) - self.assertIsNotNone(result.first_result.shape) - - def test_setting_boolean_variable(self): - script = textwrap.dedent( - """ - h = True - build_object( "*%s*" % str(h) ) - """ - ) - - #result = cqgi.execute(script) - result = cqgi.parse(script).build({'h': False}) - - self.assertTrue(result.success) - self.assertEquals(result.first_result.shape,'*False*') - - def test_that_only_top_level_vars_are_detected(self): - script = textwrap.dedent( - """ - h = 1.0 - w = 2.0 - - def do_stuff(): - x = 1 - y = 2 - - build_object( "result" ) - """ - ) - - model = cqgi.parse(script) - - self.assertEquals(2, len(model.metadata.parameters)) diff --git a/Libs/cadquery-lib/tests/TestCQSelectors.py b/Libs/cadquery-lib/tests/TestCQSelectors.py deleted file mode 100644 index 1bc411b..0000000 --- a/Libs/cadquery-lib/tests/TestCQSelectors.py +++ /dev/null @@ -1,503 +0,0 @@ -__author__ = 'dcowden' - -""" - Tests for CadQuery Selectors - - These tests do not construct any solids, they test only selectors that query - an existing solid - -""" - -import math -import unittest,sys -import os.path - -#my modules -from tests import BaseTest,makeUnitCube,makeUnitSquareWire -from cadquery import * -from cadquery import selectors - -class TestCQSelectors(BaseTest): - - - def testWorkplaneCenter(self): - "Test Moving workplane center" - s = Workplane(Plane.XY()) - - #current point and world point should be equal - self.assertTupleAlmostEquals((0.0,0.0,0.0),s.plane.origin.toTuple(),3) - - #move origin and confirm center moves - s.center(-2.0,-2.0) - - #current point should be 0,0, but - - self.assertTupleAlmostEquals((-2.0,-2.0,0.0),s.plane.origin.toTuple(),3) - - - def testVertices(self): - t = makeUnitSquareWire() # square box - c = CQ(t) - - self.assertEqual(4,c.vertices().size() ) - self.assertEqual(4,c.edges().size() ) - self.assertEqual(0,c.vertices().edges().size() ) #no edges on any vertices - self.assertEqual(4,c.edges().vertices().size() ) #but selecting all edges still yields all vertices - self.assertEqual(1,c.wires().size()) #just one wire - self.assertEqual(0,c.faces().size()) - self.assertEqual(0,c.vertices().faces().size()) #odd combinations all work but yield no results - self.assertEqual(0,c.edges().faces().size()) - self.assertEqual(0,c.edges().vertices().faces().size()) - - def testEnd(self): - c = CQ(makeUnitSquareWire()) - self.assertEqual(4,c.vertices().size() ) #4 because there are 4 vertices - self.assertEqual(1,c.vertices().end().size() ) #1 because we started with 1 wire - - def testAll(self): - "all returns a list of CQ objects, so that you can iterate over them individually" - c = CQ(makeUnitCube()) - self.assertEqual(6,c.faces().size()) - self.assertEqual(6,len(c.faces().all())) - self.assertEqual(4,c.faces().all()[0].vertices().size() ) - - def testFirst(self): - c = CQ( makeUnitCube()) - self.assertEqual(type(c.vertices().first().val()),Vertex) - self.assertEqual(type(c.vertices().first().first().first().val()),Vertex) - - def testCompounds(self): - c = CQ(makeUnitSquareWire()) - self.assertEqual(0,c.compounds().size() ) - self.assertEqual(0,c.shells().size() ) - self.assertEqual(0,c.solids().size() ) - - def testSolid(self): - c = CQ(makeUnitCube()) - #make sure all the counts are right for a cube - self.assertEqual(1,c.solids().size() ) - self.assertEqual(6,c.faces().size() ) - self.assertEqual(12,c.edges().size()) - self.assertEqual(8,c.vertices().size() ) - self.assertEqual(0,c.compounds().size()) - - #now any particular face should result in 4 edges and four vertices - self.assertEqual(4,c.faces().first().edges().size() ) - self.assertEqual(1,c.faces().first().size() ) - self.assertEqual(4,c.faces().first().vertices().size() ) - - self.assertEqual(4,c.faces().last().edges().size() ) - - - - def testFaceTypesFilter(self): - "Filters by face type" - c = CQ(makeUnitCube()) - self.assertEqual(c.faces().size(), c.faces('%PLANE').size()) - self.assertEqual(c.faces().size(), c.faces('%plane').size()) - self.assertEqual(0, c.faces('%sphere').size()) - self.assertEqual(0, c.faces('%cone').size()) - self.assertEqual(0, c.faces('%SPHERE').size()) - - def testPerpendicularDirFilter(self): - c = CQ(makeUnitCube()) - - self.assertEqual(8,c.edges("#Z").size() ) #8 edges are perp. to z - self.assertEqual(4, c.faces("#Z").size()) #4 faces are perp to z too! - - def testFaceDirFilter(self): - c = CQ(makeUnitCube()) - #a cube has one face in each direction - self.assertEqual(1, c.faces("+Z").size()) - self.assertEqual(1, c.faces("-Z").size()) - self.assertEqual(1, c.faces("+X").size()) - self.assertEqual(1, c.faces("X").size()) #should be same as +X - self.assertEqual(1, c.faces("-X").size()) - self.assertEqual(1, c.faces("+Y").size()) - self.assertEqual(1, c.faces("-Y").size()) - self.assertEqual(0, c.faces("XY").size()) - - def testParallelPlaneFaceFilter(self): - c = CQ(makeUnitCube()) - - #faces parallel to Z axis - self.assertEqual(2, c.faces("|Z").size()) - #TODO: provide short names for ParallelDirSelector - self.assertEqual(2, c.faces(selectors.ParallelDirSelector(Vector((0,0,1)))).size()) #same thing as above - self.assertEqual(2, c.faces(selectors.ParallelDirSelector(Vector((0,0,-1)))).size()) #same thing as above - - #just for fun, vertices on faces parallel to z - self.assertEqual(8, c.faces("|Z").vertices().size()) - - def testParallelEdgeFilter(self): - c = CQ(makeUnitCube()) - self.assertEqual(4, c.edges("|Z").size()) - self.assertEqual(4, c.edges("|X").size()) - self.assertEqual(4, c.edges("|Y").size()) - - def testMaxDistance(self): - c = CQ(makeUnitCube()) - - #should select the topmost face - self.assertEqual(1, c.faces(">Z").size()) - self.assertEqual(4, c.faces(">Z").vertices().size()) - - #vertices should all be at z=1, if this is the top face - self.assertEqual(4, len(c.faces(">Z").vertices().vals() )) - for v in c.faces(">Z").vertices().vals(): - self.assertAlmostEqual(1.0,v.Z,3) - - # test the case of multiple objects at the same distance - el = c.edges("(1,0,0)[1]').val() - self.assertAlmostEqual(val.Center().x,-1.5) - val = c.faces('>X[1]').val() - self.assertAlmostEqual(val.Center().x,-1.5) - - #2nd face with inversed selection vector - val = c.faces('>(-1,0,0)[1]').val() - self.assertAlmostEqual(val.Center().x,1.5) - val = c.faces('X[-2]').val() - self.assertAlmostEqual(val.Center().x,1.5) - - #Last face - val = c.faces('>X[-1]').val() - self.assertAlmostEqual(val.Center().x,2.5) - - #check if the selected face if normal to the specified Vector - self.assertAlmostEqual(val.normalAt().cross(Vector(1,0,0)).Length,0.0) - - #test selection of multiple faces with the same distance - c = Workplane('XY')\ - .box(1,4,1,centered=(False,True,False)).faces('Z')\ - .box(1,1,1,centered=(True,True,False)) - - #select 2nd from the bottom (NB python indexing is 0-based) - vals = c.faces('>Z[1]').vals() - self.assertEqual(len(vals),2) - - val = c.faces('>Z[1]').val() - self.assertAlmostEqual(val.Center().z,1) - - #do the same but by selecting 3rd from the top - vals = c.faces('Z[-1] is equivalent to >Z - val1 = c.faces('>Z[-1]').val() - val2 = c.faces('>Z').val() - self.assertTupleAlmostEquals(val1.Center().toTuple(), - val2.Center().toTuple(), - 3) - - def testNearestTo(self): - c = CQ(makeUnitCube()) - - #nearest vertex to origin is (0,0,0) - t = (0.1,0.1,0.1) - - v = c.vertices(selectors.NearestToPointSelector(t)).vals()[0] - self.assertTupleAlmostEquals((0.0,0.0,0.0),(v.X,v.Y,v.Z),3) - - t = (0.1,0.1,0.2) - #nearest edge is the vertical side edge, 0,0,0 -> 0,0,1 - e = c.edges(selectors.NearestToPointSelector(t)).vals()[0] - v = c.edges(selectors.NearestToPointSelector(t)).vertices().vals() - self.assertEqual(2,len(v)) - - #nearest solid is myself - s = c.solids(selectors.NearestToPointSelector(t)).vals() - self.assertEqual(1,len(s)) - - def testBox(self): - c = CQ(makeUnitCube()) - - # test vertice selection - test_data_vertices = [ - # box point0, box point1, selected vertice - ((0.9, 0.9, 0.9), (1.1, 1.1, 1.1), (1.0, 1.0, 1.0)), - ((-0.1, 0.9, 0.9), (0.9, 1.1, 1.1), (0.0, 1.0, 1.0)), - ((-0.1, -0.1, 0.9), (0.1, 0.1, 1.1), (0.0, 0.0, 1.0)), - ((-0.1, -0.1, -0.1), (0.1, 0.1, 0.1), (0.0, 0.0, 0.0)), - ((0.9, -0.1, -0.1), (1.1, 0.1, 0.1), (1.0, 0.0, 0.0)), - ((0.9, 0.9, -0.1), (1.1, 1.1, 0.1), (1.0, 1.0, 0.0)), - ((-0.1, 0.9, -0.1), (0.1, 1.1, 0.1), (0.0, 1.0, 0.0)), - ((0.9, -0.1, 0.9), (1.1, 0.1, 1.1), (1.0, 0.0, 1.0)) - ] - - for d in test_data_vertices: - vl = c.vertices(selectors.BoxSelector(d[0], d[1])).vals() - self.assertEqual(1, len(vl)) - v = vl[0] - self.assertTupleAlmostEquals(d[2], (v.X, v.Y, v.Z), 3) - - # this time box points are swapped - vl = c.vertices(selectors.BoxSelector(d[1], d[0])).vals() - self.assertEqual(1, len(vl)) - v = vl[0] - self.assertTupleAlmostEquals(d[2], (v.X, v.Y, v.Z), 3) - - # test multiple vertices selection - vl = c.vertices(selectors.BoxSelector((-0.1, -0.1, 0.9),(0.1, 1.1, 1.1))).vals() - self.assertEqual(2, len(vl)) - vl = c.vertices(selectors.BoxSelector((-0.1, -0.1, -0.1),(0.1, 1.1, 1.1))).vals() - self.assertEqual(4, len(vl)) - - # test edge selection - test_data_edges = [ - # box point0, box point1, edge center - ((0.4, -0.1, -0.1), (0.6, 0.1, 0.1), (0.5, 0.0, 0.0)), - ((-0.1, -0.1, 0.4), (0.1, 0.1, 0.6), (0.0, 0.0, 0.5)), - ((0.9, 0.9, 0.4), (1.1, 1.1, 0.6), (1.0, 1.0, 0.5)), - ((0.4, 0.9, 0.9), (0.6, 1.1, 1.1,), (0.5, 1.0, 1.0)) - ] - - for d in test_data_edges: - el = c.edges(selectors.BoxSelector(d[0], d[1])).vals() - self.assertEqual(1, len(el)) - ec = el[0].Center() - self.assertTupleAlmostEquals(d[2], (ec.x, ec.y, ec.z), 3) - - # test again by swapping box points - el = c.edges(selectors.BoxSelector(d[1], d[0])).vals() - self.assertEqual(1, len(el)) - ec = el[0].Center() - self.assertTupleAlmostEquals(d[2], (ec.x, ec.y, ec.z), 3) - - # test multiple edge selection - el = c.edges(selectors.BoxSelector((-0.1, -0.1, -0.1), (0.6, 0.1, 0.6))).vals() - self.assertEqual(2, len(el)) - el = c.edges(selectors.BoxSelector((-0.1, -0.1, -0.1), (1.1, 0.1, 0.6))).vals() - self.assertEqual(3, len(el)) - - # test face selection - test_data_faces = [ - # box point0, box point1, face center - ((0.4, -0.1, 0.4), (0.6, 0.1, 0.6), (0.5, 0.0, 0.5)), - ((0.9, 0.4, 0.4), (1.1, 0.6, 0.6), (1.0, 0.5, 0.5)), - ((0.4, 0.4, 0.9), (0.6, 0.6, 1.1), (0.5, 0.5, 1.0)), - ((0.4, 0.4, -0.1), (0.6, 0.6, 0.1), (0.5, 0.5, 0.0)) - ] - - for d in test_data_faces: - fl = c.faces(selectors.BoxSelector(d[0], d[1])).vals() - self.assertEqual(1, len(fl)) - fc = fl[0].Center() - self.assertTupleAlmostEquals(d[2], (fc.x, fc.y, fc.z), 3) - - # test again by swapping box points - fl = c.faces(selectors.BoxSelector(d[1], d[0])).vals() - self.assertEqual(1, len(fl)) - fc = fl[0].Center() - self.assertTupleAlmostEquals(d[2], (fc.x, fc.y, fc.z), 3) - - # test multiple face selection - fl = c.faces(selectors.BoxSelector((0.4, 0.4, 0.4), (0.6, 1.1, 1.1))).vals() - self.assertEqual(2, len(fl)) - fl = c.faces(selectors.BoxSelector((0.4, 0.4, 0.4), (1.1, 1.1, 1.1))).vals() - self.assertEqual(3, len(fl)) - - # test boundingbox option - el = c.edges(selectors.BoxSelector((-0.1, -0.1, -0.1), (1.1, 0.1, 0.6), True)).vals() - self.assertEqual(1, len(el)) - fl = c.faces(selectors.BoxSelector((0.4, 0.4, 0.4), (1.1, 1.1, 1.1), True)).vals() - self.assertEqual(0, len(fl)) - fl = c.faces(selectors.BoxSelector((-0.1, 0.4, -0.1), (1.1, 1.1, 1.1), True)).vals() - self.assertEqual(1, len(fl)) - - def testAndSelector(self): - c = CQ(makeUnitCube()) - - S = selectors.StringSyntaxSelector - BS = selectors.BoxSelector - - el = c.edges(selectors.AndSelector(S('|X'), BS((-2,-2,0.1), (2,2,2)))).vals() - self.assertEqual(2, len(el)) - - # test 'and' (intersection) operator - el = c.edges(S('|X') & BS((-2,-2,0.1), (2,2,2))).vals() - self.assertEqual(2, len(el)) - - # test using extended string syntax - v = c.vertices(">X and >Y").vals() - self.assertEqual(2, len(v)) - - def testSumSelector(self): - c = CQ(makeUnitCube()) - - S = selectors.StringSyntaxSelector - - fl = c.faces(selectors.SumSelector(S(">Z"), S("Z") + S("Z or X"))).vals() - self.assertEqual(3, len(fl)) - - # test the subtract operator - fl = c.faces(S("#Z") - S(">X")).vals() - self.assertEqual(3, len(fl)) - - # test using extended string syntax - fl = c.faces("#Z exc >X").vals() - self.assertEqual(3, len(fl)) - - def testInverseSelector(self): - c = CQ(makeUnitCube()) - - S = selectors.StringSyntaxSelector - - fl = c.faces(selectors.InverseSelector(S('>Z'))).vals() - self.assertEqual(5, len(fl)) - el = c.faces('>Z').edges(selectors.InverseSelector(S('>X'))).vals() - self.assertEqual(3, len(el)) - - # test invert operator - fl = c.faces(-S('>Z')).vals() - self.assertEqual(5, len(fl)) - el = c.faces('>Z').edges(-S('>X')).vals() - self.assertEqual(3, len(el)) - - # test using extended string syntax - fl = c.faces('not >Z').vals() - self.assertEqual(5, len(fl)) - el = c.faces('>Z').edges('not >X').vals() - self.assertEqual(3, len(el)) - - def testComplexStringSelector(self): - c = CQ(makeUnitCube()) - - v = c.vertices('(>X and >Y) or (XZ', - '(1,4,55.)[20]', - '|XY', - '(0,0,1) or XY except >(1,1,1)[-1]', - '(not |(1,1,0) and >(0,0,1)) exc XY and (Z or X)', - 'not ( X or Y )'] - - for e in expressions: gram.parseString(e,parseAll=True) - \ No newline at end of file diff --git a/Libs/cadquery-lib/tests/TestCadObjects.py b/Libs/cadquery-lib/tests/TestCadObjects.py deleted file mode 100644 index 3b2f98e..0000000 --- a/Libs/cadquery-lib/tests/TestCadObjects.py +++ /dev/null @@ -1,104 +0,0 @@ -#system modules -import sys -import unittest -from tests import BaseTest -import FreeCAD -import Part - - -from cadquery import * - -class TestCadObjects(BaseTest): - - def testVectorConstructors(self): - v1 = Vector(1, 2, 3) - v2 = Vector((1, 2, 3)) - v3 = Vector(FreeCAD.Base.Vector(1, 2, 3)) - - for v in [v1, v2, v3]: - self.assertTupleAlmostEquals((1, 2, 3), v.toTuple(), 4) - - def testVertex(self): - """ - Tests basic vertex functions - """ - v = Vertex(Part.Vertex(1, 1, 1)) - self.assertEqual(1, v.X) - self.assertEquals(Vector, type(v.Center())) - - def testBasicBoundingBox(self): - v = Vertex(Part.Vertex(1, 1, 1)) - v2 = Vertex(Part.Vertex(2, 2, 2)) - self.assertEquals(BoundBox, type(v.BoundingBox())) - self.assertEquals(BoundBox, type(v2.BoundingBox())) - - bb1 = v.BoundingBox().add(v2.BoundingBox()) - - self.assertEquals(bb1.xlen, 1.0) - - def testEdgeWrapperCenter(self): - e = Edge(Part.makeCircle(2.0, FreeCAD.Base.Vector(1, 2, 3))) - - self.assertTupleAlmostEquals((1.0, 2.0, 3.0), e.Center().toTuple(), 3) - - def testEdgeWrapperMakeCircle(self): - halfCircleEdge = Edge.makeCircle(radius=10, pnt=(0, 0, 0), dir=(0, 0, 1), angle1=0, angle2=180) - - self.assertTupleAlmostEquals((0.0, 5.0, 0.0), halfCircleEdge.CenterOfBoundBox(0.0001).toTuple(),3) - self.assertTupleAlmostEquals((10.0, 0.0, 0.0), halfCircleEdge.startPoint().toTuple(), 3) - self.assertTupleAlmostEquals((-10.0, 0.0, 0.0), halfCircleEdge.endPoint().toTuple(), 3) - - def testFaceWrapperMakePlane(self): - mplane = Face.makePlane(10,10) - - self.assertTupleAlmostEquals((0.0, 0.0, 1.0), mplane.normalAt().toTuple(), 3) - - def testCenterOfBoundBox(self): - pass - - def testCombinedCenterOfBoundBox(self): - pass - - def testCompoundCenter(self): - """ - Tests whether or not a proper weighted center can be found for a compound - """ - def cylinders(self, radius, height): - def _cyl(pnt): - # Inner function to build a cylinder - return Solid.makeCylinder(radius, height, pnt) - - # Combine all the cylinders into a single compound - r = self.eachpoint(_cyl, True).combineSolids() - - return r - - Workplane.cyl = cylinders - - # Now test. here we want weird workplane to see if the objects are transformed right - s = Workplane("XY").rect(2.0, 3.0, forConstruction=True).vertices().cyl(0.25, 0.5) - - self.assertEquals(4, len(s.val().Solids())) - self.assertTupleAlmostEquals((0.0, 0.0, 0.25), s.val().Center().toTuple(), 3) - - def testDot(self): - v1 = Vector(2, 2, 2) - v2 = Vector(1, -1, 1) - self.assertEquals(2.0, v1.dot(v2)) - - def testVectorAdd(self): - result = Vector(1, 2, 0) + Vector(0, 0, 3) - self.assertTupleAlmostEquals((1.0, 2.0, 3.0), result.toTuple(), 3) - - def testTranslate(self): - e = Shape.cast(Part.makeCircle(2.0, FreeCAD.Base.Vector(1, 2, 3))) - e2 = e.translate(Vector(0, 0, 1)) - - self.assertTupleAlmostEquals((1.0, 2.0, 4.0), e2.Center().toTuple(), 3) - - def testVertices(self): - e = Shape.cast(Part.makeLine((0, 0, 0), (1, 1, 0))) - self.assertEquals(2, len(e.Vertices())) - -if __name__ == '__main__': - unittest.main() diff --git a/Libs/cadquery-lib/tests/TestCadQuery.py b/Libs/cadquery-lib/tests/TestCadQuery.py deleted file mode 100644 index 12f41b7..0000000 --- a/Libs/cadquery-lib/tests/TestCadQuery.py +++ /dev/null @@ -1,1424 +0,0 @@ -""" - This module tests cadquery creation and manipulation functions - -""" -#system modules -import math,sys,os.path,time - -#my modules -from cadquery import * -from cadquery import exporters -from tests import BaseTest,writeStringToFile,makeUnitCube,readFileAsString,makeUnitSquareWire,makeCube - -#where unit test output will be saved -import sys -if sys.platform.startswith("win"): - OUTDIR = "c:/temp" -else: - OUTDIR = "/tmp" -SUMMARY_FILE = os.path.join(OUTDIR,"testSummary.html") - -SUMMARY_TEMPLATE=""" - - - - - - -""" - -TEST_RESULT_TEMPLATE=""" -

%(name)s

- %(svg)s -
- -""" - -#clean up any summary file that is in the output directory. -#i know, this sux, but there is no other way to do this in 2.6, as we cannot do class fixutres till 2.7 -writeStringToFile(SUMMARY_TEMPLATE,SUMMARY_FILE) - - -class TestCadQuery(BaseTest): - - def tearDown(self): - """ - Update summary with data from this test. - This is a really hackey way of doing it-- we get a startup event from module load, - but there is no way in unittest to get a single shutdown event-- except for stuff in 2.7 and above - - So what we do here is to read the existing file, stick in more content, and leave it - """ - svgFile = os.path.join(OUTDIR,self._testMethodName + ".svg") - - #all tests do not produce output - if os.path.exists(svgFile): - existingSummary = readFileAsString(SUMMARY_FILE) - svgText = readFileAsString(svgFile) - svgText = svgText.replace('',"") - - #now write data into the file - #the content we are replacing it with also includes the marker, so it can be replaced again - existingSummary = existingSummary.replace("", TEST_RESULT_TEMPLATE % ( - dict(svg=svgText, name=self._testMethodName))) - - writeStringToFile(existingSummary,SUMMARY_FILE) - - def saveModel(self, shape): - """ - shape must be a CQ object - Save models in SVG and STEP format - """ - shape.exportSvg(os.path.join(OUTDIR,self._testMethodName + ".svg")) - shape.val().exportStep(os.path.join(OUTDIR,self._testMethodName + ".step")) - - def testToFreeCAD(self): - """ - Tests to make sure that a CadQuery object is converted correctly to a FreeCAD object. - """ - r = Workplane('XY').rect(5, 5).extrude(5) - - r = r.toFreecad() - - self.assertEqual(12, len(r.Edges)) - - def testToSVG(self): - """ - Tests to make sure that a CadQuery object is converted correctly to SVG - """ - r = Workplane('XY').rect(5, 5).extrude(5) - - r_str = r.toSvg() - - # Make sure that a couple of sections from the SVG output make sense - self.assertTrue(r_str.index('path d=" M 2.35965 -2.27987 L 4.0114 -3.23936 "') > 0) - self.assertTrue(r_str.index('line x1="30" y1="-30" x2="58" y2="-15" stroke-width="3"') > 0) - - def testCubePlugin(self): - """ - Tests a plugin that combines cubes together with a base - :return: - """ - #make the plugin method - def makeCubes(self,length): - #self refers to the CQ or Workplane object - - #inner method that creates a cube - def _singleCube(pnt): - #pnt is a location in local coordinates - #since we're using eachpoint with useLocalCoordinates=True - return Solid.makeBox(length,length,length,pnt) - - #use CQ utility method to iterate over the stack, call our - #method, and convert to/from local coordinates. - return self.eachpoint(_singleCube,True) - - #link the plugin in - Workplane.makeCubes = makeCubes - - #call it - result = Workplane("XY").box(6.0,8.0,0.5).faces(">Z").rect(4.0,4.0,forConstruction=True).vertices() - result = result.makeCubes(1.0) - result = result.combineSolids() - self.saveModel(result) - self.assertEquals(1,result.solids().size() ) - - - def testCylinderPlugin(self): - """ - Tests a cylinder plugin. - The plugin creates cylinders of the specified radius and height for each item on the stack - - This is a very short plugin that illustrates just about the simplest possible - plugin - """ - - def cylinders(self,radius,height): - - def _cyl(pnt): - #inner function to build a cylinder - return Solid.makeCylinder(radius,height,pnt) - - #combine all the cylinders into a single compound - r = self.eachpoint(_cyl,True).combineSolids() - return r - Workplane.cyl = cylinders - - #now test. here we want weird workplane to see if the objects are transformed right - s = Workplane(Plane(Vector((0,0,0)),Vector((1,-1,0)),Vector((1,1,0)))).rect(2.0,3.0,forConstruction=True).vertices() \ - .cyl(0.25,0.5) - self.assertEquals(1,s.solids().size() ) - self.saveModel(s) - - def testPolygonPlugin(self): - """ - Tests a plugin to make regular polygons around points on the stack - - Demonstratings using eachpoint to allow working in local coordinates - to create geometry - """ - def rPoly(self,nSides,diameter): - - def _makePolygon(center): - #pnt is a vector in local coordinates - angle = 2.0 *math.pi / nSides - pnts = [] - for i in range(nSides+1): - pnts.append( center + Vector((diameter / 2.0 * math.cos(angle*i)),(diameter / 2.0 * math.sin(angle*i)),0)) - return Wire.makePolygon(pnts) - - return self.eachpoint(_makePolygon,True) - - Workplane.rPoly = rPoly - - s = Workplane("XY").box(4.0,4.0,0.25).faces(">Z").workplane().rect(2.0,2.0,forConstruction=True).vertices()\ - .rPoly(5,0.5).cutThruAll() - - self.assertEquals(26,s.faces().size()) #6 base sides, 4 pentagons, 5 sides each = 26 - self.saveModel(s) - - - def testPointList(self): - """ - Tests adding points and using them - """ - c = CQ(makeUnitCube()) - - s = c.faces(">Z").workplane().pushPoints([(-0.3, 0.3), (0.3, 0.3), (0, 0)]) - self.assertEqual(3, s.size()) - #TODO: is the ability to iterate over points with circle really worth it? - #maybe we should just require using all() and a loop for this. the semantics and - #possible combinations got too hard ( ie, .circle().circle() ) was really odd - body = s.circle(0.05).cutThruAll() - self.saveModel(body) - self.assertEqual(9, body.faces().size()) - - # Test the case when using eachpoint with only a blank workplane - def callback_fn(pnt): - self.assertEqual((0.0, 0.0), (pnt.x, pnt.y)) - - r = Workplane('XY') - r.objects = [] - r.eachpoint(callback_fn) - - - def testWorkplaneFromFace(self): - s = CQ(makeUnitCube()).faces(">Z").workplane() #make a workplane on the top face - r = s.circle(0.125).cutBlind(-2.0) - self.saveModel(r) - #the result should have 7 faces - self.assertEqual(7,r.faces().size() ) - self.assertEqual(type(r.val()), Solid) - self.assertEqual(type(r.first().val()),Solid) - - def testFrontReference(self): - s = CQ(makeUnitCube()).faces("front").workplane() #make a workplane on the top face - r = s.circle(0.125).cutBlind(-2.0) - self.saveModel(r) - #the result should have 7 faces - self.assertEqual(7,r.faces().size() ) - self.assertEqual(type(r.val()), Solid) - self.assertEqual(type(r.first().val()),Solid) - - def testRotate(self): - """Test solid rotation at the CQ object level.""" - box = Workplane("XY").box(1, 1, 5) - box.rotate((0, 0, 0), (1, 0, 0), 90) - startPoint = box.faces("Z").circle(1.5)\ - .workplane(offset=3.0).rect(0.75,0.5).loft(combine=True) - self.saveModel(s) - #self.assertEqual(1,s.solids().size() ) - #self.assertEqual(8,s.faces().size() ) - - def testRevolveCylinder(self): - """ - Test creating a solid using the revolve operation. - :return: - """ - # The dimensions of the model. These can be modified rather than changing the - # shape's code directly. - rectangle_width = 10.0 - rectangle_length = 10.0 - angle_degrees = 360.0 - - #Test revolve without any options for making a cylinder - result = Workplane("XY").rect(rectangle_width, rectangle_length, False).revolve() - self.assertEqual(3, result.faces().size()) - self.assertEqual(2, result.vertices().size()) - self.assertEqual(3, result.edges().size()) - - #Test revolve when only setting the angle to revolve through - result = Workplane("XY").rect(rectangle_width, rectangle_length, False).revolve(angle_degrees) - self.assertEqual(3, result.faces().size()) - self.assertEqual(2, result.vertices().size()) - self.assertEqual(3, result.edges().size()) - result = Workplane("XY").rect(rectangle_width, rectangle_length, False).revolve(270.0) - self.assertEqual(5, result.faces().size()) - self.assertEqual(6, result.vertices().size()) - self.assertEqual(9, result.edges().size()) - - #Test when passing revolve the angle and the axis of revolution's start point - result = Workplane("XY").rect(rectangle_width, rectangle_length).revolve(angle_degrees,(-5,-5)) - self.assertEqual(3, result.faces().size()) - self.assertEqual(2, result.vertices().size()) - self.assertEqual(3, result.edges().size()) - result = Workplane("XY").rect(rectangle_width, rectangle_length).revolve(270.0,(-5,-5)) - self.assertEqual(5, result.faces().size()) - self.assertEqual(6, result.vertices().size()) - self.assertEqual(9, result.edges().size()) - - #Test when passing revolve the angle and both the start and ends of the axis of revolution - result = Workplane("XY").rect(rectangle_width, rectangle_length).revolve(angle_degrees,(-5, -5),(-5, 5)) - self.assertEqual(3, result.faces().size()) - self.assertEqual(2, result.vertices().size()) - self.assertEqual(3, result.edges().size()) - result = Workplane("XY").rect(rectangle_width, rectangle_length).revolve(270.0,(-5, -5),(-5, 5)) - self.assertEqual(5, result.faces().size()) - self.assertEqual(6, result.vertices().size()) - self.assertEqual(9, result.edges().size()) - - #Testing all of the above without combine - result = Workplane("XY").rect(rectangle_width, rectangle_length).revolve(angle_degrees,(-5,-5),(-5,5), False) - self.assertEqual(3, result.faces().size()) - self.assertEqual(2, result.vertices().size()) - self.assertEqual(3, result.edges().size()) - result = Workplane("XY").rect(rectangle_width, rectangle_length).revolve(270.0,(-5,-5),(-5,5), False) - self.assertEqual(5, result.faces().size()) - self.assertEqual(6, result.vertices().size()) - self.assertEqual(9, result.edges().size()) - - def testRevolveDonut(self): - """ - Test creating a solid donut shape with square walls - :return: - """ - # The dimensions of the model. These can be modified rather than changing the - # shape's code directly. - rectangle_width = 10.0 - rectangle_length = 10.0 - angle_degrees = 360.0 - - result = Workplane("XY").rect(rectangle_width, rectangle_length, True)\ - .revolve(angle_degrees, (20, 0), (20, 10)) - self.assertEqual(4, result.faces().size()) - self.assertEqual(4, result.vertices().size()) - self.assertEqual(6, result.edges().size()) - - def testRevolveCone(self): - """ - Test creating a solid from a revolved triangle - :return: - """ - result = Workplane("XY").lineTo(0,10).lineTo(5,0).close().revolve() - self.assertEqual(2, result.faces().size()) - self.assertEqual(2, result.vertices().size()) - self.assertEqual(3, result.edges().size()) - - def testSweep(self): - """ - Tests the operation of sweeping a wire(s) along a path - """ - pts = [ - (0, 1), - (1, 2), - (2, 4) - ] - - # Spline path - path = Workplane("XZ").spline(pts) - - # Test defaults - result = Workplane("XY").circle(1.0).sweep(path) - self.assertEqual(3, result.faces().size()) - self.assertEqual(3, result.edges().size()) - - # Test with makeSolid False - result = Workplane("XY").circle(1.0).sweep(path, makeSolid=False) - self.assertEqual(1, result.faces().size()) - self.assertEqual(3, result.edges().size()) - - # Test with isFrenet True - result = Workplane("XY").circle(1.0).sweep(path, isFrenet=True) - self.assertEqual(3, result.faces().size()) - self.assertEqual(3, result.edges().size()) - - # Test with makeSolid False and isFrenet True - result = Workplane("XY").circle(1.0).sweep(path, makeSolid=False, isFrenet=True) - self.assertEqual(1, result.faces().size()) - self.assertEqual(3, result.edges().size()) - - # Test rectangle with defaults - result = Workplane("XY").rect(1.0, 1.0).sweep(path) - self.assertEqual(6, result.faces().size()) - self.assertEqual(12, result.edges().size()) - - # Polyline path - path = Workplane("XZ").polyline(pts) - - # Test defaults - result = Workplane("XY").circle(0.1).sweep(path) - self.assertEqual(5, result.faces().size()) - self.assertEqual(7, result.edges().size()) - - # Arc path - path = Workplane("XZ").threePointArc((1.0, 1.5),(0.0, 1.0)) - - # Test defaults - result = Workplane("XY").circle(0.1).sweep(path) - self.assertEqual(3, result.faces().size()) - self.assertEqual(3, result.edges().size()) - - def testTwistExtrude(self): - """ - Tests extrusion while twisting through an angle. - """ - profile = Workplane('XY').rect(10, 10) - r = profile.twistExtrude(10, 45, False) - - self.assertEqual(6, r.faces().size()) - - def testTwistExtrudeCombine(self): - """ - Tests extrusion while twisting through an angle, combining with other solids. - """ - profile = Workplane('XY').rect(10, 10) - r = profile.twistExtrude(10, 45) - - self.assertEqual(6, r.faces().size()) - - def testRectArray(self): - NUMX=3 - NUMY=3 - s = Workplane("XY").box(40,40,5,centered=(True,True,True)).faces(">Z").workplane().rarray(8.0,8.0,NUMX,NUMY,True).circle(2.0).extrude(2.0) - #s = Workplane("XY").box(40,40,5,centered=(True,True,True)).faces(">Z").workplane().circle(2.0).extrude(2.0) - self.saveModel(s) - self.assertEqual(6+NUMX*NUMY*2,s.faces().size()) #6 faces for the box, 2 faces for each cylinder - - def testNestedCircle(self): - s = Workplane("XY").box(40,40,5).pushPoints([(10,0),(0,10)]).circle(4).circle(2).extrude(4) - self.saveModel(s) - self.assertEqual(14,s.faces().size() ) - - def testLegoBrick(self): - #test making a simple lego brick - #which of the below - - #inputs - lbumps = 8 - wbumps = 2 - - #lego brick constants - P = 8.0 #nominal pitch - c = 0.1 #clearance on each brick side - H = 1.2 * P #nominal height of a brick - bumpDiam = 4.8 #the standard bump diameter - t = ( P - ( 2*c) - bumpDiam ) / 2.0 # the nominal thickness of the walls, normally 1.5 - - postDiam = P - t #works out to 6.5 - total_length = lbumps*P - 2.0*c - total_width = wbumps*P - 2.0*c - - #build the brick - s = Workplane("XY").box(total_length,total_width,H) #make the base - s = s.faces("Z").workplane().rarray(P,P,lbumps,wbumps,True).circle(bumpDiam/2.0).extrude(1.8) # make the bumps on the top - - #add posts on the bottom. posts are different diameter depending on geometry - #solid studs for 1 bump, tubes for multiple, none for 1x1 - tmp = s.faces(" 1 and wbumps > 1: - tmp = tmp.rarray(P,P,lbumps - 1,wbumps - 1,center=True).circle(postDiam/2.0).circle(bumpDiam/2.0).extrude(H-t) - elif lbumps > 1: - tmp = tmp.rarray(P,P,lbumps - 1,1,center=True).circle(t).extrude(H-t) - elif wbumps > 1: - tmp = tmp.rarray(P,P,1,wbumps -1,center=True).circle(t).extrude(H-t) - - self.saveModel(s) - - def testAngledHoles(self): - s = Workplane("front").box(4.0,4.0,0.25).faces(">Z").workplane().transformed(offset=Vector(0,-1.5,1.0),rotate=Vector(60,0,0))\ - .rect(1.5,1.5,forConstruction=True).vertices().hole(0.25) - self.saveModel(s) - self.assertEqual(10,s.faces().size()) - - def testTranslateSolid(self): - c = CQ(makeUnitCube()) - self.assertAlmostEqual(0.0,c.faces("Z').workplane().circle(0.125).extrude(0.5,True) #make a boss, not updating the original - self.assertEqual(8,r.faces().size()) #just the boss faces - self.assertEqual(8,c.faces().size()) #original is modified too - - def testSolidReferencesCombineTrue(self): - s = Workplane(Plane.XY()) - r = s.rect(2.0,2.0).extrude(0.5) - self.assertEqual(6,r.faces().size() ) #the result of course has 6 faces - self.assertEqual(0,s.faces().size() ) # the original workplane does not, because it did not have a solid initially - - t = r.faces(">Z").workplane().rect(0.25,0.25).extrude(0.5,True) - self.assertEqual(11,t.faces().size()) #of course the result has 11 faces - self.assertEqual(11,r.faces().size()) #r does as well. the context solid for r was updated since combine was true - self.saveModel(r) - - def testSolidReferenceCombineFalse(self): - s = Workplane(Plane.XY()) - r = s.rect(2.0,2.0).extrude(0.5) - self.assertEqual(6,r.faces().size() ) #the result of course has 6 faces - self.assertEqual(0,s.faces().size() ) # the original workplane does not, because it did not have a solid initially - - t = r.faces(">Z").workplane().rect(0.25,0.25).extrude(0.5,False) - self.assertEqual(6,t.faces().size()) #result has 6 faces, becuase it was not combined with the original - self.assertEqual(6,r.faces().size()) #original is unmodified as well - #subseuent opertions use that context solid afterwards - - def testSimpleWorkplane(self): - """ - A simple square part with a hole in it - """ - s = Workplane(Plane.XY()) - r = s.rect(2.0,2.0).extrude(0.5)\ - .faces(">Z").workplane()\ - .circle(0.25).cutBlind(-1.0) - - self.saveModel(r) - self.assertEqual(7,r.faces().size() ) - - def testMultiFaceWorkplane(self): - """ - Test Creation of workplane from multiple co-planar face - selection. - """ - s = Workplane('XY').box(1,1,1).faces('>Z').rect(1,0.5).cutBlind(-0.2) - - w = s.faces('>Z').workplane() - o = w.objects[0] # origin of the workplane - self.assertAlmostEqual(o.x, 0., 3) - self.assertAlmostEqual(o.y, 0., 3) - self.assertAlmostEqual(o.z, 0.5, 3) - - def testTriangularPrism(self): - s = Workplane("XY").lineTo(1,0).lineTo(1,1).close().extrude(0.2) - self.saveModel(s) - - def testMultiWireWorkplane(self): - """ - A simple square part with a hole in it-- but this time done as a single extrusion - with two wires, as opposed to s cut - """ - s = Workplane(Plane.XY()) - r = s.rect(2.0,2.0).circle(0.25).extrude(0.5) - - self.saveModel(r) - self.assertEqual(7,r.faces().size() ) - - def testConstructionWire(self): - """ - Tests a wire with several holes, that are based on the vertices of a square - also tests using a workplane plane other than XY - """ - s = Workplane(Plane.YZ()) - r = s.rect(2.0,2.0).rect(1.3,1.3,forConstruction=True).vertices().circle(0.125).extrude(0.5) - self.saveModel(r) - self.assertEqual(10,r.faces().size() ) # 10 faces-- 6 plus 4 holes, the vertices of the second rect. - - def testTwoWorkplanes(self): - """ - Tests a model that uses more than one workplane - """ - #base block - s = Workplane(Plane.XY()) - - #TODO: this syntax is nice, but the iteration might not be worth - #the complexity. - #the simpler and slightly longer version would be: - # r = s.rect(2.0,2.0).rect(1.3,1.3,forConstruction=True).vertices() - # for c in r.all(): - # c.circle(0.125).extrude(0.5,True) - r = s.rect(2.0,2.0).rect(1.3,1.3,forConstruction=True).vertices().circle(0.125).extrude(0.5) - - #side hole, blind deep 1.9 - t = r.faces(">Y").workplane().circle(0.125).cutBlind(-1.9) - self.saveModel(t) - self.assertEqual(12,t.faces().size() ) - - def testCut(self): - """ - Tests the cut function by itself to catch the case where a Solid object is passed. - """ - s = Workplane(Plane.XY()) - currentS = s.rect(2.0,2.0).extrude(0.5) - toCut = s.rect(1.0,1.0).extrude(0.5) - - currentS.cut(toCut.val()) - - self.assertEqual(10,currentS.faces().size()) - - def testIntersect(self): - """ - Tests the intersect function. - """ - s = Workplane(Plane.XY()) - currentS = s.rect(2.0, 2.0).extrude(0.5) - toIntersect = s.rect(1.0, 1.0).extrude(1) - - currentS.intersect(toIntersect.val()) - - self.assertEqual(6, currentS.faces().size()) - bb = currentS.val().BoundingBox() - self.assertListEqual([bb.xlen, bb.ylen, bb.zlen], [1, 1, 0.5]) - - def testBoundingBox(self): - """ - Tests the boudingbox center of a model - """ - result0 = (Workplane("XY") - .moveTo(10,0) - .lineTo(5,0) - .threePointArc((3.9393,0.4393),(3.5,1.5)) - .threePointArc((3.0607,2.5607),(2,3)) - .lineTo(1.5,3) - .threePointArc((0.4393,3.4393),(0,4.5)) - .lineTo(0,13.5) - .threePointArc((0.4393,14.5607),(1.5,15)) - .lineTo(28,15) - .lineTo(28,13.5) - .lineTo(24,13.5) - .lineTo(24,11.5) - .lineTo(27,11.5) - .lineTo(27,10) - .lineTo(22,10) - .lineTo(22,13.2) - .lineTo(14.5,13.2) - .lineTo(14.5,10) - .lineTo(12.5,10 ) - .lineTo(12.5,13.2) - .lineTo(5.5,13.2) - .lineTo(5.5,2) - .threePointArc((5.793,1.293),(6.5,1)) - .lineTo(10,1) - .close()) - result = result0.extrude(100) - bb_center = result.val().BoundingBox().center - self.saveModel(result) - self.assertAlmostEqual(14.0, bb_center.x, 3) - self.assertAlmostEqual(7.5, bb_center.y, 3) - self.assertAlmostEqual(50.0, bb_center.z, 3) - - def testCutThroughAll(self): - """ - Tests a model that uses more than one workplane - """ - #base block - s = Workplane(Plane.XY()) - r = s.rect(2.0,2.0).rect(1.3,1.3,forConstruction=True).vertices().circle(0.125).extrude(0.5) - - #side hole, thru all - t = r.faces(">Y").workplane().circle(0.125).cutThruAll() - self.saveModel(t) - self.assertEqual(11,t.faces().size() ) - - def testCutToFaceOffsetNOTIMPLEMENTEDYET(self): - """ - Tests cutting up to a given face, or an offset from a face - """ - #base block - s = Workplane(Plane.XY()) - r = s.rect(2.0,2.0).rect(1.3,1.3,forConstruction=True).vertices().circle(0.125).extrude(0.5) - - #side hole, up to 0.1 from the last face - try: - t = r.faces(">Y").workplane().circle(0.125).cutToOffsetFromFace(r.faces().mminDist(Dir.Y),0.1) - self.assertEqual(10,t.faces().size() ) #should end up being a blind hole - t.first().val().exportStep('c:/temp/testCutToFace.STEP') - except: - pass - #Not Implemented Yet - - def testWorkplaneOnExistingSolid(self): - "Tests extruding on an existing solid" - c = CQ( makeUnitCube()).faces(">Z").workplane().circle(0.25).circle(0.125).extrude(0.25) - self.saveModel(c) - self.assertEqual(10,c.faces().size() ) - - - def testWorkplaneCenterMove(self): - #this workplane is centered at x=0.5,y=0.5, the center of the upper face - s = Workplane("XY").box(1,1,1).faces(">Z").workplane().center(-0.5,-0.5) # move the center to the corner - - t = s.circle(0.25).extrude(0.2) # make a boss - self.assertEqual(9,t.faces().size() ) - self.saveModel(t) - - - def testBasicLines(self): - "Make a triangluar boss" - global OUTDIR - s = Workplane(Plane.XY()) - - #TODO: extrude() should imply wire() if not done already - #most users dont understand what a wire is, they are just drawing - - r = s.lineTo(1.0,0).lineTo(0,1.0).close().wire().extrude(0.25) - r.val().exportStep(os.path.join(OUTDIR, 'testBasicLinesStep1.STEP')) - - self.assertEqual(0,s.faces().size()) #no faces on the original workplane - self.assertEqual(5,r.faces().size() ) # 5 faces on newly created object - - #now add a circle through a side face - r.faces("+XY").workplane().circle(0.08).cutThruAll() - self.assertEqual(6,r.faces().size()) - r.val().exportStep(os.path.join(OUTDIR, 'testBasicLinesXY.STEP')) - - #now add a circle through a top - r.faces("+Z").workplane().circle(0.08).cutThruAll() - self.assertEqual(9,r.faces().size()) - r.val().exportStep(os.path.join(OUTDIR, 'testBasicLinesZ.STEP')) - - self.saveModel(r) - - def test2DDrawing(self): - """ - Draw things like 2D lines and arcs, should be expanded later to include all 2D constructs - """ - s = Workplane(Plane.XY()) - r = s.lineTo(1.0, 0.0) \ - .lineTo(1.0, 1.0) \ - .threePointArc((1.0, 1.5), (0.0, 1.0)) \ - .lineTo(0.0, 0.0) \ - .moveTo(1.0, 0.0) \ - .lineTo(2.0, 0.0) \ - .lineTo(2.0, 2.0) \ - .threePointArc((2.0, 2.5), (0.0, 2.0)) \ - .lineTo(-2.0, 2.0) \ - .lineTo(-2.0, 0.0) \ - .close() - - self.assertEqual(1, r.wires().size()) - - # Test the *LineTo functions - s = Workplane(Plane.XY()) - r = s.hLineTo(1.0).vLineTo(1.0).hLineTo(0.0).close() - - self.assertEqual(1, r.wire().size()) - self.assertEqual(4, r.edges().size()) - - # Test the *Line functions - s = Workplane(Plane.XY()) - r = s.hLine(1.0).vLine(1.0).hLine(-1.0).close() - - self.assertEqual(1, r.wire().size()) - self.assertEqual(4, r.edges().size()) - - # Test the move function - s = Workplane(Plane.XY()) - r = s.move(1.0, 1.0).hLine(1.0).vLine(1.0).hLine(-1.0).close() - - self.assertEqual(1, r.wire().size()) - self.assertEqual(4, r.edges().size()) - self.assertEqual((1.0, 1.0), - (r.vertices(selectors.NearestToPointSelector((0.0, 0.0, 0.0)))\ - .first().val().X, - r.vertices(selectors.NearestToPointSelector((0.0, 0.0, 0.0)))\ - .first().val().Y)) - - def testLargestDimension(self): - """ - Tests the largestDimension function when no solids are on the stack and when there are - """ - r = Workplane('XY').box(1, 1, 1) - dim = r.largestDimension() - - self.assertAlmostEqual(8.66025403784, dim) - - r = Workplane('XY') - dim = r.largestDimension() - - self.assertEqual(-1, dim) - - def testOccBottle(self): - """ - Make the OCC bottle example. - """ - - L = 20.0 - w = 6.0 - t = 3.0 - - s = Workplane(Plane.XY()) - #draw half the profile of the bottle - p = s.center(-L/2.0,0).vLine(w/2.0).threePointArc((L/2.0, w/2.0 + t),(L,w/2.0)).vLine(-w/2.0).mirrorX()\ - .extrude(30.0,True) - - #make the neck - p.faces(">Z").workplane().circle(3.0).extrude(2.0,True) #.edges().fillet(0.05) - - #make a shell - p.faces(">Z").shell(0.3) - self.saveModel(p) - - - def testSplineShape(self): - """ - Tests making a shape with an edge that is a spline - """ - s = Workplane(Plane.XY()) - sPnts = [ - (2.75,1.5), - (2.5,1.75), - (2.0,1.5), - (1.5,1.0), - (1.0,1.25), - (0.5,1.0), - (0,1.0) - ] - r = s.lineTo(3.0,0).lineTo(3.0,1.0).spline(sPnts).close() - r = r.extrude(0.5) - self.saveModel(r) - - def testSimpleMirror(self): - """ - Tests a simple mirroring operation - """ - s = Workplane("XY").lineTo(2, 2).threePointArc((3, 1), (2, 0)) \ - .mirrorX().extrude(0.25) - self.assertEquals(6, s.faces().size()) - self.saveModel(s) - - def testUnorderedMirror(self): - """ - Tests whether or not a wire can be mirrored if its mirror won't connect to it - """ - r = 20 - s = 7 - t = 1.5 - - points = [ - (0, t/2), - (r/2-1.5*t, r/2-t), - (s/2, r/2-t), - (s/2, r/2), - (r/2, r/2), - (r/2, s/2), - (r/2-t, s/2), - (r/2-t, r/2-1.5*t), - (t/2, 0) - ] - - r = Workplane("XY").polyline(points).mirrorX() - - self.assertEquals(1, r.wires().size()) - self.assertEquals(18, r.edges().size()) - - # def testChainedMirror(self): - # """ - # Tests whether or not calling mirrorX().mirrorY() works correctly - # """ - # r = 20 - # s = 7 - # t = 1.5 - # - # points = [ - # (0, t/2), - # (r/2-1.5*t, r/2-t), - # (s/2, r/2-t), - # (s/2, r/2), - # (r/2, r/2), - # (r/2, s/2), - # (r/2-t, s/2), - # (r/2-t, r/2-1.5*t), - # (t/2, 0) - # ] - # - # r = Workplane("XY").polyline(points).mirrorX().mirrorY() - # - # self.assertEquals(1, r.wires().size()) - # self.assertEquals(32, r.edges().size()) - - #TODO: Re-work testIbeam test below now that chaining works - #TODO: Add toLocalCoords and toWorldCoords tests - - def testIbeam(self): - """ - Make an ibeam. demonstrates fancy mirroring - """ - s = Workplane(Plane.XY()) - L = 100.0 - H = 20.0 - W = 20.0 - - t = 1.0 - #TODO: for some reason doing 1/4 of the profile and mirroring twice ( .mirrorX().mirrorY() ) - #did not work, due to a bug in freecad-- it was losing edges when creating a composite wire. - #i just side-stepped it for now - - pts = [ - (0, H/2.0), - (W/2.0, H/2.0), - (W/2.0, (H/2.0 - t)), - (t/2.0, (H/2.0-t)), - (t/2.0, (t - H/2.0)), - (W/2.0, (t - H/2.0)), - (W/2.0, H / -2.0), - (0, H/-2.0) - ] - r = s.polyline(pts).mirrorY() #these other forms also work - res = r.extrude(L) - self.saveModel(res) - - def testCone(self): - """ - Tests that a simple cone works - """ - s = Solid.makeCone(0, 1.0, 2.0) - t = CQ(s) - self.saveModel(t) - self.assertEqual(2, t.faces().size()) - - def testFillet(self): - """ - Tests filleting edges on a solid - """ - c = CQ( makeUnitCube()).faces(">Z").workplane().circle(0.25).extrude(0.25,True).edges("|Z").fillet(0.2) - self.saveModel(c) - self.assertEqual(12,c.faces().size() ) - - def testChamfer(self): - """ - Test chamfer API with a box shape - """ - cube = CQ(makeUnitCube()).faces(">Z").chamfer(0.1) - self.saveModel(cube) - self.assertEqual(10, cube.faces().size()) - - def testChamferAsymmetrical(self): - """ - Test chamfer API with a box shape for asymmetrical lengths - """ - cube = CQ(makeUnitCube()).faces(">Z").chamfer(0.1, 0.2) - self.saveModel(cube) - self.assertEqual(10, cube.faces().size()) - - # test if edge lengths are different - edge = cube.edges(">Z").vals()[0] - self.assertAlmostEqual(0.6, edge.Length(), 3) - edge = cube.edges("|Z").vals()[0] - self.assertAlmostEqual(0.9, edge.Length(), 3) - - def testChamferCylinder(self): - """ - Test chamfer API with a cylinder shape - """ - cylinder = Workplane("XY").circle(1).extrude(1).faces(">Z").chamfer(0.1) - self.saveModel(cylinder) - self.assertEqual(4, cylinder.faces().size()) - - def testCounterBores(self): - """ - Tests making a set of counterbored holes in a face - """ - c = CQ(makeCube(3.0)) - pnts = [ - (-1.0, -1.0), (0.0, 0.0), (1.0, 1.0) - ] - c.faces(">Z").workplane().pushPoints(pnts).cboreHole(0.1, 0.25, 0.25, 0.75) - self.assertEquals(18, c.faces().size()) - self.saveModel(c) - - # Tests the case where the depth of the cboreHole is not specified - c2 = CQ(makeCube(3.0)) - pnts = [ - (-1.0, -1.0), (0.0, 0.0), (1.0, 1.0) - ] - c2.faces(">Z").workplane().pushPoints(pnts).cboreHole(0.1, 0.25, 0.25) - self.assertEquals(15, c2.faces().size()) - - def testCounterSinks(self): - """ - Tests countersinks - """ - s = Workplane(Plane.XY()) - result = s.rect(2.0, 4.0).extrude(0.5).faces(">Z").workplane()\ - .rect(1.5, 3.5, forConstruction=True).vertices().cskHole(0.125, 0.25, 82, depth=None) - self.saveModel(result) - - def testSplitKeepingHalf(self): - """ - Tests splitting a solid - """ - - #drill a hole in the side - c = CQ(makeUnitCube()).faces(">Z").workplane().circle(0.25).cutThruAll() - - self.assertEqual(7, c.faces().size()) - - #now cut it in half sideways - c.faces(">Y").workplane(-0.5).split(keepTop=True) - self.saveModel(c) - self.assertEqual(8, c.faces().size()) - - def testSplitKeepingBoth(self): - """ - Tests splitting a solid - """ - - #drill a hole in the side - c = CQ(makeUnitCube()).faces(">Z").workplane().circle(0.25).cutThruAll() - self.assertEqual(7, c.faces().size()) - - #now cut it in half sideways - result = c.faces(">Y").workplane(-0.5).split(keepTop=True, keepBottom=True) - - #stack will have both halves, original will be unchanged - self.assertEqual(2, result.solids().size()) # two solids are on the stack, eac - self.assertEqual(8, result.solids().item(0).faces().size()) - self.assertEqual(8, result.solids().item(1).faces().size()) - - def testSplitKeepingBottom(self): - """ - Tests splitting a solid improperly - """ - # Drill a hole in the side - c = CQ(makeUnitCube()).faces(">Z").workplane().circle(0.25).cutThruAll() - self.assertEqual(7, c.faces().size()) - - # Now cut it in half sideways - result = c.faces(">Y").workplane(-0.5).split(keepTop=False, keepBottom=True) - - #stack will have both halves, original will be unchanged - self.assertEqual(1, result.solids().size()) # one solid is on the stack - self.assertEqual(8, result.solids().item(0).faces().size()) - - def testBoxDefaults(self): - """ - Tests creating a single box - """ - s = Workplane("XY").box(2, 3, 4) - self.assertEquals(1, s.solids().size()) - self.saveModel(s) - - def testSimpleShell(self): - """ - Create s simple box - """ - s = Workplane("XY").box(2, 2, 2).faces("+Z").shell(0.05) - self.saveModel(s) - self.assertEquals(23, s.faces().size()) - - - def testOpenCornerShell(self): - s = Workplane("XY").box(1, 1, 1) - s1 = s.faces("+Z") - s1.add(s.faces("+Y")).add(s.faces("+X")) - self.saveModel(s1.shell(0.2)) - - # Tests the list option variation of add - s1 = s.faces("+Z") - s1.add(s.faces("+Y")).add([s.faces("+X")]) - - # Tests the raw object option variation of add - s1 = s.faces("+Z") - s1.add(s.faces("+Y")).add(s.faces("+X").val().wrapped) - - def testTopFaceFillet(self): - s = Workplane("XY").box(1, 1, 1).faces("+Z").edges().fillet(0.1) - self.assertEquals(s.faces().size(), 10) - self.saveModel(s) - - def testBoxPointList(self): - """ - Tests creating an array of boxes - """ - s = Workplane("XY").rect(4.0, 4.0, forConstruction=True).vertices().box(0.25, 0.25, 0.25, combine=True) - #1 object, 4 solids because the object is a compound - self.assertEquals(1, s.solids().size()) - self.assertEquals(1, s.size()) - self.saveModel(s) - - s = Workplane("XY").rect(4.0, 4.0, forConstruction=True).vertices().box(0.25, 0.25, 0.25, combine=False) - #4 objects, 4 solids, because each is a separate solid - self.assertEquals(4, s.size()) - self.assertEquals(4, s.solids().size()) - - def testBoxCombine(self): - s = Workplane("XY").box(4, 4, 0.5).faces(">Z").workplane().rect(3, 3, forConstruction=True).vertices().box(0.25, 0.25, 0.25, combine=True) - - self.saveModel(s) - self.assertEquals(1, s.solids().size()) # we should have one big solid - self.assertEquals(26, s.faces().size()) # should have 26 faces. 6 for the box, and 4x5 for the smaller cubes - - def testSphereDefaults(self): - s = Workplane("XY").sphere(10) - #self.saveModel(s) # Until FreeCAD fixes their sphere operation - self.assertEquals(1, s.solids().size()) - self.assertEquals(1, s.faces().size()) - - def testSphereCustom(self): - s = Workplane("XY").sphere(10, angle1=0, angle2=90, angle3=360, centered=(False, False, False)) - self.saveModel(s) - self.assertEquals(1, s.solids().size()) - self.assertEquals(2, s.faces().size()) - - def testSpherePointList(self): - s = Workplane("XY").rect(4.0, 4.0, forConstruction=True).vertices().sphere(0.25, combine=False) - #self.saveModel(s) # Until FreeCAD fixes their sphere operation - self.assertEquals(4, s.solids().size()) - self.assertEquals(4, s.faces().size()) - - def testSphereCombine(self): - s = Workplane("XY").rect(4.0, 4.0, forConstruction=True).vertices().sphere(0.25, combine=True) - #self.saveModel(s) # Until FreeCAD fixes their sphere operation - self.assertEquals(1, s.solids().size()) - self.assertEquals(4, s.faces().size()) - - def testQuickStartXY(self): - s = Workplane(Plane.XY()).box(2, 4, 0.5).faces(">Z").workplane().rect(1.5, 3.5, forConstruction=True)\ - .vertices().cskHole(0.125, 0.25, 82, depth=None) - self.assertEquals(1, s.solids().size()) - self.assertEquals(14, s.faces().size()) - self.saveModel(s) - - def testQuickStartYZ(self): - s = Workplane(Plane.YZ()).box(2, 4, 0.5).faces(">X").workplane().rect(1.5, 3.5, forConstruction=True)\ - .vertices().cskHole(0.125, 0.25, 82, depth=None) - self.assertEquals(1, s.solids().size()) - self.assertEquals(14, s.faces().size()) - self.saveModel(s) - - def testQuickStartXZ(self): - s = Workplane(Plane.XZ()).box(2, 4, 0.5).faces(">Y").workplane().rect(1.5, 3.5, forConstruction=True)\ - .vertices().cskHole(0.125, 0.25, 82, depth=None) - self.assertEquals(1, s.solids().size()) - self.assertEquals(14, s.faces().size()) - self.saveModel(s) - - def testDoubleTwistedLoft(self): - s = Workplane("XY").polygon(8, 20.0).workplane(offset=4.0).transformed(rotate=Vector(0, 0, 15.0)).polygon(8, 20).loft() - s2 = Workplane("XY").polygon(8, 20.0).workplane(offset=-4.0).transformed(rotate=Vector(0, 0, 15.0)).polygon(8, 20).loft() - #self.assertEquals(10,s.faces().size()) - #self.assertEquals(1,s.solids().size()) - s3 = s.combineSolids(s2) - self.saveModel(s3) - - def testTwistedLoft(self): - s = Workplane("XY").polygon(8,20.0).workplane(offset=4.0).transformed(rotate=Vector(0,0,15.0)).polygon(8,20).loft() - self.assertEquals(10,s.faces().size()) - self.assertEquals(1,s.solids().size()) - self.saveModel(s) - - def testUnions(self): - #duplicates a memory problem of some kind reported when combining lots of objects - s = Workplane("XY").rect(0.5,0.5).extrude(5.0) - o = [] - beginTime = time.time() - for i in range(15): - t = Workplane("XY").center(10.0*i,0).rect(0.5,0.5).extrude(5.0) - o.append(t) - - #union stuff - for oo in o: - s = s.union(oo) - print "Total time %0.3f" % (time.time() - beginTime) - - #Test unioning a Solid object - s = Workplane(Plane.XY()) - currentS = s.rect(2.0,2.0).extrude(0.5) - toUnion = s.rect(1.0,1.0).extrude(1.0) - - currentS.union(toUnion.val(), combine=False) - - #TODO: When unioning and combining is figured out, uncomment the following assert - #self.assertEqual(10,currentS.faces().size()) - - def testCombine(self): - s = Workplane(Plane.XY()) - objects1 = s.rect(2.0,2.0).extrude(0.5).faces('>Z').rect(1.0,1.0).extrude(0.5) - - objects1.combine() - - self.assertEqual(11, objects1.faces().size()) - - - def testCombineSolidsInLoop(self): - #duplicates a memory problem of some kind reported when combining lots of objects - s = Workplane("XY").rect(0.5,0.5).extrude(5.0) - o = [] - beginTime = time.time() - for i in range(15): - t = Workplane("XY").center(10.0*i,0).rect(0.5,0.5).extrude(5.0) - o.append(t) - - #append the 'good way' - for oo in o: - s.add(oo) - s = s.combineSolids() - - print "Total time %0.3f" % (time.time() - beginTime) - - self.saveModel(s) - - def testClean(self): - """ - Tests the `clean()` method which is called automatically. - """ - - # make a cube with a splitter edge on one of the faces - # autosimplify should remove the splitter - s = Workplane("XY").moveTo(0,0).line(5,0).line(5,0).line(0,10).\ - line(-10,0).close().extrude(10) - - self.assertEqual(6, s.faces().size()) - - # test removal of splitter caused by union operation - s = Workplane("XY").box(10,10,10).union(Workplane("XY").box(20,10,10)) - - self.assertEqual(6, s.faces().size()) - - # test removal of splitter caused by extrude+combine operation - s = Workplane("XY").box(10,10,10).faces(">Y").\ - workplane().rect(5,10,5).extrude(20) - - self.assertEqual(10, s.faces().size()) - - # test removal of splitter caused by double hole operation - s = Workplane("XY").box(10,10,10).faces(">Z").workplane().\ - hole(3,5).faces(">Z").workplane().hole(3,10) - - self.assertEqual(7, s.faces().size()) - - # test removal of splitter caused by cutThruAll - s = Workplane("XY").box(10,10,10).faces(">Y").workplane().\ - rect(10,5).cutBlind(-5).faces(">Z").workplane().\ - center(0,2.5).rect(5,5).cutThruAll() - - self.assertEqual(18, s.faces().size()) - - # test removal of splitter with box - s = Workplane("XY").box(5,5,5).box(10,5,2) - - self.assertEqual(14, s.faces().size()) - - def testNoClean(self): - """ - Test the case when clean is disabled. - """ - # test disabling autoSimplify - s = Workplane("XY").moveTo(0,0).line(5,0).line(5,0).line(0,10).\ - line(-10,0).close().extrude(10, clean=False) - self.assertEqual(7, s.faces().size()) - - s = Workplane("XY").box(10,10,10).\ - union(Workplane("XY").box(20,10,10), clean=False) - self.assertEqual(14, s.faces().size()) - - s = Workplane("XY").box(10,10,10).faces(">Y").\ - workplane().rect(5,10,5).extrude(20, clean=False) - - self.assertEqual(12, s.faces().size()) - - def testExplicitClean(self): - """ - Test running of `clean()` method explicitly. - """ - s = Workplane("XY").moveTo(0,0).line(5,0).line(5,0).line(0,10).\ - line(-10,0).close().extrude(10,clean=False).clean() - self.assertEqual(6, s.faces().size()) - - def testCup(self): - - """ - UOM = "mm" - - # - # PARAMETERS and PRESETS - # These parameters can be manipulated by end users - # - bottomDiameter = FloatParam(min=10.0,presets={'default':50.0,'tumbler':50.0,'shot':35.0,'tea':50.0,'saucer':100.0},group="Basics", desc="Bottom diameter") - topDiameter = FloatParam(min=10.0,presets={'default':85.0,'tumbler':85.0,'shot':50.0,'tea':51.0,'saucer':400.0 },group="Basics", desc="Top diameter") - thickness = FloatParam(min=0.1,presets={'default':2.0,'tumbler':2.0,'shot':2.66,'tea':2.0,'saucer':2.0},group="Basics", desc="Thickness") - height = FloatParam(min=1.0,presets={'default':80.0,'tumbler':80.0,'shot':59.0,'tea':125.0,'saucer':40.0},group="Basics", desc="Overall height") - lipradius = FloatParam(min=1.0,presets={'default':1.0,'tumbler':1.0,'shot':0.8,'tea':1.0,'saucer':1.0},group="Basics", desc="Lip Radius") - bottomThickness = FloatParam(min=1.0,presets={'default':5.0,'tumbler':5.0,'shot':10.0,'tea':10.0,'saucer':5.0},group="Basics", desc="BottomThickness") - - # - # Your build method. It must return a solid object - # - def build(): - br = bottomDiameter.value / 2.0 - tr = topDiameter.value / 2.0 - t = thickness.value - s1 = Workplane("XY").circle(br).workplane(offset=height.value).circle(tr).loft() - s2 = Workplane("XY").workplane(offset=bottomThickness.value).circle(br - t ).workplane(offset=height.value - t ).circle(tr - t).loft() - - cup = s1.cut(s2) - cup.faces(">Z").edges().fillet(lipradius.value) - return cup - """ - - #for some reason shell doesnt work on this simple shape. how disappointing! - td = 50.0 - bd = 20.0 - h = 10.0 - t = 1.0 - s1 = Workplane("XY").circle(bd).workplane(offset=h).circle(td).loft() - s2 = Workplane("XY").workplane(offset=t).circle(bd-(2.0*t)).workplane(offset=(h-t)).circle(td-(2.0*t)).loft() - s3 = s1.cut(s2) - self.saveModel(s3) - - - def testEnclosure(self): - """ - Builds an electronics enclosure - Original FreeCAD script: 81 source statements ,not including variables - This script: 34 - """ - - #parameter definitions - p_outerWidth = 100.0 #Outer width of box enclosure - p_outerLength = 150.0 #Outer length of box enclosure - p_outerHeight = 50.0 #Outer height of box enclosure - - p_thickness = 3.0 #Thickness of the box walls - p_sideRadius = 10.0 #Radius for the curves around the sides of the bo - p_topAndBottomRadius = 2.0 #Radius for the curves on the top and bottom edges of the box - - p_screwpostInset = 12.0 #How far in from the edges the screwposts should be place. - p_screwpostID = 4.0 #nner Diameter of the screwpost holes, should be roughly screw diameter not including threads - p_screwpostOD = 10.0 #Outer Diameter of the screwposts.\nDetermines overall thickness of the posts - - p_boreDiameter = 8.0 #Diameter of the counterbore hole, if any - p_boreDepth = 1.0 #Depth of the counterbore hole, if - p_countersinkDiameter = 0.0 #Outer diameter of countersink. Should roughly match the outer diameter of the screw head - p_countersinkAngle = 90.0 #Countersink angle (complete angle between opposite sides, not from center to one side) - p_flipLid = True #Whether to place the lid with the top facing down or not. - p_lipHeight = 1.0 #Height of lip on the underside of the lid.\nSits inside the box body for a snug fit. - - #outer shell - oshell = Workplane("XY").rect(p_outerWidth,p_outerLength).extrude(p_outerHeight + p_lipHeight) - - #weird geometry happens if we make the fillets in the wrong order - if p_sideRadius > p_topAndBottomRadius: - oshell.edges("|Z").fillet(p_sideRadius) - oshell.edges("#Z").fillet(p_topAndBottomRadius) - else: - oshell.edges("#Z").fillet(p_topAndBottomRadius) - oshell.edges("|Z").fillet(p_sideRadius) - - #inner shell - ishell = oshell.faces("Z").workplane(-p_thickness)\ - .rect(POSTWIDTH,POSTLENGTH,forConstruction=True)\ - .vertices() - - for v in postCenters.all(): - v.circle(p_screwpostOD/2.0).circle(p_screwpostID/2.0)\ - .extrude((-1.0)*(p_outerHeight + p_lipHeight -p_thickness ),True) - - #split lid into top and bottom parts - (lid,bottom) = box.faces(">Z").workplane(-p_thickness -p_lipHeight ).split(keepTop=True,keepBottom=True).all() #splits into two solids - - #translate the lid, and subtract the bottom from it to produce the lid inset - lowerLid = lid.translate((0,0,-p_lipHeight)) - cutlip = lowerLid.cut(bottom).translate((p_outerWidth + p_thickness ,0,p_thickness - p_outerHeight + p_lipHeight)) - - #compute centers for counterbore/countersink or counterbore - topOfLidCenters = cutlip.faces(">Z").workplane().rect(POSTWIDTH,POSTLENGTH,forConstruction=True).vertices() - - #add holes of the desired type - if p_boreDiameter > 0 and p_boreDepth > 0: - topOfLid = topOfLidCenters.cboreHole(p_screwpostID,p_boreDiameter,p_boreDepth,(2.0)*p_thickness) - elif p_countersinkDiameter > 0 and p_countersinkAngle > 0: - topOfLid = topOfLidCenters.cskHole(p_screwpostID,p_countersinkDiameter,p_countersinkAngle,(2.0)*p_thickness) - else: - topOfLid= topOfLidCenters.hole(p_screwpostID,(2.0)*p_thickness) - - #flip lid upside down if desired - if p_flipLid: - topOfLid.rotateAboutCenter((1,0,0),180) - - #return the combined result - result =topOfLid.union(bottom) - - self.saveModel(result) - - def testExtrude(self): - """ - Test symmetric extrude - """ - r = 1. - h = 1. - decimal_places = 9. - - #extrude symmetrically - s = Workplane("XY").circle(r).extrude(h,both=True) - - top_face = s.faces(">Z") - bottom_face = s.faces(" -1 ) - return result - - def testSTL(self): - self._exportBox(exporters.ExportTypes.STL,['facet normal']) - - def testSVG(self): - self._exportBox(exporters.ExportTypes.SVG,['']) - - def testSTEP(self): - self._exportBox(exporters.ExportTypes.STEP,['FILE_SCHEMA']) - - def testTJS(self): - self._exportBox(exporters.ExportTypes.TJS,['vertices','formatVersion','faces']) diff --git a/Libs/cadquery-lib/tests/TestImporters.py b/Libs/cadquery-lib/tests/TestImporters.py deleted file mode 100644 index edee5d5..0000000 --- a/Libs/cadquery-lib/tests/TestImporters.py +++ /dev/null @@ -1,54 +0,0 @@ -""" - Tests file importers such as STEP -""" -#core modules -import StringIO - -from cadquery import * -from cadquery import exporters -from cadquery import importers -from tests import BaseTest - -#where unit test output will be saved -import sys -if sys.platform.startswith("win"): - OUTDIR = "c:/temp" -else: - OUTDIR = "/tmp" - - -class TestImporters(BaseTest): - def importBox(self, importType, fileName): - """ - Exports a simple box to a STEP file and then imports it again - :param importType: The type of file we're importing (STEP, STL, etc) - :param fileName: The path and name of the file to write to - """ - #We're importing a STEP file - if importType == importers.ImportTypes.STEP: - #We first need to build a simple shape to export - shape = Workplane("XY").box(1, 2, 3).val() - - #Export the shape to a temporary file - shape.exportStep(fileName) - - # Reimport the shape from the new STEP file - importedShape = importers.importShape(importType,fileName) - - #Check to make sure we got a solid back - self.assertTrue(importedShape.val().ShapeType() == "Solid") - - #Check the number of faces and vertices per face to make sure we have a box shape - self.assertTrue(importedShape.faces("+X").size() == 1 and importedShape.faces("+X").vertices().size() == 4) - self.assertTrue(importedShape.faces("+Y").size() == 1 and importedShape.faces("+Y").vertices().size() == 4) - self.assertTrue(importedShape.faces("+Z").size() == 1 and importedShape.faces("+Z").vertices().size() == 4) - - def testSTEP(self): - """ - Tests STEP file import - """ - self.importBox(importers.ImportTypes.STEP, OUTDIR + "/tempSTEP.step") - -if __name__ == '__main__': - import unittest - unittest.main() diff --git a/Libs/cadquery-lib/tests/TestWorkplanes.py b/Libs/cadquery-lib/tests/TestWorkplanes.py deleted file mode 100644 index 838b953..0000000 --- a/Libs/cadquery-lib/tests/TestWorkplanes.py +++ /dev/null @@ -1,125 +0,0 @@ -""" - Tests basic workplane functionality -""" -#core modules - -#my modules -from cadquery import * -from tests import BaseTest,toTuple - -xAxis_ = Vector(1, 0, 0) -yAxis_ = Vector(0, 1, 0) -zAxis_ = Vector(0, 0, 1) -xInvAxis_ = Vector(-1, 0, 0) -yInvAxis_ = Vector(0, -1, 0) -zInvAxis_ = Vector(0, 0, -1) - -class TestWorkplanes(BaseTest): - - def testYZPlaneOrigins(self): - #xy plane-- with origin at x=0.25 - base = Vector(0.25,0,0) - p = Plane(base, Vector(0,1,0), Vector(1,0,0)) - - #origin is always (0,0,0) in local coordinates - self.assertTupleAlmostEquals((0,0,0), p.toLocalCoords(p.origin).toTuple() ,2 ) - - #(0,0,0) is always the original base in global coordinates - self.assertTupleAlmostEquals(base.toTuple(), p.toWorldCoords((0,0)).toTuple() ,2 ) - - def testXYPlaneOrigins(self): - base = Vector(0,0,0.25) - p = Plane(base, Vector(1,0,0), Vector(0,0,1)) - - #origin is always (0,0,0) in local coordinates - self.assertTupleAlmostEquals((0,0,0), p.toLocalCoords(p.origin).toTuple() ,2 ) - - #(0,0,0) is always the original base in global coordinates - self.assertTupleAlmostEquals(toTuple(base), p.toWorldCoords((0,0)).toTuple() ,2 ) - - def testXZPlaneOrigins(self): - base = Vector(0,0.25,0) - p = Plane(base, Vector(0,0,1), Vector(0,1,0)) - - #(0,0,0) is always the original base in global coordinates - self.assertTupleAlmostEquals(toTuple(base), p.toWorldCoords((0,0)).toTuple() ,2 ) - - #origin is always (0,0,0) in local coordinates - self.assertTupleAlmostEquals((0,0,0), p.toLocalCoords(p.origin).toTuple() ,2 ) - - def testPlaneBasics(self): - p = Plane.XY() - #local to world - self.assertTupleAlmostEquals((1.0,1.0,0),p.toWorldCoords((1,1)).toTuple(),2 ) - self.assertTupleAlmostEquals((-1.0,-1.0,0), p.toWorldCoords((-1,-1)).toTuple(),2 ) - - #world to local - self.assertTupleAlmostEquals((-1.0,-1.0), p.toLocalCoords(Vector(-1,-1,0)).toTuple() ,2 ) - self.assertTupleAlmostEquals((1.0,1.0), p.toLocalCoords(Vector(1,1,0)).toTuple() ,2 ) - - p = Plane.YZ() - self.assertTupleAlmostEquals((0,1.0,1.0),p.toWorldCoords((1,1)).toTuple() ,2 ) - - #world to local - self.assertTupleAlmostEquals((1.0,1.0), p.toLocalCoords(Vector(0,1,1)).toTuple() ,2 ) - - p = Plane.XZ() - r = p.toWorldCoords((1,1)).toTuple() - self.assertTupleAlmostEquals((1.0,0.0,1.0),r ,2 ) - - #world to local - self.assertTupleAlmostEquals((1.0,1.0), p.toLocalCoords(Vector(1,0,1)).toTuple() ,2 ) - - def testOffsetPlanes(self): - "Tests that a plane offset from the origin works ok too" - p = Plane.XY(origin=(10.0,10.0,0)) - - - self.assertTupleAlmostEquals((11.0,11.0,0.0),p.toWorldCoords((1.0,1.0)).toTuple(),2 ) - self.assertTupleAlmostEquals((2.0,2.0), p.toLocalCoords(Vector(12.0,12.0,0)).toTuple() ,2 ) - - #TODO test these offsets in the other dimensions too - p = Plane.YZ(origin=(0,2,2)) - self.assertTupleAlmostEquals((0.0,5.0,5.0), p.toWorldCoords((3.0,3.0)).toTuple() ,2 ) - self.assertTupleAlmostEquals((10,10.0,0.0), p.toLocalCoords(Vector(0.0,12.0,12.0)).toTuple() ,2 ) - - p = Plane.XZ(origin=(2,0,2)) - r = p.toWorldCoords((1.0,1.0)).toTuple() - self.assertTupleAlmostEquals((3.0,0.0,3.0),r ,2 ) - self.assertTupleAlmostEquals((10.0,10.0), p.toLocalCoords(Vector(12.0,0.0,12.0)).toTuple() ,2 ) - - def testXYPlaneBasics(self): - p = Plane.named('XY') - self.assertTupleAlmostEquals(p.zDir.toTuple(), zAxis_.toTuple(), 4) - self.assertTupleAlmostEquals(p.xDir.toTuple(), xAxis_.toTuple(), 4) - self.assertTupleAlmostEquals(p.yDir.toTuple(), yAxis_.toTuple(), 4) - - def testYZPlaneBasics(self): - p = Plane.named('YZ') - self.assertTupleAlmostEquals(p.zDir.toTuple(), xAxis_.toTuple(), 4) - self.assertTupleAlmostEquals(p.xDir.toTuple(), yAxis_.toTuple(), 4) - self.assertTupleAlmostEquals(p.yDir.toTuple(), zAxis_.toTuple(), 4) - - def testZXPlaneBasics(self): - p = Plane.named('ZX') - self.assertTupleAlmostEquals(p.zDir.toTuple(), yAxis_.toTuple(), 4) - self.assertTupleAlmostEquals(p.xDir.toTuple(), zAxis_.toTuple(), 4) - self.assertTupleAlmostEquals(p.yDir.toTuple(), xAxis_.toTuple(), 4) - - def testXZPlaneBasics(self): - p = Plane.named('XZ') - self.assertTupleAlmostEquals(p.zDir.toTuple(), yInvAxis_.toTuple(), 4) - self.assertTupleAlmostEquals(p.xDir.toTuple(), xAxis_.toTuple(), 4) - self.assertTupleAlmostEquals(p.yDir.toTuple(), zAxis_.toTuple(), 4) - - def testYXPlaneBasics(self): - p = Plane.named('YX') - self.assertTupleAlmostEquals(p.zDir.toTuple(), zInvAxis_.toTuple(), 4) - self.assertTupleAlmostEquals(p.xDir.toTuple(), yAxis_.toTuple(), 4) - self.assertTupleAlmostEquals(p.yDir.toTuple(), xAxis_.toTuple(), 4) - - def testZYPlaneBasics(self): - p = Plane.named('ZY') - self.assertTupleAlmostEquals(p.zDir.toTuple(), xInvAxis_.toTuple(), 4) - self.assertTupleAlmostEquals(p.xDir.toTuple(), zAxis_.toTuple(), 4) - self.assertTupleAlmostEquals(p.yDir.toTuple(), yAxis_.toTuple(), 4) diff --git a/Libs/cadquery-lib/tests/__init__.py b/Libs/cadquery-lib/tests/__init__.py deleted file mode 100644 index 5dfc40e..0000000 --- a/Libs/cadquery-lib/tests/__init__.py +++ /dev/null @@ -1,54 +0,0 @@ -from cadquery import * -import unittest -import sys -import os - -import FreeCAD - -import Part as P -from FreeCAD import Vector as V - - -def readFileAsString(fileName): - f= open(fileName, 'r') - s = f.read() - f.close() - return s - - -def writeStringToFile(strToWrite, fileName): - f = open(fileName, 'w') - f.write(strToWrite) - f.close() - - -def makeUnitSquareWire(): - return Solid.cast(P.makePolygon([V(0, 0, 0), V(1, 0, 0), V(1, 1, 0), V(0, 1, 0), V(0, 0, 0)])) - - -def makeUnitCube(): - return makeCube(1.0) - - -def makeCube(size): - return Solid.makeBox(size, size, size) - - -def toTuple(v): - """convert a vector or a vertex to a 3-tuple: x,y,z""" - pnt = v - if type(v) == FreeCAD.Base.Vector: - return (v.Point.x, v.Point.y, v.Point.z) - elif type(v) == Vector: - return v.toTuple() - else: - raise RuntimeError("dont know how to convert type %s to tuple" % str(type(v)) ) - - -class BaseTest(unittest.TestCase): - - def assertTupleAlmostEquals(self, expected, actual, places): - for i, j in zip(actual, expected): - self.assertAlmostEquals(i, j, places) - -__all__ = ['TestCadObjects', 'TestCadQuery', 'TestCQSelectors', 'TestWorkplanes', 'TestExporters', 'TestCQSelectors', 'TestImporters','TestCQGI'] From fed83573f2b71521632062ffe0dcffdefe3b7667 Mon Sep 17 00:00:00 2001 From: Jeremy Mack Wright Date: Fri, 15 Sep 2017 22:13:39 -0400 Subject: [PATCH 15/19] Changes for show_object and updates to examples. --- Examples/Ex001_Simple_Block.py | 2 +- .../Ex002_Block_With_Bored_Center_Hole.py | 2 +- ...03_Pillow_Block_With_Counterbored_Holes.py | 2 +- Examples/Ex004_Extruded_Cylindrical_Plate.py | 2 +- Examples/Ex005_Extruded_Lines_and_Arcs.py | 2 +- .../Ex006_Moving_the_Current_Working_Point.py | 2 +- Examples/Ex007_Using_Point_Lists.py | 2 +- Examples/Ex008_Polygon_Creation.py | 2 +- Examples/Ex009_Polylines.py | 33 ++++++++++++++----- .../Ex010_Defining_an_Edge_with_a_Spline.py | 19 ++++++----- Gui/Command.py | 6 ++-- Libs/cadquery | 2 +- 12 files changed, 46 insertions(+), 30 deletions(-) diff --git a/Examples/Ex001_Simple_Block.py b/Examples/Ex001_Simple_Block.py index 12c0ae5..f72445f 100644 --- a/Examples/Ex001_Simple_Block.py +++ b/Examples/Ex001_Simple_Block.py @@ -16,4 +16,4 @@ result = cq.Workplane("XY").box(length, height, thickness) # from Helpers import show # show(result) # Render the result of this script -build_object(result) +show_object(result) diff --git a/Examples/Ex002_Block_With_Bored_Center_Hole.py b/Examples/Ex002_Block_With_Bored_Center_Hole.py index a1dda36..a825f98 100644 --- a/Examples/Ex002_Block_With_Bored_Center_Hole.py +++ b/Examples/Ex002_Block_With_Bored_Center_Hole.py @@ -17,4 +17,4 @@ result = cq.Workplane("XY").box(length, height, thickness) \ .faces(">Z").workplane().hole(center_hole_dia) # Displays the result of this script -build_object(result) +show_object(result) diff --git a/Examples/Ex003_Pillow_Block_With_Counterbored_Holes.py b/Examples/Ex003_Pillow_Block_With_Counterbored_Holes.py index 981b5c1..50ad422 100644 --- a/Examples/Ex003_Pillow_Block_With_Counterbored_Holes.py +++ b/Examples/Ex003_Pillow_Block_With_Counterbored_Holes.py @@ -31,4 +31,4 @@ result = cq.Workplane("XY").box(length, height, thickness) \ .vertices().cboreHole(cbore_hole_diameter, cbore_diameter, cbore_depth) # Displays the result of this script -build_object(result) +show_object(result) diff --git a/Examples/Ex004_Extruded_Cylindrical_Plate.py b/Examples/Ex004_Extruded_Cylindrical_Plate.py index 4ab483d..6ccb2ec 100644 --- a/Examples/Ex004_Extruded_Cylindrical_Plate.py +++ b/Examples/Ex004_Extruded_Cylindrical_Plate.py @@ -26,4 +26,4 @@ result = cq.Workplane("front").circle(circle_radius) \ .extrude(thickness) # Displays the result of this script -build_object(result) +show_object(result) diff --git a/Examples/Ex005_Extruded_Lines_and_Arcs.py b/Examples/Ex005_Extruded_Lines_and_Arcs.py index cc67cbf..62b51a4 100644 --- a/Examples/Ex005_Extruded_Lines_and_Arcs.py +++ b/Examples/Ex005_Extruded_Lines_and_Arcs.py @@ -29,4 +29,4 @@ result = cq.Workplane("front").lineTo(width, 0) \ .close().extrude(thickness) # Displays the result of this script -build_object(result) +show_object(result) diff --git a/Examples/Ex006_Moving_the_Current_Working_Point.py b/Examples/Ex006_Moving_the_Current_Working_Point.py index 166fe9f..3c26121 100644 --- a/Examples/Ex006_Moving_the_Current_Working_Point.py +++ b/Examples/Ex006_Moving_the_Current_Working_Point.py @@ -32,4 +32,4 @@ result = result.center(-1.5, 1.5).circle(0.25) result = result.extrude(thickness) # Displays the result of this script -build_object(result) +show_object(result) diff --git a/Examples/Ex007_Using_Point_Lists.py b/Examples/Ex007_Using_Point_Lists.py index 7a1bb84..d824c75 100644 --- a/Examples/Ex007_Using_Point_Lists.py +++ b/Examples/Ex007_Using_Point_Lists.py @@ -29,4 +29,4 @@ r = r.circle(hole_pattern_radius) result = r.extrude(thickness) # Displays the result of this script -build_object(result) +show_object(result) diff --git a/Examples/Ex008_Polygon_Creation.py b/Examples/Ex008_Polygon_Creation.py index c9d37c9..2fdecfc 100644 --- a/Examples/Ex008_Polygon_Creation.py +++ b/Examples/Ex008_Polygon_Creation.py @@ -36,4 +36,4 @@ result = cq.Workplane("front").box(width, height, thickness) \ .cutThruAll() # Displays the result of this script -build_object(result) +show_object(result) diff --git a/Examples/Ex009_Polylines.py b/Examples/Ex009_Polylines.py index 2de65be..fc164c6 100644 --- a/Examples/Ex009_Polylines.py +++ b/Examples/Ex009_Polylines.py @@ -1,11 +1,10 @@ -# This example is meant to be used from within the CadQuery module of FreeCAD. -import cadquery -from Helpers import show +import cadquery as cq -# Set up our Length, Height, Width, and thickness of the beam +# These can be modified rather than hardcoding values for each dimension. +# Define up our Length, Height, Width, and thickness of the beam (L, H, W, t) = (100.0, 20.0, 20.0, 1.0) -# Define the locations that the polyline will be drawn to/thru +# Define the points that the polyline will be drawn to/thru pts = [ (0, H/2.0), (W/2.0, H/2.0), @@ -18,8 +17,24 @@ pts = [ ] # We generate half of the I-beam outline and then mirror it to create the full -# I-beam -result = cadquery.Workplane("front").polyline(pts).mirrorY().extrude(L) +# I-beam. +# 1. Establishes a workplane that an object can be built on. +# 1a. Uses the named plane orientation "front" to define the workplane, meaning +# that the positive Z direction is "up", and the negative Z direction +# is "down". +# 2. moveTo() is used to move the first point from the origin (0, 0) to +# (0, 10.0), with 10.0 being half the height (H/2.0). If this is not done +# the first line will start from the origin, creating an extra segment that +# will cause the extrude to have an invalid shape. +# 3. The polyline function takes a list of points and generates the lines +# through all the points at once. +# 3. Only half of the I-beam profile has been drawn so far. That half is +# mirrored around the Y-axis to create the complete I-beam profile. +# 4. The I-beam profile is extruded to the final length of the beam. +result = cq.Workplane("front").moveTo(0, H/2.0) \ + .polyline(pts) \ + .mirrorY() \ + .extrude(L) -# Render the solid -show(result) +# Displays the result of this script +show_object(result) diff --git a/Examples/Ex010_Defining_an_Edge_with_a_Spline.py b/Examples/Ex010_Defining_an_Edge_with_a_Spline.py index ad985c5..8b4c67c 100644 --- a/Examples/Ex010_Defining_an_Edge_with_a_Spline.py +++ b/Examples/Ex010_Defining_an_Edge_with_a_Spline.py @@ -1,9 +1,9 @@ -# This example is meant to be used from within the CadQuery module of FreeCAD. -import cadquery -from Helpers import show +import cadquery as cq -# The workplane we want to create the spline on to extrude -s = cadquery.Workplane("XY") +# 1. Establishes a workplane to create the spline on to extrude. +# 1a. Uses the X and Y origins to define the workplane, meaning that the +# positive Z direction is "up", and the negative Z direction is "down". +s = cq.Workplane("XY") # The points that the spline will pass through sPnts = [ @@ -16,11 +16,12 @@ sPnts = [ (0, 1.0) ] -# Generate our plate with the spline feature and make sure it's a closed entity +# 2. Generate our plate with the spline feature and make sure it is a +# closed entity r = s.lineTo(3.0, 0).lineTo(3.0, 1.0).spline(sPnts).close() -# Extrude to turn the wire into a plate +# 3. Extrude to turn the wire into a plate result = r.extrude(0.5) -# Render the solid -show(result) +# Displays the result of this script +show_object(result) diff --git a/Gui/Command.py b/Gui/Command.py index f679ced..002742f 100644 --- a/Gui/Command.py +++ b/Gui/Command.py @@ -132,7 +132,7 @@ class CadQueryExecuteScript: scriptText = cqCodePane.toPlainText().encode('utf-8') # Check to see if we are executig a CQGI compliant script - if ("build_object(" in scriptText and "# build_object(" not in scriptText and "#build_boject(" not in scriptText) or ("debug(" in scriptText and "# debug(" not in scriptText and "#debug(" not in scriptText): + if ("show_object(" in scriptText and "# show_object(" not in scriptText and "#show_boject(" not in scriptText) or ("debug(" in scriptText and "# debug(" not in scriptText and "#debug(" not in scriptText): FreeCAD.Console.PrintMessage("Executing CQGI-compliant script.\r\n") # A repreentation of the CQ script with all the metadata attached @@ -417,8 +417,8 @@ class CadQueryValidateScript: scriptText = cqCodePane.toPlainText().encode('utf-8') - if "build_object(" not in scriptText or "# build_object(" in scriptText or "#build_boject(" in scriptText: - FreeCAD.Console.PrintError("Script did not call build_object, no output available. Script must be CQGI compliant to get build output, variable editing and validation.\r\n") + if ("show_object(" not in scriptText and "# show_object(" in scriptText and "#show_boject(" in scriptText) or ("debug(" not in scriptText and "# debug(" in scriptText and "#debug(" in scriptText): + FreeCAD.Console.PrintError("Script did not call show_object or debug, no output available. Script must be CQGI compliant to get build output, variable editing and validation.\r\n") return # A repreentation of the CQ script with all the metadata attached diff --git a/Libs/cadquery b/Libs/cadquery index 0c40258..654f04c 160000 --- a/Libs/cadquery +++ b/Libs/cadquery @@ -1 +1 @@ -Subproject commit 0c40258e28c0fad08b699430bce34ea2613d8d1e +Subproject commit 654f04c2e7e21fb1ebefcca519da86bcb342ee83 From e31b95099f2c8d9647fd77f97f308e1027c92233 Mon Sep 17 00:00:00 2001 From: Jeremy Mack Wright Date: Mon, 18 Sep 2017 16:25:57 -0400 Subject: [PATCH 16/19] Converted a few more examples. --- .../Ex011_Mirroring_Symmetric_Geometry.py | 23 ++++++++++------- .../Ex012_Creating_Workplanes_on_Faces.py | 20 +++++++++------ .../Ex013_Locating_a_Workplane_on_a_Vertex.py | 24 +++++++++++------- Examples/Ex014_Offset_Workplanes.py | 23 ++++++++++------- Examples/Ex015_Rotated_Workplanes.py | 25 +++++++++++++------ 5 files changed, 72 insertions(+), 43 deletions(-) diff --git a/Examples/Ex011_Mirroring_Symmetric_Geometry.py b/Examples/Ex011_Mirroring_Symmetric_Geometry.py index a34a46d..2fc1092 100644 --- a/Examples/Ex011_Mirroring_Symmetric_Geometry.py +++ b/Examples/Ex011_Mirroring_Symmetric_Geometry.py @@ -1,15 +1,20 @@ -# This example is meant to be used from within the CadQuery module of FreeCAD. -import cadquery -from Helpers import show +import cadquery as cq -# 1.0 is the distance, not coordinate -r = cadquery.Workplane("front").hLine(1.0) +# 1. Establishes a workplane that an object can be built on. +# 1a. Uses the named plane orientation "front" to define the workplane, meaning +# that the positive Z direction is "up", and the negative Z direction +# is "down". +# 2. A horizontal line is drawn on the workplane with the hLine function. +# 2a. 1.0 is the distance, not coordinate. hLineTo allows using xCoordinate +# not distance. +r = cq.Workplane("front").hLine(1.0) -# hLineTo allows using xCoordinate not distance +# 3. Draw a series of vertical and horizontal lines with the vLine and hLine +# functions. r = r.vLine(0.5).hLine(-0.25).vLine(-0.25).hLineTo(0.0) -# Mirror the geometry and extrude +# 4. Mirror the geometry about the Y axis and extrude it into a 3D object. result = r.mirrorY().extrude(0.25) -# Render the solid -show(result) +# Displays the result of this script +show_object(result) diff --git a/Examples/Ex012_Creating_Workplanes_on_Faces.py b/Examples/Ex012_Creating_Workplanes_on_Faces.py index 70ef1da..d73fafe 100644 --- a/Examples/Ex012_Creating_Workplanes_on_Faces.py +++ b/Examples/Ex012_Creating_Workplanes_on_Faces.py @@ -1,12 +1,16 @@ -# This example is meant to be used from within the CadQuery module of FreeCAD. -import cadquery -from Helpers import show +import cadquery as cq -# Make a basic prism -result = cadquery.Workplane("front").box(2, 3, 0.5) +# 1. Establishes a workplane that an object can be built on. +# 1a. Uses the named plane orientation "front" to define the workplane, meaning +# that the positive Z direction is "up", and the negative Z direction +# is "down". +# 2. Creates a 3D box that will have a hole placed in it later. +result = cq.Workplane("front").box(2, 3, 0.5) -# Find the top-most face and make a hole +# 3. Find the top-most face with the >Z max selector. +# 3a. Establish a new workplane to build geometry on. +# 3b. Create a hole down into the box. result = result.faces(">Z").workplane().hole(0.5) -# Render the solid -show(result) +# Displays the result of this script +show_object(result) diff --git a/Examples/Ex013_Locating_a_Workplane_on_a_Vertex.py b/Examples/Ex013_Locating_a_Workplane_on_a_Vertex.py index dc7721a..197e5c0 100644 --- a/Examples/Ex013_Locating_a_Workplane_on_a_Vertex.py +++ b/Examples/Ex013_Locating_a_Workplane_on_a_Vertex.py @@ -1,15 +1,21 @@ -# This example is meant to be used from within the CadQuery module of FreeCAD. -import cadquery -from Helpers import show +import cadquery as cq -# Make a basic prism -result = cadquery.Workplane("front").box(3, 2, 0.5) +# 1. Establishes a workplane that an object can be built on. +# 1a. Uses the named plane orientation "front" to define the workplane, meaning +# that the positive Z direction is "up", and the negative Z direction +# is "down". +# 2. Creates a 3D box that will have a hole placed in it later. +result = cq.Workplane("front").box(3, 2, 0.5) -# Select the lower left vertex and make a workplane +# 3. Select the lower left vertex and make a workplane. +# 3a. The top-most Z face is selected using the >Z selector. +# 3b. The lower-left vertex of the faces is selected with the Z").vertices("Z") \ +# 1. Establishes a workplane that an object can be built on. +# 1a. Uses the named plane orientation "front" to define the workplane, meaning +# that the positive Z direction is "up", and the negative Z direction +# is "down". +# 2. Creates a plain box to base future geometry on with the box() function. +# 3. Selects the top-most Z face of the box. +# 4. Creates a new workplane and then moves and rotates it with the +# transformed function. +# 5. Creates a for-construction rectangle that only exists to use for plancing +# other geometry. +# 6. Selects the vertices of the for-construction rectangle. +# 7. Places holes at the center of each selected vertex. +# 7a. Since the workplane is rotated, this results in angled holes in the face. +result = cq.Workplane("front").box(4.0, 4.0, 0.25).faces(">Z") \ .workplane() \ .transformed(offset=(0, -1.5, 1.0), rotate=(60, 0, 0)) \ .rect(1.5, 1.5, forConstruction=True).vertices().hole(0.25) -# Render the solid -show(result) +# Displays the result of this script +show_object(result) From a661b0ec4b724aa453675ef7710adff16a460be7 Mon Sep 17 00:00:00 2001 From: Jeremy Mack Wright Date: Wed, 20 Sep 2017 17:12:30 -0400 Subject: [PATCH 17/19] Finished converting the rest of the examples and then started fixing the ones that are broken. --- Examples/Ex015_Rotated_Workplanes.py | 2 +- Examples/Ex016_Using_Construction_Geometry.py | 26 +++++++++++----- .../Ex017_Shelling_to_Create_Thin_Features.py | 19 +++++++----- Examples/Ex018_Making_Lofts.py | 27 +++++++++++------ Examples/Ex019_Counter_Sunk_Holes.py | 24 ++++++++++----- .../Ex020_Rounding_Corners_with_Fillets.py | 18 ++++++----- Examples/Ex021_Splitting_an_Object.py | 30 +++++++++++++------ Examples/Ex022_Classic_OCC_Bottle.py | 10 +++---- Examples/Ex023_Parametric_Enclosure.py | 10 +++---- Examples/Ex025_Revolution.py | 10 +++---- Examples/Ex026_Lego_Brick.py | 8 ++--- Examples/Ex027_Remote_Enclosure.py | 18 +++++------ Examples/Ex028_Numpy.py | 11 +++---- Examples/Ex029_Braille.py | 3 +- ...arious_Holes_for_Connector_Installation.py | 8 ++--- Examples/Ex031_Sweep.py | 30 +++++++++---------- Examples/Ex032_3D_Printer_Extruder_Support.py | 3 +- ...Chamfer_With_Logical_Selector_Operators.py | 7 ++--- 18 files changed, 145 insertions(+), 119 deletions(-) diff --git a/Examples/Ex015_Rotated_Workplanes.py b/Examples/Ex015_Rotated_Workplanes.py index 598712b..a964e01 100644 --- a/Examples/Ex015_Rotated_Workplanes.py +++ b/Examples/Ex015_Rotated_Workplanes.py @@ -8,7 +8,7 @@ import cadquery as cq # 3. Selects the top-most Z face of the box. # 4. Creates a new workplane and then moves and rotates it with the # transformed function. -# 5. Creates a for-construction rectangle that only exists to use for plancing +# 5. Creates a for-construction rectangle that only exists to use for placing # other geometry. # 6. Selects the vertices of the for-construction rectangle. # 7. Places holes at the center of each selected vertex. diff --git a/Examples/Ex016_Using_Construction_Geometry.py b/Examples/Ex016_Using_Construction_Geometry.py index aee8058..48a4f87 100644 --- a/Examples/Ex016_Using_Construction_Geometry.py +++ b/Examples/Ex016_Using_Construction_Geometry.py @@ -1,11 +1,21 @@ -# This example is meant to be used from within the CadQuery module of FreeCAD. -import cadquery -from Helpers import show +import cadquery as cq -# Create a block with holes in each corner of a rectangle on that workplane -result = cadquery.Workplane("front").box(2, 2, 0.5)\ +# Create a block with holes in each corner of a rectangle on that workplane. +# 1. Establishes a workplane that an object can be built on. +# 1a. Uses the named plane orientation "front" to define the workplane, meaning +# that the positive Z direction is "up", and the negative Z direction +# is "down". +# 2. Creates a plain box to base future geometry on with the box() function. +# 3. Selects the top-most Z face of the box. +# 4. Creates a new workplane to build new geometry on. +# 5. Creates a for-construction rectangle that only exists to use for placing +# other geometry. +# 6. Selects the vertices of the for-construction rectangle. +# 7. Places holes at the center of each selected vertex. +result = cq.Workplane("front").box(2, 2, 0.5)\ .faces(">Z").workplane() \ - .rect(1.5, 1.5, forConstruction=True).vertices().hole(0.125) + .rect(1.5, 1.5, forConstruction=True).vertices() \ + .hole(0.125) -# Render the solid -show(result) +# Displays the result of this script +show_object(result) diff --git a/Examples/Ex017_Shelling_to_Create_Thin_Features.py b/Examples/Ex017_Shelling_to_Create_Thin_Features.py index b984306..91c6823 100644 --- a/Examples/Ex017_Shelling_to_Create_Thin_Features.py +++ b/Examples/Ex017_Shelling_to_Create_Thin_Features.py @@ -1,9 +1,14 @@ -# This example is meant to be used from within the CadQuery module of FreeCAD. -import cadquery -from Helpers import show +import cadquery as cq -# Create a hollow box that's open on both ends with a thin wall -result = cadquery.Workplane("front").box(2, 2, 2).faces("+Z").shell(0.05) +# Create a hollow box that's open on both ends with a thin wall. +# 1. Establishes a workplane that an object can be built on. +# 1a. Uses the named plane orientation "front" to define the workplane, meaning +# that the positive Z direction is "up", and the negative Z direction +# is "down". +# 2. Creates a plain box to base future geometry on with the box() function. +# 3. Selects faces with normal in +z direction. +# 4. Create a shell by cutting out the top-most Z face. +result = cq.Workplane("front").box(2, 2, 2).faces("+Z").shell(0.05) -# Render the solid -show(result) +# Displays the result of this script +show_object(result) diff --git a/Examples/Ex018_Making_Lofts.py b/Examples/Ex018_Making_Lofts.py index 6478f4a..6e9ad1e 100644 --- a/Examples/Ex018_Making_Lofts.py +++ b/Examples/Ex018_Making_Lofts.py @@ -1,11 +1,20 @@ -# This example is meant to be used from within the CadQuery module of FreeCAD. -import cadquery -from Helpers import show +import cadquery as cq -# Create a lofted section between a rectangle and a circular section -result = cadquery.Workplane("front").box(4.0, 4.0, 0.25).faces(">Z") \ - .circle(1.5).workplane(offset=3.0) \ - .rect(0.75, 0.5).loft(combine=True) +# Create a lofted section between a rectangle and a circular section. +# 1. Establishes a workplane that an object can be built on. +# 1a. Uses the named plane orientation "front" to define the workplane, meaning +# that the positive Z direction is "up", and the negative Z direction +# is "down". +# 2. Creates a plain box to base future geometry on with the box() function. +# 3. Selects the top-most Z face of the box. +# 4. Draws a 2D circle at the center of the the top-most face of the box. +# 5. Creates a workplane 3 mm above the face the circle was drawn on. +# 6. Draws a 2D circle on the new, offset workplane. +# 7. Creates a loft between the circle and the rectangle. +result = cq.Workplane("front").box(4.0, 4.0, 0.25).faces(">Z") \ + .circle(1.5).workplane(offset=3.0) \ + .rect(0.75, 0.5) \ + .loft(combine=True) -# Render the solid -show(result) +# Displays the result of this script +show_object(result) diff --git a/Examples/Ex019_Counter_Sunk_Holes.py b/Examples/Ex019_Counter_Sunk_Holes.py index be70587..e75039a 100644 --- a/Examples/Ex019_Counter_Sunk_Holes.py +++ b/Examples/Ex019_Counter_Sunk_Holes.py @@ -1,11 +1,19 @@ -# This example is meant to be used from within the CadQuery module of FreeCAD. -import cadquery -from Helpers import show +import cadquery as cq -# Create a plate with 4 counter-sunk holes in it -result = cadquery.Workplane(cadquery.Plane.XY()).box(4, 2, 0.5).faces(">Z") \ - .workplane().rect(3.5, 1.5, forConstruction=True)\ +# Create a plate with 4 counter-sunk holes in it. +# 1. Establishes a workplane using an XY object instead of a named plane. +# 2. Creates a plain box to base future geometry on with the box() function. +# 3. Selects the top-most face of the box and established a workplane on that. +# 4. Draws a for-construction rectangle on the workplane which only exists for +# placing other geometry. +# 5. Selects the corner vertices of the rectangle and places a counter-sink +# hole, using each vertex as the center of a hole using the cskHole() +# function. +# 5a. When the depth of the counter-sink hole is set to None, the hole will be +# cut through. +result = cq.Workplane(cq.Plane.XY()).box(4, 2, 0.5).faces(">Z") \ + .workplane().rect(3.5, 1.5, forConstruction=True) \ .vertices().cskHole(0.125, 0.25, 82.0, depth=None) -# Render the solid -show(result) +# Displays the result of this script +show_object(result) diff --git a/Examples/Ex020_Rounding_Corners_with_Fillets.py b/Examples/Ex020_Rounding_Corners_with_Fillets.py index a2f7876..a736970 100644 --- a/Examples/Ex020_Rounding_Corners_with_Fillets.py +++ b/Examples/Ex020_Rounding_Corners_with_Fillets.py @@ -1,9 +1,13 @@ -# This example is meant to be used from within the CadQuery module of FreeCAD. -import cadquery -from Helpers import show +import cadquery as cq -# Create a plate with 4 rounded corners in the Z-axis -result = cadquery.Workplane("XY").box(3, 3, 0.5).edges("|Z").fillet(0.125) +# Create a plate with 4 rounded corners in the Z-axis. +# 1. Establishes a workplane that an object can be built on. +# 1a. Uses the X and Y origins to define the workplane, meaning that the +# positive Z direction is "up", and the negative Z direction is "down". +# 2. Creates a plain box to base future geometry on with the box() function. +# 3. Selects all edges that are parallel to the Z axis. +# 4. Creates fillets on each of the selected edges with the specified radius. +result = cq.Workplane("XY").box(3, 3, 0.5).edges("|Z").fillet(0.125) -# Render the solid -show(result) +# Displays the result of this script +show_object(result) diff --git a/Examples/Ex021_Splitting_an_Object.py b/Examples/Ex021_Splitting_an_Object.py index 6cda407..e903a13 100644 --- a/Examples/Ex021_Splitting_an_Object.py +++ b/Examples/Ex021_Splitting_an_Object.py @@ -1,13 +1,25 @@ -# This example is meant to be used from within the CadQuery module of FreeCAD. -import cadquery -from Helpers import show +import cadquery as cq -# Create a simple block with a hole through it that we can split -c = cadquery.Workplane("XY").box(1, 1, 1).faces(">Z").workplane() \ - .circle(0.25).cutThruAll() +# Create a simple block with a hole through it that we can split. +# 1. Establishes a workplane that an object can be built on. +# 1a. Uses the X and Y origins to define the workplane, meaning that the +# positive Z direction is "up", and the negative Z direction is "down". +# 2. Creates a plain box to base future geometry on with the box() function. +# 3. Selects the top-most face of the box and establishes a workplane on it +# that new geometry can be built on. +# 4. Draws a 2D circle on the new workplane and then uses it to cut a hole +# all the way through the box. +c = cq.Workplane("XY").box(1, 1, 1).faces(">Z").workplane() \ + .circle(0.25).cutThruAll() -# Cut the block in half sideways +# 5. Selects the face furthest away from the origin in the +Y axis direction. +# 6. Creates an offset workplane that is set in the center of the object. +# 6a. One possible improvement to this script would be to make the dimensions +# of the box variables, and then divide the Y-axis dimension by 2.0 and +# use that to create the offset workplane. +# 7. Uses the embedded workplane to split the object, keeping only the "top" +# portion. result = c.faces(">Y").workplane(-0.5).split(keepTop=True) -# Render the solid -show(result) +# Displays the result of this script +show_object(result) diff --git a/Examples/Ex022_Classic_OCC_Bottle.py b/Examples/Ex022_Classic_OCC_Bottle.py index 0721335..5e01873 100644 --- a/Examples/Ex022_Classic_OCC_Bottle.py +++ b/Examples/Ex022_Classic_OCC_Bottle.py @@ -1,10 +1,8 @@ -# This example is meant to be used from within the CadQuery module of FreeCAD. -import cadquery -from Helpers import show +import cadquery as cq # Set up the length, width, and thickness (L, w, t) = (20.0, 6.0, 3.0) -s = cadquery.Workplane("XY") +s = cq.Workplane("XY") # Draw half the profile of the bottle and extrude it p = s.center(-L / 2.0, 0).vLine(w / 2.0) \ @@ -17,5 +15,5 @@ p.faces(">Z").workplane().circle(3.0).extrude(2.0, True) # Make a shell result = p.faces(">Z").shell(0.3) -# Render the solid -show(result) +# Displays the result of this script +show_object(result) diff --git a/Examples/Ex023_Parametric_Enclosure.py b/Examples/Ex023_Parametric_Enclosure.py index 82ebee4..3d12863 100644 --- a/Examples/Ex023_Parametric_Enclosure.py +++ b/Examples/Ex023_Parametric_Enclosure.py @@ -1,6 +1,4 @@ -# This example is meant to be used from within the CadQuery module of FreeCAD. -import cadquery -from Helpers import show +import cadquery as cq # Parameter definitions p_outerWidth = 100.0 # Outer width of box enclosure @@ -22,7 +20,7 @@ p_countersinkAngle = 90.0 # Countersink angle (complete angle between opposite p_lipHeight = 1.0 # Height of lip on the underside of the lid. Sits inside the box body for a snug fit. # Outer shell -oshell = cadquery.Workplane("XY").rect(p_outerWidth, p_outerLength) \ +oshell = cq.Workplane("XY").rect(p_outerWidth, p_outerLength) \ .extrude(p_outerHeight + p_lipHeight) # Weird geometry happens if we make the fillets in the wrong order @@ -75,5 +73,5 @@ else: # Return the combined result result = topOfLid.combineSolids(bottom) -# Render the solid -show(result) +# Displays the result of this script +show_object(result) diff --git a/Examples/Ex025_Revolution.py b/Examples/Ex025_Revolution.py index da0bb39..c5f3107 100644 --- a/Examples/Ex025_Revolution.py +++ b/Examples/Ex025_Revolution.py @@ -1,6 +1,4 @@ -# This example is meant to be used from within the CadQuery module of FreeCAD. -import cadquery -from Helpers import show +import cadquery as cq # The dimensions of the model. These can be modified rather than changing the # shape's code directly. @@ -10,7 +8,7 @@ angle_degrees = 360.0 # Revolve a cylinder from a rectangle # Switch comments around in this section to try the revolve operation with different parameters -result = cadquery.Workplane("XY").rect(rectangle_width, rectangle_length, False).revolve() +result = cq.Workplane("XY").rect(rectangle_width, rectangle_length, False).revolve() #result = cadquery.Workplane("XY").rect(rectangle_width, rectangle_length, False).revolve(angle_degrees) #result = cadquery.Workplane("XY").rect(rectangle_width, rectangle_length).revolve(angle_degrees,(-5,-5)) #result = cadquery.Workplane("XY").rect(rectangle_width, rectangle_length).revolve(angle_degrees,(-5, -5),(-5, 5)) @@ -19,5 +17,5 @@ result = cadquery.Workplane("XY").rect(rectangle_width, rectangle_length, False) # Revolve a donut with square walls #result = cadquery.Workplane("XY").rect(rectangle_width, rectangle_length, True).revolve(angle_degrees, (20, 0), (20, 10)) -# Render the solid -show(result) +# Displays the result of this script +show_object(result) diff --git a/Examples/Ex026_Lego_Brick.py b/Examples/Ex026_Lego_Brick.py index e52dde2..6a6381f 100644 --- a/Examples/Ex026_Lego_Brick.py +++ b/Examples/Ex026_Lego_Brick.py @@ -1,7 +1,5 @@ -# This example is meant to be used from within the CadQuery module of FreeCAD. # This script can create any regular rectangular Lego(TM) Brick -import cadquery -from Helpers import show +import cadquery as cq ##### # Inputs @@ -28,7 +26,7 @@ total_length = lbumps*pitch - 2.0*clearance total_width = wbumps*pitch - 2.0*clearance # make the base -s = cadquery.Workplane("XY").box(total_length, total_width, height) +s = cq.Workplane("XY").box(total_length, total_width, height) # shell inwards not outwards s = s.faces("Z") .fillet(yFilletRadius) # shell the solid from the bottom face, with a .060" wall thickness - .faces("-Z") + .faces("Z") .workplane() .pushPoints([(0, 0), (-xHoleOffset, 0), @@ -84,6 +80,6 @@ cover = (base(coverThickness) # Conditionally render the parts if showTop: - show(top) + show_object(top) if showCover: - show(cover) + show_object(cover) diff --git a/Examples/Ex028_Numpy.py b/Examples/Ex028_Numpy.py index 0aa12a0..df7c8b9 100644 --- a/Examples/Ex028_Numpy.py +++ b/Examples/Ex028_Numpy.py @@ -1,7 +1,5 @@ -# This example is meant to be used from within the CadQuery module of FreeCAD. import numpy as np -import cadquery -from Helpers import show +import cadquery as cq # Square side and offset in x and y. side = 10 @@ -11,16 +9,15 @@ offset = 5 # The polyline is defined as numpy.array so that operations like translation # of all points are simplified. pts = np.array([ - (0, 0), (side, 0), (side, side), (0, side), (0, 0), ]) + [offset, offset] -result = cadquery.Workplane('XY') \ - .polyline(pts).extrude(2) \ +result = cq.Workplane('XY') \ + .polyline(pts).close().extrude(2) \ .faces('+Z').workplane().circle(side / 2).extrude(1) # Render the solid -show(result) +show_object(result) diff --git a/Examples/Ex029_Braille.py b/Examples/Ex029_Braille.py index c366f4a..85918cf 100644 --- a/Examples/Ex029_Braille.py +++ b/Examples/Ex029_Braille.py @@ -5,7 +5,6 @@ from __future__ import unicode_literals, division from collections import namedtuple import cadquery as cq -from Helpers import show # text_lines is a list of text lines. # FreeCAD in braille (converted with braille-converter: @@ -180,4 +179,4 @@ _cell_geometry = BrailleCellGeometry( if base_thickness < get_cylinder_radius(_cell_geometry): raise ValueError('Base thickness should be at least {}'.format(dot_height)) -show(make_embossed_plate(text_lines, _cell_geometry)) +show_object(make_embossed_plate(text_lines, _cell_geometry)) diff --git a/Examples/Ex030_Panel_with_Various_Holes_for_Connector_Installation.py b/Examples/Ex030_Panel_with_Various_Holes_for_Connector_Installation.py index f3f08b4..f428e6b 100644 --- a/Examples/Ex030_Panel_with_Various_Holes_for_Connector_Installation.py +++ b/Examples/Ex030_Panel_with_Various_Holes_for_Connector_Installation.py @@ -1,6 +1,4 @@ -# This example is meant to be used from within the CadQuery module of FreeCAD. -import cadquery -from Helpers import show +import cadquery as cq # The dimensions of the model. These can be modified rather than changing the # object's code directly. @@ -9,7 +7,7 @@ height = 500 thickness = 2 # Create a plate with two polygons cut through it -result = cadquery.Workplane("front").box(width, height, thickness) +result = cq.Workplane("front").box(width, height, thickness) h_sep = 60 for idx in range(4): @@ -44,4 +42,4 @@ for idx in range(4): result = result.workplane(offset=1, centerOption='CenterOfBoundBox').center(-173,-30-idx*h_sep).moveTo(-2.9176,-5.3).threePointArc((-6.05,0),(-2.9176,5.3)).lineTo(2.9176,5.3).threePointArc((6.05,0),(2.9176,-5.3)).close().cutThruAll() # Render the solid -show(result) +show_object(result) diff --git a/Examples/Ex031_Sweep.py b/Examples/Ex031_Sweep.py index 16201b9..7c5ebdd 100644 --- a/Examples/Ex031_Sweep.py +++ b/Examples/Ex031_Sweep.py @@ -1,6 +1,4 @@ -# This example is meant to be used from within the CadQuery module for FreeCAD -import cadquery -from Helpers import show +import cadquery as cq # Points we will use to create spline and polyline paths to sweep over pts = [ @@ -10,33 +8,33 @@ pts = [ ] # Spline path generated from our list of points (tuples) -path = cadquery.Workplane("XZ").spline(pts) +path = cq.Workplane("XZ").spline(pts) # Sweep a circle with a diameter of 1.0 units along the spline path we just created -defaultSweep = cadquery.Workplane("XY").circle(1.0).sweep(path) +defaultSweep = cq.Workplane("XY").circle(1.0).sweep(path) # Sweep defaults to making a solid and not generating a Frenet solid. Setting Frenet to True helps prevent creep in # the orientation of the profile as it is being swept -frenetShell = cadquery.Workplane("XY").circle(1.0).sweep(path, makeSolid=False, isFrenet=True) +frenetShell = cq.Workplane("XY").circle(1.0).sweep(path, makeSolid=False, isFrenet=True) # We can sweep shapes other than circles -defaultRect = cadquery.Workplane("XY").rect(1.0, 1.0).sweep(path) +defaultRect = cq.Workplane("XY").rect(1.0, 1.0).sweep(path) # Switch to a polyline path, but have it use the same points as the spline -path = cadquery.Workplane("XZ").polyline(pts) +path = cq.Workplane("XZ").polyline(pts) # Using a polyline path leads to the resulting solid having segments rather than a single swept outer face -plineSweep = cadquery.Workplane("XY").circle(1.0).sweep(path) +plineSweep = cq.Workplane("XY").circle(1.0).sweep(path) # Switch to an arc for the path -path = cadquery.Workplane("XZ").threePointArc((1.0, 1.5), (0.0, 1.0)) +path = cq.Workplane("XZ").threePointArc((1.0, 1.5), (0.0, 1.0)) # Use a smaller circle section so that the resulting solid looks a little nicer -arcSweep = cadquery.Workplane("XY").circle(0.5).sweep(path) +arcSweep = cq.Workplane("XY").circle(0.5).sweep(path) # Translate the resulting solids so that they do not overlap and display them left to right -show(defaultSweep) -show(frenetShell.translate((5, 0, 0))) -show(defaultRect.translate((10, 0, 0))) -show(plineSweep.translate((15, 0, 0))) -show(arcSweep.translate((20, 0, 0))) \ No newline at end of file +show_object(defaultSweep) +show_object(frenetShell.translate((5, 0, 0))) +show_object(defaultRect.translate((10, 0, 0))) +show_object(plineSweep.translate((15, 0, 0))) +show_object(arcSweep.translate((20, 0, 0))) \ No newline at end of file diff --git a/Examples/Ex032_3D_Printer_Extruder_Support.py b/Examples/Ex032_3D_Printer_Extruder_Support.py index 556a4d1..0b34f50 100644 --- a/Examples/Ex032_3D_Printer_Extruder_Support.py +++ b/Examples/Ex032_3D_Printer_Extruder_Support.py @@ -1,7 +1,6 @@ # 3d printer for mounting hotend to X-carriage inspired by the P3steel Toolson # edition - http://www.thingiverse.com/thing:1054909 import cadquery as cq -from Helpers import show def move_to_center(cqObject, shape): @@ -213,4 +212,4 @@ hole_sep = 0.5*face_right.Area()/main_plate_thickness res = make_aux_holes(res, hole_sep, 2) # show the result -show(res) \ No newline at end of file +show_object(res) \ No newline at end of file diff --git a/Examples/Ex033_Shelled_Cube_Inside_Chamfer_With_Logical_Selector_Operators.py b/Examples/Ex033_Shelled_Cube_Inside_Chamfer_With_Logical_Selector_Operators.py index 3137055..241615b 100644 --- a/Examples/Ex033_Shelled_Cube_Inside_Chamfer_With_Logical_Selector_Operators.py +++ b/Examples/Ex033_Shelled_Cube_Inside_Chamfer_With_Logical_Selector_Operators.py @@ -1,11 +1,10 @@ -# Example using advanced logical operators in string selectors -# to select only the inside edges on a shelled cube to chamfer. +# Example using advanced logical operators in string selectors to select only +# the inside edges on a shelled cube to chamfer. import cadquery as cq -from Helpers import show result = cq.Workplane("XY").box(2, 2, 2).\ faces(">Z").shell(-0.2).\ faces(">Z").edges("not(X or Y)").\ chamfer(0.125) -show(result) +show_object(result) From 6a1aa83760f8998bebd118fa45146156d936b8c9 Mon Sep 17 00:00:00 2001 From: Jeremy Mack Wright Date: Thu, 28 Sep 2017 16:42:14 -0400 Subject: [PATCH 18/19] Moved examples to CadQuery library and adapted the UI to use those. --- Examples/Ex001_Simple_Block.py | 19 -- .../Ex002_Block_With_Bored_Center_Hole.py | 20 -- ...03_Pillow_Block_With_Counterbored_Holes.py | 34 --- Examples/Ex004_Extruded_Cylindrical_Plate.py | 29 --- Examples/Ex005_Extruded_Lines_and_Arcs.py | 32 --- .../Ex006_Moving_the_Current_Working_Point.py | 35 --- Examples/Ex007_Using_Point_Lists.py | 32 --- Examples/Ex008_Polygon_Creation.py | 39 ---- Examples/Ex009_Polylines.py | 40 ---- .../Ex010_Defining_an_Edge_with_a_Spline.py | 27 --- .../Ex011_Mirroring_Symmetric_Geometry.py | 20 -- .../Ex012_Creating_Workplanes_on_Faces.py | 16 -- .../Ex013_Locating_a_Workplane_on_a_Vertex.py | 21 -- Examples/Ex014_Offset_Workplanes.py | 20 -- Examples/Ex015_Rotated_Workplanes.py | 22 -- Examples/Ex016_Using_Construction_Geometry.py | 21 -- .../Ex017_Shelling_to_Create_Thin_Features.py | 14 -- Examples/Ex018_Making_Lofts.py | 20 -- Examples/Ex019_Counter_Sunk_Holes.py | 19 -- .../Ex020_Rounding_Corners_with_Fillets.py | 13 -- Examples/Ex021_Splitting_an_Object.py | 25 -- Examples/Ex022_Classic_OCC_Bottle.py | 19 -- Examples/Ex023_Parametric_Enclosure.py | 77 ------- ...x024_Using_FreeCAD_Solids_as_CQ_Objects.py | 23 -- Examples/Ex025_Revolution.py | 21 -- Examples/Ex026_Lego_Brick.py | 56 ----- Examples/Ex027_Remote_Enclosure.py | 85 ------- Examples/Ex028_Numpy.py | 23 -- Examples/Ex029_Braille.py | 182 --------------- ...arious_Holes_for_Connector_Installation.py | 45 ---- Examples/Ex031_Sweep.py | 40 ---- Examples/Ex032_3D_Printer_Extruder_Support.py | 215 ------------------ ...Chamfer_With_Logical_Selector_Operators.py | 10 - Gui/Command.py | 6 +- InitGui.py | 2 +- Libs/cadquery | 2 +- 36 files changed, 5 insertions(+), 1319 deletions(-) delete mode 100644 Examples/Ex001_Simple_Block.py delete mode 100644 Examples/Ex002_Block_With_Bored_Center_Hole.py delete mode 100644 Examples/Ex003_Pillow_Block_With_Counterbored_Holes.py delete mode 100644 Examples/Ex004_Extruded_Cylindrical_Plate.py delete mode 100644 Examples/Ex005_Extruded_Lines_and_Arcs.py delete mode 100644 Examples/Ex006_Moving_the_Current_Working_Point.py delete mode 100644 Examples/Ex007_Using_Point_Lists.py delete mode 100644 Examples/Ex008_Polygon_Creation.py delete mode 100644 Examples/Ex009_Polylines.py delete mode 100644 Examples/Ex010_Defining_an_Edge_with_a_Spline.py delete mode 100644 Examples/Ex011_Mirroring_Symmetric_Geometry.py delete mode 100644 Examples/Ex012_Creating_Workplanes_on_Faces.py delete mode 100644 Examples/Ex013_Locating_a_Workplane_on_a_Vertex.py delete mode 100644 Examples/Ex014_Offset_Workplanes.py delete mode 100644 Examples/Ex015_Rotated_Workplanes.py delete mode 100644 Examples/Ex016_Using_Construction_Geometry.py delete mode 100644 Examples/Ex017_Shelling_to_Create_Thin_Features.py delete mode 100644 Examples/Ex018_Making_Lofts.py delete mode 100644 Examples/Ex019_Counter_Sunk_Holes.py delete mode 100644 Examples/Ex020_Rounding_Corners_with_Fillets.py delete mode 100644 Examples/Ex021_Splitting_an_Object.py delete mode 100644 Examples/Ex022_Classic_OCC_Bottle.py delete mode 100644 Examples/Ex023_Parametric_Enclosure.py delete mode 100644 Examples/Ex024_Using_FreeCAD_Solids_as_CQ_Objects.py delete mode 100644 Examples/Ex025_Revolution.py delete mode 100644 Examples/Ex026_Lego_Brick.py delete mode 100644 Examples/Ex027_Remote_Enclosure.py delete mode 100644 Examples/Ex028_Numpy.py delete mode 100644 Examples/Ex029_Braille.py delete mode 100644 Examples/Ex030_Panel_with_Various_Holes_for_Connector_Installation.py delete mode 100644 Examples/Ex031_Sweep.py delete mode 100644 Examples/Ex032_3D_Printer_Extruder_Support.py delete mode 100644 Examples/Ex033_Shelled_Cube_Inside_Chamfer_With_Logical_Selector_Operators.py diff --git a/Examples/Ex001_Simple_Block.py b/Examples/Ex001_Simple_Block.py deleted file mode 100644 index f72445f..0000000 --- a/Examples/Ex001_Simple_Block.py +++ /dev/null @@ -1,19 +0,0 @@ -import cadquery as cq - -# These can be modified rather than hardcoding values for each dimension. -length = 80.0 # Length of the block -height = 60.0 # Height of the block -thickness = 10.0 # Thickness of the block - -# Create a 3D block based on the dimension variables above. -# 1. Establishes a workplane that an object can be built on. -# 1a. Uses the X and Y origins to define the workplane, meaning that the -# positive Z direction is "up", and the negative Z direction is "down". -result = cq.Workplane("XY").box(length, height, thickness) - -# The following method is now outdated, but can still be used to display the -# results of the script if you want -# from Helpers import show -# show(result) # Render the result of this script - -show_object(result) diff --git a/Examples/Ex002_Block_With_Bored_Center_Hole.py b/Examples/Ex002_Block_With_Bored_Center_Hole.py deleted file mode 100644 index a825f98..0000000 --- a/Examples/Ex002_Block_With_Bored_Center_Hole.py +++ /dev/null @@ -1,20 +0,0 @@ -import cadquery as cq - -# These can be modified rather than hardcoding values for each dimension. -length = 80.0 # Length of the block -height = 60.0 # Height of the block -thickness = 10.0 # Thickness of the block -center_hole_dia = 22.0 # Diameter of center hole in block - -# Create a block based on the dimensions above and add a 22mm center hole. -# 1. Establishes a workplane that an object can be built on. -# 1a. Uses the X and Y origins to define the workplane, meaning that the -# positive Z direction is "up", and the negative Z direction is "down". -# 2. The highest (max) Z face is selected and a new workplane is created on it. -# 3. The new workplane is used to drill a hole through the block. -# 3a. The hole is automatically centered in the workplane. -result = cq.Workplane("XY").box(length, height, thickness) \ - .faces(">Z").workplane().hole(center_hole_dia) - -# Displays the result of this script -show_object(result) diff --git a/Examples/Ex003_Pillow_Block_With_Counterbored_Holes.py b/Examples/Ex003_Pillow_Block_With_Counterbored_Holes.py deleted file mode 100644 index 50ad422..0000000 --- a/Examples/Ex003_Pillow_Block_With_Counterbored_Holes.py +++ /dev/null @@ -1,34 +0,0 @@ -import cadquery as cq - -# These can be modified rather than hardcoding values for each dimension. -length = 80.0 # Length of the block -height = 60.0 # Height of the block -thickness = 10.0 # Thickness of the block -center_hole_dia = 22.0 # Diameter of center hole in block -cbore_hole_diameter = 2.4 # Bolt shank/threads clearance hole diameter -cbore_diameter = 4.4 # Bolt head pocket hole diameter -cbore_depth = 2.1 # Bolt head pocket hole depth - -# Create a 3D block based on the dimensions above and add a 22mm center hold -# and 4 counterbored holes for bolts -# 1. Establishes a workplane that an object can be built on. -# 1a. Uses the X and Y origins to define the workplane, meaning that the -# positive Z direction is "up", and the negative Z direction is "down". -# 2. The highest(max) Z face is selected and a new workplane is created on it. -# 3. The new workplane is used to drill a hole through the block. -# 3a. The hole is automatically centered in the workplane. -# 4. The highest(max) Z face is selected and a new workplane is created on it. -# 5. A for-construction rectangle is created on the workplane based on the -# block's overall dimensions. -# 5a. For-construction objects are used only to place other geometry, they -# do not show up in the final displayed geometry. -# 6. The vertices of the rectangle (corners) are selected, and a counter-bored -# hole is placed at each of the vertices (all 4 of them at once). -result = cq.Workplane("XY").box(length, height, thickness) \ - .faces(">Z").workplane().hole(center_hole_dia) \ - .faces(">Z").workplane() \ - .rect(length - 8.0, height - 8.0, forConstruction=True) \ - .vertices().cboreHole(cbore_hole_diameter, cbore_diameter, cbore_depth) - -# Displays the result of this script -show_object(result) diff --git a/Examples/Ex004_Extruded_Cylindrical_Plate.py b/Examples/Ex004_Extruded_Cylindrical_Plate.py deleted file mode 100644 index 6ccb2ec..0000000 --- a/Examples/Ex004_Extruded_Cylindrical_Plate.py +++ /dev/null @@ -1,29 +0,0 @@ -import cadquery as cq - -# These can be modified rather than hardcoding values for each dimension. -circle_radius = 50.0 # Radius of the plate -thickness = 13.0 # Thickness of the plate -rectangle_width = 13.0 # Width of rectangular hole in cylindrical plate -rectangle_length = 19.0 # Length of rectangular hole in cylindrical plate - -# Extrude a cylindrical plate with a rectangular hole in the middle of it. -# 1. Establishes a workplane that an object can be built on. -# 1a. Uses the named plane orientation "front" to define the workplane, meaning -# that the positive Z direction is "up", and the negative Z direction -# is "down". -# 2. The 2D geometry for the outer circle is created at the same time as the -# rectangle that will create the hole in the center. -# 2a. The circle and the rectangle will be automatically centered on the -# workplane. -# 2b. Unlike some other functions like the hole(), circle() takes -# a radius and not a diameter. -# 3. The circle and rectangle are extruded together, creating a cylindrical -# plate with a rectangular hole in the center. -# 3a. circle() and rect() could be changed to any other shape to completely -# change the resulting plate and/or the hole in it. -result = cq.Workplane("front").circle(circle_radius) \ - .rect(rectangle_width, rectangle_length) \ - .extrude(thickness) - -# Displays the result of this script -show_object(result) diff --git a/Examples/Ex005_Extruded_Lines_and_Arcs.py b/Examples/Ex005_Extruded_Lines_and_Arcs.py deleted file mode 100644 index 62b51a4..0000000 --- a/Examples/Ex005_Extruded_Lines_and_Arcs.py +++ /dev/null @@ -1,32 +0,0 @@ -import cadquery as cq - -# These can be modified rather than hardcoding values for each dimension. -width = 2.0 # Overall width of the plate -thickness = 0.25 # Thickness of the plate - -# Extrude a plate outline made of lines and an arc -# 1. Establishes a workplane that an object can be built on. -# 1a. Uses the named plane orientation "front" to define the workplane, meaning -# that the positive Z direction is "up", and the negative Z direction -# is "down". -# 2. Draws a line from the origin to an X position of the plate's width. -# 2a. The starting point of a 2D drawing like this will be at the center of the -# workplane (0, 0) unless the moveTo() function moves the starting point. -# 3. A line is drawn from the last position straight up in the Y direction -# 1.0 millimeters. -# 4. An arc is drawn from the last point, through point (1.0, 1.5) which is -# half-way back to the origin in the X direction and 0.5 mm above where -# the last line ended at. The arc then ends at (0.0, 1.0), which is 1.0 mm -# above (in the Y direction) where our first line started from. -# 5. close() is called to automatically draw the last line for us and close -# the sketch so that it can be extruded. -# 5a. Without the close(), the 2D sketch will be left open and the extrude -# operation will provide unpredictable results. -# 6. The 2D sketch is extruded into a solid object of the specified thickness. -result = cq.Workplane("front").lineTo(width, 0) \ - .lineTo(width, 1.0) \ - .threePointArc((1.0, 1.5), (0.0, 1.0)) \ - .close().extrude(thickness) - -# Displays the result of this script -show_object(result) diff --git a/Examples/Ex006_Moving_the_Current_Working_Point.py b/Examples/Ex006_Moving_the_Current_Working_Point.py deleted file mode 100644 index 3c26121..0000000 --- a/Examples/Ex006_Moving_the_Current_Working_Point.py +++ /dev/null @@ -1,35 +0,0 @@ -import cadquery as cq - -# These can be modified rather than hardcoding values for each dimension. -circle_radius = 3.0 # The outside radius of the plate -thickness = 0.25 # The thickness of the plate - -# Make a plate with two cutouts in it by moving the workplane center point -# 1. Establishes a workplane that an object can be built on. -# 1a. Uses the named plane orientation "front" to define the workplane, meaning -# that the positive Z direction is "up", and the negative Z direction -# is "down". -# 1b. The initial workplane center point is the center of the circle, at (0,0). -# 2. A circle is created at the center of the workplane -# 2a. Notice that circle() takes a radius and not a diameter -result = cq.Workplane("front").circle(circle_radius) - -# 3. The work center is movide to (1.5, 0.0) by calling center(). -# 3a. The new center is specified relative to the previous center,not -# relative to global coordinates. -# 4. A 0.5mm x 0.5mm 2D square is drawn inside the circle. -# 4a. The plate has not been extruded yet, only 2D geometry is being created. -result = result.center(1.5, 0.0).rect(0.5, 0.5) - -# 5. The work center is moved again, this time to (-1.5, 1.5). -# 6. A 2D circle is created at that new center with a radius of 0.25mm. -result = result.center(-1.5, 1.5).circle(0.25) - -# 7. All 2D geometry is extruded to the specified thickness of the plate. -# 7a. The small circle and the square are enclosed in the outer circle of the -# plate and so it is assumed that we want them to be cut out of the plate. -# A separate cut operation is not needed. -result = result.extrude(thickness) - -# Displays the result of this script -show_object(result) diff --git a/Examples/Ex007_Using_Point_Lists.py b/Examples/Ex007_Using_Point_Lists.py deleted file mode 100644 index d824c75..0000000 --- a/Examples/Ex007_Using_Point_Lists.py +++ /dev/null @@ -1,32 +0,0 @@ -import cadquery as cq - -# These can be modified rather than hardcoding values for each dimension. -plate_radius = 2.0 # The radius of the plate that will be extruded -hole_pattern_radius = 0.25 # Radius of circle where the holes will be placed -thickness = 0.125 # The thickness of the plate that will be extruded - -# Make a plate with 4 holes in it at various points in a polar arrangement from -# the center of the workplane. -# 1. Establishes a workplane that an object can be built on. -# 1a. Uses the named plane orientation "front" to define the workplane, meaning -# that the positive Z direction is "up", and the negative Z direction -# is "down". -# 2. A 2D circle is drawn that will become though outer profile of the plate. -r = cq.Workplane("front").circle(plate_radius) - -# 3. Push 4 points on the stack that will be used as the center points of the -# holes. -r = r.pushPoints([(1.5, 0), (0, 1.5), (-1.5, 0), (0, -1.5)]) - -# 4. This circle() call will operate on all four points, putting a circle at -# each one. -r = r.circle(hole_pattern_radius) - -# 5. All 2D geometry is extruded to the specified thickness of the plate. -# 5a. The small hole circles are enclosed in the outer circle of the plate and -# so it is assumed that we want them to be cut out of the plate. A -# separate cut operation is not needed. -result = r.extrude(thickness) - -# Displays the result of this script -show_object(result) diff --git a/Examples/Ex008_Polygon_Creation.py b/Examples/Ex008_Polygon_Creation.py deleted file mode 100644 index 2fdecfc..0000000 --- a/Examples/Ex008_Polygon_Creation.py +++ /dev/null @@ -1,39 +0,0 @@ -import cadquery as cq - -# These can be modified rather than hardcoding values for each dimension. -width = 3.0 # The width of the plate -height = 4.0 # The height of the plate -thickness = 0.25 # The thickness of the plate -polygon_sides = 6 # The number of sides that the polygonal holes should have -polygon_dia = 1.0 # The diameter of the circle enclosing the polygon points - -# Create a plate with two polygons cut through it -# 1. Establishes a workplane that an object can be built on. -# 1a. Uses the named plane orientation "front" to define the workplane, meaning -# that the positive Z direction is "up", and the negative Z direction -# is "down". -# 2. A 3D box is created in one box() operation to represent the plate. -# 2a. The box is centered around the origin, which creates a result that may -# be unituitive when the polygon cuts are made. -# 3. 2 points are pushed onto the stack and will be used as centers for the -# polygonal holes. -# 4. The two polygons are created, on for each point, with one call to -# polygon() using the number of sides and the circle that bounds the -# polygon. -# 5. The polygons are cut thru all objects that are in the line of extrusion. -# 5a. A face was not selected, and so the polygons are created on the -# workplane. Since the box was centered around the origin, the polygons end -# up being in the center of the box. This makes them cut from the center to -# the outside along the normal (positive direction). -# 6. The polygons are cut through all objects, starting at the center of the -# box/plate and going "downward" (opposite of normal) direction. Functions -# like cutBlind() assume a positive cut direction, but cutThruAll() assumes -# instead that the cut is made from a max direction and cuts downward from -# that max through all objects. -result = cq.Workplane("front").box(width, height, thickness) \ - .pushPoints([(0, 0.75), (0, -0.75)]) \ - .polygon(polygon_sides, polygon_dia) \ - .cutThruAll() - -# Displays the result of this script -show_object(result) diff --git a/Examples/Ex009_Polylines.py b/Examples/Ex009_Polylines.py deleted file mode 100644 index fc164c6..0000000 --- a/Examples/Ex009_Polylines.py +++ /dev/null @@ -1,40 +0,0 @@ -import cadquery as cq - -# These can be modified rather than hardcoding values for each dimension. -# Define up our Length, Height, Width, and thickness of the beam -(L, H, W, t) = (100.0, 20.0, 20.0, 1.0) - -# Define the points that the polyline will be drawn to/thru -pts = [ - (0, H/2.0), - (W/2.0, H/2.0), - (W/2.0, (H/2.0 - t)), - (t/2.0, (H/2.0-t)), - (t/2.0, (t - H/2.0)), - (W/2.0, (t - H/2.0)), - (W/2.0, H/-2.0), - (0, H/-2.0) -] - -# We generate half of the I-beam outline and then mirror it to create the full -# I-beam. -# 1. Establishes a workplane that an object can be built on. -# 1a. Uses the named plane orientation "front" to define the workplane, meaning -# that the positive Z direction is "up", and the negative Z direction -# is "down". -# 2. moveTo() is used to move the first point from the origin (0, 0) to -# (0, 10.0), with 10.0 being half the height (H/2.0). If this is not done -# the first line will start from the origin, creating an extra segment that -# will cause the extrude to have an invalid shape. -# 3. The polyline function takes a list of points and generates the lines -# through all the points at once. -# 3. Only half of the I-beam profile has been drawn so far. That half is -# mirrored around the Y-axis to create the complete I-beam profile. -# 4. The I-beam profile is extruded to the final length of the beam. -result = cq.Workplane("front").moveTo(0, H/2.0) \ - .polyline(pts) \ - .mirrorY() \ - .extrude(L) - -# Displays the result of this script -show_object(result) diff --git a/Examples/Ex010_Defining_an_Edge_with_a_Spline.py b/Examples/Ex010_Defining_an_Edge_with_a_Spline.py deleted file mode 100644 index 8b4c67c..0000000 --- a/Examples/Ex010_Defining_an_Edge_with_a_Spline.py +++ /dev/null @@ -1,27 +0,0 @@ -import cadquery as cq - -# 1. Establishes a workplane to create the spline on to extrude. -# 1a. Uses the X and Y origins to define the workplane, meaning that the -# positive Z direction is "up", and the negative Z direction is "down". -s = cq.Workplane("XY") - -# The points that the spline will pass through -sPnts = [ - (2.75, 1.5), - (2.5, 1.75), - (2.0, 1.5), - (1.5, 1.0), - (1.0, 1.25), - (0.5, 1.0), - (0, 1.0) -] - -# 2. Generate our plate with the spline feature and make sure it is a -# closed entity -r = s.lineTo(3.0, 0).lineTo(3.0, 1.0).spline(sPnts).close() - -# 3. Extrude to turn the wire into a plate -result = r.extrude(0.5) - -# Displays the result of this script -show_object(result) diff --git a/Examples/Ex011_Mirroring_Symmetric_Geometry.py b/Examples/Ex011_Mirroring_Symmetric_Geometry.py deleted file mode 100644 index 2fc1092..0000000 --- a/Examples/Ex011_Mirroring_Symmetric_Geometry.py +++ /dev/null @@ -1,20 +0,0 @@ -import cadquery as cq - -# 1. Establishes a workplane that an object can be built on. -# 1a. Uses the named plane orientation "front" to define the workplane, meaning -# that the positive Z direction is "up", and the negative Z direction -# is "down". -# 2. A horizontal line is drawn on the workplane with the hLine function. -# 2a. 1.0 is the distance, not coordinate. hLineTo allows using xCoordinate -# not distance. -r = cq.Workplane("front").hLine(1.0) - -# 3. Draw a series of vertical and horizontal lines with the vLine and hLine -# functions. -r = r.vLine(0.5).hLine(-0.25).vLine(-0.25).hLineTo(0.0) - -# 4. Mirror the geometry about the Y axis and extrude it into a 3D object. -result = r.mirrorY().extrude(0.25) - -# Displays the result of this script -show_object(result) diff --git a/Examples/Ex012_Creating_Workplanes_on_Faces.py b/Examples/Ex012_Creating_Workplanes_on_Faces.py deleted file mode 100644 index d73fafe..0000000 --- a/Examples/Ex012_Creating_Workplanes_on_Faces.py +++ /dev/null @@ -1,16 +0,0 @@ -import cadquery as cq - -# 1. Establishes a workplane that an object can be built on. -# 1a. Uses the named plane orientation "front" to define the workplane, meaning -# that the positive Z direction is "up", and the negative Z direction -# is "down". -# 2. Creates a 3D box that will have a hole placed in it later. -result = cq.Workplane("front").box(2, 3, 0.5) - -# 3. Find the top-most face with the >Z max selector. -# 3a. Establish a new workplane to build geometry on. -# 3b. Create a hole down into the box. -result = result.faces(">Z").workplane().hole(0.5) - -# Displays the result of this script -show_object(result) diff --git a/Examples/Ex013_Locating_a_Workplane_on_a_Vertex.py b/Examples/Ex013_Locating_a_Workplane_on_a_Vertex.py deleted file mode 100644 index 197e5c0..0000000 --- a/Examples/Ex013_Locating_a_Workplane_on_a_Vertex.py +++ /dev/null @@ -1,21 +0,0 @@ -import cadquery as cq - -# 1. Establishes a workplane that an object can be built on. -# 1a. Uses the named plane orientation "front" to define the workplane, meaning -# that the positive Z direction is "up", and the negative Z direction -# is "down". -# 2. Creates a 3D box that will have a hole placed in it later. -result = cq.Workplane("front").box(3, 2, 0.5) - -# 3. Select the lower left vertex and make a workplane. -# 3a. The top-most Z face is selected using the >Z selector. -# 3b. The lower-left vertex of the faces is selected with the Z").vertices("Z") \ - .workplane() \ - .transformed(offset=(0, -1.5, 1.0), rotate=(60, 0, 0)) \ - .rect(1.5, 1.5, forConstruction=True).vertices().hole(0.25) - -# Displays the result of this script -show_object(result) diff --git a/Examples/Ex016_Using_Construction_Geometry.py b/Examples/Ex016_Using_Construction_Geometry.py deleted file mode 100644 index 48a4f87..0000000 --- a/Examples/Ex016_Using_Construction_Geometry.py +++ /dev/null @@ -1,21 +0,0 @@ -import cadquery as cq - -# Create a block with holes in each corner of a rectangle on that workplane. -# 1. Establishes a workplane that an object can be built on. -# 1a. Uses the named plane orientation "front" to define the workplane, meaning -# that the positive Z direction is "up", and the negative Z direction -# is "down". -# 2. Creates a plain box to base future geometry on with the box() function. -# 3. Selects the top-most Z face of the box. -# 4. Creates a new workplane to build new geometry on. -# 5. Creates a for-construction rectangle that only exists to use for placing -# other geometry. -# 6. Selects the vertices of the for-construction rectangle. -# 7. Places holes at the center of each selected vertex. -result = cq.Workplane("front").box(2, 2, 0.5)\ - .faces(">Z").workplane() \ - .rect(1.5, 1.5, forConstruction=True).vertices() \ - .hole(0.125) - -# Displays the result of this script -show_object(result) diff --git a/Examples/Ex017_Shelling_to_Create_Thin_Features.py b/Examples/Ex017_Shelling_to_Create_Thin_Features.py deleted file mode 100644 index 91c6823..0000000 --- a/Examples/Ex017_Shelling_to_Create_Thin_Features.py +++ /dev/null @@ -1,14 +0,0 @@ -import cadquery as cq - -# Create a hollow box that's open on both ends with a thin wall. -# 1. Establishes a workplane that an object can be built on. -# 1a. Uses the named plane orientation "front" to define the workplane, meaning -# that the positive Z direction is "up", and the negative Z direction -# is "down". -# 2. Creates a plain box to base future geometry on with the box() function. -# 3. Selects faces with normal in +z direction. -# 4. Create a shell by cutting out the top-most Z face. -result = cq.Workplane("front").box(2, 2, 2).faces("+Z").shell(0.05) - -# Displays the result of this script -show_object(result) diff --git a/Examples/Ex018_Making_Lofts.py b/Examples/Ex018_Making_Lofts.py deleted file mode 100644 index 6e9ad1e..0000000 --- a/Examples/Ex018_Making_Lofts.py +++ /dev/null @@ -1,20 +0,0 @@ -import cadquery as cq - -# Create a lofted section between a rectangle and a circular section. -# 1. Establishes a workplane that an object can be built on. -# 1a. Uses the named plane orientation "front" to define the workplane, meaning -# that the positive Z direction is "up", and the negative Z direction -# is "down". -# 2. Creates a plain box to base future geometry on with the box() function. -# 3. Selects the top-most Z face of the box. -# 4. Draws a 2D circle at the center of the the top-most face of the box. -# 5. Creates a workplane 3 mm above the face the circle was drawn on. -# 6. Draws a 2D circle on the new, offset workplane. -# 7. Creates a loft between the circle and the rectangle. -result = cq.Workplane("front").box(4.0, 4.0, 0.25).faces(">Z") \ - .circle(1.5).workplane(offset=3.0) \ - .rect(0.75, 0.5) \ - .loft(combine=True) - -# Displays the result of this script -show_object(result) diff --git a/Examples/Ex019_Counter_Sunk_Holes.py b/Examples/Ex019_Counter_Sunk_Holes.py deleted file mode 100644 index e75039a..0000000 --- a/Examples/Ex019_Counter_Sunk_Holes.py +++ /dev/null @@ -1,19 +0,0 @@ -import cadquery as cq - -# Create a plate with 4 counter-sunk holes in it. -# 1. Establishes a workplane using an XY object instead of a named plane. -# 2. Creates a plain box to base future geometry on with the box() function. -# 3. Selects the top-most face of the box and established a workplane on that. -# 4. Draws a for-construction rectangle on the workplane which only exists for -# placing other geometry. -# 5. Selects the corner vertices of the rectangle and places a counter-sink -# hole, using each vertex as the center of a hole using the cskHole() -# function. -# 5a. When the depth of the counter-sink hole is set to None, the hole will be -# cut through. -result = cq.Workplane(cq.Plane.XY()).box(4, 2, 0.5).faces(">Z") \ - .workplane().rect(3.5, 1.5, forConstruction=True) \ - .vertices().cskHole(0.125, 0.25, 82.0, depth=None) - -# Displays the result of this script -show_object(result) diff --git a/Examples/Ex020_Rounding_Corners_with_Fillets.py b/Examples/Ex020_Rounding_Corners_with_Fillets.py deleted file mode 100644 index a736970..0000000 --- a/Examples/Ex020_Rounding_Corners_with_Fillets.py +++ /dev/null @@ -1,13 +0,0 @@ -import cadquery as cq - -# Create a plate with 4 rounded corners in the Z-axis. -# 1. Establishes a workplane that an object can be built on. -# 1a. Uses the X and Y origins to define the workplane, meaning that the -# positive Z direction is "up", and the negative Z direction is "down". -# 2. Creates a plain box to base future geometry on with the box() function. -# 3. Selects all edges that are parallel to the Z axis. -# 4. Creates fillets on each of the selected edges with the specified radius. -result = cq.Workplane("XY").box(3, 3, 0.5).edges("|Z").fillet(0.125) - -# Displays the result of this script -show_object(result) diff --git a/Examples/Ex021_Splitting_an_Object.py b/Examples/Ex021_Splitting_an_Object.py deleted file mode 100644 index e903a13..0000000 --- a/Examples/Ex021_Splitting_an_Object.py +++ /dev/null @@ -1,25 +0,0 @@ -import cadquery as cq - -# Create a simple block with a hole through it that we can split. -# 1. Establishes a workplane that an object can be built on. -# 1a. Uses the X and Y origins to define the workplane, meaning that the -# positive Z direction is "up", and the negative Z direction is "down". -# 2. Creates a plain box to base future geometry on with the box() function. -# 3. Selects the top-most face of the box and establishes a workplane on it -# that new geometry can be built on. -# 4. Draws a 2D circle on the new workplane and then uses it to cut a hole -# all the way through the box. -c = cq.Workplane("XY").box(1, 1, 1).faces(">Z").workplane() \ - .circle(0.25).cutThruAll() - -# 5. Selects the face furthest away from the origin in the +Y axis direction. -# 6. Creates an offset workplane that is set in the center of the object. -# 6a. One possible improvement to this script would be to make the dimensions -# of the box variables, and then divide the Y-axis dimension by 2.0 and -# use that to create the offset workplane. -# 7. Uses the embedded workplane to split the object, keeping only the "top" -# portion. -result = c.faces(">Y").workplane(-0.5).split(keepTop=True) - -# Displays the result of this script -show_object(result) diff --git a/Examples/Ex022_Classic_OCC_Bottle.py b/Examples/Ex022_Classic_OCC_Bottle.py deleted file mode 100644 index 5e01873..0000000 --- a/Examples/Ex022_Classic_OCC_Bottle.py +++ /dev/null @@ -1,19 +0,0 @@ -import cadquery as cq - -# Set up the length, width, and thickness -(L, w, t) = (20.0, 6.0, 3.0) -s = cq.Workplane("XY") - -# Draw half the profile of the bottle and extrude it -p = s.center(-L / 2.0, 0).vLine(w / 2.0) \ - .threePointArc((L / 2.0, w / 2.0 + t), (L, w / 2.0)).vLine(-w / 2.0) \ - .mirrorX().extrude(30.0, True) - -# Make the neck -p.faces(">Z").workplane().circle(3.0).extrude(2.0, True) - -# Make a shell -result = p.faces(">Z").shell(0.3) - -# Displays the result of this script -show_object(result) diff --git a/Examples/Ex023_Parametric_Enclosure.py b/Examples/Ex023_Parametric_Enclosure.py deleted file mode 100644 index 3d12863..0000000 --- a/Examples/Ex023_Parametric_Enclosure.py +++ /dev/null @@ -1,77 +0,0 @@ -import cadquery as cq - -# Parameter definitions -p_outerWidth = 100.0 # Outer width of box enclosure -p_outerLength = 150.0 # Outer length of box enclosure -p_outerHeight = 50.0 # Outer height of box enclosure - -p_thickness = 3.0 # Thickness of the box walls -p_sideRadius = 10.0 # Radius for the curves around the sides of the bo -p_topAndBottomRadius = 2.0 # Radius for the curves on the top and bottom edges - -p_screwpostInset = 12.0 # How far in from the edges the screwposts should be -p_screwpostID = 4.0 # Inner diameter of the screwpost holes, should be roughly screw diameter not including threads -p_screwpostOD = 10.0 # Outer diameter of the screwposts. Determines overall thickness of the posts - -p_boreDiameter = 8.0 # Diameter of the counterbore hole, if any -p_boreDepth = 1.0 # Depth of the counterbore hole, if -p_countersinkDiameter = 0.0 # Outer diameter of countersink. Should roughly match the outer diameter of the screw head -p_countersinkAngle = 90.0 # Countersink angle (complete angle between opposite sides, not from center to one side) -p_lipHeight = 1.0 # Height of lip on the underside of the lid. Sits inside the box body for a snug fit. - -# Outer shell -oshell = cq.Workplane("XY").rect(p_outerWidth, p_outerLength) \ - .extrude(p_outerHeight + p_lipHeight) - -# Weird geometry happens if we make the fillets in the wrong order -if p_sideRadius > p_topAndBottomRadius: - oshell.edges("|Z").fillet(p_sideRadius) - oshell.edges("#Z").fillet(p_topAndBottomRadius) -else: - oshell.edges("#Z").fillet(p_topAndBottomRadius) - oshell.edges("|Z").fillet(p_sideRadius) - -# Inner shell -ishell = oshell.faces("Z").workplane(-p_thickness)\ - .rect(POSTWIDTH, POSTLENGTH, forConstruction=True)\ - .vertices() - -for v in postCenters.all(): - v.circle(p_screwpostOD / 2.0).circle(p_screwpostID / 2.0)\ - .extrude((-1.0) * ((p_outerHeight + p_lipHeight) - (2.0 * p_thickness)), True) - -# Split lid into top and bottom parts -(lid, bottom) = box.faces(">Z").workplane(-p_thickness - p_lipHeight).split(keepTop=True, keepBottom=True).all() - -# Translate the lid, and subtract the bottom from it to produce the lid inset -lowerLid = lid.translate((0, 0, -p_lipHeight)) -cutlip = lowerLid.cut(bottom).translate((p_outerWidth + p_thickness, 0, p_thickness - p_outerHeight + p_lipHeight)) - -# Compute centers for counterbore/countersink or counterbore -topOfLidCenters = cutlip.faces(">Z").workplane().rect(POSTWIDTH, POSTLENGTH, forConstruction=True).vertices() - -# Add holes of the desired type -if p_boreDiameter > 0 and p_boreDepth > 0: - topOfLid = topOfLidCenters.cboreHole(p_screwpostID, p_boreDiameter, p_boreDepth, (2.0) * p_thickness) -elif p_countersinkDiameter > 0 and p_countersinkAngle > 0: - topOfLid = topOfLidCenters.cskHole(p_screwpostID, p_countersinkDiameter, p_countersinkAngle, (2.0) * p_thickness) -else: - topOfLid= topOfLidCenters.hole(p_screwpostID, 2.0 * p_thickness) - -# Return the combined result -result = topOfLid.combineSolids(bottom) - -# Displays the result of this script -show_object(result) diff --git a/Examples/Ex024_Using_FreeCAD_Solids_as_CQ_Objects.py b/Examples/Ex024_Using_FreeCAD_Solids_as_CQ_Objects.py deleted file mode 100644 index 7bb1371..0000000 --- a/Examples/Ex024_Using_FreeCAD_Solids_as_CQ_Objects.py +++ /dev/null @@ -1,23 +0,0 @@ -# This example is meant to be used from within the CadQuery module of FreeCAD. -import cadquery -import FreeCAD - -# Create a new document that we can draw our model on -newDoc = FreeCAD.newDocument() - -# Shows a 1x1x1 FreeCAD cube in the display -initialBox = newDoc.addObject("Part::Box", "initialBox") -newDoc.recompute() - -# Make a CQ object -cqBox = cadquery.CQ(cadquery.Solid(initialBox.Shape)) - -# Extrude a peg -newThing = cqBox.faces(">Z").workplane().circle(0.5).extrude(0.25) - -# Add a FreeCAD object to the tree and then store a CQ object in it -nextShape = newDoc.addObject("Part::Feature", "nextShape") -nextShape.Shape = newThing.val().wrapped - -# Rerender the doc to see what the new solid looks like -newDoc.recompute() diff --git a/Examples/Ex025_Revolution.py b/Examples/Ex025_Revolution.py deleted file mode 100644 index c5f3107..0000000 --- a/Examples/Ex025_Revolution.py +++ /dev/null @@ -1,21 +0,0 @@ -import cadquery as cq - -# The dimensions of the model. These can be modified rather than changing the -# shape's code directly. -rectangle_width = 10.0 -rectangle_length = 10.0 -angle_degrees = 360.0 - -# Revolve a cylinder from a rectangle -# Switch comments around in this section to try the revolve operation with different parameters -result = cq.Workplane("XY").rect(rectangle_width, rectangle_length, False).revolve() -#result = cadquery.Workplane("XY").rect(rectangle_width, rectangle_length, False).revolve(angle_degrees) -#result = cadquery.Workplane("XY").rect(rectangle_width, rectangle_length).revolve(angle_degrees,(-5,-5)) -#result = cadquery.Workplane("XY").rect(rectangle_width, rectangle_length).revolve(angle_degrees,(-5, -5),(-5, 5)) -#result = cadquery.Workplane("XY").rect(rectangle_width, rectangle_length).revolve(angle_degrees,(-5,-5),(-5,5), False) - -# Revolve a donut with square walls -#result = cadquery.Workplane("XY").rect(rectangle_width, rectangle_length, True).revolve(angle_degrees, (20, 0), (20, 10)) - -# Displays the result of this script -show_object(result) diff --git a/Examples/Ex026_Lego_Brick.py b/Examples/Ex026_Lego_Brick.py deleted file mode 100644 index 6a6381f..0000000 --- a/Examples/Ex026_Lego_Brick.py +++ /dev/null @@ -1,56 +0,0 @@ -# This script can create any regular rectangular Lego(TM) Brick -import cadquery as cq - -##### -# Inputs -###### -lbumps = 1 # number of bumps long -wbumps = 1 # number of bumps wide -thin = True # True for thin, False for thick - -# -# Lego Brick Constants-- these make a lego brick a lego :) -# -pitch = 8.0 -clearance = 0.1 -bumpDiam = 4.8 -bumpHeight = 1.8 -if thin: - height = 3.2 -else: - height = 9.6 - -t = (pitch - (2 * clearance) - bumpDiam) / 2.0 -postDiam = pitch - t # works out to 6.5 -total_length = lbumps*pitch - 2.0*clearance -total_width = wbumps*pitch - 2.0*clearance - -# make the base -s = cq.Workplane("XY").box(total_length, total_width, height) - -# shell inwards not outwards -s = s.faces("Z").workplane(). \ - rarray(pitch, pitch, lbumps, wbumps, True).circle(bumpDiam / 2.0) \ - .extrude(bumpHeight) - -# add posts on the bottom. posts are different diameter depending on geometry -# solid studs for 1 bump, tubes for multiple, none for 1x1 -tmp = s.faces(" 1 and wbumps > 1: - tmp = tmp.rarray(pitch, pitch, lbumps - 1, wbumps - 1, center=True). \ - circle(postDiam / 2.0).circle(bumpDiam / 2.0).extrude(height - t) -elif lbumps > 1: - tmp = tmp.rarray(pitch, pitch, lbumps - 1, 1, center=True). \ - circle(t).extrude(height - t) -elif wbumps > 1: - tmp = tmp.rarray(pitch, pitch, 1, wbumps - 1, center=True). \ - circle(t).extrude(height - t) -else: - tmp = s - -# Render the solid -show_object(tmp) diff --git a/Examples/Ex027_Remote_Enclosure.py b/Examples/Ex027_Remote_Enclosure.py deleted file mode 100644 index 6825a90..0000000 --- a/Examples/Ex027_Remote_Enclosure.py +++ /dev/null @@ -1,85 +0,0 @@ -import cadquery as cq - -exploded = False # when true, moves the base away from the top so we see -showTop = True # When true, the top is rendered. -showCover = True # When true, the cover is rendered - -width = 2.2 # Nominal x dimension of the part -height = 0.5 # Height from bottom top to the top of the top :P -length = 1.5 # Nominal y dimension of the part -trapezoidFudge = 0.7 # ratio of trapezoid bases. set to 1.0 for cube -xHoleOffset = 0.500 # Holes are distributed symetrically about each axis -yHoleOffset = 0.500 -zFilletRadius = 0.50 # Fillet radius of corners perp. to Z axis. -yFilletRadius = 0.250 # Fillet readius of the top edge of the case -lipHeight = 0.1 # The height of the lip on the inside of the cover -wallThickness = 0.06 # Wall thickness for the case -coverThickness = 0.2 # Thickness of the cover plate -holeRadius = 0.30 # Button hole radius -counterSyncAngle = 100 # Countersink angle. - -xyplane = cq.Workplane("XY") -yzplane = cq.Workplane("YZ") - - -def trapezoid(b1, b2, h): - "Defines a symetrical trapezoid in the XY plane." - - y = h / 2 - x1 = b1 / 2 - x2 = b2 / 2 - return (xyplane.moveTo(-x1, y) - .polyline([(x1, y), - (x2, -y), - (-x2, -y)]).close()) - - -# Defines our base shape: a box with fillets around the vertical edges. -# This has to be a function because we need to create multiple copies of -# the shape. -def base(h): - return (trapezoid(width, width * trapezoidFudge, length) - .extrude(h) - .translate((0, 0, height / 2)) - .edges("Z") - .fillet(zFilletRadius)) - -# start with the base shape -top = (base(height) - # then fillet the top edge - .edges(">Z") - .fillet(yFilletRadius) - # shell the solid from the bottom face, with a .060" wall thickness - .faces("Z") - .workplane() - .pushPoints([(0, 0), - (-xHoleOffset, 0), - (0, -yHoleOffset), - (xHoleOffset, 0), - (0, yHoleOffset)]) - .cskHole(diameter=holeRadius, - cskDiameter=holeRadius * 1.5, - cskAngle=counterSyncAngle)) - -# the bottom cover begins with the same basic shape as the top -cover = (base(coverThickness) - # we need to move it upwards into the parent solid slightly. - .translate((0, 0, -coverThickness + lipHeight)) - # now we subtract the top from the cover. This produces a lip on the - # solid NOTE: that this does not account for mechanical tolerances. - # But it looks cool. - .cut(top) - # try to fillet the inner edge of the cover lip. Technically this - # fillets every edge perpendicular to the Z axis. - .edges("#Z") - .fillet(.020) - .translate((0, 0, -0.5 if exploded else 0))) - -# Conditionally render the parts -if showTop: - show_object(top) -if showCover: - show_object(cover) diff --git a/Examples/Ex028_Numpy.py b/Examples/Ex028_Numpy.py deleted file mode 100644 index df7c8b9..0000000 --- a/Examples/Ex028_Numpy.py +++ /dev/null @@ -1,23 +0,0 @@ -import numpy as np -import cadquery as cq - -# Square side and offset in x and y. -side = 10 -offset = 5 - -# Define the locations that the polyline will be drawn to/thru. -# The polyline is defined as numpy.array so that operations like translation -# of all points are simplified. -pts = np.array([ - (side, 0), - (side, side), - (0, side), - (0, 0), -]) + [offset, offset] - -result = cq.Workplane('XY') \ - .polyline(pts).close().extrude(2) \ - .faces('+Z').workplane().circle(side / 2).extrude(1) - -# Render the solid -show_object(result) diff --git a/Examples/Ex029_Braille.py b/Examples/Ex029_Braille.py deleted file mode 100644 index 85918cf..0000000 --- a/Examples/Ex029_Braille.py +++ /dev/null @@ -1,182 +0,0 @@ -# -*- coding: utf-8 -*- - -from __future__ import unicode_literals, division - -from collections import namedtuple - -import cadquery as cq - -# text_lines is a list of text lines. -# FreeCAD in braille (converted with braille-converter: -# https://github.com/jpaugh/braille-converter.git). -text_lines = ['⠠ ⠋ ⠗ ⠑ ⠑ ⠠ ⠉ ⠠ ⠁ ⠠ ⠙'] -# See http://www.tiresias.org/research/reports/braille_cell.htm for examples -# of braille cell geometry. -horizontal_interdot = 2.5 -vertical_interdot = 2.5 -horizontal_intercell = 6 -vertical_interline = 10 -dot_height = 0.5 -dot_diameter = 1.3 - -base_thickness = 1.5 - -# End of configuration. -BrailleCellGeometry = namedtuple('BrailleCellGeometry', - ('horizontal_interdot', - 'vertical_interdot', - 'intercell', - 'interline', - 'dot_height', - 'dot_diameter')) - - -class Point(object): - def __init__(self, x, y): - self.x = x - self.y = y - - def __add__(self, other): - return Point(self.x + other.x, self.y + other.y) - - def __len__(self): - return 2 - - def __getitem__(self, index): - return (self.x, self.y)[index] - - def __str__(self): - return '({}, {})'.format(self.x, self.y) - - -def brailleToPoints(text, cell_geometry): - # Unicode bit pattern (cf. https://en.wikipedia.org/wiki/Braille_Patterns). - mask1 = 0b00000001 - mask2 = 0b00000010 - mask3 = 0b00000100 - mask4 = 0b00001000 - mask5 = 0b00010000 - mask6 = 0b00100000 - mask7 = 0b01000000 - mask8 = 0b10000000 - masks = (mask1, mask2, mask3, mask4, mask5, mask6, mask7, mask8) - - # Corresponding dot position - w = cell_geometry.horizontal_interdot - h = cell_geometry.vertical_interdot - pos1 = Point(0, 2 * h) - pos2 = Point(0, h) - pos3 = Point(0, 0) - pos4 = Point(w, 2 * h) - pos5 = Point(w, h) - pos6 = Point(w, 0) - pos7 = Point(0, -h) - pos8 = Point(w, -h) - pos = (pos1, pos2, pos3, pos4, pos5, pos6, pos7, pos8) - - # Braille blank pattern (u'\u2800'). - blank = '⠀' - points = [] - # Position of dot1 along the x-axis (horizontal). - character_origin = 0 - for c in text: - for m, p in zip(masks, pos): - delta_to_blank = ord(c) - ord(blank) - if (m & delta_to_blank): - points.append(p + Point(character_origin, 0)) - character_origin += cell_geometry.intercell - return points - - -def get_plate_height(text_lines, cell_geometry): - # cell_geometry.vertical_interdot is also used as space between base - # borders and characters. - return (2 * cell_geometry.vertical_interdot + - 2 * cell_geometry.vertical_interdot + - (len(text_lines) - 1) * cell_geometry.interline) - - -def get_plate_width(text_lines, cell_geometry): - # cell_geometry.horizontal_interdot is also used as space between base - # borders and characters. - max_len = max([len(t) for t in text_lines]) - return (2 * cell_geometry.horizontal_interdot + - cell_geometry.horizontal_interdot + - (max_len - 1) * cell_geometry.intercell) - - -def get_cylinder_radius(cell_geometry): - """Return the radius the cylinder should have - - The cylinder have the same radius as the half-sphere make the dots (the - hidden and the shown part of the dots). - The radius is such that the spherical cap with diameter - cell_geometry.dot_diameter has a height of cell_geometry.dot_height. - """ - h = cell_geometry.dot_height - r = cell_geometry.dot_diameter / 2 - return (r ** 2 + h ** 2) / 2 / h - - -def get_base_plate_thickness(plate_thickness, cell_geometry): - """Return the height on which the half spheres will sit""" - return (plate_thickness + - get_cylinder_radius(cell_geometry) - - cell_geometry.dot_height) - - -def make_base(text_lines, cell_geometry, plate_thickness): - base_width = get_plate_width(text_lines, cell_geometry) - base_height = get_plate_height(text_lines, cell_geometry) - base_thickness = get_base_plate_thickness(plate_thickness, cell_geometry) - base = cq.Workplane('XY').box(base_width, base_height, base_thickness, - centered=(False, False, False)) - return base - - -def make_embossed_plate(text_lines, cell_geometry): - """Make an embossed plate with dots as spherical caps - - Method: - - make a thin plate on which sit cylinders - - fillet the upper edge of the cylinders so to get pseudo half-spheres - - make the union with a thicker plate so that only the sphere caps stay - "visible". - """ - base = make_base(text_lines, cell_geometry, base_thickness) - - dot_pos = [] - base_width = get_plate_width(text_lines, cell_geometry) - base_height = get_plate_height(text_lines, cell_geometry) - y = base_height - 3 * cell_geometry.vertical_interdot - line_start_pos = Point(cell_geometry.horizontal_interdot, y) - for text in text_lines: - dots = brailleToPoints(text, cell_geometry) - dots = [p + line_start_pos for p in dots] - dot_pos += dots - line_start_pos += Point(0, -cell_geometry.interline) - - r = get_cylinder_radius(cell_geometry) - base = base.faces('>Z').vertices('Z').edges() \ - .fillet(r - 0.001) - hidding_box = cq.Workplane('XY').box( - base_width, base_height, base_thickness, centered=(False, False, False)) - result = hidding_box.union(base) - return result - -_cell_geometry = BrailleCellGeometry( - horizontal_interdot, - vertical_interdot, - horizontal_intercell, - vertical_interline, - dot_height, - dot_diameter) - -if base_thickness < get_cylinder_radius(_cell_geometry): - raise ValueError('Base thickness should be at least {}'.format(dot_height)) - -show_object(make_embossed_plate(text_lines, _cell_geometry)) diff --git a/Examples/Ex030_Panel_with_Various_Holes_for_Connector_Installation.py b/Examples/Ex030_Panel_with_Various_Holes_for_Connector_Installation.py deleted file mode 100644 index f428e6b..0000000 --- a/Examples/Ex030_Panel_with_Various_Holes_for_Connector_Installation.py +++ /dev/null @@ -1,45 +0,0 @@ -import cadquery as cq - -# The dimensions of the model. These can be modified rather than changing the -# object's code directly. -width = 400 -height = 500 -thickness = 2 - -# Create a plate with two polygons cut through it -result = cq.Workplane("front").box(width, height, thickness) - -h_sep = 60 -for idx in range(4): - result = result.workplane(offset=1, centerOption='CenterOfBoundBox').center(157,210-idx*h_sep).moveTo(-23.5,0).circle(1.6).moveTo(23.5,0).circle(1.6).moveTo(-17.038896,-5.7).threePointArc((-19.44306,-4.70416),(-20.438896,-2.3)).lineTo(-21.25,2.3).threePointArc((-20.25416,4.70416),(-17.85,5.7)).lineTo(17.85,5.7).threePointArc((20.25416,4.70416),(21.25,2.3)).lineTo(20.438896,-2.3).threePointArc((19.44306,-4.70416),(17.038896,-5.7)).close().cutThruAll() - -for idx in range(4): - result = result.workplane(offset=1, centerOption='CenterOfBoundBox').center(157,-30-idx*h_sep).moveTo(-16.65,0).circle(1.6).moveTo(16.65,0).circle(1.6).moveTo(-10.1889,-5.7).threePointArc((-12.59306,-4.70416),(-13.5889,-2.3)).lineTo(-14.4,2.3).threePointArc((-13.40416,4.70416),(-11,5.7)).lineTo(11,5.7).threePointArc((13.40416,4.70416),(14.4,2.3)).lineTo(13.5889,-2.3).threePointArc((12.59306,-4.70416),(10.1889,-5.7)).close().cutThruAll() - -h_sep4DB9 = 30 -for idx in range(8): - result = result.workplane(offset=1, centerOption='CenterOfBoundBox').center(91,225-idx*h_sep4DB9).moveTo(-12.5,0).circle(1.6).moveTo(12.5,0).circle(1.6).moveTo(-6.038896,-5.7).threePointArc((-8.44306,-4.70416),(-9.438896,-2.3)).lineTo(-10.25,2.3).threePointArc((-9.25416,4.70416),(-6.85,5.7)).lineTo(6.85,5.7).threePointArc((9.25416,4.70416),(10.25,2.3)).lineTo(9.438896,-2.3).threePointArc((8.44306,-4.70416),(6.038896,-5.7)).close().cutThruAll() - -for idx in range(4): - result = result.workplane(offset=1, centerOption='CenterOfBoundBox').center(25,210-idx*h_sep).moveTo(-23.5,0).circle(1.6).moveTo(23.5,0).circle(1.6).moveTo(-17.038896,-5.7).threePointArc((-19.44306,-4.70416),(-20.438896,-2.3)).lineTo(-21.25,2.3).threePointArc((-20.25416,4.70416),(-17.85,5.7)).lineTo(17.85,5.7).threePointArc((20.25416,4.70416),(21.25,2.3)).lineTo(20.438896,-2.3).threePointArc((19.44306,-4.70416),(17.038896,-5.7)).close().cutThruAll() - -for idx in range(4): - result = result.workplane(offset=1, centerOption='CenterOfBoundBox').center(25,-30-idx*h_sep).moveTo(-16.65,0).circle(1.6).moveTo(16.65,0).circle(1.6).moveTo(-10.1889,-5.7).threePointArc((-12.59306,-4.70416),(-13.5889,-2.3)).lineTo(-14.4,2.3).threePointArc((-13.40416,4.70416),(-11,5.7)).lineTo(11,5.7).threePointArc((13.40416,4.70416),(14.4,2.3)).lineTo(13.5889,-2.3).threePointArc((12.59306,-4.70416),(10.1889,-5.7)).close().cutThruAll() - -for idx in range(8): - result = result.workplane(offset=1, centerOption='CenterOfBoundBox').center(-41,225-idx*h_sep4DB9).moveTo(-12.5,0).circle(1.6).moveTo(12.5,0).circle(1.6).moveTo(-6.038896,-5.7).threePointArc((-8.44306,-4.70416),(-9.438896,-2.3)).lineTo(-10.25,2.3).threePointArc((-9.25416,4.70416),(-6.85,5.7)).lineTo(6.85,5.7).threePointArc((9.25416,4.70416),(10.25,2.3)).lineTo(9.438896,-2.3).threePointArc((8.44306,-4.70416),(6.038896,-5.7)).close().cutThruAll() - -for idx in range(4): - result = result.workplane(offset=1, centerOption='CenterOfBoundBox').center(-107,210-idx*h_sep).moveTo(-23.5,0).circle(1.6).moveTo(23.5,0).circle(1.6).moveTo(-17.038896,-5.7).threePointArc((-19.44306,-4.70416),(-20.438896,-2.3)).lineTo(-21.25,2.3).threePointArc((-20.25416,4.70416),(-17.85,5.7)).lineTo(17.85,5.7).threePointArc((20.25416,4.70416),(21.25,2.3)).lineTo(20.438896,-2.3).threePointArc((19.44306,-4.70416),(17.038896,-5.7)).close().cutThruAll() - -for idx in range(4): - result = result.workplane(offset=1, centerOption='CenterOfBoundBox').center(-107,-30-idx*h_sep).circle(14).rect(24.7487,24.7487, forConstruction=True).vertices().hole(3.2).cutThruAll() - -for idx in range(8): - result = result.workplane(offset=1, centerOption='CenterOfBoundBox').center(-173,225-idx*h_sep4DB9).moveTo(-12.5,0).circle(1.6).moveTo(12.5,0).circle(1.6).moveTo(-6.038896,-5.7).threePointArc((-8.44306,-4.70416),(-9.438896,-2.3)).lineTo(-10.25,2.3).threePointArc((-9.25416,4.70416),(-6.85,5.7)).lineTo(6.85,5.7).threePointArc((9.25416,4.70416),(10.25,2.3)).lineTo(9.438896,-2.3).threePointArc((8.44306,-4.70416),(6.038896,-5.7)).close().cutThruAll() - -for idx in range(4): - result = result.workplane(offset=1, centerOption='CenterOfBoundBox').center(-173,-30-idx*h_sep).moveTo(-2.9176,-5.3).threePointArc((-6.05,0),(-2.9176,5.3)).lineTo(2.9176,5.3).threePointArc((6.05,0),(2.9176,-5.3)).close().cutThruAll() - -# Render the solid -show_object(result) diff --git a/Examples/Ex031_Sweep.py b/Examples/Ex031_Sweep.py deleted file mode 100644 index 7c5ebdd..0000000 --- a/Examples/Ex031_Sweep.py +++ /dev/null @@ -1,40 +0,0 @@ -import cadquery as cq - -# Points we will use to create spline and polyline paths to sweep over -pts = [ - (0, 1), - (1, 2), - (2, 4) -] - -# Spline path generated from our list of points (tuples) -path = cq.Workplane("XZ").spline(pts) - -# Sweep a circle with a diameter of 1.0 units along the spline path we just created -defaultSweep = cq.Workplane("XY").circle(1.0).sweep(path) - -# Sweep defaults to making a solid and not generating a Frenet solid. Setting Frenet to True helps prevent creep in -# the orientation of the profile as it is being swept -frenetShell = cq.Workplane("XY").circle(1.0).sweep(path, makeSolid=False, isFrenet=True) - -# We can sweep shapes other than circles -defaultRect = cq.Workplane("XY").rect(1.0, 1.0).sweep(path) - -# Switch to a polyline path, but have it use the same points as the spline -path = cq.Workplane("XZ").polyline(pts) - -# Using a polyline path leads to the resulting solid having segments rather than a single swept outer face -plineSweep = cq.Workplane("XY").circle(1.0).sweep(path) - -# Switch to an arc for the path -path = cq.Workplane("XZ").threePointArc((1.0, 1.5), (0.0, 1.0)) - -# Use a smaller circle section so that the resulting solid looks a little nicer -arcSweep = cq.Workplane("XY").circle(0.5).sweep(path) - -# Translate the resulting solids so that they do not overlap and display them left to right -show_object(defaultSweep) -show_object(frenetShell.translate((5, 0, 0))) -show_object(defaultRect.translate((10, 0, 0))) -show_object(plineSweep.translate((15, 0, 0))) -show_object(arcSweep.translate((20, 0, 0))) \ No newline at end of file diff --git a/Examples/Ex032_3D_Printer_Extruder_Support.py b/Examples/Ex032_3D_Printer_Extruder_Support.py deleted file mode 100644 index 0b34f50..0000000 --- a/Examples/Ex032_3D_Printer_Extruder_Support.py +++ /dev/null @@ -1,215 +0,0 @@ -# 3d printer for mounting hotend to X-carriage inspired by the P3steel Toolson -# edition - http://www.thingiverse.com/thing:1054909 -import cadquery as cq - - -def move_to_center(cqObject, shape): - ''' - Moves the origin of the current Workplane to the center of a given - geometry object - ''' - - # transform to workplane local coordinates - shape_center = shape.Center().sub(cqObject.plane.origin) - - # project onto plane using dot product - x_offset = shape_center.dot(cqObject.plane.xDir) - y_offset = shape_center.dot(cqObject.plane.yDir) - - return cqObject.center(x_offset, y_offset) - -# Parameter definitions - -main_plate_size_y = 67 # size of the main plate in y direction -main_plate_size_x = 50. # size of the main plate in x direction -main_plate_thickness = 10. # thickness of the main plate - -wing_size_x = 10. # size of the side wing supporting the bridge in x direction -wing_size_y = 10. # size of the side wing supporting the bridge in y direction - -bridge_depth = 35. # depth of the bridge - -support_depth = 18. # depth of the bridge support - -cutout_depth = 15. # depth of the hotend cutout -cutout_rad = 8. # radius of the cutout (cf groove mount sizes of E3D hotends) -cutout_offset = 2. # delta radius of the second cutout (cf groove mount sizes of E3D hotends) - -extruder_hole_spacing = 50. # spacing of the extruder mounting holes (Wade's geared extruder) - -m4_predrill = 3.7 # hole diameter for m4 tapping -m3_predrill = 2.5 # hole diameter for m3 tapping -m3_cbore = 5. # counterbore size for m3 socket screw - -mounting_hole_spacing = 28. # spacing of the mounting holes for attaching to x-carriage - -aux_hole_depth = 6. # depth of the auxiliary holes at the sides of the object -aux_hole_spacing = 5. # spacing of the auxiliary holes within a group -aux_hole_N = 2 # number of the auxiliary hole per group - -# make the main plate -res = cq.Workplane('front').box(main_plate_size_x, - main_plate_size_y, - main_plate_thickness) - - -def add_wing(obj, sign=1): - ''' - Adds a wing to the main plate, defined to keep the code DRY - ''' - obj = obj.workplane()\ - .hLine(sign*wing_size_x)\ - .vLine(-wing_size_y)\ - .line(-sign*wing_size_x, -2*wing_size_y)\ - .close().extrude(main_plate_thickness) - return obj - -# add wings - -# add right wing -res = res.faces('XY') -res = add_wing(res) - -# store sides of the plate for further reuse, their area is used later on to calculate "optimum" spacing of the aux hole groups -face_right = res.faces('>X[1]').val() -face_left = res.faces('>X[-2]').val() - -# add left wing -res = res.faces('Y').vertices('Z') # select top face -e = wp.edges('>Y') # select most extreme edge in Y direction - -bridge_length = e.val().Length() # the width of the bridge equals to the length of the selected edge - -# draw the bridge x-section and extrude -res = e.vertices('Z[1]') # take all faces in Z direction and select the middle one; note the new selector syntax -edge = faces.edges('>Y') # select the top edge of this face... -res = move_to_center(faces.workplane(), edge.val()).\ - transformed(rotate=(0, 90, 0)) # ...and make a workplane that is centered in this edge and oriented along X direction - -res = res.vLine(-support_depth).\ - line(-support_depth, support_depth).\ - close() # draw a triangle - -res = res.extrude(main_plate_size_x/2, both=True, clean=True) # extrude the triangle, now the bridge has a nice support making it much more stiff - -# Start cutting out a slot for hotend mounting -face = res.faces('>Y') # select the most extreme face in Y direction, i.e. top ot the "bridge" -res = move_to_center(face.workplane(), face.edges('>Z').val()) # shift the workplane to the center of the most extreme edge of the bridge - - -def make_slot(obj, depth=None): - ''' - Utility function that makes a slot for hotend mounting - ''' - obj = obj.moveTo(cutout_rad, -cutout_depth).\ - threePointArc((0, -cutout_depth-cutout_rad), - (-cutout_rad, -cutout_depth)).\ - vLineTo(0).hLineTo(cutout_rad).close() - - if depth is None: - obj = obj.cutThruAll() - else: - obj = obj.cutBlind(depth) - - return obj - -res = make_slot(res, None) # make the smaller slot - -cutout_rad += cutout_offset # increase the cutout radius... -res = make_slot(res.end().end(), -main_plate_thickness/2) # ...and make a slightly larger slot - -res = res.end().moveTo(0, 0) \ - .pushPoints([(-extruder_hole_spacing/2, -cutout_depth), (extruder_hole_spacing/2, -cutout_depth)]) \ - .hole(m4_predrill) # add extruder mounting holes at the top of the bridge - - -# make additional slot in the bridge support which allows the hotend's radiator to fit -cutout_rad += 3*cutout_offset -res = make_slot(res.end().moveTo(0, 0).workplane(offset=-main_plate_thickness)) - -# add reinforcement holes -cutout_rad -= 2*cutout_offset -res = res.faces('>Z').workplane().\ - pushPoints([(-cutout_rad, -main_plate_thickness/4), - (cutout_rad, -main_plate_thickness/4)]).\ - hole(m3_predrill) - -# add aux holes on the front face -res = res.moveTo(-main_plate_size_x/2., 0).workplane().rarray(aux_hole_spacing, 1, aux_hole_N, 1) \ - .hole(m3_predrill, depth=aux_hole_depth) -res = res.moveTo(main_plate_size_x, 0).workplane().rarray(aux_hole_spacing, 1, aux_hole_N, 1) \ - .hole(m3_predrill, depth=aux_hole_depth) - -# make a hexagonal cutout -res = res.faces('>Z[1]') -res = res.workplane(offset=bridge_depth). \ - transformed(rotate=(0, 0, 90)). \ - polygon(6, 30).cutThruAll() - -# make 4 mounting holes with cbores -res = res.end().moveTo(0, 0). \ - rect(mounting_hole_spacing, - mounting_hole_spacing, forConstruction=True) - -res = res.vertices(). \ - cboreHole(m3_predrill, - m3_cbore, - bridge_depth+m3_cbore/2) - -# make cutout and holes for mounting of the fan -res = res.transformed(rotate=(0, 0, 45)). \ - rect(35, 35).cutBlind(-bridge_depth).end(). \ - rect(25, 25, forConstruction=True).vertices().hole(m3_predrill) - - -def make_aux_holes(workplane, holes_span, N_hole_groups=3): - ''' - Utility function for creation of auxiliary mouting holes at the sides of the object - ''' - res = workplane.moveTo(-holes_span/2).workplane().rarray(aux_hole_spacing, 1, aux_hole_N, 1) \ - .hole(m3_predrill, depth=aux_hole_depth) - for i in range(N_hole_groups-1): - res = res.moveTo(holes_span/(N_hole_groups-1.)).workplane().rarray(aux_hole_spacing, 1, aux_hole_N, 1) \ - .hole(m3_predrill, depth=aux_hole_depth) - - return res - -# make aux holes at the bottom -res = res.faces('X').workplane().transformed((90, 0, 0)) -res = make_aux_holes(res, main_plate_size_x*2/3., 3) - -# make aux holes at the side (@main plate) -res = res.faces('|X').edges('X') -res = res.workplane() -res = move_to_center(res, face_right) -res = res.transformed((90, 0, 0)) -hole_sep = 0.5*face_right.Area()/main_plate_thickness -res = make_aux_holes(res, hole_sep, 2) - -# make aux holes at the side (@main plate) -res = res.faces('|X').edges('Z").shell(-0.2).\ - faces(">Z").edges("not(X or Y)").\ - chamfer(0.125) - -show_object(result) diff --git a/Gui/Command.py b/Gui/Command.py index 002742f..4a558eb 100644 --- a/Gui/Command.py +++ b/Gui/Command.py @@ -101,7 +101,7 @@ class CadQueryExecuteExample: # Start off defaulting to the Examples directory module_base_path = module_locator.module_path() - exs_dir_path = os.path.join(module_base_path, 'Examples') + exs_dir_path = os.path.join(module_base_path, 'Libs/cadquery/examples/FreeCAD') # Append this script's directory to sys.path sys.path.append(os.path.dirname(exs_dir_path)) @@ -247,7 +247,7 @@ class CadQueryOpenScript: if self.previousPath is None: # Start off defaulting to the Examples directory module_base_path = module_locator.module_path() - exs_dir_path = os.path.join(module_base_path, 'Examples') + exs_dir_path = os.path.join(module_base_path, 'Libs/cadquery/examples/FreeCAD') self.previousPath = exs_dir_path @@ -288,7 +288,7 @@ class CadQuerySaveScript: # If the code pane doesn't have a filename, we need to present the save as dialog if len(cqCodePane.file.path) == 0 or os.path.basename(cqCodePane.file.path) == 'script_template.py' \ - or os.path.split(cqCodePane.file.path)[-2].endswith('Examples'): + or os.path.split(cqCodePane.file.path)[0].endswith('FreeCAD'): FreeCAD.Console.PrintError("You cannot save over a blank file, example file or template file.\r\n") CadQuerySaveAsScript().Activated() diff --git a/InitGui.py b/InitGui.py index 25425b9..5f8468e 100644 --- a/InitGui.py +++ b/InitGui.py @@ -99,7 +99,7 @@ class CadQueryWorkbench (Workbench): # List all of the example files in an order that makes sense module_base_path = module_locator.module_path() - exs_dir_path = os.path.join(module_base_path, 'Examples') + exs_dir_path = os.path.join(module_base_path, 'Libs/cadquery/examples/FreeCAD') dirs = os.listdir(exs_dir_path) dirs.sort() diff --git a/Libs/cadquery b/Libs/cadquery index 654f04c..0a107cf 160000 --- a/Libs/cadquery +++ b/Libs/cadquery @@ -1 +1 @@ -Subproject commit 654f04c2e7e21fb1ebefcca519da86bcb342ee83 +Subproject commit 0a107cf9350c779c20e87342213021811113e244 From 8999380fdf76208b83e110a62279846472c1645f Mon Sep 17 00:00:00 2001 From: Jeremy Mack Wright Date: Wed, 4 Oct 2017 06:19:28 -0400 Subject: [PATCH 19/19] CadQuery library update. --- Libs/cadquery | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Libs/cadquery b/Libs/cadquery index 0a107cf..d1fb644 160000 --- a/Libs/cadquery +++ b/Libs/cadquery @@ -1 +1 @@ -Subproject commit 0a107cf9350c779c20e87342213021811113e244 +Subproject commit d1fb644aa45705c91067a74d3d37845dbc0faef9