============ Highlighting ============ When using selection, `highlighting `_ is important visual feedback expected by the user. Like selection, highlighting can be applied at different levels (segment, entity, and subentity). In this section, we'll discuss highlighting by `KeyPath `_. A key path is like a fully-qualified filename - it is an unambiguous list of segment keys from the root segment to the selected segment. .. image:: images/turbine_subentity_selection.png Although not strictly necessary, the sandbox bundles highlighting into its subclassed ``SandboxHighlightOperator``. If you bring up ``SandboxHighlightOperator::HighlightCommon()``, you'll see the following code: .. code-block:: cpp HPS::HighlightOptionsKit highlight_options(HPS::HighlightOptionsKit::GetDefault()); highlight_options.SetStyleName("highlight_style"); highlight_options.SetSubentityHighlighting(SelectionLevel == HPS::Selection::Level::Subentity); highlight_options.SetOverlay(HPS::Drawing::Overlay::InPlace); The first two lines of code are building a highlight style using a `HPS::HighlightOptionsKit `_. In this case, the default options are being supplied by `HPS::HighlightOptionsKit::GetDefault `_ (this is where the orange color comes from). Next, the style is given the generic name "highlight_style", which is required. This way of building a style is sufficient for this simple application, but style needs can vary widely and be very complex. Please see our Programming Guide page on `highlight styles `_ for full details on building styles. Next, the code takes one of two paths depending on whether the current model is a CAD model or not. If it is a CAD model, you'll see the CAD data being highlighted as well as the geometry: .. code-block:: cpp if (!cad_model.Empty()) { // since we have a CADModel, we want to highlight the components, not just the Visualize geometry HPS::SelectionResultsIterator it = selection_results.GetIterator(); HPS::Canvas canvas = cview->GetCanvas(); while (it.IsValid()) { HPS::ComponentPath component_path = cad_model.GetComponentPath(it.GetItem()); if (!component_path.Empty()) { // Make the selected component get highlighted in the model browser highlight_options.SetNotification(true); component_path.Highlight(canvas, highlight_options); // if we selected PMI, highlight the associated components (if any) HPS::Component const & leaf_component = component_path.Front(); if (leaf_component.HasComponentType(HPS::Component::ComponentType::ExchangePMIMask)) { // Only highlight the Visualize geometry for the associated components, don't highlight the associated components in the model browser highlight_options.SetNotification(false); for (auto const & reference : leaf_component.GetReferences()) HPS::ComponentPath(1, &reference).Highlight(canvas, highlight_options); } } it.Next(); } } This code snippet shows the selected object grouped into an array with a `HPS::SelectionResultsIterator `_, then the highlight style is applied to each. However, if there is no CAD model, there are no additional components to highlight, so this simple code does this job: .. code-block:: cpp else { // since there is no CADModel, just highlight the Visualize geometry cview->GetCanvas().GetWindowKey().GetHighlightControl().Highlight(selection_results, highlight_options); HPS::Database::GetEventDispatcher().InjectEvent(HPS::HighlightEvent(HPS::HighlightEvent::Action::Highlight, selection_results, highlight_options)); } The last snippet shows the highlight style created in the first part being applied to those selected objects. The end of this function redraws the scene with the highlighted geometry by calling ``cview->Update()``. With few exceptions, HNP will not detect and update changes for you - so it is always important to call ``Update()`` whenever a redraw is needed. Keep in mind that very large models can be expensive to redraw, so use ``Update()`` accordingly! If your application requires logic in addition to highlighting, you can use the `HPS::SelectionResultsIterator `_ shown in the examples above to get the geometry keys that were selected. From there, any sort of logic can be built in to your operator to achieve your goals.