mirror of
https://github.com/xibyte/jsketcher
synced 2025-12-14 04:12:53 +01:00
separate loft preview from actual craft / engine layer refactoring
This commit is contained in:
parent
6e16e39383
commit
9af681b21f
6 changed files with 356 additions and 300 deletions
95
web/app/cad/craft/e0/common.js
Normal file
95
web/app/cad/craft/e0/common.js
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
export const BOOLEAN_TYPES = {
|
||||
UNION : 1,
|
||||
SUBTRACT: 2,
|
||||
INTERSECT: 3
|
||||
};
|
||||
|
||||
export const CURVE_TYPES = {
|
||||
SEGMENT: 1,
|
||||
B_SPLINE: 2,
|
||||
CIRCLE: 3,
|
||||
ARC: 4
|
||||
};
|
||||
|
||||
export const DEFLECTION = 2;
|
||||
export const E0_TOLERANCE = 1e-3;
|
||||
|
||||
export function singleShellRespone(oldShell, newShellData) {
|
||||
if (newShellData.error) {
|
||||
throw 'operation failed';
|
||||
}
|
||||
|
||||
let consumed = [oldShell];
|
||||
let created = readShellData(newShellData, consumed, oldShell.csys);
|
||||
return {
|
||||
consumed: consumed,
|
||||
created: [created]
|
||||
};
|
||||
}
|
||||
|
||||
export function readShellData(data, consumed, csys) {
|
||||
let tpi = __CAD_APP.services.tpi;
|
||||
let model = new tpi.scene.readShellEntityFromJson(data, consumed, csys);
|
||||
model.brepShell.data.externals.engine = 'e0';
|
||||
return model;
|
||||
}
|
||||
|
||||
export function managedByE0(mShell) {
|
||||
let externals = mShell.brepShell && mShell.brepShell.data && mShell.brepShell.data.externals;
|
||||
return externals && externals.engine === 'e0';
|
||||
}
|
||||
|
||||
export function readSketchContour(contour, face) {
|
||||
let tr = face.csys.outTransformation;
|
||||
let path = [];
|
||||
contour.segments.forEach(s => {
|
||||
if (s.isCurve) {
|
||||
if (s.constructor.name === 'Circle') {
|
||||
const dir = face.csys.z.data();
|
||||
path.push({TYPE: CURVE_TYPES.CIRCLE, c: tr.apply(s.c).data(), dir, r: s.r});
|
||||
} else if (s.constructor.name === 'Arc') {
|
||||
let a = s.inverted ? s.b : s.a;
|
||||
let b = s.inverted ? s.a : s.b;
|
||||
let tangent = tr._apply(s.c.minus(a))._cross(face.csys.z)._normalize();
|
||||
if (s.inverted) {
|
||||
tangent._negate();
|
||||
}
|
||||
path.push({
|
||||
TYPE: CURVE_TYPES.ARC,
|
||||
a: tr.apply(a).data(),
|
||||
b: tr.apply(b).data(),
|
||||
tangent: tangent.data()
|
||||
});
|
||||
} else {
|
||||
let nurbs = s.toNurbs(face.csys).impl;
|
||||
path.push(Object.assign({TYPE: CURVE_TYPES.B_SPLINE}, nurbs.serialize()));
|
||||
}
|
||||
} else {
|
||||
let ab = [s.a, s.b];
|
||||
if (s.inverted) {
|
||||
ab.reverse();
|
||||
}
|
||||
ab = ab.map(v => tr.apply(v).data());
|
||||
path.push({TYPE: CURVE_TYPES.SEGMENT, a: ab[0], b: ab[1]});
|
||||
}
|
||||
});
|
||||
return path;
|
||||
}
|
||||
|
||||
export function readSketch(face, request, sketcher) {
|
||||
let sketch = sketcher.readSketch(face.id);
|
||||
if (!sketch) throw 'illegal state';
|
||||
return sketch.fetchContours().map(c => readSketchContour(c, face));
|
||||
}
|
||||
|
||||
export function shellsToPointers(shells) {
|
||||
return shells.filter(managedByE0).map(m => m.brepShell.data.externals.ptr);
|
||||
}
|
||||
|
||||
export function writeCsys(csys, swapToY) {
|
||||
return {
|
||||
origin: csys.origin.data(),
|
||||
normal: (swapToY ? csys.y : csys.z).data(),
|
||||
xDir: csys.x.data()
|
||||
};
|
||||
}
|
||||
147
web/app/cad/craft/e0/craftMethods.js
Normal file
147
web/app/cad/craft/e0/craftMethods.js
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
import {
|
||||
BOOLEAN_TYPES, DEFLECTION, E0_TOLERANCE, managedByE0, readShellData, readSketch, readSketchContour, shellsToPointers,
|
||||
singleShellRespone,
|
||||
writeCsys
|
||||
} from './common';
|
||||
import {callEngine} from './interact';
|
||||
import {resolveExtrudeVector} from '../cutExtrude/cutExtrude';
|
||||
|
||||
export function boolean({type, operandsA, operandsB}) {
|
||||
let engineParams = {
|
||||
type: BOOLEAN_TYPES[type],
|
||||
operandsA: shellsToPointers(operandsA),
|
||||
operandsB: shellsToPointers(operandsB),
|
||||
tolerance: E0_TOLERANCE,
|
||||
deflection: DEFLECTION,
|
||||
};
|
||||
let data = callEngine(engineParams, Module._SPI_boolean);
|
||||
let consumed = [...operandsA, ...operandsB];
|
||||
return {
|
||||
consumed,
|
||||
created: [readShellData(data.result, consumed, operandsA[0].csys)]
|
||||
}
|
||||
}
|
||||
|
||||
export function createBox(params) {
|
||||
return booleanBasedOperation({
|
||||
csys: writeCsys(params.csys),
|
||||
dx: params.width,
|
||||
dy: params.height,
|
||||
dz: params.depth
|
||||
}, params, Module._SPI_box);
|
||||
}
|
||||
|
||||
export function createTorus(params) {
|
||||
return booleanBasedOperation({
|
||||
csys: writeCsys(params.csys),
|
||||
r1: params.radius,
|
||||
r2: params.tube
|
||||
}, params, Module._SPI_torus);
|
||||
}
|
||||
|
||||
export function createCone(params) {
|
||||
return booleanBasedOperation({
|
||||
csys: writeCsys(params.csys, true),
|
||||
r1: params.radius,
|
||||
r2: params.frustum,
|
||||
h: params.height
|
||||
}, params, Module._SPI_cone);
|
||||
}
|
||||
|
||||
export function createCylinder(params) {
|
||||
return booleanBasedOperation({
|
||||
csys: writeCsys(params.csys, true),
|
||||
r: params.radius,
|
||||
h: params.height,
|
||||
}, params, Module._SPI_cylinder);
|
||||
}
|
||||
|
||||
export function createSphere(params) {
|
||||
return booleanBasedOperation({
|
||||
csys: writeCsys(params.csys),
|
||||
r: params.radius,
|
||||
}, params, Module._SPI_sphere);
|
||||
}
|
||||
|
||||
function booleanBasedOperation(engineParams, params, impl) {
|
||||
engineParams.deflection = DEFLECTION;
|
||||
if (params.boolean && BOOLEAN_TYPES[params.boolean.type] > 0) {
|
||||
engineParams.boolean = {
|
||||
type: BOOLEAN_TYPES[params.boolean.type],
|
||||
operands: shellsToPointers(params.boolean.operands),
|
||||
tolerance: E0_TOLERANCE,
|
||||
}
|
||||
}
|
||||
let data = callEngine(engineParams, impl);
|
||||
let consumed = [];
|
||||
if (params.boolean) {
|
||||
data.consumed.forEach(ptr => {
|
||||
let model = params.boolean.operands.find(m => managedByE0(m) && m.brepShell.data.externals.ptr === ptr);
|
||||
if (model) {
|
||||
consumed.push(model);
|
||||
}
|
||||
});
|
||||
}
|
||||
return {
|
||||
consumed,
|
||||
created: data.created.map(shape => readShellData(shape, consumed, params.csys))
|
||||
}
|
||||
}
|
||||
|
||||
function cutExtrude(isCut, request) {
|
||||
|
||||
function createExtrudeCommand(request, {cadRegistry, sketcher}, invert) {
|
||||
const face = cadRegistry.findFace(request.face);
|
||||
const paths = readSketch(face, request, sketcher);
|
||||
|
||||
return {
|
||||
face,
|
||||
request: {
|
||||
vector: resolveExtrudeVector(cadRegistry, face, request, !invert).data(),
|
||||
sketch: paths,
|
||||
tolerance: E0_TOLERANCE,
|
||||
deflection: DEFLECTION
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
let {request: engineReq, face} = createExtrudeCommand(request, services, isCut);
|
||||
if (managedByE0(face.shell)) {
|
||||
engineReq.boolean = {
|
||||
type: isCut ? BOOLEAN_TYPES.SUBTRACT : BOOLEAN_TYPES.UNION,
|
||||
operand: face.shell.brepShell.data.externals.ptr
|
||||
}
|
||||
}
|
||||
|
||||
let data = callEngine(engineReq, Module._SPI_extrude);
|
||||
|
||||
return singleShellRespone(face.shell, data);
|
||||
}
|
||||
|
||||
export function cut(params) {
|
||||
return cutExtrude(true, params);
|
||||
}
|
||||
|
||||
export function extrude(params) {
|
||||
return cutExtrude(false, params);
|
||||
}
|
||||
|
||||
const mapLoftParams = params => ({
|
||||
sections: params.sections.map(sec => readSketchContour(sec.contour, sec.face)),
|
||||
tolerance: E0_TOLERANCE,
|
||||
deflection: DEFLECTION
|
||||
});
|
||||
|
||||
export function loftPreview(params) {
|
||||
return callEngine(mapLoftParams(params), Module._SPI_loftPreview);
|
||||
}
|
||||
|
||||
export function loft(params) {
|
||||
let result = callEngine(mapLoftParams(params), Module._SPI_loftPreview);
|
||||
throw 'unsupported';
|
||||
// let consumed = [...operandsA, ...operandsB];
|
||||
// return {
|
||||
// consumed,
|
||||
// created: [readShellData(data.result, consumed, operandsA[0].csys)]
|
||||
// }
|
||||
}
|
||||
|
|
@ -1,315 +1,19 @@
|
|||
/**
|
||||
* This is an internal alternative to native engine. It overrides basic 3d part design operations
|
||||
*/
|
||||
import {resolveExtrudeVector} from '../cutExtrude/cutExtrude';
|
||||
|
||||
let BOOLEAN_TYPES = {
|
||||
UNION : 1,
|
||||
SUBTRACT: 2,
|
||||
INTERSECT: 3
|
||||
};
|
||||
|
||||
let CURVE_TYPES = {
|
||||
SEGMENT: 1,
|
||||
B_SPLINE: 2,
|
||||
CIRCLE: 3,
|
||||
ARC: 4
|
||||
};
|
||||
|
||||
const DEFLECTION = 2;
|
||||
const TOLERANCE = 1e-3;
|
||||
import * as craftMethods from './craftMethods';
|
||||
import operationHandler from './operationHandler';
|
||||
|
||||
export function activate(ctx) {
|
||||
|
||||
loadWasm(ctx);
|
||||
|
||||
ctx.services.operation.handlers.push(operationHandler);
|
||||
function booleanBasedOperation(engineParams, params, impl) {
|
||||
engineParams.deflection = DEFLECTION;
|
||||
if (params.boolean && BOOLEAN_TYPES[params.boolean.type] > 0) {
|
||||
engineParams.boolean = {
|
||||
type: BOOLEAN_TYPES[params.boolean.type],
|
||||
operands: shellsToPointers(params.boolean.operands),
|
||||
tolerance: TOLERANCE,
|
||||
}
|
||||
}
|
||||
let data = callEngine(engineParams, impl);
|
||||
let consumed = [];
|
||||
if (params.boolean) {
|
||||
data.consumed.forEach(ptr => {
|
||||
let model = params.boolean.operands.find(m => managedByE0(m) && m.brepShell.data.externals.ptr === ptr);
|
||||
if (model) {
|
||||
consumed.push(model);
|
||||
}
|
||||
});
|
||||
}
|
||||
return {
|
||||
consumed,
|
||||
created: data.created.map(shape => readShellData(shape, consumed, params.csys))
|
||||
}
|
||||
}
|
||||
ctx.services.craftEngine = {
|
||||
createBox: function(params) {
|
||||
return booleanBasedOperation({
|
||||
csys: writeCsys(params.csys),
|
||||
dx: params.width,
|
||||
dy: params.height,
|
||||
dz: params.depth
|
||||
}, params, Module._SPI_box);
|
||||
},
|
||||
createTorus: function(params) {
|
||||
return booleanBasedOperation({
|
||||
csys: writeCsys(params.csys),
|
||||
r1: params.radius,
|
||||
r2: params.tube
|
||||
}, params, Module._SPI_torus);
|
||||
},
|
||||
createCone: function(params) {
|
||||
return booleanBasedOperation({
|
||||
csys: writeCsys(params.csys, true),
|
||||
r1: params.radius,
|
||||
r2: params.frustum,
|
||||
h: params.height
|
||||
}, params, Module._SPI_cone);
|
||||
},
|
||||
createCylinder: function(params) {
|
||||
return booleanBasedOperation({
|
||||
csys: writeCsys(params.csys, true),
|
||||
r: params.radius,
|
||||
h: params.height,
|
||||
}, params, Module._SPI_cylinder);
|
||||
},
|
||||
createSphere: function(params) {
|
||||
return booleanBasedOperation({
|
||||
csys: writeCsys(params.csys),
|
||||
r: params.radius,
|
||||
}, params, Module._SPI_sphere);
|
||||
},
|
||||
boolean: function({type, operandsA, operandsB}) {
|
||||
let engineParams = {
|
||||
type: BOOLEAN_TYPES[type],
|
||||
operandsA: shellsToPointers(operandsA),
|
||||
operandsB: shellsToPointers(operandsB),
|
||||
tolerance: TOLERANCE,
|
||||
deflection: DEFLECTION,
|
||||
};
|
||||
let data = callEngine(engineParams, Module._SPI_boolean);
|
||||
let consumed = [...operandsA, ...operandsB];
|
||||
return {
|
||||
consumed,
|
||||
created: [readShellData(data.result, consumed, operandsA[0].csys)]
|
||||
}
|
||||
},
|
||||
loft: function(params) {
|
||||
let engineParams = {
|
||||
sections: params.sections.map(sec => readSketchContour(sec.contour, sec.face)),
|
||||
preview: params.preview,
|
||||
tolerance: TOLERANCE,
|
||||
deflection: DEFLECTION,
|
||||
};
|
||||
let data = callEngine(engineParams, Module._SPI_loft);
|
||||
if (params.preview) {
|
||||
return data;
|
||||
}
|
||||
throw 'unsupported';
|
||||
// let consumed = [...operandsA, ...operandsB];
|
||||
// return {
|
||||
// consumed,
|
||||
// created: [readShellData(data.result, consumed, operandsA[0].csys)]
|
||||
// }
|
||||
}
|
||||
...craftMethods
|
||||
}
|
||||
}
|
||||
|
||||
function shellsToPointers(shells) {
|
||||
return shells.filter(managedByE0).map(m => m.brepShell.data.externals.ptr);
|
||||
}
|
||||
|
||||
function writeCsys(csys, swapToY) {
|
||||
return {
|
||||
origin: csys.origin.data(),
|
||||
normal: (swapToY ? csys.y : csys.z).data(),
|
||||
xDir: csys.x.data()
|
||||
};
|
||||
}
|
||||
|
||||
function operationHandler(id, request, services) {
|
||||
switch (id) {
|
||||
case 'CUT':
|
||||
case 'EXTRUDE': {
|
||||
|
||||
let isCut = id === 'CUT';
|
||||
let {request: engineReq, face} = createExtrudeCommand(request, services, isCut);
|
||||
if (managedByE0(face.shell)) {
|
||||
engineReq.boolean = {
|
||||
type: isCut ? BOOLEAN_TYPES.SUBTRACT : BOOLEAN_TYPES.UNION,
|
||||
operand: face.shell.brepShell.data.externals.ptr
|
||||
}
|
||||
}
|
||||
|
||||
let data = callEngine(engineReq, Module._SPI_extrude);
|
||||
|
||||
return singleShellRespone(face.shell, data);
|
||||
}
|
||||
case 'REVOLVE': {
|
||||
let {request: engineReq, face} = createRevolveCommand(request, services);
|
||||
let data = callEngine(engineReq, Module._SPI_revolve);
|
||||
return singleShellRespone(face.shell, data);
|
||||
}
|
||||
case 'FILLET': {
|
||||
let edge = services.cadRegistry.findEdge(request.edges[0]);
|
||||
let engineReq = {
|
||||
deflection: DEFLECTION,
|
||||
solid: edge.shell.brepShell.data.externals.ptr,
|
||||
edges: request.edges.map(e => ({
|
||||
edge: services.cadRegistry.findEdge(e).brepEdge.data.externals.ptr,
|
||||
thickness: request.thickness
|
||||
}))
|
||||
};
|
||||
|
||||
let data = callEngine(engineReq, Module._SPI_fillet);
|
||||
return singleShellRespone(edge.shell, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function singleShellRespone(oldShell, newShellData) {
|
||||
if (newShellData.error) {
|
||||
throw 'operation failed';
|
||||
}
|
||||
|
||||
let consumed = [oldShell];
|
||||
let created = readShellData(newShellData, consumed, oldShell.csys);
|
||||
return {
|
||||
consumed: consumed,
|
||||
created: [created]
|
||||
};
|
||||
}
|
||||
|
||||
function readShellData(data, consumed, csys) {
|
||||
let tpi = __CAD_APP.services.tpi;
|
||||
let model = new tpi.scene.readShellEntityFromJson(data, consumed, csys);
|
||||
model.brepShell.data.externals.engine = 'e0';
|
||||
return model;
|
||||
}
|
||||
|
||||
function managedByE0(mShell) {
|
||||
let externals = mShell.brepShell && mShell.brepShell.data && mShell.brepShell.data.externals;
|
||||
return externals && externals.engine === 'e0';
|
||||
}
|
||||
|
||||
function readSketchContour(contour, face) {
|
||||
let tr = face.csys.outTransformation;
|
||||
let path = [];
|
||||
contour.segments.forEach(s => {
|
||||
if (s.isCurve) {
|
||||
if (s.constructor.name === 'Circle') {
|
||||
const dir = face.csys.z.data();
|
||||
path.push({TYPE: CURVE_TYPES.CIRCLE, c: tr.apply(s.c).data(), dir, r: s.r});
|
||||
} else if (s.constructor.name === 'Arc') {
|
||||
let a = s.inverted ? s.b : s.a;
|
||||
let b = s.inverted ? s.a : s.b;
|
||||
let tangent = tr._apply(s.c.minus(a))._cross(face.csys.z)._normalize();
|
||||
if (s.inverted) {
|
||||
tangent._negate();
|
||||
}
|
||||
path.push({
|
||||
TYPE: CURVE_TYPES.ARC,
|
||||
a: tr.apply(a).data(),
|
||||
b: tr.apply(b).data(),
|
||||
tangent: tangent.data()
|
||||
});
|
||||
} else {
|
||||
let nurbs = s.toNurbs(face.csys).impl;
|
||||
path.push(Object.assign({TYPE: CURVE_TYPES.B_SPLINE}, nurbs.serialize()));
|
||||
}
|
||||
} else {
|
||||
let ab = [s.a, s.b];
|
||||
if (s.inverted) {
|
||||
ab.reverse();
|
||||
}
|
||||
ab = ab.map(v => tr.apply(v).data());
|
||||
path.push({TYPE: CURVE_TYPES.SEGMENT, a: ab[0], b: ab[1]});
|
||||
}
|
||||
});
|
||||
return path;
|
||||
}
|
||||
|
||||
function readSketch(face, request, sketcher) {
|
||||
let sketch = sketcher.readSketch(face.id);
|
||||
if (!sketch) throw 'illegal state';
|
||||
return sketch.fetchContours().map(c => readSketchContour(c, face));
|
||||
}
|
||||
|
||||
function createExtrudeCommand(request, {cadRegistry, sketcher}, invert) {
|
||||
const face = cadRegistry.findFace(request.face);
|
||||
const paths = readSketch(face, request, sketcher);
|
||||
|
||||
return {
|
||||
face,
|
||||
request: {
|
||||
vector: resolveExtrudeVector(cadRegistry, face, request, !invert).data(),
|
||||
sketch: paths,
|
||||
tolerance: TOLERANCE,
|
||||
deflection: DEFLECTION
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function createRevolveCommand(request, {cadRegistry, sketcher}) {
|
||||
const face = cadRegistry.findFace(request.face);
|
||||
const paths = readSketch(face, request, sketcher);
|
||||
|
||||
let pivot = cadRegistry.findSketchObject(request.axis).sketchPrimitive;
|
||||
let tr = face.csys.outTransformation;
|
||||
let vec = __CAD_APP.services.tpi.math.vec;
|
||||
let axisOrigin = tr._apply3(pivot.a.data());
|
||||
let axisDir = vec._normalize(vec._sub(tr._apply3(pivot.b.data()), axisOrigin))
|
||||
|
||||
let res = {
|
||||
face,
|
||||
request: {
|
||||
axisOrigin,
|
||||
axisDir,
|
||||
angle: request.angle / 180.0 * Math.PI,
|
||||
sketch: paths,
|
||||
tolerance: TOLERANCE,
|
||||
deflection: DEFLECTION
|
||||
}
|
||||
};
|
||||
if (managedByE0(face.shell) && request.boolean && BOOLEAN_TYPES[request.boolean] > 0) {
|
||||
res.request.boolean = {
|
||||
type: BOOLEAN_TYPES[request.boolean],
|
||||
operand: face.shell.brepShell.data.externals.ptr
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
function toCString(str) {
|
||||
let buffer = Module._malloc(str.length + 1);
|
||||
writeAsciiToMemory(str, buffer);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
function callEngine(request, engineFunc) {
|
||||
let toCStringRequest = toCString(JSON.stringify(request));
|
||||
engineFunc(toCStringRequest);
|
||||
Module._free(toCStringRequest);
|
||||
return __E0_ENGINE_EXCHANGE_VAL;
|
||||
}
|
||||
|
||||
|
||||
let __E0_ENGINE_EXCHANGE_VAL = null;
|
||||
window.__E0_ENGINE_EXCHANGE = function(objStr) {
|
||||
__E0_ENGINE_EXCHANGE_VAL = JSON.parse(objStr);
|
||||
// let tpi = __CAD_APP.services.tpi;
|
||||
// let sceneObject = new tpi.scene.UnmanagedSceneSolid(data, 'SOLID');
|
||||
// tpi.addOnScene(sceneObject);
|
||||
// __DEBUG__.AddTessDump(obj);
|
||||
};
|
||||
|
||||
function instantiateEngine(importObject, callback) {
|
||||
const url = '/wasm/e0/main.wasm';
|
||||
WebAssembly.instantiateStreaming(fetch(url), importObject).then(results => {
|
||||
|
|
|
|||
23
web/app/cad/craft/e0/interact.js
Normal file
23
web/app/cad/craft/e0/interact.js
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
|
||||
export function toCString(str) {
|
||||
let buffer = Module._malloc(str.length + 1);
|
||||
writeAsciiToMemory(str, buffer);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
export function callEngine(request, engineFunc) {
|
||||
let toCStringRequest = toCString(JSON.stringify(request));
|
||||
engineFunc(toCStringRequest);
|
||||
Module._free(toCStringRequest);
|
||||
return __E0_ENGINE_EXCHANGE_VAL;
|
||||
}
|
||||
|
||||
|
||||
let __E0_ENGINE_EXCHANGE_VAL = null;
|
||||
window.__E0_ENGINE_EXCHANGE = function(objStr) {
|
||||
__E0_ENGINE_EXCHANGE_VAL = JSON.parse(objStr);
|
||||
// let tpi = __CAD_APP.services.tpi;
|
||||
// let sceneObject = new tpi.scene.UnmanagedSceneSolid(data, 'SOLID');
|
||||
// tpi.addOnScene(sceneObject);
|
||||
// __DEBUG__.AddTessDump(obj);
|
||||
};
|
||||
87
web/app/cad/craft/e0/operationHandler.js
Normal file
87
web/app/cad/craft/e0/operationHandler.js
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
import {BOOLEAN_TYPES, DEFLECTION, E0_TOLERANCE, managedByE0, readSketch, singleShellRespone} from './common';
|
||||
import {callEngine} from './interact';
|
||||
import {resolveExtrudeVector} from '../cutExtrude/cutExtrude';
|
||||
|
||||
export default function operationHandler(id, request, services) {
|
||||
switch (id) {
|
||||
case 'CUT':
|
||||
case 'EXTRUDE': {
|
||||
let isCut = id === 'CUT';
|
||||
let {request: engineReq, face} = createExtrudeCommand(request, services, isCut);
|
||||
if (managedByE0(face.shell)) {
|
||||
engineReq.boolean = {
|
||||
type: isCut ? BOOLEAN_TYPES.SUBTRACT : BOOLEAN_TYPES.UNION,
|
||||
operand: face.shell.brepShell.data.externals.ptr
|
||||
}
|
||||
}
|
||||
|
||||
let data = callEngine(engineReq, Module._SPI_extrude);
|
||||
|
||||
return singleShellRespone(face.shell, data);
|
||||
}
|
||||
case 'REVOLVE': {
|
||||
let {request: engineReq, face} = createRevolveCommand(request, services);
|
||||
let data = callEngine(engineReq, Module._SPI_revolve);
|
||||
return singleShellRespone(face.shell, data);
|
||||
}
|
||||
case 'FILLET': {
|
||||
let edge = services.cadRegistry.findEdge(request.edges[0]);
|
||||
let engineReq = {
|
||||
deflection: DEFLECTION,
|
||||
solid: edge.shell.brepShell.data.externals.ptr,
|
||||
edges: request.edges.map(e => ({
|
||||
edge: services.cadRegistry.findEdge(e).brepEdge.data.externals.ptr,
|
||||
thickness: request.thickness
|
||||
}))
|
||||
};
|
||||
|
||||
let data = callEngine(engineReq, Module._SPI_fillet);
|
||||
return singleShellRespone(edge.shell, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function createExtrudeCommand(request, {cadRegistry, sketcher}, invert) {
|
||||
const face = cadRegistry.findFace(request.face);
|
||||
const paths = readSketch(face, request, sketcher);
|
||||
|
||||
return {
|
||||
face,
|
||||
request: {
|
||||
vector: resolveExtrudeVector(cadRegistry, face, request, !invert).data(),
|
||||
sketch: paths,
|
||||
tolerance: E0_TOLERANCE,
|
||||
deflection: DEFLECTION
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function createRevolveCommand(request, {cadRegistry, sketcher}) {
|
||||
const face = cadRegistry.findFace(request.face);
|
||||
const paths = readSketch(face, request, sketcher);
|
||||
|
||||
let pivot = cadRegistry.findSketchObject(request.axis).sketchPrimitive;
|
||||
let tr = face.csys.outTransformation;
|
||||
let vec = __CAD_APP.services.tpi.math.vec;
|
||||
let axisOrigin = tr._apply3(pivot.a.data());
|
||||
let axisDir = vec._normalize(vec._sub(tr._apply3(pivot.b.data()), axisOrigin))
|
||||
|
||||
let res = {
|
||||
face,
|
||||
request: {
|
||||
axisOrigin,
|
||||
axisDir,
|
||||
angle: request.angle / 180.0 * Math.PI,
|
||||
sketch: paths,
|
||||
tolerance: E0_TOLERANCE,
|
||||
deflection: DEFLECTION
|
||||
}
|
||||
};
|
||||
if (managedByE0(face.shell) && request.boolean && BOOLEAN_TYPES[request.boolean] > 0) {
|
||||
res.request.boolean = {
|
||||
type: BOOLEAN_TYPES[request.boolean],
|
||||
operand: face.shell.brepShell.data.externals.ptr
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
|
@ -2,7 +2,7 @@ import {createSmoothMeshGeometryFromData} from '../../../../../modules/scene/geo
|
|||
|
||||
export function loftPreviewGeomProvider(params, services) {
|
||||
|
||||
const tessInfo = services.craftEngine.loft({
|
||||
const tessInfo = services.craftEngine.loftPreview({
|
||||
sections: params.sections.map(services.cadRegistry.findLoop),
|
||||
preview: true
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue