or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

addons.mdcolors.mddocument-operations.mdentities.mdindex.mdlayouts.mdmath.mdpath-processing.mdrendering.mdtools.md

rendering.mddocs/

0

# Rendering

1

2

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.

3

4

## Capabilities

5

6

### Mesh Construction

7

8

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

9

10

```python { .api }

11

class MeshBuilder:

12

"""3D mesh construction with vertices, faces, and materials"""

13

14

def __init__(self): ...

15

16

@property

17

def vertices(self) -> List[Vec3]:

18

"""Vertex coordinates"""

19

20

@property

21

def faces(self) -> List[List[int]]:

22

"""Face definitions as vertex indices"""

23

24

def add_vertex(self, vertex: Vec3) -> int:

25

"""Add vertex and return its index"""

26

27

def add_vertices(self, vertices) -> List[int]:

28

"""Add multiple vertices and return their indices"""

29

30

def add_face(self, face) -> 'MeshBuilder':

31

"""Add face defined by vertex indices"""

32

33

def add_mesh(self, vertices = None, faces = None, mesh = None) -> 'MeshBuilder':

34

"""Add another mesh to this mesh"""

35

36

def transform(self, matrix: Matrix44) -> 'MeshBuilder':

37

"""Transform all vertices by matrix"""

38

39

def translate(self, dx: float, dy: float, dz: float) -> 'MeshBuilder':

40

"""Translate all vertices"""

41

42

def scale(self, sx: float, sy: float, sz: float) -> 'MeshBuilder':

43

"""Scale all vertices"""

44

45

def render_mesh(self, layout, dxfattribs: dict = None, matrix: Matrix44 = None):

46

"""Render mesh to layout as DXF entities"""

47

48

def render_polyface(self, layout, dxfattribs: dict = None, matrix: Matrix44 = None):

49

"""Render mesh as POLYFACE entity"""

50

51

class MeshVertexMerger:

52

"""Utility for merging duplicate vertices in meshes"""

53

54

def __init__(self, mesh: MeshBuilder, precision: int = 6): ...

55

56

def merged_mesh(self) -> MeshBuilder:

57

"""Return mesh with merged vertices"""

58

59

class MeshAverageVertexMerger:

60

"""Merge vertices by averaging coordinates"""

61

62

def __init__(self, mesh: MeshBuilder, precision: int = 6): ...

63

64

class MeshTransformer:

65

"""Advanced mesh transformation utilities"""

66

67

def __init__(self, mesh: MeshBuilder): ...

68

69

def subdivide_faces(self, quads: bool = True) -> MeshBuilder:

70

"""Subdivide mesh faces for smoother surfaces"""

71

72

def subdivide_ngons(self, max_vertices: int = 4) -> MeshBuilder:

73

"""Subdivide n-gons into triangles or quads"""

74

```

75

76

Usage examples:

77

```python

78

from ezdxf.render import MeshBuilder

79

from ezdxf.math import Vec3, Matrix44

80

81

# Create a simple pyramid mesh

82

mesh = MeshBuilder()

83

84

# Add vertices

85

v0 = mesh.add_vertex(Vec3(0, 0, 0)) # base vertices

86

v1 = mesh.add_vertex(Vec3(10, 0, 0))

87

v2 = mesh.add_vertex(Vec3(10, 10, 0))

88

v3 = mesh.add_vertex(Vec3(0, 10, 0))

89

v4 = mesh.add_vertex(Vec3(5, 5, 8)) # apex

90

91

# Add faces (triangles using vertex indices)

92

mesh.add_face([v0, v1, v4]) # side faces

93

mesh.add_face([v1, v2, v4])

94

mesh.add_face([v2, v3, v4])

95

mesh.add_face([v3, v0, v4])

96

mesh.add_face([v3, v2, v1, v0]) # base quad

97

98

# Transform mesh

99

matrix = Matrix44.z_rotate(math.radians(45))

100

mesh.transform(matrix)

101

102

# Render to layout

103

msp.render_mesh(mesh, dxfattribs={'color': 1})

104

```

