+
+void XGUI_Displayer::appendResultObject(ObjectPtr theObject, AISObjectPtr theAIS)
+{
+ myResult2AISObjectMap[theObject] = theAIS;
+
+#ifdef DEBUG_DISPLAY
+ std::ostringstream aPtrStr;
+ aPtrStr << theObject.get();
+ qDebug(QString("display object: %1").arg(aPtrStr.str().c_str()).toStdString().c_str());
+ qDebug(getResult2AISObjectMapInfo().c_str());
+#endif
+}
+
+#ifdef _DEBUG
+std::string XGUI_Displayer::getResult2AISObjectMapInfo() const
+{
+ QStringList aContent;
+ foreach (ObjectPtr aObj, myResult2AISObjectMap.keys()) {
+ AISObjectPtr aAISObj = myResult2AISObjectMap[aObj];
+ std::ostringstream aPtrStr;
+ aPtrStr << "aObj = " << aObj.get() << ":";
+ aPtrStr << "anAIS = " << aAISObj.get() << ":";
+ aPtrStr << "[" << ModuleBase_Tools::objectInfo(aObj).toStdString().c_str() << "]";
+
+ aContent.append(aPtrStr.str().c_str());
+ }
+ return QString("myResult2AISObjectMap: size = %1\n%2\n").arg(myResult2AISObjectMap.size()).
+ arg(aContent.join("\n")).toStdString().c_str();
+}
+#endif
+
+void XGUI_Displayer::getPresentations(const ObjectPtr& theObject,
+ NCollection_Map<Handle(AIS_InteractiveObject)>& thePresentations)
+{
+ ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(theObject);
+ if (aResult.get()) {
+ AISObjectPtr aAISObj = getAISObject(aResult);
+ if (aAISObj.get() == NULL) {
+ // if result is a result of a composite feature, it is visualized by visualization of
+ // composite children, so we should get one of this presentations
+ ResultCompSolidPtr aCompSolid = std::dynamic_pointer_cast<ModelAPI_ResultCompSolid>(aResult);
+ if (aCompSolid.get() && aCompSolid->numberOfSubs() > 0) {
+ aAISObj = getAISObject(aCompSolid->subResult(0));
+ }
+ }
+ if (aAISObj.get() != NULL) {
+ Handle(AIS_InteractiveObject) anAIS = aAISObj->impl<Handle(AIS_InteractiveObject)>();
+ if (!anAIS.IsNull() && !thePresentations.Contains(anAIS))
+ thePresentations.Add(anAIS);
+ }
+ }
+ else {
+ FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theObject);
+ // find presentation of the feature
+ AISObjectPtr aAISObj = getAISObject(aFeature);
+ if (aAISObj.get() != NULL) {
+ Handle(AIS_InteractiveObject) anAIS = aAISObj->impl<Handle(AIS_InteractiveObject)>();
+ if (!anAIS.IsNull() && !thePresentations.Contains(anAIS))
+ thePresentations.Add(anAIS);
+ }
+ // find presentations of the feature results
+ std::list<ResultPtr> aResults;
+ ModelAPI_Tools::allResults(aFeature, aResults);
+ std::list<ResultPtr>::const_iterator anIt = aResults.begin(), aLast = aResults.end();
+ for (; anIt != aLast; ++anIt) {
+ AISObjectPtr aAISObj = getAISObject(*anIt);
+ if (aAISObj.get() != NULL) {
+ Handle(AIS_InteractiveObject) anAIS = aAISObj->impl<Handle(AIS_InteractiveObject)>();
+ if (!anAIS.IsNull() && !thePresentations.Contains(anAIS))
+ thePresentations.Add(anAIS);
+ }
+ }
+ }
+}
+
+void XGUI_Displayer::activateTrihedron(bool theIsActive)
+{
+ myIsTrihedronActive = theIsActive;
+ if (!myIsTrihedronActive) {
+ deactivateTrihedron(true);
+ }
+}
+
+void XGUI_Displayer::displayTrihedron(bool theToDisplay) const
+{
+ Handle(AIS_InteractiveContext) aContext = AISContext();
+ if (aContext.IsNull())
+ return;
+
+ Handle(AIS_Trihedron) aTrihedron = myWorkshop->viewer()->trihedron();
+
+ if (theToDisplay) {
+ if (!aContext->IsDisplayed(aTrihedron))
+ aContext->Display(aTrihedron,
+ 0 /*wireframe*/,
+ -1 /* selection mode */,
+ Standard_True /* update viewer*/,
+ Standard_False /* allow decomposition */,
+ AIS_DS_Displayed /* xdisplay status */);
+ #ifdef TINSPECTOR
+ if (getCallBack()) getCallBack()->Display(aTrihedron);
+ #endif
+
+ if (!isTrihedronActive())
+ deactivateTrihedron(false);
+ else
+ activate(aTrihedron, myActiveSelectionModes, false);
+ } else {
+ deactivateTrihedron(false);
+
+ aContext->Erase(aTrihedron, Standard_True);
+ #ifdef TINSPECTOR
+ if (getCallBack()) getCallBack()->Remove(aTrihedron);
+ #endif
+ }
+
+ updateViewer();
+}
+
+QIntList XGUI_Displayer::activeSelectionModes() const
+{
+ QIntList aModes;
+ foreach (int aMode, myActiveSelectionModes) {
+ // aMode < 9 is a Shape Enum values
+ aModes << ((aMode < 9)? AIS_Shape::SelectionType(aMode) : aMode);
+ }
+ return aModes;
+}
+
+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<long> 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((long)anOwner.get()))
+ continue;
+ aSelectedIds.append((long)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();
+ // 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 (aParameterShape.IsSame(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);
+ }
+}