]> SALOME platform Git repositories - modules/shaper.git/blob - src/GeomAlgoAPI/GeomAlgoAPI_Pipe.cpp
Salome HOME
Issue #1860: fix end lines with spaces
[modules/shaper.git] / src / GeomAlgoAPI / GeomAlgoAPI_Pipe.cpp
1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
2
3 // File:        GeomAlgoAPI_Pipe.cpp
4 // Created:     16 March 2016
5 // Author:      Dmitry Bobylev
6
7 #include "GeomAlgoAPI_Pipe.h"
8
9 #include "GeomAlgoAPI_DFLoader.h"
10
11 #include <GeomAPI_Dir.h>
12 #include <GeomAPI_Edge.h>
13 #include <GeomAPI_Lin.h>
14
15 #include <BRep_Tool.hxx>
16 #include <BRepOffsetAPI_MakePipe.hxx>
17 #include <BRepOffsetAPI_MakePipeShell.hxx>
18 #include <BRepBuilderAPI_MakeWire.hxx>
19 #include <Geom_Curve.hxx>
20 #include <Geom_Line.hxx>
21 #include <gp_Lin.hxx>
22 #include <NCollection_List.hxx>
23 #include <TopExp_Explorer.hxx>
24 #include <TopoDS.hxx>
25 #include <TopoDS_Shape.hxx>
26
27 static bool getBase(TopoDS_Shape& theBaseOut,
28                     TopAbs_ShapeEnum& theBaseTypeOut,
29                     const GeomShapePtr theBaseShape);
30 static bool getPath(TopoDS_Wire& thePathOut,
31                     const GeomShapePtr thePathShape);
32 static bool buildPipe(BRepOffsetAPI_MakePipeShell* thePipeBuilder);
33 static ListOfShape getListFromShape(const TopoDS_Shape& theShape);
34
35 //==================================================================================================
36 GeomAlgoAPI_Pipe::GeomAlgoAPI_Pipe(const GeomShapePtr theBaseShape,
37                                    const GeomShapePtr thePathShape)
38 {
39   build(theBaseShape, thePathShape);
40 }
41
42 //==================================================================================================
43 GeomAlgoAPI_Pipe::GeomAlgoAPI_Pipe(const GeomShapePtr theBaseShape,
44                                    const GeomShapePtr thePathShape,
45                                    const GeomShapePtr theBiNormal)
46 {
47   build(theBaseShape, thePathShape, theBiNormal);
48 }
49
50 //==================================================================================================
51 GeomAlgoAPI_Pipe::GeomAlgoAPI_Pipe(const ListOfShape& theBaseShapes,
52                                    const ListOfShape& theLocations,
53                                    const GeomShapePtr thePathShape)
54 {
55   build(theBaseShapes, theLocations, thePathShape);
56 }
57
58 //==================================================================================================
59 void GeomAlgoAPI_Pipe::build(const GeomShapePtr theBaseShape,
60                              const GeomShapePtr thePathShape)
61 {
62   // Getting base shape.
63   if(!theBaseShape.get()) {
64     return;
65   }
66   TopoDS_Shape aBaseShape = theBaseShape->impl<TopoDS_Shape>();
67   if(aBaseShape.IsNull()) {
68     return;
69   }
70   TopAbs_ShapeEnum aBaseShapeType = aBaseShape.ShapeType();
71   if(aBaseShapeType != TopAbs_VERTEX && aBaseShapeType != TopAbs_EDGE &&
72      aBaseShapeType != TopAbs_WIRE && aBaseShapeType != TopAbs_FACE &&
73      aBaseShapeType != TopAbs_SHELL && aBaseShapeType != TopAbs_COMPOUND) {
74     return;
75   }
76
77   // Getting path.
78   TopoDS_Wire aPathWire;
79   if(!getPath(aPathWire, thePathShape)) {
80     return;
81   }
82
83   // Making pipe.
84   BRepOffsetAPI_MakePipe* aPipeBuilder = new BRepOffsetAPI_MakePipe(aPathWire, aBaseShape);
85   if(!aPipeBuilder) {
86     return;
87   }
88   aPipeBuilder->Build();
89
90   // Checking result.
91   if(!aPipeBuilder->IsDone() || aPipeBuilder->Shape().IsNull()) {
92     delete aPipeBuilder;
93     return;
94   }
95   this->initialize(aPipeBuilder);
96
97   // Setting naming.
98   this->setToShapes(getListFromShape(aPipeBuilder->LastShape()));
99   this->setFromShapes(getListFromShape(aPipeBuilder->FirstShape()));
100
101   // Setting result.
102   TopoDS_Shape aResult = aPipeBuilder->Shape();
103   aResult = GeomAlgoAPI_DFLoader::refineResult(aResult);
104   GeomShapePtr aGeomSh(new GeomAPI_Shape());
105   aGeomSh->setImpl(new TopoDS_Shape(aResult));
106   this->setShape(aGeomSh);
107   this->setDone(true);
108 }
109
110 //==================================================================================================
111 void GeomAlgoAPI_Pipe::build(const GeomShapePtr theBaseShape,
112                              const GeomShapePtr thePathShape,
113                              const GeomShapePtr theBiNormal)
114 {
115   // Getting base shape.
116   TopoDS_Shape aBaseShape;
117   TopAbs_ShapeEnum aBaseShapeType;
118   if(!getBase(aBaseShape, aBaseShapeType, theBaseShape)) {
119     return;
120   }
121
122   // Getting path.
123   TopoDS_Wire aPathWire;
124   if(!getPath(aPathWire, thePathShape)) {
125     return;
126   }
127
128   // Getting Bi-Normal.
129   if(!theBiNormal.get()) {
130     return;
131   }
132   TopoDS_Shape aBiNormalShape = theBiNormal->impl<TopoDS_Shape>();
133   if(aBiNormalShape.IsNull() || aBiNormalShape.ShapeType() != TopAbs_EDGE) {
134     return;
135   }
136   TopoDS_Edge aBiNormalEdge = TopoDS::Edge(aBiNormalShape);
137   Standard_Real aFirst, aLast;
138   Handle(Geom_Curve) aBiNormalCurve = BRep_Tool::Curve(aBiNormalEdge, aFirst, aLast);
139   Handle(Geom_Line) aBiNormalLine = Handle(Geom_Line)::DownCast(aBiNormalCurve);
140   if(aBiNormalLine.IsNull()) {
141     return;
142   }
143   gp_Dir aBiNormalDir = aBiNormalLine->Lin().Direction();
144
145   // Making pipe.
146   BRepOffsetAPI_MakePipeShell* aPipeBuilder = new BRepOffsetAPI_MakePipeShell(aPathWire);
147   if(!aPipeBuilder) {
148     return;
149   }
150   aPipeBuilder->Add(aBaseShape);
151   aPipeBuilder->SetMode(aBiNormalDir);
152   if(!buildPipe(aPipeBuilder)) {
153     delete aPipeBuilder;
154     return;
155   }
156   this->initialize(aPipeBuilder);
157
158   // Checking result.
159   if(aBaseShapeType == TopAbs_FACE) {
160     if(aPipeBuilder->MakeSolid() == Standard_False) {
161       return;
162     }
163   }
164   TopoDS_Shape aResult = aPipeBuilder->Shape();
165   if(aResult.IsNull()) {
166     return;
167   }
168
169   // Setting naming.
170   this->setToShapes(getListFromShape(aPipeBuilder->LastShape()));
171   this->setFromShapes(getListFromShape(aPipeBuilder->FirstShape()));
172
173   // Setting result.
174   aResult = GeomAlgoAPI_DFLoader::refineResult(aResult);
175   GeomShapePtr aGeomSh(new GeomAPI_Shape());
176   aGeomSh->setImpl(new TopoDS_Shape(aResult));
177   this->setShape(aGeomSh);
178   this->setDone(true);
179 }
180
181 //==================================================================================================
182 void GeomAlgoAPI_Pipe::build(const ListOfShape& theBaseShapes,
183                              const ListOfShape& theLocations,
184                              const GeomShapePtr thePathShape)
185 {
186   if(theBaseShapes.empty() ||
187      (!theLocations.empty() && theLocations.size() != theBaseShapes.size())) {
188     return;
189   }
190
191   bool aHasLocations = false;
192   if(!theLocations.empty()) {
193     aHasLocations = true;
194   }
195
196   // Getting path.
197   TopoDS_Wire aPathWire;
198   if(!getPath(aPathWire, thePathShape)) {
199     return;
200   }
201
202   // Making pipe.
203   BRepOffsetAPI_MakePipeShell* aPipeBuilder = new BRepOffsetAPI_MakePipeShell(aPathWire);
204   if(!aPipeBuilder) {
205     return;
206   }
207   bool anIsSolidNeeded = false;
208   ListOfShape::const_iterator aBaseIt = theBaseShapes.cbegin();
209   ListOfShape::const_iterator aLocIt = theLocations.cbegin();
210   while(aBaseIt != theBaseShapes.cend()) {
211     GeomShapePtr aBase = *aBaseIt;
212     TopoDS_Shape aBaseShape;
213     TopAbs_ShapeEnum aBaseShapeType;
214     if(!getBase(aBaseShape, aBaseShapeType, aBase)) {
215       delete aPipeBuilder;
216       return;
217     }
218     ++aBaseIt;
219     if(aBaseShapeType == TopAbs_FACE) {
220       anIsSolidNeeded = true;
221     }
222
223     if(aHasLocations) {
224       GeomShapePtr aLocation = *aLocIt;
225       if(!aLocation.get() || aLocation->shapeType() != GeomAPI_Shape::VERTEX) {
226         delete aPipeBuilder;
227         return;
228       }
229       TopoDS_Vertex aLocationVertex = aLocation->impl<TopoDS_Vertex>();
230       ++aLocIt;
231       aPipeBuilder->Add(aBaseShape, aLocationVertex);
232     } else {
233       aPipeBuilder->Add(aBaseShape);
234     }
235   }
236
237   if(aPipeBuilder->IsReady() == Standard_False) {
238     delete aPipeBuilder;
239     return;
240   }
241
242   if(!buildPipe(aPipeBuilder)) {
243     delete aPipeBuilder;
244     return;
245   }
246   this->initialize(aPipeBuilder);
247
248   // Checking result.
249   if(anIsSolidNeeded) {
250     if(aPipeBuilder->MakeSolid() == Standard_False) {
251       return;
252     }
253   }
254   TopoDS_Shape aResult = aPipeBuilder->Shape();
255
256   // Setting naming.
257   GeomShapePtr aFromShape(new GeomAPI_Shape), aToShape(new GeomAPI_Shape);
258   aFromShape->setImpl(new TopoDS_Shape(aPipeBuilder->FirstShape()));
259   aToShape->setImpl(new TopoDS_Shape(aPipeBuilder->LastShape()));
260   this->addFromShape(aFromShape);
261   this->addToShape(aToShape);
262
263   // Setting result.
264   if(aResult.IsNull()) {
265     return;
266   }
267   aResult = GeomAlgoAPI_DFLoader::refineResult(aResult);
268   GeomShapePtr aGeomSh(new GeomAPI_Shape());
269   aGeomSh->setImpl(new TopoDS_Shape(aResult));
270   this->setShape(aGeomSh);
271   this->setDone(true);
272 }
273
274 //==================================================================================================
275 void GeomAlgoAPI_Pipe::generated(const GeomShapePtr theShape,
276                                  ListOfShape& theHistory)
277 {
278   GeomAlgoAPI_MakeShape::generated(theShape, theHistory);
279 }
280
281 // Auxilary functions:
282 //==================================================================================================
283 bool getBase(TopoDS_Shape& theBaseOut,
284              TopAbs_ShapeEnum& theBaseTypeOut,
285              const GeomShapePtr theBaseShape)
286 {
287   if(!theBaseShape.get()) {
288     return false;
289   }
290
291   theBaseOut = theBaseShape->impl<TopoDS_Shape>();
292   if(theBaseOut.IsNull()) {
293     return false;
294   }
295   theBaseTypeOut = theBaseOut.ShapeType();
296   if(theBaseTypeOut == TopAbs_VERTEX) {
297     // Do nothing.
298   } else if(theBaseTypeOut == TopAbs_EDGE) {
299     theBaseOut = BRepBuilderAPI_MakeWire(TopoDS::Edge(theBaseOut)).Shape();
300   } else if(theBaseTypeOut == TopAbs_WIRE) {
301     // Do nothing.
302   } else if(theBaseTypeOut == TopAbs_FACE) {
303     TopExp_Explorer anExp(theBaseOut, TopAbs_WIRE);
304     theBaseOut = anExp.Current();
305   } else {
306     return false;
307   }
308
309   return true;
310 }
311
312 //==================================================================================================
313 bool getPath(TopoDS_Wire& thePathOut,
314              const GeomShapePtr thePathShape)
315 {
316   if(!thePathShape.get()) {
317     return false;
318   }
319
320   TopoDS_Shape aPathShape = thePathShape->impl<TopoDS_Shape>();
321   if(aPathShape.IsNull()) {
322     return false;
323   }
324   TopAbs_ShapeEnum aPathShapeType = aPathShape.ShapeType();
325   if(aPathShapeType == TopAbs_EDGE) {
326     TopoDS_Edge aPathEdge = TopoDS::Edge(aPathShape);
327     thePathOut = BRepBuilderAPI_MakeWire(aPathEdge).Wire();
328   } else if(aPathShapeType == TopAbs_WIRE) {
329     thePathOut = TopoDS::Wire(aPathShape);
330   } else {
331     return false;
332   }
333
334   return true;
335 }
336
337 //==================================================================================================
338 bool buildPipe(BRepOffsetAPI_MakePipeShell* thePipeBuilder)
339 {
340   thePipeBuilder->Build();
341
342   Standard_Boolean isDone = thePipeBuilder->IsDone();
343
344   if (!isDone) {
345     // Try to use Descrete Trihedron mode.
346     thePipeBuilder->SetDiscreteMode();
347     thePipeBuilder->Build();
348     isDone = thePipeBuilder->IsDone();
349   }
350
351   return isDone == Standard_True;
352 }
353
354 //==================================================================================================
355 ListOfShape getListFromShape(const TopoDS_Shape& theShape)
356 {
357   ListOfShape aList;
358
359   TopAbs_ShapeEnum aType = theShape.ShapeType();
360   if(aType == TopAbs_WIRE || aType == TopAbs_SHELL || aType == TopAbs_COMPOUND) {
361     for(TopoDS_Iterator anIt(theShape); anIt.More(); anIt.Next()) {
362       GeomShapePtr aGeomShape(new GeomAPI_Shape());
363       aGeomShape->setImpl(new TopoDS_Shape(anIt.Value()));
364       aList.push_back(aGeomShape);
365     }
366   } else {
367     GeomShapePtr aGeomShape(new GeomAPI_Shape());
368     aGeomShape->setImpl(new TopoDS_Shape(theShape));
369     aList.push_back(aGeomShape);
370   }
371
372   return aList;
373 }