or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

advanced-features.mdanalysis.mdcore-operations.mdfile-io.mdindex.mdmesh-processing.mdpoint-clouds.mdspatial-queries.mdvisualization.md

visualization.mddocs/

0

# Visualization and Rendering

1

2

Interactive 3D visualization, material and texture support, scene management, and integration with various rendering systems. Trimesh provides comprehensive tools for displaying, rendering, and exporting 3D content.

3

4

## Capabilities

5

6

### Interactive 3D Viewing

7

8

Display meshes and scenes in interactive 3D viewers.

9

10

```python { .api }

11

def show(self, viewer=None, **kwargs) -> None:

12

"""

13

Display mesh in interactive 3D viewer.

14

15

Parameters:

16

- viewer: str, viewer type ('gl', 'notebook', 'pyglet')

17

- **kwargs: viewer-specific options like window size, lighting

18

"""

19

20

def scene(self) -> Scene:

21

"""

22

Create Scene object containing this mesh.

23

24

Returns:

25

Scene object with mesh added

26

"""

27

28

class Scene:

29

"""Scene graph container for multiple geometries"""

30

31

def show(self, viewer=None, **kwargs) -> None:

32

"""Display scene in interactive viewer"""

33

34

def save_image(self, resolution=(1920, 1080), **kwargs) -> bytes:

35

"""

36

Render scene to image.

37

38

Parameters:

39

- resolution: (width, height) image size

40

- **kwargs: rendering options

41

42

Returns:

43

bytes, PNG image data

44

"""

45

```

46

47

### Visual Properties and Materials

48

49

Control appearance through colors, materials, and textures.

50

51

```python { .api }

52

@property

53

def visual(self):

54

"""Visual properties interface"""

55

56

class ColorVisuals:

57

"""Simple color-based visual properties"""

58

59

@property

60

def face_colors(self) -> np.ndarray:

61

"""

62

Face colors as (m, 4) RGBA array.

63

64

Returns:

65

(m, 4) face colors in RGBA format

66

"""

67

68

@face_colors.setter

69

def face_colors(self, colors: np.ndarray) -> None:

70

"""Set face colors"""

71

72

@property

73

def vertex_colors(self) -> np.ndarray:

74

"""

75

Vertex colors as (n, 4) RGBA array.

76

77

Returns:

78

(n, 4) vertex colors in RGBA format

79

"""

80

81

@vertex_colors.setter

82

def vertex_colors(self, colors: np.ndarray) -> None:

83

"""Set vertex colors"""

84

85

class TextureVisuals:

86

"""Texture-based visual properties"""

87

88

@property

89

def material(self):

90

"""Material properties object"""

91

92

@property

93

def uv(self) -> np.ndarray:

94

"""

95

UV texture coordinates.

96

97

Returns:

98

(n, 2) UV coordinates for vertices

99

"""

100

101

def copy(self) -> 'TextureVisuals':

102

"""Create copy of texture visuals"""

103

```

104

105

### Scene Management

106

107

Manage complex scenes with multiple objects and transformations.

108

109

```python { .api }

110

class Scene:

111

"""Scene graph for multiple geometries with transforms"""

112

113

@property

114

def geometry(self) -> dict:

115

"""Dictionary of geometry objects in scene"""

116

117

@property

118

def graph(self) -> dict:

119

"""Scene graph with transformation hierarchy"""

120

121

@property

122

def bounds(self) -> np.ndarray:

123

"""Combined bounds of all geometries"""

124

125

@property

126

def extents(self) -> np.ndarray:

127

"""Size of scene bounding box"""

128

129

@property

130

def centroid(self) -> np.ndarray:

131

"""Geometric center of scene"""

132

133

def add_geometry(self, geometry, node_name=None, geom_name=None, parent_node_name=None, transform=None) -> str:

134

"""

135

Add geometry to scene.

136

137

Parameters:

138

- geometry: Trimesh or other geometry object

139

- node_name: str, name for scene graph node

140

- geom_name: str, name for geometry object

141

- parent_node_name: str, parent node for hierarchy

142

- transform: (4, 4) transformation matrix

143

144

Returns:

145

str, name of created node

146

"""

147

148

def delete_geometry(self, names) -> None:

149

"""

150

Remove geometry from scene.

151

152

Parameters:

153

- names: str or list of geometry names to remove

154

"""

155

156

def set_camera_transform(self, transform=None, angles=None, distance=None, center=None) -> None:

157

"""

158

Set camera position and orientation.

159

160

Parameters:

161

- transform: (4, 4) camera transformation matrix

162

- angles: (3,) camera rotation angles

163

- distance: float, distance from center

164

- center: (3,) point to look at

165

"""

166

```

