CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-ezdxf

A comprehensive Python package for creating, reading, modifying, and writing DXF (Drawing Exchange Format) documents with support for multiple DXF versions.

Pending
Overview
Eval results
Files

tools.mddocs/

Tools

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.

Capabilities

Date and Time Utilities

Conversion functions between Julian dates and standard datetime objects.

def juliandate(datetime) -> float:
    """
    Convert datetime object to Julian date number.
    
    Parameters:
    - datetime: Python datetime object
    
    Returns:
    float: Julian date number
    """

def calendardate(julian: float):
    """
    Convert Julian date number to datetime object.
    
    Parameters:
    - julian: Julian date number
    
    Returns:
    datetime: Python datetime object
    """

Usage examples:

from ezdxf.tools import juliandate, calendardate
from datetime import datetime

# Convert to Julian date
now = datetime.now()
julian = juliandate(now)
print(f"Current Julian date: {julian}")

# Convert back to datetime
converted = calendardate(julian)
print(f"Converted back: {converted}")

# Use in DXF entities (some entities store dates as Julian dates)
creation_date = juliandate(datetime(2023, 1, 1, 12, 0, 0))

Binary Data Utilities

Functions for handling binary data and hex string conversions.

def hex_strings_to_bytes(hex_strings) -> bytes:
    """
    Convert list of hex strings to bytes.
    
    Parameters:
    - hex_strings: list of hexadecimal strings
    
    Returns:
    bytes: Combined binary data
    """

def bytes_to_hexstr(data: bytes, group_size: int = 1, upper: bool = True) -> str:
    """
    Convert bytes to hex string representation.
    
    Parameters:
    - data: binary data
    - group_size: bytes per group (for spacing)
    - upper: use uppercase hex digits
    
    Returns:
    str: Hex string representation
    """

Usage examples:

from ezdxf.tools import hex_strings_to_bytes, bytes_to_hexstr

# Convert hex strings to binary
hex_data = ['48656C6C6F', '20576F726C64']  # "Hello World" in hex
binary_data = hex_strings_to_bytes(hex_data)
print(binary_data.decode('utf-8'))  # "Hello World"

# Convert binary to hex string
test_data = b"Test data"
hex_string = bytes_to_hexstr(test_data, group_size=2, upper=True)
print(f"Hex representation: {hex_string}")

String and Text Utilities

Text processing and formatting utilities for CAD-specific operations.

def escape(text: str) -> str:
    """
    HTML escape text for safe display.
    
    Parameters:
    - text: input text
    
    Returns:
    str: HTML-escaped text
    """

def guid() -> str:
    """
    Generate GUID string.
    
    Returns:
    str: GUID in standard format
    """

def suppress_zeros(s: str, leading: bool = True, trailing: bool = True) -> str:
    """
    Remove leading and/or trailing zeros from number strings.
    
    Parameters:
    - s: number string
    - leading: remove leading zeros
    - trailing: remove trailing zeros
    
    Returns:
    str: Formatted number string
    """

def normalize_text_angle(angle: float, fix_upside_down: bool = True) -> float:
    """
    Normalize text angle for readability.
    
    Parameters:
    - angle: text angle in radians
    - fix_upside_down: flip upside-down text
    
    Returns:
    float: Normalized angle
    """

Usage examples:

from ezdxf.tools import escape, guid, suppress_zeros, normalize_text_angle
import math

# HTML escape for safe display
unsafe_text = "<script>alert('test')</script>"
safe_text = escape(unsafe_text)
print(f"Escaped: {safe_text}")

# Generate unique identifier
unique_id = guid()
print(f"GUID: {unique_id}")

# Format numbers
number_str = "00012.3400"
clean_number = suppress_zeros(number_str, leading=True, trailing=True)
print(f"Cleaned: {clean_number}")  # "12.34"

# Normalize text angles
upside_down_angle = math.radians(200)  # 200 degrees
normalized = normalize_text_angle(upside_down_angle, fix_upside_down=True)
print(f"Normalized angle: {math.degrees(normalized)} degrees")

Binary Flag Utilities

Functions for manipulating binary flags in integer values.

def set_flag_state(flags: int, flag: int, state: bool = True) -> int:
    """
    Set or clear binary flag in integer value.
    
    Parameters:
    - flags: current flag value
    - flag: flag bit to modify
    - state: True to set, False to clear
    
    Returns:
    int: Modified flag value
    """

Usage examples:

from ezdxf.tools import set_flag_state

# Work with entity flags
current_flags = 0b00000000  # No flags set

