Hide menu
No Matches
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 Lab when generating thumbnails of imported 3D models:

CAD Exchanger thumbnail

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

This functionality is specific to Visualization Toolkit API. In case you don't have the latter component, use Image_Writer class to generate screenshots.

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:

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):

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
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

For technical reasons, the User-defined data feature is available only for C++.

Refer to Selection Handling Example to see feature usage and workaround for other languages.