Salome HOME
Issue #1560: Updated validator for extrusion direction. Not it is not allow to select...
authordbv <dbv@opencascade.com>
Wed, 22 Jun 2016 08:10:37 +0000 (11:10 +0300)
committerdbv <dbv@opencascade.com>
Wed, 22 Jun 2016 08:11:03 +0000 (11:11 +0300)
src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp
src/FeaturesPlugin/FeaturesPlugin_Validators.cpp
src/FeaturesPlugin/FeaturesPlugin_Validators.h
src/FeaturesPlugin/extrusion_widget.xml
src/FeaturesPlugin/extrusioncut_widget.xml
src/FeaturesPlugin/extrusionfuse_widget.xml
src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.cpp
src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.h

index de245dfd69dba8cafc2538e3291e20b0fe09be86..54b0021f0a8bdaf51151f27e9aec857875a20381 100644 (file)
@@ -44,8 +44,8 @@ FeaturesPlugin_Plugin::FeaturesPlugin_Plugin()
                               new FeaturesPlugin_ValidatorBaseForGeneration);
   aFactory->registerValidator("FeaturesPlugin_ValidatorPipeLocations",
                               new FeaturesPlugin_ValidatorPipeLocations);
-  aFactory->registerValidator("FeaturesPlugin_ValidatorCanBeEmpty",
-                              new FeaturesPlugin_ValidatorCanBeEmpty);
+  aFactory->registerValidator("FeaturesPlugin_ValidatorExtrusionDir",
+                              new FeaturesPlugin_ValidatorExtrusionDir);
   aFactory->registerValidator("FeaturesPlugin_ValidatorBooleanSelection",
                               new FeaturesPlugin_ValidatorBooleanSelection);
   aFactory->registerValidator("FeaturesPlugin_ValidatorPartitionSelection",
index 96997a0e0d401e33e3c8fd2b7def7bfc2e6c9d2f..db8348cd2a1b8fd0af2099e061313b34b8cd0369 100644 (file)
@@ -22,6 +22,7 @@
 #include <GeomValidators_ShapeType.h>
 
 #include <GeomAPI_DataMapOfShapeShape.h>
+#include <GeomAPI_Lin.h>
 #include <GeomAPI_PlanarEdges.h>
 #include <GeomAPI_ShapeExplorer.h>
 #include <GeomAPI_ShapeIterator.h>
@@ -31,6 +32,9 @@
 #include <GeomAlgoAPI_ShapeTools.h>
 #include <GeomAlgoAPI_WireBuilder.h>
 
+#define _USE_MATH_DEFINES
+#include <math.h>
+
 //==================================================================================================
 bool FeaturesPlugin_ValidatorPipePath::isValid(const AttributePtr& theAttribute,
                                                const std::list<std::string>& theArguments,
@@ -334,7 +338,7 @@ bool FeaturesPlugin_ValidatorCompositeLauncher::isValid(const AttributePtr& theA
 }
 
 //==================================================================================================
-bool FeaturesPlugin_ValidatorCanBeEmpty::isValid(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+bool FeaturesPlugin_ValidatorExtrusionDir::isValid(const std::shared_ptr<ModelAPI_Feature>& theFeature,
                                                  const std::list<std::string>& theArguments,
                                                  std::string& theError) const
 {
@@ -348,45 +352,81 @@ bool FeaturesPlugin_ValidatorCanBeEmpty::isValid(const std::shared_ptr<ModelAPI_
   AttributePtr aCheckAttribute = theFeature->attribute(*anArgsIt);
   ++anArgsIt;
 
-  if(isShapesCanBeEmpty(aCheckAttribute, theError)) {
-    return true;
-  }
-
+  GeomShapePtr aDirShape;
   AttributeSelectionPtr aSelAttr = theFeature->selection(*anArgsIt);
-  if(!aSelAttr.get()) {
-    theError = "Error: Could not get selection attribute \"" + *anArgsIt + "\".";
-    return false;
+  if(aSelAttr.get()) {
+    aDirShape = aSelAttr->value();
+    if(!aDirShape.get()) {
+      ResultPtr aContext = aSelAttr->context();
+      if(aContext.get()) {
+        aDirShape = aContext->shape();
+      }
+    }
   }
 
-  GeomShapePtr aShape = aSelAttr->value();
-  if(!aShape.get()) {
-    ResultPtr aContext = aSelAttr->context();
-    if(!aContext.get()) {
+  if(!aDirShape.get()) {
+    // Check that dir can be empty.
+    if(!isShapesCanBeEmpty(aCheckAttribute, theError)) {
       theError = "Error: Base objects list contains vertex or edge, so attribute \"" + *anArgsIt
                + "\" can not be used with default value. Select direction for extrusion.";
       return false;
+    } else {
+      return true;
     }
-
-    aShape = aContext->shape();
   }
 
-  if(!aShape.get()) {
-    theError = "Error: Base objects list contains vertex or edge, so attribute \"" + *anArgsIt
-              + "\" can not be used with default value. Select direction for extrusion.";
-    return false;
+  std::shared_ptr<GeomAPI_Edge> aDirEdge(new GeomAPI_Edge(aDirShape));
+
+  // If faces selected check that direction not parallel with them.
+  AttributeSelectionListPtr aListAttr = std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(aCheckAttribute);
+  for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
+    AttributeSelectionPtr anAttr = aListAttr->value(anIndex);
+    GeomShapePtr aShapeInList = anAttr->value();
+    if(!aShapeInList.get()) {
+      aShapeInList = anAttr->context()->shape();
+    }
+    bool isParallel = true;
+    if(aShapeInList->shapeType() == GeomAPI_Shape::FACE || aShapeInList->shapeType() == GeomAPI_Shape::SHELL) {
+      for(GeomAPI_ShapeExplorer anExp(aShapeInList, GeomAPI_Shape::FACE); anExp.more(); anExp.next()) {
+        std::shared_ptr<GeomAPI_Face> aFace(new GeomAPI_Face(anExp.current()));
+        isParallel = GeomAlgoAPI_ShapeTools::isParallel(aDirEdge, aFace);
+        if(isParallel) {
+          break;
+        }
+      }
+    } else if(aShapeInList->shapeType() == GeomAPI_Shape::COMPOUND) {
+      std::shared_ptr<GeomAPI_PlanarEdges> aPlanarEdges = std::dynamic_pointer_cast<GeomAPI_PlanarEdges>(aShapeInList);
+      if(aPlanarEdges.get()) {
+        std::shared_ptr<GeomAPI_Dir> aSketchDir = aPlanarEdges->norm();
+        if(aDirEdge->isLine()) {
+          std::shared_ptr<GeomAPI_Dir> aDir = aDirEdge->line()->direction();
+          isParallel = abs(aSketchDir->angle(aDir) - M_PI / 2.0) < 10e-7;
+        } else {
+          isParallel = false;
+        }
+      } else {
+        isParallel = false;
+      }
+    } else {
+      isParallel = false;
+    }
+    if(isParallel) {
+      theError = "Error: Direction is parallel to one of the selected face or face on selected shell.";
+      return false;
+    }
   }
 
   return true;
 }
 
 //==================================================================================================
-bool FeaturesPlugin_ValidatorCanBeEmpty::isNotObligatory(std::string theFeature, std::string theAttribute)
+bool FeaturesPlugin_ValidatorExtrusionDir::isNotObligatory(std::string theFeature, std::string theAttribute)
 {
   return false;
 }
 
 //==================================================================================================
-bool FeaturesPlugin_ValidatorCanBeEmpty::isShapesCanBeEmpty(const AttributePtr& theAttribute,
+bool FeaturesPlugin_ValidatorExtrusionDir::isShapesCanBeEmpty(const AttributePtr& theAttribute,
                                                             std::string& theError) const
 {
   if(!theAttribute.get()) {
index 1ca14c03aa80458932779d84232c90550377e33c..c806e754b8957904b3a62167aee37b7cbe09d91c 100644 (file)
@@ -79,11 +79,11 @@ public:
                         std::string& theError) const;
 };
 
-/// \class FeaturesPlugin_ValidatorCanBeEmpty
+/// \class FeaturesPlugin_ValidatorExtrusionDir
 /// \ingroup Validators
 /// \brief A validator for extrusion direction attribute. Allows it to be empty if base objects are
 ///        planar and do not contain vertices and edges.
-class FeaturesPlugin_ValidatorCanBeEmpty: public ModelAPI_FeatureValidator
+class FeaturesPlugin_ValidatorExtrusionDir: public ModelAPI_FeatureValidator
 {
 public:
   //! \return true if attribute listed in the parameter arguments are planar.
index 5951fccb1ee1558a076a91ad49e1e0bb3e5d0b20..c63fccc242d290565a5dd92fa757ec692ddadf19 100644 (file)
@@ -84,5 +84,5 @@
     </box>
   </toolbox>
   <validator id="GeomValidators_ZeroOffset" parameters="CreationMethod,BySizes,base,to_size,from_size,to_object,to_offset,from_object,from_offset"/>
-  <validator id="FeaturesPlugin_ValidatorCanBeEmpty" parameters="base,direction_object"/>
+  <validator id="FeaturesPlugin_ValidatorExtrusionDir" parameters="base,direction_object"/>
 </source>
index 5c0fbb3e24f9750565ac076dfd1ab4018eb64a53..02a201527ffa91f9c9aa71a2a308f2fe19139d16 100755 (executable)
@@ -92,5 +92,5 @@
     <validator id="GeomValidators_ShapeType" parameters="solid"/>
   </multi_selector>
   <validator id="GeomValidators_ZeroOffset" parameters="CreationMethod,BySizes,sketch_selection,to_size,from_size,to_object,to_offset,from_object,from_offset"/>
-  <validator id="FeaturesPlugin_ValidatorCanBeEmpty" parameters="base,direction_object"/>
+  <validator id="FeaturesPlugin_ValidatorExtrusionDir" parameters="base,direction_object"/>
 </source>
index 4098b79028fd8538f0acc792cfeccd18b1f5adc0..728e9edc8af1748d8856641e095e807bb1cd58f9 100644 (file)
@@ -92,5 +92,5 @@
     <validator id="GeomValidators_ShapeType" parameters="solid"/>
   </multi_selector>
   <validator id="GeomValidators_ZeroOffset" parameters="CreationMethod,BySizes,sketch_selection,to_size,from_size,to_object,to_offset,from_object,from_offset"/>
-  <validator id="FeaturesPlugin_ValidatorCanBeEmpty" parameters="base,direction_object"/>
+  <validator id="FeaturesPlugin_ValidatorExtrusionDir" parameters="base,direction_object"/>
 </source>
index 21530babb2dd0694624728d1e0616285b98b8cb3..3d072c2225a7b16975eebaf2c4c0d560d4149d9b 100644 (file)
@@ -9,6 +9,7 @@
 #include "GeomAlgoAPI_SketchBuilder.h"
 
 #include <GeomAPI_Dir.h>
+#include <GeomAPI_Face.h>
 #include <GeomAPI_PlanarEdges.h>
 #include <GeomAPI_Pln.h>
 #include <GeomAPI_Pnt.h>
@@ -24,6 +25,7 @@
 #include <BRepBuilderAPI_MakeFace.hxx>
 #include <BRepCheck_Analyzer.hxx>
 #include <BRepExtrema_DistShapeShape.hxx>
+#include <BRepExtrema_ExtCF.hxx>
 #include <BRepGProp.hxx>
 #include <BRepTools.hxx>
 #include <BRepTopAdaptor_FClass2d.hxx>
@@ -634,3 +636,18 @@ std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_ShapeTools::getFaceOuterWire(const st
 
   return anOuterWire;
 }
+
+//==================================================================================================
+bool GeomAlgoAPI_ShapeTools::isParallel(const std::shared_ptr<GeomAPI_Edge> theEdge,
+                                        const std::shared_ptr<GeomAPI_Face> theFace)
+{
+  if(!theEdge.get() || !theFace.get()) {
+    return false;
+  }
+
+  TopoDS_Edge anEdge = TopoDS::Edge(theEdge->impl<TopoDS_Shape>());
+  TopoDS_Face aFace  = TopoDS::Face(theFace->impl<TopoDS_Shape>());
+
+  BRepExtrema_ExtCF anExt(anEdge, aFace);
+  return anExt.IsParallel() == Standard_True;
+}
index bc02ecb92b9c25160fcf384cc2309376bec1545b..01b1e73669e6ba4826bec044e3e5601fa6561cca 100644 (file)
@@ -12,7 +12,9 @@
 #include <GeomAPI_Shape.h>
 #include <GeomAPI_Vertex.h>
 
+class GeomAPI_Edge;
 class GeomAPI_Dir;
+class GeomAPI_Face;
 class GeomAPI_PlanarEdges;
 class GeomAPI_Pln;
 class GeomAPI_Pnt;
@@ -97,6 +99,10 @@ public:
   /// \return outer wire for face. If theShape has different type returns empty pointer.
   GEOMALGOAPI_EXPORT static std::shared_ptr<GeomAPI_Shape> getFaceOuterWire(const std::shared_ptr<GeomAPI_Shape> theFace);
 
+  /// \return true if edge is parallel to face.
+  GEOMALGOAPI_EXPORT static bool isParallel(const std::shared_ptr<GeomAPI_Edge> theEdge,
+                                            const std::shared_ptr<GeomAPI_Face> theFace);
+
 };
 
 #endif