# Set specific flags
current_flags = set_flag_state(current_flags, 0b00000001, True)   # Set bit 0
current_flags = set_flag_state(current_flags, 0b00000100, True)   # Set bit 2
current_flags = set_flag_state(current_flags, 0b00010000, True)   # Set bit 4

print(f"Flags: {bin(current_flags)}")  # 0b00010101

# Clear a flag
current_flags = set_flag_state(current_flags, 0b00000100, False)  # Clear bit 2
print(f"Flags: {bin(current_flags)}")  # 0b00010001

Iterator Utilities

Utility functions for processing sequences and iterables.

def take2(iterable):
    """
    Iterate sequence as non-overlapping pairs.
    
    Parameters:
    - iterable: sequence to process
    
    Yields:
    tuple: consecutive pairs of elements
    """

def pairwise(iterable, close: bool = False):
    """
    Iterate sequence as overlapping pairs.
    
    Parameters:
    - iterable: sequence to process
    - close: include pair from last to first element
    
    Yields:
    tuple: overlapping pairs of elements
    """

Usage examples:

from ezdxf.tools import take2, pairwise

# Process points as non-overlapping pairs
points = [(0, 0), (1, 1), (2, 0), (3, 1), (4, 0)]

# Non-overlapping pairs for line segments
for start, end in take2(points):
    line = msp.add_line(start, end)

# Overlapping pairs for connected polyline
vertices = []
for p1, p2 in pairwise(points, close=True):
    # Process each edge of the polygon
    vertices.extend([p1, p2])

# Create closed polyline
poly = msp.add_lwpolyline(points)
poly.close()

Hatch Pattern Management

Comprehensive hatch pattern loading, analysis, and manipulation utilities.

def load(measurement: int = 1, factor: float = 1.0):
    """
    Load hatch pattern definitions.
    
    Parameters:
    - measurement: measurement system (0=Imperial, 1=Metric)
    - factor: scaling factor for patterns
    
    Returns:  
    dict: Pattern definitions
    """

def scale_pattern(pattern, factor: float):
    """
    Scale individual hatch pattern.
    
    Parameters:
    - pattern: pattern definition
    - factor: scaling factor
    
    Returns:
    Pattern definition scaled by factor
    """

def scale_all(patterns, factor: float):
    """
    Scale all patterns in collection.
    
    Parameters:
    - patterns: pattern collection
    - factor: scaling factor
    
    Returns:
    Scaled pattern collection
    """

def parse(pattern_str: str):
    """
    Parse hatch pattern definition string.
    
    Parameters:
    - pattern_str: pattern definition in AutoCAD format
    
    Returns:
    Parsed pattern data structure
    """

class PatternAnalyser:
    """Hatch pattern analysis and validation"""
    
    def __init__(self, pattern): ...
    
    def analyse(self):
        """Analyze pattern structure and properties"""
        
    @property
    def line_count(self) -> int:
        """Number of pattern lines"""
        
    @property
    def is_valid(self) -> bool:
        """True if pattern is valid"""

# Pattern constants and type definitions
ISO_PATTERN: dict
    """ISO standard hatch patterns"""

IMPERIAL_PATTERN: dict
    """Imperial measurement hatch patterns"""

HatchPatternLineType = List[float]
HatchPatternType = List[HatchPatternLineType]

Usage examples:

from ezdxf.tools.pattern import load, scale_pattern, parse, PatternAnalyser
from ezdxf.tools.pattern import ISO_PATTERN

# Load standard patterns
metric_patterns = load(measurement=1, factor=1.0)  # Metric
imperial_patterns = load(measurement=0, factor=25.4)  # Imperial scaled to mm

# Scale specific pattern
if 'ANSI31' in metric_patterns:
    scaled_ansi31 = scale_pattern(metric_patterns['ANSI31'], 2.0)

# Parse custom pattern
custom_pattern_str = """*CUSTOM,Custom diagonal lines
45, 0,0, 0,2.83, 2.83,-1.41
"""
custom_pattern = parse(custom_pattern_str)

# Analyze pattern
analyser = PatternAnalyser(custom_pattern)
analyser.analyse()
print(f"Pattern has {analyser.line_count} lines")
print(f"Pattern is valid: {analyser.is_valid}")

# Use pattern in hatch
hatch = msp.add_hatch()
hatch.set_pattern_fill('ANSI31', color=1, angle=0, scale=1.0)
# Add boundary paths to hatch...

Standard Setup Tools

Functions for setting up standard drawing configurations, styles, and definitions.

def setup_drawing(doc, topics = None):
    """
    Setup standard drawing configuration.
    
    Parameters:
    - doc: DXF document
    - topics: list of setup topics ('linetypes', 'styles', 'dimstyles', etc.)
    """