167

168

### Lighting and Shading

169

170

Control lighting conditions and shading models.

171

172

```python { .api }

173

def set_lights(self, lights=None) -> None:

174

"""

175

Set scene lighting.

176

177

Parameters:

178

- lights: list of light dictionaries or None for default

179

"""

180

181

class DirectionalLight:

182

"""Directional light source"""

183

def __init__(self, direction=[0, 0, -1], color=[1, 1, 1], intensity=1.0):

184

"""

185

Parameters:

186

- direction: (3,) light direction vector

187

- color: (3,) RGB color

188

- intensity: float, light intensity

189

"""

190

191

class PointLight:

192

"""Point light source"""

193

def __init__(self, position=[0, 0, 0], color=[1, 1, 1], intensity=1.0):

194

"""

195

Parameters:

196

- position: (3,) light position

197

- color: (3,) RGB color

198

- intensity: float, light intensity

199

"""

200

```

201

202

### Export and Rendering

203

204

Export scenes and render to various formats.

205

206

```python { .api }

207

def export(self, file_obj=None, file_type=None, **kwargs):

208

"""

209

Export scene to file.

210

211

Parameters:

212

- file_obj: file path or file-like object

213

- file_type: str, export format

214

- **kwargs: format-specific options

215

216

Returns:

217

bytes if file_obj is None

218

"""

219

220

def save_image(self, resolution=(1920, 1080), visible=True, **kwargs) -> bytes:

221

"""

222

Render scene to image.

223

224

Parameters:

225

- resolution: (width, height) pixel resolution

226

- visible: bool, show viewer window during render

227

- **kwargs: rendering options

228

229

Returns:

230

bytes, PNG image data

231

"""

232

233

def to_gltf(self, merge_buffers=True, **kwargs) -> dict:

234

"""

235

Convert scene to GLTF format.

236

237

Parameters:

238

- merge_buffers: bool, combine binary data

239

- **kwargs: GLTF export options

240

241

Returns:

242

dict, GLTF scene data

243

"""

244

```

245

246

### Jupyter Notebook Integration

247

248

Display meshes and scenes in Jupyter notebooks.

249

250

```python { .api }

251

def scene_to_notebook(scene, height=500, **kwargs):

252

"""

253

Display scene in Jupyter notebook.

254

255

Parameters:

256

- scene: Scene object to display

257

- height: int, viewer height in pixels

258

- **kwargs: notebook viewer options

259

260

Returns:

261

Interactive 3D widget for notebook

262

"""

263

264

def scene_to_html(scene, **kwargs) -> str:

265

"""

266

Generate HTML for scene visualization.

267

268

Parameters:

269

- scene: Scene object

270

- **kwargs: HTML generation options

271

272

Returns:

273

str, HTML content for 3D visualization

274

"""

275

276

def in_notebook() -> bool:

277

"""

278

Check if running in Jupyter notebook.

279

280

Returns:

281

bool, True if in notebook environment

282

"""

283

```

284

285

### Viewer Customization

286

287

Customize viewer appearance and behavior.

288

289

```python { .api }

290

class SceneViewer:

291

"""Interactive OpenGL scene viewer"""

292

293

def __init__(self, scene, start_loop=True, **kwargs):

294

"""

295

Parameters:

296

- scene: Scene object to display

297

- start_loop: bool, start event loop immediately

298

- **kwargs: viewer options

299

"""

300

301

def save_image(self, filename=None) -> None:

302

"""Save current view as image"""

303

304

def reset_view(self) -> None:

305

"""Reset camera to default position"""

306

307

def on_key_press(self, symbol, modifiers) -> None:

308

"""Handle keyboard input"""

309

310

def on_mouse_press(self, x, y, button, modifiers) -> None:

311

"""Handle mouse input"""

312

```

313

314

### Color and Texture Utilities

315

316

Work with colors, textures, and visual materials.

317

318

