or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

data-access.mdfile-operations.mdindex.mdmesh-analysis.mdmesh-processing.mdtransformations.md

mesh-analysis.mddocs/

0

# Mesh Analysis

1

2

Calculate geometric properties, validate mesh integrity, and analyze 3D mesh characteristics including volume, mass properties, surface area, and mesh closure validation.

3

4

## Capabilities

5

6

### Mass Properties Calculation

7

8

Calculate volume, center of gravity, and inertia tensor for closed meshes.

9

10

```python { .api }

11

def get_mass_properties(self):

12

"""

13

Calculate volume, center of gravity, and inertia matrix.

14

15

Returns:

16

tuple[float, numpy.array, numpy.array]: (volume, cog, inertia)

17

- volume (float): Volume of the closed mesh

18

- cog (numpy.array): Center of gravity coordinates (3,)

19

- inertia (numpy.array): 3x3 inertia matrix expressed at COG

20

21

Notes:

22

- Requires a closed mesh for accurate results

23

- Automatically calls check() to validate mesh closure

24

- Uses polyhedral mass properties algorithm

25

"""

26

27

def get_mass_properties_with_density(self, density):

28

"""

29

Calculate mass properties with specified material density.

30

31

Parameters:

32

- density (float): Material density in kg/m³ (when mesh units are meters)

33

34

Returns:

35

tuple[float, float, numpy.array, numpy.array]: (volume, mass, cog, inertia)

36

- volume (float): Volume of the mesh

37

- mass (float): Total mass (volume * density)

38

- cog (numpy.array): Center of gravity coordinates (3,)

39

- inertia (numpy.array): 3x3 inertia matrix at COG including mass

40

"""

41

```

42

43

### Surface Area and Centroids

44

45

Calculate triangle areas and centroid positions for geometric analysis.

46

47

```python { .api }

48

def update_areas(self, normals=None):

49

"""

50

Calculate surface areas for all triangles.

51

52

Parameters:

53

- normals (numpy.array, optional): Pre-computed normal vectors

54

(calculated if not provided)

55

56

Notes:

57

- Updates the areas property with triangle surface areas

58

- Areas calculated as 0.5 * |cross_product|

59

- Results stored in areas property as (N, 1) array

60

"""

61

62

def update_centroids(self):

63

"""

64

Calculate centroid positions for all triangles.

65

66

Notes:

67

- Updates the centroids property with triangle centers

68

- Centroids calculated as mean of three vertices

69

- Results stored in centroids property as (N, 3) array

70

"""

71

72

def update_min(self):

73

"""

74

Calculate minimum coordinate values across all vertices.

75

76

Notes:

77

- Updates the min_ property with computed values

78

- Called automatically when min_ property is accessed

79

"""

80

81

def update_max(self):

82

"""

83

Calculate maximum coordinate values across all vertices.

84

85

Notes:

86

- Updates the max_ property with computed values

87

- Called automatically when max_ property is accessed

88

"""

89

```

90

91

### Mesh Validation

92

93

Validate mesh integrity and closure for accurate geometric calculations.

94

95

```python { .api }

96

def is_closed(self, exact=False):

97

"""

98

Check if the mesh forms a closed surface.

99

100

Parameters:

101

- exact (bool): Perform exact edge-based validation

102

False uses normal vector sum approximation

103

104

Returns:

105

bool: True if mesh is closed, False otherwise

106

107

Notes:

108

- Exact=True: Validates all edges are properly paired

109

- Exact=False: Uses normal vector sum (faster but less reliable)

110

- Closed meshes required for volume and mass calculations

111

- Warns about potential issues when mesh is not closed

112

"""

113

114

def check(self, exact=False):

115

"""

116

Validate mesh integrity.

117

118

Parameters:

119

- exact (bool): Perform exact validation checks

120

121

Returns:

122

bool: True if mesh passes validation, False otherwise

123

124

Notes:

125

- Currently equivalent to is_closed()

126

- May include additional validation checks in future versions

127

"""

128

```

129

130

### Geometric Property Access

131

132

Access computed geometric properties through convenient properties.

133

134

```python { .api }

135

@property

136

def areas(self):

137

"""

138

Triangle surface areas.

139

140

Returns:

141

numpy.array: Surface areas for each triangle (N, 1)

142

143

Notes:

144

- Automatically calculated when first accessed

145

- Cached until mesh geometry changes

146

"""

147

148

@property

149

def centroids(self):

150

"""

151

Triangle centroid positions.

152

153

Returns:

154

numpy.array: Centroid coordinates for each triangle (N, 3)

155

156

Notes:

157

- Automatically calculated when first accessed

158

- Centroids are geometric centers of triangles

159

"""

160

161

@property

162

def min_(self):

163

"""

164

Minimum coordinate values across all vertices.

165

166

Returns:

167

numpy.array: Minimum [x, y, z] coordinates (3,)

168

169

Notes:

170

- Automatically calculated when first accessed

171

- Cached until mesh geometry changes

172

"""

173

174

@property

175

def max_(self):

176

"""

177

Maximum coordinate values across all vertices.

178

179

Returns:

180

numpy.array: Maximum [x, y, z] coordinates (3,)

181

182

Notes:

183

- Automatically calculated when first accessed

184

- Cached until mesh geometry changes

185

"""

186

187

def update_min(self):

188

"""

189

Calculate minimum coordinate values across all vertices.

190

191

Notes:

192

- Updates the min_ property with computed values

193

- Called automatically when min_ property is accessed

194

- Can be called manually to refresh cached values

195

"""

196

197

def update_max(self):

198

"""

199

Calculate maximum coordinate values across all vertices.

200

201

Notes:

202

- Updates the max_ property with computed values

203

- Called automatically when max_ property is accessed

204

- Can be called manually to refresh cached values

205

"""

206

207

@property

208

def units(self):

209

"""

210

Unit normal vectors for each triangle.

211

212

Returns:

213

numpy.array: Normalized normal vectors (N, 3)

214

215

Notes:

216

- Automatically calculated when first accessed

217

- Used for surface area and orientation calculations

218

"""

219

```

