X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FGeomAlgoAPI%2FGeomAlgoAPI_Pipe.cpp;h=067a249bd592d27e11cf924b8923f6dcee1b48d2;hb=f813e863f0a60ee69846227f99f0dd6a84f8498c;hp=04b310006af1f7ef84c917153b5fdece5c2b2bfb;hpb=a8cfbfb436c27ff96edd5c808e9a452c35cef207;p=modules%2Fshaper.git diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Pipe.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_Pipe.cpp index 04b310006..067a249bd 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_Pipe.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Pipe.cpp @@ -1,8 +1,21 @@ -// Copyright (C) 2014-20xx CEA/DEN, EDF R&D - -// File: GeomAlgoAPI_Pipe.cpp -// Created: 16 March 2016 -// Author: Dmitry Bobylev +// Copyright (C) 2014-2019 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// #include "GeomAlgoAPI_Pipe.h" @@ -11,8 +24,10 @@ #include #include #include +#include #include +#include #include #include #include @@ -23,12 +38,15 @@ #include #include #include +#include static bool getBase(TopoDS_Shape& theBaseOut, TopAbs_ShapeEnum& theBaseTypeOut, const GeomShapePtr theBaseShape); static bool getPath(TopoDS_Wire& thePathOut, const GeomShapePtr thePathShape); +static gp_Trsf getPathToBaseTranslation(const TopoDS_Shape& theBase, + const TopoDS_Shape& thePath); static bool buildPipe(BRepOffsetAPI_MakePipeShell* thePipeBuilder); static ListOfShape getListFromShape(const TopoDS_Shape& theShape); @@ -79,6 +97,12 @@ void GeomAlgoAPI_Pipe::build(const GeomShapePtr theBaseShape, if(!getPath(aPathWire, thePathShape)) { return; } + GeomShapePtr anOldPath(new GeomAPI_Shape), aNewPath(new GeomAPI_Shape); + anOldPath->setImpl(new TopoDS_Shape(aPathWire)); + aPathWire.Move(getPathToBaseTranslation(aBaseShape, aPathWire)); + aNewPath->setImpl(new TopoDS_Shape(aPathWire)); + if (!anOldPath->isSame(aNewPath)) + addMovedPath(anOldPath, aNewPath); // Making pipe. BRepOffsetAPI_MakePipe* aPipeBuilder = new BRepOffsetAPI_MakePipe(aPathWire, aBaseShape); @@ -112,23 +136,24 @@ void GeomAlgoAPI_Pipe::build(const GeomShapePtr theBaseShape, const GeomShapePtr thePathShape, const GeomShapePtr theBiNormal) { - // Getting base shape. + // Getting base shape and path. TopoDS_Shape aBaseShape; TopAbs_ShapeEnum aBaseShapeType; - if(!getBase(aBaseShape, aBaseShapeType, theBaseShape)) { - return; - } - - // Getting path. TopoDS_Wire aPathWire; - if(!getPath(aPathWire, thePathShape)) { + if (!getBase(aBaseShape, aBaseShapeType, theBaseShape) || + !getPath(aPathWire, thePathShape) || + !theBiNormal.get()) { return; } + GeomShapePtr anOldPath(new GeomAPI_Shape), aNewPath(new GeomAPI_Shape); + anOldPath->setImpl(new TopoDS_Shape(aPathWire)); + aPathWire.Move(getPathToBaseTranslation(theBaseShape->impl(), aPathWire)); + aNewPath->setImpl(new TopoDS_Shape(aPathWire)); + if (!anOldPath->isSame(aNewPath)) + addMovedPath(anOldPath, aNewPath); + // Getting Bi-Normal. - if(!theBiNormal.get()) { - return; - } TopoDS_Shape aBiNormalShape = theBiNormal->impl(); if(aBiNormalShape.IsNull() || aBiNormalShape.ShapeType() != TopAbs_EDGE) { return; @@ -156,10 +181,8 @@ void GeomAlgoAPI_Pipe::build(const GeomShapePtr theBaseShape, this->initialize(aPipeBuilder); // Checking result. - if(aBaseShapeType == TopAbs_FACE) { - if(aPipeBuilder->MakeSolid() == Standard_False) { - return; - } + if(aBaseShapeType == TopAbs_FACE && !aPipeBuilder->MakeSolid()) { + return; } TopoDS_Shape aResult = aPipeBuilder->Shape(); if(aResult.IsNull()) { @@ -183,72 +206,119 @@ void GeomAlgoAPI_Pipe::build(const ListOfShape& theBaseShapes, const ListOfShape& theLocations, const GeomShapePtr thePathShape) { - if(theBaseShapes.empty() || (!theLocations.empty() && theLocations.size() != theBaseShapes.size())) { + if(theBaseShapes.empty() || + (!theLocations.empty() && theLocations.size() != theBaseShapes.size())) { return; } - bool aHasLocations = false; - if(!theLocations.empty()) { - aHasLocations = true; - } - - // Getting path. + // Getting base shape and path. + TopoDS_Shape aBaseShape; + TopAbs_ShapeEnum aBaseShapeType; TopoDS_Wire aPathWire; - if(!getPath(aPathWire, thePathShape)) { + if (!getBase(aBaseShape, aBaseShapeType, theBaseShapes.front()) || + !getPath(aPathWire, thePathShape)) { return; } - // Making pipe. - BRepOffsetAPI_MakePipeShell* aPipeBuilder = new BRepOffsetAPI_MakePipeShell(aPathWire); - if(!aPipeBuilder) { + TopoDS_Shape aReallyBase = theBaseShapes.front()->impl(); + gp_Trsf aTrsf = getPathToBaseTranslation(aReallyBase, aPathWire); + + GeomShapePtr anOldPath(new GeomAPI_Shape), aNewPath(new GeomAPI_Shape); + anOldPath->setImpl(new TopoDS_Shape(aPathWire)); + aPathWire.Move(aTrsf); + aNewPath->setImpl(new TopoDS_Shape(aPathWire)); + if (!anOldPath->isSame(aNewPath)) + addMovedPath(anOldPath, aNewPath); + + // Get locations after moving path shape. + std::list aLocations; + for (ListOfShape::const_iterator aLocIt = theLocations.cbegin(); + aLocIt != theLocations.cend(); + ++aLocIt) + { + GeomShapePtr aLocation = *aLocIt; + if (!aLocation.get() || aLocation->shapeType() != GeomAPI_Shape::VERTEX) { + return; + } + + TopoDS_Vertex aLocationVertex = aLocation->impl(); + TopoDS_Vertex aMovedVertex; + for (TopExp_Explorer anExp(aPathWire, TopAbs_VERTEX); anExp.More(); anExp.Next()) { + if (anExp.Current().IsPartner(aLocationVertex)) { + aMovedVertex = TopoDS::Vertex(anExp.Current()); + aLocations.push_back(aMovedVertex); + break; + } + } + if (aMovedVertex.IsNull()) { + return; + } + } + + if (theLocations.size() != aLocations.size()) { return; } + + bool aHasLocations = !aLocations.empty(); + + // Making pipe. + Standard_Boolean isDone = Standard_False; bool anIsSolidNeeded = false; - ListOfShape::const_iterator aBaseIt = theBaseShapes.cbegin(); - ListOfShape::const_iterator aLocIt = theLocations.cbegin(); - while(aBaseIt != theBaseShapes.cend()) { - GeomShapePtr aBase = *aBaseIt; - TopoDS_Shape aBaseShape; - TopAbs_ShapeEnum aBaseShapeType; - if(!getBase(aBaseShape, aBaseShapeType, aBase)) { - delete aPipeBuilder; + BRepOffsetAPI_MakePipeShell* aPipeBuilder; + for(int i = 0; i < 2; ++i) { + aPipeBuilder = new BRepOffsetAPI_MakePipeShell(aPathWire); + if(!aPipeBuilder) { return; } - ++aBaseIt; - if(aBaseShapeType == TopAbs_FACE) { - anIsSolidNeeded = true; - } - - if(aHasLocations) { - GeomShapePtr aLocation = *aLocIt; - if(!aLocation.get() || aLocation->shapeType() != GeomAPI_Shape::VERTEX) { + ListOfShape::const_iterator aBaseIt = theBaseShapes.cbegin(); + std::list::const_iterator aLocationsIt = aLocations.cbegin(); + while(aBaseIt != theBaseShapes.cend()) { + GeomShapePtr aBase = *aBaseIt; + if(!getBase(aBaseShape, aBaseShapeType, aBase)) { delete aPipeBuilder; return; } - TopoDS_Vertex aLocationVertex = aLocation->impl(); - ++aLocIt; - aPipeBuilder->Add(aBaseShape, aLocationVertex); - } else { - aPipeBuilder->Add(aBaseShape); + ++aBaseIt; + if(aBaseShapeType == TopAbs_FACE) { + anIsSolidNeeded = true; + } + + if(aHasLocations) { + aPipeBuilder->Add(aBaseShape, *aLocationsIt); + ++aLocationsIt; + } else { + aPipeBuilder->Add(aBaseShape); + } + } + + if(aPipeBuilder->IsReady() == Standard_False) { + delete aPipeBuilder; + return; + } + + if (i == 1) { + // Try to use Descrete Trihedron mode. + aPipeBuilder->SetDiscreteMode(); + } + aPipeBuilder->Build(); + isDone = aPipeBuilder->IsDone(); + + if (isDone) { + break; } - } - if(aPipeBuilder->IsReady() == Standard_False) { delete aPipeBuilder; - return; } - if(!buildPipe(aPipeBuilder)) { - delete aPipeBuilder; + if (!isDone) { return; } + this->initialize(aPipeBuilder); // Checking result. - if(anIsSolidNeeded) { - if(aPipeBuilder->MakeSolid() == Standard_False) { - return; - } + if(anIsSolidNeeded && !aPipeBuilder->MakeSolid()) { + return; } TopoDS_Shape aResult = aPipeBuilder->Shape(); @@ -256,6 +326,8 @@ void GeomAlgoAPI_Pipe::build(const ListOfShape& theBaseShapes, GeomShapePtr aFromShape(new GeomAPI_Shape), aToShape(new GeomAPI_Shape); aFromShape->setImpl(new TopoDS_Shape(aPipeBuilder->FirstShape())); aToShape->setImpl(new TopoDS_Shape(aPipeBuilder->LastShape())); + fixOrientation(aFromShape); + fixOrientation(aToShape); this->addFromShape(aFromShape); this->addToShape(aToShape); @@ -274,7 +346,10 @@ void GeomAlgoAPI_Pipe::build(const ListOfShape& theBaseShapes, void GeomAlgoAPI_Pipe::generated(const GeomShapePtr theShape, ListOfShape& theHistory) { - GeomAlgoAPI_MakeShape::generated(theShape, theHistory); + if (myMovedPath.isBound(theShape)) + GeomAlgoAPI_MakeShape::generated(myMovedPath.find(theShape), theHistory); + else + GeomAlgoAPI_MakeShape::generated(theShape, theHistory); } // Auxilary functions: @@ -309,8 +384,7 @@ bool getBase(TopoDS_Shape& theBaseOut, } //================================================================================================== -bool getPath(TopoDS_Wire& thePathOut, - const GeomShapePtr thePathShape) +bool getPath(TopoDS_Wire& thePathOut, const GeomShapePtr thePathShape) { if(!thePathShape.get()) { return false; @@ -333,6 +407,22 @@ bool getPath(TopoDS_Wire& thePathOut, return true; } +//================================================================================================== +gp_Trsf getPathToBaseTranslation(const TopoDS_Shape& theBase, const TopoDS_Shape& thePath) +{ + gp_Trsf aTranslation; + + BRepExtrema_DistShapeShape aDist(theBase, thePath); + aDist.Perform(); + if (aDist.IsDone() && aDist.Value() > Precision::Confusion()) { + gp_Pnt aPntBase = aDist.PointOnShape1(1); + gp_Pnt aPntPath = aDist.PointOnShape2(1); + aTranslation.SetTranslation(aPntPath, aPntBase); + } + + return aTranslation; +} + //================================================================================================== bool buildPipe(BRepOffsetAPI_MakePipeShell* thePipeBuilder) { @@ -370,3 +460,14 @@ ListOfShape getListFromShape(const TopoDS_Shape& theShape) return aList; } + +//================================================================================================== +void GeomAlgoAPI_Pipe::addMovedPath(GeomShapePtr thePath, GeomShapePtr theMoved) +{ + myMovedPath.clear(); + GeomAPI_ShapeExplorer anOldExp(thePath, GeomAPI_Shape::EDGE); + GeomAPI_ShapeExplorer aNewExp(theMoved, GeomAPI_Shape::EDGE); + for(; anOldExp.more(); anOldExp.next(), aNewExp.next()) { + myMovedPath.bind(anOldExp.current(), aNewExp.current()); + } +}