]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Issue #1369: Added "Create Face" feature.
authordbv <dbv@opencascade.com>
Fri, 22 Apr 2016 11:07:14 +0000 (14:07 +0300)
committerdbv <dbv@opencascade.com>
Fri, 22 Apr 2016 11:07:40 +0000 (14:07 +0300)
15 files changed:
src/BuildPlugin/BuildPlugin_Face.cpp [new file with mode: 0644]
src/BuildPlugin/BuildPlugin_Face.h [new file with mode: 0644]
src/BuildPlugin/BuildPlugin_Plugin.cpp
src/BuildPlugin/BuildPlugin_Validators.cpp
src/BuildPlugin/BuildPlugin_Validators.h
src/BuildPlugin/BuildPlugin_Wire.cpp
src/BuildPlugin/CMakeLists.txt
src/BuildPlugin/face_widget.xml [new file with mode: 0644]
src/BuildPlugin/icons/feature_face.png [new file with mode: 0644]
src/BuildPlugin/plugin-Build.xml
src/GeomAPI/GeomAPI_Pln.cpp
src/GeomAPI/GeomAPI_Pln.h
src/GeomAPI/GeomAPI_Shape.cpp
src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.cpp
src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.h

diff --git a/src/BuildPlugin/BuildPlugin_Face.cpp b/src/BuildPlugin/BuildPlugin_Face.cpp
new file mode 100644 (file)
index 0000000..36ef2b3
--- /dev/null
@@ -0,0 +1,108 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File:        BuildPlugin_Face.cpp
+// Created:     14 April 2016
+// Author:      Dmitry Bobylev
+
+#include "BuildPlugin_Face.h"
+
+#include <ModelAPI_AttributeSelectionList.h>
+#include <ModelAPI_ResultBody.h>
+#include <ModelAPI_ResultConstruction.h>
+
+#include <Events_Error.h>
+
+#include <GeomAPI_DataMapOfShapeShape.h>
+#include <GeomAPI_PlanarEdges.h>
+#include <GeomAPI_Pln.h>
+#include <GeomAPI_ShapeExplorer.h>
+
+#include <GeomAlgoAPI_ShapeTools.h>
+#include <GeomAlgoAPI_SketchBuilder.h>
+#include <GeomAlgoAPI_WireBuilder.h>
+
+#include <algorithm>
+#include <sstream>
+
+//=================================================================================================
+BuildPlugin_Face::BuildPlugin_Face()
+{
+}
+
+//=================================================================================================
+void BuildPlugin_Face::initAttributes()
+{
+  data()->addAttribute(BASE_OBJECTS_ID(), ModelAPI_AttributeSelectionList::typeId());
+}
+
+//=================================================================================================
+void BuildPlugin_Face::execute()
+{
+  // Get base objects list.
+  AttributeSelectionListPtr aSelectionList = selectionList(BASE_OBJECTS_ID());
+  if(!aSelectionList.get()) {
+    setError("Error: Could not get selection list.");
+    return;
+  }
+  if(aSelectionList->size() == 0) {
+    setError("Error: Empty selection list.");
+    return;
+  }
+
+  // Collect base shapes.
+  ListOfShape anEdges;
+  for(int anIndex = 0; anIndex < aSelectionList->size(); ++anIndex) {
+    AttributeSelectionPtr aSelection = aSelectionList->value(anIndex);
+    GeomShapePtr aShape = aSelection->value();
+    if(!aShape.get()) {
+      aShape = aSelection->context()->shape();
+    }
+    for(GeomAPI_ShapeExplorer anExp(aShape, GeomAPI_Shape::EDGE); anExp.more(); anExp.next()) {
+      GeomShapePtr anEdge = anExp.current();
+      anEdges.push_back(anEdge);
+    }
+  }
+
+  // Get plane.
+  std::shared_ptr<GeomAPI_Pln> aPln = GeomAlgoAPI_ShapeTools::findPlane(anEdges);
+
+  // Get faces.
+  ListOfShape aFaces;
+  GeomAlgoAPI_SketchBuilder::createFaces(aPln->location(), aPln->xDirection(), aPln->direction(), anEdges, aFaces);
+
+  // Get wires from faces.
+  ListOfShape aWires;
+  for(ListOfShape::const_iterator anIt = aFaces.cbegin(); anIt != aFaces.cend(); ++anIt) {
+    for(GeomAPI_ShapeExplorer anExp(*anIt, GeomAPI_Shape::WIRE); anExp.more(); anExp.next()) {
+      aWires.push_back(anExp.current());
+    }
+  }
+
+  // Make faces with holes.
+  aFaces.clear();
+  GeomAlgoAPI_ShapeTools::makeFacesWithHoles(aPln->location(), aPln->direction(), aWires, aFaces);
+
+  // Store result.
+  int anIndex = 0;
+  for(ListOfShape::const_iterator anIt = aFaces.cbegin(); anIt != aFaces.cend(); ++anIt) {
+    ResultBodyPtr aResultBody = document()->createBody(data(), anIndex);
+    GeomShapePtr aShape = *anIt;
+    aResultBody->store(aShape);
+
+    for(GeomAPI_ShapeExplorer anExp(aShape, GeomAPI_Shape::EDGE); anExp.more(); anExp.next()) {
+      GeomShapePtr anEdgeInResult = anExp.current();
+      for(ListOfShape::const_iterator anIt = anEdges.cbegin(); anIt != anEdges.cend(); ++anIt) {
+        std::shared_ptr<GeomAPI_Edge> anEdgeInList(new GeomAPI_Edge(*anIt));
+        if(anEdgeInList->isEqual(anEdgeInResult)) {
+          aResultBody->modified(anEdgeInList, anEdgeInResult, "Edge");
+          break;
+        }
+      }
+    }
+
+    setResult(aResultBody, anIndex);
+    ++anIndex;
+  }
+
+  removeResults(anIndex);
+}
diff --git a/src/BuildPlugin/BuildPlugin_Face.h b/src/BuildPlugin/BuildPlugin_Face.h
new file mode 100644 (file)
index 0000000..fafd51d
--- /dev/null
@@ -0,0 +1,51 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File:        BuildPlugin_Face.h
+// Created:     14 April 2016
+// Author:      Dmitry Bobylev
+
+#ifndef BuildPlugin_Face_H_
+#define BuildPlugin_Face_H_
+
+#include "BuildPlugin.h"
+
+#include <ModelAPI_Feature.h>
+
+/// \class BuildPlugin_Face
+/// \ingroup Plugins
+/// \brief Feature for creation of face from sketch edges or existing wires.
+class BuildPlugin_Face: public ModelAPI_Feature
+{
+public:
+  /// Use plugin manager for features creation
+  BuildPlugin_Face();
+
+  /// Feature kind.
+  inline static const std::string& ID()
+  {
+    static const std::string MY_ID("Face");
+    return MY_ID;
+  }
+
+  /// Attribute name of base objects.
+  inline static const std::string& BASE_OBJECTS_ID()
+  {
+    static const std::string MY_BASE_OBJECTS_ID("base_objects");
+    return MY_BASE_OBJECTS_ID;
+  }
+
+  /// \return the kind of a feature.
+  BUILDPLUGIN_EXPORT virtual const std::string& getKind()
+  {
+    static std::string MY_KIND = BuildPlugin_Face::ID();
+    return MY_KIND;
+  }
+
+  /// Request for initialization of data model of the feature: adding all attributes.
+  BUILDPLUGIN_EXPORT virtual void initAttributes();
+
+  /// Creates a new part document if needed.
+  BUILDPLUGIN_EXPORT virtual void execute();
+};
+
+#endif
index f26c60ace00e00d3d24de00aba2f28927b3d2984..f11e4ba6ecc6c035687089412acb7c57651ed0e3 100644 (file)
@@ -12,6 +12,7 @@
 #include <BuildPlugin_Vertex.h>
 #include <BuildPlugin_Edge.h>
 #include <BuildPlugin_Wire.h>
