File: hatch.py

package info (click to toggle)
ezdxf 1.4.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 104,528 kB
  • sloc: python: 182,341; makefile: 116; lisp: 20; ansic: 4
file content (289 lines) | stat: -rw-r--r-- 10,893 bytes parent folder | download
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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
# Copyright (c) 2015-2024 Manfred Moitzi
# License: MIT License
import pathlib
import ezdxf
from ezdxf import zoom
from ezdxf.lldxf import const
from ezdxf.math import Vec2
from ezdxf.tools import pattern

CWD = pathlib.Path("~/Desktop/Outbox").expanduser()
if not CWD.exists():
    CWD = pathlib.Path(".")

# ------------------------------------------------------------------------------
# Multiple example for creating a HATCH entity.
#
# docs: https://ezdxf.mozman.at/docs/dxfentities/hatch.html
# tutorial: https://ezdxf.mozman.at/docs/tutorials/hatch.html
# ------------------------------------------------------------------------------


def create_solid_polyline_hatch():
    doc = ezdxf.new("R2010")  # create a new DXF drawing (AutoCAD 2010)
    msp = doc.modelspace()  # we are working in model space
    hatch = msp.add_hatch(color=2)  # by default a SOLID fill
    # if only 1 path - flags = 1 (external) by default
    hatch.paths.add_polyline_path([(0, 0), (0, 3), (3, 6), (6, 6), (6, 3), (3, 0)])
    zoom.extents(msp)
    doc.saveas(CWD / "hatch_solid_polyline.dxf")  # save DXF drawing


def create_pattern_fill_polyline_hatch():
    doc = ezdxf.new("R2010")  # create a new DXF drawing (AutoCAD 2010)
    msp = doc.modelspace()  # we are working in model space
    hatch = msp.add_hatch()  # by default a SOLID fill
    hatch.set_pattern_fill("ANSI33", color=7, scale=0.01)
    # if only 1 path - flags = 1 (external) by default
    hatch.paths.add_polyline_path([(0, 0), (0, 3), (3, 6), (6, 6), (6, 3), (3, 0)])
    zoom.extents(msp)
    doc.saveas(CWD / "hatch_pattern_fill_polyline.dxf")


def create_user_pattern_fill():
    doc = ezdxf.new("R2010")  # create a new DXF drawing (AutoCAD 2010)
    msp = doc.modelspace()  # we are working in model space
    hatch = msp.add_hatch()  # by default a SOLID fill
    offset = Vec2.from_deg_angle(45 + 90, length=0.7)
    hatch.set_pattern_fill(
        "MyPattern",
        color=7,
        angle=0,
        scale=1.0,
        style=0,
        pattern_type=0,
        definition=[
            [0, (0, 0), (0, 1), [1, -1]],  # horizontal dashed line
            [45, (0, 0), offset, []],  # slanted solid line
        ],
    )
    points = [(0, 0), (10, 0), (10, 10), (0, 10)]
    hatch.paths.add_polyline_path(points)
    msp.add_lwpolyline(points, close=True, dxfattribs={"color": 1})
    zoom.extents(msp)
    doc.saveas(CWD / "hatch_user_pattern_fill.dxf")


EXAMPLE = """; a pattern file

*SOLID, Solid fill
45, 0,0, 0,.125
*ANSI31, ANSI Iron, Brick, Stone masonry
45, 0,0, 0,.125
*ANSI32, ANSI Steel
45, 0,0, 0,.375
45, .176776695,0, 0,.375
*ANSI33, ANSI Bronze, Brass, Copper
45, 0,0, 0,.25
45, .176776695,0, 0,.25, .125,-.0625
*ANSI34, ANSI Plastic, Rubber
45, 0,0, 0,.75
45, .176776695,0, 0,.75
45, .353553391,0, 0,.75
45, .530330086,0, 0,.75
"""


def load_pattern_from_file():

    doc = ezdxf.new("R2010")  # create a new DXF drawing (AutoCAD 2010)
    msp = doc.modelspace()  # we are working in model space
    hatch = msp.add_hatch()  # by default a SOLID fill
    # load your pattern file fro file system as string:
    # with open("pattern_file.pat", "rt") as fp:
    #      EXAMPLE = fp.read()
    patterns = pattern.parse(EXAMPLE)

    hatch.set_pattern_fill(
        "MyPattern",
        color=7,
        angle=0,
        scale=1.0,
        style=0,
        pattern_type=0,
        # pattern name without the preceding asterisk
        definition=patterns["ANSI34"],
    )
    points = [(0, 0), (10, 0), (10, 10), (0, 10)]
    hatch.paths.add_polyline_path(points)
    msp.add_lwpolyline(points, close=True, dxfattribs={"color": 1})
    zoom.extents(msp)
    doc.saveas(CWD / "loaded_pattern_from_file.dxf")


