-
Notifications
You must be signed in to change notification settings - Fork 3
Description
I'm super content seeing this written down in a way like this. Here are some discussion points:
referencing virtual entities
I think this is a really interesting idea, but I'm not convinced it's necessary. Also I have some doubts about how well this would work with shared ownership where you don't necessarily own the full path, or intermediate nodes in that path get deleted?
What this provides is:
graph TD;
A-.->B;
C-.->B;
A.B-->Property1
C.B-->Property2
A-->Location;
B-->Geometry;
style A fill:#63c408
style B fill:#63c408
style C fill:#63c408
style A.B fill:#63c408,stroke-dasharray: 5 5,stroke-width:4px
style C.B fill:#63c408,stroke-dasharray: 5 5,stroke-width:4px
style Geometry fill:#08aec4
style Location fill:#08aec4
style Property1 fill:#08aec4
style Property2 fill:#08aec4
But in my mind it's equivalent to
graph TD;
A-.->B;
C-.->B;
A-->Property1
C-->Property2
A-->Location;
B-->Geometry;
style A fill:#63c408
style B fill:#63c408
style C fill:#63c408
style Geometry fill:#08aec4
style Location fill:#08aec4
style Property1 fill:#08aec4
style Property2 fill:#08aec4
The property then is not associated to B (in the context of A and C respectively) but to either A or C directly. But don't we say that's semantically equivalent due to the composing behaviour of the typing relationship?
which entities are "products"
In the IFC4 (and ECS without typing) it's trivial to query the model for all products (things to display in the 3d view).
Considering a diagram like this:
graph TD;
Window1:::E-.->WindowType;
Window2:::E-.->WindowType;
WindowType:::E-->Assembly:::C;
Assembly-->Frame:::E;
Assembly-->Glazing:::E;
Frame-->Placement1:::C;
Frame-->Assembly2:::C;
Assembly2-->Bar1:::E;
Assembly2-->Bar2:::E;
Bar1-.->BarType:::E;
Bar2-.->BarType:::E;
Bar1-->Placement6:::C;
Bar2-->Placement7:::C;
BarType-->Geometry4:::C;
Glazing-->Placement2:::C;
Glazing-->Geometry2:::C;
Wall:::E-->Placement3:::C;
Wall-->Geometry3:::C;
Wall-->Contains:::C;
Contains-->Window1:::E;
Contains-->Window2:::E;
Window1-->Placement4:::C;
Window2-->Placement5:::C;
classDef E fill:#63c408
classDef C fill:#08aec4
How do we know the elements to display are Wall Window1.Glazing Window2.Glazing Window1.Frame.Bar1 Window1.Frame.Bar2 Window2.Frame.Bar1 Window2.Frame.Bar2.
In my implementation I did:
- select all entities having a placement
- eliminate entities that are part of a type tree
- for each remaining: recursion over type and assembly to identify entities with geometry, concatenating the path to form a unique id
But does this wouldn't capture all possibilities to define a product?
If you compose/flatten before evaluating how can you still construct an id path to uniquely identify instanced geometry?
edit: this is not really a thing. the combination of assembly+typing causes subcomponent ids not being able to uniquely instantiate an object, but the evaluating the implications of typing pre or post querying doesn't affect this.
evaluation of the broken placement tree
As identified in the discussions, we agreed on definition relative positions as the primary information carrier on placements. But in the cases of typing we can't do that because the type can't relate back to its instance placements.
What I did in my implementations is:
- select all entities having a placement
- for each:
- recursion to identify entities with geometry
- concatenating the path to form a unique id
- recursion to identify entities with placement
- for all geometry paths:
- find placement paths that are a prefix of the geometry paths (in the dependency graph they are all placements at a higher rank than the geometry and thus affect the geometry).
- for all these placements:
- filter out the shared relative positions (because otherwise you'd apply placements multiple times. I couldn't get the back edges to render in mermaid with destroying the layout, but let's say Placement6 is relative to Placement1, in my list of placements you would get both Placement1 and Placement6 (which already contains Placement1 when evaluated). So essentially
((Placement3 x Placement4) x Placement1 x (Placement6 x Placement1)->(Placement3 x Placement4 x Placement1 x Placement6).
- filter out the shared relative positions (because otherwise you'd apply placements multiple times. I couldn't get the back edges to render in mermaid with destroying the layout, but let's say Placement6 is relative to Placement1, in my list of placements you would get both Placement1 and Placement6 (which already contains Placement1 when evaluated). So essentially
This requires some effort in documenting.
Can typing still be a component relationship?
Entity -> TypingComponent -> Entity instead of Entity -> Entity?
Because: How would you even express Entity -> Entity relationships, since components are the only data being exchanged.
Although I think I also understand that making it more "special" might help in understanding and implementation.
3 levels of schema
What I like a lot about the formalization of the composition described here is that we can provide three levels of schema, which greatly unifies what we currently do in IFC4!
- exchange (component header + payload)
- component (component payload types)
- usage patterns on composed graph
The last one requires some elaboration, but basically it completely eliminates the need for a separate technology that we used mvdXML for in the past.
Because if we have a schema on the composed graph we can use the kind of structural typing + data variants from e.g jsonschema to say things like:
- A stair is either an assembly of (railing, flight) or an element with a body geometry or ...
- A wall has an axis geometry and a body geometry
(This might require openapi's schema instead of basic jsonschema to have a discriminator field, i.e to map a type on a object based on the valuation of a field, classification in this case).
These layered kind of schemas don't need to have the same kind of severity. The last layer anyway can only be validated post composition so it doesn't really prevent import, but having these kind of usage patterns as first class entities in a proper schema language is potentially really powerful.