Salome HOME
Support of wide string
[modules/shaper.git] / src / PartSet / PartSet_Validators.cpp
old mode 100755 (executable)
new mode 100644 (file)
index 32fea83..76c8e61
@@ -1,4 +1,4 @@
-// Copyright (C) 2014-2017  CEA/DEN, EDF R&D
+// Copyright (C) 2014-2019  CEA/DEN, EDF R&D
 //
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
 //
 // You should have received a copy of the GNU Lesser General Public
 // License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 //
-// See http://www.salome-platform.org/ or
-// email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
 
 #include "PartSet_Validators.h"
@@ -55,6 +54,7 @@
 #include <GeomAPI_Edge.h>
 
 #include <list>
+#include <unordered_map>
 #ifdef _DEBUG
 #include <iostream>
 #endif
@@ -75,7 +75,9 @@ int shapesNbPoints(const ModuleBase_ISelection* theSelection)
   return aCount;
 }
 
-int shapesNbLines(const ModuleBase_ISelection* theSelection)
+typedef std::unordered_map<int, int> ShapeQuantity;
+
+int shapesNbEdges(const ModuleBase_ISelection* theSelection, ShapeQuantity& theEdges)
 {
   QList<ModuleBase_ViewerPrsPtr> aList = theSelection->getSelected(ModuleBase_ISelection::Viewer);
   int aCount = 0;
@@ -88,8 +90,8 @@ int shapesNbLines(const ModuleBase_ISelection* theSelection)
         Standard_Real aStart, aEnd;
         Handle(Geom_Curve) aCurve = BRep_Tool::Curve(aEdge, aStart, aEnd);
         GeomAdaptor_Curve aAdaptor(aCurve);
-        if (aAdaptor.GetType() == GeomAbs_Line)
-          aCount++;
+        theEdges[(int)aAdaptor.GetType()] += 1;
+        aCount++;
       }
     }
   }
@@ -142,8 +144,11 @@ bool PartSet_DistanceSelection::isValid(const ModuleBase_ISelection* theSelectio
   if (theSelection->getSelected(ModuleBase_ISelection::Viewer).size() == 0) {
     return isEmptySelectionValid(theOperation);
   } else {
-    int aCount = shapesNbPoints(theSelection) + shapesNbLines(theSelection);
-    return (aCount > 0) && (aCount < 3);
+    int aNbPoints = shapesNbPoints(theSelection);
+    ShapeQuantity aShapes;
+    int aNbEdges = shapesNbEdges(theSelection, aShapes);
+    return (aNbPoints >= 0 && aNbPoints < 3) &&
+           (aShapes[GeomAbs_Line] == aNbEdges && aNbEdges >= 0 && aNbEdges < 2);
   }
 }
 
@@ -153,8 +158,10 @@ bool PartSet_LengthSelection::isValid(const ModuleBase_ISelection* theSelection,
   if (theSelection->getSelected(ModuleBase_ISelection::Viewer).size() == 0) {
     return isEmptySelectionValid(theOperation);
   } else {
-    int aCount = shapesNbLines(theSelection);
-    return (aCount == 1);
+    int aNbPoints = shapesNbPoints(theSelection);
+    ShapeQuantity aShapes;
+    int aNbEdges = shapesNbEdges(theSelection, aShapes);
+    return aNbPoints == 0 && (aShapes[GeomAbs_Line] == aNbEdges && aNbEdges == 1);
   }
 }
 
@@ -164,8 +171,10 @@ bool PartSet_PerpendicularSelection::isValid(const ModuleBase_ISelection* theSel
   if (theSelection->getSelected(ModuleBase_ISelection::Viewer).size() == 0) {
     return isEmptySelectionValid(theOperation);
   } else {
-    int aCount = shapesNbLines(theSelection);
-    return (aCount > 0) && (aCount < 3);
+    int aNbPoints = shapesNbPoints(theSelection);
+    ShapeQuantity aShapes;
+    int aNbEdges = shapesNbEdges(theSelection, aShapes);
+    return aNbPoints == 0 && aShapes[GeomAbs_Line] == aNbEdges && aNbEdges > 0 && aNbEdges < 3;
   }
 }
 
@@ -175,8 +184,10 @@ bool PartSet_ParallelSelection::isValid(const ModuleBase_ISelection* theSelectio
   if (theSelection->getSelected(ModuleBase_ISelection::Viewer).size() == 0) {
     return isEmptySelectionValid(theOperation);
   } else {
-    int aCount = shapesNbLines(theSelection);
-    return (aCount > 0) && (aCount < 3);
+    int aNbPoints = shapesNbPoints(theSelection);
+    ShapeQuantity aShapes;
+    int aNbEdges = shapesNbEdges(theSelection, aShapes);
+    return aNbPoints == 0 && aShapes[GeomAbs_Line] == aNbEdges && aNbEdges > 0 && aNbEdges < 3;
   }
 }
 
