Salome HOME
Issue #3236: Generalization of extrusion
[modules/shaper.git] / src / FeaturesPlugin / FeaturesPlugin_Validators.cpp
index f47f5ba79d1580b936fe78cb19afbdb5b703cc76..9235d933e78d40e886dc4902e2f84649f016f7e3 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2014-2019  CEA/DEN, EDF R&D
+// Copyright (C) 2014-2020  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
@@ -23,6 +23,7 @@
 #include "FeaturesPlugin_BooleanFuse.h"
 #include "FeaturesPlugin_BooleanCommon.h"
 #include "FeaturesPlugin_BooleanSmash.h"
+#include "FeaturesPlugin_CompositeBoolean.h"
 #include "FeaturesPlugin_Extrusion.h"
 #include "FeaturesPlugin_Pipe.h"
 #include "FeaturesPlugin_Union.h"
 #include <GeomAlgoAPI_ShapeTools.h>
 #include <GeomAlgoAPI_WireBuilder.h>
 
+#include <algorithm>
+
 #define _USE_MATH_DEFINES
 #include <math.h>
 
+#ifdef _MSC_VER
+#pragma warning(disable: 4100)
+#endif
+
 //==================================================================================================
 bool FeaturesPlugin_ValidatorPipePath::isValid(const AttributePtr& theAttribute,
                                                const std::list<std::string>& theArguments,
@@ -394,9 +401,32 @@ bool FeaturesPlugin_ValidatorBaseForGeneration::isValidAttribute(const Attribute
   if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
     AttributeSelectionListPtr aListAttr =
       std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
+
+    const std::string& aSelType = aListAttr->selectionType();
+    std::list<std::string> anApplicableTypes;
+    switch (GeomValidators_ShapeType::shapeType(aSelType)) {
+    case GeomValidators_ShapeType::Vertex:
+      anApplicableTypes.push_back("vertex");
+      break;
+    case GeomValidators_ShapeType::Edge:
+      anApplicableTypes.push_back("edge");
+      anApplicableTypes.push_back("wire");
+      break;
+    case GeomValidators_ShapeType::Face:
+      anApplicableTypes.push_back("face");
+      anApplicableTypes.push_back("shell");
+      // wire should not be the first in this list to be able to check
+      // the type of selection when evaluating shape by shape
+      anApplicableTypes.push_back("wire");
+      break;
+    default:
+      anApplicableTypes = theArguments;
+      break;
+    }
+
     for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
       // If at least one attribute is invalid, the result is false.
-      if(!isValidAttribute(aListAttr->value(anIndex), theArguments, theError)) {
+      if(!isValidAttribute(aListAttr->value(anIndex), anApplicableTypes, theError)) {
         return false;
       }
     }
@@ -429,28 +459,32 @@ bool FeaturesPlugin_ValidatorBaseForGeneration::isValidAttribute(const Attribute
       aConstruction = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
     if(aConstruction.get()) {
       // Construction selected. Check that it is not infinite.
-      if(aConstruction->isInfinite()) {
+      if(aConstruction->isInfinite() && !aConstruction->shape()->isVertex()) {
         theError = "Error: Infinite constructions is not allowed as base.";
         return false;
       }
 
-      GeomShapePtr aContextShape = aContext->shape();
+      aContextShape = aContext->shape();
       if(aShape->isEqual(aContextShape)) {
-        // Whole construction selected. Check that it have faces.
-        if(aConstruction->facesNum() > 0) {
+        // Whole construction selected. Check that it has faces.
+        if((theArguments.front() == "face" && aConstruction->facesNum() > 0) ||
+            theArguments.front() == "edge") {
           return true;
         }
       } else {
-        // Shape on construction selected. Check that it is a face or wire.
-        if(aShape->shapeType() == GeomAPI_Shape::WIRE ||
-           aShape->shapeType() == GeomAPI_Shape::FACE) {
-          return true;
+        // CUT operation supports only FACE or WIRE as a tool base
+        std::shared_ptr<FeaturesPlugin_CompositeBoolean> aComposite =
+            std::dynamic_pointer_cast<FeaturesPlugin_CompositeBoolean>(
+            ModelAPI_Feature::feature(theAttribute->owner()));
+        if (aComposite &&
+            aComposite->operationType() == FeaturesPlugin_CompositeBoolean::BOOL_CUT) {
+          return aShape->shapeType() == GeomAPI_Shape::WIRE ||
+                 aShape->shapeType() == GeomAPI_Shape::FACE;
         }
       }
-      return false;
     }
 
-    if(aContextShape.get() && !aShape->isEqual(aContextShape)) {
+    if(!aConstruction && aContextShape.get() && !aShape->isEqual(aContextShape)) {
       // Local selection on body does not allowed.
       theError =
         "Error: Selected shape is in the local selection. Only global selection is allowed.";
@@ -547,8 +581,7 @@ bool FeaturesPlugin_ValidatorExtrusionDir::isValid(
 // LCOV_EXCL_STOP
   }
 
-  std::list<std::string>::const_iterator
-    anArgsIt = theArguments.begin(), aLast = theArguments.end();
+  std::list<std::string>::const_iterator anArgsIt = theArguments.begin();
 
   AttributePtr aCheckAttribute = theFeature->attribute(*anArgsIt);
   ++anArgsIt;
@@ -1209,7 +1242,6 @@ bool FeaturesPlugin_ValidatorUnionSelection::isValid(const AttributePtr& theAttr
   }
 
   for(int anIndex = 0; anIndex < aBaseObjectsAttrList->size(); ++anIndex) {
-    bool isSameFound = false;
     AttributeSelectionPtr anAttrSelectionInList = aBaseObjectsAttrList->value(anIndex);
     ResultPtr aContext = anAttrSelectionInList->context();
     if (!aContext.get()) {
@@ -1635,16 +1667,16 @@ bool FeaturesPlugin_IntersectionSelection::isValid(const AttributePtr& theAttrib
       return false;
     }
     ResultPtr aContext = anAttrSelection->context();
-    if(!aContext.get()) {
-      FeaturePtr aContFeat = anAttrSelection->contextFeature();
-      if (!aContFeat.get() || !aContFeat->results().size() ||
-          aContFeat->firstResult()->groupName() != ModelAPI_ResultBody::group()) {
+    if (aContext.get()) {
+      aFeature = ModelAPI_Feature::feature(aContext);
+    } else {
+      aFeature = anAttrSelection->contextFeature();
+      if (!aFeature.get() || !aFeature->results().size() ||
+          aFeature->firstResult()->groupName() != ModelAPI_ResultBody::group()) {
         theError = "Error: Empty selection context.";
         return false;
       }
     }
-    FeaturePtr aFeature = anAttrSelection->contextFeature().get() ?
-      anAttrSelection->contextFeature() : ModelAPI_Feature::feature(aContext);
     if (!aFeature.get()) {
       theError = "Error: empty feature.";
       return false;
@@ -1760,7 +1792,7 @@ bool FeaturesPlugin_ValidatorBooleanFuseArguments::isValid(
 
   int anObjectsNb = 0, aToolsNb = 0;
 
-  std::list<std::string>::const_iterator anIt = theArguments.begin(), aLast = theArguments.end();
+  std::list<std::string>::const_iterator anIt = theArguments.begin();
 
   bool isAllInSameCompSolid = true;
   ResultBodyPtr aCompSolid;
@@ -1811,8 +1843,6 @@ bool FeaturesPlugin_ValidatorBooleanFuseArguments::isValid(
     }
   }
 
-  anIt++;
-
   if (anObjectsNb + aToolsNb < 2) {
     theError = "Not enough arguments for Fuse operation.";
     return false;
@@ -1914,9 +1944,8 @@ bool FeaturesPlugin_ValidatorBooleanCommonArguments::isValid(
 
   int anObjectsNb = 0, aToolsNb = 0;
 
-  std::list<std::string>::const_iterator anIt = theArguments.begin(), aLast = theArguments.end();
+  std::list<std::string>::const_iterator anIt = theArguments.begin();
 
-  bool isAllInSameCompSolid = true;
   ResultBodyPtr aCompSolid;
 
   AttributeSelectionListPtr anAttrSelList = theFeature->selectionList(*anIt);