awv3
Version:
⚡ AWV3 embedded CAD
156 lines (138 loc) • 6 kB
JavaScript
import * as THREE from 'three';
import Plugin from '../../session/plugin';
import { buildFeaturePath, normalizeName } from '../../session/helpers';
import {
Slider,
Spacer,
Group,
Button,
Input,
Label,
Selection,
Checkbox,
Dropdown,
Console
} from '../../session/elements';
const resources = ['csys'].reduce((prev, item) => ({ ...prev, [item]: require('!!url-loader!awv3-icons/32x32/' + item + '.png') }), {});
export default class Csys extends Plugin {
static persistent = true;
constructor(session, args) {
super(session, { type: 'Csys', icon: 'csys', resources, ...args });
this.origin = new Selection(this, { name: 'Origin', types: ['Point'] });
this.axis = new Selection(this, { name: 'Axis', types: ['Mesh', 'LineSegments'] });
this.secondary = new Selection(this, { name: 'Secondary', types: ['Mesh', 'LineSegments'] });
this.refsGroup = new Group(this, {
format: Group.Format.Table,
children: [this.origin, this.axis, this.secondary]
});
this.collapse = new Group(this, {
name: 'References',
children: [this.refsGroup],
format: Group.Format.Collapse
});
this.addElement(this.collapse);
this.offsetInput = new Input(this, { name: 'Offset', value: '0,0,0', format: Input.Format.Vector });
this.sliderX = new Slider(this, {
name: 'Rotation X',
max: 360,
step: 10,
positions: { 0: '0°', 90: '90°', 180: '180°', 270: '270°', 360: '360°' }
});
this.sliderY = new Slider(this, {
name: 'Rotation Y',
max: 360,
step: 10,
positions: { 0: '0°', 90: '90°', 180: '180°', 270: '270°', 360: '360°' }
});
this.sliderZ = new Slider(this, {
name: 'Rotation Z',
max: 360,
step: 10,
positions: { 0: '0°', 90: '90°', 180: '180°', 270: '270°', 360: '360°' }
});
this.main = new Group(this, {
format: Group.Format.Table,
children: [this.offsetInput, this.sliderX, this.sliderY, this.sliderZ]
});
this.addElement(this.main);
let coords = args.feature.coordinateSystem;
this.position = new THREE.Vector3(...coords[0]);
this.rotation = new THREE.Euler();
let x = new THREE.Vector3(...coords[1]);
let y = new THREE.Vector3(...coords[2]);
let m = new THREE.Matrix4().makeBasis(x, y, x.clone().cross(y));
this.xAxis = m;
this.yAxis = new THREE.Matrix4();
this.offset = new THREE.Vector3();
this.csys = new THREE.AxisHelper(this.pool.getRadius() / 5);
this.csys.interactive = false;
this.csys.matrixAutoUpdate = false;
this.pool.add(this.csys);
this.translate();
}
onEnabled() {
this.apply.observe(state => state.lastEvent, async event => {
let feature = this.tree[this.feature];
let xAxis = new THREE.Vector3(), yAxis = new THREE.Vector3(), zAxis = new THREE.Vector3();
this.csys.matrix.extractBasis(xAxis, yAxis, zAxis);
let pos = new THREE.Vector3().setFromMatrixPosition(this.csys.matrix);
let path = buildFeaturePath(this.tree, feature.id);
await this.connection.execute(`${path}.SetName("${feature.name}");`);
path = buildFeaturePath(this.tree, feature.id);
this.connection.execute(
`${path}.OBJ_SetCoordSystem({${pos.toArray().join(',')}},{${xAxis
.toArray()
.join(',')}},{${yAxis.toArray().join(',')}});`
);
this.connection.recalc();
});
this.origin.observe(state => state.children, selection => {
if (selection.length) {
this.position = this.session.selector.getSelectedElements()[0].meta.position;
this.translate();
}
});
this.sliderX.observe(state => state.value, value => {
this.rotation.x = value * Math.PI / 180;
this.translate();
});
this.sliderY.observe(state => state.value, value => {
this.rotation.y = value * Math.PI / 180;
this.translate();
});
this.sliderZ.observe(state => state.value, value => {
this.rotation.z = value * Math.PI / 180;
this.translate();
});
this.offsetInput.observe(state => state.value, value => {
this.offset = new THREE.Vector3(...value.split(','));
this.translate();
});
this.axis.observe(state => state.children, selection => this.rotate(selection, 'x'));
this.secondary.observe(state => state.children, selection => this.rotate(selection, 'y'));
}
onDestroyed() {
this.csys.destroy();
}
translate() {
this.csys.matrix = new THREE.Matrix4()
.setPosition(this.position)
.multiply(this.xAxis)
.multiply(this.yAxis)
.multiply(new THREE.Matrix4().makeRotationFromEuler(this.rotation))
.multiply(new THREE.Matrix4().makeTranslation(...this.offset.toArray()));
this.pool.view.invalidate();
}
rotate(selection, whichAxis) {
if (selection.length) {
let meta = this.session.selector.getSelectedElements()[0].meta;
if (meta.type === 'line') var dir = meta.end.clone().sub(meta.start.clone()).normalize();
else if (meta.type === 'plane') var dir = meta.normal.clone();
let axis = whichAxis === 'x' ? new THREE.Vector3(1, 0, 0) : new THREE.Vector3(0, 1, 0);
let rotAxis = axis.clone().cross(dir).normalize();
let angle = axis.angleTo(dir);
this[`${whichAxis}Axis`] = new THREE.Matrix4().makeRotationAxis(rotAxis, angle);
this.translate();
}
}
}