@algoz098/3mf-pr-js
v0.1.0
Published
Biblioteca em TypeScript para geração de arquivos 3MF (3D Manufacturing Format)
Downloads
98
Readme
3mf-pr-js
Biblioteca TypeScript/JavaScript para geração de arquivos 3MF (3D Manufacturing Format)
Biblioteca moderna e completa para criar arquivos 3MF production-ready compatíveis com Bambu Studio, PrusaSlicer e outros slicers profissionais.
Início Rápido • Documentação • Exemplos • API • Contribuir
📑 Índice
- Características
- Instalação
- Uso Rápido
- Recursos Avançados
- Documentação
- Exemplos
- Testes
- API Reference
- Compatibilidade
- Contribuindo
- Licença
🚀 Características
Core 3MF
- ✅ Especificação completa v1.3 - Suporte total à especificação 3MF Core
- ✅ Geometria 3D - Malhas triangulares com vértices e triângulos
- ✅ Transformações - Matrizes 4x3 para posicionamento e rotação
- ✅ Unidades flexíveis - millimeter, inch, micron, centimeter, foot, meter
- ✅ Metadados - Title, Designer, Author, Description e mais
Extensões
- ✅ Production Extension - UUIDs, multifile, assemblies, partnumbers
- ✅ Materials Extension - Color groups, texturas, composite e multi-materials
- ✅ Triangle Sets - Agrupamento lógico de triângulos
Materiais
- ✅ Base Materials - Múltiplos conjuntos com cores RGBA
- ✅ Color Groups - Paletas de cores reutilizáveis
- ✅ Texturas - PNG/JPEG com coordenadas UV
- ✅ Composite Materials - Misturas ponderadas de materiais
- ✅ Multi-Materials - Combinação de múltiplos recursos
- ✅ Por triângulo - Override de materiais por face
Validação
- ✅ JSON Schema - Validação de entrada com AJV
- ✅ Geometria - Winding order e manifold checks
- ✅ lib3mf - Validação estrutural e OPC via SDK oficial
- ✅ Relatórios detalhados - Erros e warnings explicativos
Otimização de Memória
- ✅ TypedArrays - Float32Array/Uint32Array para redução de 90%+ memória
- ✅ Deduplicação de vértices - Remove vértices duplicados automaticamente
- ✅ Geometry pooling - Reutiliza meshes idênticas
- ✅ Estimativa de memória - Análise de uso em tempo real
- ✅ Suporte a modelos grandes - Processa modelos 10-100x maiores
Developer Experience
- ✅ API simples - Função de alto nível
generate3MF()ou API fluenteModel - ✅ TypeScript nativo - Tipos completos e autocomplete
- ✅ Thumbnails flexíveis - PNG/JPEG em
/Thumbnailsou/Metadata - ✅ Testado - 76 testes cobrindo todos os recursos
- ✅ Documentação extensa - Guias, exemplos e referência completa
📦 Instalação
npm install 3mf-pr-js🎯 Uso Rápido
API de Alto Nível (Recomendado)
import { generate3MF } from '3mf-pr-js';
import { writeFile } from 'fs/promises';
const scene = {
unit: 'millimeter',
metadata: {
Title: 'My 3D Model',
Designer: 'Your Name'
},
basematerials: [
{ name: 'PLA Red', displaycolor: '#FF0000FF' }
],
objects: [
{
type: 'mesh',
name: 'Cube',
vertices: [
[0, 0, 0], [10, 0, 0], [10, 10, 0], [0, 10, 0],
[0, 0, 10], [10, 0, 10], [10, 10, 10], [0, 10, 10]
],
triangles: [
[0, 1, 2], [0, 2, 3],
[4, 6, 5], [4, 7, 6],
[0, 5, 1], [0, 4, 5],
[1, 6, 2], [1, 5, 6],
[2, 7, 3], [2, 6, 7],
[3, 4, 0], [3, 7, 4]
],
materialIndex: 0
}
]
};
// Gerar 3MF com validação e Production extension
const buffer = await generate3MF(scene, {
production: true,
validate: true
});
await writeFile('output.3mf', buffer);API Fluente (Controle Detalhado)
import { Model } from '3mf-pr-js';
const model = new Model();
// Configuração
model.setUnit('millimeter');
model.enableProduction(true);
model.addMetadata('Title', 'Complex Model');
// Materiais
const red = model.addBaseMaterial('PLA Red', '#FF0000FF');
const blue = model.addBaseMaterial('PLA Blue', '#0000FFFF');
// Objetos
const cube = model.addMesh(
[[0,0,0], [10,0,0], [10,10,0], [0,10,0], [0,0,10], [10,0,10], [10,10,10], [0,10,10]],
[[0,1,2], [0,2,3], [4,6,5], [4,7,6], [0,5,1], [0,4,5], [1,6,2], [1,5,6], [2,7,3], [2,6,7], [3,4,0], [3,7,4]],
{ name: 'Cube', material: red }
);
// Assembly
const assembly = model.addComponentObject('Assembly', [
{ objectid: cube, transform: [1,0,0, 0,1,0, 0,0,1, 0,0,0] },
{ objectid: cube, transform: [1,0,0, 0,1,0, 0,0,1, 15,0,0] }
]);
// Build item
model.addBuildItem(assembly, [1,0,0, 0,1,0, 0,0,1, 50,50,0]);
// Gerar
const buffer = await model.to3MF();
await model.writeToFile('output.3mf');🛠️ Geração via API
Use a API para gerar 3MFs programaticamente. Exemplos:
npm run build
node examples/materials-api.mjs📋 Recursos Avançados
Múltiplos Conjuntos de Materiais
const model = new Model();
// Criar conjuntos separados
model.createBaseMaterialsSet(1); // PLA
model.createBaseMaterialsSet(2); // ABS
const pla_red = model.addBaseMaterial('PLA Red', '#FF0000FF', 1);
const abs_black = model.addBaseMaterial('ABS Black', '#000000FF', 2);
model.addMesh(vertices, triangles, { material: pla_red });
model.addMesh(vertices2, triangles2, { material: abs_black });Multifile (Production)
model.enableProduction(true);
// Criar part externo
const ext = model.addExternalMesh(
'3D/parts/widget.model',
'Widget',
vertices,
triangles,
{ material: myMaterial }
);
// Referenciar no build
model.addExternalBuildItem(ext.objectid, ext.path, transform);Validação de Geometria
import { validateWindingOrder, validateManifold } from '3mf-pr-js';
// Verificar winding order
const windingResult = validateWindingOrder(vertices, triangles);
if (!windingResult.ok) {
console.warn('Winding warnings:', windingResult.warnings);
}
// Verificar manifold
const manifoldResult = validateManifold(vertices, triangles);
if (!manifoldResult.ok) {
console.error('Manifold errors:', manifoldResult.errors);
}Thumbnails
import { readFile } from 'fs/promises';
// PNG em /Thumbnails (padrão)
const thumb = await readFile('thumbnail.png');
model.setThumbnail(thumb, 'png');
// JPEG em /Metadata
const jpg = await readFile('thumbnail.jpg');
model.setThumbnail(jpg, 'jpg', 'Metadata');
// Thumbnail por objeto
model.setObjectThumbnail(cube, thumb, 'png', 'Metadata');Otimização de Memória
import { Model, deduplicateVertices, estimateMemoryUsage } from '3mf-pr-js';
const model = new Model();
// TypedArrays para eficiência máxima
const vertices = new Float32Array([/* ... */]);
const triangles = new Uint32Array([/* ... */]);
// Adicionar com deduplicação automática
model.addMeshOptimized(vertices, triangles, {
name: 'Large Mesh',
deduplicate: true, // Remove vértices duplicados
reuseGeometry: true, // Reutiliza geometrias idênticas
});
// Estimar uso de memória
const usage = estimateMemoryUsage(vertices, triangles);
console.log(`Memória: ${(usage.total / 1024 / 1024).toFixed(2)} MB`);
console.log(`Economia potencial: ${usage.savings}`);
// Ver estatísticas do pool
const stats = model.getGeometryPoolStats();
console.log(`Geometrias únicas: ${stats.poolSize}`);
console.log(`Economia: ~${((stats.totalRefs - stats.poolSize) / stats.totalRefs * 100).toFixed(0)}%`);💡 Veja o guia completo: MEMORY_OPTIMIZATION.md
Triangle Sets (Extensão)
// Criar um conjunto de triângulos e adicionar referências
const idx = model.addTriangleSet(cube, 'Faces Superiores', 't:topFaces');
model.addTriangleSetRefs(cube, idx, [0, 1, { startindex: 2, endindex: 5 }]);Partnumbers e MustPreserve
// Partnumber em objeto e build item
model.setObjectPartNumber(cube, 'PN-001');
model.addBuildItem(cube, undefined, { partnumber: 'BI-001' });
// Adicionar part customizado com MustPreserve
model.addPreservePart('/Metadata/notes.txt', 'Informações importantes');Materials Extension (Color Groups)
// Criar grupo de cores e adicionar cores
const groupId = model.createColorGroup();
const red = model.addColorToGroup('#FF0000FF', 'Red', groupId);
const green = model.addColorToGroup('#00FF00FF', 'Green', groupId);
// Usar o grupo como default do objeto
const colored = model.addMesh(vertices, triangles, { name: 'Colored', material: red });
// Override por triângulo usando pid/p1..p3
model.setTriangleMaterials(colored, [
{ index: 0, pid: red.pid, p1: red.pindex, p2: red.pindex, p3: red.pindex },
{ index: 1, pid: green.pid, p1: green.pindex, p2: green.pindex, p3: green.pindex },
]);Texturas (Texture2D)
import { readFile } from 'fs/promises';
// Adicionar um recurso de textura PNG/JPEG
const png = await readFile('texture.png');
const texId = model.addTexture(png, 'png');
// O recurso é emitido como `m:texture2d` e embalado em `3D/Textures/`Property Resources (Composite/Multi)
// CompositeMaterials: mistura de entradas de um basematerials
const setId = model.createBaseMaterialsSet();
model.addBaseMaterial('Red', '#FF0000FF', setId);
model.addBaseMaterial('Blue', '#0000FFFF', setId);
const compId = model.createCompositeMaterials(setId);
const mix = model.addComposite(compId, [0.5, 0.5]); // soma=1.0
model.addMesh(vertices, triangles, { material: { pid: compId, pindex: mix } });
// MultiMaterials: combina recursos por índice (ex.: dois pids)
const setA = model.createBaseMaterialsSet();
const aMat = model.addBaseMaterial('A', '#FF0000FF', setA);
const setB = model.createBaseMaterialsSet();
model.addBaseMaterial('B', '#0000FFFF', setB);
const mmId = model.createMultiMaterials([setA, setB]);
const combo = model.addMultiMaterial(mmId, [aMat.pindex, 0]);
model.addMesh(vertices, triangles, { material: { pid: mmId, pindex: combo } });📚 Documentação Completa
Guias Principais
| Documento | Descrição | Público | |-----------|-----------|---------| | GETTING_STARTED.md | Tutorial passo-a-passo para iniciantes | 🟢 Iniciante | | API.md | Referência completa da API | 🔵 Intermediário/Referência | | CONCEPTS.md | Conceitos fundamentais do 3MF | 🔵 Intermediário | | EXAMPLES.md | Exemplos práticos de uso | 🟢 Todos | | MEMORY_OPTIMIZATION.md | 🚀 Otimização de memória e performance | 🔵 Intermediário | | VALIDATION.md | Guia de validação | 🔵 Intermediário | | TROUBLESHOOTING.md | Solução de problemas comuns | 🟢 Todos | | CONTRIBUTING.md | Guia para contribuidores | 🟣 Avançado | | CHANGELOG.md | Histórico de mudanças | 📋 Referência |
Documentação Técnica
Para documentação técnica detalhada, consulte a pasta docs/:
| Documento | Descrição | |-----------|-----------| | INDEX.md | 📑 Índice navegável de toda documentação | | 020-especificacao-core.md | Core 3MF Specification | | 030-extensao-production.md | Production Extension | | 080-esquema-entrada.md | JSON Schema | | 110-exemplos-xml.md | Exemplos XML | | 120-referencia-rapida.md | Referência rápida | | 140-status-compatibilidade.md | Status de compatibilidade |
💡 Dica: Comece com GETTING_STARTED.md se você é novo na biblioteca!
🧪 Testes
npm test # Rodar todos os testes
npm run dev:test # Watch modeCobertura: 58 testes passando
- Core 3MF (6 testes)
- Recursos avançados (12 testes)
- API generate3MF (9 testes)
- Validação (11 testes)
🎨 Exemplos
Veja a pasta examples/:
minimal.json- Exemplo mínimocomplex.json- Assembly com múltiplos objetos e materiaisapi-usage.js- Uso programático da API
📖 API Reference
generate3MF(scene, options)
interface Generate3MFOptions {
production?: boolean; // Habilitar Production extension
validate?: boolean; // Validar entrada (default: true)
strictValidation?: boolean; // Throw em erro de validação (default: true)
}
function generate3MF(scene: SceneJSON, options?: Generate3MFOptions): Promise<Buffer>Classe Model
class Model {
// Configuração
setUnit(unit: 'millimeter' | 'inch' | 'micron' | 'centimeter' | 'foot' | 'meter'): void
setLanguage(lang: string): void
enableProduction(enable?: boolean): void
// Metadados
addMetadata(name: string, value: string): void
// Materiais
createBaseMaterialsSet(id?: number): number
addBaseMaterial(name: string, displaycolor: string, setId?: number): { pid: number; pindex: number }
// Objetos
addMesh(vertices: Vec3[], triangles: Triangle[], opts?: MeshOptions): number
addComponentObject(name: string, components: ComponentRef[]): number
setTriangleMaterials(objectid: number, assignments: TriangleMaterial[]): void
// Build
addBuildItem(objectid: number, transform?: Transform): void
// Multifile
addExternalMesh(path: string, name: string, vertices: Vec3[], triangles: Triangle[], opts?: MeshOptions): { path: string; objectid: number }
addExternalBuildItem(objectid: number, path: string, transform?: Transform): void
// Thumbnails
setThumbnail(data: Uint8Array, ext?: 'png' | 'jpg', dir?: 'Thumbnails' | 'Metadata'): void
// Geração
to3MF(): Promise<Buffer>
writeToFile(path: string): Promise<void>
}Tipos
type Vec3 = [number, number, number];
type Triangle = [number, number, number];
type Transform = [
number, number, number, // m00 m01 m02
number, number, number, // m10 m11 m12
number, number, number, // m20 m21 m22
number, number, number // m30 m31 m32 (translation)
];🎯 Compatibilidade
✅ Testado com:
- Bambu Studio
- PrusaSlicer
- lib3mf validator
✅ Especificações:
- 3MF Core Specification v1.3
- Production Extension v1.0
- OPC Package compliant
Matriz de Compatibilidade (Bambu Studio)
- Basematerials/displaycolor: visual; slicing recalcula configurações.
m:colorgroup: visual por objeto/triângulo; não afeta slicing.- Texturas/UVs (
m:texture2d/m:texture2dgroup): visual; lib3mf aceitatexture2d; UVs são validados estruturalmente. - Property Resources (
m:compositematerials,m:multimaterials): estrutural/visual; suporte varia por consumidor. - Thumbnails (pacote/objeto): apenas visual.
- Triangle Sets (
t:): organizacional; não afeta slicing. - Production multifile (
p:path): assemblies preservados; slicer usa geometria consolidada. - PrintTicket: opcional; Bambu Studio não requer.
🤝 Contribuindo
Contribuições são bem-vindas! Veja o roadmap em docs/130-plano-implementacao.md.
📄 Licença
MIT
🔗 Links Úteis
Made with ❤️ for the 3D printing community
