|
14 | 14 | import subprocess |
15 | 15 | import tempfile |
16 | 16 |
|
17 | | -openscad_builtins = [ |
18 | | - # 2D primitives |
19 | | - {'name': 'polygon', 'args': ['points', 'paths'], 'kwargs': []} , |
20 | | - {'name': 'circle', 'args': [], 'kwargs': ['r', 'd', 'segments']} , |
21 | | - {'name': 'square', 'args': [], 'kwargs': ['size', 'center']} , |
22 | | - |
23 | | - # 3D primitives |
24 | | - {'name': 'sphere', 'args': [], 'kwargs': ['r', 'd', 'segments']} , |
25 | | - {'name': 'cube', 'args': [], 'kwargs': ['size', 'center']} , |
26 | | - {'name': 'cylinder', 'args': [], 'kwargs': ['r','h','r1', 'r2', 'd', 'd1', 'd2', 'center', 'segments']} , |
27 | | - {'name': 'polyhedron', 'args': ['points', 'faces' ], 'kwargs': ['convexity', 'triangles']} , |
28 | | - |
29 | | - # Boolean operations |
30 | | - {'name': 'union', 'args': [], 'kwargs': []} , |
31 | | - {'name': 'intersection', 'args': [], 'kwargs': []} , |
32 | | - {'name': 'difference', 'args': [], 'kwargs': []} , |
33 | | - {'name': 'hole', 'args': [], 'kwargs': []} , |
34 | | - {'name': 'part', 'args': [], 'kwargs': []} , |
35 | | - |
36 | | - # Transforms |
37 | | - {'name': 'translate', 'args': [], 'kwargs': ['v']} , |
38 | | - {'name': 'scale', 'args': [], 'kwargs': ['v']} , |
39 | | - {'name': 'rotate', 'args': [], 'kwargs': ['a', 'v']} , |
40 | | - {'name': 'mirror', 'args': ['v'], 'kwargs': []}, |
41 | | - {'name': 'multmatrix', 'args': ['m'], 'kwargs': []}, |
42 | | - {'name': 'color', 'args': ['c'], 'kwargs': []}, |
43 | | - {'name': 'minkowski', 'args': [], 'kwargs': []}, |
44 | | - {'name': 'hull', 'args': [], 'kwargs': []}, |
45 | | - {'name': 'render', 'args': [], 'kwargs': ['convexity']}, |
46 | | - |
47 | | - # 2D to 3D transitions |
48 | | - # FIXME: linear_extrude now has a scale parameter as of OpenSCAD 13.06 -ETJ 20 Jan 2014 |
49 | | - # Also: Check release notes for any other changes to the language, here: |
50 | | - # https://github.com/openscad/openscad/blob/master/RELEASE_NOTES |
51 | | - # Add Colors as here: http://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Transformations |
52 | | - {'name': 'linear_extrude', 'args': [], 'kwargs': ['height', 'center', 'convexity', 'twist','slices']} , |
53 | | - {'name': 'rotate_extrude', 'args': [], 'kwargs': ['convexity', 'segments']} , |
54 | | - {'name': 'dxf_linear_extrude', 'args': ['file'],'kwargs': ['layer', 'height', 'center', 'convexity', 'twist', 'slices']} , |
55 | | - {'name': 'projection', 'args': [], 'kwargs': ['cut']} , |
56 | | - {'name': 'surface', 'args': ['file'], 'kwargs': ['center','convexity','invert']} , |
57 | | - {'name': 'text', 'args': ['text'], 'kwargs': ['size','font','halign','valign','spacing','direction','language','script','segments']} , |
58 | | - |
59 | | - #Child/ren |
60 | | - {'name': 'child', 'args': [], 'kwargs': ['index', 'vector', 'range']} , |
61 | | - {'name': 'children', 'args': [], 'kwargs': ['index', 'vector', 'range']} , |
62 | | - |
63 | | - # FIXME: support 'resize' as well -ETJ 20 Jan 2014 |
64 | | - |
65 | | - # Import/export |
66 | | - {'name': 'import_stl', 'args': ['file'], 'kwargs': ['layer', 'origin']} , |
67 | | - {'name': 'import_dxf', 'args': ['file'], 'kwargs': ['layer', 'origin']}, |
68 | | - {'name': 'import_', 'args': ['file'], 'kwargs': ['layer', 'origin']}, |
69 | | - |
70 | | - |
71 | | - # Modifiers; These are implemented by calling e.g. |
72 | | - # obj.set_modifier( '*') or |
73 | | - # obj.set_modifier('disable') |
74 | | - # disable(obj) |
75 | | - # on an existing object. |
76 | | - # {'name': 'background', 'args': [], 'kwargs': []}, # %{} |
77 | | - # {'name': 'debug', 'args': [], 'kwargs': []} , # #{} |
78 | | - # {'name': 'root', 'args': [], 'kwargs': []} , # !{} |
79 | | - # {'name': 'disable', 'args': [], 'kwargs': []} , # *{} |
80 | | - |
81 | | - {'name': 'intersection_for', 'args': ['n'], 'kwargs': []} , # e.g.: intersection_for(n=[1..6]){} |
82 | | - |
83 | | - # Not really needed for Python. Also needs a **args argument so it accepts anything |
84 | | - {'name': 'assign', 'args': [], 'kwargs': []} |
85 | | -] |
86 | | - |
87 | | -# Some functions need custom code in them; put that code here |
88 | | -builtin_literals = { |
89 | | - 'polygon': '''class polygon(OpenSCADObject): |
90 | | - def __init__(self, points, paths=None): |
91 | | - if not paths: |
92 | | - paths = [ list(range(len(points)))] |
93 | | - OpenSCADObject.__init__(self, 'polygon', {'points':points, 'paths': paths}) |
94 | | - |
95 | | - ''', |
96 | | - 'hole': '''class hole(OpenSCADObject): |
97 | | - def __init__(self): |
98 | | - OpenSCADObject.__init__(self, 'hole', {}) |
99 | | - self.set_hole(True) |
100 | | - |
101 | | - ''', |
102 | | - 'part': '''class part(OpenSCADObject): |
103 | | - def __init__(self): |
104 | | - OpenSCADObject.__init__(self, 'part', {}) |
105 | | - self.set_part_root(True) |
106 | | - ''', |
107 | | - # Import, import_dxf, and import_stl all resolve to the same OpenSCAD |
108 | | - # keyword, 'import' |
109 | | - 'import_': '''class import_(OpenSCADObject): |
110 | | - def __init__(self, file, origin=(0,0), layer=None): |
111 | | - OpenSCADObject.__init__(self, 'import', {'file':file, 'origin':origin, 'layer':layer}) |
112 | | - ''', |
113 | | - 'import_dxf': '''class import_dxf(OpenSCADObject): |
114 | | - def __init__(self, file, origin=(0,0), layer=None): |
115 | | - OpenSCADObject.__init__(self, 'import', {'file':file, 'origin':origin, 'layer':layer}) |
116 | | - ''', |
117 | | - 'import_stl': '''class import_stl(OpenSCADObject): |
118 | | - def __init__(self, file, origin=(0,0), layer=None): |
119 | | - OpenSCADObject.__init__(self, 'import', {'file':file, 'origin':origin, 'layer':layer}) |
120 | | - ''' |
121 | 17 |
|
122 | | -} |
| 18 | + |
123 | 19 | # These are features added to SolidPython but NOT in OpenSCAD. |
124 | 20 | # Mark them for special treatment |
125 | 21 | non_rendered_classes = ['hole', 'part'] |
@@ -815,12 +711,219 @@ def parse_scad_callables(scad_code_str): |
815 | 711 | return callables |
816 | 712 |
|
817 | 713 |
|
818 | | -# Dynamically add all builtins to this namespace on import |
819 | | -for sym_dict in openscad_builtins: |
820 | | - # entries in 'builtin_literals' override the entries in 'openscad_builtins' |
821 | | - if sym_dict['name'] in builtin_literals: |
822 | | - class_str = builtin_literals[sym_dict['name']] |
823 | | - else: |
824 | | - class_str = new_openscad_class_str(sym_dict['name'], sym_dict['args'], sym_dict['kwargs']) |
| 714 | +# =============================== |
| 715 | +# Classes for OpenSCAD builtins = |
| 716 | +# =============================== |
| 717 | +class polygon(OpenSCADObject): |
| 718 | + def __init__(self, points, paths=None): |
| 719 | + if not paths: |
| 720 | + paths = [list(range(len(points)))] |
| 721 | + OpenSCADObject.__init__(self, 'polygon', |
| 722 | + {'points': points, 'paths': paths}) |
| 723 | + |
| 724 | + |
| 725 | +class circle(OpenSCADObject): |
| 726 | + def __init__(self, r=None, d=None, segments=None): |
| 727 | + OpenSCADObject.__init__(self, 'circle', |
| 728 | + {'r': r, 'd': d, 'segments': segments}) |
| 729 | + |
| 730 | + |
| 731 | +class square(OpenSCADObject): |
| 732 | + def __init__(self, size=None, center=None): |
| 733 | + OpenSCADObject.__init__(self, 'square', |
| 734 | + {'size': size, 'center': center}) |
| 735 | + |
| 736 | + |
| 737 | +class sphere(OpenSCADObject): |
| 738 | + def __init__(self, r=None, d=None, segments=None): |
| 739 | + OpenSCADObject.__init__(self, 'sphere', |
| 740 | + {'r': r, 'd': d, 'segments': segments}) |
| 741 | + |
| 742 | + |
| 743 | +class cube(OpenSCADObject): |
| 744 | + def __init__(self, size=None, center=None): |
| 745 | + OpenSCADObject.__init__(self, 'cube', |
| 746 | + {'size': size, 'center': center}) |
| 747 | + |
| 748 | + |
| 749 | +class cylinder(OpenSCADObject): |
| 750 | + def __init__(self, r=None, h=None, r1=None, r2=None, d=None, d1=None, |
| 751 | + d2=None, center=None, segments=None): |
| 752 | + OpenSCADObject.__init__(self, 'cylinder', |
| 753 | + {'r': r, 'h': h, 'r1': r1, 'r2': r2, 'd': d, |
| 754 | + 'd1': d1, 'd2': d2, 'center': center, |
| 755 | + 'segments': segments}) |
| 756 | + |
| 757 | + |
| 758 | +class polyhedron(OpenSCADObject): |
| 759 | + def __init__(self, points, faces, convexity=None, triangles=None): |
| 760 | + OpenSCADObject.__init__(self, 'polyhedron', |
| 761 | + {'points': points, 'faces': faces, |
| 762 | + 'convexity': convexity, |
| 763 | + 'triangles': triangles}) |
| 764 | + |
| 765 | + |
| 766 | +class union(OpenSCADObject): |
| 767 | + def __init__(self): |
| 768 | + OpenSCADObject.__init__(self, 'union', {}) |
| 769 | + |
| 770 | + |
| 771 | +class intersection(OpenSCADObject): |
| 772 | + def __init__(self): |
| 773 | + OpenSCADObject.__init__(self, 'intersection', {}) |
| 774 | + |
| 775 | + |
| 776 | +class difference(OpenSCADObject): |
| 777 | + def __init__(self): |
| 778 | + OpenSCADObject.__init__(self, 'difference', {}) |
| 779 | + |
| 780 | + |
| 781 | +class hole(OpenSCADObject): |
| 782 | + def __init__(self): |
| 783 | + OpenSCADObject.__init__(self, 'hole', {}) |
| 784 | + self.set_hole(True) |
| 785 | + |
| 786 | + |
| 787 | +class part(OpenSCADObject): |
| 788 | + def __init__(self): |
| 789 | + OpenSCADObject.__init__(self, 'part', {}) |
| 790 | + self.set_part_root(True) |
| 791 | + |
| 792 | + |
| 793 | +class translate(OpenSCADObject): |
| 794 | + def __init__(self, v=None): |
| 795 | + OpenSCADObject.__init__(self, 'translate', {'v': v}) |
| 796 | + |
825 | 797 |
|
826 | | - exec(class_str) |
| 798 | +class scale(OpenSCADObject): |
| 799 | + def __init__(self, v=None): |
| 800 | + OpenSCADObject.__init__(self, 'scale', {'v': v}) |
| 801 | + |
| 802 | + |
| 803 | +class rotate(OpenSCADObject): |
| 804 | + def __init__(self, a=None, v=None): |
| 805 | + OpenSCADObject.__init__(self, 'rotate', {'a': a, 'v': v}) |
| 806 | + |
| 807 | + |
| 808 | +class mirror(OpenSCADObject): |
| 809 | + def __init__(self, v): |
| 810 | + OpenSCADObject.__init__(self, 'mirror', {'v': v}) |
| 811 | + |
| 812 | + |
| 813 | +class multmatrix(OpenSCADObject): |
| 814 | + def __init__(self, m): |
| 815 | + OpenSCADObject.__init__(self, 'multmatrix', {'m': m}) |
| 816 | + |
| 817 | + |
| 818 | +class color(OpenSCADObject): |
| 819 | + def __init__(self, c): |
| 820 | + OpenSCADObject.__init__(self, 'color', {'c': c}) |
| 821 | + |
| 822 | + |
| 823 | +class minkowski(OpenSCADObject): |
| 824 | + def __init__(self): |
| 825 | + OpenSCADObject.__init__(self, 'minkowski', {}) |
| 826 | + |
| 827 | + |
| 828 | +class hull(OpenSCADObject): |
| 829 | + def __init__(self): |
| 830 | + OpenSCADObject.__init__(self, 'hull', {}) |
| 831 | + |
| 832 | + |
| 833 | +class render(OpenSCADObject): |
| 834 | + def __init__(self, convexity=None): |
| 835 | + OpenSCADObject.__init__(self, 'render', {'convexity': convexity}) |
| 836 | + |
| 837 | + |
| 838 | +class linear_extrude(OpenSCADObject): |
| 839 | + def __init__(self, height=None, center=None, convexity=None, twist=None, |
| 840 | + slices=None): |
| 841 | + OpenSCADObject.__init__(self, 'linear_extrude', |
| 842 | + {'height': height, 'center': center, |
| 843 | + 'convexity': convexity, 'twist': twist, |
| 844 | + 'slices': slices}) |
| 845 | + |
| 846 | + |
| 847 | +class rotate_extrude(OpenSCADObject): |
| 848 | + def __init__(self, convexity=None, segments=None): |
| 849 | + OpenSCADObject.__init__(self, 'rotate_extrude', |
| 850 | + {'convexity': convexity, 'segments': segments}) |
| 851 | + |
| 852 | + |
| 853 | +class dxf_linear_extrude(OpenSCADObject): |
| 854 | + def __init__(self, file, layer=None, height=None, center=None, |
| 855 | + convexity=None, twist=None, slices=None): |
| 856 | + OpenSCADObject.__init__(self, 'dxf_linear_extrude', |
| 857 | + {'file': file, 'layer': layer, |
| 858 | + 'height': height, 'center': center, |
| 859 | + 'convexity': convexity, 'twist': twist, |
| 860 | + 'slices': slices}) |
| 861 | + |
| 862 | + |
| 863 | +class projection(OpenSCADObject): |
| 864 | + def __init__(self, cut=None): |
| 865 | + OpenSCADObject.__init__(self, 'projection', {'cut': cut}) |
| 866 | + |
| 867 | + |
| 868 | +class surface(OpenSCADObject): |
| 869 | + def __init__(self, file, center=None, convexity=None, invert=None): |
| 870 | + OpenSCADObject.__init__(self, 'surface', |
| 871 | + {'file': file, 'center': center, |
| 872 | + 'convexity': convexity, 'invert': invert}) |
| 873 | + |
| 874 | + |
| 875 | +class text(OpenSCADObject): |
| 876 | + def __init__(self, text, size=None, font=None, halign=None, valign=None, |
| 877 | + spacing=None, direction=None, language=None, script=None, |
| 878 | + segments=None): |
| 879 | + OpenSCADObject.__init__(self, 'text', |
| 880 | + {'text': text, 'size': size, 'font': font, |
| 881 | + 'halign': halign, 'valign': valign, |
| 882 | + 'spacing': spacing, 'direction': direction, |
| 883 | + 'language': language, 'script': script, |
| 884 | + 'segments': segments}) |
| 885 | + |
| 886 | + |
| 887 | +class child(OpenSCADObject): |
| 888 | + def __init__(self, index=None, vector=None, range=None): |
| 889 | + OpenSCADObject.__init__(self, 'child', |
| 890 | + {'index': index, 'vector': vector, |
| 891 | + 'range': range}) |
| 892 | + |
| 893 | + |
| 894 | +class children(OpenSCADObject): |
| 895 | + def __init__(self, index=None, vector=None, range=None): |
| 896 | + OpenSCADObject.__init__(self, 'children', |
| 897 | + {'index': index, 'vector': vector, |
| 898 | + 'range': range}) |
| 899 | + |
| 900 | + |
| 901 | +class import_stl(OpenSCADObject): |
| 902 | + def __init__(self, file, origin=(0, 0), layer=None): |
| 903 | + OpenSCADObject.__init__(self, 'import', |
| 904 | + {'file': file, 'origin': origin, |
| 905 | + 'layer': layer}) |
| 906 | + |
| 907 | + |
| 908 | +class import_dxf(OpenSCADObject): |
| 909 | + def __init__(self, file, origin=(0, 0), layer=None): |
| 910 | + OpenSCADObject.__init__(self, 'import', |
| 911 | + {'file': file, 'origin': origin, |
| 912 | + 'layer': layer}) |
| 913 | + |
| 914 | + |
| 915 | +class import_(OpenSCADObject): |
| 916 | + def __init__(self, file, origin=(0, 0), layer=None): |
| 917 | + OpenSCADObject.__init__(self, 'import', |
| 918 | + {'file': file, 'origin': origin, |
| 919 | + 'layer': layer}) |
| 920 | + |
| 921 | + |
| 922 | +class intersection_for(OpenSCADObject): |
| 923 | + def __init__(self, n): |
| 924 | + OpenSCADObject.__init__(self, 'intersection_for', {'n': n}) |
| 925 | + |
| 926 | + |
| 927 | +class assign(OpenSCADObject): |
| 928 | + def __init__(self): |
| 929 | + OpenSCADObject.__init__(self, 'assign', {}) |
0 commit comments