@linkiez/dxf-renew 5.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintignore +17 -0
- package/.eslintrc.json +61 -0
- package/.gitattributes +4 -0
- package/.github/instructions/project-en_US.instructions.md +352 -0
- package/.github/workflows/release.yml +110 -0
- package/.husky/commit-msg +4 -0
- package/.husky/pre-commit +1 -0
- package/.prettierignore +1 -0
- package/.prettierrc.json +6 -0
- package/.releaserc.json +76 -0
- package/.travis.yml +6 -0
- package/.yarn/install-state.gz +0 -0
- package/.yarnrc.yml +1 -0
- package/CHANGELOG.md +134 -0
- package/CONTRIBUTING.md +271 -0
- package/LICENSE +21 -0
- package/PLAN.md +517 -0
- package/README.md +306 -0
- package/build.mjs +66 -0
- package/commitlint.config.js +25 -0
- package/dist/dxf.js +7234 -0
- package/docs/CODE_PATTERNS.md +182 -0
- package/docs/DIMENSION_SUMMARY.md +248 -0
- package/docs/DIMENSION_SUMMARY.pt-BR.md +248 -0
- package/docs/IMPLEMENTED-2D-ENTITIES.md +54 -0
- package/docs/IMPLEMENTED-2D-ENTITIES.pt-BR.md +54 -0
- package/docs/TEXT-MTEXT-DIMENSION-SUPPORT.md +241 -0
- package/docs/TEXT-MTEXT-DIMENSION-SUPPORT.pt-BR.md +169 -0
- package/docs/autocad_2012_pdf_dxf-reference_enu.md +8272 -0
- package/examples/dxf.html +36 -0
- package/examples/example.es5.js +30 -0
- package/examples/example.es6.js +30 -0
- package/examples/text-dimension-viewer.html +133 -0
- package/lib/Helper.cjs +89 -0
- package/lib/Helper.cjs.map +7 -0
- package/lib/Helper.js +59 -0
- package/lib/Helper.js.map +7 -0
- package/lib/applyTransforms.cjs +59 -0
- package/lib/applyTransforms.cjs.map +7 -0
- package/lib/applyTransforms.js +39 -0
- package/lib/applyTransforms.js.map +7 -0
- package/lib/cli.cjs +53 -0
- package/lib/cli.cjs.map +7 -0
- package/lib/cli.js +29 -0
- package/lib/cli.js.map +7 -0
- package/lib/config.cjs +30 -0
- package/lib/config.cjs.map +7 -0
- package/lib/config.js +10 -0
- package/lib/config.js.map +7 -0
- package/lib/constants.cjs +39 -0
- package/lib/constants.cjs.map +7 -0
- package/lib/constants.js +15 -0
- package/lib/constants.js.map +7 -0
- package/lib/denormalise.cjs +148 -0
- package/lib/denormalise.cjs.map +7 -0
- package/lib/denormalise.js +118 -0
- package/lib/denormalise.js.map +7 -0
- package/lib/dimensionToSVG.cjs +307 -0
- package/lib/dimensionToSVG.cjs.map +7 -0
- package/lib/dimensionToSVG.js +273 -0
- package/lib/dimensionToSVG.js.map +7 -0
- package/lib/entityToPolyline.cjs +248 -0
- package/lib/entityToPolyline.cjs.map +7 -0
- package/lib/entityToPolyline.js +213 -0
- package/lib/entityToPolyline.js.map +7 -0
- package/lib/getRGBForEntity.cjs +53 -0
- package/lib/getRGBForEntity.cjs.map +7 -0
- package/lib/getRGBForEntity.js +23 -0
- package/lib/getRGBForEntity.js.map +7 -0
- package/lib/groupEntitiesByLayer.cjs +34 -0
- package/lib/groupEntitiesByLayer.cjs.map +7 -0
- package/lib/groupEntitiesByLayer.js +14 -0
- package/lib/groupEntitiesByLayer.js.map +7 -0
- package/lib/handlers/blocks.cjs +93 -0
- package/lib/handlers/blocks.cjs.map +7 -0
- package/lib/handlers/blocks.js +63 -0
- package/lib/handlers/blocks.js.map +7 -0
- package/lib/handlers/entities.cjs +118 -0
- package/lib/handlers/entities.cjs.map +7 -0
- package/lib/handlers/entities.js +88 -0
- package/lib/handlers/entities.js.map +7 -0
- package/lib/handlers/entity/arc.cjs +82 -0
- package/lib/handlers/entity/arc.cjs.map +7 -0
- package/lib/handlers/entity/arc.js +47 -0
- package/lib/handlers/entity/arc.js.map +7 -0
- package/lib/handlers/entity/attdef.cjs +318 -0
- package/lib/handlers/entity/attdef.cjs.map +7 -0
- package/lib/handlers/entity/attdef.js +282 -0
- package/lib/handlers/entity/attdef.js.map +7 -0
- package/lib/handlers/entity/attrib.cjs +52 -0
- package/lib/handlers/entity/attrib.cjs.map +7 -0
- package/lib/handlers/entity/attrib.js +27 -0
- package/lib/handlers/entity/attrib.js.map +7 -0
- package/lib/handlers/entity/circle.cjs +73 -0
- package/lib/handlers/entity/circle.cjs.map +7 -0
- package/lib/handlers/entity/circle.js +38 -0
- package/lib/handlers/entity/circle.js.map +7 -0
- package/lib/handlers/entity/common.cjs +83 -0
- package/lib/handlers/entity/common.cjs.map +7 -0
- package/lib/handlers/entity/common.js +63 -0
- package/lib/handlers/entity/common.js.map +7 -0
- package/lib/handlers/entity/dimension.cjs +203 -0
- package/lib/handlers/entity/dimension.cjs.map +7 -0
- package/lib/handlers/entity/dimension.js +168 -0
- package/lib/handlers/entity/dimension.js.map +7 -0
- package/lib/handlers/entity/ellipse.cjs +88 -0
- package/lib/handlers/entity/ellipse.cjs.map +7 -0
- package/lib/handlers/entity/ellipse.js +53 -0
- package/lib/handlers/entity/ellipse.js.map +7 -0
- package/lib/handlers/entity/hatch.cjs +470 -0
- package/lib/handlers/entity/hatch.cjs.map +7 -0
- package/lib/handlers/entity/hatch.js +435 -0
- package/lib/handlers/entity/hatch.js.map +7 -0
- package/lib/handlers/entity/insert.cjs +106 -0
- package/lib/handlers/entity/insert.cjs.map +7 -0
- package/lib/handlers/entity/insert.js +71 -0
- package/lib/handlers/entity/insert.js.map +7 -0
- package/lib/handlers/entity/line.cjs +84 -0
- package/lib/handlers/entity/line.cjs.map +7 -0
- package/lib/handlers/entity/line.js +49 -0
- package/lib/handlers/entity/line.js.map +7 -0
- package/lib/handlers/entity/lwpolyline.cjs +82 -0
- package/lib/handlers/entity/lwpolyline.cjs.map +7 -0
- package/lib/handlers/entity/lwpolyline.js +47 -0
- package/lib/handlers/entity/lwpolyline.js.map +7 -0
- package/lib/handlers/entity/mtext.cjs +121 -0
- package/lib/handlers/entity/mtext.cjs.map +7 -0
- package/lib/handlers/entity/mtext.js +85 -0
- package/lib/handlers/entity/mtext.js.map +7 -0
- package/lib/handlers/entity/ole2Frame.cjs +98 -0
- package/lib/handlers/entity/ole2Frame.cjs.map +7 -0
- package/lib/handlers/entity/ole2Frame.js +63 -0
- package/lib/handlers/entity/ole2Frame.js.map +7 -0
- package/lib/handlers/entity/point.cjs +73 -0
- package/lib/handlers/entity/point.cjs.map +7 -0
- package/lib/handlers/entity/point.js +38 -0
- package/lib/handlers/entity/point.js.map +7 -0
- package/lib/handlers/entity/polyline.cjs +70 -0
- package/lib/handlers/entity/polyline.cjs.map +7 -0
- package/lib/handlers/entity/polyline.js +35 -0
- package/lib/handlers/entity/polyline.js.map +7 -0
- package/lib/handlers/entity/solid.cjs +101 -0
- package/lib/handlers/entity/solid.cjs.map +7 -0
- package/lib/handlers/entity/solid.js +66 -0
- package/lib/handlers/entity/solid.js.map +7 -0
- package/lib/handlers/entity/spline.cjs +109 -0
- package/lib/handlers/entity/spline.cjs.map +7 -0
- package/lib/handlers/entity/spline.js +74 -0
- package/lib/handlers/entity/spline.js.map +7 -0
- package/lib/handlers/entity/text.cjs +85 -0
- package/lib/handlers/entity/text.cjs.map +7 -0
- package/lib/handlers/entity/text.js +49 -0
- package/lib/handlers/entity/text.js.map +7 -0
- package/lib/handlers/entity/threeDFace.cjs +98 -0
- package/lib/handlers/entity/threeDFace.cjs.map +7 -0
- package/lib/handlers/entity/threeDFace.js +63 -0
- package/lib/handlers/entity/threeDFace.js.map +7 -0
- package/lib/handlers/entity/vertex.cjs +78 -0
- package/lib/handlers/entity/vertex.cjs.map +7 -0
- package/lib/handlers/entity/vertex.js +53 -0
- package/lib/handlers/entity/vertex.js.map +7 -0
- package/lib/handlers/entity/viewport.cjs +153 -0
- package/lib/handlers/entity/viewport.cjs.map +7 -0
- package/lib/handlers/entity/viewport.js +118 -0
- package/lib/handlers/entity/viewport.js.map +7 -0
- package/lib/handlers/header.cjs +92 -0
- package/lib/handlers/header.cjs.map +7 -0
- package/lib/handlers/header.js +72 -0
- package/lib/handlers/header.js.map +7 -0
- package/lib/handlers/objects.cjs +170 -0
- package/lib/handlers/objects.cjs.map +7 -0
- package/lib/handlers/objects.js +150 -0
- package/lib/handlers/objects.js.map +7 -0
- package/lib/handlers/tables.cjs +587 -0
- package/lib/handlers/tables.cjs.map +7 -0
- package/lib/handlers/tables.js +557 -0
- package/lib/handlers/tables.js.map +7 -0
- package/lib/index.cjs +60 -0
- package/lib/index.cjs.map +7 -0
- package/lib/index.js +19 -0
- package/lib/index.js.map +7 -0
- package/lib/parseString.cjs +118 -0
- package/lib/parseString.cjs.map +7 -0
- package/lib/parseString.js +88 -0
- package/lib/parseString.js.map +7 -0
- package/lib/toPolylines.cjs +69 -0
- package/lib/toPolylines.cjs.map +7 -0
- package/lib/toPolylines.js +39 -0
- package/lib/toPolylines.js.map +7 -0
- package/lib/toSVG.cjs +395 -0
- package/lib/toSVG.cjs.map +7 -0
- package/lib/toSVG.js +361 -0
- package/lib/toSVG.js.map +7 -0
- package/lib/types/arc-entity.cjs +17 -0
- package/lib/types/arc-entity.cjs.map +7 -0
- package/lib/types/arc-entity.js +1 -0
- package/lib/types/arc-entity.js.map +7 -0
- package/lib/types/base-entity.cjs +17 -0
- package/lib/types/base-entity.cjs.map +7 -0
- package/lib/types/base-entity.js +1 -0
- package/lib/types/base-entity.js.map +7 -0
- package/lib/types/circle-entity.cjs +17 -0
- package/lib/types/circle-entity.cjs.map +7 -0
- package/lib/types/circle-entity.js +1 -0
- package/lib/types/circle-entity.js.map +7 -0
- package/lib/types/common.cjs +17 -0
- package/lib/types/common.cjs.map +7 -0
- package/lib/types/common.js +1 -0
- package/lib/types/common.js.map +7 -0
- package/lib/types/dimension-entity.cjs +17 -0
- package/lib/types/dimension-entity.cjs.map +7 -0
- package/lib/types/dimension-entity.js +1 -0
- package/lib/types/dimension-entity.js.map +7 -0
- package/lib/types/dxf.cjs +17 -0
- package/lib/types/dxf.cjs.map +7 -0
- package/lib/types/dxf.js +1 -0
- package/lib/types/dxf.js.map +7 -0
- package/lib/types/ellipse-entity.cjs +17 -0
- package/lib/types/ellipse-entity.cjs.map +7 -0
- package/lib/types/ellipse-entity.js +1 -0
- package/lib/types/ellipse-entity.js.map +7 -0
- package/lib/types/entity.cjs +17 -0
- package/lib/types/entity.cjs.map +7 -0
- package/lib/types/entity.js +1 -0
- package/lib/types/entity.js.map +7 -0
- package/lib/types/handler-internal.cjs +17 -0
- package/lib/types/handler-internal.cjs.map +7 -0
- package/lib/types/handler-internal.js +1 -0
- package/lib/types/handler-internal.js.map +7 -0
- package/lib/types/handler.cjs +17 -0
- package/lib/types/handler.cjs.map +7 -0
- package/lib/types/handler.js +1 -0
- package/lib/types/handler.js.map +7 -0
- package/lib/types/hatch-entity.cjs +17 -0
- package/lib/types/hatch-entity.cjs.map +7 -0
- package/lib/types/hatch-entity.js +1 -0
- package/lib/types/hatch-entity.js.map +7 -0
- package/lib/types/helper.cjs +17 -0
- package/lib/types/helper.cjs.map +7 -0
- package/lib/types/helper.js +1 -0
- package/lib/types/helper.js.map +7 -0
- package/lib/types/index.cjs +77 -0
- package/lib/types/index.cjs.map +7 -0
- package/lib/types/index.js +29 -0
- package/lib/types/index.js.map +7 -0
- package/lib/types/insert-entity.cjs +17 -0
- package/lib/types/insert-entity.cjs.map +7 -0
- package/lib/types/insert-entity.js +1 -0
- package/lib/types/insert-entity.js.map +7 -0
- package/lib/types/layer-groups.cjs +17 -0
- package/lib/types/layer-groups.cjs.map +7 -0
- package/lib/types/layer-groups.js +1 -0
- package/lib/types/layer-groups.js.map +7 -0
- package/lib/types/line-entity.cjs +17 -0
- package/lib/types/line-entity.cjs.map +7 -0
- package/lib/types/line-entity.js +1 -0
- package/lib/types/line-entity.js.map +7 -0
- package/lib/types/mtext-entity.cjs +17 -0
- package/lib/types/mtext-entity.cjs.map +7 -0
- package/lib/types/mtext-entity.js +1 -0
- package/lib/types/mtext-entity.js.map +7 -0
- package/lib/types/ole2frame-entity.cjs +17 -0
- package/lib/types/ole2frame-entity.cjs.map +7 -0
- package/lib/types/ole2frame-entity.js +1 -0
- package/lib/types/ole2frame-entity.js.map +7 -0
- package/lib/types/options.cjs +17 -0
- package/lib/types/options.cjs.map +7 -0
- package/lib/types/options.js +1 -0
- package/lib/types/options.js.map +7 -0
- package/lib/types/point-entity.cjs +17 -0
- package/lib/types/point-entity.cjs.map +7 -0
- package/lib/types/point-entity.js +1 -0
- package/lib/types/point-entity.js.map +7 -0
- package/lib/types/polyline-entity.cjs +17 -0
- package/lib/types/polyline-entity.cjs.map +7 -0
- package/lib/types/polyline-entity.js +1 -0
- package/lib/types/polyline-entity.js.map +7 -0
- package/lib/types/polylines.cjs +17 -0
- package/lib/types/polylines.cjs.map +7 -0
- package/lib/types/polylines.js +1 -0
- package/lib/types/polylines.js.map +7 -0
- package/lib/types/solid-entity.cjs +17 -0
- package/lib/types/solid-entity.cjs.map +7 -0
- package/lib/types/solid-entity.js +1 -0
- package/lib/types/solid-entity.js.map +7 -0
- package/lib/types/spline-entity.cjs +17 -0
- package/lib/types/spline-entity.cjs.map +7 -0
- package/lib/types/spline-entity.js +1 -0
- package/lib/types/spline-entity.js.map +7 -0
- package/lib/types/svg.cjs +17 -0
- package/lib/types/svg.cjs.map +7 -0
- package/lib/types/svg.js +1 -0
- package/lib/types/svg.js.map +7 -0
- package/lib/types/tables.cjs +17 -0
- package/lib/types/tables.cjs.map +7 -0
- package/lib/types/tables.js +1 -0
- package/lib/types/tables.js.map +7 -0
- package/lib/types/text-entity.cjs +17 -0
- package/lib/types/text-entity.cjs.map +7 -0
- package/lib/types/text-entity.js +1 -0
- package/lib/types/text-entity.js.map +7 -0
- package/lib/types/util-types.cjs +17 -0
- package/lib/types/util-types.cjs.map +7 -0
- package/lib/types/util-types.js +1 -0
- package/lib/types/util-types.js.map +7 -0
- package/lib/types/vecks.d.cjs +2 -0
- package/lib/types/vecks.d.cjs.map +7 -0
- package/lib/types/vecks.d.js +1 -0
- package/lib/types/vecks.d.js.map +7 -0
- package/lib/types/viewport-entity.cjs +17 -0
- package/lib/types/viewport-entity.cjs.map +7 -0
- package/lib/types/viewport-entity.js +1 -0
- package/lib/types/viewport-entity.js.map +7 -0
- package/lib/types.cjs +23 -0
- package/lib/types.cjs.map +7 -0
- package/lib/types.js +2 -0
- package/lib/types.js.map +7 -0
- package/lib/util/bSpline.cjs +95 -0
- package/lib/util/bSpline.cjs.map +7 -0
- package/lib/util/bSpline.js +65 -0
- package/lib/util/bSpline.js.map +7 -0
- package/lib/util/colors.cjs +283 -0
- package/lib/util/colors.cjs.map +7 -0
- package/lib/util/colors.js +263 -0
- package/lib/util/colors.js.map +7 -0
- package/lib/util/createArcForLWPolyline.cjs +84 -0
- package/lib/util/createArcForLWPolyline.cjs.map +7 -0
- package/lib/util/createArcForLWPolyline.js +64 -0
- package/lib/util/createArcForLWPolyline.js.map +7 -0
- package/lib/util/dxfColorToRGB.cjs +115 -0
- package/lib/util/dxfColorToRGB.cjs.map +7 -0
- package/lib/util/dxfColorToRGB.js +90 -0
- package/lib/util/dxfColorToRGB.js.map +7 -0
- package/lib/util/insertKnot.cjs +77 -0
- package/lib/util/insertKnot.cjs.map +7 -0
- package/lib/util/insertKnot.js +57 -0
- package/lib/util/insertKnot.js.map +7 -0
- package/lib/util/logger.cjs +53 -0
- package/lib/util/logger.cjs.map +7 -0
- package/lib/util/logger.js +23 -0
- package/lib/util/logger.js.map +7 -0
- package/lib/util/rgbToColorAttribute.cjs +32 -0
- package/lib/util/rgbToColorAttribute.cjs.map +7 -0
- package/lib/util/rgbToColorAttribute.js +12 -0
- package/lib/util/rgbToColorAttribute.js.map +7 -0
- package/lib/util/rotate.cjs +30 -0
- package/lib/util/rotate.cjs.map +7 -0
- package/lib/util/rotate.js +10 -0
- package/lib/util/rotate.js.map +7 -0
- package/lib/util/round10.cjs +38 -0
- package/lib/util/round10.cjs.map +7 -0
- package/lib/util/round10.js +18 -0
- package/lib/util/round10.js.map +7 -0
- package/lib/util/toPiecewiseBezier.cjs +90 -0
- package/lib/util/toPiecewiseBezier.cjs.map +7 -0
- package/lib/util/toPiecewiseBezier.js +54 -0
- package/lib/util/toPiecewiseBezier.js.map +7 -0
- package/lib/util/transformBoundingBoxAndElement.cjs +80 -0
- package/lib/util/transformBoundingBoxAndElement.cjs.map +7 -0
- package/lib/util/transformBoundingBoxAndElement.js +60 -0
- package/lib/util/transformBoundingBoxAndElement.js.map +7 -0
- package/package.json +127 -0
- package/src/Helper.ts +71 -0
- package/src/applyTransforms.ts +54 -0
- package/src/cli.ts +41 -0
- package/src/config.ts +10 -0
- package/src/constants.ts +14 -0
- package/src/denormalise.ts +153 -0
- package/src/dimensionToSVG.ts +427 -0
- package/src/entityToPolyline.ts +338 -0
- package/src/getRGBForEntity.ts +28 -0
- package/src/groupEntitiesByLayer.ts +14 -0
- package/src/handlers/blocks.ts +65 -0
- package/src/handlers/entities.ts +111 -0
- package/src/handlers/entity/arc.ts +61 -0
- package/src/handlers/entity/attdef.ts +284 -0
- package/src/handlers/entity/attrib.ts +29 -0
- package/src/handlers/entity/circle.ts +47 -0
- package/src/handlers/entity/common.ts +79 -0
- package/src/handlers/entity/dimension.ts +217 -0
- package/src/handlers/entity/ellipse.ts +55 -0
- package/src/handlers/entity/hatch.ts +471 -0
- package/src/handlers/entity/insert.ts +73 -0
- package/src/handlers/entity/line.ts +56 -0
- package/src/handlers/entity/lwpolyline.ts +54 -0
- package/src/handlers/entity/mtext.ts +150 -0
- package/src/handlers/entity/ole2Frame.ts +64 -0
- package/src/handlers/entity/point.ts +47 -0
- package/src/handlers/entity/polyline.ts +49 -0
- package/src/handlers/entity/solid.ts +73 -0
- package/src/handlers/entity/spline.ts +103 -0
- package/src/handlers/entity/text.ts +83 -0
- package/src/handlers/entity/threeDFace.ts +69 -0
- package/src/handlers/entity/vertex.ts +55 -0
- package/src/handlers/entity/viewport.ts +119 -0
- package/src/handlers/header.ts +73 -0
- package/src/handlers/objects.ts +152 -0
- package/src/handlers/tables.ts +581 -0
- package/src/index.ts +19 -0
- package/src/parseString.ts +97 -0
- package/src/toPolylines.ts +47 -0
- package/src/toSVG.ts +518 -0
- package/src/types/README.md +91 -0
- package/src/types/arc-entity.ts +10 -0
- package/src/types/base-entity.ts +25 -0
- package/src/types/circle-entity.ts +8 -0
- package/src/types/common.ts +37 -0
- package/src/types/dimension-entity.ts +23 -0
- package/src/types/dxf.ts +64 -0
- package/src/types/ellipse-entity.ts +13 -0
- package/src/types/entity.ts +32 -0
- package/src/types/handler-internal.ts +51 -0
- package/src/types/handler.ts +10 -0
- package/src/types/hatch-entity.ts +127 -0
- package/src/types/helper.ts +12 -0
- package/src/types/index.ts +53 -0
- package/src/types/insert-entity.ts +19 -0
- package/src/types/layer-groups.ts +8 -0
- package/src/types/line-entity.ts +10 -0
- package/src/types/mtext-entity.ts +35 -0
- package/src/types/ole2frame-entity.ts +35 -0
- package/src/types/options.ts +17 -0
- package/src/types/point-entity.ts +7 -0
- package/src/types/polyline-entity.ts +20 -0
- package/src/types/polylines.ts +22 -0
- package/src/types/solid-entity.ts +9 -0
- package/src/types/spline-entity.ts +12 -0
- package/src/types/svg.ts +31 -0
- package/src/types/tables.ts +414 -0
- package/src/types/text-entity.ts +23 -0
- package/src/types/util-types.ts +27 -0
- package/src/types/vecks.d.ts +29 -0
- package/src/types/viewport-entity.ts +81 -0
- package/src/types.ts +5 -0
- package/src/util/bSpline.ts +97 -0
- package/src/util/colors.ts +266 -0
- package/src/util/createArcForLWPolyline.ts +93 -0
- package/src/util/diagram.png +0 -0
- package/src/util/dxfColorToRGB.ts +106 -0
- package/src/util/insertKnot.ts +69 -0
- package/src/util/logger.ts +23 -0
- package/src/util/rgbToColorAttribute.ts +14 -0
- package/src/util/rotate.ts +14 -0
- package/src/util/round10.ts +24 -0
- package/src/util/toPiecewiseBezier.ts +70 -0
- package/src/util/transformBoundingBoxAndElement.ts +74 -0
- package/tsconfig.json +34 -0
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { Box2 } from 'vecks'
|
|
2
|
+
|
|
3
|
+
import applyTransforms from './applyTransforms'
|
|
4
|
+
import denormalise from './denormalise'
|
|
5
|
+
import entityToPolyline from './entityToPolyline'
|
|
6
|
+
import colors from './util/colors'
|
|
7
|
+
import logger from './util/logger'
|
|
8
|
+
|
|
9
|
+
import type { Entity, ParsedDXF } from './types'
|
|
10
|
+
import type { Polyline, PolylineResult } from './types/polylines'
|
|
11
|
+
|
|
12
|
+
export default function toPolylines(parsed: ParsedDXF): PolylineResult {
|
|
13
|
+
const entities = denormalise(parsed)
|
|
14
|
+
const polylines: Polyline[] = entities.map((entity: Entity) => {
|
|
15
|
+
const layer = entity.layer ?? '0'
|
|
16
|
+
const layerTable = parsed.tables.layers[layer]
|
|
17
|
+
let colorNumber = 0
|
|
18
|
+
if ('colorNumber' in entity && typeof entity.colorNumber === 'number') {
|
|
19
|
+
colorNumber = entity.colorNumber
|
|
20
|
+
} else if (
|
|
21
|
+
layerTable &&
|
|
22
|
+
typeof layerTable.colorNumber === 'number'
|
|
23
|
+
) {
|
|
24
|
+
colorNumber = layerTable.colorNumber
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (colors[colorNumber] === undefined) {
|
|
28
|
+
logger.warn('Color index', colorNumber, 'invalid, defaulting to black')
|
|
29
|
+
colorNumber = 0
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return {
|
|
33
|
+
rgb: colors[colorNumber],
|
|
34
|
+
layer: layerTable,
|
|
35
|
+
vertices: applyTransforms(entityToPolyline(entity as any), entity.transforms),
|
|
36
|
+
}
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
const bbox = new Box2()
|
|
40
|
+
for (const polyline of polylines) {
|
|
41
|
+
for (const vertex of polyline.vertices) {
|
|
42
|
+
bbox.expandByPoint({ x: vertex[0], y: vertex[1] })
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return { bbox, polylines }
|
|
47
|
+
}
|
package/src/toSVG.ts
ADDED
|
@@ -0,0 +1,518 @@
|
|
|
1
|
+
import { Box2 } from 'vecks'
|
|
2
|
+
|
|
3
|
+
import denormalise from './denormalise'
|
|
4
|
+
import dimensionToSVG from './dimensionToSVG'
|
|
5
|
+
import entityToPolyline from './entityToPolyline'
|
|
6
|
+
import getRGBForEntity from './getRGBForEntity'
|
|
7
|
+
import logger from './util/logger'
|
|
8
|
+
import rgbToColorAttribute from './util/rgbToColorAttribute'
|
|
9
|
+
import rotate from './util/rotate'
|
|
10
|
+
import toPiecewiseBezier, { multiplicity } from './util/toPiecewiseBezier'
|
|
11
|
+
import transformBoundingBoxAndElement from './util/transformBoundingBoxAndElement'
|
|
12
|
+
|
|
13
|
+
import type {
|
|
14
|
+
ArcEntity,
|
|
15
|
+
CircleEntity,
|
|
16
|
+
DimensionEntity,
|
|
17
|
+
EllipseEntity,
|
|
18
|
+
Entity,
|
|
19
|
+
MTextEntity,
|
|
20
|
+
ParsedDXF,
|
|
21
|
+
SplineEntity,
|
|
22
|
+
TextEntity,
|
|
23
|
+
} from './types'
|
|
24
|
+
import type { BoundsAndElement } from './types/svg'
|
|
25
|
+
|
|
26
|
+
const addFlipXIfApplicable = (
|
|
27
|
+
entity: Entity,
|
|
28
|
+
{ bbox, element }: BoundsAndElement,
|
|
29
|
+
): BoundsAndElement => {
|
|
30
|
+
if (entity.extrusionZ === -1) {
|
|
31
|
+
return {
|
|
32
|
+
bbox: new Box2()
|
|
33
|
+
.expandByPoint({ x: -bbox.min.x, y: bbox.min.y })
|
|
34
|
+
.expandByPoint({ x: -bbox.max.x, y: bbox.max.y }),
|
|
35
|
+
element: `<g transform="matrix(-1 0 0 1 0 0)">
|
|
36
|
+
${element}
|
|
37
|
+
</g>`,
|
|
38
|
+
}
|
|
39
|
+
} else {
|
|
40
|
+
return { bbox, element }
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Create a <path /> element. Interpolates curved entities.
|
|
46
|
+
*/
|
|
47
|
+
const polyline = (entity: Entity): BoundsAndElement => {
|
|
48
|
+
const vertices = entityToPolyline(entity as any)
|
|
49
|
+
const bbox = vertices.reduce(
|
|
50
|
+
(acc, [x, y]) => acc.expandByPoint({ x, y }),
|
|
51
|
+
new Box2(),
|
|
52
|
+
)
|
|
53
|
+
const d = vertices.reduce((acc, point, i) => {
|
|
54
|
+
acc += i === 0 ? 'M' : 'L'
|
|
55
|
+
acc += point[0] + ',' + point[1]
|
|
56
|
+
return acc
|
|
57
|
+
}, '')
|
|
58
|
+
// Empirically it appears that flipping horizontally does not apply to polyline
|
|
59
|
+
return transformBoundingBoxAndElement(
|
|
60
|
+
bbox,
|
|
61
|
+
`<path d="${d}" />`,
|
|
62
|
+
entity.transforms ?? [],
|
|
63
|
+
)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Create a <path /> element. Interpolates curved entities.
|
|
68
|
+
* lwpolyline is the same as polyline but addFlipXIfApplicable does apply
|
|
69
|
+
*/
|
|
70
|
+
const lwpolyline = (entity: Entity): BoundsAndElement => {
|
|
71
|
+
const vertices = entityToPolyline(entity as any)
|
|
72
|
+
const bbox0 = vertices.reduce(
|
|
73
|
+
(acc, [x, y]) => acc.expandByPoint({ x, y }),
|
|
74
|
+
new Box2(),
|
|
75
|
+
)
|
|
76
|
+
const d = vertices.reduce((acc, point, i) => {
|
|
77
|
+
acc += i === 0 ? 'M' : 'L'
|
|
78
|
+
acc += point[0] + ',' + point[1]
|
|
79
|
+
return acc
|
|
80
|
+
}, '')
|
|
81
|
+
const element0 = `<path d="${d}" />`
|
|
82
|
+
const { bbox, element } = addFlipXIfApplicable(entity, {
|
|
83
|
+
bbox: bbox0,
|
|
84
|
+
element: element0,
|
|
85
|
+
})
|
|
86
|
+
return transformBoundingBoxAndElement(
|
|
87
|
+
bbox,
|
|
88
|
+
element,
|
|
89
|
+
entity.transforms ?? [],
|
|
90
|
+
)
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Create a <circle /> element for the CIRCLE entity.
|
|
96
|
+
*/
|
|
97
|
+
const circle = (entity: CircleEntity): BoundsAndElement => {
|
|
98
|
+
const bbox0 = new Box2()
|
|
99
|
+
.expandByPoint({
|
|
100
|
+
x: entity.x + entity.r,
|
|
101
|
+
y: entity.y + entity.r,
|
|
102
|
+
})
|
|
103
|
+
.expandByPoint({
|
|
104
|
+
x: entity.x - entity.r,
|
|
105
|
+
y: entity.y - entity.r,
|
|
106
|
+
})
|
|
107
|
+
const element0 = `<circle cx="${entity.x}" cy="${entity.y}" r="${entity.r}" />`
|
|
108
|
+
const { bbox, element } = addFlipXIfApplicable(entity, {
|
|
109
|
+
bbox: bbox0,
|
|
110
|
+
element: element0,
|
|
111
|
+
})
|
|
112
|
+
return transformBoundingBoxAndElement(bbox, element, entity.transforms ?? [])
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
interface EllipticArcParams {
|
|
116
|
+
cx: number
|
|
117
|
+
cy: number
|
|
118
|
+
majorX: number
|
|
119
|
+
majorY: number
|
|
120
|
+
axisRatio: number
|
|
121
|
+
startAngle: number
|
|
122
|
+
endAngle: number
|
|
123
|
+
flipX?: boolean
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Create a a <path d="A..." /> or <ellipse /> element for the ARC or ELLIPSE
|
|
128
|
+
* DXF entity (<ellipse /> if start and end point are the same).
|
|
129
|
+
*/
|
|
130
|
+
const ellipseOrArc = (params: EllipticArcParams): BoundsAndElement => {
|
|
131
|
+
const { cx, cy, majorX, majorY, axisRatio, startAngle, endAngle } = params
|
|
132
|
+
const rx = Math.hypot(majorX, majorY)
|
|
133
|
+
const ry = axisRatio * rx
|
|
134
|
+
const rotationAngle = -Math.atan2(-majorY, majorX)
|
|
135
|
+
|
|
136
|
+
const bbox = bboxEllipseOrArc(params)
|
|
137
|
+
|
|
138
|
+
if (
|
|
139
|
+
Math.abs(startAngle - endAngle) < 1e-9 ||
|
|
140
|
+
Math.abs(startAngle - endAngle + Math.PI * 2) < 1e-9
|
|
141
|
+
) {
|
|
142
|
+
// Use a native <ellipse> when start and end angles are the same, and
|
|
143
|
+
// arc paths with same start and end points don't render (at least on Safari)
|
|
144
|
+
const element = `<g transform="rotate(${
|
|
145
|
+
(rotationAngle / Math.PI) * 180
|
|
146
|
+
} ${cx}, ${cy})">
|
|
147
|
+
<ellipse cx="${cx}" cy="${cy}" rx="${rx}" ry="${ry}" />
|
|
148
|
+
</g>`
|
|
149
|
+
return { bbox, element }
|
|
150
|
+
} else {
|
|
151
|
+
const startOffset = rotate(
|
|
152
|
+
{
|
|
153
|
+
x: Math.cos(startAngle) * rx,
|
|
154
|
+
y: Math.sin(startAngle) * ry,
|
|
155
|
+
},
|
|
156
|
+
rotationAngle,
|
|
157
|
+
)
|
|
158
|
+
const startPoint = {
|
|
159
|
+
x: cx + startOffset.x,
|
|
160
|
+
y: cy + startOffset.y,
|
|
161
|
+
}
|
|
162
|
+
const endOffset = rotate(
|
|
163
|
+
{
|
|
164
|
+
x: Math.cos(endAngle) * rx,
|
|
165
|
+
y: Math.sin(endAngle) * ry,
|
|
166
|
+
},
|
|
167
|
+
rotationAngle,
|
|
168
|
+
)
|
|
169
|
+
const endPoint = {
|
|
170
|
+
x: cx + endOffset.x,
|
|
171
|
+
y: cy + endOffset.y,
|
|
172
|
+
}
|
|
173
|
+
const adjustedEndAngle =
|
|
174
|
+
endAngle < startAngle ? endAngle + Math.PI * 2 : endAngle
|
|
175
|
+
const largeArcFlag = adjustedEndAngle - startAngle < Math.PI ? 0 : 1
|
|
176
|
+
const d = `M ${startPoint.x} ${startPoint.y} A ${rx} ${ry} ${
|
|
177
|
+
(rotationAngle / Math.PI) * 180
|
|
178
|
+
} ${largeArcFlag} 1 ${endPoint.x} ${endPoint.y}`
|
|
179
|
+
const element = `<path d="${d}" />`
|
|
180
|
+
return { bbox, element }
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Compute the bounding box of an elliptical arc, given the DXF entity parameters
|
|
186
|
+
*/
|
|
187
|
+
|
|
188
|
+
const bboxEllipseOrArc = (params: EllipticArcParams): Box2 => {
|
|
189
|
+
const { cx, cy, majorX, majorY, axisRatio } = params
|
|
190
|
+
let { startAngle, endAngle } = params
|
|
191
|
+
|
|
192
|
+
// The bounding box will be defined by the starting point of the ellipse, and ending point,
|
|
193
|
+
// and any extrema on the ellipse that are between startAngle and endAngle.
|
|
194
|
+
// The extrema are found by setting either the x or y component of the ellipse's
|
|
195
|
+
// tangent vector to zero and solving for the angle.
|
|
196
|
+
|
|
197
|
+
// Ensure start and end angles are > 0 and well-ordered
|
|
198
|
+
while (startAngle < 0) startAngle += Math.PI * 2
|
|
199
|
+
while (endAngle <= startAngle) endAngle += Math.PI * 2
|
|
200
|
+
|
|
201
|
+
// When rotated, the extrema of the ellipse will be found at these angles
|
|
202
|
+
const angles = []
|
|
203
|
+
|
|
204
|
+
if (Math.abs(majorX) < 1e-12 || Math.abs(majorY) < 1e-12) {
|
|
205
|
+
// Special case for majorX or majorY = 0
|
|
206
|
+
for (let i = 0; i < 4; i++) {
|
|
207
|
+
angles.push((i / 2) * Math.PI)
|
|
208
|
+
}
|
|
209
|
+
} else {
|
|
210
|
+
// reference https://github.com/bjnortier/dxf/issues/47#issuecomment-545915042
|
|
211
|
+
angles[0] = Math.atan((-majorY * axisRatio) / majorX) - Math.PI // Ensure angles < 0
|
|
212
|
+
angles[1] = Math.atan((majorX * axisRatio) / majorY) - Math.PI
|
|
213
|
+
angles[2] = angles[0] - Math.PI
|
|
214
|
+
angles[3] = angles[1] - Math.PI
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// Remove angles not falling between start and end
|
|
218
|
+
for (let i = 4; i >= 0; i--) {
|
|
219
|
+
while (angles[i] < startAngle) angles[i] += Math.PI * 2
|
|
220
|
+
if (angles[i] > endAngle) {
|
|
221
|
+
angles.splice(i, 1)
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// Also to consider are the starting and ending points:
|
|
226
|
+
angles.push(startAngle, endAngle)
|
|
227
|
+
|
|
228
|
+
// Compute points lying on the unit circle at these angles
|
|
229
|
+
const pts = angles.map((a) => ({
|
|
230
|
+
x: Math.cos(a),
|
|
231
|
+
y: Math.sin(a),
|
|
232
|
+
}))
|
|
233
|
+
|
|
234
|
+
// Transformation matrix, formed by the major and minor axes
|
|
235
|
+
const M = [
|
|
236
|
+
[majorX, -majorY * axisRatio],
|
|
237
|
+
[majorY, majorX * axisRatio],
|
|
238
|
+
]
|
|
239
|
+
|
|
240
|
+
// Rotate, scale, and translate points
|
|
241
|
+
const rotatedPts = pts.map((p) => ({
|
|
242
|
+
x: p.x * M[0][0] + p.y * M[0][1] + cx,
|
|
243
|
+
y: p.x * M[1][0] + p.y * M[1][1] + cy,
|
|
244
|
+
}))
|
|
245
|
+
|
|
246
|
+
// Compute extents of bounding box
|
|
247
|
+
const bbox = rotatedPts.reduce((acc, p) => {
|
|
248
|
+
acc.expandByPoint(p)
|
|
249
|
+
return acc
|
|
250
|
+
}, new Box2())
|
|
251
|
+
|
|
252
|
+
return bbox
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* An ELLIPSE is defined by the major axis, convert to X and Y radius with
|
|
257
|
+
* a rotation angle
|
|
258
|
+
*/
|
|
259
|
+
const ellipse = (entity: EllipseEntity): BoundsAndElement => {
|
|
260
|
+
const { bbox: bbox0, element: element0 } = ellipseOrArc({
|
|
261
|
+
cx: entity.x,
|
|
262
|
+
cy: entity.y,
|
|
263
|
+
majorX: entity.majorX,
|
|
264
|
+
majorY: entity.majorY,
|
|
265
|
+
axisRatio: entity.axisRatio,
|
|
266
|
+
startAngle: entity.startAngle,
|
|
267
|
+
endAngle: entity.endAngle,
|
|
268
|
+
})
|
|
269
|
+
const { bbox, element } = addFlipXIfApplicable(entity, {
|
|
270
|
+
bbox: bbox0,
|
|
271
|
+
element: element0,
|
|
272
|
+
})
|
|
273
|
+
return transformBoundingBoxAndElement(bbox, element, entity.transforms ?? [])
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* An ARC is an ellipse with equal radii
|
|
278
|
+
*/
|
|
279
|
+
const arc = (entity: ArcEntity): BoundsAndElement => {
|
|
280
|
+
const { bbox: bbox0, element: element0 } = ellipseOrArc({
|
|
281
|
+
cx: entity.x,
|
|
282
|
+
cy: entity.y,
|
|
283
|
+
majorX: entity.r,
|
|
284
|
+
majorY: 0,
|
|
285
|
+
axisRatio: 1,
|
|
286
|
+
startAngle: entity.startAngle,
|
|
287
|
+
endAngle: entity.endAngle,
|
|
288
|
+
flipX: entity.extrusionZ === -1,
|
|
289
|
+
})
|
|
290
|
+
const { bbox, element } = addFlipXIfApplicable(entity, {
|
|
291
|
+
bbox: bbox0,
|
|
292
|
+
element: element0,
|
|
293
|
+
})
|
|
294
|
+
return transformBoundingBoxAndElement(bbox, element, entity.transforms ?? [])
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* Create a <text /> element for TEXT entity
|
|
299
|
+
*/
|
|
300
|
+
const text = (entity: TextEntity): BoundsAndElement => {
|
|
301
|
+
const x = entity.x ?? 0
|
|
302
|
+
const y = entity.y ?? 0
|
|
303
|
+
const height = entity.textHeight ?? 1
|
|
304
|
+
const rotation = entity.rotation ?? 0
|
|
305
|
+
const content = entity.string ?? ''
|
|
306
|
+
|
|
307
|
+
// Estimate text bounding box (approximate)
|
|
308
|
+
const textWidth = content.length * height * 0.6
|
|
309
|
+
const bbox0 = new Box2()
|
|
310
|
+
.expandByPoint({ x, y })
|
|
311
|
+
.expandByPoint({ x: x + textWidth, y: y + height })
|
|
312
|
+
|
|
313
|
+
const rotationDegrees = (rotation * 180) / Math.PI
|
|
314
|
+
const element0 = `<text x="${x}" y="${y}" font-size="${height}" transform="rotate(${-rotationDegrees} ${x} ${y}) scale(1,-1) translate(0 ${-2 * y})">${content}</text>`
|
|
315
|
+
|
|
316
|
+
const { bbox, element } = addFlipXIfApplicable(entity, {
|
|
317
|
+
bbox: bbox0,
|
|
318
|
+
element: element0,
|
|
319
|
+
})
|
|
320
|
+
return transformBoundingBoxAndElement(bbox, element, entity.transforms ?? [])
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
/**
|
|
324
|
+
* Create a <text /> element for MTEXT entity
|
|
325
|
+
*/
|
|
326
|
+
const mtext = (entity: MTextEntity): BoundsAndElement => {
|
|
327
|
+
const x = entity.x ?? 0
|
|
328
|
+
const y = entity.y ?? 0
|
|
329
|
+
const height = entity.nominalTextHeight ?? entity.textHeight ?? 1
|
|
330
|
+
const content = entity.string ?? ''
|
|
331
|
+
|
|
332
|
+
// Estimate text bounding box (approximate)
|
|
333
|
+
const textWidth = (entity.refRectangleWidth ?? content.length * height * 0.6)
|
|
334
|
+
const bbox0 = new Box2()
|
|
335
|
+
.expandByPoint({ x, y })
|
|
336
|
+
.expandByPoint({ x: x + textWidth, y: y + height })
|
|
337
|
+
|
|
338
|
+
// Calculate rotation from x-axis direction
|
|
339
|
+
const rotation = entity.xAxisX !== undefined && entity.xAxisY !== undefined
|
|
340
|
+
? Math.atan2(entity.xAxisY, entity.xAxisX)
|
|
341
|
+
: 0
|
|
342
|
+
const rotationDegrees = (rotation * 180) / Math.PI
|
|
343
|
+
|
|
344
|
+
const element0 = `<text x="${x}" y="${y}" font-size="${height}" transform="rotate(${-rotationDegrees} ${x} ${y}) scale(1,-1) translate(0 ${-2 * y})">${content}</text>`
|
|
345
|
+
|
|
346
|
+
const { bbox, element } = addFlipXIfApplicable(entity, {
|
|
347
|
+
bbox: bbox0,
|
|
348
|
+
element: element0,
|
|
349
|
+
})
|
|
350
|
+
return transformBoundingBoxAndElement(bbox, element, entity.transforms ?? [])
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
/**
|
|
354
|
+
* Create dimension visualization with DIMSTYLE support
|
|
355
|
+
*/
|
|
356
|
+
const dimension = (
|
|
357
|
+
entity: DimensionEntity,
|
|
358
|
+
dimStyle?: any,
|
|
359
|
+
): BoundsAndElement => {
|
|
360
|
+
const result = dimensionToSVG(entity, dimStyle)
|
|
361
|
+
return transformBoundingBoxAndElement(
|
|
362
|
+
result.bbox,
|
|
363
|
+
result.element,
|
|
364
|
+
entity.transforms ?? [],
|
|
365
|
+
)
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
export const piecewiseToPaths = (
|
|
369
|
+
k: number,
|
|
370
|
+
knots: number[],
|
|
371
|
+
controlPoints: Array<{ x: number; y: number }>,
|
|
372
|
+
): string[] => {
|
|
373
|
+
const paths: string[] = []
|
|
374
|
+
let controlPointIndex = 0
|
|
375
|
+
let knotIndex = k
|
|
376
|
+
while (knotIndex < knots.length - k + 1) {
|
|
377
|
+
const m = multiplicity(knots, knotIndex)
|
|
378
|
+
const cp = controlPoints.slice(controlPointIndex, controlPointIndex + k)
|
|
379
|
+
if (k === 4) {
|
|
380
|
+
paths.push(
|
|
381
|
+
`<path d="M ${cp[0].x} ${cp[0].y} C ${cp[1].x} ${cp[1].y} ${cp[2].x} ${cp[2].y} ${cp[3].x} ${cp[3].y}" />`,
|
|
382
|
+
)
|
|
383
|
+
} else if (k === 3) {
|
|
384
|
+
paths.push(
|
|
385
|
+
`<path d="M ${cp[0].x} ${cp[0].y} Q ${cp[1].x} ${cp[1].y} ${cp[2].x} ${cp[2].y}" />`,
|
|
386
|
+
)
|
|
387
|
+
}
|
|
388
|
+
controlPointIndex += m
|
|
389
|
+
knotIndex += m
|
|
390
|
+
}
|
|
391
|
+
return paths
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
const bezier = (entity: SplineEntity): BoundsAndElement => {
|
|
395
|
+
let bbox = new Box2()
|
|
396
|
+
for (const p of entity.controlPoints) {
|
|
397
|
+
bbox = bbox.expandByPoint(p)
|
|
398
|
+
}
|
|
399
|
+
const k = entity.degree + 1
|
|
400
|
+
const piecewise = toPiecewiseBezier(k, entity.controlPoints, entity.knots)
|
|
401
|
+
const paths = piecewiseToPaths(k, piecewise.knots, piecewise.controlPoints)
|
|
402
|
+
const element = `<g>${paths.join('')}</g>`
|
|
403
|
+
return transformBoundingBoxAndElement(bbox, element, entity.transforms ?? [])
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
/**
|
|
407
|
+
* Switch the appropriate function on entity type. CIRCLE, ARC and ELLIPSE
|
|
408
|
+
* produce native SVG elements, the rest produce interpolated polylines.
|
|
409
|
+
*/
|
|
410
|
+
const entityToBoundsAndElement = (
|
|
411
|
+
entity: Entity,
|
|
412
|
+
dimStyles?: { [name: string]: any },
|
|
413
|
+
): BoundsAndElement | null => {
|
|
414
|
+
switch (entity.type) {
|
|
415
|
+
case 'CIRCLE':
|
|
416
|
+
return circle(entity as CircleEntity)
|
|
417
|
+
case 'ELLIPSE':
|
|
418
|
+
return ellipse(entity as EllipseEntity)
|
|
419
|
+
case 'ARC':
|
|
420
|
+
return arc(entity as ArcEntity)
|
|
421
|
+
case 'TEXT':
|
|
422
|
+
return text(entity as TextEntity)
|
|
423
|
+
case 'MTEXT':
|
|
424
|
+
return mtext(entity as MTextEntity)
|
|
425
|
+
case 'DIMENSION': {
|
|
426
|
+
const dimEntity = entity as DimensionEntity
|
|
427
|
+
const styleName = typeof dimEntity.styleName === 'string'
|
|
428
|
+
? dimEntity.styleName
|
|
429
|
+
: undefined
|
|
430
|
+
const dimStyle = styleName && dimStyles
|
|
431
|
+
? dimStyles[styleName]
|
|
432
|
+
: undefined
|
|
433
|
+
return dimension(dimEntity, dimStyle)
|
|
434
|
+
}
|
|
435
|
+
case 'SPLINE': {
|
|
436
|
+
const splineEntity = entity as SplineEntity
|
|
437
|
+
const hasWeights = splineEntity.weights?.some((w: number) => w !== 1)
|
|
438
|
+
if ((splineEntity.degree === 2 || splineEntity.degree === 3) && !hasWeights) {
|
|
439
|
+
try {
|
|
440
|
+
return bezier(splineEntity)
|
|
441
|
+
} catch (err) {
|
|
442
|
+
const error = err as Error
|
|
443
|
+
logger.warn('bezier conversion failed, using polyline:', error.message)
|
|
444
|
+
return polyline(entity)
|
|
445
|
+
}
|
|
446
|
+
} else {
|
|
447
|
+
return polyline(entity)
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
case 'LINE':
|
|
451
|
+
case 'POLYLINE': {
|
|
452
|
+
return polyline(entity)
|
|
453
|
+
}
|
|
454
|
+
case 'LWPOLYLINE': {
|
|
455
|
+
return lwpolyline(entity)
|
|
456
|
+
}
|
|
457
|
+
default:
|
|
458
|
+
logger.warn('entity type not supported in SVG rendering:', entity.type)
|
|
459
|
+
return null
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
export default function toSVG(parsed: ParsedDXF): string {
|
|
464
|
+
const entities = denormalise(parsed)
|
|
465
|
+
const dimStyles = parsed.tables.dimStyles
|
|
466
|
+
const { bbox, elements } = entities.reduce(
|
|
467
|
+
(
|
|
468
|
+
acc: { bbox: Box2; elements: string[] },
|
|
469
|
+
entity: Entity,
|
|
470
|
+
): { bbox: Box2; elements: string[] } => {
|
|
471
|
+
const rgb = getRGBForEntity(parsed.tables.layers, entity)
|
|
472
|
+
const boundsAndElement = entityToBoundsAndElement(entity, dimStyles)
|
|
473
|
+
// Ignore entities that don't produce SVG elements or have unsupported types
|
|
474
|
+
if (boundsAndElement) {
|
|
475
|
+
const { bbox, element } = boundsAndElement
|
|
476
|
+
// Ignore invalid bounding boxes
|
|
477
|
+
if (bbox.valid) {
|
|
478
|
+
acc.bbox.expandByPoint(bbox.min)
|
|
479
|
+
acc.bbox.expandByPoint(bbox.max)
|
|
480
|
+
}
|
|
481
|
+
acc.elements.push(
|
|
482
|
+
`<g stroke="${rgbToColorAttribute(rgb)}">${element}</g>`,
|
|
483
|
+
)
|
|
484
|
+
}
|
|
485
|
+
return acc
|
|
486
|
+
},
|
|
487
|
+
{
|
|
488
|
+
bbox: new Box2(),
|
|
489
|
+
elements: [],
|
|
490
|
+
},
|
|
491
|
+
)
|
|
492
|
+
|
|
493
|
+
const viewBox = bbox.valid
|
|
494
|
+
? {
|
|
495
|
+
x: bbox.min.x,
|
|
496
|
+
y: -bbox.max.y,
|
|
497
|
+
width: bbox.max.x - bbox.min.x,
|
|
498
|
+
height: bbox.max.y - bbox.min.y,
|
|
499
|
+
}
|
|
500
|
+
: {
|
|
501
|
+
x: 0,
|
|
502
|
+
y: 0,
|
|
503
|
+
width: 0,
|
|
504
|
+
height: 0,
|
|
505
|
+
}
|
|
506
|
+
return `<?xml version="1.0"?>
|
|
507
|
+
<svg
|
|
508
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
509
|
+
xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1"
|
|
510
|
+
preserveAspectRatio="xMinYMin meet"
|
|
511
|
+
viewBox="${viewBox.x} ${viewBox.y} ${viewBox.width} ${viewBox.height}"
|
|
512
|
+
width="100%" height="100%"
|
|
513
|
+
>
|
|
514
|
+
<g stroke="#000000" stroke-width="0.1%" fill="none" transform="matrix(1,0,0,-1,0,0)">
|
|
515
|
+
${elements.join('\n')}
|
|
516
|
+
</g>
|
|
517
|
+
</svg>`
|
|
518
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# DXF Types
|
|
2
|
+
|
|
3
|
+
Tipos TypeScript organizados para o parser DXF.
|
|
4
|
+
|
|
5
|
+
## Estrutura
|
|
6
|
+
|
|
7
|
+
### Tipos Comuns (`common.ts`)
|
|
8
|
+
|
|
9
|
+
- `Point2D` - Ponto 2D (x, y)
|
|
10
|
+
- `Point3D` - Ponto 3D (x, y, z)
|
|
11
|
+
- `RGB` - Cor RGB
|
|
12
|
+
- `ColorRGB` - Tupla de cor [r, g, b]
|
|
13
|
+
- `Transform` - Transformação geométrica
|
|
14
|
+
- `ZeroTransform` - Transformação zero completa
|
|
15
|
+
|
|
16
|
+
### Entidade Base (`base-entity.ts`)
|
|
17
|
+
|
|
18
|
+
- `BaseEntity` - Interface base que todas as entidades DXF estendem
|
|
19
|
+
|
|
20
|
+
### Entidades DXF
|
|
21
|
+
|
|
22
|
+
Cada tipo de entidade em seu próprio arquivo:
|
|
23
|
+
|
|
24
|
+
- `line-entity.ts` - `LineEntity` (LINE)
|
|
25
|
+
- `circle-entity.ts` - `CircleEntity` (CIRCLE)
|
|
26
|
+
- `arc-entity.ts` - `ArcEntity` (ARC)
|
|
27
|
+
- `ellipse-entity.ts` - `EllipseEntity` (ELLIPSE)
|
|
28
|
+
- `text-entity.ts` - `TextEntity` (TEXT)
|
|
29
|
+
- `mtext-entity.ts` - `MTextEntity` (MTEXT)
|
|
30
|
+
- `point-entity.ts` - `PointEntity` (POINT)
|
|
31
|
+
- `polyline-entity.ts` - `PolylineEntity`, `Vertex` (POLYLINE/LWPOLYLINE)
|
|
32
|
+
- `spline-entity.ts` - `SplineEntity` (SPLINE)
|
|
33
|
+
- `dimension-entity.ts` - `DimensionEntity` (DIMENSION)
|
|
34
|
+
- `solid-entity.ts` - `SolidEntity` (SOLID/3DFACE)
|
|
35
|
+
- `insert-entity.ts` - `InsertEntity` (INSERT)
|
|
36
|
+
- `hatch-entity.ts` - `HatchEntity` (HATCH)
|
|
37
|
+
|
|
38
|
+
### Tipos Estruturais
|
|
39
|
+
|
|
40
|
+
- `entity.ts` - Union type `Entity` de todas as entidades
|
|
41
|
+
- `dxf.ts` - Estruturas DXF principais
|
|
42
|
+
- `LayerTable`
|
|
43
|
+
- `Tables`
|
|
44
|
+
- `Block`
|
|
45
|
+
- `Blocks`
|
|
46
|
+
- `BlockArray`
|
|
47
|
+
- `ParsedDXF`
|
|
48
|
+
- `DXFTuple`
|
|
49
|
+
|
|
50
|
+
### Tipos Utilitários
|
|
51
|
+
|
|
52
|
+
- `handler.ts` - `EntityHandler` - Interface para handlers de entidades
|
|
53
|
+
- `options.ts` - Opções de configuração
|
|
54
|
+
- `ToPolylinesOptions`
|
|
55
|
+
- `ToSVGOptions`
|
|
56
|
+
- `Config`
|
|
57
|
+
- `helper.ts` - `HelperInterface` - Interface da classe Helper
|
|
58
|
+
|
|
59
|
+
## Uso
|
|
60
|
+
|
|
61
|
+
### Import Barrel (Recomendado)
|
|
62
|
+
|
|
63
|
+
```typescript
|
|
64
|
+
import type { LineEntity, Point3D, ParsedDXF } from './types'
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Import Específico
|
|
68
|
+
|
|
69
|
+
```typescript
|
|
70
|
+
import type { LineEntity } from './types/line-entity'
|
|
71
|
+
import type { Point3D } from './types/common'
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Backward Compatibility
|
|
75
|
+
|
|
76
|
+
O arquivo `types.ts` na raiz re-exporta todos os tipos para compatibilidade:
|
|
77
|
+
|
|
78
|
+
```typescript
|
|
79
|
+
import type { LineEntity } from './types' // Funciona
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Organização
|
|
83
|
+
|
|
84
|
+
Cada arquivo segue o padrão:
|
|
85
|
+
|
|
86
|
+
1. Comentário descritivo do tipo
|
|
87
|
+
2. Imports de tipos dependentes
|
|
88
|
+
3. Definição da interface/type
|
|
89
|
+
4. Exports
|
|
90
|
+
|
|
91
|
+
O arquivo `index.ts` faz barrel export de todos os tipos.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// Base entity interface that all DXF entities extend from
|
|
2
|
+
|
|
3
|
+
import type { Point3D, Transform } from './common'
|
|
4
|
+
|
|
5
|
+
export interface BaseEntity {
|
|
6
|
+
type: string
|
|
7
|
+
handle?: string
|
|
8
|
+
layer?: string
|
|
9
|
+
lineTypeName?: string
|
|
10
|
+
lineTypeScale?: number
|
|
11
|
+
visible?: boolean
|
|
12
|
+
colorNumber?: number
|
|
13
|
+
paperSpace?: number
|
|
14
|
+
viewportOn?: number
|
|
15
|
+
extrusionDirection?: Point3D
|
|
16
|
+
extrusionZ?: number
|
|
17
|
+
transforms?: Transform[]
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/** Base for entities with positional coordinates (x, y, z) */
|
|
21
|
+
export interface PositionalEntity extends BaseEntity {
|
|
22
|
+
x: number
|
|
23
|
+
y: number
|
|
24
|
+
z?: number
|
|
25
|
+
}
|