1# Copyright (c) 2018-2020 Manfred Moitzi
2# License: MIT License
3import math
4from pathlib import Path
5import ezdxf
6from ezdxf.render import forms
7from itertools import cycle
8
9DIR = Path('~/desktop/Outbox').expanduser()
10
11
12def write_mesh(filename, mesh):
13    doc = ezdxf.new('R2000')
14    mesh.render_mesh(doc.modelspace())
15    try:
16        doc.saveas(filename)
17    except IOError as e:
18        print('ERROR: can not write "{0}": {1}'.format(e.filename, e.strerror))
19    else:
20        print('saving cylinder as "{}": done'.format(filename))
21
22
23def write_mesh_as_3dface(filename, mesh):
24    doc = ezdxf.new('R2000')
25    msp = doc.modelspace()
26    for vertices in mesh.faces_as_vertices():
27        msp.add_3dface(vertices)
28
29    try:
30        doc.saveas(filename)
31    except IOError as e:
32        print('ERROR: can not write "{0}": {1}'.format(e.filename, e.strerror))
33    else:
34        print('saving mesh as "{}": done'.format(filename))
35
36
37def build_rotation_form(filename, alpha=2 * math.pi, sides=16):
38    profile = forms.spline_interpolation([(0, 0.1), (1, 1), (3, 1.5), (5, 3)], subdivide=8)  # in xy-plane
39    mesh = forms.rotation_form(sides, profile, angle=alpha, axis=(1, 0, 0))
40    # write_mesh(filename, mesh)
41    write_mesh_as_3dface(filename, mesh)
42
43
44def build_cylinder(filename, sides=16):
45    cylinder = forms.cylinder(sides)
46    write_mesh(filename, cylinder)
47
48
49def create_gear(filename, teeth=20, outside_radius=10, top_width=2, bottom_width=3, height=2):
50    doc = ezdxf.new('R2000')
51    msp = doc.modelspace()
52    vertices = zip(
53        forms.gear(
54            count=teeth,
55            top_width=top_width,
56            bottom_width=bottom_width,
57            height=height,
58            outside_radius=outside_radius,
59        ),
60        cycle([0, .1, 0, .1])  # bulge values: top, down flank,  bottom, up flank
61    )
62    msp.add_lwpolyline(
63        vertices,
64        format='vb',
65        close=True,
66    )
67    doc.saveas(filename)
68
69
70if __name__ == '__main__':
71    build_cylinder(DIR / "forms_cylinder_16.dxf", sides=16)
72    build_rotation_form(DIR / "forms_rotate_profile_32.dxf", sides=32)
73    create_gear(DIR / 'gear.dxf')
74