UNPKG

awv3

Version:
502 lines (428 loc) 14.5 kB
import _inheritsLoose from "@babel/runtime/helpers/inheritsLoose"; import _assertThisInitialized from "@babel/runtime/helpers/assertThisInitialized"; import _extends from "@babel/runtime/helpers/extends"; var _class, _temp2; import * as THREE from 'three'; import React from 'react'; import { connect } from 'react-redux'; import PropTypes from 'prop-types'; import Plugin from '../../session/plugin'; import Object3 from '../../three/object3'; var resources = ['measure'].reduce(function (prev, item) { var _extends2; return _extends({}, prev, (_extends2 = {}, _extends2[item] = require('!!url-loader!awv3-icons/32x32/' + item + '.png'), _extends2)); }, {}); var Root = (_temp2 = _class = /*#__PURE__*/ function (_React$Component) { _inheritsLoose(Root, _React$Component); function Root() { var _temp, _this; for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } return (_temp = _this = _React$Component.call.apply(_React$Component, [this].concat(args)) || this, Object.defineProperty(_assertThisInitialized(_this), "state", { configurable: true, enumerable: true, writable: true, value: { items: [], labels: [] } }), Object.defineProperty(_assertThisInitialized(_this), "handleChange", { configurable: true, enumerable: true, writable: true, value: function value(items) { var selectedItems = _this.context.session.selector.selectedItems; var labels = Measure.solve(selectedItems); _this.setState({ items: items, labels: labels }); } }), _temp) || _assertThisInitialized(_this); } var _proto = Root.prototype; _proto.render = function render() { var _context$plugin = this.context.plugin, selectionActive = _context$plugin.selectionActive, selectionVisible = _context$plugin.selectionVisible, maxNofLabels = _context$plugin.maxNofLabels; return React.createElement("group", null, React.createElement("selection", { types: ['Mesh', 'LineSegments', 'Region'], visible: selectionVisible, active: selectionActive, items: this.state.items, onItems: this.handleChange, limit: 10 }), this.state.labels.slice(0, maxNofLabels).map(function (label, index) { return React.createElement("group", { key: index, format: "Rows" }, React.createElement("label", { value: index + ".", flex: 0.1 }), React.createElement("label", { value: label.description }), React.createElement("label", { value: label.result })); })); }; return Root; }(React.Component), Object.defineProperty(_class, "contextTypes", { configurable: true, enumerable: true, writable: true, value: { session: PropTypes.object, plugin: PropTypes.object } }), _temp2); /** * Class Measure is based on awv3's plugin architecture. It calculates distances * and angles between various selected geometry elements. */ var Measure = /*#__PURE__*/ function (_Plugin) { _inheritsLoose(Measure, _Plugin); function Measure(session, args) { return _Plugin.call(this, session, _extends({ type: 'Measure', icon: 'measure', selectionVisible: true, selectionActive: true, maxNofLabels: 10, render: React.createElement(Root, null), resources: resources }, args)) || this; } Measure.transform = function transform(_ref) { var object = _ref.object, material = _ref.material; return _extends({}, material.meta, Object.keys(material.meta).filter(function (key) { return material.meta[key] instanceof THREE.Vector3; }).reduce(function (acc, key) { var _extends3; var transform = key.includes('normal') ? material.meta[key].clone().applyMatrix3(new THREE.Matrix3().getNormalMatrix(object.matrixWorld)) : object.localToWorld(material.meta[key].clone()); return _extends({}, acc, (_extends3 = {}, _extends3[key] = transform, _extends3)); }, {})); }; /** * This function triggers the calculation of distances / angles between * two geometry objects or gets a description for each selected object * if the number of objects is not equal to two. * * objects = Array of hits as given by the selector originally * The critical parts are: { object, material } */ Measure.solve = function solve(objects) { // Transform meta correctly var transforms = objects.map(function (object) { return Measure.transform(object); }); // this.storeSelectedIds(objects) switch (transforms.length) { case 2: return Measure.calculateMeasures(transforms); default: return transforms.map(function (item) { return Measure.getInfo(item); }); } }; /** * Collects information about a single geometry element * @param {three object} element - the meta data * @return { object } - Calculated information object with result * {number} and description {string} */ Measure.getInfo = function getInfo(element) { switch (element.type) { case 'point': return { result: "[ " + element.position.toArray().map(function (n) { return Math.round(n * 100) / 100; }).join(', ') + " ]", description: 'Position' }; case 'line': { var absoluteDistance = element.start.distanceTo(element.end); absoluteDistance = Measure.round(absoluteDistance, 3); return { result: absoluteDistance, description: 'Line length' }; } case 'arc': return { result: element.radius, description: 'Arc radius' }; case 'circle': return { result: element.radius, description: 'Circle radius' }; case 'nurbs': return { result: 0, description: 'NURBS' }; case 'plane': return { result: "[ " + element.normal.toArray().map(function (n) { return Math.round(n * 100) / 100; }).join(', ') + " ]", description: 'Plane normal' }; case 'cylinder': return { result: "R:" + element.radius + ", L:" + element.height, description: 'Cylinder' }; case 'cone': var R = Math.max(element.radiusBottom, element.radiusTop); var r = Math.min(element.radiusBottom, element.radiusTop); return { result: "R:" + R + ", r:" + r + ", L:" + element.height, description: 'Cone' }; case 'sphere': return { result: element.radius, description: 'Sphere radius' }; case 'nurbsSurface': return { result: 0, description: 'NURBS Surface' }; default: return { result: 0, description: 'Undefined' }; } }; Measure.calculateMeasures = function calculateMeasures(objects) { var first = objects[0]; var second = objects[1]; var results = []; switch (first.type) { case 'point': switch (second.type) { case 'point': results = Measure.calculatePointPoint(first, second); break; case 'line': results = Measure.calculatePointLine(first, second); break; case 'plane': results = Measure.calculatePointPlane(first, second); } break; case 'line': switch (second.type) { case 'point': results = Measure.calculatePointLine(second, first); break; case 'line': results = Measure.calculateLineLine(first, second); break; case 'plane': results = Measure.calculateLinePlane(first, second); } break; case 'plane': { switch (second.type) { case 'point': results = Measure.calculatePointPlane(second, first); break; case 'line': results = Measure.calculateLinePlane(second, first); break; case 'arc': results = Measure.calculateArcPlane(first, second); break; case 'plane': console.log(first, second); results = Measure.calculatePlanePlane(first, second); } } } return results; }; Measure.calculatePointPoint = function calculatePointPoint(point1, point2) { var distance = Measure.distancePointPoint(point1, point2); distance = Measure.round(distance, 3); var dx = Measure.round(Math.abs(point1.position.x - point2.position.x), 3); var dy = Measure.round(Math.abs(point1.position.y - point2.position.y), 3); var dz = Measure.round(Math.abs(point1.position.z - point2.position.z), 3); return [{ result: distance, description: 'Distance' }, { result: dx, description: 'dx' }, { result: dy, description: 'dy' }, { result: dz, description: 'dz' }]; }; Measure.calculatePointLine = function calculatePointLine(point, line) { var distance = Measure.distancePointLine(point.position, line); distance = Measure.round(distance, 3); return [{ result: distance, description: 'Distance' }]; }; Measure.calculatePointPlane = function calculatePointPlane(point, plane) { var distance = Measure.distancePointPlane(point.position, plane); distance = Measure.round(distance, 3); return [{ result: distance, description: 'Distance' }]; }; Measure.calculateLineLine = function calculateLineLine(first, second) { var distance = Measure.distanceLineLine(first, second); distance = Measure.round(distance, 3); var angle = Measure.degrees(Measure.angleLineLine(first, second)); angle = Measure.round(angle, 3); var angleS = 180 - angle; return [{ result: distance, description: 'Distance' }, { result: angle, description: 'Angle1' }, { result: angleS, description: 'Angle2' }]; }; Measure.calculateLinePlane = function calculateLinePlane(line, plane) { var distance = Measure.distanceLinePlane(line, plane); distance = Measure.round(distance, 3); return [{ result: distance, description: 'Distance' }]; }; Measure.calculateArcPlane = function calculateArcPlane(arc, plane) { var distance = Measure.distanceArcPlane(arc, plane); distance = Measure.round(distance, 3); return [{ result: distance, description: 'Distance' }]; }; Measure.calculatePlanePlane = function calculatePlanePlane(plane1, plane2) { var distance = Measure.distancePlanePlane(plane1, plane2); distance = Measure.round(distance, 3); var angle = Measure.degrees(Measure.anglePlanePlane(plane1, plane2)); angle = Measure.round(angle, 3); return [{ result: distance, description: 'Distance' }, { result: angle, description: 'Angle' }]; }; Measure.isNullVector = function isNullVector(vec) { var tolerance = 1e-12; if (Math.abs(vec.x) < tolerance && Math.abs(vec.y) < tolerance && Math.abs(vec.z) < tolerance) { return true; } else { return false; } }; Measure.distancePointPoint = function distancePointPoint(point1, point2) { return point1.position.clone().distanceTo(point2.position); }; Measure.distancePointLine = function distancePointLine(pointPosition, line) { var vec = line.start.clone().sub(line.end); var vecAB = line.start.clone().sub(pointPosition); var distance = 0; var length = vec.length(); if (length > 0) { distance = vec.cross(vecAB).length() / length; } return distance; }; Measure.distanceLineLine = function distanceLineLine(line1, line2) { var vec1 = line1.start.clone().sub(line1.end); var vec2 = line2.start.clone().sub(line2.end); var nVec = vec1.clone().cross(vec2); var distance = 0; if (Measure.isNullVector(nVec)) { // lines are parallel var vecAB = line1.start.clone().sub(line2.start); var nVec2 = vecAB.clone().cross(vec1); if (!Measure.isNullVector(nVec2)) { // lines are not conincident return Measure.distancePointLine(line1.start, line2); } } else { distance = Math.abs(nVec.clone().dot(line2.start.clone().sub(line1.start)) / nVec.length()); } return distance; }; Measure.distanceLinePlane = function distanceLinePlane(line, plane) { var vec = line.start.clone().sub(line.end); var product = vec.dot(plane.normal); if (product < 1e-12) { // line is parallel to plane return Measure.distancePointPlane(line.start, plane); } }; Measure.distanceArcPlane = function distanceArcPlane(arc, plane) { var vec = arc.normal.clone().cross(plane.normal); if (Measure.isNullVector(vec)) { // parallel return Measure.distancePointPlane(arc.center, plane); } }; Measure.distancePointPlane = function distancePointPlane(pointPosition, plane) { var normal = plane.normal.normalize(); var d = -1 * plane.pointOnPlane.clone().dot(normal); return Math.abs(normal.clone().dot(pointPosition) + d) / normal.length(); }; Measure.distancePlanePlane = function distancePlanePlane(plane1, plane2) { var vec = plane1.normal.clone().cross(plane2.normal); if (Measure.isNullVector(vec)) { // parallel return Measure.distancePointPlane(plane1.pointOnPlane, plane2); } else { return 0; } }; Measure.angleLineLine = function angleLineLine(line1, line2) { var vec1 = line1.start.clone().sub(line1.end); var vec2 = line2.start.clone().sub(line2.end); return vec1.angleTo(vec2); }; Measure.anglePlanePlane = function anglePlanePlane(plane1, plane2) { var normal1 = plane1.normal; var normal2 = plane2.normal; return normal1.angleTo(normal2); }; Measure.degrees = function degrees(radians) { return radians / Math.PI * 180; }; Measure.round = function round(value, digits) { var factor = Math.pow(10, digits); return Math.round(value * factor) / factor; }; return Measure; }(Plugin); export { Measure as default };