Exchange Toolkit
|
If you are familiar with the Exchange API, then you have almost certainly seen this pattern before:
Most programmers would agree that this is verbose and error prone.
The Exchange Toolkit provides a solution to this pattern by exposing the macro A3D_HELPERS( A3D_VOID_TYPE ). This macro is expanded for many of the Exchange data types which results in a set of structs that can be used to read data from the Exchange API in a more concise way.
In order to make the concept more clear let's take a look at the following code snippet, which is similar to the code expansion of the macro A3D_HELPERS( A3DAsmModelFile ).
With this implementation, we now have easy access to the data from the Exchange API. If we rewrite the doSomething
code from above, it might look like this:
Or, if you want to go crazy with concise code, simply write:
The class ts3d::Instance provides additional functionality for computing "net attributes" that are based on a specific ts3d::InstancePath.
To understand this better, lets consider the specific example of a part that is instanced multple times in a model. A bolt is a great example of this because one bolt size is often used throughout a model, with each instance having a different world position.
The world position of each bolt instance is determined by the nodes of the assembly tree that contain it. Each node of the assembly tree imparts a local transformation, and once reaching the leaf node of the product structure, you arrive at a part instance of the bolt with some final accumulated transform.
Without the help of the Exchange Toolkit, one would have to write recursive code to traverse the assembly hierarchy. At each node of the traversal, you must obtain the node's transform and accumulate the transform with those previously encountered. To further complicate this task, A3DAsmProductOccurrence
objects store their transform in two different ways.
The ts3d::Instance class makes this task easier when used with the function ts3d::getNetMatrix(). Similarly, there are several attributes whose final (or "net") values are determined by the path taken through the assembly hierarchy to arrive at a particular leaf node.
Coupling this class with the Traversal functionality from exchange, you can easily obtain net attributes from individual parts by writing the following code:
The Exchange API often contains C-style arrays. The struct containing the array will typically have two data members, one for the pointer and another for the size of the array.
For convenience, the Exchange Toolkit provides the function ts3d::toVector for converting these arrays to std::vector objects.
As an example, the traditional implementation:
Can be rewritten as:
The Exchange API provides access to a tessellated representation of data in the form of triangles, triangle strips and triangle fans. There are variations of the form this data takes depending on the presence of per-vertex normal vectors, or texture coordinates. This variation results in about 12 different cases for parsing the tessellation.
Many tessellation-based use cases are concerned with triangle primitives only. Fans and strips must be decomposed, along with normal vectors and texture coordinates. This simplification of the Exchange data set can lead to confusion and is indeed error prone.
To address this challenge, the Exchange Toolkit provides some tools and objects making access to an index mesh much easier.
The class ts3d::RepresentationItemInstance is the entry point to obtaining the simplified tessellation data. Since represenation items contain the tessellation, this class requires a ts3d::InstancePath with a leaf node type that is a represenation item. Once constructed, used the method ts3d::RepresentationItemInstance::getTessellation() to obtain the data.
The Exchange toolkit provides an abstraction that simplifies access to the triangles that make up a topological face. The class that provides this functionality is ts3d::Tess3DInstance. This is a concrete implementation of ts3d::TessBaseInstance returned from the call to ts3d::RepresentationItemInstance::getTessellation(). From this object you can obtain a ts3d::TessFaceDataHelper object for each face.
Refer to this snippet of code extracted from examples/obj/main.cpp as an example of how this functionality can be used. This code writes the tessellation data to an OBJ file. Note the use of ts3d::Instance::getNetShow() and ts3d::getNetMatrix().
ts3d::TessFaceDataHelper provides a method for obtaining the loops of edges associated with the topological face it is associated with. ts3d::TessFaceDataHelper::loops() returns an ordered collection of ts3d::TessFaceDataHelper::TessLoop objects. Each TessLoop
contains an ordered collection of ts3d::TessFaceDataHelper::TessEdge objects. Each TessEdge
contains a visibility flag, and an order collection of index values for the points of the polyline representing the edge.