1# Purpose: setup initial viewport for a DXF drawing
2# Copyright (c) 2016-2021 Manfred Moitzi
3# License: MIT License
4import pathlib
5import ezdxf
6
7DIR = pathlib.Path('~/Desktop/Outbox').expanduser()
8FILENAME = 'page_setup_R2000.dxf'
9
10
11def draw_raster(doc):
12    marker = doc.blocks.new(name='MARKER')
13    attribs = {'color': 2}
14    marker.add_line((-1, 0), (1, 0), dxfattribs=attribs)
15    marker.add_line((0, -1), (0, 1), dxfattribs=attribs)
16    marker.add_circle((0, 0), .4, dxfattribs=attribs)
17
18    marker.add_attdef('XPOS', (0.5, -1.0), dxfattribs={'height': 0.25, 'color': 4})
19    marker.add_attdef('YPOS', (0.5, -1.5), dxfattribs={'height': 0.25, 'color': 4})
20    modelspace = doc.modelspace()
21    for x in range(10):
22        for y in range(10):
23            xcoord = x * 10
24            ycoord = y * 10
25            values = {
26                'XPOS': f"x = {xcoord}",
27                'YPOS': f"y = {ycoord}",
28            }
29            modelspace.add_auto_blockref('MARKER', (xcoord, ycoord), values)
30
31
32def setup_active_viewport(doc):
33    # delete '*Active' viewport configuration
34    doc.viewports.delete_config('*ACTIVE')
35    # the available display area in AutoCAD has the virtual lower-left corner (0, 0) and the virtual upper-right corner
36    # (1, 1)
37
38    # first viewport, uses the left half of the screen
39    viewport = doc.viewports.new('*ACTIVE')
40    viewport.dxf.lower_left = (0, 0)
41    viewport.dxf.upper_right = (.5, 1)
42    viewport.dxf.target = (0, 0, 0)  # target point defines the origin of the DCS, this is the default value
43    viewport.dxf.center = (40, 30)  # move this location (in DCS) to the center of the viewport
44    viewport.dxf.height = 15  # height of viewport in drawing units, this parameter works
45    viewport.dxf.aspect_ratio = 1.0  # aspect ratio of viewport (x/y)
46
47    # second viewport, uses the right half of the screen
48    viewport = doc.viewports.new('*ACTIVE')
49    viewport.dxf.lower_left = (.5, 0)
50    viewport.dxf.upper_right = (1, 1)
51    viewport.dxf.target = (60, 20, 0)  # target point defines the origin of the DCS
52    viewport.dxf.center = (0, 0)  # move this location (in DCS, model space = 60, 20) to the center of the viewport
53    viewport.dxf.height = 15  # height of viewport in drawing units, this parameter works
54    viewport.dxf.aspect_ratio = 2.0  # aspect ratio of viewport (x/y)
55
56
57def layout_page_setup(doc):
58    name = 'Layout1'
59    if name in doc.layouts:
60        layout = doc.layouts.get(name)
61    else:
62        layout = doc.layouts.new(name)
63
64    layout.page_setup(size=(11, 8.5), margins=(.5, .5, .5, .5), units='inch')
65    lower_left, upper_right = layout.get_paper_limits()
66    x1, y1 = lower_left
67    x2, y2 = upper_right
68    center = lower_left.lerp(upper_right)
69    layout.add_line((x1, center.y), (x2, center.y))  # horizontal center line
70    layout.add_line((center.x, y1), (center.x, y2))  # vertical center line
71    layout.add_circle((0, 0), radius=.1)  # plot origin
72
73    layout2 = doc.layouts.new('ezdxf scale 1-1')
74    layout2.page_setup(size=(297, 210), margins=(10, 10, 10, 10), units='mm')
75    layout2.add_viewport(
76        center=(100, 100),  # center of viewport in paper_space units
77        size=(50, 50),  # viewport size in paper_space units
78        view_center_point=(60, 40),  # model space point to show in center of viewport in WCS
79        view_height=20,  # how much model space area to show in viewport in drawing units
80    )
81    lower_left, upper_right = layout2.get_paper_limits()
82    x1, y1 = lower_left
83    x2, y2 = upper_right
84    center = lower_left.lerp(upper_right)
85
86    layout2.add_line((x1, center.y), (x2, center.y))  # horizontal center line
87    layout2.add_line((center.x, y1), (center.x, y2))  # vertical center line
88    layout2.add_circle((0, 0), radius=5)  # plot origin
89
90    layout3 = doc.layouts.new('ezdxf scale 1-50')
91    layout3.page_setup(size=(297, 210), margins=(10, 10, 10, 10), units='mm',
92                       scale=(1, 50))
93    layout3.add_viewport(
94        center=(5000, 5000),  # center of viewport in paper_space units, scale = 1:50
95        size=(5000, 2500),  # viewport size in paper_space units, scale = 1:50
96        view_center_point=(60, 40),  # model space point to show in center of viewport in WCS
97        view_height=20,  # how much model space area to show in viewport in drawing units
98    )
99    layout3.add_circle((0, 0), radius=250)  # plot origin
100
101    layout4 = doc.layouts.new('ezdxf scale 1-1 with offset')
102    layout4.page_setup(size=(297, 210), margins=(10, 10, 10, 10), units='mm',
103                       scale=(1, 1), offset=(50, 50))
104    lower_left, upper_right = layout4.get_paper_limits()
105    x1, y1 = lower_left
106    x2, y2 = upper_right
107    center = lower_left.lerp(upper_right)
108
109    layout4.add_line((x1, center.y), (x2, center.y))  # horizontal center line
110    layout4.add_line((center.x, y1), (center.x, y2))  # vertical center line
111    layout4.add_circle((0, 0), radius=5)  # plot origin
112
113
114if __name__ == '__main__':
115    doc = ezdxf.new('R2000')
116    draw_raster(doc)
117    setup_active_viewport(doc)
118    layout_page_setup(doc)
119    doc.saveas(DIR / FILENAME)
120    print(f'DXF file "{FILENAME}" created.')
121