Upgrade to Pro — share decks privately, control downloads, hide ads and more …

IFC5 Technical prototypes

IFC5 Technical prototypes

Thomas Krijnen

August 28, 2024
Tweet

More Decks by Thomas Krijnen

Other Decks in Technology

Transcript

  1. Prototype - v1 https:/ /github.com/AECgeeks/ecs-prototype Lessons learned: - type relationships

    (where components are ‘inherited’ from type to occurence) are necessary to maintain IFC<=4 functionality - type relationships are somewhat complex and deserve should not be modelled as regular components - id prefixing for instantiated ‘typical’ parts - name/tag as an additional key to bind a component to an entity (e.g RepresentationIdentifier, PropertySet.Name)
  2. Prototype – v2 https:/ /github.com/tomvandig/eccg Lessons learned: - Name prefix

    everything. Not just ‘typical parts’. - Think about composition at a fundamental level, not just as another ordinary component
  3. Prototype – v3 https:/ /github.com/tomvandig/schema-lang/tree/master - Universal tree in serialization

    simplifies composition for end-user and developer - Maintain a strict separation between naming+placement and domain-specific schema definitions. An element’s name path does not equate to it’s domain- specific decomposition path. - Classification only through components is sometimes somewhat painful - Importance of schemas and validation - Inclusion of layers as ‘conflict-free multi-author data composition’
  4. Prototype – v4 https:/ /github.com/aothms/ifc-usdj - USD-compatibility is possible without

    the bagage and platform inneutrality of C++ OpenUSD. - USD composition unifies several concepts that are currently expressed as schema-level mechanisms in IFC or ECS-based prototypes. Such as occurence-type, mapped-item and perhaps also property set relationships.
  5. Prototype – v5 A component-based reinterpretation of procedural geometry graphs

    is possible. Where components are universal triangle meshes, but with appropriate tagging their procedural role is annotated. NB: The geometry is still fully explicit and static. Akin to IFC4 ReferenceView (which was an inversion from complexity to reliability).
  6. #usda 1.0 ( upAxis = "Z" ) def Xform "wall"

    { matrix4d xformOp:transform = ( (0, -1, 0, 0), (1, 0, 0, ... uniform token[] xformOpOrder = ["xformOp:transform"] def Xform "ifc5" { def Mesh "body" { int[] faceVertexCounts = [3, 3, 3, 3, 3, 3, 3, 3... int[] faceVertexIndices = [3, 118, 117, 118, 3, ... point3f[] points = [(0.3, -0.3, 0), (9.7, -0.3, ... } def BasisCurves "directrix" { int[] curveVertexCounts = [2] point3f[] points = [(0, -0.3, 0), (0, -0.3, 3.5)] uniform token type = "linear" float[] widths = [0.01, 0.01] } def Mesh "basis" { int[] faceVertexCounts = [4] int[] faceVertexIndices = [0, 1, 2, 3] point3f[] points = [(0.3, -0.3, 0), (9.7, -0.3, ... } def "clip" { def Mesh "plane0" { int[] faceVertexCounts = [4] int[] faceVertexIndices = [0, 1, 2, 3] point3f[] points = [(-0.01, -0.31, 0.4942265... } def Mesh "plane1" { int[] faceVertexCounts = [4] int[] faceVertexIndices = [0, 1, 2, 3] point3f[] points = [(5, -0.31, 3.3867514), (... } } } def Xform "window" { matrix4d xformOp:transform = ( (1, 0, 0, 0), (0, 1, ... uniform token[] xformOpOrder = ["xformOp:transform"] def Xform "ifc5" { def Mesh "void" { int[] faceVertexCounts = [3, 3, 3, 3, 3, 3, ... int[] faceVertexIndices = [1, 0, 3, 2, 1, 3,... point3f[] points = [(-0.5, -0.115, 0.5), (-0... } } } }
  7. #usda 1.0 ( upAxis = "Z" ) def Xform "wall"

    { matrix4d xformOp:transform = ( (0, -1, 0, 0), (1, 0, 0, ... uniform token[] xformOpOrder = ["xformOp:transform"] def Xform "ifc5" { def Mesh "body" { int[] faceVertexCounts = [3, 3, 3, 3, 3, 3, 3, 3... int[] faceVertexIndices = [3, 118, 117, 118, 3, ... point3f[] points = [(0.3, -0.3, 0), (9.7, -0.3, ... } def BasisCurves "directrix" { int[] curveVertexCounts = [2] point3f[] points = [(0, -0.3, 0), (0, -0.3, 3.5)] uniform token type = "linear" float[] widths = [0.01, 0.01] } def Mesh "basis" { int[] faceVertexCounts = [4] int[] faceVertexIndices = [0, 1, 2, 3] point3f[] points = [(0.3, -0.3, 0), (9.7, -0.3, ... } def "clip" { def Mesh "plane0" { int[] faceVertexCounts = [4] int[] faceVertexIndices = [0, 1, 2, 3] point3f[] points = [(-0.01, -0.31, 0.4942265... } def Mesh "plane1" { int[] faceVertexCounts = [4] int[] faceVertexIndices = [0, 1, 2, 3] point3f[] points = [(5, -0.31, 3.3867514), (... } } } def Xform "window" { matrix4d xformOp:transform = ( (1, 0, 0, 0), (0, 1, ... uniform token[] xformOpOrder = ["xformOp:transform"] def Xform "ifc5" { def Mesh "void" { int[] faceVertexCounts = [3, 3, 3, 3, 3, 3, ... int[] faceVertexIndices = [1, 0, 3, 2, 1, 3,... point3f[] points = [(-0.5, -0.115, 0.5), (-0... } } } }
  8. #usda 1.0 ( upAxis = "Z" ) def Xform "wall"

    { matrix4d xformOp:transform = ( (0, -1, 0, 0), (1, 0, 0, ... uniform token[] xformOpOrder = ["xformOp:transform"] def Xform "ifc5" { def Mesh "body" { int[] faceVertexCounts = [3, 3, 3, 3, 3, 3, 3, 3... int[] faceVertexIndices = [3, 118, 117, 118, 3, ... point3f[] points = [(0.3, -0.3, 0), (9.7, -0.3, ... } def BasisCurves "directrix" { int[] curveVertexCounts = [2] point3f[] points = [(0, -0.3, 0), (0, -0.3, 3.5)] uniform token type = "linear" float[] widths = [0.01, 0.01] } def Mesh "basis" { int[] faceVertexCounts = [4] int[] faceVertexIndices = [0, 1, 2, 3] point3f[] points = [(0.3, -0.3, 0), (9.7, -0.3, ... } def "clip" { def Mesh "plane0" { int[] faceVertexCounts = [4] int[] faceVertexIndices = [0, 1, 2, 3] point3f[] points = [(-0.01, -0.31, 0.4942265... } def Mesh "plane1" { int[] faceVertexCounts = [4] int[] faceVertexIndices = [0, 1, 2, 3] point3f[] points = [(5, -0.31, 3.3867514), (... } } } def Xform "window" { matrix4d xformOp:transform = ( (1, 0, 0, 0), (0, 1, ... uniform token[] xformOpOrder = ["xformOp:transform"] def Xform "ifc5" { def Mesh "void" { int[] faceVertexCounts = [3, 3, 3, 3, 3, 3, ... int[] faceVertexIndices = [1, 0, 3, 2, 1, 3,... point3f[] points = [(-0.5, -0.115, 0.5), (-0... } } } }
  9. #usda 1.0 ( upAxis = "Z" ) def Xform "wall"

    { matrix4d xformOp:transform = ( (0, -1, 0, 0), (1, 0, 0, ... uniform token[] xformOpOrder = ["xformOp:transform"] def Xform "ifc5" { def Mesh "body" { int[] faceVertexCounts = [3, 3, 3, 3, 3, 3, 3, 3... int[] faceVertexIndices = [3, 118, 117, 118, 3, ... point3f[] points = [(0.3, -0.3, 0), (9.7, -0.3, ... } def BasisCurves "directrix" { int[] curveVertexCounts = [2] point3f[] points = [(0, -0.3, 0), (0, -0.3, 3.5)] uniform token type = "linear" float[] widths = [0.01, 0.01] } def Mesh "basis" { int[] faceVertexCounts = [4] int[] faceVertexIndices = [0, 1, 2, 3] point3f[] points = [(0.3, -0.3, 0), (9.7, -0.3, ... } def "clip" { def Mesh "plane0" { int[] faceVertexCounts = [4] int[] faceVertexIndices = [0, 1, 2, 3] point3f[] points = [(-0.01, -0.31, 0.4942265... } def Mesh "plane1" { int[] faceVertexCounts = [4] int[] faceVertexIndices = [0, 1, 2, 3] point3f[] points = [(5, -0.31, 3.3867514), (... } } } def Xform "window" { matrix4d xformOp:transform = ( (1, 0, 0, 0), (0, 1, ... uniform token[] xformOpOrder = ["xformOp:transform"] def Xform "ifc5" { def Mesh "void" { int[] faceVertexCounts = [3, 3, 3, 3, 3, 3, ... int[] faceVertexIndices = [1, 0, 3, 2, 1, 3,... point3f[] points = [(-0.5, -0.115, 0.5), (-0... } } } }
  10. Entity Component * Prim API Schema IsA Schema 1 parent

    1 * Schema Non-applied Single-applied Multi-applied ECS qualities of USD
  11. Observations Schema language is also USD. So you can compose

    on schema level as well (e.g publish Addenda and TC as new layers) Schema language is not very expressive in terms of constraining relationships or cardinality (but can be added as userdefined data in the schema for a bespoke validator). USD allows user-defined data on prims so things like PropertySingleValue (wrap user-defined data in a class) is not necessary. But standardized property sets can equally well be layered schemas.
  12. Observations We don’t necessarily need to define IsA schemas in

    IFC5 (it would make things a bit more OOPy with inheritance), we can stick to the existing USD ones and treat them as ‘entities’ in ECS. But it can be useful to constrain the possible application of API schemas (apiSchemaCanOnlyApplyTo). E.g so that we cannot apply a material to a property set. I feel this is an under explored part of using a pure ECS in a heterogeneous context. Placement needs to live directly on the Prim, because otherwise it doesn’t participate in the hierarchy.
  13. Observations Geometry is also not a APISchema, but would be

    named subprims (because e.g UsdGeomMesh is an IsA Schema). This is in fact beautiful because it allows to substitute geometry with decomposition. For property sets we need to choose between inheritance, schema relationships or subprims (or references which are inheritance + subprims).
  14. Observations The universal tree eliminates the need for a divide

    between rooted and non-rooted definitions. This is a massive opportunity to clean up duplicated constructs (e.g IfcProfileProperties). But is also a responsibility to form meaningful and consistent trees.