From a47af7109078eea1a585d1f10a176f16ab838b87 Mon Sep 17 00:00:00 2001 From: azv Date: Thu, 4 Jul 2019 15:00:03 +0300 Subject: [PATCH] Implement filter "F9: External Faces" --- src/FiltersPlugin/CMakeLists.txt | 3 + src/FiltersPlugin/FiltersPlugin_BelongsTo.cpp | 4 +- src/FiltersPlugin/FiltersPlugin_BelongsTo.h | 5 +- .../FiltersPlugin_ExternalFaces.cpp | 52 +++++++++++++ .../FiltersPlugin_ExternalFaces.h | 54 +++++++++++++ .../FiltersPlugin_HorizontalFace.cpp | 4 +- .../FiltersPlugin_HorizontalFace.h | 5 +- .../FiltersPlugin_OnGeometry.cpp | 4 +- src/FiltersPlugin/FiltersPlugin_OnGeometry.h | 3 +- src/FiltersPlugin/FiltersPlugin_OnLine.cpp | 2 +- src/FiltersPlugin/FiltersPlugin_OnLine.h | 3 +- src/FiltersPlugin/FiltersPlugin_OnPlane.cpp | 4 +- src/FiltersPlugin/FiltersPlugin_OnPlane.h | 5 +- .../FiltersPlugin_OnPlaneSide.cpp | 2 +- src/FiltersPlugin/FiltersPlugin_OnPlaneSide.h | 3 +- .../FiltersPlugin_OppositeToEdge.cpp | 2 +- .../FiltersPlugin_OppositeToEdge.h | 3 +- src/FiltersPlugin/FiltersPlugin_Plugin.cpp | 2 + .../FiltersPlugin_RelativeToSolid.cpp | 2 +- .../FiltersPlugin_RelativeToSolid.h | 3 +- .../FiltersPlugin_VerticalFace.cpp | 4 +- .../FiltersPlugin_VerticalFace.h | 5 +- .../Test/TestFilter_ExternalFaces.py | 76 +++++++++++++++++++ src/Model/Model_FiltersFactory.cpp | 6 +- src/Model/Model_FiltersFactory.h | 6 +- src/ModelAPI/ModelAPI_Filter.h | 7 +- src/ModelAPI/ModelAPI_FiltersFactory.h | 6 +- .../ModuleBase_WidgetSelectionFilter.cpp | 2 +- src/PythonAPI/model/tests/tests.py | 8 +- 29 files changed, 248 insertions(+), 37 deletions(-) create mode 100644 src/FiltersPlugin/FiltersPlugin_ExternalFaces.cpp create mode 100644 src/FiltersPlugin/FiltersPlugin_ExternalFaces.h create mode 100644 src/FiltersPlugin/Test/TestFilter_ExternalFaces.py diff --git a/src/FiltersPlugin/CMakeLists.txt b/src/FiltersPlugin/CMakeLists.txt index 994931287..75ebaf3ef 100644 --- a/src/FiltersPlugin/CMakeLists.txt +++ b/src/FiltersPlugin/CMakeLists.txt @@ -33,6 +33,7 @@ SET(PROJECT_HEADERS FiltersPlugin_OnPlaneSide.h FiltersPlugin_OppositeToEdge.h FiltersPlugin_RelativeToSolid.h + FiltersPlugin_ExternalFaces.h ) SET(PROJECT_SOURCES @@ -47,6 +48,7 @@ SET(PROJECT_SOURCES FiltersPlugin_OnPlaneSide.cpp FiltersPlugin_OppositeToEdge.cpp FiltersPlugin_RelativeToSolid.cpp + FiltersPlugin_ExternalFaces.cpp ) SET(PROJECT_LIBRARIES @@ -94,6 +96,7 @@ ADD_UNIT_TESTS( TestFilter_RelativeToSolid_NotOn.py TestFilter_RelativeToSolid_InAndOn.py TestFilter_RelativeToSolid_OutAndOn.py + TestFilter_ExternalFaces.py TestFilter_HorizontalFaces.py TestFilter_VerticalFaces.py ) diff --git a/src/FiltersPlugin/FiltersPlugin_BelongsTo.cpp b/src/FiltersPlugin/FiltersPlugin_BelongsTo.cpp index b03093e0f..6a1553ace 100644 --- a/src/FiltersPlugin/FiltersPlugin_BelongsTo.cpp +++ b/src/FiltersPlugin/FiltersPlugin_BelongsTo.cpp @@ -26,8 +26,8 @@ bool FiltersPlugin_BelongsTo::isSupported(GeomAPI_Shape::ShapeType theType) cons return true; } -bool FiltersPlugin_BelongsTo::isOk(const GeomShapePtr& theShape, - const ModelAPI_FiltersArgs& theArgs) const +bool FiltersPlugin_BelongsTo::isOk(const GeomShapePtr& theShape, const ResultPtr&, + const ModelAPI_FiltersArgs& theArgs) const { AttributePtr aAttr = theArgs.argument("BelongsTo"); AttributeSelectionListPtr aList = diff --git a/src/FiltersPlugin/FiltersPlugin_BelongsTo.h b/src/FiltersPlugin/FiltersPlugin_BelongsTo.h index 7e0b6bb6e..ebe4e6177 100644 --- a/src/FiltersPlugin/FiltersPlugin_BelongsTo.h +++ b/src/FiltersPlugin/FiltersPlugin_BelongsTo.h @@ -44,8 +44,9 @@ public: /// This method should contain the filter logic. It returns true if the given shape /// is accepted by the filter. /// \param theShape the given shape - virtual bool isOk(const GeomShapePtr& theShape, - const ModelAPI_FiltersArgs& theArgs) const override; + /// \param theArgs arguments of the filter + virtual bool isOk(const GeomShapePtr& theShape, const ResultPtr&, + const ModelAPI_FiltersArgs& theArgs) const override; /// Returns XML string which represents GUI of the filter virtual std::string xmlRepresentation() const override; diff --git a/src/FiltersPlugin/FiltersPlugin_ExternalFaces.cpp b/src/FiltersPlugin/FiltersPlugin_ExternalFaces.cpp new file mode 100644 index 000000000..1ad322537 --- /dev/null +++ b/src/FiltersPlugin/FiltersPlugin_ExternalFaces.cpp @@ -0,0 +1,52 @@ +// Copyright (C) 2014-2019 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 "FiltersPlugin_ExternalFaces.h" + +#include + +#include +#include + +bool FiltersPlugin_ExternalFaces::isSupported(GeomAPI_Shape::ShapeType theType) const +{ + return theType == GeomAPI_Shape::FACE; +} + +bool FiltersPlugin_ExternalFaces::isOk(const GeomShapePtr& theShape, + const ResultPtr& theResult, + const ModelAPI_FiltersArgs& theArgs) const +{ + if (!theShape->isFace()) + return false; + + ResultBodyPtr anOwner = ModelAPI_Tools::bodyOwner(theResult, true); + if (!anOwner) { + anOwner = std::dynamic_pointer_cast(theResult); + if (!anOwner) + return false; + } + GeomShapePtr anOwnerShape = anOwner->shape(); + + TopTools_IndexedDataMapOfShapeListOfShape aMapFS; + TopExp::MapShapesAndUniqueAncestors(anOwnerShape->impl(), + TopAbs_FACE, TopAbs_SOLID, aMapFS); + const TopTools_ListOfShape& aSolids = aMapFS.FindFromKey(theShape->impl()); + return aSolids.Extent() <= 1; +} diff --git a/src/FiltersPlugin/FiltersPlugin_ExternalFaces.h b/src/FiltersPlugin/FiltersPlugin_ExternalFaces.h new file mode 100644 index 000000000..e34e4421a --- /dev/null +++ b/src/FiltersPlugin/FiltersPlugin_ExternalFaces.h @@ -0,0 +1,54 @@ +// Copyright (C) 2014-2019 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 FILTERSPLUGIN_EXTERNALFACES_H_ +#define FILTERSPLUGIN_EXTERNALFACES_H_ + +#include "FiltersPlugin.h" + +#include + +/**\class FiltersPlugin_ExternalFaces +* \ingroup DataModel +* \brief Filter for faces not shared between solids in compsolid. +*/ +class FiltersPlugin_ExternalFaces : public ModelAPI_Filter +{ +public: + FiltersPlugin_ExternalFaces() : ModelAPI_Filter() {} + + virtual const std::string& name() const { + static const std::string kName("External faces"); + return kName; + } + + /// Returns true for any type because it supports all selection types + virtual bool isSupported(GeomAPI_Shape::ShapeType theType) const override; + + /// This method should contain the filter logic. It returns true if the given shape + /// is accepted by the filter. + /// \param theShape the given shape + /// \param theResult parent result of the shape to be checked + /// \param theArgs arguments of the filter + virtual bool isOk(const GeomShapePtr& theShape, + const ResultPtr& theResult, + const ModelAPI_FiltersArgs& theArgs) const override; +}; + +#endif \ No newline at end of file diff --git a/src/FiltersPlugin/FiltersPlugin_HorizontalFace.cpp b/src/FiltersPlugin/FiltersPlugin_HorizontalFace.cpp index 6bda6a6cf..ce1ec8b3f 100644 --- a/src/FiltersPlugin/FiltersPlugin_HorizontalFace.cpp +++ b/src/FiltersPlugin/FiltersPlugin_HorizontalFace.cpp @@ -27,8 +27,8 @@ bool FiltersPlugin_HorizontalFace::isSupported(GeomAPI_Shape::ShapeType theType) return theType == GeomAPI_Shape::FACE; } -bool FiltersPlugin_HorizontalFace::isOk( - const GeomShapePtr& theShape, const ModelAPI_FiltersArgs& theArgs) const +bool FiltersPlugin_HorizontalFace::isOk(const GeomShapePtr& theShape, const ResultPtr&, + const ModelAPI_FiltersArgs& theArgs) const { if (!theShape->isFace() || !theShape->isPlanar()) return false; diff --git a/src/FiltersPlugin/FiltersPlugin_HorizontalFace.h b/src/FiltersPlugin/FiltersPlugin_HorizontalFace.h index aa3a3168f..8417e0f27 100644 --- a/src/FiltersPlugin/FiltersPlugin_HorizontalFace.h +++ b/src/FiltersPlugin/FiltersPlugin_HorizontalFace.h @@ -44,8 +44,9 @@ public: /// This method should contain the filter logic. It returns true if the given shape /// is accepted by the filter. /// \param theShape the given shape - virtual bool isOk( - const GeomShapePtr& theShape, const ModelAPI_FiltersArgs& theArgs) const override; + /// \param theArgs arguments of the filter + virtual bool isOk(const GeomShapePtr& theShape, const ResultPtr&, + const ModelAPI_FiltersArgs& theArgs) const override; }; #endif \ No newline at end of file diff --git a/src/FiltersPlugin/FiltersPlugin_OnGeometry.cpp b/src/FiltersPlugin/FiltersPlugin_OnGeometry.cpp index e62dba49c..44d9ff401 100644 --- a/src/FiltersPlugin/FiltersPlugin_OnGeometry.cpp +++ b/src/FiltersPlugin/FiltersPlugin_OnGeometry.cpp @@ -26,8 +26,8 @@ bool FiltersPlugin_OnGeometry::isSupported(GeomAPI_Shape::ShapeType theType) con return theType == GeomAPI_Shape::EDGE || theType == GeomAPI_Shape::FACE; } -bool FiltersPlugin_OnGeometry::isOk(const GeomShapePtr& theShape, - const ModelAPI_FiltersArgs& theArgs) const +bool FiltersPlugin_OnGeometry::isOk(const GeomShapePtr& theShape, const ResultPtr&, + const ModelAPI_FiltersArgs& theArgs) const { AttributePtr aAttr = theArgs.argument("OnGeometry"); AttributeSelectionListPtr aList = diff --git a/src/FiltersPlugin/FiltersPlugin_OnGeometry.h b/src/FiltersPlugin/FiltersPlugin_OnGeometry.h index 98d197aa4..c90e5dd87 100644 --- a/src/FiltersPlugin/FiltersPlugin_OnGeometry.h +++ b/src/FiltersPlugin/FiltersPlugin_OnGeometry.h @@ -44,7 +44,8 @@ public: /// This method should contain the filter logic. It returns true if the given shape /// is accepted by the filter. /// \param theShape the given shape - virtual bool isOk(const GeomShapePtr& theShape, + /// \param theArgs arguments of the filter + virtual bool isOk(const GeomShapePtr& theShape, const ResultPtr&, const ModelAPI_FiltersArgs& theArgs) const override; /// Returns XML string which represents GUI of the filter diff --git a/src/FiltersPlugin/FiltersPlugin_OnLine.cpp b/src/FiltersPlugin/FiltersPlugin_OnLine.cpp index 092321eaf..d2e438432 100644 --- a/src/FiltersPlugin/FiltersPlugin_OnLine.cpp +++ b/src/FiltersPlugin/FiltersPlugin_OnLine.cpp @@ -46,7 +46,7 @@ bool FiltersPlugin_OnLine::isSupported(GeomAPI_Shape::ShapeType theType) const return theType == GeomAPI_Shape::EDGE || theType == GeomAPI_Shape::VERTEX; } -bool FiltersPlugin_OnLine::isOk(const GeomShapePtr& theShape, +bool FiltersPlugin_OnLine::isOk(const GeomShapePtr& theShape, const ResultPtr&, const ModelAPI_FiltersArgs& theArgs) const { AttributePtr aAttr = theArgs.argument("OnLine"); diff --git a/src/FiltersPlugin/FiltersPlugin_OnLine.h b/src/FiltersPlugin/FiltersPlugin_OnLine.h index 8678159d6..b609bd940 100644 --- a/src/FiltersPlugin/FiltersPlugin_OnLine.h +++ b/src/FiltersPlugin/FiltersPlugin_OnLine.h @@ -44,7 +44,8 @@ public: /// This method should contain the filter logic. It returns true if the given shape /// is accepted by the filter. /// \param theShape the given shape - virtual bool isOk(const GeomShapePtr& theShape, + /// \param theArgs arguments of the filter + virtual bool isOk(const GeomShapePtr& theShape, const ResultPtr&, const ModelAPI_FiltersArgs& theArgs) const override; /// Returns XML string which represents GUI of the filter diff --git a/src/FiltersPlugin/FiltersPlugin_OnPlane.cpp b/src/FiltersPlugin/FiltersPlugin_OnPlane.cpp index c86a33474..f7b4a07a6 100644 --- a/src/FiltersPlugin/FiltersPlugin_OnPlane.cpp +++ b/src/FiltersPlugin/FiltersPlugin_OnPlane.cpp @@ -52,8 +52,8 @@ GeomPlanePtr getPlane(AttributeSelectionPtr theAttr) return aFace->getPlane(); } -bool FiltersPlugin_OnPlane::isOk(const GeomShapePtr& theShape, - const ModelAPI_FiltersArgs& theArgs) const +bool FiltersPlugin_OnPlane::isOk(const GeomShapePtr& theShape, const ResultPtr&, + const ModelAPI_FiltersArgs& theArgs) const { AttributePtr aAttr = theArgs.argument("OnPlane"); AttributeSelectionListPtr aList = diff --git a/src/FiltersPlugin/FiltersPlugin_OnPlane.h b/src/FiltersPlugin/FiltersPlugin_OnPlane.h index e496d9f42..62fccd1fc 100644 --- a/src/FiltersPlugin/FiltersPlugin_OnPlane.h +++ b/src/FiltersPlugin/FiltersPlugin_OnPlane.h @@ -44,8 +44,9 @@ public: /// This method should contain the filter logic. It returns true if the given shape /// is accepted by the filter. /// \param theShape the given shape - virtual bool isOk(const GeomShapePtr& theShape, - const ModelAPI_FiltersArgs& theArgs) const override; + /// \param theArgs arguments of the filter + virtual bool isOk(const GeomShapePtr& theShape, const ResultPtr&, + const ModelAPI_FiltersArgs& theArgs) const override; /// Returns XML string which represents GUI of the filter virtual std::string xmlRepresentation() const override; diff --git a/src/FiltersPlugin/FiltersPlugin_OnPlaneSide.cpp b/src/FiltersPlugin/FiltersPlugin_OnPlaneSide.cpp index b19a98ec5..1d77e6b74 100644 --- a/src/FiltersPlugin/FiltersPlugin_OnPlaneSide.cpp +++ b/src/FiltersPlugin/FiltersPlugin_OnPlaneSide.cpp @@ -32,7 +32,7 @@ bool FiltersPlugin_OnPlaneSide::isSupported(GeomAPI_Shape::ShapeType theType) co return true; } -bool FiltersPlugin_OnPlaneSide::isOk(const GeomShapePtr& theShape, +bool FiltersPlugin_OnPlaneSide::isOk(const GeomShapePtr& theShape, const ResultPtr&, const ModelAPI_FiltersArgs& theArgs) const { static const double THE_TOLERANCE = 1.e-7; diff --git a/src/FiltersPlugin/FiltersPlugin_OnPlaneSide.h b/src/FiltersPlugin/FiltersPlugin_OnPlaneSide.h index ef3f4a88a..9939e4588 100644 --- a/src/FiltersPlugin/FiltersPlugin_OnPlaneSide.h +++ b/src/FiltersPlugin/FiltersPlugin_OnPlaneSide.h @@ -44,7 +44,8 @@ public: /// This method should contain the filter logic. It returns true if the given shape /// is accepted by the filter. /// \param theShape the given shape - virtual bool isOk(const GeomShapePtr& theShape, + /// \param theArgs arguments of the filter + virtual bool isOk(const GeomShapePtr& theShape, const ResultPtr&, const ModelAPI_FiltersArgs& theArgs) const override; /// Returns XML string which represents GUI of the filter diff --git a/src/FiltersPlugin/FiltersPlugin_OppositeToEdge.cpp b/src/FiltersPlugin/FiltersPlugin_OppositeToEdge.cpp index 35d1a42c6..b2cc86a6c 100644 --- a/src/FiltersPlugin/FiltersPlugin_OppositeToEdge.cpp +++ b/src/FiltersPlugin/FiltersPlugin_OppositeToEdge.cpp @@ -117,7 +117,7 @@ bool FiltersPlugin_OppositeToEdge::isSupported(GeomAPI_Shape::ShapeType theType) return theType == GeomAPI_Shape::EDGE; } -bool FiltersPlugin_OppositeToEdge::isOk(const GeomShapePtr& theShape, +bool FiltersPlugin_OppositeToEdge::isOk(const GeomShapePtr& theShape, const ResultPtr&, const ModelAPI_FiltersArgs& theArgs) const { AttributePtr aAttr = theArgs.argument("OppositeToEdge"); diff --git a/src/FiltersPlugin/FiltersPlugin_OppositeToEdge.h b/src/FiltersPlugin/FiltersPlugin_OppositeToEdge.h index 9db4458f9..5d745d3ab 100644 --- a/src/FiltersPlugin/FiltersPlugin_OppositeToEdge.h +++ b/src/FiltersPlugin/FiltersPlugin_OppositeToEdge.h @@ -49,7 +49,8 @@ public: /// This method should contain the filter logic. It returns true if the given shape /// is accepted by the filter. /// \param theShape the given shape - virtual bool isOk(const GeomShapePtr& theShape, + /// \param theArgs arguments of the filter + virtual bool isOk(const GeomShapePtr& theShape, const ResultPtr&, const ModelAPI_FiltersArgs& theArgs) const override; /// Returns XML string which represents GUI of the filter diff --git a/src/FiltersPlugin/FiltersPlugin_Plugin.cpp b/src/FiltersPlugin/FiltersPlugin_Plugin.cpp index a0181d6bf..2538b8f26 100644 --- a/src/FiltersPlugin/FiltersPlugin_Plugin.cpp +++ b/src/FiltersPlugin/FiltersPlugin_Plugin.cpp @@ -28,6 +28,7 @@ #include "FiltersPlugin_OnPlaneSide.h" #include "FiltersPlugin_OppositeToEdge.h" #include "FiltersPlugin_RelativeToSolid.h" +#include "FiltersPlugin_ExternalFaces.h" #include #include @@ -49,6 +50,7 @@ FiltersPlugin_Plugin::FiltersPlugin_Plugin() aFactory->registerFilter("OnPlaneSide", new FiltersPlugin_OnPlaneSide); aFactory->registerFilter("OppositeToEdge", new FiltersPlugin_OppositeToEdge); aFactory->registerFilter("RelativeToSolid", new FiltersPlugin_RelativeToSolid); + aFactory->registerFilter("ExternalFaces", new FiltersPlugin_ExternalFaces); ModelAPI_Session::get()->registerPlugin(this); } diff --git a/src/FiltersPlugin/FiltersPlugin_RelativeToSolid.cpp b/src/FiltersPlugin/FiltersPlugin_RelativeToSolid.cpp index 512f66563..df1559485 100644 --- a/src/FiltersPlugin/FiltersPlugin_RelativeToSolid.cpp +++ b/src/FiltersPlugin/FiltersPlugin_RelativeToSolid.cpp @@ -32,7 +32,7 @@ bool FiltersPlugin_RelativeToSolid::isSupported(GeomAPI_Shape::ShapeType theType return true; } -bool FiltersPlugin_RelativeToSolid::isOk(const GeomShapePtr& theShape, +bool FiltersPlugin_RelativeToSolid::isOk(const GeomShapePtr& theShape, const ResultPtr&, const ModelAPI_FiltersArgs& theArgs) const { AttributePtr anAttr = theArgs.argument("Solid"); diff --git a/src/FiltersPlugin/FiltersPlugin_RelativeToSolid.h b/src/FiltersPlugin/FiltersPlugin_RelativeToSolid.h index 61d0b5900..821b9a7ec 100644 --- a/src/FiltersPlugin/FiltersPlugin_RelativeToSolid.h +++ b/src/FiltersPlugin/FiltersPlugin_RelativeToSolid.h @@ -44,7 +44,8 @@ public: /// This method should contain the filter logic. It returns true if the given shape /// is accepted by the filter. /// \param theShape the given shape - virtual bool isOk(const GeomShapePtr& theShape, + /// \param theArgs arguments of the filter + virtual bool isOk(const GeomShapePtr& theShape, const ResultPtr&, const ModelAPI_FiltersArgs& theArgs) const override; /// Returns XML string which represents GUI of the filter diff --git a/src/FiltersPlugin/FiltersPlugin_VerticalFace.cpp b/src/FiltersPlugin/FiltersPlugin_VerticalFace.cpp index 56ab8ff2b..9d1883126 100644 --- a/src/FiltersPlugin/FiltersPlugin_VerticalFace.cpp +++ b/src/FiltersPlugin/FiltersPlugin_VerticalFace.cpp @@ -32,8 +32,8 @@ bool FiltersPlugin_VerticalFace::isSupported(GeomAPI_Shape::ShapeType theType) c return theType == GeomAPI_Shape::FACE; } -bool FiltersPlugin_VerticalFace::isOk( - const GeomShapePtr& theShape, const ModelAPI_FiltersArgs& theArgs) const +bool FiltersPlugin_VerticalFace::isOk(const GeomShapePtr& theShape, const ResultPtr&, + const ModelAPI_FiltersArgs& theArgs) const { if (!theShape->isFace() || !theShape->isPlanar()) return false; diff --git a/src/FiltersPlugin/FiltersPlugin_VerticalFace.h b/src/FiltersPlugin/FiltersPlugin_VerticalFace.h index e920f4ced..df733d3c0 100644 --- a/src/FiltersPlugin/FiltersPlugin_VerticalFace.h +++ b/src/FiltersPlugin/FiltersPlugin_VerticalFace.h @@ -44,8 +44,9 @@ public: /// This method should contain the filter logic. It returns true if the given shape /// is accepted by the filter. /// \param theShape the given shape - virtual bool isOk( - const GeomShapePtr& theShape, const ModelAPI_FiltersArgs& theArgs) const override; + /// \param theArgs arguments of the filter + virtual bool isOk(const GeomShapePtr& theShape, const ResultPtr&, + const ModelAPI_FiltersArgs& theArgs) const override; }; #endif \ No newline at end of file diff --git a/src/FiltersPlugin/Test/TestFilter_ExternalFaces.py b/src/FiltersPlugin/Test/TestFilter_ExternalFaces.py new file mode 100644 index 000000000..58f21450e --- /dev/null +++ b/src/FiltersPlugin/Test/TestFilter_ExternalFaces.py @@ -0,0 +1,76 @@ +# Copyright (C) 2014-2019 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 +# + +from salome.shaper import model +from GeomAPI import * + +model.begin() +partSet = model.moduleDocument() +Part_1 = model.addPart(partSet) +Part_1_doc = Part_1.document() +Box_1 = model.addBox(Part_1_doc, 10, 10, 10) +Plane_4 = model.addPlane(Part_1_doc, model.selection("FACE", "Box_1_1/Left"), model.selection("FACE", "Box_1_1/Right")) +Partition_1 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Box_1_1"), model.selection("FACE", "Plane_1")], 20190506) +Cylinder_1 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), 5, 10) +Translation_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Cylinder_1_1")], model.selection("EDGE", "PartSet/OX"), 20) +Filters = model.filters(Part_1_doc, [model.addFilter(name = "ExternalFaces")]) +model.end() + +Reference = {} +# Faces of the box +ResultBox_1 = Partition_1.result().resultSubShapePair()[0] +exp = GeomAPI_ShapeExplorer(ResultBox_1.shape(), GeomAPI_Shape.FACE) +Reference[model.selection(ResultBox_1, exp.current())] = True; exp.next() +Reference[model.selection(ResultBox_1, exp.current())] = True; exp.next() +Reference[model.selection(ResultBox_1, exp.current())] = False; exp.next() +Reference[model.selection(ResultBox_1, exp.current())] = True; exp.next() +Reference[model.selection(ResultBox_1, exp.current())] = True; exp.next() +Reference[model.selection(ResultBox_1, exp.current())] = True; exp.next() +Reference[model.selection(ResultBox_1, exp.current())] = True; exp.next() +Reference[model.selection(ResultBox_1, exp.current())] = True; exp.next() +Reference[model.selection(ResultBox_1, exp.current())] = True; exp.next() +Reference[model.selection(ResultBox_1, exp.current())] = True; exp.next() +Reference[model.selection(ResultBox_1, exp.current())] = False; exp.next() +Reference[model.selection(ResultBox_1, exp.current())] = True; exp.next() +# Faces of the cylinder +ResultCylinder_1 = Translation_1.result().resultSubShapePair()[0] +exp = GeomAPI_ShapeExplorer(ResultCylinder_1.shape(), GeomAPI_Shape.FACE) +while exp.more(): + Reference[model.selection(ResultCylinder_1, exp.current())] = True + exp.next() +model.checkFilter(Part_1_doc, model, Filters, Reference) + +Reference = { + model.selection("FACE", "Partition_1_1_2/Modified_Face&Box_1_1/Back"): True, + model.selection("FACE", "Partition_1_1_2/Modified_Face&Plane_1/Plane_1"): True, + model.selection("FACE", "Partition_1_1_2/Modified_Face&Box_1_1/Bottom"): True, + model.selection("FACE", "Box_1_1/Right"): True, + model.selection("FACE", "Partition_1_1_2/Modified_Face&Box_1_1/Top"): True, + model.selection("FACE", "Partition_1_1_2/Modified_Face&Box_1_1/Front"): True, + model.selection("FACE", "Partition_1_1_1/Modified_Face&Box_1_1/Back"): True, + model.selection("FACE", "Box_1_1/Left"): True, + model.selection("FACE", "Partition_1_1_1/Modified_Face&Box_1_1/Bottom"): True, + model.selection("FACE", "Partition_1_1_1/Modified_Face&Plane_1/Plane_1"): True, + model.selection("FACE", "Partition_1_1_1/Modified_Face&Box_1_1/Top"): True, + model.selection("FACE", "Partition_1_1_1/Modified_Face&Box_1_1/Front"): True, + model.selection("FACE", "Translation_1_1/MF:Translated&Cylinder_1_1/Face_1"): True, + model.selection("FACE", "Translation_1_1/MF:Translated&Cylinder_1_1/Face_2"): True, + model.selection("FACE", "Translation_1_1/MF:Translated&Cylinder_1_1/Face_3"): True, +} +model.checkFilter(Part_1_doc, model, Filters, Reference) diff --git a/src/Model/Model_FiltersFactory.cpp b/src/Model/Model_FiltersFactory.cpp index f0a7c9242..f84febdfc 100644 --- a/src/Model/Model_FiltersFactory.cpp +++ b/src/Model/Model_FiltersFactory.cpp @@ -40,7 +40,9 @@ struct FilterArgs { std::string myFilterID; }; -bool Model_FiltersFactory::isValid(FeaturePtr theFiltersFeature, GeomShapePtr theShape) +bool Model_FiltersFactory::isValid(FeaturePtr theFiltersFeature, + ResultPtr theResult, + GeomShapePtr theShape) { // check that the shape type corresponds to the attribute list type AttributePtr aBase = @@ -84,7 +86,7 @@ bool Model_FiltersFactory::isValid(FeaturePtr theFiltersFeature, GeomShapePtr th std::list::iterator aFilter = aFilters.begin(); for(; aFilter != aFilters.end(); aFilter++) { anArgs.setFilter(aFilter->myFilterID); - bool aResult = aFilter->myFilter->isOk(theShape, anArgs); + bool aResult = aFilter->myFilter->isOk(theShape, theResult, anArgs); if (aFilter->myReverse) aResult = !aResult; if (!aResult) // one filter is failed => exit immediately diff --git a/src/Model/Model_FiltersFactory.h b/src/Model/Model_FiltersFactory.h index 3672516f8..b52078651 100644 --- a/src/Model/Model_FiltersFactory.h +++ b/src/Model/Model_FiltersFactory.h @@ -41,9 +41,11 @@ public: /// Returns true if all filters of the Filters feature are ok for the Shape (taking into account /// the Reversed states). - /// \param theFiltersFeature feature that contains all information about the filters + /// \param theResult parent result of the shape to check /// \param theShape the checked shape - virtual bool isValid(FeaturePtr theFiltersFeature, GeomShapePtr theShape); + virtual bool isValid(FeaturePtr theFiltersFeature, + ResultPtr theResult, + GeomShapePtr theShape); /// Returns the filters that support the given shape type virtual std::list filters(GeomAPI_Shape::ShapeType theType); diff --git a/src/ModelAPI/ModelAPI_Filter.h b/src/ModelAPI/ModelAPI_Filter.h index 0e5d5b9df..0469801fe 100644 --- a/src/ModelAPI/ModelAPI_Filter.h +++ b/src/ModelAPI/ModelAPI_Filter.h @@ -21,6 +21,7 @@ #define ModelAPI_Filter_H_ #include "ModelAPI_FiltersArgs.h" +#include "ModelAPI_ResultBody.h" #include @@ -41,7 +42,11 @@ public: /// This method should contain the filter logic. It returns true if the given shape /// is accepted by the filter. /// \param theShape the given shape - virtual bool isOk(const GeomShapePtr& theShape, const ModelAPI_FiltersArgs& theArgs) const = 0; + /// \param theResult parent result of the shape to be checked + /// \param theArgs arguments of the filter + virtual bool isOk(const GeomShapePtr& theShape, + const ResultPtr& theResult, + const ModelAPI_FiltersArgs& theArgs) const = 0; /// Returns XML string which represents GUI of the filter /// By default it returns nothing (no GUI) diff --git a/src/ModelAPI/ModelAPI_FiltersFactory.h b/src/ModelAPI/ModelAPI_FiltersFactory.h index bc24d0d3e..6e5e7a3e7 100644 --- a/src/ModelAPI/ModelAPI_FiltersFactory.h +++ b/src/ModelAPI/ModelAPI_FiltersFactory.h @@ -22,6 +22,7 @@ #include "ModelAPI_Feature.h" #include "ModelAPI_Filter.h" +#include "ModelAPI_ResultBody.h" #include @@ -41,8 +42,11 @@ public: /// Returns true if all filters of the Filters feature are ok for the Shape (taking into account /// the Reversed states). /// \param theFiltersFeature feature that contains all information about the filters + /// \param theResult parent result of the shape to check /// \param theShape the checked shape - virtual bool isValid(FeaturePtr theFiltersFeature, GeomShapePtr theShape) = 0; + virtual bool isValid(FeaturePtr theFiltersFeature, + ResultPtr theResult, + GeomShapePtr theShape) = 0; /// Returns the filters that support the given shape type virtual std::list filters(GeomAPI_Shape::ShapeType theType) = 0; diff --git a/src/ModuleBase/ModuleBase_WidgetSelectionFilter.cpp b/src/ModuleBase/ModuleBase_WidgetSelectionFilter.cpp index 0abdd259c..2b7763ce2 100644 --- a/src/ModuleBase/ModuleBase_WidgetSelectionFilter.cpp +++ b/src/ModuleBase/ModuleBase_WidgetSelectionFilter.cpp @@ -456,7 +456,7 @@ void ModuleBase_WidgetSelectionFilter::onSelect() if (!alreadyThere.Add(aTShape)) continue; static SessionPtr aSession = ModelAPI_Session::get(); - bool isValid = aSession->filters()->isValid(myFeature, aShape); + bool isValid = aSession->filters()->isValid(myFeature, aBody, aShape); if (isValid) { aBuilder.Add(aComp, aTShape); ModuleBase_ViewerPrsPtr aValue(new ModuleBase_ViewerPrs(aObj, aShape)); diff --git a/src/PythonAPI/model/tests/tests.py b/src/PythonAPI/model/tests/tests.py index 687d2e1bb..f80fd84f4 100644 --- a/src/PythonAPI/model/tests/tests.py +++ b/src/PythonAPI/model/tests/tests.py @@ -343,19 +343,21 @@ def checkFilter(thePartDoc, theModel, theFilter, theShapesList): shapeName = "" shapeType = "UNKNOWN" if sel.variantType() == ModelHighAPI_Selection.VT_ResultSubShapePair: + parent = sel.resultSubShapePair()[0] shape = sel.resultSubShapePair()[1] if shape.isNull(): shape = sel.resultSubShapePair()[0].shape() - shapeName = sel.name() - shapeType = shape.shapeTypeStr() + shapeName = sel.name() + shapeType = shape.shapeTypeStr() else: needUndo = True theModel.begin() subShapeFeature = createSubShape(thePartDoc, theModel, sel) theModel.end() + parent = subShapeFeature.results()[0].resultSubShapePair()[0] shape = subShapeFeature.results()[0].resultSubShapePair()[0].shape() shapeType = sel.typeSubShapeNamePair()[0] shapeName = sel.typeSubShapeNamePair()[1] - assert aFiltersFactory.isValid(theFilter.feature(), shape) == res, "Filter result for {} \"{}\" incorrect. Expected {}.".format(shapeType, shapeName, res) + assert aFiltersFactory.isValid(theFilter.feature(), parent, shape) == res, "Filter result for {} \"{}\" incorrect. Expected {}.".format(shapeType, shapeName, res) if needUndo: theModel.undo() -- 2.39.2