mirror of
https://github.com/xibyte/jsketcher
synced 2025-12-25 01:45:26 +01:00
scratch tests for nurbs boolean
This commit is contained in:
parent
3c910e4838
commit
496cf22ba9
3 changed files with 53 additions and 28 deletions
|
|
@ -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();
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in a new issue