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

96.96% Statements 64/66
77.77% Branches 14/18
100% Functions 5/5
98.38% Lines 61/62

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                        23x       23x 23x   23x   23x 23x         23x 23x 23x 23x 23x   23x 23x 23x     23x 13x 13x 13x 13x 13x 13x       23x       5x 5x 5x 25x 25x 25x 25x 25x 25x 25x 25x 25x     5x 2x 2x 2x 2x 2x 2x     5x 1x 1x     4x       12x 12x 65x 65x 65x 65x 65x 65x 65x 65x     12x 12x 12x 12x 12x     12x        
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 = 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;
    }
 
}