mirror of
https://github.com/xibyte/jsketcher
synced 2025-12-07 08:53:25 +01:00
BREP boolean operations / debug info
This commit is contained in:
parent
c4ee5ba7c6
commit
edad41be1e
7 changed files with 85 additions and 31 deletions
|
|
@ -1,12 +1,49 @@
|
|||
import {checkForSelectedFaces} from './actions/action-helpers'
|
||||
|
||||
export const DEBUG = false;
|
||||
export const DEBUG = true;
|
||||
|
||||
export function AddDebugSupport(app) {
|
||||
if (!DEBUG) return;
|
||||
app.actionManager.registerActions(DebugActions);
|
||||
app.ui.registerMenuActions(DebugMenuConfig);
|
||||
app.controlBar.add('menu.debug', true);
|
||||
addGlobalDebugActions(app);
|
||||
}
|
||||
|
||||
function addGlobalDebugActions(app) {
|
||||
window.__DEBUG__ = {
|
||||
AddLine: (a, b) => {
|
||||
app.viewer.workGroup.add(createLine(a, b));
|
||||
app.viewer.render();
|
||||
},
|
||||
AddPoint: (coordinates, or, vector) => {
|
||||
app.viewer.workGroup.add(createPoint(coordinates, or, vector));
|
||||
app.viewer.render();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function createLine(a, b) {
|
||||
const debugLineMaterial = new THREE.LineBasicMaterial({color: 0xFA8072, linewidth: 3});
|
||||
const lg = new THREE.Geometry();
|
||||
lg.vertices.push(a.three());
|
||||
lg.vertices.push(b.three());
|
||||
return new THREE.Line(lg, debugLineMaterial);
|
||||
}
|
||||
|
||||
function createPoint(x, y, z) {
|
||||
if (!y) {
|
||||
y = x.y;
|
||||
z = x.z;
|
||||
x = x.x;
|
||||
}
|
||||
var geometry = new THREE.SphereGeometry( 5, 16, 16 );
|
||||
var material = new THREE.MeshBasicMaterial( {color: 0x00ff00} );
|
||||
var sphere = new THREE.Mesh(geometry, material);
|
||||
sphere.position.x = x;
|
||||
sphere.position.y = y;
|
||||
sphere.position.z = z;
|
||||
return sphere;
|
||||
}
|
||||
|
||||
const DebugMenuConfig = {
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@ import {init as initSample} from './sample'
|
|||
import '../../css/app3d.less'
|
||||
|
||||
import * as BREPPrimitives from '../brep/brep-primitives'
|
||||
import * as BREPAffine from '../brep/operations/affine'
|
||||
import * as BREPBool from '../brep/operations/boolean'
|
||||
import {SceneSolid} from '../brep/viz/scene-solid'
|
||||
|
||||
|
|
@ -77,15 +76,13 @@ App.prototype.BREPTest = function() {
|
|||
this.viewer.workGroup.add(sceneSolid.cadGroup);
|
||||
};
|
||||
const box1 = BREPPrimitives.box(500, 500, 500);
|
||||
const box2 = BREPPrimitives.box(500, 500, 500);
|
||||
const box2 = BREPPrimitives.box(500, 500, 500, new Matrix3().translate(250, 250, 250));
|
||||
|
||||
BREPAffine.transform(box2, new Matrix3().translate(250, 250, 250));
|
||||
|
||||
//addToScene(box1);
|
||||
//addToScene(box2);
|
||||
addToScene(box1);
|
||||
addToScene(box2);
|
||||
|
||||
const result = BREPBool.union(box1, box2);
|
||||
addToScene(result);
|
||||
//addToScene(result);
|
||||
|
||||
this.viewer.render()
|
||||
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ export function createPrism(basePoints, height) {
|
|||
});
|
||||
|
||||
baseFace.debugName = 'base';
|
||||
baseFace.debugName = 'lid';
|
||||
lidFace.debugName = 'lid';
|
||||
|
||||
shell.faces.push(baseFace, lidFace);
|
||||
return shell;
|
||||
|
|
|
|||
|
|
@ -1,13 +1,19 @@
|
|||
import * as BREPBuilder from './brep-builder'
|
||||
import {Matrix3} from '../math/l3space'
|
||||
|
||||
export function box(w, h, d) {
|
||||
export function box(w, h, d, tr) {
|
||||
const wh = w * 0.5;
|
||||
const hh = h * 0.5;
|
||||
const dh = d * 0.5;
|
||||
if (!tr) {
|
||||
tr = IDENTITY;
|
||||
}
|
||||
return BREPBuilder.createPrism([
|
||||
BREPBuilder.point(-wh, -hh, dh),
|
||||
BREPBuilder.point( wh, -hh, dh),
|
||||
BREPBuilder.point( wh, hh, dh),
|
||||
BREPBuilder.point(-wh, hh, dh)
|
||||
tr._apply(BREPBuilder.point(-wh, -hh, dh)),
|
||||
tr._apply(BREPBuilder.point( wh, -hh, dh)),
|
||||
tr._apply(BREPBuilder.point( wh, hh, dh)),
|
||||
tr._apply(BREPBuilder.point(-wh, hh, dh))
|
||||
], d);
|
||||
}
|
||||
}
|
||||
|
||||
const IDENTITY = new Matrix3();
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
|
||||
export function transform(shell, matrix) {
|
||||
for (let vertex of shell.vertices) {
|
||||
matrix._apply(vertex.point);
|
||||
}
|
||||
}
|
||||
|
|
@ -22,8 +22,11 @@ export function union( shell1, shell2 ) {
|
|||
|
||||
const seen = new Set();
|
||||
const face = faceData.face;
|
||||
const edges = faceData.newEdges.concat(face.outerLoop);
|
||||
|
||||
if (shell2.faces.indexOf(face) != -1) {
|
||||
continue;
|
||||
}
|
||||
const edges = faceData.newEdges.concat(face.outerLoop.halfEdges);
|
||||
edges.forEach(e => __DEBUG__.AddLine(e.vertexA.point, e.vertexB.point));
|
||||
while (true) {
|
||||
let edge = edges.pop();
|
||||
if (!edge) {
|
||||
|
|
@ -37,7 +40,10 @@ export function union( shell1, shell2 ) {
|
|||
loop.halfEdges.push(edge);
|
||||
seen.add(edge);
|
||||
let candidates = faceData.vertexToEdge.get(edge.vertexB);
|
||||
edge = findMaxTurningLeft(candidates, face);
|
||||
if (!candidates) {
|
||||
break;
|
||||
}
|
||||
edge = findMaxTurningLeft(edge, candidates);
|
||||
if (seen.has(edge)) {
|
||||
break;
|
||||
}
|
||||
|
|
@ -47,9 +53,10 @@ export function union( shell1, shell2 ) {
|
|||
const newFace = new Face(face.surface);
|
||||
newFace.outerLoop = loop;
|
||||
newFace.outerLoop.face = newFace;
|
||||
result.push(newFace);
|
||||
result.faces.push(newFace);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function initSolveData(shell, facesData) {
|
||||
|
|
@ -64,7 +71,7 @@ function initSolveData(shell, facesData) {
|
|||
}
|
||||
}
|
||||
|
||||
function findMaxTurningLeft(edge, edges, face) {
|
||||
function findMaxTurningLeft(edge, edges) {
|
||||
edges = edges.slice();
|
||||
function edgeVector(edge) {
|
||||
return edge.vertexB.point.minus(edge.vertexA.point)._normalize();
|
||||
|
|
@ -89,6 +96,10 @@ function intersectFaces(shell1, shell2) {
|
|||
for (let j = 0; j < shell2.faces.length; j++) {
|
||||
const face1 = shell1.faces[i];
|
||||
const face2 = shell2.faces[j];
|
||||
|
||||
if (face1.debugName == 'base' && face2.debugName == 'wall_3') {
|
||||
console.log('there');
|
||||
}
|
||||
|
||||
const curve = face1.surface.intersect(face2.surface);
|
||||
|
||||
|
|
@ -125,10 +136,11 @@ function split(face, loop, result, onCurve, direction) {
|
|||
}
|
||||
for (let i = 0; i < nodes.length; i++) {
|
||||
let inNode = nodes[i];
|
||||
if (inNode == null) continue;
|
||||
nodes[i] = null;
|
||||
let closestIdx = findCloserProjection(nodes, inNode.point);
|
||||
if (closestIdx == -1) {
|
||||
throw 'consider me';
|
||||
continue;
|
||||
}
|
||||
let outNode = nodes[closestIdx];
|
||||
|
||||
|
|
@ -181,8 +193,8 @@ function splitEdgeByVertex(originHalfEdge, vertex) {
|
|||
orig.vertexB = vertex;
|
||||
twin.vertexA = vertex;
|
||||
|
||||
orig.loop.push(halfEdge1);
|
||||
twin.loop.push(halfEdge2);
|
||||
orig.loop.halfEdges.push(halfEdge1);
|
||||
twin.loop.halfEdges.push(halfEdge2);
|
||||
|
||||
halfEdge1.loop = orig.loop;
|
||||
halfEdge2.loop = twin.loop;
|
||||
|
|
@ -277,6 +289,8 @@ function Node(vertex, normal, splitsEdge) {
|
|||
this.vertex = vertex;
|
||||
this.normal = normal;
|
||||
this.point = vertex.point;
|
||||
this.edge = splitsEdge;
|
||||
__DEBUG__.AddPoint(this.point);
|
||||
}
|
||||
|
||||
class SolveData {
|
||||
|
|
@ -299,5 +313,5 @@ function addToListInMap(map, key, value) {
|
|||
list = [];
|
||||
map.set(key, list);
|
||||
}
|
||||
list.add(value);
|
||||
list.push(value);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,7 +50,13 @@ export class SceneSolid {
|
|||
face.normal = normal;
|
||||
face.materialIndex = gIdx ++;
|
||||
geom.faces.push(face);
|
||||
//face.color.set(new THREE.Color().setRGB( Math.random(), Math.random(), Math.random()));
|
||||
if (brepFace.debugName == 'base') {
|
||||
face.color.set(new THREE.Color().setHex( 0x000077 ));
|
||||
}
|
||||
if (brepFace.debugName == 'wall_3') {
|
||||
face.color.set(new THREE.Color().setHex( 0x007700 ));
|
||||
}
|
||||
|
||||
}
|
||||
//view.setFaceColor(polyFace, utils.isSmoothPiece(group.shared) ? 0xFF0000 : null);
|
||||
off = geom.vertices.length;
|
||||
|
|
|
|||
Loading…
Reference in a new issue