Salome HOME
Issue #1367: Fill feature.
[modules/shaper.git] / src / FeaturesPlugin / FeaturesPlugin_Validators.cpp
index c8559d01175a10099e166643ccc633415079fcfd..37d03e3a9476a17a8a9406e106dd921346da2b95 100644 (file)
@@ -7,20 +7,24 @@
 #include "FeaturesPlugin_Validators.h"
 
 #include <ModelAPI_Attribute.h>
+#include <ModelAPI_AttributeInteger.h>
 #include <ModelAPI_AttributeSelectionList.h>
 #include <ModelAPI_AttributeString.h>
-#include <ModelAPI_ResultConstruction.h>
 #include <ModelAPI_AttributeReference.h>
+#include <ModelAPI_Feature.h>
+#include <ModelAPI_ResultConstruction.h>
 
 #include <Events_Error.h>
 
 #include <GeomValidators_FeatureKind.h>
 #include <GeomValidators_ShapeType.h>
 
+#include <GeomAPI_DataMapOfShapeShape.h>
 #include <GeomAPI_PlanarEdges.h>
+#include <GeomAPI_ShapeExplorer.h>
 #include <GeomAlgoAPI_WireBuilder.h>
 
-//=================================================================================================
+//==================================================================================================
 bool FeaturesPlugin_ValidatorPipeLocations::isValid(const std::shared_ptr<ModelAPI_Feature>& theFeature,
                                                     const std::list<std::string>& theArguments,
                                                     std::string& theError) const
@@ -64,13 +68,13 @@ bool FeaturesPlugin_ValidatorPipeLocations::isValid(const std::shared_ptr<ModelA
   return true;
 }
 
-//=================================================================================================
+//==================================================================================================
 bool FeaturesPlugin_ValidatorPipeLocations::isNotObligatory(std::string theFeature, std::string theAttribute)
 {
   return false;
 }
 
-//=================================================================================================
+//==================================================================================================
 bool FeaturesPlugin_ValidatorBaseForGeneration::isValid(const AttributePtr& theAttribute,
                                                         const std::list<std::string>& theArguments,
                                                         std::string& theError) const
@@ -88,10 +92,60 @@ bool FeaturesPlugin_ValidatorBaseForGeneration::isValid(const AttributePtr& theA
     return false;
   }
 
+  std::set<ResultConstructionPtr> aSelectedSketches;
+  std::set<ResultConstructionPtr> aSelectedSketchesFromObjects;
+  GeomAPI_DataMapOfShapeShape aSelectedWiresFromObjects;
+  std::string anAttributeType = theAttribute->attributeType();
+  if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
+    AttributeSelectionListPtr aListAttr = std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
+    for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
+      AttributeSelectionPtr aSelectionAttr = aListAttr->value(anIndex);
+      ResultConstructionPtr aContext = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aSelectionAttr->context());
+      if(!aContext.get()) {
+        // It is not a result construction, continue.
+        continue;
+      }
+
+      GeomShapePtr aShape = aSelectionAttr->value();
+      GeomShapePtr aContextShape = aContext->shape();
+      if(!aShape.get()) {
+        // Whole sketch selected.
+        if(aSelectedSketchesFromObjects.find(aContext) != aSelectedSketchesFromObjects.cend()) {
+          theError = "Object from this sketch is already selected. Sketch is not allowed for selection.";
+          return false;
+        }
+
+        aSelectedSketches.insert(aContext);
+      } else {
+        // Object from sketch selected.
+        if(aSelectedSketches.find(aContext) != aSelectedSketches.cend()) {
+          theError = "Whole sketch with this object is already selected. Don't allow to select this object.";
+          return false;
+        }
+
+        for(GeomAPI_ShapeExplorer anExp(aShape, GeomAPI_Shape::WIRE); anExp.more(); anExp.next()) {
+          GeomShapePtr aWire = anExp.current();
+          if(aWire->orientation() != GeomAPI_Shape::FORWARD) {
+            theError = "Wire with wrong orientation selected.";
+            return false;
+          }
+
+          if(aSelectedWiresFromObjects.isBound(aWire)) {
+            theError = "Objects with such wire already selected. Don't allow to select this object.";
+            return false;
+          }
+
+          aSelectedWiresFromObjects.bind(aWire, aWire);
+          aSelectedSketchesFromObjects.insert(aContext);
+        }
+      }
+    }
+  }
+
   return true;
 }
 
-//=================================================================================================
+//==================================================================================================
 bool FeaturesPlugin_ValidatorBaseForGeneration::isValidAttribute(const AttributePtr& theAttribute,
                                                                  const std::list<std::string>& theArguments,
                                                                  std::string& theError) const
@@ -148,6 +202,8 @@ bool FeaturesPlugin_ValidatorBaseForGeneration::isValidAttribute(const Attribute
           return true;
         }
       }
