awv3
Version:
⚡ AWV3 embedded CAD
382 lines (305 loc) • 12.9 kB
JavaScript
import _inheritsLoose from "@babel/runtime/helpers/inheritsLoose";
import _assertThisInitialized from "@babel/runtime/helpers/assertThisInitialized";
import cloneDeep from 'lodash/cloneDeep';
import * as THREE from 'three';
import Object3 from '../../three/object3';
export var Handle =
/*#__PURE__*/
function (_THREE$Mesh) {
_inheritsLoose(Handle, _THREE$Mesh);
function Handle(geometry, material) {
var _this;
_this = _THREE$Mesh.call(this, geometry, material) || this;
_this.createInteraction({
priority: 1000,
types: ['DimensionHandle']
});
var _arr = Object.values(Object3.Events);
for (var _i = 0; _i < _arr.length; _i++) {
var category = _arr[_i];
var _arr2 = Object.values(category);
for (var _i2 = 0; _i2 < _arr2.length; _i2++) {
var event = _arr2[_i2];
if (_this[event]) _this.on(event, _this[event].bind(_assertThisInitialized(_this)), {
sync: true
});
}
}
_this.text = undefined;
return _this;
}
var _proto = Handle.prototype;
_proto[Object3.Events.Interaction.Hovered] = function (hitObject) {
this.view.setCursor('grab');
if (this.parent.plugin.selector) this.parent.plugin.selector.hovered(hitObject);else this.animate({
material: {
color: new THREE.Color(this.colors.accent),
opacity: 0.6
}
}).start(0);
};
_proto[Object3.Events.Interaction.Unhovered] = function (hitObject) {
if (this.parent.plugin.selector) this.parent.plugin.selector.unhovered(hitObject);else this.animate({
material: {
color: new THREE.Color(this.colors.primary),
opacity: 0.3
}
}).start(1000);
};
_proto[Object3.Events.Interaction.Picked] = function (hitObject) {
//this.rotateCamera(hitObject.point)
this.view.controls.enabled = false;
this.info.dimension = cloneDeep(this.info.dimension);
};
_proto[Object3.Events.Interaction.Dragged] = function (hitObject) {
this.view.setCursor('grabbing');
var ray = hitObject.ray.clone().applyMatrix4(new THREE.Matrix4().getInverse(this.parent.matrixWorld));
var position = new THREE.Vector3();
ray.intersectPlane(new THREE.Plane(new THREE.Vector3(0, 0, 1)), position);
this.onDrag(this.info, position);
this.parent.updateFromState(this.info);
};
_proto[Object3.Events.Interaction.Dropped] = function (hitObject) {
//if (this.rotated) this.view.controls.back()
this.view.setCursor('grab');
this.view.controls.enabled = true;
this.onDrop(this.info);
};
_proto[Object3.Events.Interaction.Clicked] = function (hitObject) {
if (this.parent.plugin.selector) this.parent.plugin.selector.clicked(hitObject);
};
_proto[Object3.Events.Interaction.Missed] = function (hitObject) {
if (this.parent.plugin.selector) this.parent.plugin.selector.missed(hitObject);
};
_proto[Object3.Events.Lifecycle.Rendered] = function () {
var position = new THREE.Vector3();
this.getWorldPosition(position);
var scale = this.view.calculateScaleFactor(position, 1);
this.onScale(scale);
};
_proto.rotateCamera = function rotateCamera(bubblePos) {
var controls = this.view.controls; // NOTE: controls.up is unchanged
// this means that only sketch normal is aligned, but x/y axis aren't necessary so
var normal = new THREE.Vector3();
this.parent.getWorldDirection(normal); // rotate to the "y-axis-is-up" space used in controls
normal.applyQuaternion(controls._quat);
var theta = Math.atan2(normal.x, normal.z); // -pi to pi
var phi = Math.atan2(Math.hypot(normal.x, normal.z), normal.y); // 0 to pi
var oldCam = (controls.camera || controls.view.camera).display;
oldCam.updateMatrixWorld();
var oldNdc = bubblePos.clone().project(oldCam); //choose whether it is closer to go to opposite side
var worldDir = new THREE.Vector3();
oldCam.getWorldDirection(worldDir);
var dirToCam = worldDir.negate();
if (dirToCam.clone().cross(normal).length() <= 0.1) {
this.rotated = false;
return; //good orientation already
}
this.rotated = true;
if (dirToCam.dot(normal) < 0.0) {
theta += Math.PI;
phi = Math.PI - phi;
}
controls.store().rotate(theta, phi).frame(function () {
var newCam = (controls.camera || controls.view.camera).display;
newCam.updateMatrixWorld(); //determine desired camera displacement to keep bubble fixed
var newNdc = bubblePos.clone().project(newCam);
var from = new THREE.Vector3(newNdc.x, newNdc.y, newNdc.z).unproject(newCam);
var to = new THREE.Vector3(oldNdc.x, oldNdc.y, newNdc.z).unproject(newCam);
var movement = to.clone().sub(from);
movement.negate(); //note: we have to change both orbit.target and camera.position
//because now camera is already set up for current frame
controls.target.add(movement);
newCam.position.add(movement);
});
}; // called when the dimension state changes, should update meshes
_proto.updateFromState = function updateFromState(info) {
this.info = info;
this.colors = this.parent.plugin.session.globals.colors;
this.material.color = new THREE.Color(this.colors.primary);
this.visible = info.visible;
var textParts = [];
if (!info.dimension.members.paramName.value.startsWith('_')) textParts.push(info.dimension.members.paramName.value);
var num = info.dimension.previewValue !== undefined ? info.dimension.previewValue : info.dimension.id ? info.value : undefined;
if (num !== undefined) textParts.push(Number.isInteger(num) ? String(num) : num.toFixed(2));
this.text = textParts.join(' ');
}; // called from Object3.Events.Interaction.Dragged/Dropped, should update state from position
_proto.onDrag = function onDrag(info, position) {}; // called from Object3.Events.Interaction.Dropped, should send state update to the server
_proto.onDrop = function onDrop(info) {}; // called from Object3.Events.Lifecycle.Rendered, should scale meshes
_proto.onScale = function onScale(scale) {};
return Handle;
}(THREE.Mesh);
export var PositionHandle =
/*#__PURE__*/
function (_Handle) {
_inheritsLoose(PositionHandle, _Handle);
function PositionHandle(plugin) {
var _this2;
var colors = plugin.session.globals.colors;
_this2 = _Handle.call(this, new THREE.SphereBufferGeometry(1, 16, 16), new THREE.MeshBasicMaterial({
color: colors.primary,
transparent: true,
opacity: 0.3
})) || this;
_this2.colors = colors;
return _this2;
}
var _proto2 = PositionHandle.prototype;
_proto2.updateFromState = function updateFromState(info) {
_Handle.prototype.updateFromState.call(this, info);
this.position.fromArray(info.dimension.members.dimPt.value);
};
_proto2.onDrag = function onDrag(info, position) {
position.toArray(info.dimension.members.dimPt.value);
};
_proto2.onDrop = function onDrop(info) {
info.dimPt = "{" + info.dimension.members.dimPt.value.join(', ') + "}";
};
_proto2.onScale = function onScale(scale) {
this.scale.setScalar(7 * scale);
};
return PositionHandle;
}(Handle);
export var ValueHandle =
/*#__PURE__*/
function (_Handle2) {
_inheritsLoose(ValueHandle, _Handle2);
function ValueHandle(plugin) {
var _this3;
var colors = plugin.session.globals.colors;
_this3 = _Handle2.call(this, new THREE.SphereBufferGeometry(1.5, 16, 16), new THREE.MeshBasicMaterial({
color: colors.primary,
transparent: true,
opacity: 0.3
})) || this;
_this3.colors = colors;
return _this3;
}
var _proto3 = ValueHandle.prototype;
_proto3.updateFromState = function updateFromState(info) {
_Handle2.prototype.updateFromState.call(this, info);
var dimension = info.dimension;
var _map = ['startPt', 'endPt', 'dimPt', 'cornerPt', 'center'].map(function (x) {
return new THREE.Vector3().fromArray((dimension.members[x] || {
value: [0, 0, 0]
}).value);
}),
start = _map[0],
end = _map[1],
dim = _map[2],
corner = _map[3],
center = _map[4];
var nearend = (dimension.members.valHandlePos || {}).value ? start : end;
switch (dimension.class) {
case 'CC_AngularDimension':
case 'CC_AngularFeatureDimension':
this.position.copy(nearend).sub(corner).setLength(corner.distanceTo(dim)).add(corner);
break;
case 'CC_LinearDimension':
case 'CC_LinearFeatureDimension':
case 'CC_LinearRefDimension':
var d = new THREE.Vector3(Math.cos(dimension.members.angle.value), Math.sin(dimension.members.angle.value), 0);
this.position.copy(nearend).sub(dim).projectOnVector(d).add(dim);
break;
case 'CC_RadialDimension':
case 'CC_RadialFeatureDimension':
case 'CC_DiameterDimension':
case 'CC_DiameterFeatureDimension':
this.position.copy(dim).sub(center).setLength(dimension.members.radius.value).add(center);
break;
}
this.visible = (dimension.members.isDriven || {
value: 0
}).value === 0;
};
_proto3.onDrag = function onDrag(_ref, position) {
var dimension = _ref.dimension,
hasAngle = _ref.angle;
var _map2 = ['startPt', 'endPt', 'dimPt', 'cornerPt', 'center'].map(function (x) {
return new THREE.Vector3().fromArray((dimension.members[x] || {
value: [0, 0, 0]
}).value);
}),
start = _map2[0],
end = _map2[1],
dim = _map2[2],
corner = _map2[3],
center = _map2[4];
var _ref2 = (dimension.members.valHandlePos || {}).value ? [start, end] : [end, start],
nearend = _ref2[0],
farend = _ref2[1];
switch (dimension.class) {
case 'CC_AngularDimension':
case 'CC_AngularFeatureDimension':
var toPolar = function toPolar(v) {
return v.sub(corner).set(Math.atan2(v.y, v.x), v.length(), 0);
};
var fromPolar = function fromPolar(v) {
return v.set(v.y * Math.cos(v.x), v.y * Math.sin(v.x), 0).add(corner);
};
toPolar(nearend);
toPolar(farend);
var diffAng = toPolar(position).x - nearend.x;
nearend.x += diffAng;
if (dimension.members.valHandleBehaviour.value) farend.x -= diffAng;
var angle = (nearend.x - farend.x) % (2 * Math.PI);
fromPolar(nearend);
fromPolar(farend);
start.toArray(dimension.members.startPt.value);
end.toArray(dimension.members.endPt.value);
if (!Boolean(dimension.members.ccw.value) ^ Boolean(dimension.members.valHandlePos.value)) angle = -angle;
if (angle < 0) angle += 2 * Math.PI;
if (hasAngle) angle = THREE.Math.radToDeg(angle);
dimension.previewValue = angle;
break;
case 'CC_LinearDimension':
case 'CC_LinearFeatureDimension':
case 'CC_LinearRefDimension':
var d = new THREE.Vector3(Math.cos(dimension.members.angle.value), Math.sin(dimension.members.angle.value), 0);
var diff = position.clone().sub(nearend).projectOnVector(d);
nearend.add(diff);
if (dimension.members.valHandleBehaviour.value) farend.sub(diff);
start.toArray(dimension.members.startPt.value);
end.toArray(dimension.members.endPt.value);
dimension.previewValue = Math.abs(end.clone().sub(start).dot(d));
break;
case 'CC_RadialDimension':
case 'CC_RadialFeatureDimension':
dimension.members.radius.value = center.distanceTo(position);
dimension.previewValue = dimension.members.radius.value;
break;
case 'CC_DiameterDimension':
case 'CC_DiameterFeatureDimension':
dimension.members.radius.value = center.distanceTo(position);
dimension.previewValue = 2 * dimension.members.radius.value;
break;
}
};
_proto3.onDrop = function onDrop(info) {
if (info.dimension.previewValue) //PreviewValue sets onDrag handler, but onDrop can be called without onDrag function.
info.expression = info.dimension.previewValue.toFixed(2);
this.parent.plugin.afterSetCallback();
};
_proto3.onScale = function onScale(scale) {
this.scale.setScalar(7 * scale);
};
return ValueHandle;
}(Handle);
export var PositionValueHandle =
/*#__PURE__*/
function (_ValueHandle) {
_inheritsLoose(PositionValueHandle, _ValueHandle);
function PositionValueHandle() {
return _ValueHandle.apply(this, arguments) || this;
}
var _proto4 = PositionValueHandle.prototype;
_proto4.onDrag = function onDrag(info, position) {
position.toArray(info.dimension.members.dimPt.value);
_ValueHandle.prototype.onDrag.call(this, info, position);
};
_proto4.onDrop = function onDrop(info) {
info.dimPt = "{" + info.members.dimPt.value.join(', ') + "}";
_ValueHandle.prototype.onDrop.call(this, info);
};
return PositionValueHandle;
}(ValueHandle);