CAD Exchanger SDK
Advanced techniques

Using pimpl pattern

Most classes used in the visualization component (including ModelPrs_SceneNode subclass) use the "pimpl" (private implementation) idiom. The class subclasses Base_PublicObject which has a shared pointer (Base_Handle) to a private implementation.

This allows to ensure binary compatibility with future versions as well as to pass the objects themselves by their copies, which are essentially shallow ones. For instance, in the following code snippet:

std::vector<ModelPrs_SceneNode> v;
ModelPrs_SceneNode aRootNode = ModelPrs_SceneNodeFactory::Create (anAssembly);
v.push_back (aRootNode);

placing aRootNode in the vector does not incur any deep copy.

Offscreen rendering and screenshot generation

In addition to platform-specific back-ends (and their respective viewports), CAD Exchanger SDK supports offscreen viewport.

Such a viewport can be particularly useful for screenshot generation. This functionality is used by CAD Exchanger GUI and CAD Exchanger Cloud when generating thumbnails of imported 3D models:

vis_cloud_thumbnail.png
CAD Exchanger Cloud dashboard

A code snippet for screenshot generation can be found in Offscreen component.

Asynchronous display

CAD Exchanger SDK, including its visualization component, intensively uses multi-threading in order to provide the best user experience.

The visualization component utilizes multi-threading in order to perform heavy-weight computations when preparing visual presentations of 3D models. This may include concurrent invoking the visualization mesher if the B-Rep representation has not been tessellated yet, populating internal data structures with triangles and colors, used for further rendering, etc. Rendering itself may also happen in a separate thread, distinct from the UI thread that invoked the display process.

The following diagram shows possible organization of the computations and other tasks:

vis_async_displaying.png
Gradual display of the 3D model while maintaining interactive UI

All this allows to balance the heavy-weight tasks among available compute resources on the system and to support responsive UI in the user’s application (including gradual display of large assemblies):

vis_displaying.gif

User-defined geometry data support

At the time of writing this User’s Guide, the CAD Exchanger SDK visualization component has been mainly tailored to display data specified via the ModelData classes API (such as ModelData_Model, ModelData_Assembly, ModelData_Part, ModelData_Shape for B-Reps, ModelData_PolyVertexSet for meshes, etc). However, internal implementation has been made flexible enough to enable custom data support. Future releases of CAD Exchanger SDK will provide additional API to directly support user-defined data when interim storage in the ModelData classes may be suboptimal.

User-defined scene node data support

Any application-specific can be attached to a scene node using ModelPrs_SceneNode::SetUserData(). Semantics and use of this data is entirely up to the user's application.

The following example demonstrates attaching a name and a centroid to a scene node which are used later on in a selection event:

class CustomData : public ModelPrs_SceneNode::Data
{
public:
CustomData (const Base_UTF16String& theName, const ModelData_Point& theCOG) : myName (theName), myCentroid (theCOG)
Base_UTF16String myName;
ModelData_Point myCentroid;
};
aNode.SetUserData (std::make_shared<CustomData> (aName, aCentroid));

For example this data may be useful when selection event occur:

void Visit (const ModelPrs_SceneNode& theNode) override // the node itself is selected
{
if (auto aCustomData = std::dynamic_pointer_cast<CustomData> (theNode.UserData()) {
auto c = aCustomData.myCentroid;
std::cout << "Selected node \"" << aCustomData.myName.ToUTF8().String().c_str()
<< "\" with centroid: (" << c.X() << ", " << c.Y() << ", " << c.Z() << ")" << std::endl;
}
}
See also
Hover and selection

Interoperability with user-defined 3D viewports

If the user’s application already utilizes certain 3D viewport to display own data then it is possible to make CAD Exchanger’s viewport to co-exist with that existing viewport.

To be added.