Skip to content

Commit 101f411

Browse files
Basic support for some elements of ImplicitCAD, as suggested in #134
1 parent 0624cc3 commit 101f411

File tree

1 file changed

+58
-0
lines changed

1 file changed

+58
-0
lines changed

solid/implicit.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
#! /usr/bin/env python
2+
import solid.objects
3+
from solid.solidpython import calling_module, OpenSCADObject
4+
5+
from textwrap import dedent
6+
from typing import Dict, Callable
7+
8+
def implicitCAD_patch_objects():
9+
"""
10+
Usage:
11+
`from solid.implicit import *`, (rather than `from solid import *`)
12+
All other usage should be like normal SolidPython.
13+
14+
Monkey-patching for basic compatibility with Christopher Olah's ImplicitCAD
15+
(https://github.com/colah/ImplicitCAD)
16+
NOTE that this *only* enables `r` arguments to a number of geometry classes.
17+
ImplicitCAD has a number of other syntax features that are still unsupported,
18+
notably functions as arguments to some functions. PRs for that are welcome!
19+
-ETJ 22 January 2020
20+
21+
"""
22+
to_add_rad = [
23+
'square', 'polygon',
24+
'cube', 'cylinder', 'polyhedron',
25+
'union', 'intersection', 'difference'
26+
]
27+
28+
cur_mod = calling_module(stack_depth=1)
29+
30+
for cls_name, cls in solid.objects.__dict__.items():
31+
if cls_name in to_add_rad:
32+
args_dict_orig = method_args_dict(cls.__init__)
33+
args_str_orig = ', '.join(['self'] + [f'{k} = {v}' for k, v in args_dict_orig.items()])
34+
args_str = ', '.join([args_str_orig, 'r = 0'])
35+
super_args_str = ', '.join([f'{k} = {k}' for k in args_dict_orig.keys()])
36+
37+
cls_str = dedent(f'''
38+
class {cls_name}(solid.objects.{cls_name}):
39+
def __init__({args_str}):
40+
super().__init__({super_args_str})
41+
self.params['r'] = r
42+
43+
''')
44+
exec(cls_str)
45+
46+
cls = locals()[cls_name]
47+
48+
# Add the class (original or new subclass) to this module's top level namespace
49+
setattr(cur_mod, cls_name, cls)
50+
51+
def method_args_dict(method:Callable) -> Dict:
52+
var_names = method.__code__.co_varnames
53+
var_names = tuple((v for v in var_names if v is not 'self'))
54+
default_vals = method.__defaults__ or [None] # type:ignore
55+
56+
return dict(zip(var_names, default_vals))
57+
58+
implicitCAD_patch_objects()

0 commit comments

Comments
 (0)