```python { .api }

319

def random_color() -> np.ndarray:

320

"""

321

Generate random RGBA color.

322

323

Returns:

324

(4,) RGBA color array

325

"""

326

327

def interpolate_color(color_a, color_b, factor) -> np.ndarray:

328

"""

329

Interpolate between two colors.

330

331

Parameters:

332

- color_a: (3,) or (4,) first color

333

- color_b: (3,) or (4,) second color

334

- factor: float, interpolation factor (0-1)

335

336

Returns:

337

Interpolated color array

338

"""

339

340

def to_rgba(colors) -> np.ndarray:

341

"""

342

Convert colors to RGBA format.

343

344

Parameters:

345

- colors: color array in various formats

346

347

Returns:

348

(n, 4) RGBA color array

349

"""

350

351

def vertex_colors_from_face_colors(mesh, face_colors) -> np.ndarray:

352

"""

353

Convert face colors to vertex colors by averaging.

354

355

Parameters:

356

- mesh: Trimesh object

357

- face_colors: (m, 3) or (m, 4) face colors

358

359

Returns:

360

(n, 4) vertex colors

361

"""

362

```

363

364

## Usage Examples

365

366

### Basic Visualization

367

368

```python

369

import trimesh

370

import numpy as np

371

372

# Load and display mesh

373

mesh = trimesh.load('model.stl')

374

mesh.show() # Opens interactive 3D viewer

375

376

# Create scene with multiple objects

377

scene = trimesh.Scene()

378

379

# Add meshes to scene

380

box = trimesh.primitives.Box(extents=[1, 1, 1])

381

sphere = trimesh.primitives.Sphere(radius=0.5)

382

383

# Position objects with transforms

384

box_transform = trimesh.transformations.translation_matrix([2, 0, 0])

385

sphere_transform = trimesh.transformations.translation_matrix([-2, 0, 0])

386

387

scene.add_geometry(box, transform=box_transform)

388

scene.add_geometry(sphere, transform=sphere_transform)

389

scene.add_geometry(mesh) # At origin

390

391

# Display scene

392

scene.show()

393

```

394

395

### Colors and Materials

396

397

```python

398

# Set solid colors

399

mesh.visual.face_colors = [255, 0, 0, 255] # Red faces

400

mesh.visual.vertex_colors = np.random.randint(0, 255, (len(mesh.vertices), 4)) # Random vertex colors

401

402

# Color faces by height

403

face_centers = mesh.triangles_center

404

heights = face_centers[:, 2] # Z-coordinates

405

normalized_heights = (heights - heights.min()) / (heights.max() - heights.min())

406

407

# Create color map

408

import matplotlib.pyplot as plt

409

colors = plt.cm.viridis(normalized_heights)

410

mesh.visual.face_colors = (colors * 255).astype(np.uint8)

411

412

mesh.show()

413

414

# Color vertices by curvature

415

if hasattr(mesh, 'discrete_mean_curvature_measure'):

416

curvature = mesh.discrete_mean_curvature_measure()

417

curvature_normalized = (curvature - curvature.min()) / (curvature.max() - curvature.min())

418

419

curvature_colors = plt.cm.coolwarm(curvature_normalized)

420

mesh.visual.vertex_colors = (curvature_colors * 255).astype(np.uint8)

421

mesh.show()

422

```

423

424

### Scene Management

425

426

```python

427

# Create complex scene

428

scene = trimesh.Scene()

429

430

# Add multiple geometries with different materials

431

geometries = [

432

(trimesh.primitives.Box(extents=[1, 1, 1]), [1, 0, 0], [0, 0, 0]), # Red box at origin

433

(trimesh.primitives.Sphere(radius=0.7), [0, 1, 0], [3, 0, 0]), # Green sphere

434

(trimesh.primitives.Cylinder(radius=0.5, height=2), [0, 0, 1], [0, 3, 0]), # Blue cylinder

435

]

436

437

for geom, color, position in geometries:

438

# Set color

439

geom.visual.face_colors = color + [1.0] # Add alpha

440

441

# Create transform

442

transform = trimesh.transformations.translation_matrix(position)

443

444

# Add to scene

445

scene.add_geometry(geom, transform=transform)

446

447

# Set camera position

448

scene.set_camera_transform(

449

distance=10,

450

center=[1.5, 1.5, 0],

451

angles=[np.pi/6, np.pi/4, 0]

452

)

453

454

# Display scene

455

scene.show()

456

457

# Save scene as image

458

image_data = scene.save_image(resolution=(1920, 1080))

459

with open('scene_render.png', 'wb') as f:

460

f.write(image_data)

461

```

