From: nds Date: Thu, 21 Apr 2016 08:19:02 +0000 (+0300) Subject: #1404 Random crash with Shaper: AIS presentations: avoid IsReadyToDisplay calling... X-Git-Tag: V_2.3.0~161 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=935fe05ec267f2b38c82ab5fd12d89bcdd78c2a4;p=modules%2Fshaper.git #1404 Random crash with Shaper: AIS presentations: avoid IsReadyToDisplay calling twice. --- diff --git a/src/ModuleBase/ModuleBase_ResultPrs.cpp b/src/ModuleBase/ModuleBase_ResultPrs.cpp index 726821ec1..310bb78f8 100755 --- a/src/ModuleBase/ModuleBase_ResultPrs.cpp +++ b/src/ModuleBase/ModuleBase_ResultPrs.cpp @@ -76,19 +76,21 @@ void ModuleBase_ResultPrs::Compute(const Handle(PrsMgr_PresentationManager3d)& t const Standard_Integer theMode) { std::shared_ptr aShapePtr = ModelAPI_Tools::shape(myResult); - if (aShapePtr.get()) { + bool aReadyToDisplay = aShapePtr.get(); + if (aReadyToDisplay) { myOriginalShape = aShapePtr->impl(); if (!myOriginalShape.IsNull()) Set(myOriginalShape); } - else { + // change deviation coefficient to provide more precise circle + ModuleBase_Tools::setDefaultDeviationCoefficient(Shape(), Attributes()); + AIS_Shape::Compute(thePresentationManager, thePresentation, theMode); + + if (!aReadyToDisplay) { Events_Error::throwException("An empty AIS presentation: ModuleBase_ResultPrs"); static const Events_ID anEvent = Events_Loop::eventByName(EVENT_EMPTY_AIS_PRESENTATION); ModelAPI_EventCreator::get()->sendUpdated(myResult, anEvent); } - // change deviation coefficient to provide more precise circle - ModuleBase_Tools::setDefaultDeviationCoefficient(Shape(), Attributes()); - AIS_Shape::Compute(thePresentationManager, thePresentation, theMode); } void ModuleBase_ResultPrs::ComputeSelection(const Handle(SelectMgr_Selection)& aSelection, diff --git a/src/PartSet/PartSet_OperationPrs.cpp b/src/PartSet/PartSet_OperationPrs.cpp index 3858042e3..a749611f5 100755 --- a/src/PartSet/PartSet_OperationPrs.cpp +++ b/src/PartSet/PartSet_OperationPrs.cpp @@ -82,10 +82,12 @@ void PartSet_OperationPrs::Compute(const Handle(PrsMgr_PresentationManager3d)& t NCollection_DataMap aShapeToPrsMap; fillShapeList(myFeatureShapes, aShapeToPrsMap); - if (!aShapeToPrsMap.IsEmpty()) { + bool aReadyToDisplay = !myShapeToPrsMap.IsEmpty(); + if (aReadyToDisplay) { myShapeToPrsMap.Clear(); myShapeToPrsMap.Assign(aShapeToPrsMap); } + XGUI_Displayer* aDisplayer = XGUI_Tools::workshop(myWorkshop)->displayer(); Handle(Prs3d_Drawer) aDrawer = Attributes(); // create presentations on the base of the shapes @@ -110,9 +112,8 @@ void PartSet_OperationPrs::Compute(const Handle(PrsMgr_PresentationManager3d)& t StdPrs_WFDeflectionShape::Add(thePresentation, aShape, aDrawer); } - if (myShapeToPrsMap.IsEmpty()) { + if (!aReadyToDisplay) { Events_Error::throwException("An empty AIS presentation: PartSet_OperationPrs"); - //std::shared_ptr aMsg = std::shared_ptr( // new Events_Message(Events_Loop::eventByName(EVENT_EMPTY_OPERATION_PRESENTATION))); //Events_Loop::loop()->send(aMsg); diff --git a/src/PartSet/PartSet_ResultSketchPrs.cpp b/src/PartSet/PartSet_ResultSketchPrs.cpp index 04d9318ea..0e7319f8f 100755 --- a/src/PartSet/PartSet_ResultSketchPrs.cpp +++ b/src/PartSet/PartSet_ResultSketchPrs.cpp @@ -84,20 +84,20 @@ void PartSet_ResultSketchPrs::Compute(const Handle(PrsMgr_PresentationManager3d) NCollection_List aFaceList; fillShapes(aResultShape, anAuxiliaryCompound, mySketchFaceList); - bool isEmptyPresentation = aResultShape.IsNull() && anAuxiliaryCompound.IsNull(); + bool aReadyToDisplay = !aResultShape.IsNull() || !anAuxiliaryCompound.IsNull(); - if (!aResultShape.IsNull()) { - myOriginalShape = aResultShape; - if (!myOriginalShape.IsNull()) - Set(myOriginalShape); - } - - if (!anAuxiliaryCompound.IsNull()) + if (aReadyToDisplay) { + if (!aResultShape.IsNull()) { + myOriginalShape = aResultShape; + if (!myOriginalShape.IsNull()) + Set(myOriginalShape); + } myAuxiliaryCompound = anAuxiliaryCompound; + } setAuxiliaryPresentationStyle(false); - // change deviation coefficient to provide more precise circle + // change deviation coefficient to provide more precise circle ModuleBase_Tools::setDefaultDeviationCoefficient(Shape(), Attributes()); AIS_Shape::Compute(thePresentationManager, thePresentation, theMode); @@ -108,7 +108,7 @@ void PartSet_ResultSketchPrs::Compute(const Handle(PrsMgr_PresentationManager3d) StdPrs_WFDeflectionShape::Add(thePresentation, myAuxiliaryCompound, aDrawer); } - if (isEmptyPresentation) { + if (!aReadyToDisplay) { Events_Error::throwException("An empty AIS presentation: PartSet_ResultSketchPrs"); static const Events_ID anEvent = Events_Loop::eventByName(EVENT_EMPTY_AIS_PRESENTATION); ModelAPI_EventCreator::get()->sendUpdated(myResult, anEvent); diff --git a/src/SketcherPrs/SketcherPrs_Coincident.cpp b/src/SketcherPrs/SketcherPrs_Coincident.cpp index 1dbf3e73b..d8cb88cb2 100644 --- a/src/SketcherPrs/SketcherPrs_Coincident.cpp +++ b/src/SketcherPrs/SketcherPrs_Coincident.cpp @@ -42,17 +42,26 @@ SketcherPrs_Coincident::SketcherPrs_Coincident(ModelAPI_Feature* theConstraint, } bool SketcherPrs_Coincident::IsReadyToDisplay(ModelAPI_Feature* theConstraint, - const std::shared_ptr&/* thePlane*/) + const std::shared_ptr& thePlane) { - bool aReadyToDisplay = false; + gp_Pnt aPoint; + return readyToDisplay(theConstraint, thePlane, aPoint); +} +bool SketcherPrs_Coincident::readyToDisplay(ModelAPI_Feature* theConstraint, + const std::shared_ptr& thePlane, + gp_Pnt& thePoint) +{ + bool aReadyToDisplay = false; // Get point of the presentation std::shared_ptr aPnt = SketcherPrs_Tools::getPoint(theConstraint, SketchPlugin_Constraint::ENTITY_A()); - if (aPnt.get() == NULL) + if (aPnt.get() == NULL) { aPnt = SketcherPrs_Tools::getPoint(theConstraint, SketchPlugin_Constraint::ENTITY_B()); - - aReadyToDisplay = aPnt.get() != NULL; + aReadyToDisplay = aPnt.get() != NULL; + if (aReadyToDisplay) + thePoint = aPnt->impl(); + } return aReadyToDisplay; } @@ -61,15 +70,10 @@ void SketcherPrs_Coincident::Compute(const Handle(PrsMgr_PresentationManager3d)& const Handle(Prs3d_Presentation)& thePresentation, const Standard_Integer theMode) { - bool aReadyToDisplay = IsReadyToDisplay(myConstraint, mySketcherPlane); - if (aReadyToDisplay) { - std::shared_ptr aPnt = SketcherPrs_Tools::getPoint(myConstraint, - SketchPlugin_Constraint::ENTITY_A()); - if (aPnt.get() == NULL) - aPnt = SketcherPrs_Tools::getPoint(myConstraint, SketchPlugin_Constraint::ENTITY_B()); - std::shared_ptr aPoint = mySketcherPlane->to3D(aPnt->x(), aPnt->y()); - myPoint = aPoint->impl(); - } + gp_Pnt aPoint; + bool aReadyToDisplay = readyToDisplay(myConstraint, mySketcherPlane, aPoint); + if (aReadyToDisplay) + myPoint = aPoint; // Get point of the presentation static Handle(Graphic3d_AspectMarker3d) aPtA; diff --git a/src/SketcherPrs/SketcherPrs_Coincident.h b/src/SketcherPrs/SketcherPrs_Coincident.h index baad5e7fd..082016c81 100644 --- a/src/SketcherPrs/SketcherPrs_Coincident.h +++ b/src/SketcherPrs/SketcherPrs_Coincident.h @@ -55,6 +55,11 @@ protected: Standard_EXPORT virtual void ComputeSelection(const Handle(SelectMgr_Selection)& aSelection, const Standard_Integer aMode) ; +private: + static bool readyToDisplay(ModelAPI_Feature* theConstraint, + const std::shared_ptr& thePlane, + gp_Pnt& thePoint); + private: ModelAPI_Feature* myConstraint; std::shared_ptr mySketcherPlane; diff --git a/src/SketcherPrs/SketcherPrs_LengthDimension.cpp b/src/SketcherPrs/SketcherPrs_LengthDimension.cpp index d1bbd0cfd..f17a22dd1 100644 --- a/src/SketcherPrs/SketcherPrs_LengthDimension.cpp +++ b/src/SketcherPrs/SketcherPrs_LengthDimension.cpp @@ -56,22 +56,21 @@ SketcherPrs_LengthDimension::~SketcherPrs_LengthDimension() bool SketcherPrs_LengthDimension::IsReadyToDisplay(ModelAPI_Feature* theConstraint, const std::shared_ptr& thePlane) { - bool aReadyToDisplay = false; - gp_Pnt aPnt1, aPnt2; - aReadyToDisplay = getPoints(theConstraint, thePlane, aPnt1, aPnt2); - - return aReadyToDisplay; + return readyToDisplay(theConstraint, thePlane, aPnt1, aPnt2); } void SketcherPrs_LengthDimension::Compute(const Handle(PrsMgr_PresentationManager3d)& thePresentationManager, const Handle(Prs3d_Presentation)& thePresentation, const Standard_Integer theMode) { - bool aReadyToDisplay = IsReadyToDisplay(myConstraint, mySketcherPlane); + gp_Pnt aPnt1, aPnt2; + bool aReadyToDisplay = readyToDisplay(myConstraint, mySketcherPlane, aPnt1, aPnt2); if (aReadyToDisplay) { + myFirstPoint = aPnt1; + mySecondPoint = aPnt2; + myDistance = SketcherPrs_Tools::getFlyoutDistance(myConstraint); - getPoints(myConstraint, mySketcherPlane, myFirstPoint, mySecondPoint); myPlane = gp_Pln(mySketcherPlane->impl()); AttributeDoublePtr anAttributeValue = myConstraint->data()->real(SketchPlugin_Constraint::VALUE()); @@ -97,12 +96,11 @@ void SketcherPrs_LengthDimension::Compute(const Handle(PrsMgr_PresentationManage if (!aReadyToDisplay) SketcherPrs_Tools::sendEmptyPresentationError(myConstraint, "An empty AIS presentation: SketcherPrs_LengthDimension"); - } -bool SketcherPrs_LengthDimension::getPoints(ModelAPI_Feature* theConstraint, - const std::shared_ptr& thePlane, - gp_Pnt& thePnt1, gp_Pnt& thePnt2) +bool SketcherPrs_LengthDimension::readyToDisplay(ModelAPI_Feature* theConstraint, + const std::shared_ptr& thePlane, + gp_Pnt& thePnt1, gp_Pnt& thePnt2) { DataPtr aData = theConstraint->data(); if (theConstraint->getKind() == SketchPlugin_ConstraintLength::ID()) { diff --git a/src/SketcherPrs/SketcherPrs_LengthDimension.h b/src/SketcherPrs/SketcherPrs_LengthDimension.h index 97bd39a83..75d5aa4c6 100644 --- a/src/SketcherPrs/SketcherPrs_LengthDimension.h +++ b/src/SketcherPrs/SketcherPrs_LengthDimension.h @@ -56,9 +56,9 @@ protected: const Standard_Integer aMode); private: - static bool getPoints(ModelAPI_Feature* theConstraint, - const std::shared_ptr& thePlane, - gp_Pnt& thePnt1, gp_Pnt& thePnt2); + static bool readyToDisplay(ModelAPI_Feature* theConstraint, + const std::shared_ptr& thePlane, + gp_Pnt& thePnt1, gp_Pnt& thePnt2); /// Constraint feature ModelAPI_Feature* myConstraint; diff --git a/src/SketcherPrs/SketcherPrs_Radius.cpp b/src/SketcherPrs/SketcherPrs_Radius.cpp index 579b36f61..c842033ba 100644 --- a/src/SketcherPrs/SketcherPrs_Radius.cpp +++ b/src/SketcherPrs/SketcherPrs_Radius.cpp @@ -45,6 +45,17 @@ SketcherPrs_Radius::~SketcherPrs_Radius() bool SketcherPrs_Radius::IsReadyToDisplay(ModelAPI_Feature* theConstraint, const std::shared_ptr& thePlane) +{ + gp_Circ aCircle; + gp_Pnt anAnchorPoint; + double aRadius; + return readyToDisplay(theConstraint, thePlane, aCircle, anAnchorPoint, aRadius); +} + +bool SketcherPrs_Radius::readyToDisplay(ModelAPI_Feature* theConstraint, + const std::shared_ptr& thePlane, + gp_Circ& theCircle, gp_Pnt& theAnchorPoint, + double& theRadius) { bool aReadyToDisplay = false; @@ -66,7 +77,7 @@ bool SketcherPrs_Radius::IsReadyToDisplay(ModelAPI_Feature* theConstraint, return aReadyToDisplay; std::shared_ptr aCyrcFeature = ModelAPI_Feature::feature(anAttr->object()); - double aRadius = 1; + theRadius = 1; std::shared_ptr aCenterAttr; // it is possible that circle result becomes zero, in this case the presentation should disappear // for example, it happens when circle radius is set to zero @@ -78,28 +89,26 @@ bool SketcherPrs_Radius::IsReadyToDisplay(ModelAPI_Feature* theConstraint, AttributeDoublePtr aCircRadius = std::dynamic_pointer_cast( aCyrcFeature->data()->attribute(SketchPlugin_Circle::RADIUS_ID())); - aRadius = aCircRadius->value(); + theRadius = aCircRadius->value(); } else { // arc aCenterAttr = std::dynamic_pointer_cast( aCyrcFeature->data()->attribute(SketchPlugin_Arc::CENTER_ID())); std::shared_ptr aStartAttr = std::dynamic_pointer_cast (aCyrcFeature->data()->attribute(SketchPlugin_Arc::START_ID())); - aRadius = aCenterAttr->pnt()->distance(aStartAttr->pnt()); + theRadius = aCenterAttr->pnt()->distance(aStartAttr->pnt()); } std::shared_ptr aCenter = thePlane->to3D(aCenterAttr->x(), aCenterAttr->y()); std::shared_ptr aNormal = thePlane->normal(); - GeomAPI_Circ aCircle(aCenter, aNormal, aRadius); - + GeomAPI_Circ aCircle(aCenter, aNormal, theRadius); std::shared_ptr anAnchor = SketcherPrs_Tools::getAnchorPoint(theConstraint, thePlane); - gp_Circ aCirc = aCircle.impl(); - gp_Pnt anAncorPnt = anAnchor->impl(); - // anchor point should not coincide to the location point of the circle - // OCCT does not process this case. + theCircle = aCircle.impl(); + theAnchorPoint = anAnchor->impl(); + + aReadyToDisplay = theAnchorPoint.Distance(theCircle.Location()) > 1e-7; - aReadyToDisplay = anAncorPnt.Distance(aCirc.Location()) > 1e-7; return aReadyToDisplay; } @@ -107,55 +116,21 @@ void SketcherPrs_Radius::Compute(const Handle(PrsMgr_PresentationManager3d)& the const Handle(Prs3d_Presentation)& thePresentation, const Standard_Integer theMode) { - bool aReadyToDisplay = IsReadyToDisplay(myConstraint, mySketcherPlane); + gp_Circ aCircle; + gp_Pnt anAnchorPoint; + double aRadius; + bool aReadyToDisplay = readyToDisplay(myConstraint, mySketcherPlane, aCircle, anAnchorPoint, aRadius); if (aReadyToDisplay) { - //myDistance = SketcherPrs_Tools::getFlyoutDistance(myConstraint); - - DataPtr aData = myConstraint->data(); - - // Flyout point - std::shared_ptr aFlyoutAttr = - std::dynamic_pointer_cast - (aData->attribute(SketchPlugin_Constraint::FLYOUT_VALUE_PNT())); - - // Get circle - std::shared_ptr anAttr = - std::dynamic_pointer_cast - (aData->attribute(SketchPlugin_Constraint::ENTITY_A())); - - std::shared_ptr aCyrcFeature = ModelAPI_Feature::feature(anAttr->object()); - myRadius = 1; - std::shared_ptr aCenterAttr; - if (aCyrcFeature->getKind() == SketchPlugin_Circle::ID()) { // circle - aCenterAttr = std::dynamic_pointer_cast( - aCyrcFeature->data()->attribute(SketchPlugin_Circle::CENTER_ID())); - AttributeDoublePtr aCircRadius = - std::dynamic_pointer_cast( - aCyrcFeature->data()->attribute(SketchPlugin_Circle::RADIUS_ID())); - myRadius = aCircRadius->value(); - } else { // arc - aCenterAttr = std::dynamic_pointer_cast( - aCyrcFeature->data()->attribute(SketchPlugin_Arc::CENTER_ID())); - std::shared_ptr aStartAttr = - std::dynamic_pointer_cast - (aCyrcFeature->data()->attribute(SketchPlugin_Arc::START_ID())); - myRadius = aCenterAttr->pnt()->distance(aStartAttr->pnt()); - } - std::shared_ptr aCenter = mySketcherPlane->to3D(aCenterAttr->x(), aCenterAttr->y()); - std::shared_ptr aNormal = mySketcherPlane->normal(); - - GeomAPI_Circ aCircle(aCenter, aNormal, myRadius); - std::shared_ptr anAnchor = SketcherPrs_Tools::getAnchorPoint(myConstraint, mySketcherPlane); - - myCircle = aCircle.impl(); - myAncorPnt = anAnchor->impl(); + myCircle = aCircle; + myAnchorPoint = anAnchorPoint; + myRadius = aRadius; AttributeDoublePtr anAttributeValue = myConstraint->data()->real(SketchPlugin_Constraint::VALUE()); myHasParameters = anAttributeValue->usedParameters().size() > 0; myValue = anAttributeValue->text(); } - SetMeasuredGeometry(myCircle, myAncorPnt); + SetMeasuredGeometry(myCircle, myAnchorPoint); SetCustomValue(myRadius); // Update variable aspect parameters (depending on viewer scale) diff --git a/src/SketcherPrs/SketcherPrs_Radius.h b/src/SketcherPrs/SketcherPrs_Radius.h index 2c940061b..3ba60e083 100644 --- a/src/SketcherPrs/SketcherPrs_Radius.h +++ b/src/SketcherPrs/SketcherPrs_Radius.h @@ -42,6 +42,18 @@ public: /// \return boolean result value static bool IsReadyToDisplay(ModelAPI_Feature* theConstraint, const std::shared_ptr& thePlane); +private: + /// Fills the constraint parameters by constraint and plane + /// \param theConstraint a constraint feature + /// \param thePlane a coordinate plane of current sketch + /// \param theCircle a circle build on the constraint values + /// \param thePoint an anchor point to show text value + /// \param theRadius a circle custom radius value to be visualized + /// \return boolean result value + static bool readyToDisplay(ModelAPI_Feature* theConstraint, + const std::shared_ptr& thePlane, + gp_Circ& theCircle, gp_Pnt& theAnchorPoint, + double& theRadius); protected: /// Redefinition of virtual function Standard_EXPORT virtual void Compute(const Handle(PrsMgr_PresentationManager3d)& thePresentationManager, @@ -64,7 +76,7 @@ private: /// container of values obtained from the constraint, which are necessary to fill the presentation double myRadius; ///< the radius custom value gp_Circ myCircle; ///< the radius circle - gp_Pnt myAncorPnt; ///< an ancor for the radius value visualization + gp_Pnt myAnchorPoint; ///< an ancor for the radius value visualization bool myHasParameters; ///< true if the atrribute value has used parameters std::string myValue; ///< dimension value