Salome HOME
Add copyright header according to request of CEA from 06.06.2017
[modules/shaper.git] / src / GeomAlgoAPI / GeomAlgoAPI_MakeShape.cpp
1 // Copyright (C) 2014-2017  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
18 //
19
20 #include "GeomAlgoAPI_MakeShape.h"
21
22 #include <BOPAlgo_Builder.hxx>
23 #include <BRepBuilderAPI_MakeShape.hxx>
24 #include <BRepCheck_Analyzer.hxx>
25 #include <BRepGProp.hxx>
26 #include <GProp_GProps.hxx>
27 #include <Precision.hxx>
28 #include <TopExp_Explorer.hxx>
29 #include <TopTools_ListOfShape.hxx>
30 #include <TopTools_ListIteratorOfListOfShape.hxx>
31 #include <GeomAPI_ShapeExplorer.h>
32
33 //=================================================================================================
34 GeomAlgoAPI_MakeShape::GeomAlgoAPI_MakeShape()
35 : myBuilderType(Unknown),
36   myDone(false)
37 {
38 }
39
40 //=================================================================================================
41 bool GeomAlgoAPI_MakeShape::isDone() const
42 {
43   return myDone;
44 }
45
46 //=================================================================================================
47 const std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_MakeShape::shape() const
48 {
49   return myShape;
50 }
51
52 //=================================================================================================
53 bool GeomAlgoAPI_MakeShape::isValid() const
54 {
55   BRepCheck_Analyzer aChecker(myShape->impl<TopoDS_Shape>());
56   return (aChecker.IsValid() == Standard_True);
57 }
58
59 //=================================================================================================
60 bool GeomAlgoAPI_MakeShape::hasVolume() const
61 {
62   bool hasVolume = false;
63   if(isValid()) {
64     const TopoDS_Shape& aRShape = myShape->impl<TopoDS_Shape>();
65     GProp_GProps aGProp;
66     BRepGProp::VolumeProperties(aRShape, aGProp);
67     if(aGProp.Mass() > Precision::Confusion())
68       hasVolume = true;
69   }
70   return hasVolume;
71 }
72
73 //=================================================================================================
74 std::shared_ptr<GeomAPI_DataMapOfShapeShape> GeomAlgoAPI_MakeShape::mapOfSubShapes() const
75 {
76   return myMap;
77 }
78
79 //=================================================================================================
80 void GeomAlgoAPI_MakeShape::generated(const std::shared_ptr<GeomAPI_Shape> theShape,
81                                       ListOfShape& theHistory)
82 {
83   TopTools_ListOfShape aList;
84   if(myBuilderType == OCCT_BRepBuilderAPI_MakeShape) {
85     BRepBuilderAPI_MakeShape* aMakeShape = implPtr<BRepBuilderAPI_MakeShape>();
86     aList = aMakeShape->Generated(theShape->impl<TopoDS_Shape>());
87   } else if(myBuilderType == OCCT_BOPAlgo_Builder) {
88     BOPAlgo_Builder* aBOPBuilder = implPtr<BOPAlgo_Builder>();
89     aList = aBOPBuilder->Generated(theShape->impl<TopoDS_Shape>());
90   }
91   for(TopTools_ListIteratorOfListOfShape anIt(aList); anIt.More(); anIt.Next()) {
92     if(anIt.Value().IsNull()) {
93       continue;
94     }
95     std::shared_ptr<GeomAPI_Shape> aShape(new GeomAPI_Shape());
96     aShape->setImpl(new TopoDS_Shape(anIt.Value()));
97     theHistory.push_back(aShape);
98   }
99 }
100
101 //=================================================================================================
102 void GeomAlgoAPI_MakeShape::modified(const std::shared_ptr<GeomAPI_Shape> theShape,
103                                      ListOfShape& theHistory)
104 {
105   TopTools_ListOfShape aList;
106   if(myBuilderType == OCCT_BRepBuilderAPI_MakeShape) {
107     BRepBuilderAPI_MakeShape* aMakeShape = implPtr<BRepBuilderAPI_MakeShape>();
108     try {
109       aList = aMakeShape->Modified(theShape->impl<TopoDS_Shape>());
110     } catch(Standard_NoSuchObject) {
111     }
112   } else if(myBuilderType == OCCT_BOPAlgo_Builder) {
113     BOPAlgo_Builder* aBOPBuilder = implPtr<BOPAlgo_Builder>();
114     aList = aBOPBuilder->Modified(theShape->impl<TopoDS_Shape>());
115   }
116   for(TopTools_ListIteratorOfListOfShape anIt(aList); anIt.More(); anIt.Next()) {
117     if(anIt.Value().IsNull()) {
118       continue;
119     }
120     std::shared_ptr<GeomAPI_Shape> aShape(new GeomAPI_Shape());
121     aShape->setImpl(new TopoDS_Shape(anIt.Value()));
122     theHistory.push_back(aShape);
123   }
124 }
125
126 //=================================================================================================
127 bool GeomAlgoAPI_MakeShape::isDeleted(const std::shared_ptr<GeomAPI_Shape> theShape)
128 {
129   bool isDeleted = false;
130   if(myBuilderType == OCCT_BRepBuilderAPI_MakeShape) {
131     BRepBuilderAPI_MakeShape* aMakeShape = implPtr<BRepBuilderAPI_MakeShape>();
132     isDeleted = aMakeShape->IsDeleted(theShape->impl<TopoDS_Shape>()) == Standard_True;
133   } else if(myBuilderType == OCCT_BOPAlgo_Builder) {
134     BOPAlgo_Builder* aBOPBuilder = implPtr<BOPAlgo_Builder>();
135     isDeleted = aBOPBuilder->IsDeleted(theShape->impl<TopoDS_Shape>()) == Standard_True;
136   }
137
138   return isDeleted;
139 }
140
141 //=================================================================================================
142 void GeomAlgoAPI_MakeShape::setBuilderType(const BuilderType theBuilderType)
143 {
144   myBuilderType = theBuilderType;
145 }
146
147 //=================================================================================================
148 void GeomAlgoAPI_MakeShape::setDone(const bool theFlag)
149 {
150   myDone = theFlag;
151 }
152
153 //=================================================================================================
154 void GeomAlgoAPI_MakeShape::setShape(const std::shared_ptr<GeomAPI_Shape> theShape)
155 {
156   if(myShape.get() && myShape->isEqual(theShape)) {
157     return;
158   }
159
160   myShape = theShape;
161
162   // Filling data map to keep correct orientation of sub-shapes.
163   if(myShape.get()) {
164     if(myMap.get()) {
165       myMap->clear();
166     } else {
167       myMap.reset(new GeomAPI_DataMapOfShapeShape);
168     }
169
170     const TopoDS_Shape& aTopoDSShape = myShape->impl<TopoDS_Shape>();
171     for(TopExp_Explorer anExp(aTopoDSShape,TopAbs_VERTEX); anExp.More(); anExp.Next()) {
172       std::shared_ptr<GeomAPI_Shape> aCurrentShape(new GeomAPI_Shape());
173       aCurrentShape->setImpl(new TopoDS_Shape(anExp.Current()));
174       myMap->bind(aCurrentShape, aCurrentShape);
175     }
176     for(TopExp_Explorer anExp(aTopoDSShape,TopAbs_EDGE); anExp.More(); anExp.Next()) {
177       std::shared_ptr<GeomAPI_Shape> aCurrentShape(new GeomAPI_Shape());
178       aCurrentShape->setImpl(new TopoDS_Shape(anExp.Current()));
179       myMap->bind(aCurrentShape, aCurrentShape);
180     }
181     for(TopExp_Explorer anExp(aTopoDSShape,TopAbs_FACE); anExp.More(); anExp.Next()) {
182       std::shared_ptr<GeomAPI_Shape> aCurrentShape(new GeomAPI_Shape());
183       aCurrentShape->setImpl(new TopoDS_Shape(anExp.Current()));
184       myMap->bind(aCurrentShape, aCurrentShape);
185     }
186   } else {
187     if(myMap.get()) {
188       myMap->clear();
189     }
190   }
191 }
192
193 //=================================================================================================
194 void GeomAlgoAPI_MakeShape::initialize() {
195   switch (myBuilderType) {
196     case OCCT_BRepBuilderAPI_MakeShape: {
197       myDone = implPtr<BRepBuilderAPI_MakeShape>()->IsDone() == Standard_True;
198       myShape.reset(new GeomAPI_Shape());
199       myShape->setImpl(new TopoDS_Shape(implPtr<BRepBuilderAPI_MakeShape>()->Shape()));
200       break;
201     }
202     case OCCT_BOPAlgo_Builder: {
203       myDone = true;
204       myShape.reset(new GeomAPI_Shape());
205       myShape->setImpl(new TopoDS_Shape(implPtr<BOPAlgo_Builder>()->Shape()));
206       break;
207     }
208   }
209
210   if(myMap.get()) {
211     myMap->clear();
212   } else {
213     myMap.reset(new GeomAPI_DataMapOfShapeShape);
214   }
215
216   const TopoDS_Shape& aTopoDSShape = myShape->impl<TopoDS_Shape>();
217   for(TopExp_Explorer anExp(aTopoDSShape,TopAbs_FACE); anExp.More(); anExp.Next()) {
218     std::shared_ptr<GeomAPI_Shape> aCurrentShape(new GeomAPI_Shape());
219     aCurrentShape->setImpl(new TopoDS_Shape(anExp.Current()));
220     myMap->bind(aCurrentShape, aCurrentShape);
221   }
222 }
223
224
225 //=================================================================================================
226 void GeomAlgoAPI_MakeShape::prepareNamingFaces()
227 {
228   long long index = 1;
229   GeomAPI_ShapeExplorer anExp(shape(), GeomAPI_Shape::FACE);
230   for(GeomAPI_ShapeExplorer anExp(shape(), GeomAPI_Shape::FACE); anExp.more(); anExp.next()) {
231     std::shared_ptr<GeomAPI_Shape> aFace = anExp.current();
232     myCreatedFaces["Face_" + std::to_string(index++)] = aFace;
233   }
234 }
235
236
237 //=================================================================================================
238 bool GeomAlgoAPI_MakeShape::checkValid(std::string theMessage){
239
240   // isValid() is called from this method
241   if (!isValid()) {
242     myError = theMessage + " :: resulting shape is not valid.";
243     return false;
244   }
245
246   // Check the number of volumes in myShape, make sure there's one and only one.
247   TopoDS_Shape aTopoDSShape = myShape->impl<TopoDS_Shape>();
248   int aNbVolumes = 0;
249   for(TopExp_Explorer anExp(aTopoDSShape,TopAbs_SOLID); anExp.More(); anExp.Next()) {
250     aNbVolumes ++;
251   }
252
253   if (aNbVolumes != 1) {
254     myError = theMessage +
255       " :: connexity error, the resulting shape is made of several separate solids.";
256     return false;
257   }
258
259   return true ;
260 }
261