0
# Configuration and Utilities
1
2
Logging configuration, exception handling, and utility functions for customizing PyWavefront behavior and debugging.
3
4
## Capabilities
5
6
### Logging Configuration
7
8
PyWavefront provides configurable logging for debugging and monitoring parsing operations.
9
10
```python { .api }
11
def configure_logging(level, formatter=None) -> None:
12
"""
13
Configure PyWavefront's logging system.
14
15
Parameters:
16
- level: Logging level (logging.DEBUG, logging.INFO, logging.WARNING, logging.ERROR)
17
- formatter: Optional logging.Formatter instance for custom formatting
18
19
Default behavior:
20
- Logger name: "pywavefront"
21
- Default level: ERROR
22
- Default handler: StreamHandler (console output)
23
"""
24
```
25
26
**Default Logging Configuration:**
27
- Logger name: `"pywavefront"`
28
- Default level: `ERROR` (only errors shown)
29
- Output: Console via `StreamHandler`
30
31
### Exception Handling
32
33
```python { .api }
34
class PywavefrontException(Exception):
35
"""
36
Custom exception class for PyWavefront-specific errors.
37
38
Raised for:
39
- File parsing errors
40
- Missing material references
41
- Unsupported .obj features in strict mode
42
- File access issues
43
- Malformed geometry data
44
"""
45
```
46
47
**Common Exception Scenarios:**
48
- File not found or permission denied
49
- Invalid .obj syntax or malformed data
50
- Missing .mtl files when `create_materials=False`
51
- Unknown material references in `usemtl` statements
52
- Unsupported features when `strict=True`
53
- Encoding issues with international characters
54
55
### Version Information
56
57
```python { .api }
58
__version__: str # Current version string
59
```
60
61
```python
62
import pywavefront
63
print(pywavefront.__version__) # "1.3.3"
64
```
65
66
### Usage Examples
67
68
#### Basic Logging Setup
69
70
```python
71
import logging
72
import pywavefront
73
74
# Enable debug logging for detailed parsing information
75
pywavefront.configure_logging(logging.DEBUG)
76
77
# Load a file with debug output
78
scene = pywavefront.Wavefront('model.obj')
79
# Output: Debug information about parsing progress, timing, etc.
80
```
81
82
#### Custom Logging Formatter
83
84
```python
85
import logging
86
import pywavefront
87
88
# Create a custom formatter
89
formatter = logging.Formatter(
90
'%(asctime)s - %(name)s - %(levelname)s - %(message)s'
91
)
92
93
# Configure with custom formatter
94
pywavefront.configure_logging(logging.INFO, formatter=formatter)
95
96
# Load with timestamped logging
97
scene = pywavefront.Wavefront('model.obj')
98
```
99
100
#### Logging Levels and Output
101
102
```python
103
import logging
104
import pywavefront
105
106
# Different logging levels show different information:
107
108
# ERROR (default): Only critical errors
109
pywavefront.configure_logging(logging.ERROR)
110
111
# WARNING: Warnings about potential issues
112
pywavefront.configure_logging(logging.WARNING)
113
114
# INFO: General information about parsing progress
115
pywavefront.configure_logging(logging.INFO)
116
117
# DEBUG: Detailed parsing information and timing
118
pywavefront.configure_logging(logging.DEBUG)
119
```
120
121
#### Exception Handling
122
123
```python
124
import pywavefront
125
126
try:
127
# Strict parsing that raises exceptions for unsupported features
128
scene = pywavefront.Wavefront('model.obj', strict=True)
129
130
except pywavefront.PywavefrontException as e:
131
print(f"PyWavefront error: {e}")
132
# Handle PyWavefront-specific errors
133
134
except FileNotFoundError as e:
135
print(f"File not found: {e}")
136
# Handle file access errors
137
138
except Exception as e:
139
print(f"Unexpected error: {e}")
140
# Handle other unexpected errors
141
142
# Graceful handling of missing materials
143
try:
144
scene = pywavefront.Wavefront('model_with_missing_mtl.obj')
145
except pywavefront.PywavefrontException:
146
print("Missing materials detected, creating defaults...")
147
scene = pywavefront.Wavefront('model_with_missing_mtl.obj', create_materials=True)
148
```
149
150
#### Debugging File Loading Issues
151
152
```python
153
import logging
154
import pywavefront
155
156
# Enable debug logging to troubleshoot loading issues
157
pywavefront.configure_logging(logging.DEBUG)
158
159
try:
160
# Load with maximum debugging information
161
scene = pywavefront.Wavefront(
162
'problematic_model.obj',
163
strict=True, # Catch parsing issues
164
encoding='utf-8' # Ensure correct encoding
165
)
166
167
print(f"Successfully loaded {len(scene.materials)} materials")
168
print(f"Found {len(scene.mesh_list)} meshes")
169
170
except pywavefront.PywavefrontException as e:
171
print(f"Parsing failed: {e}")
172
173
# Try with relaxed settings
174
print("Retrying with relaxed parsing...")
175
scene = pywavefront.Wavefront(
176
'problematic_model.obj',
177
strict=False,
178
create_materials=True
179
)
180
```
181
182
#### Performance Monitoring
183
184
```python
185
import time
186
import logging
187
import pywavefront
188
189
# Configure INFO level to see load timing
190
pywavefront.configure_logging(logging.INFO)
191
192
start_time = time.time()
193
194
# Load with caching for performance
195
scene = pywavefront.Wavefront('large_model.obj', cache=True)
196
197
load_time = time.time() - start_time
198
print(f"Load completed in {load_time:.2f} seconds")
199
200
# Subsequent loads will be much faster due to caching
201
start_time = time.time()
202
scene2 = pywavefront.Wavefront('large_model.obj', cache=True)
203
cached_load_time = time.time() - start_time
204
print(f"Cached load completed in {cached_load_time:.2f} seconds")
205
print(f"Speedup: {load_time / cached_load_time:.1f}x")
206
```
207
208
#### Error Recovery Strategies
209
210
```python
211
import pywavefront
212
213
def load_model_robust(filepath):
214
"""Robust model loading with multiple fallback strategies."""
215
216
# Strategy 1: Normal loading
217
try:
218
return pywavefront.Wavefront(filepath)
219
except pywavefront.PywavefrontException:
220
pass
221
222
# Strategy 2: Create missing materials
223
try:
224
return pywavefront.Wavefront(filepath, create_materials=True)
225
except pywavefront.PywavefrontException:
226
pass
227
228
# Strategy 3: Disable strict parsing
229
try:
230
return pywavefront.Wavefront(
231
filepath,
232
strict=False,
233
create_materials=True
234
)
235
except pywavefront.PywavefrontException:
236
pass
237
238
# Strategy 4: Try different encoding
239
try:
240
return pywavefront.Wavefront(
241
filepath,
242
encoding='latin1',
243
strict=False,
244
create_materials=True
245
)
246
except Exception as e:
247
raise pywavefront.PywavefrontException(
248
f"Failed to load {filepath} with all strategies: {e}"
249
)
250
251
# Usage
252
try:
253
scene = load_model_robust('difficult_model.obj')
254
print("Model loaded successfully")
255
except pywavefront.PywavefrontException as e:
256
print(f"All loading strategies failed: {e}")
257
```
258
259
### Logging Output Examples
260
261
**DEBUG Level Output:**
262
```
263
pywavefront: Load time: 0.123
264
pywavefront: Parsing vertex data: 1000 vertices
265
pywavefront: Loading material library: materials.mtl
266
pywavefront: Created material: wood_material
267
pywavefront: Face parsing complete: 500 triangular faces
268
```
269
270
**INFO Level Output:**
271
```
272
pywavefront: model.obj: Load time: 0.123
273
```
274
275
**WARNING Level Output:**
276
```
277
pywavefront: Unknown material reference: missing_material
278
pywavefront: Creating default material: default0
279
```
280
281
**ERROR Level Output:**
282
```
283
pywavefront: Failed to load material library: materials.mtl
284
pywavefront: PywavefrontException: Unknown material: metal_surface
285
```