brep builder type safety

This commit is contained in:
Val Erastov (xibyte) 2020-07-19 23:33:43 -07:00
parent f24a3f45a5
commit a99c8cf5a5
5 changed files with 31 additions and 21 deletions

View file

@ -9,32 +9,38 @@ import BBox from 'math/bbox';
import NurbsSurface from 'geom/surfaces/nurbsSurface'; import NurbsSurface from 'geom/surfaces/nurbsSurface';
import {BrepSurface} from 'geom/surfaces/brepSurface'; import {BrepSurface} from 'geom/surfaces/brepSurface';
import EdgeIndex from './edgeIndex'; import EdgeIndex from './edgeIndex';
import {HalfEdge} from "brep/topo/edge";
import Vector from "math/vector";
export default class BrepBuilder { export default class BrepBuilder {
_shell: Shell;
_face: Face;
_loop: Loop;
edgeIndex: EdgeIndex;
constructor(edgeStra) { constructor() {
this._shell = new Shell(); this._shell = new Shell();
this._face = null; this._face = null;
this._loop = null; this._loop = null;
this.edgeIndex = new EdgeIndex(); this.edgeIndex = new EdgeIndex();
} }
get lastHalfEdge() { get lastHalfEdge(): HalfEdge {
return this._loop.halfEdges[this._loop.halfEdges.length - 1]; return this._loop.halfEdges[this._loop.halfEdges.length - 1];
} }
face(surface) { face(surface: BrepSurface): BrepBuilder {
this._face = new Face(surface ? surface : null); this._face = new Face(surface ? surface : null);
this._shell.faces.push(this._face); this._shell.faces.push(this._face);
this._loop = null; this._loop = null;
return this; return this;
} }
loop(vertices) { loop(vertices: Vertex[]): BrepBuilder {
if (this._loop === null) { if (this._loop === null) {
this._loop = this._face.outerLoop; this._loop = this._face.outerLoop;
} else { } else {
this._loop = new Loop(); this._loop = new Loop(null);
this._face.innerLoops.push(this._loop); this._face.innerLoops.push(this._loop);
} }
this._loop.face = this._face; this._loop.face = this._face;
@ -57,17 +63,17 @@ export default class BrepBuilder {
return this; return this;
} }
edge(a, b, curveCreate, invertedToCurve, tag) { edge(a, b, curveCreate?, invertedToCurve?, tag?): BrepBuilder {
let he = this.edgeIndex.getHalfEdgeOrCreate(a, b, curveCreate, invertedToCurve, tag); let he = this.edgeIndex.getHalfEdgeOrCreate(a, b, curveCreate, invertedToCurve, tag);
this._loop.halfEdges.push(he); this._loop.halfEdges.push(he);
return this; return this;
} }
vertex(x, y, z) { vertex(x: number, y: number, z: number): Vertex {
return new Vertex(new Point(x, y, z)); return new Vertex(new Point(x, y, z));
} }
build() { build(): Shell {
for (let face of this._shell.faces) { for (let face of this._shell.faces) {
for (let loop of face.loops) { for (let loop of face.loops) {
loop.link(); loop.link();
@ -90,7 +96,7 @@ export default class BrepBuilder {
} }
} }
export function createBoundingSurface(points, plane) { export function createBoundingSurface(points: Vector[], plane?: Plane): BrepSurface {
if (!plane) { if (!plane) {
const normal = normalOfCCWSeq(points); const normal = normalOfCCWSeq(points);
const w = points[0].dot(normal); const w = points[0].dot(normal);
@ -102,7 +108,7 @@ export function createBoundingSurface(points, plane) {
return createBoundingSurfaceFrom2DPoints(points2d, plane); return createBoundingSurfaceFrom2DPoints(points2d, plane);
} }
export function createBoundingSurfaceFrom2DPoints(points2d, plane, minWidth, minHeight, offset = 0) { export function createBoundingSurfaceFrom2DPoints(points2d: Vector[], plane: Plane, minWidth?: number, minHeight?: number, offset = 0): BrepSurface {
let bBox = new BBox(); let bBox = new BBox();
points2d.forEach(p => bBox.checkPoint(p)); points2d.forEach(p => bBox.checkPoint(p));
@ -125,9 +131,9 @@ export function createBoundingSurfaceFrom2DPoints(points2d, plane, minWidth, min
return createBoundingSurfaceFromBBox(bBox, plane); return createBoundingSurfaceFromBBox(bBox, plane);
} }
export function createBoundingSurfaceFromBBox(bBox, plane) { export function createBoundingSurfaceFromBBox(bBox: BBox, plane: Plane): BrepSurface {
let to3D = plane.get3DTransformation(); let to3D = plane.get3DTransformation();
let polygon = bBox.toPolygon(); let polygon = bBox.toPolygon() as Vector[];
polygon = polygon.map(p => to3D._apply(p).data()); polygon = polygon.map(p => to3D._apply(p).data());
let planeNurbs = verb.geom.NurbsSurface.byKnotsControlPointsWeights( 1, 1, [0,0,1,1], [0,0,1,1], let planeNurbs = verb.geom.NurbsSurface.byKnotsControlPointsWeights( 1, 1, [0,0,1,1], [0,0,1,1],

View file

@ -1,13 +1,18 @@
import {Edge} from './topo/edge'; import {Edge, HalfEdge} from './topo/edge';
import BrepCurve from 'geom/curves/brepCurve'; import BrepCurve from 'geom/curves/brepCurve';
import {Vertex} from "brep/topo/vertex";
export type Tag = string | number;
export default class EdgeIndex { export default class EdgeIndex {
index: Map<Vertex, Set<[HalfEdge, Tag]>>;
constructor() { constructor() {
this.index = new Map(); this.index = new Map();
} }
addEdge(edge, tag) { addEdge(edge: Edge, tag: Tag) {
if (edge.halfEdge1) { if (edge.halfEdge1) {
this.addHalfEdge(edge.halfEdge1, tag); this.addHalfEdge(edge.halfEdge1, tag);
} }
@ -16,11 +21,11 @@ export default class EdgeIndex {
} }
} }
addHalfEdge(he, tag) { addHalfEdge(he: HalfEdge, tag: Tag) {
this._edgesForVertex(he.vertexA).add([he, tag]); this._edgesForVertex(he.vertexA).add([he, tag]);
} }
_edgesForVertex(v) { _edgesForVertex(v: Vertex): Set<[HalfEdge, Tag]> {
let edges = this.index.get(v); let edges = this.index.get(v);
if (!edges) { if (!edges) {
edges = new Set(); edges = new Set();
@ -29,7 +34,7 @@ export default class EdgeIndex {
return edges; return edges;
} }
getHalfEdge(a, b, tag) { getHalfEdge(a: Vertex, b: Vertex, tag?: Tag): HalfEdge {
let edges = this.index.get(a); let edges = this.index.get(a);
if (edges) { if (edges) {
for (let [he, _tag] of edges) { for (let [he, _tag] of edges) {
@ -41,7 +46,7 @@ export default class EdgeIndex {
return null; return null;
} }
getHalfEdgeOrCreate(a, b, curveCreate, invertedToCurve, tag) { getHalfEdgeOrCreate(a: Vertex, b: Vertex, curveCreate?: () => BrepCurve, invertedToCurve?: boolean, tag?: Tag): HalfEdge {
let he = this.getHalfEdge(a, b, tag); let he = this.getHalfEdge(a, b, tag);
if (he === null) { if (he === null) {
let curve; let curve;

View file

@ -241,7 +241,7 @@ function curveExactIntersection(curve1, curve2, u1, u2) {
let d2 = verb.eval.Eval.rationalCurveDerivatives(curve2, u2, 1); let d2 = verb.eval.Eval.rationalCurveDerivatives(curve2, u2, 1);
let r = vec.sub(d1[0], d2[0]); let r = vec.sub(d1[0], d2[0]);
let drdu = d1[1]; let drdu = d1[1];
let drdt = vec.mul(-1, d2[1]); let drdt = vec.mul(d2[1], -1);
return [2 * vec.dot(drdu, r), 2 * vec.dot(drdt,r)]; return [2 * vec.dot(drdu, r), 2 * vec.dot(drdt,r)];
} }
let params = [u1, u2]; let params = [u1, u2];

View file

@ -20,8 +20,7 @@ export default class BBox {
this.maxZ = -Number.MAX_VALUE; this.maxZ = -Number.MAX_VALUE;
} }
checkBounds(x: number, y: number, z: number): void { checkBounds(x: number, y: number, z: number = 0): void {
z = z || 0;
this.minX = Math.min(this.minX, x); this.minX = Math.min(this.minX, x);
this.minY = Math.min(this.minY, y); this.minY = Math.min(this.minY, y);
this.minZ = Math.min(this.minZ, z); this.minZ = Math.min(this.minZ, z);