Salome HOME
#1150 Tab buttons problems
[modules/shaper.git] / src / PartSet / PartSet_Validators.cpp
index 5b985c8915e1918be97fabcaa9dd190716d56a27..b446bab1642528b4922b8ce7e84956f677309445 100755 (executable)
@@ -7,13 +7,13 @@
 #include "PartSet_Validators.h"
 
 #include "PartSet_Tools.h"
+#include "PartSet_SketcherMgr.h"
 
 #include <TopoDS.hxx>
 #include <TopoDS_Edge.hxx>
 #include <BRep_Tool.hxx>
 #include <GeomAdaptor_Curve.hxx>
 #include <GeomAbs_CurveType.hxx>
-#include <GeomValidators_Tools.h>
 #include <ModuleBase_ISelection.h>
 #include <ModuleBase_WidgetShapeSelector.h>
 #include <ModuleBase_OperationFeature.h>
@@ -89,18 +89,31 @@ std::shared_ptr<GeomAPI_Pln> sketcherPlane(ModuleBase_Operation* theOperation)
   return aEmptyPln; 
 }
 
-bool PartSet_DistanceSelection::isValid(const ModuleBase_ISelection* theSelection, ModuleBase_Operation* theOperation) const
+
+bool isEmptySelectionValid(ModuleBase_Operation* theOperation)
 {
-  if (theSelection->getSelected(ModuleBase_ISelection::Viewer).size() == 0) {
-    ModuleBase_OperationFeature* aFeatureOp = dynamic_cast<ModuleBase_OperationFeature*>(theOperation);
-    if (!aFeatureOp->isEditOperation()) {
-      return true;
+  ModuleBase_OperationFeature* aFeatureOp = dynamic_cast<ModuleBase_OperationFeature*>(theOperation);
+  // during the create operation empty selection is always valid
+  if (!aFeatureOp->isEditOperation()) {
+    return true;
+  }
+  else {
+    if (PartSet_SketcherMgr::isSketchOperation(aFeatureOp)) {
+      std::shared_ptr<GeomAPI_Pln> aPlane = sketcherPlane(theOperation);
+      if (aPlane.get())
+        return true;
+      else 
+        return false;
     }
-    std::shared_ptr<GeomAPI_Pln> aPlane = sketcherPlane(theOperation);
-    if (aPlane.get())
+    else// in edit operation an empty selection is always valid, performed for re-entrant operrations
       return true;
-    else 
-      return false;
+  }
+}
+
+bool PartSet_DistanceSelection::isValid(const ModuleBase_ISelection* theSelection, ModuleBase_Operation* theOperation) const
+{
+  if (theSelection->getSelected(ModuleBase_ISelection::Viewer).size() == 0) {
+    return isEmptySelectionValid(theOperation);
   } else {
     int aCount = shapesNbPoints(theSelection) + shapesNbLines(theSelection);
     return (aCount > 0) && (aCount < 3);
@@ -110,15 +123,7 @@ bool PartSet_DistanceSelection::isValid(const ModuleBase_ISelection* theSelectio
 bool PartSet_LengthSelection::isValid(const ModuleBase_ISelection* theSelection, ModuleBase_Operation* theOperation) const
 {
   if (theSelection->getSelected(ModuleBase_ISelection::Viewer).size() == 0) {
-    ModuleBase_OperationFeature* aFeatureOp = dynamic_cast<ModuleBase_OperationFeature*>(theOperation);
-    if (!aFeatureOp->isEditOperation()) {
-      return true;
-    }
-    std::shared_ptr<GeomAPI_Pln> aPlane = sketcherPlane(theOperation);
-    if (aPlane.get())
-      return true;
-    else 
-      return false;
+    return isEmptySelectionValid(theOperation);
   } else {
     int aCount = shapesNbLines(theSelection);
     return (aCount == 1);
@@ -128,15 +133,7 @@ bool PartSet_LengthSelection::isValid(const ModuleBase_ISelection* theSelection,
 bool PartSet_PerpendicularSelection::isValid(const ModuleBase_ISelection* theSelection, ModuleBase_Operation* theOperation) const
 {
   if (theSelection->getSelected(ModuleBase_ISelection::Viewer).size() == 0) {
-    ModuleBase_OperationFeature* aFeatureOp = dynamic_cast<ModuleBase_OperationFeature*>(theOperation);
-    if (!aFeatureOp->isEditOperation()) {
-      return true;
-    }
-    std::shared_ptr<GeomAPI_Pln> aPlane = sketcherPlane(theOperation);
-    if (aPlane.get())
-      return true;
-    else 
-      return false;
+    return isEmptySelectionValid(theOperation);
   } else {
     int aCount = shapesNbLines(theSelection);
     return (aCount > 0) && (aCount < 3);
@@ -146,15 +143,7 @@ bool PartSet_PerpendicularSelection::isValid(const ModuleBase_ISelection* theSel
 bool PartSet_ParallelSelection::isValid(const ModuleBase_ISelection* theSelection, ModuleBase_Operation* theOperation) const
 {
   if (theSelection->getSelected(ModuleBase_ISelection::Viewer).size() == 0) {
-    ModuleBase_OperationFeature* aFeatureOp = dynamic_cast<ModuleBase_OperationFeature*>(theOperation);
-    if (!aFeatureOp->isEditOperation()) {
-      return true;
-    }
-    std::shared_ptr<GeomAPI_Pln> aPlane = sketcherPlane(theOperation);
-    if (aPlane.get())
-      return true;
-    else 
-      return false;
+    return isEmptySelectionValid(theOperation);
   } else {
     int aCount = shapesNbLines(theSelection);
     return (aCount > 0) && (aCount < 3);
@@ -164,15 +153,7 @@ bool PartSet_ParallelSelection::isValid(const ModuleBase_ISelection* theSelectio
 bool PartSet_RadiusSelection::isValid(const ModuleBase_ISelection* theSelection, ModuleBase_Operation* theOperation) const
 {
   if (theSelection->getSelected(ModuleBase_ISelection::Viewer).size() == 0) {
-    ModuleBase_OperationFeature* aFeatureOp = dynamic_cast<ModuleBase_OperationFeature*>(theOperation);
-    if (!aFeatureOp->isEditOperation()) {
-      return true;
-    }
-    std::shared_ptr<GeomAPI_Pln> aPlane = sketcherPlane(theOperation);
-    if (aPlane.get())
-      return true;
-    else 
-      return false;
+    return isEmptySelectionValid(theOperation);
   } else {
     QList<ModuleBase_ViewerPrs> aList = theSelection->getSelected(ModuleBase_ISelection::Viewer);
     ModuleBase_ViewerPrs aPrs;
@@ -197,15 +178,7 @@ bool PartSet_RadiusSelection::isValid(const ModuleBase_ISelection* theSelection,
 bool PartSet_RigidSelection::isValid(const ModuleBase_ISelection* theSelection, ModuleBase_Operation* theOperation) const
 {
   if (theSelection->getSelected(ModuleBase_ISelection::Viewer).size() == 0) {
-    ModuleBase_OperationFeature* aFeatureOp = dynamic_cast<ModuleBase_OperationFeature*>(theOperation);
-    if (!aFeatureOp->isEditOperation()) {
-      return true;
-    }
-    std::shared_ptr<GeomAPI_Pln> aPlane = sketcherPlane(theOperation);
-    if (aPlane.get())
-      return true;
-    else 
-      return false;
+    return isEmptySelectionValid(theOperation);
   } else {
     QList<ModuleBase_ViewerPrs> aList = theSelection->getSelected(ModuleBase_ISelection::Viewer);
     return (aList.count() == 1);
@@ -216,15 +189,7 @@ bool PartSet_RigidSelection::isValid(const ModuleBase_ISelection* theSelection,
 bool PartSet_CoincidentSelection::isValid(const ModuleBase_ISelection* theSelection, ModuleBase_Operation* theOperation) const
 {
   if (theSelection->getSelected(ModuleBase_ISelection::Viewer).size() == 0) {
-    ModuleBase_OperationFeature* aFeatureOp = dynamic_cast<ModuleBase_OperationFeature*>(theOperation);
-    if (!aFeatureOp->isEditOperation()) {
-      return true;
-    }
-    std::shared_ptr<GeomAPI_Pln> aPlane = sketcherPlane(theOperation);
-    if (aPlane.get())
-      return true;
-    else 
-      return false;
+    return isEmptySelectionValid(theOperation);
   } else {
     // Coincident can be applied to points and to lines
     int aCount = shapesNbPoints(theSelection);
@@ -236,15 +201,7 @@ bool PartSet_CoincidentSelection::isValid(const ModuleBase_ISelection* theSelect
 bool PartSet_HVDirSelection::isValid(const ModuleBase_ISelection* theSelection, ModuleBase_Operation* theOperation) const
 {
   if (theSelection->getSelected(ModuleBase_ISelection::Viewer).size() == 0) {
-    ModuleBase_OperationFeature* aFeatureOp = dynamic_cast<ModuleBase_OperationFeature*>(theOperation);
-    if (!aFeatureOp->isEditOperation()) {
-      return true;
-    }
-    std::shared_ptr<GeomAPI_Pln> aPlane = sketcherPlane(theOperation);
-    if (aPlane.get())
-      return true;
-    else 
-      return false;
+    return isEmptySelectionValid(theOperation);
   } else {
     int aCount = shapesNbLines(theSelection);
     return (aCount == 1);
@@ -254,33 +211,17 @@ bool PartSet_HVDirSelection::isValid(const ModuleBase_ISelection* theSelection,
 bool PartSet_FilletSelection::isValid(const ModuleBase_ISelection* theSelection, ModuleBase_Operation* theOperation) const
 {
   if (theSelection->getSelected(ModuleBase_ISelection::Viewer).size() == 0) {
-    ModuleBase_OperationFeature* aFeatureOp = dynamic_cast<ModuleBase_OperationFeature*>(theOperation);
-    if (!aFeatureOp->isEditOperation()) {
-      return true;
-    }
-    std::shared_ptr<GeomAPI_Pln> aPlane = sketcherPlane(theOperation);
-    if (aPlane.get())
-      return true;
-    else 
-      return false;
+    return isEmptySelectionValid(theOperation);
   } else {
-    int aCount = shapesNbLines(theSelection);
-    return (aCount > 0) && (aCount < 3);
+    int aCount = shapesNbPoints(theSelection);
+    return aCount == 1;
   }
 }
 
 bool PartSet_TangentSelection::isValid(const ModuleBase_ISelection* theSelection, ModuleBase_Operation* theOperation) const
 {
   if (theSelection->getSelected(ModuleBase_ISelection::Viewer).size() == 0) {
-    ModuleBase_OperationFeature* aFeatureOp = dynamic_cast<ModuleBase_OperationFeature*>(theOperation);
-    if (!aFeatureOp->isEditOperation()) {
-      return true;
-    }
-    std::shared_ptr<GeomAPI_Pln> aPlane = sketcherPlane(theOperation);
-    if (aPlane.get())
-      return true;
-    else 
-      return false;
+    return isEmptySelectionValid(theOperation);
   } else {
     QList<ModuleBase_ViewerPrs> aList = theSelection->getSelected(ModuleBase_ISelection::Viewer);
     if ((aList.size() == 0) || (aList.size() > 2))
@@ -328,21 +269,52 @@ bool PartSet_TangentSelection::isValid(const ModuleBase_ISelection* theSelection
 bool PartSet_AngleSelection::isValid(const ModuleBase_ISelection* theSelection, ModuleBase_Operation* theOperation) const
 {
   if (theSelection->getSelected(ModuleBase_ISelection::Viewer).size() == 0) {
-    ModuleBase_OperationFeature* aFeatureOp = dynamic_cast<ModuleBase_OperationFeature*>(theOperation);
-    if (!aFeatureOp->isEditOperation()) {
-      return true;
-    }
-    std::shared_ptr<GeomAPI_Pln> aPlane = sketcherPlane(theOperation);
-    if (aPlane.get())
-      return true;
-    else 
-      return false;
+    return isEmptySelectionValid(theOperation);
   } else {
     int aCount = shapesNbLines(theSelection);
     return (aCount > 0) && (aCount < 3);
   }
 }
 
+bool PartSet_EqualSelection::isValid(const ModuleBase_ISelection* theSelection, ModuleBase_Operation* theOperation) const
+{
+  if (theSelection->getSelected(ModuleBase_ISelection::Viewer).size() == 0) {
+    return isEmptySelectionValid(theOperation);
+  } else {
+    QList<ModuleBase_ViewerPrs> aList = theSelection->getSelected(ModuleBase_ISelection::Viewer);
+    ModuleBase_ViewerPrs aPrs;
+    int aCount = 0;
+    int aType = 0;
+    foreach (ModuleBase_ViewerPrs aPrs, aList) {
+      std::shared_ptr<GeomAPI_Shape> aShape(new GeomAPI_Shape);
+      aShape->setImpl(new TopoDS_Shape(aPrs.shape()));
+      if (aShape->isEdge()) {
+        aCount++;
+        GeomAPI_Edge aEdge(aShape);
+        if (aEdge.isLine()) {
+          if (aCount == 1)
+            aType = 1;
+          else if (aType != 1)
+            return false;
+        } else if (aEdge.isCircle()) {
+          if (aCount == 1)
+            aType = 2;
+          else if (aType != 2)
+            return false;
+        } else if (aEdge.isArc()) {
+          if (aCount == 1)
+            aType = 3;
+          else if (aType != 3)
+            return false;
+        }
+      } else
+        return false;
+    }
+    return (aCount > 0) && (aCount < 3);
+  }
+}
+
+
 std::string PartSet_DifferentObjectsValidator::errorMessage(
                          const PartSet_DifferentObjectsValidator::ErrorType& theType,
                          const std::string& thEqualObject, const std::string& theFirstAttribute,
@@ -578,6 +550,21 @@ bool PartSet_SketchEntityValidator::isValid(const AttributePtr& theAttribute,
       }
     }
   }
+  if (anAttributeType == ModelAPI_AttributeSelection::typeId()) {
+    AttributeSelectionPtr aSelectAttr = 
+                      std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
+    ObjectPtr anObject = aSelectAttr->context();
+    // a context of the selection attribute is a feature result. It can be a case when the result
+    // of the feature is null, e.g. the feature is modified and has not been executed yet.
+    // The validator returns an invalid result here. The case is an extrusion built on a sketch
+    // feature. A new sketch element creation leads to an empty result.
+    if (!anObject.get())
+      isSketchEntities = false;
+    else {
+      FeaturePtr aFeature = ModelAPI_Feature::feature(anObject);
+      isSketchEntities = anEntityKinds.find(aFeature->getKind()) != anEntityKinds.end();
+    }
+  }
   if (anAttributeType == ModelAPI_AttributeRefList::typeId()) {
     AttributeRefListPtr aRefListAttr =
       std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(theAttribute);