add obj export

This commit is contained in:
Stewart Allen 2022-01-08 21:00:19 -05:00
commit 7ea66a9e7b
6 changed files with 91 additions and 38 deletions

View file

@ -127,33 +127,33 @@ function space_init(data) {
}
let { shiftKey, metaKey, ctrlKey, code } = evt;
switch (code) {
case 'KeyD':
if (shiftKey) {
for (let m of selection.models()) {
m.debug();
}
}
break;
case 'KeyC':
selection.centerXY().focus();
break;
return selection.centerXY().focus();
case 'KeyX':
return api.file.export();
case 'KeyV':
selection.focus();
break;
return selection.focus();
case 'KeyW':
api.wireframe();
break;
return api.wireframe();
case 'KeyG':
api.grid();
break;
return api.grid();
case 'KeyB':
selection.boundsBox({toggle:true});
break;
return selection.boundsBox({toggle:true});
case 'KeyH':
space.view.home();
break;
return space.view.home();
case 'KeyR':
api.tool.repair();
break;
return api.tool.repair();
case 'KeyT':
space.view.top();
break;
return space.view.top();
case 'KeyZ':
space.view.reset();
break;
return space.view.reset();
}
},
'keydown', evt => {
@ -172,13 +172,6 @@ function space_init(data) {
estop(evt);
}
break;
case 'KeyD':
if (shiftKey) {
for (let m of selection.models()) {
m.debug();
}
}
break;
case 'Escape':
selection.clear();
estop(evt);

View file

@ -218,7 +218,16 @@ let file = {
},
export() {
console.log('...export todo');
let recs = selection.models().map(m => { return {
id: m.id, matrix: m.matrix, file: m.file
} });
api.log.emit(`exporting ${recs.length} model(s)`);
moto.client.fn.file_export({
recs, format: "obj"
}).then(data => {
console.log({work_export: data});
util.download(data, "export.obj");
});
},
};
@ -244,7 +253,7 @@ let tool = {
}
};
// api is augmented in mesh.build
// api is augmented in mesh.build (log, modal, download)
let api = mesh.api = {
clear() {
for (let group of group.list()) {
@ -300,8 +309,8 @@ let api = mesh.api = {
let deferFn = [];
let boundsCache = {};
// util functions augmented in build (download)
let util = mesh.util = {
uuid(segs = 1) {
let uid = [];
while (segs-- > 0) {

View file

@ -20,6 +20,13 @@ broker.listeners({
let spin_timer;
// add download / blob export to util
let download = mesh.util.download = (data, filename = "mesh-data") => {
let url = window.URL.createObjectURL(new Blob([data], {type: "octet/stream"}));
$('download').innerHTML = `<a id="_data_export_" href="${url}" download="${filename}">x</a>`;
$('_data_export_').click();
};
// add modal dialog functions to api
let modal = mesh.api.modal = {
show(title, contents) {
@ -155,7 +162,8 @@ function ui_build() {
h.div({ id: 'actions' }),
h.div({ id: 'grouplist'}),
h.div({ id: 'selectlist'}),
h.div({ id: 'logger', onmouseover() { log.show() } })
h.div({ id: 'logger', onmouseover() { log.show() } }),
h.div({ id: 'download', class: "hide" })
]);
let { actions, grouplist, selectlist, logger } = bound;
@ -174,7 +182,7 @@ function ui_build() {
onchange(evt) { broker.send.load_files(evt.target.files) }
})
]),
h.button({ _: 'export', onclick: api.file.export, disabled: true }),
h.button({ _: 'export', onclick: api.file.export }),
h.div({ class: "vsep" }),
h.button({ _: 'analyze', disabled: true }),
h.button({ _: 'repair', onclick: api.tool.repair }),
@ -215,7 +223,9 @@ function ui_build() {
.map(g => h.div([
h.button({ _: `group`, title: g.id,
class: [ "group", selHas(g) ? 'selected' : undefined ],
onclick() { api.selection.toggle(g) }
onclick(e) {
e.shiftKey ? api.selection.toggle(g) : api.selection.set([g])
}
}),
h.div({ class: "vsep" }),
h.div({ class: "models"},

View file

@ -76,9 +76,13 @@ mesh.model = class MeshModel extends mesh.object {
return this.mesh;
}
get matrix() {
return this.mesh.matrixWorld.elements;
}
debug() {
worker.model_debug({
matrix: this.mesh.matrixWorld.elements,
matrix: this.matrix,
id: this.id
}).then(data => {
// for debugging matrix ops

View file

@ -31,6 +31,13 @@ function cacheUpdate(id, data) {
Object.assign(cache[id], data);
}
function translate_encode(id, matrix) {
let rec = cache[id];
let geo = rec.geo.clone();
geo.applyMatrix4(core_matrix.clone().multiply( new THREE.Matrix4().fromArray(matrix) ));
return geo.attributes.position.array;
}
let model = {
load(data) {
let { vertices, indices, name, id } = data;
@ -41,7 +48,9 @@ let model = {
},
debug(data) {
let { matrix, id } = data;
let { id, matrix } = data;
return translate_encode(id, matrix);
throw "should not here";
let rec = cache[id];
let geo = rec.geo.clone();
let m4 = core_matrix.clone().multiply( new THREE.Matrix4().fromArray(matrix) );
@ -108,14 +117,41 @@ let object = {
}
};
worker.bind("debug", (data, send) => {
let file = {
export(data, send) {
let { format, recs } = data;
switch (format) {
case "obj":
let p = 1;
let obj = [];
for (let rec of recs) {
let { id, matrix, file } = rec;
let verts = translate_encode(id, matrix);
obj.push(`g ${file}`);
for (let i=0; i<verts.length; p += 3) {
obj.push(`v ${verts[i++]} ${verts[i++]} ${verts[i++]}`);
obj.push(`v ${verts[i++]} ${verts[i++]} ${verts[i++]}`);
obj.push(`v ${verts[i++]} ${verts[i++]} ${verts[i++]}`);
obj.push(`f ${p} ${p+1} ${p+2}`);
}
}
return obj.join('\n');
default:
throw `invalid format "${format}"`;
}
}
};
function debug() {
console.log({work_cache: cache});
});
}
worker.bindObject({
debug,
model,
group,
object
object,
file
});
worker.ready();

View file

@ -86,12 +86,13 @@ const dispatch = moto.worker = {
if (run) {
try {
let data = run(msg.data, send);
if (data || async === false) {
if (!done && (data || async === false)) {
send.done(data);
}
} catch (error) {
console.trace(error.stack);
dispatch.send({ data: {error: error.toString()}, done: true });
send.error(error.toString());
// dispatch.send({ data: {error: error.toString()}, done: true });
}
} else {
console.log({worker_unhandled: e});