@omnitexts/cad3d-cli
v0.2.0
Published
Convert DWG and ASCII DXF drawings to normalized JSON and optional GLB linework.
Readme
cad3d-cli
Convert DWG and ASCII DXF drawings into a normalized JSON document and, optionally, a GLB linework model.
cad3d-cli is a format-conversion tool. It preserves CAD layers, blocks, entities, units, extents, and basic geometry. It does not infer buildings, floors, heights, materials, or other architectural semantics.
Requirements
- Node.js 20 or newer
- A readable DWG file or an ASCII DXF file
Binary DXF is not supported. Resave it as ASCII DXF before conversion.
Install
Run without installing:
npx @omnitexts/cad3d-cli drawing.dwg --glbOr install globally:
npm install --global @omnitexts/cad3d-cli
cad3d drawing.dwg --glbCLI
cad3d <input.dwg|input.dxf> [options]
Options:
-o, --output <directory> Output directory
--glb Also create drawing.glb
--pretty Pretty-print drawing.json
--units <unit> Override units: mm, cm, m, in, ft, yd, km, dm, mi
-h, --help Show help
-v, --version Show versionExamples:
cad3d factory.dwg --pretty
cad3d floor.dxf --glb -o output/floor
cad3d unitless.dwg --units mm --glbBy default, files are written to cad3d-output/<source-name>/:
drawing.json: normalized document metadata, units, extents, statistics, layers, blocks, and entities.drawing.glb: optional meter-based linework grouped by CAD layer.
Node.js API
import { convertCadFile, createGlb } from "@omnitexts/cad3d-cli";
import { writeFile } from "node:fs/promises";
const drawing = await convertCadFile("factory.dwg", { units: "mm" });
const glb = await createGlb(drawing);
await writeFile("drawing.json", JSON.stringify(drawing));
await writeFile("drawing.glb", glb);Browser API
Use the browser entry with a File, Blob, ArrayBuffer, or Uint8Array. DWG parsing requires the LibreDWG WASM directory to be served by the application; DXF parsing does not.
import { convertCadBuffer, createGlb } from "@omnitexts/cad3d-cli/browser";
const drawing = await convertCadBuffer(file, {
wasmDirectory: "/libredwg/",
});
const glbBytes = await createGlb(drawing);
const glbUrl = URL.createObjectURL(new Blob([glbBytes], { type: "model/gltf-binary" }));For large uploads, use the packaged worker client so parsing does not block the interface:
import { createCad3dWorker } from "@omnitexts/cad3d-cli/worker";
const converter = createCad3dWorker();
const { drawing, glb } = await converter.convert(
file,
{ name: file.name, wasmDirectory: "/libredwg/" },
({ message, ratio }) => console.log(message, ratio),
);
converter.terminate();Copy node_modules/@mlightcad/libredwg-web/wasm/libredwg-web.wasm into the directory configured by wasmDirectory. ASCII DXF conversion does not require the WASM asset.
Normalized data
The top-level schema is versioned independently from the npm package:
{
"schema": "cad3d.drawing",
"schemaVersion": "1.0.0",
"source": {},
"units": {},
"coordinateSystem": {},
"extents": {},
"statistics": {},
"layers": [],
"blocks": [],
"entities": []
}Supported normalized geometry kinds include line, polyline, arc, circle, ellipse, point, insert, text, dimension, polygon, and hatch. Unsupported CAD entities retain their basic metadata with geometry: null and are counted in unsupportedTypeCounts.
Text is retained in JSON but is not converted to GLB glyph geometry. Block inserts are recursively expanded for GLB output. Coordinates are recentered to avoid floating-point precision loss and converted to meters using the drawing units or the --units override.
Known limitations
- Some damaged, encrypted, or custom-object DWG files may not be readable by LibreDWG.
- DXF input must be ASCII.
- The GLB contains CAD linework and points, not walls, roofs, doors, or semantic 3D solids.
- Unsupported entities are reported rather than silently discarded from the JSON document.
Development
pnpm install
pnpm test
pnpm packThe test fixture is synthetic and contains no customer drawing data.
License
GPL-2.0-only. DWG parsing is provided by @mlightcad/libredwg-web, which is also distributed under GPL-2.0-only. dxf-parser and Three.js are MIT-licensed dependencies.
