or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

index.mdmaterials.mdmath-utilities.mdpost-processing.mdscene-data.mdscene-loading.md

scene-data.mddocs/

0

# Scene Data Structures

1

2

Complete scene graph representation including nodes, meshes, materials, textures, animations, cameras, lights, and metadata. PyAssimp provides hierarchical access to all 3D scene components with Python-friendly data structures and optional NumPy array integration.

3

4

## Capabilities

5

6

### Scene Container

7

8

Root container for all 3D scene data and resources.

9

10

```python { .api }

11

class Scene:

12

"""

13

Root scene container holding all 3D data.

14

15

Attributes:

16

- rootnode: Node, root node of scene hierarchy

17

- meshes: list, list of Mesh objects

18

- materials: list, list of Material objects

19

- textures: list, list of embedded Texture objects

20

- animations: list, list of Animation sequences

21

- cameras: list, list of Camera objects

22

- lights: list, list of Light objects

23

"""

24

rootnode: Node

25

meshes: list

26

materials: list

27

textures: list

28

animations: list

29

cameras: list

30

lights: list

31

```

32

33

Usage examples:

34

35

```python

36

import pyassimp

37

38

scene = pyassimp.load("model.dae")

39

40

# Access scene components

41

print(f"Scene has {len(scene.meshes)} meshes")

42

print(f"Scene has {len(scene.materials)} materials")

43

print(f"Scene has {len(scene.textures)} embedded textures")

44

print(f"Scene has {len(scene.animations)} animations")

45

46

# Traverse scene hierarchy

47

def print_node_hierarchy(node, depth=0):

48

indent = " " * depth

49

print(f"{indent}Node: {node.name}")

50

print(f"{indent} Meshes: {len(node.meshes)}")

51

print(f"{indent} Children: {len(node.children)}")

52

53

for child in node.children:

54

print_node_hierarchy(child, depth + 1)

55

56

print_node_hierarchy(scene.rootnode)

57

58

pyassimp.release(scene)

59

```

60

61

### Scene Graph Nodes

62

63

Hierarchical scene graph nodes containing transformation data and mesh references.

64

65

```python { .api }

66

class Node:

67

"""

68

Scene graph node representing spatial hierarchy.

69

70

Attributes:

71

- name: str, node name/identifier

72

- transformation: array, 4x4 transformation matrix (numpy array if available)

73

- parent: Node, parent node (None for root)

74

- children: list, child Node objects

75

- meshes: list, mesh references/indices for this node

76

"""

77

name: str

78

transformation: array

79

parent: Node

80

children: list

81

meshes: list

82

```

83

84

Usage examples:

85

86

```python

87

import pyassimp

88

import numpy as np

89

90

scene = pyassimp.load("model.dae")

91

92

def process_node(node):

93

print(f"Processing node: {node.name}")

94

95

# Access transformation matrix

96

if hasattr(node, 'transformation'):

97

transform = node.transformation

98

print(f"Transform matrix shape: {transform.shape if hasattr(transform, 'shape') else len(transform)}")

99

100

# Decompose transformation if needed

101

if isinstance(transform, np.ndarray):

102

# NumPy array - can do matrix operations

103

position = transform[:3, 3] # Translation component

104

print(f"Position: {position}")

105

106

# Process node meshes

107

for mesh_ref in node.meshes:

108

mesh = scene.meshes[mesh_ref] if isinstance(mesh_ref, int) else mesh_ref

109

print(f" Mesh: {len(mesh.vertices)} vertices")

110

111

# Recursively process children

112

for child in node.children:

113

process_node(child)

114

115

process_node(scene.rootnode)

116

pyassimp.release(scene)

117

```

118

119

### Mesh Data

120

121

3D mesh geometry data including vertices, faces, normals, texture coordinates, and vertex attributes.

122

123

