mirror of
https://github.com/xibyte/jsketcher
synced 2025-12-06 08:25:19 +01:00
87 lines
3 KiB
JavaScript
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;
|
|
};
|