1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
3 // File: GeomAlgoAPI_Pipe.cpp
4 // Created: 16 March 2016
5 // Author: Dmitry Bobylev
7 #include "GeomAlgoAPI_Pipe.h"
9 #include <GeomAPI_Dir.h>
10 #include <GeomAPI_Edge.h>
11 #include <GeomAPI_Lin.h>
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>
20 #include <NCollection_List.hxx>
21 #include <TopExp_Explorer.hxx>
23 #include <TopoDS_Shape.hxx>
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);
32 //=================================================================================================
33 GeomAlgoAPI_Pipe::GeomAlgoAPI_Pipe(const GeomShapePtr theBaseShape,
34 const GeomShapePtr thePathShape)
35 : /*myIsPipeShellUsed(false),*/
36 myBaseShape(theBaseShape),
37 myPathShape(thePathShape)
39 build(theBaseShape, thePathShape);
42 //=================================================================================================
43 GeomAlgoAPI_Pipe::GeomAlgoAPI_Pipe(const GeomShapePtr theBaseShape,
44 const GeomShapePtr thePathShape,
45 const GeomShapePtr theBiNormal)
46 //: myIsPipeShellUsed(true)
48 build(theBaseShape, thePathShape, theBiNormal);
51 //=================================================================================================
52 GeomAlgoAPI_Pipe::GeomAlgoAPI_Pipe(const ListOfShape& theBaseShapes,
53 const ListOfShape& theLocations,
54 const GeomShapePtr thePathShape)
55 //: myIsPipeShellUsed(true)
57 build(theBaseShapes, theLocations, thePathShape);
60 //=================================================================================================
61 void GeomAlgoAPI_Pipe::build(const GeomShapePtr theBaseShape,
62 const GeomShapePtr thePathShape)
64 // Getting base shape.
65 if(!theBaseShape.get()) {
68 TopoDS_Shape aBaseShape = theBaseShape->impl<TopoDS_Shape>();
69 if(aBaseShape.IsNull()) {
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) {
80 TopoDS_Wire aPathWire;
81 if(!getPath(aPathWire, thePathShape)) {
86 BRepOffsetAPI_MakePipe* aPipeBuilder = new BRepOffsetAPI_MakePipe(aPathWire, aBaseShape);
90 aPipeBuilder->Build();
93 if(!aPipeBuilder->IsDone() || aPipeBuilder->Shape().IsNull()) {
97 this->initialize(aPipeBuilder);
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);
107 TopoDS_Shape aResultShape = aPipeBuilder->Shape();
108 GeomShapePtr aResultGeomShape(new GeomAPI_Shape());
109 aResultGeomShape->setImpl(new TopoDS_Shape(aResultShape));
110 this->setShape(aResultGeomShape);
114 //=================================================================================================
115 void GeomAlgoAPI_Pipe::build(const GeomShapePtr theBaseShape,
116 const GeomShapePtr thePathShape,
117 const GeomShapePtr theBiNormal)
119 // Getting base shape.
120 TopoDS_Shape aBaseShape;
121 TopAbs_ShapeEnum aBaseShapeType;
122 if(!getBase(aBaseShape, aBaseShapeType, theBaseShape)) {
127 TopoDS_Wire aPathWire;
128 if(!getPath(aPathWire, thePathShape)) {
132 // Getting Bi-Normal.
133 if(!theBiNormal.get()) {
136 TopoDS_Shape aBiNormalShape = theBiNormal->impl<TopoDS_Shape>();
137 if(aBiNormalShape.IsNull() || aBiNormalShape.ShapeType() != TopAbs_EDGE) {
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()) {
147 gp_Dir aBiNormalDir = aBiNormalLine->Lin().Direction();
150 BRepOffsetAPI_MakePipeShell* aPipeBuilder = new BRepOffsetAPI_MakePipeShell(aPathWire);
154 aPipeBuilder->Add(aBaseShape);
155 aPipeBuilder->SetMode(aBiNormalDir);
156 if(!buildPipe(aPipeBuilder)) {
160 this->initialize(aPipeBuilder);
163 if(aBaseShapeType == TopAbs_FACE) {
164 if(aPipeBuilder->MakeSolid() == Standard_False) {
168 if(aPipeBuilder->Shape().IsNull()) {
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);
180 TopoDS_Shape aResultShape = aPipeBuilder->Shape();
181 GeomShapePtr aResultGeomShape(new GeomAPI_Shape());
182 aResultGeomShape->setImpl(new TopoDS_Shape(aResultShape));
183 this->setShape(aResultGeomShape);
187 //=================================================================================================
188 void GeomAlgoAPI_Pipe::build(const ListOfShape& theBaseShapes,
189 const ListOfShape& theLocations,
190 const GeomShapePtr thePathShape)
192 if(theBaseShapes.empty() || (!theLocations.empty() && theLocations.size() != theBaseShapes.size())) {
196 bool aHasLocations = false;
197 if(!theLocations.empty()) {
198 aHasLocations = true;
202 TopoDS_Wire aPathWire;
203 if(!getPath(aPathWire, thePathShape)) {
208 BRepOffsetAPI_MakePipeShell* aPipeBuilder = new BRepOffsetAPI_MakePipeShell(aPathWire);
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)) {
224 if(aBaseShapeType == TopAbs_FACE) {
225 anIsSolidNeeded = true;
229 GeomShapePtr aLocation = *aLocIt;
230 if(!aLocation.get() || aLocation->shapeType() != GeomAPI_Shape::VERTEX) {
234 TopoDS_Vertex aLocationVertex = aLocation->impl<TopoDS_Vertex>();
236 aPipeBuilder->Add(aBaseShape, aLocationVertex);
238 aPipeBuilder->Add(aBaseShape);
242 if(aPipeBuilder->IsReady() == Standard_False) {
247 if(!buildPipe(aPipeBuilder)) {
251 this->initialize(aPipeBuilder);
254 if(anIsSolidNeeded) {
255 if(aPipeBuilder->MakeSolid() == Standard_False) {
259 if(aPipeBuilder->Shape().IsNull()) {
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);
271 TopoDS_Shape aResultShape = aPipeBuilder->Shape();
272 GeomShapePtr aResultGeomShape(new GeomAPI_Shape());
273 aResultGeomShape->setImpl(new TopoDS_Shape(aResultShape));
274 this->setShape(aResultGeomShape);
278 //=================================================================================================
279 void GeomAlgoAPI_Pipe::generated(const GeomShapePtr theShape,
280 ListOfShape& theHistory)
282 GeomAlgoAPI_MakeShape::generated(theShape, theHistory);
285 // Auxilary functions:
286 //=================================================================================================
287 bool getBase(TopoDS_Shape& theBaseOut,
288 TopAbs_ShapeEnum& theBaseTypeOut,
289 const GeomShapePtr theBaseShape)
291 if(!theBaseShape.get()) {
295 theBaseOut = theBaseShape->impl<TopoDS_Shape>();
296 if(theBaseOut.IsNull()) {
299 theBaseTypeOut = theBaseOut.ShapeType();
300 if(theBaseTypeOut == TopAbs_VERTEX) {
302 } else if(theBaseTypeOut == TopAbs_EDGE) {
303 theBaseOut = BRepBuilderAPI_MakeWire(TopoDS::Edge(theBaseOut)).Shape();
304 } else if(theBaseTypeOut == TopAbs_WIRE) {
306 } else if(theBaseTypeOut == TopAbs_FACE) {
307 TopExp_Explorer anExp(theBaseOut, TopAbs_WIRE);
308 theBaseOut = anExp.Current();
316 //=================================================================================================
317 bool getPath(TopoDS_Wire& thePathOut,
318 const GeomShapePtr thePathShape)
320 if(!thePathShape.get()) {
324 TopoDS_Shape aPathShape = thePathShape->impl<TopoDS_Shape>();
325 if(aPathShape.IsNull()) {
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);
341 //=================================================================================================
342 bool buildPipe(BRepOffsetAPI_MakePipeShell* thePipeBuilder)
344 thePipeBuilder->Build();
346 Standard_Boolean isDone = thePipeBuilder->IsDone();
349 // Try to use Descrete Trihedron mode.
350 thePipeBuilder->SetDiscreteMode();
351 thePipeBuilder->Build();
352 isDone = thePipeBuilder->IsDone();
355 return isDone == Standard_True;