Before I get into what is undoubtedly going to be a very controversial proposal (buckle in for a wall of text!)…
… when I first read the IFC specification about how geometries are shared, and read about the concept of mapped representations, and learned about mapped items, reuse of items within representations, possibly nested mapped representations, and cartesian transformation operator 3d (and its non-uniform variant) …
… I was really confused.
Fast forward to now, after a non-negligible amount of time poking at the spec: I get it, it’s an almost crazily flexible and nuanced shape reuse structure and as a result even after I think I understand it I still treat the potential nesting and detection of reused representations as a heavily complex part of any real coded implementation. In short:
- It was confusing when I first read it. It was scary to me, it probably scared other people too.
- I still treat it with caution now.
- Any further in-spec operations then multiply in complexity when you have to take into account this geometry and potential (non-uniform scaling) transformations (e.g. quantity take off, project libraries, type mapped representation reuse, colour fallbacks on material when the representation item isn’t styled, but still reused across objects…) - I can almost guarantee bugs in implementations once we really start poking at these scenarios …
- Out-of-spec operations, such as when Bob The Coder wants to build a script to extract and analyse BIM geometry explodes in complexity. Especially when you deal with native IFC authoring and you have to make decisions on how representations are shared and reused and modified. Usually, the only way to make sure I’m doing things right is to then test the result with a bunch of viewers - again, I can almost guarantee bugs in a lot of user-written scripts …
- Regardless of spec scope, it makes it less practical for humans to debug and understand, as multiple ways can be used to achieve similar things. (Esp. the hacks used as a workaround to incomplete or incorrect geolocation support - where the object placements are offset, the absolute coords are offset, the mapped items are offset, or a combination of the three…)
- I’m probably not the only one who feels this way. Raise your hand if this stuff makes you feel uneasy too!
In the spirit of proposing daring and possibly breaking changes for IFC5, I’d like to test the waters on how the community feels about a drastic simplification of representation reuse and representation transformations. I’d like to propose a few high level bullet points.
The purpose of all the following bullet points is to heavily simplify mapped representations. This will come at the cost of reduced flexibility and reduced efficiency. In exchange, I expect to gain a schema that is much less complex, easily scripted, easily learned by newcomers, less buggy implementations, easier to optimise coded implementations, and please please please let’s make geometry just easier overall so we can move on to more interesting data relationships.
- If geometry is reused, that means that they share the same construction type. End of story. See related discussion.
- A product definition shape must map either all of its representations, or none at all. Let’s get rid of “oh, body is mapped, box isn’t, footprint isn’t either but annotation is…” confusion.
- Just … delete MappedItem. Crazy, I know. But this is what leads to the majority of complexities in other operations. See related discussion. The
IfcMappedItem.MappingSource.MappingOrigin
will simply be part of theObjectPlacement
of the product / type product instead. - No scaling allowed. Scaling, which used to be in
IfcMappedItem.MappingTarget
, will be deleted, and instead buildingSMART should come up with a new strategy to represent scaling, alongside other complex geometry operations which have cascading effects downstream on other relationships (qto, costing, typing, structural analysis, energy modeling, normals for geometric analysis and handling materials and textures, backface culling for viewers…). Other complex geometry operations include mirroring and arraying. The sooner that scaling is ripped out of the shape representation tree, the less likely it is for arraying to enter there and make it even messier. - Remove MappingOrigin. Just use ObjectPlacement.
- No nested mapped representations.
To demonstrate how aggressive this proposal is, here is the current situation, with everything I have removed:
Here is the aggressively cleaned up proposal:
Also, a ton of diagrams can be simplified in the IFC spec too:
In words, here is how you’d explain the concept to a newcomer to IFC:
IFC products can have a local origin known as the object placement, which determines the insertion point of its geometry. Its geometry can have multiple visual representations belonging to different viewing contexts, such as 3D views, or 2D views. If a product is assigned to a typical construction type, it is possible to instead define the representations once only to that construction type. The product then inherits all of the construction type’s representations. The inherited representations from the construction type are inserted at the object placement of each product.
In the past, it would be:
So IFC products has an object placement and a product definition, which then has multiple representations. These representations may be unique to the product, or mapped. If it is mapped, it is likely but not guaranteed to be part of the construction type so don’t assume inheritance. Some representations may be mapped, but others may not, so you need to check each individually, and also don’t assume changing one representation from one context affects another, since it may or may not be equally mapped. Also, if it is mapped, you don’t know what type of geometry (e.g. brep vs solid) it is until you navigate through the nested mapped item. So the representation can have one or more items. Some of those might map to representations, some might not, I haven’t checked if there is a WR constraining this but mostly you’ll find they either all map or all don’t map, but I’m not 100% sure. So, assuming they map, the insertion point may first be transformed by a non-scaling matrix called the mapping origin. Then, the geometry itself may be transformed again by another matrix which may or may not be uniformly scaled. Also, this process may nest a few times. The final representation is the accumulated result of resolving the matrixes of all of these potentially mapped and unmapped items. Then finally you use the object placement. Also, don’t ask me how it affects quantity take off. Here’s some battle tested libraries to make sure you get it right.
So, thoughts and tomatoes? Maybe I’m totally off the mark here and everybody reckons the shape representation tree is fine as-is and maybe it’s just me …
P.S. a clarification that this proposal is an obvious trade off where we lose efficiency / flexibility, and gain schema simplicity. Also, note that I have mentioned some valid usecases such as mirroring, scaling, and (poor man’s non-parametric) arraying which in my proposal I do not mention how to handle these usecases. I think these usecases are still valid, and should not be removed… but just, should perhaps be handled a different way (which I don’t know how yet) that prevents ambiguity to downstream applications (qto, costing, typing). On the other hand, usecases such as reusing a door knob as a mapped item across many different IfcDoor types … well, we lose that. Tough luck.