mirror of
https://github.com/xibyte/jsketcher
synced 2025-12-06 16:33:15 +01:00
fix eslint issues
This commit is contained in:
parent
e439e43aaf
commit
26c4ea218b
24 changed files with 29 additions and 516 deletions
|
|
@ -14,6 +14,13 @@
|
||||||
"CSG" : true,
|
"CSG" : true,
|
||||||
"PNLTRI" : true,
|
"PNLTRI" : true,
|
||||||
"__DEBUG__": true,
|
"__DEBUG__": true,
|
||||||
|
"__CAD_APP": true,
|
||||||
|
"Module": true,
|
||||||
|
"_free": true,
|
||||||
|
"_malloc": true,
|
||||||
|
"writeAsciiToMemory": true,
|
||||||
|
"__E0_ENGINE_EXCHANGE_VAL": true,
|
||||||
|
"verb": true,
|
||||||
"$": true
|
"$": true
|
||||||
},
|
},
|
||||||
"rules": {
|
"rules": {
|
||||||
|
|
@ -22,5 +29,9 @@
|
||||||
"max-len": "off",
|
"max-len": "off",
|
||||||
"no-console": "off",
|
"no-console": "off",
|
||||||
"no-extra-boolean-cast": "off"
|
"no-extra-boolean-cast": "off"
|
||||||
}
|
},
|
||||||
|
"ignorePatterns": [
|
||||||
|
"/modules/math/optim/*.js",
|
||||||
|
"/modules/math/qr.js"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
/web/app/math/lm.js
|
|
||||||
/web/app/math/qr.js
|
|
||||||
|
|
||||||
|
|
@ -1,54 +0,0 @@
|
||||||
import {polyhedronify} from './polyhedronify'
|
|
||||||
import {union as unionImpl, intersect as intersectImpl, subtract as subtractImpl} from './boolean'
|
|
||||||
|
|
||||||
|
|
||||||
export function union( shell1, shell2 ) {
|
|
||||||
return doOp(shell1, shell2, unionImpl);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function intersect( shell1, shell2 ) {
|
|
||||||
return doOp(shell1, shell2, intersectImpl);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function subtract( shell1, shell2 ) {
|
|
||||||
return doOp(shell1, shell2, subtractImpl);
|
|
||||||
}
|
|
||||||
|
|
||||||
function doOp(shell1, shell2, transformFunc) {
|
|
||||||
shell1 = polyhedronify(shell1);
|
|
||||||
shell2 = polyhedronify(shell2);
|
|
||||||
|
|
||||||
const result = transformFunc(shell1, shell2);
|
|
||||||
//return reconstruct(result);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
function extractLoops(polygons) {
|
|
||||||
const seen = new Set();
|
|
||||||
for (let p of polygons) {
|
|
||||||
for (let v of p.vertices) {
|
|
||||||
for (let e of v.edges) {
|
|
||||||
|
|
||||||
}
|
|
||||||
if (seen.has(v)) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function splitByFace(polygons) {
|
|
||||||
const byFace = new Map();
|
|
||||||
for (let p of polygons) {
|
|
||||||
addToListInMap(byFace, p.group, p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function addToListInMap(map, key, value) {
|
|
||||||
let list = map.get(key);
|
|
||||||
if (!list) {
|
|
||||||
list = [];
|
|
||||||
map.set(key, list);
|
|
||||||
}
|
|
||||||
list.push(value);
|
|
||||||
}
|
|
||||||
|
|
@ -182,7 +182,7 @@ function detectLoops(surface, graph) {
|
||||||
BREP_DEBUG.startBooleanLoopDetection(graph);
|
BREP_DEBUG.startBooleanLoopDetection(graph);
|
||||||
const loops = [];
|
const loops = [];
|
||||||
const seen = new Set();
|
const seen = new Set();
|
||||||
while (true) {
|
for (;;) {
|
||||||
let edge = graph.graphEdges.pop();
|
let edge = graph.graphEdges.pop();
|
||||||
if (!edge) {
|
if (!edge) {
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -1,87 +0,0 @@
|
||||||
import {TriangulateFace} from '../../../web/app/cad/tess/triangulation'
|
|
||||||
import {Shell} from '../topo/shell'
|
|
||||||
import {HalfEdge} from '../topo/edge'
|
|
||||||
import {Loop} from '../topo/loop'
|
|
||||||
import {Face} from '../topo/face'
|
|
||||||
import {BREPValidator} from '../brep-validator';
|
|
||||||
import {linkSegments} from '../brep-builder';
|
|
||||||
import {Line} from 'geom/impl/line'
|
|
||||||
|
|
||||||
export function polyhedronify(shell) {
|
|
||||||
shell.reindexVertices();
|
|
||||||
const faces = [];
|
|
||||||
|
|
||||||
const edgeIndex = new EdgeIndex();
|
|
||||||
|
|
||||||
for (let face of shell.faces) {
|
|
||||||
const plane = face.surface;
|
|
||||||
const triangles = TriangulateFace(face);
|
|
||||||
for (let triangle of triangles) {
|
|
||||||
const loop = new Loop();
|
|
||||||
const n = triangle.length; // obviously it's 3
|
|
||||||
for (let p = n - 1, q = 0; q < n; p = q++) {
|
|
||||||
|
|
||||||
const a = triangle[p];
|
|
||||||
const b = triangle[q];
|
|
||||||
|
|
||||||
const edge = edgeIndex.get(a, b);
|
|
||||||
edge.loop = loop;
|
|
||||||
loop.halfEdges.push(edge);
|
|
||||||
if (a.edgeFor(b) != null) {
|
|
||||||
edge.data.outline = true;
|
|
||||||
__DEBUG__.AddHalfEdge(edge, 0x00ff00);
|
|
||||||
} else {
|
|
||||||
__DEBUG__.AddHalfEdge(edge, 0xffffff);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const newFace = new Face(face.surface);
|
|
||||||
newFace.outerLoop = loop;
|
|
||||||
loop.face = newFace;
|
|
||||||
newFace.data.originFace = face;
|
|
||||||
linkSegments(loop.halfEdges);
|
|
||||||
faces.push(newFace);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const polyhedron = new Shell();
|
|
||||||
faces.forEach(face => {
|
|
||||||
face.shell = polyhedron;
|
|
||||||
polyhedron.faces.push(face);
|
|
||||||
});
|
|
||||||
|
|
||||||
BREPValidator.validateToConsole(polyhedron);
|
|
||||||
|
|
||||||
return polyhedron;
|
|
||||||
}
|
|
||||||
|
|
||||||
class EdgeIndex {
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
this.index = new Map();
|
|
||||||
}
|
|
||||||
|
|
||||||
get(a, b) {
|
|
||||||
const subMap = this.getForPoint(a);
|
|
||||||
let edge = subMap.get(b);
|
|
||||||
|
|
||||||
if (edge == null) {
|
|
||||||
|
|
||||||
edge = HalfEdge.fromVertices(a, b, Line.fromSegment(a.point, b.point));
|
|
||||||
subMap.set(b, edge);
|
|
||||||
const twinMap = this.getForPoint(b);
|
|
||||||
if (twinMap.has(a)) {
|
|
||||||
throw 'illegal state';
|
|
||||||
}
|
|
||||||
twinMap.set(a, edge.twin());
|
|
||||||
}
|
|
||||||
return edge;
|
|
||||||
}
|
|
||||||
|
|
||||||
getForPoint(p) {
|
|
||||||
let subMap = this.index.get(p);
|
|
||||||
if (subMap == null) {
|
|
||||||
subMap = new Map();
|
|
||||||
this.index.set(p, subMap);
|
|
||||||
}
|
|
||||||
return subMap;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -46,10 +46,6 @@ function distanceSqToSegment(a, b, pt) {
|
||||||
|
|
||||||
export function solveClosestToCurveParamExactly(curve, pt, intMin, intMax, tol) {
|
export function solveClosestToCurveParamExactly(curve, pt, intMin, intMax, tol) {
|
||||||
|
|
||||||
function boundParam(u) {
|
|
||||||
return Math.min(max, Math.max(min, u));
|
|
||||||
}
|
|
||||||
|
|
||||||
//solving minimization problem of squared distance
|
//solving minimization problem of squared distance
|
||||||
|
|
||||||
//f(u) = (fx(u) - x)^2 + (fy(u) - y)^2 + (fz(u) - z)^2 = fx^2 - 2*fx*x + x^2 ...
|
//f(u) = (fx(u) - x)^2 + (fy(u) - y)^2 + (fz(u) - z)^2 = fx^2 - 2*fx*x + x^2 ...
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import {newtonIterationsOnInterval} from '../curves/newtonIterations';
|
||||||
|
|
||||||
export function surfaceSurfaceStablePoints(surfaceA, surfaceB) {
|
export function surfaceSurfaceStablePoints(surfaceA, surfaceB) {
|
||||||
|
|
||||||
function impl(surfaceA, surfaceB) {
|
function impl(curve) {
|
||||||
|
|
||||||
//solving minimization problem of squared distance
|
//solving minimization problem of squared distance
|
||||||
|
|
||||||
|
|
@ -16,8 +16,8 @@ export function surfaceSurfaceStablePoints(surfaceA, surfaceB) {
|
||||||
|
|
||||||
let [f, d1, d2] = curve.eval(u, 2);
|
let [f, d1, d2] = curve.eval(u, 2);
|
||||||
|
|
||||||
let r1Comp = i => 2 * f[i] * d1[i] - 2 * pt[i] * d1[i];
|
let r1Comp = i => 2 * f[i] * d1[i] - 2 * f[i] * d1[i];
|
||||||
let r2Comp = i => 2 * f[i] * d2[i] + 2 * d1[i] * d1[i] - 2 * pt[i] * d2[i];
|
let r2Comp = i => 2 * f[i] * d2[i] + 2 * d1[i] * d1[i] - 2 * f[i] * d2[i];
|
||||||
|
|
||||||
let r1 = r1Comp(X) + r1Comp(Y) + r1Comp(Z);
|
let r1 = r1Comp(X) + r1Comp(Y) + r1Comp(Z);
|
||||||
let r2 = r2Comp(X) + r2Comp(Y) + r2Comp(Z);
|
let r2 = r2Comp(X) + r2Comp(Y) + r2Comp(Z);
|
||||||
|
|
@ -25,7 +25,9 @@ export function surfaceSurfaceStablePoints(surfaceA, surfaceB) {
|
||||||
return [r1, r2];
|
return [r1, r2];
|
||||||
}
|
}
|
||||||
|
|
||||||
return newtonIterationsOnInterval(squareDistanceFn, intMin, intMax, tol);
|
let intMin = 0;
|
||||||
|
let intMax = 0;
|
||||||
|
return newtonIterationsOnInterval(squareDistanceFn, intMin, intMax, 1e-5);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
|
|
||||||
|
|
||||||
export default function(vA, vB, vC) {
|
|
||||||
let ab = new Vector3();
|
|
||||||
face.normal.subVectors( vC, vB );
|
|
||||||
ab.subVectors( vA, vB );
|
|
||||||
face.normal.cross( ab );
|
|
||||||
face.normal.normalize();
|
|
||||||
}
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
"pack": "node ./node_modules/webpack/bin/webpack.js --config webpack.config.js --progress --profile --colors",
|
"pack": "node ./node_modules/webpack/bin/webpack.js --config webpack.config.js --progress --profile --colors",
|
||||||
"start-with-docs": "concurrently --kill-others 'npm start' './node_modules/grunt/bin/grunt docs-start'",
|
"start-with-docs": "concurrently --kill-others 'npm start' './node_modules/grunt/bin/grunt docs-start'",
|
||||||
"build": "grunt",
|
"build": "grunt",
|
||||||
"lint": "./node_modules/eslint/bin/eslint web/app web/modules",
|
"lint": "./node_modules/eslint/bin/eslint.js web/app modules",
|
||||||
"check-code": "./node_modules/typescript/bin/tsc --noEmit",
|
"check-code": "./node_modules/typescript/bin/tsc --noEmit",
|
||||||
"before-mainline-merging": "npm run lint && npm run check-code",
|
"before-mainline-merging": "npm run lint && npm run check-code",
|
||||||
"cypress": "npx cypress open"
|
"cypress": "npx cypress open"
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ export function activate(context: ApplicationContext) {
|
||||||
|
|
||||||
let showAnonymousActionHint = enableAnonymousActionHint(context);
|
let showAnonymousActionHint = enableAnonymousActionHint(context);
|
||||||
|
|
||||||
function run(id: string, data: any): void {
|
function run(id: string, data?: any): void {
|
||||||
let state = streams.action.state[id].value;
|
let state = streams.action.state[id].value;
|
||||||
let runner = runners[id];
|
let runner = runners[id];
|
||||||
if (!state||!runner) {
|
if (!state||!runner) {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
import * as ActionHelpers from './actionHelpers'
|
import * as ActionHelpers from './actionHelpers'
|
||||||
import {AiOutlineExport} from "react-icons/ai";
|
import {AiOutlineExport} from "react-icons/ai";
|
||||||
import {CurrentWorkbenchIcon} from "cad/workbench/CurrentWorkbenchIcon";
|
|
||||||
|
|
||||||
export default [
|
export default [
|
||||||
{
|
{
|
||||||
|
|
@ -183,17 +182,6 @@ export default [
|
||||||
info: 'toggle whether to show sketches on a solid face'
|
info: 'toggle whether to show sketches on a solid face'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
|
||||||
id: 'LookAtSolid',
|
|
||||||
appearance: {
|
|
||||||
cssIcons: ['crosshairs'],
|
|
||||||
label: 'look at solid',
|
|
||||||
info: 'position camera at the solid at zoom to fit it',
|
|
||||||
},
|
|
||||||
invoke: (context) => app.lookAtSolid(app.inputManager.context.attr('data-id'))
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
{
|
||||||
id: 'noIcon',
|
id: 'noIcon',
|
||||||
appearance: {
|
appearance: {
|
||||||
|
|
|
||||||
|
|
@ -30,15 +30,6 @@ export function vec(v) {
|
||||||
return new Vector(v.x, v.y, v.z);
|
return new Vector(v.x, v.y, v.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createBox(w, h, d) {
|
|
||||||
var square = createSquare(w, h);
|
|
||||||
//var rot = Matrix3.rotateMatrix(3/4, AXIS.Z, ORIGIN);
|
|
||||||
var halfDepth = d / 2;
|
|
||||||
square.forEach(function(v) { v.z -= halfDepth; } );
|
|
||||||
var normal = normalOfCCWSeq(square);
|
|
||||||
return extrude(square, normal, normal.multiply(d), 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function checkPolygon(poly) {
|
export function checkPolygon(poly) {
|
||||||
if (poly.length < 3) {
|
if (poly.length < 3) {
|
||||||
throw new Error('Polygon should contain at least 3 point');
|
throw new Error('Polygon should contain at least 3 point');
|
||||||
|
|
|
||||||
|
|
@ -20,12 +20,10 @@ export function CallCommand(command, args) {
|
||||||
|
|
||||||
// c_strings.forEach(_free);
|
// c_strings.forEach(_free);
|
||||||
|
|
||||||
// free c_arr
|
|
||||||
_free(c_arr);
|
_free(c_arr);
|
||||||
|
|
||||||
// _free(commandPtr);
|
// _free(commandPtr);
|
||||||
|
|
||||||
// return
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -300,7 +300,7 @@ const DebugMenuConfig = {
|
||||||
cssIcons: ['bug'],
|
cssIcons: ['bug'],
|
||||||
info: 'set of debug actions',
|
info: 'set of debug actions',
|
||||||
actions: ['DebugPrintAllSolids', 'DebugPrintFace', 'DebugFaceId', 'DebugFaceSketch',
|
actions: ['DebugPrintAllSolids', 'DebugPrintFace', 'DebugFaceId', 'DebugFaceSketch',
|
||||||
'DebugSetSketcherIntegerPrecision', 'DebugOpenLastTest', 'DebugGenerateTest', 'DebugOpenBrepDebugger']
|
'DebugSetSketcherIntegerPrecision', 'DebugOpenLastTest', 'DebugOpenBrepDebugger']
|
||||||
};
|
};
|
||||||
|
|
||||||
const DebugActions = [
|
const DebugActions = [
|
||||||
|
|
@ -411,50 +411,6 @@ const DebugActions = [
|
||||||
window.location.href = '/index.html?$$$__test__$$$';
|
window.location.href = '/index.html?$$$__test__$$$';
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
id: 'DebugGenerateTest',
|
|
||||||
appearance: {
|
|
||||||
cssIcons: ['gear'],
|
|
||||||
label: 'generate unit test',
|
|
||||||
info: 'it will generate a unit code code containing sketches and operation sequence and output it to terminal',
|
|
||||||
},
|
|
||||||
invoke: ({bus, services: {project, storage, sketchStorageService, cadRegistry}}) => {
|
|
||||||
|
|
||||||
const pt = ({x, y}) => [x, y];
|
|
||||||
|
|
||||||
let sketches = sketchStorageService.getAllSketches().reduce((sketches, {id, url}) => {
|
|
||||||
let sketch = sketchStorageService.readSketch(id).getAllObjects().reduce((byType, obj) => {
|
|
||||||
|
|
||||||
let type = obj.constructor.name;
|
|
||||||
|
|
||||||
let arr = byType[type];
|
|
||||||
if (!arr) {
|
|
||||||
arr = [];
|
|
||||||
byType[type] = arr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type === 'Segment' ){
|
|
||||||
arr.push([pt(obj.a), pt(obj.b)]);
|
|
||||||
} else {
|
|
||||||
throw 'unsupported ' + type;
|
|
||||||
}
|
|
||||||
return byType;
|
|
||||||
}, {});
|
|
||||||
sketches[id] = sketch;
|
|
||||||
return sketches;
|
|
||||||
}, {});
|
|
||||||
|
|
||||||
let testMetadata = {
|
|
||||||
name: project.id,
|
|
||||||
state: {
|
|
||||||
sketches,
|
|
||||||
operations: bus.state[CRAFT_TOKENS.MODIFICATIONS].history
|
|
||||||
},
|
|
||||||
expected: toLoops(cadRegistry.getAllShells()[0].shell, readSketchFloat)
|
|
||||||
};
|
|
||||||
console.log(JSON.stringify(testMetadata));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
id: 'DebugOpenBrepDebugger',
|
id: 'DebugOpenBrepDebugger',
|
||||||
appearance: {
|
appearance: {
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,6 @@
|
||||||
import Vector from 'math/vector';
|
import Vector from 'math/vector';
|
||||||
import * as cad_utils from '../../cad-utils'
|
import * as cad_utils from '../../cad-utils'
|
||||||
import {HashTable} from '../../../utils/hashmap'
|
import {HashTable} from '../../../utils/hashmap'
|
||||||
import {Mesh} from '../mesh'
|
|
||||||
import revolve from './revolve'
|
|
||||||
import {Triangulate} from '../../tess/triangulation'
|
import {Triangulate} from '../../tess/triangulation'
|
||||||
import {distanceAB3} from "math/distance";
|
import {distanceAB3} from "math/distance";
|
||||||
import {areEqual, equal, strictEqual} from "math/equality";
|
import {areEqual, equal, strictEqual} from "math/equality";
|
||||||
|
|
@ -51,85 +49,6 @@ export function sortPolygons(polygons) {
|
||||||
return allShells;
|
return allShells;
|
||||||
}
|
}
|
||||||
|
|
||||||
function extrudeNestedLoops(sketchedPolygons, normal, target, expansionFactor) {
|
|
||||||
const loops = sortPolygons(sketchedPolygons);
|
|
||||||
const doExtrude = (polygon) => {
|
|
||||||
const extruded = cad_utils.extrude(polygon, normal, target, expansionFactor);
|
|
||||||
return CSG.fromPolygons(_triangulateCSG(extruded));
|
|
||||||
};
|
|
||||||
let blob = null;
|
|
||||||
for (let loop of loops) {
|
|
||||||
let shell = doExtrude(loop.polygon);
|
|
||||||
for (let nestedLoop of loop.nesting) {
|
|
||||||
const hole = doExtrude(nestedLoop.polygon);
|
|
||||||
shell = shell.subtract(hole);
|
|
||||||
}
|
|
||||||
if (blob === null) {
|
|
||||||
blob = shell;
|
|
||||||
} else {
|
|
||||||
blob = blob.union(shell);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return blob;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function extrude(app, request) {
|
|
||||||
const face = request.face;
|
|
||||||
const sketchedPolygons = getSketchedPolygons3D(app, face);
|
|
||||||
if (sketchedPolygons == null) return null;
|
|
||||||
const normal = cad_utils.vec(face.csgGroup.plane.normal);
|
|
||||||
let blob = extrudeNestedLoops(sketchedPolygons, normal, request.params.target, request.params.expansionFactor);
|
|
||||||
let solid = request.solids[0];
|
|
||||||
if (solid.mergeable) {
|
|
||||||
blob = solid.csg.union(blob);
|
|
||||||
}
|
|
||||||
face.csgGroup.shared.__tcad.faceId += '$';
|
|
||||||
return [cad_utils.createSolid(blob, solid.id)];
|
|
||||||
}
|
|
||||||
|
|
||||||
export function cut(app, request) {
|
|
||||||
const face = request.face;
|
|
||||||
const sketchedPolygons = getSketchedPolygons3D(app, face);
|
|
||||||
if (sketchedPolygons == null) return null;
|
|
||||||
const normal = cad_utils.vec(face.csgGroup.plane.normal);
|
|
||||||
let cutter = extrudeNestedLoops(sketchedPolygons, normal, request.params.target, request.params.expansionFactor);
|
|
||||||
|
|
||||||
face.csgGroup.shared.__tcad.faceId += '$';
|
|
||||||
var outSolids = [];
|
|
||||||
for (var si = 0; si < request.solids.length; si++) {
|
|
||||||
let solid = request.solids[si];
|
|
||||||
let work = solid.csg;
|
|
||||||
let cut = work.subtract(cutter);
|
|
||||||
let solidMesh = cad_utils.createSolid(cut, solid.id);
|
|
||||||
outSolids.push(solidMesh);
|
|
||||||
}
|
|
||||||
return outSolids;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function performRevolve(app, request) {
|
|
||||||
const face = request.face;
|
|
||||||
const sketchedPolygons = getSketchedPolygons3D(app, face);
|
|
||||||
if (sketchedPolygons == null) return null;
|
|
||||||
|
|
||||||
const params = request.params;
|
|
||||||
|
|
||||||
const vertices = face.getSketchObjectVerticesIn3D(params.pivotSketchObjectId);
|
|
||||||
if (!vertices) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
const axis = [vertices[0], vertices[vertices.length-1]];
|
|
||||||
const revolved = revolve(sketchedPolygons, axis, params.angle / 180 * Math.PI, params.resolution);
|
|
||||||
|
|
||||||
const solid = request.solids[0];
|
|
||||||
let meld = CSG.fromPolygons(_triangulateCSG(revolved));
|
|
||||||
if (solid.mergeable) {
|
|
||||||
meld = solid.csg.union(meld);
|
|
||||||
}
|
|
||||||
|
|
||||||
face.csgGroup.shared.__tcad.faceId += '$';
|
|
||||||
return [cad_utils.createSolid(meld, solid.id)];
|
|
||||||
}
|
|
||||||
|
|
||||||
function _pointOnLine(p, a, b) {
|
function _pointOnLine(p, a, b) {
|
||||||
|
|
||||||
var ab = a.minus(b);
|
var ab = a.minus(b);
|
||||||
|
|
@ -512,131 +431,4 @@ function attract(vectors, precision) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function recoverySketchInfo(polygons) {
|
|
||||||
var nonStructuralGons = [];
|
|
||||||
var sketchEdges = HashTable.forDoubleArray();
|
|
||||||
function key(a, b) {return [a.x, a.y, b.x, b.y]}
|
|
||||||
|
|
||||||
for (var pi = 0; pi < polygons.length; pi++) {
|
|
||||||
var poly = polygons[pi];
|
|
||||||
var paths = [];
|
|
||||||
poly.collectPaths(paths);
|
|
||||||
var i, path, n, p, q;
|
|
||||||
for (i = 0; i < paths.length; i++) {
|
|
||||||
path = paths[i];
|
|
||||||
if (poly.csgInfo !== undefined && poly.csgInfo.derivedFrom !== undefined) {
|
|
||||||
n = path.length;
|
|
||||||
for (p = n - 1, q = 0; q < n ; p = q++ ) {
|
|
||||||
sketchEdges.put(key(path[p], path[q]), poly.csgInfo);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
nonStructuralGons.push(path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < nonStructuralGons.length; i++) {
|
|
||||||
path = nonStructuralGons[i];
|
|
||||||
n = path.length;
|
|
||||||
for (p = n - 1, q = 0; q < n ; p = q++ ) {
|
|
||||||
var csgInfo = sketchEdges.get(key(path[p], path[q]));
|
|
||||||
if (csgInfo === null) {
|
|
||||||
csgInfo = sketchEdges.get(key(path[q], path[p]));
|
|
||||||
}
|
|
||||||
if (csgInfo) {
|
|
||||||
path[p].sketchConnectionObject = csgInfo.derivedFrom;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function detach(request) {
|
|
||||||
var detachedConfig = {};
|
|
||||||
for (var prop in request) {
|
|
||||||
if (request.hasOwnProperty(prop)) {
|
|
||||||
var value = request[prop];
|
|
||||||
if (prop == 'solids') {
|
|
||||||
detachedConfig[prop] = value.map(function(s){return s.tCadId});
|
|
||||||
} else if (prop == 'face') {
|
|
||||||
detachedConfig[prop] = value.id;
|
|
||||||
} else if (prop == 'target') {
|
|
||||||
detachedConfig[prop] = [value.x, value.y, value.z];
|
|
||||||
} else if (prop == 'basis') {
|
|
||||||
detachedConfig[prop] = value.map(function(v){return [v.x, v.y, v.z]});
|
|
||||||
} else if (prop == 'params') {
|
|
||||||
detachedConfig[prop] = detach(value);
|
|
||||||
} else {
|
|
||||||
detachedConfig[prop] = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return detachedConfig
|
|
||||||
}
|
|
||||||
|
|
||||||
function materialize(index, detachedConfig) {
|
|
||||||
var request = {};
|
|
||||||
function required(value) {
|
|
||||||
if (value == null || value == undefined) throw "value is required";
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
for (var prop in detachedConfig) {
|
|
||||||
if (detachedConfig.hasOwnProperty(prop)) {
|
|
||||||
var value = detachedConfig[prop];
|
|
||||||
if (prop == 'solids') {
|
|
||||||
request[prop] = value.map(function(id){return required(index.solids[id])});
|
|
||||||
} else if (prop == 'target') {
|
|
||||||
request[prop] = new Vector().set3(value);
|
|
||||||
} else if (prop == 'face') {
|
|
||||||
request[prop] = required(index.faces[value]);
|
|
||||||
} else if (prop == 'basis') {
|
|
||||||
request[prop] = value.map(function(v) {return new Vector().set3(v)});
|
|
||||||
} else if (prop == 'params') {
|
|
||||||
request[prop] = materialize(index, value);
|
|
||||||
} else {
|
|
||||||
request[prop] = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return request;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const MESH_OPERATIONS = {
|
|
||||||
CUT : cut,
|
|
||||||
EXTRUDE : extrude,
|
|
||||||
REVOLVE : performRevolve,
|
|
||||||
PLANE : function(app, request) {
|
|
||||||
let basis, depth = request.params.depth;
|
|
||||||
const relativeToFaceId = request.params.relativeToFaceId;
|
|
||||||
if (relativeToFaceId != undefined && relativeToFaceId != '') {
|
|
||||||
const face = app.findFace(relativeToFaceId);
|
|
||||||
if (!face) return;
|
|
||||||
basis = face.basis();
|
|
||||||
depth += face.depth();
|
|
||||||
} else {
|
|
||||||
basis = request.params.basis;
|
|
||||||
}
|
|
||||||
return [cad_utils.createPlane(basis, depth)];
|
|
||||||
},
|
|
||||||
BOX : function(app, request) {
|
|
||||||
var p = request.params;
|
|
||||||
return [cad_utils.createCSGBox(p.w, p.h, p.d)];
|
|
||||||
},
|
|
||||||
SPHERE : function(app, request) {
|
|
||||||
return [cad_utils.createSphere(request.params.radius)];
|
|
||||||
},
|
|
||||||
IMPORT_STL: function(app, request) {
|
|
||||||
return request.params.objects.map(s => {
|
|
||||||
const smoothAngle = 1 / 180 * Math.PI;
|
|
||||||
const mesh = Mesh.fromPolygons(s.faces.map(f => f.vertices.map(v => new Vector().set3(v))), smoothAngle);
|
|
||||||
const polygons = [];
|
|
||||||
for (let meshFace of mesh.faces) {
|
|
||||||
const pl = meshFace.polygons[0];
|
|
||||||
const plane = new CSG.Plane(pl.normal.csg(), pl.w);
|
|
||||||
const shared = cad_utils.createShared();
|
|
||||||
meshFace.polygons.map(p => new CSG.Polygon(p.points.map(v => new CSG.Vertex(v.csg())), shared, plane))
|
|
||||||
.forEach(p => polygons.push(p));
|
|
||||||
}
|
|
||||||
return cad_utils.createSolid(CSG.fromPolygons(polygons));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
|
||||||
|
|
@ -38,12 +38,6 @@ export function createPreviewer(sceneGeometryCreator, services, initialParams) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function sketchBasedPreviewCreator(params) {
|
|
||||||
const face = app.findFace(params.face);
|
|
||||||
if (!face) return null;
|
|
||||||
const triangles = this.createImpl(app, params, face.sketch.fetchContours(), face);
|
|
||||||
return createMeshFromTriangles(triangles, IMAGINARY_SURFACE_MATERIAL);
|
|
||||||
}
|
|
||||||
//
|
//
|
||||||
// function sketchBasedNurbsPreviewCreator(params) {
|
// function sketchBasedNurbsPreviewCreator(params) {
|
||||||
// const face = app.findFace(params.face);
|
// const face = app.findFace(params.face);
|
||||||
|
|
|
||||||
|
|
@ -1,28 +0,0 @@
|
||||||
import {state} from 'lstream';
|
|
||||||
import {DATUM, EDGE, FACE, SHELL, SKETCH_OBJECT} from '../../model/entities';
|
|
||||||
|
|
||||||
const SELECTABLE_ENTITIES = [FACE, EDGE, SKETCH_OBJECT, DATUM, SHELL];
|
|
||||||
|
|
||||||
|
|
||||||
export function defineDefaultSelectionState(ctx) {
|
|
||||||
ctx.streams.selection = {
|
|
||||||
};
|
|
||||||
SELECTABLE_ENTITIES.forEach(entity => {
|
|
||||||
ctx.streams.selection[entity] = state([]);
|
|
||||||
});
|
|
||||||
|
|
||||||
SELECTABLE_ENTITIES.forEach(entity => {
|
|
||||||
let entitySelectApi = {
|
|
||||||
objects: [],
|
|
||||||
single: undefined
|
|
||||||
};
|
|
||||||
ctx.services.selection[entity] = entitySelectApi;
|
|
||||||
let selectionState = streams.selection[entity];
|
|
||||||
selectionState.attach(selection => {
|
|
||||||
entitySelectApi.objects = selection.map(id => services.cadRegistry.findEntity(entity, id));
|
|
||||||
entitySelectApi.single = entitySelectApi.objects[0];
|
|
||||||
});
|
|
||||||
entitySelectApi.select = selection => selectionState.value = selection;
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -29,7 +29,7 @@ export default function initReassignSketchMode(ctx) {
|
||||||
return {enter, exit};
|
return {enter, exit};
|
||||||
}
|
}
|
||||||
|
|
||||||
function ReassignSketchTool({from, cancel}) {
|
function ReassignSketchToolImp({from, cancel}) {
|
||||||
return <div style={{
|
return <div style={{
|
||||||
margin: 10
|
margin: 10
|
||||||
}}>
|
}}>
|
||||||
|
|
@ -37,7 +37,7 @@ function ReassignSketchTool({from, cancel}) {
|
||||||
</div>;
|
</div>;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReassignSketchTool = mapContext(ctx => ({
|
const ReassignSketchTool = mapContext(ctx => ({
|
||||||
from: ctx.services.selection.face.single.id,
|
from: ctx.services.selection.face.single.id,
|
||||||
cancel: ctx.services.sketcher.reassignSketchMode.exit
|
cancel: ctx.services.sketcher.reassignSketchMode.exit
|
||||||
}))(ReassignSketchTool);
|
}))(ReassignSketchToolImp);
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ export function parse(buf) {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'vertex':
|
case 'vertex':
|
||||||
const position = parts.slice(1).map(Number);
|
var position = parts.slice(1).map(Number);
|
||||||
face.vertices.push(position);
|
face.vertices.push(position);
|
||||||
break;
|
break;
|
||||||
case 'endfacet':
|
case 'endfacet':
|
||||||
|
|
@ -42,6 +42,7 @@ export function parse(buf) {
|
||||||
console.warn('bad stl face at line ' + lineNumber);
|
console.warn('bad stl face at line ' + lineNumber);
|
||||||
}
|
}
|
||||||
face = new StlFace(null);
|
face = new StlFace(null);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
// skip
|
// skip
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -52,24 +52,3 @@ class NestedLoop {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function createFaces() {
|
|
||||||
const loop = nestedLoop.loop;
|
|
||||||
const newFace = new Face(surface);
|
|
||||||
Object.assign(newFace.data, originFace.data);
|
|
||||||
newFace.outerLoop = loop;
|
|
||||||
loop.face = newFace;
|
|
||||||
out.push(newFace);
|
|
||||||
|
|
||||||
for (let child of nestedLoop.nesting) {
|
|
||||||
if (child.level == level + 2) {
|
|
||||||
createFaces(child, surface, level + 2);
|
|
||||||
} else if (child.level == level + 1) {
|
|
||||||
if (!child.loop.isCCW(surface)) {
|
|
||||||
child.loop.face = newFace;
|
|
||||||
newFace.innerLoops.push(child.loop);
|
|
||||||
} else {
|
|
||||||
createFaces(child, surface, level + 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -51,12 +51,6 @@ export default [
|
||||||
'PLANE', 'BOX', 'SPHERE', 'CONE', 'CYLINDER', 'TORUS', '-',
|
'PLANE', 'BOX', 'SPHERE', 'CONE', 'CYLINDER', 'TORUS', '-',
|
||||||
'EditFace']
|
'EditFace']
|
||||||
},
|
},
|
||||||
{
|
|
||||||
id: 'SolidContext',
|
|
||||||
label: 'solid-context',
|
|
||||||
info: 'solid context actions',
|
|
||||||
actions: ['LookAtSolid']
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
id: 'datum',
|
id: 'datum',
|
||||||
label: 'datum',
|
label: 'datum',
|
||||||
|
|
|
||||||
|
|
@ -768,7 +768,6 @@ function EllipseTangent(params) {
|
||||||
|
|
||||||
if (perpendicularLength < 0) {
|
if (perpendicularLength < 0) {
|
||||||
perpendicularLength *= -1;
|
perpendicularLength *= -1;
|
||||||
} else {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (radiusY - perpendicularLength); //*1000;
|
return (radiusY - perpendicularLength); //*1000;
|
||||||
|
|
|
||||||
|
|
@ -77,10 +77,10 @@ export class BezierCurve extends SketchObject {
|
||||||
ctx.stroke();
|
ctx.stroke();
|
||||||
|
|
||||||
//debug lut and hull
|
//debug lut and hull
|
||||||
//this.drawLUTAndHull();
|
//this.drawLUTAndHull(ctx, scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
drawLUTAndHull() {
|
drawLUTAndHull(ctx, scale) {
|
||||||
if (this.lut) {
|
if (this.lut) {
|
||||||
for (let p of this.lut) {
|
for (let p of this.lut) {
|
||||||
draw_utils.DrawPoint(ctx, p.x, p.y, 3, scale);
|
draw_utils.DrawPoint(ctx, p.x, p.y, 3, scale);
|
||||||
|
|
|
||||||
|
|
@ -17,13 +17,6 @@ export function askNumber(promptText, initValue, promptCallback, resolver) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const extend = function(func, parent) {
|
|
||||||
for(var prop in parent.prototype) {
|
|
||||||
if(parent.prototype.hasOwnProperty(prop))
|
|
||||||
func.prototype[prop] = parent.prototype[prop];
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export function constRef(value) {
|
export function constRef(value) {
|
||||||
return function() {
|
return function() {
|
||||||
return value;
|
return value;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue