9.3 Component hierarchy
HOOPS Visualize uses a generic component hierarchy to represent third-party CAD models which feature topological entities. The component hierarchy is a way to organize the scene graph uniformly across disparate file formats. It also provides developers the ability to extend the capabilities of our importers, as well as to create entirely new importers in a way that is compatible with the Visualize scene graph. The HOOPS Exchange and Parasolid importers both use the component hierarchy.

The major parts of the hierarchy are described below:
Object name | Description |
---|---|
HPS::CADModel | The root entity of the 3D model. Files loaded with the HOOPS Exchange importer will have a root entity of type HPS::Exchange::CADModel. The Parasolid importer uses HPS::Parasolid::CADModel. |
HPS::Capture | A specific view of an object, including the camera, materials, transforms, etc. |
HPS::Filter | A collection of visibility settings for a HPS::CADModel |
HPS::*::Component | A complex object which can represent a variety of model components, including non-geometric components |
In general, components refer to Visualize objects, whereas entities refer to the underlying object of the model's native platform. However, there is not a perfect one-to-one mapping between components and entities. For example, some modeling APIs represent faces and edges as two separate entities, but Visualize groups the two into a single shell. For a list of all supported entities and their corresponding components, see the reference manual entry for HPS::Component.
Using a model browser
When loading a model using HOOPS Exchange, a common operation is to navigate the model hierarchy using a tree control. HOOPS Visualize does not provide such a control as part of its API, but you can see an example of one in use in the WPF or MFC sandboxes.
9.3.1 Utilizing the ComponentPath
A ComponentPath is an explicit list of components that form a path from an individual component to the top of the scene graph. A ComponentPath is very similar to a KeyPath, except that it forms a list of Component objects instead of Key objects (key path objects are discussed in section 1.2). If necessary, you can get a component path from a key path by calling CADModel::GetComponentPath().
When using GetComponentPath(), it is important to understand that only unambiguous portions of paths are returned. For example, consider the cube below – specifically, the edge between the red and green faces:

If you ask Visualize to return a path describing this edge, what should that component path look like? Since the component path is ordered leaf to root, it should start with the edge that was selected and should make its way towards the CADModel object. But as we go up the hierarchy we find that we have a problem: which face will be part of the path? The red or the green one?
The edge selected belongs to both faces, and there is no information provided to indicate whether the user is interested in the red one, the green one, or neither. The situation is ambiguous.
If you call GetComponentPath() with the PathType::Unique argument, it will only include unambiguous components in the component path. Therefore the path returned might look something like this:
- Edge / Shell / Connex / Body / RI BRep Model / Part Definition / P. Occurrence / Model
Visualize also provides an option to return a complete component path. What this means is that HPS will make an assumption as to which face the user needs in the example above. In this case, the returned path will look like this:
- Edge / Co-Edge / Loop / Face / Shell / Connex / Body / RI BRep Model / Part Definition / P. Occurrence / Model
Which face was returned in the above component path? The red or the green one? Visualize returns the face encountered first – therefore, the result is not guaranteed.
Managing component visibility
HPS::ComponentPath contains several utilities which allow you to show, hide, and isolate components at a high level. The visibility changes made by these functions are intended to be HPS::View local and transient so they will not be reflected in the model if exported. Calling HPS::ComponentPath::Hide() will force all geometry contained at or below that path to become invisible. Calling HPS::ComponentPath::Show() with the default options will force all geometry contained at or below that path to become visible. Calling HPS::ComponentPath::Isolate() with the default options will force all geometry contained at or below that path to become visible and force all other geometry in that HPS::CADModel to become invisible.

HPS::ComponentPath::Show() and HPS::ComponentPath::Isolate() also allow for more complex behavior. These functions take the enumeration HPS::Component::Visibility, which can be used to preserve the visibility of subcomponents under the specified path. The default value of HPS::Component::Visibility::PreserveNone indicates that we do not intend to preserve the visibilities of any subcomponents, resulting in every component underneath the specified path becoming visible. However, the HPS::ComponentPath being operated on may have hidden subcomponents defined by the model that we want to preserve. In this case, we can pass the value HPS::Component::Visibility::PreserveModelDefined which will make all geometry at or below the specified path visible except the geometry defined by the model as invisible.

In addition, HPS::ComponentPath::Show() and HPS::ComponentPath::Isolate() allow for preserving the visibility of subcomponents that were modified explicitly by previous calls to HPS::ComponentPath::Show() and HPS::ComponentPath::Hide(). Providing the value HPS::Component::Visibility::PreserveUserDefined indicates that any visibility changes made to subcomponents via HPS::ComponentPath::Show() and HPS::ComponentPath::Hide() should be preserved when performing the current operation.
Providing the value HPS::Component::Visibility::PreserveAll indicates that we want to preserve previous HPS::ComponentPath::Show() and HPS::ComponentPath::Hide() actions under the specified path in addition to preserving the visibility of any subcomponents defined by the model itself.

Limitations: Geometry modified by HPS::ComponentPath::Show(), HPS::ComponentPath::Hide(), and HPS::ComponentPath::Isolate() may not interact properly with other transparent geometry contained in the scene. If HPS::ComponentPath::Isolate() is called on an assembly containing only hidden subcomponents (and subcomponents visibility is preserved) the scene may become empty (unless the part being isolated contains geometry directly at the specified path).
Interacting with highlights
Performing highlights on HPS::ComponentPath requires special considerations when used in combination with HPS::ComponentPath::Show(), HPS::ComponentPath::Hide(), and HPS::ComponentPath::Isolate(). These functions internally use highlights to perform their transient visibility changes, and external highlights need to mirror some of the same highlight settings to work properly.
External highlights should be applied using the HPS::Drawing::Overlay::WithZValues overlay and should not contain visibility changes of their own as this may interfere with the visibility changes performed by HPS::ComponentPath::Show(), HPS::ComponentPath::Hide(), and HPS::ComponentPath::Isolate().
In addition, the external highlight should be passive, which can be enabled by HPS::HighlightOptionsKit::SetPassive(true).
Using transforms with Components
When working with components of types Exchange, Parasolid, and ExchangeParasolid, there are two data layers associated with any model: the Visualize scene graph, and the underlying PRC data. Making changes to the Visualize scene graph may produce a distinct visual result, but generally does not modify the PRC. For example, if you apply a transform to a segment which contains part of an Exchange model, then save the file, that transform will not be present in the saved model.
To make a transform to both the scene graph and to the PRC data, use Component::SetTransform(). The transform will be applied both visually and to the underlying native data.
Only certain types of components can have transforms applied to them:
-
For Exchange components, valid choices are components of type ExchangeProductOccurrence, or components which have the mask ExchangeRepresentationItemMask
- For Parasolid components, valid choices are components of any of these types: ParasolidAssembly, ParasolidInstance, and ParasolidTopoBody
NOTE: The transform set will REPLACE any existing transforms set on that component.
DeInstancing Components
Deinstancing a component refers to analyzing a geometry's HPS::ComponentPath to determine the level at which changes can be made without interefering with other instanced geometry. This is done using HPS::Factory::DeInstanceComponent, which is available for components of types Exchange, Parasolid, and ExchangeParasolid.
For example, imagine a model of a car which contains four wheels. Each wheel is just an instance of one original wheel geometry. When a user wants to move a wheel, setting a transform on the wheel itself will cause all four wheels to move.
To move just one wheel, you can collect a HPS::ComponentPath for the wheel you are interested in, then call HPS::Factory::DeInstanceComponent().
This function will analyze the path and return a component along it at which level it is safe to apply a transform, such that only the selected wheel will be affected.
Example usage: