fix 3mf import for components using object path refrerences
This commit is contained in:
parent
30d417c2e0
commit
0fc25999e0
1 changed files with 78 additions and 11 deletions
|
|
@ -65,6 +65,16 @@ function transform(def, mesh) {
|
||||||
return pos.array;
|
return pos.array;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** find matching attribute regardless of namespace */
|
||||||
|
function getLocalAttribute(node, name) {
|
||||||
|
for (let attr of node.attributes) {
|
||||||
|
if (attr.localName === name) {
|
||||||
|
return attr.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
function loadModel(doc) {
|
function loadModel(doc) {
|
||||||
let items = [];
|
let items = [];
|
||||||
let objects = {};
|
let objects = {};
|
||||||
|
|
@ -118,13 +128,16 @@ function loadModel(doc) {
|
||||||
query(node, ["components","+component"], (type, node) => {
|
query(node, ["components","+component"], (type, node) => {
|
||||||
object.components.push({
|
object.components.push({
|
||||||
oid: node.getAttribute('objectid'),
|
oid: node.getAttribute('objectid'),
|
||||||
xform: node.getAttribute('transform')
|
path: getLocalAttribute(node, "path"),
|
||||||
|
xform: node.getAttribute('transform'),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return resolve({ objects, items });
|
||||||
|
|
||||||
// create object mesh from components
|
// create object mesh from components
|
||||||
for (let object of Object.values(objects)) {
|
for (let object of Object.values(objects)) {
|
||||||
let { mesh, components } = object;
|
let { mesh, components } = object;
|
||||||
|
|
@ -135,7 +148,9 @@ function loadModel(doc) {
|
||||||
for (let component of components) {
|
for (let component of components) {
|
||||||
let { oid, xform } = component;
|
let { oid, xform } = component;
|
||||||
let ref = objects[oid];
|
let ref = objects[oid];
|
||||||
if (xform) {
|
if (!ref) {
|
||||||
|
console.log({ missing_ref: oid, objects, components, doc });
|
||||||
|
} else if (xform) {
|
||||||
mesh.appendAll(transform(xform, ref.mesh));
|
mesh.appendAll(transform(xform, ref.mesh));
|
||||||
} else {
|
} else {
|
||||||
mesh.appendAll(ref.mesh);
|
mesh.appendAll(ref.mesh);
|
||||||
|
|
@ -160,21 +175,73 @@ function loadModel(doc) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function extractItems(records) {
|
||||||
|
let outItems = [];
|
||||||
|
let models = Object.values(records);
|
||||||
|
|
||||||
|
// create object mesh from components
|
||||||
|
for (let model of models) {
|
||||||
|
let { objects } = model;
|
||||||
|
for (let object of Object.values(objects)) {
|
||||||
|
let { mesh, components } = object;
|
||||||
|
if (mesh) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
mesh = object.mesh = [];
|
||||||
|
for (let component of components) {
|
||||||
|
let { oid, path, xform } = component;
|
||||||
|
let omap = objects;
|
||||||
|
if (path) {
|
||||||
|
omap = records[path.substring(1)].objects;
|
||||||
|
// console.log({ component_from_ob_path: path, using: omap });
|
||||||
|
}
|
||||||
|
let ref = omap[oid];
|
||||||
|
if (!ref) {
|
||||||
|
console.log({ missing_ref: oid, objects, components });
|
||||||
|
} else if (xform) {
|
||||||
|
mesh.appendAll(transform(xform, ref.mesh));
|
||||||
|
} else {
|
||||||
|
mesh.appendAll(ref.mesh);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// create export items from object references
|
||||||
|
for (let model of models) {
|
||||||
|
let { items, objects } = model;
|
||||||
|
for (let item of items || []) {
|
||||||
|
let { oid, xform } = item;
|
||||||
|
let { name, mesh } = objects[oid];
|
||||||
|
item.name = name;
|
||||||
|
if (xform) {
|
||||||
|
item.faces = transform(xform, mesh);
|
||||||
|
} else {
|
||||||
|
item.faces = mesh;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
outItems.push(...items);
|
||||||
|
}
|
||||||
|
|
||||||
|
return outItems;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Object} data binary file
|
* @param {Object} data binary file
|
||||||
* @returns {Array} vertex face array
|
* @returns {Array} vertex face array
|
||||||
*/
|
*/
|
||||||
function parseAsync(data) {
|
function parseAsync(data) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise(async (resolve, reject) => {
|
||||||
JSZip.loadAsync(data).then(zip => {
|
let zip = await JSZip.loadAsync(data);
|
||||||
for (let [key,value] of Object.entries(zip.files)) {
|
let models = {};
|
||||||
if (key.indexOf(".model") > 0) {
|
for (let [key, value] of Object.entries(zip.files)) {
|
||||||
value.async("string").then(xml => {
|
if (key.endsWith(".model")) {
|
||||||
resolve(loadModel(new DOMParser().parseFromString(xml, "text/xml")));
|
let xml = await value.async("string");
|
||||||
});
|
let { objects, items } = await loadModel(new DOMParser().parseFromString(xml, "text/xml"));
|
||||||
}
|
models[key] = { objects, items };
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
resolve(extractItems(models));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue