1 // Copyright (C) 2014-2017 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
20 #include "GeomAlgoAPI_Pipe.h"
22 #include "GeomAlgoAPI_DFLoader.h"
24 #include <GeomAPI_Dir.h>
25 #include <GeomAPI_Edge.h>
26 #include <GeomAPI_Lin.h>
28 #include <BRep_Tool.hxx>
29 #include <BRepOffsetAPI_MakePipe.hxx>
30 #include <BRepOffsetAPI_MakePipeShell.hxx>
31 #include <BRepBuilderAPI_MakeWire.hxx>
32 #include <Geom_Curve.hxx>
33 #include <Geom_Line.hxx>
35 #include <NCollection_List.hxx>
36 #include <TopExp_Explorer.hxx>
38 #include <TopoDS_Shape.hxx>
40 static bool getBase(TopoDS_Shape& theBaseOut,
41 TopAbs_ShapeEnum& theBaseTypeOut,
42 const GeomShapePtr theBaseShape);
43 static bool getPath(TopoDS_Wire& thePathOut,
44 const GeomShapePtr thePathShape);
45 static bool buildPipe(BRepOffsetAPI_MakePipeShell* thePipeBuilder);
46 static ListOfShape getListFromShape(const TopoDS_Shape& theShape);
48 //==================================================================================================
49 GeomAlgoAPI_Pipe::GeomAlgoAPI_Pipe(const GeomShapePtr theBaseShape,
50 const GeomShapePtr thePathShape)
52 build(theBaseShape, thePathShape);
55 //==================================================================================================
56 GeomAlgoAPI_Pipe::GeomAlgoAPI_Pipe(const GeomShapePtr theBaseShape,
57 const GeomShapePtr thePathShape,
58 const GeomShapePtr theBiNormal)
60 build(theBaseShape, thePathShape, theBiNormal);
63 //==================================================================================================
64 GeomAlgoAPI_Pipe::GeomAlgoAPI_Pipe(const ListOfShape& theBaseShapes,
65 const ListOfShape& theLocations,
66 const GeomShapePtr thePathShape)
68 build(theBaseShapes, theLocations, thePathShape);
71 //==================================================================================================
72 void GeomAlgoAPI_Pipe::build(const GeomShapePtr theBaseShape,
73 const GeomShapePtr thePathShape)
75 // Getting base shape.
76 if(!theBaseShape.get()) {
79 TopoDS_Shape aBaseShape = theBaseShape->impl<TopoDS_Shape>();
80 if(aBaseShape.IsNull()) {
83 TopAbs_ShapeEnum aBaseShapeType = aBaseShape.ShapeType();
84 if(aBaseShapeType != TopAbs_VERTEX && aBaseShapeType != TopAbs_EDGE &&
85 aBaseShapeType != TopAbs_WIRE && aBaseShapeType != TopAbs_FACE &&
86 aBaseShapeType != TopAbs_SHELL && aBaseShapeType != TopAbs_COMPOUND) {
91 TopoDS_Wire aPathWire;
92 if(!getPath(aPathWire, thePathShape)) {
97 BRepOffsetAPI_MakePipe* aPipeBuilder = new BRepOffsetAPI_MakePipe(aPathWire, aBaseShape);
101 aPipeBuilder->Build();
104 if(!aPipeBuilder->IsDone() || aPipeBuilder->Shape().IsNull()) {
108 this->initialize(aPipeBuilder);
111 this->setToShapes(getListFromShape(aPipeBuilder->LastShape()));
112 this->setFromShapes(getListFromShape(aPipeBuilder->FirstShape()));
115 TopoDS_Shape aResult = aPipeBuilder->Shape();
116 aResult = GeomAlgoAPI_DFLoader::refineResult(aResult);
117 GeomShapePtr aGeomSh(new GeomAPI_Shape());
118 aGeomSh->setImpl(new TopoDS_Shape(aResult));
119 this->setShape(aGeomSh);
123 //==================================================================================================
124 void GeomAlgoAPI_Pipe::build(const GeomShapePtr theBaseShape,
125 const GeomShapePtr thePathShape,
126 const GeomShapePtr theBiNormal)
128 // Getting base shape.
129 TopoDS_Shape aBaseShape;
130 TopAbs_ShapeEnum aBaseShapeType;
131 if(!getBase(aBaseShape, aBaseShapeType, theBaseShape)) {
136 TopoDS_Wire aPathWire;
137 if(!getPath(aPathWire, thePathShape)) {
141 // Getting Bi-Normal.
142 if(!theBiNormal.get()) {
145 TopoDS_Shape aBiNormalShape = theBiNormal->impl<TopoDS_Shape>();
146 if(aBiNormalShape.IsNull() || aBiNormalShape.ShapeType() != TopAbs_EDGE) {
149 TopoDS_Edge aBiNormalEdge = TopoDS::Edge(aBiNormalShape);
150 Standard_Real aFirst, aLast;
151 Handle(Geom_Curve) aBiNormalCurve = BRep_Tool::Curve(aBiNormalEdge, aFirst, aLast);
152 Handle(Geom_Line) aBiNormalLine = Handle(Geom_Line)::DownCast(aBiNormalCurve);
153 if(aBiNormalLine.IsNull()) {
156 gp_Dir aBiNormalDir = aBiNormalLine->Lin().Direction();
159 BRepOffsetAPI_MakePipeShell* aPipeBuilder = new BRepOffsetAPI_MakePipeShell(aPathWire);
163 aPipeBuilder->Add(aBaseShape);
164 aPipeBuilder->SetMode(aBiNormalDir);
165 if(!buildPipe(aPipeBuilder)) {
169 this->initialize(aPipeBuilder);
172 if(aBaseShapeType == TopAbs_FACE) {
173 if(aPipeBuilder->MakeSolid() == Standard_False) {
177 TopoDS_Shape aResult = aPipeBuilder->Shape();
178 if(aResult.IsNull()) {
183 this->setToShapes(getListFromShape(aPipeBuilder->LastShape()));
184 this->setFromShapes(getListFromShape(aPipeBuilder->FirstShape()));
187 aResult = GeomAlgoAPI_DFLoader::refineResult(aResult);
188 GeomShapePtr aGeomSh(new GeomAPI_Shape());
189 aGeomSh->setImpl(new TopoDS_Shape(aResult));
190 this->setShape(aGeomSh);
194 //==================================================================================================
195 void GeomAlgoAPI_Pipe::build(const ListOfShape& theBaseShapes,
196 const ListOfShape& theLocations,
197 const GeomShapePtr thePathShape)
199 if(theBaseShapes.empty() ||
200 (!theLocations.empty() && theLocations.size() != theBaseShapes.size())) {
204 bool aHasLocations = false;
205 if(!theLocations.empty()) {
206 aHasLocations = true;
210 TopoDS_Wire aPathWire;
211 if(!getPath(aPathWire, thePathShape)) {
216 BRepOffsetAPI_MakePipeShell* aPipeBuilder = new BRepOffsetAPI_MakePipeShell(aPathWire);
220 bool anIsSolidNeeded = false;
221 ListOfShape::const_iterator aBaseIt = theBaseShapes.cbegin();
222 ListOfShape::const_iterator aLocIt = theLocations.cbegin();
223 while(aBaseIt != theBaseShapes.cend()) {
224 GeomShapePtr aBase = *aBaseIt;
225 TopoDS_Shape aBaseShape;
226 TopAbs_ShapeEnum aBaseShapeType;
227 if(!getBase(aBaseShape, aBaseShapeType, aBase)) {
232 if(aBaseShapeType == TopAbs_FACE) {
233 anIsSolidNeeded = true;
237 GeomShapePtr aLocation = *aLocIt;
238 if(!aLocation.get() || aLocation->shapeType() != GeomAPI_Shape::VERTEX) {
242 TopoDS_Vertex aLocationVertex = aLocation->impl<TopoDS_Vertex>();
244 aPipeBuilder->Add(aBaseShape, aLocationVertex);
246 aPipeBuilder->Add(aBaseShape);
250 if(aPipeBuilder->IsReady() == Standard_False) {
255 if(!buildPipe(aPipeBuilder)) {
259 this->initialize(aPipeBuilder);
262 if(anIsSolidNeeded) {
263 if(aPipeBuilder->MakeSolid() == Standard_False) {
267 TopoDS_Shape aResult = aPipeBuilder->Shape();
270 GeomShapePtr aFromShape(new GeomAPI_Shape), aToShape(new GeomAPI_Shape);
271 aFromShape->setImpl(new TopoDS_Shape(aPipeBuilder->FirstShape()));
272 aToShape->setImpl(new TopoDS_Shape(aPipeBuilder->LastShape()));
273 this->addFromShape(aFromShape);
274 this->addToShape(aToShape);
277 if(aResult.IsNull()) {
280 aResult = GeomAlgoAPI_DFLoader::refineResult(aResult);
281 GeomShapePtr aGeomSh(new GeomAPI_Shape());
282 aGeomSh->setImpl(new TopoDS_Shape(aResult));
283 this->setShape(aGeomSh);
287 //==================================================================================================
288 void GeomAlgoAPI_Pipe::generated(const GeomShapePtr theShape,
289 ListOfShape& theHistory)
291 GeomAlgoAPI_MakeShape::generated(theShape, theHistory);
294 // Auxilary functions:
295 //==================================================================================================
296 bool getBase(TopoDS_Shape& theBaseOut,
297 TopAbs_ShapeEnum& theBaseTypeOut,
298 const GeomShapePtr theBaseShape)
300 if(!theBaseShape.get()) {
304 theBaseOut = theBaseShape->impl<TopoDS_Shape>();
305 if(theBaseOut.IsNull()) {
308 theBaseTypeOut = theBaseOut.ShapeType();
309 if(theBaseTypeOut == TopAbs_VERTEX) {
311 } else if(theBaseTypeOut == TopAbs_EDGE) {
312 theBaseOut = BRepBuilderAPI_MakeWire(TopoDS::Edge(theBaseOut)).Shape();
313 } else if(theBaseTypeOut == TopAbs_WIRE) {
315 } else if(theBaseTypeOut == TopAbs_FACE) {
316 TopExp_Explorer anExp(theBaseOut, TopAbs_WIRE);
317 theBaseOut = anExp.Current();
325 //==================================================================================================
326 bool getPath(TopoDS_Wire& thePathOut,
327 const GeomShapePtr thePathShape)
329 if(!thePathShape.get()) {
333 TopoDS_Shape aPathShape = thePathShape->impl<TopoDS_Shape>();
334 if(aPathShape.IsNull()) {
337 TopAbs_ShapeEnum aPathShapeType = aPathShape.ShapeType();
338 if(aPathShapeType == TopAbs_EDGE) {
339 TopoDS_Edge aPathEdge = TopoDS::Edge(aPathShape);
340 thePathOut = BRepBuilderAPI_MakeWire(aPathEdge).Wire();
341 } else if(aPathShapeType == TopAbs_WIRE) {
342 thePathOut = TopoDS::Wire(aPathShape);
350 //==================================================================================================
351 bool buildPipe(BRepOffsetAPI_MakePipeShell* thePipeBuilder)
353 thePipeBuilder->Build();
355 Standard_Boolean isDone = thePipeBuilder->IsDone();
358 // Try to use Descrete Trihedron mode.
359 thePipeBuilder->SetDiscreteMode();
360 thePipeBuilder->Build();
361 isDone = thePipeBuilder->IsDone();
364 return isDone == Standard_True;
367 //==================================================================================================
368 ListOfShape getListFromShape(const TopoDS_Shape& theShape)
372 TopAbs_ShapeEnum aType = theShape.ShapeType();
373 if(aType == TopAbs_WIRE || aType == TopAbs_SHELL || aType == TopAbs_COMPOUND) {
374 for(TopoDS_Iterator anIt(theShape); anIt.More(); anIt.Next()) {
375 GeomShapePtr aGeomShape(new GeomAPI_Shape());
376 aGeomShape->setImpl(new TopoDS_Shape(anIt.Value()));
377 aList.push_back(aGeomShape);
380 GeomShapePtr aGeomShape(new GeomAPI_Shape());
381 aGeomShape->setImpl(new TopoDS_Shape(theShape));
382 aList.push_back(aGeomShape);