From 0ab5992d85bc182d575cc066e6ae27ab6ae31e22 Mon Sep 17 00:00:00 2001 From: azv Date: Fri, 15 Nov 2019 14:09:31 +0300 Subject: [PATCH] Task 5.1.7: To be able to export a part to a file and import it into an existing part (issue #3065) Set unique name for imported feature/result. --- src/ExchangePlugin/CMakeLists.txt | 9 ++ .../ExchangePlugin_ExportPart.cpp | 30 ++-- .../ExchangePlugin_ImportPart.cpp | 127 +++++++++++++++- .../Test/TestImportPart_AfterCurrent_1.py | 113 ++++++++++++++ .../Test/TestImportPart_AfterCurrent_2.py | 112 ++++++++++++++ .../Test/TestImportPart_AfterLast_1.py | 137 +++++++++++++++++ .../Test/TestImportPart_AfterLast_2.py | 142 ++++++++++++++++++ .../Test/TestImportPart_AfterLast_3.py | 138 +++++++++++++++++ .../Test/TestImportPart_AfterLast_4.py | 138 +++++++++++++++++ .../Test/TestImportPart_AfterLast_5.py | 137 +++++++++++++++++ .../Test/TestImportPart_AfterLast_6.py | 138 +++++++++++++++++ .../Test/TestImportPart_Multiple.py | 115 ++++++++++++++ src/Model/Model_Document.cpp | 5 +- src/Model/Model_Document.h | 5 +- src/ModelAPI/ModelAPI_Document.h | 5 +- 15 files changed, 1335 insertions(+), 16 deletions(-) create mode 100644 src/ExchangePlugin/Test/TestImportPart_AfterCurrent_1.py create mode 100644 src/ExchangePlugin/Test/TestImportPart_AfterCurrent_2.py create mode 100644 src/ExchangePlugin/Test/TestImportPart_AfterLast_1.py create mode 100644 src/ExchangePlugin/Test/TestImportPart_AfterLast_2.py create mode 100644 src/ExchangePlugin/Test/TestImportPart_AfterLast_3.py create mode 100644 src/ExchangePlugin/Test/TestImportPart_AfterLast_4.py create mode 100644 src/ExchangePlugin/Test/TestImportPart_AfterLast_5.py create mode 100644 src/ExchangePlugin/Test/TestImportPart_AfterLast_6.py create mode 100644 src/ExchangePlugin/Test/TestImportPart_Multiple.py diff --git a/src/ExchangePlugin/CMakeLists.txt b/src/ExchangePlugin/CMakeLists.txt index d52a44858..f18a44110 100644 --- a/src/ExchangePlugin/CMakeLists.txt +++ b/src/ExchangePlugin/CMakeLists.txt @@ -107,10 +107,19 @@ ADD_UNIT_TESTS( TestExportPart_Results_6.py TestExportPart_Results_7.py TestExportPart_Results_8.py + TestImportPart_AfterCurrent_1.py + TestImportPart_AfterCurrent_2.py + TestImportPart_AfterLast_1.py + TestImportPart_AfterLast_2.py + TestImportPart_AfterLast_3.py + TestImportPart_AfterLast_4.py + TestImportPart_AfterLast_5.py + TestImportPart_AfterLast_6.py TestImportPart_Construction_1.py TestImportPart_Construction_2.py TestImportPart_Construction_3.py TestImportPart_Construction_4.py + TestImportPart_Multiple.py TestImportPart_ToEmptyPart.py TestImportPart_ToEmptyPartSet.py ) diff --git a/src/ExchangePlugin/ExchangePlugin_ExportPart.cpp b/src/ExchangePlugin/ExchangePlugin_ExportPart.cpp index cc4af14c6..2957ce721 100644 --- a/src/ExchangePlugin/ExchangePlugin_ExportPart.cpp +++ b/src/ExchangePlugin/ExchangePlugin_ExportPart.cpp @@ -142,6 +142,14 @@ void ExchangePlugin_ExportPart::execute() // ================================ Auxiliary functions =================================== +static bool isCoordinate(FeaturePtr theFeature) +{ + return !theFeature->isInHistory() && + (theFeature->getKind() == ConstructionPlugin_Point::ID() || + theFeature->getKind() == ConstructionPlugin_Axis::ID() || + theFeature->getKind() == ConstructionPlugin_Plane::ID()); +} + static void allReferencedFeatures(const std::set& theFeatures, std::set& theReferencedFeatures) { @@ -158,7 +166,8 @@ static void allReferencedFeatures(const std::set& theFeatures, for (std::list::iterator anObjIt = aRIt->second.begin(); anObjIt != aRIt->second.end(); ++anObjIt) { FeaturePtr aFeature = ModelAPI_Feature::feature(*anObjIt); - if (aFeature && theReferencedFeatures.find(aFeature) == theReferencedFeatures.end()) + if (aFeature && !isCoordinate(aFeature) && + theReferencedFeatures.find(aFeature) == theReferencedFeatures.end()) aReferences.insert(aFeature); } } @@ -168,20 +177,21 @@ static void allReferencedFeatures(const std::set& theFeatures, allReferencedFeatures(aReferences, theReferencedFeatures); } -static bool isCoordinate(FeaturePtr theFeature) -{ - return !theFeature->isInHistory() && - (theFeature->getKind() == ConstructionPlugin_Point::ID() || - theFeature->getKind() == ConstructionPlugin_Axis::ID() || - theFeature->getKind() == ConstructionPlugin_Plane::ID()); -} - void collectFeatures(DocumentPtr theDocument, AttributeSelectionListPtr theSelected, std::list& theExport) { theExport = theDocument->allFeatures(); + // remove all features after the current one + FeaturePtr aCurrentFeature = theDocument->currentFeature(false); + std::list::iterator anIt = theExport.begin(); + for (; anIt != theExport.end(); ++anIt) + if (*anIt == aCurrentFeature) { + theExport.erase(++anIt, theExport.end()); + break; + } + if (!theSelected || theSelected->size() == 0) { // nothing is selected, return all features of the document return; @@ -199,7 +209,7 @@ void collectFeatures(DocumentPtr theDocument, allReferencedFeatures(aFeaturesToExport, aFeaturesToExport); // remove the features which are not affect the selected results - std::list::iterator anIt = theExport.begin(); + anIt = theExport.begin(); while (anIt != theExport.end()) { if (aFeaturesToExport.find(*anIt) == aFeaturesToExport.end()) { std::list::iterator aRemoveIt = anIt++; diff --git a/src/ExchangePlugin/ExchangePlugin_ImportPart.cpp b/src/ExchangePlugin/ExchangePlugin_ImportPart.cpp index 9522e20bc..4a40de68c 100644 --- a/src/ExchangePlugin/ExchangePlugin_ImportPart.cpp +++ b/src/ExchangePlugin/ExchangePlugin_ImportPart.cpp @@ -25,6 +25,12 @@ #include +#include +#include + +// Update names of imported features/results concurent with existing objects. +static void correntNonUniqueNames(DocumentPtr theDocument, std::list& theImported); + ExchangePlugin_ImportPart::ExchangePlugin_ImportPart() { } @@ -47,7 +53,8 @@ void ExchangePlugin_ImportPart::execute() SessionPtr aSession = ModelAPI_Session::get(); DocumentPtr aDoc = document(); bool isPartSet = aDoc == aSession->moduleDocument(); - bool isOk = aDoc->import(aFilename.c_str(), isPartSet); + std::list anImportedFeatures; + bool isOk = aDoc->import(aFilename.c_str(), anImportedFeatures, isPartSet); if (!isOk && isPartSet) { // there are features not appropriate for PartSet, // create new part and load there @@ -57,8 +64,122 @@ void ExchangePlugin_ImportPart::execute() aPartFeature->execute(); aPartResult = std::dynamic_pointer_cast(aPartFeature->lastResult()); } - isOk = aPartResult && aPartResult->partDoc()->import(aFilename.c_str()); + if (aPartResult) { + aDoc = aPartResult->partDoc(); + isOk = aDoc->import(aFilename.c_str(), anImportedFeatures); + } } - if (!isOk) + if (isOk) + correntNonUniqueNames(aDoc, anImportedFeatures); + else setError("Cannot import the document."); } + + +// ================================ Auxiliary functions =================================== + +bool splitName(std::string& theName, int& theIndex) +{ + size_t aLastUndercore = theName.find_last_of('_'); + bool isOk = aLastUndercore != std::string::npos; + if (isOk) { + char* isNumber; + std::string anIndexStr = theName.substr(aLastUndercore + 1); + theIndex = std::strtol(anIndexStr.c_str(), &isNumber, 10); + isOk = isNumber != 0; + if (isOk) + theName.erase(aLastUndercore); + } + return isOk; +} + +void addIndexedName(const std::string& theName, std::map >& theIndexedNames) +{ + std::string aName = theName; + int anIndex = 0; + bool isIndexed = splitName(aName, anIndex); + std::set& anIndices = theIndexedNames[aName]; + if (isIndexed) + anIndices.insert(anIndex); +} + +// Collect names of features and results in the document before the import. +// The name of indexed feature/result will be split to the name and the index. For example , +// 'Point_1', 'Point_2' will be placed at the same key with the set of corrsponding indices: +// 'Point_1', 'Point_2' => {'Point', [1, 2]}. +// Thus, the new point should have index 3 and therefore the name 'Point_3'. +static void collectOldNames(DocumentPtr theDocument, std::list& theAvoided, + std::map >& theIndexedNames) +{ + std::list anAllFeatures = theDocument->allFeatures(); + std::list::iterator aFIt = anAllFeatures.begin(); + std::list::iterator anAvoidIt = theAvoided.begin(); + for (; aFIt != anAllFeatures.end(); ++aFIt) { + if (anAvoidIt != theAvoided.end() && *aFIt == *anAvoidIt) { + // skip this feature + ++anAvoidIt; + continue; + } + + // store name of feature + addIndexedName((*aFIt)->data()->name(), theIndexedNames); + // store names of results + const std::list& aResults = (*aFIt)->results(); + for (std::list::const_iterator aRIt = aResults.begin(); + aRIt != aResults.end(); ++aRIt) + addIndexedName((*aRIt)->data()->name(), theIndexedNames); + } +} + +static std::string uniqueName(const std::string& theName, + std::map >& theExistingNames) +{ + std::string aName = theName; + int anIndex = 1; + splitName(aName, anIndex); + + std::map >::iterator aFound = theExistingNames.find(aName); + bool isUnique = false; + if (aFound == theExistingNames.end()) + isUnique = true; + else { + // search the appropriate index + std::set::iterator aFoundIndex = aFound->second.find(anIndex); + for (; aFoundIndex != aFound->second.end(); ++aFoundIndex, ++anIndex) + if (anIndex != *aFoundIndex) + break; + // compose the new name + std::ostringstream aNewName; + aNewName << aName << "_" << anIndex; + aName = aNewName.str(); + // add new index + aFound->second.insert(anIndex); + } + + if (isUnique) { + // name is unique + aName = theName; + addIndexedName(theName, theExistingNames); + } + return aName; +} + +void correntNonUniqueNames(DocumentPtr theDocument, std::list& theImported) +{ + std::map > aNames; + collectOldNames(theDocument, theImported, aNames); + + for (std::list::iterator anIt = theImported.begin(); + anIt != theImported.end(); ++anIt) { + // update name of feature + std::string aNewName = uniqueName((*anIt)->data()->name(), aNames); + (*anIt)->data()->setName(aNewName); + // update names of results + const std::list& aResults = (*anIt)->results(); + for (std::list::const_iterator aRIt = aResults.begin(); + aRIt != aResults.end(); ++aRIt) { + aNewName = uniqueName((*aRIt)->data()->name(), aNames); + (*aRIt)->data()->setName(aNewName); + } + } +} diff --git a/src/ExchangePlugin/Test/TestImportPart_AfterCurrent_1.py b/src/ExchangePlugin/Test/TestImportPart_AfterCurrent_1.py new file mode 100644 index 000000000..e633e8834 --- /dev/null +++ b/src/ExchangePlugin/Test/TestImportPart_AfterCurrent_1.py @@ -0,0 +1,113 @@ +# Copyright (C) 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 GeomAlgoAPI import * +from SketchAPI import * +from salome.shaper import model + +import os +import math + +model.begin() +partSet = model.moduleDocument() +Part_1 = model.addPart(partSet) +Part_1_doc = Part_1.document() +Box_1 = model.addBox(Part_1_doc, 10, 10, 10) +Translation_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_1_1")], model.selection("EDGE", "PartSet/OX"), 100) +Plane_4 = model.addPlane(Part_1_doc, model.selection("FACE", "PartSet/YOZ"), model.selection("EDGE", "PartSet/OY"), 45) +model.do() +model.end() + +filename = model.tempFileName() +model.removeFile(filename) + +# store the reference data +features = Part_1_doc.allFeatures() +refData = [] +for feat in features: + res = [] + for r in feat.results(): + res.append(GeomAlgoAPI_ShapeTools.volume(r.shape())) + refData.append( (feat.getKind(), res) ) + +# export all features from Part_1 +model.begin() +model.exportPart(Part_1_doc, filename) +model.end() +assert os.path.exists(filename), "ERROR: Cannot export features from {}".format(Part_1.name()) + +# close all documents +model.reset() + +# create new Part +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")) +SketchLine_1 = Sketch_1.addLine(-20, -40, -50, -40) +SketchLine_2 = Sketch_1.addLine(-50, -40, -50, -10) +SketchLine_3 = Sketch_1.addLine(-50, -10, -20, -10) +SketchLine_4 = Sketch_1.addLine(-20, -10, -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()) +SketchConstraintEqual_1 = Sketch_1.setEqual(SketchLine_1.result(), SketchLine_2.result()) +SketchConstraintLength_1 = Sketch_1.setLength(SketchLine_1.result(), 30) +SketchProjection_1 = Sketch_1.addProjection(model.selection("VERTEX", "PartSet/Origin"), False) +SketchPoint_1 = SketchProjection_1.createdFeature() +SketchConstraintDistanceHorizontal_1 = Sketch_1.setHorizontalDistance(SketchLine_3.endPoint(), SketchAPI_Point(SketchPoint_1).coordinates(), 20) +SketchConstraintDistanceVertical_1 = Sketch_1.setVerticalDistance(SketchLine_3.endPoint(), SketchAPI_Point(SketchPoint_1).coordinates(), 10) +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(), 30, 0) +Translation_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Extrusion_1_1")], model.selection("EDGE", "PartSet/OX"), 50) +model.end() + +# store features before the import +featuresBeforeImportBegin = Part_1_doc.allFeatures() +featuresBeforeImportBegin.pop_back() # remove Translation_1 +featuresBeforeImportBegin.pop_back() # remove Extrusion_1 +featuresBeforeImportFinish = [Translation_1.feature(), Extrusion_1.feature()] + +# import the document after Sketch_1 +model.begin() +model.importPart(Part_1_doc, filename, Sketch_1) +model.end() + +# compare results with the reference data +TOLERANCE = 1.e-7 +features = Part_1_doc.allFeatures() +for feat in featuresBeforeImportBegin: + if features.front().getKind() == feat.getKind() and features.front().name() == feat.name(): + features.pop_front() +for feat in featuresBeforeImportFinish: + if features.back().getKind() == feat.getKind() and features.back().name() == feat.name(): + features.pop_back() +assert(len(features) == len(refData)) +for feat, ref in zip(features, refData): + assert(feat.getKind() == ref[0]) + for fv, rv in zip(feat.results(), ref[1]): + assert(math.fabs(GeomAlgoAPI_ShapeTools.volume(fv.shape()) - rv) < TOLERANCE) + +assert(model.checkPythonDump()) diff --git a/src/ExchangePlugin/Test/TestImportPart_AfterCurrent_2.py b/src/ExchangePlugin/Test/TestImportPart_AfterCurrent_2.py new file mode 100644 index 000000000..e96927228 --- /dev/null +++ b/src/ExchangePlugin/Test/TestImportPart_AfterCurrent_2.py @@ -0,0 +1,112 @@ +# Copyright (C) 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 GeomAlgoAPI import * +from SketchAPI import * +from salome.shaper import model + +import os +import math + +model.begin() +partSet = model.moduleDocument() +Part_1 = model.addPart(partSet) +Part_1_doc = Part_1.document() +Box_1 = model.addBox(Part_1_doc, 10, 10, 10) +Translation_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_1_1")], model.selection("EDGE", "PartSet/OX"), 100) +Plane_4 = model.addPlane(Part_1_doc, model.selection("FACE", "PartSet/YOZ"), model.selection("EDGE", "PartSet/OY"), 45) +model.do() +model.end() + +filename = model.tempFileName() +model.removeFile(filename) + +# store the reference data +features = Part_1_doc.allFeatures() +refData = [] +for feat in features: + res = [] + for r in feat.results(): + res.append(GeomAlgoAPI_ShapeTools.volume(r.shape())) + refData.append( (feat.getKind(), res) ) + +# export all features from Part_1 +model.begin() +model.exportPart(Part_1_doc, filename) +model.end() +assert os.path.exists(filename), "ERROR: Cannot export features from {}".format(Part_1.name()) + +# close all documents +model.reset() + +# create new Part +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")) +SketchLine_1 = Sketch_1.addLine(-20, -40, -50, -40) +SketchLine_2 = Sketch_1.addLine(-50, -40, -50, -10) +SketchLine_3 = Sketch_1.addLine(-50, -10, -20, -10) +SketchLine_4 = Sketch_1.addLine(-20, -10, -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()) +SketchConstraintEqual_1 = Sketch_1.setEqual(SketchLine_1.result(), SketchLine_2.result()) +SketchConstraintLength_1 = Sketch_1.setLength(SketchLine_1.result(), 30) +SketchProjection_1 = Sketch_1.addProjection(model.selection("VERTEX", "PartSet/Origin"), False) +SketchPoint_1 = SketchProjection_1.createdFeature() +SketchConstraintDistanceHorizontal_1 = Sketch_1.setHorizontalDistance(SketchLine_3.endPoint(), SketchAPI_Point(SketchPoint_1).coordinates(), 20) +SketchConstraintDistanceVertical_1 = Sketch_1.setVerticalDistance(SketchLine_3.endPoint(), SketchAPI_Point(SketchPoint_1).coordinates(), 10) +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(), 30, 0) +Translation_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Extrusion_1_1")], model.selection("EDGE", "PartSet/OX"), 50) +model.end() + +# store features before the import +featuresBeforeImportBegin = Part_1_doc.allFeatures() +featuresBeforeImportBegin.pop_back() # remove Translation_1 +featuresBeforeImportFinish = [Translation_1.feature()] + +# import the document after Extrusion_1 +model.begin() +model.importPart(Part_1_doc, filename, Extrusion_1) +model.end() + +# compare results with the reference data +TOLERANCE = 1.e-7 +features = Part_1_doc.allFeatures() +for feat in featuresBeforeImportBegin: + if features.front().getKind() == feat.getKind() and features.front().name() == feat.name(): + features.pop_front() +for feat in featuresBeforeImportFinish: + if features.back().getKind() == feat.getKind() and features.back().name() == feat.name(): + features.pop_back() +assert(len(features) == len(refData)) +for feat, ref in zip(features, refData): + assert(feat.getKind() == ref[0]) + for fv, rv in zip(feat.results(), ref[1]): + assert(math.fabs(GeomAlgoAPI_ShapeTools.volume(fv.shape()) - rv) < TOLERANCE) + +assert(model.checkPythonDump()) diff --git a/src/ExchangePlugin/Test/TestImportPart_AfterLast_1.py b/src/ExchangePlugin/Test/TestImportPart_AfterLast_1.py new file mode 100644 index 000000000..113e738bf --- /dev/null +++ b/src/ExchangePlugin/Test/TestImportPart_AfterLast_1.py @@ -0,0 +1,137 @@ +# Copyright (C) 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 GeomAlgoAPI import * +from SketchAPI import * +from salome.shaper import model + +import os +import math + +model.begin() +partSet = model.moduleDocument() +Point_2 = model.addPoint(partSet, 100, 100, 100) +Axis_4 = model.addAxis(partSet, model.selection("VERTEX", "Origin"), model.selection("VERTEX", "Point_2")) +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("VERTEX", "PartSet/Origin"), False) +SketchPoint_1 = SketchProjection_1.createdFeature() +SketchCircle_1 = Sketch_1.addCircle(0, 0, 30) +SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchPoint_1.result(), SketchCircle_1.center()) +SketchConstraintRadius_1 = Sketch_1.setRadius(SketchCircle_1.results()[1], 30) +model.do() +Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchCircle_1_2f")], model.selection("EDGE", "PartSet/Axis_4"), 100, 0) +Sketch_2 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_1_1/To_Face")) +SketchLine_1 = Sketch_2.addLine(57.73502691896258, 57.73502691896258, 71.87716254269353, 43.59289129523163) +SketchLine_2 = Sketch_2.addLine(71.87716254269353, 43.59289129523163, 71.87716254269353, 71.87716254269353) +SketchConstraintCoincidence_2 = Sketch_2.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint()) +SketchLine_3 = Sketch_2.addLine(71.87716254269353, 71.87716254269353, 57.73502691896258, 57.73502691896258) +SketchConstraintCoincidence_3 = Sketch_2.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint()) +SketchConstraintCoincidence_4 = Sketch_2.setCoincident(SketchLine_1.startPoint(), SketchLine_3.endPoint()) +SketchConstraintPerpendicular_1 = Sketch_2.setPerpendicular(SketchLine_1.result(), SketchLine_3.result()) +SketchConstraintVertical_1 = Sketch_2.setVertical(SketchLine_2.result()) +SketchConstraintEqual_1 = Sketch_2.setEqual(SketchLine_1.result(), SketchLine_3.result()) +SketchProjection_2 = Sketch_2.addProjection(model.selection("VERTEX", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchCircle_1_2][Extrusion_1_1/To_Face]__cc"), False) +SketchPoint_2 = SketchProjection_2.createdFeature() +SketchConstraintCoincidence_5 = Sketch_2.setCoincident(SketchAPI_Point(SketchPoint_2).coordinates(), SketchLine_1.startPoint()) +SketchConstraintLength_1 = Sketch_2.setLength(SketchLine_1.result(), 20) +model.do() +Revolution_1 = model.addRevolution(Part_1_doc, [model.selection("FACE", "Sketch_2/Face-SketchLine_1r-SketchLine_2f-SketchLine_3f")], model.selection("EDGE", "PartSet/OX"), 180, 0) +model.do() + +Part_2 = model.addPart(partSet) +Part_2_doc = Part_2.document() +Box_1 = model.addBox(Part_2_doc, 10, 10, 10) +Translation_1 = model.addTranslation(Part_2_doc, [model.selection("SOLID", "Box_1_1")], model.selection("EDGE", "PartSet/OX"), 100) +model.do() + +model.end() + +filename = model.tempFileName() +model.removeFile(filename) + +# store the reference data +features = [Point_2.feature(), Axis_4.feature()] +refData = [] +for feat in features: + res = [] + for r in feat.results(): + res.append(GeomAlgoAPI_ShapeTools.volume(r.shape())) + refData.append( (feat.getKind(), res) ) + +# export feature from PartSet +featureToExport = Axis_4 +model.begin() +model.exportPart(partSet, filename, [featureToExport.result()]) +model.end() +assert os.path.exists(filename), "ERROR: Cannot export feature {}".format(featureToExport.name()) + +# close all documents +model.reset() + +# create new Part +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")) +SketchLine_1 = Sketch_1.addLine(-20, -40, -50, -40) +SketchLine_2 = Sketch_1.addLine(-50, -40, -50, -10) +SketchLine_3 = Sketch_1.addLine(-50, -10, -20, -10) +SketchLine_4 = Sketch_1.addLine(-20, -10, -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()) +SketchConstraintEqual_1 = Sketch_1.setEqual(SketchLine_1.result(), SketchLine_2.result()) +SketchConstraintLength_1 = Sketch_1.setLength(SketchLine_1.result(), 30) +SketchProjection_1 = Sketch_1.addProjection(model.selection("VERTEX", "PartSet/Origin"), False) +SketchPoint_1 = SketchProjection_1.createdFeature() +SketchConstraintDistanceHorizontal_1 = Sketch_1.setHorizontalDistance(SketchLine_3.endPoint(), SketchAPI_Point(SketchPoint_1).coordinates(), 20) +SketchConstraintDistanceVertical_1 = Sketch_1.setVerticalDistance(SketchLine_3.endPoint(), SketchAPI_Point(SketchPoint_1).coordinates(), 10) +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(), 30, 0) +model.end() + +# store features before the import +featuresBeforeImport = Part_1_doc.allFeatures() + +# import the document +model.begin() +model.importPart(Part_1_doc, filename) +model.end() + +# compare results with the reference data +TOLERANCE = 1.e-7 +features = Part_1_doc.allFeatures() +for feat in featuresBeforeImport: + if features.front().getKind() == feat.getKind() and features.front().name() == feat.name(): + features.pop_front() +assert(len(features) == len(refData)) +for feat, ref in zip(features, refData): + assert(feat.getKind() == ref[0]) + for fv, rv in zip(feat.results(), ref[1]): + assert(math.fabs(GeomAlgoAPI_ShapeTools.volume(fv.shape()) - rv) < TOLERANCE) + +assert(model.checkPythonDump()) diff --git a/src/ExchangePlugin/Test/TestImportPart_AfterLast_2.py b/src/ExchangePlugin/Test/TestImportPart_AfterLast_2.py new file mode 100644 index 000000000..7b89ef1b8 --- /dev/null +++ b/src/ExchangePlugin/Test/TestImportPart_AfterLast_2.py @@ -0,0 +1,142 @@ +# Copyright (C) 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 GeomAlgoAPI import * +from ModelAPI import * +from SketchAPI import * +from salome.shaper import model + +import os +import math + +model.begin() +partSet = model.moduleDocument() +Point_2 = model.addPoint(partSet, 100, 100, 100) +Axis_4 = model.addAxis(partSet, model.selection("VERTEX", "Origin"), model.selection("VERTEX", "Point_2")) +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("VERTEX", "PartSet/Origin"), False) +SketchPoint_1 = SketchProjection_1.createdFeature() +SketchCircle_1 = Sketch_1.addCircle(0, 0, 30) +SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchPoint_1.result(), SketchCircle_1.center()) +SketchConstraintRadius_1 = Sketch_1.setRadius(SketchCircle_1.results()[1], 30) +model.do() +Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchCircle_1_2f")], model.selection("EDGE", "PartSet/Axis_4"), 100, 0) +Sketch_2 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_1_1/To_Face")) +SketchLine_1 = Sketch_2.addLine(57.73502691896258, 57.73502691896258, 71.87716254269353, 43.59289129523163) +SketchLine_2 = Sketch_2.addLine(71.87716254269353, 43.59289129523163, 71.87716254269353, 71.87716254269353) +SketchConstraintCoincidence_2 = Sketch_2.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint()) +SketchLine_3 = Sketch_2.addLine(71.87716254269353, 71.87716254269353, 57.73502691896258, 57.73502691896258) +SketchConstraintCoincidence_3 = Sketch_2.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint()) +SketchConstraintCoincidence_4 = Sketch_2.setCoincident(SketchLine_1.startPoint(), SketchLine_3.endPoint()) +SketchConstraintPerpendicular_1 = Sketch_2.setPerpendicular(SketchLine_1.result(), SketchLine_3.result()) +SketchConstraintVertical_1 = Sketch_2.setVertical(SketchLine_2.result()) +SketchConstraintEqual_1 = Sketch_2.setEqual(SketchLine_1.result(), SketchLine_3.result()) +SketchProjection_2 = Sketch_2.addProjection(model.selection("VERTEX", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchCircle_1_2][Extrusion_1_1/To_Face]__cc"), False) +SketchPoint_2 = SketchProjection_2.createdFeature() +SketchConstraintCoincidence_5 = Sketch_2.setCoincident(SketchAPI_Point(SketchPoint_2).coordinates(), SketchLine_1.startPoint()) +SketchConstraintLength_1 = Sketch_2.setLength(SketchLine_1.result(), 20) +model.do() +Revolution_1 = model.addRevolution(Part_1_doc, [model.selection("FACE", "Sketch_2/Face-SketchLine_1r-SketchLine_2f-SketchLine_3f")], model.selection("EDGE", "PartSet/OX"), 180, 0) +model.do() + +Part_2 = model.addPart(partSet) +Part_2_doc = Part_2.document() +Box_1 = model.addBox(Part_2_doc, 10, 10, 10) +Translation_1 = model.addTranslation(Part_2_doc, [model.selection("SOLID", "Box_1_1")], model.selection("EDGE", "PartSet/OX"), 100) +model.do() + +model.end() + +filename = model.tempFileName() +model.removeFile(filename) + +featureToExport = Sketch_1 + +# store the reference data +sketch = featureToCompositeFeature(featureToExport.feature()) +features = [sketch] +for i in range(0, sketch.numberOfSubs()): + features.append(sketch.subFeature(i)) +refData = [] +for feat in features: + res = [] + for r in feat.results(): + res.append(GeomAlgoAPI_ShapeTools.volume(r.shape())) + refData.append( (feat.getKind(), res) ) + +# export sketch from Part_1 +model.begin() +model.exportPart(Part_1_doc, filename, [featureToExport.result()]) +model.end() +assert os.path.exists(filename), "ERROR: Cannot export feature {}".format(featureToExport.name()) + +# close all documents +model.reset() + +# create new Part +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")) +SketchLine_1 = Sketch_1.addLine(-20, -40, -50, -40) +SketchLine_2 = Sketch_1.addLine(-50, -40, -50, -10) +SketchLine_3 = Sketch_1.addLine(-50, -10, -20, -10) +SketchLine_4 = Sketch_1.addLine(-20, -10, -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()) +SketchConstraintEqual_1 = Sketch_1.setEqual(SketchLine_1.result(), SketchLine_2.result()) +SketchConstraintLength_1 = Sketch_1.setLength(SketchLine_1.result(), 30) +SketchProjection_1 = Sketch_1.addProjection(model.selection("VERTEX", "PartSet/Origin"), False) +SketchPoint_1 = SketchProjection_1.createdFeature() +SketchConstraintDistanceHorizontal_1 = Sketch_1.setHorizontalDistance(SketchLine_3.endPoint(), SketchAPI_Point(SketchPoint_1).coordinates(), 20) +SketchConstraintDistanceVertical_1 = Sketch_1.setVerticalDistance(SketchLine_3.endPoint(), SketchAPI_Point(SketchPoint_1).coordinates(), 10) +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(), 30, 0) +model.end() + +# store features before the import +featuresBeforeImport = Part_1_doc.allFeatures() + +# import the document +model.begin() +model.importPart(Part_1_doc, filename) +model.end() + +# compare results with the reference data +TOLERANCE = 1.e-7 +features = Part_1_doc.allFeatures() +for feat in featuresBeforeImport: + if features.front().getKind() == feat.getKind() and features.front().name() == feat.name(): + features.pop_front() +assert(len(features) == len(refData)) +for feat, ref in zip(features, refData): + assert(feat.getKind() == ref[0]) + for fv, rv in zip(feat.results(), ref[1]): + assert(math.fabs(GeomAlgoAPI_ShapeTools.volume(fv.shape()) - rv) < TOLERANCE) + +assert(model.checkPythonDump()) diff --git a/src/ExchangePlugin/Test/TestImportPart_AfterLast_3.py b/src/ExchangePlugin/Test/TestImportPart_AfterLast_3.py new file mode 100644 index 000000000..0f5074871 --- /dev/null +++ b/src/ExchangePlugin/Test/TestImportPart_AfterLast_3.py @@ -0,0 +1,138 @@ +# Copyright (C) 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 GeomAlgoAPI import * +from SketchAPI import * +from salome.shaper import model + +import os +import math + +model.begin() +partSet = model.moduleDocument() +Point_2 = model.addPoint(partSet, 100, 100, 100) +Axis_4 = model.addAxis(partSet, model.selection("VERTEX", "Origin"), model.selection("VERTEX", "Point_2")) +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("VERTEX", "PartSet/Origin"), False) +SketchPoint_1 = SketchProjection_1.createdFeature() +SketchCircle_1 = Sketch_1.addCircle(0, 0, 30) +SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchPoint_1.result(), SketchCircle_1.center()) +SketchConstraintRadius_1 = Sketch_1.setRadius(SketchCircle_1.results()[1], 30) +model.do() +Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchCircle_1_2f")], model.selection("EDGE", "PartSet/Axis_4"), 100, 0) +Sketch_2 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_1_1/To_Face")) +SketchLine_1 = Sketch_2.addLine(57.73502691896258, 57.73502691896258, 71.87716254269353, 43.59289129523163) +SketchLine_2 = Sketch_2.addLine(71.87716254269353, 43.59289129523163, 71.87716254269353, 71.87716254269353) +SketchConstraintCoincidence_2 = Sketch_2.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint()) +SketchLine_3 = Sketch_2.addLine(71.87716254269353, 71.87716254269353, 57.73502691896258, 57.73502691896258) +SketchConstraintCoincidence_3 = Sketch_2.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint()) +SketchConstraintCoincidence_4 = Sketch_2.setCoincident(SketchLine_1.startPoint(), SketchLine_3.endPoint()) +SketchConstraintPerpendicular_1 = Sketch_2.setPerpendicular(SketchLine_1.result(), SketchLine_3.result()) +SketchConstraintVertical_1 = Sketch_2.setVertical(SketchLine_2.result()) +SketchConstraintEqual_1 = Sketch_2.setEqual(SketchLine_1.result(), SketchLine_3.result()) +SketchProjection_2 = Sketch_2.addProjection(model.selection("VERTEX", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchCircle_1_2][Extrusion_1_1/To_Face]__cc"), False) +SketchPoint_2 = SketchProjection_2.createdFeature() +SketchConstraintCoincidence_5 = Sketch_2.setCoincident(SketchAPI_Point(SketchPoint_2).coordinates(), SketchLine_1.startPoint()) +SketchConstraintLength_1 = Sketch_2.setLength(SketchLine_1.result(), 20) +model.do() +Revolution_1 = model.addRevolution(Part_1_doc, [model.selection("FACE", "Sketch_2/Face-SketchLine_1r-SketchLine_2f-SketchLine_3f")], model.selection("EDGE", "PartSet/OX"), 180, 0) +model.do() + +Part_2 = model.addPart(partSet) +Part_2_doc = Part_2.document() +Box_1 = model.addBox(Part_2_doc, 10, 10, 10) +Translation_1 = model.addTranslation(Part_2_doc, [model.selection("SOLID", "Box_1_1")], model.selection("EDGE", "PartSet/OX"), 100) +model.do() + +model.end() + +filename = model.tempFileName() +model.removeFile(filename) + +featureToExport = Box_1 + +# store the reference data +features = [featureToExport.feature()] +refData = [] +for feat in features: + res = [] + for r in feat.results(): + res.append(GeomAlgoAPI_ShapeTools.volume(r.shape())) + refData.append( (feat.getKind(), res) ) + +# export feature from Part_2 +model.begin() +model.exportPart(Part_2_doc, filename, [featureToExport.result()]) +model.end() +assert os.path.exists(filename), "ERROR: Cannot export feature {}".format(featureToExport.name()) + +# close all documents +model.reset() + +# create new Part +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")) +SketchLine_1 = Sketch_1.addLine(-20, -40, -50, -40) +SketchLine_2 = Sketch_1.addLine(-50, -40, -50, -10) +SketchLine_3 = Sketch_1.addLine(-50, -10, -20, -10) +SketchLine_4 = Sketch_1.addLine(-20, -10, -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()) +SketchConstraintEqual_1 = Sketch_1.setEqual(SketchLine_1.result(), SketchLine_2.result()) +SketchConstraintLength_1 = Sketch_1.setLength(SketchLine_1.result(), 30) +SketchProjection_1 = Sketch_1.addProjection(model.selection("VERTEX", "PartSet/Origin"), False) +SketchPoint_1 = SketchProjection_1.createdFeature() +SketchConstraintDistanceHorizontal_1 = Sketch_1.setHorizontalDistance(SketchLine_3.endPoint(), SketchAPI_Point(SketchPoint_1).coordinates(), 20) +SketchConstraintDistanceVertical_1 = Sketch_1.setVerticalDistance(SketchLine_3.endPoint(), SketchAPI_Point(SketchPoint_1).coordinates(), 10) +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(), 30, 0) +model.end() + +# store features before the import +featuresBeforeImport = Part_1_doc.allFeatures() + +# import the document +model.begin() +model.importPart(Part_1_doc, filename) +model.end() + +# compare results with the reference data +TOLERANCE = 1.e-7 +features = Part_1_doc.allFeatures() +for feat in featuresBeforeImport: + if features.front().getKind() == feat.getKind() and features.front().name() == feat.name(): + features.pop_front() +assert(len(features) == len(refData)) +for feat, ref in zip(features, refData): + assert(feat.getKind() == ref[0]) + for fv, rv in zip(feat.results(), ref[1]): + assert(math.fabs(GeomAlgoAPI_ShapeTools.volume(fv.shape()) - rv) < TOLERANCE) + +assert(model.checkPythonDump()) diff --git a/src/ExchangePlugin/Test/TestImportPart_AfterLast_4.py b/src/ExchangePlugin/Test/TestImportPart_AfterLast_4.py new file mode 100644 index 000000000..2dc22241e --- /dev/null +++ b/src/ExchangePlugin/Test/TestImportPart_AfterLast_4.py @@ -0,0 +1,138 @@ +# Copyright (C) 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 GeomAlgoAPI import * +from SketchAPI import * +from salome.shaper import model + +import os +import math + +model.begin() +partSet = model.moduleDocument() +Point_2 = model.addPoint(partSet, 100, 100, 100) +Axis_4 = model.addAxis(partSet, model.selection("VERTEX", "Origin"), model.selection("VERTEX", "Point_2")) +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("VERTEX", "PartSet/Origin"), False) +SketchPoint_1 = SketchProjection_1.createdFeature() +SketchCircle_1 = Sketch_1.addCircle(0, 0, 30) +SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchPoint_1.result(), SketchCircle_1.center()) +SketchConstraintRadius_1 = Sketch_1.setRadius(SketchCircle_1.results()[1], 30) +model.do() +Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchCircle_1_2f")], model.selection("EDGE", "PartSet/Axis_4"), 100, 0) +Sketch_2 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_1_1/To_Face")) +SketchLine_1 = Sketch_2.addLine(57.73502691896258, 57.73502691896258, 71.87716254269353, 43.59289129523163) +SketchLine_2 = Sketch_2.addLine(71.87716254269353, 43.59289129523163, 71.87716254269353, 71.87716254269353) +SketchConstraintCoincidence_2 = Sketch_2.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint()) +SketchLine_3 = Sketch_2.addLine(71.87716254269353, 71.87716254269353, 57.73502691896258, 57.73502691896258) +SketchConstraintCoincidence_3 = Sketch_2.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint()) +SketchConstraintCoincidence_4 = Sketch_2.setCoincident(SketchLine_1.startPoint(), SketchLine_3.endPoint()) +SketchConstraintPerpendicular_1 = Sketch_2.setPerpendicular(SketchLine_1.result(), SketchLine_3.result()) +SketchConstraintVertical_1 = Sketch_2.setVertical(SketchLine_2.result()) +SketchConstraintEqual_1 = Sketch_2.setEqual(SketchLine_1.result(), SketchLine_3.result()) +SketchProjection_2 = Sketch_2.addProjection(model.selection("VERTEX", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchCircle_1_2][Extrusion_1_1/To_Face]__cc"), False) +SketchPoint_2 = SketchProjection_2.createdFeature() +SketchConstraintCoincidence_5 = Sketch_2.setCoincident(SketchAPI_Point(SketchPoint_2).coordinates(), SketchLine_1.startPoint()) +SketchConstraintLength_1 = Sketch_2.setLength(SketchLine_1.result(), 20) +model.do() +Revolution_1 = model.addRevolution(Part_1_doc, [model.selection("FACE", "Sketch_2/Face-SketchLine_1r-SketchLine_2f-SketchLine_3f")], model.selection("EDGE", "PartSet/OX"), 180, 0) +model.do() + +Part_2 = model.addPart(partSet) +Part_2_doc = Part_2.document() +Box_1 = model.addBox(Part_2_doc, 10, 10, 10) +Translation_1 = model.addTranslation(Part_2_doc, [model.selection("SOLID", "Box_1_1")], model.selection("EDGE", "PartSet/OX"), 100) +model.do() + +model.end() + +filename = model.tempFileName() +model.removeFile(filename) + +featureToExport = Translation_1 + +# store the reference data +features = [Box_1.feature(), Translation_1.feature()] +refData = [] +for feat in features: + res = [] + for r in feat.results(): + res.append(GeomAlgoAPI_ShapeTools.volume(r.shape())) + refData.append( (feat.getKind(), res) ) + +# export all features from Part_2 +model.begin() +model.exportPart(Part_2_doc, filename) +model.end() +assert os.path.exists(filename), "ERROR: Cannot export feature {}".format(featureToExport.name()) + +# close all documents +model.reset() + +# create new Part +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")) +SketchLine_1 = Sketch_1.addLine(-20, -40, -50, -40) +SketchLine_2 = Sketch_1.addLine(-50, -40, -50, -10) +SketchLine_3 = Sketch_1.addLine(-50, -10, -20, -10) +SketchLine_4 = Sketch_1.addLine(-20, -10, -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()) +SketchConstraintEqual_1 = Sketch_1.setEqual(SketchLine_1.result(), SketchLine_2.result()) +SketchConstraintLength_1 = Sketch_1.setLength(SketchLine_1.result(), 30) +SketchProjection_1 = Sketch_1.addProjection(model.selection("VERTEX", "PartSet/Origin"), False) +SketchPoint_1 = SketchProjection_1.createdFeature() +SketchConstraintDistanceHorizontal_1 = Sketch_1.setHorizontalDistance(SketchLine_3.endPoint(), SketchAPI_Point(SketchPoint_1).coordinates(), 20) +SketchConstraintDistanceVertical_1 = Sketch_1.setVerticalDistance(SketchLine_3.endPoint(), SketchAPI_Point(SketchPoint_1).coordinates(), 10) +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(), 30, 0) +model.end() + +# store features before the import +featuresBeforeImport = Part_1_doc.allFeatures() + +# import the document +model.begin() +model.importPart(Part_1_doc, filename) +model.end() + +# compare results with the reference data +TOLERANCE = 1.e-7 +features = Part_1_doc.allFeatures() +for feat in featuresBeforeImport: + if features.front().getKind() == feat.getKind() and features.front().name() == feat.name(): + features.pop_front() +assert(len(features) == len(refData)) +for feat, ref in zip(features, refData): + assert(feat.getKind() == ref[0]) + for fv, rv in zip(feat.results(), ref[1]): + assert(math.fabs(GeomAlgoAPI_ShapeTools.volume(fv.shape()) - rv) < TOLERANCE) + +assert(model.checkPythonDump()) diff --git a/src/ExchangePlugin/Test/TestImportPart_AfterLast_5.py b/src/ExchangePlugin/Test/TestImportPart_AfterLast_5.py new file mode 100644 index 000000000..294f48589 --- /dev/null +++ b/src/ExchangePlugin/Test/TestImportPart_AfterLast_5.py @@ -0,0 +1,137 @@ +# Copyright (C) 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 GeomAlgoAPI import * +from SketchAPI import * +from salome.shaper import model + +import os +import math + +model.begin() +partSet = model.moduleDocument() +Point_2 = model.addPoint(partSet, 100, 100, 100) +Axis_4 = model.addAxis(partSet, model.selection("VERTEX", "Origin"), model.selection("VERTEX", "Point_2")) +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("VERTEX", "PartSet/Origin"), False) +SketchPoint_1 = SketchProjection_1.createdFeature() +SketchCircle_1 = Sketch_1.addCircle(0, 0, 30) +SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchPoint_1.result(), SketchCircle_1.center()) +SketchConstraintRadius_1 = Sketch_1.setRadius(SketchCircle_1.results()[1], 30) +model.do() +Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchCircle_1_2f")], model.selection("EDGE", "PartSet/Axis_4"), 100, 0) +Sketch_2 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_1_1/To_Face")) +SketchLine_1 = Sketch_2.addLine(57.73502691896258, 57.73502691896258, 71.87716254269353, 43.59289129523163) +SketchLine_2 = Sketch_2.addLine(71.87716254269353, 43.59289129523163, 71.87716254269353, 71.87716254269353) +SketchConstraintCoincidence_2 = Sketch_2.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint()) +SketchLine_3 = Sketch_2.addLine(71.87716254269353, 71.87716254269353, 57.73502691896258, 57.73502691896258) +SketchConstraintCoincidence_3 = Sketch_2.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint()) +SketchConstraintCoincidence_4 = Sketch_2.setCoincident(SketchLine_1.startPoint(), SketchLine_3.endPoint()) +SketchConstraintPerpendicular_1 = Sketch_2.setPerpendicular(SketchLine_1.result(), SketchLine_3.result()) +SketchConstraintVertical_1 = Sketch_2.setVertical(SketchLine_2.result()) +SketchConstraintEqual_1 = Sketch_2.setEqual(SketchLine_1.result(), SketchLine_3.result()) +SketchProjection_2 = Sketch_2.addProjection(model.selection("VERTEX", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchCircle_1_2][Extrusion_1_1/To_Face]__cc"), False) +SketchPoint_2 = SketchProjection_2.createdFeature() +SketchConstraintCoincidence_5 = Sketch_2.setCoincident(SketchAPI_Point(SketchPoint_2).coordinates(), SketchLine_1.startPoint()) +SketchConstraintLength_1 = Sketch_2.setLength(SketchLine_1.result(), 20) +model.do() +Revolution_1 = model.addRevolution(Part_1_doc, [model.selection("FACE", "Sketch_2/Face-SketchLine_1r-SketchLine_2f-SketchLine_3f")], model.selection("EDGE", "PartSet/OX"), 180, 0) +model.do() + +Part_2 = model.addPart(partSet) +Part_2_doc = Part_2.document() +Box_1 = model.addBox(Part_2_doc, 10, 10, 10) +Translation_1 = model.addTranslation(Part_2_doc, [model.selection("SOLID", "Box_1_1")], model.selection("EDGE", "PartSet/OX"), 100) +Plane_4 = model.addPlane(Part_2_doc, model.selection("FACE", "PartSet/YOZ"), model.selection("EDGE", "PartSet/OY"), 45) +model.do() + +model.end() + +filename = model.tempFileName() +model.removeFile(filename) + +# store the reference data +features = [Box_1.feature(), Plane_4.feature()] +refData = [] +for feat in features: + res = [] + for r in feat.results(): + res.append(GeomAlgoAPI_ShapeTools.volume(r.shape())) + refData.append( (feat.getKind(), res) ) + +# export specified features from Part_2 +model.begin() +model.exportPart(Part_2_doc, filename, [Box_1.result(), Plane_4.result()]) +model.end() +assert os.path.exists(filename), "ERROR: Cannot export features {} and {}".format(feature[0].name(), features[1].name()) + +# close all documents +model.reset() + +# create new Part +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")) +SketchLine_1 = Sketch_1.addLine(-20, -40, -50, -40) +SketchLine_2 = Sketch_1.addLine(-50, -40, -50, -10) +SketchLine_3 = Sketch_1.addLine(-50, -10, -20, -10) +SketchLine_4 = Sketch_1.addLine(-20, -10, -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()) +SketchConstraintEqual_1 = Sketch_1.setEqual(SketchLine_1.result(), SketchLine_2.result()) +SketchConstraintLength_1 = Sketch_1.setLength(SketchLine_1.result(), 30) +SketchProjection_1 = Sketch_1.addProjection(model.selection("VERTEX", "PartSet/Origin"), False) +SketchPoint_1 = SketchProjection_1.createdFeature() +SketchConstraintDistanceHorizontal_1 = Sketch_1.setHorizontalDistance(SketchLine_3.endPoint(), SketchAPI_Point(SketchPoint_1).coordinates(), 20) +SketchConstraintDistanceVertical_1 = Sketch_1.setVerticalDistance(SketchLine_3.endPoint(), SketchAPI_Point(SketchPoint_1).coordinates(), 10) +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(), 30, 0) +model.end() + +# store features before the import +featuresBeforeImport = Part_1_doc.allFeatures() + +# import the document +model.begin() +model.importPart(Part_1_doc, filename) +model.end() + +# compare results with the reference data +TOLERANCE = 1.e-7 +features = Part_1_doc.allFeatures() +for feat in featuresBeforeImport: + if features.front().getKind() == feat.getKind() and features.front().name() == feat.name(): + features.pop_front() +assert(len(features) == len(refData)) +for feat, ref in zip(features, refData): + assert(feat.getKind() == ref[0]) + for fv, rv in zip(feat.results(), ref[1]): + assert(math.fabs(GeomAlgoAPI_ShapeTools.volume(fv.shape()) - rv) < TOLERANCE) + +assert(model.checkPythonDump()) diff --git a/src/ExchangePlugin/Test/TestImportPart_AfterLast_6.py b/src/ExchangePlugin/Test/TestImportPart_AfterLast_6.py new file mode 100644 index 000000000..f812d071f --- /dev/null +++ b/src/ExchangePlugin/Test/TestImportPart_AfterLast_6.py @@ -0,0 +1,138 @@ +# Copyright (C) 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 GeomAlgoAPI import * +from SketchAPI import * +from salome.shaper import model + +import os +import math + +model.begin() +partSet = model.moduleDocument() +Point_2 = model.addPoint(partSet, 100, 100, 100) +Axis_4 = model.addAxis(partSet, model.selection("VERTEX", "Origin"), model.selection("VERTEX", "Point_2")) +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("VERTEX", "PartSet/Origin"), False) +SketchPoint_1 = SketchProjection_1.createdFeature() +SketchCircle_1 = Sketch_1.addCircle(0, 0, 30) +SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchPoint_1.result(), SketchCircle_1.center()) +SketchConstraintRadius_1 = Sketch_1.setRadius(SketchCircle_1.results()[1], 30) +model.do() +Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchCircle_1_2f")], model.selection("EDGE", "PartSet/Axis_4"), 100, 0) +Sketch_2 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_1_1/To_Face")) +SketchLine_1 = Sketch_2.addLine(57.73502691896258, 57.73502691896258, 71.87716254269353, 43.59289129523163) +SketchLine_2 = Sketch_2.addLine(71.87716254269353, 43.59289129523163, 71.87716254269353, 71.87716254269353) +SketchConstraintCoincidence_2 = Sketch_2.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint()) +SketchLine_3 = Sketch_2.addLine(71.87716254269353, 71.87716254269353, 57.73502691896258, 57.73502691896258) +SketchConstraintCoincidence_3 = Sketch_2.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint()) +SketchConstraintCoincidence_4 = Sketch_2.setCoincident(SketchLine_1.startPoint(), SketchLine_3.endPoint()) +SketchConstraintPerpendicular_1 = Sketch_2.setPerpendicular(SketchLine_1.result(), SketchLine_3.result()) +SketchConstraintVertical_1 = Sketch_2.setVertical(SketchLine_2.result()) +SketchConstraintEqual_1 = Sketch_2.setEqual(SketchLine_1.result(), SketchLine_3.result()) +SketchProjection_2 = Sketch_2.addProjection(model.selection("VERTEX", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchCircle_1_2][Extrusion_1_1/To_Face]__cc"), False) +SketchPoint_2 = SketchProjection_2.createdFeature() +SketchConstraintCoincidence_5 = Sketch_2.setCoincident(SketchAPI_Point(SketchPoint_2).coordinates(), SketchLine_1.startPoint()) +SketchConstraintLength_1 = Sketch_2.setLength(SketchLine_1.result(), 20) +model.do() +Revolution_1 = model.addRevolution(Part_1_doc, [model.selection("FACE", "Sketch_2/Face-SketchLine_1r-SketchLine_2f-SketchLine_3f")], model.selection("EDGE", "PartSet/OX"), 180, 0) +model.do() + +Part_2 = model.addPart(partSet) +Part_2_doc = Part_2.document() +Box_1 = model.addBox(Part_2_doc, 10, 10, 10) +Translation_1 = model.addTranslation(Part_2_doc, [model.selection("SOLID", "Box_1_1")], model.selection("EDGE", "PartSet/OX"), 100) +Plane_4 = model.addPlane(Part_2_doc, model.selection("FACE", "PartSet/YOZ"), model.selection("EDGE", "PartSet/OY"), 45) +model.do() + +model.end() + +filename = model.tempFileName() +model.removeFile(filename) + +# store the reference data +features = [Box_1.feature(), Translation_1.feature()] +refData = [] +for feat in features: + res = [] + for r in feat.results(): + res.append(GeomAlgoAPI_ShapeTools.volume(r.shape())) + refData.append( (feat.getKind(), res) ) + +# export all features before the history line from Part_2 +model.begin() +Part_2_doc.setCurrentFeature(Translation_1.feature(), False) +model.exportPart(Part_2_doc, filename) +model.end() +assert os.path.exists(filename), "ERROR: Cannot export features {} and {}".format(feature[0].name(), features[1].name()) + +# close all documents +model.reset() + +# create new Part +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")) +SketchLine_1 = Sketch_1.addLine(-20, -40, -50, -40) +SketchLine_2 = Sketch_1.addLine(-50, -40, -50, -10) +SketchLine_3 = Sketch_1.addLine(-50, -10, -20, -10) +SketchLine_4 = Sketch_1.addLine(-20, -10, -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()) +SketchConstraintEqual_1 = Sketch_1.setEqual(SketchLine_1.result(), SketchLine_2.result()) +SketchConstraintLength_1 = Sketch_1.setLength(SketchLine_1.result(), 30) +SketchProjection_1 = Sketch_1.addProjection(model.selection("VERTEX", "PartSet/Origin"), False) +SketchPoint_1 = SketchProjection_1.createdFeature() +SketchConstraintDistanceHorizontal_1 = Sketch_1.setHorizontalDistance(SketchLine_3.endPoint(), SketchAPI_Point(SketchPoint_1).coordinates(), 20) +SketchConstraintDistanceVertical_1 = Sketch_1.setVerticalDistance(SketchLine_3.endPoint(), SketchAPI_Point(SketchPoint_1).coordinates(), 10) +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(), 30, 0) +model.end() + +# store features before the import +featuresBeforeImport = Part_1_doc.allFeatures() + +# import the document +model.begin() +model.importPart(Part_1_doc, filename) +model.end() + +# compare results with the reference data +TOLERANCE = 1.e-7 +features = Part_1_doc.allFeatures() +for feat in featuresBeforeImport: + if features.front().getKind() == feat.getKind() and features.front().name() == feat.name(): + features.pop_front() +assert(len(features) == len(refData)) +for feat, ref in zip(features, refData): + assert(feat.getKind() == ref[0]) + for fv, rv in zip(feat.results(), ref[1]): + assert(math.fabs(GeomAlgoAPI_ShapeTools.volume(fv.shape()) - rv) < TOLERANCE) + +assert(model.checkPythonDump()) diff --git a/src/ExchangePlugin/Test/TestImportPart_Multiple.py b/src/ExchangePlugin/Test/TestImportPart_Multiple.py new file mode 100644 index 000000000..9d3ad6218 --- /dev/null +++ b/src/ExchangePlugin/Test/TestImportPart_Multiple.py @@ -0,0 +1,115 @@ +# Copyright (C) 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 GeomAlgoAPI import * +from ModelAPI import * +from SketchAPI import * +from salome.shaper import model + +import os +import math + +model.begin() +partSet = model.moduleDocument() +Part_1 = model.addPart(partSet) +Part_1_doc = Part_1.document() +Box_1 = model.addBox(Part_1_doc, 10, 10, 10) +Translation_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_1_1")], model.selection("EDGE", "PartSet/OX"), 100) +Translation_1.setName("MovedBox") +Plane_4 = model.addPlane(Part_1_doc, model.selection("FACE", "PartSet/YOZ"), model.selection("EDGE", "PartSet/OY"), 45) +model.do() +model.end() + +filename = model.tempFileName() +model.removeFile(filename) + +# export all features from Part_1 +model.begin() +model.exportPart(Part_1_doc, filename) +model.end() +assert os.path.exists(filename), "ERROR: Cannot export features from {}".format(Part_1.name()) + +# close all documents +model.reset() + +# create new Part +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")) +SketchLine_1 = Sketch_1.addLine(-20, -40, -50, -40) +SketchLine_2 = Sketch_1.addLine(-50, -40, -50, -10) +SketchLine_3 = Sketch_1.addLine(-50, -10, -20, -10) +SketchLine_4 = Sketch_1.addLine(-20, -10, -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()) +SketchConstraintEqual_1 = Sketch_1.setEqual(SketchLine_1.result(), SketchLine_2.result()) +SketchConstraintLength_1 = Sketch_1.setLength(SketchLine_1.result(), 30) +SketchProjection_1 = Sketch_1.addProjection(model.selection("VERTEX", "PartSet/Origin"), False) +SketchPoint_1 = SketchProjection_1.createdFeature() +SketchConstraintDistanceHorizontal_1 = Sketch_1.setHorizontalDistance(SketchLine_3.endPoint(), SketchAPI_Point(SketchPoint_1).coordinates(), 20) +SketchConstraintDistanceVertical_1 = Sketch_1.setVerticalDistance(SketchLine_3.endPoint(), SketchAPI_Point(SketchPoint_1).coordinates(), 10) +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(), 30, 0) +Translation_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Extrusion_1_1")], model.selection("EDGE", "PartSet/OX"), 50) +model.end() + + +def checkUniqueNames(theDocument): + features = theDocument.allObjects() + names = set() + for feat in features: + name = feat.data().name() + if not name == "": + assert(not name in names), "'{}' already exists in {}".format(name, names) + names.add(name) + + +# import the document at the end +model.begin() +model.importPart(Part_1_doc, filename) +model.end() +checkUniqueNames(Part_1_doc) + +# import the document after Extrusion_1 +model.begin() +model.importPart(Part_1_doc, filename, Extrusion_1) +model.end() +checkUniqueNames(Part_1_doc) + +# import the document after Sketch_1 +model.begin() +model.importPart(Part_1_doc, filename, Sketch_1) +model.end() +checkUniqueNames(Part_1_doc) + +# import the document after Translation_1 +model.begin() +model.importPart(Part_1_doc, filename, Translation_1) +model.end() +checkUniqueNames(Part_1_doc) + +assert(model.checkPythonDump()) diff --git a/src/Model/Model_Document.cpp b/src/Model/Model_Document.cpp index c2323e13b..216acecd7 100644 --- a/src/Model/Model_Document.cpp +++ b/src/Model/Model_Document.cpp @@ -349,7 +349,9 @@ bool Model_Document::load(const char* theDirName, const char* theFileName, Docum return isOk; } -bool Model_Document::import(const char* theFileName, bool theCheckBefore) +bool Model_Document::import(const char* theFileName, + std::list >& theImported, + bool theCheckBefore) { Handle(Model_Application) anApp = Model_Application::getApplication(); TCollection_ExtendedString aFormat; @@ -396,6 +398,7 @@ bool Model_Document::import(const char* theFileName, bool theCheckBefore) std::dynamic_pointer_cast(aNewFeature->data()); aNewFeatuerLab = aData->label().Father(); Model_Tools::copyLabels(aCurrentLab, aNewFeatuerLab, aRelocTable); + theImported.push_back(aNewFeature); } anAllNewFeatures.Append(aNewFeatuerLab); } diff --git a/src/Model/Model_Document.h b/src/Model/Model_Document.h index f7246758f..023770a4d 100644 --- a/src/Model/Model_Document.h +++ b/src/Model/Model_Document.h @@ -59,10 +59,13 @@ class Model_Document : public ModelAPI_Document //! Loads the OCAF document from the file into the current document. //! All the features are added after the active feature. //! \param theFileName name of the file to import + //! \param theImported list of features imported from the file //! \param theCheckBefore verify the document does not contain unappropriate features //! (useful for import to PartSet) //! \returns true if file was loaded successfully - MODEL_EXPORT virtual bool import(const char* theFileName, bool theCheckBefore = false); + MODEL_EXPORT virtual bool import(const char* theFileName, + std::list >& theImported, + bool theCheckBefore = false); //! Saves the OCAF document to the file. //! \param theDirName directory where the document will be saved diff --git a/src/ModelAPI/ModelAPI_Document.h b/src/ModelAPI/ModelAPI_Document.h index 071d2284c..6900965d5 100644 --- a/src/ModelAPI/ModelAPI_Document.h +++ b/src/ModelAPI/ModelAPI_Document.h @@ -262,10 +262,13 @@ public: /// Loads the OCAF document from the file into the current document. /// All the features are added after the active feature. /// \param theFileName name of the file to import + /// \param theImported list of features imported from the file /// \param theCheckBefore verify the document does not contain unappropriate features /// (useful for import to PartSet) /// \returns true if file was loaded successfully - MODELAPI_EXPORT virtual bool import(const char* theFileName, bool theCheckBefore = false) = 0; + MODELAPI_EXPORT virtual bool import(const char* theFileName, + std::list >& theImported, + bool theCheckBefore = false) = 0; /// Export the list of features to the file /// \param theFilename path to save the file -- 2.39.2