From adf26479b37f6238c3fd33b7da5f37dd57b68b00 Mon Sep 17 00:00:00 2001 From: azv Date: Tue, 14 May 2019 15:27:22 +0300 Subject: [PATCH] Task 3.2. Concealment into multi-level Compounds Update behavior of PARTITION operation to keep hierarchy of compounds. --- src/FeaturesAPI/FeaturesAPI_Partition.cpp | 22 +- src/FeaturesAPI/FeaturesAPI_Partition.h | 6 +- src/FeaturesPlugin/CMakeLists.txt | 7 +- .../FeaturesPlugin_Partition.cpp | 279 +++++++----------- src/FeaturesPlugin/FeaturesPlugin_Partition.h | 13 +- .../FeaturesPlugin_VersionedBoolean.cpp | 79 ++--- .../FeaturesPlugin_VersionedBoolean.h | 11 +- ... TestPartition_MultiLevelCompound_v0_1.py} | 6 +- .../TestPartition_MultiLevelCompound_v0_2.py | 121 ++++++++ .../TestPartition_MultiLevelCompound_v0_3.py | 112 +++++++ ...artition_MultiLevelCompound_v20190506_1.py | 96 ++++++ ...artition_MultiLevelCompound_v20190506_2.py | 121 ++++++++ ...artition_MultiLevelCompound_v20190506_3.py | 110 +++++++ 13 files changed, 756 insertions(+), 227 deletions(-) rename src/FeaturesPlugin/Test/{TestPartition_MultiLevelCompound0.py => TestPartition_MultiLevelCompound_v0_1.py} (98%) create mode 100644 src/FeaturesPlugin/Test/TestPartition_MultiLevelCompound_v0_2.py create mode 100644 src/FeaturesPlugin/Test/TestPartition_MultiLevelCompound_v0_3.py create mode 100644 src/FeaturesPlugin/Test/TestPartition_MultiLevelCompound_v20190506_1.py create mode 100644 src/FeaturesPlugin/Test/TestPartition_MultiLevelCompound_v20190506_2.py create mode 100644 src/FeaturesPlugin/Test/TestPartition_MultiLevelCompound_v20190506_3.py diff --git a/src/FeaturesAPI/FeaturesAPI_Partition.cpp b/src/FeaturesAPI/FeaturesAPI_Partition.cpp index 1af34d830..e0a0186ef 100644 --- a/src/FeaturesAPI/FeaturesAPI_Partition.cpp +++ b/src/FeaturesAPI/FeaturesAPI_Partition.cpp @@ -30,11 +30,14 @@ FeaturesAPI_Partition::FeaturesAPI_Partition(const std::shared_ptr& theFeature, - const std::list& theBaseObjects) +FeaturesAPI_Partition::FeaturesAPI_Partition( + const std::shared_ptr& theFeature, + const std::list& theBaseObjects, + const int theVersion) : ModelHighAPI_Interface(theFeature) { if(initialize()) { + fillAttribute(theVersion, theFeature->integer(FeaturesPlugin_Partition::VERSION_ID())); setBase(theBaseObjects); } } @@ -61,15 +64,22 @@ void FeaturesAPI_Partition::dump(ModelHighAPI_Dumper& theDumper) const AttributeSelectionListPtr anAttrObjects = aBase->selectionList(FeaturesPlugin_Partition::BASE_OBJECTS_ID()); + AttributeIntegerPtr aVersion = + aBase->integer(FeaturesPlugin_Partition::VERSION_ID()); - theDumper << aBase << " = model.addPartition(" << aDocName << - ", " << anAttrObjects << ")" << std::endl; + theDumper << aBase << " = model.addPartition(" << aDocName << ", " << anAttrObjects; + + if (aVersion && aVersion->isInitialized()) + theDumper << ", " << aVersion->value(); + + theDumper << ")" << std::endl; } //================================================================================================== PartitionPtr addPartition(const std::shared_ptr& thePart, - const std::list& theBaseObjects) + const std::list& theBaseObjects, + const int theVersion) { std::shared_ptr aFeature = thePart->addFeature(FeaturesAPI_Partition::ID()); - return PartitionPtr(new FeaturesAPI_Partition(aFeature, theBaseObjects)); + return PartitionPtr(new FeaturesAPI_Partition(aFeature, theBaseObjects, theVersion)); } diff --git a/src/FeaturesAPI/FeaturesAPI_Partition.h b/src/FeaturesAPI/FeaturesAPI_Partition.h index 15c7253fb..07b534972 100644 --- a/src/FeaturesAPI/FeaturesAPI_Partition.h +++ b/src/FeaturesAPI/FeaturesAPI_Partition.h @@ -43,7 +43,8 @@ public: /// Constructor with values. FEATURESAPI_EXPORT explicit FeaturesAPI_Partition(const std::shared_ptr& theFeature, - const std::list& theBaseObjects); + const std::list& theBaseObjects, + const int theVersion = 0); /// Destructor. FEATURESAPI_EXPORT @@ -69,6 +70,7 @@ typedef std::shared_ptr PartitionPtr; /// \brief Create Partition feature. FEATURESAPI_EXPORT PartitionPtr addPartition(const std::shared_ptr& thePart, - const std::list& theBaseObjects); + const std::list& theBaseObjects, + const int theVersion = 0); #endif // FeaturesAPI_Partition_H_ diff --git a/src/FeaturesPlugin/CMakeLists.txt b/src/FeaturesPlugin/CMakeLists.txt index 0e8117970..417760da5 100644 --- a/src/FeaturesPlugin/CMakeLists.txt +++ b/src/FeaturesPlugin/CMakeLists.txt @@ -486,5 +486,10 @@ ADD_UNIT_TESTS(TestExtrusion.py TestBooleanSplit_MultiLevelCompound_v0_2.py TestBooleanSplit_MultiLevelCompound_v20190506_1.py TestBooleanSplit_MultiLevelCompound_v20190506_2.py - TestPartition_MultiLevelCompound0.py + TestPartition_MultiLevelCompound_v0_1.py + TestPartition_MultiLevelCompound_v0_2.py + TestPartition_MultiLevelCompound_v0_3.py + TestPartition_MultiLevelCompound_v20190506_1.py + TestPartition_MultiLevelCompound_v20190506_2.py + TestPartition_MultiLevelCompound_v20190506_3.py ) diff --git a/src/FeaturesPlugin/FeaturesPlugin_Partition.cpp b/src/FeaturesPlugin/FeaturesPlugin_Partition.cpp index 7c29a3efe..83a87047e 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Partition.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Partition.cpp @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -47,19 +48,7 @@ #include #include -typedef std::list > CompsolidSubs; - -static void pullObjectsAndPlanes(const AttributeSelectionListPtr& theSelectedList, - CompsolidSubs& theObjects, ListOfShape& thePlanes); - -static void resizePlanes(const CompsolidSubs& theObjects, ListOfShape& thePlanes, - std::shared_ptr& theMakeShapeList); - -static void unusedSubsOfComposolid(const CompsolidSubs& theObjects, CompsolidSubs& theNotUsed); - -static bool cutUnusedSubs(CompsolidSubs& theObjects, CompsolidSubs& theNotUsed, - std::shared_ptr& theMakeShapeList, - std::string& theError); +static const int THE_PARTITION_VERSION_1 = 20190506; //================================================================================================= @@ -71,50 +60,42 @@ FeaturesPlugin_Partition::FeaturesPlugin_Partition() void FeaturesPlugin_Partition::initAttributes() { data()->addAttribute(BASE_OBJECTS_ID(), ModelAPI_AttributeSelectionList::typeId()); + initVersion(THE_PARTITION_VERSION_1, selectionList(BASE_OBJECTS_ID())); } //================================================================================================= void FeaturesPlugin_Partition::execute() { - CompsolidSubs anObjects; + ObjectHierarchy anObjects; ListOfShape aPlanes; // Getting objects. - pullObjectsAndPlanes(selectionList(BASE_OBJECTS_ID()), anObjects, aPlanes); - if(anObjects.empty()) { + processAttribute(BASE_OBJECTS_ID(), anObjects, aPlanes); + if(anObjects.IsEmpty()) { static const std::string aFeatureError = "Error: No objects for partition."; setError(aFeatureError); return; } - ListOfShape aBaseObjects; - for (CompsolidSubs::iterator anIt = anObjects.begin(); anIt != anObjects.end(); ++anIt) - aBaseObjects.insert(aBaseObjects.end(), anIt->second.begin(), anIt->second.end()); + ListOfShape aBaseObjects = anObjects.Objects(); aBaseObjects.insert(aBaseObjects.end(), aPlanes.begin(), aPlanes.end()); // resize planes to the bounding box of operated shapes std::shared_ptr aMakeShapeList(new GeomAlgoAPI_MakeShapeList()); - resizePlanes(anObjects, aPlanes, aMakeShapeList); + resizePlanes(anObjects.Objects(), aPlanes, aMakeShapeList); // cut unused solids of composolids from the objects of partition - CompsolidSubs anUnusedSubs; - unusedSubsOfComposolid(anObjects, anUnusedSubs); - for (CompsolidSubs::iterator anIt = anUnusedSubs.begin(); anIt != anUnusedSubs.end(); ++anIt) - aBaseObjects.insert(aBaseObjects.end(), anIt->second.begin(), anIt->second.end()); - + ListOfShape aTargetObjects, anUnusedSubs; std::string aError; - if (!cutUnusedSubs(anObjects, anUnusedSubs, aMakeShapeList, aError)) { + if (!cutSubs(anObjects, aTargetObjects, anUnusedSubs, aMakeShapeList, aError)) { setError(aError); return; } + aBaseObjects.insert(aBaseObjects.end(), anUnusedSubs.begin(), anUnusedSubs.end()); - // perform partition first time to split target solids - ListOfShape aTargetObjects; - for (CompsolidSubs::iterator anIt = anObjects.begin(); anIt != anObjects.end(); ++anIt) - aTargetObjects.insert(aTargetObjects.end(), anIt->second.begin(), anIt->second.end()); - + // perform partition first time to split target solids by planes std::shared_ptr aPartitionAlgo( - new GeomAlgoAPI_Partition(aTargetObjects, aPlanes)); + new GeomAlgoAPI_Partition(aTargetObjects, aPlanes)); // Checking that the algorithm worked properly. if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aPartitionAlgo, getKind(), aError)) { @@ -129,8 +110,7 @@ void FeaturesPlugin_Partition::execute() // second pass of a partition to split shared faces of compsolids aTargetObjects.clear(); aTargetObjects.push_back(aResultShape); - for (CompsolidSubs::iterator anIt = anUnusedSubs.begin(); anIt != anUnusedSubs.end(); ++anIt) - aTargetObjects.insert(aTargetObjects.end(), anIt->second.begin(), anIt->second.end()); + aTargetObjects.insert(aTargetObjects.end(), anUnusedSubs.begin(), anUnusedSubs.end()); aPartitionAlgo.reset(new GeomAlgoAPI_Partition(aTargetObjects, ListOfShape())); @@ -145,13 +125,41 @@ void FeaturesPlugin_Partition::execute() } int aResultIndex = 0; - if(aResultShape->shapeType() == GeomAPI_Shape::COMPOUND) { - for(GeomAPI_ShapeIterator anIt(aResultShape); anIt.more(); anIt.next()) { - storeResult(aBaseObjects, aPlanes, anIt.current(), aMakeShapeList, aResultIndex); + + int aPartitionVersion = version(); + if (aPartitionVersion < THE_PARTITION_VERSION_1) { + // default behaviours of Partition + if(aResultShape->shapeType() == GeomAPI_Shape::COMPOUND) { + for(GeomAPI_ShapeIterator anIt(aResultShape); anIt.more(); anIt.next()) { + storeResult(aBaseObjects, aPlanes, anIt.current(), aMakeShapeList, aResultIndex); + ++aResultIndex; + } + } else { + storeResult(aBaseObjects, aPlanes, aResultShape, aMakeShapeList, aResultIndex); ++aResultIndex; } - } else { - storeResult(aBaseObjects, aPlanes, aResultShape, aMakeShapeList, aResultIndex); + } + else { + // merge hierarchies of compounds containing objects and tools + GeomShapePtr aFirstShape = aResultShape; + GeomAPI_ShapeIterator anIt; + if (aResultShape->shapeType() == GeomAPI_Shape::COMPOUND) { + anIt = GeomAPI_ShapeIterator(aResultShape); + aFirstShape = anIt.current(); + anIt.next(); + } + + GeomShapePtr aResultCompound = + keepUnusedSubsOfCompound(aFirstShape, anObjects, ObjectHierarchy(), aMakeShapeList); + + if (anIt.more()) { + std::shared_ptr aBuilder(new GeomAlgoAPI_ShapeBuilder); + for (; anIt.more(); anIt.next()) + aBuilder->add(aResultCompound, anIt.current()); + aMakeShapeList->appendAlgo(aBuilder); + } + + storeResult(aBaseObjects, aPlanes, aResultCompound, aMakeShapeList, aResultIndex); ++aResultIndex; } @@ -197,160 +205,75 @@ void FeaturesPlugin_Partition::storeResult( } -//================= Auxiliary functions =================================================== - -static CompsolidSubs::iterator findOrAdd(CompsolidSubs& theList, const GeomShapePtr& theCompsolid) -{ - CompsolidSubs::iterator aFound = theList.begin(); - for (; aFound != theList.end(); ++aFound) - if (aFound->first == theCompsolid) - break; - if (aFound == theList.end()) { - theList.push_back(std::pair(theCompsolid, ListOfShape())); - aFound = --theList.end(); - } - return aFound; -} - -void pullObjectsAndPlanes(const AttributeSelectionListPtr& theSelectedList, - CompsolidSubs& theObjects, ListOfShape& thePlanes) -{ - std::map aMapCompsolidShape; - - int aSize = theSelectedList->size(); - for (int anIndex = 0; anIndex < aSize; ++anIndex) { - AttributeSelectionPtr anObjectAttr = theSelectedList->value(anIndex); - ResultPtr aContext = anObjectAttr->context(); - GeomShapePtr anObject = anObjectAttr->value(); - if (anObject) { - GeomShapePtr anOwnerShape = anObject; - // check the result is a compsolid and store all used subs in a single list - ResultBodyPtr aResCompSolidPtr = ModelAPI_Tools::bodyOwner(aContext); - if (aResCompSolidPtr && aResCompSolidPtr->shape()->shapeType() == GeomAPI_Shape::COMPSOLID) { - std::map::const_iterator - aFound = aMapCompsolidShape.find(aResCompSolidPtr); - if (aFound != aMapCompsolidShape.end()) - anOwnerShape = aFound->second; - else { - anOwnerShape = aResCompSolidPtr->shape(); - aMapCompsolidShape[aResCompSolidPtr] = anOwnerShape; - } - } - - CompsolidSubs::iterator aFound = findOrAdd(theObjects, anOwnerShape); - aFound->second.push_back(anObject); - } - else { - // It could be a construction plane. - thePlanes.push_back(anObjectAttr->context()->shape()); - } - } -} - -void resizePlanes(const CompsolidSubs& theObjects, ListOfShape& thePlanes, - std::shared_ptr& theMakeShapeList) -{ - ListOfShape aSolidsInOperation; - for (CompsolidSubs::const_iterator anIt = theObjects.begin(); anIt != theObjects.end(); ++anIt) - aSolidsInOperation.insert(aSolidsInOperation.end(), anIt->second.begin(), anIt->second.end()); - - std::list > aBoundingPoints = - GeomAlgoAPI_ShapeTools::getBoundingBox(aSolidsInOperation, 1.0); - - ListOfShape aPlanesCopy = thePlanes; - thePlanes.clear(); - - // Resize planes to fit in bounding box - for (ListOfShape::const_iterator anIt = aPlanesCopy.begin(); anIt != aPlanesCopy.end(); ++anIt) { - GeomShapePtr aPlane = *anIt; - GeomShapePtr aTool = GeomAlgoAPI_ShapeTools::fitPlaneToBox(aPlane, aBoundingPoints); - std::shared_ptr aMkShCustom(new GeomAlgoAPI_MakeShapeCustom); - aMkShCustom->addModified(aPlane, aTool); - theMakeShapeList->appendAlgo(aMkShCustom); - thePlanes.push_back(aTool); - } -} - -void unusedSubsOfComposolid(const CompsolidSubs& theObjects, CompsolidSubs& theNotUsed) -{ - for (CompsolidSubs::const_iterator aCSIt = theObjects.begin(); - aCSIt != theObjects.end(); ++aCSIt) { - if (aCSIt->first->shapeType() != GeomAPI_Shape::COMPSOLID) - continue; - - // check the compsolid is selected - if (aCSIt->second.size() == 1 && aCSIt->first->isEqual(aCSIt->second.front())) - continue; - - // process all sub-solids of compsolid - ListOfShape aNotUsedSolids; - for (GeomAPI_ShapeExplorer anExp(aCSIt->first, GeomAPI_Shape::SOLID); - anExp.more(); anExp.next()) { - GeomShapePtr aSolidInCompSolid = anExp.current(); - ListOfShape::const_iterator anIt = aCSIt->second.begin(); - for (; anIt != aCSIt->second.end(); ++anIt) - if (aSolidInCompSolid->isEqual(*anIt)) - break; - - if (anIt == aCSIt->second.end()) - aNotUsedSolids.push_back(aSolidInCompSolid); - } - - if (!aNotUsedSolids.empty()) - theNotUsed.push_back(std::pair(aCSIt->first, aNotUsedSolids)); - } -} +//================================================================================================= -static bool cutSubs(const GeomShapePtr& theFirstArgument, - CompsolidSubs& theSubsToCut, +static bool cutSubs(ListOfShape& theSubsToCut, const ListOfShape& theTools, std::shared_ptr& theMakeShapeList, std::string& theError) { - if (theTools.empty()) + if (theSubsToCut.empty() || theTools.empty()) return true; - std::shared_ptr aCutAlgo; - - for (CompsolidSubs::iterator aUIt= theSubsToCut.begin(); aUIt != theSubsToCut.end(); ++aUIt) { - if (aUIt->first == theFirstArgument) - continue; // no need to split unused subs of the first compsolid - - // cut from current list of solids - aCutAlgo.reset( - new GeomAlgoAPI_Boolean(aUIt->second, theTools, GeomAlgoAPI_Tools::BOOL_CUT)); - if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aCutAlgo, "", theError)) - return false; - theMakeShapeList->appendAlgo(aCutAlgo); - - // update list of un-selected objects of the partition - GeomAPI_Shape::ShapeType aType = aUIt->second.front()->shapeType(); - aUIt->second.clear(); - for (GeomAPI_ShapeExplorer anExp(aCutAlgo->shape(), aType); anExp.more(); anExp.next()) - aUIt->second.push_back(anExp.current()); - } + // cut from current list of solids + std::shared_ptr aCutAlgo( + new GeomAlgoAPI_Boolean(theSubsToCut, theTools, GeomAlgoAPI_Tools::BOOL_CUT)); + if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aCutAlgo, "", theError)) + return false; + theMakeShapeList->appendAlgo(aCutAlgo); + + // update list of un-selected objects of the partition + GeomAPI_Shape::ShapeType aType = theSubsToCut.front()->shapeType(); + theSubsToCut.clear(); + for (GeomAPI_ShapeExplorer anExp(aCutAlgo->shape(), aType); anExp.more(); anExp.next()) + theSubsToCut.push_back(anExp.current()); return true; } -bool cutUnusedSubs(CompsolidSubs& theObjects, CompsolidSubs& theNotUsed, - std::shared_ptr& theMakeShapeList, - std::string& theError) +bool FeaturesPlugin_Partition::cutSubs( + FeaturesPlugin_Partition::ObjectHierarchy& theHierarchy, + ListOfShape& theUsed, + ListOfShape& theNotUsed, + std::shared_ptr& theMakeShapeList, + std::string& theError) { - GeomShapePtr aFirstArgument = theObjects.front().first; + theUsed.clear(); + theNotUsed.clear(); + + ObjectHierarchy::Iterator anIt = theHierarchy.Begin(); // compose a set of tools for the CUT operation: // find the list of unused subs of the first argument or use itself - ListOfShape aToolsForUsed; - CompsolidSubs::iterator aUIt = theNotUsed.begin(); - for (; aUIt != theNotUsed.end(); ++aUIt) - if (aUIt->first == aFirstArgument) { - aToolsForUsed.insert(aToolsForUsed.end(), aUIt->second.begin(), aUIt->second.end()); - break; - } - ListOfShape aToolsForUnused; + ListOfShape aToolsForUsed, aToolsForUnused; + GeomShapePtr aFirstArgument = theHierarchy.Parent(*anIt); + if (aFirstArgument && aFirstArgument->shapeType() == GeomAPI_Shape::COMPSOLID) { + theHierarchy.SplitCompound(aFirstArgument, theUsed, aToolsForUsed); + theNotUsed = aToolsForUsed; + } + else { + aFirstArgument = *anIt; + theUsed.push_back(aFirstArgument); + } aToolsForUnused.push_back(aFirstArgument); // cut subs - return cutSubs(aFirstArgument, theObjects, aToolsForUsed, theMakeShapeList, theError) - && cutSubs(aFirstArgument, theNotUsed, aToolsForUnused, theMakeShapeList, theError); + bool isOk = true; + for (; anIt != theHierarchy.End() && isOk; ++anIt) { + ListOfShape aUsed, aNotUsed; + + GeomShapePtr aParent = theHierarchy.Parent(*anIt); + if (aParent && aParent->shapeType() == GeomAPI_Shape::COMPSOLID) + theHierarchy.SplitCompound(aParent, aUsed, aNotUsed); + else + aUsed.push_back(*anIt); + + isOk = ::cutSubs(aUsed, aToolsForUsed, theMakeShapeList, theError) + && ::cutSubs(aNotUsed, aToolsForUnused, theMakeShapeList, theError); + if (isOk) { + theUsed.insert(theUsed.end(), aUsed.begin(), aUsed.end()); + theNotUsed.insert(theNotUsed.end(), aNotUsed.begin(), aNotUsed.end()); + } + } + + return isOk; } diff --git a/src/FeaturesPlugin/FeaturesPlugin_Partition.h b/src/FeaturesPlugin/FeaturesPlugin_Partition.h index 08269203f..aee69380b 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Partition.h +++ b/src/FeaturesPlugin/FeaturesPlugin_Partition.h @@ -20,7 +20,7 @@ #ifndef FeaturesPlugin_Partition_H_ #define FeaturesPlugin_Partition_H_ -#include "FeaturesPlugin.h" +#include "FeaturesPlugin_VersionedBoolean.h" #include #include @@ -29,7 +29,7 @@ /// \ingroup Plugins /// \brief Feature for applying of Partition operations on Shapes. Partition makes conjunctional /// faces of solids as shared. The result of partitions is a compsolid. -class FeaturesPlugin_Partition : public ModelAPI_Feature +class FeaturesPlugin_Partition : public FeaturesPlugin_VersionedBoolean { public: /// Feature kind. @@ -69,6 +69,15 @@ private: const GeomShapePtr theResultShape, const std::shared_ptr theMakeShape, const int theIndex = 0); + + /// Cut all of unused subs of compsolids by the full compsolid of the first selected object, + /// and vice versa, cut all objects of Partition by not used subs of the first selected object. + /// Store results of operation to the separated lists of shapes. + bool cutSubs(ObjectHierarchy& theHierarchy, + ListOfShape& theUsed, + ListOfShape& theNotUsed, + std::shared_ptr& theMakeShapeList, + std::string& theError); }; #endif diff --git a/src/FeaturesPlugin/FeaturesPlugin_VersionedBoolean.cpp b/src/FeaturesPlugin/FeaturesPlugin_VersionedBoolean.cpp index ba7d81ba1..9021a192f 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_VersionedBoolean.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_VersionedBoolean.cpp @@ -121,20 +121,11 @@ bool FeaturesPlugin_VersionedBoolean::processObject( std::shared_ptr aBoolAlgo; GeomShapePtr aResShape; - std::list > aBoundingPoints = - GeomAlgoAPI_ShapeTools::getBoundingBox(aListWithObject, 1.0); - // Resize planes. ListOfShape aToolsWithPlanes = theTools; - for (ListOfShape::const_iterator anIt = thePlanes.begin(); anIt != thePlanes.end(); ++anIt) { - GeomShapePtr aPlane = *anIt; - GeomShapePtr aTool = GeomAlgoAPI_ShapeTools::fitPlaneToBox(aPlane, aBoundingPoints); - std::shared_ptr aMkShCustom( - new GeomAlgoAPI_MakeShapeCustom); - aMkShCustom->addModified(aPlane, aTool); - aMakeShapeList->appendAlgo(aMkShCustom); - aToolsWithPlanes.push_back(aTool); - } + ListOfShape aPlanesCopy = thePlanes; + resizePlanes(aListWithObject, aPlanesCopy, aMakeShapeList); + aToolsWithPlanes.insert(aToolsWithPlanes.end(), aPlanesCopy.begin(), aPlanesCopy.end()); if (theBooleanType == GeomAlgoAPI_Tools::BOOL_PARTITION) aBoolAlgo.reset(new GeomAlgoAPI_Partition(aListWithObject, aToolsWithPlanes)); @@ -222,21 +213,11 @@ bool FeaturesPlugin_VersionedBoolean::processCompsolid( std::shared_ptr aMakeShapeList(new GeomAlgoAPI_MakeShapeList()); - std::list > aBoundingPoints = - GeomAlgoAPI_ShapeTools::getBoundingBox(aUsedInOperationSolids, 1.0); - // Resize planes. ListOfShape aToolsWithPlanes = theTools; - for (ListOfShape::const_iterator anIt = thePlanes.begin(); anIt != thePlanes.end(); ++anIt) - { - GeomShapePtr aPlane = *anIt; - GeomShapePtr aTool = GeomAlgoAPI_ShapeTools::fitPlaneToBox(aPlane, aBoundingPoints); - std::shared_ptr aMkShCustom( - new GeomAlgoAPI_MakeShapeCustom); - aMkShCustom->addModified(aPlane, aTool); - aMakeShapeList->appendAlgo(aMkShCustom); - aToolsWithPlanes.push_back(aTool); - } + ListOfShape aPlanesCopy = thePlanes; + resizePlanes(aUsedInOperationSolids, aPlanesCopy, aMakeShapeList); + aToolsWithPlanes.insert(aToolsWithPlanes.end(), aPlanesCopy.begin(), aPlanesCopy.end()); std::shared_ptr aBoolAlgo; if (theBooleanType == GeomAlgoAPI_Tools::BOOL_PARTITION) @@ -431,6 +412,29 @@ GeomShapePtr FeaturesPlugin_VersionedBoolean::keepUnusedSubsOfCompound( return aResultShape; } +//================================================================================================= +void FeaturesPlugin_VersionedBoolean::resizePlanes( + const ListOfShape& theObjects, + ListOfShape& thePlanes, + std::shared_ptr& theMakeShapeList) +{ + if (thePlanes.empty()) + return; + + std::list > aBoundingPoints = + GeomAlgoAPI_ShapeTools::getBoundingBox(theObjects, 1.0); + + // Resize planes to fit in bounding box + for (ListOfShape::iterator anIt = thePlanes.begin(); anIt != thePlanes.end(); ++anIt) { + GeomShapePtr aPlane = *anIt; + GeomShapePtr aTool = GeomAlgoAPI_ShapeTools::fitPlaneToBox(aPlane, aBoundingPoints); + std::shared_ptr aMkShCustom(new GeomAlgoAPI_MakeShapeCustom); + aMkShCustom->addModified(aPlane, aTool); + theMakeShapeList->appendAlgo(aMkShCustom); + *anIt = aTool; + } +} + //================================================================================================= int FeaturesPlugin_VersionedBoolean::version() { @@ -449,7 +453,7 @@ void FeaturesPlugin_VersionedBoolean::ObjectHierarchy::AddObject(const GeomShape } void FeaturesPlugin_VersionedBoolean::ObjectHierarchy::AddParent(const GeomShapePtr& theShape, - const GeomShapePtr& theParent) + const GeomShapePtr& theParent) { myParent[theShape] = theParent; @@ -465,7 +469,7 @@ void FeaturesPlugin_VersionedBoolean::ObjectHierarchy::AddParent(const GeomShape } GeomShapePtr FeaturesPlugin_VersionedBoolean::ObjectHierarchy::Parent(const GeomShapePtr& theShape, - bool theMarkProcessed) + bool theMarkProcessed) { MapShapeToParent::const_iterator aFound = myParent.find(theShape); GeomShapePtr aParent; @@ -507,9 +511,10 @@ void FeaturesPlugin_VersionedBoolean::ObjectHierarchy::ObjectsByType( } -void FeaturesPlugin_VersionedBoolean::ObjectHierarchy::SplitCompound(const GeomShapePtr& theCompShape, - ListOfShape& theUsed, - ListOfShape& theNotUsed) const +void FeaturesPlugin_VersionedBoolean::ObjectHierarchy::SplitCompound( + const GeomShapePtr& theCompShape, + ListOfShape& theUsed, + ListOfShape& theNotUsed) const { theUsed.clear(); theNotUsed.clear(); @@ -583,7 +588,7 @@ GeomShapePtr FeaturesPlugin_VersionedBoolean::ObjectHierarchy::collectUnusedSubs } else { GeomShapePtr aCompound = collectUnusedSubs(aCurrent, theUsed); if (aCompound) { - GeomAlgoAPI_ShapeBuilder::add(theTopLevelCompound, aCompound); + GeomAlgoAPI_ShapeBuilder::add(aResult, aCompound); isResultEmpty = false; } } @@ -592,12 +597,14 @@ GeomShapePtr FeaturesPlugin_VersionedBoolean::ObjectHierarchy::collectUnusedSubs } -FeaturesPlugin_VersionedBoolean::ObjectHierarchy::Iterator FeaturesPlugin_VersionedBoolean::ObjectHierarchy::Begin() +FeaturesPlugin_VersionedBoolean::ObjectHierarchy::Iterator +FeaturesPlugin_VersionedBoolean::ObjectHierarchy::Begin() { return Iterator(this); } -FeaturesPlugin_VersionedBoolean::ObjectHierarchy::Iterator FeaturesPlugin_VersionedBoolean::ObjectHierarchy::End() +FeaturesPlugin_VersionedBoolean::ObjectHierarchy::Iterator +FeaturesPlugin_VersionedBoolean::ObjectHierarchy::End() { return Iterator(this, false); } @@ -620,12 +627,14 @@ void FeaturesPlugin_VersionedBoolean::ObjectHierarchy::Iterator::SkipAlreadyProc ++myObject; } -bool FeaturesPlugin_VersionedBoolean::ObjectHierarchy::Iterator::operator==(const Iterator& theOther) const +bool FeaturesPlugin_VersionedBoolean::ObjectHierarchy::Iterator::operator==( + const Iterator& theOther) const { return myObject == theOther.myObject; } -bool FeaturesPlugin_VersionedBoolean::ObjectHierarchy::Iterator::operator!=(const Iterator& theOther) const +bool FeaturesPlugin_VersionedBoolean::ObjectHierarchy::Iterator::operator!=( + const Iterator& theOther) const { return !operator==(theOther); } diff --git a/src/FeaturesPlugin/FeaturesPlugin_VersionedBoolean.h b/src/FeaturesPlugin/FeaturesPlugin_VersionedBoolean.h index 81e662649..97266c776 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_VersionedBoolean.h +++ b/src/FeaturesPlugin/FeaturesPlugin_VersionedBoolean.h @@ -53,8 +53,10 @@ protected: /// The version is initialized for newly created features, /// not read from previously stored document. void initVersion(const int theVersion, - const std::shared_ptr theObjectsAttr, - const std::shared_ptr theToolsAttr); + const std::shared_ptr theObjectsAttr + = std::shared_ptr(), + const std::shared_ptr theToolsAttr + = std::shared_ptr()); /// Auxiliary class to store hierarchy of Boolean operation objects/tools /// and their parent shapes (compounds or compsolids) @@ -179,6 +181,11 @@ protected: ListOfShape& theResultShapesList, GeomShapePtr theResulCompound = GeomShapePtr()); + /// Resize planes to fit them to the bounding box of the given lins of objects. + static void resizePlanes(const ListOfShape& theObjects, + ListOfShape& thePlanes, + std::shared_ptr& theMakeShapeList); + /// Process unused sub-shapes of compounds. /// Keep the compound hierarchy, but merge top-level compounds /// into a single compound and add the result of the FUSE operation. diff --git a/src/FeaturesPlugin/Test/TestPartition_MultiLevelCompound0.py b/src/FeaturesPlugin/Test/TestPartition_MultiLevelCompound_v0_1.py similarity index 98% rename from src/FeaturesPlugin/Test/TestPartition_MultiLevelCompound0.py rename to src/FeaturesPlugin/Test/TestPartition_MultiLevelCompound_v0_1.py index 68ce6af49..f639003b6 100644 --- a/src/FeaturesPlugin/Test/TestPartition_MultiLevelCompound0.py +++ b/src/FeaturesPlugin/Test/TestPartition_MultiLevelCompound_v0_1.py @@ -78,7 +78,9 @@ Compound_1.result().subResult(0).subResult(1).setColor(0, 170, 0) Compound_1.result().subResult(1).subResult(0).setColor(0, 255, 0) Compound_1.result().subResult(1).subResult(1).setColor(0, 255, 0) Partition_1 = model.addPartition(Part_1_doc, [model.selection("SOLID", "LinearCopy_2_1_1_1"), model.selection("COMPOUND", "Compound_1_1_2")]) -model.do() + +model.testHaveNamingSubshapes(Partition_1, model, Part_1_doc) + model.end() from GeomAPI import GeomAPI_Shape @@ -90,3 +92,5 @@ model.testNbSubShapes(Partition_1, GeomAPI_Shape.FACE, [77]) model.testNbSubShapes(Partition_1, GeomAPI_Shape.EDGE, [328]) model.testNbSubShapes(Partition_1, GeomAPI_Shape.VERTEX, [656]) model.testResultsVolumes(Partition_1, [9335.251534206097858259454369545]) + +assert(model.checkPythonDump()) diff --git a/src/FeaturesPlugin/Test/TestPartition_MultiLevelCompound_v0_2.py b/src/FeaturesPlugin/Test/TestPartition_MultiLevelCompound_v0_2.py new file mode 100644 index 000000000..9c5654feb --- /dev/null +++ b/src/FeaturesPlugin/Test/TestPartition_MultiLevelCompound_v0_2.py @@ -0,0 +1,121 @@ +# 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() +Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY")) +SketchProjection_1 = Sketch_1.addProjection(model.selection("EDGE", "PartSet/OX"), False) +SketchLine_1 = SketchProjection_1.createdFeature() +SketchCircle_1 = Sketch_1.addCircle(0, 0, 10) +SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchAPI_Line(SketchLine_1).startPoint(), SketchCircle_1.center()) +SketchConstraintRadius_1 = Sketch_1.setRadius(SketchCircle_1.results()[1], 10) +SketchCircle_2 = Sketch_1.addCircle(10, 0, 10) +SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_1.result(), SketchCircle_2.center()) +SketchConstraintEqual_1 = Sketch_1.setEqual(SketchCircle_1.results()[1], SketchCircle_2.results()[1]) +SketchConstraintDistanceHorizontal_1 = Sketch_1.setHorizontalDistance(SketchAPI_Line(SketchLine_1).startPoint(), SketchCircle_2.center(), 10) +model.do() +Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("COMPOUND", "Sketch_1")], model.selection(), 20, 0) +Sketch_2 = model.addSketch(Part_1_doc, model.defaultPlane("XOY")) +SketchProjection_2 = Sketch_2.addProjection(model.selection("EDGE", "PartSet/OY"), False) +SketchLine_2 = SketchProjection_2.createdFeature() +SketchCircle_3 = Sketch_2.addCircle(0, -7, 10) +SketchConstraintCoincidence_3 = Sketch_2.setCoincident(SketchLine_2.result(), SketchCircle_3.center()) +SketchConstraintRadius_2 = Sketch_2.setRadius(SketchCircle_3.results()[1], 10) +SketchConstraintDistanceVertical_1 = Sketch_2.setVerticalDistance(SketchCircle_3.center(), SketchAPI_Line(SketchLine_2).startPoint(), 7) +SketchCircle_4 = Sketch_2.addCircle(40, -27, 10) +SketchConstraintEqual_2 = Sketch_2.setEqual(SketchCircle_4.results()[1], SketchCircle_3.results()[1]) +SketchConstraintDistanceHorizontal_2 = Sketch_2.setHorizontalDistance(SketchCircle_3.center(), SketchCircle_4.center(), 40) +SketchConstraintDistanceVertical_2 = Sketch_2.setVerticalDistance(SketchCircle_4.center(), SketchCircle_3.center(), 20) +model.do() +Extrusion_2 = model.addExtrusion(Part_1_doc, [model.selection("COMPOUND", "Sketch_2")], model.selection(), 20, 0) +Compound_1 = model.addCompound(Part_1_doc, [model.selection("SOLID", "Extrusion_2_1"), model.selection("SOLID", "Extrusion_2_2")]) +Compound_2 = model.addCompound(Part_1_doc, [model.selection("COMPOUND", "Compound_1_1"), model.selection("COMPSOLID", "Extrusion_1_1")]) +Compound_2.result().subResult(0).setColor(255, 170, 0) +Compound_2.result().subResult(0).subResult(0).setColor(255, 170, 0) +Compound_2.result().subResult(0).subResult(1).setColor(255, 170, 0) +Compound_2.result().subResult(1).setColor(0, 85, 255) +Compound_2.result().subResult(1).subResult(0).setColor(0, 85, 255) +Compound_2.result().subResult(1).subResult(1).setColor(0, 85, 255) +Compound_2.result().subResult(1).subResult(2).setColor(0, 85, 255) +Sketch_3 = model.addSketch(Part_1_doc, model.defaultPlane("YOZ")) +SketchLine_3 = Sketch_3.addLine(7, 0, -7, 0) +SketchLine_4 = Sketch_3.addLine(-7, 0, -7, 5) +SketchLine_5 = Sketch_3.addLine(-7, 5, 7, 5) +SketchLine_6 = Sketch_3.addLine(7, 5, 7, 0) +SketchConstraintCoincidence_4 = Sketch_3.setCoincident(SketchLine_6.endPoint(), SketchLine_3.startPoint()) +SketchConstraintCoincidence_5 = Sketch_3.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint()) +SketchConstraintCoincidence_6 = Sketch_3.setCoincident(SketchLine_4.endPoint(), SketchLine_5.startPoint()) +SketchConstraintCoincidence_7 = Sketch_3.setCoincident(SketchLine_5.endPoint(), SketchLine_6.startPoint()) +SketchConstraintHorizontal_1 = Sketch_3.setHorizontal(SketchLine_3.result()) +SketchConstraintVertical_1 = Sketch_3.setVertical(SketchLine_4.result()) +SketchConstraintHorizontal_2 = Sketch_3.setHorizontal(SketchLine_5.result()) +SketchConstraintVertical_2 = Sketch_3.setVertical(SketchLine_6.result()) +SketchProjection_3 = Sketch_3.addProjection(model.selection("EDGE", "PartSet/OZ"), False) +SketchLine_7 = SketchProjection_3.createdFeature() +SketchConstraintDistance_1 = Sketch_3.setDistance(SketchLine_5.endPoint(), SketchLine_7.result(), 7, True) +SketchConstraintMiddle_1 = Sketch_3.setMiddlePoint(SketchAPI_Line(SketchLine_7).startPoint(), SketchLine_3.result()) +SketchConstraintLength_1 = Sketch_3.setLength(SketchLine_4.result(), 5) +SketchLine_8 = Sketch_3.addLine(7, 7, -7, 7) +SketchLine_9 = Sketch_3.addLine(-7, 7, -7, 10) +SketchLine_10 = Sketch_3.addLine(-7, 10, 7, 10) +SketchLine_11 = Sketch_3.addLine(7, 10, 7, 7) +SketchConstraintCoincidence_8 = Sketch_3.setCoincident(SketchLine_11.endPoint(), SketchLine_8.startPoint()) +SketchConstraintCoincidence_9 = Sketch_3.setCoincident(SketchLine_8.endPoint(), SketchLine_9.startPoint()) +SketchConstraintCoincidence_10 = Sketch_3.setCoincident(SketchLine_9.endPoint(), SketchLine_10.startPoint()) +SketchConstraintCoincidence_11 = Sketch_3.setCoincident(SketchLine_10.endPoint(), SketchLine_11.startPoint()) +SketchConstraintHorizontal_3 = Sketch_3.setHorizontal(SketchLine_8.result()) +SketchConstraintVertical_3 = Sketch_3.setVertical(SketchLine_9.result()) +SketchConstraintHorizontal_4 = Sketch_3.setHorizontal(SketchLine_10.result()) +SketchConstraintVertical_4 = Sketch_3.setVertical(SketchLine_11.result()) +SketchConstraintCoincidence_12 = Sketch_3.setCoincident(SketchLine_9.startPoint(), SketchLine_4.result()) +SketchConstraintCoincidence_13 = Sketch_3.setCoincident(SketchLine_8.startPoint(), SketchLine_6.result()) +SketchConstraintLength_2 = Sketch_3.setLength(SketchLine_9.result(), 3) +SketchConstraintDistance_2 = Sketch_3.setDistance(SketchLine_9.startPoint(), SketchLine_5.result(), 2, True) +model.do() +Extrusion_3 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_3/Face-SketchLine_6r-SketchLine_5r-SketchLine_4r-SketchLine_3r")], model.selection(), 50, -10) +Extrusion_4 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_3/Face-SketchLine_11r-SketchLine_10r-SketchLine_9r-SketchLine_8r")], model.selection(), 60, 20) +AngularCopy_1 = model.addMultiRotation(Part_1_doc, [model.selection("SOLID", "Extrusion_4_1")], model.selection("EDGE", "PartSet/OZ"), 90, 2) +Compound_3 = model.addCompound(Part_1_doc, [model.selection("SOLID", "Extrusion_3_1"), model.selection("COMPOUND", "AngularCopy_1_1")]) +Compound_3.result().subResult(0).setColor(0, 170, 0) +Compound_3.result().subResult(1).setColor(0, 255, 0) +Compound_3.result().subResult(1).subResult(0).setColor(0, 255, 0) +Compound_3.result().subResult(1).subResult(1).setColor(0, 255, 0) +Partition_1 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Compound_2_1_1_1"), model.selection("SOLID", "Compound_2_1_2_3"), model.selection("COMPOUND", "Compound_3_1_2")]) + +model.testHaveNamingSubshapes(Partition_1, model, Part_1_doc) + +model.end() + +from GeomAPI import GeomAPI_Shape + +model.testNbResults(Partition_1, 1) +model.testNbSubResults(Partition_1, [24]) +model.testNbSubShapes(Partition_1, GeomAPI_Shape.SOLID, [24]) +model.testNbSubShapes(Partition_1, GeomAPI_Shape.FACE, [208]) +model.testNbSubShapes(Partition_1, GeomAPI_Shape.EDGE, [938]) +model.testNbSubShapes(Partition_1, GeomAPI_Shape.VERTEX, [1876]) +model.testResultsVolumes(Partition_1, [17001.414867225816]) + +assert(model.checkPythonDump()) diff --git a/src/FeaturesPlugin/Test/TestPartition_MultiLevelCompound_v0_3.py b/src/FeaturesPlugin/Test/TestPartition_MultiLevelCompound_v0_3.py new file mode 100644 index 000000000..f562091d0 --- /dev/null +++ b/src/FeaturesPlugin/Test/TestPartition_MultiLevelCompound_v0_3.py @@ -0,0 +1,112 @@ +# 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 GeomAPI import GeomAPI_Shape +from SketchAPI import * + +from salome.shaper import model + +model.begin() +partSet = model.moduleDocument() +Part_1 = model.addPart(partSet) +Part_1_doc = Part_1.document() +Cylinder_1 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), 10, 20) +LinearCopy_1 = model.addMultiTranslation(Part_1_doc, [model.selection("SOLID", "Cylinder_1_1")], model.selection("EDGE", "PartSet/OX"), 40, 2) +LinearCopy_2 = model.addMultiTranslation(Part_1_doc, [model.selection("COMPOUND", "LinearCopy_1_1")], model.selection("EDGE", "PartSet/OY"), 40, 2) +LinearCopy_2.result().subResult(0).subResult(0).setColor(255, 170, 0) +LinearCopy_2.result().subResult(0).subResult(1).setColor(255, 170, 0) +LinearCopy_2.result().subResult(1).subResult(0).setColor(0, 0, 255) +LinearCopy_2.result().subResult(1).subResult(1).setColor(0, 0, 255) +Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("YOZ")) +SketchLine_1 = Sketch_1.addLine(7, 0, -7, 0) +SketchLine_2 = Sketch_1.addLine(-7, 0, -7, 5) +SketchLine_3 = Sketch_1.addLine(-7, 5, 7, 5) +SketchLine_4 = Sketch_1.addLine(7, 5, 7, 0) +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("EDGE", "PartSet/OZ"), False) +SketchLine_5 = SketchProjection_1.createdFeature() +SketchConstraintDistance_1 = Sketch_1.setDistance(SketchLine_3.endPoint(), SketchLine_5.result(), 7, True) +SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchAPI_Line(SketchLine_5).startPoint(), SketchLine_1.result()) +SketchConstraintLength_1 = Sketch_1.setLength(SketchLine_1.result(), 14) +SketchConstraintLength_2 = Sketch_1.setLength(SketchLine_2.result(), 5) +SketchLine_6 = Sketch_1.addLine(5, 12, -5, 12) +SketchLine_7 = Sketch_1.addLine(-5, 12, -5, 15) +SketchLine_8 = Sketch_1.addLine(-5, 15, 5, 15) +SketchLine_9 = Sketch_1.addLine(5, 15, 5, 12) +SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchLine_9.endPoint(), SketchLine_6.startPoint()) +SketchConstraintCoincidence_7 = Sketch_1.setCoincident(SketchLine_6.endPoint(), SketchLine_7.startPoint()) +SketchConstraintCoincidence_8 = Sketch_1.setCoincident(SketchLine_7.endPoint(), SketchLine_8.startPoint()) +SketchConstraintCoincidence_9 = Sketch_1.setCoincident(SketchLine_8.endPoint(), SketchLine_9.startPoint()) +SketchConstraintHorizontal_3 = Sketch_1.setHorizontal(SketchLine_6.result()) +SketchConstraintVertical_3 = Sketch_1.setVertical(SketchLine_7.result()) +SketchConstraintHorizontal_4 = Sketch_1.setHorizontal(SketchLine_8.result()) +SketchConstraintVertical_4 = Sketch_1.setVertical(SketchLine_9.result()) +SketchConstraintLength_3 = Sketch_1.setLength(SketchLine_7.result(), 3) +SketchConstraintLength_4 = Sketch_1.setLength(SketchLine_8.result(), 10) +SketchConstraintDistance_2 = Sketch_1.setDistance(SketchLine_8.endPoint(), SketchLine_5.result(), 5, True) +SketchConstraintDistance_3 = Sketch_1.setDistance(SketchLine_6.startPoint(), SketchLine_3.result(), 7, True) +model.do() +Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_4r-SketchLine_3r-SketchLine_2r-SketchLine_1r")], model.selection(), 60, 20) +Extrusion_2 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_9r-SketchLine_8r-SketchLine_7r-SketchLine_6r")], model.selection(), 55, 15) +LinearCopy_3 = model.addMultiTranslation(Part_1_doc, [model.selection("SOLID", "Extrusion_1_1")], model.selection("EDGE", "PartSet/OY"), 40, 2) +AngularCopy_1 = model.addMultiRotation(Part_1_doc, [model.selection("SOLID", "Extrusion_2_1")], model.selection("EDGE", "PartSet/OZ"), 90, 2) +Compound_1 = model.addCompound(Part_1_doc, [model.selection("COMPOUND", "LinearCopy_3_1"), model.selection("COMPOUND", "AngularCopy_1_1")]) +Compound_1.result().subResult(0).subResult(0).setColor(0, 170, 0) +Compound_1.result().subResult(0).subResult(1).setColor(0, 170, 0) +Compound_1.result().subResult(1).subResult(0).setColor(0, 255, 0) +Compound_1.result().subResult(1).subResult(1).setColor(0, 255, 0) +Partition_1_objects = [model.selection("SOLID", "LinearCopy_2_1_1_1"), model.selection("SOLID", "Compound_1_1_2_2"), model.selection("SOLID", "LinearCopy_2_1_2_2"), model.selection("SOLID", "Compound_1_1_1_2")] +Partition_1 = model.addPartition(Part_1_doc, Partition_1_objects) +model.do() + +model.testNbResults(Partition_1, 2) +model.testNbSubResults(Partition_1, [4, 4]) +model.testNbSubShapes(Partition_1, GeomAPI_Shape.SOLID, [4, 4]) +model.testNbSubShapes(Partition_1, GeomAPI_Shape.FACE, [25, 27]) +model.testNbSubShapes(Partition_1, GeomAPI_Shape.EDGE, [102, 114]) +model.testNbSubShapes(Partition_1, GeomAPI_Shape.VERTEX, [204, 228]) +model.testResultsVolumes(Partition_1, [7809.218420698664886, 10607.88782061204438]) + +# change Partition objects +Partition_1_objects = [model.selection("SOLID", "LinearCopy_2_1_1_1"), model.selection("SOLID", "Compound_1_1_2_2"), model.selection("SOLID", "LinearCopy_2_1_2_2")] +Partition_1.setBase(Partition_1_objects) +model.do() + +model.testHaveNamingSubshapes(Partition_1, model, Part_1_doc) + +model.end() + +from GeomAPI import GeomAPI_Shape + +model.testNbResults(Partition_1, 2) +model.testNbSubResults(Partition_1, [4, 0]) +model.testNbSubShapes(Partition_1, GeomAPI_Shape.SOLID, [4, 1]) +model.testNbSubShapes(Partition_1, GeomAPI_Shape.FACE, [25, 3]) +model.testNbSubShapes(Partition_1, GeomAPI_Shape.EDGE, [102, 6]) +model.testNbSubShapes(Partition_1, GeomAPI_Shape.VERTEX, [204, 12]) +model.testResultsVolumes(Partition_1, [7809.218420698664886, 6283.185307179586744]) + +assert(model.checkPythonDump()) diff --git a/src/FeaturesPlugin/Test/TestPartition_MultiLevelCompound_v20190506_1.py b/src/FeaturesPlugin/Test/TestPartition_MultiLevelCompound_v20190506_1.py new file mode 100644 index 000000000..de14905ba --- /dev/null +++ b/src/FeaturesPlugin/Test/TestPartition_MultiLevelCompound_v20190506_1.py @@ -0,0 +1,96 @@ +# 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() +Cylinder_1 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), 10, 20) +LinearCopy_1 = model.addMultiTranslation(Part_1_doc, [model.selection("SOLID", "Cylinder_1_1")], model.selection("EDGE", "PartSet/OX"), 40, 2) +LinearCopy_2 = model.addMultiTranslation(Part_1_doc, [model.selection("COMPOUND", "LinearCopy_1_1")], model.selection("EDGE", "PartSet/OY"), 40, 2) +LinearCopy_2.result().subResult(0).subResult(0).setColor(255, 170, 0) +LinearCopy_2.result().subResult(0).subResult(1).setColor(255, 170, 0) +LinearCopy_2.result().subResult(1).subResult(0).setColor(0, 0, 255) +LinearCopy_2.result().subResult(1).subResult(1).setColor(0, 0, 255) +Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("YOZ")) +SketchLine_1 = Sketch_1.addLine(7, 0, -7, 0) +SketchLine_2 = Sketch_1.addLine(-7, 0, -7, 5) +SketchLine_3 = Sketch_1.addLine(-7, 5, 7, 5) +SketchLine_4 = Sketch_1.addLine(7, 5, 7, 0) +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("EDGE", "PartSet/OZ"), False) +SketchLine_5 = SketchProjection_1.createdFeature() +SketchConstraintDistance_1 = Sketch_1.setDistance(SketchLine_3.endPoint(), SketchLine_5.result(), 7, True) +SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchAPI_Line(SketchLine_5).startPoint(), SketchLine_1.result()) +SketchConstraintLength_1 = Sketch_1.setLength(SketchLine_1.result(), 14) +SketchConstraintLength_2 = Sketch_1.setLength(SketchLine_2.result(), 5) +SketchLine_6 = Sketch_1.addLine(5, 12, -5, 12) +SketchLine_7 = Sketch_1.addLine(-5, 12, -5, 15) +SketchLine_8 = Sketch_1.addLine(-5, 15, 5, 15) +SketchLine_9 = Sketch_1.addLine(5, 15, 5, 12) +SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchLine_9.endPoint(), SketchLine_6.startPoint()) +SketchConstraintCoincidence_7 = Sketch_1.setCoincident(SketchLine_6.endPoint(), SketchLine_7.startPoint()) +SketchConstraintCoincidence_8 = Sketch_1.setCoincident(SketchLine_7.endPoint(), SketchLine_8.startPoint()) +SketchConstraintCoincidence_9 = Sketch_1.setCoincident(SketchLine_8.endPoint(), SketchLine_9.startPoint()) +SketchConstraintHorizontal_3 = Sketch_1.setHorizontal(SketchLine_6.result()) +SketchConstraintVertical_3 = Sketch_1.setVertical(SketchLine_7.result()) +SketchConstraintHorizontal_4 = Sketch_1.setHorizontal(SketchLine_8.result()) +SketchConstraintVertical_4 = Sketch_1.setVertical(SketchLine_9.result()) +SketchConstraintLength_3 = Sketch_1.setLength(SketchLine_7.result(), 3) +SketchConstraintLength_4 = Sketch_1.setLength(SketchLine_8.result(), 10) +SketchConstraintDistance_2 = Sketch_1.setDistance(SketchLine_8.endPoint(), SketchLine_5.result(), 5, True) +SketchConstraintDistance_3 = Sketch_1.setDistance(SketchLine_6.startPoint(), SketchLine_3.result(), 7, True) +model.do() +Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_4r-SketchLine_3r-SketchLine_2r-SketchLine_1r")], model.selection(), 60, 20) +Extrusion_2 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_9r-SketchLine_8r-SketchLine_7r-SketchLine_6r")], model.selection(), 55, 15) +LinearCopy_3 = model.addMultiTranslation(Part_1_doc, [model.selection("SOLID", "Extrusion_1_1")], model.selection("EDGE", "PartSet/OY"), 40, 2) +AngularCopy_1 = model.addMultiRotation(Part_1_doc, [model.selection("SOLID", "Extrusion_2_1")], model.selection("EDGE", "PartSet/OZ"), 90, 2) +Compound_1 = model.addCompound(Part_1_doc, [model.selection("COMPOUND", "LinearCopy_3_1"), model.selection("COMPOUND", "AngularCopy_1_1")]) +Compound_1.result().subResult(0).subResult(0).setColor(0, 170, 0) +Compound_1.result().subResult(0).subResult(1).setColor(0, 170, 0) +Compound_1.result().subResult(1).subResult(0).setColor(0, 255, 0) +Compound_1.result().subResult(1).subResult(1).setColor(0, 255, 0) +Partition_1 = model.addPartition(Part_1_doc, [model.selection("SOLID", "LinearCopy_2_1_1_1"), model.selection("COMPOUND", "Compound_1_1_2")], 20190506) + +model.testHaveNamingSubshapes(Partition_1, model, Part_1_doc) + +model.end() + +from GeomAPI import GeomAPI_Shape + +model.testNbResults(Partition_1, 1) +model.testNbSubResults(Partition_1, [4]) +model.testNbSubShapes(Partition_1, GeomAPI_Shape.SOLID, [15]) +model.testNbSubShapes(Partition_1, GeomAPI_Shape.FACE, [98]) +model.testNbSubShapes(Partition_1, GeomAPI_Shape.EDGE, [394]) +model.testNbSubShapes(Partition_1, GeomAPI_Shape.VERTEX, [788]) +model.testResultsVolumes(Partition_1, [39384.807455744848994]) + +assert(model.checkPythonDump()) diff --git a/src/FeaturesPlugin/Test/TestPartition_MultiLevelCompound_v20190506_2.py b/src/FeaturesPlugin/Test/TestPartition_MultiLevelCompound_v20190506_2.py new file mode 100644 index 000000000..26e0f567b --- /dev/null +++ b/src/FeaturesPlugin/Test/TestPartition_MultiLevelCompound_v20190506_2.py @@ -0,0 +1,121 @@ +# 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() +Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY")) +SketchProjection_1 = Sketch_1.addProjection(model.selection("EDGE", "PartSet/OX"), False) +SketchLine_1 = SketchProjection_1.createdFeature() +SketchCircle_1 = Sketch_1.addCircle(0, 0, 10) +SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchAPI_Line(SketchLine_1).startPoint(), SketchCircle_1.center()) +SketchConstraintRadius_1 = Sketch_1.setRadius(SketchCircle_1.results()[1], 10) +SketchCircle_2 = Sketch_1.addCircle(10, 0, 10) +SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_1.result(), SketchCircle_2.center()) +SketchConstraintEqual_1 = Sketch_1.setEqual(SketchCircle_1.results()[1], SketchCircle_2.results()[1]) +SketchConstraintDistanceHorizontal_1 = Sketch_1.setHorizontalDistance(SketchAPI_Line(SketchLine_1).startPoint(), SketchCircle_2.center(), 10) +model.do() +Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("COMPOUND", "Sketch_1")], model.selection(), 20, 0) +Sketch_2 = model.addSketch(Part_1_doc, model.defaultPlane("XOY")) +SketchProjection_2 = Sketch_2.addProjection(model.selection("EDGE", "PartSet/OY"), False) +SketchLine_2 = SketchProjection_2.createdFeature() +SketchCircle_3 = Sketch_2.addCircle(0, -7, 10) +SketchConstraintCoincidence_3 = Sketch_2.setCoincident(SketchLine_2.result(), SketchCircle_3.center()) +SketchConstraintRadius_2 = Sketch_2.setRadius(SketchCircle_3.results()[1], 10) +SketchConstraintDistanceVertical_1 = Sketch_2.setVerticalDistance(SketchCircle_3.center(), SketchAPI_Line(SketchLine_2).startPoint(), 7) +SketchCircle_4 = Sketch_2.addCircle(40, -27, 10) +SketchConstraintEqual_2 = Sketch_2.setEqual(SketchCircle_4.results()[1], SketchCircle_3.results()[1]) +SketchConstraintDistanceHorizontal_2 = Sketch_2.setHorizontalDistance(SketchCircle_3.center(), SketchCircle_4.center(), 40) +SketchConstraintDistanceVertical_2 = Sketch_2.setVerticalDistance(SketchCircle_4.center(), SketchCircle_3.center(), 20) +model.do() +Extrusion_2 = model.addExtrusion(Part_1_doc, [model.selection("COMPOUND", "Sketch_2")], model.selection(), 20, 0) +Compound_1 = model.addCompound(Part_1_doc, [model.selection("SOLID", "Extrusion_2_1"), model.selection("SOLID", "Extrusion_2_2")]) +Compound_2 = model.addCompound(Part_1_doc, [model.selection("COMPOUND", "Compound_1_1"), model.selection("COMPSOLID", "Extrusion_1_1")]) +Compound_2.result().subResult(0).setColor(255, 170, 0) +Compound_2.result().subResult(0).subResult(0).setColor(255, 170, 0) +Compound_2.result().subResult(0).subResult(1).setColor(255, 170, 0) +Compound_2.result().subResult(1).setColor(0, 85, 255) +Compound_2.result().subResult(1).subResult(0).setColor(0, 85, 255) +Compound_2.result().subResult(1).subResult(1).setColor(0, 85, 255) +Compound_2.result().subResult(1).subResult(2).setColor(0, 85, 255) +Sketch_3 = model.addSketch(Part_1_doc, model.defaultPlane("YOZ")) +SketchLine_3 = Sketch_3.addLine(7, 0, -7, 0) +SketchLine_4 = Sketch_3.addLine(-7, 0, -7, 5) +SketchLine_5 = Sketch_3.addLine(-7, 5, 7, 5) +SketchLine_6 = Sketch_3.addLine(7, 5, 7, 0) +SketchConstraintCoincidence_4 = Sketch_3.setCoincident(SketchLine_6.endPoint(), SketchLine_3.startPoint()) +SketchConstraintCoincidence_5 = Sketch_3.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint()) +SketchConstraintCoincidence_6 = Sketch_3.setCoincident(SketchLine_4.endPoint(), SketchLine_5.startPoint()) +SketchConstraintCoincidence_7 = Sketch_3.setCoincident(SketchLine_5.endPoint(), SketchLine_6.startPoint()) +SketchConstraintHorizontal_1 = Sketch_3.setHorizontal(SketchLine_3.result()) +SketchConstraintVertical_1 = Sketch_3.setVertical(SketchLine_4.result()) +SketchConstraintHorizontal_2 = Sketch_3.setHorizontal(SketchLine_5.result()) +SketchConstraintVertical_2 = Sketch_3.setVertical(SketchLine_6.result()) +SketchProjection_3 = Sketch_3.addProjection(model.selection("EDGE", "PartSet/OZ"), False) +SketchLine_7 = SketchProjection_3.createdFeature() +SketchConstraintDistance_1 = Sketch_3.setDistance(SketchLine_5.endPoint(), SketchLine_7.result(), 7, True) +SketchConstraintMiddle_1 = Sketch_3.setMiddlePoint(SketchAPI_Line(SketchLine_7).startPoint(), SketchLine_3.result()) +SketchConstraintLength_1 = Sketch_3.setLength(SketchLine_4.result(), 5) +SketchLine_8 = Sketch_3.addLine(7, 7, -7, 7) +SketchLine_9 = Sketch_3.addLine(-7, 7, -7, 10) +SketchLine_10 = Sketch_3.addLine(-7, 10, 7, 10) +SketchLine_11 = Sketch_3.addLine(7, 10, 7, 7) +SketchConstraintCoincidence_8 = Sketch_3.setCoincident(SketchLine_11.endPoint(), SketchLine_8.startPoint()) +SketchConstraintCoincidence_9 = Sketch_3.setCoincident(SketchLine_8.endPoint(), SketchLine_9.startPoint()) +SketchConstraintCoincidence_10 = Sketch_3.setCoincident(SketchLine_9.endPoint(), SketchLine_10.startPoint()) +SketchConstraintCoincidence_11 = Sketch_3.setCoincident(SketchLine_10.endPoint(), SketchLine_11.startPoint()) +SketchConstraintHorizontal_3 = Sketch_3.setHorizontal(SketchLine_8.result()) +SketchConstraintVertical_3 = Sketch_3.setVertical(SketchLine_9.result()) +SketchConstraintHorizontal_4 = Sketch_3.setHorizontal(SketchLine_10.result()) +SketchConstraintVertical_4 = Sketch_3.setVertical(SketchLine_11.result()) +SketchConstraintCoincidence_12 = Sketch_3.setCoincident(SketchLine_9.startPoint(), SketchLine_4.result()) +SketchConstraintCoincidence_13 = Sketch_3.setCoincident(SketchLine_8.startPoint(), SketchLine_6.result()) +SketchConstraintLength_2 = Sketch_3.setLength(SketchLine_9.result(), 3) +SketchConstraintDistance_2 = Sketch_3.setDistance(SketchLine_9.startPoint(), SketchLine_5.result(), 2, True) +model.do() +Extrusion_3 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_3/Face-SketchLine_6r-SketchLine_5r-SketchLine_4r-SketchLine_3r")], model.selection(), 50, -10) +Extrusion_4 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_3/Face-SketchLine_11r-SketchLine_10r-SketchLine_9r-SketchLine_8r")], model.selection(), 60, 20) +AngularCopy_1 = model.addMultiRotation(Part_1_doc, [model.selection("SOLID", "Extrusion_4_1")], model.selection("EDGE", "PartSet/OZ"), 90, 2) +Compound_3 = model.addCompound(Part_1_doc, [model.selection("SOLID", "Extrusion_3_1"), model.selection("COMPOUND", "AngularCopy_1_1")]) +Compound_3.result().subResult(0).setColor(0, 170, 0) +Compound_3.result().subResult(1).setColor(0, 255, 0) +Compound_3.result().subResult(1).subResult(0).setColor(0, 255, 0) +Compound_3.result().subResult(1).subResult(1).setColor(0, 255, 0) +Partition_1 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Compound_2_1_1_1"), model.selection("SOLID", "Compound_2_1_2_3"), model.selection("COMPOUND", "Compound_3_1_2")], 20190506) + +model.testHaveNamingSubshapes(Partition_1, model, Part_1_doc) + +model.end() + +from GeomAPI import GeomAPI_Shape + +model.testNbResults(Partition_1, 1) +model.testNbSubResults(Partition_1, [3]) +model.testNbSubShapes(Partition_1, GeomAPI_Shape.SOLID, [26]) +model.testNbSubShapes(Partition_1, GeomAPI_Shape.FACE, [217]) +model.testNbSubShapes(Partition_1, GeomAPI_Shape.EDGE, [968]) +model.testNbSubShapes(Partition_1, GeomAPI_Shape.VERTEX, [1936]) +model.testResultsVolumes(Partition_1, [26084.60017440541]) + +assert(model.checkPythonDump()) diff --git a/src/FeaturesPlugin/Test/TestPartition_MultiLevelCompound_v20190506_3.py b/src/FeaturesPlugin/Test/TestPartition_MultiLevelCompound_v20190506_3.py new file mode 100644 index 000000000..0007bd6bb --- /dev/null +++ b/src/FeaturesPlugin/Test/TestPartition_MultiLevelCompound_v20190506_3.py @@ -0,0 +1,110 @@ +# 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 GeomAPI import GeomAPI_Shape +from SketchAPI import * + +from salome.shaper import model + +model.begin() +partSet = model.moduleDocument() +Part_1 = model.addPart(partSet) +Part_1_doc = Part_1.document() +Cylinder_1 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), 10, 20) +LinearCopy_1 = model.addMultiTranslation(Part_1_doc, [model.selection("SOLID", "Cylinder_1_1")], model.selection("EDGE", "PartSet/OX"), 40, 2) +LinearCopy_2 = model.addMultiTranslation(Part_1_doc, [model.selection("COMPOUND", "LinearCopy_1_1")], model.selection("EDGE", "PartSet/OY"), 40, 2) +LinearCopy_2.result().subResult(0).subResult(0).setColor(255, 170, 0) +LinearCopy_2.result().subResult(0).subResult(1).setColor(255, 170, 0) +LinearCopy_2.result().subResult(1).subResult(0).setColor(0, 0, 255) +LinearCopy_2.result().subResult(1).subResult(1).setColor(0, 0, 255) +Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("YOZ")) +SketchLine_1 = Sketch_1.addLine(7, 0, -7, 0) +SketchLine_2 = Sketch_1.addLine(-7, 0, -7, 5) +SketchLine_3 = Sketch_1.addLine(-7, 5, 7, 5) +SketchLine_4 = Sketch_1.addLine(7, 5, 7, 0) +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("EDGE", "PartSet/OZ"), False) +SketchLine_5 = SketchProjection_1.createdFeature() +SketchConstraintDistance_1 = Sketch_1.setDistance(SketchLine_3.endPoint(), SketchLine_5.result(), 7, True) +SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchAPI_Line(SketchLine_5).startPoint(), SketchLine_1.result()) +SketchConstraintLength_1 = Sketch_1.setLength(SketchLine_1.result(), 14) +SketchConstraintLength_2 = Sketch_1.setLength(SketchLine_2.result(), 5) +SketchLine_6 = Sketch_1.addLine(5, 12, -5, 12) +SketchLine_7 = Sketch_1.addLine(-5, 12, -5, 15) +SketchLine_8 = Sketch_1.addLine(-5, 15, 5, 15) +SketchLine_9 = Sketch_1.addLine(5, 15, 5, 12) +SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchLine_9.endPoint(), SketchLine_6.startPoint()) +SketchConstraintCoincidence_7 = Sketch_1.setCoincident(SketchLine_6.endPoint(), SketchLine_7.startPoint()) +SketchConstraintCoincidence_8 = Sketch_1.setCoincident(SketchLine_7.endPoint(), SketchLine_8.startPoint()) +SketchConstraintCoincidence_9 = Sketch_1.setCoincident(SketchLine_8.endPoint(), SketchLine_9.startPoint()) +SketchConstraintHorizontal_3 = Sketch_1.setHorizontal(SketchLine_6.result()) +SketchConstraintVertical_3 = Sketch_1.setVertical(SketchLine_7.result()) +SketchConstraintHorizontal_4 = Sketch_1.setHorizontal(SketchLine_8.result()) +SketchConstraintVertical_4 = Sketch_1.setVertical(SketchLine_9.result()) +SketchConstraintLength_3 = Sketch_1.setLength(SketchLine_7.result(), 3) +SketchConstraintLength_4 = Sketch_1.setLength(SketchLine_8.result(), 10) +SketchConstraintDistance_2 = Sketch_1.setDistance(SketchLine_8.endPoint(), SketchLine_5.result(), 5, True) +SketchConstraintDistance_3 = Sketch_1.setDistance(SketchLine_6.startPoint(), SketchLine_3.result(), 7, True) +model.do() +Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_4r-SketchLine_3r-SketchLine_2r-SketchLine_1r")], model.selection(), 60, 20) +Extrusion_2 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_9r-SketchLine_8r-SketchLine_7r-SketchLine_6r")], model.selection(), 55, 15) +LinearCopy_3 = model.addMultiTranslation(Part_1_doc, [model.selection("SOLID", "Extrusion_1_1")], model.selection("EDGE", "PartSet/OY"), 40, 2) +AngularCopy_1 = model.addMultiRotation(Part_1_doc, [model.selection("SOLID", "Extrusion_2_1")], model.selection("EDGE", "PartSet/OZ"), 90, 2) +Compound_1 = model.addCompound(Part_1_doc, [model.selection("COMPOUND", "LinearCopy_3_1"), model.selection("COMPOUND", "AngularCopy_1_1")]) +Compound_1.result().subResult(0).subResult(0).setColor(0, 170, 0) +Compound_1.result().subResult(0).subResult(1).setColor(0, 170, 0) +Compound_1.result().subResult(1).subResult(0).setColor(0, 255, 0) +Compound_1.result().subResult(1).subResult(1).setColor(0, 255, 0) +Partition_1_objects = [model.selection("SOLID", "LinearCopy_2_1_1_1"), model.selection("SOLID", "Compound_1_1_2_2"), model.selection("SOLID", "LinearCopy_2_1_2_2"), model.selection("SOLID", "Compound_1_1_1_2")] +Partition_1 = model.addPartition(Part_1_doc, Partition_1_objects, 20190506) +model.do() + +model.testNbResults(Partition_1, 1) +model.testNbSubResults(Partition_1, [6]) +model.testNbSubShapes(Partition_1, GeomAPI_Shape.SOLID, [12]) +model.testNbSubShapes(Partition_1, GeomAPI_Shape.FACE, [70]) +model.testNbSubShapes(Partition_1, GeomAPI_Shape.EDGE, [276]) +model.testNbSubShapes(Partition_1, GeomAPI_Shape.VERTEX, [552]) +model.testResultsVolumes(Partition_1, [38683.4768556698836619]) + +# change Partition objects +Partition_1_objects = [model.selection("SOLID", "LinearCopy_2_1_1_1"), model.selection("SOLID", "Compound_1_1_2_2"), model.selection("SOLID", "LinearCopy_2_1_2_2")] +Partition_1.setBase(Partition_1_objects) +model.do() + +model.testHaveNamingSubshapes(Partition_1, model, Part_1_doc) + +model.end() + +model.testNbResults(Partition_1, 1) +model.testNbSubResults(Partition_1, [6]) +model.testNbSubShapes(Partition_1, GeomAPI_Shape.SOLID, [10]) +model.testNbSubShapes(Partition_1, GeomAPI_Shape.FACE, [52]) +model.testNbSubShapes(Partition_1, GeomAPI_Shape.EDGE, [192]) +model.testNbSubShapes(Partition_1, GeomAPI_Shape.VERTEX, [384]) +model.testResultsVolumes(Partition_1, [39958.774342237426]) + +assert(model.checkPythonDump()) -- 2.39.2