462

463

### Custom Lighting

464

465

```python

466

# Create scene with custom lighting

467

scene = trimesh.Scene([mesh])

468

469

# Define multiple light sources

470

lights = [

471

{

472

'type': 'DirectionalLight',

473

'direction': [1, -1, -1],

474

'color': [1.0, 1.0, 1.0],

475

'intensity': 0.8

476

},

477

{

478

'type': 'DirectionalLight',

479

'direction': [-1, 1, 0.5],

480

'color': [0.8, 0.9, 1.0], # Slightly blue

481

'intensity': 0.4

482

},

483

{

484

'type': 'PointLight',

485

'position': [0, 0, 5],

486

'color': [1.0, 0.8, 0.6], # Warm color

487

'intensity': 0.6

488

}

489

]

490

491

scene.set_lights(lights)

492

scene.show()

493

```

494

495

### Jupyter Notebook Visualization

496

497

```python

498

# In Jupyter notebook

499

import trimesh

500

from trimesh.viewer import scene_to_notebook

501

502

# Create scene

503

mesh = trimesh.load('model.stl')

504

scene = mesh.scene()

505

506

# Display in notebook with custom height

507

scene_to_notebook(scene, height=600)

508

509

# Or generate HTML for embedding

510

html_content = trimesh.viewer.scene_to_html(scene)

511

from IPython.display import HTML

512

HTML(html_content)

513

```

514

515

### Advanced Visualization Techniques

516

517

```python

518

# Transparency and advanced materials

519

mesh.visual.face_colors = [128, 128, 255, 100] # Semi-transparent blue

520

521

# Wireframe visualization

522

edges = mesh.edges_unique

523

edge_viz = trimesh.load_path(mesh.vertices[edges])

524

edge_viz.colors = [255, 255, 255, 255] # White edges

525

526

# Combine mesh and wireframe in scene

527

scene = trimesh.Scene([mesh, edge_viz])

528

scene.show()

529

530

# Vertex highlighting

531

# Find boundary vertices (if mesh has boundary)

532

boundary_edges = mesh.edges[mesh.face_adjacency_edges[mesh.face_adjacency_unshared]]

533

boundary_vertices = np.unique(boundary_edges)

534

535

# Create vertex color array

536

vertex_colors = np.full((len(mesh.vertices), 4), [200, 200, 200, 255]) # Gray default

537

vertex_colors[boundary_vertices] = [255, 0, 0, 255] # Red boundary vertices

538

539

mesh.visual.vertex_colors = vertex_colors

540

mesh.show()

541

542

# Normal visualization

543

face_centers = mesh.triangles_center

544

face_normals = mesh.face_normals

545

normal_length = 0.1

546

547

# Create line segments for normals

548

normal_lines = []

549

for center, normal in zip(face_centers, face_normals):

550

normal_lines.extend([center, center + normal * normal_length])

551

552

normal_path = trimesh.load_path(np.array(normal_lines).reshape(-1, 3))

553

normal_path.colors = [0, 255, 0, 255] # Green normals

554

555

# Show mesh with normals

556

scene = trimesh.Scene([mesh, normal_path])

557

scene.show()

558

```

559

560

### Export and Rendering

561

562

```python

563

# Render high-quality images

564

scene = mesh.scene()

565

566

# Set up professional lighting

567

scene.set_lights([

568

{'type': 'DirectionalLight', 'direction': [1, -1, -1], 'intensity': 0.8},

569

{'type': 'DirectionalLight', 'direction': [-1, 1, 0.5], 'intensity': 0.3},

570

])

571

572

# Render at different resolutions

573

resolutions = [(1920, 1080), (3840, 2160), (1024, 1024)]

574

for i, res in enumerate(resolutions):

575

image_data = scene.save_image(resolution=res)

576

with open(f'render_{res[0]}x{res[1]}.png', 'wb') as f:

577

f.write(image_data)

578

579

# Export scene to various formats

580

scene.export('scene.gltf') # GLTF with materials

581

scene.export('scene.obj') # OBJ format

582

scene.export('scene.dae') # COLLADA format

583

584

# Export to web-friendly format

585

gltf_data = scene.to_gltf(merge_buffers=True)

586

import json

587

with open('scene_web.gltf', 'w') as f:

588

json.dump(gltf_data, f, indent=2)

589

```