Salome HOME
Fix for naming in Build features.
[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_VERTEX); 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_EDGE); 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     for(TopExp_Explorer anExp(aTopoDSShape,TopAbs_FACE); anExp.More(); anExp.Next()) {
171       std::shared_ptr<GeomAPI_Shape> aCurrentShape(new GeomAPI_Shape());
172       aCurrentShape->setImpl(new TopoDS_Shape(anExp.Current()));
173       myMap->bind(aCurrentShape, aCurrentShape);
174     }
175   } else {
176     if(myMap.get()) {
177       myMap->clear();
178     }
179   }
180 }
181
182 //=================================================================================================
183 void GeomAlgoAPI_MakeShape::initialize() {
184   switch (myBuilderType) {
185     case OCCT_BRepBuilderAPI_MakeShape: {
186       myDone = implPtr<BRepBuilderAPI_MakeShape>()->IsDone() == Standard_True;
187       myShape.reset(new GeomAPI_Shape());
188       myShape->setImpl(new TopoDS_Shape(implPtr<BRepBuilderAPI_MakeShape>()->Shape()));
189       break;
190     }
191     case OCCT_BOPAlgo_Builder: {
192       myDone = true;
193       myShape.reset(new GeomAPI_Shape());
194       myShape->setImpl(new TopoDS_Shape(implPtr<BOPAlgo_Builder>()->Shape()));
195       break;
196     }
197   }
198
199   if(myMap.get()) {
200     myMap->clear();
201   } else {
202     myMap.reset(new GeomAPI_DataMapOfShapeShape);
203   }
204
205   const TopoDS_Shape& aTopoDSShape = myShape->impl<TopoDS_Shape>();
206   for(TopExp_Explorer anExp(aTopoDSShape,TopAbs_FACE); anExp.More(); anExp.Next()) {
207     std::shared_ptr<GeomAPI_Shape> aCurrentShape(new GeomAPI_Shape());
208     aCurrentShape->setImpl(new TopoDS_Shape(anExp.Current()));
209     myMap->bind(aCurrentShape, aCurrentShape);
210   }
211 }
212
213
214 //=================================================================================================
215 void GeomAlgoAPI_MakeShape::prepareNamingFaces()
216 {
217   long long index = 1;
218   GeomAPI_ShapeExplorer anExp(shape(), GeomAPI_Shape::FACE);
219   for(GeomAPI_ShapeExplorer anExp(shape(), GeomAPI_Shape::FACE); anExp.more(); anExp.next()) {
220     std::shared_ptr<GeomAPI_Shape> aFace = anExp.current();
221     myCreatedFaces["Face_" + std::to_string(index++)] = aFace;
222   }
223 }
224
225
226 //=================================================================================================
227 bool GeomAlgoAPI_MakeShape::checkValid(std::string theMessage){
228
229   // isValid() is called from this method
230   if (!isValid()) {
231     myError = theMessage + " :: resulting shape is not valid.";
232     return false;
233   }
234
235   // Check the number of volumes in myShape, make sure there's one and only one.
236   TopoDS_Shape aTopoDSShape = myShape->impl<TopoDS_Shape>();
237   int aNbVolumes = 0;
238   for(TopExp_Explorer anExp(aTopoDSShape,TopAbs_SOLID); anExp.More(); anExp.Next()) {
239     aNbVolumes ++;
240   }
241   
242   if (aNbVolumes != 1) {
243     myError = theMessage + " :: connexity error, the resulting shape is made of several separate solids."; 
244     return false;
245   }
246   
247   return true ;
248 }
249