-
Notifications
You must be signed in to change notification settings - Fork 177
/
hole_example.py
executable file
·95 lines (68 loc) · 3.21 KB
/
hole_example.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#! /usr/bin/env python3
import sys
from solid import scad_render_to_file
from solid.objects import cube, cylinder, hole, part, rotate
from solid.utils import FORWARD_VEC, right, up
SEGMENTS = 120
def pipe_intersection_hole():
pipe_od = 12
pipe_id = 10
seg_length = 30
outer = cylinder(r=pipe_od, h=seg_length, center=True)
inner = cylinder(r=pipe_id, h=seg_length + 2, center=True)
# By declaring that the internal void of pipe_a should
# explicitly remain empty, the combination of both pipes
# is empty all the way through.
# Any OpenSCAD / SolidPython object can be declared a hole(),
# and after that will always be empty
pipe_a = outer + hole()(inner)
# Note that "pipe_a = outer - hole()(inner)" would work identically;
# inner will always be subtracted now that it's a hole
pipe_b = rotate(a=90, v=FORWARD_VEC)(pipe_a)
return pipe_a + pipe_b
def pipe_intersection_no_hole():
pipe_od = 12
pipe_id = 10
seg_length = 30
outer = cylinder(r=pipe_od, h=seg_length, center=True)
inner = cylinder(r=pipe_id, h=seg_length + 2, center=True)
pipe_a = outer - inner
pipe_b = rotate(a=90, v=FORWARD_VEC)(pipe_a)
# pipe_a and pipe_b are both hollow, but because
# their central voids aren't explicitly holes,
# the union of both pipes has unwanted internal walls
return pipe_a + pipe_b
def multipart_hole():
# It's good to be able to keep holes empty, but often we want to put
# things (bolts, etc.) in them. The way to do this is to declare the
# object containing the hole a "part". Then, the hole will remain
# empty no matter what you add to the 'part'. But if you put an object
# that is NOT part of the 'part' into the hole, it will still appear.
# On the left (not_part), here's what happens if we try to put an object
# into an explicit hole: the object gets erased by the hole.
# On the right (is_part), we mark the cube-with-hole as a "part",
# and then insert the same 'bolt' cylinder into it. The entire
# bolt rematins.
b = cube(10, center=True)
c = cylinder(r=2, h=12, center=True)
# A cube with an explicit hole
not_part = b - hole()(c)
# Mark this cube-with-hole as a separate part from the cylinder
is_part = part()(not_part.copy())
# This fits in the holes
bolt = cylinder(r=1.5, h=14, center=True) + up(8)(cylinder(r=2.5, h=2.5, center=True))
# The section of the bolt inside not_part disappears. The section
# of the bolt inside is_part is still there.
return not_part + bolt + right(45)(is_part + bolt)
if __name__ == '__main__':
out_dir = sys.argv[1] if len(sys.argv) > 1 else None
# On the left, pipes with no explicit holes, which can give
# unexpected walls where we don't want them.
# On the right, we use the hole() function to fix the problem
a = pipe_intersection_no_hole() + right(45)(pipe_intersection_hole())
# Below is an example of how to put objects into holes and have them
# still appear
b = up(40)(multipart_hole())
a += b
file_out = scad_render_to_file(a, out_dir=out_dir, file_header=f'$fn = {SEGMENTS};', include_orig_code=True)
print(f"{__file__}: SCAD file written to: \n{file_out}")