Import the GLB files Pascal produces and get a structured, editable Blender scene instead of a flat pile of meshes:
- one collection per level (
Ground Floor,First Floor, …) with sub-collections per kind (Walls,Doors,Windows,Items,Zones,Slabs,Ceilings, …) - objects named after their Pascal labels, with
pascalId/kind/labelkept as custom properties - zones rebuilt as coloured floor polygons (viewport only, excluded from renders)
- the door and window
openclips as NLA tracks on the moving parts - metric units, 1 unit = 1 m
- re-importing the same project replaces the previous import instead of stacking
.001copies - a loopback listener so the editor's Send to Blender lands the live scene in the open Blender
- optional material polish on import (on by default): see-through surfaces become real glass with transmission, leaf textures get their cutout alpha wired up, and the site ground gets a calmer albedo so it stops blowing out the frame
- optional lighting on import (on by default): a physical sky with a matching sun, a camera framing the building, EEVEE with shadows and ray tracing, and the viewport switched to rendered shading
Pascal is a tool that produces files you own. The GLB it exports is plain glTF with a small,
documented set of extras; this add-on just reads them.
Blender 4.2 or newer.
- Download
pascal-<version>.zipfrom the releases (or build one, see below). - Blender → Edit → Preferences → Get Extensions → ▾ → Install from Disk… → pick the zip.
- File → Import → Pascal scene (.glb), or the Pascal tab in the 3D viewport sidebar (
N). - In Pascal: Settings → Export → Export GLB (the "Include in file" switches choose which procedural content is baked into the file).
Untick Replace previous import in the file dialog to keep an earlier import of the same project.
Polish materials fixes what glTF cannot express: windows arrive as a 30% alpha blend and read as
blue plastic, so they become Principled glass (files exported with transmission are left alone);
textures whose alpha channel really cuts something out get that alpha wired to the shader; the
site's ground plane gets a mid-grey albedo. Set up lighting (file dialog, Pascal tab, and the
add-on preferences for scenes sent from the editor) adds a Pascal sky world, a Pascal sun, a
Pascal ground and a Pascal camera — press Numpad 0 to look through it. The look comes from a
preset you pick in the Pascal tab (Daylight, Golden hour, Overcast, Night, Physical
sky); the refresh button next to it re-lights the current scene. Night adds a warm bulb in
every room (one per zone) and a porch light at the spawn point, in a Pascal lights collection
that the other presets remove again. Lighting uses one of Blender's bundled
world HDRIs (neutral, no colour cast) with a sun lamp for crisp shadows, while the camera sees a
physical-sky backdrop. Your render engine is left alone (EEVEE gets shadows, ray tracing and fast
GI switched on; Cycles gets denoising); the add-on preferences can make it switch to EEVEE or
Cycles on import instead. They are a starting point: tweak or delete them, a re-import reuses the
same ones.
Every Pascal scene node is a glTF node named by its pascalId with extras:
| extra | meaning |
|---|---|
pascalId |
stable id, also the node name |
kind |
site, building, level, wall, door, window, item, zone, slab, ceiling, roof, … |
label |
the user-facing name |
openable, clips |
doors and windows that actually bake an open clip ("<id>: open", 1 s) |
polygon, color |
zones: [x, z] pairs (three.js Y-up) and a hex colour; the fill mesh is left out of the file |
Anything else in the file is ordinary glTF 2.0 that Blender's own importer handles.
# headless checks against the committed fixture (or any Pascal export)
./scripts/test.sh
./scripts/test.sh path/to/export.glb
# build and validate the extension zip (Blender's own tool; file list is [build].paths
# in blender_manifest.toml, so only those files can ever end up in the package)
./scripts/build.shSet BLENDER to point at another binary. Real exports for local testing go in
tests/fixtures/local/ (git-ignored).
The add-on listens on 127.0.0.1:27412 (next few ports if taken) so the Pascal editor can hand
the live scene to the open Blender without a download step. Blender itself opens no socket and
starts no thread: server.py runs as a helper process (Blender's bundled Python, started with
subprocess) and hands received scenes over through a temporary spool folder, which a
bpy.app.timers callback drains on Blender's main thread. The helper stops with Blender — and
lets itself out if Blender goes away without stopping it. Only web origins you allow can send:
https://editor.pascal.app by default; any other origin that tries shows up in the Pascal
sidebar tab with an Allow button (useful for a local editor on http://localhost:3001).
Port, origins and auto-start live in the add-on preferences.
Protocol, for anyone building another sender:
| Route | Purpose |
|---|---|
OPTIONS * |
CORS preflight, answers Access-Control-Allow-Private-Network: true (Chrome private-network access) |
GET /pascal/health |
{ app: "blender", version, addon, port, allowed } — allowed tells the caller whether its origin may send |
POST /pascal/import |
body model/gltf-binary; optional X-Pascal-Project-Name (percent-encoded UTF-8), X-Pascal-Project-Id, X-Pascal-Version; 202 { id, state: "queued" }, 403 origin_not_allowed, 400 not_glb |
GET /pascal/import/<id> |
`{ id, state: queued |
Requests without an Origin header (curl, scripts on the same machine) are accepted: the
allowlist gates browsers, which are the only callers acting with ambient authority.
- Send to Blender button in the Pascal editor (the listener side above is in).
- Pull a project straight from your Pascal account.
GPL-3.0-or-later, as required for Blender add-ons.