def create_pattern_fill_hatch_with_bgcolor():
    doc = ezdxf.new("R2010")  # create a new DXF drawing (AutoCAD 2010)
    msp = doc.modelspace()  # we are working in model space
    hatch = msp.add_hatch()  # by default a SOLID fill
    hatch.set_pattern_fill("ANSI33", color=7, scale=0.01)
    # if only 1 path - flags = 1 (external) by default
    hatch.paths.add_polyline_path([(0, 0), (0, 3), (3, 6), (6, 6), (6, 3), (3, 0)])
    hatch.bgcolor = (100, 200, 100)
    zoom.extents(msp)
    doc.saveas(CWD / "hatch_pattern_fill_with_bgcolor.dxf")


def using_hatch_style():
    def place_square_1(hatch, x, y):
        def shift(point):
            return x + point[0], y + point[1]

        # outer loop - flags = 1 (external) default value
        hatch.paths.add_polyline_path(map(shift, [(0, 0), (8, 0), (8, 8), (0, 8)]))
        # first inner loop - flags = 16 (outermost)
        hatch.paths.add_polyline_path(
            map(shift, [(2, 2), (7, 2), (7, 7), (2, 7)]),
            flags=const.BOUNDARY_PATH_OUTERMOST,
        )
        # any further inner loops - flags = 0 (default)
        hatch.paths.add_polyline_path(
            map(shift, [(4, 4), (6, 4), (6, 6), (4, 6)]),
            flags=const.BOUNDARY_PATH_DEFAULT,
        )

    def place_square_2(hatch, x, y):
        def shift(point):
            return x + point[0], y + point[1]

        # outer loop - flags = 1 (external) default value
        hatch.paths.add_polyline_path(map(shift, [(0, 0), (8, 0), (8, 8), (0, 8)]))
        # partly 1. inner loop - flags = 16 (outermost)
        hatch.paths.add_polyline_path(
            map(shift, [(3, 1), (7, 1), (7, 5), (3, 5)]),
            flags=const.BOUNDARY_PATH_OUTERMOST,
        )
        # partly 1. inner loop - flags = 16 (outermost)
        hatch.paths.add_polyline_path(
            map(shift, [(1, 3), (5, 3), (5, 7), (1, 7)]),
            flags=const.BOUNDARY_PATH_OUTERMOST,
        )

    doc = ezdxf.new("R2010")  # create a new DXF drawing (AutoCAD 2010)
    msp = doc.modelspace()  # we are working in model space
    # first create DXF hatch entities
    hatch_style_0 = msp.add_hatch(color=3, dxfattribs={"hatch_style": 0})
    hatch_style_1 = msp.add_hatch(color=3, dxfattribs={"hatch_style": 1})
    hatch_style_2 = msp.add_hatch(color=3, dxfattribs={"hatch_style": 2})
    # then insert path elements to define the hatch boundaries
    place_square_1(hatch_style_0, 0, 0)
    place_square_1(hatch_style_1, 10, 0)
    place_square_1(hatch_style_2, 20, 0)

    # first create DXF hatch entities
    hatch_style_0b = msp.add_hatch(color=4, dxfattribs={"hatch_style": 0})
    hatch_style_1b = msp.add_hatch(color=4, dxfattribs={"hatch_style": 1})
    hatch_style_2b = msp.add_hatch(color=4, dxfattribs={"hatch_style": 2})
    # then insert path elements to define the hatch boundaries
    place_square_2(hatch_style_0b, 0, 10)
    place_square_2(hatch_style_1b, 10, 10)
    place_square_2(hatch_style_2b, 20, 10)
    zoom.extents(msp)
    doc.saveas(CWD / "hatch_styles_examples.dxf")


