From: nds Date: Mon, 15 Feb 2016 11:17:33 +0000 (+0300) Subject: Tangent Arc: reentrance from the last point of the previous arc X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=ff9be83fc377b384424f78a82ecb8e7f4a0aed28;p=modules%2Fshaper.git Tangent Arc: reentrance from the last point of the previous arc Crash fixed approved by AZV --- diff --git a/src/PartSet/PartSet_SketcherReetntrantMgr.cpp b/src/PartSet/PartSet_SketcherReetntrantMgr.cpp index d37adaf44..ae06c60e4 100755 --- a/src/PartSet/PartSet_SketcherReetntrantMgr.cpp +++ b/src/PartSet/PartSet_SketcherReetntrantMgr.cpp @@ -7,6 +7,9 @@ #include "ModelAPI_Session.h" #include "ModelAPI_AttributeString.h" +#include "ModelAPI_AttributeRefAttr.h" + +#include "GeomDataAPI_Point2D.h" #include #include @@ -17,6 +20,7 @@ #include #include #include +#include "ModuleBase_ToolBox.h" #include #include @@ -101,24 +105,55 @@ bool PartSet_SketcherReetntrantMgr::processMouseMoved(ModuleBase_IViewWindow* /* return aProcessed; if (myIsInternalEditOperation) { - PartSet_WidgetPoint2D* aPoint2DWdg = dynamic_cast(module()->activeWidget()); - if (aPoint2DWdg && aPoint2DWdg->canBeActivatedByMove()) { - ModuleBase_OperationFeature* aFOperation = dynamic_cast + ModuleBase_OperationFeature* aFOperation = dynamic_cast (myWorkshop->currentOperation()); - FeaturePtr aLastFeature = myRestartingMode == RM_LastFeatureUsed ? aFOperation->feature() : FeaturePtr(); - restartOperation(); - aProcessed = true; - - if (aLastFeature) { - ModuleBase_IPropertyPanel* aPanel = myWorkshop->currentOperation()->propertyPanel(); - PartSet_WidgetPoint2D* aPoint2DWdg = dynamic_cast(aPanel->activeWidget()); - if (aPoint2DWdg && aPoint2DWdg->canBeActivatedByMove()) { - QList aSelection; - aSelection.append(ModuleBase_ViewerPrs(aLastFeature, TopoDS_Shape(), NULL)); - if (aPoint2DWdg->setSelection(aSelection, true)) - aPanel->activateNextWidget(aPoint2DWdg); + FeaturePtr aLastFeature = myRestartingMode == RM_LastFeatureUsed ? aFOperation->feature() + : FeaturePtr(); + if (aLastFeature) { + ModuleBase_ModelWidget* anActiveWidget = module()->activeWidget(); + ModuleBase_IPropertyPanel* aPanel = myWorkshop->currentOperation()->propertyPanel(); + bool aWidgetIsFilled = false; + + //bool aCanBeActivatedByMove = false; + FeaturePtr aCurrentFeature = anActiveWidget->feature(); + bool isLineFeature = false, isArcFeature = false; + if (aCurrentFeature->getKind() == SketchPlugin_Line::ID()) + isLineFeature = anActiveWidget->attributeID() == SketchPlugin_Line::START_ID(); + else if (isTangentArc(aFOperation)) + isArcFeature = anActiveWidget->attributeID() == SketchPlugin_Arc::TANGENT_POINT_ID(); + + bool aCanBeActivatedByMove = isLineFeature || isArcFeature; + if (aCanBeActivatedByMove) { + restartOperation(); + + anActiveWidget = module()->activeWidget(); + aCurrentFeature = anActiveWidget->feature(); + aProcessed = true; + if (isLineFeature) { + PartSet_WidgetPoint2D* aPoint2DWdg = dynamic_cast(anActiveWidget); + if (aPoint2DWdg) { // line, start point should be equal last point of the last feature line + QList aSelection; + aSelection.append(ModuleBase_ViewerPrs(aLastFeature, TopoDS_Shape(), NULL)); + aWidgetIsFilled = aPoint2DWdg->setSelection(aSelection, true); + } + } + else if (isArcFeature) { // arc, start point should be equal last point of the last feature arc + if (aCurrentFeature->getKind() == SketchPlugin_Arc::ID()) { + // get the last point of the previuos arc feature(geom point 2d) + std::shared_ptr aData = aLastFeature->data(); + std::shared_ptr aPointAttr = + std::dynamic_pointer_cast( + aData->attribute(SketchPlugin_Arc::END_ID())); + // get point attribute on the current feature + AttributeRefAttrPtr aTangentPointAttr = aCurrentFeature->data()->refattr( + SketchPlugin_Arc::TANGENT_POINT_ID()); + aTangentPointAttr->setAttr(aPointAttr); + aWidgetIsFilled = true; + } } } + if (aWidgetIsFilled) + aPanel->activateNextWidget(anActiveWidget); } } return aProcessed; @@ -236,23 +271,6 @@ bool PartSet_SketcherReetntrantMgr::processEnter(const std::string& thePreviousA return isDone; } -/*bool isTangentArc(ModuleBase_Operation* theOperation) -{ - bool aTangentArc = false; - ModuleBase_OperationFeature* aFOperation = dynamic_cast - (theOperation); - if (aFOperation && PartSet_SketcherMgr::isNestedSketchOperation(aFOperation)) { - FeaturePtr aFeature = aFOperation->feature(); - if (aFeature.get() && aFeature->getKind() == SketchPlugin_Arc::ID()) { - AttributeStringPtr aTypeAttr = aFeature->data()->string(SketchPlugin_Arc::ARC_TYPE()); - std::string anArcType = aTypeAttr.get() ? aTypeAttr->value() : ""; - aTangentArc = anArcType == SketchPlugin_Arc::ARC_TYPE_TANGENT(); - } - } - - return aTangentArc; -}*/ - void PartSet_SketcherReetntrantMgr::onVertexSelected() { if (!isActiveMgr()) @@ -343,8 +361,12 @@ bool PartSet_SketcherReetntrantMgr::startInternalEdit(const std::string& thePrev ModuleBase_ModelWidget* aPreviousAttributeWidget = 0; QList aWidgets = aPanel->modelWidgets(); for (int i = 0, aNb = aWidgets.size(); i < aNb && !aPreviousAttributeWidget; i++) { - if (aWidgets[i]->attributeID() == thePreviousAttributeID) + if (aWidgets[i]->attributeID() == thePreviousAttributeID) { + /// workaround for the same attributes used in different stacked widgets(attribute types) + if (ModuleBase_ToolBox::isOffToolBoxParent(aWidgets[i])) + continue; aPreviousAttributeWidget = aWidgets[i]; + } } // If the current widget is a selector, do nothing, it processes the mouse press if (aPreviousAttributeWidget) { @@ -418,27 +440,6 @@ void PartSet_SketcherReetntrantMgr::restartOperation() } } -bool PartSet_SketcherReetntrantMgr::copyReetntrantAttributes(const FeaturePtr& theSourceFeature, - const FeaturePtr& theNewFeature) -{ - bool aChanged = false; - std::string aTypeAttributeId; - if (theSourceFeature->getKind() == SketchPlugin_Circle::ID()) { - aTypeAttributeId = SketchPlugin_Circle::CIRCLE_TYPE(); - } - if (theSourceFeature->getKind() == SketchPlugin_Arc::ID()) { - aTypeAttributeId = SketchPlugin_Arc::ARC_TYPE(); - } - if (!aTypeAttributeId.empty()) { - AttributeStringPtr aSourceFeatureTypeAttr = theSourceFeature->data()->string(aTypeAttributeId); - AttributeStringPtr aNewFeatureTypeAttr = theNewFeature->data()->string(aTypeAttributeId); - aNewFeatureTypeAttr->setValue(aSourceFeatureTypeAttr->value()); - ModuleBase_ModelWidget::updateObject(theNewFeature); - aChanged = true; - } - return aChanged; -} - void PartSet_SketcherReetntrantMgr::createInternalFeature() { ModuleBase_OperationFeature* aFOperation = dynamic_cast @@ -505,6 +506,43 @@ void PartSet_SketcherReetntrantMgr::resetFlags() } } +bool PartSet_SketcherReetntrantMgr::copyReetntrantAttributes(const FeaturePtr& theSourceFeature, + const FeaturePtr& theNewFeature) +{ + bool aChanged = false; + std::string aTypeAttributeId; + if (theSourceFeature->getKind() == SketchPlugin_Circle::ID()) { + aTypeAttributeId = SketchPlugin_Circle::CIRCLE_TYPE(); + } + if (theSourceFeature->getKind() == SketchPlugin_Arc::ID()) { + aTypeAttributeId = SketchPlugin_Arc::ARC_TYPE(); + } + if (!aTypeAttributeId.empty()) { + AttributeStringPtr aSourceFeatureTypeAttr = theSourceFeature->data()->string(aTypeAttributeId); + AttributeStringPtr aNewFeatureTypeAttr = theNewFeature->data()->string(aTypeAttributeId); + aNewFeatureTypeAttr->setValue(aSourceFeatureTypeAttr->value()); + ModuleBase_ModelWidget::updateObject(theNewFeature); + aChanged = true; + } + return aChanged; +} + +bool PartSet_SketcherReetntrantMgr::isTangentArc(ModuleBase_Operation* theOperation) +{ + bool aTangentArc = false; + ModuleBase_OperationFeature* aFOperation = dynamic_cast + (theOperation); + if (aFOperation && PartSet_SketcherMgr::isNestedSketchOperation(aFOperation)) { + FeaturePtr aFeature = aFOperation->feature(); + if (aFeature.get() && aFeature->getKind() == SketchPlugin_Arc::ID()) { + AttributeStringPtr aTypeAttr = aFeature->data()->string(SketchPlugin_Arc::ARC_TYPE()); + std::string anArcType = aTypeAttr.get() ? aTypeAttr->value() : ""; + aTangentArc = anArcType == SketchPlugin_Arc::ARC_TYPE_TANGENT(); + } + } + return aTangentArc; +} + XGUI_Workshop* PartSet_SketcherReetntrantMgr::workshop() const { XGUI_ModuleConnector* aConnector = dynamic_cast(myWorkshop); diff --git a/src/PartSet/PartSet_SketcherReetntrantMgr.h b/src/PartSet/PartSet_SketcherReetntrantMgr.h index 8f16bce6d..93691362d 100755 --- a/src/PartSet/PartSet_SketcherReetntrantMgr.h +++ b/src/PartSet/PartSet_SketcherReetntrantMgr.h @@ -147,6 +147,8 @@ private: static bool copyReetntrantAttributes(const FeaturePtr& theSourceFeature, const FeaturePtr& theNewFeature); + static bool isTangentArc(ModuleBase_Operation* theOperation); + /// Returns the workshop XGUI_Workshop* workshop() const; diff --git a/src/SketchPlugin/SketchPlugin_Arc.cpp b/src/SketchPlugin/SketchPlugin_Arc.cpp index ac9981b00..ce91d8158 100644 --- a/src/SketchPlugin/SketchPlugin_Arc.cpp +++ b/src/SketchPlugin/SketchPlugin_Arc.cpp @@ -42,11 +42,6 @@ const double paramTolerance = 1.e-4; const double PI =3.141592653589793238463; namespace { - /*static const std::string& ARC_TYPE() - { - static const std::string TYPE("ArcType"); - return TYPE; - }*/ static const std::string& ARC_TYPE_CENTER_START_END() { static const std::string TYPE("CenterStartEnd"); @@ -57,22 +52,12 @@ namespace { static const std::string TYPE("ThreePoints"); return TYPE; } - /*static const std::string& ARC_TYPE_TANGENT() - { - static const std::string TYPE("Tangent"); - return TYPE; - }*/ static const std::string& PASSED_POINT_ID() { static const std::string PASSED_PNT("ArcPassedPoint"); return PASSED_PNT; } - static const std::string& TANGENT_POINT_ID() - { - static const std::string TANGENT_PNT("ArcTangentPoint"); - return TANGENT_PNT; - } static const std::string& RADIUS_ID() { static const std::string RADIUS("ArcRadius"); @@ -381,6 +366,10 @@ static inline void calculatePassedPoint( bool theArcReversed, std::shared_ptr thePassedPoint) { + if (theCenter->distance(theStartPoint) < tolerance || + theCenter->distance(theEndPoint) < tolerance) + return; + std::shared_ptr aStartDir(new GeomAPI_Dir2d( theStartPoint->xy()->decreased(theCenter->xy()))); std::shared_ptr aEndDir(new GeomAPI_Dir2d( @@ -425,8 +414,9 @@ void SketchPlugin_Arc::updateDependentAttributes() if (aRadiusAttr && anAngleAttr) { std::shared_ptr aCircle( new GeomAPI_Circ2d(aStartAttr->pnt(), anEndAttr->pnt(), aPassedPoint->pnt())); - calculateArcAngleRadius(aCircle, aStartAttr->pnt(), anEndAttr->pnt(), aPassedPoint->pnt(), - anAngleAttr, aRadiusAttr); + if (aCircle->implPtr()) + calculateArcAngleRadius(aCircle, aStartAttr->pnt(), anEndAttr->pnt(), aPassedPoint->pnt(), + anAngleAttr, aRadiusAttr); } data()->blockSendAttributeUpdated(false); } diff --git a/src/SketchPlugin/SketchPlugin_Arc.h b/src/SketchPlugin/SketchPlugin_Arc.h index b3cfa3a2d..6accaa209 100644 --- a/src/SketchPlugin/SketchPlugin_Arc.h +++ b/src/SketchPlugin/SketchPlugin_Arc.h @@ -50,6 +50,12 @@ class SketchPlugin_Arc : public SketchPlugin_SketchEntity, public GeomAPI_IPrese return TYPE; } + static const std::string& TANGENT_POINT_ID() + { + static const std::string TANGENT_PNT("ArcTangentPoint"); + return TANGENT_PNT; + } + /// Central 2D point of the circle which contains the arc inline static const std::string& CENTER_ID() { diff --git a/src/SketchPlugin/SketchPlugin_Circle.cpp b/src/SketchPlugin/SketchPlugin_Circle.cpp index f252df658..4159df870 100644 --- a/src/SketchPlugin/SketchPlugin_Circle.cpp +++ b/src/SketchPlugin/SketchPlugin_Circle.cpp @@ -25,11 +25,6 @@ #include namespace { - static const std::string& CIRCLE_TYPE() - { - static const std::string TYPE("CircleType"); - return TYPE; - } static const std::string& CIRCLE_TYPE_CENTER_AND_RADIUS() { static const std::string TYPE("CenterRadius");