From e7b1bd7f8bc0bc7a12852a4d98fb19195c3a88de Mon Sep 17 00:00:00 2001 From: dbv Date: Thu, 3 Sep 2015 11:05:59 +0300 Subject: [PATCH] Extrusion returned previous algo for simple faces. --- src/GeomAlgoAPI/GeomAlgoAPI_Prism.cpp | 372 ++++++++++++++------------ 1 file changed, 206 insertions(+), 166 deletions(-) diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Prism.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_Prism.cpp index 6e2dbc1f2..36c644f39 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_Prism.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Prism.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -76,14 +77,14 @@ void GeomAlgoAPI_Prism::build(const std::shared_ptr& theBasis, // If bounding faces was not set creating them. std::shared_ptr aBaseFace; - if(theBasis->shapeType() == GeomAPI_Shape::SHELL) { + if(theBasis->shapeType() == GeomAPI_Shape::FACE) { + aBaseFace = std::shared_ptr(new GeomAPI_Face(theBasis)); + } else if(theBasis->shapeType() == GeomAPI_Shape::SHELL){ GeomAPI_ShapeExplorer anExp(theBasis, GeomAPI_Shape::FACE); if(anExp.more()) { std::shared_ptr aFaceOnShell = anExp.current(); aBaseFace = std::shared_ptr(new GeomAPI_Face(aFaceOnShell)); } - } else { - aBaseFace = std::shared_ptr(new GeomAPI_Face(theBasis)); } if(!aBaseFace.get()) { return; @@ -117,186 +118,225 @@ void GeomAlgoAPI_Prism::build(const std::shared_ptr& theBasis, aSign ? -theToSize : theToSize)))); aBoundingToShape = GeomAlgoAPI_FaceBuilder::planarFace(aToPnt, aToDir); - // Getting bounding box for base shape. - const TopoDS_Shape& aBasisShape = theBasis->impl(); - Bnd_Box aBndBox; - BRepBndLib::Add(aBasisShape, aBndBox); - Standard_Real aXArr[2] = {aBndBox.CornerMin().X(), aBndBox.CornerMax().X()}; - Standard_Real aYArr[2] = {aBndBox.CornerMin().Y(), aBndBox.CornerMax().Y()}; - Standard_Real aZArr[2] = {aBndBox.CornerMin().Z(), aBndBox.CornerMax().Z()}; - gp_Pnt aPoints[8]; - int aNum = 0; - for(int i = 0; i < 2; i++) { - for(int j = 0; j < 2; j++) { - for(int k = 0; k < 2; k++) { - aPoints[aNum] = gp_Pnt(aXArr[i], aYArr[j], aZArr[k]); - aNum++; + if(theBasis->shapeType() == GeomAPI_Shape::FACE) { + TopoDS_Face aBasis = TopoDS::Face(aBaseFace->impl()); + const gp_Dir& aNormal = aBaseDir->impl(); + BRepFeat_MakePrism* aBuilder = new BRepFeat_MakePrism(aBasis, aBasis, aBasis, aNormal, 2, Standard_True); + + if(aBuilder) { + const TopoDS_Shape& aFromShape = aBoundingFromShape->impl(); + const TopoDS_Shape& aToShape = aBoundingToShape->impl(); + aBuilder->Perform(aFromShape, aToShape); + myDone = aBuilder->IsDone() == Standard_True; + if(myDone){ + TopoDS_Shape aResult = aBuilder->Shape(); + TopExp_Explorer anExp(aResult, TopAbs_SOLID); + if(!anExp.More()) { + return; + } + if(aResult.ShapeType() == TopAbs_COMPOUND) { + aResult = GeomAlgoAPI_DFLoader::refineResult(aResult); + } + // fill data map to keep correct orientation of sub-shapes + myMap.reset(new GeomAPI_DataMapOfShapeShape); + for (TopExp_Explorer Exp(aResult,TopAbs_FACE); Exp.More(); Exp.Next()) { + std::shared_ptr aCurrentShape(new GeomAPI_Shape()); + aCurrentShape->setImpl(new TopoDS_Shape(Exp.Current())); + myMap->bind(aCurrentShape, aCurrentShape); + } + myShape.reset(new GeomAPI_Shape); + myShape->setImpl(new TopoDS_Shape(aResult)); + std::shared_ptr aFrom(new GeomAPI_Shape()); + aFrom->setImpl(new TopoDS_Shape(aBuilder->Modified(aFromShape).First())); + myFromFaces.push_back(aFrom); + std::shared_ptr aTo(new GeomAPI_Shape()); + aTo->setImpl(new TopoDS_Shape(aBuilder->Modified(aToShape).First())); + myToFaces.push_back(aTo); + myMkShape.reset(new GeomAlgoAPI_MakeShape(aBuilder)); + } + } + } else { + // Getting bounding box for base shape. + const TopoDS_Shape& aBasisShape = theBasis->impl(); + Bnd_Box aBndBox; + BRepBndLib::Add(aBasisShape, aBndBox); + Standard_Real aXArr[2] = {aBndBox.CornerMin().X(), aBndBox.CornerMax().X()}; + Standard_Real aYArr[2] = {aBndBox.CornerMin().Y(), aBndBox.CornerMax().Y()}; + Standard_Real aZArr[2] = {aBndBox.CornerMin().Z(), aBndBox.CornerMax().Z()}; + gp_Pnt aPoints[8]; + int aNum = 0; + for(int i = 0; i < 2; i++) { + for(int j = 0; j < 2; j++) { + for(int k = 0; k < 2; k++) { + aPoints[aNum] = gp_Pnt(aXArr[i], aYArr[j], aZArr[k]); + aNum++; + } } } - } - // Project points to bounding planes. Search max distance to them. - const TopoDS_Shape& aBndToShape = aBoundingToShape->impl(); - const TopoDS_Shape& aBndFromShape = aBoundingFromShape->impl(); - Standard_Real aMaxToDist = 0, aMaxFromDist = 0; - gp_Vec aNormal(aBaseDir->impl()); - for(int i = 0; i < 8; i++) { - gp_Lin aLine(aPoints[i], aNormal); + // Project points to bounding planes. Search max distance to them. + const TopoDS_Shape& aBndToShape = aBoundingToShape->impl(); + const TopoDS_Shape& aBndFromShape = aBoundingFromShape->impl(); + Standard_Real aMaxToDist = 0, aMaxFromDist = 0; + gp_Vec aNormal(aBaseDir->impl()); + for(int i = 0; i < 8; i++) { + gp_Lin aLine(aPoints[i], aNormal); + TopoDS_Edge anEdge = BRepBuilderAPI_MakeEdge(aLine).Edge(); + BRepExtrema_ExtCF aToExt(anEdge, TopoDS::Face(aBndToShape)); + BRepExtrema_ExtCF aFromExt(anEdge, TopoDS::Face(aBndFromShape)); + if(aToExt.NbExt() == 0 || aFromExt.NbExt() == 0) { + return; + } + const gp_Pnt& aPntOnToFace = aToExt.PointOnFace(1); + const gp_Pnt& aPntOnFromFace = aFromExt.PointOnFace(1); + if(aPoints[i].Distance(aPntOnToFace) > aMaxToDist) { + aMaxToDist = aPoints[i].Distance(aPntOnToFace); + } + if(aPoints[i].Distance(aPntOnFromFace) > aMaxFromDist) { + aMaxFromDist = aPoints[i].Distance(aPntOnFromFace); + } + } + // We added 1 just to be sure that pipe is long enough for boolean operation. + Standard_Real aPipeLength = aMaxToDist + aMaxFromDist + 1; + + // Making wire for pipe. + std::shared_ptr aCentreOfMass = GeomAlgoAPI_ShapeTools::centreOfMass(theBasis); + const gp_Pnt aCentrePnt = aCentreOfMass->impl(); + TopoDS_Face aFace = TopoDS::Face(aBaseFace->impl()); + gp_Pnt aPipeStartPnt = aCentrePnt.Translated(aNormal.Scaled(aPipeLength)); + gp_Pnt aPipeEndPnt = aCentrePnt.Translated(aNormal.Scaled(-aPipeLength)); + TopoDS_Edge aPipeEdge = BRepBuilderAPI_MakeEdge(aPipeStartPnt, aPipeEndPnt); + TopoDS_Wire aPipeWire = BRepBuilderAPI_MakeWire(aPipeEdge).Wire(); + + // Making pipe. + ListOfMakeShape aListOfMakeShape; + BRepOffsetAPI_MakePipe* aPipeBuilder = new BRepOffsetAPI_MakePipe(aPipeWire, aBasisShape); + if(!aPipeBuilder) { + return; + } + std::shared_ptr aWire(new GeomAPI_Shape); + std::shared_ptr aBShape(new GeomAPI_Shape); + aWire->setImpl(new TopoDS_Shape(aPipeWire)); + aBShape->setImpl(new TopoDS_Shape(aBasisShape)); + aListOfMakeShape.push_back(std::shared_ptr(new GeomAlgoAPI_MakeShape(aPipeBuilder, aWire, aBShape))); + TopoDS_Shape aResult = aPipeBuilder->Shape(); + + // Orienting bounding planes. + gp_Lin aLine(aCentrePnt, aNormal); TopoDS_Edge anEdge = BRepBuilderAPI_MakeEdge(aLine).Edge(); BRepExtrema_ExtCF aToExt(anEdge, TopoDS::Face(aBndToShape)); BRepExtrema_ExtCF aFromExt(anEdge, TopoDS::Face(aBndFromShape)); - if(aToExt.NbExt() == 0 || aFromExt.NbExt() == 0) { - return; + Standard_Real aToParameter = aToExt.ParameterOnEdge(1); + Standard_Real aFromParameter = aFromExt.ParameterOnEdge(1); + if(aToParameter > aFromParameter) { + gp_Vec aVec = aToDir->impl(); + if((aVec * aNormal) > 0) { + aToDir->setImpl(new gp_Dir(aVec.Reversed())); + aBoundingToShape = GeomAlgoAPI_FaceBuilder::planarFace(aToPnt, aToDir); + } + aVec = aFromDir->impl(); + if((aVec * aNormal) < 0) { + aFromDir->setImpl(new gp_Dir(aVec.Reversed())); + aBoundingFromShape = GeomAlgoAPI_FaceBuilder::planarFace(aFromPnt, aFromDir); + } + } else { + gp_Vec aVec = aToDir->impl(); + if((aVec * aNormal) < 0) { + aToDir->setImpl(new gp_Dir(aVec.Reversed())); + aBoundingToShape = GeomAlgoAPI_FaceBuilder::planarFace(aToPnt, aToDir); + } + aVec = aFromDir->impl(); + if((aVec * aNormal) > 0) { + aFromDir->setImpl(new gp_Dir(aVec.Reversed())); + aBoundingFromShape = GeomAlgoAPI_FaceBuilder::planarFace(aFromPnt, aFromDir); + } } - const gp_Pnt& aPntOnToFace = aToExt.PointOnFace(1); - const gp_Pnt& aPntOnFromFace = aFromExt.PointOnFace(1); - if(aPoints[i].Distance(aPntOnToFace) > aMaxToDist) { - aMaxToDist = aPoints[i].Distance(aPntOnToFace); + + // Making solids from bounding planes. + TopoDS_Shell aToShell, aFromShell; + TopoDS_Solid aToSolid, aFromSolid; + const TopoDS_Shape& aToShape = aBoundingToShape->impl(); + const TopoDS_Shape& aFromShape = aBoundingFromShape->impl(); + BRep_Builder aBoundingBuilder; + aBoundingBuilder.MakeShell(aToShell); + aBoundingBuilder.MakeShell(aFromShell); + aBoundingBuilder.Add(aToShell, aToShape); + aBoundingBuilder.Add(aFromShell, aFromShape); + aBoundingBuilder.MakeSolid(aToSolid); + aBoundingBuilder.MakeSolid(aFromSolid); + aBoundingBuilder.Add(aToSolid, aToShell); + aBoundingBuilder.Add(aFromSolid, aFromShell); + + // Cutting with to plane. + BRepAlgoAPI_Cut* aToCutBuilder = new BRepAlgoAPI_Cut(aResult, aToSolid); + aToCutBuilder->Build(); + if(!aToCutBuilder->IsDone()) { + return; } - if(aPoints[i].Distance(aPntOnFromFace) > aMaxFromDist) { - aMaxFromDist = aPoints[i].Distance(aPntOnFromFace); + aListOfMakeShape.push_back(std::shared_ptr(new GeomAlgoAPI_MakeShape(aToCutBuilder))); + const TopTools_ListOfShape& aToShapes = aToCutBuilder->Modified(aToShape); + for(TopTools_ListIteratorOfListOfShape anIt(aToShapes); anIt.More(); anIt.Next()) { + std::shared_ptr aShape(new GeomAPI_Shape()); + aShape->setImpl(new TopoDS_Shape(anIt.Value())); + myToFaces.push_back(aShape); } - } - // We added 1 just to be sure that pipe is long enough for boolean operation. - Standard_Real aPipeLength = aMaxToDist + aMaxFromDist + 1; - - // Making wire for pipe. - std::shared_ptr aCentreOfMass = GeomAlgoAPI_ShapeTools::centreOfMass(theBasis); - const gp_Pnt aCentrePnt = aCentreOfMass->impl(); - TopoDS_Face aFace = TopoDS::Face(aBaseFace->impl()); - gp_Pnt aPipeStartPnt = aCentrePnt.Translated(aNormal.Scaled(aPipeLength)); - gp_Pnt aPipeEndPnt = aCentrePnt.Translated(aNormal.Scaled(-aPipeLength)); - TopoDS_Edge aPipeEdge = BRepBuilderAPI_MakeEdge(aPipeStartPnt, aPipeEndPnt); - TopoDS_Wire aPipeWire = BRepBuilderAPI_MakeWire(aPipeEdge).Wire(); - - // Making pipe. - ListOfMakeShape aListOfMakeShape; - BRepOffsetAPI_MakePipe* aPipeBuilder = new BRepOffsetAPI_MakePipe(aPipeWire, aBasisShape); - if(!aPipeBuilder) { - return; - } - std::shared_ptr aWire(new GeomAPI_Shape); - std::shared_ptr aBShape(new GeomAPI_Shape); - aWire->setImpl(new TopoDS_Shape(aPipeWire)); - aBShape->setImpl(new TopoDS_Shape(aBasisShape)); - aListOfMakeShape.push_back(std::shared_ptr(new GeomAlgoAPI_MakeShape(aPipeBuilder, aWire, aBShape))); - TopoDS_Shape aResult = aPipeBuilder->Shape(); - - // Orienting bounding planes. - gp_Lin aLine(aCentrePnt, aNormal); - TopoDS_Edge anEdge = BRepBuilderAPI_MakeEdge(aLine).Edge(); - BRepExtrema_ExtCF aToExt(anEdge, TopoDS::Face(aBndToShape)); - BRepExtrema_ExtCF aFromExt(anEdge, TopoDS::Face(aBndFromShape)); - Standard_Real aToParameter = aToExt.ParameterOnEdge(1); - Standard_Real aFromParameter = aFromExt.ParameterOnEdge(1); - if(aToParameter > aFromParameter) { - gp_Vec aVec = aToDir->impl(); - if((aVec * aNormal) > 0) { - aToDir->setImpl(new gp_Dir(aVec.Reversed())); - aBoundingToShape = GeomAlgoAPI_FaceBuilder::planarFace(aToPnt, aToDir); + aResult = aToCutBuilder->Shape(); + + // Cutting with from plane. + BRepAlgoAPI_Cut* aFromCutBuilder = new BRepAlgoAPI_Cut(aResult, aFromSolid); + aFromCutBuilder->Build(); + if(!aFromCutBuilder->IsDone()) { + return; } - aVec = aFromDir->impl(); - if((aVec * aNormal) < 0) { - aFromDir->setImpl(new gp_Dir(aVec.Reversed())); - aBoundingFromShape = GeomAlgoAPI_FaceBuilder::planarFace(aFromPnt, aFromDir); + aListOfMakeShape.push_back(std::shared_ptr(new GeomAlgoAPI_MakeShape(aFromCutBuilder))); + const TopTools_ListOfShape& aFromShapes = aFromCutBuilder->Modified(aFromShape); + for(TopTools_ListIteratorOfListOfShape anIt(aFromShapes); anIt.More(); anIt.Next()) { + std::shared_ptr aShape(new GeomAPI_Shape()); + aShape->setImpl(new TopoDS_Shape(anIt.Value())); + myFromFaces.push_back(aShape); } - } else { - gp_Vec aVec = aToDir->impl(); - if((aVec * aNormal) < 0) { - aToDir->setImpl(new gp_Dir(aVec.Reversed())); - aBoundingToShape = GeomAlgoAPI_FaceBuilder::planarFace(aToPnt, aToDir); + aResult = aFromCutBuilder->Shape(); + + TopExp_Explorer anExp(aResult, TopAbs_SOLID); + if(!anExp.More()) { + return; } - aVec = aFromDir->impl(); - if((aVec * aNormal) > 0) { - aFromDir->setImpl(new gp_Dir(aVec.Reversed())); - aBoundingFromShape = GeomAlgoAPI_FaceBuilder::planarFace(aFromPnt, aFromDir); + if(aResult.ShapeType() == TopAbs_COMPOUND) { + aResult = GeomAlgoAPI_DFLoader::refineResult(aResult); } - } - - // Making solids from bounding planes. - TopoDS_Shell aToShell, aFromShell; - TopoDS_Solid aToSolid, aFromSolid; - const TopoDS_Shape& aToShape = aBoundingToShape->impl(); - const TopoDS_Shape& aFromShape = aBoundingFromShape->impl(); - BRep_Builder aBoundingBuilder; - aBoundingBuilder.MakeShell(aToShell); - aBoundingBuilder.MakeShell(aFromShell); - aBoundingBuilder.Add(aToShell, aToShape); - aBoundingBuilder.Add(aFromShell, aFromShape); - aBoundingBuilder.MakeSolid(aToSolid); - aBoundingBuilder.MakeSolid(aFromSolid); - aBoundingBuilder.Add(aToSolid, aToShell); - aBoundingBuilder.Add(aFromSolid, aFromShell); - - // Cutting with to plane. - BRepAlgoAPI_Cut* aToCutBuilder = new BRepAlgoAPI_Cut(aResult, aToSolid); - aToCutBuilder->Build(); - if(!aToCutBuilder->IsDone()) { - return; - } - aListOfMakeShape.push_back(std::shared_ptr(new GeomAlgoAPI_MakeShape(aToCutBuilder))); - const TopTools_ListOfShape& aToShapes = aToCutBuilder->Modified(aToShape); - for(TopTools_ListIteratorOfListOfShape anIt(aToShapes); anIt.More(); anIt.Next()) { - std::shared_ptr aShape(new GeomAPI_Shape()); - aShape->setImpl(new TopoDS_Shape(anIt.Value())); - myToFaces.push_back(aShape); - } - aResult = aToCutBuilder->Shape(); - - // Cutting with from plane. - BRepAlgoAPI_Cut* aFromCutBuilder = new BRepAlgoAPI_Cut(aResult, aFromSolid); - aFromCutBuilder->Build(); - if(!aFromCutBuilder->IsDone()) { - return; - } - aListOfMakeShape.push_back(std::shared_ptr(new GeomAlgoAPI_MakeShape(aFromCutBuilder))); - const TopTools_ListOfShape& aFromShapes = aFromCutBuilder->Modified(aFromShape); - for(TopTools_ListIteratorOfListOfShape anIt(aFromShapes); anIt.More(); anIt.Next()) { - std::shared_ptr aShape(new GeomAPI_Shape()); - aShape->setImpl(new TopoDS_Shape(anIt.Value())); - myFromFaces.push_back(aShape); - } - aResult = aFromCutBuilder->Shape(); - - TopExp_Explorer anExp(aResult, TopAbs_SOLID); - if(!anExp.More()) { - return; - } - if(aResult.ShapeType() == TopAbs_COMPOUND) { - aResult = GeomAlgoAPI_DFLoader::refineResult(aResult); - } - if(aResult.ShapeType() == TopAbs_COMPOUND) { - std::shared_ptr aCompound(new GeomAPI_Shape); - aCompound->setImpl(new TopoDS_Shape(aResult)); - ListOfShape aCompSolids, aFreeSolids; - GeomAlgoAPI_ShapeTools::combineShapes(aCompound, GeomAPI_Shape::COMPSOLID, aCompSolids, aFreeSolids); - if(aCompSolids.size() == 1 && aFreeSolids.size() == 0) { - aResult = aCompSolids.front()->impl(); - } else if (aCompSolids.size() > 1 || (aCompSolids.size() >= 1 && aFreeSolids.size() >= 1)) { - TopoDS_Compound aResultComp; - TopoDS_Builder aBuilder; - aBuilder.MakeCompound(aResultComp); - for(ListOfShape::const_iterator anIter = aCompSolids.cbegin(); anIter != aCompSolids.cend(); anIter++) { - aBuilder.Add(aResultComp, (*anIter)->impl()); - } - for(ListOfShape::const_iterator anIter = aFreeSolids.cbegin(); anIter != aFreeSolids.cend(); anIter++) { - aBuilder.Add(aResultComp, (*anIter)->impl()); + if(aResult.ShapeType() == TopAbs_COMPOUND) { + std::shared_ptr aCompound(new GeomAPI_Shape); + aCompound->setImpl(new TopoDS_Shape(aResult)); + ListOfShape aCompSolids, aFreeSolids; + GeomAlgoAPI_ShapeTools::combineShapes(aCompound, GeomAPI_Shape::COMPSOLID, aCompSolids, aFreeSolids); + if(aCompSolids.size() == 1 && aFreeSolids.size() == 0) { + aResult = aCompSolids.front()->impl(); + } else if (aCompSolids.size() > 1 || (aCompSolids.size() >= 1 && aFreeSolids.size() >= 1)) { + TopoDS_Compound aResultComp; + TopoDS_Builder aBuilder; + aBuilder.MakeCompound(aResultComp); + for(ListOfShape::const_iterator anIter = aCompSolids.cbegin(); anIter != aCompSolids.cend(); anIter++) { + aBuilder.Add(aResultComp, (*anIter)->impl()); + } + for(ListOfShape::const_iterator anIter = aFreeSolids.cbegin(); anIter != aFreeSolids.cend(); anIter++) { + aBuilder.Add(aResultComp, (*anIter)->impl()); + } + aResult = aResultComp; } - aResult = aResultComp; } - } - // Fill data map to keep correct orientation of sub-shapes. - myMap = std::shared_ptr(new GeomAPI_DataMapOfShapeShape); - for (TopExp_Explorer Exp(aResult,TopAbs_FACE); Exp.More(); Exp.Next()) { - std::shared_ptr aCurrentShape(new GeomAPI_Shape()); - aCurrentShape->setImpl(new TopoDS_Shape(Exp.Current())); - myMap->bind(aCurrentShape, aCurrentShape); + // Fill data map to keep correct orientation of sub-shapes. + myMap = std::shared_ptr(new GeomAPI_DataMapOfShapeShape); + for (TopExp_Explorer Exp(aResult,TopAbs_FACE); Exp.More(); Exp.Next()) { + std::shared_ptr aCurrentShape(new GeomAPI_Shape()); + aCurrentShape->setImpl(new TopoDS_Shape(Exp.Current())); + myMap->bind(aCurrentShape, aCurrentShape); + } + myShape = std::shared_ptr(new GeomAPI_Shape); + myShape->setImpl(new TopoDS_Shape(aResult)); + myMkShape = std::shared_ptr(new GeomAlgoAPI_MakeShapeList(aListOfMakeShape)); + myDone = true; } - myShape = std::shared_ptr(new GeomAPI_Shape); - myShape->setImpl(new TopoDS_Shape(aResult)); - myMkShape = std::shared_ptr(new GeomAlgoAPI_MakeShapeList(aListOfMakeShape)); - myDone = true; } //================================================================================================= -- 2.39.2