Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

bimview

An IFC model goes in. One HTML file comes out, and it is the whole viewer.

No CDN, no three.js, no server, no cloud account, no upload. The geometry layer, the WebGL2 renderer and the Revit compound-file reader are all in this package, in the standard library, on top of ifc-spf.

pip install git+https://github.com/aecplatform/bimview.git
bimview office.ifc
office.html
  20 elements · 944 triangles · 78 KB

Open office.html anywhere. Orbit, pan, zoom, click an element to read its property sets, filter by IFC class or by storey. Mail it to a client, attach it to a pull request, open it on a site laptop with no network.


What it will not do, said up front

.rvt files have no geometry here, and never will. Revit stores element data in undocumented proprietary streams. The only supported routes to it are Autodesk's paid Model Derivative service or an IFC export from Revit itself. Guessing at the format would produce a viewer that is right until it silently isn't, which is worse than useless for a compliance conversation.

So bimview reads what a .rvt genuinely offers — and says so:

bimview Tower.rvt
Tower.rvt.html
  Revit version    2024
  Build            20230512_1200(x64)
  Worksharing      Not enabled
  Last saved to    C:\Projects\Tower.rvt
  Preview          embedded

  No geometry. Revit's element data is in undocumented streams;
  export IFC from Revit (File → Export → IFC) and view that.

That comes from a real compound-file reader — [MS-CFB], including the extended DIFAT and the mini-stream, because BasicFileInfo lives in the mini stream in every real model. Exit code is 2: the file was read, no geometry was drawn. .rfa, .rte and .rft are handled the same way.

The coverage report is the point

A viewer that renders three quarters of a model and says nothing is how a missing shaft becomes a site problem. Every representation bimview cannot tessellate is counted, named, and printed — and carried into the HTML, so the person you sent the file to sees the same gaps you did:

  14 of 220 products did not draw:
      9  unsupported representation IfcSweptDiskSolid
      3  boolean subtraction not applied (openings render filled)
      2  outer curve is not a polyline, indexed poly-curve or circle

Two consequences worth stating plainly:

  • Openings render filled. A door void is an IfcBooleanClippingResult. Without a CSG kernel the honest output is the un-cut wall plus a recorded reason — not a hole drawn where no hole was computed.
  • Hollow sections render solid. The bore of a CircleHollowProfileDef is not cut.

What draws today

Solids IfcExtrudedAreaSolid · IfcFacetedBrep · IfcPolygonalFaceSet · IfcTriangulatedFaceSet · IfcMappedItem · IfcBooleanResult (first operand)
Profiles rectangle · rounded rectangle · circle · circle-hollow · I-shape · arbitrary closed · derived
Curves polyline · indexed poly-curve incl. arc segments · circle · composite
Placement full IfcLocalPlacement chains, IfcAxis2Placement2D/3D, cartesian transformation operators
Units resolved to metres once, so a millimetre file is not a thousand times too big

Why it is fast without a library

Two decisions do most of the work:

  • Normals come from screen-space derivatives in the fragment shader, so the vertex buffer carries a position and an element id — sixteen bytes — and nothing else.
  • Colour and visibility live in data textures indexed by that element id. Hiding a storey is a texture upload, not a rebuild, and the entire model stays a single drawArrays call.

Selection is a colour-picking pass into an offscreen framebuffer, which is exact at any zoom and needs no spatial index.

Try it without a model

python examples/make_demo.py examples/office.ifc
bimview examples/office.ifc

make_demo.py writes a two-storey building — wall ring, slabs, circular columns, an I-section beam — as readable IFC4 text. No binary fixture nobody can diff.

Library use

from bimview import from_path, render

scene = from_path("office.ifc")
print(scene.coverage.drawn, "of", scene.coverage.products, "products drew")
for reason, count in scene.coverage.top_reasons():
    print(f"  {count:>4}  {reason}")

Path("office.html").write_text(render(scene), encoding="utf-8")

Where the schema lives

ifc-spf stops at products on purpose — it promises no geometry kernel, and it keeps that promise: it knows IfcWall has a Representation and knows nothing about IfcExtrudedAreaSolid. So the geometry entities are addressed positionally here, from a table in bimview/geometry/ifcattr.py that lists each type's full attribute sequence. A wrong position reads a neighbouring attribute and produces confidently wrong geometry, so the table is written out in full rather than by index.

Tests

pip install -e ".[dev]" && pytest

50 tests. The IFC fixtures are hand-written SPF text, so every coordinate in an expectation traces to a line you can read. The compound-file fixtures are real containers assembled byte by byte — a mocked reader would prove nothing about the FAT walk, and the FAT walk is what breaks on real files.

Licence

MIT.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages