persist surface op selections with minimal face data

This commit is contained in:
Stewart Allen 2022-04-06 21:25:11 -07:00
commit de0c224f6d
3 changed files with 96 additions and 62 deletions

View file

@ -11,8 +11,7 @@ const { newPoint, newPolygon } = base;
const { driver } = kiri;
const { CAM } = driver;
let PRO = CAM.process,
isAnimate,
let isAnimate,
isArrange,
isCamMode,
isParsed,
@ -568,20 +567,29 @@ CAM.init = function(kiri, api) {
func.traceDone();
func.surfaceDone();
alert = api.show.alert("analyzing surfaces...", 1000);
CAM.surfaces(data => {
let surfaces = poppedRec.surfaces;
CAM.surfaces(() => {
api.hide.alert(alert);
alert = api.show.alert("[esc] cancels surface editing");
for (let [wid, arr] of Object.entries(surfaces)) {
let widget = api.widgets.forid(wid);
if (widget && arr.length)
for (let faceid of arr) {
CAM.surface_toggle(widget, faceid, faceids => {
// surfaces[widget.id] = faceids;
});
}
}
});
surfaceOn = hoveredOp;
surfaceOn.classList.add("editing");
api.feature.on_mouse_up = (obj, ev) => {
let { face } = obj;
let min = Math.min(face.a, face.b, face.c);
let faceid = min / 3;
let widget = lastWidget = obj.object.widget;
CAM.surface_find(widget.id, min / 3, faces => {
if (faces && faces.length) {
widget.selectFaces(faces);
}
CAM.surface_toggle(widget, faceid, faceids => {
surfaces[widget.id] = faceids;
});
};
};
@ -589,7 +597,12 @@ CAM.init = function(kiri, api) {
if (!surfaceOn) {
return;
}
lastWidget.selectFaces([]);
if (lastWidget) {
let surfaces = poppedRec.surfaces;
for (let wid of Object.keys(surfaces)) {
CAM.surface_clear(api.widgets.forid(wid));
}
}
api.hide.alert(alert);
api.feature.on_mouse_up = undefined;
surfaceOn.classList.remove("editing");

View file

@ -24,68 +24,88 @@ CAM.process = {
// defer loading until kiri.client and kiri.worker exist
kiri.load(api => {
if (kiri.client)
CAM.traces = function(ondone, single) {
kiri.client.sync();
const settings = api.conf.get();
const widgets = api.widgets.map();
kiri.client.send("cam_traces", { settings, single }, output => {
const ids = [];
kiri.codec.decode(output).forEach(rec => {
ids.push(rec.id);
widgets[rec.id].traces = rec.traces;
if (kiri.client) {
CAM.surfaces = function(ondone) {
kiri.client.sync();
const settings = api.conf.get();
kiri.client.send("cam_surfaces", { settings }, output => {
ondone(output);
});
ondone(ids);
});
};
};
if (kiri.worker)
kiri.worker.cam_traces = function(data, send) {
const { settings, single } = data;
const widgets = Object.values(kiri.worker.cache);
const fresh = widgets.filter(widget => CAM.traces(settings, widget, single));
send.done(kiri.codec.encode(fresh.map(widget => { return {
id: widget.id,
traces: widget.traces,
} } )));
};
function select_face_groups(widget) {
widget.selectFaces(Object.values(widget._surfaces).flat());
};
if (kiri.client)
CAM.surfaces = function(ondone) {
kiri.client.sync();
const settings = api.conf.get();
kiri.client.send("cam_surfaces", { settings }, output => {
ondone(output);
});
};
if (kiri.worker)
kiri.worker.cam_surfaces = function(data, send) {
const { settings } = data;
const widgets = Object.values(kiri.worker.cache);
for (let widget of widgets) {
if (!widget.tool) {
let tool = widget.tool = new mesh.tool();
tool.generateFaceMap(widget.getVertices().array);
CAM.surface_toggle = function(widget, face, ondone) {
let surfaces = widget._surfaces = widget._surfaces || {};
for (let [root, faces] of Object.entries(surfaces)) {
if (faces.contains(face)) {
// delete this face group
delete surfaces[root];
select_face_groups(widget);
ondone(Object.keys(surfaces));
return;
}
}
kiri.client.send("cam_surface_find", { id: widget.id, face }, faces => {
surfaces[face] = faces;
select_face_groups(widget);
ondone(Object.keys(surfaces));
});
};
CAM.surface_clear = function(widget) {
widget.selectFaces([]);
widget._surfaces = {};
};
CAM.traces = function(ondone, single) {
kiri.client.sync();
const settings = api.conf.get();
const widgets = api.widgets.map();
kiri.client.send("cam_traces", { settings, single }, output => {
const ids = [];
kiri.codec.decode(output).forEach(rec => {
ids.push(rec.id);
widgets[rec.id].traces = rec.traces;
});
ondone(ids);
});
};
}
if (kiri.worker) {
kiri.worker.cam_surfaces = function(data, send) {
const { settings } = data;
const widgets = Object.values(kiri.worker.cache);
for (let widget of widgets) {
if (!widget.tool) {
let tool = widget.tool = new mesh.tool();
tool.generateFaceMap(widget.getVertices().array);
}
}
send.done({});
};
kiri.worker.cam_surface_find = function(data, send) {
const { id, face } = data;
const widget = kiri.worker.cache[id];
const faces = widget.tool.findConnectedSurface([face], 0.1, 0.001);
send.done(faces);
}
send.done({});
};
if (kiri.client)
CAM.surface_find = function(id, face, ondone) {
kiri.client.send("cam_surface_find", { id, face }, faces => {
ondone(faces);
});
};
kiri.worker.cam_traces = function(data, send) {
const { settings, single } = data;
const widgets = Object.values(kiri.worker.cache);
const fresh = widgets.filter(widget => CAM.traces(settings, widget, single));
send.done(kiri.codec.encode(fresh.map(widget => { return {
id: widget.id,
traces: widget.traces,
} } )));
};
}
if (kiri.worker)
kiri.worker.cam_surface_find = function(data, send) {
const { id, face } = data;
const widget = kiri.worker.cache[id];
const faces = widget.tool.findConnectedSurface([face], 0.1, 0.001);
send.done(faces);
};
});
});