import * as Inputs from "../../api/inputs/inputs";
export class OperationsService {
    constructor(occ, enumService, entitiesService, converterService, booleansService, shapeGettersService, edgesService, transformsService, vecHelper, wiresService, facesService, shellsService) {
        this.occ = occ;
        this.enumService = enumService;
        this.entitiesService = entitiesService;
        this.converterService = converterService;
        this.booleansService = booleansService;
        this.shapeGettersService = shapeGettersService;
        this.edgesService = edgesService;
        this.transformsService = transformsService;
        this.vecHelper = vecHelper;
        this.wiresService = wiresService;
        this.facesService = facesService;
        this.shellsService = shellsService;
    }
    loftAdvanced(inputs) {
        if (inputs.periodic && !inputs.closed) {
            throw new Error("Cant construct periodic non closed loft.");
        }
        const pipe = new this.occ.BRepOffsetAPI_ThruSections(inputs.makeSolid, inputs.straight, inputs.tolerance);
        const wires = [];
        const vertices = [];
        if (inputs.startVertex) {
            const v = this.entitiesService.makeVertex(inputs.startVertex);
            pipe.AddVertex(v);
            vertices.push(v);
        }
        if (inputs.closed && !inputs.periodic) {
            inputs.shapes.push(inputs.shapes[0]);
        }
        else if (inputs.closed && inputs.periodic) {
            const pointsOnCrvs = [];
            inputs.shapes.forEach((s) => {
                if (this.enumService.getShapeTypeEnum(s) === Inputs.OCCT.shapeTypeEnum.edge) {
                    s = this.entitiesService.bRepBuilderAPIMakeWire(s);
                }
                const pts = this.wiresService.divideWireByParamsToPoints({ shape: s, nrOfDivisions: inputs.nrPeriodicSections, removeStartPoint: false, removeEndPoint: false });
                pointsOnCrvs.push(pts);
            });
            // <= needed due to start and end points that are added
            for (let i = 0; i <= inputs.nrPeriodicSections; i++) {
                const ptsForPerpWire = pointsOnCrvs.map(p => p[i]);
                const periodicWire = this.wiresService.interpolatePoints({ points: ptsForPerpWire, tolerance: inputs.tolerance, periodic: true });
                pipe.AddWire(periodicWire);
                wires.push(periodicWire);
            }
        }
        if (!inputs.periodic) {
            inputs.shapes.forEach((wire) => {
                pipe.AddWire(wire);
            });
        }
        const endVertices = [];
        if (inputs.endVertex) {
            const v = this.entitiesService.makeVertex(inputs.endVertex);
            pipe.AddVertex(v);
            endVertices.push(v);
        }
        if (inputs.useSmoothing) {
            pipe.SetSmoothing(inputs.useSmoothing);
        }
        if (inputs.maxUDegree) {
            pipe.SetMaxDegree(inputs.maxUDegree);
        }
        let parType = undefined;
        if (inputs.parType === Inputs.OCCT.approxParametrizationTypeEnum.approxChordLength) {
            parType = this.occ.Approx_ParametrizationType.Approx_ChordLength;
        }
        else if (inputs.parType === Inputs.OCCT.approxParametrizationTypeEnum.approxCentripetal) {
            parType = this.occ.Approx_ParametrizationType.Approx_Centripetal;
        }
        else if (inputs.parType === Inputs.OCCT.approxParametrizationTypeEnum.approxIsoParametric) {
            parType = this.occ.Approx_ParametrizationType.Approx_IsoParametric;
        }
        if (parType) {
            pipe.SetParType(parType);
        }
        pipe.CheckCompatibility(false);
        const pipeShape = pipe.Shape();
        const res = this.converterService.getActualTypeOfShape(pipeShape);
        pipeShape.delete();
        pipe.delete();
        wires.forEach(w => w.delete());
        vertices.forEach(v => v.delete());
        endVertices.forEach(v => v.delete());
        return res;
    }
    closestPointsBetweenTwoShapes(shape1, shape2) {
        const messageProgress = new this.occ.Message_ProgressRange_1();
        const extrema = new this.occ.BRepExtrema_DistShapeShape_2(shape1, shape2, this.occ.Extrema_ExtFlag.Extrema_ExtFlag_MIN, this.occ.Extrema_ExtAlgo.Extrema_ExtAlgo_Grad, messageProgress);
        const messageProgress1 = new this.occ.Message_ProgressRange_1();
        extrema.Perform(messageProgress1);
        if (extrema.IsDone() && extrema.NbSolution() > 0) {
            const closestPoint1 = extrema.PointOnShape1(1);
            const closestPoint2 = extrema.PointOnShape2(1);
            return [[closestPoint1.X(), closestPoint1.Y(), closestPoint1.Z()], [closestPoint2.X(), closestPoint2.Y(), closestPoint2.Z()]];
        }
        else {
            throw new Error("Closest points could not be found.");
        }
    }
    closestPointsOnShapeFromPoints(inputs) {
        const vertexes = inputs.points.map(p => this.entitiesService.makeVertex(p));
        const pointsOnShape = vertexes.map(v => this.closestPointsBetweenTwoShapes(v, inputs.shape));
        return pointsOnShape.map(p => p[1]);
    }
    closestPointsOnShapesFromPoints(inputs) {
        const vertexes = inputs.points.map(p => this.entitiesService.makeVertex(p));
        const result = [];
        inputs.shapes.forEach((s) => {
            const pointsOnShape = vertexes.map(v => this.closestPointsBetweenTwoShapes(v, s));
            result.push(...pointsOnShape.map(p => p[1]));
        });
        return result;
    }
    distancesToShapeFromPoints(inputs) {
        const vertexes = inputs.points.map(p => this.entitiesService.makeVertex(p));
        const pointsOnShape = vertexes.map(v => this.closestPointsBetweenTwoShapes(v, inputs.shape));
        return pointsOnShape.map(p => {
            return this.vecHelper.distanceBetweenPoints(p[0], p[1]);
        });
    }
    loft(inputs) {
        const pipe = new this.occ.BRepOffsetAPI_ThruSections(inputs.makeSolid, false, 1.0e-06);
        inputs.shapes.forEach((wire) => {
            if (this.enumService.getShapeTypeEnum(wire) === Inputs.OCCT.shapeTypeEnum.edge) {
                wire = this.entitiesService.bRepBuilderAPIMakeWire(wire);
            }
            pipe.AddWire(wire);
        });
        pipe.CheckCompatibility(false);
        const pipeShape = pipe.Shape();
        const res = this.converterService.getActualTypeOfShape(pipeShape);
        pipeShape.delete();
        pipe.delete();
        return res;
    }
    offset(inputs) {
        return this.offsetAdv({ shape: inputs.shape, face: inputs.face, distance: inputs.distance, tolerance: inputs.tolerance, joinType: Inputs.OCCT.joinTypeEnum.arc, removeIntEdges: false });
    }
    offsetAdv(inputs) {
        if (!inputs.tolerance) {
            inputs.tolerance = 0.1;
        }
        if (inputs.distance === 0.0) {
            return inputs.shape;
        }
        let offset;
        const joinType = this.getJoinType(inputs.joinType);
        // only this mode is implemented currently, so we cannot expose others...
        const brepOffsetMode = this.occ.BRepOffset_Mode.BRepOffset_Skin;
        const wires = [];
        if ((this.enumService.getShapeTypeEnum(inputs.shape) === Inputs.OCCT.shapeTypeEnum.wire ||
            this.enumService.getShapeTypeEnum(inputs.shape) === Inputs.OCCT.shapeTypeEnum.edge)) {
            let wire;
            if (this.enumService.getShapeTypeEnum(inputs.shape) === Inputs.OCCT.shapeTypeEnum.edge) {
                wire = this.entitiesService.bRepBuilderAPIMakeWire(inputs.shape);
                wires.push(wire);
            }
            else {
                wire = inputs.shape;
            }
            try {
                offset = new this.occ.BRepOffsetAPI_MakeOffset_1();
                if (inputs.face) {
                    offset.Init_1(inputs.face, joinType, false);
                }
                else {
                    offset.Init_2(joinType, false);
                }
                offset.AddWire(wire);
                const messageProgress1 = new this.occ.Message_ProgressRange_1();
                offset.Build(messageProgress1);
                offset.Perform(inputs.distance, 0.0);
            }
            catch (ex) {
                offset = new this.occ.BRepOffsetAPI_MakeOffsetShape();
                offset.PerformByJoin(wire, inputs.distance, inputs.tolerance, brepOffsetMode, false, false, joinType, inputs.removeIntEdges, new this.occ.Message_ProgressRange_1());
            }
        }
        else {
            const shapeToOffset = inputs.shape;
            offset = new this.occ.BRepOffsetAPI_MakeOffsetShape();
            offset.PerformByJoin(shapeToOffset, inputs.distance, inputs.tolerance, brepOffsetMode, false, false, joinType, inputs.removeIntEdges, new this.occ.Message_ProgressRange_1());
        }
        const offsetShape = offset.Shape();
        const result = this.converterService.getActualTypeOfShape(offsetShape);
        offsetShape.delete();
        if (offset) {
            offset.delete();
        }
        wires.forEach(w => w.delete());
        return result;
    }
    offset3DWire(inputs) {
        const extrusion = this.extrude({
            shape: inputs.shape,
            direction: inputs.direction,
        });
        const thickSolid = this.makeThickSolidSimple({
            shape: extrusion,
            offset: inputs.offset,
        });
        const nrOfEdges = this.shapeGettersService.getEdges({ shape: inputs.shape }).length;
        const predictedNrOfFaces = nrOfEdges * 4 + 2;
        const lastFaceIndex = predictedNrOfFaces / 2 - 1;
        const firstFaceIndex = lastFaceIndex - nrOfEdges + 1;
        const faceEdges = [];
        this.shapeGettersService.getFaces({ shape: thickSolid }).forEach((f, index) => {
            if (index >= firstFaceIndex && index <= lastFaceIndex) {
                const firstEdge = this.shapeGettersService.getEdges({ shape: f })[2];
                faceEdges.push(firstEdge);
            }
        });
        let result;
        try {
            result = this.converterService.combineEdgesAndWiresIntoAWire({ shapes: faceEdges });
            result = result.Reversed();
            result = this.converterService.getActualTypeOfShape(result);
        }
        catch (_a) {
            result = faceEdges;
            return result;
        }
        return result;
    }
    extrudeShapes(inputs) {
        return inputs.shapes.map(shape => {
            const extruded = this.extrude({ shape, direction: inputs.direction });
            const result = this.converterService.getActualTypeOfShape(extruded);
            extruded.delete();
            return result;
        });
    }
    extrude(inputs) {
        const gpVec = new this.occ.gp_Vec_4(inputs.direction[0], inputs.direction[1], inputs.direction[2]);
        const prismMaker = new this.occ.BRepPrimAPI_MakePrism_1(inputs.shape, gpVec, false, true);
        const prismShape = prismMaker.Shape();
        prismMaker.delete();
        gpVec.delete();
        return prismShape;
    }
    splitShapeWithShapes(inputs) {
        const listOfShapes = new this.occ.TopTools_ListOfShape_1();
        inputs.shapes.forEach(shape => {
            listOfShapes.Append_1(shape);
        });
        const shape = this.occ.BitByBitDev.BitSplit(inputs.shape, listOfShapes);
        return shape;
    }
    revolve(inputs) {
        if (!inputs.angle) {
            inputs.angle = 360.0;
        }
        if (!inputs.direction) {
            inputs.direction = [0, 0, 1];
        }
        let result;
        if (inputs.angle >= 360.0) {
            const pt1 = new this.occ.gp_Pnt_3(0, 0, 0);
            const dir = new this.occ.gp_Dir_4(inputs.direction[0], inputs.direction[1], inputs.direction[2]);
            const ax1 = new this.occ.gp_Ax1_2(pt1, dir);
            const makeRevol = new this.occ.BRepPrimAPI_MakeRevol_2(inputs.shape, ax1, inputs.copy);
            result = makeRevol.Shape();
            makeRevol.delete();
            pt1.delete();
            dir.delete();
            ax1.delete();
        }
        else {
            const pt1 = new this.occ.gp_Pnt_3(0, 0, 0);
            const dir = new this.occ.gp_Dir_4(inputs.direction[0], inputs.direction[1], inputs.direction[2]);
            const ax1 = new this.occ.gp_Ax1_2(pt1, dir);
            const makeRevol = new this.occ.BRepPrimAPI_MakeRevol_1(inputs.shape, ax1, inputs.angle * 0.0174533, inputs.copy);
            result = makeRevol.Shape();
            makeRevol.delete();
            pt1.delete();
            dir.delete();
            ax1.delete();
        }
        const actual = this.converterService.getActualTypeOfShape(result);
        result.delete();
        return actual;
    }
    rotatedExtrude(inputs) {
        const translatedShape = this.transformsService.translate({
            translation: [0, inputs.height, 0],
            shape: inputs.shape,
        });
        const upperPolygon = this.transformsService.rotate({
            axis: [0, 1, 0],
            angle: inputs.angle,
            shape: translatedShape
        });
        // Define the straight spine going up the middle of the sweep
        const spineWire = this.wiresService.createBSpline({
            points: [
                [0, 0, 0],
                [0, inputs.height, 0]
            ],
            closed: false,
        });
        // Define the guiding helical auxiliary spine (which controls the rotation)
        const steps = 30;
        const aspinePoints = [];
        for (let i = 0; i <= steps; i++) {
            const alpha = i / steps;
            aspinePoints.push([
                20 * Math.sin(alpha * inputs.angle * 0.0174533),
                inputs.height * alpha,
                20 * Math.cos(alpha * inputs.angle * 0.0174533),
            ]);
        }
        const aspineWire = this.wiresService.createBSpline({ points: aspinePoints, closed: false });
        // Sweep the face wires along the spine to create the extrusion
        const pipe = new this.occ.BRepOffsetAPI_MakePipeShell(spineWire);
        pipe.SetMode_5(aspineWire, true, this.occ.BRepFill_TypeOfContact.BRepFill_NoContact);
        pipe.Add_1(inputs.shape, false, false);
        pipe.Add_1(upperPolygon, false, false);
        pipe.Build(new this.occ.Message_ProgressRange_1());
        pipe.MakeSolid();
        const pipeShape = pipe.Shape();
        const result = this.converterService.getActualTypeOfShape(pipeShape);
        pipeShape.delete();
        pipe.delete();
        aspineWire.delete();
        spineWire.delete();
        upperPolygon.delete();
        translatedShape.delete();
        return result;
    }
    pipe(inputs) {
        const pipe = new this.occ.BRepOffsetAPI_MakePipeShell(inputs.shape);
        inputs.shapes.forEach(sh => {
            pipe.Add_1(sh, false, false);
        });
        pipe.Build(new this.occ.Message_ProgressRange_1());
        pipe.MakeSolid();
        const pipeShape = pipe.Shape();
        const result = this.converterService.getActualTypeOfShape(pipeShape);
        pipeShape.delete();
        pipe.delete();
        return result;
    }
    pipePolylineWireNGon(inputs) {
        const wire = inputs.shape;
        const shapesToPassThrough = [];
        const edges = this.shapeGettersService.getEdges({ shape: wire });
        edges.forEach((e, index) => {
            const edgeStartPt = this.edgesService.startPointOnEdge({ shape: e });
            const tangent = this.edgesService.tangentOnEdgeAtParam({ shape: e, param: 0 });
            let tangentPreviousEdgeEnd;
            let averageTangentVec = tangent;
            if (index > 0 && index < edges.length - 1) {
                const previousEdge = edges[index - 1];
                tangentPreviousEdgeEnd = this.edgesService.tangentOnEdgeAtParam({ shape: previousEdge, param: 1 });
                averageTangentVec = [tangent[0] + tangentPreviousEdgeEnd[0] / 2, tangent[1] + tangentPreviousEdgeEnd[1] / 2, tangent[2] + tangentPreviousEdgeEnd[2] / 2];
            }
            const ngon = this.wiresService.createNGonWire({ radius: inputs.radius, center: edgeStartPt, direction: averageTangentVec, nrCorners: inputs.nrCorners });
            shapesToPassThrough.push(ngon);
            if (index === edges.length - 1) {
                const edgeEndPt = this.edgesService.endPointOnEdge({ shape: e });
                const tangentEndPt = this.edgesService.tangentOnEdgeAtParam({ shape: e, param: 1 });
                const ngon = this.wiresService.createNGonWire({ radius: inputs.radius, center: edgeEndPt, direction: tangentEndPt, nrCorners: inputs.nrCorners });
                shapesToPassThrough.push(ngon);
            }
        });
        const pipe = new this.occ.BRepOffsetAPI_MakePipeShell(wire);
        shapesToPassThrough.forEach(s => {
            pipe.Add_1(s, false, false);
        });
        pipe.Build(new this.occ.Message_ProgressRange_1());
        pipe.MakeSolid();
        const pipeShape = pipe.Shape();
        const result = this.converterService.getActualTypeOfShape(pipeShape);
        pipeShape.delete();
        pipe.delete();
        return result;
    }
    pipeWireCylindrical(inputs) {
        const wire = inputs.shape;
        const shapesToPassThrough = [];
        const edges = this.shapeGettersService.getEdges({ shape: wire });
        edges.forEach((e, index) => {
            const edgeStartPt = this.edgesService.startPointOnEdge({ shape: e });
            const tangent = this.edgesService.tangentOnEdgeAtParam({ shape: e, param: 0 });
            let tangentPreviousEdgeEnd;
            let averageTangentVec = tangent;
            if (index > 0 && index < edges.length - 1) {
                const previousEdge = edges[index - 1];
                tangentPreviousEdgeEnd = this.edgesService.tangentOnEdgeAtParam({ shape: previousEdge, param: 1 });
                averageTangentVec = [tangent[0] + tangentPreviousEdgeEnd[0] / 2, tangent[1] + tangentPreviousEdgeEnd[1] / 2, tangent[2] + tangentPreviousEdgeEnd[2] / 2];
            }
            const circle = this.entitiesService.createCircle(inputs.radius, edgeStartPt, averageTangentVec, Inputs.OCCT.typeSpecificityEnum.wire);
            shapesToPassThrough.push(circle);
            if (index === edges.length - 1) {
                const edgeEndPt = this.edgesService.endPointOnEdge({ shape: e });
                const tangentEndPt = this.edgesService.tangentOnEdgeAtParam({ shape: e, param: 1 });
                const line = this.entitiesService.createCircle(inputs.radius, edgeEndPt, tangentEndPt, Inputs.OCCT.typeSpecificityEnum.wire);
                shapesToPassThrough.push(line);
            }
        });
        const pipe = new this.occ.BRepOffsetAPI_MakePipeShell(wire);
        shapesToPassThrough.forEach(s => {
            pipe.Add_1(s, false, false);
        });
        pipe.Build(new this.occ.Message_ProgressRange_1());
        pipe.MakeSolid();
        const pipeShape = pipe.Shape();
        const result = this.converterService.getActualTypeOfShape(pipeShape);
        pipeShape.delete();
        pipe.delete();
        return result;
    }
    pipeWiresCylindrical(inputs) {
        return inputs.shapes.map(wire => {
            return this.pipeWireCylindrical({ shape: wire, radius: inputs.radius });
        });
    }
    makeThickSolidSimple(inputs) {
        const maker = new this.occ.BRepOffsetAPI_MakeThickSolid();
        maker.MakeThickSolidBySimple(inputs.shape, inputs.offset);
        maker.Build(new this.occ.Message_ProgressRange_1());
        const makerShape = maker.Shape();
        const result = this.converterService.getActualTypeOfShape(makerShape);
        let res2 = result;
        if (inputs.offset > 0) {
            const faces = this.shapeGettersService.getFaces({ shape: result });
            const revFaces = faces.map(face => face.Reversed());
            res2 = this.shellsService.sewFaces({ shapes: revFaces, tolerance: 1e-7 });
            result.delete();
        }
        maker.delete();
        makerShape.delete();
        return res2;
    }
    makeThickSolidByJoin(inputs) {
        const facesToRemove = new this.occ.TopTools_ListOfShape_1();
        inputs.shapes.forEach(shape => {
            facesToRemove.Append_1(shape);
        });
        const myBody = new this.occ.BRepOffsetAPI_MakeThickSolid();
        const jointType = this.getJoinType(inputs.joinType);
        myBody.MakeThickSolidByJoin(inputs.shape, facesToRemove, inputs.offset, inputs.tolerance, this.occ.BRepOffset_Mode.BRepOffset_Skin, // currently a single option
        inputs.intersection, inputs.selfIntersection, jointType, inputs.removeIntEdges, new this.occ.Message_ProgressRange_1());
        const makeThick = myBody.Shape();
        const result = this.converterService.getActualTypeOfShape(makeThick);
        makeThick.delete();
        myBody.delete();
        facesToRemove.delete();
        return result;
    }
    getJoinType(jointType) {
        let res;
        switch (jointType) {
            case Inputs.OCCT.joinTypeEnum.arc: {
                res = this.occ.GeomAbs_JoinType.GeomAbs_Arc;
                break;
            }
            case Inputs.OCCT.joinTypeEnum.intersection: {
                res = this.occ.GeomAbs_JoinType.GeomAbs_Intersection;
                break;
            }
            case Inputs.OCCT.joinTypeEnum.tangent: {
                res = this.occ.GeomAbs_JoinType.GeomAbs_Tangent;
                break;
            }
        }
        return res;
    }
    getBRepOffsetMode(offsetMode) {
        let res;
        switch (offsetMode) {
            case Inputs.OCCT.bRepOffsetModeEnum.skin: {
                res = this.occ.BRepOffset_Mode.BRepOffset_Skin;
                break;
            }
            case Inputs.OCCT.bRepOffsetModeEnum.pipe: {
                res = this.occ.BRepOffset_Mode.BRepOffset_Pipe;
                break;
            }
            case Inputs.OCCT.bRepOffsetModeEnum.rectoVerso: {
                res = this.occ.BRepOffset_Mode.BRepOffset_RectoVerso;
                break;
            }
        }
        return res;
    }
    slice(inputs) {
        if (inputs.step <= 0) {
            throw new Error("Step needs to be positive.");
        }
        const { bbox, transformedShape } = this.createBBoxAndTransformShape(inputs.shape, inputs.direction);
        const intersections = [];
        if (!bbox.IsThin(0.0001)) {
            const { minY, maxY, maxDist } = this.computeBounds(bbox);
            const planes = [];
            for (let i = minY; i < maxY; i += inputs.step) {
                const pq = this.facesService.createSquareFace({ size: maxDist, center: [0, i, 0], direction: [0, 1, 0] });
                planes.push(pq);
            }
            this.applySlices(transformedShape, planes, inputs.direction, intersections);
        }
        const res = this.converterService.makeCompound({ shapes: intersections });
        return res;
    }
    sliceInStepPattern(inputs) {
        if (!inputs.steps || inputs.steps.length === 0) {
            throw new Error("Steps must be provided with at elast one positive value");
        }
        const { bbox, transformedShape } = this.createBBoxAndTransformShape(inputs.shape, inputs.direction);
        const intersections = [];
        if (!bbox.IsThin(0.0001)) {
            const { minY, maxY, maxDist } = this.computeBounds(bbox);
            const planes = [];
            let index = 0;
            for (let i = minY; i < maxY; i += inputs.steps[index]) {
                const pq = this.facesService.createSquareFace({ size: maxDist, center: [0, i, 0], direction: [0, 1, 0] });
                planes.push(pq);
                if (inputs.steps[index + 1] === undefined) {
                    index = 0;
                }
                else {
                    index++;
                }
            }
            this.applySlices(transformedShape, planes, inputs.direction, intersections);
        }
        const res = this.converterService.makeCompound({ shapes: intersections });
        return res;
    }
    createBBoxAndTransformShape(shape, direction) {
        // we orient the given shape to the reverse direction of sections so that slicing
        // would always happen in flat bbox aligned orientation
        // after algorithm computes, we turn all intersections to original shape so that it would match a given shape.
        // const fromDir
        const transformedShape = this.transformsService.align({
            shape,
            fromOrigin: [0, 0, 0],
            fromDirection: direction,
            toOrigin: [0, 0, 0],
            toDirection: [0, 1, 0],
        });
        const bbox = new this.occ.Bnd_Box_1();
        this.occ.BRepBndLib.Add(transformedShape, bbox, false);
        return { bbox, transformedShape };
    }
    computeBounds(bbox) {
        const cornerMin = bbox.CornerMin();
        const cornerMax = bbox.CornerMax();
        const minY = cornerMin.Y();
        const maxY = cornerMax.Y();
        const minX = cornerMin.X();
        const maxX = cornerMax.X();
        const minZ = cornerMin.Z();
        const maxZ = cornerMax.Z();
        const distX = maxX - minX;
        const distZ = maxZ - minZ;
        const percentage = 1.2;
        let maxDist = distX >= distZ ? distX : distZ;
        maxDist *= percentage;
        return { minY, maxY, maxDist };
    }
    applySlices(transformedShape, planes, direction, intersections) {
        const shapesToSlice = [];
        if (this.enumService.getShapeTypeEnum(transformedShape) === Inputs.OCCT.shapeTypeEnum.solid) {
            shapesToSlice.push(transformedShape);
        }
        else {
            const solids = this.shapeGettersService.getSolids({ shape: transformedShape });
            shapesToSlice.push(...solids);
        }
        if (shapesToSlice.length === 0) {
            throw new Error("No solids found to slice.");
        }
        shapesToSlice.forEach(s => {
            const intInputs = new Inputs.OCCT.IntersectionDto();
            intInputs.keepEdges = true;
            intInputs.shapes = [s];
            const compound = this.converterService.makeCompound({ shapes: planes });
            intInputs.shapes.push(compound);
            const ints = this.booleansService.intersection(intInputs);
            ints.forEach(int => {
                if (int && !int.IsNull()) {
                    const transformedInt = this.transformsService.align({
                        shape: int,
                        fromOrigin: [0, 0, 0],
                        fromDirection: [0, 1, 0],
                        toOrigin: [0, 0, 0],
                        toDirection: direction,
                    });
                    intersections.push(transformedInt);
                }
            });
        });
    }
}
