Salome HOME
Merge branch 'master' into cgt/devCEA
[modules/shaper.git] / src / GeomAlgoAPI / GeomAlgoAPI_MakeShape.cpp
index d743b567ab15c82663d048240e85dc207bd2d99f..dad018f0cee8d427301db1e382540b5df2e37a49 100644 (file)
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
 // File:        GeomAlgoAPI_MakeShape.cpp
 // Created:     20 Oct 2014
 // Author:      Sergey ZARITCHNY
+//
+// Modified by Clarisse Genrault (CEA) : 17 Mar 2016
+
+#include "GeomAlgoAPI_MakeShape.h"
 
-#include <GeomAlgoAPI_MakeShape.h>
+#include <BOPAlgo_Builder.hxx>
+#include <BRepBuilderAPI_MakeShape.hxx>
+#include <BRepCheck_Analyzer.hxx>
+#include <BRepGProp.hxx>
+#include <GProp_GProps.hxx>
+#include <Precision.hxx>
+#include <TopExp_Explorer.hxx>
 #include <TopTools_ListOfShape.hxx>
 #include <TopTools_ListIteratorOfListOfShape.hxx>
-GeomAlgoAPI_MakeShape::GeomAlgoAPI_MakeShape(BRepBuilderAPI_MakeShape *  theMkShape)
-{ myBuilder = theMkShape;}
+#include <GeomAPI_ShapeExplorer.h>
+
+//=================================================================================================
+GeomAlgoAPI_MakeShape::GeomAlgoAPI_MakeShape()
+: myBuilderType(Unknown),
+  myDone(false)
+{
+}
+
+//=================================================================================================
+bool GeomAlgoAPI_MakeShape::isDone() const
+{
+  return myDone;
+}
+
+//=================================================================================================
+const std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_MakeShape::shape() const
+{
+  return myShape;
+}
+
+//=================================================================================================
+bool GeomAlgoAPI_MakeShape::isValid() const
+{
+  BRepCheck_Analyzer aChecker(myShape->impl<TopoDS_Shape>());
+  return (aChecker.IsValid() == Standard_True);
+}
+
+//=================================================================================================
+bool GeomAlgoAPI_MakeShape::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 boost::shared_ptr<GeomAPI_Shape>  GeomAlgoAPI_MakeShape::shape() const
+//=================================================================================================
+std::shared_ptr<GeomAPI_DataMapOfShapeShape> GeomAlgoAPI_MakeShape::mapOfSubShapes() const
 {
-  boost::shared_ptr<GeomAPI_Shape> aShape(new GeomAPI_Shape());
-  if(myBuilder != NULL) 
-    aShape->setImpl(new TopoDS_Shape(myBuilder->Shape()));
-  return aShape;
+  return myMap;
 }
 
