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);
33 static ListOfShape getListFromShape(const TopoDS_Shape& theShape);
35 //==================================================================================================
36 GeomAlgoAPI_Pipe::GeomAlgoAPI_Pipe(const GeomShapePtr theBaseShape,
37 const GeomShapePtr thePathShape)
39 build(theBaseShape, thePathShape);
42 //==================================================================================================
43 GeomAlgoAPI_Pipe::GeomAlgoAPI_Pipe(const GeomShapePtr theBaseShape,
44 const GeomShapePtr thePathShape,
45 const GeomShapePtr theBiNormal)
47 build(theBaseShape, thePathShape, theBiNormal);
50 //==================================================================================================
51 GeomAlgoAPI_Pipe::GeomAlgoAPI_Pipe(const ListOfShape& theBaseShapes,
52 const ListOfShape& theLocations,
53 const GeomShapePtr thePathShape)
55 build(theBaseShapes, theLocations, thePathShape);
58 //==================================================================================================
59 void GeomAlgoAPI_Pipe::build(const GeomShapePtr theBaseShape,
60 const GeomShapePtr thePathShape)
62 // Getting base shape.
63 if(!theBaseShape.get()) {
66 TopoDS_Shape aBaseShape = theBaseShape->impl<TopoDS_Shape>();
67 if(aBaseShape.IsNull()) {
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) {
78 TopoDS_Wire aPathWire;
79 if(!getPath(aPathWire, thePathShape)) {
84 BRepOffsetAPI_MakePipe* aPipeBuilder = new BRepOffsetAPI_MakePipe(aPathWire, aBaseShape);
88 aPipeBuilder->Build();
91 if(!aPipeBuilder->IsDone() || aPipeBuilder->Shape().IsNull()) {
95 this->initialize(aPipeBuilder);
98 this->setToShapes(getListFromShape(aPipeBuilder->LastShape()));
99 this->setFromShapes(getListFromShape(aPipeBuilder->FirstShape()));
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);
110 //==================================================================================================
111 void GeomAlgoAPI_Pipe::build(const GeomShapePtr theBaseShape,
112 const GeomShapePtr thePathShape,
113 const GeomShapePtr theBiNormal)
115 // Getting base shape.
116 TopoDS_Shape aBaseShape;
117 TopAbs_ShapeEnum aBaseShapeType;
118 if(!getBase(aBaseShape, aBaseShapeType, theBaseShape)) {
123 TopoDS_Wire aPathWire;
124 if(!getPath(aPathWire, thePathShape)) {
128 // Getting Bi-Normal.
129 if(!theBiNormal.get()) {
132 TopoDS_Shape aBiNormalShape = theBiNormal->impl<TopoDS_Shape>();
133 if(aBiNormalShape.IsNull() || aBiNormalShape.ShapeType() != TopAbs_EDGE) {
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()) {
143 gp_Dir aBiNormalDir = aBiNormalLine->Lin().Direction();
146 BRepOffsetAPI_MakePipeShell* aPipeBuilder = new BRepOffsetAPI_MakePipeShell(aPathWire);
150 aPipeBuilder->Add(aBaseShape);
151 aPipeBuilder->SetMode(aBiNormalDir);
152 if(!buildPipe(aPipeBuilder)) {
156 this->initialize(aPipeBuilder);
159 if(aBaseShapeType == TopAbs_FACE) {
160 if(aPipeBuilder->MakeSolid() == Standard_False) {
164 TopoDS_Shape aResult = aPipeBuilder->Shape();
165 if(aResult.IsNull()) {
170 this->setToShapes(getListFromShape(aPipeBuilder->LastShape()));
171 this->setFromShapes(getListFromShape(aPipeBuilder->FirstShape()));
174 aResult = GeomAlgoAPI_DFLoader::refineResult(aResult);
175 GeomShapePtr aGeomSh(new GeomAPI_Shape());
176 aGeomSh->setImpl(new TopoDS_Shape(aResult));
177 this->setShape(aGeomSh);
181 //==================================================================================================
182 void GeomAlgoAPI_Pipe::build(const ListOfShape& theBaseShapes,
183 const ListOfShape& theLocations,
184 const GeomShapePtr thePathShape)
186 if(theBaseShapes.empty() ||
187 (!theLocations.empty() && theLocations.size() != theBaseShapes.size())) {
191 bool aHasLocations = false;
192 if(!theLocations.empty()) {
193 aHasLocations = true;
197 TopoDS_Wire aPathWire;
198 if(!getPath(aPathWire, thePathShape)) {
203 BRepOffsetAPI_MakePipeShell* aPipeBuilder = new BRepOffsetAPI_MakePipeShell(aPathWire);
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)) {
219 if(aBaseShapeType == TopAbs_FACE) {
220 anIsSolidNeeded = true;
224 GeomShapePtr aLocation = *aLocIt;
225 if(!aLocation.get() || aLocation->shapeType() != GeomAPI_Shape::VERTEX) {
229 TopoDS_Vertex aLocationVertex = aLocation->impl<TopoDS_Vertex>();
231 aPipeBuilder->Add(aBaseShape, aLocationVertex);
233 aPipeBuilder->Add(aBaseShape);
237 if(aPipeBuilder->IsReady() == Standard_False) {
242 if(!buildPipe(aPipeBuilder)) {
246 this->initialize(aPipeBuilder);
249 if(anIsSolidNeeded) {
250 if(aPipeBuilder->MakeSolid() == Standard_False) {
254 TopoDS_Shape aResult = aPipeBuilder->Shape();
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);
264 if(aResult.IsNull()) {
267 aResult = GeomAlgoAPI_DFLoader::refineResult(aResult);
268 GeomShapePtr aGeomSh(new GeomAPI_Shape());
269 aGeomSh->setImpl(new TopoDS_Shape(aResult));
270 this->setShape(aGeomSh);
274 //==================================================================================================
275 void GeomAlgoAPI_Pipe::generated(const GeomShapePtr theShape,
276 ListOfShape& theHistory)
278 GeomAlgoAPI_MakeShape::generated(theShape, theHistory);
281 // Auxilary functions:
282 //==================================================================================================
283 bool getBase(TopoDS_Shape& theBaseOut,
284 TopAbs_ShapeEnum& theBaseTypeOut,
285 const GeomShapePtr theBaseShape)
287 if(!theBaseShape.get()) {
291 theBaseOut = theBaseShape->impl<TopoDS_Shape>();
292 if(theBaseOut.IsNull()) {
295 theBaseTypeOut = theBaseOut.ShapeType();
296 if(theBaseTypeOut == TopAbs_VERTEX) {
298 } else if(theBaseTypeOut == TopAbs_EDGE) {
299 theBaseOut = BRepBuilderAPI_MakeWire(TopoDS::Edge(theBaseOut)).Shape();
300 } else if(theBaseTypeOut == TopAbs_WIRE) {
302 } else if(theBaseTypeOut == TopAbs_FACE) {
303 TopExp_Explorer anExp(theBaseOut, TopAbs_WIRE);
304 theBaseOut = anExp.Current();
312 //==================================================================================================
313 bool getPath(TopoDS_Wire& thePathOut,
314 const GeomShapePtr thePathShape)
316 if(!thePathShape.get()) {
320 TopoDS_Shape aPathShape = thePathShape->impl<TopoDS_Shape>();
321 if(aPathShape.IsNull()) {
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);
337 //==================================================================================================
338 bool buildPipe(BRepOffsetAPI_MakePipeShell* thePipeBuilder)
340 thePipeBuilder->Build();
342 Standard_Boolean isDone = thePipeBuilder->IsDone();
345 // Try to use Descrete Trihedron mode.
346 thePipeBuilder->SetDiscreteMode();
347 thePipeBuilder->Build();
348 isDone = thePipeBuilder->IsDone();
351 return isDone == Standard_True;
354 //==================================================================================================
355 ListOfShape getListFromShape(const TopoDS_Shape& theShape)
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);
367 GeomShapePtr aGeomShape(new GeomAPI_Shape());
368 aGeomShape->setImpl(new TopoDS_Shape(theShape));
369 aList.push_back(aGeomShape);