1.3 Type definitions
A3DSDKTypes.h* provides the most common fixed-size numeric types. They are used within the whole API:
Type | Description | C Type |
---|---|---|
A3DBool | Boolean descriptor. Can be A3D_TRUE or A3D_FALSE | char |
A3DUns8 | Unsigned integer type with width of exactly 8 bits | unsigned char |
A3DInt8 | Signed integer type with width of exactly 8 bits | char |
A3DUns16 | Unsigned integer type with width of exactly 16 bits | unsigned short |
A3DInt16 | Signed integer type with width of exactly 16 bits | short |
A3DInt32 | Signed integer type with width of exactly 32 bits | implementation dependent |
A3DInt32 | Signed integer type with width of exactly 32 bits | implementation dependent |
A3DDouble | IEEE 754 64-bits floating-point number | double |
A3DFloat | IEEE 754 32-bits floating-point number | float |
A3DVoid | Void type | void |
A3DPtr | Void pointer type type | void* |
A3DUTF8Char | UTF-8 character type | char* |
1.5 Architecture
HOOPS Exchange architecture is tightly coupled with its naming design. Most data of your HOOPS application are manipulated through entities, may they be PRC, features, BIM or any other entity type. An entity type consists in:
- an enumerator value within
A3DEEntityType
which is used to identify it as an entity. - a handle type which uniquely identifies the entity within the entire HOOPS application
- optionaly a data structure that is used to retrieve or edit the state of an entity.
On top of that, the API may provide each entity type with a set of CRUD-like functions which are used to manipulate the entity or its content. Not every entity types provide all of these functions. This is either because it would be irrelevant or because the operation is indirectly performed by another function.
The following table illustrates the strict naming convention used for an entity type with some examples:
Name | Handle type | A3DEEntityType | struct | Functions (Create , Get , Set , Delete ) |
---|---|---|---|---|
___ | A3D___ | kA3DType___ | A3D___Data | A3D___Create() , A3D___Get() , A3D___Set() , A3D___Delete() |
Model file | A3DAsmModelFile | kA3DTypeAsmModelFile | A3DAsmModelFileData | A3DAsmModelFileCreate() , A3DAsmModelFileGet() , A3DAsmModelFileDelete() |
BIM data | A3DBIMData | kA3DTypeBIMData | A3DBIMDataData | A3DBIMDataGet() |
NURBS Curve | A3DCrvNurbs | kA3DTypeCrvNurbs | A3DCrvNurbsData | A3DCrvNurbsCreate() , A3DCrvNurbsGet() |
Querying the entity type of a handle
When you hold an entity handle you don't know the underlying type, you can use A3DEntityGetType
and match its result to any value of A3DEEntityType
. The following example checks if pHandle
is a model file:
Retrieving the data of an entity
The most common operation performed on an entity is retrieving its data for reading. This is a 3-steps operation: initializing the data structure, retrieving the entity data, then disposing the data structure once not needed anymore. The following function retrieves the data of a product occurrence and prints the number of children product occurrences it contains:
Let's detail this code line by line. To initialize a data structure, declare it as a non-const variable use the A3D_INITIALIZE_DATA
macro:
Once the structure is initialized, use the Get function to retrieve the data. In the following line, pHandle
is of type const A3DAsmProductOccurrence*
.
Then, when the data is not needed anymore, give the data back to the API by calling the same function. Set the handle paremeter to 0.
- Note
- Why disposing the data structure? HOOPS Exchange structures may contains heap allocated data such as arrays and strings. It is essentials to remain memory consistent by letting the API releasing it. See the section about memory management for more.
Arrays as struct
fields
Various data fields are made available through lists, such as the product occurrences within a model file or the representation items making and A3DRiSet
. HOOPS Exchange provides lists using standard C sequential array types As such, arrays are represented by two fields: an A3DUns32
for the size of the array and a pointer for the array itself:
Some array size specifiers may be used to describe two or more arrays. It illustrates the tight coupling between the respective arrays.
Entity hierarchy
HOOPS architecture provides an abstraction/specialization mechanism for its entities. For example, all entities can be abstracted into an A3DEntity
type, while most entities are specializations of A3DRootBase
.
In practical, it means that when an entity can be abstracted into another, it can then be safely manipulated as the abstract type. Some of these abstract types have their own data structure. For example, any product occurrence (A3DAsmProductOccurrence
) is also a root base entity (A3DRootBase
). Thus this code is valid event if pHandle
is an A3DAsmProductOccurrence*
:
Conversely, it is possible to give a handle of type A3DRootBase*
to a function expecting an A3DAsmProductOccurrence*
. In that case, it is up to the caller to ensure the entity has the correct type. This example checks on pHandle
before sending it to PrintChildrenPO
from the above example:
Any API call using an unexpected entity type will return A3D_INVALID_ENTITY_TYPE
.
- Note
- The hierarchical point of view of entities can be confusing to some readers. Another way to express the relation between entity types is to view HOOPS Exchange as a database. In this example, the key
pHandle
would exist both in theProductOccurrence
and theA3DRootBase
tables.
Structural hierarchy
A lot of complex structures within Exchange are organiszed as trees. For example, the PRC tree contains all the entities that makes a model file. And the Feature tree organizes all steps performed by a CAD application to obtain the final part. Within such structures, an entity instance may be parent to one or more children entities.
While there is no direct relation between structural and types hierarchies, it's worth being mentionned that all entities of a same tree are usually specializations of a same entity type. For example, entities making a PRC tree can be A3DAsmProductOccurrence
, A3DRiRepresentationItemor
A3DRiPart<tt>(amongst others), but they are all specializations ofA3DRootBase`.
Memory management
As a C API, any runtime allocated memory must be explicitely freed after use. A lot of functions and data structure provide you with such memory. Even if it is HOOPS Exchange's responsibility to actually free it, it is the user application's to decide when.
The most common use case of memory disposal is with entity data retrieval. If its Get function allocates memory blocks, they are specific to this call. In the following example, sData0.m_pcName
and sData1.m_pcName
don't point to the same address space although the entity is the same. This is because internally, the Name of a root base is copied into the A3DRootBaseData parameter.
At the end of such code, sData0
and sData1
must be returned to the library so it can clean the memory properly. This is done by calling again A3DRootBaseGet
with 0 as the handle:
- Attention
- Even if a data structure does not contain heap allocated memory, it may not be the case for future versions of the API. Hence, to ensure robustness against code change and avoid difficult to track memory leaks, you should always dispose your data structure whatever its type is.
Some functions also provide heap-allocated memory through "out parameters". In this case, the documentation of the fonction provides the information about how to release it.
Providing the memory functions
If you want to control how memory is allocated within HOOPS API functions, you can set your own allocation and deallocation functions:
A3DDllSetCallbacksMemory
must be called before A3DDllInitialize
.
Deleting entities
Deleting an entity itself is not a common operation within HOOPS Exchange, but some types provide a deletion operation nevertheless.
When A3DModelFileDelete()
is called on a model file enitty, it is entirely dropped. That includes all A3DRootBase
that makes the PRC. Most of the time, this is the only deletion function to call.
The more general purpose A3DEntityDelete()
function can be called on a specific entity. It drops the entity itself as well as any child entities in the case of an A3DRootBase
. This function does not perform any check on the presence of the given entity somewhere in the PRC tree.
Some specific entities provide their own Delete() function:
A3DFaceUVPointInsideManagerDelete
A3DFileContextDelete
A3DMiscCascadedAttributesDelete
A3DMkpRTFDelete
A3DMkpRTFFieldDelete
A3DProjectPointCloudManagerDelete
Garbage collection
When the library is terminated, the deletion of the HOOPS context releases any remaining memory block. That includes internal buffers and unlinked entities.
Error Management
HOOPS provides error management through a status code return by all the functions. A value of A3D_SUCCESS
(0) means the function performed with no error. Otherwise, a non-zero value indicates an error. The list of all error codes can be found in A3DSDKErrorCodes.h as the A3DStatus
enumeration.
The same error code may have a different signfication according to the function returning it. For more information about a value returned by a specific call, check out the documentation of the function.
A3DMiscGetErrorMsg()
can be used to obtain a description of the error code:
String encoding
HOOPS uses standard C-String for character manipulation: in-memory sequential arrays with a null-termination character (*\0*).
When storing and manipulating character data, HOOPS Exchange uses UTF-8 encoding. As such, any function and structure requiring string as input should ensure it is converted correctly before being used. The API provides conversion utility functions:
A3DMiscUnicodeToUTF8
A3DMiscUTF16ToUTF8
A3DMiscUTF8ToUnicode
A3DMiscUTF8ToUTF16
1.2 API Conventions
HOOPS Exchange is a C API. Any source code including our headers are guaranteed compile using a C or C++ compliant compiler. For more information about compiler requirements, check out the platform requirements page.
Header files
All headers are located directly under the include/ folder of your HOOPS installation. Files are named using PascalCase, they all contain one of the following prefixes:
- A3DSDK for most of our SDK
- A3DPDF for file specific to HOOPS Publish SDK
- A3DCommon any code common to both APIs
The only exception is hoops_license.h. This file must be replaced with the one usually obtained from the license file generator.
All our header files contain only the declarations and inclusions they need to compile. They are also guaranteed self-sufficient, which mean they don't rely on the inclusion context to work properly, as long as the #include
directive is at global scope.
To compile a source file using HOOPS declaration, you only need to include the header file where the declaration is. For example, you just have to include A3DSDKStructure.h to compile a source using only the A3DAsmModelFileData
structure.
If you want to include all API header files at once, use the convenience header A3DSDKIncludes.h. This file is also included within A3DSDKLoader.h to make sure all functions are loaded properly upon initialization.
Naming conventions
The API uses PascalCase for symbol naming with the exception of macro definitions and A3DStatus
values which use CAPITAL_CASE. Variables, formal parameters and struct members follow a Systems Hungarian Notation for naming:
m_
for struct members, thenp
for pointer type, then- according on data type:
b
forA3DBool
i
forA3DInt8
,A3DInt16
andA3DInt32
ui
forA3DUns8
,A3DUns16
andA3DUns32
f
andd
forA3DFloat
andA3DDouble
respectivelyc
forA3DUTF8Char
e
for enumerationss
for structures
Namespacing
All data types and functions are namespaced using a list of concatenated prefixes. The leftmost prefix is A3D
and is always present. Then, successives prefixes are used to sub-namespace each functions. For example, A3DTess3DCreate()
and A3DTessMarkupCreate()
both have the same base name, but they are within the Tess3D
and TessMarkup
namespaces respectively.
Associated symbols use the same namespacing:
A3DAsmModelFile
: An entity handle representing an assembly model fileA3DAsmModelFileData
: A data structure describing a model fileA3DAsmModelFileLoadFromFile()
: A function loading a model file into memory