220

221

### Normal Vector Operations

222

223

Calculate and work with triangle normal vectors for mesh analysis.

224

225

```python { .api }

226

def update_normals(self, update_areas=True, update_centroids=True):

227

"""

228

Calculate normal vectors for all triangles.

229

230

Parameters:

231

- update_areas (bool): Whether to update surface areas

232

- update_centroids (bool): Whether to update centroid positions

233

234

Notes:

235

- Normals calculated using cross product of edge vectors

236

- Updates normals property with computed vectors

237

- Optionally updates dependent properties (areas, centroids)

238

"""

239

240

def get_unit_normals(self):

241

"""

242

Get normalized normal vectors.

243

244

Returns:

245

numpy.array: Unit normal vectors (N, 3)

246

247

Notes:

248

- Returns normalized versions of current normals

249

- Zero-length normals remain unchanged

250

- Does not modify the original normals property

251

"""

252

```

253

254

## Usage Examples

255

256

### Volume and Mass Analysis

257

258

```python

259

import numpy as np

260

from stl import mesh

261

262

# Load a mesh

263

my_mesh = mesh.Mesh.from_file('model.stl')

264

265

# Calculate basic mass properties

266

volume, cog, inertia = my_mesh.get_mass_properties()

267

print(f"Volume: {volume:.3f}")

268

print(f"Center of gravity: {cog}")

269

print(f"Inertia matrix:\n{inertia}")

270

271

# Calculate with material density (aluminum: ~2700 kg/m³)

272

volume, mass, cog, inertia = my_mesh.get_mass_properties_with_density(2700)

273

print(f"Mass: {mass:.3f} kg")

274

```

275

276

### Mesh Validation

277

278

```python

279

from stl import mesh

280

281

my_mesh = mesh.Mesh.from_file('model.stl')

282

283

# Quick validation using normal vectors

284

if my_mesh.is_closed():

285

print("Mesh is closed - volume calculations will be accurate")

286

else:

287

print("Warning: Mesh is not closed")

288

289

# More thorough validation (slower)

290

if my_mesh.is_closed(exact=True):

291

print("Mesh passes exact closure validation")

292

else:

293

print("Mesh has gaps or inconsistent edge orientations")

294

```

295

296

### Surface Analysis

297

298

```python

299

from stl import mesh

300

import numpy as np

301

302

my_mesh = mesh.Mesh.from_file('model.stl')

303

304

# Calculate surface properties

305

my_mesh.update_areas()

306

my_mesh.update_centroids()

307

308

# Analyze surface area distribution

309

total_area = np.sum(my_mesh.areas)

310

mean_area = np.mean(my_mesh.areas)

311

print(f"Total surface area: {total_area:.3f}")

312

print(f"Average triangle area: {mean_area:.6f}")

313

314

# Find largest triangles

315

large_triangles = my_mesh.areas.flatten() > mean_area * 2

316

print(f"Large triangles: {np.sum(large_triangles)}")

317

318

# Analyze bounding box

319

bounds = my_mesh.max_ - my_mesh.min_

320

print(f"Bounding box: {bounds}")

321

```

322

323

### Normal Vector Analysis

324

325

```python

326

from stl import mesh

327

import numpy as np

328

329

my_mesh = mesh.Mesh.from_file('model.stl')

330

331

# Get normalized normal vectors

332

unit_normals = my_mesh.get_unit_normals()

333

334

# Analyze surface orientations

335

up_facing = unit_normals[:, 2] > 0.9 # Nearly vertical faces

336

print(f"Upward-facing triangles: {np.sum(up_facing)}")

337

338

# Check for degenerate triangles

339

normal_lengths = np.linalg.norm(my_mesh.normals, axis=1)

340

degenerate = normal_lengths < 1e-6

341

if np.any(degenerate):

342

print(f"Warning: {np.sum(degenerate)} degenerate triangles found")

343

```

344

345

## Error Handling

346

347

- **AssertionError**: Raised when mesh is not closed during mass property calculations

348

- **RuntimeError**: Raised for invalid mesh data or calculation failures

349

- **NumPy warnings**: May occur for degenerate triangles or numerical precision issues