Salome HOME
Compsolids in boolean operations
[modules/shaper.git] / src / GeomAlgoAPI / GeomAlgoAPI_Boolean.cpp
1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
2
3 // File:        GeomAlgoAPI_Boolean.cpp
4 // Created:     02 Sept 2014
5 // Author:      Vitaly Smetannikov
6
7 #include "GeomAlgoAPI_Boolean.h"
8
9 #include <GeomAlgoAPI_DFLoader.h>
10
11 #include <BRepAlgoAPI_BooleanOperation.hxx>
12 #include <BRepAlgoAPI_Common.hxx>
13 #include <BRepAlgoAPI_Cut.hxx>
14 #include <BRepAlgoAPI_Fuse.hxx>
15 #include <BRepCheck_Analyzer.hxx>
16 #include <TopExp_Explorer.hxx>
17 #include <TopTools_ListOfShape.hxx>
18
19 //=================================================================================================
20 std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_Boolean::makeCut(const ListOfShape& theObjects,
21                                                             const ListOfShape& theTools)
22 {
23   GeomAlgoAPI_Boolean aBoolAlgo(theObjects, theTools, BOOL_CUT);
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 std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_Boolean::makeFuse(const ListOfShape& theObjects,
32                                                              const ListOfShape& theTools)
33 {
34   GeomAlgoAPI_Boolean aBoolAlgo(theObjects, theTools, BOOL_FUSE);
35   if(aBoolAlgo.isDone() && !aBoolAlgo.shape()->isNull() && aBoolAlgo.isValid()) {
36     return aBoolAlgo.shape();
37   }
38   return std::shared_ptr<GeomAPI_Shape>();
39 }
40
41 //=================================================================================================
42 std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_Boolean::makeCommon(const ListOfShape& theObjects,
43                                                                const ListOfShape& theTools)
44 {
45   GeomAlgoAPI_Boolean aBoolAlgo(theObjects, theTools, BOOL_COMMON);
46   if(aBoolAlgo.isDone() && !aBoolAlgo.shape()->isNull() && aBoolAlgo.isValid()) {
47     return aBoolAlgo.shape();
48   }
49   return std::shared_ptr<GeomAPI_Shape>();
50 }
51
52 //=================================================================================================
53 GeomAlgoAPI_Boolean::GeomAlgoAPI_Boolean(const ListOfShape& theObjects,
54                                          const ListOfShape& theTools,
55                                          const OperationType theOperationType)
56 : myDone(false)
57 {
58   build(theObjects, theTools, theOperationType);
59 }
60
61
62 //=================================================================================================
63 void GeomAlgoAPI_Boolean::build(const ListOfShape& theObjects,
64                                 const ListOfShape& theTools,
65                                 const OperationType theOperationType)
66 {
67   if(theObjects.empty() || theTools.empty()) {
68     return;
69   }
70
71   // Getting objects.
72   TopTools_ListOfShape anObjects;
73   for(ListOfShape::const_iterator anObjectsIt = theObjects.begin(); anObjectsIt != theObjects.end(); anObjectsIt++)
74   {
75     anObjects.Append((*anObjectsIt)->impl<TopoDS_Shape>());
76   }
77
78   // Getting tools.
79   TopTools_ListOfShape aTools;
80   for(ListOfShape::const_iterator aToolsIt = theTools.begin(); aToolsIt != theTools.end(); aToolsIt++)
81   {
82     aTools.Append((*aToolsIt)->impl<TopoDS_Shape>());
83   }
84
85   // Creating boolean operation.
86   BRepAlgoAPI_BooleanOperation* anOperation;
87   switch (theOperationType) {
88     case BOOL_CUT: {
89       anOperation = new BRepAlgoAPI_Cut();
90       break;
91     }
92     case BOOL_FUSE: {
93       anOperation = new BRepAlgoAPI_Fuse();
94       break;
95     }
96     case BOOL_COMMON: {
97       anOperation = new BRepAlgoAPI_Common();
98       break;
99     }
100     default: {
101       return;
102     }
103   }
104   myMkShape.reset(new GeomAlgoAPI_MakeShape(anOperation));
105   anOperation->SetArguments(anObjects);
106   anOperation->SetTools(aTools);
107
108   // Building and getting result.
109   anOperation->Build();
110   myDone = anOperation->IsDone() == Standard_True;
111   if(!myDone) {
112     return;
113   }
114   TopoDS_Shape aResult = anOperation->Shape();
115
116   if(aResult.ShapeType() == TopAbs_COMPOUND) {
117     aResult = GeomAlgoAPI_DFLoader::refineResult(aResult);
118   }
119
120   // fill data map to keep correct orientation of sub-shapes
121   myMap.reset(new GeomAPI_DataMapOfShapeShape());
122   for (TopExp_Explorer Exp(aResult,TopAbs_FACE); Exp.More(); Exp.Next()) {
123     std::shared_ptr<GeomAPI_Shape> aCurrentShape(new GeomAPI_Shape());
124     aCurrentShape->setImpl(new TopoDS_Shape(Exp.Current()));
125     myMap->bind(aCurrentShape, aCurrentShape);
126   }
127   myShape.reset(new GeomAPI_Shape());
128   myShape->setImpl(new TopoDS_Shape(aResult));
129
130 }
131
132 //=================================================================================================
133 const bool GeomAlgoAPI_Boolean::isDone() const
134 {
135   return myDone;
136 }
137
138 //=================================================================================================
139 const bool GeomAlgoAPI_Boolean::isValid() const
140 {
141   BRepCheck_Analyzer aChecker(myShape->impl<TopoDS_Shape>());
142   return (aChecker.IsValid() == Standard_True);
143 }
144
145 //=================================================================================================
146 const std::shared_ptr<GeomAPI_Shape>& GeomAlgoAPI_Boolean::shape() const
147 {
148   return myShape;
149 }
150
151 //=================================================================================================
152 std::shared_ptr<GeomAPI_DataMapOfShapeShape> GeomAlgoAPI_Boolean::mapOfShapes() const
153 {
154   return myMap;
155 }
156
157 //=================================================================================================
158 std::shared_ptr<GeomAlgoAPI_MakeShape> GeomAlgoAPI_Boolean::makeShape() const
159 {
160   return myMkShape;
161 }