105

106

### Form Generators

107

108

Predefined geometric form generators for common shapes and patterns.

109

110

```python { .api }

111

def circle(radius: float = 1, segments: int = None) -> List[Vec3]:

112

"""

113

Generate circle vertex coordinates.

114

115

Parameters:

116

- radius: circle radius

117

- segments: number of segments (auto-calculated if None)

118

119

Returns:

120

List[Vec3]: Circle vertices

121

"""

122

123

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

124

"""Generate ellipse vertex coordinates"""

125

126

def ngon(count: int, radius: float = 1, rotation: float = 0,

127

elevation: float = 0, close: bool = False) -> List[Vec3]:

128

"""

129

Generate regular polygon vertices.

130

131

Parameters:

132

- count: number of sides

133

- radius: circumscribed radius

134

- rotation: rotation angle in radians

135

- elevation: Z coordinate

136

- close: add closing vertex

137

"""

138

139

def star(count: int, r1: float, r2: float, rotation: float = 0,

140

elevation: float = 0, close: bool = False) -> List[Vec3]:

141

"""Generate star shape vertices with alternating radii"""

142

143

def box(width: float = 2, height: float = 1, depth: float = 1,

144

center: bool = True) -> MeshBuilder:

145

"""Generate box/cube mesh"""

146

147

def cylinder(radius: float = 1, height: float = 1, segments: int = 16,

148

caps: bool = True) -> MeshBuilder:

149

"""Generate cylinder mesh"""

150

151

def cone(radius: float = 1, height: float = 1, segments: int = 16,

152

caps: bool = True) -> MeshBuilder:

153

"""Generate cone mesh"""

154

155

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

156

"""Generate sphere mesh"""

157

```

158

159

Usage examples:

160

```python

161

from ezdxf.render import forms

162

from ezdxf.math import Vec3

163

import math

164

165

# Generate basic shapes

166

circle_verts = forms.circle(radius=5, segments=20)

167

pentagon = forms.ngon(count=5, radius=3)

168

star_shape = forms.star(count=8, r1=5, r2=2.5)

169

170

# Create polylines from vertices

171

circle_poly = msp.add_lwpolyline(circle_verts)

172

circle_poly.close()

173

174

# Generate 3D meshes

175

box_mesh = forms.box(width=10, height=6, depth=4)

176

cylinder_mesh = forms.cylinder(radius=3, height=10, segments=12)

177

sphere_mesh = forms.sphere(radius=4, stacks=12, slices=16)

178

179

# Render meshes to layout

180

box_mesh.render_mesh(msp, dxfattribs={'color': 1})

181

cylinder_mesh.render_mesh(msp, dxfattribs={'color': 2})

182

sphere_mesh.render_mesh(msp, dxfattribs={'color': 3})

183

```

184

185

### Curve Rendering

186

187

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

188

189

```python { .api }

190

class Bezier:

191

"""Bézier curve renderer"""

192

193

@staticmethod

194

def from_3_points(start: Vec3, control: Vec3, end: Vec3, segments: int = 20) -> List[Vec3]:

195

"""Create quadratic Bézier curve from 3 points"""

196

197

@staticmethod

198

def from_4_points(start: Vec3, ctrl1: Vec3, ctrl2: Vec3, end: Vec3,

199

segments: int = 20) -> List[Vec3]:

200

"""Create cubic Bézier curve from 4 points"""

201

202

class EulerSpiral:

203

"""Euler spiral (clothoid) curve renderer"""

204

205

@staticmethod

206

def from_params(radius: float, curvature: float, length: float,

207

segments: int = 100) -> List[Vec3]:

208

"""Generate Euler spiral vertices"""

209

210

class Spline:

211

"""Spline curve rendering utilities"""

212

213

@staticmethod

214

def from_fit_points(points, degree: int = 3, segments: int = 100) -> List[Vec3]:

215

"""Render spline from fit points"""

216

217

@staticmethod

218

def from_control_points(points, degree: int = 3, segments: int = 100) -> List[Vec3]:

219

"""Render spline from control points"""

220

221

class R12Spline:

222

"""DXF R12 compatible spline rendering"""

223

224

@staticmethod

225

def from_fit_points(points, segments: int = 100) -> List[Vec3]:

226

"""Render as polyline for R12 compatibility"""

227

```

