From b04366b7cb8e262e53383f50b3bc536c2d525816 Mon Sep 17 00:00:00 2001 From: azv Date: Tue, 28 May 2019 18:23:11 +0300 Subject: [PATCH] Task 3.8. Extrusion to any face --- src/FeaturesPlugin/CMakeLists.txt | 19 + .../FeaturesPlugin_CompositeSketch.cpp | 106 +-- .../FeaturesPlugin_Extrusion.cpp | 35 +- src/FeaturesPlugin/FeaturesPlugin_Extrusion.h | 8 + .../FeaturesPlugin_ExtrusionBoolean.cpp | 3 +- src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp | 2 + src/FeaturesPlugin/FeaturesPlugin_Tools.cpp | 108 +++ src/FeaturesPlugin/FeaturesPlugin_Tools.h | 8 +- .../FeaturesPlugin_Validators.cpp | 96 +++ .../FeaturesPlugin_Validators.h | 15 + .../Test/TestExtrusion_ByFaces01.py | 134 +++ .../Test/TestExtrusion_ByFaces02.py | 124 +++ .../Test/TestExtrusion_ByFaces03.py | 154 ++++ .../Test/TestExtrusion_ByFaces04.py | 132 +++ .../Test/TestExtrusion_ByFaces05.py | 161 ++++ .../Test/TestExtrusion_ByFaces06.py | 115 +++ .../Test/TestExtrusion_ByFaces07.py | 143 ++++ .../Test/TestExtrusion_ByFaces08.py | 129 +++ .../Test/TestExtrusion_ByFaces09.py | 157 ++++ .../Test/TestExtrusion_ByFaces10.py | 136 +++ .../Test/TestExtrusion_ByFaces11.py | 166 ++++ .../Test/TestExtrusion_ByFaces12.py | 120 +++ .../Test/TestExtrusion_ByFaces13.py | 128 +++ .../Test/TestExtrusion_ByFaces14.py | 129 +++ .../Test/TestExtrusion_ByFaces15.py | 165 ++++ .../Test/TestExtrusion_ByFaces16.py | 137 +++ .../Test/TestExtrusion_ByFaces17.py | 162 ++++ .../Test/TestExtrusion_ByFaces18.py | 120 +++ .../Test/TestExtrusion_ByFaces19.py | 144 ++++ src/FeaturesPlugin/doc/extrusionFeature.rst | 13 +- src/FeaturesPlugin/extrusion_widget.xml | 14 +- src/GeomAlgoAPI/CMakeLists.txt | 2 + src/GeomAlgoAPI/GeomAlgoAPI_Offset.cpp | 55 ++ src/GeomAlgoAPI/GeomAlgoAPI_Offset.h | 47 ++ src/GeomAlgoAPI/GeomAlgoAPI_Prism.cpp | 798 +++++++++++++----- src/GeomAlgoAPI/GeomAlgoAPI_Prism.h | 39 +- src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.cpp | 18 + src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.h | 7 + 38 files changed, 3695 insertions(+), 354 deletions(-) create mode 100644 src/FeaturesPlugin/Test/TestExtrusion_ByFaces01.py create mode 100644 src/FeaturesPlugin/Test/TestExtrusion_ByFaces02.py create mode 100644 src/FeaturesPlugin/Test/TestExtrusion_ByFaces03.py create mode 100644 src/FeaturesPlugin/Test/TestExtrusion_ByFaces04.py create mode 100644 src/FeaturesPlugin/Test/TestExtrusion_ByFaces05.py create mode 100644 src/FeaturesPlugin/Test/TestExtrusion_ByFaces06.py create mode 100644 src/FeaturesPlugin/Test/TestExtrusion_ByFaces07.py create mode 100644 src/FeaturesPlugin/Test/TestExtrusion_ByFaces08.py create mode 100644 src/FeaturesPlugin/Test/TestExtrusion_ByFaces09.py create mode 100644 src/FeaturesPlugin/Test/TestExtrusion_ByFaces10.py create mode 100644 src/FeaturesPlugin/Test/TestExtrusion_ByFaces11.py create mode 100644 src/FeaturesPlugin/Test/TestExtrusion_ByFaces12.py create mode 100644 src/FeaturesPlugin/Test/TestExtrusion_ByFaces13.py create mode 100644 src/FeaturesPlugin/Test/TestExtrusion_ByFaces14.py create mode 100644 src/FeaturesPlugin/Test/TestExtrusion_ByFaces15.py create mode 100644 src/FeaturesPlugin/Test/TestExtrusion_ByFaces16.py create mode 100644 src/FeaturesPlugin/Test/TestExtrusion_ByFaces17.py create mode 100644 src/FeaturesPlugin/Test/TestExtrusion_ByFaces18.py create mode 100644 src/FeaturesPlugin/Test/TestExtrusion_ByFaces19.py create mode 100644 src/GeomAlgoAPI/GeomAlgoAPI_Offset.cpp create mode 100644 src/GeomAlgoAPI/GeomAlgoAPI_Offset.h diff --git a/src/FeaturesPlugin/CMakeLists.txt b/src/FeaturesPlugin/CMakeLists.txt index 26c65c2b2..1b383d545 100644 --- a/src/FeaturesPlugin/CMakeLists.txt +++ b/src/FeaturesPlugin/CMakeLists.txt @@ -181,6 +181,25 @@ ADD_UNIT_TESTS(TestExtrusion.py TestExtrusionFuse_ByPlanesAndOffsets.py TestExtrusion_ErrorMsg.py TestExtrusion_ZeroOffsetError.py + TestExtrusion_ByFaces01.py + TestExtrusion_ByFaces02.py + TestExtrusion_ByFaces03.py + TestExtrusion_ByFaces04.py + TestExtrusion_ByFaces05.py + TestExtrusion_ByFaces06.py + TestExtrusion_ByFaces07.py + TestExtrusion_ByFaces08.py + TestExtrusion_ByFaces09.py + TestExtrusion_ByFaces10.py + TestExtrusion_ByFaces11.py + TestExtrusion_ByFaces12.py + TestExtrusion_ByFaces13.py + TestExtrusion_ByFaces14.py + TestExtrusion_ByFaces15.py + TestExtrusion_ByFaces16.py + TestExtrusion_ByFaces17.py + TestExtrusion_ByFaces18.py + TestExtrusion_ByFaces19.py TestRevolution.py TestRevolution_ByAngle.py TestRevolutionOfPoint.py diff --git a/src/FeaturesPlugin/FeaturesPlugin_CompositeSketch.cpp b/src/FeaturesPlugin/FeaturesPlugin_CompositeSketch.cpp index 1a2d4589f..1a6767086 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_CompositeSketch.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_CompositeSketch.cpp @@ -18,6 +18,7 @@ // #include +#include #include #include @@ -26,16 +27,10 @@ #include #include -#include #include -#include -#include -#include #include -#include -#include static void storeSubShape(const std::shared_ptr theMakeShape, ResultBodyPtr theResultBody, @@ -132,101 +127,12 @@ void FeaturesPlugin_CompositeSketch::removeFeature(std::shared_ptr aSketchWiresMap; AttributeSelectionListPtr aBaseObjectsSelectionList = selectionList(BASE_OBJECTS_ID()); - if(!aBaseObjectsSelectionList.get()) { - setError("Error: Could not get base objects selection list."); - return; - } - if(aBaseObjectsSelectionList->size() == 0) { - setError("Error: Base objects list is empty."); - return; - } - for(int anIndex = 0; anIndex < aBaseObjectsSelectionList->size(); anIndex++) { - AttributeSelectionPtr aBaseObjectSelection = aBaseObjectsSelectionList->value(anIndex); - if(!aBaseObjectSelection.get()) { - setError("Error: Selected base object is empty."); - return; - } - GeomShapePtr aBaseShape = aBaseObjectSelection->value(); - if(aBaseShape.get() && !aBaseShape->isNull()) { - GeomAPI_Shape::ShapeType aST = aBaseShape->shapeType(); - if(aST == GeomAPI_Shape::SOLID || aST == GeomAPI_Shape::COMPSOLID) { - setError("Error: Selected shapes has unsupported type."); - return; - } - ResultConstructionPtr aConstruction = - std::dynamic_pointer_cast(aBaseObjectSelection->context()); - if(aConstruction.get() && !aBaseShape->isEqual(aConstruction->shape()) && - aST == GeomAPI_Shape::WIRE) { - // 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: Selected sketches does not have results."); - return; - } - int aFacesNum = aConstruction->facesNum(); - if(aFacesNum == 0) { - // Probably it can be construction. - aBaseShape = aConstruction->shape(); - 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) { - setError("Error: Selected shapes has unsupported type."); - return; - } - aST == GeomAPI_Shape::FACE ? aBaseFacesList.push_back(aBaseShape) : - theBaseShapesList.push_back(aBaseShape); - } - } else { - 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."); - return; - } - aBaseFacesList.push_back(aBaseFace); - } - } - } - } - - // 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 && aBaseFacesList.size() > 1) { - GeomShapePtr aFacesCompound = GeomAlgoAPI_CompoundBuilder::compound(aBaseFacesList); - GeomAlgoAPI_ShapeTools::combineShapes(aFacesCompound, GeomAPI_Shape::SHELL, theBaseShapesList); - } else { - theBaseShapesList.insert(theBaseShapesList.end(), aBaseFacesList.begin(), - aBaseFacesList.end()); - } + std::string anError; + bool isOk = FeaturesPlugin_Tools::getShape( + aBaseObjectsSelectionList, theIsMakeShells, theBaseShapesList, anError); + if (!isOk) + setError(anError); } //================================================================================================= diff --git a/src/FeaturesPlugin/FeaturesPlugin_Extrusion.cpp b/src/FeaturesPlugin/FeaturesPlugin_Extrusion.cpp index 3ff47274e..dc754bf94 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Extrusion.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Extrusion.cpp @@ -18,6 +18,7 @@ // #include "FeaturesPlugin_Extrusion.h" +#include "FeaturesPlugin_Tools.h" #include #include @@ -66,11 +67,11 @@ void FeaturesPlugin_Extrusion::initAttributes() //================================================================================================= void FeaturesPlugin_Extrusion::execute() { - ListOfShape aBaseShapesList; + ListOfShape aBaseShapesList, aBoundaryShapes; ListOfMakeShape aMakeShapesList; // Make extrusions. - if(!makeExtrusions(aBaseShapesList, aMakeShapesList)) { + if(!makeExtrusions(aBaseShapesList, aBoundaryShapes, aMakeShapesList)) { return; } @@ -80,7 +81,10 @@ void FeaturesPlugin_Extrusion::execute() ListOfMakeShape::const_iterator anAlgoIt = aMakeShapesList.cbegin(); for(; aBaseIt != aBaseShapesList.cend() && anAlgoIt != aMakeShapesList.cend(); ++aBaseIt, ++anAlgoIt) { - storeResult(*aBaseIt, *anAlgoIt, aResultIndex++); + if (aBoundaryShapes.empty()) + storeResult(*aBaseIt, *anAlgoIt, aResultIndex++); + else + storeResultWithBoundaries(*aBaseIt, aBoundaryShapes, *anAlgoIt, aResultIndex++); } removeResults(aResultIndex); @@ -88,6 +92,7 @@ void FeaturesPlugin_Extrusion::execute() //================================================================================================= bool FeaturesPlugin_Extrusion::makeExtrusions(ListOfShape& theBaseShapes, + ListOfShape& theBoundaryShapes, ListOfMakeShape& theMakeShapes) { theMakeShapes.clear(); @@ -165,6 +170,10 @@ bool FeaturesPlugin_Extrusion::makeExtrusions(ListOfShape& theBaseShapes, } } } + if (aToShape) + theBoundaryShapes.push_back(aToShape); + if (aFromShape) + theBoundaryShapes.push_back(aFromShape); // Generating result for each base shape. std::string anError; @@ -185,3 +194,23 @@ bool FeaturesPlugin_Extrusion::makeExtrusions(ListOfShape& theBaseShapes, return true; } + +//================================================================================================= +void FeaturesPlugin_Extrusion::storeResultWithBoundaries( + const GeomShapePtr theBaseShape, + const ListOfShape& theBoundaryShapes, + const std::shared_ptr theMakeShape, + const int theIndex) +{ + // Create result body. + ResultBodyPtr aResultBody = document()->createBody(data(), theIndex); + + // Store modified shapes. + FeaturesPlugin_Tools::loadModifiedShapes(aResultBody, theBoundaryShapes, ListOfShape(), + theMakeShape, theMakeShape->shape()); + + // Store generated edges/faces. + storeGenerationHistory(aResultBody, theBaseShape, theMakeShape); + + setResult(aResultBody, theIndex); +} diff --git a/src/FeaturesPlugin/FeaturesPlugin_Extrusion.h b/src/FeaturesPlugin/FeaturesPlugin_Extrusion.h index 216d1704c..d0a6e3745 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Extrusion.h +++ b/src/FeaturesPlugin/FeaturesPlugin_Extrusion.h @@ -132,10 +132,18 @@ public: protected: /// Generates extrusions. /// \param[out] theBaseShapes list of base shapes. + /// \param[out] theBoundaryShapes list of faces limiting the extrusion /// \param[out] theMakeShapes list of according algos. /// \return false in case one of algo failed. bool makeExtrusions(ListOfShape& theBaseShapes, + ListOfShape& theBoundaryShapes, ListOfMakeShape& theMakeShapes); + + /// Stores result of generation. + void storeResultWithBoundaries(const GeomShapePtr theBaseShape, + const ListOfShape& theBoundaryShapes, + const std::shared_ptr theMakeShape, + const int theIndex = 0); }; #endif diff --git a/src/FeaturesPlugin/FeaturesPlugin_ExtrusionBoolean.cpp b/src/FeaturesPlugin/FeaturesPlugin_ExtrusionBoolean.cpp index 774328da0..edbdcf948 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_ExtrusionBoolean.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_ExtrusionBoolean.cpp @@ -31,7 +31,8 @@ void FeaturesPlugin_ExtrusionBoolean::initAttributes() bool FeaturesPlugin_ExtrusionBoolean::makeGeneration(ListOfShape& theBaseShapes, ListOfMakeShape& theMakeShapes) { - return makeExtrusions(theBaseShapes, theMakeShapes); + ListOfShape aBoundaryShapes; + return makeExtrusions(theBaseShapes, aBoundaryShapes, theMakeShapes); } //================================================================================================= diff --git a/src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp b/src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp index 9efa6c1fd..87db42a87 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp @@ -77,6 +77,8 @@ FeaturesPlugin_Plugin::FeaturesPlugin_Plugin() new FeaturesPlugin_ValidatorPipeLocationsNumber); aFactory->registerValidator("FeaturesPlugin_ValidatorExtrusionDir", new FeaturesPlugin_ValidatorExtrusionDir); + aFactory->registerValidator("FeaturesPlugin_ValidatorExtrusionBoundary", + new FeaturesPlugin_ValidatorExtrusionBoundaryFace); aFactory->registerValidator("FeaturesPlugin_ValidatorBooleanSelection", new FeaturesPlugin_ValidatorBooleanSelection); aFactory->registerValidator("FeaturesPlugin_ValidatorPartitionSelection", diff --git a/src/FeaturesPlugin/FeaturesPlugin_Tools.cpp b/src/FeaturesPlugin/FeaturesPlugin_Tools.cpp index dc1b1a7e1..55a173842 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Tools.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Tools.cpp @@ -19,8 +19,14 @@ #include "FeaturesPlugin_Tools.h" +#include #include +#include +#include +#include + +#include #include //================================================================================================== @@ -133,3 +139,105 @@ void FeaturesPlugin_Tools::loadDeletedShapes( theResultShapesCompound); } } + +//================================================================================================== +bool FeaturesPlugin_Tools::getShape(const AttributeSelectionListPtr theSelectionList, + const bool theShareTopology, + ListOfShape& theShapesList, + std::string& theError) +{ + theShapesList.clear(); + + ListOfShape aBaseFacesList; + std::map aSketchWiresMap; + if(!theSelectionList.get()) { + theError = "Error: Could not get base objects selection list."; + return false; + } + if(theSelectionList->size() == 0) { + theError = "Error: Base objects list is empty."; + return false; + } + for(int anIndex = 0; anIndex < theSelectionList->size(); anIndex++) { + AttributeSelectionPtr aBaseObjectSelection = theSelectionList->value(anIndex); + if(!aBaseObjectSelection.get()) { + theError = "Error: Selected base object is empty."; + return false; + } + GeomShapePtr aBaseShape = aBaseObjectSelection->value(); + if(aBaseShape.get() && !aBaseShape->isNull()) { + GeomAPI_Shape::ShapeType aST = aBaseShape->shapeType(); + if(aST == GeomAPI_Shape::SOLID || aST == GeomAPI_Shape::COMPSOLID) { + theError = "Error: Selected shapes has unsupported type."; + return false; + } + ResultConstructionPtr aConstruction = + std::dynamic_pointer_cast(aBaseObjectSelection->context()); + if(aConstruction.get() && !aBaseShape->isEqual(aConstruction->shape()) && + aST == GeomAPI_Shape::WIRE) { + // 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) : + theShapesList.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()) { + theError = "Error: Selected sketches does not have results."; + return false; + } + int aFacesNum = aConstruction->facesNum(); + if(aFacesNum == 0) { + // Probably it can be construction. + aBaseShape = aConstruction->shape(); + 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) { + theError = "Error: Selected shapes has unsupported type."; + return false; + } + aST == GeomAPI_Shape::FACE ? aBaseFacesList.push_back(aBaseShape) : + theShapesList.push_back(aBaseShape); + } + } else { + for(int aFaceIndex = 0; aFaceIndex < aFacesNum; aFaceIndex++) { + GeomShapePtr aBaseFace = aConstruction->face(aFaceIndex); + if(!aBaseFace.get() || aBaseFace->isNull()) { + theError = "Error: One of the faces on selected sketch is null."; + return false; + } + aBaseFacesList.push_back(aBaseFace); + } + } + } + } + + // 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(theShareTopology && aBaseFacesList.size() > 1) { + GeomShapePtr aFacesCompound = GeomAlgoAPI_CompoundBuilder::compound(aBaseFacesList); + GeomAlgoAPI_ShapeTools::combineShapes(aFacesCompound, GeomAPI_Shape::SHELL, theShapesList); + } else { + theShapesList.insert(theShapesList.end(), aBaseFacesList.begin(), aBaseFacesList.end()); + } + return true; +} diff --git a/src/FeaturesPlugin/FeaturesPlugin_Tools.h b/src/FeaturesPlugin/FeaturesPlugin_Tools.h index dd04de569..36ad73bdd 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Tools.h +++ b/src/FeaturesPlugin/FeaturesPlugin_Tools.h @@ -45,7 +45,7 @@ public: const GeomShapePtr& theBaseShape, const GeomMakeShapePtr& theMakeShape, const std::string theName); - /// Stores deleted shapes. + /// Stores deleted shapes. static void loadDeletedShapes(ResultBodyPtr theResultBody, const GeomShapePtr theBaseShape, const ListOfShape& theTools, @@ -56,6 +56,12 @@ public: static void loadDeletedShapes(std::vector& theResultBaseAlgoList, const ListOfShape& theTools, const GeomShapePtr theResultShapesCompound); + + /// Obtain shapes from the selection list attribute. + static bool getShape(const std::shared_ptr theSelectionList, + const bool theShareTopology, + ListOfShape& theShapesList, + std::string& theError); }; #endif /* FeaturesPlugin_Tools_H_ */ diff --git a/src/FeaturesPlugin/FeaturesPlugin_Validators.cpp b/src/FeaturesPlugin/FeaturesPlugin_Validators.cpp index ee82a62f5..30993f225 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Validators.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Validators.cpp @@ -23,12 +23,14 @@ #include "FeaturesPlugin_BooleanFuse.h" #include "FeaturesPlugin_BooleanCommon.h" #include "FeaturesPlugin_BooleanSmash.h" +#include "FeaturesPlugin_Extrusion.h" #include "FeaturesPlugin_Pipe.h" #include "FeaturesPlugin_Union.h" #include #include +#include > #include #include #include @@ -52,6 +54,7 @@ #include #include +#include #include #include #include @@ -686,6 +689,99 @@ bool FeaturesPlugin_ValidatorExtrusionDir::isShapesCanBeEmpty(const AttributePtr return true; } +//================================================================================================== +bool FeaturesPlugin_ValidatorExtrusionBoundaryFace::isValid( + const AttributePtr& theAttribute, + const std::list& theArguments, + Events_InfoMessage& theError) const +{ + FeaturePtr aFeature = ModelAPI_Feature::feature(theAttribute->owner()); + + // Collect all necessary attributes and try to build prism + + // base face + AttributeSelectionListPtr aBaseShapeAttr = + aFeature->selectionList(FeaturesPlugin_Extrusion::BASE_OBJECTS_ID()); + ListOfShape aBaseShapeList; + std::string anError; + if (!FeaturesPlugin_Tools::getShape(aBaseShapeAttr, true, aBaseShapeList, anError)) { + theError = anError; + return false; + } + + // direction + AttributeSelectionPtr aSelection = + aFeature->selection(FeaturesPlugin_Extrusion::DIRECTION_OBJECT_ID()); + GeomShapePtr aShape = aSelection->value(); + if (!aShape.get() && aSelection->context().get()) + aShape = aSelection->context()->shape(); + + GeomEdgePtr anEdge; + if (aShape.get()) { + if (aShape->isEdge()) + anEdge = aShape->edge(); + else if (aShape->isCompound()) { + GeomAPI_ShapeIterator anIt(aShape); + anEdge = anIt.current()->edge(); + } + } + + std::shared_ptr aDir; + if (anEdge.get() && anEdge->isLine()) + aDir = anEdge->line()->direction(); + + // from/to shapes + GeomShapePtr aFromShape, aToShape; + aSelection = aFeature->selection(FeaturesPlugin_Extrusion::TO_OBJECT_ID()); + if (aSelection.get()) { + aToShape = aSelection->value(); + if (!aToShape.get() && aSelection->context().get()) + aToShape = aSelection->context()->shape(); + if (aToShape.get() && aToShape->isCompound()) { + GeomAPI_ShapeIterator anIt(aToShape); + aToShape = anIt.current(); + } + if (aToShape.get() && !aToShape->isFace()) { + theError = "\"To\" shape is not a face"; + return false; + } + } + aSelection = aFeature->selection(FeaturesPlugin_Extrusion::FROM_OBJECT_ID()); + if (aSelection.get()) { + aFromShape = aSelection->value(); + if (!aFromShape.get() && aSelection->context().get()) + aFromShape = aSelection->context()->shape(); + if (aFromShape.get() && aFromShape->isCompound()) { + GeomAPI_ShapeIterator anIt(aFromShape); + aFromShape = anIt.current(); + } + if (aFromShape.get() && !aFromShape->isFace()) { + theError = "\"From\" shape is not a face"; + return false; + } + } + + double aToSize = aFeature->real(FeaturesPlugin_Extrusion::TO_OFFSET_ID())->value(); + double aFromSize = aFeature->real(FeaturesPlugin_Extrusion::FROM_OFFSET_ID())->value(); + + // check extrusion + for (ListOfShape::iterator anIt = aBaseShapeList.begin(); anIt != aBaseShapeList.end(); anIt++) { + std::shared_ptr aBaseShape = *anIt; + + std::shared_ptr aPrismAlgo( + new GeomAlgoAPI_Prism(aBaseShape, aDir, aToShape, aToSize, aFromShape, aFromSize)); + bool isFailed = GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aPrismAlgo, + FeaturesPlugin_Extrusion::ID(), + anError); + if (isFailed) { + theError = anError; + return false; + } + } + + return true; +} + //================================================================================================== bool FeaturesPlugin_ValidatorBooleanSelection::isValid(const AttributePtr& theAttribute, const std::list& theArguments, diff --git a/src/FeaturesPlugin/FeaturesPlugin_Validators.h b/src/FeaturesPlugin/FeaturesPlugin_Validators.h index a0a4006b5..6af882454 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Validators.h +++ b/src/FeaturesPlugin/FeaturesPlugin_Validators.h @@ -141,6 +141,21 @@ private: Events_InfoMessage& theError) const; }; +/// \class FeaturesPlugin_ValidatorExtrusionBoundaryFace +/// \ingroup Validators +/// \brief A validator for extrusion from/to face attribute. +class FeaturesPlugin_ValidatorExtrusionBoundaryFace: public ModelAPI_AttributeValidator +{ +public: + //! \return true if attribute listed in the parameter arguments are planar. + //! \param[in] theFeature the checked feature. + //! \param[in] theArguments arguments of the attribute. + //! \param[out] theError error message. + virtual bool isValid(const AttributePtr& theAttribute, + const std::list& theArguments, + Events_InfoMessage& theError) const; +}; + /// \class FeaturesPlugin_ValidatorBooleanSelection /// \ingroup Validators /// \brief Validates selection for boolean operation. diff --git a/src/FeaturesPlugin/Test/TestExtrusion_ByFaces01.py b/src/FeaturesPlugin/Test/TestExtrusion_ByFaces01.py new file mode 100644 index 000000000..c7b08bb94 --- /dev/null +++ b/src/FeaturesPlugin/Test/TestExtrusion_ByFaces01.py @@ -0,0 +1,134 @@ +# 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 +# + +from SketchAPI import * + +from salome.shaper import model + +model.begin() +partSet = model.moduleDocument() +Part_1 = model.addPart(partSet) +Part_1_doc = Part_1.document() +ParamR = model.addParameter(Part_1_doc, "R", "50") +ParamFrom = model.addParameter(Part_1_doc, "offsetFrom", "0") +ParamTo = model.addParameter(Part_1_doc, "offsetTo", "0") +Cylinder_1 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), "R", 100, 180) +Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOZ")) +SketchLine_1 = Sketch_1.addLine(20, 40, -30, 40) +SketchLine_2 = Sketch_1.addLine(-30, 40, -30, 20) +SketchLine_3 = Sketch_1.addLine(-30, 20, 20, 20) +SketchLine_4 = Sketch_1.addLine(20, 20, 20, 40) +SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_1.startPoint()) +SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint()) +SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint()) +SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint()) +SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_1.result()) +SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_2.result()) +SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_3.result()) +SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_4.result()) +SketchConstraintLength_1 = Sketch_1.setLength(SketchLine_3.result(), 50) +SketchConstraintLength_2 = Sketch_1.setLength(SketchLine_2.result(), 20) +SketchProjection_1 = Sketch_1.addProjection(model.selection("VERTEX", "PartSet/Origin"), False) +SketchPoint_1 = SketchProjection_1.createdFeature() +SketchConstraintDistanceHorizontal_1 = Sketch_1.setHorizontalDistance(SketchAPI_Point(SketchPoint_1).coordinates(), SketchLine_3.endPoint(), 20) +SketchConstraintDistanceVertical_1 = Sketch_1.setVerticalDistance(SketchAPI_Point(SketchPoint_1).coordinates(), SketchLine_3.endPoint(), 20) +model.do() +Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("COMPOUND", "Sketch_1")], model.selection(), model.selection("FACE", "Cylinder_1_1/Face_1"), "offsetTo", model.selection(), "offsetFrom") + +from GeomAPI import GeomAPI_Shape + +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [1]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [6]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [24]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [48]) +model.testResultsVolumes(Extrusion_1, [47540.6]) + +# change radius of cylinder +ParamR.setValue(10) +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [1]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [4]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [12]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [24]) +model.testResultsVolumes(Extrusion_1, [3141.59265]) + +# check the intersected boundaries are processed well +ParamR.setValue(30) +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [1]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [5]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [18]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [36]) +model.testResultsVolumes(Extrusion_1, [25176.8518]) + +ParamR.setValue(40); +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [1]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [6]) +model.testResultsVolumes(Extrusion_1, [36812.03]) + +# change offsetting "To" face +ParamTo.setValue(-20) +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [1]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [4]) +model.testResultsVolumes(Extrusion_1, [12566.37]) + +ParamTo.setValue(20) +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [1]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [6]) +model.testResultsVolumes(Extrusion_1, [57985.85]) + +# offset "From" face +ParamFrom.setValue(-20) +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [1]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [6]) +model.testResultsVolumes(Extrusion_1, [37985.85]) + +ParamFrom.setValue(20) +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [1]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [6]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [24]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [48]) +model.testResultsVolumes(Extrusion_1, [77985.85]) + +model.testHaveNamingSubshapes(Extrusion_1, model, Part_1_doc) + +model.end() + +assert(model.checkPythonDump()) diff --git a/src/FeaturesPlugin/Test/TestExtrusion_ByFaces02.py b/src/FeaturesPlugin/Test/TestExtrusion_ByFaces02.py new file mode 100644 index 000000000..a55c34e6d --- /dev/null +++ b/src/FeaturesPlugin/Test/TestExtrusion_ByFaces02.py @@ -0,0 +1,124 @@ +# 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 +# + +from SketchAPI import * + +from salome.shaper import model + +model.begin() +partSet = model.moduleDocument() +Part_1 = model.addPart(partSet) +Part_1_doc = Part_1.document() +ParamR = model.addParameter(Part_1_doc, "R", "50") +ParamFrom = model.addParameter(Part_1_doc, "offsetFrom", "0") +ParamTo = model.addParameter(Part_1_doc, "offsetTo", "0") +Cylinder_1 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), "R", 100, 180) +Translation_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Cylinder_1_1")], model.selection("EDGE", "PartSet/OY"), 50) +Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOZ")) +SketchLine_1 = Sketch_1.addLine(20, 40, -30, 40) +SketchLine_2 = Sketch_1.addLine(-30, 40, -30, 20) +SketchLine_3 = Sketch_1.addLine(-30, 20, 20, 20) +SketchLine_4 = Sketch_1.addLine(20, 20, 20, 40) +SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_1.startPoint()) +SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint()) +SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint()) +SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint()) +SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_1.result()) +SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_2.result()) +SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_3.result()) +SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_4.result()) +SketchConstraintLength_1 = Sketch_1.setLength(SketchLine_3.result(), 50) +SketchConstraintLength_2 = Sketch_1.setLength(SketchLine_2.result(), 20) +SketchProjection_1 = Sketch_1.addProjection(model.selection("VERTEX", "PartSet/Origin"), False) +SketchPoint_1 = SketchProjection_1.createdFeature() +SketchConstraintDistanceHorizontal_1 = Sketch_1.setHorizontalDistance(SketchAPI_Point(SketchPoint_1).coordinates(), SketchLine_3.endPoint(), 20) +SketchConstraintDistanceVertical_1 = Sketch_1.setVerticalDistance(SketchAPI_Point(SketchPoint_1).coordinates(), SketchLine_3.endPoint(), 20) +model.do() +Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("COMPOUND", "Sketch_1")], model.selection(), model.selection("FACE", "Translation_1_1/MF:Translated&Cylinder_1_1/Face_1"), "offsetTo", model.selection(), "offsetFrom") + +from GeomAPI import GeomAPI_Shape + +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [1]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [6]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [24]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [48]) +model.testResultsVolumes(Extrusion_1, [97540.6]) + +# change radius of cylinder and check failure +ParamR.setValue(10) +model.do() +assert(Extrusion_1.feature().error() != "") + +# revert failure, check the intersected boundaries are processed well +ParamR.setValue(30) +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [1]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [6]) +model.testResultsVolumes(Extrusion_1, [75176.8518]) + +ParamR.setValue(40); +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [1]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [6]) +model.testResultsVolumes(Extrusion_1, [86812.03]) + +# change offsetting "To" face and check failure +ParamTo.setValue(-20) +model.do() +assert(Extrusion_1.feature().error() != "") + +# revert failure +ParamTo.setValue(20) +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [1]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [6]) +model.testResultsVolumes(Extrusion_1, [107985.85]) + +# offset "From" face +ParamFrom.setValue(-20) +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [1]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [6]) +model.testResultsVolumes(Extrusion_1, [87985.85]) + +ParamFrom.setValue(20) +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [1]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [6]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [24]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [48]) +model.testResultsVolumes(Extrusion_1, [127985.85]) + +model.testHaveNamingSubshapes(Extrusion_1, model, Part_1_doc) + +model.end() + +assert(model.checkPythonDump()) diff --git a/src/FeaturesPlugin/Test/TestExtrusion_ByFaces03.py b/src/FeaturesPlugin/Test/TestExtrusion_ByFaces03.py new file mode 100644 index 000000000..83608d6ed --- /dev/null +++ b/src/FeaturesPlugin/Test/TestExtrusion_ByFaces03.py @@ -0,0 +1,154 @@ +# 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 +# + +from SketchAPI import * + +from salome.shaper import model + +model.begin() +partSet = model.moduleDocument() +Part_1 = model.addPart(partSet) +Part_1_doc = Part_1.document() +ParamR = model.addParameter(Part_1_doc, "R", "50") +ParamSize = model.addParameter(Part_1_doc, "Size", "50") +ParamFrom = model.addParameter(Part_1_doc, "offsetFrom", "0") +ParamTo = model.addParameter(Part_1_doc, "offsetTo", "0") +Sphere_1 = model.addSphere(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), "R") +Partition_1 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Sphere_1_1"), model.selection("FACE", "PartSet/XOZ")]) +Plane_4 = model.addPlane(Part_1_doc, model.selection("FACE", "PartSet/XOZ"), 10, False) +Sketch_1 = model.addSketch(Part_1_doc, model.selection("FACE", "Plane_1")) +SketchLine_1 = Sketch_1.addLine(50, -50, -50, -50) +SketchLine_2 = Sketch_1.addLine(-50, -50, -50, 50) +SketchLine_3 = Sketch_1.addLine(-50, 50, 50, 50) +SketchLine_4 = Sketch_1.addLine(50, 50, 50, -50) +SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_1.startPoint()) +SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint()) +SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint()) +SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint()) +SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_1.result()) +SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_2.result()) +SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_3.result()) +SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_4.result()) +SketchProjection_1 = Sketch_1.addProjection(model.selection("VERTEX", "PartSet/Origin"), False) +SketchPoint_1 = SketchProjection_1.createdFeature() +SketchConstraintDistance_1 = Sketch_1.setDistance(SketchAPI_Point(SketchPoint_1).coordinates(), SketchLine_4.result(), "Size", True) +SketchConstraintDistance_2 = Sketch_1.setDistance(SketchAPI_Point(SketchPoint_1).coordinates(), SketchLine_2.result(), "Size", True) +SketchConstraintDistance_3 = Sketch_1.setDistance(SketchAPI_Point(SketchPoint_1).coordinates(), SketchLine_1.result(), "Size", True) +SketchConstraintDistance_4 = Sketch_1.setDistance(SketchAPI_Point(SketchPoint_1).coordinates(), SketchLine_3.result(), "Size", True) +model.do() +Face_1 = model.addFace(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_4r-SketchLine_3r-SketchLine_2r-SketchLine_1r")]) +Sketch_2 = model.addSketch(Part_1_doc, model.defaultPlane("XOZ")) +SketchLine_5 = Sketch_2.addLine(20, -15, 20, 20) +SketchLine_6 = Sketch_2.addLine(20, 20, -15, 20) +SketchConstraintCoincidence_5 = Sketch_2.setCoincident(SketchLine_5.endPoint(), SketchLine_6.startPoint()) +SketchConstraintVertical_3 = Sketch_2.setVertical(SketchLine_5.result()) +SketchConstraintHorizontal_3 = Sketch_2.setHorizontal(SketchLine_6.result()) +SketchArc_1 = Sketch_2.addArc(0, 0, -15, 20, 20, -15, False) +SketchConstraintCoincidence_6 = Sketch_2.setCoincident(SketchLine_6.endPoint(), SketchArc_1.startPoint()) +SketchConstraintCoincidence_7 = Sketch_2.setCoincident(SketchArc_1.endPoint(), SketchLine_5.startPoint()) +SketchConstraintEqual_1 = Sketch_2.setEqual(SketchLine_5.result(), SketchLine_6.result()) +SketchConstraintDistance_5 = Sketch_2.setDistance(SketchArc_1.center(), SketchLine_5.result(), 20, True) +SketchProjection_2 = Sketch_2.addProjection(model.selection("VERTEX", "PartSet/Origin"), False) +SketchPoint_2 = SketchProjection_2.createdFeature() +SketchConstraintCoincidence_8 = Sketch_2.setCoincident(SketchAPI_Point(SketchPoint_2).coordinates(), SketchArc_1.center()) +SketchConstraintRadius_1 = Sketch_2.setRadius(SketchArc_1.results()[1], 25) +model.do() +Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_2/Face-SketchLine_5r-SketchLine_6f-SketchArc_1_2f")], model.selection(), model.selection("FACE", "Partition_1_1_2/Modified_Face&Sphere_1_1/Face_1"), "offsetTo", model.selection("FACE", "Face_1_1"), "offsetFrom") + +from GeomAPI import GeomAPI_Shape + +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [1]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [5]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [18]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [36]) +model.testResultsVolumes(Extrusion_1, [100878.6]) + +# change radius of sphere and check failure +ParamR.setValue(10) +model.do() +assert(Extrusion_1.feature().error() != "") + +# revert failure, check the intersected boundaries are processed well +ParamR.setValue(30) +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [1]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [5]) +model.testResultsVolumes(Extrusion_1, [60964.23998]) + +ParamR.setValue(40); +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [1]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [5]) +model.testResultsVolumes(Extrusion_1, [81651.666]) + +# change size of the face +ParamSize.setValue(10) +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [1]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [5]) +model.testResultsVolumes(Extrusion_1, [81651.666]) + +# change offsetting "To" face and check failure +ParamTo.setValue(-20) +model.do() +assert(Extrusion_1.feature().error() != "") + +# revert failure +ParamTo.setValue(20) +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [1]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [5]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [22]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [44]) +model.testResultsVolumes(Extrusion_1, [119535.04]) + +# offset "From" face +ParamFrom.setValue(-20) +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [1]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [5]) +model.testResultsVolumes(Extrusion_1, [84126.377]) + +ParamFrom.setValue(20) +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [1]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [5]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [22]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [44]) +model.testResultsVolumes(Extrusion_1, [154943.7]) + +model.testHaveNamingSubshapes(Extrusion_1, model, Part_1_doc) + +model.end() + +assert(model.checkPythonDump()) diff --git a/src/FeaturesPlugin/Test/TestExtrusion_ByFaces04.py b/src/FeaturesPlugin/Test/TestExtrusion_ByFaces04.py new file mode 100644 index 000000000..7e8a0eb9d --- /dev/null +++ b/src/FeaturesPlugin/Test/TestExtrusion_ByFaces04.py @@ -0,0 +1,132 @@ +# 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 +# + +from SketchAPI import * +from GeomAPI import GeomAPI_Shape + +from salome.shaper import model + +model.begin() +partSet = model.moduleDocument() +Part_1 = model.addPart(partSet) +Part_1_doc = Part_1.document() +ParamR = model.addParameter(Part_1_doc, "R", "50") +ParamSize = model.addParameter(Part_1_doc, "Size", "50") +ParamFrom = model.addParameter(Part_1_doc, "offsetFrom", "0") +ParamTo = model.addParameter(Part_1_doc, "offsetTo", "0") +Sphere_1 = model.addSphere(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), "R") +Partition_1 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Sphere_1_1"), model.selection("FACE", "PartSet/XOZ")]) +Plane_4 = model.addPlane(Part_1_doc, model.selection("FACE", "PartSet/XOZ"), 30, False) +Sketch_1 = model.addSketch(Part_1_doc, model.selection("FACE", "Plane_1")) +SketchLine_1 = Sketch_1.addLine(50, -50, -50, -50) +SketchLine_2 = Sketch_1.addLine(-50, -50, -50, 50) +SketchLine_3 = Sketch_1.addLine(-50, 50, 50, 50) +SketchLine_4 = Sketch_1.addLine(50, 50, 50, -50) +SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_1.startPoint()) +SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint()) +SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint()) +SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint()) +SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_1.result()) +SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_2.result()) +SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_3.result()) +SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_4.result()) +SketchProjection_1 = Sketch_1.addProjection(model.selection("VERTEX", "PartSet/Origin"), False) +SketchPoint_1 = SketchProjection_1.createdFeature() +SketchConstraintDistance_1 = Sketch_1.setDistance(SketchAPI_Point(SketchPoint_1).coordinates(), SketchLine_4.result(), "Size", True) +SketchConstraintDistance_2 = Sketch_1.setDistance(SketchAPI_Point(SketchPoint_1).coordinates(), SketchLine_2.result(), "Size", True) +SketchConstraintDistance_3 = Sketch_1.setDistance(SketchAPI_Point(SketchPoint_1).coordinates(), SketchLine_1.result(), "Size", True) +SketchConstraintDistance_4 = Sketch_1.setDistance(SketchAPI_Point(SketchPoint_1).coordinates(), SketchLine_3.result(), "Size", True) +model.do() +Face_1 = model.addFace(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_4r-SketchLine_3r-SketchLine_2r-SketchLine_1r")]) +Sketch_2 = model.addSketch(Part_1_doc, model.defaultPlane("XOZ")) +SketchLine_5 = Sketch_2.addLine(20, -40.3112887414928, 20, 20) +SketchLine_6 = Sketch_2.addLine(20, 20, -40.31128874149281, 20.00000000000001) +SketchConstraintCoincidence_5 = Sketch_2.setCoincident(SketchLine_5.endPoint(), SketchLine_6.startPoint()) +SketchConstraintVertical_3 = Sketch_2.setVertical(SketchLine_5.result()) +SketchConstraintHorizontal_3 = Sketch_2.setHorizontal(SketchLine_6.result()) +SketchArc_1 = Sketch_2.addArc(0, 0, -40.31128874149281, 20.00000000000001, 20, -40.3112887414928, False) +SketchConstraintCoincidence_6 = Sketch_2.setCoincident(SketchLine_6.endPoint(), SketchArc_1.startPoint()) +SketchConstraintCoincidence_7 = Sketch_2.setCoincident(SketchArc_1.endPoint(), SketchLine_5.startPoint()) +SketchConstraintEqual_1 = Sketch_2.setEqual(SketchLine_5.result(), SketchLine_6.result()) +SketchConstraintDistance_5 = Sketch_2.setDistance(SketchArc_1.center(), SketchLine_5.result(), 20, True) +SketchProjection_2 = Sketch_2.addProjection(model.selection("VERTEX", "PartSet/Origin"), False) +SketchPoint_2 = SketchProjection_2.createdFeature() +SketchConstraintCoincidence_8 = Sketch_2.setCoincident(SketchAPI_Point(SketchPoint_2).coordinates(), SketchArc_1.center()) +SketchConstraintRadius_1 = Sketch_2.setRadius(SketchArc_1.results()[1], 45) +model.do() +Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_2/Face-SketchLine_5r-SketchLine_6f-SketchArc_1_2f")], model.selection(), model.selection("FACE", "Partition_1_1_1/Modified_Face&Sphere_1_1/Face_1"), "offsetTo", model.selection("FACE", "Face_1_1"), "offsetFrom") + +# extrusion have to fail because of several results with shared topology +assert(Extrusion_1.feature().error() != "") + +# change radius of sphere and check failure +ParamR.setValue(10) +model.do() +assert(Extrusion_1.feature().error() != "") + +ParamR.setValue(45) +model.do() +assert(Extrusion_1.feature().error() != "") + +# change offsetting "To" face and check failure +ParamTo.setValue(-20) +model.do() +assert(Extrusion_1.feature().error() != "") + +# revert failure +ParamTo.setValue(20) +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [1]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [5]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [22]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [44]) +model.testResultsVolumes(Extrusion_1, [105008.93]) + +# offset "From" face +ParamFrom.setValue(-20) +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [1]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [5]) +model.testResultsVolumes(Extrusion_1, [179594.5]) + +# check failure +ParamFrom.setValue(20) +model.do() +assert(Extrusion_1.feature().error() != "") + +# revert failure +ParamTo.setValue(0) +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [1]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [5]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [21]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [42]) +model.testResultsVolumes(Extrusion_1, [62569.416]) + +model.testHaveNamingSubshapes(Extrusion_1, model, Part_1_doc) + +model.end() + +assert(model.checkPythonDump()) diff --git a/src/FeaturesPlugin/Test/TestExtrusion_ByFaces05.py b/src/FeaturesPlugin/Test/TestExtrusion_ByFaces05.py new file mode 100644 index 000000000..fff109f06 --- /dev/null +++ b/src/FeaturesPlugin/Test/TestExtrusion_ByFaces05.py @@ -0,0 +1,161 @@ +# 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 +# + +from SketchAPI import * + +from salome.shaper import model + +model.begin() +partSet = model.moduleDocument() +Part_1 = model.addPart(partSet) +Part_1_doc = Part_1.document() +ParamRSph = model.addParameter(Part_1_doc, "rSphere", "50") +ParamRCyl = model.addParameter(Part_1_doc, "rCyl", "30") +ParamRCir = model.addParameter(Part_1_doc, "rCircle", "10") +ParamFrom = model.addParameter(Part_1_doc, "offsetFrom", "0") +ParamTo = model.addParameter(Part_1_doc, "offsetTo", "0") +Sphere_1 = model.addSphere(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), "rSphere") +Cylinder_1 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), "rCyl", 100) +Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOZ")) +SketchCircle_1 = Sketch_1.addCircle(15, 20, 10) +SketchConstraintRadius_1 = Sketch_1.setRadius(SketchCircle_1.results()[1], "rCircle") +SketchProjection_1 = Sketch_1.addProjection(model.selection("VERTEX", "PartSet/Origin"), False) +SketchPoint_1 = SketchProjection_1.createdFeature() +SketchConstraintDistanceHorizontal_1 = Sketch_1.setHorizontalDistance(SketchAPI_Point(SketchPoint_1).coordinates(), SketchCircle_1.center(), 15) +SketchConstraintDistanceVertical_1 = Sketch_1.setVerticalDistance(SketchAPI_Point(SketchPoint_1).coordinates(), SketchCircle_1.center(), 20) +model.do() +Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchCircle_1_2r")], model.selection(), model.selection("FACE", "Sphere_1_1/Face_1"), "offsetTo", model.selection("FACE", "Cylinder_1_1/Face_1"), "offsetFrom") + +from GeomAPI import GeomAPI_Shape + +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [6]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [12]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [24]) +model.testResultsVolumes(Extrusion_1, [10878.5462]) + +# change radius of sketch circle +ParamRCir.setValue(17) +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [1]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [5]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [18]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [36]) +model.testResultsVolumes(Extrusion_1, [32102.718377]) + +# change radius of sphere and check failure +ParamRSph.setValue(10) +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [1]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [6]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [18]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [36]) +model.testResultsVolumes(Extrusion_1, [42694.3277614]) + +# change radius of sketch circle and check failure +ParamRCir.setValue(10) +model.do() +assert(Extrusion_1.feature().error() != "") + +# revert failure +ParamRSph.setValue(45); +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [6]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [12]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [24]) +model.testResultsVolumes(Extrusion_1, [7083.567843]) + +# change radius of cylinder +ParamRCyl.setValue(10) +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [1]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [5]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [12]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [24]) +model.testResultsVolumes(Extrusion_1, [22295.845141]) + +ParamRCyl.setValue(50) +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [6]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [12]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [24]) +model.testResultsVolumes(Extrusion_1, [6805.1007457]) + +# change offsetting "To" face +ParamTo.setValue(-20) +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [1]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [5]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [18]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [36]) +model.testResultsVolumes(Extrusion_1, [26158.63076]) + +# revert failure +ParamTo.setValue(20) +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [6]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [16]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [32]) +model.testResultsVolumes(Extrusion_1, [7626.2279286]) + +# offset "From" face +ParamFrom.setValue(-20) +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [6]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [20]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [40]) +model.testResultsVolumes(Extrusion_1, [21514.8965]) + +ParamFrom.setValue(20) +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [6]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [20]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [40]) +model.testResultsVolumes(Extrusion_1, [5427.194275658]) + +model.testHaveNamingSubshapes(Extrusion_1, model, Part_1_doc) + +model.end() + +assert(model.checkPythonDump()) diff --git a/src/FeaturesPlugin/Test/TestExtrusion_ByFaces06.py b/src/FeaturesPlugin/Test/TestExtrusion_ByFaces06.py new file mode 100644 index 000000000..095c96796 --- /dev/null +++ b/src/FeaturesPlugin/Test/TestExtrusion_ByFaces06.py @@ -0,0 +1,115 @@ +# 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 +# + +from SketchAPI import * + +from salome.shaper import model + +model.begin() +partSet = model.moduleDocument() +Part_1 = model.addPart(partSet) +Part_1_doc = Part_1.document() +ParamR = model.addParameter(Part_1_doc, "R", "50") +ParamFrom = model.addParameter(Part_1_doc, "offsetFrom", "0") +ParamTo = model.addParameter(Part_1_doc, "offsetTo", "0") +Cone_1 = model.addCone(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), "R", "R/5", "R") +Partition_1 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Cone_1_1"), model.selection("FACE", "PartSet/XOZ")]) +Plane_4 = model.addPlane(Part_1_doc, model.selection("FACE", "PartSet/XOZ"), 20, False) +Plane_5 = model.addPlane(Part_1_doc, model.selection("FACE", "Plane_1"), model.selection("EDGE", "PartSet/OZ"), 330) +Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOZ")) +SketchLine_1 = Sketch_1.addLine(10, 8.819660112501044, 10, 30) +SketchLine_2 = Sketch_1.addLine(10, 30, -11.18033988749895, 30) +SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint()) +SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_1.result()) +SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_2.result()) +SketchArc_1 = Sketch_1.addArc(0, 20, -11.18033988749895, 30, 10, 8.819660112501044, False) +SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchArc_1.startPoint()) +SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchArc_1.endPoint(), SketchLine_1.startPoint()) +SketchConstraintEqual_1 = Sketch_1.setEqual(SketchLine_1.result(), SketchLine_2.result()) +SketchConstraintDistance_1 = Sketch_1.setDistance(SketchArc_1.center(), SketchLine_1.result(), 10, True) +SketchConstraintRadius_1 = Sketch_1.setRadius(SketchArc_1.results()[1], 15) +SketchProjection_1 = Sketch_1.addProjection(model.selection("EDGE", "PartSet/OZ"), False) +SketchLine_3 = SketchProjection_1.createdFeature() +SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchArc_1.center(), SketchLine_3.result()) +SketchConstraintDistanceVertical_1 = Sketch_1.setVerticalDistance(SketchAPI_Line(SketchLine_3).startPoint(), SketchArc_1.center(), 20) +model.do() +Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_1r-SketchLine_2f-SketchArc_1_2f")], model.selection(), model.selection("FACE", "Partition_1_1_2/Modified_Face&Cone_1_1/Face_1"), "offsetTo", model.selection("FACE", "Plane_2"), "offsetFrom") + +from GeomAPI import GeomAPI_Shape + +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [1]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [5]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [20]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [40]) +model.testResultsVolumes(Extrusion_1, [31363.4963946]) + +# change radius of sphere and check failure +ParamR.setValue(10) +model.do() +assert(Extrusion_1.feature().error() != "") + +# revert failure, check the intersected boundaries are processed well +ParamR.setValue(40) +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [1]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [5]) +model.testResultsVolumes(Extrusion_1, [25645.0102138]) + +# change offsetting "To" face and check failure +ParamTo.setValue(-20) +model.do() +assert(Extrusion_1.feature().error() != "") + +# revert failure +ParamTo.setValue(8) +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [1]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [5]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [20]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [40]) +model.testResultsVolumes(Extrusion_1, [31501.9671234]) + +# offset "From" face +ParamFrom.setValue(-20) +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [1]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [5]) +model.testResultsVolumes(Extrusion_1, [18737.752452]) + +ParamFrom.setValue(20) +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [1]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [5]) +model.testResultsVolumes(Extrusion_1, [44266.1817647]) + +model.testHaveNamingSubshapes(Extrusion_1, model, Part_1_doc) + +model.end() + +assert(model.checkPythonDump()) diff --git a/src/FeaturesPlugin/Test/TestExtrusion_ByFaces07.py b/src/FeaturesPlugin/Test/TestExtrusion_ByFaces07.py new file mode 100644 index 000000000..0318fcd13 --- /dev/null +++ b/src/FeaturesPlugin/Test/TestExtrusion_ByFaces07.py @@ -0,0 +1,143 @@ +# 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 +# + +from SketchAPI import * + +from salome.shaper import model + +model.begin() +partSet = model.moduleDocument() +Part_1 = model.addPart(partSet) +Part_1_doc = Part_1.document() +ParamR = model.addParameter(Part_1_doc, "R", "50") +ParamFrom = model.addParameter(Part_1_doc, "offsetFrom", "0") +ParamTo = model.addParameter(Part_1_doc, "offsetTo", "0") +Cylinder_1 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), "R", 100, 180) +Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOZ")) +SketchLine_1 = Sketch_1.addLine(20, 40, -30, 40) +SketchLine_2 = Sketch_1.addLine(-30, 40, -30, 20) +SketchLine_3 = Sketch_1.addLine(-30, 20, 20, 20) +SketchLine_4 = Sketch_1.addLine(20, 20, 20, 40) +SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_1.startPoint()) +SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint()) +SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint()) +SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint()) +SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_1.result()) +SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_2.result()) +SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_3.result()) +SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_4.result()) +SketchConstraintLength_1 = Sketch_1.setLength(SketchLine_3.result(), 50) +SketchConstraintLength_2 = Sketch_1.setLength(SketchLine_2.result(), 20) +SketchProjection_1 = Sketch_1.addProjection(model.selection("VERTEX", "PartSet/Origin"), False) +SketchPoint_1 = SketchProjection_1.createdFeature() +SketchConstraintDistanceHorizontal_1 = Sketch_1.setHorizontalDistance(SketchAPI_Point(SketchPoint_1).coordinates(), SketchLine_3.endPoint(), 20) +SketchConstraintDistanceVertical_1 = Sketch_1.setVerticalDistance(SketchAPI_Point(SketchPoint_1).coordinates(), SketchLine_3.endPoint(), 20) +SketchLine_5 = Sketch_1.addLine(-10, 20, 5, 40) +SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_5.startPoint(), SketchLine_3.result()) +SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchLine_5.endPoint(), SketchLine_1.result()) +SketchConstraintDistanceHorizontal_2 = Sketch_1.setHorizontalDistance(SketchLine_2.endPoint(), SketchLine_5.startPoint(), 20) +SketchConstraintDistanceHorizontal_3 = Sketch_1.setHorizontalDistance(SketchLine_5.endPoint(), SketchLine_1.startPoint(), 15) +model.do() +Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("COMPOUND", "Sketch_1")], model.selection(), model.selection("FACE", "Cylinder_1_1/Face_1"), "offsetTo", model.selection(), "offsetFrom") + +from GeomAPI import GeomAPI_Shape + +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [12]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [48]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [96]) +model.testResultsVolumes(Extrusion_1, [47540.6]) + +# change radius of cylinder +ParamR.setValue(10) +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [9]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [28]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [56]) +model.testResultsVolumes(Extrusion_1, [3141.59265]) + +# check the intersected boundaries are processed well +ParamR.setValue(30) +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [11]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [42]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [84]) +model.testResultsVolumes(Extrusion_1, [25176.8518]) + +ParamR.setValue(40); +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [12]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [48]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [96]) +model.testResultsVolumes(Extrusion_1, [36812.03]) + +# change offsetting "To" face +ParamTo.setValue(-20) +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [10]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [36]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [72]) +model.testResultsVolumes(Extrusion_1, [12566.37]) + +ParamTo.setValue(20) +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [12]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [48]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [96]) +model.testResultsVolumes(Extrusion_1, [57985.85]) + +# offset "From" face +ParamFrom.setValue(-20) +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [12]) +model.testResultsVolumes(Extrusion_1, [37985.85]) + +ParamFrom.setValue(20) +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [12]) +model.testResultsVolumes(Extrusion_1, [77985.85]) + +model.testHaveNamingSubshapes(Extrusion_1, model, Part_1_doc) + +model.end() + +assert(model.checkPythonDump()) diff --git a/src/FeaturesPlugin/Test/TestExtrusion_ByFaces08.py b/src/FeaturesPlugin/Test/TestExtrusion_ByFaces08.py new file mode 100644 index 000000000..18ce0b442 --- /dev/null +++ b/src/FeaturesPlugin/Test/TestExtrusion_ByFaces08.py @@ -0,0 +1,129 @@ +# 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 +# + +from SketchAPI import * + +from salome.shaper import model + +model.begin() +partSet = model.moduleDocument() +Part_1 = model.addPart(partSet) +Part_1_doc = Part_1.document() +ParamR = model.addParameter(Part_1_doc, "R", "50") +ParamFrom = model.addParameter(Part_1_doc, "offsetFrom", "0") +ParamTo = model.addParameter(Part_1_doc, "offsetTo", "0") +Cylinder_1 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), "R", 100, 180) +Translation_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Cylinder_1_1")], model.selection("EDGE", "PartSet/OY"), 50) +Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOZ")) +SketchLine_1 = Sketch_1.addLine(20, 40, -30, 40) +SketchLine_2 = Sketch_1.addLine(-30, 40, -30, 20) +SketchLine_3 = Sketch_1.addLine(-30, 20, 20, 20) +SketchLine_4 = Sketch_1.addLine(20, 20, 20, 40) +SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_1.startPoint()) +SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint()) +SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint()) +SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint()) +SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_1.result()) +SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_2.result()) +SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_3.result()) +SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_4.result()) +SketchConstraintLength_1 = Sketch_1.setLength(SketchLine_3.result(), 50) +SketchConstraintLength_2 = Sketch_1.setLength(SketchLine_2.result(), 20) +SketchProjection_1 = Sketch_1.addProjection(model.selection("VERTEX", "PartSet/Origin"), False) +SketchPoint_1 = SketchProjection_1.createdFeature() +SketchConstraintDistanceHorizontal_1 = Sketch_1.setHorizontalDistance(SketchAPI_Point(SketchPoint_1).coordinates(), SketchLine_3.endPoint(), 20) +SketchConstraintDistanceVertical_1 = Sketch_1.setVerticalDistance(SketchAPI_Point(SketchPoint_1).coordinates(), SketchLine_3.endPoint(), 20) +SketchLine_5 = Sketch_1.addLine(-10, 20, 5, 40) +SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_5.startPoint(), SketchLine_3.result()) +SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchLine_5.endPoint(), SketchLine_1.result()) +SketchConstraintDistanceHorizontal_2 = Sketch_1.setHorizontalDistance(SketchLine_2.endPoint(), SketchLine_5.startPoint(), 20) +SketchConstraintDistanceHorizontal_3 = Sketch_1.setHorizontalDistance(SketchLine_5.endPoint(), SketchLine_1.startPoint(), 15) +model.do() +Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_1r-SketchLine_2f-SketchLine_3f-SketchLine_5f"), model.selection("FACE", "Sketch_1/Face-SketchLine_1r-SketchLine_5r-SketchLine_3f-SketchLine_4f")], model.selection(), model.selection("FACE", "Translation_1_1/MF:Translated&Cylinder_1_1/Face_1"), "offsetTo", model.selection(), "offsetFrom") + +from GeomAPI import GeomAPI_Shape + +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [12]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [48]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [96]) +model.testResultsVolumes(Extrusion_1, [97540.6]) + +# change radius of cylinder and check failure +ParamR.setValue(10) +model.do() +assert(Extrusion_1.feature().error() != "") + +# revert failure, check the intersected boundaries are processed well +ParamR.setValue(30) +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [12]) +model.testResultsVolumes(Extrusion_1, [75176.8518]) + +ParamR.setValue(40); +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [12]) +model.testResultsVolumes(Extrusion_1, [86812.03]) + +# change offsetting "To" face and check failure +ParamTo.setValue(-25) +model.do() +assert(Extrusion_1.feature().error() != "") + +# revert failure +ParamTo.setValue(20) +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [12]) +model.testResultsVolumes(Extrusion_1, [107985.85]) + +# offset "From" face +ParamFrom.setValue(-20) +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [12]) +model.testResultsVolumes(Extrusion_1, [87985.85]) + +ParamFrom.setValue(20) +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [12]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [48]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [96]) +model.testResultsVolumes(Extrusion_1, [127985.85]) + +model.testHaveNamingSubshapes(Extrusion_1, model, Part_1_doc) + +model.end() + +assert(model.checkPythonDump()) diff --git a/src/FeaturesPlugin/Test/TestExtrusion_ByFaces09.py b/src/FeaturesPlugin/Test/TestExtrusion_ByFaces09.py new file mode 100644 index 000000000..da81086ad --- /dev/null +++ b/src/FeaturesPlugin/Test/TestExtrusion_ByFaces09.py @@ -0,0 +1,157 @@ +# 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 +# + +from SketchAPI import * + +from salome.shaper import model + +model.begin() +partSet = model.moduleDocument() +Part_1 = model.addPart(partSet) +Part_1_doc = Part_1.document() +ParamR = model.addParameter(Part_1_doc, "R", "50") +ParamSize = model.addParameter(Part_1_doc, "Size", "50") +ParamFrom = model.addParameter(Part_1_doc, "offsetFrom", "0") +ParamTo = model.addParameter(Part_1_doc, "offsetTo", "0") +Sphere_1 = model.addSphere(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), "R") +Partition_1 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Sphere_1_1"), model.selection("FACE", "PartSet/XOZ")]) +Plane_4 = model.addPlane(Part_1_doc, model.selection("FACE", "PartSet/XOZ"), 10, False) +Sketch_1 = model.addSketch(Part_1_doc, model.selection("FACE", "Plane_1")) +SketchLine_1 = Sketch_1.addLine(50, -50, -50, -50) +SketchLine_2 = Sketch_1.addLine(-50, -50, -50, 50) +SketchLine_3 = Sketch_1.addLine(-50, 50, 50, 50) +SketchLine_4 = Sketch_1.addLine(50, 50, 50, -50) +SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_1.startPoint()) +SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint()) +SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint()) +SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint()) +SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_1.result()) +SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_2.result()) +SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_3.result()) +SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_4.result()) +SketchProjection_1 = Sketch_1.addProjection(model.selection("VERTEX", "PartSet/Origin"), False) +SketchPoint_1 = SketchProjection_1.createdFeature() +SketchConstraintDistance_1 = Sketch_1.setDistance(SketchAPI_Point(SketchPoint_1).coordinates(), SketchLine_4.result(), "Size", True) +SketchConstraintDistance_2 = Sketch_1.setDistance(SketchAPI_Point(SketchPoint_1).coordinates(), SketchLine_2.result(), "Size", True) +SketchConstraintDistance_3 = Sketch_1.setDistance(SketchAPI_Point(SketchPoint_1).coordinates(), SketchLine_1.result(), "Size", True) +SketchConstraintDistance_4 = Sketch_1.setDistance(SketchAPI_Point(SketchPoint_1).coordinates(), SketchLine_3.result(), "Size", True) +model.do() +Face_1 = model.addFace(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_4r-SketchLine_3r-SketchLine_2r-SketchLine_1r")]) +Sketch_2 = model.addSketch(Part_1_doc, model.defaultPlane("XOZ")) +SketchLine_5 = Sketch_2.addLine(20, -15, 20, 20) +SketchLine_6 = Sketch_2.addLine(20, 20, -15, 20) +SketchConstraintCoincidence_5 = Sketch_2.setCoincident(SketchLine_5.endPoint(), SketchLine_6.startPoint()) +SketchConstraintVertical_3 = Sketch_2.setVertical(SketchLine_5.result()) +SketchConstraintHorizontal_3 = Sketch_2.setHorizontal(SketchLine_6.result()) +SketchArc_1 = Sketch_2.addArc(0, 0, -15, 20, 20, -15, False) +SketchConstraintCoincidence_6 = Sketch_2.setCoincident(SketchLine_6.endPoint(), SketchArc_1.startPoint()) +SketchConstraintCoincidence_7 = Sketch_2.setCoincident(SketchArc_1.endPoint(), SketchLine_5.startPoint()) +SketchConstraintEqual_1 = Sketch_2.setEqual(SketchLine_5.result(), SketchLine_6.result()) +SketchConstraintDistance_5 = Sketch_2.setDistance(SketchArc_1.center(), SketchLine_5.result(), 20, True) +SketchProjection_2 = Sketch_2.addProjection(model.selection("VERTEX", "PartSet/Origin"), False) +SketchPoint_2 = SketchProjection_2.createdFeature() +SketchConstraintCoincidence_8 = Sketch_2.setCoincident(SketchAPI_Point(SketchPoint_2).coordinates(), SketchArc_1.center()) +SketchConstraintRadius_1 = Sketch_2.setRadius(SketchArc_1.results()[1], 25) +SketchLine_7 = Sketch_2.addLine(-15, 20, 20, -15) +SketchConstraintCoincidence_9 = Sketch_2.setCoincident(SketchLine_6.endPoint(), SketchLine_7.startPoint()) +SketchConstraintCoincidence_10 = Sketch_2.setCoincident(SketchLine_5.startPoint(), SketchLine_7.endPoint()) +model.do() +Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_2/Face-SketchArc_1_2f-SketchLine_7r"), model.selection("FACE", "Sketch_2/Face-SketchLine_5r-SketchLine_6f-SketchLine_7f")], model.selection(), model.selection("FACE", "Partition_1_1_2/Modified_Face&Sphere_1_1/Face_1"), "offsetTo", model.selection("FACE", "Face_1_1"), "offsetFrom") + +from GeomAPI import GeomAPI_Shape + +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [9]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [30]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [60]) +model.testResultsVolumes(Extrusion_1, [100878.6]) + +# change radius of sphere and check failure +ParamR.setValue(10) +model.do() +assert(Extrusion_1.feature().error() != "") + +# revert failure, check the intersected boundaries are processed well +ParamR.setValue(30) +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [9]) +model.testResultsVolumes(Extrusion_1, [60964.23998]) + +ParamR.setValue(40); +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [9]) +model.testResultsVolumes(Extrusion_1, [81651.666]) + +# change size of the face +ParamSize.setValue(10) +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [9]) +model.testResultsVolumes(Extrusion_1, [81651.666]) + +# change offsetting "To" face and check failure +ParamTo.setValue(-20) +model.do() +assert(Extrusion_1.feature().error() != "") + +# revert failure +ParamTo.setValue(20) +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [9]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [34]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [68]) +model.testResultsVolumes(Extrusion_1, [119535.04]) + +# offset "From" face +ParamFrom.setValue(-20) +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [9]) +model.testResultsVolumes(Extrusion_1, [84126.377]) + +ParamFrom.setValue(20) +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [9]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [34]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [68]) +model.testResultsVolumes(Extrusion_1, [154943.7]) + +model.testHaveNamingSubshapes(Extrusion_1, model, Part_1_doc) + +model.end() + +assert(model.checkPythonDump()) diff --git a/src/FeaturesPlugin/Test/TestExtrusion_ByFaces10.py b/src/FeaturesPlugin/Test/TestExtrusion_ByFaces10.py new file mode 100644 index 000000000..e618ca61c --- /dev/null +++ b/src/FeaturesPlugin/Test/TestExtrusion_ByFaces10.py @@ -0,0 +1,136 @@ +# 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 +# + +from SketchAPI import * +from GeomAPI import GeomAPI_Shape + +from salome.shaper import model + +model.begin() +partSet = model.moduleDocument() +Part_1 = model.addPart(partSet) +Part_1_doc = Part_1.document() +ParamR = model.addParameter(Part_1_doc, "R", "50") +ParamSize = model.addParameter(Part_1_doc, "Size", "50") +ParamFrom = model.addParameter(Part_1_doc, "offsetFrom", "0") +ParamTo = model.addParameter(Part_1_doc, "offsetTo", "0") +Sphere_1 = model.addSphere(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), "R") +Partition_1 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Sphere_1_1"), model.selection("FACE", "PartSet/XOZ")]) +Plane_4 = model.addPlane(Part_1_doc, model.selection("FACE", "PartSet/XOZ"), 30, False) +Sketch_1 = model.addSketch(Part_1_doc, model.selection("FACE", "Plane_1")) +SketchLine_1 = Sketch_1.addLine(50, -50, -50, -50) +SketchLine_2 = Sketch_1.addLine(-50, -50, -50, 50) +SketchLine_3 = Sketch_1.addLine(-50, 50, 50, 50) +SketchLine_4 = Sketch_1.addLine(50, 50, 50, -50) +SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_1.startPoint()) +SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint()) +SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint()) +SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint()) +SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_1.result()) +SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_2.result()) +SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_3.result()) +SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_4.result()) +SketchProjection_1 = Sketch_1.addProjection(model.selection("VERTEX", "PartSet/Origin"), False) +SketchPoint_1 = SketchProjection_1.createdFeature() +SketchConstraintDistance_1 = Sketch_1.setDistance(SketchAPI_Point(SketchPoint_1).coordinates(), SketchLine_4.result(), "Size", True) +SketchConstraintDistance_2 = Sketch_1.setDistance(SketchAPI_Point(SketchPoint_1).coordinates(), SketchLine_2.result(), "Size", True) +SketchConstraintDistance_3 = Sketch_1.setDistance(SketchAPI_Point(SketchPoint_1).coordinates(), SketchLine_1.result(), "Size", True) +SketchConstraintDistance_4 = Sketch_1.setDistance(SketchAPI_Point(SketchPoint_1).coordinates(), SketchLine_3.result(), "Size", True) +model.do() +Face_1 = model.addFace(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_4r-SketchLine_3r-SketchLine_2r-SketchLine_1r")]) +Sketch_2 = model.addSketch(Part_1_doc, model.defaultPlane("XOZ")) +SketchLine_5 = Sketch_2.addLine(20, -40.3112887414928, 20, 20) +SketchLine_6 = Sketch_2.addLine(20, 20, -40.31128874149281, 20.00000000000001) +SketchConstraintCoincidence_5 = Sketch_2.setCoincident(SketchLine_5.endPoint(), SketchLine_6.startPoint()) +SketchConstraintVertical_3 = Sketch_2.setVertical(SketchLine_5.result()) +SketchConstraintHorizontal_3 = Sketch_2.setHorizontal(SketchLine_6.result()) +SketchArc_1 = Sketch_2.addArc(0, 0, -40.31128874149281, 20.00000000000001, 20, -40.3112887414928, False) +SketchConstraintCoincidence_6 = Sketch_2.setCoincident(SketchLine_6.endPoint(), SketchArc_1.startPoint()) +SketchConstraintCoincidence_7 = Sketch_2.setCoincident(SketchArc_1.endPoint(), SketchLine_5.startPoint()) +SketchConstraintEqual_1 = Sketch_2.setEqual(SketchLine_5.result(), SketchLine_6.result()) +SketchConstraintDistance_5 = Sketch_2.setDistance(SketchArc_1.center(), SketchLine_5.result(), 20, True) +SketchProjection_2 = Sketch_2.addProjection(model.selection("VERTEX", "PartSet/Origin"), False) +SketchPoint_2 = SketchProjection_2.createdFeature() +SketchConstraintCoincidence_8 = Sketch_2.setCoincident(SketchAPI_Point(SketchPoint_2).coordinates(), SketchArc_1.center()) +SketchConstraintRadius_1 = Sketch_2.setRadius(SketchArc_1.results()[1], 45) +SketchLine_7 = Sketch_2.addLine(20, 20, -31.81980515339464, -31.81980515339464) +SketchConstraintCoincidence_9 = Sketch_2.setCoincident(SketchLine_5.endPoint(), SketchLine_7.startPoint()) +SketchConstraintCoincidence_10 = Sketch_2.setCoincident(SketchLine_7.endPoint(), SketchArc_1.results()[1]) +SketchConstraintCoincidence_11 = Sketch_2.setCoincident(SketchArc_1.center(), SketchLine_7.result()) +model.do() +Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("COMPOUND", "Sketch_2")], model.selection(), model.selection("FACE", "Partition_1_1_1/Modified_Face&Sphere_1_1/Face_1"), "offsetTo", model.selection("FACE", "Face_1_1"), "offsetFrom") + +# extrusion have to fail because of several results with shared topology +assert(Extrusion_1.feature().error() != "") + +# change radius of sphere and check failure +ParamR.setValue(10) +model.do() +assert(Extrusion_1.feature().error() != "") + +ParamR.setValue(45) +model.do() +assert(Extrusion_1.feature().error() != "") + +# change offsetting "To" face and check failure +ParamTo.setValue(-20) +model.do() +assert(Extrusion_1.feature().error() != "") + +# revert failure +ParamTo.setValue(20) +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [10]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [40]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [80]) +model.testResultsVolumes(Extrusion_1, [105008.93]) + +# offset "From" face +ParamFrom.setValue(-20) +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [10]) +model.testResultsVolumes(Extrusion_1, [179594.5]) + +# check failure +ParamFrom.setValue(20) +model.do() +assert(Extrusion_1.feature().error() != "") + +# revert failure +ParamTo.setValue(0) +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [10]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [39]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [78]) +model.testResultsVolumes(Extrusion_1, [62569.416]) + +model.testHaveNamingSubshapes(Extrusion_1, model, Part_1_doc) + +model.end() + +assert(model.checkPythonDump()) diff --git a/src/FeaturesPlugin/Test/TestExtrusion_ByFaces11.py b/src/FeaturesPlugin/Test/TestExtrusion_ByFaces11.py new file mode 100644 index 000000000..f66471f5b --- /dev/null +++ b/src/FeaturesPlugin/Test/TestExtrusion_ByFaces11.py @@ -0,0 +1,166 @@ +# 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 +# + +from SketchAPI import * + +from salome.shaper import model + +model.begin() +partSet = model.moduleDocument() +Part_1 = model.addPart(partSet) +Part_1_doc = Part_1.document() +ParamRSph = model.addParameter(Part_1_doc, "rSphere", "50") +ParamRCyl = model.addParameter(Part_1_doc, "rCyl", "30") +ParamRCir = model.addParameter(Part_1_doc, "rCircle", "10") +ParamFrom = model.addParameter(Part_1_doc, "offsetFrom", "0") +ParamTo = model.addParameter(Part_1_doc, "offsetTo", "0") +Sphere_1 = model.addSphere(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), "rSphere") +Cylinder_1 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), "rCyl", 100) +Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOZ")) +SketchCircle_1 = Sketch_1.addCircle(15, 20, 10) +SketchConstraintRadius_1 = Sketch_1.setRadius(SketchCircle_1.results()[1], "rCircle") +SketchProjection_1 = Sketch_1.addProjection(model.selection("VERTEX", "PartSet/Origin"), False) +SketchPoint_1 = SketchProjection_1.createdFeature() +SketchConstraintDistanceHorizontal_1 = Sketch_1.setHorizontalDistance(SketchAPI_Point(SketchPoint_1).coordinates(), SketchCircle_1.center(), 15) +SketchConstraintDistanceVertical_1 = Sketch_1.setVerticalDistance(SketchAPI_Point(SketchPoint_1).coordinates(), SketchCircle_1.center(), 20) +SketchLine_1 = Sketch_1.addLine(6.339745962155468, 15, 23.66025403784453, 15) +SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchCircle_1.results()[1]) +SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchCircle_1.results()[1]) +SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_1.result()) +SketchConstraintDistance_1 = Sketch_1.setDistance(SketchCircle_1.center(), SketchLine_1.result(), "rCircle/2", True) +model.do() +Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchCircle_1_2r-SketchCircle_1_2r-SketchLine_1r"), model.selection("FACE", "Sketch_1/Face-SketchCircle_1_2r-SketchLine_1f")], model.selection(), model.selection("FACE", "Sphere_1_1/Face_1"), "offsetTo", model.selection("FACE", "Cylinder_1_1/Face_1"), "offsetFrom") + +from GeomAPI import GeomAPI_Shape + +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [4]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [18]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [60]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [120]) +model.testResultsVolumes(Extrusion_1, [10878.5462]) + +# change radius of sketch circle +ParamRCir.setValue(17) +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [3]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [3]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [17]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [66]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [132]) +model.testResultsVolumes(Extrusion_1, [32102.71838]) + +# change radius of sphere and check failure +ParamRSph.setValue(15) +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [13]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [61]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [122]) +model.testResultsVolumes(Extrusion_1, [41289.10946]) + +# change radius of sketch circle and check failure +ParamRCir.setValue(10) +model.do() +assert(Extrusion_1.feature().error() != "") + +# revert failure +ParamRSph.setValue(45); +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [4]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [18]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [60]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [120]) +model.testResultsVolumes(Extrusion_1, [7083.567842]) + +# change radius of cylinder +ParamRCyl.setValue(10) +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [13]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [54]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [108]) +model.testResultsVolumes(Extrusion_1, [22295.845141]) + +ParamRCyl.setValue(50) +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [4]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [18]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [60]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [120]) +model.testResultsVolumes(Extrusion_1, [6805.1007457]) + +# change offsetting "To" face +ParamTo.setValue(-20) +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [14]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [60]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [120]) +model.testResultsVolumes(Extrusion_1, [26158.63076]) + +# revert failure +ParamTo.setValue(20) +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [4]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [18]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [64]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [128]) +model.testResultsVolumes(Extrusion_1, [7626.2279286]) + +# offset "From" face +ParamFrom.setValue(-20) +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [4]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [18]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [68]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [136]) +model.testResultsVolumes(Extrusion_1, [21514.8965]) + +ParamFrom.setValue(20) +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [4]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [18]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [68]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [136]) +model.testResultsVolumes(Extrusion_1, [5427.194275658]) + +model.testHaveNamingSubshapes(Extrusion_1, model, Part_1_doc) + +model.end() + +assert(model.checkPythonDump()) diff --git a/src/FeaturesPlugin/Test/TestExtrusion_ByFaces12.py b/src/FeaturesPlugin/Test/TestExtrusion_ByFaces12.py new file mode 100644 index 000000000..5473797ac --- /dev/null +++ b/src/FeaturesPlugin/Test/TestExtrusion_ByFaces12.py @@ -0,0 +1,120 @@ +# 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 +# + +from SketchAPI import * + +from salome.shaper import model + +model.begin() +partSet = model.moduleDocument() +Part_1 = model.addPart(partSet) +Part_1_doc = Part_1.document() +ParamR = model.addParameter(Part_1_doc, "R", "50") +ParamFrom = model.addParameter(Part_1_doc, "offsetFrom", "0") +ParamTo = model.addParameter(Part_1_doc, "offsetTo", "0") +Cone_1 = model.addCone(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), "R", "R/5", "R") +Partition_1 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Cone_1_1"), model.selection("FACE", "PartSet/XOZ")]) +Plane_4 = model.addPlane(Part_1_doc, model.selection("FACE", "PartSet/XOZ"), 20, False) +Plane_5 = model.addPlane(Part_1_doc, model.selection("FACE", "Plane_1"), model.selection("EDGE", "PartSet/OZ"), 330) +Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOZ")) +SketchLine_1 = Sketch_1.addLine(10, 8.819660112501044, 10, 30) +SketchLine_2 = Sketch_1.addLine(10, 30, -11.18033988749895, 30) +SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint()) +SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_1.result()) +SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_2.result()) +SketchArc_1 = Sketch_1.addArc(0, 20, -11.18033988749895, 30, 10, 8.819660112501044, False) +SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchArc_1.startPoint()) +SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchArc_1.endPoint(), SketchLine_1.startPoint()) +SketchConstraintEqual_1 = Sketch_1.setEqual(SketchLine_1.result(), SketchLine_2.result()) +SketchConstraintDistance_1 = Sketch_1.setDistance(SketchArc_1.center(), SketchLine_1.result(), 10, True) +SketchConstraintRadius_1 = Sketch_1.setRadius(SketchArc_1.results()[1], 15) +SketchProjection_1 = Sketch_1.addProjection(model.selection("EDGE", "PartSet/OZ"), False) +SketchLine_3 = SketchProjection_1.createdFeature() +SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchArc_1.center(), SketchLine_3.result()) +SketchConstraintDistanceVertical_1 = Sketch_1.setVerticalDistance(SketchAPI_Line(SketchLine_3).startPoint(), SketchArc_1.center(), 20) +SketchLine_4 = Sketch_1.addLine(-11.18033988749895, 30, 10, 8.819660112501044) +SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_4.startPoint()) +SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchArc_1.endPoint(), SketchLine_4.endPoint()) +model.do() +Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("COMPOUND", "Sketch_1")], model.selection(), model.selection("FACE", "Partition_1_1_2/Modified_Face&Cone_1_1/Face_1"), "offsetTo", model.selection("FACE", "Plane_2"), "offsetFrom") + +from GeomAPI import GeomAPI_Shape + +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [9]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [32]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [64]) +model.testResultsVolumes(Extrusion_1, [31363.4963946]) + +# change radius of sphere and check failure +ParamR.setValue(10) +model.do() +assert(Extrusion_1.feature().error() != "") + +# revert failure, check the intersected boundaries are processed well +ParamR.setValue(40) +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [9]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [32]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [64]) +model.testResultsVolumes(Extrusion_1, [25645.0102138]) + +# change offsetting "To" face and check failure +ParamTo.setValue(-20) +model.do() +assert(Extrusion_1.feature().error() != "") + +# revert failure +ParamTo.setValue(8) +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [9]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [32]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [64]) +model.testResultsVolumes(Extrusion_1, [31501.9671234]) + +# offset "From" face +ParamFrom.setValue(-20) +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [9]) +model.testResultsVolumes(Extrusion_1, [18737.752452]) + +ParamFrom.setValue(20) +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [9]) +model.testResultsVolumes(Extrusion_1, [44266.1817647]) + +model.testHaveNamingSubshapes(Extrusion_1, model, Part_1_doc) + +model.end() + +assert(model.checkPythonDump()) diff --git a/src/FeaturesPlugin/Test/TestExtrusion_ByFaces13.py b/src/FeaturesPlugin/Test/TestExtrusion_ByFaces13.py new file mode 100644 index 000000000..710db14d5 --- /dev/null +++ b/src/FeaturesPlugin/Test/TestExtrusion_ByFaces13.py @@ -0,0 +1,128 @@ +# 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 +# + +from SketchAPI import * + +from salome.shaper import model + +model.begin() +partSet = model.moduleDocument() +Part_1 = model.addPart(partSet) +Part_1_doc = Part_1.document() +ParamR = model.addParameter(Part_1_doc, "R", "50") +ParamFrom = model.addParameter(Part_1_doc, "offsetFrom", "0") +ParamTo = model.addParameter(Part_1_doc, "offsetTo", "0") +Cylinder_1 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), "R", 100, 180) +Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOZ")) +SketchLine_1 = Sketch_1.addLine(20, 40, -30, 40) +SketchLine_2 = Sketch_1.addLine(-30, 40, -30, 20) +SketchLine_3 = Sketch_1.addLine(-30, 20, 20, 20) +SketchLine_4 = Sketch_1.addLine(20, 20, 20, 40) +SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_1.startPoint()) +SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint()) +SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint()) +SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint()) +SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_1.result()) +SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_2.result()) +SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_3.result()) +SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_4.result()) +SketchConstraintLength_1 = Sketch_1.setLength(SketchLine_3.result(), 50) +SketchConstraintLength_2 = Sketch_1.setLength(SketchLine_2.result(), 20) +SketchProjection_1 = Sketch_1.addProjection(model.selection("VERTEX", "PartSet/Origin"), False) +SketchPoint_1 = SketchProjection_1.createdFeature() +SketchConstraintDistanceHorizontal_1 = Sketch_1.setHorizontalDistance(SketchAPI_Point(SketchPoint_1).coordinates(), SketchLine_3.endPoint(), 20) +SketchConstraintDistanceVertical_1 = Sketch_1.setVerticalDistance(SketchAPI_Point(SketchPoint_1).coordinates(), SketchLine_3.endPoint(), 20) +model.do() +Edge_1_objects = [model.selection("EDGE", "Sketch_1/SketchLine_1"), model.selection("EDGE", "Sketch_1/SketchLine_2"), model.selection("EDGE", "Sketch_1/SketchLine_3"), model.selection("EDGE", "Sketch_1/SketchLine_4")] +Edge_1 = model.addEdge(Part_1_doc, Edge_1_objects) +Extrusion_1_objects = [model.selection("EDGE", "Edge_1_1"), model.selection("EDGE", "Edge_1_2"), model.selection("EDGE", "Edge_1_3"), model.selection("EDGE", "Edge_1_4")] +Extrusion_1 = model.addExtrusion(Part_1_doc, Extrusion_1_objects, model.selection("EDGE", "PartSet/OY"), model.selection("FACE", "Cylinder_1_1/Face_1"), "offsetTo", model.selection(), "offsetFrom") + +from GeomAPI import GeomAPI_Shape + +model.testNbResults(Extrusion_1, 4) +model.testNbSubResults(Extrusion_1, [0, 0, 0, 0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [0, 0, 0, 0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [1, 1, 1, 1]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [4, 4, 4, 4]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [8, 8, 8, 8]) +model.testResultsVolumes(Extrusion_1, [2377.030013, 800, 2377.030013, 916.515139]) + +# change radius of cylinder +ParamR.setValue(10) +model.do() +assert(Extrusion_1.feature().error() != "") + +ParamR.setValue(30) +model.do() +assert(Extrusion_1.feature().error() != "") + +# revert failure and check the intersected boundaries are processed well +ParamR.setValue(40); +model.do() +model.testNbResults(Extrusion_1, 4) +model.testNbSubResults(Extrusion_1, [0, 0, 0, 0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [0, 0, 0, 0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [1, 1, 1, 1]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [4, 4, 4, 4]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [8, 8, 8, 8]) +model.testResultsVolumes(Extrusion_1, [1840.601542, 529.150262, 1840.601542, 692.820323]) + +# change offsetting "To" face +ParamTo.setValue(-20) +model.do() +assert(Extrusion_1.feature().error() != "") + +# revert failure +ParamTo.setValue(20) +model.do() +model.testNbResults(Extrusion_1, 4) +model.testNbSubResults(Extrusion_1, [0, 0, 0, 0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [0, 0, 0, 0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [1, 1, 1, 1]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [4, 4, 4, 4]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [8, 8, 8, 8]) +model.testResultsVolumes(Extrusion_1, [2899.292521, 1039.2304845, 2899.292521, 1131.3708499]) + +# offset "From" face +ParamFrom.setValue(-20) +model.do() +model.testNbResults(Extrusion_1, 4) +model.testNbSubResults(Extrusion_1, [0, 0, 0, 0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [0, 0, 0, 0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [1, 1, 1, 1]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [4, 4, 4, 4]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [8, 8, 8, 8]) +model.testResultsVolumes(Extrusion_1, [3899.292521, 1439.2304845, 3899.292521, 1531.3708499]) + +ParamFrom.setValue(20) +model.do() +model.testNbResults(Extrusion_1, 4) +model.testNbSubResults(Extrusion_1, [0, 0, 0, 0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [0, 0, 0, 0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [1, 1, 1, 1]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [4, 4, 4, 4]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [8, 8, 8, 8]) +model.testResultsVolumes(Extrusion_1, [1899.292521, 639.2304845, 1899.292521, 731.3708499]) + +model.testHaveNamingSubshapes(Extrusion_1, model, Part_1_doc) + +model.end() + +assert(model.checkPythonDump()) diff --git a/src/FeaturesPlugin/Test/TestExtrusion_ByFaces14.py b/src/FeaturesPlugin/Test/TestExtrusion_ByFaces14.py new file mode 100644 index 000000000..7f8348c69 --- /dev/null +++ b/src/FeaturesPlugin/Test/TestExtrusion_ByFaces14.py @@ -0,0 +1,129 @@ +# 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 +# + +from SketchAPI import * + +from salome.shaper import model + +model.begin() +partSet = model.moduleDocument() +Part_1 = model.addPart(partSet) +Part_1_doc = Part_1.document() +ParamR = model.addParameter(Part_1_doc, "R", "50") +ParamFrom = model.addParameter(Part_1_doc, "offsetFrom", "0") +ParamTo = model.addParameter(Part_1_doc, "offsetTo", "0") +Cylinder_1 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), "R", 100, 180) +Translation_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Cylinder_1_1")], model.selection("EDGE", "PartSet/OY"), 50) +Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOZ")) +SketchLine_1 = Sketch_1.addLine(20, 40, -30, 40) +SketchLine_2 = Sketch_1.addLine(-30, 40, -30, 20) +SketchLine_3 = Sketch_1.addLine(-30, 20, 20, 20) +SketchLine_4 = Sketch_1.addLine(20, 20, 20, 40) +SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_1.startPoint()) +SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint()) +SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint()) +SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint()) +SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_1.result()) +SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_2.result()) +SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_3.result()) +SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_4.result()) +SketchConstraintLength_1 = Sketch_1.setLength(SketchLine_3.result(), 50) +SketchConstraintLength_2 = Sketch_1.setLength(SketchLine_2.result(), 20) +SketchProjection_1 = Sketch_1.addProjection(model.selection("VERTEX", "PartSet/Origin"), False) +SketchPoint_1 = SketchProjection_1.createdFeature() +SketchConstraintDistanceHorizontal_1 = Sketch_1.setHorizontalDistance(SketchAPI_Point(SketchPoint_1).coordinates(), SketchLine_3.endPoint(), 20) +SketchConstraintDistanceVertical_1 = Sketch_1.setVerticalDistance(SketchAPI_Point(SketchPoint_1).coordinates(), SketchLine_3.endPoint(), 20) +model.do() +Edge_1_objects = [model.selection("EDGE", "Sketch_1/SketchLine_1"), model.selection("EDGE", "Sketch_1/SketchLine_2"), model.selection("EDGE", "Sketch_1/SketchLine_3"), model.selection("EDGE", "Sketch_1/SketchLine_4")] +Edge_1 = model.addEdge(Part_1_doc, Edge_1_objects) +Extrusion_1_objects = [model.selection("EDGE", "Edge_1_1"), model.selection("EDGE", "Edge_1_2"), model.selection("EDGE", "Edge_1_3"), model.selection("EDGE", "Edge_1_4")] +Extrusion_1 = model.addExtrusion(Part_1_doc, Extrusion_1_objects, model.selection("EDGE", "PartSet/OY"), model.selection("FACE", "Translation_1_1/MF:Translated&Cylinder_1_1/Face_1"), "offsetTo", model.selection(), "offsetFrom") + +from GeomAPI import GeomAPI_Shape + +model.testNbResults(Extrusion_1, 4) +model.testNbSubResults(Extrusion_1, [0, 0, 0, 0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [0, 0, 0, 0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [1, 1, 1, 1]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [4, 4, 4, 4]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [8, 8, 8, 8]) +model.testResultsVolumes(Extrusion_1, [4877.030013, 1800, 4877.030013, 1916.515139]) + +# change radius of cylinder and check failure +ParamR.setValue(10) +model.do() +assert(Extrusion_1.feature().error() != "") + +ParamR.setValue(30) +model.do() +assert(Extrusion_1.feature().error() != "") + +# revert failure, check the intersected boundaries are processed well +ParamR.setValue(40); +model.do() +model.testNbResults(Extrusion_1, 4) +model.testNbSubResults(Extrusion_1, [0, 0, 0, 0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [0, 0, 0, 0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [1, 1, 1, 1]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [4, 4, 4, 4]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [8, 8, 8, 8]) +model.testResultsVolumes(Extrusion_1, [4340.6015418, 1529.1502622, 4340.6015418, 1692.820323]) + +# change offsetting "To" face and check failure +ParamTo.setValue(-20) +model.do() +assert(Extrusion_1.feature().error() != "") + +# revert failure +ParamTo.setValue(20) +model.do() +model.testNbResults(Extrusion_1, 4) +model.testNbSubResults(Extrusion_1, [0, 0, 0, 0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [0, 0, 0, 0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [1, 1, 1, 1]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [4, 4, 4, 4]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [8, 8, 8, 8]) +model.testResultsVolumes(Extrusion_1, [5399.2925211, 2039.2304845, 5399.2925212, 2131.37085]) + +# offset "From" face +ParamFrom.setValue(-20) +model.do() +model.testNbResults(Extrusion_1, 4) +model.testNbSubResults(Extrusion_1, [0, 0, 0, 0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [0, 0, 0, 0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [1, 1, 1, 1]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [4, 4, 4, 4]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [8, 8, 8, 8]) +model.testResultsVolumes(Extrusion_1, [6399.2925211, 2439.2304845, 6399.2925212, 2531.37085]) + +ParamFrom.setValue(20) +model.do() +model.testNbResults(Extrusion_1, 4) +model.testNbSubResults(Extrusion_1, [0, 0, 0, 0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [0, 0, 0, 0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [1, 1, 1, 1]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [4, 4, 4, 4]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [8, 8, 8, 8]) +model.testResultsVolumes(Extrusion_1, [4399.2925211, 1639.2304845, 4399.2925212, 1731.37085]) + +model.testHaveNamingSubshapes(Extrusion_1, model, Part_1_doc) + +model.end() + +assert(model.checkPythonDump()) diff --git a/src/FeaturesPlugin/Test/TestExtrusion_ByFaces15.py b/src/FeaturesPlugin/Test/TestExtrusion_ByFaces15.py new file mode 100644 index 000000000..a65ebacda --- /dev/null +++ b/src/FeaturesPlugin/Test/TestExtrusion_ByFaces15.py @@ -0,0 +1,165 @@ +# 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 +# + +from SketchAPI import * + +from salome.shaper import model + +model.begin() +partSet = model.moduleDocument() +Part_1 = model.addPart(partSet) +Part_1_doc = Part_1.document() +ParamR = model.addParameter(Part_1_doc, "R", "50") +ParamSize = model.addParameter(Part_1_doc, "Size", "50") +ParamFrom = model.addParameter(Part_1_doc, "offsetFrom", "0") +ParamTo = model.addParameter(Part_1_doc, "offsetTo", "0") +Sphere_1 = model.addSphere(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), "R") +Partition_1 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Sphere_1_1"), model.selection("FACE", "PartSet/XOZ")]) +Plane_4 = model.addPlane(Part_1_doc, model.selection("FACE", "PartSet/XOZ"), 10, False) +Sketch_1 = model.addSketch(Part_1_doc, model.selection("FACE", "Plane_1")) +SketchLine_1 = Sketch_1.addLine(50, -50, -50, -50) +SketchLine_2 = Sketch_1.addLine(-50, -50, -50, 50) +SketchLine_3 = Sketch_1.addLine(-50, 50, 50, 50) +SketchLine_4 = Sketch_1.addLine(50, 50, 50, -50) +SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_1.startPoint()) +SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint()) +SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint()) +SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint()) +SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_1.result()) +SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_2.result()) +SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_3.result()) +SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_4.result()) +SketchProjection_1 = Sketch_1.addProjection(model.selection("VERTEX", "PartSet/Origin"), False) +SketchPoint_1 = SketchProjection_1.createdFeature() +SketchConstraintDistance_1 = Sketch_1.setDistance(SketchAPI_Point(SketchPoint_1).coordinates(), SketchLine_4.result(), "Size", True) +SketchConstraintDistance_2 = Sketch_1.setDistance(SketchAPI_Point(SketchPoint_1).coordinates(), SketchLine_2.result(), "Size", True) +SketchConstraintDistance_3 = Sketch_1.setDistance(SketchAPI_Point(SketchPoint_1).coordinates(), SketchLine_1.result(), "Size", True) +SketchConstraintDistance_4 = Sketch_1.setDistance(SketchAPI_Point(SketchPoint_1).coordinates(), SketchLine_3.result(), "Size", True) +model.do() +Face_1 = model.addFace(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_4r-SketchLine_3r-SketchLine_2r-SketchLine_1r")]) +Sketch_2 = model.addSketch(Part_1_doc, model.defaultPlane("XOZ")) +SketchLine_5 = Sketch_2.addLine(20, -15, 20, 20) +SketchLine_6 = Sketch_2.addLine(20, 20, -15, 20) +SketchConstraintCoincidence_5 = Sketch_2.setCoincident(SketchLine_5.endPoint(), SketchLine_6.startPoint()) +SketchConstraintVertical_3 = Sketch_2.setVertical(SketchLine_5.result()) +SketchConstraintHorizontal_3 = Sketch_2.setHorizontal(SketchLine_6.result()) +SketchArc_1 = Sketch_2.addArc(0, 0, -15, 20, 20, -15, False) +SketchConstraintCoincidence_6 = Sketch_2.setCoincident(SketchLine_6.endPoint(), SketchArc_1.startPoint()) +SketchConstraintCoincidence_7 = Sketch_2.setCoincident(SketchArc_1.endPoint(), SketchLine_5.startPoint()) +SketchConstraintEqual_1 = Sketch_2.setEqual(SketchLine_5.result(), SketchLine_6.result()) +SketchConstraintDistance_5 = Sketch_2.setDistance(SketchArc_1.center(), SketchLine_5.result(), 20, True) +SketchProjection_2 = Sketch_2.addProjection(model.selection("VERTEX", "PartSet/Origin"), False) +SketchPoint_2 = SketchProjection_2.createdFeature() +SketchConstraintCoincidence_8 = Sketch_2.setCoincident(SketchAPI_Point(SketchPoint_2).coordinates(), SketchArc_1.center()) +SketchConstraintRadius_1 = Sketch_2.setRadius(SketchArc_1.results()[1], 25) +model.do() +Edge_1_objects = [model.selection("EDGE", "Sketch_2/SketchLine_5"), model.selection("EDGE", "Sketch_2/SketchLine_6"), model.selection("EDGE", "Sketch_2/SketchArc_1_2")] +Edge_1 = model.addEdge(Part_1_doc, Edge_1_objects) +Extrusion_1_objects = [model.selection("EDGE", "Edge_1_1"), model.selection("EDGE", "Edge_1_2"), model.selection("EDGE", "Edge_1_3")] +Extrusion_1 = model.addExtrusion(Part_1_doc, Extrusion_1_objects, model.selection("EDGE", "PartSet/OY"), model.selection("FACE", "Partition_1_1_2/Modified_Face&Sphere_1_1/Face_1"), "offsetTo", model.selection("FACE", "Face_1_1"), "offsetFrom") + +from GeomAPI import GeomAPI_Shape + +model.testNbResults(Extrusion_1, 3) +model.testNbSubResults(Extrusion_1, [0, 0, 0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [0, 0, 0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [1, 1, 1]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [4, 4, 4]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [8, 8, 8]) +model.testResultsVolumes(Extrusion_1, [1911.43203298, 1911.43203298, 4564.43663366]) + +# change radius of sphere and check failure +ParamR.setValue(10) +model.do() +assert(Extrusion_1.feature().error() != "") + +# revert failure, check the intersected boundaries are processed well +ParamR.setValue(30) +model.do() +model.testNbResults(Extrusion_1, 3) +model.testNbSubResults(Extrusion_1, [0, 0, 0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [0, 0, 0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [1, 1, 1]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [4, 4, 4]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [8, 8, 8]) +model.testResultsVolumes(Extrusion_1, [1034.989222291, 1034.989222291, 2276.43702246]) + +ParamR.setValue(40); +model.do() +model.testNbResults(Extrusion_1, 3) +model.testNbSubResults(Extrusion_1, [0, 0, 0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [0, 0, 0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [1, 1, 1]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [4, 4, 4]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [8, 8, 8]) +model.testResultsVolumes(Extrusion_1, [1505.0174, 1505.0174, 3530.28837537636]) + +# change size of the face +ParamSize.setValue(10) +model.do() +model.testNbResults(Extrusion_1, 3) +model.testNbSubResults(Extrusion_1, [0, 0, 0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [0, 0, 0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [1, 1, 1]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [4, 4, 4]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [8, 8, 8]) +model.testResultsVolumes(Extrusion_1, [1505.0174, 1505.0174, 3530.28837537636]) + +# change offsetting "To" face and check failure +ParamTo.setValue(-20) +model.do() +assert(Extrusion_1.feature().error() != "") + +# revert failure +ParamTo.setValue(20) +model.do() +model.testNbResults(Extrusion_1, 3) +model.testNbSubResults(Extrusion_1, [0, 0, 0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [0, 0, 0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [1, 1, 1]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [4, 4, 6]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [8, 8, 12]) +model.testResultsVolumes(Extrusion_1, [2295.81450653, 2295.81450653, 5527.16645028]) + +# offset "From" face +ParamFrom.setValue(-20) +model.do() +model.testNbResults(Extrusion_1, 3) +model.testNbSubResults(Extrusion_1, [0, 0, 0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [0, 0, 0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [1, 1, 1]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [4, 4, 6]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [8, 8, 12]) +model.testResultsVolumes(Extrusion_1, [1595.81450653, 1595.81450653, 3814.47306888]) + +ParamFrom.setValue(20) +model.do() +model.testNbResults(Extrusion_1, 3) +model.testNbSubResults(Extrusion_1, [0, 0, 0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [0, 0, 0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [1, 1, 1]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [4, 4, 6]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [8, 8, 12]) +model.testResultsVolumes(Extrusion_1, [2995.81450653, 2995.81450653, 7239.85983168]) + +model.testHaveNamingSubshapes(Extrusion_1, model, Part_1_doc) + +model.end() + +assert(model.checkPythonDump()) diff --git a/src/FeaturesPlugin/Test/TestExtrusion_ByFaces16.py b/src/FeaturesPlugin/Test/TestExtrusion_ByFaces16.py new file mode 100644 index 000000000..bd18ce050 --- /dev/null +++ b/src/FeaturesPlugin/Test/TestExtrusion_ByFaces16.py @@ -0,0 +1,137 @@ +# 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 +# + +from SketchAPI import * +from GeomAPI import GeomAPI_Shape + +from salome.shaper import model + +model.begin() +partSet = model.moduleDocument() +Part_1 = model.addPart(partSet) +Part_1_doc = Part_1.document() +ParamR = model.addParameter(Part_1_doc, "R", "50") +ParamSize = model.addParameter(Part_1_doc, "Size", "50") +ParamFrom = model.addParameter(Part_1_doc, "offsetFrom", "0") +ParamTo = model.addParameter(Part_1_doc, "offsetTo", "0") +Sphere_1 = model.addSphere(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), "R") +Partition_1 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Sphere_1_1"), model.selection("FACE", "PartSet/XOZ")]) +Plane_4 = model.addPlane(Part_1_doc, model.selection("FACE", "PartSet/XOZ"), 30, False) +Sketch_1 = model.addSketch(Part_1_doc, model.selection("FACE", "Plane_1")) +SketchLine_1 = Sketch_1.addLine(50, -50, -50, -50) +SketchLine_2 = Sketch_1.addLine(-50, -50, -50, 50) +SketchLine_3 = Sketch_1.addLine(-50, 50, 50, 50) +SketchLine_4 = Sketch_1.addLine(50, 50, 50, -50) +SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_1.startPoint()) +SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint()) +SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint()) +SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint()) +SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_1.result()) +SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_2.result()) +SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_3.result()) +SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_4.result()) +SketchProjection_1 = Sketch_1.addProjection(model.selection("VERTEX", "PartSet/Origin"), False) +SketchPoint_1 = SketchProjection_1.createdFeature() +SketchConstraintDistance_1 = Sketch_1.setDistance(SketchAPI_Point(SketchPoint_1).coordinates(), SketchLine_4.result(), "Size", True) +SketchConstraintDistance_2 = Sketch_1.setDistance(SketchAPI_Point(SketchPoint_1).coordinates(), SketchLine_2.result(), "Size", True) +SketchConstraintDistance_3 = Sketch_1.setDistance(SketchAPI_Point(SketchPoint_1).coordinates(), SketchLine_1.result(), "Size", True) +SketchConstraintDistance_4 = Sketch_1.setDistance(SketchAPI_Point(SketchPoint_1).coordinates(), SketchLine_3.result(), "Size", True) +model.do() +Face_1 = model.addFace(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_4r-SketchLine_3r-SketchLine_2r-SketchLine_1r")]) +Sketch_2 = model.addSketch(Part_1_doc, model.defaultPlane("XOZ")) +SketchLine_5 = Sketch_2.addLine(20, -40.3112887414928, 20, 20) +SketchLine_6 = Sketch_2.addLine(20, 20, -40.31128874149281, 20.00000000000001) +SketchConstraintCoincidence_5 = Sketch_2.setCoincident(SketchLine_5.endPoint(), SketchLine_6.startPoint()) +SketchConstraintVertical_3 = Sketch_2.setVertical(SketchLine_5.result()) +SketchConstraintHorizontal_3 = Sketch_2.setHorizontal(SketchLine_6.result()) +SketchArc_1 = Sketch_2.addArc(0, 0, -40.31128874149281, 20.00000000000001, 20, -40.3112887414928, False) +SketchConstraintCoincidence_6 = Sketch_2.setCoincident(SketchLine_6.endPoint(), SketchArc_1.startPoint()) +SketchConstraintCoincidence_7 = Sketch_2.setCoincident(SketchArc_1.endPoint(), SketchLine_5.startPoint()) +SketchConstraintEqual_1 = Sketch_2.setEqual(SketchLine_5.result(), SketchLine_6.result()) +SketchConstraintDistance_5 = Sketch_2.setDistance(SketchArc_1.center(), SketchLine_5.result(), 20, True) +SketchProjection_2 = Sketch_2.addProjection(model.selection("VERTEX", "PartSet/Origin"), False) +SketchPoint_2 = SketchProjection_2.createdFeature() +SketchConstraintCoincidence_8 = Sketch_2.setCoincident(SketchAPI_Point(SketchPoint_2).coordinates(), SketchArc_1.center()) +SketchConstraintRadius_1 = Sketch_2.setRadius(SketchArc_1.results()[1], 45) +model.do() +Edge_1_objects = [model.selection("EDGE", "Sketch_2/SketchLine_5"), model.selection("EDGE", "Sketch_2/SketchLine_6"), model.selection("EDGE", "Sketch_2/SketchArc_1_2")] +Edge_1 = model.addEdge(Part_1_doc, Edge_1_objects) +Extrusion_1_objects = [model.selection("EDGE", "Edge_1_1"), model.selection("EDGE", "Edge_1_2"), model.selection("EDGE", "Edge_1_3")] +Extrusion_1 = model.addExtrusion(Part_1_doc, Extrusion_1_objects, model.selection("EDGE", "PartSet/OY"), model.selection("FACE", "Partition_1_1_1/Modified_Face&Sphere_1_1/Face_1"), "offsetTo", model.selection("FACE", "Face_1_1"), "offsetFrom") + +# extrusion have to fail because of several results with shared topology +assert(Extrusion_1.feature().error() != "") + +# change radius of sphere and check failure +ParamR.setValue(10) +model.do() +assert(Extrusion_1.feature().error() != "") + +ParamR.setValue(45) +model.do() +assert(Extrusion_1.feature().error() != "") + +# change offsetting "To" face and check failure +ParamTo.setValue(-20) +model.do() +assert(Extrusion_1.feature().error() != "") + +# revert failure +ParamTo.setValue(20) +model.do() +model.testNbResults(Extrusion_1, 3) +model.testNbSubResults(Extrusion_1, [0, 0, 0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [0, 0, 0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [1, 1, 1]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [4, 4, 6]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [8, 8, 12]) +model.testResultsVolumes(Extrusion_1, [1708.843326299, 1708.843325768, 1895.559443038]) + +# offset "From" face +ParamFrom.setValue(-20) +model.do() +model.testNbResults(Extrusion_1, 3) +model.testNbSubResults(Extrusion_1, [0, 0, 0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [0, 0, 0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [1, 1, 1]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [4, 4, 6]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [8, 8, 12]) +model.testResultsVolumes(Extrusion_1, [2915.069101129, 2915.069100598, 4138.27332218]) + +# check failure +ParamFrom.setValue(20) +model.do() +assert(Extrusion_1.feature().error() != "") + +# revert failure +ParamFrom.setValue(10) +model.do() +model.testNbResults(Extrusion_1, 3) +model.testNbSubResults(Extrusion_1, [0, 0, 0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [0, 0, 0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [1, 1, 1]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [4, 4, 6]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [8, 8, 12]) +model.testResultsVolumes(Extrusion_1, [1105.7304388842, 1105.730438353, 774.2025034671]) + +model.testHaveNamingSubshapes(Extrusion_1, model, Part_1_doc) + +model.end() + +assert(model.checkPythonDump()) diff --git a/src/FeaturesPlugin/Test/TestExtrusion_ByFaces17.py b/src/FeaturesPlugin/Test/TestExtrusion_ByFaces17.py new file mode 100644 index 000000000..fd8effa21 --- /dev/null +++ b/src/FeaturesPlugin/Test/TestExtrusion_ByFaces17.py @@ -0,0 +1,162 @@ +# 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 +# + +from SketchAPI import * + +from salome.shaper import model + +model.begin() +partSet = model.moduleDocument() +Part_1 = model.addPart(partSet) +Part_1_doc = Part_1.document() +ParamRSph = model.addParameter(Part_1_doc, "rSphere", "50") +ParamRCyl = model.addParameter(Part_1_doc, "rCyl", "30") +ParamRCir = model.addParameter(Part_1_doc, "rCircle", "10") +ParamFrom = model.addParameter(Part_1_doc, "offsetFrom", "0") +ParamTo = model.addParameter(Part_1_doc, "offsetTo", "0") +Sphere_1 = model.addSphere(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), "rSphere") +Cylinder_1 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), "rCyl", 100) +Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOZ")) +SketchCircle_1 = Sketch_1.addCircle(15, 20, 10) +SketchConstraintRadius_1 = Sketch_1.setRadius(SketchCircle_1.results()[1], "rCircle") +SketchProjection_1 = Sketch_1.addProjection(model.selection("VERTEX", "PartSet/Origin"), False) +SketchPoint_1 = SketchProjection_1.createdFeature() +SketchConstraintDistanceHorizontal_1 = Sketch_1.setHorizontalDistance(SketchAPI_Point(SketchPoint_1).coordinates(), SketchCircle_1.center(), 15) +SketchConstraintDistanceVertical_1 = Sketch_1.setVerticalDistance(SketchAPI_Point(SketchPoint_1).coordinates(), SketchCircle_1.center(), 20) +model.do() +Edge_1 = model.addEdge(Part_1_doc, [model.selection("EDGE", "Sketch_1/SketchCircle_1_2")]) +Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("EDGE", "Edge_1_1")], model.selection("EDGE", "PartSet/OY"), model.selection("FACE", "Sphere_1_1/Face_1"), "offsetTo", model.selection("FACE", "Cylinder_1_1/Face_1"), "offsetFrom") + +from GeomAPI import GeomAPI_Shape + +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [8]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [16]) +model.testResultsVolumes(Extrusion_1, [2178.8497332]) + +# change radius of sketch circle +ParamRCir.setValue(17) +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [1]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [10]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [20]) +model.testResultsVolumes(Extrusion_1, [3960.00723]) + +# change radius of sphere +ParamRSph.setValue(10) +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [1]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [5]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [10]) +model.testResultsVolumes(Extrusion_1, [3658.7714]) + +# change radius of sketch circle and check failure +ParamRCir.setValue(10) +model.do() +assert(Extrusion_1.feature().error() != "") + +# revert failure +ParamRSph.setValue(45); +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [8]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [16]) +model.testResultsVolumes(Extrusion_1, [1398.72992867]) + +# change radius of cylinder +ParamRCyl.setValue(10) +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [1]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [6]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [12]) +model.testResultsVolumes(Extrusion_1, [4194.25709]) + +ParamRCyl.setValue(50) +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [8]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [16]) +model.testResultsVolumes(Extrusion_1, [1433.0518]) + +# change offsetting "To" face +ParamTo.setValue(-20) +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [1]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [10]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [20]) +model.testResultsVolumes(Extrusion_1, [5078.347278]) + +# revert failure +ParamTo.setValue(20) +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [10]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [20]) +model.testResultsVolumes(Extrusion_1, [1504.36096473]) + +# offset "From" face +ParamFrom.setValue(-20) +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [12]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [24]) +model.testResultsVolumes(Extrusion_1, [4336.142699]) + +ParamFrom.setValue(20) +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [12]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [24]) +model.testResultsVolumes(Extrusion_1, [1118.8887326]) + +model.testHaveNamingSubshapes(Extrusion_1, model, Part_1_doc) + +model.end() + +assert(model.checkPythonDump()) diff --git a/src/FeaturesPlugin/Test/TestExtrusion_ByFaces18.py b/src/FeaturesPlugin/Test/TestExtrusion_ByFaces18.py new file mode 100644 index 000000000..2edfe7af7 --- /dev/null +++ b/src/FeaturesPlugin/Test/TestExtrusion_ByFaces18.py @@ -0,0 +1,120 @@ +# 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 +# + +from SketchAPI import * + +from salome.shaper import model + +model.begin() +partSet = model.moduleDocument() +Part_1 = model.addPart(partSet) +Part_1_doc = Part_1.document() +ParamR = model.addParameter(Part_1_doc, "R", "50") +ParamFrom = model.addParameter(Part_1_doc, "offsetFrom", "0") +ParamTo = model.addParameter(Part_1_doc, "offsetTo", "0") +Cone_1 = model.addCone(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), "R", "R/5", "R") +Partition_1 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Cone_1_1"), model.selection("FACE", "PartSet/XOZ")]) +Plane_4 = model.addPlane(Part_1_doc, model.selection("FACE", "PartSet/XOZ"), 20, False) +Plane_5 = model.addPlane(Part_1_doc, model.selection("FACE", "Plane_1"), model.selection("EDGE", "PartSet/OZ"), 330) +Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOZ")) +SketchLine_1 = Sketch_1.addLine(10, 8.819660112501044, 10, 30) +SketchLine_2 = Sketch_1.addLine(10, 30, -11.18033988749895, 30) +SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint()) +SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_1.result()) +SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_2.result()) +SketchArc_1 = Sketch_1.addArc(0, 20, -11.18033988749895, 30, 10, 8.819660112501044, False) +SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchArc_1.startPoint()) +SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchArc_1.endPoint(), SketchLine_1.startPoint()) +SketchConstraintEqual_1 = Sketch_1.setEqual(SketchLine_1.result(), SketchLine_2.result()) +SketchConstraintDistance_1 = Sketch_1.setDistance(SketchArc_1.center(), SketchLine_1.result(), 10, True) +SketchConstraintRadius_1 = Sketch_1.setRadius(SketchArc_1.results()[1], 15) +SketchProjection_1 = Sketch_1.addProjection(model.selection("EDGE", "PartSet/OZ"), False) +SketchLine_3 = SketchProjection_1.createdFeature() +SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchArc_1.center(), SketchLine_3.result()) +SketchConstraintDistanceVertical_1 = Sketch_1.setVerticalDistance(SketchAPI_Line(SketchLine_3).startPoint(), SketchArc_1.center(), 20) +model.do() +Edge_1_objects = [model.selection("EDGE", "Sketch_1/SketchLine_1"), model.selection("EDGE", "Sketch_1/SketchLine_2"), model.selection("EDGE", "Sketch_1/SketchArc_1_2")] +Edge_1 = model.addEdge(Part_1_doc, Edge_1_objects) +Extrusion_1_objects = [model.selection("EDGE", "Edge_1_1"), model.selection("EDGE", "Edge_1_2"), model.selection("EDGE", "Edge_1_3")] +Extrusion_1 = model.addExtrusion(Part_1_doc, Extrusion_1_objects, model.selection("EDGE", "PartSet/OY"), model.selection("FACE", "Partition_1_1_2/Modified_Face&Cone_1_1/Face_1"), "offsetTo", model.selection("FACE", "Plane_2"), "offsetFrom") + +from GeomAPI import GeomAPI_Shape + +model.testNbResults(Extrusion_1, 3) +model.testNbSubResults(Extrusion_1, [0, 0, 0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [0, 0, 0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [1, 1, 1]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [4, 4, 5]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [8, 8, 10]) +model.testResultsVolumes(Extrusion_1, [1309.42058662, 1016.82520496, 2589.5946928]) + +# change radius of sphere and check failure +ParamR.setValue(10) +model.do() +assert(Extrusion_1.feature().error() != "") + +# revert failure, check the intersected boundaries are processed well +ParamR.setValue(40) +model.do() +model.testNbResults(Extrusion_1, 3) +model.testNbSubResults(Extrusion_1, [0, 0, 0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [0, 0, 0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [1, 1, 1]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [4, 4, 5]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [8, 8, 10]) +model.testResultsVolumes(Extrusion_1, [1081.93830116, 793.80218227, 2095.8021933]) + +# change offsetting "To" face and check failure +ParamTo.setValue(-20) +model.do() +assert(Extrusion_1.feature().error() != "") + +# revert failure +ParamTo.setValue(8) +model.do() +model.testNbResults(Extrusion_1, 3) +model.testNbSubResults(Extrusion_1, [0, 0, 0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [0, 0, 0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [1, 1, 1]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [4, 4, 5]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [8, 8, 10]) +model.testResultsVolumes(Extrusion_1, [1314.8586588, 1022.169915122, 2601.32913399]) + +# offset "From" face +ParamFrom.setValue(-20) +model.do() +model.testNbResults(Extrusion_1, 3) +model.testNbSubResults(Extrusion_1, [0, 0, 0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [0, 0, 0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [1, 1, 1]) +model.testResultsVolumes(Extrusion_1, [825.71966141, 533.030917699, 1551.6191757579]) + +ParamFrom.setValue(20) +model.do() +model.testNbResults(Extrusion_1, 3) +model.testNbSubResults(Extrusion_1, [0, 0, 0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [0, 0, 0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [1, 1, 1]) +model.testResultsVolumes(Extrusion_1, [1803.997656259, 1511.308912545, 3651.0390970659]) + +model.testHaveNamingSubshapes(Extrusion_1, model, Part_1_doc) + +model.end() + +assert(model.checkPythonDump()) diff --git a/src/FeaturesPlugin/Test/TestExtrusion_ByFaces19.py b/src/FeaturesPlugin/Test/TestExtrusion_ByFaces19.py new file mode 100644 index 000000000..68584bc5c --- /dev/null +++ b/src/FeaturesPlugin/Test/TestExtrusion_ByFaces19.py @@ -0,0 +1,144 @@ +# 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 +# + +from SketchAPI import * + +from salome.shaper import model + +model.begin() +partSet = model.moduleDocument() +Part_1 = model.addPart(partSet) +Part_1_doc = Part_1.document() +ParamR = model.addParameter(Part_1_doc, "R", "50") +ParamFrom = model.addParameter(Part_1_doc, "offsetFrom", "0") +ParamTo = model.addParameter(Part_1_doc, "offsetTo", "0") +Cylinder_1 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), "R", 100, 180) +Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOZ")) +SketchLine_1 = Sketch_1.addLine(20, 40, -30, 40) +SketchLine_2 = Sketch_1.addLine(-30, 40, -30, 20) +SketchLine_3 = Sketch_1.addLine(-30, 20, 20, 20) +SketchLine_4 = Sketch_1.addLine(20, 20, 20, 40) +SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_1.startPoint()) +SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint()) +SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint()) +SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint()) +SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_1.result()) +SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_2.result()) +SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_3.result()) +SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_4.result()) +SketchConstraintLength_1 = Sketch_1.setLength(SketchLine_3.result(), 50) +SketchConstraintLength_2 = Sketch_1.setLength(SketchLine_2.result(), 20) +SketchProjection_1 = Sketch_1.addProjection(model.selection("VERTEX", "PartSet/Origin"), False) +SketchPoint_1 = SketchProjection_1.createdFeature() +SketchConstraintDistanceHorizontal_1 = Sketch_1.setHorizontalDistance(SketchAPI_Point(SketchPoint_1).coordinates(), SketchLine_3.endPoint(), 20) +SketchConstraintDistanceVertical_1 = Sketch_1.setVerticalDistance(SketchAPI_Point(SketchPoint_1).coordinates(), SketchLine_3.endPoint(), 20) +model.do() +Wire_1_objects = [model.selection("EDGE", "Sketch_1/SketchLine_1"), model.selection("EDGE", "Sketch_1/SketchLine_2"), model.selection("EDGE", "Sketch_1/SketchLine_3"), model.selection("EDGE", "Sketch_1/SketchLine_4")] +Wire_1 = model.addWire(Part_1_doc, Wire_1_objects) +Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("WIRE", "Wire_1_1")], model.selection("EDGE", "PartSet/OY"), model.selection("FACE", "Cylinder_1_1/Face_1"), "offsetTo", model.selection(), "offsetFrom") + +from GeomAPI import GeomAPI_Shape + +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [4]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [16]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [32]) +model.testResultsVolumes(Extrusion_1, [6470.575165134267]) + +# change radius of cylinder +ParamR.setValue(10) +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [4]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [8]) +model.testResultsVolumes(Extrusion_1, [314.159265359]) + +ParamR.setValue(30) +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [3]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [10]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [20]) +model.testResultsVolumes(Extrusion_1, [2964.89877572]) + +# check the intersected boundaries are processed well +ParamR.setValue(40); +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [4]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [16]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [32]) +model.testResultsVolumes(Extrusion_1, [4903.173668915]) + +# change offsetting "To" face +ParamTo.setValue(-20) +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [2]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [4]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [8]) +model.testResultsVolumes(Extrusion_1, [1256.637061267]) + +ParamTo.setValue(20) +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [4]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [16]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [32]) +model.testResultsVolumes(Extrusion_1, [7969.186376787]) + +# offset "From" face +ParamFrom.setValue(-20) +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [4]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [16]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [32]) +model.testResultsVolumes(Extrusion_1, [10769.186376787]) + +ParamFrom.setValue(20) +model.do() +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [4]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [16]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [32]) +model.testResultsVolumes(Extrusion_1, [5169.186376787]) + +model.testHaveNamingSubshapes(Extrusion_1, model, Part_1_doc) + +model.end() + +assert(model.checkPythonDump()) diff --git a/src/FeaturesPlugin/doc/extrusionFeature.rst b/src/FeaturesPlugin/doc/extrusionFeature.rst index d3b2b3f41..9bced660f 100644 --- a/src/FeaturesPlugin/doc/extrusionFeature.rst +++ b/src/FeaturesPlugin/doc/extrusionFeature.rst @@ -31,7 +31,7 @@ There are two variants of the property panel for Extrusion depending on the chos .. image:: images/extrusion_by_bounding_planes.png :align: left -**By Bounding Planes** extrudes objects by specifying bounding planes and offsets. +**By Bounding Faces** extrudes objects by specifying bounding faces/planes and offsets. By sizes @@ -77,22 +77,25 @@ The Result of the operation will be an extruded shape: **See Also** a sample TUI Script of :ref:`tui_create_extrusion_by_sizes` operation. -By bounding planes +By bounding faces ------------------ .. image:: images/Extrusion2.png :align: center .. centered:: - Extrusion: definition by bounding planes + Extrusion: definition by bounding faces - **Base objects** - contains a list of objects selected in the Object Browser or in the Viewer, which will be extruded. - **Axis** if selected, it will be direction of extrusion, otherwise objects normals will be used. -- **To plane** - a planar face can be selected to bound extrusion from one side. +- **To face** - a face can be selected to bound extrusion from one side. - **To offset** - offset for extrusion or for bounding plane, if selected. -- **From plane** - a planar face can be selected to bound extrusion from the other side. +- **From face** - a face can be selected to bound extrusion from the other side. - **From offset** - offset for extrusion or for bounding plane, if selected. +Planar face selected as a boundary of extrusion will be enlarged infinitely. As a result, extrusion bounded only by planar faces will be completed always. +On the other hand, if the boundary face is not planar, extrusion may fail, for example, in case of the base object cannot be projected to this face along given direction. + **TUI Command**: *model.addExtrusion(part, objects, toObject, toOffset, fromObject, fromOffset);* **Arguments**: Part + list of objects + to object + to offset + from object + from offset. diff --git a/src/FeaturesPlugin/extrusion_widget.xml b/src/FeaturesPlugin/extrusion_widget.xml index de815a28a..77e543915 100644 --- a/src/FeaturesPlugin/extrusion_widget.xml +++ b/src/FeaturesPlugin/extrusion_widget.xml @@ -46,17 +46,17 @@ - + - + + + +GeomAlgoAPI_Offset::GeomAlgoAPI_Offset(const GeomShapePtr& theShape, + const double theOffsetValue) +{ + build(theShape, theOffsetValue); +} + +void GeomAlgoAPI_Offset::build(const GeomShapePtr& theShape, const double theOffsetValue) +{ + BRepOffsetAPI_MakeOffsetShape* anOffsetAlgo = new BRepOffsetAPI_MakeOffsetShape; + anOffsetAlgo->PerformBySimple(theShape->impl(), theOffsetValue); + setImpl(anOffsetAlgo); + setBuilderType(OCCT_BRepBuilderAPI_MakeShape); + + if (anOffsetAlgo->IsDone()) { + const TopoDS_Shape& aResult = anOffsetAlgo->Shape(); + std::shared_ptr aShape(new GeomAPI_Shape()); + aShape->setImpl(new TopoDS_Shape(aResult)); + setShape(aShape); + setDone(true); + } +} + +void GeomAlgoAPI_Offset::generated(const GeomShapePtr theOldShape, + ListOfShape& theNewShapes) +{ + try { + GeomAlgoAPI_MakeShape::generated(theOldShape, theNewShapes); + } catch(...) { + // nothing is generated + } +} diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Offset.h b/src/GeomAlgoAPI/GeomAlgoAPI_Offset.h new file mode 100644 index 000000000..7939f04cd --- /dev/null +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Offset.h @@ -0,0 +1,47 @@ +// Copyright (C) 2019-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 +// + +#ifndef GeomAlgoAPI_Offset_H_ +#define GeomAlgoAPI_Offset_H_ + +#include +#include + +/// \class GeomAlgoAPI_Offset +/// \ingroup DataAlgo +/// \brief Perform 3D offset for the shape +class GeomAlgoAPI_Offset : public GeomAlgoAPI_MakeShape +{ +public: + /// \brief Construct offset. + GEOMALGOAPI_EXPORT GeomAlgoAPI_Offset(const GeomShapePtr& theShape, + const double theOffsetValue); + + /// \return the list of shapes generated from the shape \a theShape. + /// \param[in] theOldShape base shape. + /// \param[out] theNewShapes shapes generated from \a theShape. Does not cleared! + GEOMALGOAPI_EXPORT virtual void generated(const GeomShapePtr theOldShape, + ListOfShape& theNewShapes); + +private: + /// \brief Perform offset operation + void build(const GeomShapePtr& theShape, const double theOffsetValue); +}; + +#endif diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Prism.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_Prism.cpp index df1b15976..500fbf8e6 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_Prism.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Prism.cpp @@ -19,14 +19,21 @@ #include "GeomAlgoAPI_Prism.h" +#include +#include #include #include #include #include #include + +#include #include #include +#include +#include #include +#include #include #include @@ -53,6 +60,30 @@ #include +/// Expand planar face to cover the bounding box if theOriginalShape is planar. +/// Otherwise, return the same shape; +static GeomShapePtr buildPlanarFace(const GeomShapePtr& theOriginalShape, + const Bnd_Box& theBaseShapeBB); + +/// Build offset for the given shape. +/// If the offset algorithm failed, translate the shape along the direction. +static GeomShapePtr buildOffset(const GeomShapePtr& theShape, + const double theOffset, + const GeomDirPtr theDirection, + GeomAlgoAPI_MakeShapeList& theMakeShapeList); + +/// Collect base faces of the prism. +static void collectPrismBases(const TopoDS_Shape& theBaseShape, + BRepPrimAPI_MakePrism& thePrismAlgo, + ListOfShape& theBoundaries, + const GeomAPI_Shape::ShapeType theTypeToExp); + +/// Collect all solids which contain boundaries but do not contain bases of prism. +static GeomShapePtr collectResults(const GeomMakeShapePtr& theOperation, + const ListOfShape& theBoundaries, + const ListOfShape& theShapesToExclude, + const GeomAPI_Shape::ShapeType theTypeToExp); + static void storeGenerationHistory(GeomAlgoAPI_Prism* thePrismAlgo, const TopoDS_Shape& theBase, const TopAbs_ShapeEnum theType, @@ -64,25 +95,21 @@ static void storeGenerationHistory(GeomAlgoAPI_Prism* thePrismAlgo, const TopoDS_Face& theToFace, const TopoDS_Face& theFromFace); - -//================================================================================================== -GeomAlgoAPI_Prism::GeomAlgoAPI_Prism(const GeomShapePtr theBaseShape, - const std::shared_ptr theDirection, - const GeomShapePtr theToShape, - const double theToSize, - const GeomShapePtr theFromShape, - const double theFromSize) +static GeomShapePtr toShape(const TopoDS_Shape& theShape) { - build(theBaseShape, theDirection, theToShape, theToSize, theFromShape, theFromSize); + GeomShapePtr aShape(new GeomAPI_Shape()); + aShape->setImpl(new TopoDS_Shape(theShape)); + return aShape; } + //================================================================================================== -void GeomAlgoAPI_Prism::build(const GeomShapePtr& theBaseShape, - const std::shared_ptr theDirection, - const GeomShapePtr& theToShape, - const double theToSize, - const GeomShapePtr& theFromShape, - const double theFromSize) +GeomAlgoAPI_Prism::GeomAlgoAPI_Prism(const GeomShapePtr theBaseShape, + const GeomDirPtr theDirection, + const GeomShapePtr theToShape, + const double theToSize, + const GeomShapePtr theFromShape, + const double theFromSize) { if(!theBaseShape.get() || (((!theFromShape.get() && !theToShape.get()) || @@ -93,21 +120,21 @@ void GeomAlgoAPI_Prism::build(const GeomShapePtr& theBaseShape, // Getting base shape. const TopoDS_Shape& aBaseShape = theBaseShape->impl(); - TopAbs_ShapeEnum aShapeTypeToExp; + GeomAPI_Shape::ShapeType aShapeTypeToExp; switch(aBaseShape.ShapeType()) { case TopAbs_VERTEX: - aShapeTypeToExp = TopAbs_VERTEX; + aShapeTypeToExp = GeomAPI_Shape::VERTEX; break; case TopAbs_EDGE: case TopAbs_WIRE: - aShapeTypeToExp = TopAbs_EDGE; + aShapeTypeToExp = GeomAPI_Shape::EDGE; break; case TopAbs_FACE: case TopAbs_SHELL: - aShapeTypeToExp = TopAbs_FACE; + aShapeTypeToExp = GeomAPI_Shape::FACE; break; case TopAbs_COMPOUND: - aShapeTypeToExp = TopAbs_COMPOUND; + aShapeTypeToExp = GeomAPI_Shape::COMPOUND; break; default: return; @@ -168,8 +195,6 @@ void GeomAlgoAPI_Prism::build(const GeomShapePtr& theBaseShape, aBaseLoc.reset(new GeomAPI_Pnt(aLoc.X(), aLoc.Y(), aLoc.Z())); } - GeomShapePtr aBasePlane = GeomAlgoAPI_FaceBuilder::planarFace(aBaseLoc, aBaseDir); - gp_Vec anExtVec; std::shared_ptr anExtDir; if (theDirection.get()) @@ -187,249 +212,568 @@ void GeomAlgoAPI_Prism::build(const GeomShapePtr& theBaseShape, TopoDS_Shape aResult; const bool isBoundingShapesSet = theFromShape.get() || theToShape.get(); if(!isBoundingShapesSet) { - // Moving base shape. - gp_Trsf aTrsf; - aTrsf.SetTranslation(anExtVec * -theFromSize); - BRepBuilderAPI_Transform* aTransformBuilder = - new BRepBuilderAPI_Transform(aBaseShape, aTrsf); - if(!aTransformBuilder || !aTransformBuilder->IsDone()) { - return; - } - this->appendAlgo(std::shared_ptr( - new GeomAlgoAPI_MakeShape(aTransformBuilder))); - TopoDS_Shape aMovedBase = aTransformBuilder->Shape(); - - // Making prism. - BRepPrimAPI_MakePrism* aPrismBuilder = - new BRepPrimAPI_MakePrism(aMovedBase, anExtVec * (theFromSize + theToSize)); - if(!aPrismBuilder || !aPrismBuilder->IsDone()) { - return; - } - this->appendAlgo(std::shared_ptr( - new GeomAlgoAPI_MakeShape(aPrismBuilder))); - aResult = aPrismBuilder->Shape(); - - // Setting naming. - if(aShapeTypeToExp == TopAbs_COMPOUND) { - storeGenerationHistory(this, aMovedBase, TopAbs_EDGE, aPrismBuilder); - storeGenerationHistory(this, aMovedBase, TopAbs_FACE, aPrismBuilder); - } else { - storeGenerationHistory(this, aMovedBase, aShapeTypeToExp, aPrismBuilder); - } + buildBySizes(theBaseShape, anExtDir, theToSize, theFromSize, aShapeTypeToExp); } else { + GeomShapePtr aBasePlane = GeomAlgoAPI_FaceBuilder::squareFace(aBaseLoc, aBaseDir, 100.0); + GeomShapePtr aBoundingFromShape = theFromShape ? theFromShape : aBasePlane; GeomShapePtr aBoundingToShape = theToShape ? theToShape : aBasePlane; - // Moving prism bounding faces according to "from" and "to" sizes. - std::shared_ptr aFromPln = GeomAPI_Face(aBoundingFromShape).getPlane(); - std::shared_ptr aFromLoc = aFromPln->location(); - std::shared_ptr aFromDir = aFromPln->direction(); - - std::shared_ptr aToPln = GeomAPI_Face(aBoundingToShape).getPlane(); - std::shared_ptr aToLoc = aToPln->location(); - std::shared_ptr aToDir = aToPln->direction(); - - bool aSign = aFromLoc->xyz()->dot(anExtDir->xyz()) > aToLoc->xyz()->dot(anExtDir->xyz()); - - std::shared_ptr aFromPnt( - new GeomAPI_Pnt(aFromLoc->xyz()->added(anExtDir->xyz()->multiplied( - aSign ? theFromSize : -theFromSize)))); - aBoundingFromShape = GeomAlgoAPI_FaceBuilder::planarFace(aFromPnt, aFromDir); - - std::shared_ptr aToPnt( - new GeomAPI_Pnt(aToLoc->xyz()->added(anExtDir->xyz()->multiplied( - aSign ? -theToSize : theToSize)))); - aBoundingToShape = GeomAlgoAPI_FaceBuilder::planarFace(aToPnt, aToDir); - - // Getting bounding box for base shape. - Bnd_Box aBndBox; - BRepBndLib::Add(aBaseShape, 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++; - } - } + bool isFromShapePlanar = aBoundingFromShape->isPlanar(); + bool isToShapePlanar = aBoundingToShape->isPlanar(); + + // Set signs of offsets if both bounding shapes are planar + if (isFromShapePlanar && isToShapePlanar) { + std::shared_ptr aFromPln = GeomAPI_Face(aBoundingFromShape).getPlane(); + std::shared_ptr aToPln = GeomAPI_Face(aBoundingToShape).getPlane(); + buildByPlanes(theBaseShape, anExtDir, + aToPln, theToSize, + aFromPln, theFromSize, + aShapeTypeToExp); } - - // Project points to bounding planes. Search max distance to them. - IntAna_Quadric aBndToQuadric(gp_Pln(aToPnt->impl(), aToDir->impl())); - IntAna_Quadric aBndFromQuadric(gp_Pln(aFromPnt->impl(), aFromDir->impl())); - Standard_Real aMaxToDist = 0, aMaxFromDist = 0; - for(int i = 0; i < 8; i++) { - gp_Lin aLine(aPoints[i], anExtVec); - IntAna_IntConicQuad aToIntAna(aLine, aBndToQuadric); - IntAna_IntConicQuad aFromIntAna(aLine, aBndFromQuadric); - if(aToIntAna.NbPoints() == 0 || aFromIntAna.NbPoints() == 0) { - return; - } - const gp_Pnt& aPntOnToFace = aToIntAna.Point(1); - const gp_Pnt& aPntOnFromFace = aFromIntAna.Point(1); - if(aPoints[i].Distance(aPntOnToFace) > aMaxToDist) { - aMaxToDist = aPoints[i].Distance(aPntOnToFace); - } - if(aPoints[i].Distance(aPntOnFromFace) > aMaxFromDist) { - aMaxFromDist = aPoints[i].Distance(aPntOnFromFace); - } + else { + buildByFaces(theBaseShape, anExtDir, + aBoundingToShape, theToSize, isToShapePlanar, + aBoundingFromShape, theFromSize, isFromShapePlanar, + aShapeTypeToExp); } + } +} - // We added 1 just to be sure that prism is long enough for boolean operation. - double aPrismLength = aMaxToDist + aMaxFromDist + 1; +//================================================================================================== +void GeomAlgoAPI_Prism::buildBySizes(const GeomShapePtr theBaseShape, + const GeomDirPtr theDirection, + const double theToSize, + const double theFromSize, + const GeomAPI_Shape::ShapeType theTypeToExp) +{ + const TopoDS_Shape& aBaseShape = theBaseShape->impl(); + gp_Vec anExtVec = theDirection->impl(); - // Moving base shape. - gp_Trsf aTrsf; - aTrsf.SetTranslation(anExtVec * -aPrismLength); - BRepBuilderAPI_Transform* aTransformBuilder = new BRepBuilderAPI_Transform(aBaseShape, aTrsf); - if(!aTransformBuilder || !aTransformBuilder->IsDone()) { - return; - } - this->appendAlgo(std::shared_ptr( + // Moving base shape. + gp_Trsf aTrsf; + aTrsf.SetTranslation(anExtVec * -theFromSize); + BRepBuilderAPI_Transform* aTransformBuilder = + new BRepBuilderAPI_Transform(aBaseShape, aTrsf); + if (!aTransformBuilder || !aTransformBuilder->IsDone()) { + return; + } + this->appendAlgo(std::shared_ptr( new GeomAlgoAPI_MakeShape(aTransformBuilder))); - TopoDS_Shape aMovedBase = aTransformBuilder->Shape(); + TopoDS_Shape aMovedBase = aTransformBuilder->Shape(); - // Making prism. - BRepPrimAPI_MakePrism* aPrismBuilder = - new BRepPrimAPI_MakePrism(aMovedBase, anExtVec * 2 * aPrismLength); - if(!aPrismBuilder || !aPrismBuilder->IsDone()) { - return; - } - this->appendAlgo(std::shared_ptr( + // Making prism. + BRepPrimAPI_MakePrism* aPrismBuilder = + new BRepPrimAPI_MakePrism(aMovedBase, anExtVec * (theFromSize + theToSize)); + if (!aPrismBuilder || !aPrismBuilder->IsDone()) { + return; + } + this->appendAlgo(std::shared_ptr( new GeomAlgoAPI_MakeShape(aPrismBuilder))); - aResult = aPrismBuilder->Shape(); + TopoDS_Shape aResult = aPrismBuilder->Shape(); - // Orienting bounding planes. - std::shared_ptr aCentreOfMass = GeomAlgoAPI_ShapeTools::centreOfMass(theBaseShape); - const gp_Pnt& aCentrePnt = aCentreOfMass->impl(); - gp_Lin aLine(aCentrePnt, anExtVec); - IntAna_IntConicQuad aToIntAna(aLine, aBndToQuadric); - IntAna_IntConicQuad aFromIntAna(aLine, aBndFromQuadric); - Standard_Real aToParameter = aToIntAna.ParamOnConic(1); - Standard_Real aFromParameter = aFromIntAna.ParamOnConic(1); - if(aToParameter > aFromParameter) { - gp_Vec aVec = aToDir->impl(); - if((aVec * anExtVec) > 0) { - aToDir->setImpl(new gp_Dir(aVec.Reversed())); - aBoundingToShape = GeomAlgoAPI_FaceBuilder::planarFace(aToPnt, aToDir); - } - aVec = aFromDir->impl(); - if((aVec * anExtVec) < 0) { - aFromDir->setImpl(new gp_Dir(aVec.Reversed())); - aBoundingFromShape = GeomAlgoAPI_FaceBuilder::planarFace(aFromPnt, aFromDir); - } - } else { - gp_Vec aVec = aToDir->impl(); - if((aVec * anExtVec) < 0) { - aToDir->setImpl(new gp_Dir(aVec.Reversed())); - aBoundingToShape = GeomAlgoAPI_FaceBuilder::planarFace(aToPnt, aToDir); - } - aVec = aFromDir->impl(); - if((aVec * anExtVec) > 0) { - aFromDir->setImpl(new gp_Dir(aVec.Reversed())); - aBoundingFromShape = GeomAlgoAPI_FaceBuilder::planarFace(aFromPnt, aFromDir); + // Setting naming. + if(theTypeToExp == GeomAPI_Shape::COMPOUND) { + storeGenerationHistory(this, aMovedBase, TopAbs_EDGE, aPrismBuilder); + storeGenerationHistory(this, aMovedBase, TopAbs_FACE, aPrismBuilder); + } else { + storeGenerationHistory(this, aMovedBase, (TopAbs_ShapeEnum)theTypeToExp, aPrismBuilder); + } + + // Setting result. + if (!aResult.IsNull()) { + aResult = GeomAlgoAPI_DFLoader::refineResult(aResult); + this->setShape(toShape(aResult)); + this->setDone(true); + } +} + +//================================================================================================== +void GeomAlgoAPI_Prism::buildByPlanes(const GeomShapePtr theBaseShape, + const GeomDirPtr theDirection, + const GeomPlanePtr theToPlane, + const double theToSize, + const GeomPlanePtr theFromPlane, + const double theFromSize, + const GeomAPI_Shape::ShapeType theTypeToExp) +{ + const TopoDS_Shape& aBaseShape = theBaseShape->impl(); + gp_Vec anExtVec = theDirection->impl(); + + // Moving prism bounding faces according to "from" and "to" sizes. + std::shared_ptr aFromLoc = theFromPlane->location(); + std::shared_ptr aFromDir = theFromPlane->direction(); + + std::shared_ptr aToLoc = theToPlane->location(); + std::shared_ptr aToDir = theToPlane->direction(); + + std::shared_ptr anExtDir = theDirection->xyz(); + bool aSign = aFromLoc->xyz()->dot(anExtDir) > aToLoc->xyz()->dot(anExtDir); + + std::shared_ptr aFromPnt( + new GeomAPI_Pnt(aFromLoc->xyz()->added(anExtDir->multiplied( + aSign ? theFromSize : -theFromSize)))); + GeomShapePtr aBoundingFromShape = GeomAlgoAPI_FaceBuilder::planarFace(aFromPnt, aFromDir); + + std::shared_ptr aToPnt( + new GeomAPI_Pnt(aToLoc->xyz()->added(anExtDir->multiplied( + aSign ? -theToSize : theToSize)))); + GeomShapePtr aBoundingToShape = GeomAlgoAPI_FaceBuilder::planarFace(aToPnt, aToDir); + + // Getting bounding box for base shape. + Bnd_Box aBndBox; + BRepBndLib::Add(aBaseShape, 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++; } } + } - // 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(); - TopoDS_Face aToFace = TopoDS::Face(aToShape); - TopoDS_Face aFromFace = TopoDS::Face(aFromShape); - BRep_Builder aBoundingBuilder; - aBoundingBuilder.MakeShell(aToShell); - aBoundingBuilder.Add(aToShell, aToShape); - aBoundingBuilder.MakeShell(aFromShell); - aBoundingBuilder.Add(aFromShell, aFromShape); - aBoundingBuilder.MakeSolid(aToSolid); - aBoundingBuilder.Add(aToSolid, aToShell); - aBoundingBuilder.MakeSolid(aFromSolid); - aBoundingBuilder.Add(aFromSolid, aFromShell); - - // Cutting with to plane. - BRepAlgoAPI_Cut* aToCutBuilder = new BRepAlgoAPI_Cut(aResult, aToSolid); - aToCutBuilder->Build(); - if(!aToCutBuilder->IsDone()) { + // Project points to bounding planes. Search max distance to them. + IntAna_Quadric aBndToQuadric(gp_Pln(aToPnt->impl(), aToDir->impl())); + IntAna_Quadric aBndFromQuadric(gp_Pln(aFromPnt->impl(), aFromDir->impl())); + Standard_Real aMaxToDist = 0, aMaxFromDist = 0; + for(int i = 0; i < 8; i++) { + gp_Lin aLine(aPoints[i], anExtVec); + IntAna_IntConicQuad aToIntAna(aLine, aBndToQuadric); + IntAna_IntConicQuad aFromIntAna(aLine, aBndFromQuadric); + if(aToIntAna.NbPoints() == 0 || aFromIntAna.NbPoints() == 0) { return; } - this->appendAlgo(std::shared_ptr( - new GeomAlgoAPI_MakeShape(aToCutBuilder))); - aResult = aToCutBuilder->Shape(); - if(aResult.ShapeType() == TopAbs_COMPOUND) { - aResult = GeomAlgoAPI_DFLoader::refineResult(aResult); + const gp_Pnt& aPntOnToFace = aToIntAna.Point(1); + const gp_Pnt& aPntOnFromFace = aFromIntAna.Point(1); + if(aPoints[i].Distance(aPntOnToFace) > aMaxToDist) { + aMaxToDist = aPoints[i].Distance(aPntOnToFace); } - 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()); - aGeomSh->setImpl(new TopoDS_Shape(anIt.Value())); - fixOrientation(aGeomSh); - this->addToShape(aGeomSh); - } + if(aPoints[i].Distance(aPntOnFromFace) > aMaxFromDist) { + aMaxFromDist = aPoints[i].Distance(aPntOnFromFace); } + } - // Cutting with from plane. - BRepAlgoAPI_Cut* aFromCutBuilder = new BRepAlgoAPI_Cut(aResult, aFromSolid); - aFromCutBuilder->Build(); - if(!aFromCutBuilder->IsDone()) { - return; + // We added 1 just to be sure that prism is long enough for boolean operation. + double aPrismLength = aMaxToDist + aMaxFromDist + 1; + + // Moving base shape. + gp_Trsf aTrsf; + aTrsf.SetTranslation(anExtVec * -aPrismLength); + BRepBuilderAPI_Transform* aTransformBuilder = new BRepBuilderAPI_Transform(aBaseShape, aTrsf); + if(!aTransformBuilder || !aTransformBuilder->IsDone()) { + return; + } + this->appendAlgo(std::shared_ptr( + new GeomAlgoAPI_MakeShape(aTransformBuilder))); + TopoDS_Shape aMovedBase = aTransformBuilder->Shape(); + + // Making prism. + BRepPrimAPI_MakePrism* aPrismBuilder = + new BRepPrimAPI_MakePrism(aMovedBase, anExtVec * 2 * aPrismLength); + if(!aPrismBuilder || !aPrismBuilder->IsDone()) { + return; + } + this->appendAlgo(std::shared_ptr( + new GeomAlgoAPI_MakeShape(aPrismBuilder))); + TopoDS_Shape aResult = aPrismBuilder->Shape(); + + // Orienting bounding planes. + std::shared_ptr aCentreOfMass = GeomAlgoAPI_ShapeTools::centreOfMass(theBaseShape); + const gp_Pnt& aCentrePnt = aCentreOfMass->impl(); + gp_Lin aLine(aCentrePnt, anExtVec); + IntAna_IntConicQuad aToIntAna(aLine, aBndToQuadric); + IntAna_IntConicQuad aFromIntAna(aLine, aBndFromQuadric); + Standard_Real aToParameter = aToIntAna.ParamOnConic(1); + Standard_Real aFromParameter = aFromIntAna.ParamOnConic(1); + if(aToParameter > aFromParameter) { + gp_Vec aVec = aToDir->impl(); + if((aVec * anExtVec) > 0) { + aToDir->setImpl(new gp_Dir(aVec.Reversed())); + aBoundingToShape = GeomAlgoAPI_FaceBuilder::planarFace(aToPnt, aToDir); } - this->appendAlgo(std::shared_ptr( - new GeomAlgoAPI_MakeShape(aFromCutBuilder))); - aResult = aFromCutBuilder->Shape(); - TopoDS_Iterator aCheckIt(aResult); - if(!aCheckIt.More()) { - return; + aVec = aFromDir->impl(); + if((aVec * anExtVec) < 0) { + aFromDir->setImpl(new gp_Dir(aVec.Reversed())); + aBoundingFromShape = GeomAlgoAPI_FaceBuilder::planarFace(aFromPnt, aFromDir); } - if(aResult.ShapeType() == TopAbs_COMPOUND) { - aResult = GeomAlgoAPI_DFLoader::refineResult(aResult); + } else { + gp_Vec aVec = aToDir->impl(); + if((aVec * anExtVec) < 0) { + aToDir->setImpl(new gp_Dir(aVec.Reversed())); + aBoundingToShape = GeomAlgoAPI_FaceBuilder::planarFace(aToPnt, aToDir); } - 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()); - aGeomSh->setImpl(new TopoDS_Shape(anIt.Value())); - fixOrientation(aGeomSh); - this->addFromShape(aGeomSh); - } + aVec = aFromDir->impl(); + if((aVec * anExtVec) > 0) { + aFromDir->setImpl(new gp_Dir(aVec.Reversed())); + aBoundingFromShape = GeomAlgoAPI_FaceBuilder::planarFace(aFromPnt, aFromDir); } + } - // Naming for extrusion from vertex, edge. - 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); + // 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(); + TopoDS_Face aToFace = TopoDS::Face(aToShape); + TopoDS_Face aFromFace = TopoDS::Face(aFromShape); + BRep_Builder aBoundingBuilder; + aBoundingBuilder.MakeShell(aToShell); + aBoundingBuilder.Add(aToShell, aToShape); + aBoundingBuilder.MakeShell(aFromShell); + aBoundingBuilder.Add(aFromShell, aFromShape); + aBoundingBuilder.MakeSolid(aToSolid); + aBoundingBuilder.Add(aToSolid, aToShell); + aBoundingBuilder.MakeSolid(aFromSolid); + aBoundingBuilder.Add(aFromSolid, aFromShell); + + // Cutting with to plane. + BRepAlgoAPI_Cut* aToCutBuilder = new BRepAlgoAPI_Cut(aResult, aToSolid); + aToCutBuilder->Build(); + if(!aToCutBuilder->IsDone()) { + return; + } + this->appendAlgo(std::shared_ptr( + new GeomAlgoAPI_MakeShape(aToCutBuilder))); + aResult = aToCutBuilder->Shape(); + if(aResult.ShapeType() == TopAbs_COMPOUND) { + aResult = GeomAlgoAPI_DFLoader::refineResult(aResult); + } + if (theTypeToExp == GeomAPI_Shape::FACE || theTypeToExp == GeomAPI_Shape::COMPOUND) { + const TopTools_ListOfShape& aToShapes = aToCutBuilder->Modified(aToShape); + for(TopTools_ListIteratorOfListOfShape anIt(aToShapes); anIt.More(); anIt.Next()) { + GeomShapePtr aGeomSh = toShape(anIt.Value()); + fixOrientation(aGeomSh); + this->addToShape(aGeomSh); } + } - if(aResult.ShapeType() == TopAbs_COMPOUND) { - std::shared_ptr aGeomShape(new GeomAPI_Shape); - aGeomShape->setImpl(new TopoDS_Shape(aResult)); - ListOfShape aResults; - aGeomShape = GeomAlgoAPI_ShapeTools::combineShapes(aGeomShape, - GeomAPI_Shape::COMPSOLID, - aResults); - aResult = aGeomShape->impl(); + // Cutting with from plane. + BRepAlgoAPI_Cut* aFromCutBuilder = new BRepAlgoAPI_Cut(aResult, aFromSolid); + aFromCutBuilder->Build(); + if(!aFromCutBuilder->IsDone()) { + return; + } + this->appendAlgo(std::shared_ptr( + new GeomAlgoAPI_MakeShape(aFromCutBuilder))); + aResult = aFromCutBuilder->Shape(); + TopoDS_Iterator aCheckIt(aResult); + if(!aCheckIt.More()) { + return; + } + if(aResult.ShapeType() == TopAbs_COMPOUND) { + aResult = GeomAlgoAPI_DFLoader::refineResult(aResult); + } + if (theTypeToExp == GeomAPI_Shape::FACE || theTypeToExp == GeomAPI_Shape::COMPOUND) { + const TopTools_ListOfShape& aFromShapes = aFromCutBuilder->Modified(aFromShape); + for(TopTools_ListIteratorOfListOfShape anIt(aFromShapes); anIt.More(); anIt.Next()) { + GeomShapePtr aGeomSh = toShape(anIt.Value()); + fixOrientation(aGeomSh); + this->addFromShape(aGeomSh); } } + // Naming for extrusion from vertex, edge. + if(theTypeToExp == GeomAPI_Shape::COMPOUND) { + storeGenerationHistory(this, aResult, TopAbs_EDGE, aToFace, aFromFace); + storeGenerationHistory(this, aResult, TopAbs_FACE, aToFace, aFromFace); + } else { + storeGenerationHistory(this, aResult, (TopAbs_ShapeEnum)theTypeToExp, aToFace, aFromFace); + } + + if(aResult.ShapeType() == TopAbs_COMPOUND) { + GeomShapePtr aGeomShape = toShape(aResult); + ListOfShape aResults; + aGeomShape = GeomAlgoAPI_ShapeTools::combineShapes(aGeomShape, + GeomAPI_Shape::COMPSOLID, + aResults); + aResult = aGeomShape->impl(); + } + // Setting result. if (!aResult.IsNull()) { aResult = GeomAlgoAPI_DFLoader::refineResult(aResult); - GeomShapePtr aGeomSh(new GeomAPI_Shape()); - aGeomSh->setImpl(new TopoDS_Shape(aResult)); - this->setShape(aGeomSh); + this->setShape(toShape(aResult)); this->setDone(true); } } +//================================================================================================== +void GeomAlgoAPI_Prism::buildByFaces(const GeomShapePtr theBaseShape, + const GeomDirPtr theDirection, + const GeomShapePtr theToShape, + const double theToSize, + const bool theToIsPlanar, + const GeomShapePtr theFromShape, + const double theFromSize, + const bool theFromIsPlanar, + const GeomAPI_Shape::ShapeType theTypeToExp) +{ + const TopoDS_Shape& aBaseShape = theBaseShape->impl(); + gp_Vec anExtVec = theDirection->impl(); + + // Moving prism bounding faces according to "from" and "to" sizes. + GeomShapePtr aBoundingFromShape = buildOffset(theFromShape, theFromSize, theDirection, *this); + GeomShapePtr aBoundingToShape = buildOffset(theToShape, theToSize, theDirection, *this); + + // Bounding box for shapes used in prism building. + Bnd_Box aBndBox; + BRepBndLib::Add(aBaseShape, aBndBox); + BRepBndLib::Add(aBoundingFromShape->impl(), aBndBox); + BRepBndLib::Add(aBoundingToShape->impl(), aBndBox); + double aPrismLength = 2.0 * aBndBox.CornerMin().Distance(aBndBox.CornerMax()); + + // Prism building. + gp_Trsf aTrsf; + aTrsf.SetTranslation(anExtVec * -aPrismLength); + BRepBuilderAPI_Transform* aTransformBuilder = new BRepBuilderAPI_Transform(aBaseShape, aTrsf); + if (!aTransformBuilder || !aTransformBuilder->IsDone()) { + return; + } + this->appendAlgo(std::shared_ptr( + new GeomAlgoAPI_MakeShape(aTransformBuilder))); + TopoDS_Shape aMovedBase = aTransformBuilder->Shape(); + + // Making prism. + BRepPrimAPI_MakePrism* aPrismBuilder = + new BRepPrimAPI_MakePrism(aMovedBase, anExtVec * 2 * aPrismLength); + if (!aPrismBuilder || !aPrismBuilder->IsDone()) { + return; + } + this->appendAlgo(std::shared_ptr( + new GeomAlgoAPI_MakeShape(aPrismBuilder))); + + GeomShapePtr aResult = toShape(aPrismBuilder->Shape()); + + // Prism generatrix + ListOfShape aPrismBaseFaces; + collectPrismBases(aMovedBase, *aPrismBuilder, aPrismBaseFaces, theTypeToExp); + + // Build planar faces intersecting the prism fully. + BRepBndLib::Add(aResult->impl(), aBndBox); + aBoundingFromShape = buildPlanarFace(aBoundingFromShape, aBndBox); + aBoundingToShape = buildPlanarFace(aBoundingToShape, aBndBox); + + // Perform partition. + ListOfShape anObjects, aTools; + anObjects.push_back(aResult); + aTools.push_back(aBoundingFromShape); + aTools.push_back(aBoundingToShape); + + GeomMakeShapePtr aPartition(new GeomAlgoAPI_Partition(anObjects, aTools)); + if (!aPartition->isDone()) + return; + + this->appendAlgo(aPartition); + + // Collect pieces of boundary shapes, split by Partition. + if (theFromIsPlanar) { + ListOfShape anImagesFrom; + aPartition->modified(aBoundingFromShape, anImagesFrom); + for (ListOfShape::iterator anIt = anImagesFrom.begin(); anIt != anImagesFrom.end(); ++anIt) + addFromShape(*anIt); + } + + if (theToIsPlanar) { + ListOfShape anImagesTo; + aPartition->modified(aBoundingToShape, anImagesTo); + for (ListOfShape::iterator anIt = anImagesTo.begin(); anIt != anImagesTo.end(); ++anIt) + addToShape(*anIt); + } + + // Collect results which have both boundaries, selected for extrusion, + // but which do not contain top and bottom faces of the prism + // (these faces are treated as infinitely distant). + aResult = collectResults(aPartition, aTools, aPrismBaseFaces, theTypeToExp); + if (aResult && aResult->shapeType() == GeomAPI_Shape::COMPOUND) { + ListOfShape aResults; + aResult = GeomAlgoAPI_ShapeTools::combineShapes(aResult, + theTypeToExp == GeomAPI_Shape::EDGE ? GeomAPI_Shape::SHELL : GeomAPI_Shape::COMPSOLID, + aResults); + + if (aResults.size() > 1 && + (GeomAlgoAPI_ShapeTools::hasSharedTopology(aResults, GeomAPI_Shape::EDGE) || + GeomAlgoAPI_ShapeTools::hasSharedTopology(aResults, GeomAPI_Shape::VERTEX))) { + // results shuold not have shared topology + aResult = GeomShapePtr(); + } + } + + if (aResult) { + this->setShape(aResult); + this->setDone(true); + } +} + + // Auxilary functions: +//================================================================================================== +GeomShapePtr buildPlanarFace(const GeomShapePtr& theOriginalShape, + const Bnd_Box& theBaseShapeBB) +{ + GeomPlanePtr aPlane = GeomAPI_Face(theOriginalShape).getPlane(); + if (!aPlane) + return theOriginalShape; + + gp_Pnt aCornerMin = theBaseShapeBB.CornerMin(); + gp_Pnt aCornerMax = theBaseShapeBB.CornerMax(); + double aSize = aCornerMin.SquareDistance(aCornerMax); + + gp_Pnt aLocation = aPlane->location()->impl(); + + gp_Pnt aCurPnt; + for (int x = 0; x < 2; ++x) { + aCurPnt.SetX(x == 0 ? aCornerMin.X() : aCornerMax.X()); + for (int y = 0; y < 2; ++y) { + aCurPnt.SetY(y == 0 ? aCornerMin.Y() : aCornerMax.Y()); + for (int z = 0; z < 2; ++z) { + aCurPnt.SetZ(z == 0 ? aCornerMin.Z() : aCornerMax.Z()); + double aDist = aCurPnt.SquareDistance(aLocation); + if (aDist > aSize) + aSize = aDist; + } + } + } + + aSize = Sqrt(aSize); + return GeomAlgoAPI_FaceBuilder::squareFace(aPlane, 2.0 * aSize); +} + +//================================================================================================== +GeomShapePtr buildOffset(const GeomShapePtr& theShape, + const double theOffset, + const GeomDirPtr theDirection, + GeomAlgoAPI_MakeShapeList& theMakeShapeList) +{ + if (Abs(theOffset) < Precision::Confusion()) + return theShape; // no need zero offset + + GeomMakeShapePtr anAlgo(new GeomAlgoAPI_Offset(theShape, theOffset)); + if (!anAlgo->isDone()) { + // offset not done, perform translation + std::shared_ptr anAxis(new GeomAPI_Ax1()); + anAxis->setDir(theDirection); + anAlgo.reset(new GeomAlgoAPI_Translation(theShape, anAxis, theOffset)); + } + + GeomShapePtr aResult = theShape; + if (anAlgo->isDone()) { + theMakeShapeList.appendAlgo(anAlgo); + aResult = anAlgo->shape(); + } + return aResult; +} + +//================================================================================================== +void collectPrismBases(const TopoDS_Shape& theBaseShape, + BRepPrimAPI_MakePrism& thePrismAlgo, + ListOfShape& theBoundaries, + const GeomAPI_Shape::ShapeType theTypeToExp) +{ + for (TopExp_Explorer anExp(theBaseShape, (TopAbs_ShapeEnum)theTypeToExp); + anExp.More(); anExp.Next()) { + theBoundaries.push_back(toShape(thePrismAlgo.FirstShape(anExp.Current()))); + theBoundaries.push_back(toShape(thePrismAlgo.LastShape(anExp.Current()))); + } +} + +//================================================================================================== +typedef std::set SetOfShape; + +bool isShapeApplicable(const GeomShapePtr& theSolid, + const std::list& theShapesToExist, + const SetOfShape& theShapesToExclude, + const GeomAPI_Shape::ShapeType theTypeToExp) +{ + SetOfShape aFaces; + for (GeomAPI_ShapeExplorer aFExp(theSolid, theTypeToExp); + aFExp.more(); aFExp.next()) { + GeomShapePtr aCurrent = aFExp.current(); + if (theShapesToExclude.find(aCurrent) != theShapesToExclude.end()) + return false; + aFaces.insert(aCurrent); + } + + // check all faces are in solid + bool isApplicable = true; + for (std::list::const_iterator it1 = theShapesToExist.begin(); + it1 != theShapesToExist.end() && isApplicable; ++it1) { + ListOfShape::const_iterator it2 = it1->begin(); + for (; it2 != it1->end(); ++it2) + if (aFaces.find(*it2) != aFaces.end()) + break; + isApplicable = it2 != it1->end(); + } + return isApplicable; +} + +void collectModified(const GeomMakeShapePtr& theOperation, + const ListOfShape& theShapes, + std::list& theModified) +{ + for (ListOfShape::const_iterator anIt = theShapes.begin(); + anIt != theShapes.end(); ++anIt) { + theModified.push_back(ListOfShape()); + theOperation->modified(*anIt, theModified.back()); + theOperation->generated(*anIt, theModified.back()); + theModified.back().push_back(*anIt); + } +} + +GeomShapePtr collectResults(const GeomMakeShapePtr& theOperation, + const ListOfShape& theBoundaries, + const ListOfShape& theShapesToExclude, + const GeomAPI_Shape::ShapeType theTypeToExp) +{ + ListOfShape aResults; + + // collect modified shapes + std::list aModifiedBoundaries; + collectModified(theOperation, theBoundaries, aModifiedBoundaries); + + std::list aModifiedExclude; + collectModified(theOperation, theShapesToExclude, aModifiedExclude); + SetOfShape aTabooShapes; + for (std::list::iterator anIt = aModifiedExclude.begin(); + anIt != aModifiedExclude.end(); ++anIt) + aTabooShapes.insert(anIt->begin(), anIt->end()); + + // type of sub-shapes to explode + GeomAPI_Shape::ShapeType aSubshapeType; + switch (theTypeToExp) { + case GeomAPI_Shape::VERTEX: + aSubshapeType = GeomAPI_Shape::EDGE; + break; + case GeomAPI_Shape::EDGE: + aSubshapeType = GeomAPI_Shape::FACE; + break; + case GeomAPI_Shape::FACE: + aSubshapeType = GeomAPI_Shape::SOLID; + break; + default: + aSubshapeType = GeomAPI_Shape::COMPOUND; + } + + // search applicable solids + GeomShapePtr anOperationResult = theOperation->shape(); + for (GeomAPI_ShapeExplorer anExp(anOperationResult, aSubshapeType); + anExp.more(); anExp.next()) { + if (isShapeApplicable(anExp.current(), aModifiedBoundaries, aTabooShapes, theTypeToExp)) + aResults.push_back(anExp.current()); + } + + GeomShapePtr aResult; + if (aResults.size() == 1) + aResult = aResults.front(); + else if (!aResults.empty()) + aResult = GeomAlgoAPI_CompoundBuilder::compound(aResults); + return aResult; +} + //================================================================================================== void storeGenerationHistory(GeomAlgoAPI_Prism* thePrismAlgo, const TopoDS_Shape& theBase, diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Prism.h b/src/GeomAlgoAPI/GeomAlgoAPI_Prism.h index 7d2d2dbdd..a38d45557 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_Prism.h +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Prism.h @@ -20,15 +20,15 @@ #ifndef GeomAlgoAPI_Prism_H_ #define GeomAlgoAPI_Prism_H_ -#include "GeomAlgoAPI.h" - #include "GeomAlgoAPI_MakeSweep.h" -#include #include #include +class GeomAPI_Dir; +class GeomAPI_Pln; + /// \class GeomAlgoAPI_Prism /// \ingroup DataAlgo /// \brief Allows to create the prism based on a given face and bounding planes. @@ -55,13 +55,32 @@ public: const double theFromSize); private: - /// Builds resulting shape. - void build(const GeomShapePtr& theBaseShape, - const std::shared_ptr theDirection, - const GeomShapePtr& theToShape, - const double theToSize, - const GeomShapePtr& theFromShape, - const double theFromSize); + /// Build extrusion by distances from the base shape. + void buildBySizes(const GeomShapePtr theBaseShape, + const std::shared_ptr theDirection, + const double theToSize, + const double theFromSize, + const GeomAPI_Shape::ShapeType theTypeToExp); + + /// Build extrusion from plane to plane. + void buildByPlanes(const GeomShapePtr theBaseShape, + const std::shared_ptr theDirection, + const std::shared_ptr theToPlane, + const double theToSize, + const std::shared_ptr theFromPlane, + const double theFromSize, + const GeomAPI_Shape::ShapeType theTypeToExp); + + /// Build extrusion from face to face. + void buildByFaces(const GeomShapePtr theBaseShape, + const std::shared_ptr theDirection, + const GeomShapePtr theToShape, + const double theToSize, + const bool theToIsPlanar, + const GeomShapePtr theFromShape, + const double theFromSize, + const bool theFromIsPlanar, + const GeomAPI_Shape::ShapeType theTypeToExp); }; #endif diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.cpp index 357f79216..d1d3abe8b 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.cpp @@ -546,6 +546,24 @@ std::shared_ptr GeomAlgoAPI_ShapeTools::groupSharedTopology( return aResult; } +//================================================================================================== +bool GeomAlgoAPI_ShapeTools::hasSharedTopology(const ListOfShape& theShapes, + const GeomAPI_Shape::ShapeType theShapeType) +{ + TopTools_IndexedMapOfShape aSubs; + for (ListOfShape::const_iterator anIt = theShapes.begin(); anIt != theShapes.end(); ++anIt) { + TopTools_IndexedMapOfShape aCurSubs; + TopExp::MapShapes((*anIt)->impl(), (TopAbs_ShapeEnum)theShapeType, aCurSubs); + for (TopTools_IndexedMapOfShape::Iterator aSubIt(aCurSubs); aSubIt.More(); aSubIt.Next()) { + if (aSubs.Contains(aSubIt.Value())) + return true; + else + aSubs.Add(aSubIt.Value()); + } + } + return false; +} + //================================================================================================== std::list > GeomAlgoAPI_ShapeTools::getBoundingBox(const ListOfShape& theShapes, const double theEnlarge) diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.h b/src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.h index 4127ccf2c..da415d359 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.h +++ b/src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.h @@ -80,6 +80,13 @@ public: GEOMALGOAPI_EXPORT static std::shared_ptr groupSharedTopology(const std::shared_ptr theCompound); + /// \brief Check group of shapes has shared sub-shapes of the given type + /// \param[in] theShapes list of shapes + /// \param[in] theShapeType type of sub-shapes to check + /// \return \c true if shared topology exists + GEOMALGOAPI_EXPORT static bool hasSharedTopology(const ListOfShape& theShapes, + const GeomAPI_Shape::ShapeType theShapeType); + /// \brief Calculates bounding box for theShapes /// \return list of eight points. /// \param[in] theShapes list of shapes. -- 2.39.2