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

rendering.mddocs/

Rendering

Advanced geometry processing including mesh construction, curve tessellation, and entity rendering to basic primitives. The rendering system supports both 2D and 3D geometry processing with optimization utilities.

Capabilities

Mesh Construction

3D mesh building utilities for creating, modifying, and optimizing polygon meshes.

class MeshBuilder:
    """3D mesh construction with vertices, faces, and materials"""
    
    def __init__(self): ...
    
    @property
    def vertices(self) -> List[Vec3]:
        """Vertex coordinates"""
        
    @property
    def faces(self) -> List[List[int]]:
        """Face definitions as vertex indices"""
        
    def add_vertex(self, vertex: Vec3) -> int:
        """Add vertex and return its index"""
        
    def add_vertices(self, vertices) -> List[int]:
        """Add multiple vertices and return their indices"""
        
    def add_face(self, face) -> 'MeshBuilder':
        """Add face defined by vertex indices"""
        
    def add_mesh(self, vertices = None, faces = None, mesh = None) -> 'MeshBuilder':
        """Add another mesh to this mesh"""
        
    def transform(self, matrix: Matrix44) -> 'MeshBuilder':
        """Transform all vertices by matrix"""
        
    def translate(self, dx: float, dy: float, dz: float) -> 'MeshBuilder':
        """Translate all vertices"""
        
    def scale(self, sx: float, sy: float, sz: float) -> 'MeshBuilder':
        """Scale all vertices"""
        
    def render_mesh(self, layout, dxfattribs: dict = None, matrix: Matrix44 = None):
        """Render mesh to layout as DXF entities"""
        
    def render_polyface(self, layout, dxfattribs: dict = None, matrix: Matrix44 = None):
        """Render mesh as POLYFACE entity"""

class MeshVertexMerger:
    """Utility for merging duplicate vertices in meshes"""
    
    def __init__(self, mesh: MeshBuilder, precision: int = 6): ...
    
    def merged_mesh(self) -> MeshBuilder:
        """Return mesh with merged vertices"""

class MeshAverageVertexMerger:
    """Merge vertices by averaging coordinates"""
    
    def __init__(self, mesh: MeshBuilder, precision: int = 6): ...

class MeshTransformer:
    """Advanced mesh transformation utilities"""
    
    def __init__(self, mesh: MeshBuilder): ...
    
    def subdivide_faces(self, quads: bool = True) -> MeshBuilder:
        """Subdivide mesh faces for smoother surfaces"""
        
    def subdivide_ngons(self, max_vertices: int = 4) -> MeshBuilder:
        """Subdivide n-gons into triangles or quads"""

Usage examples:

from ezdxf.render import MeshBuilder
from ezdxf.math import Vec3, Matrix44

# Create a simple pyramid mesh
mesh = MeshBuilder()

# Add vertices
v0 = mesh.add_vertex(Vec3(0, 0, 0))     # base vertices
v1 = mesh.add_vertex(Vec3(10, 0, 0))
v2 = mesh.add_vertex(Vec3(10, 10, 0))
v3 = mesh.add_vertex(Vec3(0, 10, 0))
v4 = mesh.add_vertex(Vec3(5, 5, 8))     # apex

# Add faces (triangles using vertex indices)
mesh.add_face([v0, v1, v4])  # side faces
mesh.add_face([v1, v2, v4])
mesh.add_face([v2, v3, v4])
mesh.add_face([v3, v0, v4])
mesh.add_face([v3, v2, v1, v0])  # base quad

# Transform mesh
matrix = Matrix44.z_rotate(math.radians(45))
mesh.transform(matrix)

# Render to layout
msp.render_mesh(mesh, dxfattribs={'color': 1})

Form Generators

Predefined geometric form generators for common shapes and patterns.

def circle(radius: float = 1, segments: int = None) -> List[Vec3]:
    """
    Generate circle vertex coordinates.
    
    Parameters:
    - radius: circle radius
    - segments: number of segments (auto-calculated if None)
    
    Returns:
    List[Vec3]: Circle vertices
    """

def ellipse(rx: float = 1, ry: float = 1, segments: int = None) -> List[Vec3]:
    """Generate ellipse vertex coordinates"""

def ngon(count: int, radius: float = 1, rotation: float = 0, 
         elevation: float = 0, close: bool = False) -> List[Vec3]:
    """
    Generate regular polygon vertices.
    
    Parameters:
    - count: number of sides
    - radius: circumscribed radius
    - rotation: rotation angle in radians
    - elevation: Z coordinate
    - close: add closing vertex
    """

def star(count: int, r1: float, r2: float, rotation: float = 0,
         elevation: float = 0, close: bool = False) -> List[Vec3]:
    """Generate star shape vertices with alternating radii"""

