mirror of
https://github.com/xibyte/jsketcher
synced 2025-12-09 09:52:34 +01:00
removed old unused functionality.
This commit is contained in:
parent
78df458e9d
commit
69bf713fea
14 changed files with 1 additions and 1314 deletions
|
|
@ -1,35 +0,0 @@
|
|||
import {BooleanOperation, combineShells} from './boolean-operation'
|
||||
import {ReadSketchFromFace} from '../../sketch/sketchReader'
|
||||
import {revolve} from 'brep/brep-builder'
|
||||
|
||||
export function Revolve(app, params) {
|
||||
|
||||
const face = app.findFace(params.face);
|
||||
const solid = face.solid;
|
||||
const surface = face.surface;
|
||||
|
||||
const sketch = ReadSketchFromFace(app, face);
|
||||
const pivot = evalPivot(params.pivot, sketch, face.csys);
|
||||
|
||||
const shells = [];
|
||||
const contours = sketch.fetchContours();
|
||||
for (let contour of contours) {
|
||||
const basePath = contour.transferInCoordinateSystem(face.csys);
|
||||
const shell = revolve(basePath, surface, pivot.p0, pivot.v, params.angle);
|
||||
shells.push(shell);
|
||||
}
|
||||
|
||||
const operand = combineShells(shells);
|
||||
return BooleanOperation(face, solid, operand, 'union');
|
||||
}
|
||||
|
||||
export function evalPivot(pivot, sketch, csys) {
|
||||
const segment = sketch.findById(pivot);
|
||||
if (segment == null) {
|
||||
return null;
|
||||
}
|
||||
const tr = csys.outTransformation;
|
||||
const p0 = tr.apply(segment.a);
|
||||
const v = tr.apply(segment.b).minus(p0)._normalize();
|
||||
return {p0, v}
|
||||
}
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
import {CURRENT_SELECTION as S} from './wizard'
|
||||
import {PreviewWizard, SketchBasedNurbsPreviewer } from './preview-wizard'
|
||||
import {TriangulatePolygons} from '../../../tess/triangulation'
|
||||
import {revolveToWallNurbs} from 'brep/brep-builder'
|
||||
import {evalPivot} from '../revolve'
|
||||
import Vector from 'math/vector';
|
||||
|
||||
const METADATA = [
|
||||
['angle' , 'number', 5, {min: -360, max: 360, step: 10}],
|
||||
['pivot' , 'sketch.segment' , S ],
|
||||
['face' , 'face' , S ]
|
||||
];
|
||||
|
||||
export class RevolveWizard extends PreviewWizard {
|
||||
constructor(app, initialState) {
|
||||
super(app, 'REVOLVE', METADATA, initialState)
|
||||
}
|
||||
|
||||
createPreviewObject(app, params) {
|
||||
return REVOLVE_PREVIEWER.createMesh(app, params);
|
||||
}
|
||||
}
|
||||
|
||||
export class RevolvePreviewer extends SketchBasedNurbsPreviewer {
|
||||
|
||||
createNurbses(app, params, sketch, face) {
|
||||
const surface = face.surface();
|
||||
const pivot = evalPivot(params.pivot, sketch, surface);
|
||||
const nurbses = [];
|
||||
const contours = sketch.fetchContours();
|
||||
for (let contour of contours) {
|
||||
const basePath = contour.approximateOnSurface(surface);
|
||||
revolveToWallNurbs(basePath, surface, pivot.p0, pivot.v, params.angle).forEach(nurbs => nurbses.push(nurbs));
|
||||
}
|
||||
return nurbses;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const REVOLVE_PREVIEWER = new RevolvePreviewer();
|
||||
|
|
@ -1,177 +0,0 @@
|
|||
import * as tk from '../../../../ui/toolkit';
|
||||
import {isTCADError} from '../../../../utils/errors';
|
||||
|
||||
export class Wizard {
|
||||
|
||||
constructor(app, opearation, initialState) {
|
||||
this.app = app;
|
||||
this.metadata = metadata;
|
||||
this.formFields = {};
|
||||
this.box = this.createUI(opearation, metadata);
|
||||
this.overridingHistory = false;
|
||||
if (initialState !== undefined) {
|
||||
this.setFormFields(initialState);
|
||||
}
|
||||
}
|
||||
|
||||
createRequest() {
|
||||
return {
|
||||
type: this.operation,
|
||||
params: this.readFormFields()
|
||||
};
|
||||
}
|
||||
|
||||
uiLabel(name) {
|
||||
return camelCaseSplit(name).map(w => w.toLowerCase()).join(' ');
|
||||
}
|
||||
|
||||
focus() {
|
||||
this.box.root.find('input, select').first().focus()
|
||||
}
|
||||
|
||||
createUI(operation, metadata) {
|
||||
const box = new tk.Box($('#view-3d'));
|
||||
const folder = new tk.Folder(operation);
|
||||
tk.add(box, folder);
|
||||
for (let def of metadata) {
|
||||
const name = def[0];
|
||||
const type = def[1];
|
||||
const defaultValue = def[2];
|
||||
const params = def[3] || {};
|
||||
const label = this.uiLabel(name);
|
||||
const formItem = this.createFormField(name, label, type, params, defaultValue);
|
||||
formItem.setter(defaultValue);
|
||||
tk.add(folder, formItem.ui);
|
||||
this.formFields[name] = formItem;
|
||||
}
|
||||
const buttons = new tk.ButtonRow(["Cancel", "OK"], [() => this.cancelClick(), () => this.okClick()]);
|
||||
tk.add(folder, buttons);
|
||||
tk.add(folder, {root: $('<div class="errors-message" />')});
|
||||
box.root.keydown((e) => {
|
||||
switch (e.keyCode) {
|
||||
case 27 : this.cancelClick(); break;
|
||||
case 13 : this.okClick(); break;
|
||||
}
|
||||
});
|
||||
|
||||
return box;
|
||||
}
|
||||
|
||||
cancelClick() {
|
||||
this.dispose();
|
||||
}
|
||||
|
||||
okClick() {
|
||||
if (this.apply()) {
|
||||
this.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
apply() {
|
||||
let errors = this.app.craft.modify(this.createRequest(), this.overridingHistory);
|
||||
if (errors) {
|
||||
this.showErrors(errors);
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
showErrors(error) {
|
||||
this.showErrorText('performing operation with current parameters leads to an invalid object' +
|
||||
'(manifold / self-intersecting / zero-thickness / complete degeneration or unsupported cases)');
|
||||
if (!isTCADError(error)) {
|
||||
console.error('internal error while performing operation');
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
showErrorText(message) {
|
||||
this.box.root.find('.errors-message').text(message);
|
||||
}
|
||||
|
||||
onUIChange() {}
|
||||
|
||||
readFormFields() {
|
||||
const params = {};
|
||||
const keys = Object.keys(this.formFields);
|
||||
for (let key of keys) {
|
||||
params[key] = this.formFields[key].getter();
|
||||
}
|
||||
return params;
|
||||
}
|
||||
|
||||
setFormFields(params) {
|
||||
const keys = Object.keys(params);
|
||||
for (let name of keys) {
|
||||
this.setFormField(name, params[name]);
|
||||
}
|
||||
}
|
||||
|
||||
setFormField(name, value) {
|
||||
const formField = this.formFields[name];
|
||||
if (formField) {
|
||||
formField.setter(value);
|
||||
}
|
||||
}
|
||||
|
||||
dispose() {
|
||||
this.disposed = true;
|
||||
this.box.close();
|
||||
}
|
||||
|
||||
createFormField(name, label, type, params, initValue) {
|
||||
if (type === 'number') {
|
||||
const number = tk.config(new tk.Number(label, initValue, params.step, params.round), params);
|
||||
number.input.on('t-change', () => this.onUIChange(name));
|
||||
return Field.fromInput(number, Field.TEXT_TO_NUMBER_COERCION);
|
||||
} else if (type === 'choice') {
|
||||
const ops = params.options;
|
||||
const radio = new tk.InlineRadio(ops, ops, ops.indexOf(initValue));
|
||||
radio.root.find('input[type=radio]').on('change', () => {
|
||||
this.onUIChange(name);
|
||||
});
|
||||
return new Field(radio, () => radio.getValue(), (v) => radio.setValue(v));
|
||||
} else if (type === 'face') {
|
||||
return selectionWidget(name, label, initValue, this.app.context.bus, 'selection_face',(selection) => selection.id);
|
||||
} else if (type === 'sketch.segment') {
|
||||
return selectionWidget(name, label, initValue, this.app.context.bus, 'selection_sketchObject', (selection) => selection.__TCAD_SketchObject.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function selectionWidget(name, label, initValue, bus, selectionKey, toId) {
|
||||
const obj = new tk.Text(label, initValue);
|
||||
obj.input.on('change', () => this.onUIChange(name));
|
||||
return Field.fromInput(obj, undefined, (objId) => {
|
||||
if (objId === CURRENT_SELECTION) {
|
||||
let selection = bus.state[selectionKey][0];
|
||||
return selection ? toId(selection) : '';
|
||||
} else {
|
||||
return objId;
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
function FaceSelectionListener() {
|
||||
this.callbacks = [];
|
||||
}
|
||||
|
||||
function Field(ui, getter, setter) {
|
||||
this.ui = ui;
|
||||
this.getter = getter;
|
||||
this.setter = setter;
|
||||
}
|
||||
|
||||
Field.NO_COERCION = (v) => v;
|
||||
Field.NUMBER_TO_TEXT_COERCION = (v) => v + "";
|
||||
Field.TEXT_TO_NUMBER_COERCION = (v) => parseFloat(v);
|
||||
|
||||
Field.fromInput = function (inputEl, getterCoercer, setterCoercer) {
|
||||
getterCoercer = getterCoercer || Field.NO_COERCION;
|
||||
setterCoercer = setterCoercer || Field.NO_COERCION;
|
||||
return new Field(inputEl, () => getterCoercer(inputEl.input.val()), (value) => inputEl.input.val(setterCoercer(value)));
|
||||
};
|
||||
|
||||
export const CURRENT_SELECTION = {};
|
||||
|
|
@ -1,79 +0,0 @@
|
|||
import * as cad_utils from '../cad-utils'
|
||||
import {HashTable} from '../../utils/hashmap'
|
||||
|
||||
export function MeshFace() {
|
||||
this.polygons = [];
|
||||
}
|
||||
|
||||
export function MeshPolygon(id, normal, w, points) {
|
||||
this.id = id;
|
||||
this.normal = normal;
|
||||
this.w = w;
|
||||
this.points = points;
|
||||
this.neighbors = [];
|
||||
}
|
||||
|
||||
export function Mesh(edges) {
|
||||
this.edges = edges;
|
||||
this.faces = [];
|
||||
this.getEdgeInfo = function(point1, point2) {
|
||||
return edges.get(arguments)
|
||||
}
|
||||
}
|
||||
|
||||
Mesh.fromPolygons = function(polygons, smoothAngle) {
|
||||
const edges = HashTable.forEdge();
|
||||
|
||||
let counter = 0;
|
||||
const allPolygons = [];
|
||||
function index(polygon) {
|
||||
if (polygon.length < 3) {
|
||||
console.warn('invalid polygon ' + polygon);
|
||||
return;
|
||||
}
|
||||
const normal = cad_utils.normalOfCCWSeq(polygon);
|
||||
const w = normal.dot(polygon[0]);
|
||||
|
||||
const polygonInfo = new MeshPolygon(counter++, normal, w, polygon);
|
||||
|
||||
allPolygons.push(polygonInfo);
|
||||
|
||||
for (let p = polygon.length - 1, q = 0; q < polygon.length; p = q ++) {
|
||||
var edgeKey = [polygon[p], polygon[q]];
|
||||
let edgeInfo = edges.get(edgeKey);
|
||||
if (edgeInfo == null) {
|
||||
edges.put(edgeKey, [polygonInfo])
|
||||
} else {
|
||||
let other = edgeInfo[0];
|
||||
other.neighbors.push(polygonInfo);
|
||||
polygonInfo.neighbors.push(other);
|
||||
edgeInfo.push(polygonInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const visited = {};
|
||||
function mergePolygons(tr, meshFace) {
|
||||
if (visited[tr.id]) {
|
||||
return;
|
||||
}
|
||||
visited[tr.id] = true;
|
||||
meshFace.polygons.push(tr);
|
||||
for (let nb of tr.neighbors) {
|
||||
if (Math.acos(nb.normal.dot(tr.normal)) < smoothAngle) {
|
||||
mergePolygons(nb, meshFace)
|
||||
}
|
||||
}
|
||||
}
|
||||
polygons.forEach(p => index(p));
|
||||
const mesh = new Mesh(edges);
|
||||
for (let tr of allPolygons) {
|
||||
const meshFace = new MeshFace();
|
||||
mergePolygons(tr, meshFace);
|
||||
if (meshFace.polygons.length != 0) {
|
||||
mesh.faces.push(meshFace);
|
||||
}
|
||||
}
|
||||
return mesh;
|
||||
};
|
||||
|
||||
|
|
@ -1,157 +0,0 @@
|
|||
import Vector from 'math/vector';
|
||||
import {createShared} from '../../cad-utils'
|
||||
import {TriangulatePolygons} from '../../tess/triangulation';
|
||||
import {Matrix3x4} from "math/matrix";
|
||||
import {distanceAB3} from "math/distance";
|
||||
import {equal} from "math/equality";
|
||||
|
||||
function Group(derivedFrom) {
|
||||
this.polygons = [];
|
||||
this.derivedFrom = derivedFrom;
|
||||
}
|
||||
|
||||
export default function revolve(polygons, axisSegment, angle, resolution) {
|
||||
const groups = {};
|
||||
const out = [];
|
||||
let lids = revolveIterator(polygons, axisSegment, angle, resolution, (pOrig, pRot, p, q, reverse, segmentId) => {
|
||||
const polygon = [pOrig[p], pOrig[q]];
|
||||
|
||||
//skip point if they are on the axis of revolving
|
||||
if (!equal(0, distanceAB3(pOrig[q], pRot[q]))) {
|
||||
polygon.push(pRot[q]);
|
||||
}
|
||||
if (!equal(0, distanceAB3(pOrig[p], pRot[p]))) {
|
||||
polygon.push(pRot[p]);
|
||||
}
|
||||
if (polygon.length < 3) {
|
||||
return;
|
||||
}
|
||||
if (reverse) {
|
||||
polygon.reverse(); //fixes CCW order
|
||||
}
|
||||
|
||||
let shared = createShared();
|
||||
let sketchConnectionObject = pOrig[p].sketchConnectionObject;
|
||||
if (sketchConnectionObject) {
|
||||
if (sketchConnectionObject.TYPE === 'Segment') {
|
||||
sketchConnectionObject = Object.assign({}, sketchConnectionObject, {
|
||||
TYPE: 'Arc',
|
||||
id: sketchConnectionObject.id + ":REVOLVED" // just avoid having object with the same ID but different classes
|
||||
});
|
||||
}
|
||||
shared.__tcad.csgInfo = {derivedFrom: sketchConnectionObject};
|
||||
pRot[p].sketchConnectionObject = sketchConnectionObject;
|
||||
}
|
||||
|
||||
const face = csgPolygon(polygon, shared);
|
||||
out.push(face);
|
||||
});
|
||||
if (!equal(_360, angle)) {
|
||||
if (angle < 0) {
|
||||
let t = lids;
|
||||
lids = polygons;
|
||||
polygons = t;
|
||||
}
|
||||
lids.forEach(p => out.push(csgPolygon(p, createShared())));
|
||||
polygons.forEach(p => out.push(csgPolygon(p.slice().reverse(), createShared())));
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
export function revolveToWireframe(polygons, axisSegment, angle, resolution) {
|
||||
const out = [];
|
||||
//add initial polygon
|
||||
addAsSegments(out, polygons);
|
||||
revolveIterator(polygons, axisSegment, angle, resolution, (pOrig, pRot, p, q) => {
|
||||
out.push([pRot[p], pRot[q]]);
|
||||
addIfNonZero(out, [pOrig[q], pRot[q]]);
|
||||
addIfNonZero(out, [pOrig[p], pRot[p]]);
|
||||
});
|
||||
return out;
|
||||
}
|
||||
|
||||
export function revolveToTriangles(polygons, axisSegment, angle, resolution, triangulateBases) {
|
||||
const out = [];
|
||||
let lidNormal = null, baseNormal = null;
|
||||
//add initial polygon
|
||||
let lids = revolveIterator(polygons, axisSegment, angle, resolution, (pOrig, pRot, p, q, r, id, i, length) => {
|
||||
//skip point if they are on the axis of revolving
|
||||
if (!equal(0, distanceAB3(pOrig[q], pRot[q]))) {
|
||||
out.push( [pOrig[p], pOrig[q], pRot[q]] );
|
||||
}
|
||||
if (!equal(0, distanceAB3(pOrig[p], pRot[p]))) {
|
||||
out.push( [ pRot[q], pRot[p], pOrig[p]] );
|
||||
}
|
||||
let last = i === length - 1
|
||||
if (last && !lidNormal) {
|
||||
lidNormal = pRot[q].minus(pOrig[q])._normalize();
|
||||
}
|
||||
if (i === 0 && !baseNormal) {
|
||||
baseNormal = pRot[q].minus(pOrig[q])._normalize()
|
||||
}
|
||||
});
|
||||
if (triangulateBases && lidNormal && baseNormal) {
|
||||
function triangulatePolygons(polygons, normal) {
|
||||
TriangulatePolygons(polygons, normal, (v) => v.toArray(), (arr) => new Vector().set3(arr))
|
||||
.forEach(tr => out.push(tr));
|
||||
}
|
||||
triangulatePolygons(lids, lidNormal);
|
||||
triangulatePolygons(polygons, baseNormal);
|
||||
|
||||
}
|
||||
|
||||
if (angle < 0) {
|
||||
out.forEach(tr => tr.reverse());
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
export function revolveIterator(polygons, axisSegment, angle, resolution, callback) {
|
||||
|
||||
if (resolution < 2) resolution = 2;
|
||||
const reverse = angle < 0;
|
||||
angle = Math.abs(angle);
|
||||
if (angle > _360) {
|
||||
angle = _360;
|
||||
}
|
||||
|
||||
const angleStep = angle / resolution * (reverse ? -1 : 1);
|
||||
const axis = new Vector().setV(axisSegment[1])._minus(axisSegment[0]);
|
||||
const tr = Matrix3x4.rotateMatrix(angleStep, axis, axisSegment[0]);
|
||||
|
||||
for (let resIndex = 0; resIndex < resolution; resIndex++) {
|
||||
let rotatedPolygons = polygons.map(poly => poly.map(point => tr.apply(point)));
|
||||
let segmentId = 0;
|
||||
for (let i = 0; i < polygons.length; i++) {
|
||||
const pOrig = polygons[i];
|
||||
const pRot = rotatedPolygons[i];
|
||||
const n = pOrig.length;
|
||||
for (let p = n - 1, q = 0; q < n; p = q ++) {
|
||||
callback(pOrig, pRot, p, q, reverse, segmentId ++, resIndex, resolution);
|
||||
}
|
||||
}
|
||||
polygons = rotatedPolygons;
|
||||
}
|
||||
return polygons;
|
||||
}
|
||||
|
||||
|
||||
function addIfNonZero(out, seg) {
|
||||
if (!equal(0, distanceAB3(seg[0], seg[1]))) {
|
||||
out.push(seg);
|
||||
}
|
||||
}
|
||||
|
||||
function addAsSegments(out, polygons) {
|
||||
for (let poly of polygons) {
|
||||
for (let p = poly.length - 1, q = 0; q < poly.length; p = q ++) {
|
||||
out.push([poly[p], poly[q]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function csgPolygon(points, shared) {
|
||||
return new CSG.Polygon(points.map(p => new CSG.Vertex(p.csg())), shared);
|
||||
}
|
||||
|
||||
const _360 = 2 * Math.PI;
|
||||
|
|
@ -1,72 +0,0 @@
|
|||
import * as tk from '../../../../ui/toolkit.js'
|
||||
import {FACE_COLOR} from '../../../cad-utils'
|
||||
import {Wizard} from './wizard-commons'
|
||||
|
||||
export function BoxWizard(viewer, initParams) {
|
||||
Wizard.call(this, viewer, initParams);
|
||||
this.previewGroup = new THREE.Object3D();
|
||||
this.viewer.scene.add(this.previewGroup);
|
||||
this.previewGroup.add(this.box = this.createBox());
|
||||
this.synch();
|
||||
}
|
||||
|
||||
BoxWizard.prototype = Object.create( Wizard.prototype );
|
||||
|
||||
BoxWizard.prototype.DEFAULT_PARAMS = [500, 500, 500];
|
||||
|
||||
BoxWizard.prototype.title = function() {
|
||||
return "Add a Box";
|
||||
};
|
||||
|
||||
BoxWizard.prototype.createBox = function() {
|
||||
var geometry = new THREE.BoxGeometry(1, 1, 1);
|
||||
var material = new THREE.MeshLambertMaterial( { color : FACE_COLOR, transparent: true, opacity:0.5, side: THREE.DoubleSide });
|
||||
return new THREE.Mesh(geometry, material);
|
||||
};
|
||||
|
||||
BoxWizard.prototype.update = function(w, h, d) {
|
||||
this.box.scale.x = w;
|
||||
this.box.scale.y = h;
|
||||
this.box.scale.z = d;
|
||||
this.viewer.render();
|
||||
};
|
||||
|
||||
BoxWizard.prototype.createUI = function(w, h, d) {
|
||||
const ui = this.ui;
|
||||
const folder = this.ui.folder;
|
||||
ui.width = tk.config(new tk.Number("Width", w), {min : 0});
|
||||
ui.height = tk.config(new tk.Number("Height", h), {min : 0});
|
||||
ui.depth = tk.config(new tk.Number("Depth", d), {min : 0});
|
||||
tk.add(folder, ui.width);
|
||||
tk.add(folder, ui.height);
|
||||
tk.add(folder, ui.depth);
|
||||
var onChange = tk.methodRef(this, "synch");
|
||||
ui.width.input.on('t-change', onChange);
|
||||
ui.height.input.on('t-change', onChange);
|
||||
ui.depth.input.on('t-change', onChange);
|
||||
};
|
||||
|
||||
BoxWizard.prototype.synch = function() {
|
||||
this.update.apply(this, this.getParams());
|
||||
this.viewer.render();
|
||||
};
|
||||
|
||||
BoxWizard.prototype.getParams = function() {
|
||||
return [Number(this.ui.width.input.val()), Number(this.ui.height.input.val()), Number(this.ui.depth.input.val())];
|
||||
};
|
||||
|
||||
BoxWizard.prototype.createRequest = function(done) {
|
||||
var params = this.getParams();
|
||||
done({
|
||||
type: 'BOX',
|
||||
solids : [],
|
||||
params : {w : params[0], h : params[1], d : params[2]},
|
||||
protoParams : params
|
||||
});
|
||||
};
|
||||
|
||||
BoxWizard.prototype.dispose = function() {
|
||||
Wizard.prototype.dispose.call(this);
|
||||
this.viewer.scene.remove(this.previewGroup);
|
||||
this.viewer.render();
|
||||
};
|
||||
|
|
@ -1,105 +0,0 @@
|
|||
import * as tk from '../../../../ui/toolkit.js'
|
||||
import * as workbench from '../workbench'
|
||||
import * as cad_utils from '../../../cad-utils'
|
||||
import Vector, {ORIGIN} from 'math/vector';
|
||||
import {OpWizard, IMAGINE_MATERIAL, BASE_MATERIAL} from './wizard-commons'
|
||||
import {Matrix3x4} from 'math/matrix';
|
||||
|
||||
export function ExtrudeWizard(app, face, invert, initParams) {
|
||||
this.invert = invert; // title depends on invert flag
|
||||
OpWizard.call(this, app.viewer, initParams);
|
||||
this.app = app;
|
||||
this.face = face;
|
||||
this.updatePolygons();
|
||||
this.synch();
|
||||
}
|
||||
|
||||
ExtrudeWizard.prototype = Object.create( OpWizard.prototype );
|
||||
|
||||
ExtrudeWizard.prototype.DEFAULT_PARAMS = [50, 1, 0, 0];
|
||||
|
||||
ExtrudeWizard.prototype.title = function() {
|
||||
return this.invert ? "Cut Options" : "Extrude Options";
|
||||
};
|
||||
|
||||
ExtrudeWizard.prototype.updatePolygons = function() {
|
||||
this.polygons = workbench.getSketchedPolygons3D(this.app, this.face);
|
||||
};
|
||||
|
||||
ExtrudeWizard.prototype.update = function(depth, scale, deflection, angle) {
|
||||
if (this.invert) depth *= -1; //depth;
|
||||
|
||||
var basis = this.face.basis();
|
||||
var normal = new Vector().setV(this.face.csgGroup.plane.normal);
|
||||
var linesCounter = 0;
|
||||
var target;
|
||||
if (deflection != 0) {
|
||||
target = normal.copy();
|
||||
if (depth < 0) target._negate();
|
||||
target = Matrix3x4.rotateMatrix(deflection * Math.PI / 180, basis[0], ORIGIN)._apply(target);
|
||||
if (angle != 0) {
|
||||
target = Matrix3x4.rotateMatrix(angle * Math.PI / 180, basis[2], ORIGIN)._apply(target);
|
||||
}
|
||||
target._multiply(Math.abs(depth));
|
||||
} else {
|
||||
target = normal.multiply(depth)
|
||||
}
|
||||
for (var i = 0; i < this.polygons.length; i++) {
|
||||
var poly = this.polygons[i];
|
||||
var lid = cad_utils.calculateExtrudedLid(poly, normal, target, scale);
|
||||
var p, q, n = poly.length;
|
||||
for (p = n - 1, q = 0; q < n; p = q++) {
|
||||
this.setupLine(linesCounter ++, poly[p], poly[q], BASE_MATERIAL);
|
||||
this.setupLine(linesCounter ++, lid[p], lid[q], IMAGINE_MATERIAL);
|
||||
}
|
||||
for (q = 0; q < n; q++) {
|
||||
this.setupLine(linesCounter ++, poly[q], lid[q], IMAGINE_MATERIAL);
|
||||
}
|
||||
}
|
||||
this.operationParams = {
|
||||
target : target,
|
||||
expansionFactor : scale
|
||||
}
|
||||
};
|
||||
|
||||
ExtrudeWizard.prototype.createUI = function (depth, scale, deflection, angle) {
|
||||
const ui = this.ui;
|
||||
const folder = this.ui.folder;
|
||||
tk.add(ui.box, folder);
|
||||
ui.theValue = tk.config(new tk.Number(this.invert ? "Depth" : "Height", depth), {min: 0});
|
||||
ui.scale = tk.config(new tk.Number("Prism", scale, 0.1, 1), {min:0});
|
||||
ui.deflection = new tk.Number("Angle", deflection, 1);
|
||||
ui.angle = new tk.Number("Rotation", angle, 5);
|
||||
var onChange = tk.methodRef(this, "synch");
|
||||
ui.theValue.input.on('t-change', onChange);
|
||||
ui.scale.input.on('t-change', onChange);
|
||||
ui.deflection.input.on('t-change', onChange);
|
||||
ui.angle.input.on('t-change', onChange);
|
||||
tk.add(folder, ui.theValue);
|
||||
tk.add(folder, ui.scale);
|
||||
tk.add(folder, ui.deflection);
|
||||
tk.add(folder, ui.angle);
|
||||
};
|
||||
|
||||
ExtrudeWizard.prototype.synch = function() {
|
||||
this.update.apply(this, this.getParams());
|
||||
this.app.viewer.render();
|
||||
};
|
||||
|
||||
ExtrudeWizard.prototype.getParams = function() {
|
||||
var depthValue = this.ui.theValue.input.val();
|
||||
var scaleValue = this.ui.scale.input.val();
|
||||
var deflectionValue = this.ui.deflection.input.val();
|
||||
var angleValue = this.ui.angle.input.val();
|
||||
return [depthValue, scaleValue, deflectionValue, angleValue];
|
||||
};
|
||||
|
||||
ExtrudeWizard.prototype.createRequest = function(done) {
|
||||
done({
|
||||
type : this.invert ? 'CUT' : 'EXTRUDE',
|
||||
solids : [this.app.findSolidByCadId(this.face.solid.tCadId)],
|
||||
face : this.app.findFace(this.face.id),
|
||||
params : this.operationParams,
|
||||
protoParams : this.getParams()
|
||||
});
|
||||
};
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
import * as tk from '../../../../ui/toolkit.js'
|
||||
import {Wizard} from './wizard-commons'
|
||||
import {LoadSTLFromURL} from '../../../stl/io'
|
||||
|
||||
export function ImportWizard(viewer, initParams) {
|
||||
Wizard.call(this, viewer, initParams);
|
||||
}
|
||||
|
||||
ImportWizard.prototype = Object.create( Wizard.prototype );
|
||||
|
||||
ImportWizard.prototype.DEFAULT_PARAMS = ['https://cdn.thingiverse.com/assets/de/88/44/ab/fe/Touring_Bike_not_for_print.stl'];
|
||||
|
||||
ImportWizard.prototype.title = function() {
|
||||
return "Import URL";
|
||||
};
|
||||
|
||||
ImportWizard.prototype.createUI = function (url) {
|
||||
this.ui.url = new tk.Text("URL", url);
|
||||
tk.add(this.ui.folder, this.ui.url);
|
||||
};
|
||||
|
||||
ImportWizard.prototype.getParams = function() {
|
||||
return [this.ui.url.input.val()];
|
||||
};
|
||||
|
||||
ImportWizard.prototype.createRequest = function(done) {
|
||||
const protoParams = this.getParams();
|
||||
const url = protoParams[0];
|
||||
LoadSTLFromURL(url, (objects, err) => {
|
||||
if (objects == null || objects.length == 0) {
|
||||
done(new Wizard.InvalidRequest("Server returned no data or format isn't supported." + (err ? " Http Status: " + err : "") ))
|
||||
} else {
|
||||
done({
|
||||
type : 'IMPORT_STL',
|
||||
solids: [],
|
||||
params: {objects, url},
|
||||
protoParams
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
@ -1,124 +0,0 @@
|
|||
import * as tk from '../../../../ui/toolkit.js'
|
||||
import {FACE_COLOR} from '../../../cad-utils'
|
||||
import {Wizard} from './wizard-commons'
|
||||
import {IDENTITY_BASIS} from 'math/basis';
|
||||
import {AXIS} from "math/vector";
|
||||
|
||||
export function PlaneWizard(app, initParams) {
|
||||
Wizard.call(this, app.viewer, initParams);
|
||||
this.app = app;
|
||||
this.previewGroup = new THREE.Object3D();
|
||||
this.viewer.scene.add(this.previewGroup);
|
||||
this.previewGroup.add(this.plane = this.createPlane());
|
||||
this.operationParams = {
|
||||
basis : IDENTITY_BASIS,
|
||||
depth : 0,
|
||||
relativeToFaceId: ''
|
||||
};
|
||||
this.selectionListener = () => {
|
||||
const face = this.getFirstSelectedFace();
|
||||
if (face) {
|
||||
this.ui.relativeToFace.input.val(face.id);
|
||||
this.synch();
|
||||
}
|
||||
};
|
||||
app.bus.subscribe('selection', this.selectionListener);
|
||||
|
||||
this.focus = () => this.ui.depth.input.focus();
|
||||
this.synch();
|
||||
}
|
||||
|
||||
PlaneWizard.prototype = Object.create( Wizard.prototype );
|
||||
|
||||
PlaneWizard.prototype.DEFAULT_PARAMS = ['XY', 0, ''];
|
||||
|
||||
PlaneWizard.prototype.title = function() {
|
||||
return "Add a Plane";
|
||||
};
|
||||
|
||||
PlaneWizard.prototype.createPlane = function() {
|
||||
var geometry = new THREE.PlaneGeometry(750,750,1,1,1);
|
||||
var material = new THREE.MeshLambertMaterial( { color : FACE_COLOR, transparent: true, opacity:0.5, side: THREE.DoubleSide });
|
||||
return new THREE.Mesh(geometry, material);
|
||||
};
|
||||
|
||||
PlaneWizard.prototype.update = function(orientation, w, relativeToFaceId) {
|
||||
if (relativeToFaceId != '') {
|
||||
const face = this.app.findFace(relativeToFaceId);
|
||||
const m = new THREE.Matrix4();
|
||||
m.makeBasis.apply(m, face.basis());
|
||||
const wVec = new THREE.Vector3(0, 0, w + face.depth());
|
||||
wVec.applyMatrix4(m);
|
||||
m.setPosition(wVec);
|
||||
this.plane.matrix.identity();
|
||||
this.plane.applyMatrix(m);
|
||||
} else if (orientation === 'XY') {
|
||||
this.plane.rotation.x = 0;
|
||||
this.plane.rotation.y = 0;
|
||||
this.plane.rotation.z = 0;
|
||||
this.plane.position.x = 0;
|
||||
this.plane.position.y = 0;
|
||||
this.plane.position.z = w;
|
||||
this.operationParams.basis = IDENTITY_BASIS;
|
||||
} else if (orientation === 'XZ') {
|
||||
this.plane.rotation.x = Math.PI / 2;
|
||||
this.plane.rotation.y = 0;
|
||||
this.plane.rotation.z = 0;
|
||||
this.plane.position.x = 0;
|
||||
this.plane.position.y = w;
|
||||
this.plane.position.z = 0;
|
||||
this.operationParams.basis = [AXIS.X, AXIS.Z, AXIS.Y];
|
||||
} else if (orientation === 'ZY') {
|
||||
this.plane.rotation.x = 0;
|
||||
this.plane.rotation.y = Math.PI / 2;
|
||||
this.plane.rotation.z = 0;
|
||||
this.plane.position.x = w;
|
||||
this.plane.position.y = 0;
|
||||
this.plane.position.z = 0;
|
||||
this.operationParams.basis = [AXIS.Z, AXIS.Y, AXIS.X];
|
||||
} else {
|
||||
throw orientation + " isn't supported yet";
|
||||
}
|
||||
this.operationParams.depth = w;
|
||||
this.operationParams.relativeToFaceId = relativeToFaceId;
|
||||
this.viewer.render();
|
||||
};
|
||||
|
||||
PlaneWizard.prototype.createUI = function(orientation, w, relativeToFaceId) {
|
||||
const folder = this.ui.folder;
|
||||
const choice = ['XY', 'XZ', 'ZY'];
|
||||
this.ui.orientation = new tk.InlineRadio(choice, choice, choice.indexOf(orientation));
|
||||
this.ui.depth = new tk.Number("Depth", w);
|
||||
this.ui.relativeToFace = new tk.Text("Relative to Face", relativeToFaceId === undefined ? '' : relativeToFaceId);
|
||||
tk.add(folder, this.ui.orientation);
|
||||
tk.add(folder, this.ui.relativeToFace);
|
||||
tk.add(folder, this.ui.depth);
|
||||
|
||||
var onChange = tk.methodRef(this, "synch");
|
||||
this.ui.orientation.root.find('input:radio').change(onChange);
|
||||
this.ui.depth.input.on('t-change', onChange);
|
||||
};
|
||||
|
||||
PlaneWizard.prototype.synch = function() {
|
||||
this.update.apply(this, this.getParams());
|
||||
this.viewer.render();
|
||||
};
|
||||
|
||||
PlaneWizard.prototype.getParams = function() {
|
||||
return [this.ui.orientation.getValue(), parseFloat(this.ui.depth.input.val()), this.ui.relativeToFace.input.val()]
|
||||
};
|
||||
|
||||
PlaneWizard.prototype.createRequest = function(done) {
|
||||
done({
|
||||
type: 'PLANE',
|
||||
solids : [],
|
||||
params : this.operationParams,
|
||||
protoParams : this.getParams()
|
||||
});
|
||||
};
|
||||
|
||||
PlaneWizard.prototype.dispose = function() {
|
||||
Wizard.prototype.dispose.call(this);
|
||||
this.viewer.scene.remove(this.previewGroup);
|
||||
this.viewer.render();
|
||||
};
|
||||
|
|
@ -1,159 +0,0 @@
|
|||
import * as tk from '../../../../ui/toolkit.js'
|
||||
import * as workbench from '../workbench'
|
||||
import {revolveToTriangles} from '../revolve'
|
||||
import {IMAGINARY_SURFACE_MATERIAL, OpWizard,} from './wizard-commons'
|
||||
|
||||
export function RevolveWizard(app, face, initParams) {
|
||||
if (face.sketch3DGroup == null) app.refreshSketchOnFace(face);
|
||||
if (!initParams) this.DEFAULT_PARAMS[2] = findDefaultAxis(app, face);
|
||||
OpWizard.call(this, app.viewer, initParams);
|
||||
this.app = app;
|
||||
this.face = face;
|
||||
this.updatePolygons();
|
||||
this.synch();
|
||||
this.autoResoltion = true;
|
||||
this.selectionListener = () => {
|
||||
const object = this.app.getFirstSelectedFace();
|
||||
if (canBePivot(object, this.face)) {
|
||||
this.ui.pivotSketchObjectId.input.val(object.__TCAD_SketchObject.id);
|
||||
this.synch();
|
||||
}
|
||||
};
|
||||
app.bus.subscribe('selection-sketch-object', this.selectionListener);
|
||||
}
|
||||
|
||||
function canBePivot(sketchObject, face) {
|
||||
return sketchObject && isSketchSegment(sketchObject) && sketchObject.parent == face.sketch3DGroup;
|
||||
}
|
||||
|
||||
function findDefaultAxis(app, face) {
|
||||
let line;
|
||||
const preSelected = app.getFirstSelectedFace();
|
||||
if (canBePivot(preSelected, face)) {
|
||||
line = preSelected;
|
||||
} else {
|
||||
line = firstSegment(face.sketch3DGroup.children);
|
||||
if (line) {
|
||||
app.viewer.sketchSelectionMgr.select(line);
|
||||
}
|
||||
}
|
||||
if (!line) {
|
||||
alert("Sketch doesn't contain any segments which can be used as a revolve pivot");
|
||||
return undefined;
|
||||
} else {
|
||||
return line.__TCAD_SketchObject.id;
|
||||
}
|
||||
}
|
||||
|
||||
function defaultResolution(angle) {
|
||||
return Math.max(2, Math.round(Math.abs(angle) / 4.0 ));
|
||||
}
|
||||
|
||||
RevolveWizard.prototype = Object.create( OpWizard.prototype );
|
||||
|
||||
RevolveWizard.prototype.DEFAULT_PARAMS = [180, defaultResolution(180)];
|
||||
|
||||
RevolveWizard.prototype.title = function() {
|
||||
return "Revolve";
|
||||
};
|
||||
|
||||
RevolveWizard.prototype.updatePolygons = function() {
|
||||
this.polygons = workbench.getSketchedPolygons3D(this.app, this.face);
|
||||
};
|
||||
|
||||
RevolveWizard.prototype.update = function(angle, resolution, pivotSketchObjectId) {
|
||||
if (this.mesh) {
|
||||
this.mesh.geometry.dispose();
|
||||
this.previewGroup.remove(this.mesh);
|
||||
}
|
||||
|
||||
const vertices = this.face.getSketchObjectVerticesIn3D(pivotSketchObjectId);
|
||||
if (!vertices) {
|
||||
console.log('illegal state');
|
||||
return;
|
||||
}
|
||||
const axis = [vertices[0], vertices[vertices.length-1]];
|
||||
const triangles = revolveToTriangles(this.polygons, axis, angle / 180 * Math.PI, resolution);
|
||||
const geometry = new THREE.Geometry();
|
||||
|
||||
for (let tr of triangles) {
|
||||
const a = geometry.vertices.length;
|
||||
const b = a + 1;
|
||||
const c = a + 2;
|
||||
const face = new THREE.Face3(a, b, c);
|
||||
tr.forEach(v => geometry.vertices.push(v.three()));
|
||||
geometry.faces.push(face);
|
||||
}
|
||||
geometry.mergeVertices();
|
||||
geometry.computeFaceNormals();
|
||||
|
||||
this.mesh = new THREE.Mesh(geometry, IMAGINARY_SURFACE_MATERIAL);
|
||||
this.previewGroup.add(this.mesh);
|
||||
};
|
||||
|
||||
RevolveWizard.prototype.createUI = function (angle, resolution, axisObjectId) {
|
||||
const ui = this.ui;
|
||||
const folder = this.ui.folder;
|
||||
tk.add(ui.box, folder);
|
||||
ui.angle = tk.config(new tk.Number("Angle", angle, 5), {min: -360, max: 360, accelerator: 10});
|
||||
ui.resolution = tk.config(new tk.Number("Resolution", resolution), {min: 2, accelerator: 2});
|
||||
ui.pivotSketchObjectId = new tk.Text("Axis Object", axisObjectId === undefined ? "" : axisObjectId);
|
||||
|
||||
ui.angle.input.on('t-change', () => {
|
||||
if (this.autoResoltion) {
|
||||
ui.resolution.input.val(defaultResolution ( parseFloat(ui.angle.input.val()) ));
|
||||
}
|
||||
this.synch();
|
||||
});
|
||||
ui.resolution.input.on('t-change', () => {
|
||||
this.autoResoltion = false;
|
||||
this.synch();
|
||||
});
|
||||
tk.add(folder, ui.angle);
|
||||
tk.add(folder, ui.resolution);
|
||||
tk.add(folder, ui.pivotSketchObjectId);
|
||||
};
|
||||
|
||||
RevolveWizard.prototype.synch = function() {
|
||||
this.update.apply(this, this.getParams());
|
||||
this.app.viewer.render();
|
||||
};
|
||||
|
||||
RevolveWizard.prototype.getParams = function() {
|
||||
const angleValue = parseFloat(this.ui.angle.input.val());
|
||||
const resolutionValue = parseFloat(this.ui.resolution.input.val());
|
||||
const pivotSketchObjectId = this.ui.pivotSketchObjectId.input.val();
|
||||
return [angleValue, resolutionValue, pivotSketchObjectId];
|
||||
};
|
||||
|
||||
RevolveWizard.prototype.createRequest = function(done) {
|
||||
const params = this.getParams();
|
||||
done({
|
||||
type : 'REVOLVE',
|
||||
solids : [this.app.findSolidByCadId(this.face.solid.tCadId)],
|
||||
face : this.app.findFace(this.face.id),
|
||||
params : {
|
||||
angle: params[0],
|
||||
resolution: params[1],
|
||||
pivotSketchObjectId: params[2]
|
||||
},
|
||||
protoParams: params
|
||||
});
|
||||
};
|
||||
|
||||
RevolveWizard.prototype.dispose = function() {
|
||||
this.app.bus.unsubscribe('selection-sketch-object', this.selectionListener);
|
||||
OpWizard.prototype.dispose.call(this);
|
||||
};
|
||||
|
||||
function isSketchSegment(line) {
|
||||
return line.__TCAD_SketchObject && line.__TCAD_SketchObject.TYPE === 'Segment';
|
||||
}
|
||||
function firstSegment(objects) {
|
||||
for (let line of objects) {
|
||||
if (isSketchSegment(line)) {
|
||||
return line;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
|
@ -1,64 +0,0 @@
|
|||
import * as tk from '../../../../ui/toolkit.js'
|
||||
import {FACE_COLOR} from '../../../cad-utils'
|
||||
import {Wizard} from './wizard-commons'
|
||||
|
||||
export function SphereWizard(viewer, initParams) {
|
||||
Wizard.call(this, viewer, initParams);
|
||||
this.previewGroup = new THREE.Object3D();
|
||||
this.viewer.scene.add(this.previewGroup);
|
||||
this.previewGroup.add(this.sphere = this.createSphere());
|
||||
this.synch();
|
||||
}
|
||||
|
||||
SphereWizard.prototype = Object.create( Wizard.prototype );
|
||||
|
||||
SphereWizard.prototype.DEFAULT_PARAMS = [500];
|
||||
|
||||
SphereWizard.prototype.title = function() {
|
||||
return "Add a Sphere";
|
||||
};
|
||||
|
||||
SphereWizard.prototype.createSphere = function() {
|
||||
var geometry = new THREE.SphereGeometry(1, 30, 28);
|
||||
var material = new THREE.MeshLambertMaterial( { color : FACE_COLOR, transparent: true, opacity:0.9 });
|
||||
return new THREE.Mesh(geometry, material);
|
||||
};
|
||||
|
||||
SphereWizard.prototype.update = function(radius) {
|
||||
this.sphere.scale.x = radius;
|
||||
this.sphere.scale.y = radius;
|
||||
this.sphere.scale.z = radius;
|
||||
this.viewer.render();
|
||||
};
|
||||
|
||||
SphereWizard.prototype.createUI = function(radius) {
|
||||
this.ui.radius = tk.config(new tk.Number("Radius", radius), {min : 0});
|
||||
tk.add(this.ui.folder, this.ui.radius);
|
||||
var onChange = tk.methodRef(this, "synch");
|
||||
this.ui.radius.input.on('t-change', onChange);
|
||||
};
|
||||
|
||||
SphereWizard.prototype.synch = function() {
|
||||
this.update.apply(this, this.getParams());
|
||||
this.viewer.render();
|
||||
};
|
||||
|
||||
SphereWizard.prototype.getParams = function() {
|
||||
return [this.ui.radius.val()];
|
||||
};
|
||||
|
||||
SphereWizard.prototype.createRequest = function(done) {
|
||||
var params = this.getParams();
|
||||
done({
|
||||
type: 'SPHERE',
|
||||
solids : [],
|
||||
params : {radius : params[0]},
|
||||
protoParams : params
|
||||
});
|
||||
};
|
||||
|
||||
SphereWizard.prototype.dispose = function() {
|
||||
Wizard.prototype.dispose.call(this);
|
||||
this.viewer.scene.remove(this.previewGroup);
|
||||
this.viewer.render();
|
||||
};
|
||||
|
|
@ -1,129 +0,0 @@
|
|||
import * as tk from '../../../../ui/toolkit.js'
|
||||
import {FACE_COLOR} from '../../../cad-utils'
|
||||
import {Wizard} from './wizard-commons'
|
||||
import {IDENTITY_BASIS} from "math/basis";
|
||||
import {AXIS} from "math/vector";
|
||||
|
||||
export function TransformWizard(viewer, solid, initParams) {
|
||||
Wizard.call(this, viewer, initParams);
|
||||
this.previewGroup = new THREE.Object3D();
|
||||
this.solid = solid;
|
||||
this.initialPosition = this.solid.cadGroup.position.clone();
|
||||
this.viewer.transformControls.attach(this.solid.cadGroup);
|
||||
this.transfomControlListener = tk.methodRef(this, "synchToUI");
|
||||
this.viewer.transformControls.addEventListener( 'objectChange', this.transfomControlListener );
|
||||
this.synch();
|
||||
}
|
||||
|
||||
TransformWizard.prototype = Object.create( Wizard.prototype );
|
||||
|
||||
TransformWizard.prototype.DEFAULT_PARAMS = [0, 0, 0, 0, 0, 0, 1];
|
||||
|
||||
TransformWizard.prototype.title = function() {
|
||||
return "Solid Transform";
|
||||
};
|
||||
|
||||
TransformWizard.prototype.discardChanges = function() {
|
||||
this.solid.cadGroup.position.copy(this.initialPosition);
|
||||
};
|
||||
|
||||
TransformWizard.prototype.update = function(x, y, z, rotationX, rotationY, rotationZ, rotationW) {
|
||||
this.solid.cadGroup.position.setX(x);
|
||||
this.solid.cadGroup.position.setX(y);
|
||||
this.solid.cadGroup.position.setX(z);
|
||||
|
||||
this.solid.cadGroup.quaternion.x = rotationX;
|
||||
this.solid.cadGroup.quaternion.y = rotationY;
|
||||
this.solid.cadGroup.quaternion.z = rotationZ;
|
||||
this.solid.cadGroup.quaternion.w = rotationW;
|
||||
|
||||
this.viewer.transformControls.update();
|
||||
this.viewer.render();
|
||||
};
|
||||
|
||||
TransformWizard.prototype.createUI = function(x, y, z, rotationX, rotationY, rotationZ, rotationW) {
|
||||
const ui = this.ui;
|
||||
const folder = ui.folder;
|
||||
var position = new tk.Folder("Position");
|
||||
var rotation = new tk.Folder("Rotation");
|
||||
tk.add(folder, position);
|
||||
tk.add(folder, rotation);
|
||||
tk.add(ui.box, folder);
|
||||
ui.x = new tk.Number("Position X", x, 1, 6);
|
||||
ui.y = new tk.Number("Position Y", y, 1, 6);
|
||||
ui.z = new tk.Number("Position Z", z, 1, 6);
|
||||
ui.rotationX = tk.config(new tk.Number("Rotation X", rotationX, 0.1, 6), {min: -1, max: 1});
|
||||
ui.rotationY = tk.config(new tk.Number("Rotation Y", rotationY, 0.1, 6), {min: -1, max: 1});
|
||||
ui.rotationZ = tk.config(new tk.Number("Rotation Z", rotationZ, 0.1, 6), {min: -1, max: 1});
|
||||
ui.rotationW = tk.config(new tk.Number("Rotation W", rotationW, 0.1, 6), {min: -1, max: 1});
|
||||
ui.mode = new tk.InlineRadio(['translate(T)', 'rotate(R)'], ['translate', 'rotate'], 0);
|
||||
tk.add(position, ui.x);
|
||||
tk.add(position, ui.y);
|
||||
tk.add(position, ui.z);
|
||||
tk.add(rotation, ui.rotationX);
|
||||
tk.add(rotation, ui.rotationY);
|
||||
tk.add(rotation, ui.rotationZ);
|
||||
tk.add(rotation, ui.rotationW);
|
||||
tk.add(rotation, ui.mode);
|
||||
this.ui.mode.root.find('input:radio').change(tk.methodRef(this, "modeChanged"));
|
||||
var onChange = tk.methodRef(this, "synch");
|
||||
ui.x.input.on('t-change', onChange);
|
||||
ui.y.input.on('t-change', onChange);
|
||||
ui.z.input.on('t-change', onChange);
|
||||
ui.rotationX.input.on('t-change', onChange);
|
||||
ui.rotationY.input.on('t-change', onChange);
|
||||
ui.rotationZ.input.on('t-change', onChange);
|
||||
};
|
||||
|
||||
TransformWizard.prototype.modeChanged = function() {
|
||||
var mode = this.ui.mode.getValue();
|
||||
this.viewer.transformControls.setMode(mode);
|
||||
};
|
||||
|
||||
TransformWizard.prototype.synchToUI = function() {
|
||||
function round(val){return val.toFixed(6);}
|
||||
var ui = this.ui;
|
||||
ui.x.input.val( round(this.solid.cadGroup.position.x) );
|
||||
ui.y.input.val( round(this.solid.cadGroup.position.y) );
|
||||
ui.z.input.val( round(this.solid.cadGroup.position.z) );
|
||||
ui.rotationX.input.val( round(this.solid.cadGroup.quaternion.x) );
|
||||
ui.rotationY.input.val( round(this.solid.cadGroup.quaternion.y) );
|
||||
ui.rotationZ.input.val( round(this.solid.cadGroup.quaternion.z) );
|
||||
ui.rotationW.input.val( round(this.solid.cadGroup.quaternion.w) );
|
||||
this.viewer.render();
|
||||
};
|
||||
|
||||
TransformWizard.prototype.synch = function() {
|
||||
this.update.apply(this, this.getParams());
|
||||
this.viewer.render();
|
||||
};
|
||||
|
||||
TransformWizard.prototype.getParams = function() {
|
||||
return [this.ui.x.val(), this.ui.y.val(), this.ui.z.val(),
|
||||
this.ui.rotationX.val(), this.ui.rotationY.val(), this.ui.rotationZ.val(), this.ui.rotationW.val()];
|
||||
};
|
||||
|
||||
TransformWizard.prototype.createRequest = function(done) {
|
||||
var params = this.getParams();
|
||||
done({
|
||||
type: 'TRANSFORM',
|
||||
solids : [],
|
||||
params : {
|
||||
position: {x : params[0], y : params[1], z : params[2]},
|
||||
rotate: {x : params[3], y : params[4], z : params[5]}
|
||||
} ,
|
||||
protoParams : params
|
||||
});
|
||||
};
|
||||
|
||||
TransformWizard.prototype.cancelClick = function() {
|
||||
Wizard.prototype.cancelClick.call(this);
|
||||
this.discardChanges();
|
||||
};
|
||||
|
||||
TransformWizard.prototype.dispose = function() {
|
||||
Wizard.prototype.dispose.call(this);
|
||||
this.viewer.transformControls.removeEventListener( 'objectChange', this.transfomControlListener );
|
||||
this.viewer.transformControls.detach(this.solid.cadGroup);
|
||||
this.viewer.render();
|
||||
};
|
||||
|
|
@ -1,131 +0,0 @@
|
|||
import DPR from 'dpr'
|
||||
import * as tk from '../../../../ui/toolkit'
|
||||
|
||||
const IMAGINE_MATERIAL = new THREE.LineBasicMaterial({
|
||||
color: 0xFA8072,
|
||||
linewidth: 1/DPR,
|
||||
depthWrite: false,
|
||||
depthTest: false
|
||||
});
|
||||
|
||||
const BASE_MATERIAL = new THREE.LineBasicMaterial({
|
||||
color: 0x8B0000,
|
||||
linewidth: 3/DPR,
|
||||
depthWrite: false,
|
||||
depthTest: false
|
||||
});
|
||||
|
||||
const IMAGINARY_SURFACE_MATERIAL = new THREE.MeshPhongMaterial({
|
||||
vertexColors: THREE.FaceColors,
|
||||
color: 0xFA8072,
|
||||
transparent: true,
|
||||
opacity: 0.5,
|
||||
shininess: 0,
|
||||
side : THREE.DoubleSide
|
||||
});
|
||||
|
||||
export function Wizard(viewer, initParams) {
|
||||
if (!initParams) initParams = this.DEFAULT_PARAMS;
|
||||
this.viewer = viewer;
|
||||
this.disposed = false;
|
||||
this.ui = {
|
||||
box: new tk.Box($('#view-3d')),
|
||||
folder: new tk.Folder(this.title())
|
||||
};
|
||||
tk.add(this.ui.box, this.ui.folder);
|
||||
|
||||
this.ui.box.root.keydown((e) => {
|
||||
switch (e.keyCode) {
|
||||
case 27 : this.cancelClick(); break;
|
||||
case 13 : this.okClick(); break;
|
||||
}
|
||||
});
|
||||
|
||||
this.createUI.apply(this, initParams);
|
||||
this.addButtons(this.ui.folder);
|
||||
}
|
||||
|
||||
Wizard.prototype.apply = function(done) {
|
||||
this.createRequest((request) => {
|
||||
try {
|
||||
if (!this.disposed) {
|
||||
this.onRequestReady(request);
|
||||
}
|
||||
} finally {
|
||||
done();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
Wizard.prototype.onRequestReady = function() {}; // For clients
|
||||
|
||||
Wizard.prototype.okClick = function() {
|
||||
this.ui.buttons.root.find('.tc-block-btn').eq(1)
|
||||
.removeClass('active-btn')
|
||||
.html('<i class="fa fa-cog fa-spin"></i>');
|
||||
this.apply(() => this.dispose());
|
||||
};
|
||||
|
||||
Wizard.prototype.cancelClick = function() {
|
||||
this.dispose();
|
||||
};
|
||||
|
||||
Wizard.prototype.dispose = function() {
|
||||
this.disposed = true;
|
||||
this.ui.box.close();
|
||||
};
|
||||
|
||||
Wizard.prototype.focus = function() {
|
||||
this.ui.box.root.find('input, select').first().focus()
|
||||
};
|
||||
|
||||
Wizard.prototype.addButtons = function(folder) {
|
||||
this.ui.buttons = new tk.ButtonRow(["Cancel", "OK"], [() => this.cancelClick(), () => this.okClick()]);
|
||||
tk.add(folder, this.ui.buttons);
|
||||
};
|
||||
|
||||
Wizard.InvalidRequest = function(message) {
|
||||
this.invalidAndShouldBeDropped = true;
|
||||
this.message = message;
|
||||
};
|
||||
|
||||
function OpWizard(viewer, initParams) {
|
||||
Wizard.call(this, viewer, initParams);
|
||||
this.previewGroup = new THREE.Object3D();
|
||||
this.lines = [];
|
||||
viewer.scene.add(this.previewGroup);
|
||||
}
|
||||
|
||||
OpWizard.prototype = Object.create( Wizard.prototype );
|
||||
|
||||
OpWizard.prototype.setupLine = function(lineId, a, b, material) {
|
||||
var line = this.lines[lineId];
|
||||
if (line === undefined) {
|
||||
var lg = new THREE.Geometry();
|
||||
lg.vertices.push(new THREE.Vector3().copy(a));
|
||||
lg.vertices.push(new THREE.Vector3().copy(b));
|
||||
line = new THREE.Line(lg, material);
|
||||
line.renderOrder = 1e10;
|
||||
this.previewGroup.add(line);
|
||||
this.lines[lineId] = line;
|
||||
} else {
|
||||
line.geometry.vertices[0] = new THREE.Vector3().copy(a);
|
||||
line.geometry.vertices[1] = new THREE.Vector3().copy(b);
|
||||
line.geometry.verticesNeedUpdate = true;
|
||||
}
|
||||
};
|
||||
|
||||
OpWizard.prototype.disposeLines = function() {
|
||||
for (let line of this.lines) {
|
||||
line.geometry.dispose();
|
||||
}
|
||||
};
|
||||
|
||||
OpWizard.prototype.dispose = function() {
|
||||
Wizard.prototype.dispose.call(this);
|
||||
this.viewer.scene.remove(this.previewGroup);
|
||||
this.disposeLines();
|
||||
this.viewer.render();
|
||||
};
|
||||
|
||||
export {OpWizard, IMAGINE_MATERIAL, IMAGINARY_SURFACE_MATERIAL, BASE_MATERIAL}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
import {HashTable} from '../../../utils/hashmap'
|
||||
import {findOutline, reconstructSketchBounds, segmentsToPaths} from '../../legacy/mesh/workbench'
|
||||
//import {findOutline, reconstructSketchBounds, segmentsToPaths} from '../../legacy/mesh/workbench'
|
||||
import {isCurveClass} from '../../cad-utils'
|
||||
import {SceneFace, SceneSolid} from './sceneObject'
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue