mirror of
https://github.com/xibyte/jsketcher
synced 2025-12-23 08:53:07 +01:00
BREP validator
This commit is contained in:
parent
15300e225a
commit
28d341735a
4 changed files with 160 additions and 6 deletions
|
|
@ -18,6 +18,7 @@ import '../../css/app3d.less'
|
|||
|
||||
import * as BREPPrimitives from '../brep/brep-primitives'
|
||||
import * as BREPBool from '../brep/operations/boolean'
|
||||
import {BREPValidator} from '../brep/brep-validator'
|
||||
import {SceneSolid} from '../brep/viz/scene-solid'
|
||||
|
||||
function App() {
|
||||
|
|
@ -82,6 +83,8 @@ App.prototype.BREPTestImpl = function() {
|
|||
const box1 = BREPPrimitives.box(500, 500, 500);
|
||||
const box2 = BREPPrimitives.box(500, 500, 500, new Matrix3().translate(250, 250, 250));
|
||||
|
||||
BREPValidator.validateToConsole(box1);
|
||||
|
||||
//box1.faces = [box1.faces[2]];
|
||||
//box2.faces = [box2.faces[5]];
|
||||
|
||||
|
|
|
|||
|
|
@ -17,18 +17,20 @@ export function createPrism(basePoints, height) {
|
|||
const lidNormal = normal.multiply(-1);
|
||||
const offVector = lidNormal.multiply(height);
|
||||
|
||||
const lidSegments = [];
|
||||
iterateSegments(basePoints.map(p => p.plus(offVector)), (a, b) => lidSegments.push({a, b}));
|
||||
const lidLoop = new Loop();
|
||||
//iterateSegments(basePoints.map(p => new Vertex(p.plus(offVector))), (a, b) => lidSegments.push({a, b}));
|
||||
const lidPoints = basePoints.map(p => p.plus(offVector)).reverse();
|
||||
const lidLoop = createPlaneLoop(lidPoints.map(p => new Vertex(p)));
|
||||
|
||||
const shell = new Shell();
|
||||
|
||||
const n = baseLoop.halfEdges.length;
|
||||
for (let i = 0; i < n; i++) {
|
||||
let lidIdx = n - 2 - i;
|
||||
if (lidIdx == -1) {
|
||||
lidIdx = n - 1;
|
||||
}
|
||||
const baseHalfEdge = baseLoop.halfEdges[i];
|
||||
const lidSegment = lidSegments[i];
|
||||
const lidHalfEdge = createHalfEdge(lidLoop, new Vertex(lidSegment.b), new Vertex(lidSegment.a));
|
||||
|
||||
const lidHalfEdge = lidLoop.halfEdges[lidIdx];
|
||||
const wallPolygon = [baseHalfEdge.vertexB, baseHalfEdge.vertexA, lidHalfEdge.vertexB, lidHalfEdge.vertexA];
|
||||
const wallLoop = createPlaneLoop(wallPolygon);
|
||||
|
||||
|
|
|
|||
146
web/app/brep/brep-validator.js
Normal file
146
web/app/brep/brep-validator.js
Normal file
|
|
@ -0,0 +1,146 @@
|
|||
import Vector from '../math/vector'
|
||||
import * as math from '../math/math'
|
||||
|
||||
export class BREPValidator {
|
||||
|
||||
constructor() {
|
||||
this.errors = [];
|
||||
}
|
||||
|
||||
validateShell(shell) {
|
||||
for (let face of shell.faces) {
|
||||
this.validateFace(face);
|
||||
}
|
||||
}
|
||||
|
||||
validateFace(face) {
|
||||
if (face !== face.outerLoop.face) {
|
||||
this.addError(new LoopRefersToWrongFace(face.outerLoop, face));
|
||||
}
|
||||
this.validateLoop(face.outerLoop);
|
||||
}
|
||||
|
||||
validateLoop(loop) {
|
||||
const halfEdges = loop.halfEdges;
|
||||
const n = halfEdges.length;
|
||||
if (n == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (let i = 0; i < n; i ++) {
|
||||
const j = (i + 1) % n;
|
||||
const curr = halfEdges[i];
|
||||
const next = halfEdges[j];
|
||||
if (curr.loop !== loop) {
|
||||
this.addError(new HalfEdgeRefersToWrongLoop(loop, curr));
|
||||
}
|
||||
if (curr.vertexB !== next.vertexA) {
|
||||
this.addError(new VerticesOfHalfEdgeArentConnected(curr, next));
|
||||
}
|
||||
if (curr.next != next) {
|
||||
this.addError(new HalfEdgeNextPointerIncorrect(curr, next));
|
||||
}
|
||||
if (next.prev != curr) {
|
||||
this.addError(new HalfEdgePrevPointerIncorrect(next, curr));
|
||||
}
|
||||
const twin = curr.twin();
|
||||
if (twin.vertexB != curr.vertexA) {
|
||||
this.addError(new TwinStartVertexIncorrect(curr, twin));
|
||||
}
|
||||
if (twin.vertexA != curr.vertexB) {
|
||||
this.addError(new TwinEndVertexIncorrect(curr, twin));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
addError(validationError) {
|
||||
this.errors.push(validationError);
|
||||
}
|
||||
}
|
||||
|
||||
BREPValidator.validateToConsole = function(shell) {
|
||||
const brepValidator = new BREPValidator();
|
||||
|
||||
brepValidator.validateShell(shell);
|
||||
for (let brepError of brepValidator.errors) {
|
||||
console.log(brepError.message());
|
||||
}
|
||||
};
|
||||
|
||||
class VerticesOfHalfEdgeArentConnected {
|
||||
constructor(loop, halfEdge1, halfEdge2) {
|
||||
this.loop = loop;
|
||||
this.halfEdge1 = halfEdge1;
|
||||
this.halfEdge2 = halfEdge2;
|
||||
}
|
||||
|
||||
message() {
|
||||
return 'starting point of the following half edge should identically the same as ending of a half edge';
|
||||
}
|
||||
}
|
||||
|
||||
class HalfEdgeRefersToWrongLoop {
|
||||
constructor(loop, face) {
|
||||
this.loop = loop;
|
||||
this.face = face;
|
||||
}
|
||||
|
||||
message() {
|
||||
return 'half edge refers to different loop it belongs to';
|
||||
}
|
||||
}
|
||||
|
||||
class LoopRefersToWrongFace {
|
||||
constructor(loop, halfEdge) {
|
||||
this.loop = loop;
|
||||
this.halfEdge = halfEdge;
|
||||
}
|
||||
|
||||
message() {
|
||||
return 'loop refers to different face it belongs to';
|
||||
}
|
||||
}
|
||||
|
||||
class HalfEdgeNextPointerIncorrect {
|
||||
constructor(halfEdge, nextHalfEdge) {
|
||||
this.halfEdge = halfEdge;
|
||||
this.nextHalfEdge = nextHalfEdge;
|
||||
}
|
||||
|
||||
message() {
|
||||
return "half edge's next pointer doesn't refer to real next half edge";
|
||||
}
|
||||
}
|
||||
|
||||
class HalfEdgePrevPointerIncorrect {
|
||||
constructor(halfEdge, prevHalfEdge) {
|
||||
this.halfEdge = halfEdge;
|
||||
this.prevHalfEdge = prevHalfEdge;
|
||||
}
|
||||
|
||||
message() {
|
||||
return "half edge's prev pointer doesn't refer to prior half edge";
|
||||
}
|
||||
}
|
||||
|
||||
class TwinStartVertexIncorrect {
|
||||
constructor(halfEdge, twin) {
|
||||
this.halfEdge = halfEdge;
|
||||
this.twin = twin;
|
||||
}
|
||||
|
||||
message() {
|
||||
return "a twin has incorrect start vertex, should be identical to the end vertex of the half edge";
|
||||
}
|
||||
}
|
||||
|
||||
class TwinEndVertexIncorrect {
|
||||
constructor(halfEdge, twin) {
|
||||
this.halfEdge = halfEdge;
|
||||
this.twin = twin;
|
||||
}
|
||||
|
||||
message() {
|
||||
return "a twin has incorrect end vertex, should be identical to the start vertex of the half edge";
|
||||
}
|
||||
}
|
||||
|
|
@ -30,6 +30,9 @@ export function union( shell1, shell2 ) {
|
|||
//if (shell2.faces.indexOf(face) != -1) {
|
||||
// continue;
|
||||
//}
|
||||
if (face.debugName == 'lid') {
|
||||
__DEBUG__.Clear();
|
||||
}
|
||||
const edges = face.outerLoop.halfEdges.concat(faceData.newEdges);
|
||||
//edges.forEach(e => __DEBUG__.AddLine(e.vertexA.point, e.vertexB.point));
|
||||
while (true) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue