From 00ed338aec6098cd20b75179f3924c048d968e70 Mon Sep 17 00:00:00 2001 From: dbv Date: Wed, 22 Jun 2016 11:10:37 +0300 Subject: [PATCH] Issue #1560: Updated validator for extrusion direction. Not it is not allow to select direction parallel to selected faces or sketches. --- src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp | 4 +- .../FeaturesPlugin_Validators.cpp | 80 ++++++++++++++----- .../FeaturesPlugin_Validators.h | 4 +- src/FeaturesPlugin/extrusion_widget.xml | 2 +- src/FeaturesPlugin/extrusioncut_widget.xml | 2 +- src/FeaturesPlugin/extrusionfuse_widget.xml | 2 +- src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.cpp | 17 ++++ src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.h | 6 ++ 8 files changed, 90 insertions(+), 27 deletions(-) diff --git a/src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp b/src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp index de245dfd6..54b0021f0 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp @@ -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", diff --git a/src/FeaturesPlugin/FeaturesPlugin_Validators.cpp b/src/FeaturesPlugin/FeaturesPlugin_Validators.cpp index 96997a0e0..db8348cd2 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Validators.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Validators.cpp @@ -22,6 +22,7 @@ #include #include +#include #include #include #include @@ -31,6 +32,9 @@ #include #include +#define _USE_MATH_DEFINES +#include + //================================================================================================== bool FeaturesPlugin_ValidatorPipePath::isValid(const AttributePtr& theAttribute, const std::list& theArguments, @@ -334,7 +338,7 @@ bool FeaturesPlugin_ValidatorCompositeLauncher::isValid(const AttributePtr& theA } //================================================================================================== -bool FeaturesPlugin_ValidatorCanBeEmpty::isValid(const std::shared_ptr& theFeature, +bool FeaturesPlugin_ValidatorExtrusionDir::isValid(const std::shared_ptr& theFeature, const std::list& theArguments, std::string& theError) const { @@ -348,45 +352,81 @@ bool FeaturesPlugin_ValidatorCanBeEmpty::isValid(const std::shared_ptrattribute(*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 aDirEdge(new GeomAPI_Edge(aDirShape)); + + // If faces selected check that direction not parallel with them. + AttributeSelectionListPtr aListAttr = std::dynamic_pointer_cast(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 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 aPlanarEdges = std::dynamic_pointer_cast(aShapeInList); + if(aPlanarEdges.get()) { + std::shared_ptr aSketchDir = aPlanarEdges->norm(); + if(aDirEdge->isLine()) { + std::shared_ptr 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()) { diff --git a/src/FeaturesPlugin/FeaturesPlugin_Validators.h b/src/FeaturesPlugin/FeaturesPlugin_Validators.h index 1ca14c03a..c806e754b 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Validators.h +++ b/src/FeaturesPlugin/FeaturesPlugin_Validators.h @@ -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. diff --git a/src/FeaturesPlugin/extrusion_widget.xml b/src/FeaturesPlugin/extrusion_widget.xml index 5951fccb1..c63fccc24 100644 --- a/src/FeaturesPlugin/extrusion_widget.xml +++ b/src/FeaturesPlugin/extrusion_widget.xml @@ -84,5 +84,5 @@ - + diff --git a/src/FeaturesPlugin/extrusioncut_widget.xml b/src/FeaturesPlugin/extrusioncut_widget.xml index 5c0fbb3e2..02a201527 100755 --- a/src/FeaturesPlugin/extrusioncut_widget.xml +++ b/src/FeaturesPlugin/extrusioncut_widget.xml @@ -92,5 +92,5 @@ - + diff --git a/src/FeaturesPlugin/extrusionfuse_widget.xml b/src/FeaturesPlugin/extrusionfuse_widget.xml index 4098b7902..728e9edc8 100644 --- a/src/FeaturesPlugin/extrusionfuse_widget.xml +++ b/src/FeaturesPlugin/extrusionfuse_widget.xml @@ -92,5 +92,5 @@ - + diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.cpp index 21530babb..3d072c222 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.cpp @@ -9,6 +9,7 @@ #include "GeomAlgoAPI_SketchBuilder.h" #include +#include #include #include #include @@ -24,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -634,3 +636,18 @@ std::shared_ptr GeomAlgoAPI_ShapeTools::getFaceOuterWire(const st return anOuterWire; } + +//================================================================================================== +bool GeomAlgoAPI_ShapeTools::isParallel(const std::shared_ptr theEdge, + const std::shared_ptr theFace) +{ + if(!theEdge.get() || !theFace.get()) { + return false; + } + + TopoDS_Edge anEdge = TopoDS::Edge(theEdge->impl()); + TopoDS_Face aFace = TopoDS::Face(theFace->impl()); + + BRepExtrema_ExtCF anExt(anEdge, aFace); + return anExt.IsParallel() == Standard_True; +} diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.h b/src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.h index bc02ecb92..01b1e7366 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.h +++ b/src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.h @@ -12,7 +12,9 @@ #include #include +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 getFaceOuterWire(const std::shared_ptr theFace); + /// \return true if edge is parallel to face. + GEOMALGOAPI_EXPORT static bool isParallel(const std::shared_ptr theEdge, + const std::shared_ptr theFace); + }; #endif -- 2.39.2