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 "GeomAlgoAPI_DFLoader.h"
11 #include <GeomAPI_Dir.h>
12 #include <GeomAPI_Edge.h>
13 #include <GeomAPI_Lin.h>
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>
22 #include <NCollection_List.hxx>
23 #include <TopExp_Explorer.hxx>
25 #include <TopoDS_Shape.hxx>
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);
34 //=================================================================================================
35 GeomAlgoAPI_Pipe::GeomAlgoAPI_Pipe(const GeomShapePtr theBaseShape,
36 const GeomShapePtr thePathShape)
38 build(theBaseShape, thePathShape);
41 //=================================================================================================
42 GeomAlgoAPI_Pipe::GeomAlgoAPI_Pipe(const GeomShapePtr theBaseShape,
43 const GeomShapePtr thePathShape,
44 const GeomShapePtr theBiNormal)
46 build(theBaseShape, thePathShape, theBiNormal);
49 //=================================================================================================
50 GeomAlgoAPI_Pipe::GeomAlgoAPI_Pipe(const ListOfShape& theBaseShapes,
51 const ListOfShape& theLocations,
52 const GeomShapePtr thePathShape)
54 build(theBaseShapes, theLocations, thePathShape);
57 //=================================================================================================
58 void GeomAlgoAPI_Pipe::build(const GeomShapePtr theBaseShape,
59 const GeomShapePtr thePathShape)
61 // Getting base shape.
62 if(!theBaseShape.get()) {
65 TopoDS_Shape aBaseShape = theBaseShape->impl<TopoDS_Shape>();
66 if(aBaseShape.IsNull()) {
69 TopAbs_ShapeEnum aBaseShapeType = aBaseShape.ShapeType();
70 if(aBaseShapeType != TopAbs_VERTEX && aBaseShapeType != TopAbs_EDGE &&
71 aBaseShapeType != TopAbs_WIRE && aBaseShapeType != TopAbs_FACE &&
72 aBaseShapeType != TopAbs_SHELL) {
77 TopoDS_Wire aPathWire;
78 if(!getPath(aPathWire, thePathShape)) {
83 BRepOffsetAPI_MakePipe* aPipeBuilder = new BRepOffsetAPI_MakePipe(aPathWire, aBaseShape);
87 aPipeBuilder->Build();
90 if(!aPipeBuilder->IsDone() || aPipeBuilder->Shape().IsNull()) {
94 this->initialize(aPipeBuilder);
97 GeomShapePtr aFromShape(new GeomAPI_Shape), aToShape(new GeomAPI_Shape);
98 aFromShape->setImpl(new TopoDS_Shape(aPipeBuilder->FirstShape()));
99 aToShape->setImpl(new TopoDS_Shape(aPipeBuilder->LastShape()));
100 this->addFromShape(aFromShape);
101 this->addToShape(aToShape);
104 TopoDS_Shape aResult = aPipeBuilder->Shape();
105 aResult = GeomAlgoAPI_DFLoader::refineResult(aResult);
106 GeomShapePtr aGeomSh(new GeomAPI_Shape());
107 aGeomSh->setImpl(new TopoDS_Shape(aResult));
108 this->setShape(aGeomSh);
112 //=================================================================================================
113 void GeomAlgoAPI_Pipe::build(const GeomShapePtr theBaseShape,
114 const GeomShapePtr thePathShape,
115 const GeomShapePtr theBiNormal)
117 // Getting base shape.
118 TopoDS_Shape aBaseShape;
119 TopAbs_ShapeEnum aBaseShapeType;
120 if(!getBase(aBaseShape, aBaseShapeType, theBaseShape)) {
125 TopoDS_Wire aPathWire;
126 if(!getPath(aPathWire, thePathShape)) {
130 // Getting Bi-Normal.
131 if(!theBiNormal.get()) {
134 TopoDS_Shape aBiNormalShape = theBiNormal->impl<TopoDS_Shape>();
135 if(aBiNormalShape.IsNull() || aBiNormalShape.ShapeType() != TopAbs_EDGE) {
138 TopoDS_Edge aBiNormalEdge = TopoDS::Edge(aBiNormalShape);
139 Standard_Real aFirst, aLast;
140 Handle(Geom_Curve) aBiNormalCurve = BRep_Tool::Curve(aBiNormalEdge, aFirst, aLast);
141 Handle(Geom_Line) aBiNormalLine = Handle(Geom_Line)::DownCast(aBiNormalCurve);
142 if(aBiNormalLine.IsNull()) {
145 gp_Dir aBiNormalDir = aBiNormalLine->Lin().Direction();
148 BRepOffsetAPI_MakePipeShell* aPipeBuilder = new BRepOffsetAPI_MakePipeShell(aPathWire);
152 aPipeBuilder->Add(aBaseShape);
153 aPipeBuilder->SetMode(aBiNormalDir);
154 if(!buildPipe(aPipeBuilder)) {
158 this->initialize(aPipeBuilder);
161 if(aBaseShapeType == TopAbs_FACE) {
162 if(aPipeBuilder->MakeSolid() == Standard_False) {
166 TopoDS_Shape aResult = aPipeBuilder->Shape();
169 GeomShapePtr aFromShape(new GeomAPI_Shape), aToShape(new GeomAPI_Shape);
170 aFromShape->setImpl(new TopoDS_Shape(aPipeBuilder->FirstShape()));
171 aToShape->setImpl(new TopoDS_Shape(aPipeBuilder->LastShape()));
172 this->addFromShape(aFromShape);
173 this->addToShape(aToShape);
176 if(aResult.IsNull()) {
179 aResult = GeomAlgoAPI_DFLoader::refineResult(aResult);
180 GeomShapePtr aGeomSh(new GeomAPI_Shape());
181 aGeomSh->setImpl(new TopoDS_Shape(aResult));
182 this->setShape(aGeomSh);
186 //=================================================================================================
187 void GeomAlgoAPI_Pipe::build(const ListOfShape& theBaseShapes,
188 const ListOfShape& theLocations,
189 const GeomShapePtr thePathShape)
191 if(theBaseShapes.empty() || (!theLocations.empty() && theLocations.size() != theBaseShapes.size())) {
195 bool aHasLocations = false;
196 if(!theLocations.empty()) {
197 aHasLocations = true;
201 TopoDS_Wire aPathWire;
202 if(!getPath(aPathWire, thePathShape)) {
207 BRepOffsetAPI_MakePipeShell* aPipeBuilder = new BRepOffsetAPI_MakePipeShell(aPathWire);
211 bool anIsSolidNeeded = false;
212 ListOfShape::const_iterator aBaseIt = theBaseShapes.cbegin();
213 ListOfShape::const_iterator aLocIt = theLocations.cbegin();
214 while(aBaseIt != theBaseShapes.cend()) {
215 GeomShapePtr aBase = *aBaseIt;
216 TopoDS_Shape aBaseShape;
217 TopAbs_ShapeEnum aBaseShapeType;
218 if(!getBase(aBaseShape, aBaseShapeType, aBase)) {
223 if(aBaseShapeType == TopAbs_FACE) {
224 anIsSolidNeeded = true;
228 GeomShapePtr aLocation = *aLocIt;
229 if(!aLocation.get() || aLocation->shapeType() != GeomAPI_Shape::VERTEX) {
233 TopoDS_Vertex aLocationVertex = aLocation->impl<TopoDS_Vertex>();
235 aPipeBuilder->Add(aBaseShape, aLocationVertex);
237 aPipeBuilder->Add(aBaseShape);
241 if(aPipeBuilder->IsReady() == Standard_False) {
246 if(!buildPipe(aPipeBuilder)) {
250 this->initialize(aPipeBuilder);
253 if(anIsSolidNeeded) {
254 if(aPipeBuilder->MakeSolid() == Standard_False) {
258 TopoDS_Shape aResult = aPipeBuilder->Shape();
261 GeomShapePtr aFromShape(new GeomAPI_Shape), aToShape(new GeomAPI_Shape);
262 aFromShape->setImpl(new TopoDS_Shape(aPipeBuilder->FirstShape()));
263 aToShape->setImpl(new TopoDS_Shape(aPipeBuilder->LastShape()));
264 this->addFromShape(aFromShape);
265 this->addToShape(aToShape);
268 if(aResult.IsNull()) {
271 aResult = GeomAlgoAPI_DFLoader::refineResult(aResult);
272 GeomShapePtr aGeomSh(new GeomAPI_Shape());
273 aGeomSh->setImpl(new TopoDS_Shape(aResult));
274 this->setShape(aGeomSh);
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;