rotate datum operation

This commit is contained in:
Val Erastov 2018-10-25 00:27:39 -07:00
parent df742b81d6
commit 49dffd435b
13 changed files with 152 additions and 24 deletions

View file

@ -3,7 +3,6 @@ import {Geometry, Line, LineBasicMaterial, MeshBasicMaterial, Object3D, Vector3}
import CSysObject3D from './csysObject';
import {NOOP} from 'gems/func';
import {findAncestor} from '../../../../../modules/scene/sceneGraph';
export default class DatumObject3D extends Object3D {
@ -32,6 +31,7 @@ export default class DatumObject3D extends Object3D {
this.add(this.csysObj);
this.exitEditMode = NOOP;
this.beingDraggedAxis = null;
this.freezeDragging = false;
}
setMoveMode(axis) {
@ -136,6 +136,9 @@ export default class DatumObject3D extends Object3D {
function addOnHoverBehaviour(handle, viewer) {
handle.onMouseDown = function(e, hits, startDrag) {
let datum = this.parent.parent.parent;
if (datum.freezeDraggin) {
return;
}
startDrag(datum);
datum.dragStart(e, this.parent);
};

View file

@ -1,6 +1,7 @@
export default {
datum: {
type: 'datum'
type: 'datum',
defaultValue: {type: 'selection'}
},
x: {
type: 'number',

View file

@ -51,12 +51,8 @@ function previewer(ctx, initialParams, updateParams) {
function dispose() {
datum3D.csys.copy(mDatum.csys);
datum3D.finishOperation();
datum3D.operationStarted = false;
datum3D.exitEditMode();
datum3D.applyMove = NOOP;
}
update(initialParams);
return {

View file

@ -0,0 +1,15 @@
import React from 'react';
import {Group} from '../../wizard/components/form/Form';
import {NumberField, RadioButtonsField} from '../../wizard/components/form/Fields';
import {RadioButton} from 'ui/components/controls/RadioButtons';
export default function RotateDatumWizard() {
return <Group>
<RadioButtonsField name='axis'>
<RadioButton value='X' />
<RadioButton value='Y' />
<RadioButton value='Z' />
</RadioButtonsField>
<NumberField name='angle' />
</Group>;
}

View file

@ -0,0 +1,15 @@
export default {
datum: {
type: 'datum',
defaultValue: {type: 'selection'}
},
axis: {
type: 'enum',
values: ['X', 'Y', 'Z'],
defaultValue: 'X'
},
angle: {
type: 'number',
defaultValue: 0
}
}

View file

@ -0,0 +1,79 @@
import schema from './rotateDatumOpSchema';
import {MDatum} from '../../../model/mdatum';
import RotateDatumWizard from './RotateDatumWizard';
import {Matrix3, ORIGIN} from '../../../../math/l3space';
import {DEG_RAD} from '../../../../math/math';
function rotate(params, {cadRegistry}) {
let mDatum = cadRegistry.findDatum(params.datum);
let axis = mDatum.csys[params.axis.toLowerCase()];
let csys = mDatum.csys.clone();
applyRotation(mDatum.csys, csys, params.angle, axis);
return {
outdated: [mDatum],
created: [new MDatum(csys)]
}
}
let auxMatrix = new Matrix3();
function previewer(ctx, initialParams) {
let mDatum = ctx.services.cadRegistry.findDatum(initialParams.datum);
if (!mDatum) {
return null;
}
let view = mDatum.ext.view;
if (!view) {
return null;
}
let datum3D = view.rootGroup;
datum3D.beginOperation(true);
function update(params) {
let axis = mDatum.csys[params.axis.toLowerCase()];
applyRotation(mDatum.csys, datum3D.csys, params.angle, axis);
}
function dispose() {
datum3D.csys.copy(mDatum.csys);
datum3D.finishOperation();
}
update(initialParams);
return {
update, dispose
}
}
function applyRotation(origCsys, csys, angle, axis) {
auxMatrix.rotate(angle * DEG_RAD, axis, ORIGIN);
auxMatrix.__apply(origCsys.x, csys.x);
auxMatrix.__apply(origCsys.y, csys.y);
auxMatrix.__apply(origCsys.z, csys.z);
}
export default {
id: 'DATUM_ROTATE',
label: 'Rotate Datum',
icon: 'img/cad/plane',
info: 'rotates a datum',
paramsInfo: ({axis, angle}) => `${axis} - ${angle}`,
previewer,
run: rotate,
form: RotateDatumWizard,
schema
};

View file

@ -43,7 +43,7 @@ export default [
label: 'datum',
cssIcons: ['magic'],
info: 'operations on datum',
actions: ['DATUM_MOVE']
actions: ['DATUM_ROTATE', 'DATUM_MOVE']
// actions: ['DATUM_MOVE', 'DATUM_ROTATE', 'DATUM_REBASE', '-', 'PLANE_FROM_DATUM', 'BOX', 'SPHERE', 'TORUS',
// 'CONE', 'CYLINDER']
},

View file

@ -6,6 +6,7 @@ import filletOperation from '../craft/fillet/filletOperation';
import revolveOperation from '../craft/revolve/revolveOperation';
import createDatumOperation from '../craft/datum/create/createDatumOperation';
import moveDatumOperation from '../craft/datum/move/moveDatumOperation';
import rotateDatumOperation from '../craft/datum/rotate/rotateDatumOperation';
export function activate({services}) {
services.operation.registerOperations([
@ -16,6 +17,7 @@ export function activate({services}) {
revolveOperation,
filletOperation,
createDatumOperation,
moveDatumOperation
moveDatumOperation,
rotateDatumOperation
])
}

View file

@ -1,6 +1,6 @@
import * as mask from 'gems/mask'
import {getAttribute, setAttribute} from 'scene/objectData';
import {FACE, EDGE, SKETCH_OBJECT} from '../entites';
import {FACE, EDGE, SKETCH_OBJECT, DATUM} from '../entites';
import {state} from 'lstream';
export const PICK_KIND = {
@ -9,7 +9,7 @@ export const PICK_KIND = {
EDGE: mask.type(3)
};
const SELECTABLE_ENTITIES = [FACE, EDGE, SKETCH_OBJECT];
const SELECTABLE_ENTITIES = [FACE, EDGE, SKETCH_OBJECT, DATUM];
export function activate(context) {
const {services, streams} = context;
@ -130,10 +130,8 @@ export function defineStreams({streams}) {
streams.selection = {
};
SELECTABLE_ENTITIES.forEach(entity => {
let selectionState = state([]);
streams.selection[entity] = state([]);
});
}
function initStateAndServices({streams, services}) {

View file

@ -16,7 +16,7 @@ export function activate(context) {
streams.sketcher.update.attach(mFace => mFace.ext.view.updateSketch());
}
function sceneSynchronizer({services: {cadScene, cadRegistry, viewer, wizard, action}}) {
function sceneSynchronizer({services: {cadScene, cadRegistry, viewer, wizard, action, selection}}) {
return function() {
let wgChildren = cadScene.workGroup.children;
let existent = new Set();
@ -42,7 +42,10 @@ function sceneSynchronizer({services: {cadScene, cadRegistry, viewer, wizard, ac
} else if (model instanceof MShell) {
modelView = new ShellView(model);
} else if (model instanceof MDatum) {
modelView = new DatumView(model, viewer, wizard.open, (e) => action.run('menu.datum', e));
modelView = new DatumView(model, viewer,
wizard.open,
datumId => selection.datum.select([datumId]),
e => action.run('menu.datum', e));
} else {
console.warn('unsupported model ' + model);
}

View file

@ -4,10 +4,11 @@ import {DATUM} from '../entites';
import {setAttribute} from 'scene/objectData';
import {Mesh, MeshBasicMaterial, PolyhedronGeometry, SphereGeometry} from 'three';
import {CSYS_SIZE_MODEL} from '../../craft/datum/csysObject';
import {NOOP} from '../../../../../modules/gems/func';
export default class DatumView extends View {
constructor(datum, viewer, beginOperation, showDatumMenu) {
constructor(datum, viewer, beginOperation, selectDatum, showDatumMenu) {
super(datum);
class MenuButton extends Mesh {
@ -54,6 +55,7 @@ export default class DatumView extends View {
}
onMouseClick(e) {
selectDatum(datum.id);
showDatumMenu({
x: e.offsetX,
y: e.offsetY
@ -101,23 +103,24 @@ export default class DatumView extends View {
dragStart(e, axis) {
if (!this.operationStarted) {
beginOperation('DATUM_MOVE', {
datum: datum.id
});
selectDatum(datum.id);
beginOperation('DATUM_MOVE');
this.beginOperation();
}
super.dragStart(e, axis);
}
beginOperation() {
beginOperation(freezeDragging = false) {
this.freezeDragging = freezeDragging;
this.operationStarted = true;
this.menuButton.updateVisibility();
}
finishOperation() {
this.freezeDragging = false;
this.operationStarted = false;
this.exitEditMode();
this.menuButton.updateVisibility();
this.exitEditMode();
}
dispose() {

View file

@ -39,6 +39,13 @@ Matrix3.prototype.setBasis = function(basis) {
return this;
};
Matrix3.prototype.setBasisAxises = function(x, y, z) {
this.mxx = x.x; this.mxy = y.x; this.mxz = z.x; this.tx = 0;
this.myx = x.y; this.myy = y.y; this.myz = z.y; this.ty = 0;
this.mzx = x.z; this.mzy = y.z; this.mzz = z.z; this.tz = 0;
return this;
};
Matrix3.prototype.scale = function(dx, dy, dz) {
this.mxx *= dx;
this.myy *= dy;
@ -143,7 +150,7 @@ Matrix3.prototype.__invert = function(out) {
return out;
};
Matrix3.prototype.combine = function(transform) {
Matrix3.prototype.combine = function(transform, out) {
var txx = transform.mxx;
var txy = transform.mxy;
var txz = transform.mxz;
@ -157,7 +164,7 @@ Matrix3.prototype.combine = function(transform) {
var tzz = transform.mzz;
var ttz = transform.tz;
var m = new Matrix3();
var m = out || new Matrix3();
m.mxx = (this.mxx * txx + this.mxy * tyx + this.mxz * tzx);
m.mxy = (this.mxx * txy + this.mxy * tyy + this.mxz * tzy);
m.mxz = (this.mxx * txz + this.mxy * tyz + this.mxz * tzz);
@ -207,11 +214,15 @@ Matrix3.prototype.__apply3 = function([x, y, z], out) {
return out;
};
Matrix3.rotateMatrix = function(angle, axis, pivot) {
Matrix3.prototype.rotate = function(angle, axis, pivot) {
return Matrix3.rotateMatrix(angle, axis, pivot, this);
};
Matrix3.rotateMatrix = function(angle, axis, pivot, matrix) {
var sin = Math.sin(angle);
var cos = Math.cos(angle);
var axisX, axisY, axisZ;
var m = new Matrix3();
var m = matrix || new Matrix3();
if (axis === AXIS.X || axis === AXIS.Y || axis === AXIS.Z) {
axisX = axis.x;

View file

@ -245,4 +245,6 @@ export function perpendicularVector(v) {
.sort((a, b) => vec.lengthSq(b) - vec.lengthSq(a))[0];
}
export const DEG_RAD = Math.PI / 180.0;
export const sq = (a) => a * a;