pub async fn load_model_async<P: AsRef<Path>>(path: P) -> Result<Model>Expand description
Asynchronously loads a 3MF model from a file path.
This is the primary entry point for async 3MF loading. It handles all aspects of loading: file I/O, ZIP archive access, OPC relationship parsing, and XML model parsing.
§Arguments
path- Path to the 3MF file (any type implementingAsRef<Path>)
§Returns
A fully parsed Model containing all resources, build items, and metadata.
§Errors
Returns Lib3mfError::Io if:
- File cannot be opened
- ZIP archive cannot be read
- Archive entries cannot be read
Returns Lib3mfError::InvalidStructure if:
_rels/.relsfile is missing or malformed- No 3D model relationship is found (must have type
http://schemas.microsoft.com/3dmanufacturing/2013/01/3dmodel) - Model part path is invalid
Returns parsing errors from parse_model if the model XML is malformed.
§Implementation Details
§Async vs Blocking
- Async operations: File open, ZIP directory reading, entry reading
- Blocking operations: XML parsing (offloaded to
tokio::task::spawn_blocking)
The function uses spawn_blocking for XML parsing because it’s CPU-bound work that would
otherwise block the tokio executor. This allows other async tasks to progress while
parsing happens on a dedicated thread pool.
§OPC Discovery
The function follows the Open Packaging Conventions (OPC) standard to discover the main model part:
- Reads
_rels/.rels(package-level relationships) - Finds relationship with type ending in
/3dmodel - Reads the target model part (typically
/3D/3dmodel.model)
§Examples
use lib3mf_async::loader::load_model_async;
use lib3mf_core::validation::ValidationLevel;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Load a 3MF file
let model = load_model_async("complex_model.3mf").await?;
// Validate the loaded model
let report = model.validate(ValidationLevel::Standard);
if report.has_errors() {
eprintln!("Model has validation errors:");
for item in &report.items {
eprintln!(" - {}", item.message);
}
}
// Process the model
println!("Objects: {}", model.resources.iter_objects().count());
println!("Build items: {}", model.build.items.len());
Ok(())
}