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