@@ -186,24 +197,10 @@ bool PartSet_RadiusSelection::isValid(const ModuleBase_ISelection* theSelection,
   if (theSelection->getSelected(ModuleBase_ISelection::Viewer).size() == 0) {
     return isEmptySelectionValid(theOperation);
   } else {
-    QList<ModuleBase_ViewerPrsPtr> aList =
-      theSelection->getSelected(ModuleBase_ISelection::Viewer);
-    int aCount = 0;
-    foreach (ModuleBase_ViewerPrsPtr aPrs, aList) {
-      const GeomShapePtr& aShape = aPrs->shape();
-      if (aShape.get() && !aShape->isNull()) {
-        if (aShape->shapeType() == GeomAPI_Shape::EDGE) {
-          const TopoDS_Shape& aTDShape = aShape->impl<TopoDS_Shape>();
-          TopoDS_Edge aEdge = TopoDS::Edge(aTDShape);
-          Standard_Real aStart, aEnd;
-          Handle(Geom_Curve) aCurve = BRep_Tool::Curve(aEdge, aStart, aEnd);
-          GeomAdaptor_Curve aAdaptor(aCurve);
-          if (aAdaptor.GetType() == GeomAbs_Circle)
-            aCount++;
-        }
-      }
-    }
-    return (aCount == 1);
+    int aNbPoints = shapesNbPoints(theSelection);
+    ShapeQuantity aShapes;
+    int aNbEdges = shapesNbEdges(theSelection, aShapes);
+    return aNbPoints == 0 && (aShapes[GeomAbs_Circle] == aNbEdges && aNbEdges == 1);
   }
 }
 
@@ -239,9 +236,10 @@ bool PartSet_CoincidentSelection::isValid(const ModuleBase_ISelection* theSelect
     return isEmptySelectionValid(theOperation);
   } else {
     // Coincident can be applied to points and to lines
-    int aCount = shapesNbPoints(theSelection);
-    aCount += shapesNbLines(theSelection);
-    return (aCount > 0) && (aCount < 3);
+    int aNbPoints = shapesNbPoints(theSelection);
+    ShapeQuantity aShapes;
+    int aNbEdges = shapesNbEdges(theSelection, aShapes);
+    return (aNbPoints >= 0 && aNbPoints < 3) && (aNbEdges >= 0 && aNbEdges < 2);
   }
 }
 
@@ -251,8 +249,10 @@ bool PartSet_HVDirSelection::isValid(const ModuleBase_ISelection* theSelection,
   if (theSelection->getSelected(ModuleBase_ISelection::Viewer).size() == 0) {
     return isEmptySelectionValid(theOperation);
   } else {
-    int aCount = shapesNbLines(theSelection);
-    return (aCount == 1);
+    int aNbPoints = shapesNbPoints(theSelection);
+    ShapeQuantity aShapes;
+    int aNbEdges = shapesNbEdges(theSelection, aShapes);
+    return aNbPoints == 0 && (aShapes[GeomAbs_Line] == aNbEdges && aNbEdges == 1);
   }
 }
 
@@ -263,7 +263,9 @@ bool PartSet_FilletSelection::isValid(const ModuleBase_ISelection* theSelection,
     return isEmptySelectionValid(theOperation);
   } else {
     int aCount = shapesNbPoints(theSelection);
-    return aCount > 1;
+    ShapeQuantity aShapes;
+    int aNbEdges = shapesNbEdges(theSelection, aShapes);
+    return aCount > 1 && aNbEdges == 0;
   }
 }
 
