UNPKG

awv3

Version:
259 lines (218 loc) 12.5 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _getIterator2 = require('babel-runtime/core-js/get-iterator'); var _getIterator3 = _interopRequireDefault(_getIterator2); var _extends2 = require('babel-runtime/helpers/extends'); var _extends3 = _interopRequireDefault(_extends2); var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck'); var _classCallCheck3 = _interopRequireDefault(_classCallCheck2); var _createClass2 = require('babel-runtime/helpers/createClass'); var _createClass3 = _interopRequireDefault(_createClass2); var _highlevel = require('./command/highlevel'); var _lowlevel = require('./command/lowlevel'); var _type = require('./constraint/type'); var _geomutils = require('./geomutils'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var FilletProcessor = function () { function FilletProcessor(sketch) { (0, _classCallCheck3.default)(this, FilletProcessor); this.sketch = sketch; } // check if the given position is at the angle that can be filleted // return full information about the angle or null (0, _createClass3.default)(FilletProcessor, [{ key: 'recognizeFilletableAngle', value: function recognizeFilletableAngle(pos) { // find exactly matching points - children of lines var samePoints = this.findPointsAt(pos).filter(function (obj) { return obj.parent.isLine(); }); // exactly two curves must end at pos if (samePoints.length !== 2) return null; // these two points must be marked as incident var incidenceConstr = this.findConstraints(_type.incidence.type, samePoints[0], samePoints[1]); if (incidenceConstr.length !== 1) return null; // check that parent lines are not collinear var dirA = (0, _geomutils.getTangent)(lines[0].geomParams), dirB = (0, _geomutils.getTangent)(lines[1].geomParams); if (Math.abs(dirA.cross(dirB).z) <= FilletProcessor.angularTolerance) return null; //return all the found data return { lines: samePoints.map(function (p) { return p.parent; }), lineEnds: samePoints, vertex: samePoints[0], incidenceConstr: incidenceConstr }; } // checks if the given arc is a part of a correct fillet // return full information about the fillet or null }, { key: 'RecognizeFilletByArcOrEdge', value: function RecognizeFilletByArcOrEdge(obj) { var res = { obj: obj, objEnds: [], lines: [], lineEnds: [], vertex: null }; var lineDirs = []; var _arr = [obj.startPoint, obj.endPoint]; for (var _i = 0; _i < _arr.length; _i++) { var objEnd = _arr[_i]; // find incident line var samePoints = this.findPointsAt(objEnd.pos); samePoints = samePoints.filter(function (point) { return point.parent.id !== obj.id && point.parent.state.class === 'CC_Line'; }); if (samePoints.length !== 1) return null; var lineEnd = samePoints[0]; var line = lineEnd.parent; var reversed = lineEnd.state.name === 'endPoint'; // check that all constraints are in objEnd if (this.findConstraints(_type.incidence.type, objEnd, lineEnd).length !== 1) return null; if (obj.state.class === 'CC_Arc' && this.findConstraints(_type.tangency.type, obj, line).length !== 1) return null; // check that a line is tangent at a common point var lineDir = (0, _geomutils.getTangent)(line.geomParams); if (reversed) lineDir.negate(); if (obj.state.class === 'CC_Arc') { var arcDir = (0, _geomutils.getTangent)(obj.geomParams, objEnd.pos); if (objEnd.state.name === 'startPoint') arcDir.negate(); if (lineDir.distanceTo(arcDir) > FilletProcessor.angularTolerance) return null; } // save found objects res.objEnds.push(objEnd); res.lines.push(line); res.lineEnds.push(lineEnd); lineDirs.push(lineDir); } /* check that the fillet angle is in range (0; pi) TODO if (obj.state.class === 'CC_Arc') { var angle = Math.PI - obj.getAngle(); } else { var angle = lineDirs[0].angleTo(lineDirs[1]); } if (angle <= this.angularTolerance || angle >= Math.PI - FilletProcessor.angularTolerance) return null; */ // calculate the location of the fillet's vertex var vertexPos = (0, _geomutils.intersectLines)(res.lineEnds[0].pos, lineDirs[0], res.lineEnds[1].pos, lineDirs[1], FilletProcessor.angularTolerance); if (!vertexPos) return null; // check for a point there var vertices = this.findPointsAt(vertexPos); if (vertices.length !== 1) return null; res.vertex = vertices[0]; // check incidence of the vertex to lines for (var i = 0; i < 2; ++i) { if (this.findConstraints(_type.incidence.type, res.vertex, res.lines[i]).length !== 1) return null; }return res; } // calculate the filleting arc params (center, touch points) by specified radius }, { key: 'calculateFilletParamsByRadius', value: function calculateFilletParamsByRadius(info, radius) { var touch = this.getTouchPoints(info, radius, undefined); if (!touch) return null; return (0, _extends3.default)({}, (0, _geomutils.drawArcBy_S_E_CPh)(touch[0], touch[1], info.vertex.pos), { control: info.vertex.pos }); } }, { key: 'calculateChamferParamsByOffset', value: function calculateChamferParamsByOffset(info, offset) { var touch = this.getTouchPoints(info, undefined, offset); if (!touch) return null; return { start: touch[0], end: touch[1], control: info.vertex.pos }; } }, { key: 'findPointsAt', value: function findPointsAt(pos) { var samePoints = []; var _iteratorNormalCompletion = true; var _didIteratorError = false; var _iteratorError = undefined; try { for (var _iterator = (0, _getIterator3.default)(this.sketch.descendants), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { var obj = _step.value; if (obj.state.class === 'CC_Point' && obj.pos.distanceTo(pos) <= FilletProcessor.linearTolerance) samePoints.push(obj); } } catch (err) { _didIteratorError = true; _iteratorError = err; } finally { try { if (!_iteratorNormalCompletion && _iterator.return) { _iterator.return(); } } finally { if (_didIteratorError) { throw _iteratorError; } } } return samePoints; } }, { key: 'findConstraints', value: function findConstraints(type, objA, objB) { return this.sketch.children.filter(function (constr) { return constr.state.class === type && (constr.entities[0].id === objA.id && constr.entities[1].id === objB.id || constr.entities[0].id === objB.id && constr.entities[1].id === objA.id); }); } }, { key: 'getTouchPoints', value: function getTouchPoints(info, radius, distance) { var vertexPos = info.vertex.pos; var dirs = [], dists = []; var _iteratorNormalCompletion2 = true; var _didIteratorError2 = false; var _iteratorError2 = undefined; try { for (var _iterator2 = (0, _getIterator3.default)(info.lineEnds), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { var lineEnd = _step2.value; var lineGeomParams = lineEnd.parent.geomParams; dir.push((0, _geomutils.getTangent)(lineGeomParams)); if (lineEnd.state.name === 'endPoint') dir[dir.length - 1].negate(); dists.push(vertexPos.distanceTo(lineEnd) + lineGeomParams.start.distanceTo(lineGeomParams.end)); } } catch (err) { _didIteratorError2 = true; _iteratorError2 = err; } finally { try { if (!_iteratorNormalCompletion2 && _iterator2.return) { _iterator2.return(); } } finally { if (_didIteratorError2) { throw _iteratorError2; } } } var angle = dirs[0].angleTo(dirs[1]), dist = distance !== undefined ? distance : radius / Math.tan(angle / 2); if (dist + FilletProcessor.linearTolerance >= Math.max(dists[0], dists[1])) return null; // too large fillet return dirs.map(function (dir) { return dir.clone().multiplyScalar(dist).add(vertexPos); }); } }, { key: 'createNewFilletStatement', value: function createNewFilletStatement(info, params) { var vertex = (0, _lowlevel.Variable)(), curve = (0, _lowlevel.Variable)(); return (0, _lowlevel.Sequence)((0, _highlevel.removeCommand)(this.sketch, info.incidenceConstr), (0, _highlevel.updateCommand)(this.sketch, info.lineEnds[0], { start: params.start }), (0, _highlevel.updateCommand)(this.sketch, info.lineEnds[1], { start: params.end }), (0, _lowlevel.Assign)(vertex, (0, _highlevel.addCommand)(this.sketch, { start: params.vertexPos })), (0, _lowlevel.Assign)(curve, (0, _highlevel.addCommand)(this.sketch, params)), (0, _highlevel.addCommand)(this.sketch, { type: _type.incidence.type, entities: [info.lines[0], vertex], value: {} }), (0, _highlevel.addCommand)(this.sketch, { type: _type.incidence.type, entities: [info.lines[1], vertex], value: {} }), (0, _highlevel.addCommand)(this.sketch, { type: _type.incidence.type, entities: [info.lines[0], (0, _lowlevel.Member)(curve, 'startPoint')], value: {} }), (0, _highlevel.addCommand)(this.sketch, { type: _type.incidence.type, entities: [info.lines[1], (0, _lowlevel.Member)(curve, 'endPoint')], value: {} }), (0, _highlevel.addCommand)(this.sketch, { type: _type.tangency.type, entities: [info.lines[0], curve], value: {} }), (0, _highlevel.addCommand)(this.sketch, { type: _type.tangency.type, entities: [info.lines[1], curve], value: {} })); } }, { key: 'deleteFilletStatement', value: function deleteFilletStatement(info) { return (0, _lowlevel.Sequence)((0, _highlevel.removeCommand)(this.sketch, info.obj), (0, _highlevel.removeCommand)(this.sketch, info.vertex), (0, _highlevel.updateCommand)(this.sketch, info.lineEnds[1], { start: info.vertex.pos }), (0, _highlevel.updateCommand)(this.sketch, info.lineEnds[0], { start: info.vertex.pos }), (0, _highlevel.addCommand)(this.sketch, { type: _type.incidence.type, entities: [info.lineEnds[0], info.lineEnds[1]], value: {} })); } }, { key: 'updateFilletStatement', value: function updateFilletStatement(info, params) { return (0, _lowlevel.Sequence)((0, _highlevel.updateCommand)(this.sketch, info.lineEnds[0], { start: params.start }), (0, _highlevel.updateCommand)(this.sketch, info.lineEnds[1], { start: params.end }), (0, _highlevel.updateCommand)(this.sketch, info.obj, params)); } }]); return FilletProcessor; }(); FilletProcessor.linearTolerance = 1e-3; FilletProcessor.angularTolerance = 1e-3; exports.default = FilletProcessor;