def box(width: float = 2, height: float = 1, depth: float = 1,
        center: bool = True) -> MeshBuilder:
    """Generate box/cube mesh"""

def cylinder(radius: float = 1, height: float = 1, segments: int = 16,
            caps: bool = True) -> MeshBuilder:
    """Generate cylinder mesh"""

def cone(radius: float = 1, height: float = 1, segments: int = 16,
         caps: bool = True) -> MeshBuilder:
    """Generate cone mesh"""

def sphere(radius: float = 1, stacks: int = 16, slices: int = 16) -> MeshBuilder:
    """Generate sphere mesh"""

Usage examples:

from ezdxf.render import forms
from ezdxf.math import Vec3
import math

# Generate basic shapes
circle_verts = forms.circle(radius=5, segments=20)
pentagon = forms.ngon(count=5, radius=3)
star_shape = forms.star(count=8, r1=5, r2=2.5)

# Create polylines from vertices
circle_poly = msp.add_lwpolyline(circle_verts)
circle_poly.close()

# Generate 3D meshes
box_mesh = forms.box(width=10, height=6, depth=4)
cylinder_mesh = forms.cylinder(radius=3, height=10, segments=12)
sphere_mesh = forms.sphere(radius=4, stacks=12, slices=16)

# Render meshes to layout
box_mesh.render_mesh(msp, dxfattribs={'color': 1})
cylinder_mesh.render_mesh(msp, dxfattribs={'color': 2})
sphere_mesh.render_mesh(msp, dxfattribs={'color': 3})

Curve Rendering

Curve tessellation and rendering utilities for converting mathematical curves to line segments and DXF entities.

class Bezier:
    """Bézier curve renderer"""
    
    @staticmethod
    def from_3_points(start: Vec3, control: Vec3, end: Vec3, segments: int = 20) -> List[Vec3]:
        """Create quadratic Bézier curve from 3 points"""
        
    @staticmethod
    def from_4_points(start: Vec3, ctrl1: Vec3, ctrl2: Vec3, end: Vec3, 
                     segments: int = 20) -> List[Vec3]:
        """Create cubic Bézier curve from 4 points"""

class EulerSpiral:
    """Euler spiral (clothoid) curve renderer"""
    
    @staticmethod
    def from_params(radius: float, curvature: float, length: float,
                   segments: int = 100) -> List[Vec3]:
        """Generate Euler spiral vertices"""

class Spline:
    """Spline curve rendering utilities"""
    
    @staticmethod  
    def from_fit_points(points, degree: int = 3, segments: int = 100) -> List[Vec3]:
        """Render spline from fit points"""
        
    @staticmethod
    def from_control_points(points, degree: int = 3, segments: int = 100) -> List[Vec3]:
        """Render spline from control points"""

class R12Spline:
    """DXF R12 compatible spline rendering"""
    
    @staticmethod
    def from_fit_points(points, segments: int = 100) -> List[Vec3]:
        """Render as polyline for R12 compatibility"""

Usage examples:

from ezdxf.render.curves import Bezier, Spline
from ezdxf.math import Vec3

# Bézier curves
start, ctrl, end = Vec3(0, 0), Vec3(5, 10), Vec3(10, 0)
bezier_points = Bezier.from_3_points(start, ctrl, end, segments=25)
bezier_poly = msp.add_lwpolyline(bezier_points)

# Cubic Bézier
ctrl_points = [Vec3(0, 0), Vec3(3, 8), Vec3(7, -3), Vec3(10, 5)]
cubic_points = Bezier.from_4_points(*ctrl_points, segments=30)

# Spline rendering
fit_points = [Vec3(i, math.sin(i), 0) for i in range(0, 10)]
spline_points = Spline.from_fit_points(fit_points, degree=3, segments=50)
spline_poly = msp.add_lwpolyline(spline_points)

Multi-leader Builders

Advanced multi-leader entity construction with support for text and block content.

class MultiLeaderBuilder:
    """Base multi-leader entity builder"""
    
    def __init__(self): ...
    
    def quick_leader(self, text: str, insert, leader_length: float = 4,
                    dogleg_length: float = 2) -> 'MultiLeader': ...

class MultiLeaderMTextBuilder:
    """Text-based multi-leader builder"""
    
    def __init__(self): ...
    
    def add_leader_line(self, start: Vec3, end: Vec3): ...
    def add_mtext_content(self, text: str, insert: Vec3, char_height: float = 2.5): ...
    
    def build(self, layout, override: dict = None, dxfattribs: dict = None) -> 'MultiLeader': ...

