All files / app/codeCharta/services/3DExports/3DPreview/CreateGeometryStrategies createSvgGeometryStrategy.ts

93.1% Statements 27/29
100% Branches 2/2
75% Functions 3/4
93.1% Lines 27/29

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 6511x 11x     11x             11x         28x 28x 28x 28x     26x 26x   26x 26x   26x 26x       26x       26x   26x 26x 26x 26x 26x   26x 26x 21x   5x 5x     26x                      
import { BufferGeometry, ExtrudeGeometry } from "three"
import { SVGLoader } from "three/examples/jsm/loaders/SVGLoader"
import { CreateGeometryStrategy, CreateGeometryStrategyOptions } from "./createGeometryStrategy"
import { GeometryOptions } from "../preview3DPrintMesh"
import * as BufferGeometryUtils from "three/examples/jsm/utils/BufferGeometryUtils.js"
 
export interface CreateSvgGeometryStrategyOptions extends CreateGeometryStrategyOptions {
    filePath: string
    size: number
    side: "front" | "back"
}
export class CreateSvgGeometryStrategy implements CreateGeometryStrategy {
    async create(
        geometryOptions: GeometryOptions,
        createSvgGeometryStrategyOptions: CreateSvgGeometryStrategyOptions
    ): Promise<BufferGeometry> {
        const filePath = createSvgGeometryStrategyOptions.filePath
        const loader = new SVGLoader()
        return new Promise((resolve, reject) => {
            loader.load(
                filePath,
                function (data) {
                    const paths = data.paths
                    const geometries: BufferGeometry[] = []
 
                    for (const path of paths) {
                        const shapes = path.toShapes(true)
 
                        for (const shape of shapes) {
                            const geometry = new ExtrudeGeometry(shape, {
                                depth: geometryOptions.printHeight,
                                bevelEnabled: false
                            })
                            geometries.push(geometry)
                        }
                    }
 
                    const mergedGeometry = BufferGeometryUtils.mergeGeometries(geometries)
 
                    mergedGeometry.computeBoundingBox()
                    const width = mergedGeometry.boundingBox.max.x - mergedGeometry.boundingBox.min.x
                    const depth = mergedGeometry.boundingBox.max.y - mergedGeometry.boundingBox.min.y
                    const scale = createSvgGeometryStrategyOptions.size / Math.max(width, depth)
                    mergedGeometry.scale(scale, scale, 1)
 
                    mergedGeometry.center()
                    if (createSvgGeometryStrategyOptions.side === "back") {
                        mergedGeometry.rotateZ(Math.PI)
                    } else {
                        mergedGeometry.rotateZ(Math.PI)
                        mergedGeometry.rotateY(Math.PI)
                    }
 
                    resolve(mergedGeometry)
                },
                undefined,
                function (error) {
                    console.error(`Error loading ${filePath}`)
                    reject(error)
                }
            )
        })
    }
}