Reselect sub shape of an AIS_Shape

Hello, what is the best way to select a sub-shape (TopoDS_Shape) of an AIS_Shape?
I want to do the reserve of what AIS_InteractiveContext::DetectedShape() gave me, starting from a state where nothing is selected in AIS_InteractiveContext and add a sub-selection using the API.

Best regards,
François.

Kirill Gavrilov's picture

There is a method AIS_InteractiveContext::AddOrRemoveSelected() to select (and highlight) or unselect specific Owner within Interactive Context. You may check if specific Owner is already selected or not through it's property SelectMgr_EntityOwner::IsSelected().

But I guess your main question is where to find SelectMgr_EntityOwner for a subshape (TopoDS_Shape)? When activating local selection modes, AIS_Shape::ComputeSelection(), or StdSelect_BRepSelectionTool to be precise, iterates over sub-shapes, creates individual StdSelect_BRepOwner (storing sub-shape as property StdSelect_BRepOwner::Shape()) and adds them to selection SelectMgr_Selection of active selection mode.

This routine creates transient StdSelect_BRepOwner objects, so that there is no map or some other structure which would directly return you a StdSelect_BRepOwner from TopoDS_Shape, as it is normally used in opposite way (a Shape is retrieved from picked Owner). To find such association, you may iterator over computed selections and find a match on your own (and fill in some lookup map in case if this has to be done many times):

Handle(AIS_InteractiveContext) theCtx;
Handle(AIS_Shape) aShape;
const int aVertSelMode = AIS_Shape::SelectionMode (TopAbs_VERTEX);
theCtx->Display (aShape, AIS_Shaded, aVertSelMode, false);

TopTools_IndexedMapOfShape aSubShapes;
TopExp::MapShapes (aShape->Shape(), TopAbs_VERTEX, aSubShapes);
TopoDS_Vertex aTestVertex = aSubShapes.First();

const Handle(SelectMgr_Selection)& aSel = aShape->Selection (aVertSelMode);
for (NCollection_Vector<Handle(SelectMgr_SensitiveEntity)>::Iterator aSelEntIter (aSel->Entities());
     aSelEntIter.More(); aSelEntIter.Next())
{
  const Handle(SelectMgr_EntityOwner)& anOwner = aSelEntIter.Value()->BaseSensitive()->OwnerId();
  Handle(StdSelect_BRepOwner) aBRepOwner = Handle(StdSelect_BRepOwner)::DownCast (anOwner);
  if (!aBRepOwner.IsNull()
   &&  aBRepOwner->Shape().IsEqual (aTestVertex)
   && !aBRepOwner->IsSelected())
  {
    theCtx->AddOrRemoveSelected (aBRepOwner, false);
    break;
  }
}

theCtx->CurrentViewer()->Redraw();

Each StdSelect_BRepOwner might be shared by more than one SelectMgr_SensitiveEntity (for instance, TopoDS_Wire will be decomposed into TopoDS_Edge).

Francois Lauzon's picture

Hello Kirill,
thank you for the information, I was able to implement re-selection of sub-shape using part of your answer.
The right way the sensitive could be explored back using the ::Selection() method is what I was looking for.

Thank you,
François.