jsketcher/web/app/cad/sketch/sketchBoundaries.js

160 lines
4 KiB
JavaScript

import {Matrix3} from "../../math/l3space";
import {circleFromPoints, distanceAB, TOLERANCE} from "../../math/math";
import {iteratePath} from "../cad-utils";
export function getSketchBoundaries(sceneFace) {
const boundary = {lines: [], arcs: [], circles: []};
function sameSketchObject(a, b) {
if (a.sketchConnectionObject === undefined || b.sketchConnectionObject === undefined) {
return false;
}
return a.sketchConnectionObject.id === b.sketchConnectionObject.id;
}
let paths = sceneFace.getBounds();
//sceneFace.polygon.collectPaths(paths);
let w2sTr = sceneFace.worldToSketchTransformation;
function addSegment(a, b) {
boundary.lines.push({
a: {x: a.x, y: a.y},
b: {x: b.x, y: b.y}
});
}
let dist = distanceAB;
function addArc(arc) {
function addArcAsSegments(arc) {
for (let i = 1; i < arc.length; i++) {
addSegment(arc[i - 1], arc[i]);
}
}
if (arc.length < 5) {
addArcAsSegments(arc);
return;
}
let a = arc[1], b = arc[arc.length - 2];
let mid = (arc.length / 2) >> 0;
let c = circleFromPoints(a, arc[mid], b);
if (c === null) {
addArcAsSegments(arc);
return;
}
let rad = dist(a, c);
if (Math.abs(rad - dist(b, c)) > TOLERANCE) {
addArcAsSegments(arc);
return;
}
let firstPoint = arc[0];
let lastPoint = arc[arc.length - 1];
if (Math.abs(rad - dist(firstPoint, c)) < TOLERANCE) {
a = firstPoint;
} else {
addSegment(firstPoint, a);
}
if (Math.abs(rad - dist(lastPoint, c)) < TOLERANCE) {
b = lastPoint;
} else {
addSegment(b, lastPoint);
}
if (!cad_utils.isCCW([a, arc[mid], b])) {
let t = a;
a = b;
b = t;
}
boundary.arcs.push({
a: {x: a.x, y: a.y},
b: {x: b.x, y: b.y},
c: {x: c.x, y: c.y}
});
}
function addCircle(circle) {
let n = circle.length;
//let c = math.circleFromPoints(circle[0], circle[((n / 3) >> 0) % n], circle[((2 * n / 3) >> 0) % n]);
let c = circleFromPoints(circle[0], circle[1], circle[2]);
if (c === null) return;
let r = dist(circle[0], c);
boundary.circles.push({
c: {x: c.x, y: c.y},
r: r
});
}
function isCircle(path) {
for (let i = 0; i < path.length; i++) {
let p = path[i];
if (p.sketchConnectionObject === undefined
|| p.sketchConnectionObject._class !== 'TCAD.TWO.Circle'
|| p.sketchConnectionObject.id !== path[0].sketchConnectionObject.id) {
return false;
}
}
return true;
}
function trPath(path) {
let out = [];
for (let i = 0; i < path.length; i++) {
out.push(w2sTr.apply(path[i]));
}
return out;
}
for (let i = 0; i < paths.length; i++) {
let path = paths[i];
if (path.length < 3) continue;
let shift = 0;
if (isCircle(path)) {
addCircle(trPath(path));
continue;
}
iteratePath(path, 0, function (a, b, ai, bi) {
shift = bi;
return sameSketchObject(a, b);
});
let currSko = null;
let arc = null;
iteratePath(path, shift + 1, function (a, b, ai, bi, iterNumber, path) {
let isArc = a.sketchConnectionObject !== undefined &&
(a.sketchConnectionObject._class === 'TCAD.TWO.Arc' || a.sketchConnectionObject._class === 'TCAD.TWO.Circle'); //if circle gets splitted
let a2d = w2sTr.apply(a);
if (isArc) {
if (currSko !== a.sketchConnectionObject.id) {
currSko = a.sketchConnectionObject.id;
if (arc !== null) {
arc.push(a2d);
addArc(arc);
}
arc = [];
}
arc.push(a2d);
if (iterNumber === path.length - 1) {
arc.push(w2sTr.apply(b));
addArc(arc);
}
} else {
if (arc !== null) {
arc.push(a2d);
addArc(arc);
arc = null;
}
currSko = null;
addSegment(a2d, w2sTr.apply(b));
}
return true;
});
}
return boundary;
}