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