Salome HOME
Issue #273: Add copyright string
[modules/shaper.git] / src / GeomAlgoAPI / GeomAlgoAPI_Extrusion.cpp
index d5affc09469e1bd75b92c9a6bbb1272f4a94f348..29c4aec277baa4167af118b36f05d4f343f9e261 100644 (file)
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
 // File:        GeomAlgoAPI_Extrusion.cpp
 // Created:     06 Jun 2014
 // Author:      Artem ZHIDKOV
 
 #include <GeomAlgoAPI_Extrusion.h>
-
+#include <GeomAlgoAPI_MakeShape.h>
+#include <GeomAlgoAPI_DFLoader.h>
+#include <GeomAlgoAPI_MakeShape.h>
 #include <gp_Pln.hxx>
-
 #include <BRepPrimAPI_MakePrism.hxx>
+#include <BRepBuilderAPI_MakeShape.hxx>
 #include <Geom_Plane.hxx>
 #include <Geom_Surface.hxx>
 #include <TopExp_Explorer.hxx>
-
+#include <BRepCheck_Analyzer.hxx>
+#include <GProp_GProps.hxx>
+#include <BRepGProp.hxx>
+#include <TopoDS.hxx>
+#include <TopTools_ListIteratorOfListOfShape.hxx>
 #include <Precision.hxx>
-const double tolerance = Precision::Angular();
+#include <TDF_TagSource.hxx>
+#include <memory>
+#include <BRepPrimAPI_MakePrism.hxx>
+#include <TopoDS_Shape.hxx>
 
-boost::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_Extrusion::makeExtrusion(
-                        boost::shared_ptr<GeomAPI_Shape> theShape,
-                        boost::shared_ptr<GeomAPI_Dir>   theDir,
-                        double                           theSize)
+const double tolerance = Precision::Angular();
+// Constructor
+GeomAlgoAPI_Extrusion::GeomAlgoAPI_Extrusion(
+  std::shared_ptr<GeomAPI_Shape> theBasis, double theSize)
+: mySize(theSize), myDone(false), myShape(new GeomAPI_Shape()),
+  myFirst(new GeomAPI_Shape()), myLast(new GeomAPI_Shape())
 {
-  const TopoDS_Shape& aShape = theShape->impl<TopoDS_Shape>();
-  gp_Vec aDir(theDir->impl<gp_Dir>().XYZ() * theSize);
-
-  TopoDS_Shape aPrism = BRepPrimAPI_MakePrism(aShape, aDir);
-  if (aPrism.IsNull())
-    return boost::shared_ptr<GeomAPI_Shape>();
-
-  boost::shared_ptr<GeomAPI_Shape> aResult(new GeomAPI_Shape());
-  aResult->setImpl(new TopoDS_Shape(aPrism));
-  return aResult;
+  build(theBasis);
 }
 
-boost::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_Extrusion::makeExtrusion(
-                        boost::shared_ptr<GeomAPI_Shape> theShape,
-                        double                           theSize)
+//============================================================================
+void GeomAlgoAPI_Extrusion::build(const std::shared_ptr<GeomAPI_Shape>& theBasis)
 {
   bool isFirstNorm = true;
   gp_Dir aShapeNormal;
+  TopoDS_Face aBasis = TopoDS::Face(theBasis->impl<TopoDS_Shape>());
+  Handle(Geom_Plane) aPlane = Handle(Geom_Plane)::DownCast(
+    BRep_Tool::Surface(aBasis));
+  if (aPlane.IsNull())  // non-planar shapes is not supported for extrusion yet
+    return;
+
+  const gp_Dir& aNormal = aPlane->Pln().Axis().Direction();  
+  gp_Vec aVec(aNormal);
+  aVec = aVec * mySize;
+
+  BRepPrimAPI_MakePrism* aBuilder = new BRepPrimAPI_MakePrism(aBasis, aVec);
+  if(aBuilder) {
+    setImpl(aBuilder);
+    myDone = aBuilder->IsDone() == Standard_True;
+    if (myDone) {       
+      TopoDS_Shape aResult;
+      if(aBuilder->Shape().ShapeType() == TopAbs_COMPOUND) 
+        aResult = GeomAlgoAPI_DFLoader::refineResult(aBuilder->Shape());
+      else
+        aResult = aBuilder->Shape();
+         // fill data map to keep correct orientation of sub-shapes 
+         for (TopExp_Explorer Exp(aResult,TopAbs_FACE); Exp.More(); Exp.Next()) {
+           std::shared_ptr<GeomAPI_Shape> aCurrentShape(new GeomAPI_Shape());
+        aCurrentShape->setImpl(new TopoDS_Shape(Exp.Current()));
+           myMap.bind(aCurrentShape, aCurrentShape);
+         }   
+      myShape->setImpl(new TopoDS_Shape(aResult));
+      myFirst->setImpl(new TopoDS_Shape(aBuilder->FirstShape()));
+      myLast->setImpl(new TopoDS_Shape(aBuilder-> LastShape()));
+         myMkShape = new GeomAlgoAPI_MakeShape (aBuilder);
+       }  
+  }
+}
 