def setup_linetypes(doc):
    """Setup standard AutoCAD linetypes in document"""

def setup_styles(doc):
    """Setup standard text styles in document"""

def setup_dimstyles(doc):
    """Setup standard dimension styles in document"""

def setup_dimstyle(doc, name: str):
    """
    Setup specific dimension style by name.
    
    Parameters:
    - doc: DXF document
    - name: dimension style name
    """

Usage examples:

from ezdxf.tools.standards import setup_linetypes, setup_styles, setup_dimstyles
import ezdxf

# Create document with standard setup
doc = ezdxf.new('R2018')

# Setup standard configurations
setup_linetypes(doc)   # CONTINUOUS, DASHED, DOTTED, etc.
setup_styles(doc)      # Standard text styles
setup_dimstyles(doc)   # Standard dimension styles

# Now you can use standard linetypes
line = doc.modelspace().add_line((0, 0), (10, 10), dxfattribs={
    'linetype': 'DASHED',
    'color': 1
})

# Check what was added
print("Available linetypes:")
for linetype in doc.linetypes:
    print(f"  {linetype.dxf.name}")

print("Available text styles:")  
for style in doc.styles:
    print(f"  {style.dxf.name}")

Transparency Utilities

Transparency conversion functions (also available in colors module).

def float2transparency(value: float) -> int:
    """Convert float transparency (0-1) to DXF format"""

def transparency2float(value: int) -> float:
    """Convert DXF transparency to float (0-1)"""

Additional Utilities

Various specialized utility functions for CAD operations.

# Text and string utilities
def text_size(text: str, font_size: float, font: str = None) -> tuple:
    """Estimate text size for layout calculations"""

def complex_ltype_definition(name: str, pattern, text_style: str = None):
    """Create complex linetype with text or shapes"""

# Debugging and analysis
def analyze_entity(entity):
    """Analyze entity structure and properties"""

def debug_entity(entity, stream = None):
    """Output detailed entity information for debugging"""

# Coordinate system utilities  
def ocs_to_wcs(points, ocs_axis):
    """Convert Object Coordinate System points to World Coordinate System"""

def wcs_to_ocs(points, ocs_axis):
    """Convert World Coordinate System points to Object Coordinate System"""

Complete Tools Usage Example

import ezdxf
from ezdxf.tools import juliandate, guid, suppress_zeros
from ezdxf.tools.pattern import load as load_patterns
from ezdxf.tools.standards import setup_drawing
from datetime import datetime

# Create document with full standard setup
doc = ezdxf.new('R2018')
setup_drawing(doc, topics=['linetypes', 'styles', 'dimstyles'])

# Load hatch patterns
patterns = load_patterns(measurement=1, factor=1.0)  # Metric patterns

msp = doc.modelspace()

# Create drawing with various tools utilities
# Date stamp using Julian date
creation_date = juliandate(datetime.now())
title_text = f"Drawing created: {datetime.now().strftime('%Y-%m-%d')}"
title = msp.add_text(title_text, dxfattribs={
    'height': 2.5,
    'layer': 'TITLE'
})

# Unique identifier for drawing
drawing_id = guid()
id_text = msp.add_text(f"ID: {drawing_id}", dxfattribs={
    'height': 1.5,
    'insert': (0, -5),
    'layer': 'TITLE'
})

# Dimension with suppressed zeros
dimension_value = "00012.5000"
clean_value = suppress_zeros(dimension_value)
dim_text = msp.add_text(f"Dimension: {clean_value}", dxfattribs={
    'height': 2.0,
    'insert': (0, -10),
    'layer': 'DIMENSIONS'
})

# Hatch with pattern
if 'ANSI31' in patterns:
    # Create boundary for hatch
    boundary_points = [(10, 0), (20, 0), (20, 10), (10, 10)]
    boundary = msp.add_lwpolyline(boundary_points, dxfattribs={'layer': 'HATCH_BOUNDARY'})
    boundary.close()
    
    # Create hatch with pattern
    hatch = msp.add_hatch(dxfattribs={'layer': 'HATCHES'})
    hatch.paths.add_polyline_path(boundary_points, is_closed=True)
    hatch.set_pattern_fill('ANSI31', color=3, angle=45, scale=0.5)

# Save document  
doc.saveas('tools_example.dxf')
print(f"Drawing saved with ID: {drawing_id}")

Install with Tessl CLI

npx tessl i tessl/pypi-ezdxf

docs

addons.md

colors.md

document-operations.md

entities.md

index.md

layouts.md

math.md

path-processing.md

rendering.md

tools.md

tile.json