+#include <BuildPlugin_Face.h>
 #include <BuildPlugin_Validators.h>
 
 // the only created instance of this plugin
@@ -27,6 +28,8 @@ BuildPlugin_Plugin::BuildPlugin_Plugin()
                               new BuildPlugin_ValidatorBaseForBuild());
   aFactory->registerValidator("BuildPlugin_ValidatorBaseForWire",
                               new BuildPlugin_ValidatorBaseForWire());
+  aFactory->registerValidator("BuildPlugin_ValidatorBaseForFace",
+                              new BuildPlugin_ValidatorBaseForFace());
 
   // Register this plugin.
   ModelAPI_Session::get()->registerPlugin(this);
@@ -41,6 +44,8 @@ FeaturePtr BuildPlugin_Plugin::createFeature(std::string theFeatureID)
     return FeaturePtr(new BuildPlugin_Edge());
   } else if(theFeatureID == BuildPlugin_Wire::ID()) {
     return FeaturePtr(new BuildPlugin_Wire());
+  } else if(theFeatureID == BuildPlugin_Face::ID()) {
+    return FeaturePtr(new BuildPlugin_Face());
   }
 
   // Feature of such kind is not found.
index 7204aebce1f05fd0f784cde8ee740f70e75a3960..5097fea405d887c957ffd83abc3caaa8c7850d0e 100644 (file)
 #include <ModelAPI_ResultConstruction.h>
 
 #include <GeomAPI_PlanarEdges.h>