-  const TopoDS_Shape& aShape = theShape->impl<TopoDS_Shape>();
-  TopExp_Explorer aFaceExp(aShape, TopAbs_FACE);
-  for ( ; aFaceExp.More(); aFaceExp.Next())
-  {
-    const TopoDS_Face& aFace = (const TopoDS_Face&)aFaceExp.Current();
-    Handle(BRep_TFace) aBFace = Handle(BRep_TFace)::DownCast(aFace.TShape());
-    if (aBFace.IsNull())
-      return boost::shared_ptr<GeomAPI_Shape>();
+//============================================================================
+const bool GeomAlgoAPI_Extrusion::isDone() const
+{return myDone;}
 
-    Handle(Geom_Plane) aPlane = Handle(Geom_Plane)::DownCast(aBFace->Surface());
-    if (aPlane.IsNull()) // non-planar shapes is not supported for extrusion yet
-      continue;
+//============================================================================
+const bool GeomAlgoAPI_Extrusion::isValid() const
+{
+       BRepCheck_Analyzer aChecker(myShape->impl<TopoDS_Shape>());
+    return (aChecker.IsValid() == Standard_True);
+}
 
-    const gp_Dir& aNormal = aPlane->Pln().Axis().Direction();
-    if (isFirstNorm)
-    {
-      aShapeNormal = aNormal;
-      isFirstNorm = false;
-    }
-    else if (!aShapeNormal.IsEqual(aNormal, tolerance)) // non-planar shapes is not supported for extrusion yet
-      return boost::shared_ptr<GeomAPI_Shape>();
+//============================================================================
+const bool GeomAlgoAPI_Extrusion::hasVolume() const
+{
+  bool hasVolume(false);
+  if(isValid()) {
+    const TopoDS_Shape& aRShape = myShape->impl<TopoDS_Shape>();
+    GProp_GProps aGProp;
+    BRepGProp::VolumeProperties(aRShape, aGProp);
+    if(aGProp.Mass() > Precision::Confusion()) 
+      hasVolume = true;        
   }
+  return hasVolume;
+}
+
+//============================================================================
+const std::shared_ptr<GeomAPI_Shape>& GeomAlgoAPI_Extrusion::shape () const 
+{
+  return myShape;
+}
+
+//============================================================================
+const std::shared_ptr<GeomAPI_Shape>& GeomAlgoAPI_Extrusion::firstShape()
+{
+  return myFirst;
+}
+
+//============================================================================
+const std::shared_ptr<GeomAPI_Shape>& GeomAlgoAPI_Extrusion::lastShape()
+{
+  return myLast;
+}
 
-  boost::shared_ptr<GeomAPI_Dir> aDir(
-    new GeomAPI_Dir(aShapeNormal.X(), aShapeNormal.Y(), aShapeNormal.Z()));
+//============================================================================
+void GeomAlgoAPI_Extrusion::mapOfShapes (GeomAPI_DataMapOfShapeShape& theMap) const
+{
+  theMap = myMap;
+}
 
-  return GeomAlgoAPI_Extrusion::makeExtrusion(theShape, aDir, theSize);
+//============================================================================
+GeomAlgoAPI_MakeShape * GeomAlgoAPI_Extrusion::makeShape() const
+{
+  return myMkShape;
 }
+
+//============================================================================
+GeomAlgoAPI_Extrusion::~GeomAlgoAPI_Extrusion()
+{
+  if (myImpl) {    
+       myMap.clear();
+  }
+}
\ No newline at end of file