Salome HOME
Issue #1482: Fixed results of Extrusion, Revolution, Pipe and Partition. If it is...
[modules/shaper.git] / src / GeomAlgoAPI / GeomAlgoAPI_Partition.cpp
1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
2
3 // File:        GeomAlgoAPI_Partition.cpp
4 // Created:     21 Aug 2015
5 // Author:      Sergey POKHODENKO
6
7 #include "GeomAlgoAPI_Partition.h"
8
9 #include <GeomAlgoAPI_DFLoader.h>
10 #include <GeomAlgoAPI_ShapeTools.h>
11
12 #include <GEOMAlgo_Splitter.hxx>
13
14 #include <TopExp_Explorer.hxx>
15 #include <TopoDS_Builder.hxx>
16
17 //=================================================================================================
18 std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_Partition::make(const ListOfShape& theObjects,
19                                                            const ListOfShape& theTools)
20 {
21   GeomAlgoAPI_Partition aPartitionAlgo(theObjects, theTools);
22   if(aPartitionAlgo.isDone() && !aPartitionAlgo.shape()->isNull() && aPartitionAlgo.isValid()) {
23     return aPartitionAlgo.shape();
24   }
25   return std::shared_ptr<GeomAPI_Shape>();
26 }
27
28 //=================================================================================================
29 GeomAlgoAPI_Partition::GeomAlgoAPI_Partition(const ListOfShape& theObjects,
30                                              const ListOfShape& theTools)
31 {
32   build(theObjects, theTools);
33 }
34
35
36 //=================================================================================================
37 void GeomAlgoAPI_Partition::build(const ListOfShape& theObjects,
38                                   const ListOfShape& theTools)
39 {
40   if (theObjects.empty()) {
41     return;
42   }
43
44   // Creating partition operation.
45   GEOMAlgo_Splitter* anOperation = new GEOMAlgo_Splitter;
46   this->setImpl(anOperation);
47   this->setBuilderType(OCCT_BOPAlgo_Builder);
48
49   // Getting objects.
50   for (ListOfShape::const_iterator anObjectsIt = theObjects.begin(); anObjectsIt != theObjects.end(); anObjectsIt++) {
51     const TopoDS_Shape& aShape = (*anObjectsIt)->impl<TopoDS_Shape>();
52     anOperation->AddArgument(aShape);
53   }
54
55   // Getting tools.
56   for (ListOfShape::const_iterator aToolsIt = theTools.begin(); aToolsIt != theTools.end(); aToolsIt++) {
57     const TopoDS_Shape& aShape = (*aToolsIt)->impl<TopoDS_Shape>();
58     anOperation->AddTool(aShape);
59   }
60
61   // Building and getting result.
62   anOperation->Perform();
63   if(anOperation->ErrorStatus() != 0) {
64     return;
65   }
66   TopoDS_Shape aResult = anOperation->Shape();
67
68   if(aResult.ShapeType() == TopAbs_COMPOUND) {
69     aResult = GeomAlgoAPI_DFLoader::refineResult(aResult);
70   }
71   if(aResult.ShapeType() == TopAbs_COMPOUND) {
72     std::shared_ptr<GeomAPI_Shape> aCompound(new GeomAPI_Shape);
73     aCompound->setImpl(new TopoDS_Shape(aResult));
74     ListOfShape aCompSolids, aFreeSolids;
75     GeomAlgoAPI_ShapeTools::combineShapes(aCompound, GeomAPI_Shape::COMPSOLID, aCompSolids, aFreeSolids);
76     if(aCompSolids.size() == 1 && aFreeSolids.size() == 0) {
77       aResult = aCompSolids.front()->impl<TopoDS_Shape>();
78     } else if (aCompSolids.size() > 1 || (aCompSolids.size() >= 1 && aFreeSolids.size() >= 1)) {
79       TopoDS_Compound aResultComp;
80       TopoDS_Builder aBuilder;
81       aBuilder.MakeCompound(aResultComp);
82       for(ListOfShape::const_iterator anIter = aCompSolids.cbegin(); anIter != aCompSolids.cend(); anIter++) {
83         aBuilder.Add(aResultComp, (*anIter)->impl<TopoDS_Shape>());
84       }
85       for(ListOfShape::const_iterator anIter = aFreeSolids.cbegin(); anIter != aFreeSolids.cend(); anIter++) {
86         aBuilder.Add(aResultComp, (*anIter)->impl<TopoDS_Shape>());
87       }
88       aResult = aResultComp;
89     }
90   }
91
92   // Setting result.
93   if(aResult.IsNull()) {
94     return;
95   }
96   aResult = GeomAlgoAPI_DFLoader::refineResult(aResult);
97   std::shared_ptr<GeomAPI_Shape> aShape(new GeomAPI_Shape());
98   aShape->setImpl(new TopoDS_Shape(aResult));
99   this->setShape(aShape);
100   this->setDone(true);
101 }