Skip to content

Export browser-ready 3D scenes (.glb, rvtio-scene/1) and standalone HTML viewer - #186

Closed
AndreyStartsev wants to merge 1 commit into
IOExtend:mainfrom
AndreyStartsev:feat/scene-and-html-viewer
Closed

AndreyStartsev wants to merge 1 commit into
IOExtend:mainfrom
AndreyStartsev:feat/scene-and-html-viewer

Conversation

@AndreyStartsev

Copy link
Copy Markdown
Contributor

What changes and why

Implements browser-ready 3D scene export (.glb glTF 2.0 and versioned rvtio-scene/1 JSON) and standalone zero-dependency 3D HTML viewer export (.html) directly from decoded .rvt projects and .rfa families without Revit or external runtime dependencies.

Closes #24
Closes #25

1. Browser-ready 3D scene export (RvtIO.Scene — #24)

  • Public API: Adds SceneExporter, SceneExportOptions, ModelScene (SceneMesh, SceneSubmesh, SceneMaterial, SceneInstance, SceneElement, ScenePropertyGroup, SceneProperty, SceneGridLine, SceneCompleteness), and SceneJsonSerializer.
  • Geometry & instancing:
    • Triangulates planar faces with inner hole loops (2D ear-clipping with hole-bridging), extruded GeoSolid profiles with subtracted rectangular wall/slab openings, and spatial room/MEP space boundaries when IncludeRooms = true.
    • Deduplicates repeated family symbol geometry so multiple instances reference shared mesh buffers via per-instance column-major 4x4 transforms.
    • Detects negative-determinant (mirrored, det < 0) transforms and emits reversed-winding mesh variants so outward normals and backface culling remain valid in standard glTF / WebGL viewers.
  • Materials, coordinates & metadata:
    • Decodes packed Revit 0x00BBGGRR material colors, material transparency (OPAQUE / BLEND), shininess-derived PBR roughness/metallic factors, glazing heuristics, and category fallback palettes.
    • Supports internal project coordinates or shared coordinates (UseSharedCoordinates = true) and automatically applies Relative-to-Center (RtcOffset) origin shifting when coordinates exceed 100 m to preserve float32 vertex precision.
    • Preserves stable element identity (Id, UniqueId, CategoryId, TypeId, HostId, ParentId, Level), supports subset filtering (IncludedElementIds, IncludedCategoryIds) and caller-selected metadata (IncludedParameterNames, IncludeTypeParameters, MaxParametersPerElement), and reports omitted / non-visual records cleanly via SceneCompleteness and SkipLog without leaking internal exceptions.
  • glTF 2.0 .glb & rvtio-scene/1 JSON:
    • GlbSceneWriter writes standard binary glTF 2.0 (.glb) with Z-up to Y-up root conversion, PBR metallic-roughness materials, category -> element -> subpart node hierarchy, and element identity in node.extras.
    • SceneJsonSerializer reads and writes the versioned rvtio-scene/1 JSON contract with Base64-encoded float32 / uint32 mesh buffers.

2. Self-contained 3D HTML viewer (HtmlViewerExporter — #25)

  • Single-file offline output: HtmlViewerExporter and HtmlViewerOptions generate a single standalone .html document embedding a zero-dependency WebGL renderer and the rvtio-scene/1 payload with zero external scripts, stylesheets, fonts, or network requests.
  • Interactive capabilities & large-model scalability (>1M triangles):
    • Turntable orbit, pan, dolly zoom, Fit to model/selection, and interactive ViewCube (TOP, FRONT, RIGHT, BACK, LEFT, ISO), with pre-sorted mesh/material VBO batching (opaqueDrawOrder) across thousands of placed instances.
    • Clipped AABB broadphase + front-to-back tmin-sorted CPU raycast picking with early exit, synchronized with a lazy/paginated virtualized category/element tree (TREE_PAGE_SIZE, pre-indexed search, event delegation) and grouped Element Properties inspector.
    • Visibility controls (Isolate, Hide, Show All, per-category and per-element toggles), interactive 6-plane X/Y/Z Section Box clipping in fragment shaders, two-point 3D surface Measure tool, Dark/Light theme toggle, and a Scene Completeness Summary modal.
  • XSS safety: Serializes embedded scene JSON with JavaScriptEncoder.Default (escaping <, >, &, quotes) inside <script type="application/json">, HTML-encodes document <title> / chrome labels, and populates dynamic DOM labels strictly via textContent.

3. CLI & documentation

  • Extends rvtio CLI (ExportCommand, Program, SceneCliOptions) with .glb, .html/.htm, and .scene.json extension detection, --scene-json, --scene-pretty, --scene-categories, --scene-ids, --scene-no-parameters, --scene-parameter-names, --scene-shared-coordinates, --scene-include-rooms, --scene-no-grids, --glb-z-up, --viewer-title, --viewer-theme, and ExportReport integration.
  • Adds docs/scene-export.md and updates README.md, docs/public-api.md, docs/export-report.md, docs/getting-started.md, docs/index.md, and docs/toc.yml.
  • Existing IFC, compact JSON, and full JSON export code paths and outputs are unchanged.

How it was checked

  • dotnet build RvtIO.slnx -c Release has no warnings in src/RvtIO or src/RvtIO.Cli (TreatWarningsAsErrors=true and GenerateDocumentationFile=true across net8.0 and net10.0)
  • dotnet test passes:
    • New SceneExportTests and HtmlViewerExporterTests: 36 passed, 0 failed on both net8.0 and net10.0 (covering hole triangulation, wall openings, 20-instance shared symbol + mirrored det < 0 outward winding, 0x00BBGGRR material color & transparency, georeferenced RTC sub-millimetre precision, subset/parameter filtering, room space boundaries, rvtio-scene/1 round-trip, 2,500-instance partial-completeness reporting, untrusted XSS payload neutralization, CLI flags, and --report exit codes).
    • Full RvtIO.Tests suite (net10.0, without private RVTIO_TEST_FILES): 10,383 passed, 0 failed, 437 skipped.
  • dotnet pack RvtIO.slnx -c Release --no-build builds RvtIO and RvtIO.Cli NuGet packages cleanly with no new package dependencies
  • dotnet docfx docfx.json --warningsAsErrors succeeds with 0 warnings, 0 errors
  • Real-world large-geometry stress test on multi-storey architectural and MEP .rvt sample models (702k to 1.165M triangles, 6,542–8,580 3D elements, 16,012 placed instances; scene + .glb/.html export in 2.7–9.8 s) and live WebGL browser verification: 0 console/WebGL errors, 0 external network requests, instant virtualized search/filtering, front-to-back 3D raycast picking, isolate/hide/show-all, X/Y/Z section box, measurement tool, ViewCube, theme switching, and completeness modal
  • Exports of the same files before and after are identical (IFC and compact/full JSON exporters were not modified)
  • No Revit models, customer data or vendor files are added

…TML viewer

- Add RvtIO.Scene public API (SceneExporter, ModelScene, SceneExportOptions, HtmlViewerExporter, HtmlViewerOptions, SceneJsonSerializer)
- Export binary glTF 2.0 (.glb) with reusable symbol meshes, mirrored instance handling (det < 0), PBR materials/transparency, Z-up to Y-up conversion, and node.extras identity metadata
- Export versioned rvtio-scene/1 JSON with compact Base64 mesh buffers, RTC large-coordinate centering, room/space volume boundaries, datum grids, and completeness reporting
- Export self-contained zero-CDN WebGL 3D HTML viewer (.html) with orbit/pan/zoom, ViewCube, 3D raycast picking, category hierarchy search, property inspector, isolate/hide, X/Y/Z section box, 3D measurement, theme toggle, and strict XSS escaping
- Wire CLI scene/viewer flags and format auto-detection (.glb, .html, --format scene-json) with ExportReport integration
- Add 35 unit/CLI/XSS tests across net8.0 and net10.0 and DocFX guide (docs/scene-export.md)

Closes IOExtend#24
Closes IOExtend#25
@mahach666

Copy link
Copy Markdown
Collaborator

Thank you for contributing this implementation.

We have revised the architecture for viewer support:

  • RvtIO will own RVT/RFA reading, native geometry decoding and the public geometry APIs needed by the integration.
  • IOViewer will own the generic scene model, HTML/WebGL viewer and interactive presentation features.
  • A separate optional IOViewer.RvtIO adapter in the IOViewer repository will convert an opened RvtDocument into a ViewerDocument. The adapter will depend on both libraries, while the core libraries remain independent.

We are closing this PR in favor of that architecture. The integration remains tracked in #25; see the architecture update. The goal is still planned, rather than completed by closing this PR.

Your implementation remains available as reference for the integration. If we reuse your work, we will preserve attribution and credit you as a co-author of the corresponding commits using Co-authored-by trailers.

Thank you again for the work on this feature.

@mahach666 mahach666 closed this Nov 11, 2026
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.

Export a self-contained HTML file with an embedded 3D model viewer Export a browser-ready model scene with geometry and element metadata

2 participants