```python { .api }

124

class Mesh:

125

"""

126

3D mesh data container.

127

128

Attributes:

129

- vertices: array, vertex positions (Nx3)

130

- normals: array, vertex normals (Nx3)

131

- faces: array, face indices

132

- texturecoords: array, UV coordinates (per texture channel)

133

- colors: array, vertex colors (per color channel)

134

- tangents: array, tangent vectors (Nx3)

135

- bitangents: array, bitangent vectors (Nx3)

136

- materialindex: int, index into scene materials list

137

- name: str, mesh name

138

"""

139

vertices: array

140

normals: array

141

faces: array

142

texturecoords: array

143

colors: array

144

tangents: array

145

bitangents: array

146

materialindex: int

147

name: str

148

```

149

150

Usage examples:

151

152

```python

153

import pyassimp

154

import numpy as np

155

156

scene = pyassimp.load("model.obj", processing=pyassimp.postprocess.aiProcess_Triangulate)

157

158

for i, mesh in enumerate(scene.meshes):

159

print(f"Mesh {i}: {mesh.name}")

160

161

# Vertex data

162

print(f" Vertices: {len(mesh.vertices)} ({mesh.vertices.shape if hasattr(mesh.vertices, 'shape') else 'list'})")

163

164

# Face data

165

print(f" Faces: {len(mesh.faces)}")

166

if mesh.faces:

167

face = mesh.faces[0]

168

print(f" First face indices: {face.indices if hasattr(face, 'indices') else face}")

169

170

# Normal data

171

if hasattr(mesh, 'normals') and mesh.normals is not None:

172

print(f" Normals: {len(mesh.normals)}")

173

174

# UV coordinates

175

if hasattr(mesh, 'texturecoords') and mesh.texturecoords is not None:

176

uv_channels = len(mesh.texturecoords) if isinstance(mesh.texturecoords, list) else 1

177

print(f" UV channels: {uv_channels}")

178

179

# Vertex colors

180

if hasattr(mesh, 'colors') and mesh.colors is not None:

181

color_channels = len(mesh.colors) if isinstance(mesh.colors, list) else 1

182

print(f" Color channels: {color_channels}")

183

184

# Material reference

185

print(f" Material index: {mesh.materialindex}")

186

if mesh.materialindex < len(scene.materials):

187

material = scene.materials[mesh.materialindex]

188

print(f" Material properties: {len(material.properties)}")

189

190

pyassimp.release(scene)

191

```

192

193

### Face Data

194

195

Polygon face definitions with vertex indices.

196

197

```python { .api }

198

class Face:

199

"""

200

Polygon face with vertex indices.

201

202

Attributes:

203

- indices: list, vertex indices forming this face

204

"""

205

indices: list

206

```

207

208

Usage examples:

209

210

```python

211

import pyassimp

212

213

scene = pyassimp.load("model.ply", processing=pyassimp.postprocess.aiProcess_Triangulate)

214

215

mesh = scene.meshes[0]

216

print(f"Mesh has {len(mesh.faces)} faces")

217

218

# Access face data

219

for i, face in enumerate(mesh.faces[:5]): # First 5 faces

220

if hasattr(face, 'indices'):

221

indices = face.indices

222

else:

223

indices = face # May be direct list after processing

224

225

print(f"Face {i}: vertices {indices}")

226

227

# Access vertex positions for this face

228

if hasattr(indices, '__iter__'):

229

for vertex_idx in indices:

230

if vertex_idx < len(mesh.vertices):

231

vertex = mesh.vertices[vertex_idx]

232

print(f" Vertex {vertex_idx}: {vertex}")

233

234

pyassimp.release(scene)

235

```

236

237

### Animation Data

238

239

Animation sequences and keyframe data.

240

241

```python { .api }

242

class Animation:

243

"""

244

Animation sequence data.

245

246

Attributes:

247

- name: str, animation name

248

- duration: float, animation duration

249

- tickspersecond: float, time units per second

250

- channels: list, animation channels for different nodes

251

"""

252

name: str

253

duration: float

254

tickspersecond: float

255

channels: list

256

```

257

258

Usage examples:

259

260

