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 std::shared_ptr<GeomAPI_Shape> theBaseShape);
28 static bool getPath(TopoDS_Wire& thePathOut,
29 const std::shared_ptr<GeomAPI_Shape> thePathShape);
30 static bool buildPipe(BRepOffsetAPI_MakePipeShell* thePipeBuilder);
32 //=================================================================================================
33 GeomAlgoAPI_Pipe::GeomAlgoAPI_Pipe(const std::shared_ptr<GeomAPI_Shape> theBaseShape,
34 const std::shared_ptr<GeomAPI_Shape> thePathShape)
35 : /*myIsPipeShellUsed(false),*/
36 myBaseShape(theBaseShape),
37 myPathShape(thePathShape)
39 build(theBaseShape, thePathShape);
42 //=================================================================================================
43 GeomAlgoAPI_Pipe::GeomAlgoAPI_Pipe(const std::shared_ptr<GeomAPI_Shape> theBaseShape,
44 const std::shared_ptr<GeomAPI_Shape> thePathShape,
45 const std::shared_ptr<GeomAPI_Shape> theBiNormal)
46 //: myIsPipeShellUsed(true)
48 build(theBaseShape, thePathShape, theBiNormal);
51 //=================================================================================================
52 GeomAlgoAPI_Pipe::GeomAlgoAPI_Pipe(const ListOfShape& theBaseShapes,
53 const ListOfShape& theLocations,
54 const std::shared_ptr<GeomAPI_Shape> thePathShape)
55 //: myIsPipeShellUsed(true)
57 build(theBaseShapes, theLocations, thePathShape);
60 //=================================================================================================
61 void GeomAlgoAPI_Pipe::build(const std::shared_ptr<GeomAPI_Shape> theBaseShape,
62 const std::shared_ptr<GeomAPI_Shape> 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 std::shared_ptr<GeomAPI_Shape> 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 std::shared_ptr<GeomAPI_Shape> aResultGeomShape(new GeomAPI_Shape());
109 aResultGeomShape->setImpl(new TopoDS_Shape(aResultShape));
110 this->setShape(aResultGeomShape);
114 //=================================================================================================
115 void GeomAlgoAPI_Pipe::build(const std::shared_ptr<GeomAPI_Shape> theBaseShape,
116 const std::shared_ptr<GeomAPI_Shape> thePathShape,
117 const std::shared_ptr<GeomAPI_Shape> 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 std::shared_ptr<GeomAPI_Shape> 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 std::shared_ptr<GeomAPI_Shape> 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 std::shared_ptr<GeomAPI_Shape> 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 std::shared_ptr<GeomAPI_Shape> 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 std::shared_ptr<GeomAPI_Shape> 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 std::shared_ptr<GeomAPI_Shape> 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 std::shared_ptr<GeomAPI_Shape> aResultGeomShape(new GeomAPI_Shape());
273 aResultGeomShape->setImpl(new TopoDS_Shape(aResultShape));
274 this->setShape(aResultGeomShape);
278 //=================================================================================================
279 void GeomAlgoAPI_Pipe::generated(const std::shared_ptr<GeomAPI_Shape> theShape,
280 ListOfShape& theHistory)
282 GeomAlgoAPI_MakeShape::generated(theShape, theHistory);
284 //if(myIsPipeShellUsed) {
285 // GeomAlgoAPI_MakeShape::generated(theShape, theHistory);
289 //BRepOffsetAPI_MakePipe* aMakePipe = implPtr<BRepOffsetAPI_MakePipe>();
290 //const TopoDS_Shape& aProfile = theShape->impl<TopoDS_Shape>();
291 //const TopAbs_ShapeEnum aProfileShapeType = aProfile.ShapeType();
292 //if(aProfileShapeType != TopAbs_VERTEX && aProfileShapeType != TopAbs_EDGE) {
295 //const TopoDS_Shape& aBaseShape = myBaseShape->impl<TopoDS_Shape>();
296 //TopExp_Explorer anExp(aBaseShape, aProfileShapeType);
297 //Standard_Boolean ahasShape = Standard_False;
298 //for(; anExp.More(); anExp.Next()) {
299 // if(anExp.Current().IsSame(aProfile)) {
300 // ahasShape = Standard_True;
307 //TopExp_Explorer aShapeExplorer(myPathShape->impl<TopoDS_Shape>(), TopAbs_EDGE);
308 //for(; aShapeExplorer.More(); aShapeExplorer.Next ()) {
309 // const TopoDS_Shape& aSpine = aShapeExplorer.Current();
310 // const TopoDS_Shape& aGeneratedShape = aMakePipe->Generated(aSpine, aProfile);
311 // if(aGeneratedShape.IsNull()) {
314 // std::shared_ptr<GeomAPI_Shape> aShape(new GeomAPI_Shape());
315 // aShape->setImpl(new TopoDS_Shape(aGeneratedShape));
316 // theHistory.push_back(aShape);
320 // Auxilary functions:
321 //=================================================================================================
322 bool getBase(TopoDS_Shape& theBaseOut,
323 TopAbs_ShapeEnum& theBaseTypeOut,
324 const std::shared_ptr<GeomAPI_Shape> theBaseShape)
326 if(!theBaseShape.get()) {
330 theBaseOut = theBaseShape->impl<TopoDS_Shape>();
331 if(theBaseOut.IsNull()) {
334 theBaseTypeOut = theBaseOut.ShapeType();
335 if(theBaseTypeOut == TopAbs_VERTEX) {
337 } else if(theBaseTypeOut == TopAbs_EDGE) {
338 theBaseOut = BRepBuilderAPI_MakeWire(TopoDS::Edge(theBaseOut)).Shape();
339 } else if(theBaseTypeOut == TopAbs_WIRE) {
341 } else if(theBaseTypeOut == TopAbs_FACE) {
342 TopExp_Explorer anExp(theBaseOut, TopAbs_WIRE);
343 theBaseOut = anExp.Current();
351 //=================================================================================================
352 bool getPath(TopoDS_Wire& thePathOut,
353 const std::shared_ptr<GeomAPI_Shape> thePathShape)
355 if(!thePathShape.get()) {
359 TopoDS_Shape aPathShape = thePathShape->impl<TopoDS_Shape>();
360 if(aPathShape.IsNull()) {
363 TopAbs_ShapeEnum aPathShapeType = aPathShape.ShapeType();
364 if(aPathShapeType == TopAbs_EDGE) {
365 TopoDS_Edge aPathEdge = TopoDS::Edge(aPathShape);
366 thePathOut = BRepBuilderAPI_MakeWire(aPathEdge).Wire();
367 } else if(aPathShapeType == TopAbs_WIRE) {
368 thePathOut = TopoDS::Wire(aPathShape);
376 //=================================================================================================
377 bool buildPipe(BRepOffsetAPI_MakePipeShell* thePipeBuilder)
379 thePipeBuilder->Build();
381 Standard_Boolean isDone = thePipeBuilder->IsDone();
384 // Try to use Descrete Trihedron mode.
385 thePipeBuilder->SetDiscreteMode();
386 thePipeBuilder->Build();
387 isDone = thePipeBuilder->IsDone();
390 return isDone == Standard_True;