def using_hatch_style_with_edge_path():
    def add_edge_path(paths, vertices, flags=1):
        path = paths.add_edge_path(flags)  # create a new edge path
        first_point = next(vertices)  # store first point for closing path
        last_point = first_point
        for next_point in vertices:
            path.add_line(last_point, next_point)  # add lines to edge path
            last_point = next_point
        path.add_line(last_point, first_point)  # close path

    def place_square_1(hatch, x, y):
        def shift(point):
            return x + point[0], y + point[1]

        # outer loop - flags=1 (external) default value
        add_edge_path(
            hatch.paths,
            map(shift, [(0, 0), (12.5, 0), (12.5, 12.5), (0, 12.5)]),
        )
        # first inner loop - flags=16 (outermost)
        add_edge_path(
            hatch.paths,
            map(shift, [(2.5, 2.5), (10, 2.5), (10, 10), (2.5, 10)]),
            flags=const.BOUNDARY_PATH_OUTERMOST,
        )
        # any inner loop - flags=0 (default)
        add_edge_path(
            hatch.paths,
            map(shift, [(5, 5), (7.5, 5), (7.5, 7.5), (5, 7.5)]),
            flags=const.BOUNDARY_PATH_DEFAULT,
        )

    def place_square_2(hatch, x, y):
        def shift(point):
            return x + point[0], y + point[1]

        add_edge_path(
            hatch.paths, map(shift, [(0, 0), (0, 8), (8, 8), (8, 0)])
        )  # 1. path
        add_edge_path(
            hatch.paths,
            map(shift, [(3, 1), (7, 1), (7, 5), (3, 5)]),
            flags=const.BOUNDARY_PATH_OUTERMOST,
        )
        add_edge_path(
            hatch.paths,
            map(shift, [(1, 3), (5, 3), (5, 7), (1, 7)]),
            flags=const.BOUNDARY_PATH_OUTERMOST,
        )

    doc = ezdxf.new("R2010")  # create a new DXF drawing (AutoCAD 2010)
    msp = doc.modelspace()  # we are working in model space
    # first create DXF hatch entities
    hatch_style_0 = msp.add_hatch(color=3, dxfattribs={"hatch_style": 0})
    hatch_style_1 = msp.add_hatch(color=3, dxfattribs={"hatch_style": 1})
    hatch_style_2 = msp.add_hatch(color=3, dxfattribs={"hatch_style": 2})
    # then insert path elements to define the hatch boundaries
    place_square_1(hatch_style_0, 0, 0)
    place_square_1(hatch_style_1, 15, 0)
    place_square_1(hatch_style_2, 30, 0)

    # first create DXF hatch entities
    hatch_style_0b = msp.add_hatch(color=4, dxfattribs={"hatch_style": 0})
    hatch_style_1b = msp.add_hatch(color=4, dxfattribs={"hatch_style": 1})
    hatch_style_2b = msp.add_hatch(color=4, dxfattribs={"hatch_style": 2})
    # then insert path elements to define the hatch boundaries
    place_square_2(hatch_style_0b, 0, 15)
    place_square_2(hatch_style_1b, 15, 15)
    place_square_2(hatch_style_2b, 30, 15)
    zoom.extents(msp)
    doc.saveas(CWD / "hatch_styles_examples_with_edge_path.dxf")


def using_hatch_with_spline_edge():
    doc = ezdxf.new("R2010")  # create a new DXF drawing (AutoCAD 2010)
    msp = doc.modelspace()  # we are working in model space
    # draw outline
    fitpoints = [(8, 0, 0), (10, 2, 0), (6, 6, 0), (8, 8, 0)]
    msp.add_line((8, 8), (0, 8))
    msp.add_line((0, 8), (0, 0))
    msp.add_line((0, 0), (8, 0))
    # use spline with control points created by ezdxf
    # Don't know how AutoCAD calculates control points from fit points
    msp.add_spline_control_frame(fit_points=fitpoints)

    # next create DXF hatch entities
    hatch = msp.add_hatch(color=3)
    # if only 1 path - flags = 1 (external) by default
    path = hatch.paths.add_edge_path()  # create a new edge path
    path.add_line((8, 8), (0, 8))
    path.add_line((0, 8), (0, 0))
    path.add_line((0, 0), (8, 0))
    path.add_spline_control_frame(fit_points=fitpoints)
    zoom.extents(msp)
    doc.saveas(CWD / "hatch_with_spline_edge.dxf")  # save DXF drawing


if __name__ == "__main__":
    create_solid_polyline_hatch()
    create_pattern_fill_polyline_hatch()
    create_pattern_fill_hatch_with_bgcolor()
    create_user_pattern_fill()
    using_hatch_style()
    using_hatch_style_with_edge_path()
    using_hatch_with_spline_edge()
    load_pattern_from_file()