From 4c06752c39f5b7926b84784bdf7d923c48c15b05 Mon Sep 17 00:00:00 2001 From: Jeremy Mack Wright Date: Sun, 23 Jul 2017 00:22:57 -0400 Subject: [PATCH] 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())