```python

261

import pyassimp

262

263

scene = pyassimp.load("animated_model.dae")

264

265

if scene.animations:

266

for i, animation in enumerate(scene.animations):

267

print(f"Animation {i}: {animation.name}")

268

print(f" Duration: {animation.duration}")

269

print(f" Ticks per second: {animation.tickspersecond}")

270

print(f" Channels: {len(animation.channels)}")

271

272

# Process animation channels

273

for channel in animation.channels:

274

print(f" Channel node: {channel.nodename if hasattr(channel, 'nodename') else 'unknown'}")

275

276

pyassimp.release(scene)

277

```

278

279

### Camera Data

280

281

3D camera definitions with projection parameters.

282

283

```python { .api }

284

class Camera:

285

"""

286

3D camera definition.

287

288

Attributes:

289

- name: str, camera name

290

- position: Vector3D, camera position

291

- lookat: Vector3D, look-at target direction

292

- up: Vector3D, up vector

293

- horizontalfov: float, horizontal field of view

294

- aspect: float, aspect ratio

295

- clipplanenear: float, near clipping plane

296

- clipplanefar: float, far clipping plane

297

"""

298

name: str

299

position: Vector3D

300

lookat: Vector3D

301

up: Vector3D

302

horizontalfov: float

303

aspect: float

304

clipplanenear: float

305

clipplanefar: float

306

```

307

308

Usage examples:

309

310

```python

311

import pyassimp

312

313

scene = pyassimp.load("scene_with_camera.dae")

314

315

if scene.cameras:

316

for i, camera in enumerate(scene.cameras):

317

print(f"Camera {i}: {camera.name}")

318

if hasattr(camera, 'position'):

319

pos = camera.position

320

print(f" Position: ({pos.x}, {pos.y}, {pos.z})")

321

if hasattr(camera, 'horizontalfov'):

322

print(f" FOV: {camera.horizontalfov} radians")

323

if hasattr(camera, 'aspect'):

324

print(f" Aspect ratio: {camera.aspect}")

325

326

pyassimp.release(scene)

327

```

328

329

### Light Data

330

331

Scene lighting definitions.

332

333

```python { .api }

334

class Light:

335

"""

336

Light source definition.

337

338

Attributes:

339

- name: str, light name

340

- type: int, light type (directional, point, spot, etc.)

341

- position: Vector3D, light position

342

- direction: Vector3D, light direction

343

- colorambient: Color3D, ambient color

344

- colordiffuse: Color3D, diffuse color

345

- colorspecular: Color3D, specular color

346

- attenuation*: float, attenuation parameters

347

- angle*: float, spotlight angle parameters

348

"""

349

name: str

350

type: int

351

position: Vector3D

352

direction: Vector3D

353

colorambient: Color3D

354

colordiffuse: Color3D

355

colorspecular: Color3D

356

```

357

358

Usage examples:

359

360

```python

361

import pyassimp

362

363

scene = pyassimp.load("lit_scene.dae")

364

365

if scene.lights:

366

for i, light in enumerate(scene.lights):

367

print(f"Light {i}: {light.name}")

368

if hasattr(light, 'type'):

369

print(f" Type: {light.type}")

370

if hasattr(light, 'colordiffuse'):

371

color = light.colordiffuse

372

print(f" Diffuse color: ({color.r}, {color.g}, {color.b})")

373

374

pyassimp.release(scene)

375

```

376

377

### Metadata

378

379

Key-value metadata storage for additional scene information.

380

381

```python { .api }

382

class Metadata:

383

"""

384

Key-value metadata container.

385

386

Attributes:

387

- keys: list, metadata key names

388

- values: list, MetadataEntry objects with typed values

389

"""

390

keys: list

391

values: list

392

393

class MetadataEntry:

394

"""

395

Individual metadata entry with type information.

396

397

Attributes:

398

- type: int, data type identifier

399

- data: any, typed data value

400

401

Type Constants:

402

- AI_BOOL = 0, boolean value

403

- AI_INT32 = 1, 32-bit integer

404

- AI_UINT64 = 2, 64-bit unsigned integer

405

- AI_FLOAT = 3, floating point number

406

- AI_DOUBLE = 4, double precision float

407

- AI_AISTRING = 5, string value

408

- AI_AIVECTOR3D = 6, 3D vector

409

"""

410

type: int

411

data: any

412

413

AI_BOOL = 0

414

AI_INT32 = 1

415

AI_UINT64 = 2

416

AI_FLOAT = 3

417

AI_DOUBLE = 4

418

AI_AISTRING = 5

419

AI_AIVECTOR3D = 6

420

```

