Skip to content

Add 3D representations of infrastructures in glTF 2.0 format - #172

Merged
rezib merged 16 commits into
mainfrom
3d-infrastructure
Nov 13, 2026
Merged

rezib merged 16 commits into
mainfrom
3d-infrastructure

Conversation

@rezib

@rezib rezib commented Nov 13, 2026 •

Copy link
Copy Markdown
Contributor

RacksDB can now generate 3D representations of infrastructures in glTF 2.0 format, in JSON (gltf) and binary (glb) variants. The infrastructure details page of the web UI shows them in an interactive viewer.

Library

  • New GltfInfrastructureDrawer generates a scene graph that follows the database structure: room → racks row → rack → equipment.
    • Nodes are named after database objects.
    • Metadata is stored in node extras: category, type, tags, rack, slot, size, and the selected and colliding flags.
  • Rooms have a textured raised floor, with perforated tiles in the cold aisle in front of rack doors. The textures are small palette PNGs (~45 KB in total) repeated with KHR_texture_transform, so mercury.glb is about 105 KB.
  • Infrastructure drawing parameters are honoured:
    • equipment_tags, ghost_unselected, discard_empty_racks, other_racks
    • coloring rules
    • collisions highlighting
  • Generated files pass the Khronos glTF validator with no errors or warnings.

CLI and REST API

  • racksdb draw infrastructure --format gltf|glb.
  • The /draw/infrastructure/<name>.gltf|glb endpoint returns model/gltf+json / model/gltf-binary.
  • The 3D formats are rejected with a clear error for rooms and when coordinates are requested.
  • The drawer is now selected by a shared drawer_class() factory used by both the CLI and the REST API.

Web UI

  • 2D/3D toggle in the infrastructure details page.
  • The 3D viewer is based on three.js and loaded lazily, so it stays out of the main bundle.
    • Mouse orbit, pan and zoom.
    • Equipment highlighted and labelled on hover.
    • Buttons to reset the view and switch to fullscreen.
    • A turntable mode where the camera orbits around the racks until the user clicks in the scene.
    • Eased camera transitions.

Refactoring

Before the feature, a few preparatory refactors, one commit each:

  • Split the base Drawer into a format-independent Drawer and a cairo/Pango Drawer2D.
  • Move the infrastructure lookup, racks selection and rack position in its row into Drawer. This also removes the racks selection code duplicated between the flat and axonometric drawers.
  • Gather collision detection in a new collisions module. Collision warnings are now emitted by the racksdb.drawers.collisions logger.

Docs

  • New page on 3D representations: formats, supported parameters, scene conventions and node metadata.
  • racksdb manpage, web UI page and OpenAPI description updated.
  • CHANGELOG entries.

Testing

  • Python: 366 tests pass.
    • Every commit passes on its own.
    • New coverage: GLB parsing, positions consistent with room diagrams, perforated tiles, drawing parameters, collisions, CLI and REST API.
  • Frontend: 61 unit tests, type-check and lint pass.
  • Checked manually in Chromium: rendering, hover, multi-room and rotated rows, turntable start and stop, reset view.

Closes #164

@rezib rezib added this to the v0.8.0 milestone Nov 13, 2026
@rezib rezib self-assigned this Nov 13, 2026
@rezib
rezib force-pushed the 3d-infrastructure branch 2 times, most recently from 35c36d0 to e155a0a Compare November 13, 2026 11:22
rezib added 11 commits November 13, 2026 13:49
Drawer base class mixed logic required by all representations (database,
drawing parameters, coloring rules) with logic specific to 2D images rendered
with cairo (surfaces, Pango text labels, image coordinates).

Restrict Drawer to the logic independent of the output format and move cairo
and Pango specific attributes and methods, along with ImagePoint, into new
Drawer2D class in base2d module, inherited by existing room and infrastructure
drawers.

This prepares the support of representations of other natures, starting with
3D representations of infrastructures in glTF format, which must share the
database and coloring rules logic with 2D drawers without depending on cairo,
Pango and images coordinates.

Assisted-by: Claude Opus 5.5
Move the lookup of the infrastructure to represent in database, with the error
raised when it is not found, from infrastructure drawer constructor to the
base Drawer class.

All representations of infrastructures, whatever their output format, start
with this lookup. Sharing it in base Drawer class lets upcoming 3D drawer of
infrastructures, and possibly other drawers in the future, reuse it with the
same behavior and error message as existing 2D drawers.

