Salome HOME
Removed unused fields from pipe algo
[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 <GeomAPI_Dir.h>
10 #include <GeomAPI_Edge.h>
11 #include <GeomAPI_Lin.h>
12
13 #include <BRep_Tool.hxx>
14 #include <BRepOffsetAPI_MakePipe.hxx>
15 #include <BRepOffsetAPI_MakePipeShell.hxx>
16 #include <BRepBuilderAPI_MakeWire.hxx>
17 #include <Geom_Curve.hxx>
18 #include <Geom_Line.hxx>
19 #include <gp_Lin.hxx>
20 #include <NCollection_List.hxx>
21 #include <TopExp_Explorer.hxx>
22 #include <TopoDS.hxx>
23 #include <TopoDS_Shape.hxx>
24
25 static bool getBase(TopoDS_Shape& theBaseOut,
26                     TopAbs_ShapeEnum& theBaseTypeOut,
27                     const GeomShapePtr theBaseShape);
28 static bool getPath(TopoDS_Wire& thePathOut,
29                     const GeomShapePtr thePathShape);
30 static bool buildPipe(BRepOffsetAPI_MakePipeShell* thePipeBuilder);
31
32 //=================================================================================================
33 GeomAlgoAPI_Pipe::GeomAlgoAPI_Pipe(const GeomShapePtr theBaseShape,
34                                    const GeomShapePtr thePathShape)
35 {
36   build(theBaseShape, thePathShape);
37 }
38
39 //=================================================================================================
40 GeomAlgoAPI_Pipe::GeomAlgoAPI_Pipe(const GeomShapePtr theBaseShape,
41                                    const GeomShapePtr thePathShape,
42                                    const GeomShapePtr theBiNormal)
43 {
44   build(theBaseShape, thePathShape, theBiNormal);
45 }
46
47 //=================================================================================================
48 GeomAlgoAPI_Pipe::GeomAlgoAPI_Pipe(const ListOfShape& theBaseShapes,
49                                    const ListOfShape& theLocations,
50                                    const GeomShapePtr thePathShape)
51 {
52   build(theBaseShapes, theLocations, thePathShape);
53 }
54
55 //=================================================================================================
56 void GeomAlgoAPI_Pipe::build(const GeomShapePtr theBaseShape,
57                              const GeomShapePtr thePathShape)
58 {
59   // Getting base shape.
60   if(!theBaseShape.get()) {
61     return;
62   }
63   TopoDS_Shape aBaseShape = theBaseShape->impl<TopoDS_Shape>();
64   if(aBaseShape.IsNull()) {
65     return;
66   }
67   TopAbs_ShapeEnum aBaseShapeType = aBaseShape.ShapeType();
68   if(aBaseShapeType != TopAbs_VERTEX && aBaseShapeType != TopAbs_EDGE &&
69      aBaseShapeType != TopAbs_WIRE && aBaseShapeType != TopAbs_FACE &&
70      aBaseShapeType != TopAbs_SHELL) {
71     return;
72   }
73
74   // Getting path.
75   TopoDS_Wire aPathWire;
76   if(!getPath(aPathWire, thePathShape)) {
77     return;
78   }
79
80   // Making pipe.
81   BRepOffsetAPI_MakePipe* aPipeBuilder = new BRepOffsetAPI_MakePipe(aPathWire, aBaseShape);
82   if(!aPipeBuilder) {
83     return;
84   }
85   aPipeBuilder->Build();
86
87   // Checking result.
88   if(!aPipeBuilder->IsDone() || aPipeBuilder->Shape().IsNull()) {
89     delete aPipeBuilder;
90     return;
91   }
92   this->initialize(aPipeBuilder);
93
94   // Setting naming.
95   GeomShapePtr aFromShape(new GeomAPI_Shape), aToShape(new GeomAPI_Shape);
96   aFromShape->setImpl(new TopoDS_Shape(aPipeBuilder->FirstShape()));
97   aToShape->setImpl(new TopoDS_Shape(aPipeBuilder->LastShape()));
98   this->addFromShape(aFromShape);
99   this->addToShape(aToShape);
100
101   // Setting result.
102   TopoDS_Shape aResultShape = aPipeBuilder->Shape();
103   GeomShapePtr aResultGeomShape(new GeomAPI_Shape());
104   aResultGeomShape->setImpl(new TopoDS_Shape(aResultShape));
105   this->setShape(aResultGeomShape);
106   this->setDone(true);
107 }
108
109 //=================================================================================================
110 void GeomAlgoAPI_Pipe::build(const GeomShapePtr theBaseShape,
111                              const GeomShapePtr thePathShape,
112                              const GeomShapePtr theBiNormal)
113 {
114   // Getting base shape.
115   TopoDS_Shape aBaseShape;
116   TopAbs_ShapeEnum aBaseShapeType;
117   if(!getBase(aBaseShape, aBaseShapeType, theBaseShape)) {
118     return;
119   }
120
121   // Getting path.
122   TopoDS_Wire aPathWire;
123   if(!getPath(aPathWire, thePathShape)) {
124     return;
125   }
126
127   // Getting Bi-Normal.
128   if(!theBiNormal.get()) {
129     return;
130   }
131   TopoDS_Shape aBiNormalShape = theBiNormal->impl<TopoDS_Shape>();
132   if(aBiNormalShape.IsNull() || aBiNormalShape.ShapeType() != TopAbs_EDGE) {
133     return;
134   }
135   TopoDS_Edge aBiNormalEdge = TopoDS::Edge(aBiNormalShape);
136   Standard_Real aFirst, aLast;
137   Handle(Geom_Curve) aBiNormalCurve = BRep_Tool::Curve(aBiNormalEdge, aFirst, aLast);
138   Handle(Geom_Line) aBiNormalLine = Handle(Geom_Line)::DownCast(aBiNormalCurve);
139   if(aBiNormalLine.IsNull()) {
140     return;
141   }
142   gp_Dir aBiNormalDir = aBiNormalLine->Lin().Direction();
143
144   // Making pipe.
145   BRepOffsetAPI_MakePipeShell* aPipeBuilder = new BRepOffsetAPI_MakePipeShell(aPathWire);
146   if(!aPipeBuilder) {
147     return;
148   }
149   aPipeBuilder->Add(aBaseShape);
150   aPipeBuilder->SetMode(aBiNormalDir);
151   if(!buildPipe(aPipeBuilder)) {
152     delete aPipeBuilder;
153     return;
154   }
155   this->initialize(aPipeBuilder);
156
157   // Checking result.
158   if(aBaseShapeType == TopAbs_FACE) {
159     if(aPipeBuilder->MakeSolid() == Standard_False) {
160       return;
161     }
162   }
163   if(aPipeBuilder->Shape().IsNull()) {
164     return;
165   }
166
167   // Setting naming.
168   GeomShapePtr aFromShape(new GeomAPI_Shape), aToShape(new GeomAPI_Shape);
169   aFromShape->setImpl(new TopoDS_Shape(aPipeBuilder->FirstShape()));
170   aToShape->setImpl(new TopoDS_Shape(aPipeBuilder->LastShape()));
171   this->addFromShape(aFromShape);
172   this->addToShape(aToShape);
173
174   // Setting result.
175   TopoDS_Shape aResultShape = aPipeBuilder->Shape();
176   GeomShapePtr aResultGeomShape(new GeomAPI_Shape());
177   aResultGeomShape->setImpl(new TopoDS_Shape(aResultShape));
178   this->setShape(aResultGeomShape);
179   this->setDone(true);
180 }
181
182 //=================================================================================================
183 void GeomAlgoAPI_Pipe::build(const ListOfShape& theBaseShapes,
184                              const ListOfShape& theLocations,
185                              const GeomShapePtr thePathShape)
186 {
187   if(theBaseShapes.empty() || (!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   if(aPipeBuilder->Shape().IsNull()) {
255     return;
256   }
257
258   // Setting naming.
259   GeomShapePtr aFromShape(new GeomAPI_Shape), aToShape(new GeomAPI_Shape);
260   aFromShape->setImpl(new TopoDS_Shape(aPipeBuilder->FirstShape()));
261   aToShape->setImpl(new TopoDS_Shape(aPipeBuilder->LastShape()));
262   this->addFromShape(aFromShape);
263   this->addToShape(aToShape);
264
265   // Setting result.
266   TopoDS_Shape aResultShape = aPipeBuilder->Shape();
267   GeomShapePtr aResultGeomShape(new GeomAPI_Shape());
268   aResultGeomShape->setImpl(new TopoDS_Shape(aResultShape));
269   this->setShape(aResultGeomShape);
270   this->setDone(true);
271 }
272
273 //=================================================================================================
274 void GeomAlgoAPI_Pipe::generated(const GeomShapePtr theShape,
275                                  ListOfShape& theHistory)
276 {
277   GeomAlgoAPI_MakeShape::generated(theShape, theHistory);
278 }
279
280 // Auxilary functions:
281 //=================================================================================================
282 bool getBase(TopoDS_Shape& theBaseOut,
283              TopAbs_ShapeEnum& theBaseTypeOut,
284              const GeomShapePtr theBaseShape)
285 {
286   if(!theBaseShape.get()) {
287     return false;
288   }
289
290   theBaseOut = theBaseShape->impl<TopoDS_Shape>();
291   if(theBaseOut.IsNull()) {
292     return false;
293   }
294   theBaseTypeOut = theBaseOut.ShapeType();
295   if(theBaseTypeOut == TopAbs_VERTEX) {
296     // Do nothing.
297   } else if(theBaseTypeOut == TopAbs_EDGE) {
298     theBaseOut = BRepBuilderAPI_MakeWire(TopoDS::Edge(theBaseOut)).Shape();
299   } else if(theBaseTypeOut == TopAbs_WIRE) {
300     // Do nothing.
301   } else if(theBaseTypeOut == TopAbs_FACE) {
302     TopExp_Explorer anExp(theBaseOut, TopAbs_WIRE);
303     theBaseOut = anExp.Current();
304   } else {
305     return false;
306   }
307
308   return true;
309 }
310
311 //=================================================================================================
312 bool getPath(TopoDS_Wire& thePathOut,
313              const GeomShapePtr thePathShape)
314 {
315   if(!thePathShape.get()) {
316     return false;
317   }
318
319   TopoDS_Shape aPathShape = thePathShape->impl<TopoDS_Shape>();
320   if(aPathShape.IsNull()) {
321     return false;
322   }
323   TopAbs_ShapeEnum aPathShapeType = aPathShape.ShapeType();
324   if(aPathShapeType == TopAbs_EDGE) {
325     TopoDS_Edge aPathEdge = TopoDS::Edge(aPathShape);
326     thePathOut = BRepBuilderAPI_MakeWire(aPathEdge).Wire();
327   } else if(aPathShapeType == TopAbs_WIRE) {
328     thePathOut = TopoDS::Wire(aPathShape);
329   } else {
330     return false;
331   }
332
333   return true;
334 }
335
336 //=================================================================================================
337 bool buildPipe(BRepOffsetAPI_MakePipeShell* thePipeBuilder)
338 {
339   thePipeBuilder->Build();
340
341   Standard_Boolean isDone = thePipeBuilder->IsDone();
342
343   if (!isDone) {
344     // Try to use Descrete Trihedron mode.
345     thePipeBuilder->SetDiscreteMode();
346     thePipeBuilder->Build();
347     isDone = thePipeBuilder->IsDone();
348   }
349
350   return isDone == Standard_True;
351 }