421

422

Usage examples:

423

424

```python

425

import pyassimp

426

427

scene = pyassimp.load("model_with_metadata.dae")

428

429

# Check for metadata on scene root

430

if hasattr(scene.rootnode, 'metadata') and scene.rootnode.metadata:

431

metadata = scene.rootnode.metadata

432

print(f"Metadata entries: {len(metadata.keys)}")

433

434

for key, value_entry in zip(metadata.keys, metadata.values):

435

print(f" {key}: {value_entry.data} (type: {value_entry.type})")

436

437

pyassimp.release(scene)

438

```

439

440

## Data Access Patterns

441

442

### Efficient Vertex Processing

443

444

```python

445

import pyassimp

446

import numpy as np

447

448

scene = pyassimp.load("model.obj")

449

450

for mesh in scene.meshes:

451

# Direct access to vertex arrays

452

vertices = mesh.vertices

453

454

if isinstance(vertices, np.ndarray):

455

# NumPy array - efficient operations

456

centroid = np.mean(vertices, axis=0)

457

bounds_min = np.min(vertices, axis=0)

458

bounds_max = np.max(vertices, axis=0)

459

print(f"Centroid: {centroid}")

460

print(f"Bounds: {bounds_min} to {bounds_max}")

461

else:

462

# Python list - slower but compatible

463

if vertices:

464

centroid = [sum(v[i] for v in vertices)/len(vertices) for i in range(3)]

465

print(f"Centroid: {centroid}")

466

467

pyassimp.release(scene)

468

```

469

470

### Scene Statistics

471

472

```python

473

import pyassimp

474

475

def analyze_scene(filename):

476

scene = pyassimp.load(filename)

477

478

stats = {

479

'nodes': 0,

480

'meshes': len(scene.meshes),

481

'materials': len(scene.materials),

482

'textures': len(scene.textures),

483

'animations': len(scene.animations),

484

'cameras': len(scene.cameras),

485

'lights': len(scene.lights),

486

'total_vertices': 0,

487

'total_faces': 0

488

}

489

490

def count_nodes(node):

491

stats['nodes'] += 1

492

for child in node.children:

493

count_nodes(child)

494

495

count_nodes(scene.rootnode)

496

497

for mesh in scene.meshes:

498

stats['total_vertices'] += len(mesh.vertices) if mesh.vertices else 0

499

stats['total_faces'] += len(mesh.faces) if mesh.faces else 0

500

501

pyassimp.release(scene)

502

return stats

503

504

# Usage

505

stats = analyze_scene("complex_model.dae")

506

for key, value in stats.items():

507

print(f"{key}: {value}")

508

```

509

510

### Memory Usage Optimization

511

512

```python

513

import pyassimp

514

515

def load_geometry_only(filename):

516

"""Load only geometry data, skip animations, cameras, etc."""

517

518

# Use component removal to skip unwanted data

519

processing = (pyassimp.postprocess.aiProcess_Triangulate |

520

pyassimp.postprocess.aiProcess_RemoveComponent)

521

522

# Note: RemoveComponent needs configuration via AI_CONFIG_PP_RVC_FLAGS

523

# This is a simplified example

524

scene = pyassimp.load(filename, processing=processing)

525

526

# Extract only needed data

527

geometry_data = []

528

for mesh in scene.meshes:

529

mesh_data = {

530

'vertices': mesh.vertices,

531

'faces': mesh.faces,

532

'normals': getattr(mesh, 'normals', None),

533

'material_idx': mesh.materialindex

534

}

535

geometry_data.append(mesh_data)

536

537

pyassimp.release(scene)

538

return geometry_data

539

```