Assisted-by: Claude Opus 5.5
The selection of racks and rows to represent according to equipment_tags,
discard_empty_racks and other_racks drawing parameters was duplicated in the
draw() methods of infrastructure and axonometric infrastructure drawers, and
the check of equipment tags was duplicated in their methods drawing
equipment.

Move this logic into base Drawer class, in _select_infrastructure_racks(),
_part_contains_selected_equipment() and new _equipment_selected() methods,
used by both 2D infrastructure drawers.

Besides removing duplicated code, this ensures upcoming 3D drawer of
infrastructures, and any other future representation of infrastructures,
honours drawing parameters exactly as 2D drawers do, with a single place to
fix or extend this selection logic.

Assisted-by: Claude Opus 5.5
Move _rack_preceding_widths() method, which yields the widths of racks and
empty slots before a rack in its row, from room drawer to base Drawer class,
without modification.

This method defines how racks are positioned in their rows, including the
width assumed for empty slots. Any representation placing racks in rooms,
starting with upcoming 3D representation of infrastructures, must follow the
same rule to stay consistent with rooms diagrams. Sharing it in base Drawer
class avoids diverging implementations.

Assisted-by: Claude Opus 5.5
Move racks footprints overlap detection (polygons_overlap()) out of room
drawer module and equipment overlap detection (equipment_overlap()) out of
infrastructure drawer module, along with the detection of colliding equipment
in a list of racks extracted from infrastructure drawer as
colliding_equipment(), into new collisions module.

These functions are pure geometry, independent of any rendering. Gathering them
in a dedicated module lets upcoming 3D drawer of infrastructures, and future
drawers or other consumers of datacenters geometry, detect collisions exactly
as 2D drawers do without importing 2D drawers modules and their cairo
dependency.

Collisions warnings are now emitted by racksdb.drawers.collisions logger.

Assisted-by: Claude Opus 5.5
Add GltfInfrastructureDrawer to represent infrastructures in 3D, in glTF
JSON (gltf) and binary (glb) formats. The scene graph follows database
structure (room, racks row, rack, equipment) with metadata in node extras.
Rooms have textured raised floors with perforated tiles in front of racks
doors. Equipment tags filtering, ghosts, other racks, coloring rules and
collisions highlighting drawing parameters are honored.

Assisted-by: Claude Opus 5.5
Add shared drawer_class() factory to select drawer according to entity,
format and drawing parameters, used by both racksdb CLI and REST API.

Assisted-by: Claude Opus 5.5
Add gltf and glb drawing formats.

Assisted-by: Claude Opus 5.5
Cover glTF drawer, drawer class selection, CLI and REST API with gltf and
glb formats.

Assisted-by: Claude Opus 5.5
Add 2D/3D toggle in infrastructure details view. The 3D view loads the
infrastructure glb representation in an interactive three.js viewer,
loaded dynamically, with orbit controls, equipment highlighting and label
on hover, view reset and fullscreen mode.

Assisted-by: Claude Opus 5.5
Update infrastructure details page screenshot with 2D/3D toggle and add
screenshot of 3D view of infrastructure in fullscreen mode, with its shadowed
version. Add 3D view in overview diagrams, with screenshot embedded in SVG
optimized with scour.

Assisted-by: Claude Opus 5.5
@rezib
rezib force-pushed the 3d-infrastructure branch from e155a0a to 612e831 Compare November 13, 2026 12:52
Add page about 3D representations of infrastructures with formats, supported
drawing parameters, scene conventions and nodes metadata, and reference it
in drawing parameters page.

Assisted-by: Claude Opus 5.5
Document gltf and glb formats of draw command, their restrictions to
infrastructures and incompatibility with coordinates, with an example.

Assisted-by: Claude Opus 5.5
Document 2D/3D toggle in infrastructure details page and the controls of the
interactive 3D view.

Assisted-by: Claude Opus 5.5
Mention 3D representations of infrastructures in glTF format in diagrams
section of overview page.

Assisted-by: Claude Opus 5.5
Assisted-by: Claude Opus 5.5
@rezib
rezib force-pushed the 3d-infrastructure branch from 612e831 to a323400 Compare November 13, 2026 13:13
@rezib
rezib merged commit a3e83f3 into main Nov 13, 2026
25 of 26 checks passed
@rezib
rezib deleted the 3d-infrastructure branch November 13, 2026 13:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3D representations of infrastructure in glTF format

1 participant