Building Information Modeling
=============================

Building Information Modeling (BIM) is a process for generation and
management of physical and functional features of places. The main
exchange format for BIM is :doc:`IFC </start/format/ifc_reader>`. Other formats,
such as :doc:`Revit </start/format/revit_reader>` allow creation and manipulation of
BIM data.

HOOPS Exchange allows you to read BIM data from any IFC file. The BIM
API is available from the *A3DSDKBim.h* header.

Please note that BIM Data are not part of :doc:`PRC specifications </guide/basic_operations/prc_basics>`. As such, the only way to serialize them is
by using ``A3DAsmModelFileExportToIfcXMLFile()``.

Accessing the BIM Data
----------------------

:doc:`Once a model file is loaded </guide/basic_operations/load_model>`, the entry point for
BIM data is located within the instance of ``A3DAsmModelFileData``:

::

   typedef struct {
     // ...
     A3DBIMData* m_pBIMData;
     // ...
   } A3DAsmModelFileData;

.. note::

   BIM data reading is only available with IFC files and must be toggled on by setting ``A3DRWParamsIFCData::m_bReadRelationships`` to ``A3D_TRUE``.

``A3DBIMData`` is a :doc:`standard entity type </guide/start/api-conventions>`
(``A3DBIMDataData``/``A3DBIMDataGet()``). Within the ``A3DBIMDataData``
structure, all BIM-related types are abstracted away using the
``A3DBIMRoot`` entity. This means any ``A3DBIM*`` entity can be used as
an ``A3DBIMRoot`` entity (``A3DBIMRootData``/``A3DBIMRootGet()``).
Specialized data and getters are available according to the type.

Getting BIM Relationships
-------------------------

BIM relationships handle the various relationships of objects within a
model. The list of all relationships are contained within
``A3DBIMDataData::m_ppRelationships``, a :doc:`standard array </guide/start/api-conventions>` of ``A3DBIMRelationship`` entities.

To query the actual type of the relationship, use ``A3DEntityGetType``
on the array element. Then, call the specialized data function according
to its type. The following example focuses on the *Rel Aggregates*
relationship:

::

   void traverse_aggregates_rel(const A3DBIMDataData* bim_data)
   {
     A3DEEntityType entity_type = kA3DTypeUnknown;

     for(A3DUns32 rel_i = 0 ; rel_i < bim_data->m_uiRelationshipSize ; ++rel_i) {

       A3DEntityGetType(bim_data->m_ppRelationships[rel_i], &entity_type);

       if (entity_type == kA3DTypeBIMRelAggregates) {
         A3DBIMRelAggregatesData aggregates_data = A3D_MAKE_DATA(A3DBIMRelAggregatesData);

         A3DBIMRelAggregatesGet(bim_data->m_ppRelationships[rel_i], &aggregates_data);

         // Use rel aggregates data

         A3DBIMRelAggregatesGet(0, &aggregates_data);
       }
     }
   }

All relationship are represented as pairs of **relating** and
**related** elements. They either describe *one-to-one* or *one-to-many*
relationships where the relating element is ``m_pRelating`` and the
related elements is an array where size is ``m_uiRelatedElementSize``
and the pointer is ``m_ppRelatedElements``. Both relating and related
entity types depend on the relationship. In the case of a one-to-one
relationship, ``m_uiRelatedElementsSize`` is always *1* and
``m_ppRelatedElements`` can be used as a single pointer.

All relationship entities :doc:`strictly follow the API convention </guide/start/api-conventions>` where the
data ``EData`` of an entity ``E`` can be retrieved with a call to
``EGet(const E*, EData*)``.

Rel Aggregates
^^^^^^^^^^^^^^

========================= ============================== ============================ ============================
 Entity                    Entity enumeration type        Relating type                Related type               
========================= ============================== ============================ ============================
 ``A3DBIMRelAggregates``   ``kA3DTypeBIMRelAggregates``   ``A3DBIMObjectDefinition``   ``A3DBIMObjectDefinition`` 
