Salome HOME
1. Sketch solver invalid state: do not restart the create operation;
authornds <nds@opencascade.com>
Tue, 8 Sep 2015 07:47:47 +0000 (10:47 +0300)
committernds <nds@opencascade.com>
Tue, 8 Sep 2015 07:48:08 +0000 (10:48 +0300)
2. Line creation: several click in the same point: do not deactivate point widget if the feature already contains this value. [Scenario: start sketch, start line creation, click in the same place; create contour, create other sketch, click in the point on the 1st sketch to create a line. It is not possible]
3. Correction to call customizeCurrentObject only when some is displayed/erased. If this check is absent, there can be a crash. Scenario of the crash is: Create contour, make two lines paralle, make them perpendicular, Undo. Reason: created message of Sketch comes earlies than redisplay of perpendicular. SketchPrs_Perpendicular: getResult -> crash.

src/PartSet/PartSet_Module.cpp
src/PartSet/PartSet_SketcherMgr.cpp
src/PartSet/PartSet_SketcherMgr.h
src/PartSet/PartSet_WidgetPoint2d.cpp
src/PartSet/PartSet_WidgetPoint2d.h
src/XGUI/XGUI_WorkshopListener.cpp

index 6304bd23206f68434c255e5fcc396863b7680d4b..26858896b19af355830196cee20c8a7b73f2ff8b 100755 (executable)
@@ -263,8 +263,8 @@ void PartSet_Module::onOperationCommitted(ModuleBase_Operation* theOperation)
                      myRestartingMode == RM_EmptyFeatureUsed)) {
     myLastOperationId = aFOperation->id();
     myLastFeature = myRestartingMode == RM_LastFeatureUsed ? aFOperation->feature() : FeaturePtr();
-    
-    launchOperation(myLastOperationId);
+    if (!sketchMgr()->sketchSolverError())
+      launchOperation(myLastOperationId);
   }
   breakOperationSequence();
 }
index c893f21cf3be1862145c9768ed69a1e1c0f6c7ec..b4cf246eac2e7827d57f60dcd9e7cbe781d99850 100644 (file)
@@ -11,9 +11,6 @@
 #include "PartSet_Tools.h"
 #include "PartSet_WidgetSketchLabel.h"
 
-#include <ModuleBase_WidgetEditor.h>
-#include <ModuleBase_ModelWidget.h>
-
 #include <XGUI_ModuleConnector.h>
 #include <XGUI_Displayer.h>
 #include <XGUI_Workshop.h>
 #include <XGUI_ViewerProxy.h>
 #include <XGUI_OperationMgr.h>
 
+#include <ModuleBase_IPropertyPanel.h>
+#include <ModuleBase_ISelection.h>
 #include <ModuleBase_IViewer.h>
 #include <ModuleBase_IWorkshop.h>
 #include <ModuleBase_IViewWindow.h>
+#include <ModuleBase_ModelWidget.h>
 #include <ModuleBase_Operation.h>
 #include <ModuleBase_OperationFeature.h>
-#include <ModuleBase_ISelection.h>
-#include <ModuleBase_IPropertyPanel.h>
 #include <ModuleBase_Operation.h>
+#include <ModuleBase_WidgetEditor.h>
 
 #include <GeomDataAPI_Point2D.h>
 
@@ -70,6 +69,7 @@
 
 #include <ModelAPI_Events.h>
 #include <ModelAPI_Session.h>
+#include <ModelAPI_AttributeString.h>
 
 #include <QMouseEvent>
 #include <QApplication>
@@ -667,6 +667,17 @@ void PartSet_SketcherMgr::launchEditing()
   }
 }
 
