Salome HOME
Dump Python in the High Level Parameterized Geometry API (issue #1648)
[modules/shaper.git] / src / GeomAlgoAPI / GeomAlgoAPI_MakeShape.cpp
1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
2
3 // File:        GeomAlgoAPI_MakeShape.cpp
4 // Created:     20 Oct 2014
5 // Author:      Sergey ZARITCHNY
6 //
7 // Modified by Clarisse Genrault (CEA) : 17 Mar 2016
8
9 #include "GeomAlgoAPI_MakeShape.h"
10
11 #include <BOPAlgo_Builder.hxx>
12 #include <BRepBuilderAPI_MakeShape.hxx>
13 #include <BRepCheck_Analyzer.hxx>
14 #include <BRepGProp.hxx>
15 #include <GProp_GProps.hxx>
16 #include <Precision.hxx>
17 #include <TopExp_Explorer.hxx>
18 #include <TopTools_ListOfShape.hxx>
19 #include <TopTools_ListIteratorOfListOfShape.hxx>
20 #include <GeomAPI_ShapeExplorer.h>
21
22 //=================================================================================================
23 GeomAlgoAPI_MakeShape::GeomAlgoAPI_MakeShape()
24 : myBuilderType(Unknown),
25   myDone(false)
26 {
27 }
28
29 //=================================================================================================
30 bool GeomAlgoAPI_MakeShape::isDone() const
31 {
32   return myDone;
33 }
34
35 //=================================================================================================
36 const std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_MakeShape::shape() const
37 {
38   return myShape;
39 }
40
41 //=================================================================================================
42 bool GeomAlgoAPI_MakeShape::isValid() const
43 {
44   BRepCheck_Analyzer aChecker(myShape->impl<TopoDS_Shape>());
45   return (aChecker.IsValid() == Standard_True);
46 }
47
48 //=================================================================================================
49 bool GeomAlgoAPI_MakeShape::hasVolume() const
50 {
51   bool hasVolume = false;
52   if(isValid()) {
53     const TopoDS_Shape& aRShape = myShape->impl<TopoDS_Shape>();
54     GProp_GProps aGProp;
55     BRepGProp::VolumeProperties(aRShape, aGProp);
56     if(aGProp.Mass() > Precision::Confusion())
57       hasVolume = true;
58   }
59   return hasVolume;
60 }
61
62 //=================================================================================================
63 std::shared_ptr<GeomAPI_DataMapOfShapeShape> GeomAlgoAPI_MakeShape::mapOfSubShapes() const
64 {
65   return myMap;
66 }
67
68 //=================================================================================================
69 void GeomAlgoAPI_MakeShape::generated(const std::shared_ptr<GeomAPI_Shape> theShape,
70                                       ListOfShape& theHistory)
71 {
72   TopTools_ListOfShape aList;
73   if(myBuilderType == OCCT_BRepBuilderAPI_MakeShape) {
74     BRepBuilderAPI_MakeShape* aMakeShape = implPtr<BRepBuilderAPI_MakeShape>();
75     aList = aMakeShape->Generated(theShape->impl<TopoDS_Shape>());
76   } else if(myBuilderType == OCCT_BOPAlgo_Builder) {
77     BOPAlgo_Builder* aBOPBuilder = implPtr<BOPAlgo_Builder>();
78     aList = aBOPBuilder->Generated(theShape->impl<TopoDS_Shape>());
79   }
80   for(TopTools_ListIteratorOfListOfShape anIt(aList); anIt.More(); anIt.Next()) {
81     if(anIt.Value().IsNull()) {
82       continue;
83     }
84     std::shared_ptr<GeomAPI_Shape> aShape(new GeomAPI_Shape());
85     aShape->setImpl(new TopoDS_Shape(anIt.Value()));
86     theHistory.push_back(aShape);
87   }
88 }
89
90 //=================================================================================================
91 void GeomAlgoAPI_MakeShape::modified(const std::shared_ptr<GeomAPI_Shape> theShape,
92                                      ListOfShape& theHistory)
93 {
94   TopTools_ListOfShape aList;
95   if(myBuilderType == OCCT_BRepBuilderAPI_MakeShape) {
96     BRepBuilderAPI_MakeShape* aMakeShape = implPtr<BRepBuilderAPI_MakeShape>();
97     try {
98       aList = aMakeShape->Modified(theShape->impl<TopoDS_Shape>());
99     } catch(Standard_NoSuchObject) {
100     }
101   } else if(myBuilderType == OCCT_BOPAlgo_Builder) {
102     BOPAlgo_Builder* aBOPBuilder = implPtr<BOPAlgo_Builder>();
103     aList = aBOPBuilder->Modified(theShape->impl<TopoDS_Shape>());
104   }
105   for(TopTools_ListIteratorOfListOfShape anIt(aList); anIt.More(); anIt.Next()) {
106     if(anIt.Value().IsNull()) {
107       continue;
108     }
109     std::shared_ptr<GeomAPI_Shape> aShape(new GeomAPI_Shape());
110     aShape->setImpl(new TopoDS_Shape(anIt.Value()));
111     theHistory.push_back(aShape);
112   }
113 }
114
115 //=================================================================================================
116 bool GeomAlgoAPI_MakeShape::isDeleted(const std::shared_ptr<GeomAPI_Shape> theShape)
117 {
118   bool isDeleted = false;
119   if(myBuilderType == OCCT_BRepBuilderAPI_MakeShape) {
120     BRepBuilderAPI_MakeShape* aMakeShape = implPtr<BRepBuilderAPI_MakeShape>();
121     isDeleted = aMakeShape->IsDeleted(theShape->impl<TopoDS_Shape>()) == Standard_True;
122   } else if(myBuilderType == OCCT_BOPAlgo_Builder) {
123     BOPAlgo_Builder* aBOPBuilder = implPtr<BOPAlgo_Builder>();
124     isDeleted = aBOPBuilder->IsDeleted(theShape->impl<TopoDS_Shape>()) == Standard_True;
125   }
126
127   return isDeleted;
128 }
129
130 //=================================================================================================
131 void GeomAlgoAPI_MakeShape::setBuilderType(const BuilderType theBuilderType)
132 {
133   myBuilderType = theBuilderType;
134 }
135
136 //=================================================================================================
137 void GeomAlgoAPI_MakeShape::setDone(const bool theFlag)
138 {
139   myDone = theFlag;
140 }
141
142 //=================================================================================================
143 void GeomAlgoAPI_MakeShape::setShape(const std::shared_ptr<GeomAPI_Shape> theShape)
144 {
145   if(myShape.get() && myShape->isEqual(theShape)) {
146     return;
147   }
148
149   myShape = theShape;
150
151   // Filling data map to keep correct orientation of sub-shapes.
152   if(myShape.get()) {
153     if(myMap.get()) {
154       myMap->clear();
155     } else {
156       myMap.reset(new GeomAPI_DataMapOfShapeShape);
157     }
158
159     const TopoDS_Shape& aTopoDSShape = myShape->impl<TopoDS_Shape>();
160     for(TopExp_Explorer anExp(aTopoDSShape,TopAbs_EDGE); anExp.More(); anExp.Next()) {
161       std::shared_ptr<GeomAPI_Shape> aCurrentShape(new GeomAPI_Shape());
162       aCurrentShape->setImpl(new TopoDS_Shape(anExp.Current()));
163       myMap->bind(aCurrentShape, aCurrentShape);
164     }
165     for(TopExp_Explorer anExp(aTopoDSShape,TopAbs_FACE); anExp.More(); anExp.Next()) {
166       std::shared_ptr<GeomAPI_Shape> aCurrentShape(new GeomAPI_Shape());
167       aCurrentShape->setImpl(new TopoDS_Shape(anExp.Current()));
168       myMap->bind(aCurrentShape, aCurrentShape);
169     }
170   } else {
171     if(myMap.get()) {
172       myMap->clear();
173     }
174   }
175 }
176
177 //=================================================================================================
178 void GeomAlgoAPI_MakeShape::initialize() {
179   switch (myBuilderType) {
180     case OCCT_BRepBuilderAPI_MakeShape: {
181       myDone = implPtr<BRepBuilderAPI_MakeShape>()->IsDone() == Standard_True;
182       myShape.reset(new GeomAPI_Shape());
183       myShape->setImpl(new TopoDS_Shape(implPtr<BRepBuilderAPI_MakeShape>()->Shape()));
184       break;
185     }
186     case OCCT_BOPAlgo_Builder: {
187       myDone = true;
188       myShape.reset(new GeomAPI_Shape());
189       myShape->setImpl(new TopoDS_Shape(implPtr<BOPAlgo_Builder>()->Shape()));
190       break;
191     }
192   }
193
194   if(myMap.get()) {
195     myMap->clear();
196   } else {
197     myMap.reset(new GeomAPI_DataMapOfShapeShape);
198   }
199
200   const TopoDS_Shape& aTopoDSShape = myShape->impl<TopoDS_Shape>();
201   for(TopExp_Explorer anExp(aTopoDSShape,TopAbs_FACE); anExp.More(); anExp.Next()) {
202     std::shared_ptr<GeomAPI_Shape> aCurrentShape(new GeomAPI_Shape());
203     aCurrentShape->setImpl(new TopoDS_Shape(anExp.Current()));
204     myMap->bind(aCurrentShape, aCurrentShape);
205   }
206 }
207
208
209 //=================================================================================================
210 void GeomAlgoAPI_MakeShape::prepareNamingFaces()
211 {
212   long long index = 1;
213   GeomAPI_ShapeExplorer anExp(shape(), GeomAPI_Shape::FACE);
214   for(GeomAPI_ShapeExplorer anExp(shape(), GeomAPI_Shape::FACE); anExp.more(); anExp.next()) {
215     std::shared_ptr<GeomAPI_Shape> aFace = anExp.current();
216     myCreatedFaces["Face_" + std::to_string(index++)] = aFace;
217   }
218 }
219
220
221 //=================================================================================================
222 bool GeomAlgoAPI_MakeShape::checkValid(std::string theMessage){
223
224   // isValid() is called from this method
225   if (!isValid()) {
226     myError = theMessage + " :: resulting shape is not valid.";
227     return false;
228   }
229
230   // Check the number of volumes in myShape, make sure there's one and only one.
231   TopoDS_Shape aTopoDSShape = myShape->impl<TopoDS_Shape>();
232   int aNbVolumes = 0;
233   for(TopExp_Explorer anExp(aTopoDSShape,TopAbs_SOLID); anExp.More(); anExp.Next()) {
234     aNbVolumes ++;
235   }
236   
237   if (aNbVolumes != 1) {
238     myError = theMessage + " :: connexity error, the resulting shape is made of several separate solids."; 
239     return false;
240   }
241   
242   return true ;
243 }
244