diff --git a/web/app/3d/modeler-app.js b/web/app/3d/modeler-app.js index 64ecad2e..7e10bff0 100644 --- a/web/app/3d/modeler-app.js +++ b/web/app/3d/modeler-app.js @@ -24,6 +24,7 @@ import * as BREPBool from '../brep/operations/boolean' import {BREPValidator} from '../brep/brep-validator' import {BREPSceneSolid} from './scene/brep-scene-object' import TPI from './tpi' +import {NurbsCurve} from "../brep/geom/impl/nurbs"; // import {createSphere, rayMarchOntoCanvas, sdfIntersection, sdfSolid, sdfSubtract, sdfTransform, sdfUnion} from "../hds/sdf"; function App() { @@ -37,18 +38,18 @@ function App() { this.tabSwitcher = new TabSwitcher($('#tab-switcher'), $('#view-3d')); this.controlBar = new ControlBar(this, $('#control-bar')); this.TPI = TPI; - + this.craft = new Craft(this); this.ui = new UI(this); AddDebugSupport(this); - + if (this.id.startsWith('$scratch$')) { setTimeout(() => this.scratchCode(), 0); } else { this.load(); } - + this._refreshSketches(); this.viewer.render(); @@ -85,14 +86,34 @@ App.prototype.addShellOnScene = function(shell, skin) { App.prototype.scratchCode = function() { const app = this; + const box1 = app.TPI.brep.primitives.box(500, 500, 500); const box2 = app.TPI.brep.primitives.box(250, 250, 750, new Matrix3().translate(25, 25, 0)); + const box3 = app.TPI.brep.primitives.box(150, 600, 350, new Matrix3().translate(25, 25, -250)); // let result = app.TPI.brep.bool.union(box1, box2); - let result = app.TPI.brep.bool.subtract(box1, box2); - result = app.TPI.brep.bool.subtract(result, box3); + // let result = app.TPI.brep.bool.subtract(box1, box2); + // result = app.TPI.brep.bool.subtract(result, box3); // app.addShellOnScene(box1); - app.addShellOnScene(result); + // app.addShellOnScene(result); + + + let curve1 = new NurbsCurve(new verb.geom.NurbsCurve({"degree":6,"controlPoints":[[150,149.99999999999997,-249.99999999999994,1],[108.33333333333051,150.00000000000907,-250.00000000001975,1],[66.6666666666712,149.99999999998562,-249.99999999996987,1],[24.99999999999545,150.00000000001364,-250.00000000002711,1],[-16.66666666666362,149.99999999999145,-249.9999999999837,1],[-58.33333333333436,150.0000000000029,-250.00000000000531,1],[-99.99999999999997,150,-250,1]],"knots":[0,0,0,0,0,0,0,1,1,1,1,1,1,1]})); + let curve2 = new NurbsCurve(new verb.geom.NurbsCurve({"degree":9,"controlPoints":[[100,-250,-250,1],[99.9999999999927,-194.44444444444687,-250.00000000000028,1],[100.00000000002228,-138.8888888888811,-249.99999999999838,1],[99.99999999995923,-83.33333333334777,-250.00000000000287,1],[100.00000000005268,-27.77777777775936,-249.99999999999744,1],[99.9999999999493,27.777777777760704,-250.0000000000008,1],[100.00000000003591,83.33333333334477,-250.00000000000063,1],[99.99999999998269,138.88888888888374,-249.99999999999966,1],[100.00000000000443,194.44444444444562,-249.99999999999986,1],[100,250,-250,1]],"knots":[0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1]})); + + __DEBUG__.AddCurve(curve1); + __DEBUG__.AddCurve(curve2); + + + // let curves = surface.intersectSurface(box1.faces[0].surface); + // const curve = box1.faces[0].outerLoop.halfEdges[0].edge.curve; + let points = curve1.intersectCurve(curve2); + for (let p of points) { + __DEBUG__.AddPoint(p.p0); + } + + + app.viewer.render(); }; diff --git a/web/app/brep/geom/impl/nurbs.js b/web/app/brep/geom/impl/nurbs.js index 2708e9ab..da86def0 100644 --- a/web/app/brep/geom/impl/nurbs.js +++ b/web/app/brep/geom/impl/nurbs.js @@ -44,7 +44,7 @@ export class NurbsCurve extends Curve { intersectCurve(other, tol) { let isecs = []; - tol = tol || 1e-6; + tol = tol || 1e-3; const eq = (v1, v2) => math.areVectorsEqual3(v1, v2, tol); @@ -85,8 +85,11 @@ export class NurbsCurve extends Curve { isecs.forEach(i => { i.p0 = pt(i.p0); i.p1 = pt(i.p1); - }) - return isecs; + }); + return isecs.filter(({u0, u1}) => { + return Math.abs(this.tangentAtParam(u0).dot(other.tangentAtParam(u1))) <= tol; + }); + } static createByPoints(points, degeree) { diff --git a/web/app/brep/operations/boolean.js b/web/app/brep/operations/boolean.js index 601ef77c..124f99c2 100644 --- a/web/app/brep/operations/boolean.js +++ b/web/app/brep/operations/boolean.js @@ -24,17 +24,17 @@ const TYPE = { }; export function union( shell1, shell2 ) { - __DEBUG_OPERANDS(shell1, shell2); + $DEBUG_OPERANDS(shell1, shell2); return BooleanAlgorithm(shell1, shell2, TYPE.UNION); } export function intersect( shell1, shell2 ) { - __DEBUG_OPERANDS(shell1, shell2); + $DEBUG_OPERANDS(shell1, shell2); return BooleanAlgorithm(shell1, shell2, TYPE.INTERSECT); } export function subtract( shell1, shell2 ) { - __DEBUG_OPERANDS(shell1, shell2); + $DEBUG_OPERANDS(shell1, shell2); invert(shell2); return BooleanAlgorithm(shell1, shell2, TYPE.INTERSECT); } @@ -81,8 +81,7 @@ export function BooleanAlgorithm( shell1, shell2, type ) { const loops = detectLoops(faceData.face); for (let loop of loops) { for (let edge of loop.halfEdges) { - const isNew = EdgeSolveData.get(edge).newEdgeFlag === true; - if (isNew) newLoops.add(loop); + if (isNew(edge)) newLoops.add(loop); } } loopsToFaces(face, loops, allFaces); @@ -99,7 +98,7 @@ export function BooleanAlgorithm( shell1, shell2, type ) { BREPValidator.validateToConsole(result); __DEBUG__.ClearVolumes(); - __DEBUG__.Clear(); + // __DEBUG__.Clear(); return result; } @@ -114,8 +113,9 @@ function detectLoops(face) { const loops = []; const seen = new Set(); let edges = []; - for (let e of face.edges) edges.push(e); - for (let e of faceData.loopOfNew.halfEdges) edges.push(e); + for (let e of face.edges) { + edges.push(e); + } while (true) { let edge = edges.pop(); if (!edge) { @@ -150,10 +150,6 @@ function detectLoops(face) { return loops; } -function edgeV(edge) { - return edge.vertexB.point.minus(edge.vertexA.point)._normalize(); -} - export function mergeVertices(shell1, shell2) { const toSwap = new Map(); for (let v1 of shell1.vertices) { @@ -450,6 +446,8 @@ function collectNodesOfIntersection(curve, loop, nodes) { } function intersectCurveWithEdge(curve, edge, result) { + __DEBUG__.AddCurve(curve, 0xffffff); + __DEBUG__.AddHalfEdge(edge, 0xff00ff); const points = edge.edge.curve.intersectCurve(curve, TOLERANCE); for (let point of points) { const {u0, u1} = point; @@ -463,6 +461,8 @@ function intersectCurveWithEdge(curve, edge, result) { vertex = vertexFactory.create(point.p0); } + __DEBUG__.AddVertex(vertex); + result.push(new Node(vertex, edge, curve, u1)); } } @@ -518,8 +518,7 @@ function nodeNormal(point, edge, curve) { const normal = edge.loop.face.surface.normal(point); const edgeTangent = edge.tangent(point); const curveTangent = curve.tangentAtPoint(point); - - + let cross = normal.cross(edgeTangent); let dot = cross.dot(curveTangent); if (eq(dot, 0)) { @@ -560,12 +559,16 @@ EdgeSolveData.transfer = function(from, to) { to.data[MY] = from.data[MY]; }; +function isNew(edge) { + return EdgeSolveData.get(edge).newEdgeFlag === true +} + function Node(vertex, edge, curve, u) { this.vertex = vertex; this.edge = edge; this.curve = curve; this.u = u; - this.normal = nodeNormal(vertex.point, edge, curve); + this.normal = isNew(edge) ? 0 : nodeNormal(vertex.point, edge, curve); //__DEBUG__.AddPoint(this.point); } @@ -620,6 +623,7 @@ class FaceSolveData { constructor(face) { this.face = face; this.loopOfNew = new Loop(face); + face.innerLoops.push(this.loopOfNew); this.vertexToEdge = new Map(); } @@ -628,9 +632,6 @@ class FaceSolveData { for (let he of this.face.edges) { this.addToGraph(he); } - for (let he of this.loopOfNew.halfEdges) { - this.addToGraph(he); - } } addToGraph(he) { @@ -657,7 +658,7 @@ function removeFromListInMap(map, key, value) { } } -function __DEBUG_OPERANDS(shell1, shell2) { +function $DEBUG_OPERANDS(shell1, shell2) { if (DEBUG.OPERANDS_MODE) { __DEBUG__.HideSolids(); __DEBUG__.AddVolume(shell1, 0x800080);