+bool PartSet_SketcherMgr::sketchSolverError()
+{
+  bool anError = false;
+  CompositeFeaturePtr aSketch = activeSketch();
+  if (aSketch.get()) {
+    AttributeStringPtr aAttributeString = aSketch->string(SketchPlugin_Sketch::SOLVER_ERROR());
+    anError = !aAttributeString->value().empty();
+  }
+  return anError;
+}
+
 
 const QStringList& PartSet_SketcherMgr::sketchOperationIdList()
 {
index cadfd32e53c924f6a6709994c4371914a2e7421b..477fdcb3053bb17c8e75443b6c6ea744e059a13f 100644 (file)
@@ -170,6 +170,10 @@ public:
   /// Restores previously saved selection state
   void restoreSelection();
 
+  /// Return error state of the sketch feature, true if the error has happened
+  /// \return boolean value
+  bool sketchSolverError();
+
   /// Returns list of strings which contains id's of sketch operations
   static const QStringList& sketchOperationIdList();
 
index 31a972e2fad97df0014f9714575072683366f8f7..1ffc4f4d234d66faf4fdb60b76450309d01eefec 100644 (file)
@@ -311,89 +311,86 @@ void PartSet_WidgetPoint2D::onMouseRelease(ModuleBase_IViewWindow* theWnd, QMous
     TopoDS_Shape aShape = aShapes.First();
     ObjectPtr aObject = aObjects.front();
     FeaturePtr aSelectedFeature = ModelAPI_Feature::feature(aObject);
+    bool anExternal = false;
     if (aSelectedFeature.get() != NULL) {
       std::shared_ptr<SketchPlugin_Feature> aSPFeature = 
               std::dynamic_pointer_cast<SketchPlugin_Feature>(aSelectedFeature);
       if ((!aSPFeature) && (!aShape.IsNull())) {
+        anExternal = true;
         ResultPtr aFixedObject = PartSet_Tools::findFixedObjectByExternal(aShape, aObject, mySketch);
         if (!aFixedObject.get())
           aObject = PartSet_Tools::createFixedObjectByExternal(aShape, aObject, mySketch);
-        setConstraintWith(aObject);
-        emit vertexSelected();
-        emit focusOutWidget(this);
-        return;
+
+        double aX, aY;
+        if (getPoint2d(aView, aShape, aX, aY) && isFeatureContainsPoint(myFeature, aX, aY)) {
+          // do not create a constraint to the point, which already used by the feature
+          // if the feature contains the point, focus is not switched
+          setPoint(aX, aY);
+        }
+        else {
+          setConstraintWith(aObject);
+          emit vertexSelected();
+          emit focusOutWidget(this);
+        }
       }
     }
-    double aX, aY;
-    bool isProcessed = false;
-    if (getPoint2d(aView, aShape, aX, aY)) {
-      bool aFeatureContainsPoint = false;
-  
-      std::shared_ptr<GeomAPI_Pnt2d> aPnt2d = 
-                                       std::shared_ptr<GeomAPI_Pnt2d>(new GeomAPI_Pnt2d(aX, aY));
-      std::list<AttributePtr> anAttributes =
-                                    myFeature->data()->attributes(GeomDataAPI_Point2D::typeId());
-      std::list<AttributePtr>::iterator anIter = anAttributes.begin();
-      for(; anIter != anAttributes.end(); anIter++) {
-        AttributePoint2DPtr aPoint2DAttribute =
-          std::dynamic_pointer_cast<GeomDataAPI_Point2D>(*anIter);
-        if (aPoint2DAttribute.get()) {
-          aFeatureContainsPoint = aPoint2DAttribute->pnt()->isEqual(aPnt2d);
-        }
+    if (!anExternal) {
+      double aX, aY;
+      bool isProcessed = false;
+      if (getPoint2d(aView, aShape, aX, aY) && isFeatureContainsPoint(myFeature, aX, aY)) {
+        // when the point is selected, the coordinates of the point should be set into the attribute
+        // if the feature contains the point, focus is not switched
+        setPoint(aX, aY);
       }
-      // when the point is selected, the coordinates of the point should be set into the attribute
-      setPoint(aX, aY);
-      // do not set a coincidence constraint in the attribute if the feature contains a point
-      // with the same coordinates. It is important for line creation in order to do not set
-      // the same constraints for the same points, oterwise the result line has zero length.
-      if (aFeatureContainsPoint)
-        return;
       else {
-        PartSet_Tools::setConstraints(mySketch, feature(), attributeID(),aX, aY);
+        // do not set a coincidence constraint in the attribute if the feature contains a point
+        // with the same coordinates. It is important for line creation in order to do not set
+        // the same constraints for the same points, oterwise the result line has zero length.
+        if (getPoint2d(aView, aShape, aX, aY))
+          PartSet_Tools::setConstraints(mySketch, feature(), attributeID(), aX, aY);
+        else if (aShape.ShapeType() == TopAbs_EDGE)
+          setConstraintWith(aObject);
+
+        // it is important to perform updateObject() in order to the current value is 
+        // processed by Sketch Solver. Test case: line is created from a previous point
+        // to some distance, but in the area of the highlighting of the point. Constraint
+        // coincidence is created, after the solver is performed, the distance between the
+        // points of the line becomes less than the tolerance. Validator of the line returns
+        // false, the line will be aborted, but sketch stays valid.
+        updateObject(feature());
+        emit vertexSelected();
+        emit focusOutWidget(this);
       }
-      isProcessed = true;
-    } else if (aShape.ShapeType() == TopAbs_EDGE) {
-      setConstraintWith(aObject);
-      isProcessed = true;
-    }
-    if (isProcessed) {
-      // it is important to perform updateObject() in order to the current value is 
-      // processed by Sketch Solver. Test case: line is created from a previous point
-      // to some distance, but in the area of the highlighting of the point. Constraint
-      // coincidence is created, after the solver is performed, the distance between the
-      // points of the line becomes less than the tolerance. Validator of the line returns
-      // false, the line will be aborted, but sketch stays valid.
-      updateObject(feature());
-      emit vertexSelected();
-      emit focusOutWidget(this);
-      return;
     }
   }
   // End of Bug dependent fragment
+  else {
+    // A case when point is taken from mouse event
+    gp_Pnt aPoint = PartSet_Tools::convertClickToPoint(theEvent->pos(), theWnd->v3dView());
+    double aX, anY;
+    PartSet_Tools::convertTo2D(aPoint, mySketch, aView, aX, anY);
 
-  // A case when point is taken from mouse event
-  gp_Pnt aPoint = PartSet_Tools::convertClickToPoint(theEvent->pos(), theWnd->v3dView());
-  double aX, anY;
-  PartSet_Tools::convertTo2D(aPoint, mySketch, aView, aX, anY);
-  if (!setPoint(aX, anY))
-    return;
+    // if the feature contains the point, focus is not switched
+    if (!setPoint(aX, anY) || isFeatureContainsPoint(myFeature, aX, anY))
+      return;
 
-  /// Start alternative code
-  //std::shared_ptr<GeomDataAPI_Point2D> aFeaturePoint = std::dynamic_pointer_cast<
-  //    GeomDataAPI_Point2D>(feature()->data()->attribute(attributeID()));
-  //QList<FeaturePtr> aIgnore;
-  //aIgnore.append(feature());
-
-  //double aTolerance = aView->Convert(7);
-  //std::shared_ptr<GeomDataAPI_Point2D> aAttrPnt = 
-  //  PartSet_Tools::findAttributePoint(mySketch, aX, anY, aTolerance, aIgnore);
-  //if (aAttrPnt.get() != NULL) {
-  //  aFeaturePoint->setValue(aAttrPnt->pnt());
-  //  PartSet_Tools::createConstraint(mySketch, aAttrPnt, aFeaturePoint);
-  //  emit vertexSelected();
-  //}
-  /// End alternative code
-  emit focusOutWidget(this);
+    /// Start alternative code
+    //std::shared_ptr<GeomDataAPI_Point2D> aFeaturePoint = std::dynamic_pointer_cast<
+    //    GeomDataAPI_Point2D>(feature()->data()->attribute(attributeID()));
+    //QList<FeaturePtr> aIgnore;
+    //aIgnore.append(feature());
+
+    //double aTolerance = aView->Convert(7);
+    //std::shared_ptr<GeomDataAPI_Point2D> aAttrPnt = 
+    //  PartSet_Tools::findAttributePoint(mySketch, aX, anY, aTolerance, aIgnore);
+    //if (aAttrPnt.get() != NULL) {
+    //  aFeaturePoint->setValue(aAttrPnt->pnt());
+    //  PartSet_Tools::createConstraint(mySketch, aAttrPnt, aFeaturePoint);
+    //  emit vertexSelected();
+    //}
+    /// End alternative code
+    emit focusOutWidget(this);
+  }
 }
 
 
@@ -419,6 +416,30 @@ double PartSet_WidgetPoint2D::y() const
   return myYSpin->value();
 }
 
+
+bool PartSet_WidgetPoint2D::isFeatureContainsPoint(const FeaturePtr& theFeature,
+                                                   double theX, double theY)
+{
+  bool aPointIsFound = false;
+  AttributePtr aWidgetAttribute = myFeature->attribute(attributeID());
+
+  std::shared_ptr<GeomAPI_Pnt2d> aPnt2d = 
+                                    std::shared_ptr<GeomAPI_Pnt2d>(new GeomAPI_Pnt2d(theX, theY));
+  std::list<AttributePtr> anAttributes =
+                                myFeature->data()->attributes(GeomDataAPI_Point2D::typeId());
+  std::list<AttributePtr>::iterator anIter = anAttributes.begin();
+  for(; anIter != anAttributes.end(); anIter++) {
+    AttributePoint2DPtr aPoint2DAttribute =
+      std::dynamic_pointer_cast<GeomDataAPI_Point2D>(*anIter);
+    if (aPoint2DAttribute == aWidgetAttribute)
+      continue;
+    if (aPoint2DAttribute.get()) {
+      aPointIsFound = aPoint2DAttribute->pnt()->isEqual(aPnt2d);
+    }
+  }
+  return aPointIsFound;
+}
+
 void PartSet_WidgetPoint2D::onValuesChanged()
 {
   myLockApplyMgr->valuesChanged();
index d8b235c9c762a3d07b5fddb55e59f6e6ef47c589..a07107f669ab30a56c698ddcd5333d1ea7fec5bc 100644 (file)
@@ -112,6 +112,13 @@ protected:
   /// The methiod called when widget is activated
   virtual void activateCustom();
 
+  /// Returns true if the feature contains Point2D attribute with the same coordinates
+  /// The attribute of the widget is not processed.
+  /// \param theX the X coordinate
+  /// \param theY the Y coordinate
+  /// \return boolean result
+  bool isFeatureContainsPoint(const FeaturePtr& theFeature, double theX, double theY);
+
 private slots:
   /// Process value changed event
   void onValuesChanged();
index 6e4879d57455376d509f3490885e853754254728..82620e63501d395c270b632b05e0a4ea3edaae16 100755 (executable)
@@ -324,9 +324,10 @@ void XGUI_WorkshopListener::onFeatureRedisplayMsg(const std::shared_ptr<ModelAPI
       }
     }
   }
-  aRedisplayed = customizeCurrentObject() | aRedisplayed;
-  if (aRedisplayed)
-  aDisplayer->updateViewer();
+  if (aRedisplayed) {
+    customizeCurrentObject();
+    aDisplayer->updateViewer();
+  }
 }
 //******************************************************
 void XGUI_WorkshopListener::onFeatureCreatedMsg(const std::shared_ptr<ModelAPI_ObjectUpdatedMessage>& theMsg)
@@ -374,12 +375,13 @@ void XGUI_WorkshopListener::onFeatureCreatedMsg(const std::shared_ptr<ModelAPI_O
         anObject->setDisplayed(false);
     }
   }
-  aDisplayed = customizeCurrentObject() || aDisplayed;
 
   //if (myObjectBrowser)
   //  myObjectBrowser->processEvent(theMsg);
-  if (aDisplayed)
+  if (aDisplayed) {
+    customizeCurrentObject();
     workshop()->displayer()->updateViewer();
+  }
   //if (aHasPart) { // TODO: Avoid activate last part on loading of document
   //  activateLastPart();
   //}