========================= ============================== ============================ ============================

The aggregation is a *one-to-many* relationship representing a
whole/part composition. In this relationship, the *related elements* is
a list of ``A3DBIMObjectDefinition`` entities that makes a *whole*: the
*relating element* ``A3DBIMObjectDefinition``.

Rel Connects Path Elements
^^^^^^^^^^^^^^^^^^^^^^^^^^

=================================== ======================================== =================== ===================
 Entity                              Entity enumeration type                  Relating type       Related type      
=================================== ======================================== =================== ===================
 ``A3DBIMRelConnectsPathElements``   ``kA3DTypeBIMRelConnectsPathElements``   ``A3DBIMElement``   ``A3DBIMElement`` 
=================================== ======================================== =================== ===================

This *one-to-one* relationship provides connectivity information between
two path-based elements.

Rel Contained in Spatial Structure
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

========================================== =============================================== =================================== ===================
 Entity                                     Entity enumeration type                         Relating type                       Related type      
========================================== =============================================== =================================== ===================
 ``A3DBIMRelContainedInSpatialStructure``   ``kA3DTypeBIMRelContainedInSpatialStructure``   ``A3DBIMSpatialStructureElement``   ``A3DBIMProduct`` 
========================================== =============================================== =================================== ===================

This *one-to-many* relationship assigns elements to specific levels of a
segmented spatial project structure.

Specializations of the relating elements are available:

-  ``kA3DTypeBIMBuilding``
-  ``kA3DTypeBIMBuildingStorey``
-  ``kA3DTypeBIMSpace``
-  ``kA3DTypeBIMSite``

Rel Fills Element
^^^^^^^^^^^^^^^^^

=========================== ================================ ========================== ===========================
 Entity                      Entity enumeration type          Relating type              Related type              
=========================== ================================ ========================== ===========================
 ``A3DBIMRelFillsElement``   ``kA3DTypeBIMRelFillsElement``   ``A3DBIMOpeningElement``   ``A3DBIMBuildingElement`` 
=========================== ================================ ========================== ===========================

This *one-to-one* relationship describes an opening element (the
relating type) and another element that completely or partially fills it.

.. note::

   To read opening elements, ``A3DRWParamsIFCData::m_bReadOpeningElements`` must be set to ``A3D_TRUE``.

Rel Space Boundary
^^^^^^^^^^^^^^^^^^

============================ ================================= =================== =================
 Entity                       Entity enumeration type           Relating type       Related type    
============================ ================================= =================== =================
 ``A3DBIMRelSpaceBoundary``   ``kA3DTypeBIMRelSpaceBoundary``   ``A3DBIMElement``   ``A3DBIMSpace`` 
============================ ================================= =================== =================

This *one-to-one* relationship describes a space in an element using
boundaries. The relating element is the space itself, which is delimited
by the related element.

Rel Voids Element
^^^^^^^^^^^^^^^^^

=========================== ================================ ========================== ===================
 Entity                      Entity enumeration type          Relating type              Related type      
=========================== ================================ ========================== ===================
 ``A3DBIMRelVoidsElement``   ``kA3DTypeBIMRelVoidsElement``   ``A3DBIMOpeningElement``   ``A3DBIMElement`` 
=========================== ================================ ========================== ===================

.. note::

   To read opening elements, ``A3DRWParamsIFCData::m_bReadOpeningElements`` must be set to ``A3D_TRUE``.

The rel voids element describes an opening element that created a void
in a building element. It is a *one-to-one* relationship.

Rel Assigns To Group
^^^^^^^^^^^^^^^^^^^^

============================= ================================== ================= ============================
 Entity                        Entity enumeration type            Relating type     Related type               
============================= ================================== ================= ============================
 ``A3DBIMRelAssignsToGroup``   ``kA3DTypeBIMRelAssignsToGroup``   ``A3DBIMGroup``   ``A3DBIMObjectDefinition`` 
============================= ================================== ================= ============================

This *one-to-many* relationship describes the assignment of object
definitions to a group.