Salome HOME
Implement filter "F5: On geometry"
authorazv <azv@opencascade.com>
Tue, 25 Jun 2019 11:09:14 +0000 (14:09 +0300)
committerazv <azv@opencascade.com>
Tue, 25 Jun 2019 11:09:14 +0000 (14:09 +0300)
12 files changed:
src/FiltersPlugin/CMakeLists.txt
src/FiltersPlugin/FiltersPlugin_OnGeometry.cpp [new file with mode: 0644]
src/FiltersPlugin/FiltersPlugin_OnGeometry.h [new file with mode: 0644]
src/FiltersPlugin/FiltersPlugin_Plugin.cpp
src/FiltersPlugin/Test/TestFilter_OnGeometry_Edge.py [new file with mode: 0644]
src/FiltersPlugin/Test/TestFilter_OnGeometry_Face.py [new file with mode: 0644]
src/GeomAPI/GeomAPI_Edge.cpp
src/GeomAPI/GeomAPI_Edge.h
src/GeomAPI/GeomAPI_Face.cpp
src/GeomAPI/GeomAPI_Face.h
src/GeomAPI/GeomAPI_Shape.cpp
src/GeomAPI/GeomAPI_Shape.h

index 26b732a55d92b2001781f936196f81492b581877..8fd0b5d3a5ffc30286da5dff6120593154ea98fb 100644 (file)
@@ -29,6 +29,7 @@ SET(PROJECT_HEADERS
     FiltersPlugin_BelongsTo.h
     FiltersPlugin_OnPlane.h
     FiltersPlugin_OnLine.h
+    FiltersPlugin_OnGeometry.h
 )
 
 SET(PROJECT_SOURCES
@@ -39,6 +40,7 @@ SET(PROJECT_SOURCES
     FiltersPlugin_BelongsTo.cpp
     FiltersPlugin_OnPlane.cpp
     FiltersPlugin_OnLine.cpp
+    FiltersPlugin_OnGeometry.cpp
 )
 
 SET(PROJECT_LIBRARIES
@@ -73,6 +75,8 @@ ADD_UNIT_TESTS(
   TestFilter_BelongsTo.py
   TestFilter_OnPlane.py
   TestFilter_OnLine.py
+  TestFilter_OnGeometry_Edge.py
+  TestFilter_OnGeometry_Face.py
   TestFilter_HorizontalFaces.py
   TestFilter_VerticalFaces.py
 )
diff --git a/src/FiltersPlugin/FiltersPlugin_OnGeometry.cpp b/src/FiltersPlugin/FiltersPlugin_OnGeometry.cpp
new file mode 100644 (file)
index 0000000..e62dba4
--- /dev/null
@@ -0,0 +1,65 @@
+// 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());
+}
diff --git a/src/FiltersPlugin/FiltersPlugin_OnGeometry.h b/src/FiltersPlugin/FiltersPlugin_OnGeometry.h
new file mode 100644 (file)
index 0000000..98d197a
--- /dev/null
@@ -0,0 +1,57 @@
+// 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
index d35bf7f40ce557a4c0fa529f35b8d7cdb994c280..1780ec50fac05a7bf4c48efcadcf792c129e664e 100644 (file)
@@ -24,6 +24,7 @@
 #include "FiltersPlugin_BelongsTo.h"
 #include "FiltersPlugin_OnPlane.h"
 #include "FiltersPlugin_OnLine.h"
+#include "FiltersPlugin_OnGeometry.h"
 
 #include <ModelAPI_Session.h>
 #include <ModelAPI_FiltersFactory.h>
@@ -41,6 +42,7 @@ FiltersPlugin_Plugin::FiltersPlugin_Plugin()
   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);
 }
diff --git a/src/FiltersPlugin/Test/TestFilter_OnGeometry_Edge.py b/src/FiltersPlugin/Test/TestFilter_OnGeometry_Edge.py
new file mode 100644 (file)
index 0000000..7a14e68
--- /dev/null
@@ -0,0 +1,115 @@
+# 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)
diff --git a/src/FiltersPlugin/Test/TestFilter_OnGeometry_Face.py b/src/FiltersPlugin/Test/TestFilter_OnGeometry_Face.py
new file mode 100644 (file)
index 0000000..1638b0b
--- /dev/null
@@ -0,0 +1,79 @@
+# 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)
index ede977f30df08670d940ebbf007986f89286d43f..f69cbca46a5c1c7e51fb36f7869dfadd6727452a 100644 (file)
@@ -67,6 +67,19 @@ GeomAPI_Edge::GeomAPI_Edge(const std::shared_ptr<GeomAPI_Shape>& theShape)
   }
 }
 
+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>();
index eb3b668a8c5f02d5f175134c31a3d6f2647a1d62..9d3a4f47b9ae1fe26df16c724cd795a5386c2d27 100644 (file)
@@ -44,6 +44,10 @@ public:
   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;
index c17fe87d3ec243f47aa5fd42269f5047be7c1514..c03ec7f23313092e4c01a181333a6ffab1492ca2 100644 (file)
@@ -104,6 +104,18 @@ bool GeomAPI_Face::isEqual(std::shared_ptr<GeomAPI_Shape> theFace) 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>();
index 271667107557da13f0aeb486bf2fdf02ac41e50c..c81d6c265b1c0d1a0814dc305b72c067e9930c20 100644 (file)
@@ -47,6 +47,10 @@ public:
   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;
index 98bfdcf9ea22993bd7d5555c395f9ed1334b1078..011aa3dd435edb34a2ccd60f01db05468a749070 100644 (file)
@@ -101,6 +101,15 @@ bool GeomAPI_Shape::isSame(const std::shared_ptr<GeomAPI_Shape> theShape) 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>();
index cf3222bca246fc178d895d381812016bebdc9121..ab0166bfb62023385b19dbd02f3c234061a162b8 100644 (file)
@@ -77,6 +77,10 @@ public:
   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;