jsketcher/modules/brep/brep-validator.js
2022-08-15 23:47:20 -07:00

87 lines
3 KiB
JavaScript

export class BREPValidator {
constructor() {
this.errors = [];
}
validateShell(shell) {
for (const face of shell.faces) {
if (face.shell !== shell) {
this.addError('FACE_REFERS_TO_WRONG_SHELL', "face refers to a shell it doesn't belong to", {face, shell});
}
this.validateFace(face);
}
}
validateFace(face) {
for (const loop of [face.outerLoop, ...face.innerLoops]) {
if (face !== loop.face) {
this.addError('LOOP_REFERS_TO_WRONG_FACE', 'loop refers to different face it belongs to', {loop, face});
}
this.validateLoop(loop);
}
}
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('HALF_EDGE_REFERS_TO_WRONG_LOOP', 'half edge refers to different loop it belongs to', {loop, he:curr});
}
if (curr.vertexB !== next.vertexA) {
this.addError('VERTICES_OF_HALF_EDGE_NOT_CONNECTED', 'starting point of the following half edge should identically the same as ending of a half edge', {curr, next});
}
if (curr.next !== next) {
this.addError('HALF_EDGE_NEXT_POINTER_INCORRECT', "half edge's next pointer doesn't refer to real next half edge", {curr, next});
}
if (next.prev !== curr) {
this.addError('HALF_EDGE_PREV_POINTER_INCORRECT', "half edge's prev pointer doesn't refer to prior half edge", {next, curr});
}
if (!curr.edge) {
this.addError('EDGE_FOR_HALF_EDGE_NOT_SET', "half edge doesn't refer to an edge", {he:curr});
} else {
const twin = curr.twin();
if (curr.edge !== twin.edge) {
this.addError('EDGE_OF_TWIN_DIFFERENT', "edge of twin doesn't match to the half edge's edge", {he:curr, twin});
}
if (twin.vertexB !== curr.vertexA) {
this.addError('TWIN_START_VERTEX_INCORRECT', "a twin has incorrect start vertex, should be identical to the end vertex of the half edge", {he:curr, twin});
}
if (twin.vertexA !== curr.vertexB) {
this.addError('TWIN_END_VERTEX_INCORRECT', "a twin has incorrect end vertex, should be identical to the start vertex of the half edge", {he:curr, twin});
}
}
}
}
addError(code, message, validationError) {
Object.assign(validationError, {code, message});
this.errors.push(validationError);
}
}
BREPValidator.validateToConsole = function(shell) {
const brepValidator = new BREPValidator();
brepValidator.validateShell(shell);
for (const brepError of brepValidator.errors) {
console.warn(brepError.message);
}
if (brepValidator.errors.length === 0) {
console.log('BREP is Valid.');
}
};
BREPValidator.validate = function(shell) {
const validator = new BREPValidator();
validator.validateShell(shell);
return validator.errors;
};