From 63c0bd9b8a64cc4b2c6f4177a7f727bef87d60d9 Mon Sep 17 00:00:00 2001 From: dbv Date: Fri, 27 May 2016 20:54:48 +0300 Subject: [PATCH] Allow Extrusion on compounds with edges and faces. --- .../FeaturesPlugin_CompositeSketch.cpp | 72 ++++++++-- .../FeaturesPlugin_Partition.cpp | 1 + src/FeaturesPlugin/extrusion_widget.xml | 2 +- src/FeaturesPlugin/extrusionfuse_widget.xml | 2 +- src/FeaturesPlugin/pipe_widget.xml | 2 +- src/FeaturesPlugin/revolution_widget.xml | 2 +- src/FeaturesPlugin/revolutionfuse_widget.xml | 2 +- src/GeomAlgoAPI/GeomAlgoAPI_MakeSweep.h | 20 +-- src/GeomAlgoAPI/GeomAlgoAPI_Prism.cpp | 136 ++++++++++++------ 9 files changed, 166 insertions(+), 73 deletions(-) diff --git a/src/FeaturesPlugin/FeaturesPlugin_CompositeSketch.cpp b/src/FeaturesPlugin/FeaturesPlugin_CompositeSketch.cpp index 309a4bd9d..bf8cc53e2 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_CompositeSketch.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_CompositeSketch.cpp @@ -25,6 +25,14 @@ #include #include +static void storeSubShape(ResultBodyPtr theResultBody, + const GeomShapePtr theShape, + const GeomAPI_Shape::ShapeType theType, + const std::shared_ptr theMapOfSubShapes, + const std::string theName, + int& theShapeIndex, + int& theTag); + //================================================================================================= void FeaturesPlugin_CompositeSketch::initCompositeSketchAttribtues(const int theInitFlags) { @@ -134,8 +142,7 @@ void FeaturesPlugin_CompositeSketch::getBaseShapes(ListOfShape& theBaseShapesLis GeomShapePtr aBaseShape = aBaseObjectSelection->value(); if(aBaseShape.get() && !aBaseShape->isNull()) { GeomAPI_Shape::ShapeType aST = aBaseShape->shapeType(); - if(aST != GeomAPI_Shape::VERTEX && aST != GeomAPI_Shape::EDGE && aST != GeomAPI_Shape::WIRE && - aST != GeomAPI_Shape::FACE && aST != GeomAPI_Shape::SHELL) { + if(aST == GeomAPI_Shape::SOLID || aST == GeomAPI_Shape::COMPSOLID) { setError("Error: Selected shapes has unsupported type."); return; } @@ -290,9 +297,19 @@ void FeaturesPlugin_CompositeSketch::storeGenerationHistory(ResultBodyPtr theRes aGenName += "Face"; break; } + case GeomAPI_Shape::COMPOUND: { + aShapeTypeToExplode = GeomAPI_Shape::COMPOUND; + } + } + + if(aShapeTypeToExplode == GeomAPI_Shape::VERTEX || aShapeTypeToExplode == GeomAPI_Shape::COMPOUND) { + theResultBody->loadAndOrientGeneratedShapes(theMakeShape.get(), theBaseShape, GeomAPI_Shape::VERTEX, + theTag++, aGenName + "Edge", *aMapOfSubShapes.get()); + } + if(aShapeTypeToExplode == GeomAPI_Shape::EDGE || aShapeTypeToExplode == GeomAPI_Shape::COMPOUND) { + theResultBody->loadAndOrientGeneratedShapes(theMakeShape.get(), theBaseShape, GeomAPI_Shape::EDGE, + theTag++, aGenName + "Face", *aMapOfSubShapes.get()); } - theResultBody->loadAndOrientGeneratedShapes(theMakeShape.get(), theBaseShape, aShapeTypeToExplode, - theTag++, aGenName, *aMapOfSubShapes.get()); std::shared_ptr aMakeSweep = std::dynamic_pointer_cast(theMakeShape); if(aMakeSweep.get()) { @@ -332,21 +349,50 @@ void FeaturesPlugin_CompositeSketch::storeShapes(ResultBodyPtr theResultBody, aShapeTypeStr = "Face"; break; } + case GeomAPI_Shape::COMPOUND: { + aShapeTypeToExplore = GeomAPI_Shape::COMPOUND; + break; + } } // Store shapes. int aShapeIndex = 1; - std::string aName = theName + aShapeTypeStr; + int aFaceIndex = 1; for(ListOfShape::const_iterator anIt = theShapes.cbegin(); anIt != theShapes.cend(); ++anIt) { GeomShapePtr aShape = *anIt; - for(GeomAPI_ShapeExplorer anExp(aShape, aShapeTypeToExplore); anExp.more(); anExp.next()) { - GeomShapePtr aSubShape = anExp.current(); - if(theMapOfSubShapes->isBound(aSubShape)) { - aSubShape = theMapOfSubShapes->find(aSubShape); - } - std::ostringstream aStr; - aStr << aName << "_" << aShapeIndex++; - theResultBody->generated(aSubShape, aStr.str(), theTag++); + + if(aShapeTypeToExplore == GeomAPI_Shape::COMPOUND) { + std::string aName = theName + (aShape->shapeType() == GeomAPI_Shape::EDGE ? "Edge" : "Face"); + storeSubShape(theResultBody, + aShape, + aShape->shapeType(), + theMapOfSubShapes, + aName, + aShape->shapeType() == GeomAPI_Shape::EDGE ? aShapeIndex : aFaceIndex, + theTag); + } else { + std::string aName = theName + aShapeTypeStr; + storeSubShape(theResultBody, aShape, aShapeTypeToExplore, + theMapOfSubShapes, aName, aShapeIndex, theTag); + } + } +} + +void storeSubShape(ResultBodyPtr theResultBody, + const GeomShapePtr theShape, + const GeomAPI_Shape::ShapeType theType, + const std::shared_ptr theMapOfSubShapes, + const std::string theName, + int& theShapeIndex, + int& theTag) +{ + for(GeomAPI_ShapeExplorer anExp(theShape, theType); anExp.more(); anExp.next()) { + GeomShapePtr aSubShape = anExp.current(); + if(theMapOfSubShapes->isBound(aSubShape)) { + aSubShape = theMapOfSubShapes->find(aSubShape); } + std::ostringstream aStr; + aStr << theName << "_" << theShapeIndex++; + theResultBody->generated(aSubShape, aStr.str(), theTag++); } } \ No newline at end of file diff --git a/src/FeaturesPlugin/FeaturesPlugin_Partition.cpp b/src/FeaturesPlugin/FeaturesPlugin_Partition.cpp index ec16dd41e..a105bd1db 100755 --- a/src/FeaturesPlugin/FeaturesPlugin_Partition.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Partition.cpp @@ -145,6 +145,7 @@ void FeaturesPlugin_Partition::storeResult(const ListOfShape& theObjects, // Store modified shape. if(aBaseShape->isEqual(theResultShape)) { aResultBody->store(theResultShape); + setResult(aResultBody, theIndex); return; } diff --git a/src/FeaturesPlugin/extrusion_widget.xml b/src/FeaturesPlugin/extrusion_widget.xml index d52aae72a..5951fccb1 100644 --- a/src/FeaturesPlugin/extrusion_widget.xml +++ b/src/FeaturesPlugin/extrusion_widget.xml @@ -15,7 +15,7 @@ tooltip="Select a base objects" type_choice="wires faces objects" concealment="true"> - + - + - + - + - + theShape); + GEOMALGOAPI_EXPORT void addFromShape(const std::shared_ptr theShape); /// \brief Sets from shapes /// \param[in] theListOfShapes list of from shapes. - void setFromShapes(const ListOfShape& theListOfShapes); + GEOMALGOAPI_EXPORT void setFromShapes(const ListOfShape& theListOfShapes); /// \brief Adds a face to list of to shape. /// \param[in] theShape a face to add. - void addToShape(const std::shared_ptr theShape); + GEOMALGOAPI_EXPORT void addToShape(const std::shared_ptr theShape); /// \brief Sets to shapes /// \param[in] theListOfShapes list of to shapes. - void setToShapes(const ListOfShape& theListOfShapes); + GEOMALGOAPI_EXPORT void setToShapes(const ListOfShape& theListOfShapes); + +protected: + /// Empty constructor. + GeomAlgoAPI_MakeSweep() : GeomAlgoAPI_MakeShapeList() {}; private: ListOfShape myFromShapes; diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Prism.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_Prism.cpp index 0c0136f17..49204ee90 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_Prism.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Prism.cpp @@ -39,7 +39,20 @@ #include #include -//================================================================================================= + +static void storeGenerationHistory(GeomAlgoAPI_Prism* thePrismAlgo, + const TopoDS_Shape& theBase, + const TopAbs_ShapeEnum theType, + BRepPrimAPI_MakePrism* thePrismBuilder); + +static void storeGenerationHistory(GeomAlgoAPI_Prism* thePrismAlgo, + const TopoDS_Shape& theResult, + const TopAbs_ShapeEnum theType, + const TopoDS_Face& theToFace, + const TopoDS_Face& theFromFace); + + +//================================================================================================== GeomAlgoAPI_Prism::GeomAlgoAPI_Prism(const GeomShapePtr theBaseShape, const double theToSize, const double theFromSize) @@ -47,7 +60,7 @@ GeomAlgoAPI_Prism::GeomAlgoAPI_Prism(const GeomShapePtr theBaseShape, build(theBaseShape, std::shared_ptr(), GeomShapePtr(), theToSize, GeomShapePtr(), theFromSize); } -//================================================================================================= +//================================================================================================== GeomAlgoAPI_Prism::GeomAlgoAPI_Prism(const GeomShapePtr theBaseShape, const std::shared_ptr theDirection, const double theToSize, @@ -56,7 +69,7 @@ GeomAlgoAPI_Prism::GeomAlgoAPI_Prism(const GeomShapePtr theBaseS build(theBaseShape, theDirection, GeomShapePtr(), theToSize, GeomShapePtr(), theFromSize); } -//================================================================================================= +//================================================================================================== GeomAlgoAPI_Prism::GeomAlgoAPI_Prism(const GeomShapePtr theBaseShape, const GeomShapePtr theToShape, const double theToSize, @@ -66,7 +79,7 @@ GeomAlgoAPI_Prism::GeomAlgoAPI_Prism(const GeomShapePtr theBaseShape, build(theBaseShape, std::shared_ptr(), theToShape, theToSize, theFromShape, theFromSize); } -//================================================================================================= +//================================================================================================== GeomAlgoAPI_Prism::GeomAlgoAPI_Prism(const GeomShapePtr theBaseShape, const std::shared_ptr theDirection, const GeomShapePtr theToShape, @@ -77,7 +90,7 @@ GeomAlgoAPI_Prism::GeomAlgoAPI_Prism(const GeomShapePtr theBaseS build(theBaseShape, theDirection, theToShape, theToSize, theFromShape, theFromSize); } -//================================================================================================= +//================================================================================================== void GeomAlgoAPI_Prism::build(const GeomShapePtr& theBaseShape, const std::shared_ptr theDirection, const GeomShapePtr& theToShape, @@ -106,6 +119,9 @@ void GeomAlgoAPI_Prism::build(const GeomShapePtr& theBaseShape, case TopAbs_SHELL: aShapeTypeToExp = TopAbs_FACE; break; + case TopAbs_COMPOUND: + aShapeTypeToExp = TopAbs_COMPOUND; + break; default: return; } @@ -193,13 +209,11 @@ void GeomAlgoAPI_Prism::build(const GeomShapePtr& theBaseShape, aResult = aPrismBuilder->Shape(); // Setting naming. - for(TopExp_Explorer anExp(aMovedBase, aShapeTypeToExp); anExp.More(); anExp.Next()) { - const TopoDS_Shape& aShape = anExp.Current(); - GeomShapePtr aFromShape(new GeomAPI_Shape), aToShape(new GeomAPI_Shape); - aFromShape->setImpl(new TopoDS_Shape(aPrismBuilder->FirstShape(aShape))); - aToShape->setImpl(new TopoDS_Shape(aPrismBuilder->LastShape(aShape))); - this->addFromShape(aFromShape); - this->addToShape(aToShape); + if(aShapeTypeToExp == TopAbs_COMPOUND) { + storeGenerationHistory(this, aMovedBase, TopAbs_EDGE, aPrismBuilder); + storeGenerationHistory(this, aMovedBase, TopAbs_FACE, aPrismBuilder); + } else { + storeGenerationHistory(this, aMovedBase, aShapeTypeToExp, aPrismBuilder); } } else { GeomShapePtr aBoundingFromShape = theFromShape ? theFromShape : aBasePlane; @@ -349,7 +363,7 @@ void GeomAlgoAPI_Prism::build(const GeomShapePtr& theBaseShape, if(aResult.ShapeType() == TopAbs_COMPOUND) { aResult = GeomAlgoAPI_DFLoader::refineResult(aResult); } - if(aShapeTypeToExp == TopAbs_FACE) { + if(aShapeTypeToExp == TopAbs_FACE || aShapeTypeToExp == TopAbs_COMPOUND) { const TopTools_ListOfShape& aToShapes = aToCutBuilder->Modified(aToShape); for(TopTools_ListIteratorOfListOfShape anIt(aToShapes); anIt.More(); anIt.Next()) { GeomShapePtr aGeomSh(new GeomAPI_Shape()); @@ -373,7 +387,7 @@ void GeomAlgoAPI_Prism::build(const GeomShapePtr& theBaseShape, if(aResult.ShapeType() == TopAbs_COMPOUND) { aResult = GeomAlgoAPI_DFLoader::refineResult(aResult); } - if(aShapeTypeToExp == TopAbs_FACE) { + if(aShapeTypeToExp == TopAbs_FACE || aShapeTypeToExp == TopAbs_COMPOUND) { const TopTools_ListOfShape& aFromShapes = aFromCutBuilder->Modified(aFromShape); for(TopTools_ListIteratorOfListOfShape anIt(aFromShapes); anIt.More(); anIt.Next()) { GeomShapePtr aGeomSh(new GeomAPI_Shape()); @@ -383,37 +397,11 @@ void GeomAlgoAPI_Prism::build(const GeomShapePtr& theBaseShape, } // Naming for extrusion from vertex, edge. - for(TopExp_Explorer anExp(aResult, aShapeTypeToExp); anExp.More(); anExp.Next()) { - const TopoDS_Shape& aShape = anExp.Current(); - GeomShapePtr aGeomSh(new GeomAPI_Shape()); - if(aShapeTypeToExp == TopAbs_VERTEX) { - gp_Pnt aPnt = BRep_Tool::Pnt(TopoDS::Vertex(aShape)); - IntTools_Context anIntTools; - if(anIntTools.IsValidPointForFace(aPnt, aToFace, Precision::Confusion()) == Standard_True) { - aGeomSh->setImpl(new TopoDS_Shape(aShape)); - this->addToShape(aGeomSh); - } - if(anIntTools.IsValidPointForFace(aPnt, aFromFace, Precision::Confusion()) == Standard_True) { - aGeomSh->setImpl(new TopoDS_Shape(aShape)); - this->addFromShape(aGeomSh); - } - } else if(aShapeTypeToExp == TopAbs_EDGE) { - TopoDS_Edge anEdge = TopoDS::Edge(aShape); - BRepLib_CheckCurveOnSurface anEdgeCheck(anEdge, aToFace); - anEdgeCheck.Perform(); - if(anEdgeCheck.MaxDistance() < Precision::Confusion()) { - aGeomSh->setImpl(new TopoDS_Shape(aShape)); - this->addToShape(aGeomSh); - } - anEdgeCheck.Init(anEdge, aFromFace); - anEdgeCheck.Perform(); - if(anEdgeCheck.MaxDistance() < Precision::Confusion()) { - aGeomSh->setImpl(new TopoDS_Shape(aShape)); - this->addFromShape(aGeomSh); - } - } else { - break; - } + if(aShapeTypeToExp == TopAbs_COMPOUND) { + storeGenerationHistory(this, aResult, TopAbs_EDGE, aToFace, aFromFace); + storeGenerationHistory(this, aResult, TopAbs_FACE, aToFace, aFromFace); + } else { + storeGenerationHistory(this, aResult, aShapeTypeToExp, aToFace, aFromFace); } if(aResult.ShapeType() == TopAbs_COMPOUND) { @@ -438,3 +426,61 @@ void GeomAlgoAPI_Prism::build(const GeomShapePtr& theBaseShape, this->setShape(aGeomSh); this->setDone(true); } + +// Auxilary functions: +//================================================================================================== +void storeGenerationHistory(GeomAlgoAPI_Prism* thePrismAlgo, + const TopoDS_Shape& theBase, + const TopAbs_ShapeEnum theType, + BRepPrimAPI_MakePrism* thePrismBuilder) +{ + for(TopExp_Explorer anExp(theBase, theType); anExp.More(); anExp.Next()) { + const TopoDS_Shape& aShape = anExp.Current(); + GeomShapePtr aFromShape(new GeomAPI_Shape), aToShape(new GeomAPI_Shape); + aFromShape->setImpl(new TopoDS_Shape(thePrismBuilder->FirstShape(aShape))); + aToShape->setImpl(new TopoDS_Shape(thePrismBuilder->LastShape(aShape))); + thePrismAlgo->addFromShape(aFromShape); + thePrismAlgo->addToShape(aToShape); + } +} + +//================================================================================================== +void storeGenerationHistory(GeomAlgoAPI_Prism* thePrismAlgo, + const TopoDS_Shape& theResult, + const TopAbs_ShapeEnum theType, + const TopoDS_Face& theToFace, + const TopoDS_Face& theFromFace) +{ + for(TopExp_Explorer anExp(theResult, theType); anExp.More(); anExp.Next()) { + const TopoDS_Shape& aShape = anExp.Current(); + GeomShapePtr aGeomSh(new GeomAPI_Shape()); + if(theType == TopAbs_VERTEX) { + gp_Pnt aPnt = BRep_Tool::Pnt(TopoDS::Vertex(aShape)); + IntTools_Context anIntTools; + if(anIntTools.IsValidPointForFace(aPnt, theToFace, Precision::Confusion()) == Standard_True) { + aGeomSh->setImpl(new TopoDS_Shape(aShape)); + thePrismAlgo->addToShape(aGeomSh); + } + if(anIntTools.IsValidPointForFace(aPnt, theFromFace, Precision::Confusion()) == Standard_True) { + aGeomSh->setImpl(new TopoDS_Shape(aShape)); + thePrismAlgo->addFromShape(aGeomSh); + } + } else if(theType == TopAbs_EDGE) { + TopoDS_Edge anEdge = TopoDS::Edge(aShape); + BRepLib_CheckCurveOnSurface anEdgeCheck(anEdge, theToFace); + anEdgeCheck.Perform(); + if(anEdgeCheck.MaxDistance() < Precision::Confusion()) { + aGeomSh->setImpl(new TopoDS_Shape(aShape)); + thePrismAlgo->addToShape(aGeomSh); + } + anEdgeCheck.Init(anEdge, theFromFace); + anEdgeCheck.Perform(); + if(anEdgeCheck.MaxDistance() < Precision::Confusion()) { + aGeomSh->setImpl(new TopoDS_Shape(aShape)); + thePrismAlgo->addFromShape(aGeomSh); + } + } else { + break; + } + } +} -- 2.39.2