+ aContext->Erase(aTrihedron, Standard_True);
+ #ifdef TINSPECTOR
+ if (getCallBack()) getCallBack()->Remove(aTrihedron);
+ #endif
+ }
+}
+
+//**************************************************************
+void XGUI_Displayer::AddOrRemoveSelectedShapes(Handle(AIS_InteractiveContext) theContext,
+ const NCollection_DataMap<TopoDS_Shape,
+ NCollection_Map<Handle(AIS_InteractiveObject)>>& theShapesToBeSelected)
+{
+ NCollection_Map<Handle(AIS_InteractiveObject)> aCompsolidPresentations;
+ NCollection_Map<Handle(AIS_InteractiveObject)> aSelectedPresentations;
+
+ NCollection_List<Handle(SelectBasics_EntityOwner)> anActiveOwners;
+ theContext->MainSelector()->ActiveOwners(anActiveOwners);
+ NCollection_List<Handle(SelectBasics_EntityOwner)>::Iterator anOwnersIt (anActiveOwners);
+ Handle(SelectMgr_EntityOwner) anOwner;
+
+ /// It is very important to check that the owner is processed only once and has a map of
+ /// processed owners because SetSelected works as a switch.
+ /// If count of calls setSelectec is even, the object stays in the previous state
+ /// (selected, deselected)
+ /// OCCT: to write about the problem that active owners method returns one owner several times
+ QList<size_t> aSelectedIds; // Remember of selected address in order to avoid duplicates
+ for (; anOwnersIt.More(); anOwnersIt.Next()) {
+ anOwner = Handle(SelectMgr_EntityOwner)::DownCast (anOwnersIt.Value());
+ if (aSelectedIds.contains((size_t)anOwner.get()))
+ continue;
+ aSelectedIds.append((size_t)anOwner.get());
+
+ Handle(StdSelect_BRepOwner) BROwnr = Handle(StdSelect_BRepOwner)::DownCast(anOwner);
+ if (!BROwnr.IsNull() && BROwnr->HasShape()) {
+ const TopoDS_Shape& aShape = BROwnr->Shape();
+ if (aShape.IsNull())
+ continue;
+
+ Handle(ModuleBase_BRepOwner) aCustomOwner = Handle(ModuleBase_BRepOwner)::DownCast(anOwner);
+
+ NCollection_DataMap<TopoDS_Shape, NCollection_Map<Handle(AIS_InteractiveObject)> >
+ ::Iterator aShapeIt(theShapesToBeSelected);
+ for (; aShapeIt.More(); aShapeIt.Next()) {
+ const TopoDS_Shape& aParameterShape = aShapeIt.Key();
+ // In case of compound we cannot rely on simple comparison method.
+ // If the compound is generated by Group feature then this compound is alwais new.
+ // So, we have to compare content of these compounds
+
+ // isSame should be used here as it does not check orientation of shapes
+ // despite on isEqual of shapes or IsBound for shape in QMap. Orientation is
+ // different for Edges shapes in model shape and owner even if this is the same shape
+ if (ModuleBase_Tools::isSameShape(aParameterShape, aShape)) {
+ Handle(AIS_InteractiveObject) anOwnerPresentation =
+ Handle(AIS_InteractiveObject)::DownCast(anOwner->Selectable());
+ NCollection_Map<Handle(AIS_InteractiveObject)> aPresentations =
+ theShapesToBeSelected.Find(aParameterShape);
+ if (aPresentations.Contains(anOwnerPresentation)) {
+ theContext->AddOrRemoveSelected(anOwner, Standard_False);
+ anOwner->SetSelected(Standard_True);
+ // collect selected presentations to do not select them if compsolid is selected
+ if (!aSelectedPresentations.Contains(anOwnerPresentation))
+ aSelectedPresentations.Add(anOwnerPresentation);
+ }
+ }
+ else if (!aCustomOwner.IsNull()) { // CompSolid processing #2219
+ // shape of owner is compound, but shape to be selected is compsolid, so
+ // we need to compare shape to AIS presentation of owner(rule of the owner creation)
+ Handle(AIS_Shape) anOwnerPresentation =
+ Handle(AIS_Shape)::DownCast(anOwner->Selectable());
+ const TopoDS_Shape& aPresentationShape = anOwnerPresentation->Shape();
+ if (aParameterShape.IsSame(anOwnerPresentation->Shape()) &&
+ !aCompsolidPresentations.Contains(anOwnerPresentation))
+ aCompsolidPresentations.Add(anOwnerPresentation);
+ }
+ }
+ }
+ }
+ // select CompSolid presentations if their owners was not selected yet
+ NCollection_Map<Handle(AIS_InteractiveObject)>::Iterator anIt (aCompsolidPresentations);
+ for (; anIt.More(); anIt.Next()) {
+ if (aSelectedPresentations.Contains(anIt.Value()))
+ continue;
+ theContext->AddOrRemoveSelected(anIt.Value(), Standard_False);
+ }
+}
+
+//**************************************************************
+XGUI_SelectionActivate* XGUI_Displayer::selectionActivate() const
+{
+ return myWorkshop->selectionActivate();
+}
+
+//**************************************************************
+GeomPlanePtr XGUI_Displayer::getScreenPlane() const
+{
+ GeomPlanePtr aResult;
+ Handle(AIS_InteractiveContext) aContext = AISContext();
+ if (!aContext.IsNull()) {
+ Handle(V3d_Viewer) aViewer = aContext->CurrentViewer();
+ Handle(V3d_View) aView;
+ for (aViewer->InitActiveViews(); aViewer->MoreActiveViews(); aViewer->NextActiveViews()) {
+ aView = aViewer->ActiveView();
+ break;
+ }
+ if (!aView.IsNull()) {
+ double aEyeX, aEyeY, aEyeZ;
+ aView->Eye(aEyeX, aEyeY, aEyeZ);
+
+ double aProjX, aProjY, aProjZ;
+ aView->Proj(aProjX, aProjY, aProjZ);
+
+ GeomPointPtr aPnt = GeomPointPtr(new GeomAPI_Pnt(aEyeX, aEyeY, aEyeZ));
+ GeomDirPtr aDir = GeomDirPtr(new GeomAPI_Dir(aProjX, aProjY, aProjZ));
+
+ aResult = GeomPlanePtr(new GeomAPI_Pln(aPnt, aDir));
+ }
+ }
+ return aResult;
+}
+
+double XGUI_Displayer::getViewScale() const
+{
+ Handle(AIS_InteractiveContext) aContext = AISContext();
+ if (!aContext.IsNull()) {
+ Handle(V3d_Viewer) aViewer = aContext->CurrentViewer();
+ Handle(V3d_View) aView;
+ for (aViewer->InitActiveViews(); aViewer->MoreActiveViews(); aViewer->NextActiveViews()) {
+ aView = aViewer->ActiveView();
+ break;
+ }
+ return aView->Camera()->Scale();