Exchange Toolkit
|
The Exchange data model is complex. It captures details about a model file such as assembly organization, attribute inheritance, PMI, geometry and tessellation. As a result, the code required to traverse the data model can be burdensome. Figure 1 illustrates a portion of this complexity as a UML diagram with recursive containers.
A direct approach for navigating the data structures to get to an object containing the information of interest typically involves writing one function per object type, with each implementation iterating over a child container and calling appropriate functions to traverse deeper into the hierarchy. This has the downside of complexity and function implementations that are just slight variations from one another, giving the feeling of code duplication. Another possible implementation is to employ the Visitor Design Pattern. This approach has a tendency of being overly complex and requires object inheritance, virtual function calls and a bloated interface if it is to cover the entirety of the Exchange data model.
The Exchange Toolkit solves this problem in a much simpler way.
The Exchange Toolkit addresses this challenge by first introducing the concept of an ts3d::EntityArray. This is nothing more than a typedef
of a standard ordered container of A3DEntity*
. An ordered container of generic "base class" pointers allows us to represent a particular path through the model's hierarchy. In the context of a path through the hierarchy, the alias ts3d::InstancePath is used.
Why is an InstancePath useful?
Throughought the Exchange Toolkit, you may encounter the term "leaf node". This simply refers to the last object in an instance path.
The Exchange Toolkit provides just three functions for easily traversing the entirety of the Exchange data model. They are:
ts3d::getLeafInstances( A3DEntity *owner, A3DEEntityType const &leaf_type )
This function is used to obtain instance paths from the owner
to all child objects of the type specified by leaf_type
. The result is a ts3d::InstancePathArray containing unique paths. The leaf entity object may appear multiple times via differing paths.
owner
object is not important. The traversal algorithm will begin at whatever level of the hierarchy you need.As an example of how this can be used, imagine you'd like to know the total number of parts in a model file. This would look something like this:
This count would include all instances of shared parts.
ts3d::getUniqueLeafEntities( A3DEntity *owner, A3DEEntityType const &leaf_type );
This function is used to obtain a set of unique child objects of type leaf_type
. The result is a ts3d::EntitySet containing all unique leaf entities. This function does not provide any information about how the hierarchy was traversed to arrive at these leaf objects.
As an example of how this can be used, here is a snippet from the attrib example. In this code, brep_model
is a ts3d::InstancePath containing a leaf object of type A3DRiBrepModel
.
Internally, the B-Rep model is traversed and all A3DTopoFace
objects are gathered and returned in an unordered set. In this sample, we don't need to know the path to each A3DTopoFace
in order to attach attributes, so this variation of the function is appropriate.
This overloaded variation can be used when you need a collection of unique child objects of a particular type and you want the instance paths for each occurrence. The final parameter instance_path_map
is used with each entity from the returned set as key values. The lookup returns an array of instance paths indicating the unique occurrences of the child object. The following code snippet from the bom example shows how to easily print a bill of materials.
Using samples/data/catiaV5/CV5_Micro_Engine/_micro engine.CATProduct
as input, this code writes the following lines to standard out: