Salome HOME
New "Combine" flag for partition
[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 <BRepCheck_Analyzer.hxx>
15 #include <TopExp_Explorer.hxx>
16 #include <TopoDS_Builder.hxx>
17 #include <TopTools_ListOfShape.hxx>
18
19 //=================================================================================================
20 std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_Partition::make(const ListOfShape& theObjects,
21                                                            const ListOfShape& theTools)
22 {
23   GeomAlgoAPI_Partition aBoolAlgo(theObjects, theTools);
24   if(aBoolAlgo.isDone() && !aBoolAlgo.shape()->isNull() && aBoolAlgo.isValid()) {
25     return aBoolAlgo.shape();
26   }
27   return std::shared_ptr<GeomAPI_Shape>();
28 }
29
30 //=================================================================================================
31 GeomAlgoAPI_Partition::GeomAlgoAPI_Partition(const ListOfShape& theObjects,
32                                              const ListOfShape& theTools)
33 : myDone(false)
34 {
35   build(theObjects, theTools);
36 }
37
38
39 //=================================================================================================
40 void GeomAlgoAPI_Partition::build(const ListOfShape& theObjects,
41                                   const ListOfShape& theTools)
42 {
43   if (theObjects.empty()) {
44     return;
45   }
46
47   // Creating partition operation.
48   GEOMAlgo_Splitter* anOperation = new GEOMAlgo_Splitter;
49   myMkShape.reset(new GeomAlgoAPI_MakeShape(anOperation, GeomAlgoAPI_MakeShape::BOPAlgoBuilder));
50
51   // Getting objects.
52   for (ListOfShape::const_iterator anObjectsIt = theObjects.begin(); anObjectsIt != theObjects.end(); anObjectsIt++) {
53     const TopoDS_Shape& aShape = (*anObjectsIt)->impl<TopoDS_Shape>();
54     anOperation->AddArgument(aShape);
55   }
56
57   // Getting tools.
58   for (ListOfShape::const_iterator aToolsIt = theTools.begin(); aToolsIt != theTools.end(); aToolsIt++) {
59     const TopoDS_Shape& aShape = (*aToolsIt)->impl<TopoDS_Shape>();
60     anOperation->AddTool(aShape);
61   }
62
63   // Building and getting result.
64   anOperation->Perform();
65   TopoDS_Shape aResult = anOperation->Shape();
66   myDone = !aResult.IsNull();
67   if (!myDone) {
68     return;
69   }
70
71   if(aResult.ShapeType() == TopAbs_COMPOUND) {
72     aResult = GeomAlgoAPI_DFLoader::refineResult(aResult);
73   }
74   if(aResult.ShapeType() == TopAbs_COMPOUND) {
75     std::shared_ptr<GeomAPI_Shape> aCompound(new GeomAPI_Shape);
76     aCompound->setImpl(new TopoDS_Shape(aResult));
77     ListOfShape aCompSolids, aFreeSolids;
78     GeomAlgoAPI_ShapeTools::combineShapes(aCompound, GeomAPI_Shape::COMPSOLID, aCompSolids, aFreeSolids);
79     if(aCompSolids.size() == 1 && aFreeSolids.size() == 0) {
80       aResult = aCompSolids.front()->impl<TopoDS_Shape>();
81     } else if (aCompSolids.size() > 1 || (aCompSolids.size() >= 1 && aFreeSolids.size() >= 1)) {
82       TopoDS_Compound aResultComp;
83       TopoDS_Builder aBuilder;
84       aBuilder.MakeCompound(aResultComp);
85       for(ListOfShape::const_iterator anIter = aCompSolids.cbegin(); anIter != aCompSolids.cend(); anIter++) {
86         aBuilder.Add(aResultComp, (*anIter)->impl<TopoDS_Shape>());
87       }
88       for(ListOfShape::const_iterator anIter = aFreeSolids.cbegin(); anIter != aFreeSolids.cend(); anIter++) {
89         aBuilder.Add(aResultComp, (*anIter)->impl<TopoDS_Shape>());
90       }
91       aResult = aResultComp;
92     }
93   }
94
95   // fill data map to keep correct orientation of sub-shapes
96   myMap.reset(new GeomAPI_DataMapOfShapeShape());
97   for (TopExp_Explorer Exp(aResult,TopAbs_FACE); Exp.More(); Exp.Next()) {
98     std::shared_ptr<GeomAPI_Shape> aCurrentShape(new GeomAPI_Shape());
99     aCurrentShape->setImpl(new TopoDS_Shape(Exp.Current()));
100     myMap->bind(aCurrentShape, aCurrentShape);
101   }
102   myShape.reset(new GeomAPI_Shape());
103   myShape->setImpl(new TopoDS_Shape(aResult));
104 }
105
106 //=================================================================================================
107 const bool GeomAlgoAPI_Partition::isDone() const
108 {
109   return myDone;
110 }
111
112 //=================================================================================================
113 const bool GeomAlgoAPI_Partition::isValid() const
114 {
115   BRepCheck_Analyzer aChecker(myShape->impl<TopoDS_Shape>());
116   return (aChecker.IsValid() == Standard_True);
117 }
118
119 //=================================================================================================
120 const std::shared_ptr<GeomAPI_Shape>& GeomAlgoAPI_Partition::shape() const
121 {
122   return myShape;
123 }
124
125 //=================================================================================================
126 std::shared_ptr<GeomAPI_DataMapOfShapeShape> GeomAlgoAPI_Partition::mapOfShapes() const
127 {
128   return myMap;
129 }
130
131 //=================================================================================================
132 std::shared_ptr<GeomAlgoAPI_MakeShape> GeomAlgoAPI_Partition::makeShape() const
133 {
134   return myMkShape;
135 }