@@ -273,35 +275,10 @@ bool PartSet_TangentSelection::isValid(const ModuleBase_ISelection* theSelection
   if (theSelection->getSelected(ModuleBase_ISelection::Viewer).size() == 0) {
     return isEmptySelectionValid(theOperation);
   } else {
-    QList<ModuleBase_ViewerPrsPtr> aList = theSelection->getSelected(ModuleBase_ISelection::Viewer);
-    if ((aList.size() == 0) || (aList.size() > 2))
-      return false;
-
-    ModuleBase_ViewerPrsPtr aPrs = aList.first();
-    const GeomShapePtr& aShape = aPrs->shape();
-    if (!aShape.get() || aShape->isNull() || aShape->shapeType() != GeomAPI_Shape::EDGE)
-      return false;
-    GeomAPI_Edge aEdge1(aShape);
-
-    if (aEdge1.isLine() || aEdge1.isArc()) {
-      if (aList.size() == 2) {
-        // Check second selection
-        aPrs = aList.last();
-        const GeomShapePtr& aShape2 = aPrs->shape();
-        if (!aShape2.get() || aShape2->isNull() || aShape2->shapeType() != GeomAPI_Shape::EDGE)
-          return false;
-        GeomAPI_Edge aEdge2(aShape2);
-
-        if (aEdge1.isLine() && aEdge2.isArc())
-          return true;
-        else if (aEdge1.isArc() && aEdge2.isLine())
-          return true;
-        else
-          return false;
-      } else
-        return true;
-    }
-    return false;
+    int aNbPoints = shapesNbPoints(theSelection);
+    ShapeQuantity aShapes;
+    int aNbEdges = shapesNbEdges(theSelection, aShapes);
+    return aNbPoints == 0 && (aNbEdges == 1 || (aNbEdges == 2 && aShapes[GeomAbs_Line] == 1));
   }
 }
 
@@ -311,8 +288,10 @@ bool PartSet_AngleSelection::isValid(const ModuleBase_ISelection* theSelection,
   if (theSelection->getSelected(ModuleBase_ISelection::Viewer).size() == 0) {
     return isEmptySelectionValid(theOperation);
   } else {
-    int aCount = shapesNbLines(theSelection);
-    return (aCount > 0) && (aCount < 3);
+    int aNbPoints = shapesNbPoints(theSelection);
+    ShapeQuantity aShapes;
+    int aNbEdges = shapesNbEdges(theSelection, aShapes);
+    return aNbPoints == 0 && aShapes[GeomAbs_Line] == aNbEdges && aNbEdges > 0 && aNbEdges < 3;
   }
 }
 
