From b12258709e3cdfda48bcf4bd9479bf6a4b49928d Mon Sep 17 00:00:00 2001 From: dbv Date: Thu, 30 Aug 2018 10:59:45 +0300 Subject: [PATCH] Issue #2608: Invalid shape when select compound as a tool object for cut Added validator that checks the cut arguments for self-intersection. --- src/FeaturesPlugin/boolean_widget.xml | 1 + src/GeomAPI/GeomAPI_Shape.cpp | 19 ++++ src/GeomAPI/GeomAPI_Shape.h | 14 +++ src/GeomValidators/CMakeLists.txt | 2 + .../GeomValidators_NotSelfIntersected.cpp | 94 +++++++++++++++++++ .../GeomValidators_NotSelfIntersected.h | 49 ++++++++++ src/GeomValidators/GeomValidators_Plugin.cpp | 3 + 7 files changed, 182 insertions(+) create mode 100644 src/GeomValidators/GeomValidators_NotSelfIntersected.cpp create mode 100644 src/GeomValidators/GeomValidators_NotSelfIntersected.h diff --git a/src/FeaturesPlugin/boolean_widget.xml b/src/FeaturesPlugin/boolean_widget.xml index e584a531f..4e82542b9 100644 --- a/src/FeaturesPlugin/boolean_widget.xml +++ b/src/FeaturesPlugin/boolean_widget.xml @@ -41,4 +41,5 @@ email : webmaster.salome@opencascade.com + diff --git a/src/GeomAPI/GeomAPI_Shape.cpp b/src/GeomAPI/GeomAPI_Shape.cpp index fc736ac74..4cde5e736 100644 --- a/src/GeomAPI/GeomAPI_Shape.cpp +++ b/src/GeomAPI/GeomAPI_Shape.cpp @@ -50,6 +50,9 @@ #include #include +#include +#include + #include #include // for std::transform @@ -628,3 +631,19 @@ void GeomAPI_Shape::translate(const std::shared_ptr theDir, const d TopoDS_Shape aResult = MY_SHAPE->Moved(aTranslation); setImpl(new TopoDS_Shape(aResult)); } + +bool GeomAPI_Shape::isSelfIntersected(const int theLevelOfCheck) const +{ + BOPAlgo_CheckerSI aCSI; // checker of self-interferences + aCSI.SetLevelOfCheck(theLevelOfCheck); + TopTools_ListOfShape aList; + const TopoDS_Shape& aThisShape = const_cast(this)->impl(); + aList.Append(aThisShape); + aCSI.SetArguments(aList); + aCSI.Perform(); + if (aCSI.HasErrors() || aCSI.DS().Interferences().Extent() > 0) { + return true; + } + + return false; +} diff --git a/src/GeomAPI/GeomAPI_Shape.h b/src/GeomAPI/GeomAPI_Shape.h index 66e6a2aad..4091f5911 100644 --- a/src/GeomAPI/GeomAPI_Shape.h +++ b/src/GeomAPI/GeomAPI_Shape.h @@ -200,6 +200,20 @@ public: /// Returns type of shapes in the compound. // If shapes are of different type then it will return SHAPE type GEOMAPI_EXPORT ShapeType typeOfCompoundShapes() const; + + /// Returns true if shape have self-intersections. + /// \param[in] theLevelOfCheck defines which interferences will be checked:
+ /// 0 - only V/V;
+ /// 1 - V/V and V/E;
+ /// 2 - V/V, V/E and E/E;
+ /// 3 - V/V, V/E, E/E and V/F;
+ /// 4 - V/V, V/E, E/E, V/F and E/F;
+ /// 5 - V/V, V/E, E/E, V/F, E/F and F/F;
+ /// 6 - V/V, V/E, E/E, V/F, E/F, F/F and V/S;
+ /// 7 - V/V, V/E, E/E, V/F, E/F, F/F, V/S and E/S;
+ /// 8 - V/V, V/E, E/E, V/F, E/F, F/F, V/S, E/S and F/S;
+ /// 9 - V/V, V/E, E/E, V/F, E/F, F/F, V/S, E/S, F/S and S/S - all interferences (Default value) + GEOMAPI_EXPORT bool isSelfIntersected(const int theLevelOfCheck = 9) const; }; //! Pointer on list of shapes diff --git a/src/GeomValidators/CMakeLists.txt b/src/GeomValidators/CMakeLists.txt index 8de30586a..85527474e 100644 --- a/src/GeomValidators/CMakeLists.txt +++ b/src/GeomValidators/CMakeLists.txt @@ -38,6 +38,7 @@ SET(PROJECT_HEADERS GeomValidators_MinObjectsSelected.h GeomValidators_ValueOrder.h GeomValidators_Intersected.h + GeomValidators_NotSelfIntersected.h ) SET(PROJECT_SOURCES @@ -57,6 +58,7 @@ SET(PROJECT_SOURCES GeomValidators_MinObjectsSelected.cpp GeomValidators_ValueOrder.cpp GeomValidators_Intersected.cpp + GeomValidators_NotSelfIntersected.cpp ) SET(PROJECT_LIBRARIES diff --git a/src/GeomValidators/GeomValidators_NotSelfIntersected.cpp b/src/GeomValidators/GeomValidators_NotSelfIntersected.cpp new file mode 100644 index 000000000..e3032b624 --- /dev/null +++ b/src/GeomValidators/GeomValidators_NotSelfIntersected.cpp @@ -0,0 +1,94 @@ +// Copyright (C) 2014-2017 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 +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// 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 +// +// See http://www.salome-platform.org/ or +// email : webmaster.salome@opencascade.com +// + +#include "GeomValidators_NotSelfIntersected.h" + +#include + +#include + +#include +#include > +#include + +bool GeomValidators_NotSelfIntersected::isValid(const std::shared_ptr& theFeature, + const std::list& theArguments, + Events_InfoMessage& theError) const +{ + if (theArguments.empty()) { + theError = "Error: empty selection."; + return false; + } + + for (std::list::const_iterator anIt = theArguments.cbegin(); + anIt != theArguments.cend(); + ++anIt) + { + std::string anArgument = *anIt; + AttributePtr anAttribute = theFeature->attribute(anArgument); + if (!anAttribute.get()) { + theError = std::string("Error: Feature does not contain attribute: ") + anArgument; + return false; + } + if (anAttribute->attributeType() == ModelAPI_AttributeSelectionList::typeId()) { + AttributeSelectionListPtr anAttrSelectionList = + std::dynamic_pointer_cast(anAttribute); + 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()) { + FeaturePtr aContFeat = anAttrSelection->contextFeature(); + if (!aContFeat.get() || !aContFeat->results().size()) { + theError = "Error: Empty selection context."; + return false; + } + } + std::shared_ptr aShape = anAttrSelection->value(); + if (!aShape.get() && aContext.get()) { + GeomShapePtr aContextShape = aContext->shape(); + aShape = aContextShape; + } + if (!aShape.get()) { + theError = "Error: Empty shape."; + return false; + } + + if (aShape->isSelfIntersected()) { + theError = "Error: One of selected shapes are self-intersected."; + return false; + } + } + } + else { + theError = std::string("Error: validator does not support attribute with type: ") + + anAttribute->attributeType(); + } + } +} + +bool GeomValidators_NotSelfIntersected::isNotObligatory(std::string /*theFeature*/, + std::string /*theAttribute*/) +{ + return false; +} diff --git a/src/GeomValidators/GeomValidators_NotSelfIntersected.h b/src/GeomValidators/GeomValidators_NotSelfIntersected.h new file mode 100644 index 000000000..1244389e2 --- /dev/null +++ b/src/GeomValidators/GeomValidators_NotSelfIntersected.h @@ -0,0 +1,49 @@ +// Copyright (C) 2014-2017 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 +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// 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 +// +// See http://www.salome-platform.org/ or +// email : webmaster.salome@opencascade.com +// + +#ifndef GeomValidators_NotSelfIntersected_H +#define GeomValidators_NotSelfIntersected_H + +#include + +#include +#include + +/// \class GeomValidators_NotSelfIntersected +/// \ingroup Validators +/// \brief Validates that selected shapes are not self intersected. +class GeomValidators_NotSelfIntersected: public ModelAPI_FeatureValidator +{ +public: + /// \return True if the attribute is valid. It checks whether the selection + /// is not self intersected. + /// \param[in] theAttribute an attribute to check. + /// \param[in] theArguments a filter parameters. + /// \param[out] theError error message. + GEOMVALIDATORS_EXPORT virtual bool isValid(const std::shared_ptr& theFeature, + const std::list& theArguments, + Events_InfoMessage& theError) const; + + /// \return true if the attribute in feature is not obligatory for the feature execution. + GEOMVALIDATORS_EXPORT virtual bool isNotObligatory(std::string theFeature, + std::string theAttribute); +}; + +#endif diff --git a/src/GeomValidators/GeomValidators_Plugin.cpp b/src/GeomValidators/GeomValidators_Plugin.cpp index 3a0d06ee0..733fc17bf 100644 --- a/src/GeomValidators/GeomValidators_Plugin.cpp +++ b/src/GeomValidators/GeomValidators_Plugin.cpp @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -61,6 +62,8 @@ GeomValidators_Plugin::GeomValidators_Plugin() aFactory->registerValidator("GeomValidators_MinObjectsSelected", new GeomValidators_MinObjectsSelected); aFactory->registerValidator("GeomValidators_Intersected", new GeomValidators_Intersected); + aFactory->registerValidator("GeomValidators_NotSelfIntersected", + new GeomValidators_NotSelfIntersected); // register this plugin ModelAPI_Session::get()->registerPlugin(this); -- 2.39.2