diff --git a/src/kiri-mode/cam/client.js b/src/kiri-mode/cam/client.js index 7507f48a..6aaaf477 100644 --- a/src/kiri-mode/cam/client.js +++ b/src/kiri-mode/cam/client.js @@ -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"); diff --git a/src/kiri-mode/cam/driver.js b/src/kiri-mode/cam/driver.js index 28fb68f5..1078baa5 100644 --- a/src/kiri-mode/cam/driver.js +++ b/src/kiri-mode/cam/driver.js @@ -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); - }; }); }); diff --git a/src/kiri/widgets.js b/src/kiri/widgets.js index 81a353b7..bcf6a500 100644 --- a/src/kiri/widgets.js +++ b/src/kiri/widgets.js @@ -110,6 +110,7 @@ const widgets = api.widgets = { count() { return WIDGETS.length }, each(fn) { WIDGETS.slice().forEach(widget => fn(widget)) }, for(fn) { widgets.each(fn) }, + forid(id) { return WIDGETS.filter(w => w.id === id)[0] } }; });