===============================================
Defining Root-Level Attributes for a PRC Entity
===============================================

The Exchange API lets you create a set of attributes named root-level attributes that can be applied to any PRC entity.
These attributes are packaged as an A3DRootBase entity that is referenced from the PRC entity they describe.

* `**A3DRootBaseData**`. This structure has a name and can have pointers to multiple `A3DMiscAttribute` entities.
* `**A3DMiscSingleAttributeData**`. This structure is used for modeler data, such as string or time.
  It has a title, a type designation, and data.
  The name in the parent `A3DMiscAttributeData` must match the title in the `A3DMiscSingleAttributeData`.
  This structure is terminal.

.. note::

   See the Exchange API Reference for limitations on including modeler data in the root-level attributes for a PRC entity.

Here is a diagram that shows the structure of the A3DRootBase entity that can be associated with any PRC entity.
The `A3DMiscSingleAttributeData` structures are used only for modeler attributes.
The sample code that comes after the following task descriptions exemplifies this structure.

.. image:: /_assets/images/A3D_API_ProgGuide_29.1.jpg

******************************************************
Define Miscellaneous Attributes That Omit Modeler Data
******************************************************

* Determine the string to use at the top level of the attributes and (optionally) the strings to use at subordinate levels.
* Declare an array to accommodate pointers to the `A3DMiscAttribute` entities that you will create in a subsequent step.
* For each subordinate-level string, declare and initialize an `A3DMiscAttributeData` structure. Set the `m_pcTitle` member to the subordinate-level string. Leave the `m_uiSize` and `m_pSingleAttributesData` members set to 0 because this structure omits modeler data.

  * Package each `A3DMiscAttributeData` structure as an `A3DMiscAttribute` entity by invoking the `A3DMiscAttributeCreate` function. Save the entity pointer in the array created in Step 2.
  * Declare and initialize an `A3DRootBaseData` structure. Set its `m_pcName` member to the top-level string. Set the `m_ppAttributes` member to reference the array that contains pointers to the `A3DMiscAttribute` entities.
  * Invoke the `A3DRootBaseSet` function to package the `A3DRootBaseData` structure as an `A3DRootBase` entity associated with a PRC entity. The first argument in this call is a pointer to the entity, and the second is a pointer to the `A3DRootBaseData` structure.

*********************************************************
Define Miscellaneous Attributes That Include Modeler Data
*********************************************************

* Determine the strings to use for modeler data and the type represented by each string. Here are the possible types and the enumerations that identify them:

  * `kA3DModellerAttributeTypeInt` integer (32 bits)
  * `kA3DModellerAttributeTypeReal` floating point
  * `kA3DModellerAttributeTypeTime` integer (32 bits), which uses the same conventions as the `time_t` C data type.
  * `kA3DModellerAttributeTypeString` UTF-8 character string

* Determine the titles to use for each piece of modeler data.
* Declare an array to accommodate pointers to the `A3DMiscAttributeData` entities that you will create in a subsequent step.
* For each modeler attribute associated with the root base entity, do the following:

  * Declare and initialize an `A3DMiscSingleAttributeData` structure. Set the `m_eType` member to the type of the data, set the `m_pcData` member to a string that represents the data, and set the `m_pcTitle` member to a title that identifies the data.
  * Declare and initialize an `A3DMiscAttributeData` structure. Set the `m_pcTitle` member to the same title used in the `A3DMiscSingleAttributeData` structure. Set the `m_uiSize` member to 1, and the `m_pSingleAtttributesData` member to reference the `A3DMiscSingleAttributeData` structure.

**NOTE:**  Each `A3DMiscSingleAttributeData` structure that references another `A3DMiscSingleAttributeData` structure must reference only one such structure and must have the same title as that structure.

* Package each `A3DMiscAttributeData` structure as an `A3DMiscAttribute` entity by invoking the `A3DMiscAttributeCreate` function. Save the entity pointer in the array created in Step 3.

* Declare and initialize an `A3DRootBaseData` structure. (See Step 5 in :doc:`building_prc_6`.)

* Package the `A3DRootBaseData` structure as an `A3DRootBase` entity. (See Step 6 in :doc:`building_prc_6`.)

The following sample code creates base root attributes that describe three sets of modeler data.
For information about the relationships between the structures and entities that represent this data, see the diagram provided in :doc:`building_prc_6`.

.. code-block:: c

   A3DVoid setAttributes(A3DEntity* p)
   {
           A3DMiscSingleAttributeData Single = A3D_MAKE_DATA(A3DMiscSingleAttributeData);
           Single.m_eType = kA3DModellerAttributeTypeString;
           Single.m_pcTitle = "Title";
           Single.m_pcData = "Simple B-rep building demonstration";

           A3DMiscAttributeData sAttribs = A3D_MAKE_DATA(A3DMiscAttributeData);
           sAttribs.m_pcTitle = Single.m_pcTitle;
           sAttribs.m_pSingleAttributesData = &Single;
           sAttribs.m_uiSize = 1;
           A3DInt32 iRet = A3DMiscAttributeCreate(&sAttribs, &pAttr[0]);

           Single.m_pcTitle = "Author";
           Single.m_pcData = "HOOPS Exchange";
           sAttribs.m_pcTitle = Single.m_pcTitle;
           iRet = A3DMiscAttributeCreate(&sAttribs, &pAttr[1]);

           Single.m_pcTitle = "Company";
           Single.m_pcData = "Tech Soft 3D";
           sAttribs.m_pcTitle = Single.m_pcTitle;
           iRet = A3DMiscAttributeCreate(&sAttribs, &pAttr[2]);

           A3DRootBaseData sRootData = A3D_MAKE_DATA(A3DRootBaseData);
           sRootData.m_pcName = "Trimmed surface";
           sRootData.m_ppAttributes = pAttr;
           sRootData.m_uiSize = 3;
           iRet = A3DRootBaseSet(p, &sRootData);

           for(A3DUns32 i = 0; i < sRootData.m_uiSize; ++i)
           {
                   A3DEntityDelete(sRootData.m_ppAttributes[i]);
           }
   }

