From 1c764f170c88bd963380e9a8e08a8fcbe851667c Mon Sep 17 00:00:00 2001 From: dbv Date: Wed, 13 Apr 2016 15:51:39 +0300 Subject: [PATCH] Issue #1343: Make faces with/without holes from sketch wires. --- .../FeaturesPlugin_CompositeSketch.cpp | 39 +++++++++++++-- src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.cpp | 48 +++++++++++++++++-- src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.h | 26 ++++++---- 3 files changed, 95 insertions(+), 18 deletions(-) diff --git a/src/FeaturesPlugin/FeaturesPlugin_CompositeSketch.cpp b/src/FeaturesPlugin/FeaturesPlugin_CompositeSketch.cpp index 5e7c13d43..114b0a3b1 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_CompositeSketch.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_CompositeSketch.cpp @@ -17,8 +17,12 @@ #include #include #include +#include + +#include #include +#include #include //================================================================================================= @@ -111,6 +115,7 @@ void FeaturesPlugin_CompositeSketch::getBaseShapes(ListOfShape& theBaseShapesLis theBaseShapesList.clear(); ListOfShape aBaseFacesList; + std::map aSketchWiresMap; AttributeSelectionListPtr aBaseObjectsSelectionList = selectionList(BASE_OBJECTS_ID()); if(!aBaseObjectsSelectionList.get()) { setError("Error: Could not get base objects selection list."); @@ -123,7 +128,7 @@ void FeaturesPlugin_CompositeSketch::getBaseShapes(ListOfShape& theBaseShapesLis for(int anIndex = 0; anIndex < aBaseObjectsSelectionList->size(); anIndex++) { AttributeSelectionPtr aBaseObjectSelection = aBaseObjectsSelectionList->value(anIndex); if(!aBaseObjectSelection.get()) { - setError("Error: One of the selected base objects is empty."); + setError("Error: Selected base object is empty."); return; } GeomShapePtr aBaseShape = aBaseObjectSelection->value(); @@ -134,14 +139,24 @@ void FeaturesPlugin_CompositeSketch::getBaseShapes(ListOfShape& theBaseShapesLis setError("Error: Selected shapes has unsupported type."); return; } - aST == GeomAPI_Shape::FACE ? aBaseFacesList.push_back(aBaseShape) : - theBaseShapesList.push_back(aBaseShape); + if(aST == GeomAPI_Shape::WIRE) { + ResultConstructionPtr aConstruction = + std::dynamic_pointer_cast(aBaseObjectSelection->context()); + if(aConstruction.get() && !aBaseShape->isEqual(aConstruction->shape())) { + // It is a wire on the sketch, store it to make face later. + aSketchWiresMap[aConstruction].push_back(aBaseShape); + continue; + } + } else { + aST == GeomAPI_Shape::FACE ? aBaseFacesList.push_back(aBaseShape) : + theBaseShapesList.push_back(aBaseShape); + } } else { // This may be the whole sketch result selected, check and get faces. ResultConstructionPtr aConstruction = std::dynamic_pointer_cast(aBaseObjectSelection->context()); if(!aConstruction.get()) { - setError("Error: One of selected sketches does not have results."); + setError("Error: Selected sketches does not have results."); return; } int aFacesNum = aConstruction->facesNum(); @@ -162,7 +177,7 @@ void FeaturesPlugin_CompositeSketch::getBaseShapes(ListOfShape& theBaseShapesLis for(int aFaceIndex = 0; aFaceIndex < aFacesNum; aFaceIndex++) { GeomShapePtr aBaseFace = aConstruction->face(aFaceIndex); if(!aBaseFace.get() || aBaseFace->isNull()) { - setError("Error: One of the faces on selected sketch is Null."); + setError("Error: One of the faces on selected sketch is null."); return; } aBaseFacesList.push_back(aBaseFace); @@ -171,6 +186,20 @@ void FeaturesPlugin_CompositeSketch::getBaseShapes(ListOfShape& theBaseShapesLis } } + // Make faces from sketch wires. + for(std::map::const_iterator anIt = aSketchWiresMap.cbegin(); + anIt != aSketchWiresMap.cend(); ++anIt) { + const std::shared_ptr aSketchPlanarEdges = + std::dynamic_pointer_cast((*anIt).first->shape()); + const ListOfShape& aWiresList = (*anIt).second; + ListOfShape aFaces; + GeomAlgoAPI_ShapeTools::makeFacesWithHoles(aSketchPlanarEdges->origin(), + aSketchPlanarEdges->norm(), + aWiresList, + aFaces); + aBaseFacesList.insert(aBaseFacesList.end(), aFaces.begin(), aFaces.end()); + } + // Searching faces with common edges. if(theIsMakeShells) { ListOfShape aShells; diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.cpp index fda821e1f..f793d5b0e 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.cpp @@ -4,28 +4,31 @@ // Created: 3 August 2015 // Author: Dmitry Bobylev -#include +#include "GeomAlgoAPI_ShapeTools.h" -#include +#include "GeomAlgoAPI_SketchBuilder.h" -#include +#include +#include +#include #include #include +#include +#include #include #include #include -#include #include #include #include #include +#include #include #include #include #include #include -#include #include #include #include @@ -35,6 +38,9 @@ #include +void mapWireFaces(const TopoDS_Shape& theShape, + BOPCol_IndexedDataMapOfShapeListOfShape& theMapWireFaces); + //================================================================================================= double GeomAlgoAPI_ShapeTools::volume(const std::shared_ptr theShape) { @@ -333,3 +339,35 @@ void GeomAlgoAPI_ShapeTools::findBounds(const std::shared_ptr the theV1 = aGeomV1; theV2 = aGeomV2; } + +//================================================================================================= +void GeomAlgoAPI_ShapeTools::makeFacesWithHoles(const std::shared_ptr theOrigin, + const std::shared_ptr theDirection, + const ListOfShape& theWires, + ListOfShape& theFaces) +{ + BRepBuilderAPI_MakeFace aMKFace(gp_Pln(theOrigin->impl(), + theDirection->impl())); + TopoDS_Face aFace = aMKFace.Face(); + + BRepAlgo_FaceRestrictor aFRestrictor; + aFRestrictor.Init(aFace); + for(ListOfShape::const_iterator anIt = theWires.cbegin(); + anIt != theWires.cend(); + ++anIt) { + TopoDS_Wire aWire = TopoDS::Wire((*anIt)->impl()); + aFRestrictor.Add(aWire); + } + + aFRestrictor.Perform(); + + if(!aFRestrictor.IsDone()) { + return; + } + + for(; aFRestrictor.More(); aFRestrictor.Next()) { + GeomShapePtr aShape(new GeomAPI_Shape()); + aShape->setImpl(new TopoDS_Shape(aFRestrictor.Current())); + theFaces.push_back(aShape); + } +} diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.h b/src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.h index 8726f670a..6e2364218 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.h +++ b/src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.h @@ -9,10 +9,13 @@ #include "GeomAlgoAPI.h" -#include #include #include +class GeomAPI_Dir; +class GeomAPI_PlanarEdges; +class GeomAPI_Pnt; + /// \class GeomAlgoAPI_ShapeTools /// \ingroup DataAlgo /// \brief Useful tools for working with shapes. @@ -20,18 +23,18 @@ class GEOMALGOAPI_EXPORT GeomAlgoAPI_ShapeTools { public: /// \return the total volume of the solids of the current shape or 0.0 if it can be computed. - static double volume(const std::shared_ptr theShape); + static double volume(const GeomShapePtr theShape); /// \return the centre of mass of the current face. The coordinates returned for the center of mass /// are expressed in the absolute Cartesian coordinate system. (This function works only for surfaces). - static std::shared_ptr centreOfMass(const std::shared_ptr theShape); + static std::shared_ptr centreOfMass(const GeomShapePtr theShape); /// \brief Combines faces with common edges to shells, or solids to compsolids. /// \param[in] theCompound compound of shapes. /// \param[in] theType type of combine. /// \param[out] theCombinedShapes resulting shapes. /// \param[out] theFreeShapes shapes that does not have common subshapes. - static void combineShapes(const std::shared_ptr theCompound, + static void combineShapes(const GeomShapePtr theCompound, const GeomAPI_Shape::ShapeType theType, ListOfShape& theCombinedShapes, ListOfShape& theFreeShapes); @@ -43,14 +46,14 @@ public: static std::list > getBoundingBox(const ListOfShape& theShapes, const double theEnlarge = 0.0); /// \return infinite plane received from theFace plane. - static std::shared_ptr faceToInfinitePlane(const std::shared_ptr theFace); + static GeomShapePtr faceToInfinitePlane(const GeomShapePtr theFace); /// \brief Enlarges or reduces plane to fit bounding box. /// \return plane that fits to bounding box. /// \param[in] thePlane base plane. /// \param[in] thePoints bounding box points (shoud be eight). - static std::shared_ptr fitPlaneToBox(const std::shared_ptr thePlane, - const std::list >& thePoints); + static GeomShapePtr fitPlaneToBox(const GeomShapePtr thePlane, + const std::list >& thePoints); /// \brief Finds the start and end vertices of theShape. theShape can be of the following type:\n /// Vertex: theV1 and theV2 are the same and equal to theShape;\n @@ -58,10 +61,17 @@ public: /// Wire : theV1 is start vertex of the first edge, theV2 is end vertex of the last edge. If wire /// contains no edges theV1 and theV2 are nullified.\n /// If none of the above theV1 and theV2 are nullified. - static void findBounds(const std::shared_ptr theShape, + static void findBounds(const GeomShapePtr theShape, std::shared_ptr& theV1, std::shared_ptr& theV2); + /// \Creates faces with holes from wires. + /// \param[in] theWires base wires. + /// \param[out] theFaces resulting faces. + static void makeFacesWithHoles(const std::shared_ptr theOrigin, + const std::shared_ptr theDirection, + const ListOfShape& theWires, + ListOfShape& theFaces); }; #endif -- 2.39.2