228

229

Usage examples:

230

```python

231

from ezdxf.render.curves import Bezier, Spline

232

from ezdxf.math import Vec3

233

234

# Bézier curves

235

start, ctrl, end = Vec3(0, 0), Vec3(5, 10), Vec3(10, 0)

236

bezier_points = Bezier.from_3_points(start, ctrl, end, segments=25)

237

bezier_poly = msp.add_lwpolyline(bezier_points)

238

239

# Cubic Bézier

240

ctrl_points = [Vec3(0, 0), Vec3(3, 8), Vec3(7, -3), Vec3(10, 5)]

241

cubic_points = Bezier.from_4_points(*ctrl_points, segments=30)

242

243

# Spline rendering

244

fit_points = [Vec3(i, math.sin(i), 0) for i in range(0, 10)]

245

spline_points = Spline.from_fit_points(fit_points, degree=3, segments=50)

246

spline_poly = msp.add_lwpolyline(spline_points)

247

```

248

249

### Multi-leader Builders

250

251

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

252

253

```python { .api }

254

class MultiLeaderBuilder:

255

"""Base multi-leader entity builder"""

256

257

def __init__(self): ...

258

259

def quick_leader(self, text: str, insert, leader_length: float = 4,

260

dogleg_length: float = 2) -> 'MultiLeader': ...

261

262

class MultiLeaderMTextBuilder:

263

"""Text-based multi-leader builder"""

264

265

def __init__(self): ...

266

267

def add_leader_line(self, start: Vec3, end: Vec3): ...

268

def add_mtext_content(self, text: str, insert: Vec3, char_height: float = 2.5): ...

269

270

def build(self, layout, override: dict = None, dxfattribs: dict = None) -> 'MultiLeader': ...

271

272

class MultiLeaderBlockBuilder:

273

"""Block-based multi-leader builder"""

274

275

def __init__(self): ...

276

277

def add_leader_line(self, start: Vec3, end: Vec3): ...

278

def add_block_content(self, name: str, insert: Vec3, scale: float = 1.0): ...

279

280

def build(self, layout, override: dict = None, dxfattribs: dict = None) -> 'MultiLeader': ...

281

282

# Enumerations for multi-leader configuration

283

class LeaderType(Enum):

284

STRAIGHT = 0

285

SPLINE = 1

286

287

class TextAlignment(Enum):

288

LEFT = 0

289

CENTER = 1

290

RIGHT = 2

291

292

class BlockAlignment(Enum):

293

CENTER = 0

294

INSERT_POINT = 1

295

```

296

297

### Dimension Rendering

298

299

Dimension entity rendering utilities for creating measurement annotations.

300

301

```python { .api }

302

class AngularDimension:

303

"""Angular dimension renderer"""

304

305

@staticmethod

306

def from_2_lines(line1_start: Vec3, line1_end: Vec3, line2_start: Vec3,

307

line2_end: Vec3, dimstyle: str = 'EZDXF') -> List[DXFEntity]: ...

308

309

class Angular3PDimension:

310

"""3-point angular dimension renderer"""

311

312

@staticmethod

313

def from_3_points(center: Vec3, p1: Vec3, p2: Vec3,

314

dimstyle: str = 'EZDXF') -> List[DXFEntity]: ...

315

316

class ArcLengthDimension:

317

"""Arc length dimension renderer"""

318

319

@staticmethod

320

def from_arc(center: Vec3, radius: float, start_angle: float, end_angle: float,

321

dimstyle: str = 'EZDXF') -> List[DXFEntity]: ...

322

323

class OrdinateDimension:

324

"""Ordinate dimension renderer"""

325

326

@staticmethod

327

def from_point(origin: Vec3, point: Vec3, axis: str = 'X',

328

dimstyle: str = 'EZDXF') -> List[DXFEntity]: ...

329

```

