]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Tangent Arc: reentrance from the last point of the previous arc
authornds <nds@opencascade.com>
Mon, 15 Feb 2016 11:17:33 +0000 (14:17 +0300)
committernds <nds@opencascade.com>
Mon, 15 Feb 2016 11:17:33 +0000 (14:17 +0300)
Crash fixed approved by AZV

src/PartSet/PartSet_SketcherReetntrantMgr.cpp
src/PartSet/PartSet_SketcherReetntrantMgr.h
src/SketchPlugin/SketchPlugin_Arc.cpp
src/SketchPlugin/SketchPlugin_Arc.h
src/SketchPlugin/SketchPlugin_Circle.cpp

index d37adaf443968be01f585f15ec45e6fc5fa3055b..ae06c60e45ae9488a76ce92f733e612653a8109a 100755 (executable)
@@ -7,6 +7,9 @@
 
 #include "ModelAPI_Session.h"
 #include "ModelAPI_AttributeString.h"
+#include "ModelAPI_AttributeRefAttr.h"
+
+#include "GeomDataAPI_Point2D.h"
 
 #include <ModuleBase_IPropertyPanel.h>
 #include <ModuleBase_OperationFeature.h>
@@ -17,6 +20,7 @@
 #include <ModuleBase_PageBase.h>
 #include <ModuleBase_WidgetFactory.h>
 #include <ModuleBase_OperationDescription.h>
+#include "ModuleBase_ToolBox.h"
 
 #include <SketchPlugin_Feature.h>
 #include <SketchPlugin_Line.h>
@@ -101,24 +105,55 @@ bool PartSet_SketcherReetntrantMgr::processMouseMoved(ModuleBase_IViewWindow* /*
     return aProcessed;
 
   if  (myIsInternalEditOperation) {
-    PartSet_WidgetPoint2D* aPoint2DWdg = dynamic_cast<PartSet_WidgetPoint2D*>(module()->activeWidget());
-    if (aPoint2DWdg && aPoint2DWdg->canBeActivatedByMove()) {
-      ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
+    ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
                                                          (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<PartSet_WidgetPoint2D*>(aPanel->activeWidget());
-        if (aPoint2DWdg && aPoint2DWdg->canBeActivatedByMove()) {
-          QList<ModuleBase_ViewerPrs> 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<PartSet_WidgetPoint2D*>(anActiveWidget);
+          if (aPoint2DWdg) { // line, start point should be equal last point of the last feature line
+            QList<ModuleBase_ViewerPrs> 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<ModelAPI_Data> aData = aLastFeature->data();
+            std::shared_ptr<GeomDataAPI_Point2D> aPointAttr = 
+                std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+                                           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<ModuleBase_OperationFeature*>
-                                                                        (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<ModuleBase_ModelWidget*> 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<ModuleBase_OperationFeature*>
@@ -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<ModuleBase_OperationFeature*>
+                                                                        (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<XGUI_ModuleConnector*>(myWorkshop);
index 8f16bce6d11466442d314a9873fdb7f657d0856b..93691362dff9b37649b07ab448e576101dd0f854 100755 (executable)
@@ -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;
 
index ac9981b002ce4684a3a5921d617f1d7c321bec49..ce91d8158c2c85543a8d4e8018da9de55f59afa6 100644 (file)
@@ -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<GeomDataAPI_Point2D> thePassedPoint)
 {
+  if (theCenter->distance(theStartPoint) < tolerance ||
+      theCenter->distance(theEndPoint) < tolerance)
+    return;
+
   std::shared_ptr<GeomAPI_Dir2d> aStartDir(new GeomAPI_Dir2d(
       theStartPoint->xy()->decreased(theCenter->xy())));
   std::shared_ptr<GeomAPI_Dir2d> aEndDir(new GeomAPI_Dir2d(
@@ -425,8 +414,9 @@ void SketchPlugin_Arc::updateDependentAttributes()
   if (aRadiusAttr && anAngleAttr) {
     std::shared_ptr<GeomAPI_Circ2d> aCircle(
         new GeomAPI_Circ2d(aStartAttr->pnt(), anEndAttr->pnt(), aPassedPoint->pnt()));
-    calculateArcAngleRadius(aCircle, aStartAttr->pnt(), anEndAttr->pnt(), aPassedPoint->pnt(),
-                            anAngleAttr, aRadiusAttr);
+    if (aCircle->implPtr<void*>())
+      calculateArcAngleRadius(aCircle, aStartAttr->pnt(), anEndAttr->pnt(), aPassedPoint->pnt(),
+                              anAngleAttr, aRadiusAttr);
   }
   data()->blockSendAttributeUpdated(false);
 }
index b3cfa3a2d1fc0254a9344955c2b80754bf8b2bce..6accaa209230d9e7d68e0fdbfeb4f102cb5f7796 100644 (file)
@@ -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()
   {
index f252df658aec33b08ba84de96b6d1de0512e733f..4159df870dc818c75cbbec40226aea8e2bc50d6d 100644 (file)
 #include <GeomAlgoAPI_CompoundBuilder.h>
 
 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");