UNPKG

awv3

Version:
470 lines (378 loc) 14.9 kB
import _extends from "@babel/runtime/helpers/extends"; import _regeneratorRuntime from "@babel/runtime/regenerator"; import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator"; import _inheritsLoose from "@babel/runtime/helpers/inheritsLoose"; import * as THREE from 'three'; import Object3 from '../../../three/object3'; import Ccfuturef from '../ccfuturef'; import Ccref from '../ccref'; import { addCommand, restrictionCommands } from '../command/highlevel'; import { Assign, IdToReal, Variable, Return, Sequence } from '../command/lowlevel'; import { incidence } from '../constraint/type'; import { drawPointBy_S, drawLineBy_S_E, drawArcBy_S_E_C, drawArcBy_S_E_M, drawArcBy_S_T_E, drawCircleBy_C_E, getTangent } from '../geomutils'; import { updateGeomObjectContainer } from '../preview'; import BaseHandler from './base'; var Mode = Object.freeze({ point: 'point', line: 'line', arccenter: 'arccenter', arcmiddle: 'arcmiddle', arctangent: 'arctangent', circle: 'circle' }); var DrawHandler = /*#__PURE__*/ function (_BaseHandler) { _inheritsLoose(DrawHandler, _BaseHandler); function DrawHandler(sketcher, name) { var _this; _this = _BaseHandler.call(this, sketcher, name) || this; _this.endPoint = null; // ccref of the last point of the polyline _this.endTangent = null; // normalized THREE.Vector3() tangent of the last edge _this.positions = [new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3()]; _this.preview = new THREE.Group(); _this.sketcher.pool.add(_this.preview); _this.queue = new PromiseQueue(); _this.startPointRestrictions = {}; _this.restrictions = {}; _this.startPoint = null; // ccref of the first point of the polyline _this.state = 0; // number of element filled in this.positions _this.statesCount = 2; // number of states needed to create an edge return _this; } var _proto = DrawHandler.prototype; _proto.destroy = function destroy() { this.preview.destroy(); this.sketcher.setCursorCoordinates(undefined); _BaseHandler.prototype.destroy.call(this); }; _proto.filterObjectsWithInteraction = function filterObjectsWithInteraction(object) { return object.id === this.sketch.id && object.graphics !== undefined; }; _proto[Object3.Events.Interaction.Clicked] = function (object, hitObject) { var _this2 = this; var ray = hitObject.ray.clone().applyMatrix4(new THREE.Matrix4().getInverse(this.sketch.matrixWorld)); var position = new THREE.Vector3(); ray.intersectPlane(new THREE.Plane(new THREE.Vector3(0, 0, 1)), position); return this.queue.run(function () { return _this2.afterEdgeAdded(_this2.click(position)); }); }; _proto.afterEdgeAdded = /*#__PURE__*/ function () { var _afterEdgeAdded = _asyncToGenerator( /*#__PURE__*/ _regeneratorRuntime.mark(function _callee(geomParams) { var object, objectStartPoint, manualConstrCommand, command, p, ccref; return _regeneratorRuntime.wrap(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: if (geomParams) { _context.next = 2; break; } return _context.abrupt("return"); case 2: object = new Ccfuturef(Variable(), geomParams); objectStartPoint = object.isCircle() ? object.center : object.startPoint; manualConstrCommand = this.endPoint && !this.sketcher.autoconstraintIncremental ? addCommand(this.sketch, { class: incidence.type, entities: [this.endPoint, objectStartPoint], value: {} }) : null; command = Sequence.apply(void 0, [Assign(object, addCommand(this.sketch, geomParams))].concat(this.sketcher.autoconstraintCommands(object), restrictionCommands(this.sketch, objectStartPoint, this.startPointRestrictions), restrictionCommands(this.sketch, object, this.restrictions), [manualConstrCommand, Return(IdToReal(object))])); p = this.sketcher.run(command); this.sketcher.incrementalSolveConstraints(); if (!(!object.isLine() && !object.isArc())) { _context.next = 11; break; } this.endPolyline(); return _context.abrupt("return", p); case 11: _context.t0 = Ccref; _context.t1 = this.sketcher; _context.next = 15; return p; case 15: _context.t2 = _context.sent; ccref = new _context.t0(_context.t1, _context.t2); this.startPointRestrictions = {}; this.restrictions = {}; this.startPoint = this.startPoint || ccref.startPoint; this.endPoint = ccref.endPoint || this.endPoint; this.endTangent = getTangent(ccref.geomParams, this.endPoint.pos); this.click(this.endPoint.pos); case 23: case "end": return _context.stop(); } } }, _callee, this); })); return function afterEdgeAdded(_x) { return _afterEdgeAdded.apply(this, arguments); }; }(); _proto.cancel = function cancel() { if (this.state !== 0) this.endPolyline();else _BaseHandler.prototype.cancel.call(this); }; _proto.endPolyline = function endPolyline() { this.endPoint = null; this.endTangent = null; this.startPointRestrictions = {}; this.restrictions = {}; this.startPoint = null; this.state = 0; this.onMouseMove(); }; _proto.closePolyline = /*#__PURE__*/ function () { var _closePolyline = _asyncToGenerator( /*#__PURE__*/ _regeneratorRuntime.mark(function _callee2() { var geomParams, object, command; return _regeneratorRuntime.wrap(function _callee2$(_context2) { while (1) { switch (_context2.prev = _context2.next) { case 0: if (!(!this.startPoint || !this.endPoint)) { _context2.next = 2; break; } return _context2.abrupt("return"); case 2: geomParams = { start: this.startPoint.pos, end: this.endPoint.pos }; object = new Ccfuturef(Variable(), geomParams); command = Sequence(Assign(object, addCommand(this.sketch, geomParams)), addCommand(this.sketch, { class: incidence.type, entities: [this.endPoint, object.startPoint], value: {} }), addCommand(this.sketch, { class: incidence.type, entities: [object.endPoint, this.startPoint], value: {} })); _context2.next = 7; return this.sketcher.run(command); case 7: this.endPolyline(); case 8: case "end": return _context2.stop(); } } }, _callee2, this); })); return function closePolyline() { return _closePolyline.apply(this, arguments); }; }(); _proto.click = function click(position, doSnapping) { if (doSnapping === void 0) { doSnapping = true; } var geomParams = this.move(position, true, doSnapping); if (!this.handleClick(this.positions[this.state])) return; if (++this.state === this.statesCount) { this.state = 0; return geomParams; } else if (this.state === 1) { this.startPointRestrictions = this.restrictions; this.restrictions = {}; } }; _proto.getPreviewGeomParams = function getPreviewGeomParams() { if (this.state === 0) return drawPointBy_S(this.positions, this.restrictions); switch (this.name) { case Mode.point: return drawPointBy_S(this.positions, this.restrictions); case Mode.line: return drawLineBy_S_E(this.positions, this.restrictions); case Mode.arccenter: return drawArcBy_S_E_C(this.positions, this.restrictions); case Mode.arcmiddle: return drawArcBy_S_E_M(this.positions, this.restrictions); case Mode.arctangent: return drawArcBy_S_T_E([this.positions[0], this.endTangent, this.positions[1]], this.restrictions); case Mode.circle: return drawCircleBy_C_E(this.positions, this.restrictions); } }; _proto.move = function move(position, force, doSnapping) { if (doSnapping === void 0) { doSnapping = true; } if (!force && this.queue.isBusy()) return; if (doSnapping) position.copy(this.doSnapping(position)); this.sketcher.setCursorCoordinates(position); for (var i = this.state; i < this.positions.length; ++i) { this.positions[i].copy(position); } var previewParams = this.getPreviewGeomParams(); if (this.state === 0) this.positions[0].copy(previewParams.start); updateGeomObjectContainer(this.preview, _extends({ coordinateSystem: this.sketch.graphics.matrix, scale: this.sketcher.graphicScale }, previewParams)); return previewParams; }; _proto.onMouseMove = function onMouseMove() { this.move(this.getRecentMousePosition()); this.sketcher.refresh(); }; _proto.switchMode = function switchMode(mode) { if (this.state > 1) this.state = 1; this.statesCount = mode === Mode.point ? 1 : mode === Mode.arccenter || mode === Mode.arcmiddle ? 3 : 2; // handler switching logic in handler/index.js expects mode to be stored in this.name this.name = mode; }; _proto.consoleComplete = function consoleComplete(cmd) { cmd = cmd.trim(); var tokens = cmd === '' ? [] : cmd.split(/\s+/); var completions = _BaseHandler.prototype.consoleComplete.call(this, cmd); if (completions.indexOf(cmd) !== -1) return completions; return [cmd].concat(this.name.startsWith('point') ? [cmd + " ax", cmd + " ay"] : this.name.startsWith('line') ? [cmd + " l", cmd + " a", cmd + " x", cmd + " y"] : this.name.startsWith('arc') ? [cmd + " a", cmd + " r", cmd + " cw", cmd + " ccw"] : [], completions); }; _proto.consoleExecute = function consoleExecute(cmd) { if (_BaseHandler.prototype.consoleExecute.call(this, cmd)) return; // switch handlers if (cmd === 'cl' || cmd === 'close') return this.closePolyline();else return this.afterEdgeAdded(this.click(this.getRecentMousePosition(), false)); }; _proto.parseRestrictions = function parseRestrictions(cmd) { var tokens = cmd.trim().split(/\s+/); this.restrictions = {}; while (tokens.length !== 0) { var name = tokens.shift(); var value = Number.NaN; switch (name) { case 'x': name = 'xoffset'; value = Number(tokens.shift()); break; case 'y': name = 'yoffset'; value = Number(tokens.shift()); break; case 'ax': name = 'xabsolute'; value = Number(tokens.shift()); break; case 'ay': name = 'yabsolute'; value = Number(tokens.shift()); break; case 'l': name = 'length'; value = Number(tokens.shift()); break; case 'a': name = 'angle'; value = Math.PI / 180 * Number(tokens.shift()); break; case 'r': name = 'radius'; value = Number(tokens.shift()); break; case 'cw': name = 'clockwise'; value = true; break; case 'ccw': name = 'clockwise'; value = false; break; } if (!isFinite(value)) continue; this.restrictions[name] = value; } // update priview this.onMouseMove(); }; _proto.doSnapping = function doSnapping(position) { if (this.preview.geomType === 'CC_Point') return this.createSnapper().snapPoint(position).position; if (this.preview.geomType === 'CC_Line') return this.createSnapper().snapPoint(position).position; if (this.preview.geomType === 'CC_Arc') return this.createSnapper().snapPoint(position).position; return position; }; _proto.handleClick = function handleClick(position) { if (!this.endTangent) { var variants = []; // for all lines/arcs on the sketch for (var _iterator = this.sketch.children, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) { var _ref; if (_isArray) { if (_i >= _iterator.length) break; _ref = _iterator[_i++]; } else { _i = _iterator.next(); if (_i.done) break; _ref = _i.value; } var _object = _ref; if (!_object.isLine() && !_object.isArc()) continue; // for their endpoint matching position var _arr = ['startPoint', 'endPoint']; for (var _i2 = 0; _i2 < _arr.length; _i2++) { var end = _arr[_i2]; if (!_object[end].pos.equals(position)) continue; var tangent = getTangent(_object.geomParams, position); if (tangent.lengthSq() === 0) continue; if (end === 'startPoint') tangent.negate(); variants.push(tangent); } } // deny click in arctangent mode if doesn't uniquely determine the tangent if (this.name === 'arctangent' && variants.length !== 1) return false; this.endTangent = variants[0] || new THREE.Vector3(); return true; } return true; }; return DrawHandler; }(BaseHandler); export { DrawHandler as default }; var PromiseQueue = /*#__PURE__*/ function () { function PromiseQueue() { this.nPending = 0; this.promise = Promise.resolve(); } var _proto2 = PromiseQueue.prototype; _proto2.run = function run(functor) { var _this3 = this; this.promise = function () { var _ref2 = _asyncToGenerator( /*#__PURE__*/ _regeneratorRuntime.mark(function _callee3(promise) { return _regeneratorRuntime.wrap(function _callee3$(_context3) { while (1) { switch (_context3.prev = _context3.next) { case 0: ++_this3.nPending; _context3.next = 3; return promise; case 3: _context3.next = 5; return functor(); case 5: --_this3.nPending; case 6: case "end": return _context3.stop(); } } }, _callee3, this); })); return function (_x2) { return _ref2.apply(this, arguments); }; }()(this.promise); return this.promise; }; _proto2.isBusy = function isBusy() { return this.nPending > 0; }; return PromiseQueue; }();