All files / lib/services/base booleans.service.ts

97.01% Statements 65/67
77.77% Branches 14/18
100% Functions 5/5
98.41% Lines 62/63

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109                        11x       11x 11x   11x   11x 11x         11x 11x 11x 11x 11x   11x 11x 11x     11x 1x 1x 1x 1x 1x 1x       11x       17x 17x 17x 159x 159x 159x 159x 159x 159x 159x 159x 159x     17x 2x 2x 2x 2x 2x 2x     17x 1x 1x 1x     16x       8x 8x 57x 57x 57x 57x 57x 57x 57x 57x     8x 8x 8x 8x 8x     8x        
import { OpenCascadeInstance, TopoDS_Shape } from "../../../bitbybit-dev-occt/bitbybit-dev-occt";
import * as Inputs from "../../api/inputs/inputs";
import { ShapeGettersService } from "./shape-getters";
 
export class BooleansService {
 
    constructor(
        private readonly occ: OpenCascadeInstance,
        private readonly shapeGettersService: ShapeGettersService
    ) { }
 
    intersection(inputs: Inputs.OCCT.IntersectionDto<TopoDS_Shape>): TopoDS_Shape[] {
        Iif (inputs.shapes.length < 2) {
            throw (new Error("Intersection requires 2 or more shapes to be given"));
        }
 
        const intersectShape = inputs.shapes[0];
        let intersectionResults: TopoDS_Shape[] = [];
 
        for (let i = 1; i < inputs.shapes.length; i++) {
            let intersectionResult: TopoDS_Shape;
            const messageProgress = new this.occ.Message_ProgressRange_1();
            const intersectedCommon = new this.occ.BRepAlgoAPI_Common_3(
                intersectShape,
                inputs.shapes[i],
                messageProgress
            );
            const messageProgress2 = new this.occ.Message_ProgressRange_1();
            Eif (intersectedCommon.HasGenerated()) {
                intersectedCommon.Build(messageProgress2);
                intersectionResult = intersectedCommon.Shape();
                intersectionResults.push(intersectionResult);
            }
            messageProgress.delete();
            intersectedCommon.delete();
            messageProgress2.delete();
        }
 
        if (!inputs.keepEdges && intersectionResults.length > 0) {
            intersectionResults = intersectionResults.map(i => {
                const fusor = new this.occ.ShapeUpgrade_UnifySameDomain_2(i, true, true, false);
                fusor.Build();
                const fusedShape = fusor.Shape();
                fusor.delete();
                return fusedShape;
            });
        }
 
        return intersectionResults;
    }
 
    difference(inputs: Inputs.OCCT.DifferenceDto<TopoDS_Shape>): TopoDS_Shape {
        let difference = inputs.shape;
        const objectsToSubtract = inputs.shapes;
        for (let i = 0; i < objectsToSubtract.length; i++) {
            Iif (!objectsToSubtract[i] || objectsToSubtract[i].IsNull()) { console.error("Tool in Difference is null!"); }
            const messageProgress1 = new this.occ.Message_ProgressRange_1();
            const differenceCut = new this.occ.BRepAlgoAPI_Cut_3(difference, objectsToSubtract[i], messageProgress1);
            const messageProgress2 = new this.occ.Message_ProgressRange_1();
            differenceCut.Build(messageProgress2);
            difference = differenceCut.Shape();
            messageProgress1.delete();
            messageProgress2.delete();
            differenceCut.delete();
        }
 
        if (!inputs.keepEdges) {
            const fusor = new this.occ.ShapeUpgrade_UnifySameDomain_2(difference, true, true, false);
            fusor.Build();
            const fusedShape = fusor.Shape();
            difference.delete();
            difference = fusedShape;
            fusor.delete();
        }
 
        if (this.shapeGettersService.getNumSolidsInCompound(difference) === 1) {
            const solid = this.shapeGettersService.getSolidFromCompound(difference, 0);
            difference.delete();
            difference = solid;
        }
 
        return difference;
    }
 
    union(inputs: Inputs.OCCT.UnionDto<TopoDS_Shape>): TopoDS_Shape {
        let combined = inputs.shapes[0];
        for (let i = 0; i < inputs.shapes.length; i++) {
            const messageProgress1 = new this.occ.Message_ProgressRange_1();
            const combinedFuse = new this.occ.BRepAlgoAPI_Fuse_3(combined, inputs.shapes[i], messageProgress1);
            const messageProgress2 = new this.occ.Message_ProgressRange_1();
            combinedFuse.Build(messageProgress2);
            combined = combinedFuse.Shape();
            messageProgress1.delete();
            messageProgress2.delete();
            combinedFuse.delete();
        }
 
        Eif (!inputs.keepEdges) {
            const fusor = new this.occ.ShapeUpgrade_UnifySameDomain_2(combined, true, true, false);
            fusor.Build();
            combined = fusor.Shape();
            fusor.delete();
        }
 
        return combined;
    }
 
}