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() || (!theLocations.empty() && theLocations.size() != theBaseShapes.size())) {
190 bool aHasLocations = false;
191 if(!theLocations.empty()) {
192 aHasLocations = true;
196 TopoDS_Wire aPathWire;
197 if(!getPath(aPathWire, thePathShape)) {
202 BRepOffsetAPI_MakePipeShell* aPipeBuilder = new BRepOffsetAPI_MakePipeShell(aPathWire);
206 bool anIsSolidNeeded = false;
207 ListOfShape::const_iterator aBaseIt = theBaseShapes.cbegin();
208 ListOfShape::const_iterator aLocIt = theLocations.cbegin();
209 while(aBaseIt != theBaseShapes.cend()) {
210 GeomShapePtr aBase = *aBaseIt;
211 TopoDS_Shape aBaseShape;
212 TopAbs_ShapeEnum aBaseShapeType;
213 if(!getBase(aBaseShape, aBaseShapeType, aBase)) {
218 if(aBaseShapeType == TopAbs_FACE) {
219 anIsSolidNeeded = true;
223 GeomShapePtr aLocation = *aLocIt;
224 if(!aLocation.get() || aLocation->shapeType() != GeomAPI_Shape::VERTEX) {
228 TopoDS_Vertex aLocationVertex = aLocation->impl<TopoDS_Vertex>();
230 aPipeBuilder->Add(aBaseShape, aLocationVertex);
232 aPipeBuilder->Add(aBaseShape);
236 if(aPipeBuilder->IsReady() == Standard_False) {
241 if(!buildPipe(aPipeBuilder)) {
245 this->initialize(aPipeBuilder);
248 if(anIsSolidNeeded) {
249 if(aPipeBuilder->MakeSolid() == Standard_False) {
253 TopoDS_Shape aResult = aPipeBuilder->Shape();
256 GeomShapePtr aFromShape(new GeomAPI_Shape), aToShape(new GeomAPI_Shape);
257 aFromShape->setImpl(new TopoDS_Shape(aPipeBuilder->FirstShape()));
258 aToShape->setImpl(new TopoDS_Shape(aPipeBuilder->LastShape()));
259 this->addFromShape(aFromShape);
260 this->addToShape(aToShape);
263 if(aResult.IsNull()) {
266 aResult = GeomAlgoAPI_DFLoader::refineResult(aResult);
267 GeomShapePtr aGeomSh(new GeomAPI_Shape());
268 aGeomSh->setImpl(new TopoDS_Shape(aResult));
269 this->setShape(aGeomSh);
273 //==================================================================================================
274 void GeomAlgoAPI_Pipe::generated(const GeomShapePtr theShape,
275 ListOfShape& theHistory)
277 GeomAlgoAPI_MakeShape::generated(theShape, theHistory);
280 // Auxilary functions:
281 //==================================================================================================
282 bool getBase(TopoDS_Shape& theBaseOut,
283 TopAbs_ShapeEnum& theBaseTypeOut,
284 const GeomShapePtr theBaseShape)
286 if(!theBaseShape.get()) {
290 theBaseOut = theBaseShape->impl<TopoDS_Shape>();
291 if(theBaseOut.IsNull()) {
294 theBaseTypeOut = theBaseOut.ShapeType();
295 if(theBaseTypeOut == TopAbs_VERTEX) {
297 } else if(theBaseTypeOut == TopAbs_EDGE) {
298 theBaseOut = BRepBuilderAPI_MakeWire(TopoDS::Edge(theBaseOut)).Shape();
299 } else if(theBaseTypeOut == TopAbs_WIRE) {
301 } else if(theBaseTypeOut == TopAbs_FACE) {
302 TopExp_Explorer anExp(theBaseOut, TopAbs_WIRE);
303 theBaseOut = anExp.Current();
311 //==================================================================================================
312 bool getPath(TopoDS_Wire& thePathOut,
313 const GeomShapePtr thePathShape)
315 if(!thePathShape.get()) {
319 TopoDS_Shape aPathShape = thePathShape->impl<TopoDS_Shape>();
320 if(aPathShape.IsNull()) {
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);
336 //==================================================================================================
337 bool buildPipe(BRepOffsetAPI_MakePipeShell* thePipeBuilder)
339 thePipeBuilder->Build();
341 Standard_Boolean isDone = thePipeBuilder->IsDone();
344 // Try to use Descrete Trihedron mode.
345 thePipeBuilder->SetDiscreteMode();
346 thePipeBuilder->Build();
347 isDone = thePipeBuilder->IsDone();
350 return isDone == Standard_True;
353 //==================================================================================================
354 ListOfShape getListFromShape(const TopoDS_Shape& theShape)
358 TopAbs_ShapeEnum aType = theShape.ShapeType();
359 if(aType == TopAbs_WIRE || aType == TopAbs_SHELL || aType == TopAbs_COMPOUND) {
360 for(TopoDS_Iterator anIt(theShape); anIt.More(); anIt.Next()) {
361 GeomShapePtr aGeomShape(new GeomAPI_Shape());
362 aGeomShape->setImpl(new TopoDS_Shape(anIt.Value()));
363 aList.push_back(aGeomShape);
366 GeomShapePtr aGeomShape(new GeomAPI_Shape());
367 aGeomShape->setImpl(new TopoDS_Shape(theShape));
368 aList.push_back(aGeomShape);