-  /// Returns the  list   of shapes generated   from the shape <theShape>
-const ListOfShape& GeomAlgoAPI_MakeShape::generated(const boost::shared_ptr<GeomAPI_Shape> theShape)
+//=================================================================================================
+void GeomAlgoAPI_MakeShape::generated(const std::shared_ptr<GeomAPI_Shape> theShape,
+                                      ListOfShape& theHistory)
 {
-  myHistory.clear();
-  if(myBuilder != NULL) {
-       const TopTools_ListOfShape& aList =  myBuilder->Generated(theShape->impl<TopoDS_Shape>());
-    TopTools_ListIteratorOfListOfShape it(aList);
-       for(;it.More();it.Next()) {
-               boost::shared_ptr<GeomAPI_Shape> aShape(new GeomAPI_Shape());
-               aShape->setImpl(&(it.Value()));
-               myHistory.push_back(aShape);
-       }
+  TopTools_ListOfShape aList;
+  if(myBuilderType == OCCT_BRepBuilderAPI_MakeShape) {
+    BRepBuilderAPI_MakeShape* aMakeShape = implPtr<BRepBuilderAPI_MakeShape>();
+    aList = aMakeShape->Generated(theShape->impl<TopoDS_Shape>());
+  } else if(myBuilderType == OCCT_BOPAlgo_Builder) {
+    BOPAlgo_Builder* aBOPBuilder = implPtr<BOPAlgo_Builder>();
+    aList = aBOPBuilder->Generated(theShape->impl<TopoDS_Shape>());
+  }
+  for(TopTools_ListIteratorOfListOfShape anIt(aList); anIt.More(); anIt.Next()) {
+    if(anIt.Value().IsNull()) {
+      continue;
+    }
+    std::shared_ptr<GeomAPI_Shape> aShape(new GeomAPI_Shape());
+    aShape->setImpl(new TopoDS_Shape(anIt.Value()));
+    theHistory.push_back(aShape);
   }
-  return myHistory;
 }
 
-  /// Returns the  list   of shapes modified   from the shape <theShape>
-const ListOfShape& GeomAlgoAPI_MakeShape::modified(const boost::shared_ptr<GeomAPI_Shape> theShape)
+//=================================================================================================
+void GeomAlgoAPI_MakeShape::modified(const std::shared_ptr<GeomAPI_Shape> theShape,
+                                     ListOfShape& theHistory)
 {
-  myHistory.clear();
-  if(myBuilder != NULL) {
-       const TopTools_ListOfShape& aList =  myBuilder->Modified(theShape->impl<TopoDS_Shape>());
-       TopTools_ListIteratorOfListOfShape it(aList);
-       for(;it.More();it.Next()) {
-               boost::shared_ptr<GeomAPI_Shape> aShape(new GeomAPI_Shape());
-               aShape->setImpl(&(it.Value()));
-               myHistory.push_back(aShape);
-       }
+  TopTools_ListOfShape aList;
+  if(myBuilderType == OCCT_BRepBuilderAPI_MakeShape) {
+    BRepBuilderAPI_MakeShape* aMakeShape = implPtr<BRepBuilderAPI_MakeShape>();
+    try {
+      aList = aMakeShape->Modified(theShape->impl<TopoDS_Shape>());
+    } catch(Standard_NoSuchObject) {
+    }
+  } else if(myBuilderType == OCCT_BOPAlgo_Builder) {
+    BOPAlgo_Builder* aBOPBuilder = implPtr<BOPAlgo_Builder>();
+    aList = aBOPBuilder->Modified(theShape->impl<TopoDS_Shape>());
+  }
+  for(TopTools_ListIteratorOfListOfShape anIt(aList); anIt.More(); anIt.Next()) {
+    if(anIt.Value().IsNull()) {
+      continue;
+    }
+    std::shared_ptr<GeomAPI_Shape> aShape(new GeomAPI_Shape());
+    aShape->setImpl(new TopoDS_Shape(anIt.Value()));
+    theHistory.push_back(aShape);
   }
-  return myHistory;
 }
 
-  /// Returns whether the shape is an edge
-bool GeomAlgoAPI_MakeShape::isDeleted(const boost::shared_ptr<GeomAPI_Shape> theShape)
+//=================================================================================================
+bool GeomAlgoAPI_MakeShape::isDeleted(const std::shared_ptr<GeomAPI_Shape> theShape)
 {
-  bool isDeleted(false);
-  if (myBuilder != NULL) 
-       isDeleted = (bool) myBuilder->IsDeleted(theShape->impl<TopoDS_Shape>());        
+  bool isDeleted = false;
+  if(myBuilderType == OCCT_BRepBuilderAPI_MakeShape) {
+    BRepBuilderAPI_MakeShape* aMakeShape = implPtr<BRepBuilderAPI_MakeShape>();
+    isDeleted = aMakeShape->IsDeleted(theShape->impl<TopoDS_Shape>()) == Standard_True;
+  } else if(myBuilderType == OCCT_BOPAlgo_Builder) {
+    BOPAlgo_Builder* aBOPBuilder = implPtr<BOPAlgo_Builder>();
+    isDeleted = aBOPBuilder->IsDeleted(theShape->impl<TopoDS_Shape>()) == Standard_True;
+  }
+
   return isDeleted;
-}
\ No newline at end of file
+}
+
+//=================================================================================================
+void GeomAlgoAPI_MakeShape::setBuilderType(const BuilderType theBuilderType)
+{
+  myBuilderType = theBuilderType;
+}
+
+//=================================================================================================
+void GeomAlgoAPI_MakeShape::setDone(const bool theFlag)
+{
+  myDone = theFlag;
+}
+
+//=================================================================================================
+void GeomAlgoAPI_MakeShape::setShape(const std::shared_ptr<GeomAPI_Shape> theShape)
+{
+  if(myShape.get() && myShape->isEqual(theShape)) {
+    return;
+  }
+
+  myShape = theShape;
+
+  // Filling data map to keep correct orientation of sub-shapes.
+  if(myShape.get()) {
+    if(myMap.get()) {
+      myMap->clear();
+    } else {
+      myMap.reset(new GeomAPI_DataMapOfShapeShape);
+    }
+
+    const TopoDS_Shape& aTopoDSShape = myShape->impl<TopoDS_Shape>();
+    for(TopExp_Explorer anExp(aTopoDSShape,TopAbs_VERTEX); anExp.More(); anExp.Next()) {
+      std::shared_ptr<GeomAPI_Shape> aCurrentShape(new GeomAPI_Shape());
+      aCurrentShape->setImpl(new TopoDS_Shape(anExp.Current()));
+      myMap->bind(aCurrentShape, aCurrentShape);
+    }
+    for(TopExp_Explorer anExp(aTopoDSShape,TopAbs_EDGE); anExp.More(); anExp.Next()) {
+      std::shared_ptr<GeomAPI_Shape> aCurrentShape(new GeomAPI_Shape());
+      aCurrentShape->setImpl(new TopoDS_Shape(anExp.Current()));
+      myMap->bind(aCurrentShape, aCurrentShape);
+    }
+    for(TopExp_Explorer anExp(aTopoDSShape,TopAbs_FACE); anExp.More(); anExp.Next()) {
+      std::shared_ptr<GeomAPI_Shape> aCurrentShape(new GeomAPI_Shape());
+      aCurrentShape->setImpl(new TopoDS_Shape(anExp.Current()));
+      myMap->bind(aCurrentShape, aCurrentShape);
+    }
+  } else {
+    if(myMap.get()) {
+      myMap->clear();
+    }
+  }
+}
+
+//=================================================================================================
+void GeomAlgoAPI_MakeShape::initialize() {
+  switch (myBuilderType) {
+    case OCCT_BRepBuilderAPI_MakeShape: {
+      myDone = implPtr<BRepBuilderAPI_MakeShape>()->IsDone() == Standard_True;
+      myShape.reset(new GeomAPI_Shape());
+      myShape->setImpl(new TopoDS_Shape(implPtr<BRepBuilderAPI_MakeShape>()->Shape()));
+      break;
+    }
+    case OCCT_BOPAlgo_Builder: {
+      myDone = true;
+      myShape.reset(new GeomAPI_Shape());
+      myShape->setImpl(new TopoDS_Shape(implPtr<BOPAlgo_Builder>()->Shape()));
+      break;
+    }
+  }
+
+  if(myMap.get()) {
+    myMap->clear();
+  } else {
+    myMap.reset(new GeomAPI_DataMapOfShapeShape);
+  }
+
+  const TopoDS_Shape& aTopoDSShape = myShape->impl<TopoDS_Shape>();
+  for(TopExp_Explorer anExp(aTopoDSShape,TopAbs_FACE); anExp.More(); anExp.Next()) {
+    std::shared_ptr<GeomAPI_Shape> aCurrentShape(new GeomAPI_Shape());
+    aCurrentShape->setImpl(new TopoDS_Shape(anExp.Current()));
+    myMap->bind(aCurrentShape, aCurrentShape);
+  }
+}
+
+
+//=================================================================================================
+void GeomAlgoAPI_MakeShape::prepareNamingFaces()
+{
+  long long index = 1;
+  GeomAPI_ShapeExplorer anExp(shape(), GeomAPI_Shape::FACE);
+  for(GeomAPI_ShapeExplorer anExp(shape(), GeomAPI_Shape::FACE); anExp.more(); anExp.next()) {
+    std::shared_ptr<GeomAPI_Shape> aFace = anExp.current();
+    myCreatedFaces["Face_" + std::to_string(index++)] = aFace;
+  }
+}
+
+
+//=================================================================================================
+bool GeomAlgoAPI_MakeShape::checkValid(std::string theMessage){
+
+  // isValid() is called from this method
+  if (!isValid()) {
+    myError = theMessage + " :: resulting shape is not valid.";
+    return false;
+  }
+
+  // Check the number of volumes in myShape, make sure there's one and only one.
+  TopoDS_Shape aTopoDSShape = myShape->impl<TopoDS_Shape>();
+  int aNbVolumes = 0;
+  for(TopExp_Explorer anExp(aTopoDSShape,TopAbs_SOLID); anExp.More(); anExp.Next()) {
+    aNbVolumes ++;
+  }
+
+  if (aNbVolumes != 1) {
+    myError = theMessage +
+      " :: connexity error, the resulting shape is made of several separate solids.";
+    return false;
+  }
+
+  return true ;
+}
+