X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FXGUI%2FXGUI_Displayer.cpp;h=be4b2cee5cec3ddceb395fa7894554352f5375b2;hb=545fb9af2e7ff2640157173275c0bbacd94537d9;hp=7d4ae0012ba5db8b645726cedd4d3cc806ac92e1;hpb=761a8a239096a9b803d2143e814a57fbff081b94;p=modules%2Fshaper.git diff --git a/src/XGUI/XGUI_Displayer.cpp b/src/XGUI/XGUI_Displayer.cpp index 7d4ae0012..be4b2cee5 100644 --- a/src/XGUI/XGUI_Displayer.cpp +++ b/src/XGUI/XGUI_Displayer.cpp @@ -20,6 +20,7 @@ #include #include +#include #include #include @@ -36,6 +37,8 @@ #include #include +#include + #include #include @@ -44,7 +47,10 @@ const int MOUSE_SENSITIVITY_IN_PIXEL = 10; ///< defines the local context mouse selection sensitivity //#define DEBUG_DISPLAY -//#define DEBUG_ACTIVATE +#define DEBUG_ACTIVATE +//#define DEBUG_FEATURE_REDISPLAY +//#define DEBUG_SELECTION_FILTERS +//#define DEBUG_USE_CLEAR_OUTDATED_SELECTION // Workaround for bug #25637 void displayedObjects(const Handle(AIS_InteractiveContext)& theAIS, AIS_ListOfInteractive& theList) @@ -90,20 +96,12 @@ void XGUI_Displayer::display(ObjectPtr theObject, bool isUpdateViewer) if (isVisible(theObject)) { redisplay(theObject, isUpdateViewer); } else { -#ifdef DEBUG_DISPLAY - FeaturePtr aFeature = ModelAPI_Feature::feature(theObject); - if (aFeature.get() != NULL) { - qDebug(QString("display feature: %1, displayed: %2"). - arg(aFeature->data()->name().c_str()). - arg(displayedObjects().size()).toStdString().c_str()); - } -#endif AISObjectPtr anAIS; GeomPresentablePtr aPrs = std::dynamic_pointer_cast(theObject); bool isShading = false; if (aPrs.get() != NULL) { - anAIS = aPrs->getAISObject(AISObjectPtr()); + anAIS = aPrs->getAISObject(anAIS); } else { ResultPtr aResult = std::dynamic_pointer_cast(theObject); if (aResult.get() != NULL) { @@ -149,29 +147,21 @@ void XGUI_Displayer::display(ObjectPtr theObject, AISObjectPtr theAIS, Handle(AIS_InteractiveObject) anAISIO = theAIS->impl(); if (!anAISIO.IsNull()) { - myResult2AISObjectMap[theObject] = theAIS; - bool aCanBeShaded = ::canBeShaded(anAISIO); + appendResultObject(theObject, theAIS); + // In order to avoid extra closing/opening context SelectMgr_IndexedMapOfOwner aSelectedOwners; - if (aCanBeShaded) { - myWorkshop->selector()->selection()->selectedOwners(aSelectedOwners); - closeLocalContexts(false); - } aContext->Display(anAISIO, false); - aContext->SetDisplayMode(anAISIO, isShading? Shading : Wireframe, false); + if (isShading) + anAISIO->Attributes()->SetFaceBoundaryDraw( Standard_True ); + emit objectDisplayed(theObject, theAIS); bool isCustomized = customizeObject(theObject); if (isCustomized) aContext->Redisplay(anAISIO, false); - if (aCanBeShaded) { - openLocalContext(); - activateObjects(myActiveSelectionModes); - myWorkshop->selector()->setSelectedOwners(aSelectedOwners, false); - } - else - activate(anAISIO, myActiveSelectionModes); + activate(anAISIO, myActiveSelectionModes); } if (isUpdateViewer) updateViewer(); @@ -189,6 +179,7 @@ void XGUI_Displayer::erase(ObjectPtr theObject, const bool isUpdateViewer) if (anObject) { Handle(AIS_InteractiveObject) anAIS = anObject->impl(); if (!anAIS.IsNull()) { + emit beforeObjectErase(theObject, anObject); aContext->Remove(anAIS, isUpdateViewer); } } @@ -211,7 +202,7 @@ void XGUI_Displayer::redisplay(ObjectPtr theObject, bool isUpdateViewer) return; } if (aAIS_Obj != aAISObj) { - myResult2AISObjectMap[theObject] = aAIS_Obj; + appendResultObject(theObject, aAIS_Obj); } aAISIO = aAIS_Obj->impl(); } @@ -235,18 +226,22 @@ void XGUI_Displayer::redisplay(ObjectPtr theObject, bool isUpdateViewer) if (!aShapePrs.IsNull()) { std::shared_ptr aShapePtr = ModelAPI_Tools::shape(aResult); if (aShapePtr.get()) { - const TopoDS_Shape& aShape = aShapePrs->Shape(); - std::shared_ptr anAISShapePtr(new GeomAPI_Shape()); - anAISShapePtr->setImpl(new TopoDS_Shape(aShape)); - - isEqualShapes = aShapePtr->isEqual(anAISShapePtr); + const TopoDS_Shape& aOldShape = aShapePrs->Shape(); + isEqualShapes = aOldShape.IsEqual(aShapePtr->impl()); } } } // Customization of presentation bool isCustomized = customizeObject(theObject); + #ifdef DEBUG_FEATURE_REDISPLAY + //qDebug(QString("Redisplay: %1, isEqualShapes=%2, isCustomized=%3"). + // arg(!isEqualShapes || isCustomized).arg(isEqualShapes).arg(isCustomized).toStdString().c_str()); + #endif if (!isEqualShapes || isCustomized) { aContext->Redisplay(aAISIO, false); + #ifdef DEBUG_FEATURE_REDISPLAY + //qDebug(" Redisplay happens"); + #endif if (isUpdateViewer) updateViewer(); } @@ -263,6 +258,10 @@ void XGUI_Displayer::deactivate(ObjectPtr theObject) AISObjectPtr anObj = myResult2AISObjectMap[theObject]; Handle(AIS_InteractiveObject) anAIS = anObj->impl(); aContext->Deactivate(anAIS); +#ifdef DEBUG_USE_CLEAR_OUTDATED_SELECTION + aContext->LocalContext()->ClearOutdatedSelection(anAIS, true); + updateViewer(); +#endif } } @@ -323,7 +322,7 @@ void XGUI_Displayer::getModesOfActivation(ObjectPtr theObject, QIntList& theMode } } -void XGUI_Displayer::activateObjects(const QIntList& theModes) +void XGUI_Displayer::activateObjects(const QIntList& theModes, const QObjectPtrList& theObjList) { #ifdef DEBUG_ACTIVATE qDebug(QString("activate all features: theModes: %2, myActiveSelectionModes: %3"). @@ -345,19 +344,38 @@ void XGUI_Displayer::activateObjects(const QIntList& theModes) if (!aContext->HasOpenedContext()) return; + // we need to block the sort of the viewer selector during deactivate/activate because + // it takes a lot of time if there are a many objects are processed. It can be performed + // manualy after the activation is peformed + Handle(StdSelect_ViewerSelector3d) aSelector = aContext->LocalContext()->MainSelector(); + bool isUpdateSortPossible = !aSelector.IsNull() && aSelector->IsUpdateSortPossible(); + if (!aSelector.IsNull()) + aSelector->SetUpdateSortPossible(false); + //aContext->UseDisplayedObjects(); //myUseExternalObjects = true; + Handle(AIS_InteractiveObject) anAISIO; AIS_ListOfInteractive aPrsList; - ::displayedObjects(aContext, aPrsList); + if (theObjList.isEmpty()) + ::displayedObjects(aContext, aPrsList); + else { + foreach(ObjectPtr aObj, theObjList) { + if (myResult2AISObjectMap.contains(aObj)) + aPrsList.Append(myResult2AISObjectMap[aObj]->impl()); + } + } - Handle(AIS_Trihedron) aTrihedron; AIS_ListIteratorOfListOfInteractive aLIt(aPrsList); - Handle(AIS_InteractiveObject) anAISIO; for(aLIt.Initialize(aPrsList); aLIt.More(); aLIt.Next()){ anAISIO = aLIt.Value(); activate(anAISIO, myActiveSelectionModes); } + // restore the sorting flag and perform the sort of selection + if (!aSelector.IsNull()) { + aSelector->SetUpdateSortPossible(isUpdateSortPossible); + aSelector->UpdateSort(); + } } @@ -379,6 +397,10 @@ void XGUI_Displayer::deactivateObjects() for(aLIt.Initialize(aPrsList); aLIt.More(); aLIt.Next()){ anAISIO = aLIt.Value(); aContext->Deactivate(anAISIO); +#ifdef DEBUG_USE_CLEAR_OUTDATED_SELECTION + aContext->LocalContext()->ClearOutdatedSelection(anAISIO, true); + updateViewer(); +#endif } } @@ -398,7 +420,7 @@ bool XGUI_Displayer::isActive(ObjectPtr theObject) const return aModes.Extent() > 0; } -void XGUI_Displayer::setSelected(const QObjectPtrList& theResults, const bool isUpdateViewer) +void XGUI_Displayer::setSelected(const QList& theValues, bool isUpdateViewer) { Handle(AIS_InteractiveContext) aContext = AISContext(); if (aContext.IsNull()) @@ -406,19 +428,35 @@ void XGUI_Displayer::setSelected(const QObjectPtrList& theResults, const bool is if (aContext->HasOpenedContext()) { aContext->UnhilightSelected(); aContext->ClearSelected(); - foreach(ObjectPtr aResult, theResults) { - if (isVisible(aResult)) { - AISObjectPtr anObj = myResult2AISObjectMap[aResult]; - Handle(AIS_InteractiveObject) anAIS = anObj->impl(); - if (!anAIS.IsNull()) - aContext->SetSelected(anAIS, false); + //if (aSelected.size() > 0) { + foreach (ModuleBase_ViewerPrs aPrs, theValues) { + const TopoDS_Shape& aShape = aPrs.shape(); + if (!aShape.IsNull()) { + aContext->AddOrRemoveSelected(aShape, false); + } else { + ObjectPtr anObject = aPrs.object(); + ResultPtr aResult = std::dynamic_pointer_cast(anObject); + if (aResult.get() && isVisible(aResult)) { + AISObjectPtr anObj = myResult2AISObjectMap[aResult]; + Handle(AIS_InteractiveObject) anAIS = anObj->impl(); + if (!anAIS.IsNull()) { + // The methods are replaced in order to provide multi-selection, e.g. restore selection + // by activating multi selector widget. It also gives an advantage that the multi + // selection in OB gives multi-selection in the viewer + //aContext->SetSelected(anAIS, false); + // The selection in the context was cleared, so the method sets the objects are selected + aContext->AddOrRemoveSelected(anAIS, false); + } + } } } } else { aContext->UnhilightCurrents(); aContext->ClearCurrents(); - foreach(ObjectPtr aResult, theResults) { - if (isVisible(aResult)) { + foreach (ModuleBase_ViewerPrs aPrs, theValues) { + ObjectPtr anObject = aPrs.object(); + ResultPtr aResult = std::dynamic_pointer_cast(anObject); + if (aResult.get() && isVisible(aResult)) { AISObjectPtr anObj = myResult2AISObjectMap[aResult]; Handle(AIS_InteractiveObject) anAIS = anObj->impl(); if (!anAIS.IsNull()) @@ -430,7 +468,6 @@ void XGUI_Displayer::setSelected(const QObjectPtrList& theResults, const bool is updateViewer(); } - void XGUI_Displayer::clearSelected() { Handle(AIS_InteractiveContext) aContext = AISContext(); @@ -444,14 +481,17 @@ void XGUI_Displayer::eraseAll(const bool isUpdateViewer) { Handle(AIS_InteractiveContext) aContext = AISContext(); if (!aContext.IsNull()) { - foreach (AISObjectPtr aAISObj, myResult2AISObjectMap) { - // erase an object - Handle(AIS_InteractiveObject) anIO = aAISObj->impl(); - if (!anIO.IsNull()) - aContext->Remove(anIO, false); - } - if (isUpdateViewer) - updateViewer(); + foreach (ObjectPtr aObj, myResult2AISObjectMap.keys()) { + AISObjectPtr aAISObj = myResult2AISObjectMap[aObj]; + // erase an object + Handle(AIS_InteractiveObject) anIO = aAISObj->impl(); + if (!anIO.IsNull()) { + emit beforeObjectErase(aObj, aAISObj); + aContext->Remove(anIO, false); + } + } + if (isUpdateViewer) + updateViewer(); } myResult2AISObjectMap.clear(); } @@ -576,7 +616,7 @@ bool XGUI_Displayer::enableUpdateViewer(const bool isEnabled) return aWasEnabled; } -void XGUI_Displayer::updateViewer() +void XGUI_Displayer::updateViewer() const { Handle(AIS_InteractiveContext) aContext = AISContext(); if (!aContext.IsNull() && myEnableUpdateViewer) @@ -650,19 +690,10 @@ void XGUI_Displayer::setDisplayMode(ObjectPtr theObject, DisplayMode theMode, bo return; Handle(AIS_InteractiveObject) aAISIO = aAISObj->impl(); - bool aCanBeShaded = ::canBeShaded(aAISIO); - // In order to avoid extra closing/opening context SelectMgr_IndexedMapOfOwner aSelectedOwners; - if (aCanBeShaded) { - myWorkshop->selector()->selection()->selectedOwners(aSelectedOwners); - closeLocalContexts(false); - } aContext->SetDisplayMode(aAISIO, theMode, false); - if (aCanBeShaded) { - openLocalContext(); - activateObjects(myActiveSelectionModes); - myWorkshop->selector()->setSelectedOwners(aSelectedOwners, false); - } + // Redisplay in order to update new mode because it could be not computed before + aContext->Redisplay(aAISIO, false); if (toUpdate) updateViewer(); } @@ -692,7 +723,17 @@ void XGUI_Displayer::addSelectionFilter(const Handle(SelectMgr_Filter)& theFilte if (theFilter.Access() == aIt.Value().Access()) return; } - GetFilter()->Add(theFilter); + Handle(SelectMgr_CompositionFilter) aCompFilter = GetFilter(); + const SelectMgr_ListOfFilter& aStoredFilters = aCompFilter->StoredFilters(); + for (aIt.Initialize(aStoredFilters); aIt.More(); aIt.Next()) { + if (theFilter.Access() == aIt.Value().Access()) + return; + } + aCompFilter->Add(theFilter); +#ifdef DEBUG_SELECTION_FILTERS + int aCount = GetFilter()->StoredFilters().Extent(); + qDebug(QString("addSelectionFilter: filters.count() = %1").arg(aCount).toStdString().c_str()); +#endif } void XGUI_Displayer::removeSelectionFilter(const Handle(SelectMgr_Filter)& theFilter) @@ -700,7 +741,13 @@ void XGUI_Displayer::removeSelectionFilter(const Handle(SelectMgr_Filter)& theFi Handle(AIS_InteractiveContext) aContext = AISContext(); if (aContext.IsNull()) return; - GetFilter()->Remove(theFilter); + Handle(SelectMgr_AndFilter) aCompositeFilter = GetFilter(); + if (aCompositeFilter->IsIn(theFilter)) + aCompositeFilter->Remove(theFilter); +#ifdef DEBUG_SELECTION_FILTERS + int aCount = GetFilter()->StoredFilters().Extent(); + qDebug(QString("removeSelectionFilter: filters.count() = %1").arg(aCount).toStdString().c_str()); +#endif } void XGUI_Displayer::removeFilters() @@ -745,20 +792,67 @@ void XGUI_Displayer::activate(const Handle(AIS_InteractiveObject)& theIO, if (aContext.IsNull() || theIO.IsNull()) return; - aContext->Load(theIO, -1, true); - aContext->Deactivate(theIO); + // deactivate object in all modes, which are not in the list of activation + // It seems that after the IO deactivation the selected state of the IO's owners + // is modified in OCC(version: 6.8.0) and the selection of the object later is lost. + // By this reason, the number of the IO deactivate is decreased and the object is deactivated + // only if there is a difference in the current modes and the parameters modes. + // If the selection problem happens again, it is possible to write a test scenario and create + // a bug. The bug steps are the following: + // Create two IO, activate them in 5 modes, select the first IO, deactivate 3 modes for both, + // with clicked SHIFT select the second object. The result is the selection of the first IO is lost. + TColStd_ListOfInteger aTColModes; + aContext->ActivatedModes(theIO, aTColModes); + TColStd_ListIteratorOfListOfInteger itr( aTColModes ); + QIntList aModesActivatedForIO; + //bool isDeactivated = false; + for (; itr.More(); itr.Next() ) { + Standard_Integer aMode = itr.Value(); + if (!theModes.contains(aMode)) { +#ifdef DEBUG_ACTIVATE + qDebug(QString("deactivate: %1").arg(aMode).toStdString().c_str()); +#endif + aContext->Deactivate(theIO, aMode); + //isDeactivated = true; + } + else { + aModesActivatedForIO.append(aMode); +#ifdef DEBUG_ACTIVATE + qDebug(QString(" active: %1").arg(aMode).toStdString().c_str()); +#endif + } + } +#ifdef DEBUG_USE_CLEAR_OUTDATED_SELECTION + if (isDeactivated) { + aContext->LocalContext()->ClearOutdatedSelection(theIO, true); + updateViewer(); + } +#endif + // loading the interactive object allowing the decomposition + if (aTColModes.IsEmpty()) + aContext->Load(theIO, -1, true); + + // trihedron AIS check should be after the AIS loading. + // If it is not loaded, it is steel selectable in the viewer. Handle(AIS_Trihedron) aTrihedron = Handle(AIS_Trihedron)::DownCast(theIO); - //Deactivate trihedron which can be activated in local selector if (aTrihedron.IsNull()) { - //aContext->Load(anAISIO, -1, true); - // In order to clear active modes list + //aContext->Load(anAISIO, -1, true); + // In order to clear active modes list if (theModes.size() == 0) { //aContext->Load(anAISIO, 0, true); aContext->Activate(theIO); + #ifdef DEBUG_ACTIVATE + qDebug("activate in all modes"); + #endif } else { foreach(int aMode, theModes) { //aContext->Load(anAISIO, aMode, true); - aContext->Activate(theIO, aMode); + if (!aModesActivatedForIO.contains(aMode)) { + aContext->Activate(theIO, aMode); + #ifdef DEBUG_ACTIVATE + qDebug(QString("activate: %1").arg(aMode).toStdString().c_str()); + #endif + } } } } @@ -787,3 +881,46 @@ bool XGUI_Displayer::customizeObject(ObjectPtr theObject) } return aCustomPrs->customisePresentation(aResult, anAISObj, myCustomPrs); } + + +QColor XGUI_Displayer::setObjectColor(ObjectPtr theObject, const QColor& theColor, bool toUpdate) +{ + if (!isVisible(theObject)) + return Qt::black; + + AISObjectPtr anAISObj = getAISObject(theObject); + int aR, aG, aB; + anAISObj->getColor(aR, aG, aB); + anAISObj->setColor(theColor.red(), theColor.green(), theColor.blue()); + if (toUpdate) + updateViewer(); + return QColor(aR, aG, aB); +} + +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 +} + +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").arg(myResult2AISObjectMap.size()). + arg(aContent.join("\n")).toStdString().c_str(); +}