From: azv Date: Mon, 25 Feb 2019 11:41:30 +0000 (+0300) Subject: High level objects history implementation for BuildPlugin features. X-Git-Tag: HighLevelObjectsHierarchy~13^2~1 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=696c11e9e4cb089e1c5496dac79420147d85496a;p=modules%2Fshaper.git High level objects history implementation for BuildPlugin features. --- diff --git a/src/BuildPlugin/BuildPlugin_CompSolid.cpp b/src/BuildPlugin/BuildPlugin_CompSolid.cpp index 0fdb399fa..7b94fff13 100644 --- a/src/BuildPlugin/BuildPlugin_CompSolid.cpp +++ b/src/BuildPlugin/BuildPlugin_CompSolid.cpp @@ -33,25 +33,3 @@ void BuildPlugin_CompSolid::initAttributes() { data()->addAttribute(BASE_OBJECTS_ID(), ModelAPI_AttributeSelectionList::typeId()); } - -//================================================================================================= -void BuildPlugin_CompSolid::execute() -{ - // all the needed checkings are in validator, so, here just make and store result - ListOfShape anOriginalShapes; - AttributeSelectionListPtr aSelectionList = selectionList(BASE_OBJECTS_ID()); - for (int anIndex = 0; anIndex < aSelectionList->size(); ++anIndex) { - AttributeSelectionPtr aSelection = aSelectionList->value(anIndex); - GeomShapePtr aShape = aSelection->value(); - if (!aShape.get()) - aShape = aSelection->context()->shape(); - anOriginalShapes.push_back(aShape); - } - std::shared_ptr anAlgo( - new GeomAlgoAPI_MakeVolume(anOriginalShapes, false)); - GeomShapePtr aVolumeRes = anAlgo->shape(); - - // check and process result of volume maker - GeomShapePtr aResShape = getSingleSubshape(aVolumeRes); - storeResult(anOriginalShapes, aResShape, anAlgo); -} diff --git a/src/BuildPlugin/BuildPlugin_CompSolid.h b/src/BuildPlugin/BuildPlugin_CompSolid.h index e31865a13..ae99a1eda 100644 --- a/src/BuildPlugin/BuildPlugin_CompSolid.h +++ b/src/BuildPlugin/BuildPlugin_CompSolid.h @@ -56,9 +56,6 @@ public: /// Request for initialization of data model of the feature: adding all attributes. BUILDPLUGIN_EXPORT virtual void initAttributes(); - - /// Creates a new part document if needed. - BUILDPLUGIN_EXPORT virtual void execute(); }; #endif diff --git a/src/BuildPlugin/BuildPlugin_Edge.cpp b/src/BuildPlugin/BuildPlugin_Edge.cpp index 28be282f6..ee1339f52 100644 --- a/src/BuildPlugin/BuildPlugin_Edge.cpp +++ b/src/BuildPlugin/BuildPlugin_Edge.cpp @@ -87,7 +87,10 @@ void BuildPlugin_Edge::execute() // Store result. ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex); - aResultBody->storeModified(aShape, aCopyAlgo->shape()); + + ListOfShape aBaseShapes; + aBaseShapes.push_back(aShape); + aResultBody->storeModified(aBaseShapes, aCopyAlgo->shape(), aCopyAlgo); aResultBody->loadModifiedShapes(aCopyAlgo, aShape, GeomAPI_Shape::VERTEX); setResult(aResultBody, aResultIndex); diff --git a/src/BuildPlugin/BuildPlugin_Face.cpp b/src/BuildPlugin/BuildPlugin_Face.cpp index c7992999a..a840fd5de 100644 --- a/src/BuildPlugin/BuildPlugin_Face.cpp +++ b/src/BuildPlugin/BuildPlugin_Face.cpp @@ -28,6 +28,7 @@ #include #include +#include #include #include #include @@ -60,6 +61,9 @@ void BuildPlugin_Face::execute() // Collect base shapes. ListOfShape anEdges; ListOfShape anOriginalFaces; + ListOfShape aContexts; + getOriginalShapesAndContexts(BASE_OBJECTS_ID(), anOriginalFaces, aContexts); + anOriginalFaces.clear(); std::list< std::shared_ptr > aListOfNormals; for(int anIndex = 0; anIndex < aSelectionList->size(); ++anIndex) { AttributeSelectionPtr aSelection = aSelectionList->value(anIndex); @@ -88,8 +92,10 @@ void BuildPlugin_Face::execute() // Build faces by edges. ListOfShape aFaces; + GeomMakeShapePtr aFaceBuilder; if (!anEdges.empty()) - buildFacesByEdges(anEdges, aListOfNormals, aFaces); + buildFacesByEdges(anEdges, aListOfNormals, aFaces, aFaceBuilder); + int aNbFacesFromEdges = (int)aFaces.size(); // Add faces selected by user. aFaces.insert(aFaces.end(), anOriginalFaces.begin(), anOriginalFaces.end()); @@ -97,22 +103,17 @@ void BuildPlugin_Face::execute() // Store result. int anIndex = 0; for(ListOfShape::const_iterator anIt = aFaces.cbegin(); anIt != aFaces.cend(); ++anIt) { - ResultBodyPtr aResultBody = document()->createBody(data(), anIndex); - GeomShapePtr aShape = *anIt; - GeomAlgoAPI_Copy aCopy(aShape); - aShape = aCopy.shape(); - aResultBody->store(aShape); + std::shared_ptr aMakeShapeList(new GeomAlgoAPI_MakeShapeList); + if (anIndex < aNbFacesFromEdges) + aMakeShapeList->appendAlgo(aFaceBuilder); - // Store edges. - int anEdgeIndex = 1; - for(GeomAPI_ShapeExplorer anExp(aShape, GeomAPI_Shape::EDGE); anExp.more(); anExp.next()) { - GeomShapePtr anEdge = anExp.current(); - aResultBody->generated(anEdge, "Edge_" + std::to_string((long long)anEdgeIndex)); - ++anEdgeIndex; - } + GeomShapePtr aShape = *anIt; + GeomMakeShapePtr aCopy(new GeomAlgoAPI_Copy(aShape)); + aMakeShapeList->appendAlgo(aCopy); - setResult(aResultBody, anIndex); - ++anIndex; + ListOfShape aBaseShapes; + aBaseShapes.push_back(aShape); + storeResult(aMakeShapeList, aBaseShapes, aContexts, aCopy->shape(), anIndex++); } removeResults(anIndex); @@ -121,7 +122,8 @@ void BuildPlugin_Face::execute() void BuildPlugin_Face::buildFacesByEdges( const ListOfShape& theEdges, const std::list< std::shared_ptr >& theNormals, - ListOfShape& theFaces) const + ListOfShape& theFaces, + std::shared_ptr& theBuilderAlgo) const { // Get plane. std::shared_ptr aPln = GeomAlgoAPI_ShapeTools::findPlane(theEdges); @@ -137,8 +139,10 @@ void BuildPlugin_Face::buildFacesByEdges( } // Get faces. - GeomAlgoAPI_SketchBuilder::createFaces(aPln->location(), aPln->xDirection(), - aPln->direction(), theEdges, theFaces); + std::shared_ptr aSketchBuilder( + new GeomAlgoAPI_SketchBuilder(aPln, theEdges)); + theFaces = aSketchBuilder->faces(); + theBuilderAlgo = aSketchBuilder; // Get wires from faces. ListOfShape aWires; diff --git a/src/BuildPlugin/BuildPlugin_Face.h b/src/BuildPlugin/BuildPlugin_Face.h index 633118eb7..ad5fd4a97 100644 --- a/src/BuildPlugin/BuildPlugin_Face.h +++ b/src/BuildPlugin/BuildPlugin_Face.h @@ -22,16 +22,16 @@ #define BuildPlugin_Face_H_ #include "BuildPlugin.h" - -#include +#include "BuildPlugin_Shape.h" class GeomAPI_Dir; class GeomAPI_Shape; +class GeomAlgoAPI_MakeShape; /// \class BuildPlugin_Face /// \ingroup Plugins /// \brief Feature for creation of face from sketch edges or existing wires. -class BuildPlugin_Face: public ModelAPI_Feature +class BuildPlugin_Face: public BuildPlugin_Shape { public: /// Use plugin manager for features creation @@ -68,7 +68,8 @@ private: /// Create faces basing on the list of edges void buildFacesByEdges(const std::list< std::shared_ptr >& theEdges, const std::list< std::shared_ptr >& theNormals, - std::list< std::shared_ptr >& theFaces) const; + std::list< std::shared_ptr >& theFaces, + std::shared_ptr& theBuilderAlgo) const; }; #endif diff --git a/src/BuildPlugin/BuildPlugin_Shape.cpp b/src/BuildPlugin/BuildPlugin_Shape.cpp new file mode 100644 index 000000000..60c273c59 --- /dev/null +++ b/src/BuildPlugin/BuildPlugin_Shape.cpp @@ -0,0 +1,78 @@ +// Copyright (C) 2014-2017 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 "BuildPlugin_Shape.h" + +#include +#include + +#include + +#include + + +//================================================================================================= +void BuildPlugin_Shape::storeResult(const GeomMakeShapePtr& theAlgorithm, + const ListOfShape& theOriginalShapes, + const ListOfShape& theOriginalSolids, + const GeomShapePtr& theResultShape, + const int theResultIndex) +{ + ResultBodyPtr aResultBody = document()->createBody(data(), theResultIndex); + aResultBody->storeModified(theOriginalSolids, theResultShape, theAlgorithm); + + for (ListOfShape::const_iterator anIt = theOriginalShapes.cbegin(); + anIt != theOriginalShapes.cend(); + ++anIt) + { + GeomShapePtr aShape = *anIt; + aResultBody->loadModifiedShapes(theAlgorithm, aShape, GeomAPI_Shape::VERTEX); + aResultBody->loadModifiedShapes(theAlgorithm, aShape, GeomAPI_Shape::EDGE); + aResultBody->loadModifiedShapes(theAlgorithm, aShape, GeomAPI_Shape::FACE); + } + setResult(aResultBody, theResultIndex); +} + +//================================================================================================= +void BuildPlugin_Shape::getOriginalShapesAndContexts(const std::string& theSelectionListID, + ListOfShape& theShapes, + ListOfShape& theContexts) +{ + std::set aContexts; + + AttributeSelectionListPtr aSelectionList = selectionList(theSelectionListID); + for (int anIndex = 0; anIndex < aSelectionList->size(); ++anIndex) { + AttributeSelectionPtr aSelection = aSelectionList->value(anIndex); + GeomShapePtr aShape = aSelection->value(); + GeomShapePtr aContext = aSelection->context()->shape(); + if (!aShape.get()) + aShape = aContext; + theShapes.push_back(aShape); + + // do not collect sketch faces, because they are stored as compounds + // and then are treated as modified by the algorithm + if (!std::dynamic_pointer_cast(aContext).get()) + aContexts.insert(aContext); + } + + std::set::const_iterator anIt = aContexts.begin(); + for (; anIt != aContexts.end(); ++anIt) + theContexts.push_back(*anIt); +} diff --git a/src/BuildPlugin/BuildPlugin_Shape.h b/src/BuildPlugin/BuildPlugin_Shape.h new file mode 100644 index 000000000..e858ca142 --- /dev/null +++ b/src/BuildPlugin/BuildPlugin_Shape.h @@ -0,0 +1,51 @@ +// Copyright (C) 2014-2017 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 +// + +#ifndef BuildPlugin_Shape_H_ +#define BuildPlugin_Shape_H_ + +#include "BuildPlugin.h" + +#include + +#include + +class GeomAlgoAPI_MakeShape; + +/// \class BuildPlugin_Shape +/// \ingroup Plugins +/// \brief Base class containing common methods for shape creating operations. +class BuildPlugin_Shape: public ModelAPI_Feature +{ +protected: + /// Obtain list of selected shapes and their contexts + void getOriginalShapesAndContexts(const std::string& theSelectionListID, + ListOfShape& theShapes, + ListOfShape& theContexts); + + /// Store result of algorithm + void storeResult(const std::shared_ptr& theAlgorithm, + const ListOfShape& theOriginalShapes, + const ListOfShape& theOriginalContexts, + const GeomShapePtr& theResultShape, + const int theResultIndex = 0); +}; + +#endif diff --git a/src/BuildPlugin/BuildPlugin_Shell.cpp b/src/BuildPlugin/BuildPlugin_Shell.cpp index bd73c2f1f..4e27b66c2 100644 --- a/src/BuildPlugin/BuildPlugin_Shell.cpp +++ b/src/BuildPlugin/BuildPlugin_Shell.cpp @@ -46,15 +46,8 @@ void BuildPlugin_Shell::execute() AttributeSelectionListPtr aSelectionList = selectionList(BASE_OBJECTS_ID()); // Collect base shapes. - ListOfShape aShapes; - for(int anIndex = 0; anIndex < aSelectionList->size(); ++anIndex) { - AttributeSelectionPtr aSelection = aSelectionList->value(anIndex); - GeomShapePtr aShape = aSelection->value(); - if(!aShape.get()) { - aShape = aSelection->context()->shape(); - } - aShapes.push_back(aShape); - } + ListOfShape aShapes, aContexts; + getOriginalShapesAndContexts(BASE_OBJECTS_ID(), aShapes, aContexts); // Sew faces. GeomMakeShapePtr aSewingAlgo(new GeomAlgoAPI_Sewing(aShapes)); @@ -71,35 +64,7 @@ void BuildPlugin_Shell::execute() int anIndex = 0; for(GeomAPI_ShapeExplorer anExp(aResult, GeomAPI_Shape::SHELL); anExp.more(); anExp.next()) { GeomShapePtr aShell = anExp.current(); - ResultBodyPtr aResultBody = document()->createBody(data(), anIndex); - aResultBody->store(aShell); - for(ListOfShape::const_iterator anIt = aShapes.cbegin(); anIt != aShapes.cend(); ++anIt) { - for (GeomAPI_ShapeExplorer aFaceExp(*anIt, GeomAPI_Shape::FACE); - aFaceExp.more(); - aFaceExp.next()) - { - GeomShapePtr aFace = aFaceExp.current(); - ListOfShape aHistory; - aSewingAlgo->modified(aFace, aHistory); - for (ListOfShape::const_iterator aHistoryIt = aHistory.cbegin(); - aHistoryIt != aHistory.cend(); - ++aHistoryIt) - { - GeomShapePtr aHistoryShape = *aHistoryIt; - if (aShell->isSubShape(aHistoryShape, false)) { - aResultBody->loadModifiedShapes(aSewingAlgo, - aFace, - GeomAPI_Shape::EDGE); - aResultBody->loadModifiedShapes(aSewingAlgo, - aFace, - GeomAPI_Shape::FACE); - break; - } - } - } - } - setResult(aResultBody, anIndex); - ++anIndex; + storeResult(aSewingAlgo, aShapes, aContexts, aShell, anIndex++); } removeResults(anIndex); diff --git a/src/BuildPlugin/BuildPlugin_Shell.h b/src/BuildPlugin/BuildPlugin_Shell.h index 4fe6d2fdb..3b7245482 100644 --- a/src/BuildPlugin/BuildPlugin_Shell.h +++ b/src/BuildPlugin/BuildPlugin_Shell.h @@ -22,13 +22,12 @@ #define BuildPlugin_Shell_H_ #include "BuildPlugin.h" - -#include +#include "BuildPlugin_Shape.h" /// \class BuildPlugin_Shell /// \ingroup Plugins /// \brief Feature for creation of shell from faces and shells. -class BuildPlugin_Shell: public ModelAPI_Feature +class BuildPlugin_Shell: public BuildPlugin_Shape { public: /// Use plugin manager for features creation diff --git a/src/BuildPlugin/BuildPlugin_Solid.cpp b/src/BuildPlugin/BuildPlugin_Solid.cpp index dc0c57ed5..399289537 100644 --- a/src/BuildPlugin/BuildPlugin_Solid.cpp +++ b/src/BuildPlugin/BuildPlugin_Solid.cpp @@ -23,6 +23,7 @@ #include #include +#include #include #include @@ -42,38 +43,15 @@ void BuildPlugin_Solid::initAttributes() void BuildPlugin_Solid::execute() { // all the needed checkings are in validator, so, here just make and store result - ListOfShape anOriginalShapes; - AttributeSelectionListPtr aSelectionList = selectionList(BASE_OBJECTS_ID()); - for (int anIndex = 0; anIndex < aSelectionList->size(); ++anIndex) { - AttributeSelectionPtr aSelection = aSelectionList->value(anIndex); - GeomShapePtr aShape = aSelection->value(); - if (!aShape.get()) - aShape = aSelection->context()->shape(); - anOriginalShapes.push_back(aShape); - } + ListOfShape anOriginalFaces; + ListOfShape anOriginalSolids; + getOriginalShapesAndContexts(BASE_OBJECTS_ID(), anOriginalFaces, anOriginalSolids); + std::shared_ptr anAlgo( - new GeomAlgoAPI_MakeVolume(anOriginalShapes, false)); + new GeomAlgoAPI_MakeVolume(anOriginalFaces, false)); // check and process result of volume maker GeomShapePtr aResShape = getSingleSubshape(anAlgo->shape()); - storeResult(anOriginalShapes, aResShape, anAlgo); -} - -void BuildPlugin_Solid::storeResult(const ListOfShape& theOriginalShapes, - const GeomShapePtr& theResultShape, - const GeomMakeShapePtr& theAlgorithm) -{ - ResultBodyPtr aResultBody = document()->createBody(data()); - aResultBody->store(theResultShape); - - // Store faces - for (ListOfShape::const_iterator anIt = theOriginalShapes.cbegin(); - anIt != theOriginalShapes.cend(); - ++anIt) - { - GeomShapePtr aShape = *anIt; - aResultBody->loadModifiedShapes(theAlgorithm, aShape, GeomAPI_Shape::FACE); - } - setResult(aResultBody); + storeResult(anAlgo, anOriginalFaces, anOriginalSolids, aResShape); } GeomShapePtr BuildPlugin_Solid::getSingleSubshape(const GeomShapePtr& theCompound) diff --git a/src/BuildPlugin/BuildPlugin_Solid.h b/src/BuildPlugin/BuildPlugin_Solid.h index 1fce3df58..1ab5168e5 100644 --- a/src/BuildPlugin/BuildPlugin_Solid.h +++ b/src/BuildPlugin/BuildPlugin_Solid.h @@ -22,16 +22,12 @@ #define BuildPlugin_Solid_H_ #include "BuildPlugin.h" - -#include -#include - -class GeomAlgoAPI_MakeShape; +#include "BuildPlugin_Shape.h" /// \class BuildPlugin_Solid /// \ingroup Plugins /// \brief Feature for creation of solid from faces or shells. -class BuildPlugin_Solid: public ModelAPI_Feature +class BuildPlugin_Solid: public BuildPlugin_Shape { public: /// Use plugin manager for features creation @@ -65,11 +61,6 @@ public: BUILDPLUGIN_EXPORT virtual void execute(); protected: - /// Store result of algorithm - void storeResult(const ListOfShape& theOriginalShapes, - const GeomShapePtr& theResultShape, - const std::shared_ptr& theAlgorithm); - /// Explode compound to get single shape GeomShapePtr getSingleSubshape(const GeomShapePtr& theCompound); }; diff --git a/src/BuildPlugin/BuildPlugin_Validators.cpp b/src/BuildPlugin/BuildPlugin_Validators.cpp index 3b4c4b950..de035b915 100644 --- a/src/BuildPlugin/BuildPlugin_Validators.cpp +++ b/src/BuildPlugin/BuildPlugin_Validators.cpp @@ -247,9 +247,8 @@ bool BuildPlugin_ValidatorBaseForFace::isValid(const std::shared_ptrlocation(), aPln->xDirection(), - aPln->direction(), anEdges, aFaces); + GeomAlgoAPI_SketchBuilder aBuilder(aPln, anEdges); + const ListOfShape& aFaces = aBuilder.faces(); if(aFaces.empty()) { theError = "Selected objects do not generate closed contour."; return false; diff --git a/src/BuildPlugin/CMakeLists.txt b/src/BuildPlugin/CMakeLists.txt index ac7d7d63f..b1fb9f155 100644 --- a/src/BuildPlugin/CMakeLists.txt +++ b/src/BuildPlugin/CMakeLists.txt @@ -32,6 +32,7 @@ INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/src/Events SET(PROJECT_HEADERS BuildPlugin.h BuildPlugin_Plugin.h + BuildPlugin_Shape.h BuildPlugin_Vertex.h BuildPlugin_Edge.h BuildPlugin_Wire.h @@ -49,6 +50,7 @@ SET(PROJECT_HEADERS SET(PROJECT_SOURCES BuildPlugin_Plugin.cpp + BuildPlugin_Shape.cpp BuildPlugin_Vertex.cpp BuildPlugin_Edge.cpp BuildPlugin_Wire.cpp diff --git a/src/CollectionPlugin/CMakeLists.txt b/src/CollectionPlugin/CMakeLists.txt index d85f2a3f9..782fdedac 100644 --- a/src/CollectionPlugin/CMakeLists.txt +++ b/src/CollectionPlugin/CMakeLists.txt @@ -123,5 +123,8 @@ ADD_UNIT_TESTS( TestGroupMove13.py TestGroupMove14.py TestGroupMove15.py + TestGroupMove16.py + TestGroupMove17.py + TestGroupMove18.py TestGroupShareTopology.py ) diff --git a/src/CollectionPlugin/Test/TestGroupMove16.py b/src/CollectionPlugin/Test/TestGroupMove16.py new file mode 100644 index 000000000..ced352d36 --- /dev/null +++ b/src/CollectionPlugin/Test/TestGroupMove16.py @@ -0,0 +1,70 @@ +## Copyright (C) 2014-2017 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 +## + +# Test of deep nested results history. Compsolid operation. +# Check the initial groups moved to the end contain the corresponding results. + +from salome.shaper import model +from ModelAPI import * + +aFactory = ModelAPI_Session.get().validators() + +def moveGroupsAndVerify(thePart, theLastFeature, theRefNumInGroups): + # move groups to the end + model.begin() + LastFeature = theLastFeature + for i in range(thePart.size("Groups")): + GroupFeature = thePart.feature(objectToResult(thePart.object("Groups", 0))) # move always the very first group + Part_1_doc.moveFeature(GroupFeature, LastFeature) + LastFeature = GroupFeature + model.end() + + a = 0 + for i in range(thePart.size("Groups")): + GroupFeature = thePart.feature(objectToResult(thePart.object("Groups", i))) + assert(aFactory.validate(GroupFeature)) + assert(GroupFeature.selectionList("group_list").size() == theRefNumInGroups[a]) + a = a + 1 + + +model.begin() +partSet = model.moduleDocument() +Part_1 = model.addPart(partSet) +Part_1_doc = Part_1.document() +Box_1 = model.addBox(Part_1_doc, 10, 10, 10) +Group_1 = model.addGroup(Part_1_doc, [model.selection("SOLID", "Box_1_1")]) +Group_2_objects = [model.selection("FACE", "Box_1_1/Back"), model.selection("FACE", "Box_1_1/Top"), model.selection("FACE", "Box_1_1/Right"), model.selection("FACE", "Box_1_1/Left"), model.selection("FACE", "Box_1_1/Bottom"), model.selection("FACE", "Box_1_1/Front")] +Group_2 = model.addGroup(Part_1_doc, Group_2_objects) +Group_3_objects = [model.selection("EDGE", "[Box_1_1/Back][Box_1_1/Bottom]"), model.selection("EDGE", "[Box_1_1/Back][Box_1_1/Right]"), model.selection("EDGE", "[Box_1_1/Back][Box_1_1/Left]"), model.selection("EDGE", "[Box_1_1/Back][Box_1_1/Top]"), model.selection("EDGE", "[Box_1_1/Left][Box_1_1/Top]"), model.selection("EDGE", "[Box_1_1/Left][Box_1_1/Bottom]"), model.selection("EDGE", "[Box_1_1/Right][Box_1_1/Top]"), model.selection("EDGE", "[Box_1_1/Right][Box_1_1/Bottom]"), model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Bottom]"), model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Right]"), model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Left]"), model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Top]")] +Group_3 = model.addGroup(Part_1_doc, Group_3_objects) +Group_4_objects = [model.selection("VERTEX", "[Box_1_1/Front][Box_1_1/Left][Box_1_1/Top]"), model.selection("VERTEX", "[Box_1_1/Back][Box_1_1/Left][Box_1_1/Top]"), model.selection("VERTEX", "[Box_1_1/Front][Box_1_1/Left][Box_1_1/Bottom]"), model.selection("VERTEX", "[Box_1_1/Front][Box_1_1/Right][Box_1_1/Top]"), model.selection("VERTEX", "[Box_1_1/Back][Box_1_1/Left][Box_1_1/Bottom]"), model.selection("VERTEX", "[Box_1_1/Front][Box_1_1/Right][Box_1_1/Bottom]"), model.selection("VERTEX", "[Box_1_1/Back][Box_1_1/Right][Box_1_1/Top]"), model.selection("VERTEX", "[Box_1_1/Back][Box_1_1/Right][Box_1_1/Bottom]")] +Group_4 = model.addGroup(Part_1_doc, Group_4_objects) +Plane_4 = model.addPlane(Part_1_doc, model.selection("FACE", "Box_1_1/Bottom"), model.selection("FACE", "Box_1_1/Top")) +Sketch_1 = model.addSketch(Part_1_doc, model.selection("FACE", "Plane_1")) +SketchCircle_1 = Sketch_1.addCircle(3.528942405489753, -5.938455554641368, 11.4411217503133) +model.do() +CompSolid_1 = model.addCompSolid(Part_1_doc, [model.selection("SOLID", "Box_1_1"), model.selection("FACE", "Sketch_1/Face-SketchCircle_1_2r")]) +model.do() +model.end() + +num_in_groups = [2, 10, 16, 8] +moveGroupsAndVerify(Part_1_doc, CompSolid_1.feature(), num_in_groups) + +assert(model.checkPythonDump()) diff --git a/src/CollectionPlugin/Test/TestGroupMove17.py b/src/CollectionPlugin/Test/TestGroupMove17.py new file mode 100644 index 000000000..673f10f4a --- /dev/null +++ b/src/CollectionPlugin/Test/TestGroupMove17.py @@ -0,0 +1,71 @@ +## Copyright (C) 2014-2017 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 +## + +# Test of deep nested results history. Solid operation. +# Check the initial groups moved to the end contain the corresponding results. + +from salome.shaper import model +from ModelAPI import * + +aFactory = ModelAPI_Session.get().validators() + +def moveGroupsAndVerify(thePart, theLastFeature, theRefNumInGroups): + # move groups to the end + model.begin() + LastFeature = theLastFeature + for i in range(thePart.size("Groups")): + GroupFeature = thePart.feature(objectToResult(thePart.object("Groups", 0))) # move always the very first group + Part_1_doc.moveFeature(GroupFeature, LastFeature) + LastFeature = GroupFeature + model.end() + + a = 0 + for i in range(thePart.size("Groups")): + GroupFeature = thePart.feature(objectToResult(thePart.object("Groups", i))) + assert(aFactory.validate(GroupFeature)) + assert(GroupFeature.selectionList("group_list").size() == theRefNumInGroups[a]) + a = a + 1 + + +model.begin() +partSet = model.moduleDocument() +Part_1 = model.addPart(partSet) +Part_1_doc = Part_1.document() +Box_1 = model.addBox(Part_1_doc, 10, 10, 10) +Group_1 = model.addGroup(Part_1_doc, [model.selection("SOLID", "Box_1_1")]) +Group_2_objects = [model.selection("FACE", "Box_1_1/Back"), model.selection("FACE", "Box_1_1/Top"), model.selection("FACE", "Box_1_1/Right"), model.selection("FACE", "Box_1_1/Left"), model.selection("FACE", "Box_1_1/Bottom"), model.selection("FACE", "Box_1_1/Front")] +Group_2 = model.addGroup(Part_1_doc, Group_2_objects) +Group_3_objects = [model.selection("EDGE", "[Box_1_1/Back][Box_1_1/Bottom]"), model.selection("EDGE", "[Box_1_1/Back][Box_1_1/Right]"), model.selection("EDGE", "[Box_1_1/Back][Box_1_1/Left]"), model.selection("EDGE", "[Box_1_1/Back][Box_1_1/Top]"), model.selection("EDGE", "[Box_1_1/Left][Box_1_1/Top]"), model.selection("EDGE", "[Box_1_1/Left][Box_1_1/Bottom]"), model.selection("EDGE", "[Box_1_1/Right][Box_1_1/Top]"), model.selection("EDGE", "[Box_1_1/Right][Box_1_1/Bottom]"), model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Bottom]"), model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Right]"), model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Left]"), model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Top]")] +Group_3 = model.addGroup(Part_1_doc, Group_3_objects) +Group_4_objects = [model.selection("VERTEX", "[Box_1_1/Front][Box_1_1/Left][Box_1_1/Top]"), model.selection("VERTEX", "[Box_1_1/Back][Box_1_1/Left][Box_1_1/Top]"), model.selection("VERTEX", "[Box_1_1/Front][Box_1_1/Left][Box_1_1/Bottom]"), model.selection("VERTEX", "[Box_1_1/Front][Box_1_1/Right][Box_1_1/Top]"), model.selection("VERTEX", "[Box_1_1/Back][Box_1_1/Left][Box_1_1/Bottom]"), model.selection("VERTEX", "[Box_1_1/Front][Box_1_1/Right][Box_1_1/Bottom]"), model.selection("VERTEX", "[Box_1_1/Back][Box_1_1/Right][Box_1_1/Top]"), model.selection("VERTEX", "[Box_1_1/Back][Box_1_1/Right][Box_1_1/Bottom]")] +Group_4 = model.addGroup(Part_1_doc, Group_4_objects) +Plane_4 = model.addPlane(Part_1_doc, model.selection("FACE", "Box_1_1/Bottom"), model.selection("FACE", "Box_1_1/Top")) +Sketch_1 = model.addSketch(Part_1_doc, model.selection("FACE", "Plane_1")) +SketchCircle_1 = Sketch_1.addCircle(3.528942405489753, -5.938455554641368, 11.4411217503133) +model.do() +Solid_1_objects = [model.selection("FACE", "Sketch_1/Face-SketchCircle_1_2r"), model.selection("FACE", "Box_1_1/Left"), model.selection("FACE", "Box_1_1/Front"), model.selection("FACE", "Box_1_1/Bottom"), model.selection("FACE", "Box_1_1/Back"), model.selection("FACE", "Box_1_1/Right")] +Solid_1 = model.addSolid(Part_1_doc, Solid_1_objects) +model.do() +model.end() + +num_in_groups = [1, 5, 8, 4] +moveGroupsAndVerify(Part_1_doc, Solid_1.feature(), num_in_groups) + +assert(model.checkPythonDump()) diff --git a/src/CollectionPlugin/Test/TestGroupMove18.py b/src/CollectionPlugin/Test/TestGroupMove18.py new file mode 100644 index 000000000..889fa545f --- /dev/null +++ b/src/CollectionPlugin/Test/TestGroupMove18.py @@ -0,0 +1,70 @@ +## Copyright (C) 2014-2017 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 +## + +# Test of deep nested results history. Shell operation. +# Check the initial groups moved to the end contain the corresponding results. + +from salome.shaper import model +from ModelAPI import * + +aFactory = ModelAPI_Session.get().validators() + +def moveGroupsAndVerify(thePart, theLastFeature, theRefNumInGroups): + # move groups to the end + model.begin() + LastFeature = theLastFeature + for i in range(thePart.size("Groups")): + GroupFeature = thePart.feature(objectToResult(thePart.object("Groups", 0))) # move always the very first group + Part_1_doc.moveFeature(GroupFeature, LastFeature) + LastFeature = GroupFeature + model.end() + + a = 0 + for i in range(thePart.size("Groups")): + GroupFeature = thePart.feature(objectToResult(thePart.object("Groups", i))) + assert(aFactory.validate(GroupFeature)) + assert(GroupFeature.selectionList("group_list").size() == theRefNumInGroups[a]) + a = a + 1 + + +model.begin() +partSet = model.moduleDocument() +Part_1 = model.addPart(partSet) +Part_1_doc = Part_1.document() +Box_1 = model.addBox(Part_1_doc, 10, 10, 10) +Group_1_objects = [model.selection("FACE", "Box_1_1/Back"), model.selection("FACE", "Box_1_1/Top"), model.selection("FACE", "Box_1_1/Right"), model.selection("FACE", "Box_1_1/Left"), model.selection("FACE", "Box_1_1/Bottom"), model.selection("FACE", "Box_1_1/Front")] +Group_1 = model.addGroup(Part_1_doc, Group_1_objects) +Group_2_objects = [model.selection("EDGE", "[Box_1_1/Back][Box_1_1/Bottom]"), model.selection("EDGE", "[Box_1_1/Back][Box_1_1/Right]"), model.selection("EDGE", "[Box_1_1/Back][Box_1_1/Left]"), model.selection("EDGE", "[Box_1_1/Back][Box_1_1/Top]"), model.selection("EDGE", "[Box_1_1/Right][Box_1_1/Bottom]"), model.selection("EDGE", "[Box_1_1/Left][Box_1_1/Top]"), model.selection("EDGE", "[Box_1_1/Left][Box_1_1/Bottom]"), model.selection("EDGE", "[Box_1_1/Right][Box_1_1/Top]"), model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Bottom]"), model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Left]"), model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Right]"), model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Top]")] +Group_2 = model.addGroup(Part_1_doc, Group_2_objects) +Group_3_objects = [model.selection("VERTEX", "[Box_1_1/Front][Box_1_1/Left][Box_1_1/Top]"), model.selection("VERTEX", "[Box_1_1/Back][Box_1_1/Left][Box_1_1/Top]"), model.selection("VERTEX", "[Box_1_1/Front][Box_1_1/Right][Box_1_1/Top]"), model.selection("VERTEX", "[Box_1_1/Front][Box_1_1/Left][Box_1_1/Bottom]"), model.selection("VERTEX", "[Box_1_1/Back][Box_1_1/Right][Box_1_1/Top]"), model.selection("VERTEX", "[Box_1_1/Back][Box_1_1/Left][Box_1_1/Bottom]"), model.selection("VERTEX", "[Box_1_1/Front][Box_1_1/Right][Box_1_1/Bottom]"), model.selection("VERTEX", "[Box_1_1/Back][Box_1_1/Right][Box_1_1/Bottom]")] +Group_3 = model.addGroup(Part_1_doc, Group_3_objects) +Plane_4 = model.addPlane(Part_1_doc, model.selection("FACE", "Box_1_1/Left"), model.selection("FACE", "Box_1_1/Right")) +Plane_5 = model.addPlane(Part_1_doc, model.selection("FACE", "Box_1_1/Front"), model.selection("FACE", "Box_1_1/Back")) +Partition_1_objects = [model.selection("SOLID", "Box_1_1"), model.selection("FACE", "Plane_1"), model.selection("FACE", "Plane_2")] +Partition_1 = model.addPartition(Part_1_doc, Partition_1_objects) +Shell_1_objects = [model.selection("FACE", "Partition_1_1_1/Modified_Face&Box_1_1/Back"), model.selection("FACE", "Partition_1_1_1/Modified_Face&Box_1_1/Left"), model.selection("FACE", "Partition_1_1_1/Modified_Face&Box_1_1/Top"), model.selection("FACE", "Partition_1_1_2/Modified_Face&Box_1_1/Back"), model.selection("FACE", "Partition_1_1_4/Modified_Face&Box_1_1/Front"), model.selection("FACE", "Partition_1_1_4/Modified_Face&Box_1_1/Right")] +Shell_1 = model.addShell(Part_1_doc, Shell_1_objects) +model.do() +model.end() + +num_in_groups = [6, 13, 6] +moveGroupsAndVerify(Part_1_doc, Shell_1.feature(), num_in_groups) + +assert(model.checkPythonDump()) diff --git a/src/GeomAPI/GeomAPI_Shape.cpp b/src/GeomAPI/GeomAPI_Shape.cpp index d7840b168..7427c4e72 100644 --- a/src/GeomAPI/GeomAPI_Shape.cpp +++ b/src/GeomAPI/GeomAPI_Shape.cpp @@ -689,3 +689,9 @@ bool GeomAPI_Shape::isSelfIntersected(const int theLevelOfCheck) const return false; } + +bool GeomAPI_Shape::Comparator::operator()(const std::shared_ptr& theShape1, + const std::shared_ptr& theShape2) const +{ + return theShape1->impl().TShape() < theShape2->impl().TShape(); +} diff --git a/src/GeomAPI/GeomAPI_Shape.h b/src/GeomAPI/GeomAPI_Shape.h index a70574aa4..d0bc66339 100644 --- a/src/GeomAPI/GeomAPI_Shape.h +++ b/src/GeomAPI/GeomAPI_Shape.h @@ -219,6 +219,16 @@ public: /// 8 - V/V, V/E, E/E, V/F, E/F, F/F, V/S, E/S and F/S;
/// 9 - V/V, V/E, E/E, V/F, E/F, F/F, V/S, E/S, F/S and S/S - all interferences (Default value) GEOMAPI_EXPORT bool isSelfIntersected(const int theLevelOfCheck = 9) const; + +public: + class Comparator + { + public: + /// Return \c true if the address of the first shape is less than the address of the second + GEOMAPI_EXPORT + bool operator ()(const std::shared_ptr& theShape1, + const std::shared_ptr& theShape2) const; + }; }; //! Pointer on list of shapes diff --git a/src/GeomAlgoAPI/GeomAlgoAPI.i b/src/GeomAlgoAPI/GeomAlgoAPI.i index a6ce40e6b..8fb19d4ba 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI.i +++ b/src/GeomAlgoAPI/GeomAlgoAPI.i @@ -50,6 +50,7 @@ %shared_ptr(GeomAlgoAPI_Revolution) %shared_ptr(GeomAlgoAPI_Rotation) %shared_ptr(GeomAlgoAPI_Sewing) +%shared_ptr(GeomAlgoAPI_SketchBuilder) %shared_ptr(GeomAlgoAPI_ShapeBuilder) %shared_ptr(GeomAlgoAPI_Translation) %shared_ptr(GeomAlgoAPI_Transform) diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_MakeVolume.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_MakeVolume.cpp index f730342fd..89549b884 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_MakeVolume.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_MakeVolume.cpp @@ -20,6 +20,8 @@ #include "GeomAlgoAPI_MakeVolume.h" +#include + #include #include @@ -91,3 +93,32 @@ void GeomAlgoAPI_MakeVolume::build(const ListOfShape& theFaces) this->setShape(aShape); this->setDone(true); } + +//================================================================================================= +void GeomAlgoAPI_MakeVolume::modified(const GeomShapePtr theOldShape, + ListOfShape& theNewShapes) +{ + if (theOldShape->shapeType() == GeomAPI_Shape::SOLID) { + ListOfShape aNewShapes; + // collect faces and parent shapes, if it is not done yet + if (!isNewShapesCollected(theOldShape, GeomAPI_Shape::FACE)) + collectNewShapes(theOldShape, GeomAPI_Shape::FACE); + + for (GeomAPI_ShapeExplorer anIt(shape(), GeomAPI_Shape::SOLID); anIt.more(); anIt.next()) { + for (GeomAPI_ShapeExplorer anExp(anIt.current(), GeomAPI_Shape::FACE); + anExp.more(); anExp.next()) { + GeomShapePtr anOldShapesCompound = + oldShapesForNew(theOldShape, anExp.current(), GeomAPI_Shape::FACE); + if (!anOldShapesCompound->isNull()) { + aNewShapes.push_back(anIt.current()); + break; + } + } + } + + if (!aNewShapes.empty()) + theNewShapes = aNewShapes; + } + else + GeomAlgoAPI_MakeShape::modified(theOldShape, theNewShapes); +} diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_MakeVolume.h b/src/GeomAlgoAPI/GeomAlgoAPI_MakeVolume.h index c8bcf3005..ab11e510c 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_MakeVolume.h +++ b/src/GeomAlgoAPI/GeomAlgoAPI_MakeVolume.h @@ -44,6 +44,12 @@ public: GEOMALGOAPI_EXPORT GeomAlgoAPI_MakeVolume(const ListOfShape& theFaces, const bool theAvoidInternal); + /// \return the list of shapes modified from the shape \a theShape. + /// \param[in] theOldShape base shape. + /// \param[out] theNewShapes shapes modified from \a theShape. Does not cleared! + GEOMALGOAPI_EXPORT virtual void modified(const GeomShapePtr theOldShape, + ListOfShape& theNewShapes); + private: /// Builds resulting shape. void build(const ListOfShape& theFaces); diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Sewing.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_Sewing.cpp index b30d1dd60..3510f8735 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_Sewing.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Sewing.cpp @@ -80,6 +80,30 @@ void GeomAlgoAPI_Sewing::build(const ListOfShape& theShapes) } //================================================================================================== +#include +#include + +typedef std::map MapFaceSolid; +static void facesBelongingToSolids(const GeomShapePtr& theShape, + MapFaceSolid& theShapeRelations) +{ + for (GeomAPI_ShapeExplorer aSolidExp(theShape, GeomAPI_Shape::SHELL); + aSolidExp.more(); aSolidExp.next()) { + GeomShapePtr aSolid = aSolidExp.current(); + for (GeomAPI_ShapeExplorer aFaceExp(aSolid, GeomAPI_Shape::FACE); + aFaceExp.more(); aFaceExp.next()) + theShapeRelations[aFaceExp.current()].push_back(aSolid); + } +} + +static bool isShapeInList(const GeomShapePtr& theShape, const ListOfShape& theList) +{ + for (ListOfShape::const_iterator anIt = theList.begin(); anIt != theList.end(); ++anIt) + if (theShape->isEqual(*anIt)) + return true; + return false; +} + void GeomAlgoAPI_Sewing::modified(const std::shared_ptr theShape, ListOfShape& theHistory) { @@ -101,4 +125,21 @@ void GeomAlgoAPI_Sewing::modified(const std::shared_ptr theShape, aGeomShape->setImpl(new TopoDS_Shape(anExp.Current())); theHistory.push_back(aGeomShape); } + + if (theShape->shapeType() < GeomAPI_Shape::FACE) { + ListOfShape aNewShapes; + // collect faces and parent shapes, if it is not done yet + if (!isNewShapesCollected(theShape, GeomAPI_Shape::FACE)) + collectNewShapes(theShape, GeomAPI_Shape::FACE); + + for (GeomAPI_ShapeIterator anIt(shape()); anIt.more(); anIt.next()) { + GeomShapePtr anOldShapesCompound = + oldShapesForNew(theShape, anIt.current(), GeomAPI_Shape::FACE); + if (!anOldShapesCompound->isNull()) + aNewShapes.push_back(anIt.current()); + } + + if (!aNewShapes.empty()) + theHistory = aNewShapes; + } } diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_SketchBuilder.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_SketchBuilder.cpp index ce3f7c82e..90fbacd0e 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_SketchBuilder.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_SketchBuilder.cpp @@ -21,6 +21,8 @@ #include #include +#include + #include #include #include @@ -199,14 +201,15 @@ static void sortFaces(TopTools_ListOfShape& theAreas, } } -void GeomAlgoAPI_SketchBuilder::createFaces( +void GeomAlgoAPI_SketchBuilder::build( const std::shared_ptr& theOrigin, const std::shared_ptr& theDirX, const std::shared_ptr& theNorm, - const std::list >& theFeatures, - std::list >& theResultFaces) + const std::list >& theEdges) { - if (theFeatures.empty()) + myResultFaces.clear(); + setDone(false); + if (theEdges.empty()) return; BRep_Builder aBuilder; @@ -216,24 +219,31 @@ void GeomAlgoAPI_SketchBuilder::createFaces( aBuilder.MakeFace(aPlnFace, aPlane, Precision::Confusion()); // Use General Fuse algorithm to prepare all subfaces, bounded by given list of edges - BOPAlgo_Builder aBB; - aBB.AddArgument(aPlnFace); + BOPAlgo_Builder* aBB = new BOPAlgo_Builder; + aBB->AddArgument(aPlnFace); + + setImpl(aBB); + setBuilderType(OCCT_BOPAlgo_Builder); NCollection_List anEdges; NCollection_List::Iterator aShapeIt; - std::list >::const_iterator aFeatIt = theFeatures.begin(); - for (; aFeatIt != theFeatures.end(); aFeatIt++) { + std::list >::const_iterator aFeatIt = theEdges.begin(); + for (; aFeatIt != theEdges.end(); aFeatIt++) { std::shared_ptr aShape(*aFeatIt); const TopoDS_Edge& anEdge = aShape->impl(); if (anEdge.ShapeType() == TopAbs_EDGE) - aBB.AddArgument(anEdge); + aBB->AddArgument(anEdge); } - aBB.Perform(); - if (aBB.HasErrors()) + aBB->Perform(); + if (aBB->HasErrors()) return; + + TopoDS_Compound aResult; + aBuilder.MakeCompound(aResult); + // Collect faces - TopTools_ListOfShape anAreas = aBB.Modified(aPlnFace); - sortFaces(anAreas, theFeatures); // sort faces by the edges in them + TopTools_ListOfShape anAreas = aBB->Modified(aPlnFace); + sortFaces(anAreas, theEdges); // sort faces by the edges in them TopTools_ListIteratorOfListOfShape anIt(anAreas); for (; anIt.More(); anIt.Next()) { TopoDS_Face aFace = TopoDS::Face(anIt.Value()); @@ -253,7 +263,7 @@ void GeomAlgoAPI_SketchBuilder::createFaces( // to make faces equal on different platforms, we will find // a vertex lying on an edge with the lowest index in the list of initial edges - TopoDS_Vertex aStartVertex = findStartVertex(aWire, aFace, theFeatures); + TopoDS_Vertex aStartVertex = findStartVertex(aWire, aFace, theEdges); TopoDS_Wire aNewWire; aBuilder.MakeWire(aNewWire); @@ -289,30 +299,43 @@ void GeomAlgoAPI_SketchBuilder::createFaces( } // store face - aFace = aNewFace; + aBuilder.Add(aResult, aNewFace); std::shared_ptr aResFace(new GeomAPI_Shape); aResFace->setImpl(new TopoDS_Face(aFace)); - theResultFaces.push_back(aResFace); + myResultFaces.push_back(aResFace); } + + // update results + GeomShapePtr aResShape(new GeomAPI_Shape); + aResShape->setImpl(new TopoDS_Shape(aResult)); + setShape(aResShape); + setDone(true); } -void GeomAlgoAPI_SketchBuilder::createFaces(const std::shared_ptr& theOrigin, - const std::shared_ptr& theDirX, - const std::shared_ptr& theNorm, - const std::shared_ptr& theWire, - std::list >& theResultFaces) +GeomAlgoAPI_SketchBuilder::GeomAlgoAPI_SketchBuilder( + const std::shared_ptr& thePlane, + const std::list >& theEdges) +{ + build(thePlane->location(), thePlane->xDirection(), thePlane->direction(), theEdges); +} + +GeomAlgoAPI_SketchBuilder::GeomAlgoAPI_SketchBuilder( + const std::shared_ptr& theOrigin, + const std::shared_ptr& theDirX, + const std::shared_ptr& theNorm, + const std::shared_ptr& theWire) { std::shared_ptr aWire = std::dynamic_pointer_cast(theWire); if(aWire) { // Filter wires, return only faces. - createFaces(theOrigin, theDirX, theNorm, aWire->getEdges(), theResultFaces); + build(theOrigin, theDirX, theNorm, aWire->getEdges()); } else { // it may be only one circle std::shared_ptr anEdge = std::dynamic_pointer_cast(theWire); if (anEdge) { std::list > aList; aList.push_back(anEdge); - createFaces(theOrigin, theDirX, theNorm, aList, theResultFaces); + build(theOrigin, theDirX, theNorm, aList); } } } diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_SketchBuilder.h b/src/GeomAlgoAPI/GeomAlgoAPI_SketchBuilder.h index 9fcaec2c3..0c93379de 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_SketchBuilder.h +++ b/src/GeomAlgoAPI/GeomAlgoAPI_SketchBuilder.h @@ -22,50 +22,59 @@ #define GeomAlgoAPI_SketchBuilder_H_ #include +#include #include #include -#include -#include -#include +class GeomAPI_Dir; +class GeomAPI_Pln; +class GeomAPI_Pnt; +class GeomAPI_Shape; /** \class GeomAlgoAPI_SketchBuilder * \ingroup DataAlgo * \brief Creates planar faces based on the list of Sketch features */ -class GEOMALGOAPI_EXPORT GeomAlgoAPI_SketchBuilder +class GeomAlgoAPI_SketchBuilder : public GeomAlgoAPI_MakeShape { - public: - /** \brief Creates list of faces based on the features of the sketch - * \param[in] theOrigin origin point of the sketch - * \param[in] theDirX x-direction of the sketch - * \param[in] theNorm normal of the sketch - * \param[in] theFeatures initial features of the sketch - * \param[out] theResultFaces faces based on closed wires +public: + /** \brief Creates list of faces based on the edges of the sketch + * \param[in] thePlane plane of the sketch + * \param[in] theEdges initial edges of the sketch * * The algorithm searches all loops of edges surrounding lesser areas. */ - static void createFaces(const std::shared_ptr& theOrigin, - const std::shared_ptr& theDirX, - const std::shared_ptr& theNorm, - const std::list >& theFeatures, - std::list >& theResultFaces); + GEOMALGOAPI_EXPORT + GeomAlgoAPI_SketchBuilder(const std::shared_ptr& thePlane, + const std::list >& theEdges); /** \brief Creates list of faces and unclosed wires on basis of the features of the sketch * \param[in] theOrigin origin point of the sketch * \param[in] theDirX x-direction of the sketch * \param[in] theNorm normal of the sketch * \param[in] theWire a wire which contains all edges - * \param[out] theResultFaces faces based on closed wires * * The algorithm searches all loops of edges surrounding lesser areas. */ - static void createFaces(const std::shared_ptr& theOrigin, - const std::shared_ptr& theDirX, - const std::shared_ptr& theNorm, - const std::shared_ptr& theWire, - std::list >& theResultFaces); + GEOMALGOAPI_EXPORT + GeomAlgoAPI_SketchBuilder(const std::shared_ptr& theOrigin, + const std::shared_ptr& theDirX, + const std::shared_ptr& theNorm, + const std::shared_ptr& theWire); + + /// Return list of created faces + GEOMALGOAPI_EXPORT const std::list >& faces() const + { return myResultFaces; } + +private: + void build(const std::shared_ptr& theOrigin, + const std::shared_ptr& theDirX, + const std::shared_ptr& theNorm, + const std::list >& theEdges); + +private: + std::list > myResultFaces; }; #endif diff --git a/src/Model/Model_ResultConstruction.cpp b/src/Model/Model_ResultConstruction.cpp index 272cb7338..8765caeb0 100644 --- a/src/Model/Model_ResultConstruction.cpp +++ b/src/Model/Model_ResultConstruction.cpp @@ -292,12 +292,12 @@ void Model_ResultConstruction::storeShape(std::shared_ptr theShap } } - std::list > aFaces; - GeomAlgoAPI_SketchBuilder::createFaces(aWirePtr->origin(), aWirePtr->dirX(), - aWirePtr->norm(), aWirePtr, aFaces); + GeomAlgoAPI_SketchBuilder aSketchBuilder(aWirePtr->origin(), aWirePtr->dirX(), + aWirePtr->norm(), aWirePtr); + const ListOfShape& aFaces = aSketchBuilder.faces(); // order is important to store faces in the same order if sketch is created from scratch NCollection_IndexedDataMap aNewIndices; // edges indices - std::list >::iterator aFIter = aFaces.begin(); + std::list >::const_iterator aFIter = aFaces.begin(); for (; aFIter != aFaces.end(); aFIter++) { std::shared_ptr aFace(new GeomAPI_Face(*aFIter)); // put them to a label, trying to keep the same faces on the same labels