@@ -322,35 +301,13 @@ bool PartSet_EqualSelection::isValid(const ModuleBase_ISelection* theSelection,
   if (theSelection->getSelected(ModuleBase_ISelection::Viewer).size() == 0) {
     return isEmptySelectionValid(theOperation);
   } else {
-    QList<ModuleBase_ViewerPrsPtr> aList =
-      theSelection->getSelected(ModuleBase_ISelection::Viewer);
-    int aCount = 0;
-    int aType = 0;
-    foreach (ModuleBase_ViewerPrsPtr aPrs, aList) {
-      GeomShapePtr aShape = aPrs->shape();
-      if (aShape.get() && 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);
+    int aNbPoints = shapesNbPoints(theSelection);
+    ShapeQuantity aShapes;
+    int aNbEdges = shapesNbEdges(theSelection, aShapes);
+    return aNbPoints == 0 && (aNbEdges > 0 && aNbEdges < 3) &&
+           (aShapes[GeomAbs_Line] == aNbEdges ||
+            aShapes[GeomAbs_Circle] == aNbEdges ||
+            aShapes[GeomAbs_Ellipse] == aNbEdges);
   }
 }
 
@@ -360,8 +317,10 @@ bool PartSet_CollinearSelection::isValid(const ModuleBase_ISelection* theSelecti
   if (theSelection->getSelected(ModuleBase_ISelection::Viewer).size() == 0) {
     return isEmptySelectionValid(theOperation);
   } else {
-    int aCount = shapesNbLines(theSelection);
-    return (aCount > 0) && (aCount < 3);
+    int aNbPoints = shapesNbPoints(theSelection);
+    ShapeQuantity aShapes;
+    int aNbEdges = shapesNbEdges(theSelection, aShapes);
+    return aNbPoints == 0 && aShapes[GeomAbs_Line] == aNbEdges && aNbEdges > 0 && aNbEdges < 3;
   }
 }
 
@@ -370,8 +329,12 @@ bool PartSet_MiddlePointSelection::isValid(const ModuleBase_ISelection* theSelec
 {
   if (theSelection->getSelected(ModuleBase_ISelection::Viewer).size() == 0)
     return isEmptySelectionValid(theOperation);
-  else
-    return shapesNbLines(theSelection) == 1 || shapesNbPoints(theSelection) == 1;
+  else {
+    int aNbPoints = shapesNbPoints(theSelection);
+    ShapeQuantity aShapes;
+    int aNbEdges = shapesNbEdges(theSelection, aShapes);
+    return (aNbPoints >= 0 && aNbPoints < 3) && (aNbEdges >= 0 && aNbEdges < 2);
+  }
 }
 
 bool PartSet_MultyTranslationSelection::isValid(const ModuleBase_ISelection* theSelection,
@@ -380,8 +343,9 @@ bool PartSet_MultyTranslationSelection::isValid(const ModuleBase_ISelection* the
   if (theSelection->getSelected(ModuleBase_ISelection::Viewer).size() == 0) {
     return isEmptySelectionValid(theOperation);
   } else {
-    int aCount = shapesNbLines(theSelection);
-    return aCount > 0;
+    ShapeQuantity aShapes;
+    int aNbEdges = shapesNbEdges(theSelection, aShapes);
+    return aNbEdges > 0;
   }
 }
 
@@ -391,31 +355,24 @@ bool PartSet_SplitSelection::isValid(const ModuleBase_ISelection* theSelection,
   if (theSelection->getSelected(ModuleBase_ISelection::Viewer).size() == 0) {
     return isEmptySelectionValid(theOperation);
   } else {
-    int aCount = shapesNbLines(theSelection);
-    return aCount > 0;
+    ShapeQuantity aShapes;
+    int aNbEdges = shapesNbEdges(theSelection, aShapes);
+    return aNbEdges > 0;
   }
 }
 
 bool PartSet_ProjectionSelection::isValid(const ModuleBase_ISelection* theSelection,
                                      ModuleBase_Operation* theOperation) const
 {
-  if (theSelection->getSelected(ModuleBase_ISelection::Viewer).size() == 0) {
-    return isEmptySelectionValid(theOperation);
-  } else {
-    int aCount = shapesNbLines(theSelection);
-    return aCount > 0;
-  }
+  return theSelection->getSelected(ModuleBase_ISelection::Viewer).size() == 0 &&
+         isEmptySelectionValid(theOperation);
 }
 
 bool PartSet_IntersectionSelection::isValid(const ModuleBase_ISelection* theSelection,
                                      ModuleBase_Operation* theOperation) const
 {
-  if (theSelection->getSelected(ModuleBase_ISelection::Viewer).size() == 0) {
-    return isEmptySelectionValid(theOperation);
-  } else {
-    int aCount = shapesNbLines(theSelection);
-    return aCount == 0;
-  }
+  return theSelection->getSelected(ModuleBase_ISelection::Viewer).size() == 0 &&
+         isEmptySelectionValid(theOperation);
 }
 
 
@@ -478,8 +435,9 @@ bool PartSet_DifferentObjectsValidator::isValid(const AttributePtr& theAttribute
             continue;
           if (isObject) {
             if (aRef->object() == anObject) {
-              theError = errorMessage(EqualObjects, anObject.get() ? anObject->data()->name() : "",
-                                      theAttribute->id(), aRef->id());
+              theError = errorMessage(EqualObjects,
+                anObject.get() ? ModelAPI_Tools::toString(anObject->data()->name()) : "",
+                theAttribute->id(), aRef->id());
               return false;
             }
           }
@@ -500,6 +458,7 @@ bool PartSet_DifferentObjectsValidator::isValid(const AttributePtr& theAttribute
     AttributeSelectionPtr anAttr =
       std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
     ResultPtr aContext = anAttr->context();
+    FeaturePtr aContextFeature = anAttr->contextFeature();
     GeomShapePtr aShape = anAttr->value();
 
     // Check selection attributes
@@ -518,6 +477,24 @@ bool PartSet_DifferentObjectsValidator::isValid(const AttributePtr& theAttribute
               return false;
             }
           }
+          // check the whole selected feature contains the result
+          if (aContextFeature.get()) {
+            if (aRef->contextFeature().get()) {
+              if (aContextFeature == aRef->contextFeature()) {
+                theError = errorMessage(EqualShapes, "", theAttribute->id(), aRef->id());
+                return false;
+              }
+            } else if (aRef->context().get() &&
+                aRef->context()->document()->feature(aRef->context()) == aContextFeature) {
+              theError = errorMessage(EqualShapes, "", theAttribute->id(), aRef->id());
+              return false;
+            }
+          } else if (aRef->contextFeature().get() && aContext.get()) {
+            if (aContext->document()->feature(aContext) == aRef->contextFeature()) {
+              theError = errorMessage(EqualShapes, "", theAttribute->id(), aRef->id());
+              return false;
+            }
+          }
         }
       }
     }
@@ -536,8 +513,9 @@ bool PartSet_DifferentObjectsValidator::isValid(const AttributePtr& theAttribute
             std::dynamic_pointer_cast<ModelAPI_AttributeReference>(*anAttr);
           // check the object is already presented
           if (aRef->value() == anObject) {
-            theError = errorMessage(EqualObjects, anObject.get() ? anObject->data()->name() : "",
-                                    theAttribute->id(), aRef->id());
+            theError = errorMessage(EqualObjects,
+              anObject.get() ? ModelAPI_Tools::toString(anObject->data()->name()) : "",
+              theAttribute->id(), aRef->id());
             return false;
           }
         }
@@ -558,6 +536,7 @@ bool PartSet_DifferentObjectsValidator::isValid(const AttributePtr& theAttribute
           for(int i = 0; i < aCurSelList->size(); i++) {
             std::shared_ptr<ModelAPI_AttributeSelection> aCurSel = aCurSelList->value(i);
             ResultPtr aCurSelContext = aCurSel->context();
+            FeaturePtr aCurSelFeature = aCurSel->contextFeature();
             ResultBodyPtr aCurSelCompSolidPtr = ModelAPI_Tools::bodyOwner(aCurSelContext);
             std::shared_ptr<GeomAPI_Shape> aCurSelCompSolid;
             if(aCurSelCompSolidPtr.get()) {
@@ -566,27 +545,47 @@ bool PartSet_DifferentObjectsValidator::isValid(const AttributePtr& theAttribute
             for(int j = 0; j < aRefSelList->size(); j++) {
               std::shared_ptr<ModelAPI_AttributeSelection> aRefSel = aRefSelList->value(j);
               ResultPtr aRefSelContext = aRefSel->context();
+              FeaturePtr aRefSelFeature = aRefSel->contextFeature();
               ResultBodyPtr aRefSelCompSolidPtr =
                 ModelAPI_Tools::bodyOwner(aRefSelContext);
               std::shared_ptr<GeomAPI_Shape> aRefSelCompSolid;
-              if(aRefSelCompSolidPtr.get()) {
+              if (aRefSelCompSolidPtr.get()) {
                 aRefSelCompSolid = aRefSelCompSolidPtr->shape();
               }
               if ((aCurSelCompSolid.get() && aCurSelCompSolid->isEqual(aRefSel->value()))
                 || (aRefSelCompSolid.get() && aRefSelCompSolid->isEqual(aCurSel->value()))) {
-                  theError = errorMessage(EqualShapes, "", theAttribute->id(),
-                                          aRefSel->id());
-                  return false;
+                theError = errorMessage(EqualShapes, "", theAttribute->id(),
+                  aRefSel->id());
+                return false;
               }
-              if(aCurSelContext == aRefSelContext) {
+              if (aCurSelContext == aRefSelContext) {
                 if (aCurSel->value().get() == NULL || aRefSel->value().get() == NULL) {
-                  theError = errorMessage(EmptyShapes, "", theAttribute->id(),
-                                          aRefSel->id());
+                  theError = errorMessage(EmptyShapes, "", theAttribute->id(), aRefSel->id());
                   return false;
                 }
                 if (aCurSel->value()->isEqual(aRefSel->value())) {
-                  theError = errorMessage(EqualShapes, "", theAttribute->id(),
-                                          aRefSel->id());
+                  theError = errorMessage(EqualShapes, "", theAttribute->id(), aRefSel->id());
+                  return false;
+                }
+              }
+
+              // check the whole selected feature contains the result
+              if (aCurSelFeature.get()) {
+                if (aRefSelFeature.get()) {
+                  if (aCurSelFeature == aRefSelFeature) {
+                    theError = errorMessage(EqualShapes, "", theAttribute->id(), aRefSel->id());
+                    return false;
+                  }
+                }
+                else if (aRefSelContext.get() &&
+                  aRefSelContext->document()->feature(aRefSelContext) == aCurSelFeature) {
+                  theError = errorMessage(EqualShapes, "", theAttribute->id(), aRefSel->id());
+                  return false;
+                }
+              }
+              else if (aRefSelFeature.get() && aCurSelContext.get()) {
+                if (aCurSelContext->document()->feature(aCurSelContext) == aRefSelFeature) {
+                  theError = errorMessage(EqualShapes, "", theAttribute->id(), aRefSel->id());
                   return false;
                 }
               }
@@ -611,8 +610,9 @@ bool PartSet_DifferentObjectsValidator::isValid(const AttributePtr& theAttribute
             for (int j = 0; j < aRefSelList->size(); j++) {
               if (aCurSelObject == aRefSelList->object(j)) {
                 theError = errorMessage(EqualObjects,
-                              aCurSelObject.get() ? aCurSelObject->data()->name() : "",
-                              theAttribute->id(), aCurSelList->id());
+                  aCurSelObject.get()?
+                  ModelAPI_Tools::toString(aCurSelObject->data()->name()) : "",
+                  theAttribute->id(), aCurSelList->id());
                 return false;
               }
             }