From 2302f15a8daf85b03bacc97fe20810f4fedec3c5 Mon Sep 17 00:00:00 2001 From: nds Date: Wed, 10 Feb 2016 10:52:43 +0300 Subject: [PATCH] 2.17. Improved management of overconstraint situation: VPA correction in symbol prs to fill it with color like by highlighting --- src/ModuleBase/ModuleBase_IModule.h | 5 ++ src/PartSet/PartSet_Module.cpp | 48 +++++++++++++++++++ src/PartSet/PartSet_Module.h | 4 ++ .../PartSet_OverconstraintListener.cpp | 32 ++----------- src/PartSet/PartSet_OverconstraintListener.h | 5 -- src/SketcherPrs/SketcherPrs_SymbolPrs.cpp | 39 ++++++++++++++- src/SketcherPrs/SketcherPrs_SymbolPrs.h | 3 +- src/XGUI/XGUI_CustomPrs.cpp | 18 +++---- src/XGUI/XGUI_CustomPrs.h | 10 ++++ 9 files changed, 115 insertions(+), 49 deletions(-) diff --git a/src/ModuleBase/ModuleBase_IModule.h b/src/ModuleBase/ModuleBase_IModule.h index a37a49c8c..da7ed2b31 100755 --- a/src/ModuleBase/ModuleBase_IModule.h +++ b/src/ModuleBase/ModuleBase_IModule.h @@ -10,6 +10,7 @@ #include #include +#include #include #include @@ -182,6 +183,10 @@ class MODULEBASE_EXPORT ModuleBase_IModule : public QObject virtual void deactivateCustomPrs(const ModuleBase_CustomizeFlag& theFlag, const bool theUpdateViewer) {} + /// Modifies the given presentation in the custom way. + virtual bool customisePresentation(ResultPtr theResult, AISObjectPtr thePrs, + GeomCustomPrsPtr theCustomPrs) { return false; }; + /// Update the object presentable properties such as color, lines width and other /// If the object is result with the color attribute value set, it is used, /// otherwise the customize is applyed to the object's feature if it is a custom prs diff --git a/src/PartSet/PartSet_Module.cpp b/src/PartSet/PartSet_Module.cpp index 7067a7819..e49ff2ce1 100755 --- a/src/PartSet/PartSet_Module.cpp +++ b/src/PartSet/PartSet_Module.cpp @@ -61,6 +61,7 @@ #include #include #include +#include #include #include @@ -778,6 +779,53 @@ void PartSet_Module::deactivateCustomPrs(const ModuleBase_CustomizeFlag& theFlag myCustomPrs->deactivate(theFlag, theUpdateViewer); } +bool PartSet_Module::customisePresentation(ResultPtr theResult, AISObjectPtr thePrs, + std::shared_ptr theCustomPrs) +{ + bool aCustomized = false; + + if (theResult.get()) + return aCustomized; + + XGUI_ModuleConnector* aConnector = dynamic_cast(myWorkshop); + XGUI_Workshop* aWorkshop = aConnector->workshop(); + XGUI_Displayer* aDisplayer = aWorkshop->displayer(); + ObjectPtr anObject = aDisplayer->getObject(thePrs); + if (anObject.get()) { + bool isConflicting = myOverconstraintListener->isConflictingObject(anObject); + // customize sketcy symbol presentation + if (thePrs.get()) { + Handle(AIS_InteractiveObject) anAISIO = thePrs->impl(); + if (!anAISIO.IsNull()) { + if (!Handle(SketcherPrs_SymbolPrs)::DownCast(anAISIO).IsNull()) { + Handle(SketcherPrs_SymbolPrs) aPrs = Handle(SketcherPrs_SymbolPrs)::DownCast(anAISIO); + if (!aPrs.IsNull()) { + std::vector aColor; + myOverconstraintListener->getConflictingColor(aColor); + aPrs->SetConflictingConstraint(isConflicting, aColor); + aCustomized = true; + } + } + } + } + // customize sketch dimension constraint presentation + if (!aCustomized) { + std::vector aColor; + if (isConflicting) { + myOverconstraintListener->getConflictingColor(aColor); + } + if (aColor.empty()) + XGUI_CustomPrs::getDefaultColor(anObject, true, aColor); + if (!aColor.empty()) { + thePrs->setColor(aColor[0], aColor[1], aColor[2]); + aCustomized = true; + } + } + } + + return aCustomized; +} + bool PartSet_Module::customizeObject(ObjectPtr theObject, const ModuleBase_CustomizeFlag& theFlag, const bool theUpdateViewer) { diff --git a/src/PartSet/PartSet_Module.h b/src/PartSet/PartSet_Module.h index cf65860f7..3cf93537c 100755 --- a/src/PartSet/PartSet_Module.h +++ b/src/PartSet/PartSet_Module.h @@ -204,6 +204,10 @@ public: virtual void deactivateCustomPrs(const ModuleBase_CustomizeFlag& theFlag, const bool theUpdateViewer); + /// Modifies the given presentation in the custom way. + virtual bool customisePresentation(ResultPtr theResult, AISObjectPtr thePrs, + std::shared_ptr theCustomPrs); + /// Update the object presentable properties such as color, lines width and other /// If the object is result with the color attribute value set, it is used, /// otherwise the customize is applyed to the object's feature if it is a custom prs diff --git a/src/PartSet/PartSet_OverconstraintListener.cpp b/src/PartSet/PartSet_OverconstraintListener.cpp index 33c0ba033..435ceca00 100755 --- a/src/PartSet/PartSet_OverconstraintListener.cpp +++ b/src/PartSet/PartSet_OverconstraintListener.cpp @@ -105,12 +105,14 @@ bool PartSet_OverconstraintListener::appendConflictingObjects( const std::set& theConflictingObjects) { std::set aModifiedObjects; + std::vector aColor; + getConflictingColor(aColor); + // set error state for new objects and append them in the internal map of objects std::set::const_iterator anIt = theConflictingObjects.begin(), aLast = theConflictingObjects.end(); for (; anIt != aLast; anIt++) { ObjectPtr anObject = *anIt; if (myConflictingObjects.find(anObject) == myConflictingObjects.end()) { // it is not found - setConflictingObject(anObject, true); aModifiedObjects.insert(anObject); myConflictingObjects.insert(anObject); } @@ -131,7 +133,6 @@ bool PartSet_OverconstraintListener::repairConflictingObjects( for (anIt = theConflictingObjects.begin(), aLast = theConflictingObjects.end() ; anIt != aLast; anIt++) { ObjectPtr anObject = *anIt; if (theConflictingObjects.find(anObject) != theConflictingObjects.end()) { // it is found - setConflictingObject(anObject, false); myConflictingObjects.erase(anObject); aModifiedObjects.insert(anObject); @@ -176,33 +177,6 @@ void PartSet_OverconstraintListener::redisplayObjects( aDisplayer->updateViewer(); } -void PartSet_OverconstraintListener::setConflictingObject(const ObjectPtr& theObject, - const bool theConflicting) -{ - if (!theObject.get() || !theObject->data()->isValid()) - return; - - AISObjectPtr anAISObject; - GeomPresentablePtr aPrs = std::dynamic_pointer_cast(theObject); - - if (aPrs.get() != NULL) { - XGUI_Workshop* aWorkshop = workshop(); - XGUI_Displayer* aDisplayer = aWorkshop->displayer(); - - anAISObject = aPrs->getAISObject(aDisplayer->getAISObject(theObject)); - if (anAISObject.get()) { - Handle(AIS_InteractiveObject) anAISIO = anAISObject->impl(); - if (!anAISIO.IsNull()) { - if (!Handle(SketcherPrs_SymbolPrs)::DownCast(anAISIO).IsNull()) { - Handle(SketcherPrs_SymbolPrs) aPrs = Handle(SketcherPrs_SymbolPrs)::DownCast(anAISIO); - if (!aPrs.IsNull()) - aPrs->SetConflictingConstraint(theConflicting); - } - } - } - } -} - XGUI_Workshop* PartSet_OverconstraintListener::workshop() const { XGUI_ModuleConnector* aConnector = dynamic_cast(myWorkshop); diff --git a/src/PartSet/PartSet_OverconstraintListener.h b/src/PartSet/PartSet_OverconstraintListener.h index 772d00987..3e8e5616e 100755 --- a/src/PartSet/PartSet_OverconstraintListener.h +++ b/src/PartSet/PartSet_OverconstraintListener.h @@ -61,11 +61,6 @@ protected: /// \return boolean value whether the list differs from the internal list bool repairConflictingObjects(const std::set& theObjects); - /// Obtains the object custom AIS presentation and change conflicting state if it exists - /// \param theObject the object which presentation error state should be changed - /// \param theConflicting if true, the object state is erroneous, else correct - void setConflictingObject(const ObjectPtr& theObject, const bool theConflicting); - /// Sends update object signal for each object in the container and flush it. /// \param theObjects a list of object to be redisplayed void redisplayObjects(const std::set& theObjects); diff --git a/src/SketcherPrs/SketcherPrs_SymbolPrs.cpp b/src/SketcherPrs/SketcherPrs_SymbolPrs.cpp index d4d0df3ce..a00c59369 100644 --- a/src/SketcherPrs/SketcherPrs_SymbolPrs.cpp +++ b/src/SketcherPrs/SketcherPrs_SymbolPrs.cpp @@ -46,6 +46,8 @@ /// Step between icons static const double MyDist = 0.02; +//#define ICON_TO_DEBUG + /// Function to convert opengl data type GLenum toGlDataType (const Graphic3d_TypeOfData theType, GLint& theNbComp) { @@ -267,6 +269,7 @@ SketcherPrs_SymbolPrs::~SketcherPrs_SymbolPrs() Handle(Image_AlienPixMap) SketcherPrs_SymbolPrs::icon() { +#ifdef ICON_TO_DEBUG if (myIsConflicting) { if (myErrorIcon.IsNull()) { char* aEnv = getenv("NEWGEOM_ROOT_DIR"); @@ -284,6 +287,7 @@ Handle(Image_AlienPixMap) SketcherPrs_SymbolPrs::icon() } return myErrorIcon; } +#endif if (myIconsMap.count(iconName()) == 1) { return myIconsMap[iconName()]; @@ -421,7 +425,7 @@ void SketcherPrs_SymbolPrs::Compute(const Handle(PrsMgr_PresentationManager3d)& void SketcherPrs_SymbolPrs::ComputeSelection(const Handle(SelectMgr_Selection)& aSelection, - const Standard_Integer aMode) + const Standard_Integer aMode) { ClearSelected(); if ((aMode == 0) || (aMode == SketcherPrs_Tools::Sel_Constraint)) { @@ -430,18 +434,40 @@ void SketcherPrs_SymbolPrs::ComputeSelection(const Handle(SelectMgr_Selection)& } } -void SketcherPrs_SymbolPrs::SetConflictingConstraint(const bool& theConflicting) +void SketcherPrs_SymbolPrs::SetConflictingConstraint(const bool& theConflicting, + const std::vector& theColor) { +#ifdef ICON_TO_DEBUG if (myIsConflicting != theConflicting) { myIsConflicting = theConflicting; Handle(Image_AlienPixMap) anIcon = icon(); if (!anIcon.IsNull()) myAspect->SetMarkerImage(new Graphic3d_MarkerImage(anIcon)); } +#else + if (theConflicting) + { + if (!myAspect.IsNull()) + myAspect->SetColor (Quantity_Color (theColor[0] / 255., theColor[1] / 255., theColor[2] / 255., + Quantity_TOC_RGB)); + myIsConflicting = true; + } + else + { + if (!myAspect.IsNull()) + myAspect->SetColor (Quantity_Color (1.0, 1.0, 0.0, Quantity_TOC_RGB)); + myIsConflicting = false; + } +#endif } void SketcherPrs_SymbolPrs::Render(const Handle(OpenGl_Workspace)& theWorkspace) const { + // this method is a combination of OCCT OpenGL functions. The main purpose is to have + // equal distance from the source object to symbol indpendently of zoom. + // It is base on OCCT 6.9.1 and might need changes when using later OCCT versions. + // The specific SHAPER modifications are marked by ShaperModification:start/end, other is OCCT code + // do not update presentation for invalid or already removed objects: the presentation // should be removed soon if (!myConstraint->data().get() || !myConstraint->data()->isValid()) @@ -451,10 +477,12 @@ void SketcherPrs_SymbolPrs::Render(const Handle(OpenGl_Workspace)& theWorkspace) const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext(); Handle(OpenGl_View) aView = theWorkspace->ActiveView(); + // ShaperModification:start double aScale = aView->Camera()->Scale(); // Update points coordinate taking the viewer scale into account if (!updatePoints(MyDist * aScale)) return; + // ShaperModification:end Handle(Graphic3d_Buffer) aAttribs = myPntArray->Attributes(); @@ -474,7 +502,14 @@ void SketcherPrs_SymbolPrs::Render(const Handle(OpenGl_Workspace)& theWorkspace) const Handle(OpenGl_PointSprite)& aSpriteNorm = anAspectMarker->SpriteRes(aCtx); if (!aSpriteNorm.IsNull() && !aSpriteNorm->IsDisplayList()) { +#ifdef ICON_TO_DEBUG const bool toHilight = (theWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT) != 0; +#else + // ShaperModification:start : filling the presentation with color if there is a conflict + const bool toHilight = (theWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT) != 0 || myIsConflicting; + // ShaperModification:end +#endif + const Handle(OpenGl_PointSprite)& aSprite = (toHilight && anAspectMarker->SpriteHighlightRes(aCtx)->IsValid()) ? anAspectMarker->SpriteHighlightRes(aCtx) : aSpriteNorm; diff --git a/src/SketcherPrs/SketcherPrs_SymbolPrs.h b/src/SketcherPrs/SketcherPrs_SymbolPrs.h index 56fc52770..fb5112927 100644 --- a/src/SketcherPrs/SketcherPrs_SymbolPrs.h +++ b/src/SketcherPrs/SketcherPrs_SymbolPrs.h @@ -66,7 +66,8 @@ public: /// visualized in error color. The state is stored in an internal field, so should be changed when /// constraint become not conflicting /// \param theConflicting a state - Standard_EXPORT void SetConflictingConstraint(const bool& theConflicting); + /// \param theColor a color for conflicting object + Standard_EXPORT void SetConflictingConstraint(const bool& theConflicting, const std::vector& theColor); /// Render of the presentation /// \param theWorkspace is OpenGl workspace diff --git a/src/XGUI/XGUI_CustomPrs.cpp b/src/XGUI/XGUI_CustomPrs.cpp index 395c7288b..7948325d7 100644 --- a/src/XGUI/XGUI_CustomPrs.cpp +++ b/src/XGUI/XGUI_CustomPrs.cpp @@ -34,7 +34,8 @@ void getColor(ResultPtr theResult, std::vector& theColor) } } -void getDefaultColor(ObjectPtr theObject, std::vector& theColor, const bool isEmptyColorValid) +void XGUI_CustomPrs::getDefaultColor(ObjectPtr theObject, const bool isEmptyColorValid, + std::vector& theColor) { theColor.clear(); // get default color from the preferences manager for the given result @@ -62,7 +63,7 @@ void XGUI_CustomPrs::getResultColor(ResultPtr theResult, std::vector& theCo { getColor(theResult, theColor); if (theColor.empty()) - getDefaultColor(theResult, theColor, false); + getDefaultColor(theResult, false, theColor); } bool XGUI_CustomPrs::customisePresentation(ResultPtr theResult, AISObjectPtr thePrs, @@ -84,16 +85,9 @@ bool XGUI_CustomPrs::customisePresentation(ResultPtr theResult, AISObjectPtr the aCustomized = !aColor.empty() && thePrs->setColor(aColor[0], aColor[1], aColor[2]); } else { - XGUI_Displayer* aDisplayer = myWorkshop->displayer(); - ObjectPtr anObject = aDisplayer->getObject(thePrs); - if (anObject.get()) { - std::vector aColor; - ModuleBase_IModule* aModule = myWorkshop->module(); - aModule->getColor(anObject, aColor); - if (aColor.empty()) - getDefaultColor(anObject, aColor, true); - if (!aColor.empty()) - thePrs->setColor(aColor[0], aColor[1], aColor[2]); + if (!aCustomized) { + ModuleBase_IModule* aModule = myWorkshop->module(); + aCustomized = aModule->customisePresentation(theResult, thePrs, theCustomPrs); } } return aCustomized; diff --git a/src/XGUI/XGUI_CustomPrs.h b/src/XGUI/XGUI_CustomPrs.h index 83b1b951e..d8b7147a2 100644 --- a/src/XGUI/XGUI_CustomPrs.h +++ b/src/XGUI/XGUI_CustomPrs.h @@ -36,6 +36,16 @@ public: /// \param theColor a color in form of RGB vector static void getResultColor(ResultPtr theResult, std::vector& theColor); + /// Returns the default object color. It obtains colorConfigInfo of the object + /// and find it in preferences. If there are no this color in preference and an empty + /// color is interpreted as invalid, it shows error message + /// \param theObject an investigated object + /// \param isEmptyColorValid boolean state about interpretation of empty color + /// \param theColor the result color + static void XGUI_EXPORT getDefaultColor(ObjectPtr theObject, const bool isEmptyColorValid, + std::vector& theColor); + + protected: XGUI_Workshop* myWorkshop; /// the current workshop }; -- 2.39.2