+
+      return false;
     }
 
     if(!aShape->isEqual(aContextShape)) {
@@ -159,8 +215,8 @@ bool FeaturesPlugin_ValidatorBaseForGeneration::isValidAttribute(const Attribute
     // Check that object is a shape with allowed type.
     GeomValidators_ShapeType aShapeTypeValidator;
     if(!aShapeTypeValidator.isValid(anAttr, theArguments, theError)) {
-      theError = "Selected shape has unacceptable type. Acceptable types are: faces or wires on sketch, \
-whole sketch(if it has at least one face), and whole objects with shape types: ";
+      theError = "Selected shape has unacceptable type. Acceptable types are: faces or wires on sketch, "
+                 "whole sketch(if it has at least one face), and whole objects with shape types: ";
       std::list<std::string>::const_iterator anIt = theArguments.cbegin();
       theError += *anIt;
       for(++anIt; anIt != theArguments.cend(); ++anIt) {
@@ -177,7 +233,7 @@ whole sketch(if it has at least one face), and whole objects with shape types: "
   return true;
 }
 
-//=================================================================================================
+//==================================================================================================
 bool FeaturesPlugin_ValidatorCompositeLauncher::isValid(const AttributePtr& theAttribute,
                                                         const std::list<std::string>& theArguments,
                                                         std::string& theError) const
@@ -222,7 +278,7 @@ bool FeaturesPlugin_ValidatorCompositeLauncher::isValid(const AttributePtr& theA
   return aValid;
 }
 
-//=================================================================================================
+//==================================================================================================
 bool FeaturesPlugin_ValidatorCanBeEmpty::isValid(const std::shared_ptr<ModelAPI_Feature>& theFeature,
                                                  const std::list<std::string>& theArguments,
                                                  std::string& theError) const
@@ -251,7 +307,8 @@ bool FeaturesPlugin_ValidatorCanBeEmpty::isValid(const std::shared_ptr<ModelAPI_
   if(!aShape.get()) {
     ResultPtr aContext = aSelAttr->context();
     if(!aContext.get()) {
-      theError = "Selection attribute \"" + *anArgsIt + "\" can not be empty.";
+      theError = "Base objects list contains vertex or edge, so attribute \"" + *anArgsIt
+               + "\" can not be used with default value. Select direction for extrusion.";
       return false;
     }
 
@@ -259,20 +316,21 @@ bool FeaturesPlugin_ValidatorCanBeEmpty::isValid(const std::shared_ptr<ModelAPI_
   }
 
   if(!aShape.get()) {
-    theError = "Selection attribute \"" + *anArgsIt + "\" can not be empty.";
+    theError = "Base objects list contains vertex or edge, so attribute \"" + *anArgsIt
+              + "\" can not be used with default value. Select direction for extrusion.";
     return false;
   }
 
   return true;
 }
 
-//=================================================================================================
+//==================================================================================================
 bool FeaturesPlugin_ValidatorCanBeEmpty::isNotObligatory(std::string theFeature, std::string theAttribute)
 {
   return false;
 }
 
-//=================================================================================================
+//==================================================================================================
 bool FeaturesPlugin_ValidatorCanBeEmpty::isShapesCanBeEmpty(const AttributePtr& theAttribute,
                                                             std::string& theError) const
 {
@@ -318,7 +376,7 @@ bool FeaturesPlugin_ValidatorCanBeEmpty::isShapesCanBeEmpty(const AttributePtr&
   return true;
 }
 
-//=================================================================================================
+//==================================================================================================
 bool FeaturesPlugin_ValidatorBaseForWire::isValid(const AttributePtr& theAttribute,
                                                   const std::list<std::string>& theArguments,
                                                   std::string& theError) const
@@ -352,7 +410,7 @@ bool FeaturesPlugin_ValidatorBaseForWire::isValid(const AttributePtr& theAttribu
       theError = "Attribute have empty context.";
       return false;
     }
-    
+
     GeomShapePtr aShape = aSelection->value();
     GeomShapePtr aContextShape = aContext->shape();
     if(!aShape.get()) {
@@ -400,4 +458,66 @@ bool FeaturesPlugin_ValidatorBaseForWire::isValid(const AttributePtr& theAttribu
   }
 
   return true;
-}
\ No newline at end of file
+}
+
+//==================================================================================================
+bool FeaturesPlugin_BooleanSelection::isValid(const AttributePtr& theAttribute,
+                                              const std::list<std::string>& theArguments,
+                                              std::string& theError) const
+{
+  AttributeSelectionListPtr anAttrSelectionList = std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
+  if(!anAttrSelectionList.get()) {
+    theError = "Error: this validator can only work with selection list attributes in Boolean feature.";
+    return false;
+  }
+  FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
+  int anOperationType = aFeature->integer("bool_type")->value();
+
+  for(int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
+    AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
+    if(!anAttrSelection.get()) {
+      theError = "Error: empty attribute selection.";
+      return false;
+    }
+    ResultPtr aContext = anAttrSelection->context();
+    if(!aContext.get()) {
+      theError = "Error: empty selection context.";
+      return false;
+    }
+    ResultConstructionPtr aResultConstruction =
+      std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
+    if(aResultConstruction.get()) {
+      theError = "Error: Result construction not allowed for selection.";
+      return false;
+    }
+    std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
+    if(!aShape.get()) {
+      aShape = aContext->shape();
+    }
+    if(!aShape.get()) {
+      theError = "Error: empty shape.";
+      return false;
+    }
+    int aShapeType = aShape->shapeType();
+    if(anOperationType == 1) {
+      // Fuse operation. Allow to select edges, faces and solids.
+      if(aShapeType != GeomAPI_Shape::EDGE &&
+         aShapeType != GeomAPI_Shape::FACE &&
+         aShapeType != GeomAPI_Shape::SOLID &&
+         aShapeType != GeomAPI_Shape::COMPSOLID &&
+         aShapeType != GeomAPI_Shape::COMPOUND) {
+        theError = "Error: selected shape has the wrong type.";
+        return false;
+      }
+    } else {
+      if(aShapeType != GeomAPI_Shape::SOLID &&
+         aShapeType != GeomAPI_Shape::COMPSOLID &&
+         aShapeType != GeomAPI_Shape::COMPOUND) {
+        theError = "Error: selected shape has the wrong type.";
+        return false;
+      }
+    }
+  }
+
+  return true;
+}