0
# Tools
1
2
Specialized utility functions for text processing, pattern management, standards setup, date/time conversion, and various CAD-specific operations. The tools package provides essential utilities that support the core ezdxf functionality.
3
4
## Capabilities
5
6
### Date and Time Utilities
7
8
Conversion functions between Julian dates and standard datetime objects.
9
10
```python { .api }
11
def juliandate(datetime) -> float:
12
"""
13
Convert datetime object to Julian date number.
14
15
Parameters:
16
- datetime: Python datetime object
17
18
Returns:
19
float: Julian date number
20
"""
21
22
def calendardate(julian: float):
23
"""
24
Convert Julian date number to datetime object.
25
26
Parameters:
27
- julian: Julian date number
28
29
Returns:
30
datetime: Python datetime object
31
"""
32
```
33
34
Usage examples:
35
```python
36
from ezdxf.tools import juliandate, calendardate
37
from datetime import datetime
38
39
# Convert to Julian date
40
now = datetime.now()
41
julian = juliandate(now)
42
print(f"Current Julian date: {julian}")
43
44
# Convert back to datetime
45
converted = calendardate(julian)
46
print(f"Converted back: {converted}")
47
48
# Use in DXF entities (some entities store dates as Julian dates)
49
creation_date = juliandate(datetime(2023, 1, 1, 12, 0, 0))
50
```
51
52
### Binary Data Utilities
53
54
Functions for handling binary data and hex string conversions.
55
56
```python { .api }
57
def hex_strings_to_bytes(hex_strings) -> bytes:
58
"""
59
Convert list of hex strings to bytes.
60
61
Parameters:
62
- hex_strings: list of hexadecimal strings
63
64
Returns:
65
bytes: Combined binary data
66
"""
67
68
def bytes_to_hexstr(data: bytes, group_size: int = 1, upper: bool = True) -> str:
69
"""
70
Convert bytes to hex string representation.
71
72
Parameters:
73
- data: binary data
74
- group_size: bytes per group (for spacing)
75
- upper: use uppercase hex digits
76
77
Returns:
78
str: Hex string representation
79
"""
80
```
81
82
Usage examples:
83
```python
84
from ezdxf.tools import hex_strings_to_bytes, bytes_to_hexstr
85
86
# Convert hex strings to binary
87
hex_data = ['48656C6C6F', '20576F726C64'] # "Hello World" in hex
88
binary_data = hex_strings_to_bytes(hex_data)
89
print(binary_data.decode('utf-8')) # "Hello World"
90
91
# Convert binary to hex string
92
test_data = b"Test data"
93
hex_string = bytes_to_hexstr(test_data, group_size=2, upper=True)
94
print(f"Hex representation: {hex_string}")
95
```
96
97
### String and Text Utilities
98
99
Text processing and formatting utilities for CAD-specific operations.
100
101
```python { .api }
102
def escape(text: str) -> str:
103
"""
104
HTML escape text for safe display.
105
106
Parameters:
107
- text: input text
108
109
Returns:
110
str: HTML-escaped text
111
"""
112
113
def guid() -> str:
114
"""
115
Generate GUID string.
116
117
Returns:
118
str: GUID in standard format
119
"""
120
121
def suppress_zeros(s: str, leading: bool = True, trailing: bool = True) -> str:
122
"""
123
Remove leading and/or trailing zeros from number strings.
124
125
Parameters:
126
- s: number string
127
- leading: remove leading zeros
128
- trailing: remove trailing zeros
129
130
Returns:
131
str: Formatted number string
132
"""
133
134
def normalize_text_angle(angle: float, fix_upside_down: bool = True) -> float:
135
"""
136
Normalize text angle for readability.
137
138
Parameters:
139
- angle: text angle in radians
140
- fix_upside_down: flip upside-down text
141
142
Returns:
143
float: Normalized angle
144
"""
145
```
146
147
Usage examples:
148
```python
149
from ezdxf.tools import escape, guid, suppress_zeros, normalize_text_angle
150
import math
151
152
# HTML escape for safe display
153
unsafe_text = "<script>alert('test')</script>"
154
safe_text = escape(unsafe_text)
155
print(f"Escaped: {safe_text}")
156
157
# Generate unique identifier
158
unique_id = guid()
159
print(f"GUID: {unique_id}")
160
161
# Format numbers
162
number_str = "00012.3400"
163
clean_number = suppress_zeros(number_str, leading=True, trailing=True)
164
print(f"Cleaned: {clean_number}") # "12.34"
165
166
# Normalize text angles
167
upside_down_angle = math.radians(200) # 200 degrees
168
normalized = normalize_text_angle(upside_down_angle, fix_upside_down=True)
169
print(f"Normalized angle: {math.degrees(normalized)} degrees")
170
```
171
172
### Binary Flag Utilities
173
174
Functions for manipulating binary flags in integer values.
175
176
```python { .api }
177
def set_flag_state(flags: int, flag: int, state: bool = True) -> int:
178
"""
179
Set or clear binary flag in integer value.
180
181
Parameters:
182
- flags: current flag value
183
- flag: flag bit to modify
184
- state: True to set, False to clear
185
186
Returns:
187
int: Modified flag value
188
"""
189
```
190
191
Usage examples:
192
```python
193
from ezdxf.tools import set_flag_state
194
195
# Work with entity flags
196
current_flags = 0b00000000 # No flags set
197
198
# Set specific flags
199
current_flags = set_flag_state(current_flags, 0b00000001, True) # Set bit 0
200
current_flags = set_flag_state(current_flags, 0b00000100, True) # Set bit 2
201
current_flags = set_flag_state(current_flags, 0b00010000, True) # Set bit 4
202
203
print(f"Flags: {bin(current_flags)}") # 0b00010101
204
205
# Clear a flag
206
current_flags = set_flag_state(current_flags, 0b00000100, False) # Clear bit 2
207
print(f"Flags: {bin(current_flags)}") # 0b00010001
208
```
209
210
### Iterator Utilities
211
212
Utility functions for processing sequences and iterables.
213
214
```python { .api }
215
def take2(iterable):
216
"""
217
Iterate sequence as non-overlapping pairs.
218
219
Parameters:
220
- iterable: sequence to process
221
222
Yields:
223
tuple: consecutive pairs of elements
224
"""
225
226
def pairwise(iterable, close: bool = False):
227
"""
228
Iterate sequence as overlapping pairs.
229
230
Parameters:
231
- iterable: sequence to process
232
- close: include pair from last to first element
233
234
Yields:
235
tuple: overlapping pairs of elements
236
"""
237
```
238
239
Usage examples:
240
```python
241
from ezdxf.tools import take2, pairwise
242
243
# Process points as non-overlapping pairs
244
points = [(0, 0), (1, 1), (2, 0), (3, 1), (4, 0)]
245
246
# Non-overlapping pairs for line segments
247
for start, end in take2(points):
248
line = msp.add_line(start, end)
249
250
# Overlapping pairs for connected polyline
251
vertices = []
252
for p1, p2 in pairwise(points, close=True):
253
# Process each edge of the polygon
254
vertices.extend([p1, p2])
255
256
# Create closed polyline
257
poly = msp.add_lwpolyline(points)
258
poly.close()
259
```
260
261
### Hatch Pattern Management
262
263
Comprehensive hatch pattern loading, analysis, and manipulation utilities.
264
265
```python { .api }
266
def load(measurement: int = 1, factor: float = 1.0):
267
"""
268
Load hatch pattern definitions.
269
270
Parameters:
271
- measurement: measurement system (0=Imperial, 1=Metric)
272
- factor: scaling factor for patterns
273
274
Returns:
275
dict: Pattern definitions
276
"""
277
278
def scale_pattern(pattern, factor: float):
279
"""
280
Scale individual hatch pattern.
281
282
Parameters:
283
- pattern: pattern definition
284
- factor: scaling factor
285
286
Returns:
287
Pattern definition scaled by factor
288
"""
289
290
def scale_all(patterns, factor: float):
291
"""
292
Scale all patterns in collection.
293
294
Parameters:
295
- patterns: pattern collection
296
- factor: scaling factor
297
298
Returns:
299
Scaled pattern collection
300
"""
301
302
def parse(pattern_str: str):
303
"""
304
Parse hatch pattern definition string.
305
306
Parameters:
307
- pattern_str: pattern definition in AutoCAD format
308
309
Returns:
310
Parsed pattern data structure
311
"""
312
313
class PatternAnalyser:
314
"""Hatch pattern analysis and validation"""
315
316
def __init__(self, pattern): ...
317
318
def analyse(self):
319
"""Analyze pattern structure and properties"""
320
321
@property
322
def line_count(self) -> int:
323
"""Number of pattern lines"""
324
325
@property
326
def is_valid(self) -> bool:
327
"""True if pattern is valid"""
328
329
# Pattern constants and type definitions
330
ISO_PATTERN: dict
331
"""ISO standard hatch patterns"""
332
333
IMPERIAL_PATTERN: dict
334
"""Imperial measurement hatch patterns"""
335
336
HatchPatternLineType = List[float]
337
HatchPatternType = List[HatchPatternLineType]
338
```
339
340
Usage examples:
341
```python
342
from ezdxf.tools.pattern import load, scale_pattern, parse, PatternAnalyser
343
from ezdxf.tools.pattern import ISO_PATTERN
344
345
# Load standard patterns
346
metric_patterns = load(measurement=1, factor=1.0) # Metric
347
imperial_patterns = load(measurement=0, factor=25.4) # Imperial scaled to mm
348
349
# Scale specific pattern
350
if 'ANSI31' in metric_patterns:
351
scaled_ansi31 = scale_pattern(metric_patterns['ANSI31'], 2.0)
352
353
# Parse custom pattern
354
custom_pattern_str = """*CUSTOM,Custom diagonal lines
355
45, 0,0, 0,2.83, 2.83,-1.41
356
"""
357
custom_pattern = parse(custom_pattern_str)
358
359
# Analyze pattern
360
analyser = PatternAnalyser(custom_pattern)
361
analyser.analyse()
362
print(f"Pattern has {analyser.line_count} lines")
363
print(f"Pattern is valid: {analyser.is_valid}")
364
365
# Use pattern in hatch
366
hatch = msp.add_hatch()
367
hatch.set_pattern_fill('ANSI31', color=1, angle=0, scale=1.0)
368
# Add boundary paths to hatch...
369
```
370
371
### Standard Setup Tools
372
373
Functions for setting up standard drawing configurations, styles, and definitions.
374
375
```python { .api }
376
def setup_drawing(doc, topics = None):
377
"""
378
Setup standard drawing configuration.
379
380
Parameters:
381
- doc: DXF document
382
- topics: list of setup topics ('linetypes', 'styles', 'dimstyles', etc.)
383
"""
384
385
def setup_linetypes(doc):
386
"""Setup standard AutoCAD linetypes in document"""
387
388
def setup_styles(doc):
389
"""Setup standard text styles in document"""
390
391
def setup_dimstyles(doc):
392
"""Setup standard dimension styles in document"""
393
394
def setup_dimstyle(doc, name: str):
395
"""
396
Setup specific dimension style by name.
397
398
Parameters:
399
- doc: DXF document
400
- name: dimension style name
401
"""
402
```
403
404
Usage examples:
405
```python
406
from ezdxf.tools.standards import setup_linetypes, setup_styles, setup_dimstyles
407
import ezdxf
408
409
# Create document with standard setup
410
doc = ezdxf.new('R2018')
411
412
# Setup standard configurations
413
setup_linetypes(doc) # CONTINUOUS, DASHED, DOTTED, etc.
414
setup_styles(doc) # Standard text styles
415
setup_dimstyles(doc) # Standard dimension styles
416
417
# Now you can use standard linetypes
418
line = doc.modelspace().add_line((0, 0), (10, 10), dxfattribs={
419
'linetype': 'DASHED',
420
'color': 1
421
})
422
423
# Check what was added
424
print("Available linetypes:")
425
for linetype in doc.linetypes:
426
print(f" {linetype.dxf.name}")
427
428
print("Available text styles:")
429
for style in doc.styles:
430
print(f" {style.dxf.name}")
431
```
432
433
### Transparency Utilities
434
435
Transparency conversion functions (also available in colors module).
436
437
```python { .api }
438
def float2transparency(value: float) -> int:
439
"""Convert float transparency (0-1) to DXF format"""
440
441
def transparency2float(value: int) -> float:
442
"""Convert DXF transparency to float (0-1)"""
443
```
444
445
### Additional Utilities
446
447
Various specialized utility functions for CAD operations.
448
449
```python { .api }
450
# Text and string utilities
451
def text_size(text: str, font_size: float, font: str = None) -> tuple:
452
"""Estimate text size for layout calculations"""
453
454
def complex_ltype_definition(name: str, pattern, text_style: str = None):
455
"""Create complex linetype with text or shapes"""
456
457
# Debugging and analysis
458
def analyze_entity(entity):
459
"""Analyze entity structure and properties"""
460
461
def debug_entity(entity, stream = None):
462
"""Output detailed entity information for debugging"""
463
464
# Coordinate system utilities
465
def ocs_to_wcs(points, ocs_axis):
466
"""Convert Object Coordinate System points to World Coordinate System"""
467
468
def wcs_to_ocs(points, ocs_axis):
469
"""Convert World Coordinate System points to Object Coordinate System"""
470
```
471
472
## Complete Tools Usage Example
473
474
```python
475
import ezdxf
476
from ezdxf.tools import juliandate, guid, suppress_zeros
477
from ezdxf.tools.pattern import load as load_patterns
478
from ezdxf.tools.standards import setup_drawing
479
from datetime import datetime
480
481
# Create document with full standard setup
482
doc = ezdxf.new('R2018')
483
setup_drawing(doc, topics=['linetypes', 'styles', 'dimstyles'])
484
485
# Load hatch patterns
486
patterns = load_patterns(measurement=1, factor=1.0) # Metric patterns
487
488
msp = doc.modelspace()
489
490
# Create drawing with various tools utilities
491
# Date stamp using Julian date
492
creation_date = juliandate(datetime.now())
493
title_text = f"Drawing created: {datetime.now().strftime('%Y-%m-%d')}"
494
title = msp.add_text(title_text, dxfattribs={
495
'height': 2.5,
496
'layer': 'TITLE'
497
})
498
499
# Unique identifier for drawing
500
drawing_id = guid()
501
id_text = msp.add_text(f"ID: {drawing_id}", dxfattribs={
502
'height': 1.5,
503
'insert': (0, -5),
504
'layer': 'TITLE'
505
})
506
507
# Dimension with suppressed zeros
508
dimension_value = "00012.5000"
509
clean_value = suppress_zeros(dimension_value)
510
dim_text = msp.add_text(f"Dimension: {clean_value}", dxfattribs={
511
'height': 2.0,
512
'insert': (0, -10),
513
'layer': 'DIMENSIONS'
514
})
515
516
# Hatch with pattern
517
if 'ANSI31' in patterns:
518
# Create boundary for hatch
519
boundary_points = [(10, 0), (20, 0), (20, 10), (10, 10)]
520
boundary = msp.add_lwpolyline(boundary_points, dxfattribs={'layer': 'HATCH_BOUNDARY'})
521
boundary.close()
522
523
# Create hatch with pattern
524
hatch = msp.add_hatch(dxfattribs={'layer': 'HATCHES'})
525
hatch.paths.add_polyline_path(boundary_points, is_closed=True)
526
hatch.set_pattern_fill('ANSI31', color=3, angle=45, scale=0.5)
527
528
# Save document
529
doc.saveas('tools_example.dxf')
530
print(f"Drawing saved with ID: {drawing_id}")
531
```