class MultiLeaderBlockBuilder:
    """Block-based multi-leader builder"""
    
    def __init__(self): ...
    
    def add_leader_line(self, start: Vec3, end: Vec3): ...
    def add_block_content(self, name: str, insert: Vec3, scale: float = 1.0): ...
    
    def build(self, layout, override: dict = None, dxfattribs: dict = None) -> 'MultiLeader': ...

# Enumerations for multi-leader configuration
class LeaderType(Enum):
    STRAIGHT = 0
    SPLINE = 1

class TextAlignment(Enum):
    LEFT = 0
    CENTER = 1  
    RIGHT = 2

class BlockAlignment(Enum):
    CENTER = 0
    INSERT_POINT = 1

Dimension Rendering

Dimension entity rendering utilities for creating measurement annotations.

class AngularDimension:
    """Angular dimension renderer"""
    
    @staticmethod
    def from_2_lines(line1_start: Vec3, line1_end: Vec3, line2_start: Vec3, 
                    line2_end: Vec3, dimstyle: str = 'EZDXF') -> List[DXFEntity]: ...

class Angular3PDimension:
    """3-point angular dimension renderer"""
    
    @staticmethod
    def from_3_points(center: Vec3, p1: Vec3, p2: Vec3,
                     dimstyle: str = 'EZDXF') -> List[DXFEntity]: ...

class ArcLengthDimension:
    """Arc length dimension renderer"""
    
    @staticmethod
    def from_arc(center: Vec3, radius: float, start_angle: float, end_angle: float,
                dimstyle: str = 'EZDXF') -> List[DXFEntity]: ...

class OrdinateDimension:
    """Ordinate dimension renderer"""
    
    @staticmethod
    def from_point(origin: Vec3, point: Vec3, axis: str = 'X',
                  dimstyle: str = 'EZDXF') -> List[DXFEntity]: ...

Trace Builders

Polyline and trace building utilities for creating complex linear features.

class TraceBuilder:
    """Base trace builder for polyline-like entities"""
    
    def __init__(self, width: float = 1.0): ...
    
    def add_vertex(self, location: Vec3, bulge: float = 0): ...
    def close(self): ...
    
    def render(self, layout, dxfattribs: dict = None) -> List[DXFEntity]: ...

class LinearTrace:
    """Linear trace with constant width"""
    
    def __init__(self, start: Vec3, end: Vec3, width: float): ...

class CurvedTrace:
    """Curved trace following a path"""
    
    def __init__(self, path, width: float): ...

Utility Functions

Miscellaneous rendering utilities and helper functions.

def virtual_entities(entity) -> List[DXFEntity]:
    """
    Extract virtual entities from complex entities like MLINE or MLEADER.
    
    Parameters:
    - entity: complex DXF entity
    
    Returns:
    List[DXFEntity]: Basic entities representing the complex entity
    """

def random_2d_path(count: int = 10, max_step: float = 1.0,
                  max_heading: float = math.pi/4) -> List[Vec2]:
    """Generate random 2D path for testing"""

def random_3d_path(count: int = 10, max_step: float = 1.0,
                  max_heading: float = math.pi/4) -> List[Vec3]:
    """Generate random 3D path for testing"""

Abstract Base Classes

class AbstractMTextRenderer:
    """Base class for custom MTEXT rendering implementations"""
    
    def word_wrap(self, text: str, box_width: float) -> List[str]: ...
    def get_font_measurements(self, char_height: float, font: str): ...
    def render_text(self, text: str, insert: Vec3, char_height: float): ...

Exception Classes

class MeshBuilderError(Exception):
    """Base exception for mesh construction errors"""

class NonManifoldMeshError(MeshBuilderError):
    """Mesh contains non-manifold geometry"""

class MultipleMeshesError(MeshBuilderError):
    """Operation requires single connected mesh"""

class NodeMergingError(Exception):
    """Error during vertex merging operations"""

class DegeneratedPathError(Exception):
    """Path contains degenerated segments"""

Usage examples:

from ezdxf.render import MeshBuilder, forms
from ezdxf.math import Vec3, Matrix44
import ezdxf

doc = ezdxf.new()
msp = doc.modelspace()

# Create complex mesh
mesh = MeshBuilder()

# Add box and cylinder
box = forms.box(width=5, height=5, depth=5)
cylinder = forms.cylinder(radius=2, height=8, segments=12)
cylinder.translate(0, 0, 5)  # Move cylinder up

# Combine meshes
mesh.add_mesh(mesh=box)
mesh.add_mesh(mesh=cylinder)

# Optimize mesh
from ezdxf.render import MeshVertexMerger
merger = MeshVertexMerger(mesh, precision=3)
optimized_mesh = merger.merged_mesh()

# Render to layout
optimized_mesh.render_mesh(msp, dxfattribs={
    'color': 1,
    'layer': 'MESH'
})

# Save document
doc.saveas('rendered_mesh.dxf')

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