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)
36 build(theBaseShape, thePathShape);
39 //=================================================================================================
40 GeomAlgoAPI_Pipe::GeomAlgoAPI_Pipe(const GeomShapePtr theBaseShape,
41 const GeomShapePtr thePathShape,
42 const GeomShapePtr theBiNormal)
44 build(theBaseShape, thePathShape, theBiNormal);
47 //=================================================================================================
48 GeomAlgoAPI_Pipe::GeomAlgoAPI_Pipe(const ListOfShape& theBaseShapes,
49 const ListOfShape& theLocations,
50 const GeomShapePtr thePathShape)
52 build(theBaseShapes, theLocations, thePathShape);
55 //=================================================================================================
56 void GeomAlgoAPI_Pipe::build(const GeomShapePtr theBaseShape,
57 const GeomShapePtr thePathShape)
59 // Getting base shape.
60 if(!theBaseShape.get()) {
63 TopoDS_Shape aBaseShape = theBaseShape->impl<TopoDS_Shape>();
64 if(aBaseShape.IsNull()) {
67 TopAbs_ShapeEnum aBaseShapeType = aBaseShape.ShapeType();
68 if(aBaseShapeType != TopAbs_VERTEX && aBaseShapeType != TopAbs_EDGE &&
69 aBaseShapeType != TopAbs_WIRE && aBaseShapeType != TopAbs_FACE &&
70 aBaseShapeType != TopAbs_SHELL) {
75 TopoDS_Wire aPathWire;
76 if(!getPath(aPathWire, thePathShape)) {
81 BRepOffsetAPI_MakePipe* aPipeBuilder = new BRepOffsetAPI_MakePipe(aPathWire, aBaseShape);
85 aPipeBuilder->Build();
88 if(!aPipeBuilder->IsDone() || aPipeBuilder->Shape().IsNull()) {
92 this->initialize(aPipeBuilder);
95 GeomShapePtr aFromShape(new GeomAPI_Shape), aToShape(new GeomAPI_Shape);
96 aFromShape->setImpl(new TopoDS_Shape(aPipeBuilder->FirstShape()));
97 aToShape->setImpl(new TopoDS_Shape(aPipeBuilder->LastShape()));
98 this->addFromShape(aFromShape);
99 this->addToShape(aToShape);
102 TopoDS_Shape aResultShape = aPipeBuilder->Shape();
103 GeomShapePtr aResultGeomShape(new GeomAPI_Shape());
104 aResultGeomShape->setImpl(new TopoDS_Shape(aResultShape));
105 this->setShape(aResultGeomShape);
109 //=================================================================================================
110 void GeomAlgoAPI_Pipe::build(const GeomShapePtr theBaseShape,
111 const GeomShapePtr thePathShape,
112 const GeomShapePtr theBiNormal)
114 // Getting base shape.
115 TopoDS_Shape aBaseShape;
116 TopAbs_ShapeEnum aBaseShapeType;
117 if(!getBase(aBaseShape, aBaseShapeType, theBaseShape)) {
122 TopoDS_Wire aPathWire;
123 if(!getPath(aPathWire, thePathShape)) {
127 // Getting Bi-Normal.
128 if(!theBiNormal.get()) {
131 TopoDS_Shape aBiNormalShape = theBiNormal->impl<TopoDS_Shape>();
132 if(aBiNormalShape.IsNull() || aBiNormalShape.ShapeType() != TopAbs_EDGE) {
135 TopoDS_Edge aBiNormalEdge = TopoDS::Edge(aBiNormalShape);
136 Standard_Real aFirst, aLast;
137 Handle(Geom_Curve) aBiNormalCurve = BRep_Tool::Curve(aBiNormalEdge, aFirst, aLast);
138 Handle(Geom_Line) aBiNormalLine = Handle(Geom_Line)::DownCast(aBiNormalCurve);
139 if(aBiNormalLine.IsNull()) {
142 gp_Dir aBiNormalDir = aBiNormalLine->Lin().Direction();
145 BRepOffsetAPI_MakePipeShell* aPipeBuilder = new BRepOffsetAPI_MakePipeShell(aPathWire);
149 aPipeBuilder->Add(aBaseShape);
150 aPipeBuilder->SetMode(aBiNormalDir);
151 if(!buildPipe(aPipeBuilder)) {
155 this->initialize(aPipeBuilder);
158 if(aBaseShapeType == TopAbs_FACE) {
159 if(aPipeBuilder->MakeSolid() == Standard_False) {
163 if(aPipeBuilder->Shape().IsNull()) {
168 GeomShapePtr aFromShape(new GeomAPI_Shape), aToShape(new GeomAPI_Shape);
169 aFromShape->setImpl(new TopoDS_Shape(aPipeBuilder->FirstShape()));
170 aToShape->setImpl(new TopoDS_Shape(aPipeBuilder->LastShape()));
171 this->addFromShape(aFromShape);
172 this->addToShape(aToShape);
175 TopoDS_Shape aResultShape = aPipeBuilder->Shape();
176 GeomShapePtr aResultGeomShape(new GeomAPI_Shape());
177 aResultGeomShape->setImpl(new TopoDS_Shape(aResultShape));
178 this->setShape(aResultGeomShape);
182 //=================================================================================================
183 void GeomAlgoAPI_Pipe::build(const ListOfShape& theBaseShapes,
184 const ListOfShape& theLocations,
185 const GeomShapePtr thePathShape)
187 if(theBaseShapes.empty() || (!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 if(aPipeBuilder->Shape().IsNull()) {
259 GeomShapePtr aFromShape(new GeomAPI_Shape), aToShape(new GeomAPI_Shape);
260 aFromShape->setImpl(new TopoDS_Shape(aPipeBuilder->FirstShape()));
261 aToShape->setImpl(new TopoDS_Shape(aPipeBuilder->LastShape()));
262 this->addFromShape(aFromShape);
263 this->addToShape(aToShape);
266 TopoDS_Shape aResultShape = aPipeBuilder->Shape();
267 GeomShapePtr aResultGeomShape(new GeomAPI_Shape());
268 aResultGeomShape->setImpl(new TopoDS_Shape(aResultShape));
269 this->setShape(aResultGeomShape);
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;