IFC vs. DWG as an Indoor Map Source
Both pipelines produce the same GeoJSON envelope, so this is not a question about output — it is a question about which source a given building actually has, and what each one costs to onboard. This page sits under IFC & BIM model ingestion and answers it building by building.
What the Choice Actually Decides
The two pipelines converge: both emit a FeatureCollection in local metres with level,
space_class and feature_id on every feature, and nothing downstream can tell them apart. What
differs is which problems you solve in code and which the source solves for you.
The three stages a drawing pipeline spends most of its effort on — establishing units, assigning levels, recovering rooms and their names — are attributes in an IFC model. That is where the saving comes from, and it is large: roughly 180 of 260 engineer-hours per building in the measurement above.
Geometry moves the other way. A drawing gives you 2D lines that polygonise into rooms; a model gives you 3D solids that must be tessellated and sectioned, which is both more compute and more code. On balance the IFC path still wins, but not because it is simpler — because the work it adds is smaller than the work it removes.
Availability Decides More Than Suitability
For most estates, the choice is made by the buildings rather than by the engineering team. A model exists if the building was designed or substantially refurbished after BIM delivery became normal, and does not otherwise. No tooling changes that: a 1970s office block has drawings, at best.
The branch worth internalising is the second one. Receiving an IFC file is not the same as
receiving a usable model. Discipline models — structural, mechanical, electrical — are valid IFC
and contain no IfcSpace entities at all, so an ingest that assumes any .ifc is a map source
produces a building with eight storeys and no rooms. Checking for spaces at the front of the
ingest, and routing the building to the drawing pipeline when there are none, costs one query and
prevents a whole class of empty publications.
Cross-Checking One Source Against the Other
When both sources exist — common for recent refurbishments, where the model covers the works and the drawings cover the whole building — running the IFC pipeline and validating against the drawings gives a free accuracy check that neither source provides alone.
import logging
from dataclasses import dataclass
logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(levelname)s] %(message)s")
logger = logging.getLogger(__name__)
@dataclass(frozen=True)
class SourceSummary:
rooms: int
total_area_m2: float
levels: tuple[float, ...]
def cross_check(ifc: SourceSummary, dwg: SourceSummary, *,
area_tol: float = 0.03, room_tol: int = 2) -> list[str]:
"""Compare two independent ingests of the same building. Empty list means agreement."""
if not ifc.rooms or not dwg.rooms:
raise ValueError("cross-check needs a non-empty summary from both sources")
problems: list[str] = []
drift = abs(ifc.total_area_m2 - dwg.total_area_m2) / max(dwg.total_area_m2, 1e-9)
if drift > area_tol:
problems.append(f"total area differs by {drift:.1%} "
f"({ifc.total_area_m2:.0f} vs {dwg.total_area_m2:.0f} m2)")
if abs(ifc.rooms - dwg.rooms) > room_tol:
problems.append(f"room count differs by {abs(ifc.rooms - dwg.rooms)} "
f"({ifc.rooms} vs {dwg.rooms})")
if set(ifc.levels) != set(dwg.levels):
problems.append(f"level sets differ: {sorted(set(ifc.levels) ^ set(dwg.levels))}")
for p in problems:
logger.warning("cross-check: %s", p)
return problems
The three checks fail in characteristic ways. Area drift usually means the section cut height
is wrong, or the drawing pipeline is including a circulation area the model treats as a separate
space. Room count drift usually means zone-level IfcSpace entities were not filtered, or the
drawing polygonizer merged rooms across a gap. Level set drift almost always means a mezzanine:
one pipeline called it a storey and the other did not.
None of these is necessarily a defect in either pipeline — the sources genuinely describe the building differently — but each one is a question worth answering before publication rather than after.
Comparison Reference
| Dimension | DWG / DXF | IFC |
|---|---|---|
| Units | $INSUNITS, often unset |
IfcUnitAssignment, always present |
| Levels | Inferred from layers or Z clustering | IfcBuildingStorey, explicit |
| Rooms | Polygonised from wall runs | IfcSpace, already bounded |
| Room names | Text anchors resolved by proximity | LongName attribute |
| Room types | Inferred from names | PredefinedType enum |
| Doors | Inferred from gaps in wall runs | IfcDoor with host wall |
| Geometry dimension | 2D | 3D, needs sectioning |
| Typical file size | 2-8 MB | 40-400 MB |
| Parse + geometry time | 3-5 s per level | 8-15 s per level |
| Coverage on a mixed estate | ~100% | 10-90% by building age |
| Failure mode | Missing rooms | Missing spaces entirely |
The file-size row has an operational consequence worth planning for: a federated hospital model can exceed a gigabyte, which changes how the ingest fetches and caches source files. Streaming from object storage per storey, rather than downloading whole models to worker disk, keeps the async batch pipeline memory-bounded in the way its design assumes.
Common Errors & Fixes
A building publishes with storeys and no rooms. A discipline model was ingested. Check for
IfcSpace at the front of the ingest and route to the drawing pipeline when there are none.
Room counts jump when a building moves from DWG to IFC. Usually zone-level spaces, and the
increase is characteristic: roughly 5-15% more “rooms”, each of them large and containing others.
Filter on PredefinedType and on the containment test described in
IFC & BIM model ingestion.
Total area drops on the IFC path. The section cut is catching a narrower part of tapered
spaces, or IfcSpace is modelled to the internal face of finishes while the drawing pipeline
polygonises to wall centrelines. The second is a genuine definitional difference of 2-5% and is
worth deciding once, portfolio-wide, rather than per building.
Both pipelines run and disagree, and nobody notices. Cross-checking has to be wired into the CI gate rather than run by hand, because the comparison is only useful before publication. A disagreement should block the build and name the specific check that failed.
Integration Point
The pipeline choice is recorded per building in its ingest record, not inferred fresh on each run.
That matters for reproducibility: a building that switched pipelines between builds would produce a
different topology_hash for identical geometry, which would invalidate every cached tile for no
reason. The record also carries the per-building decisions neither source supplies — the ground
storey override, the cut height if it deviates from the default, the wall-centreline versus
internal-face convention.
Both paths converge on geometry cleanup for the plausibility filters and the delta gate, and from there the building is indistinguishable from any other in the architecture and standards layers that follow.
Frequently Asked Questions
If a building has an IFC model, is there ever a reason to use the drawings?
Two, and both are about what the model covers rather than its quality. A refurbishment model often describes only the works — two floors of a twelve-storey building — while the drawings cover the whole thing, so the drawing pipeline is the only one that produces a complete map. And an as-designed model can be years out of date on a building that has been reconfigured since handover, where the current drawings reflect reality and the model reflects intent. Where both are current and complete, IFC wins on cost and richness every time.
Can I merge output from both pipelines for one building?
You can, and the seam is the hard part. Merging works cleanly when the split is by level — floors 3 and 4 from the model, the rest from drawings — because levels are independent and the only shared geometry is the vertical circulation. It works badly within a level, because the two sources disagree slightly about wall positions and room boundaries, and the reconciliation is manual. If you do merge, the vertical edges connecting an IFC-derived level to a drawing-derived one need explicit attention: both sides must agree on the stair and lift positions or the building splits into disconnected components at the seam.
Does IFC remove the need for the CI topology gate?
No, and expecting it to is the most common misplaced confidence about BIM sources. IFC guarantees that the model is internally consistent, not that the map derived from it is routable: sectioning can still produce a room whose only door was modelled at a different height, a mezzanine can still be indexed in a way that strands it, and a space can still be filtered out as a zone when it was a room. The reachability checks in the CI gate ask a question no source format answers, which is whether a person can get from any space to any other — so they earn their place regardless of where the geometry came from.
Related
- IFC & BIM Model Ingestion — the pipeline this page decides whether to use.
- Mapping IFC Storeys to Indoor Levels — the level convention both pipelines have to agree on.
- ezdxf vs. LibreDWG for Batch DWG Parsing — the equivalent choice inside the drawing pipeline.
This page is a companion to IFC & BIM Model Ingestion, part of the Automated Floor Plan Parsing & Vectorization section.