Appearance
Import
File import — bring external files into the Snaptrude scene: images, PDFs, CAD drawings, 3D models, and site terrain. Accessed via snaptrude.core.io.import.
Every file importer takes a single source string — an https:// URL or a data: URL; other schemes are rejected, and sources over 100 MB throw. Placed 2D assets (image/pdf/cadJson) return an UnderlayHandle; dwg returns an ImportJobHandle you poll; model returns a ComponentHandle; terrain returns a TerrainHandle. Every importer throws on failure.
Types
ModelFormat
Supported 3D model formats: "skp" | "fbx" | "obj" | "3ds" | "zip". (glb/gltf/ifc/stl and Rhino/Revit are not supported.)
CadJsonInput
Parsed CAD JSON: { unit?: string; geometry?: object[] } (additional fields passed through). geometry is the array of CAD entities (lines/polylines/arcs/circles), each tagged with its CAD layer.
Functions
image(source, storey?, scale?, opacity?, label?)
Import a raster image (PNG/JPG/JPEG/BMP) as a scene underlay — a flat reference plane on a storey to trace over. The plane is placed at the storey origin (the engine's import placement); calibrate its size afterwards with underlay.setScale.
- Parameters:
source:string— Imagehttps://URL ordata:URLstorey:number(optional) — Target storey (default: active)scale:number(optional) — Initial uniform scaleopacity:number(optional) —0..1(default ~0.5)label:string(optional) — Name for the underlay
- Returns:
UnderlayHandle - Throws: if writes are disabled, the source can't be loaded, the format is unsupported, or placement fails.
ts
// Place a floor plan on storey 1, then fit it to a real-world size.
const plan = await snaptrude.core.io.import.image(
"https://example.com/floorplan.png",
1,
undefined,
0.4,
"Ground floor plan"
);
await snaptrude.core.io.underlay.setScale(plan, { planSize: 40 });pdf(source, storey?, page?, scale?, opacity?)
Import one page of a PDF as a scene underlay. One PDF per storey, one page per call.
- Parameters:
source:string— PDFhttps://URL ordata:URLstorey:number(optional) — Target storey (default: active)page:number(optional) — 1-based page for multi-page PDFs (default1)scale:string(optional) — Drawing-scale label for the project's unit mode: metric"1:10".."1:1000"(e.g."1:100") or imperial`1/8" = 1'`/`1" = 10'`. Invalid label → throws. Defaults to"1:100"in metric projects and`1" = 1'`in imperial projectsopacity:number(optional) —0..1
- Returns:
UnderlayHandle - Throws: if the storey already has a PDF, the page is out of range, or the engine fails.
ts
const sheet = await snaptrude.core.io.import.pdf("https://example.com/plans.pdf", 1, 2, "1:100");dwg(source, storey?)
Import a DWG CAD drawing (.dwg only). Conversion runs on a server, so this returns a job immediately — poll it via core.io.job. One CAD import runs at a time: starting a second while one is in flight throws. All CAD layers are imported (there is no layer filter).
- Parameters:
source:string—.dwghttps://URL ordata:URLstorey:number(optional) — Target storey (default: active)
- Returns:
ImportJobHandle
ts
const job = await snaptrude.core.io.import.dwg("https://example.com/plan.dwg", 1);
// Always poll with a timeout — a UI-cancelled import stays "processing" forever.
const deadline = Date.now() + 5 * 60_000;
while (!(await snaptrude.core.io.job.isComplete(job))) {
if (Date.now() > deadline) throw new Error("DWG import timed out");
await new Promise((r) => setTimeout(r, 2000));
}
const cad = await snaptrude.core.io.job.getResult(job);cadJson(cad, storey?)
Sketch a CAD underlay from already-parsed CAD JSON — synchronous, no server round-trip. All layers in the JSON are sketched, at the drawing's own coordinates.
- Parameters:
cad:CadJsonInput— Parsed CAD data ({ unit, geometry })storey:number(optional) — Target storey (default: active)
- Returns:
UnderlayHandle - Throws: if the JSON yields no drawable geometry or is out of bounds.
ts
const cad = await snaptrude.core.io.import.cadJson(
{ unit: "mm", geometry: [{ type: "line", layer: "WALLS" }] },
1
);model(source, storey?, format?, position?, label?)
Import a 3D model (skp/fbx/obj/3ds/zip) and place it as a component. The model is placed at its source dimensions (the file's own units); there is no import-time scale override. Unlike dwg, this call waits for the server conversion — a large model may exceed the 60-second call cap and reject while the import still completes in the background (re-query the scene to find it). Keep sources small.
- Parameters:
source:string— Modelhttps://URL ordata:URLstorey:number(optional) — Target storey (default: active)format:ModelFormat(optional) — Inferred fromsourcewhen omittedposition:Vec3Handle(optional) — Placement (default: storey origin)label:string(optional) — Name for the component
- Returns:
ComponentHandle - Throws: if writes are disabled, the source can't be loaded, the format is unsupported, conversion/placement fails, or the converted model can't be found in the library after upload.
ts
const model = await snaptrude.core.io.import.model("https://example.com/tree.skp", 1, "skp");terrain(lat, lng, width, length, elevation?, satellite?, neighborhood?, parcels?)
Import site terrain for a location (Mapbox topography). One terrain per project. width/length are the real-world extent of the area to load in metres (regardless of the project's unit mode) — the host converts them to the map zoom internally.
- Parameters:
lat:number— Latitude (degrees),-90..90lng:number— Longitude (degrees),-180..180width:number— East–west extent (metres)length:number— North–south extent (metres)elevation:boolean(optional) — Include DEM elevation (defaulttrue)satellite:boolean(optional) — Drape satellite imagery (defaulttrue)neighborhood:boolean(optional) — Include context buildings (defaultfalse)parcels:boolean(optional) — Include parcel boundaries (defaultfalse)
- Returns:
TerrainHandle - Throws: if a terrain already exists or map/mesh generation fails.
ts
// 300m × 300m site with elevation + satellite imagery.
const terrain = await snaptrude.core.io.import.terrain(40.7128, -74.006, 300, 300, true, true);Errors
Failed calls reject with a typed PluginError — see Error Handling. Conditions specific to this namespace:
| Code | Thrown by | When | details |
|---|---|---|---|
VALIDATION | every importer taking a source | The source resolves to more than 100 MB | declaredBytes/actualBytes, maxBytes |
VALIDATION | pdf | The scale label is not valid for the project's unit mode | scale, validScales, unitSystem |
VALIDATION | cadJson | The JSON contains no drawable geometry or is out of bounds | — |
OPERATION_FAILED | image, pdf, cadJson, dwg, model, terrain | The import produced nothing, the upload failed, or placement failed | context (storey, page, format, …); engineCode where the engine reports one |
PRECONDITION_FAILED | terrain | A site terrain already exists in the project | — |
The per-method "writes are disabled" rejections carry METHOD_NOT_PERMITTED. A dwg conversion that fails server-side is not an error here — the job reaches status "failed" as data; read it via core.io.job.