three-mf
v1.1.0
Published
A comprehensive TypeScript library for parsing and working with 3D Manufacturing Format (3MF) files.
Readme
three-mf
A comprehensive TypeScript library for parsing and working with 3D Manufacturing Format (3MF) files.
Key features:
- Open and inspect OPC/ZIP-based
.3mfarchives - Parse
[Content_Types].xmland_rels/.relsrelationships - Extract and validate the
<model>element - Read
<resources>: base materials and object definitions - Handle
<mesh>: vertices, triangles, manifold and orientation checks - Compose objects via
<components>and build instructions - Parse
<build>items and link them to resources - In-memory API with
ThreeMFDocumentfor JSON serialization/round-trip - Rich error reporting (
ValidationError,ParseError) and spec warnings (WarningLogger) - CI-ready with
bun testand GitHub Actions
Installation
bun installDevelopment
Installing dependencies
bun installRunning tests
bun test --watchBuilding
bun run buildBuilding in watch mode
bun run build --watchDeployment
After building, publish the package to npm:
bun run build
npm publishRoadmap
Implementations status of 3MF spec (see 3MF specification):
- [x] Core 3MF Mesh Specification (Core spec)
- [x] Production Extension
- [x] Materials and Properties Extension
- [ ] Slice Extension
- [ ] Beam Lattice Extension
- [ ] Boolean Operations Extension
- [ ] Displacement Extension
- [ ] Secure Content Extension
- [ ] Volumetric Extension
Usage
import {
openArchive,
getPrimaryModelPath,
getModel,
parseResourcesFromXml,
parseBuildFromXml,
ThreeMFDocument
} from 'three-mf';
async function example(filePath: string) {
// 1. Open 3MF archive
const zip = await openArchive(filePath);
const modelPath = await getPrimaryModelPath(zip);
// 2. Parse the <model> element
const model = await getModel(zip, modelPath);
const xmlText = await zip.file(modelPath)!.async('text');
// 3. Extract resources and build items
const resources = parseResourcesFromXml(xmlText);
const buildItems = parseBuildFromXml(xmlText, resources);
// 4. Work with in-memory document
const document = new ThreeMFDocument(model, resources, buildItems);
console.log(JSON.stringify(document.toJSON(), null, 2));
}API Reference
OPC Utilities (src/opc.ts)
- openArchive(pathOrBuffer: string | Buffer | Uint8Array): Promise
- getPrimaryModelPath(zip: JSZip): Promise
Content Types (src/content-types.ts)
- getContentTypeMap(zip: JSZip): Promise
- getContentType(map: ContentTypeMap, partPath: string): string | null
Relationships (src/relationships.ts)
- getRelationships(zip: JSZip): Promise
- getStartPartPath(relationships: RelationshipMap): string
- getRelationshipsByType(relationships: RelationshipMap, type: string): Relationship[]
Model Parsing (src/model.ts)
- parseModel(content: string): Model
- getModel(zip: JSZip, modelPath: string): Promise
Resources (src/resources.ts)
- parseResourcesFromXml(content: string): Resources
- parseResources(modelXml: any): Resources
Build Parsing (src/build.ts)
- parseBuildFromXml(content: string, resources: Resources): BuildItem[]
Document (src/document.ts)
- ThreeMFDocument(model: Model, resources: Resources, build: BuildItem[])
- toJSON(): DocumentJSON
- fromJSON(json: DocumentJSON): ThreeMFDocument
Mesh (src/mesh.ts)
- parseMesh(element: any): Mesh
- validateMesh(mesh: Mesh, type: string): Mesh
Components (src/components.ts)
- flattenComponentHierarchy(id: number, objects: Map<number, ObjectResource>): Mesh
- validateAllComponentReferences(objects: Map<number, ObjectResource>): void
Builders (src/builder.ts)
- meshToXml(mesh: Mesh)
- objectWithMesh(id: number, mesh: Mesh, attrs?): ObjectElement
- buildItemXml(objectId: number, attrs?): BuildItemElement
- texture2dToXml(tex: Texture2D): any — Build
<texture2d>elements for the Materials & Properties Extension. - texture2dGroupToXml(grp: Texture2DGroup): any — Build
<texture2dgroup>elements. - colorGroupToXml(grp: ColorGroup): any — Build
<colorgroup>elements. - compositeMaterialsToXml(grp: CompositeMaterials): any — Build
<compositematerials>elements. - multiPropertiesToXml(mp: MultiProperties): any — Build
<multiproperties>elements. - pbSpecularDisplayPropertiesToXml(dp: PBSpecularDisplayProperties): any — Build
<pbspeculardisplayproperties>elements. - pbMetallicDisplayPropertiesToXml(dp: PBMetallicDisplayProperties): any — Build
<pbmetallicdisplayproperties>elements. - pbSpecularTextureDisplayPropertiesToXml(dp: PBSpecularTextureDisplayProperties): any — Build
<pbspeculartexturedisplayproperties>elements. - pbMetallicTextureDisplayPropertiesToXml(dp: PBMetallicTextureDisplayProperties): any — Build
<pbmetallictexturedisplayproperties>elements. - translucentDisplayPropertiesToXml(dp: TranslucentDisplayProperties): any — Build
<translucentdisplayproperties>elements.
Packager (src/packager.ts)
- create3MFArchive(xmlObj: ThreeMFXml, modelFilePath?: string): JSZip
Production Extension (src/production-extension)
- parseProductionExtensions(xmlObj: any): void
- serializeProductionExtensions(xmlObj: any): void
- generatePartRels(xmlObj: any): any[]
- generateUUID(): string
Builders and Packaging Utilities
This library provides high-level helpers to build 3MF XML structures and package them without manual XML or ZIP boilerplate.
import type { ThreeMFXml } from './src/builder';
import { objectWithMesh, buildItemXml } from './src/builder';
import { create3MFArchive } from './src/packager';
import type { Mesh } from './src/mesh';
// Given a Mesh object (from parseMesh or custom geometry)
const mesh: Mesh = /* ... */;
// 1. Build object and build-item XML elements
const objElement = objectWithMesh(1, mesh);
const itemElement = buildItemXml(1 /* object ID */, { '@_partnumber': 'baseplate' });
// 2. Assemble the top-level ThreeMFXml structure
const xmlObj: ThreeMFXml = {
model: {
'@_unit': 'millimeter',
'@_xmlns': 'http://schemas.microsoft.com/3dmanufacturing/core/2015/02',
resources: { object: objElement },
build: { item: itemElement }
}
};
// 3. Create the .3mf package and write it out
const zip = create3MFArchive(xmlObj);
const buffer = await zip.generateAsync({ type: 'nodebuffer' });
await Deno.writeFile('output.3mf', buffer);Examples
For runnable examples and usage details, see examples/README.md.
Contributing
We use a file-based task system in .ai/tasks/. New features and bug fixes should follow existing patterns:
- Pick an open task in
.ai/TASKS.mdand update its status when done. - Ensure all new code is covered by unit tests.
- Submit a pull request—CI will run automatically.
License
MIT