+#include <GeomAPI_Pln.h>
+#include <GeomAPI_ShapeExplorer.h>
 
 #include <GeomAlgoAPI_CompoundBuilder.h>
+#include <GeomAlgoAPI_PaveFiller.h>
+#include <GeomAlgoAPI_ShapeTools.h>
+#include <GeomAlgoAPI_SketchBuilder.h>
 #include <GeomAlgoAPI_WireBuilder.h>
 
 #include <GeomValidators_ShapeType.h>
@@ -100,23 +105,17 @@ bool BuildPlugin_ValidatorBaseForWire::isValid(const std::shared_ptr<ModelAPI_Fe
 {
   // Get attribute.
   if(theArguments.size() != 1) {
-    Events_Error::send("Error: BuildPlugin_ValidatorBaseForWire should be used only with 1 parameter (ID of base objects list)");
+    Events_Error::send("Error: BuildPlugin_ValidatorBaseForWire should be used only with 1 parameter (ID of base objects list).");
     return false;
   }
-  AttributePtr anAttribute = theFeature->attribute(theArguments.front());
-
-  // Check base objects list.
-  BuildPlugin_ValidatorBaseForBuild aValidatorBaseForBuild;
-  std::list<std::string> anArguments;
-  anArguments.push_back("edge");
-  anArguments.push_back("wire");
-  if(!aValidatorBaseForBuild.isValid(anAttribute, anArguments, theError)) {
+  AttributeSelectionListPtr aSelectionList = theFeature->selectionList(theArguments.front());
+  if(!aSelectionList.get()) {
+    theError = "Empty attribute \"" + theArguments.front() + "\".";
     return false;
   }
 
+
   // Collect base shapes.
-  AttributeSelectionListPtr aSelectionList =
-    std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(anAttribute);
   ListOfShape aListOfShapes;
   for(int anIndex = 0; anIndex < aSelectionList->size(); ++anIndex) {
     AttributeSelectionPtr aSelection = aSelectionList->value(anIndex);
@@ -138,40 +137,80 @@ bool BuildPlugin_ValidatorBaseForWire::isValid(const std::shared_ptr<ModelAPI_Fe
 }
 
 //=================================================================================================
-bool BuildPlugin_ValidatorBaseForWireisNotObligatory(std::string theFeature, std::string theAttribute)
+bool BuildPlugin_ValidatorBaseForWire::isNotObligatory(std::string theFeature, std::string theAttribute)
 {
   return false;
 }
 
 //=================================================================================================
-bool BuildPlugin_ValidatorBaseForFace::isValid(const AttributePtr& theAttribute,
+bool BuildPlugin_ValidatorBaseForFace::isValid(const std::shared_ptr<ModelAPI_Feature>& theFeature,
                                                const std::list<std::string>& theArguments,
                                                std::string& theError) const
 {
-  // Get base objects list.
-  BuildPlugin_ValidatorBaseForBuild aValidatorBaseForBuild;
-  std::list<std::string> anArguments;
-  anArguments.push_back("edge");
-  anArguments.push_back("wire");
-  if(!aValidatorBaseForBuild.isValid(theAttribute, anArguments, theError)) {
+  // Get attribute.
+  if(theArguments.size() != 1) {
+    Events_Error::send("Error: BuildPlugin_ValidatorBaseForFace should be used only with 1 parameter (ID of base objects list).");
+    return false;
+  }
+  AttributeSelectionListPtr aSelectionList = theFeature->selectionList(theArguments.front());
+  if(!aSelectionList.get()) {
+    theError = "Empty attribute \"" + theArguments.front() + "\".";
     return false;
   }
 
   // Collect base shapes.
-  AttributeSelectionListPtr aSelectionList =
-    std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
-  ListOfShape aListOfShapes;
+  ListOfShape anEdges;
   for(int anIndex = 0; anIndex < aSelectionList->size(); ++anIndex) {
     AttributeSelectionPtr aSelection = aSelectionList->value(anIndex);
     GeomShapePtr aShape = aSelection->value();
     if(!aShape.get()) {
       aShape = aSelection->context()->shape();
     }
-    aListOfShapes.push_back(aShape);
+    for(GeomAPI_ShapeExplorer anExp(aShape, GeomAPI_Shape::EDGE); anExp.more(); anExp.next()) {
+      GeomShapePtr anEdge = anExp.current();
+      anEdges.push_back(anEdge);
+    }
+  }
+
+  // Check that edges does not have intersections.
+  if(anEdges.size() > 1) {
+    GeomAlgoAPI_PaveFiller aPaveFiller(anEdges, false);
+    if(!aPaveFiller.isDone()) {
+      theError = "Error while checking if edges intersects.";
+      return false;
+    }
+    GeomShapePtr aSectedEdges = aPaveFiller.shape();
+
+    int anEdgesNum = 0;
+    for(GeomAPI_ShapeExplorer anExp(aSectedEdges, GeomAPI_Shape::EDGE); anExp.more(); anExp.next()) {
+      anEdgesNum++;
+    }
+    if(anEdgesNum != anEdges.size()) {
+      theError = "Selected objects have intersections.";
+      return false;
+    }
   }
 
   // Check that they are planar.
-  GeomShapePtr aCompound = GeomAlgoAPI_CompoundBuilder::compound(aListOfShapes);
+  std::shared_ptr<GeomAPI_Pln> aPln = GeomAlgoAPI_ShapeTools::findPlane(anEdges);
+  if(!aPln.get()) {
+    theError = "Selected objects are not planar.";
+    return false;
+  }
 
-  return aCompound->isPlanar();
+  // Check that selected objects have closed contours.
+  ListOfShape aFaces;
+  GeomAlgoAPI_SketchBuilder::createFaces(aPln->location(), aPln->xDirection(), aPln->direction(), anEdges, aFaces);
+  if(aFaces.empty()) {
+    theError = "Selected objects does not have closed contours.";
+    return false;
+  }
+
+  return true;
+}
+
+//=================================================================================================
+bool BuildPlugin_ValidatorBaseForFace::isNotObligatory(std::string theFeature, std::string theAttribute)
+{
+  return false;
 }
index 8792c42ce9b4af7bcac37a0f63dee1360affaca6..1f2091efe0e45347047c9eb7399cc7b3677d5a31 100644 (file)
@@ -48,17 +48,20 @@ public:
 /// \class BuildPlugin_ValidatorBaseForFace
 /// \ingroup Validators
 /// \brief A validator for selection base shapes for face. Allows to select sketch edges, edges and
-/// wires objects that lie in the same plane.
-class BuildPlugin_ValidatorBaseForFace: public ModelAPI_AttributeValidator
+/// wires objects that lie in the same plane and don't have intersections.
+class BuildPlugin_ValidatorBaseForFace: public ModelAPI_FeatureValidator
 {
 public:
-  //! Returns true if attribute is ok.
-  //! \param[in] theAttribute the checked attribute.
-  //! \param[in] theArguments arguments of the attribute.
-  //! \param[out] theError error message.
-   virtual bool isValid(const AttributePtr& theAttribute,
-                        const std::list<std::string>& theArguments,
-                        std::string& theError) const;
+  //! Returns true if attributes is ok.
+  //! \param theFeature the checked feature.
+  //! \param theArguments arguments of the feature.
+  //! \param theError error message.
+  virtual bool isValid(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+                       const std::list<std::string>& theArguments,
+                       std::string& theError) const;
+
+  /// \return true if the attribute in feature is not obligatory for the feature execution
+  virtual bool isNotObligatory(std::string theFeature, std::string theAttribute);
 };
 
 #endif
index 5a69e9f490430dabbc0d469dada2e43d94802340..99d6bd74ed7cb704e9d5bea0d831852aac9f6f9a 100644 (file)
@@ -67,7 +67,7 @@ void BuildPlugin_Wire::execute()
   // Create wire.
   GeomShapePtr aWire = GeomAlgoAPI_WireBuilder::wire(aListOfShapes);
   if(!aWire.get()) {
-    setError("Error: Result wire empty. Probably it has disconnected edges or non-manifold.");
+    setError("Error: Result wire is empty. Probably it has disconnected edges or non-manifold.");
     return;
   }
 
index 3c159e8d600399c8e6932fe6732e63f22e378ee3..a2ada0459e3b27680d19a8025560635461efed2f 100644 (file)
@@ -17,6 +17,7 @@ SET(PROJECT_HEADERS
     BuildPlugin_Vertex.h
     BuildPlugin_Edge.h
     BuildPlugin_Wire.h
+    BuildPlugin_Face.h
     BuildPlugin_Validators.h
 )
 
@@ -25,6 +26,7 @@ SET(PROJECT_SOURCES
     BuildPlugin_Vertex.cpp
     BuildPlugin_Edge.cpp
     BuildPlugin_Wire.cpp
+    BuildPlugin_Face.cpp
     BuildPlugin_Validators.cpp
 )
 
@@ -33,6 +35,7 @@ SET(XML_RESOURCES
     vertex_widget.xml
     edge_widget.xml
     wire_widget.xml
+    face_widget.xml
 )
 
 SET(PROJECT_LIBRARIES
diff --git a/src/BuildPlugin/face_widget.xml b/src/BuildPlugin/face_widget.xml
new file mode 100644 (file)
index 0000000..8a05c4a
--- /dev/null
@@ -0,0 +1,11 @@
+<!-- Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
+
+<source>
+  <multi_selector id="base_objects"
+                  label="Segments and wires:"
+                  tooltip="Select an edges on sketch or wires objects."
+                  type_choice="edges objects">
+    <validator id="BuildPlugin_ValidatorBaseForBuild" parameters="edge,wire"/>
+  </multi_selector>
+  <validator id="BuildPlugin_ValidatorBaseForFace" parameters="base_objects"/>
+</source>
diff --git a/src/BuildPlugin/icons/feature_face.png b/src/BuildPlugin/icons/feature_face.png
new file mode 100644 (file)
index 0000000..6abc697
Binary files /dev/null and b/src/BuildPlugin/icons/feature_face.png differ
index 0c2161f68ae8041b6bcb0fb401efbf05d309e677..cfa04ecf0581114acc1e6d3649ba6e6fde6d8ea2 100644 (file)
@@ -12,6 +12,9 @@
       <feature id="Wire" title="Wire" tooltip ="Create a wire from sketch edges and wires objects" icon="icons/Build/feature_wire.png">
         <source path="wire_widget.xml"/>
       </feature>
+      <feature id="Face" title="Face" tooltip ="Create a face from sketch edges and wires objects" icon="icons/Build/feature_face.png">
+        <source path="face_widget.xml"/>
+      </feature>
     </group>
    </workbench>
 </plugin>
index 347e994f4d4a98d3c1735678f5dc8d11e518c779..8dcce0a701aca40d6bc7748a6b3404dddcaecccf 100644 (file)
@@ -43,6 +43,12 @@ std::shared_ptr<GeomAPI_Dir> GeomAPI_Pln::direction() const
   return std::shared_ptr<GeomAPI_Dir>(new GeomAPI_Dir(aDir.X(), aDir.Y(), aDir.Z()));
 }
 
+std::shared_ptr<GeomAPI_Dir> GeomAPI_Pln::xDirection() const
+{
+  const gp_Dir& aDir = impl<gp_Pln>().XAxis().Direction();
+  return std::shared_ptr<GeomAPI_Dir>(new GeomAPI_Dir(aDir.X(), aDir.Y(), aDir.Z()));
+}
+
 void GeomAPI_Pln::coefficients(double& theA, double& theB, double& theC, double& theD)
 {
   impl<gp_Pln>().Coefficients(theA, theB, theC, theD);
index 3c319b78955457a22245d66922e3ad276afd3f71..5c173838dcdfbac5a2b370daabb1ee4fdd52d1f2 100644 (file)
@@ -44,6 +44,10 @@ class GeomAPI_Pln : public GeomAPI_Interface
   GEOMAPI_EXPORT 
   std::shared_ptr<GeomAPI_Dir> direction() const;
 
+  /// Returns a plane x direction
+  GEOMAPI_EXPORT 
+  std::shared_ptr<GeomAPI_Dir> xDirection() const;
+
   /// Returns the plane coefficients (Ax+By+Cz+D=0)
   GEOMAPI_EXPORT 
   void coefficients(double& theA, double& theB, double& theC, double& theD);
index 279e3738a712ad482aec9eb2e6893e08e47e0349..cba5be5ce00993d69a696c3513bb447cfd6a2a63 100644 (file)
 #include <BRepBuilderAPI_FindPlane.hxx>
 #include <BRepTools.hxx>
 #include <Bnd_Box.hxx>
+#include <Geom_Circle.hxx>
+#include <Geom_Conic.hxx>
+#include <Geom_Curve.hxx>
+#include <Geom_Ellipse.hxx>
+#include <Geom_Hyperbola.hxx>
+#include <Geom_Line.hxx>
+#include <Geom_Parabola.hxx>
 #include <Geom_Plane.hxx>
 #include <Geom_RectangularTrimmedSurface.hxx>
+#include <Geom_TrimmedCurve.hxx>
 #include <TopoDS.hxx>
 #include <TopoDS_Iterator.hxx>
 #include <TopoDS_Shape.hxx>
@@ -95,19 +103,28 @@ bool GeomAPI_Shape::isCompSolid() const
 
 bool GeomAPI_Shape::isPlanar() const
 {
-  const TopoDS_Shape& aShape = const_cast<GeomAPI_Shape*>(this)->impl<TopoDS_Shape>();
+  TopoDS_Shape aShape = impl<TopoDS_Shape>();
 
   if(aShape.IsNull()) {
     return false;
   }
 
   TopAbs_ShapeEnum aShapeType = aShape.ShapeType();
+  if(aShapeType == TopAbs_COMPOUND) {
+    TopoDS_Iterator anIt(aShape);
+    int aShNum = 0;
+    for(; anIt.More(); anIt.Next()) {
+      ++aShNum;
+    }
+    if(aShNum == 1) {
+      anIt.Initialize(aShape);
+      aShape = anIt.Value();
+    }
+  }
 
+  aShapeType = aShape.ShapeType();
   if(aShapeType == TopAbs_VERTEX) {
     return true;
-  } else if(aShapeType == TopAbs_EDGE || aShapeType ==  TopAbs_WIRE || aShapeType == TopAbs_SHELL) {
-    BRepBuilderAPI_FindPlane aFindPlane(aShape);
-    return aFindPlane.Found() == Standard_True;
   } else if(aShapeType == TopAbs_FACE) {
     const Handle(Geom_Surface)& aSurface = BRep_Tool::Surface(TopoDS::Face(aShape));
     Handle(Standard_Type) aType = aSurface->DynamicType();
@@ -118,8 +135,33 @@ bool GeomAPI_Shape::isPlanar() const
     }
     return (aType == STANDARD_TYPE(Geom_Plane)) == Standard_True;
   } else {
-    return false;
+    BRepBuilderAPI_FindPlane aFindPlane(aShape);
+    bool isFound = aFindPlane.Found() == Standard_True;
+
+    if(!isFound && aShapeType == TopAbs_EDGE) {
+      Standard_Real aFirst, aLast;
+      Handle(Geom_Curve) aCurve = BRep_Tool::Curve(TopoDS::Edge(aShape), aFirst, aLast);
+      Handle(Standard_Type) aType = aCurve->DynamicType();
+
+      if(aType == STANDARD_TYPE(Geom_TrimmedCurve)) {
+        Handle(Geom_TrimmedCurve) aTrimCurve = Handle(Geom_TrimmedCurve)::DownCast(aCurve);
+        aType = aTrimCurve->BasisCurve()->DynamicType();
+      }
+
+      if(aType == STANDARD_TYPE(Geom_Line)
+          || aType == STANDARD_TYPE(Geom_Conic)
+          || aType == STANDARD_TYPE(Geom_Circle)
+          || aType == STANDARD_TYPE(Geom_Ellipse)
+          || aType == STANDARD_TYPE(Geom_Hyperbola)
+          || aType == STANDARD_TYPE(Geom_Parabola)) {
+        isFound = true;
+      }
+    }
+
+    return isFound;
   }
+
+  return false;
 }
 
 GeomAPI_Shape::ShapeType GeomAPI_Shape::shapeType() const
index 2a5fd2083441825f1968b28748f6af09dcbc6124..47d05e566058953cd77ab69d04fc1f59493010e6 100644 (file)
@@ -10,6 +10,7 @@
 
 #include <GeomAPI_Dir.h>
 #include <GeomAPI_PlanarEdges.h>
+#include <GeomAPI_Pln.h>
 #include <GeomAPI_Pnt.h>
 
 #include <Bnd_Box.hxx>
@@ -17,6 +18,7 @@
 #include <BRep_Builder.hxx>
 #include <BRepAlgo_FaceRestrictor.hxx>
 #include <BRepBndLib.hxx>
+#include <BRepBuilderAPI_FindPlane.hxx>
 #include <BRepBuilderAPI_MakeFace.hxx>
 #include <BRepGProp.hxx>
 #include <BRep_Tool.hxx>
 #include <TopoDS.hxx>
 #include <TopExp_Explorer.hxx>
 
-
-void mapWireFaces(const TopoDS_Shape& theShape,
-                  BOPCol_IndexedDataMapOfShapeListOfShape& theMapWireFaces);
-
 //=================================================================================================
 double GeomAlgoAPI_ShapeTools::volume(const std::shared_ptr<GeomAPI_Shape> theShape)
 {
@@ -372,3 +370,31 @@ void GeomAlgoAPI_ShapeTools::makeFacesWithHoles(const std::shared_ptr<GeomAPI_Pn
     theFaces.push_back(aShape);
   }
 }
+
+//=================================================================================================
+std::shared_ptr<GeomAPI_Pln> GeomAlgoAPI_ShapeTools::findPlane(const ListOfShape& theShapes)
+{
+  TopoDS_Compound aCompound;
+  BRep_Builder aBuilder;
+  aBuilder.MakeCompound(aCompound);
+
+  for(ListOfShape::const_iterator anIt = theShapes.cbegin(); anIt != theShapes.cend(); ++anIt) {
+    aBuilder.Add(aCompound, (*anIt)->impl<TopoDS_Shape>());
+  }
+  BRepBuilderAPI_FindPlane aFindPlane(aCompound);
+
+  if(aFindPlane.Found() != Standard_True) {
+    return std::shared_ptr<GeomAPI_Pln>();
+  }
+
+  Handle(Geom_Plane) aPlane = aFindPlane.Plane();
+  gp_Pnt aLoc = aPlane->Location();
+  gp_Dir aDir = aPlane->Axis().Direction();
+
+  std::shared_ptr<GeomAPI_Pnt> aGeomPnt(new GeomAPI_Pnt(aLoc.X(), aLoc.Y(), aLoc.Z()));
+  std::shared_ptr<GeomAPI_Dir> aGeomDir(new GeomAPI_Dir(aDir.X(), aDir.Y(), aDir.Z()));
+
+  std::shared_ptr<GeomAPI_Pln> aPln(new GeomAPI_Pln(aGeomPnt, aGeomDir));
+
+  return aPln;
+}
index 6136d6c1080946836930fb36d7448acf64216c70..07d6704ab861d8cc4d0dfc2de5ec64d040d05677 100644 (file)
@@ -14,6 +14,7 @@
 
 class GeomAPI_Dir;
 class GeomAPI_PlanarEdges;
+class GeomAPI_Pln;
 class GeomAPI_Pnt;
 
 /// \class GeomAlgoAPI_ShapeTools
@@ -65,13 +66,18 @@ public:
                          std::shared_ptr<GeomAPI_Vertex>& theV1,
                          std::shared_ptr<GeomAPI_Vertex>& theV2);
 
-  /// \Creates faces with holes from wires.
+  /// \brief Creates faces with holes from wires.
   /// \param[in] theWires base wires.
   /// \param[out] theFaces resulting faces.
   static void makeFacesWithHoles(const std::shared_ptr<GeomAPI_Pnt> theOrigin,
                                  const std::shared_ptr<GeomAPI_Dir> theDirection,
                                  const ListOfShape& theWires,
                                  ListOfShape& theFaces);
+
+  /// \brief Return a plane for list of shapes if they are all planar.
+  /// \param[in] theShapes shapes to find plane.
+  /// \return plane where all shapes lie or empty ptr if they not planar.
+  static std::shared_ptr<GeomAPI_Pln> findPlane(const ListOfShape& theShapes);
 };
 
 #endif