FiltersPlugin_BelongsTo.h
FiltersPlugin_OnPlane.h
FiltersPlugin_OnLine.h
+ FiltersPlugin_OnGeometry.h
)
SET(PROJECT_SOURCES
FiltersPlugin_BelongsTo.cpp
FiltersPlugin_OnPlane.cpp
FiltersPlugin_OnLine.cpp
+ FiltersPlugin_OnGeometry.cpp
)
SET(PROJECT_LIBRARIES
TestFilter_BelongsTo.py
TestFilter_OnPlane.py
TestFilter_OnLine.py
+ TestFilter_OnGeometry_Edge.py
+ TestFilter_OnGeometry_Face.py
TestFilter_HorizontalFaces.py
TestFilter_VerticalFaces.py
)
--- /dev/null
+// 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_OnGeometry.h"
+
+#include <ModelAPI_AttributeSelectionList.h>
+
+bool FiltersPlugin_OnGeometry::isSupported(GeomAPI_Shape::ShapeType theType) const
+{
+ return theType == GeomAPI_Shape::EDGE || theType == GeomAPI_Shape::FACE;
+}
+
+bool FiltersPlugin_OnGeometry::isOk(const GeomShapePtr& theShape,
+ const ModelAPI_FiltersArgs& theArgs) const
+{
+ AttributePtr aAttr = theArgs.argument("OnGeometry");
+ AttributeSelectionListPtr aList =
+ std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(aAttr);
+ if (!aList.get())
+ return false;
+ for (int i = 0; i < aList->size(); i++) {
+ AttributeSelectionPtr aAttr = aList->value(i);
+ GeomShapePtr aGeom = aAttr->value();
+ if (aGeom->isSameGeometry(theShape))
+ return true;
+ }
+ return false;
+}
+
+static std::string XMLRepresentation =
+"<filter id = \"OnGeometry\">"
+" <multi_selector id=\"OnGeometry__OnGeometry\""
+" label=\"Edges/faces:\""
+" tooltip=\"Select objects to limit selection.\""
+" type_choice=\"edges faces\">"
+" <validator id=\"GeomValidators_ShapeType\" parameters=\"edge,face\"/>"
+" </multi_selector>"
+"</filter>";
+
+
+std::string FiltersPlugin_OnGeometry::xmlRepresentation() const
+{
+ return XMLRepresentation;
+}
+
+void FiltersPlugin_OnGeometry::initAttributes(ModelAPI_FiltersArgs& theArguments)
+{
+ theArguments.initAttribute("OnGeometry", ModelAPI_AttributeSelectionList::typeId());
+}
--- /dev/null
+// 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_ONGEOMETRY_H_
+#define FILTERSPLUGIN_ONGEOMETRY_H_
+
+#include "FiltersPlugin.h"
+
+#include <ModelAPI_Filter.h>
+
+/**\class FiltersPlugin_OnGeometry
+ * \ingroup DataModel
+ * \brief Filter for objects which have the same underlying geometry as specified objects
+ */
+class FiltersPlugin_OnGeometry : public ModelAPI_Filter
+{
+public:
+ FiltersPlugin_OnGeometry() : ModelAPI_Filter() {}
+
+ virtual const std::string& name() const {
+ static const std::string kName("On geometry");
+ 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
+ virtual bool isOk(const GeomShapePtr& theShape,
+ const ModelAPI_FiltersArgs& theArgs) const override;
+
+ /// Returns XML string which represents GUI of the filter
+ virtual std::string xmlRepresentation() const override;
+
+ /// Initializes arguments of a filter.
+ virtual void initAttributes(ModelAPI_FiltersArgs& theArguments) override;
+};
+
+#endif
\ No newline at end of file
#include "FiltersPlugin_BelongsTo.h"
#include "FiltersPlugin_OnPlane.h"
#include "FiltersPlugin_OnLine.h"
+#include "FiltersPlugin_OnGeometry.h"
#include <ModelAPI_Session.h>
#include <ModelAPI_FiltersFactory.h>
aFactory->registerFilter("BelongsTo", new FiltersPlugin_BelongsTo);
aFactory->registerFilter("OnPlane", new FiltersPlugin_OnPlane);
aFactory->registerFilter("OnLine", new FiltersPlugin_OnLine);
+ aFactory->registerFilter("OnGeometry", new FiltersPlugin_OnGeometry);
ModelAPI_Session::get()->registerPlugin(this);
}
--- /dev/null
+# 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)
+FilterFace = model.filters(Part_1_doc, [model.addFilter(name = "OnGeometry", args = [model.selection("EDGE", "Partition_1_1_2/Generated_Edge&Plane_1/Plane_1&Box_1_1/Front"), model.selection("EDGE", "[Partition_1_1_1/Modified_Face&Box_1_1/Top][Partition_1_1_1/Modified_Face&Box_1_1/Front]")])])
+model.end()
+
+Reference = {}
+# Faces of the box
+ResultBox_1 = Partition_1.result().resultSubShapePair()[0]
+exp = GeomAPI_ShapeExplorer(ResultBox_1.shape(), GeomAPI_Shape.FACE)
+while exp.more():
+ Reference[model.selection(ResultBox_1, exp.current())] = False
+ 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())] = False
+ exp.next()
+# Edges of the original box (selected as a sub-shapes of the result to keep original surface).
+# Note: the expected values have to be updated if ShapeExplorer will return another order of sub-shapes.
+exp = GeomAPI_ShapeExplorer(ResultBox_1.shape(), GeomAPI_Shape.EDGE)
+Reference[model.selection(ResultBox_1, exp.current())] = False; exp.next()
+Reference[model.selection(ResultBox_1, exp.current())] = False; exp.next()
+Reference[model.selection(ResultBox_1, exp.current())] = False; exp.next()
+Reference[model.selection(ResultBox_1, exp.current())] = False; exp.next()
+Reference[model.selection(ResultBox_1, exp.current())] = False; 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())] = False; 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())] = False; exp.next()
+Reference[model.selection(ResultBox_1, exp.current())] = False; exp.next()
+Reference[model.selection(ResultBox_1, exp.current())] = False; exp.next()
+Reference[model.selection(ResultBox_1, exp.current())] = False; exp.next()
+Reference[model.selection(ResultBox_1, exp.current())] = False; exp.next()
+Reference[model.selection(ResultBox_1, exp.current())] = False; exp.next()
+Reference[model.selection(ResultBox_1, exp.current())] = False; exp.next()
+Reference[model.selection(ResultBox_1, exp.current())] = False; exp.next()
+Reference[model.selection(ResultBox_1, exp.current())] = False; 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())] = False; exp.next()
+Reference[model.selection(ResultBox_1, exp.current())] = False; exp.next()
+Reference[model.selection(ResultBox_1, exp.current())] = False; exp.next()
+Reference[model.selection(ResultBox_1, exp.current())] = False; exp.next()
+Reference[model.selection(ResultBox_1, exp.current())] = False; exp.next()
+Reference[model.selection(ResultBox_1, exp.current())] = False; exp.next()
+Reference[model.selection(ResultBox_1, exp.current())] = False; 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())] = False; exp.next()
+Reference[model.selection(ResultBox_1, exp.current())] = False; exp.next()
+Reference[model.selection(ResultBox_1, exp.current())] = False; exp.next()
+Reference[model.selection(ResultBox_1, exp.current())] = False; exp.next()
+Reference[model.selection(ResultBox_1, exp.current())] = False; exp.next()
+Reference[model.selection(ResultBox_1, exp.current())] = False; exp.next()
+Reference[model.selection(ResultBox_1, exp.current())] = False; exp.next()
+Reference[model.selection(ResultBox_1, exp.current())] = False; exp.next()
+Reference[model.selection(ResultBox_1, exp.current())] = False; 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())] = False; 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())] = False; exp.next()
+Reference[model.selection(ResultBox_1, exp.current())] = False; exp.next()
+Reference[model.selection(ResultBox_1, exp.current())] = True; exp.next()
+# Edges of the cylinder
+exp = GeomAPI_ShapeExplorer(ResultCylinder_1.shape(), GeomAPI_Shape.EDGE)
+while exp.more():
+ Reference[model.selection(ResultCylinder_1, exp.current())] = False
+ exp.next()
+# Vertices of the original box
+exp = GeomAPI_ShapeExplorer(ResultBox_1.shape(), GeomAPI_Shape.VERTEX)
+while exp.more():
+ Reference[model.selection(ResultBox_1, exp.current())] = False
+ exp.next()
+# Vertices of the cylinder
+exp = GeomAPI_ShapeExplorer(ResultCylinder_1.shape(), GeomAPI_Shape.VERTEX)
+while exp.more():
+ Reference[model.selection(ResultCylinder_1, exp.current())] = False
+ exp.next()
+
+model.checkFilter(Part_1_doc, model, FilterFace, Reference)
--- /dev/null
+# 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)
+FilterFace = model.filters(Part_1_doc, [model.addFilter(name = "OnGeometry", args = [model.selection("FACE", "Partition_1_1_1/Modified_Face&Box_1_1/Top")])])
+model.end()
+
+Reference = {}
+# Faces of the box (selected as a sub-shapes of the result to keep original surface).
+# Note: the expected values have to be updated if ShapeExplorer will return another order of sub-shapes.
+ResultBox_1 = Partition_1.result().resultSubShapePair()[0]
+exp = GeomAPI_ShapeExplorer(ResultBox_1.shape(), GeomAPI_Shape.FACE)
+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())] = False; exp.next()
+Reference[model.selection(ResultBox_1, exp.current())] = False; exp.next()
+Reference[model.selection(ResultBox_1, exp.current())] = False; exp.next()
+Reference[model.selection(ResultBox_1, exp.current())] = False; 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())] = False; exp.next()
+Reference[model.selection(ResultBox_1, exp.current())] = False; exp.next()
+Reference[model.selection(ResultBox_1, exp.current())] = False; exp.next()
+Reference[model.selection(ResultBox_1, exp.current())] = False; 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())] = False
+ exp.next()
+# Edges of the original box
+exp = GeomAPI_ShapeExplorer(ResultBox_1.shape(), GeomAPI_Shape.EDGE)
+while exp.more():
+ Reference[model.selection(ResultBox_1, exp.current())] = False
+ exp.next()
+# Edges of the cylinder
+exp = GeomAPI_ShapeExplorer(ResultCylinder_1.shape(), GeomAPI_Shape.EDGE)
+while exp.more():
+ Reference[model.selection(ResultCylinder_1, exp.current())] = False
+ exp.next()
+# Vertices of the original box
+exp = GeomAPI_ShapeExplorer(ResultBox_1.shape(), GeomAPI_Shape.VERTEX)
+while exp.more():
+ Reference[model.selection(ResultBox_1, exp.current())] = False
+ exp.next()
+# Vertices of the cylinder
+exp = GeomAPI_ShapeExplorer(ResultCylinder_1.shape(), GeomAPI_Shape.VERTEX)
+while exp.more():
+ Reference[model.selection(ResultCylinder_1, exp.current())] = False
+ exp.next()
+
+model.checkFilter(Part_1_doc, model, FilterFace, Reference)
}
}
+bool GeomAPI_Edge::isSameGeometry(const std::shared_ptr<GeomAPI_Shape> theShape) const
+{
+ if (!theShape->isEdge())
+ return false;
+ TopoDS_Edge anOwnEdge = TopoDS::Edge(impl<TopoDS_Shape>());
+ TopoDS_Edge anOtherEdge = TopoDS::Edge(theShape->impl<TopoDS_Shape>());
+
+ double aFirst, aLast;
+ Handle(Geom_Curve) anOwnCurve = BRep_Tool::Curve(anOwnEdge, aFirst, aLast);
+ Handle(Geom_Curve) anOtherCurve = BRep_Tool::Curve(anOtherEdge, aFirst, aLast);
+ return anOwnCurve == anOtherCurve;
+}
+
bool GeomAPI_Edge::isLine() const
{
const TopoDS_Shape& aShape = const_cast<GeomAPI_Edge*>(this)->impl<TopoDS_Shape>();
GEOMAPI_EXPORT
GeomAPI_Edge(const std::shared_ptr<GeomAPI_Shape>& theShape);
+ /// Returns \c true if edges have same underlying curve
+ GEOMAPI_EXPORT
+ virtual bool isSameGeometry(const std::shared_ptr<GeomAPI_Shape> theShape) const;
+
/// Verifies that the edge is a line
GEOMAPI_EXPORT
bool isLine() const;
return aRes == Standard_True;
}
+bool GeomAPI_Face::isSameGeometry(const std::shared_ptr<GeomAPI_Shape> theShape) const
+{
+ if (!theShape->isFace())
+ return false;
+ TopoDS_Face anOwnFace = TopoDS::Face(impl<TopoDS_Shape>());
+ TopoDS_Face anOtherFace = TopoDS::Face(theShape->impl<TopoDS_Shape>());
+
+ Handle(Geom_Surface) anOwnSurf = BRep_Tool::Surface(anOwnFace);
+ Handle(Geom_Surface) anOtherSurf = BRep_Tool::Surface(anOtherFace);
+ return anOwnSurf == anOtherSurf;
+}
+
bool GeomAPI_Face::isCylindrical() const
{
const TopoDS_Shape& aShape = const_cast<GeomAPI_Face*>(this)->impl<TopoDS_Shape>();
GEOMAPI_EXPORT
virtual bool isEqual(const std::shared_ptr<GeomAPI_Shape> theFace) const;
+ /// Returns \c true if faces have same underlying surface
+ GEOMAPI_EXPORT
+ virtual bool isSameGeometry(const std::shared_ptr<GeomAPI_Shape> theShape) const;
+
/// Returns true if the face is a cylindrical face
GEOMAPI_EXPORT
bool isCylindrical() const;
return MY_SHAPE->IsSame(theShape->impl<TopoDS_Shape>()) == Standard_True;
}
+bool GeomAPI_Shape::isSameGeometry(const std::shared_ptr<GeomAPI_Shape> theShape) const
+{
+ if (isFace())
+ return face()->isSameGeometry(theShape);
+ else if (isEdge())
+ return edge()->isSameGeometry(theShape);
+ return false;
+}
+
bool GeomAPI_Shape::isVertex() const
{
const TopoDS_Shape& aShape = const_cast<GeomAPI_Shape*>(this)->impl<TopoDS_Shape>();
GEOMAPI_EXPORT
virtual bool isSame(const std::shared_ptr<GeomAPI_Shape> theShape) const;
+ /// Returns \c true if shapes have same underlying geometry
+ GEOMAPI_EXPORT
+ virtual bool isSameGeometry(const std::shared_ptr<GeomAPI_Shape> theShape) const;
+
/// Returns whether the shape is a vertex
GEOMAPI_EXPORT
virtual bool isVertex() const;