330

331

### Trace Builders

332

333

Polyline and trace building utilities for creating complex linear features.

334

335

```python { .api }

336

class TraceBuilder:

337

"""Base trace builder for polyline-like entities"""

338

339

def __init__(self, width: float = 1.0): ...

340

341

def add_vertex(self, location: Vec3, bulge: float = 0): ...

342

def close(self): ...

343

344

def render(self, layout, dxfattribs: dict = None) -> List[DXFEntity]: ...

345

346

class LinearTrace:

347

"""Linear trace with constant width"""

348

349

def __init__(self, start: Vec3, end: Vec3, width: float): ...

350

351

class CurvedTrace:

352

"""Curved trace following a path"""

353

354

def __init__(self, path, width: float): ...

355

```

356

357

### Utility Functions

358

359

Miscellaneous rendering utilities and helper functions.

360

361

```python { .api }

362

def virtual_entities(entity) -> List[DXFEntity]:

363

"""

364

Extract virtual entities from complex entities like MLINE or MLEADER.

365

366

Parameters:

367

- entity: complex DXF entity

368

369

Returns:

370

List[DXFEntity]: Basic entities representing the complex entity

371

"""

372

373

def random_2d_path(count: int = 10, max_step: float = 1.0,

374

max_heading: float = math.pi/4) -> List[Vec2]:

375

"""Generate random 2D path for testing"""

376

377

def random_3d_path(count: int = 10, max_step: float = 1.0,

378

max_heading: float = math.pi/4) -> List[Vec3]:

379

"""Generate random 3D path for testing"""

380

```

381

382

## Abstract Base Classes

383

384

```python { .api }

385

class AbstractMTextRenderer:

386

"""Base class for custom MTEXT rendering implementations"""

387

388

def word_wrap(self, text: str, box_width: float) -> List[str]: ...

389

def get_font_measurements(self, char_height: float, font: str): ...

390

def render_text(self, text: str, insert: Vec3, char_height: float): ...

391

```

392

393

## Exception Classes

394

395

```python { .api }

396

class MeshBuilderError(Exception):

397

"""Base exception for mesh construction errors"""

398

399

class NonManifoldMeshError(MeshBuilderError):

400

"""Mesh contains non-manifold geometry"""

401

402

class MultipleMeshesError(MeshBuilderError):

403

"""Operation requires single connected mesh"""

404

405

class NodeMergingError(Exception):

406

"""Error during vertex merging operations"""

407

408

class DegeneratedPathError(Exception):

409

"""Path contains degenerated segments"""

410

```

411

412

Usage examples:

413

```python

414

from ezdxf.render import MeshBuilder, forms

415

from ezdxf.math import Vec3, Matrix44

416

import ezdxf

417

418

doc = ezdxf.new()

419

msp = doc.modelspace()

420

421

# Create complex mesh

422

mesh = MeshBuilder()

423

424

# Add box and cylinder

425

box = forms.box(width=5, height=5, depth=5)

426

cylinder = forms.cylinder(radius=2, height=8, segments=12)

427

cylinder.translate(0, 0, 5) # Move cylinder up

428

429

# Combine meshes

430

mesh.add_mesh(mesh=box)

431

mesh.add_mesh(mesh=cylinder)

432

433

# Optimize mesh

434

from ezdxf.render import MeshVertexMerger

435

merger = MeshVertexMerger(mesh, precision=3)

436

optimized_mesh = merger.merged_mesh()

437

438

# Render to layout

439

optimized_mesh.render_mesh(msp, dxfattribs={

440

'color': 1,

441

'layer': 'MESH'

442

})

443

444

# Save document

445

doc.saveas('rendered_mesh.dxf')

446

```