import * as mask from 'gems/mask' import {getAttribute, setAttribute} from '../../../../../modules/scene/objectData'; import {FACE, EDGE, SKETCH_OBJECT} from '../entites'; import {state} from '../../../../../modules/lstream'; export const PICK_KIND = { FACE: mask.type(1), SKETCH: mask.type(2), EDGE: mask.type(3) }; const SELECTABLE_ENTITIES = [FACE, EDGE, SKETCH_OBJECT]; export function activate(context) { const {services, streams} = context; initStateAndServices(context); let domElement = services.viewer.sceneSetup.domElement(); domElement.addEventListener('mousedown', mousedown, false); domElement.addEventListener('mouseup', mouseup, false); let mouseState = { startX: 0, startY: 0 }; function mousedown(e) { mouseState.startX = e.offsetX; mouseState.startY = e.offsetY; } function mouseup(e) { let dx = Math.abs(mouseState.startX - e.offsetX); let dy = Math.abs(mouseState.startY - e.offsetY); let TOL = 1; if (dx < TOL && dy < TOL) { if (e.button !== 0) { handleSolidPick(e); } else { handlePick(e); } } } function selected(selection, object) { return selection.value.indexOf(object) !== -1; } function handlePick(event) { raycastObjects(event, PICK_KIND.FACE | PICK_KIND.SKETCH | PICK_KIND.EDGE, (view, kind) => { let modelId = view.model.id; if (kind === PICK_KIND.FACE) { if (dispatchSelection(streams.selection.face, modelId, event)) { services.cadScene.showBasis(view.model.basis(), view.model.depth()); return false; } } else if (kind === PICK_KIND.SKETCH) { if (dispatchSelection(streams.selection.sketchObject, modelId, event)) { return false; } } else if (kind === PICK_KIND.EDGE) { if (dispatchSelection(streams.selection.edge, modelId, event)) { return false; } } return true; }); } function dispatchSelection(selection, selectee, event) { if (selected(selection, selectee)) { return false; } let multiMode = event.shiftKey; selection.update(value => multiMode ? [...value, selectee] : [selectee]); return true; } function handleSolidPick(e) { raycastObjects(e, PICK_KIND.FACE, (sketchFace) => { streams.selection.solid.next([sketchFace.solid]); services.viewer.render(); return false; }); } function raycastObjects(event, kind, visitor) { let pickResults = services.viewer.raycast(event, services.cadScene.workGroup); const pickers = [ (pickResult) => { if (mask.is(kind, PICK_KIND.SKETCH) && pickResult.object instanceof THREE.Line) { let sketchObjectV = getAttribute(pickResult.object, SKETCH_OBJECT); if (sketchObjectV) { return !visitor(sketchObjectV, PICK_KIND.SKETCH); } } return false; }, (pickResult) => { if (mask.is(kind, PICK_KIND.EDGE)) { let edgeV = getAttribute(pickResult.object, EDGE); if (edgeV) { return !visitor(edgeV, PICK_KIND.EDGE); } } return false; }, (pickResult) => { if (mask.is(kind, PICK_KIND.FACE) && !!pickResult.face) { let faceV = getAttribute(pickResult.face, FACE); if (faceV) { return !visitor(faceV, PICK_KIND.FACE); } } return false; }, ]; for (let i = 0; i < pickResults.length; i++) { const pickResult = pickResults[i]; for (let picker of pickers) { if (picker(pickResult)) { return; } } } } } function initStateAndServices({streams, services}) { services.selection = { }; streams.selection = { }; SELECTABLE_ENTITIES.forEach(entity => { let entitySelectApi = { objects: [], single: undefined }; services.selection[entity] = entitySelectApi; let selectionState = state([]); streams.selection[entity] = selectionState; selectionState.attach(selection => { entitySelectApi.objects = selection.map(id => services.cadRegistry.findEntity(entity, id)); entitySelectApi.single = entitySelectApi.objects[0]; }); entitySelectApi.select = selection => selectionState.value = selection; }); //withdraw all streams.craft.models.attach(() => { Object.values(streams.selection).forEach(ss => ss.next([])) }) }