From: cg246364 Date: Thu, 10 Dec 2020 08:45:01 +0000 (+0100) Subject: Import STEP with materials and colors X-Git-Tag: V9_7_0a1~67^2~2 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=8c8d262b50e3fc797d0ce0096b83493ddb4e0c5f;p=modules%2Fshaper.git Import STEP with materials and colors --- diff --git a/src/ConnectorAPI/Test/TestImportSTEP.py b/src/ConnectorAPI/Test/TestImportSTEP.py new file mode 100644 index 000000000..84b6d90ce --- /dev/null +++ b/src/ConnectorAPI/Test/TestImportSTEP.py @@ -0,0 +1,124 @@ +# Copyright (C) 2014-2020 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 +# + +""" + TestImportStep.py + Unit test of ExchangePlugin_ImportFeature class for STEP +""" +#========================================================================= +# Initialization of the test +#========================================================================= + +import salome + +import os +import math +from tempfile import TemporaryDirectory + +import GEOM + +from ModelAPI import * + +from salome.shaper import model + +from salome.geom import geomBuilder + +from GeomAPI import GeomAPI_Shape + +from GeomAlgoAPI import * + +__updated__ = "2015-05-22" + +salome.salome_init(1) +geompy = geomBuilder.New() + +#========================================================================= +# Help functions +#========================================================================= +def removeFile(theFileName): + try: os.remove(theFileName) + except OSError: pass + assert not os.path.exists(theFileName), \ + "Can not remove file {0}".format(theFileName) + +#========================================================================= +# test Import STEP +#========================================================================= +def testImportSTEP(): + + model.begin() + partSet = model.moduleDocument() + Part_1 = model.addPart(partSet) + Part_1_doc = Part_1.document() + aShapePath = os.path.join(os.getenv("DATA_DIR"), "Shapes", "Step", "black_and_white.step") + print("aShapePath=",aShapePath) + Import_1 = model.addImportSTEP(Part_1_doc,aShapePath, True, True, True) + + model.do() + + # Check results + Import_1_Feature = Import_1.feature() + assert Import_1_Feature.error() == '' + assert Import_1_Feature.name() == "black_and_white" + assert len(Import_1_Feature.results()) == 1 + model.testNbSubShapes(Import_1, GeomAPI_Shape.SOLID, [2]) + + aCompositeFeature = featureToCompositeFeature(Import_1_Feature) + assert aCompositeFeature.numberOfSubs(False) == 4 + + aFeature1 = aCompositeFeature.subFeature(0, False) + assert aFeature1.getKind() == "Group" + assert aFeature1.name() == "Color_1" + + aSelectionList = aFeature1.selectionList("group_list") + assert aSelectionList.size() == 1 + + aFeature1 = aCompositeFeature.subFeature(1, False) + assert aFeature1.getKind() == "Group" + assert aFeature1.name() == "Color_2" + + aSelectionList = aFeature1.selectionList("group_list") + assert aSelectionList.size() == 1 + + aFeature1 = aCompositeFeature.subFeature(2, False) + assert aFeature1.getKind() == "Group" + assert aFeature1.name() == "Material_black" + + aSelectionList = aFeature1.selectionList("group_list") + assert aSelectionList.size() == 1 + + + aFeature1 = aCompositeFeature.subFeature(3, False) + assert aFeature1.getKind() == "Group" + assert aFeature1.name() == "Material_white" + + aSelectionList = aFeature1.selectionList("group_list") + assert aSelectionList.size() == 1 + + model.end() + +if __name__ == '__main__': + with TemporaryDirectory() as tmp_dir: + #========================================================================= + # Export a shape into STL + #========================================================================= + testImportSTEP() + #========================================================================= + # End of test + #========================================================================= diff --git a/src/ConnectorAPI/Test/tests.set b/src/ConnectorAPI/Test/tests.set index 31e182ca7..3f4eb7ec2 100644 --- a/src/ConnectorAPI/Test/tests.set +++ b/src/ConnectorAPI/Test/tests.set @@ -28,4 +28,5 @@ SET(TEST_NAMES Test18887 Test3195 TestExportSTL + TestImportSTEP ) diff --git a/src/ExchangeAPI/ExchangeAPI_Import.cpp b/src/ExchangeAPI/ExchangeAPI_Import.cpp index b1a6c832d..f12ea5dc6 100644 --- a/src/ExchangeAPI/ExchangeAPI_Import.cpp +++ b/src/ExchangeAPI/ExchangeAPI_Import.cpp @@ -28,6 +28,7 @@ #include #include #include +#include //-------------------------------------------------------------------------------------- #include @@ -47,17 +48,49 @@ ExchangeAPI_Import::ExchangeAPI_Import( setFilePath(theFilePath); } +ExchangeAPI_Import::ExchangeAPI_Import( + const std::shared_ptr & theFeature, + const std::string & theFilePath, + const bool theScalInterUnits, + const bool theMaterials, + const bool theColor) +: ModelHighAPI_Interface(theFeature) +{ + if (initialize()) + setParameters(theFilePath, theScalInterUnits, theMaterials, theColor); +} + ExchangeAPI_Import::~ExchangeAPI_Import() { } +//-------------------------------------------------------------------------------------- +void ExchangeAPI_Import::setParameters(const std::string & theFilePath, + const bool theScalInterUnits, + const bool theMaterials, + const bool theColor) +{ + fillAttribute(theFilePath, mystepFilePath); + fillAttribute("STEP", myimportType); + fillAttribute(theScalInterUnits, myscalInterUnits); + fillAttribute(theMaterials,mymaterials); + fillAttribute(theColor,mycolors); + execute(); +} + //-------------------------------------------------------------------------------------- void ExchangeAPI_Import::setFilePath(const std::string & theFilePath) { - fillAttribute(theFilePath, myfilePath); - execute(); + std::string anExtension = GeomAlgoAPI_Tools::File_Tools::extension(theFilePath); + if (anExtension == "STEP" || anExtension == "STP") { + setParameters(theFilePath,true,false,false); + } else { + fillAttribute(theFilePath, myfilePath); + fillAttribute(anExtension, myimportType); + execute(); + } } //-------------------------------------------------------------------------------------- @@ -66,7 +99,17 @@ void ExchangeAPI_Import::dump(ModelHighAPI_Dumper& theDumper) const FeaturePtr aBase = feature(); std::string aPartName = theDumper.name(aBase->document()); - std::string aFilePath = aBase->string(ExchangePlugin_ImportFeature::FILE_PATH_ID())->value(); + AttributeStringPtr aImportTypeAttr = + aBase->string(ExchangePlugin_ImportFeature::IMPORT_TYPE_ID()); + std::string aFormat = aImportTypeAttr->value(); + std::string aFilePath; + if (aFormat == "STEP" || aFormat == "STP") + { + aFilePath = aBase->string(ExchangePlugin_ImportFeature::STEP_FILE_PATH_ID())->value(); + } else { + aFilePath = aBase->string(ExchangePlugin_ImportFeature::FILE_PATH_ID())->value(); + } + std::string aFrom = "\\"; std::string aTo = "\\\\"; for(std::size_t aPos = aFilePath.find(aFrom); @@ -75,15 +118,25 @@ void ExchangeAPI_Import::dump(ModelHighAPI_Dumper& theDumper) const aFilePath.replace(aPos, aFrom.size(), aTo); aPos += aTo.size(); } - - theDumper << aBase << " = model.addImport(" << aPartName << ", \"" + std::string anExtension = GeomAlgoAPI_Tools::File_Tools::extension(aFilePath); + if (anExtension == "STP" || anExtension == "STEP"){ + theDumper << aBase << " = model.addImportSTEP(" << aPartName << ", \"" + << aFilePath << "\"" ; + + theDumper << ", " << scalInterUnits()->value() + << ", " << materials()->value() + << ", " << colors()->value() << ")"<< std::endl; + } else { + theDumper << aBase << " = model.addImport(" << aPartName << ", \"" << aFilePath << "\")" << std::endl; + } + // to make import have results theDumper << "model.do()" << std::endl; CompositeFeaturePtr aCompositeFeature = std::dynamic_pointer_cast(aBase); - if(aCompositeFeature.get()) { + if (aCompositeFeature.get()) { int aNbOfSubs = aCompositeFeature->numberOfSubs(); for(int anIndex = 0; anIndex < aNbOfSubs; ++anIndex) { std::string aSubFeatureGet = @@ -102,6 +155,18 @@ ImportPtr addImport( return ImportPtr(new ExchangeAPI_Import(aFeature, theFilePath)); } +ImportPtr addImportSTEP( + const std::shared_ptr & thePart, + const std::string & theFilePath, + const bool theScalInterUnits, + const bool theMaterials, + const bool theColor ) +{ + std::shared_ptr aFeature = thePart->addFeature(ExchangeAPI_Import::ID()); + return ImportPtr(new ExchangeAPI_Import(aFeature, theFilePath, + theScalInterUnits, theMaterials, theColor)); +} + void importPart(const std::shared_ptr & thePart, const std::string & theFilePath, const ModelHighAPI_Reference & theAfterThis) diff --git a/src/ExchangeAPI/ExchangeAPI_Import.h b/src/ExchangeAPI/ExchangeAPI_Import.h index f38db9bbb..d3403e544 100644 --- a/src/ExchangeAPI/ExchangeAPI_Import.h +++ b/src/ExchangeAPI/ExchangeAPI_Import.h @@ -46,19 +46,43 @@ public: EXCHANGEAPI_EXPORT ExchangeAPI_Import(const std::shared_ptr & theFeature, const std::string & theFilePath); + + /// Constructor with values for Step file + EXCHANGEAPI_EXPORT + ExchangeAPI_Import(const std::shared_ptr & theFeature, + const std::string & theFilePath, + const bool theScalInterUnits, + const bool theMaterials, + const bool theColor); /// Destructor EXCHANGEAPI_EXPORT virtual ~ExchangeAPI_Import(); - INTERFACE_1(ExchangePlugin_ImportFeature::ID(), + INTERFACE_6(ExchangePlugin_ImportFeature::ID(), filePath, ExchangePlugin_ImportFeature::FILE_PATH_ID(), - ModelAPI_AttributeString, /** File path */ + ModelAPI_AttributeString, /** File path */, + importType, ExchangePlugin_ImportFeature::IMPORT_TYPE_ID(), + ModelAPI_AttributeString, /**import type */, + stepFilePath, ExchangePlugin_ImportFeature::STEP_FILE_PATH_ID(), + ModelAPI_AttributeString, /**step File path */, + scalInterUnits, ExchangePlugin_ImportFeature::STEP_SCALE_INTER_UNITS_ID(), + ModelAPI_AttributeBoolean, /** Scale internationals units */, + materials, ExchangePlugin_ImportFeature::STEP_MATERIALS_ID(), + ModelAPI_AttributeBoolean, /** Materials */, + colors, ExchangePlugin_ImportFeature::STEP_COLORS_ID(), + ModelAPI_AttributeBoolean, /** Colors */ ) /// Set point values EXCHANGEAPI_EXPORT void setFilePath(const std::string & theFilePath); + EXCHANGEAPI_EXPORT + void setParameters(const std::string & theFilePath, + const bool theScalInterUnits, + const bool theMaterials, + const bool theColor); + /// Dump wrapped feature EXCHANGEAPI_EXPORT virtual void dump(ModelHighAPI_Dumper& theDumper) const; @@ -74,6 +98,17 @@ EXCHANGEAPI_EXPORT ImportPtr addImport(const std::shared_ptr & thePart, const std::string & theFilePath); +/**\ingroup CPPHighAPI + * \brief Create Import Step feature + */ +EXCHANGEAPI_EXPORT +ImportPtr addImportSTEP(const std::shared_ptr & thePart, + const std::string & theFilePath, + const bool theScalInterUnits, + const bool theMaterials, + const bool theColor); + + /** \ingroup CPPHighAPI * \brief Import features from the file to the document after the current feature (or to the end). */ diff --git a/src/ExchangePlugin/CMakeLists.txt b/src/ExchangePlugin/CMakeLists.txt index 67880c8e6..3df98bece 100644 --- a/src/ExchangePlugin/CMakeLists.txt +++ b/src/ExchangePlugin/CMakeLists.txt @@ -31,6 +31,7 @@ INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/src/Events ${PROJECT_SOURCE_DIR}/src/XAO ${PROJECT_SOURCE_DIR}/src/ConstructionPlugin ${PROJECT_SOURCE_DIR}/src/PartSetPlugin + ${OpenCASCADE_INCLUDE_DIR} ) SET(PROJECT_HEADERS diff --git a/src/ExchangePlugin/ExchangePlugin_Import.cpp b/src/ExchangePlugin/ExchangePlugin_Import.cpp index b5a51ff08..e9b041582 100644 --- a/src/ExchangePlugin/ExchangePlugin_Import.cpp +++ b/src/ExchangePlugin/ExchangePlugin_Import.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -81,8 +82,15 @@ ExchangePlugin_Import::~ExchangePlugin_Import() void ExchangePlugin_Import::initAttributes() { data()->addAttribute(FILE_PATH_ID(), ModelAPI_AttributeString::typeId()); + data()->addAttribute(STEP_FILE_PATH_ID(), ModelAPI_AttributeString::typeId()); + data()->addAttribute(IMPORT_TYPE_ID(), ModelAPI_AttributeString::typeId()); data()->addAttribute(TARGET_PART_ID(), ModelAPI_AttributeInteger::typeId()); data()->addAttribute(TARGET_PARTS_LIST_ID(), ModelAPI_AttributeStringArray::typeId()); + data()->addAttribute(STEP_TARGET_PART_ID(), ModelAPI_AttributeInteger::typeId()); + data()->addAttribute(STEP_TARGET_PARTS_LIST_ID(), ModelAPI_AttributeStringArray::typeId()); + data()->addAttribute(STEP_MATERIALS_ID(), ModelAPI_AttributeBoolean::typeId()); + data()->addAttribute(STEP_COLORS_ID(), ModelAPI_AttributeBoolean::typeId()); + data()->addAttribute(STEP_SCALE_INTER_UNITS_ID(), ModelAPI_AttributeBoolean::typeId()); } /* @@ -90,26 +98,62 @@ void ExchangePlugin_Import::initAttributes() */ void ExchangePlugin_Import::execute() { - AttributeStringPtr aFilePathAttr = string(ExchangePlugin_Import::FILE_PATH_ID()); - std::string aFilePath = aFilePathAttr->value(); - if (aFilePath.empty()) { - setError("File path is empty."); - return; + AttributeStringPtr aFormatAttr = + this->string(ExchangePlugin_Import::IMPORT_TYPE_ID()); + std::string aFormat = aFormatAttr->value(); + + AttributeStringPtr aFilePathAttr; + std::string aFilePath; + AttributeStringArrayPtr aPartsAttr; + AttributeIntegerPtr aTargetAttr; + if (aFormat == "STEP" || aFormat == "STP") + { + aFilePathAttr = string(ExchangePlugin_Import::STEP_FILE_PATH_ID()); + aFilePath = aFilePathAttr->value(); + // get the document where to import + aPartsAttr = stringArray(STEP_TARGET_PARTS_LIST_ID()); + aTargetAttr = integer(STEP_TARGET_PART_ID()); + }else{ + aFilePathAttr = string(ExchangePlugin_Import::FILE_PATH_ID()); + aFilePath = aFilePathAttr->value(); + // get the document where to import + aPartsAttr = stringArray(TARGET_PARTS_LIST_ID()); + aTargetAttr = integer(TARGET_PART_ID()); } - // get the document where to import - AttributeStringArrayPtr aPartsAttr = stringArray(TARGET_PARTS_LIST_ID()); - AttributeIntegerPtr aTargetAttr = integer(TARGET_PART_ID()); + if (aFilePath.empty()) { + setError("File path is empty."); + return; + } SessionPtr aSession = ModelAPI_Session::get(); - DocumentPtr aDoc = - findDocument(aSession->moduleDocument(), + DocumentPtr aDoc = findDocument(aSession->moduleDocument(), Locale::Convert::toWString(aPartsAttr->value(aTargetAttr->value()))); if (aDoc.get()) { FeaturePtr aImportFeature = aDoc->addFeature(ExchangePlugin_ImportFeature::ID()); DataPtr aData = aImportFeature->data(); - AttributeStringPtr aPathAttr = aData->string(ExchangePlugin_ImportFeature::FILE_PATH_ID()); + AttributeStringPtr aPathAttr; + if (aFormat == "STEP" || aFormat == "STP") + { + aPathAttr = aData->string(ExchangePlugin_ImportFeature::STEP_FILE_PATH_ID()); + }else + { + aPathAttr = aData->string(ExchangePlugin_ImportFeature::FILE_PATH_ID()); + } + + AttributeStringPtr aImportTypeAttr = + aData->string(ExchangePlugin_ImportFeature::IMPORT_TYPE_ID()); + + aData->boolean(ExchangePlugin_ImportFeature::STEP_MATERIALS_ID()) + ->setValue(boolean(ExchangePlugin_Import::STEP_MATERIALS_ID())->value()); + aData->boolean(ExchangePlugin_ImportFeature::STEP_COLORS_ID()) + ->setValue(boolean(ExchangePlugin_Import::STEP_COLORS_ID())->value()); + aData->boolean(ExchangePlugin_ImportFeature::STEP_SCALE_INTER_UNITS_ID()) + ->setValue(boolean(ExchangePlugin_Import::STEP_SCALE_INTER_UNITS_ID())->value()); + aPathAttr->setValue(aFilePathAttr->value()); + aImportTypeAttr->setValue(aFormat); + aImportFeature->execute(); } } @@ -117,14 +161,32 @@ void ExchangePlugin_Import::execute() void ExchangePlugin_Import::attributeChanged(const std::string& theID) { - if (theID == FILE_PATH_ID()) { - AttributeStringPtr aFilePathAttr = string(FILE_PATH_ID()); - if (aFilePathAttr->value().empty()) + AttributeStringPtr aFilePathAttr; + AttributeStringArrayPtr aPartsAttr; + AttributeIntegerPtr aTargetAttr; + + if (theID == FILE_PATH_ID() ||theID == STEP_FILE_PATH_ID() ) { + aFilePathAttr = string(FILE_PATH_ID()); + if (theID == FILE_PATH_ID() && aFilePathAttr->value().empty()) + return; + aPartsAttr = stringArray(TARGET_PARTS_LIST_ID()); + aTargetAttr = integer(TARGET_PART_ID()); + + updatePart(aPartsAttr, aTargetAttr); + + aFilePathAttr = string(STEP_FILE_PATH_ID()); + if (theID == STEP_FILE_PATH_ID() && aFilePathAttr->value().empty()) return; - AttributeStringArrayPtr aPartsAttr = stringArray(TARGET_PARTS_LIST_ID()); - AttributeIntegerPtr aTargetAttr = integer(TARGET_PART_ID()); + aPartsAttr = stringArray(STEP_TARGET_PARTS_LIST_ID()); + aTargetAttr = integer(STEP_TARGET_PART_ID()); + updatePart(aPartsAttr, aTargetAttr); + } +} +void ExchangePlugin_Import::updatePart(AttributeStringArrayPtr& thePartsAttr, + AttributeIntegerPtr& theTargetAttr) +{ // update the list of target parts SessionPtr aSession = ModelAPI_Session::get(); DocumentPtr aDoc = document(); @@ -141,23 +203,22 @@ void ExchangePlugin_Import::attributeChanged(const std::string& theID) anAcceptedValues.push_back((*aFIt)->name()); } - if ((size_t)aPartsAttr->size() != anAcceptedValues.size()) - aTargetAttr->setValue(0); + if ((size_t)thePartsAttr->size() != anAcceptedValues.size()) + theTargetAttr->setValue(0); - aPartsAttr->setSize((int)anAcceptedValues.size()); + thePartsAttr->setSize((int)anAcceptedValues.size()); std::list::iterator anIt = anAcceptedValues.begin(); for (int anInd = 0; anIt != anAcceptedValues.end(); ++anIt, ++anInd) - aPartsAttr->setValue(anInd, Locale::Convert::toString(*anIt)); + thePartsAttr->setValue(anInd, Locale::Convert::toString(*anIt)); } else { // keep only the name of the current part - if (aPartsAttr->size() == 0) { + if (thePartsAttr->size() == 0) { FeaturePtr aPartFeature = ModelAPI_Tools::findPartFeature(aSession->moduleDocument(), aDoc); - aPartsAttr->setSize(1); - aPartsAttr->setValue(0, Locale::Convert::toString(aPartFeature->name())); - aTargetAttr->setValue(0); + thePartsAttr->setSize(1); + thePartsAttr->setValue(0, Locale::Convert::toString(aPartFeature->name())); + theTargetAttr->setValue(0); } } - } } diff --git a/src/ExchangePlugin/ExchangePlugin_Import.h b/src/ExchangePlugin/ExchangePlugin_Import.h index c09b3ebab..994b3c8be 100644 --- a/src/ExchangePlugin/ExchangePlugin_Import.h +++ b/src/ExchangePlugin/ExchangePlugin_Import.h @@ -24,6 +24,8 @@ #include #include +#include +#include #include @@ -43,6 +45,12 @@ class ExchangePlugin_Import : public ModelAPI_Feature static const std::string MY_IMPORT_ID("ImportMacro"); return MY_IMPORT_ID; } + /// Feature kind + inline static const std::string& IMPORT_TYPE_ID() + { + static const std::string MY_IMPORT_TYPE_ID("ImportType"); + return MY_IMPORT_TYPE_ID; + } /// attribute name of file path inline static const std::string& FILE_PATH_ID() { @@ -61,6 +69,42 @@ class ExchangePlugin_Import : public ModelAPI_Feature static const std::string MY_TARGET_PARTS_LIST_ID("target_parts_list"); return MY_TARGET_PARTS_LIST_ID; } + /// attribute name of step file path + inline static const std::string& STEP_FILE_PATH_ID() + { + static const std::string MY_STEP_FILE_PATH_ID("step_file_path"); + return MY_STEP_FILE_PATH_ID; + } + /// attribute name of step target part + inline static const std::string& STEP_TARGET_PART_ID() + { + static const std::string MY_STEP_TARGET_PART_ID("step_target_part"); + return MY_STEP_TARGET_PART_ID; + } + /// attribute name of list ofstep target parts + inline static const std::string& STEP_TARGET_PARTS_LIST_ID() + { + static const std::string MY_STEP_TARGET_PARTS_LIST_ID("step_target_parts_list"); + return MY_STEP_TARGET_PARTS_LIST_ID; + } + /// attribute name of step Scale to International System Units + inline static const std::string& STEP_SCALE_INTER_UNITS_ID() + { + static const std::string MY_STEP_SCALE_INTER_UNITS_ID("step_scale_inter_units"); + return MY_STEP_SCALE_INTER_UNITS_ID; + } + /// attribute name of step materiels + inline static const std::string& STEP_MATERIALS_ID() + { + static const std::string MY_STEP_MATERIALS_ID("step_materials"); + return MY_STEP_MATERIALS_ID; + } + /// attribute name of step colors + inline static const std::string& STEP_COLORS_ID() + { + static const std::string MY_STEP_COLORS_ID("step_colors"); + return MY_STEP_COLORS_ID; + } /// Default constructor EXCHANGEPLUGIN_EXPORT ExchangePlugin_Import(); /// Default destructor @@ -79,6 +123,10 @@ class ExchangePlugin_Import : public ModelAPI_Feature /// \param theID identifier of changed attribute EXCHANGEPLUGIN_EXPORT virtual void attributeChanged(const std::string& theID); + /// Called to update part + EXCHANGEPLUGIN_EXPORT + void updatePart(AttributeStringArrayPtr& thePartsAttr, AttributeIntegerPtr& theTargetAttr); + /// Computes or recomputes the results EXCHANGEPLUGIN_EXPORT virtual void execute(); diff --git a/src/ExchangePlugin/ExchangePlugin_ImportFeature.cpp b/src/ExchangePlugin/ExchangePlugin_ImportFeature.cpp index ade0a3115..dc3542679 100644 --- a/src/ExchangePlugin/ExchangePlugin_ImportFeature.cpp +++ b/src/ExchangePlugin/ExchangePlugin_ImportFeature.cpp @@ -32,6 +32,7 @@ #include #include +#include #include #include @@ -42,6 +43,8 @@ #include #include #include +#include +#include #include #include #include @@ -60,6 +63,10 @@ #include +#include +#include + + ExchangePlugin_ImportFeature::ExchangePlugin_ImportFeature() { } @@ -77,12 +84,28 @@ void ExchangePlugin_ImportFeature::initAttributes() data()->addAttribute(ExchangePlugin_ImportFeature::FILE_PATH_ID(), ModelAPI_AttributeString::typeId()); AttributePtr aFeaturesAttribute = - data()->addAttribute(ExchangePlugin_ImportFeature::FEATURES_ID(), + data()->addAttribute(ExchangePlugin_ImportFeature::FEATURES_ID(), ModelAPI_AttributeRefList::typeId()); + data()->addAttribute(STEP_FILE_PATH_ID(), ModelAPI_AttributeString::typeId()); + data()->addAttribute(IMPORT_TYPE_ID(), ModelAPI_AttributeString::typeId()); + data()->addAttribute(STEP_MATERIALS_ID(), ModelAPI_AttributeBoolean::typeId()); + data()->addAttribute(STEP_COLORS_ID(), ModelAPI_AttributeBoolean::typeId()); + data()->addAttribute(STEP_SCALE_INTER_UNITS_ID(), ModelAPI_AttributeBoolean::typeId()); + aFeaturesAttribute->setIsArgument(false); ModelAPI_Session::get()->validators()->registerNotObligatory( getKind(), ExchangePlugin_ImportFeature::FEATURES_ID()); + ModelAPI_Session::get()->validators()->registerNotObligatory( + getKind(), ExchangePlugin_ImportFeature::STEP_COLORS_ID()); + ModelAPI_Session::get()->validators()->registerNotObligatory( + getKind(), ExchangePlugin_ImportFeature::STEP_MATERIALS_ID()); + ModelAPI_Session::get()->validators()->registerNotObligatory( + getKind(), ExchangePlugin_ImportFeature::STEP_SCALE_INTER_UNITS_ID()); + ModelAPI_Session::get()->validators()->registerNotObligatory( + getKind(), ExchangePlugin_ImportFeature::STEP_FILE_PATH_ID()); + ModelAPI_Session::get()->validators()->registerNotObligatory( + getKind(), ExchangePlugin_ImportFeature::FILE_PATH_ID()); } /* @@ -90,7 +113,15 @@ void ExchangePlugin_ImportFeature::initAttributes() */ void ExchangePlugin_ImportFeature::execute() { - AttributeStringPtr aFilePathAttr = string(ExchangePlugin_ImportFeature::FILE_PATH_ID()); + AttributeStringPtr aImportTypeAttr = string(ExchangePlugin_ImportFeature::IMPORT_TYPE_ID()); + std::string aFormat = aImportTypeAttr->value(); + AttributeStringPtr aFilePathAttr; + if (aFormat == "STEP" || aFormat == "STP") + { + aFilePathAttr = string(ExchangePlugin_ImportFeature::STEP_FILE_PATH_ID()); + } else { + aFilePathAttr = string(ExchangePlugin_ImportFeature::FILE_PATH_ID()); + } std::string aFilePath = aFilePathAttr->value(); if (aFilePath.empty()) { setError("File path is empty."); @@ -101,11 +132,11 @@ void ExchangePlugin_ImportFeature::execute() } std::shared_ptr ExchangePlugin_ImportFeature::createResultBody( - std::shared_ptr aGeomShape) + std::shared_ptr theGeomShape) { std::shared_ptr aResultBody = document()->createBody(data()); //LoadNamingDS of the imported shape - loadNamingDS(aGeomShape, aResultBody); + loadNamingDS(theGeomShape, aResultBody); return aResultBody; } @@ -122,10 +153,49 @@ void ExchangePlugin_ImportFeature::importFile(const std::string& theFileName) // Perform the import std::string anError; std::shared_ptr aGeomShape; + + std::map< std::wstring, std::list> theMaterialShape; + + std::string anObjectName = GeomAlgoAPI_Tools::File_Tools::name(theFileName); + data()->setName(Locale::Convert::toWString(anObjectName)); + + ResultBodyPtr aResult = document()->createBody(data()); + + bool anColorGroupSelected = boolean(ExchangePlugin_ImportFeature::STEP_COLORS_ID())->value(); + bool anMaterialsGroupSelected = + boolean(ExchangePlugin_ImportFeature::STEP_MATERIALS_ID())->value(); + if (anExtension == "BREP" || anExtension == "BRP") { aGeomShape = BREPImport(theFileName, anExtension, anError); } else if (anExtension == "STEP" || anExtension == "STP") { - aGeomShape = STEPImport(theFileName, anExtension, anError); + bool anScalInterUnits = + boolean(ExchangePlugin_ImportFeature::STEP_SCALE_INTER_UNITS_ID())->value(); + + try{ + + aResult->clearShapeNameAndColor(); + // Process groups/fields + std::shared_ptr aRefListOfGroups = + std::dynamic_pointer_cast(data()->attribute(FEATURES_ID())); + + // Remove previous groups/fields stored in RefList + std::list anGroupList = aRefListOfGroups->list(); + std::list::iterator anGroupIt = anGroupList.begin(); + for (; anGroupIt != anGroupList.end(); ++anGroupIt) { + std::shared_ptr aFeature = ModelAPI_Feature::feature(*anGroupIt); + if (aFeature) + document()->removeFeature(aFeature); + } + + aGeomShape = STEPImportAttributs(theFileName, aResult, anScalInterUnits, + anMaterialsGroupSelected, anColorGroupSelected, + theMaterialShape,anError); + + } + catch (OSD_Exception& e) { + //Try to load STEP file without colors... + aGeomShape = STEPImport(theFileName, anExtension,anScalInterUnits,anError); + } } else if (anExtension == "IGES" || anExtension == "IGS") { aGeomShape = IGESImport(theFileName, anExtension, anError); } else { @@ -139,10 +209,140 @@ void ExchangePlugin_ImportFeature::importFile(const std::string& theFileName) } // Pass the results into the model - std::string anObjectName = GeomAlgoAPI_Tools::File_Tools::name(theFileName); - data()->setName(Locale::Convert::toWString(anObjectName)); - setResult(createResultBody(aGeomShape)); + loadNamingDS(aGeomShape, aResult); + + // create color group + if (anColorGroupSelected) + { + setColorGroups(aResult); + } + + // create Materiel group + if (anMaterialsGroupSelected){ + setMaterielGroup(aResult,theMaterialShape); + } + + setResult(aResult); + +} + +void ExchangePlugin_ImportFeature::setColorGroups( + std::shared_ptr theResultBody) +{ + std::vector aColor; + int anIndice = 1; + std::list< std::vector > aColorsRead; + + ModelAPI_Tools::getColor(theResultBody, aColor); + if (!aColor.empty() ){ + std::wstringstream aColorName; + aColorName < allRes; + ModelAPI_Tools::allSubs(theResultBody, allRes); + for(std::list::iterator aRes = allRes.begin(); aRes != allRes.end(); ++aRes) { + ModelAPI_Tools::getColor(*aRes, aColor); + if (!aColor.empty() ){ + auto it = std::find(aColorsRead.begin(), aColorsRead.end(), aColor); + if ( it == aColorsRead.end() ){ + std::wstringstream aColorName; + aColorName< theResultBody, + std::vector &theColor, + const std::wstring& theName ) +{ + std::vector aColor; + std::shared_ptr aGroupFeature = addFeature("Group"); + + // group name + aGroupFeature->data()->setName(theName); + + // fill selection + AttributeSelectionListPtr aSelectionList = aGroupFeature->selectionList("group_list"); + + ModelAPI_Tools::getColor(theResultBody, aColor); + if (!aColor.empty() ){ + if (aColor == theColor ) { + GeomShapePtr aShape = theResultBody->shape(); + aSelectionList->setSelectionType(aShape->shapeTypeStr() ); + aSelectionList->append(theResultBody,aShape); + } + } + // add element with the same color + std::list allRes; + ModelAPI_Tools::allSubs(theResultBody, allRes); + for(std::list::iterator aRes = allRes.begin(); + aRes != allRes.end(); ++aRes) { + ModelAPI_Tools::getColor(*aRes, aColor); + GeomShapePtr aShape = (*aRes)->shape(); + + if (!aColor.empty() ){ + if (aRes->get() && aColor == theColor ) { + aSelectionList->setSelectionType(aShape->shapeTypeStr() ); + aSelectionList->append(theResultBody,aShape); + } + } + } + + // Create the group in the document to be able to set its color + ResultPtr aGroup = document()->createGroup(aGroupFeature->data()); + aGroupFeature->setResult(aGroup); + + ModelAPI_Tools::setColor(aGroupFeature->lastResult(),theColor); + + if (aSelectionList->size() == 0 ){ + document()->removeFeature(aGroupFeature); + } +} + +void ExchangePlugin_ImportFeature::setMaterielGroup( + std::shared_ptr theResultBody, + std::map< std::wstring,std::list>& theMaterialShape) +{ + std::map< std::wstring, std::list>::iterator anIt; + for( anIt = theMaterialShape.begin(); anIt != theMaterialShape.end(); ++anIt) { + + std::shared_ptr aGroupFeature = addFeature("Group"); + // group name + aGroupFeature->data()->setName((*anIt).first); + + // fill selection + AttributeSelectionListPtr aSelectionList = aGroupFeature->selectionList("group_list"); + GeomShapePtr aShape = theResultBody->shape(); + + std::list allRes; + ModelAPI_Tools::allSubs(theResultBody, allRes); + for(std::list::iterator aRes = allRes.begin(); aRes != allRes.end(); ++aRes) { + + GeomShapePtr aShape = (*aRes)->shape(); + for(std::list::iterator aResMat = anIt->second.begin(); + aResMat != anIt->second.end(); ++aResMat) { + if (aRes->get() && ((*aRes)->data()->name() == (*aResMat))) + { + aSelectionList->append(theResultBody,aShape); + aSelectionList->setSelectionType(aShape->shapeTypeStr() ); + break; + } + } + } + if (aSelectionList->size() == 0){ + document()->removeFeature(aGroupFeature); + } + } } void ExchangePlugin_ImportFeature::importXAO(const std::string& theFileName) @@ -415,7 +615,6 @@ void ExchangePlugin_ImportFeature::loadNamingDS( { //load result theResultBody->store(theGeomShape); - std::string aNameMS = "Shape"; theResultBody->loadFirstLevel(theGeomShape, aNameMS); } diff --git a/src/ExchangePlugin/ExchangePlugin_ImportFeature.h b/src/ExchangePlugin/ExchangePlugin_ImportFeature.h index c087af2ab..3c34eced6 100644 --- a/src/ExchangePlugin/ExchangePlugin_ImportFeature.h +++ b/src/ExchangePlugin/ExchangePlugin_ImportFeature.h @@ -24,6 +24,7 @@ #include #include +#include #include @@ -43,18 +44,48 @@ class ExchangePlugin_ImportFeature : public ModelAPI_CompositeFeature static const std::string MY_IMPORT_ID("Import"); return MY_IMPORT_ID; } + /// Feature kind + inline static const std::string& IMPORT_TYPE_ID() + { + static const std::string MY_IMPORT_TYPE_ID("ImportType"); + return MY_IMPORT_TYPE_ID; + } /// attribute name of file path inline static const std::string& FILE_PATH_ID() { static const std::string MY_FILE_PATH_ID("file_path"); return MY_FILE_PATH_ID; } + /// attribute name of file path + inline static const std::string& STEP_FILE_PATH_ID() + { + static const std::string MY_STEP_FILE_PATH_ID("step_file_path"); + return MY_STEP_FILE_PATH_ID; + } /// All features (list of references) inline static const std::string& FEATURES_ID() { static const std::string MY_FEATURES_ID("Features"); return MY_FEATURES_ID; } + /// attribute name of step Scale to International System Units + inline static const std::string& STEP_SCALE_INTER_UNITS_ID() + { + static const std::string MY_STEP_SCALE_INTER_UNITS_ID("step_scale_inter_units"); + return MY_STEP_SCALE_INTER_UNITS_ID; + } + /// attribute name of step materiels + inline static const std::string& STEP_MATERIALS_ID() + { + static const std::string MY_STEP_MATERIALS_ID("step_materials"); + return MY_STEP_MATERIALS_ID; + } + /// attribute name of step colors + inline static const std::string& STEP_COLORS_ID() + { + static const std::string MY_STEP_COLORS_ID("step_colors"); + return MY_STEP_COLORS_ID; + } /// Default constructor EXCHANGEPLUGIN_EXPORT ExchangePlugin_ImportFeature(); /// Default destructor @@ -108,6 +139,18 @@ private: /// Loads Naming data structure to the document void loadNamingDS(std::shared_ptr theGeomShape, std::shared_ptr theResultBody); + /// Set groups of color + void setColorGroups(std::shared_ptr theResultBody); + + /// set a group of color + void setColorGroup(std::shared_ptr theResultBody, + std::vector& theColor, + const std::wstring& theName ); + + /// set Materiel group of color + void setMaterielGroup(std::shared_ptr theResultBody, + std::map< std::wstring, std::list>& theMaterialShape); + }; #endif /* IMPORT_IMPORTFEATURE_H_ */ diff --git a/src/ExchangePlugin/ExchangePlugin_msg_fr.ts b/src/ExchangePlugin/ExchangePlugin_msg_fr.ts index 110053a1d..72f1663ec 100644 --- a/src/ExchangePlugin/ExchangePlugin_msg_fr.ts +++ b/src/ExchangePlugin/ExchangePlugin_msg_fr.ts @@ -295,9 +295,13 @@ Importer - Import a file - Importer un fichier + Create groups from + créer des groupes à partir + + Materials + Matériels + Import:file_path @@ -306,7 +310,33 @@ Importer un fichier - + + Import:step_file_path + + Import file + Importer un fichier + + + + Import:step_scale_inter_units + + Scale to International System of Units + Mettre àl'échelle du système international d'unités + + + Import:step_materials + + Materials + Matériels + + + + Import:step_materials + + Colors + Couleurs + + ImportMacro @@ -318,6 +348,10 @@ Importer un fichier + + Create groups from + créer des groupes à partir + ImportMacro:target_part @@ -325,6 +359,33 @@ Importer vers + + ImportMacro:step_target_part + + Import to + Importer vers + + + + ImportMacro:step_scale_inter_units + + Scale to International System of Units + Mettre àl'échelle du système international d'unités + + + Import:step_materials + + Materials + Matériels + + + + Import:step_materials + + Colors + Couleurs + + ImportMacro:file_path @@ -332,6 +393,14 @@ Fichier à importer + + ImportMacro:step_file_path + + Import file + Importer un fichier + + + ImportMacro:file_path:ExchangePlugin_ImportFormat diff --git a/src/ExchangePlugin/Test/TestExport.py b/src/ExchangePlugin/Test/TestExport.py index 511b95835..8e4ca9835 100644 --- a/src/ExchangePlugin/Test/TestExport.py +++ b/src/ExchangePlugin/Test/TestExport.py @@ -59,7 +59,9 @@ def testExport(theType, theFormat, theFile, theVolume, theDelta, theErrorExpecte aSession.startOperation("Import screw") anImportFeature = aPart.addFeature("Import") aShapePath = os.path.join(os.getenv("DATA_DIR"), "Shapes", "Step", "screw.step") - anImportFeature.string("file_path").setValue(aShapePath) + anImportFeature.string("step_file_path").setValue(aShapePath) + anImportFeature.string("ImportType").setValue("STEP") + anImportFeature.boolean("step_scale_inter_units").setValue(True) aSession.finishOperation() removeFile(theFile) @@ -101,6 +103,7 @@ def testExportXAO(theFile, theEmptyFormat = False): anImportFeature = aPart.addFeature("Import") aShapePath = os.path.join(os.getenv("DATA_DIR"), "Shapes", "Brep", "box1.brep") anImportFeature.string("file_path").setValue(aShapePath) + anImportFeature.string("ImportType").setValue("BREP") aSession.finishOperation() # Create groups @@ -175,21 +178,21 @@ if __name__ == '__main__': aRealVolume = 3.78827401738e-06 testExport("BREP", "BREP", os.path.join(tmp_dir, "screw_export.brep"), aRealVolume, 10 ** -17) testExport("BRP", "BREP", os.path.join(tmp_dir, "screw_export.brp"), aRealVolume, 10 ** -17) - testExport("Regular", "", os.path.join(tmp_dir, "screw_export.brep"), aRealVolume, 10 ** -17) + testExport("BREP", "", os.path.join(tmp_dir, "screw_export.brep"), aRealVolume, 10 ** -17) #========================================================================= # Export a shape into STEP #========================================================================= testExport("STEP", "STEP", os.path.join(tmp_dir, "screw_export.step"), 3.788258075329978e-06, 10 ** -17) - testExport("STP", "STEP", os.path.join(tmp_dir, "screw_export.stp"), 3.788258075329978e-06, 10 ** -17) - testExport("Regular", "", os.path.join(tmp_dir, "screw_export.step"), 3.788258075329978e-06, 10 ** -17) + testExport("STEP", "STEP", os.path.join(tmp_dir, "screw_export.stp"), 3.788258075329978e-06, 10 ** -17) + testExport("STEP", "", os.path.join(tmp_dir, "screw_export.step"), 3.788258075329978e-06, 10 ** -17) #========================================================================= # Export a shape into IGES #========================================================================= - testExport("IGES-5.1", "IGES-5.1", os.path.join(tmp_dir, "screw_export-5.1.iges"), 0.0019293313766693052, 10 ** -17) - testExport("IGS-5.1", "IGES-5.1", os.path.join(tmp_dir, "screw_export-5.1.igs"), 0.0019293313766693052, 10 ** -17) - testExport("Regular", "", os.path.join(tmp_dir, "screw_export-5.1.iges"), 0.0019293313766693052, 10 ** -17) - testExport("IGES-5.3", "IGES-5.3", os.path.join(tmp_dir, "screw_export-5.3.iges"), 3.78827401651e-06, 10 ** -17) - testExport("IGS-5.3", "IGES-5.3", os.path.join(tmp_dir, "screw_export-5.3.igs"), 3.78827401651e-06, 10 ** -17) + testExport("IGES", "IGES-5.1", os.path.join(tmp_dir, "screw_export-5.1.iges"), 0.0019293313766693052, 10 ** -17) + testExport("IGS", "IGES-5.1", os.path.join(tmp_dir, "screw_export-5.1.igs"), 0.0019293313766693052, 10 ** -17) + testExport("IGES", "", os.path.join(tmp_dir, "screw_export-5.1.iges"), 0.0019293313766693052, 10 ** -17) + testExport("IGES", "IGES-5.3", os.path.join(tmp_dir, "screw_export-5.3.iges"), 3.78827401651e-06, 10 ** -17) + testExport("IGS", "IGES-5.3", os.path.join(tmp_dir, "screw_export-5.3.igs"), 3.78827401651e-06, 10 ** -17) #========================================================================= # Export a shape into XAO #========================================================================= @@ -198,7 +201,7 @@ if __name__ == '__main__': #========================================================================= # Check error when export to unsupported format #========================================================================= - testExport("Regular", "", os.path.join(tmp_dir, "screw_export.dwg"), 3.78825807533e-06, 10 ** -17, True) + testExport("BREP", "", os.path.join(tmp_dir, "screw_export.dwg"), 3.78825807533e-06, 10 ** -17, True) #========================================================================= # End of test #========================================================================= diff --git a/src/ExchangePlugin/Test/TestImport.py b/src/ExchangePlugin/Test/TestImport.py index a4895e081..67998ea22 100644 --- a/src/ExchangePlugin/Test/TestImport.py +++ b/src/ExchangePlugin/Test/TestImport.py @@ -54,10 +54,23 @@ def testImport(theType, theFile, theVolume, theDelta, theErrorExpected = False): aFeatureKind = "Import" anImportFeature = aPart.addFeature(aFeatureKind) assert anImportFeature, "{0}: Can not create a feature {1}".format(theType, aFeatureKind) + if theType == "STP" or theType == "STEP": + aFieldName = "step_file_path" + file = anImportFeature.string(aFieldName) + assert file, "{0}: Can not receive string field {1}".format(theType, aFieldName) + file.setValue(theFile) + aFieldName = "step_scale_inter_units" + units = anImportFeature.boolean(aFieldName) + assert units, "{0}: Can not receive string field {1}".format(theType, aFieldName) + units.setValue(True) aFieldName = "file_path" file = anImportFeature.string(aFieldName) assert file, "{0}: Can not receive string field {1}".format(theType, aFieldName) file.setValue(theFile) + aFieldName = "ImportType" + type = anImportFeature.string(aFieldName) + assert type, "{0}: Can not receive string field {1}".format(theType, aFieldName) + type.setValue(theType) aSession.finishOperation() if theErrorExpected: @@ -86,6 +99,9 @@ def testImportXAO(): aSession.startOperation("Import XAO") anImportFeature = aPart.addFeature("Import") anImportFeature.string("file_path").setValue(getShapePath("Xao/box1.xao")) + aFieldName = "ImportType" + type = anImportFeature.string(aFieldName) + type.setValue("XAO") aSession.finishOperation() # Check results @@ -140,22 +156,29 @@ if __name__ == '__main__': # Create a shape imported from STEP #========================================================================= shape_path = getShapePath("Step/screw.step") - testImport("STP", shape_path, 3.78827401738e-06, 10 ** -17) + testImport("STEP", shape_path, 3.78827401738e-06, 10 ** -17) shape_path = shutil.copyfile(shape_path, os.path.join(tmp_dir, "screw.stp")) testImport("STEP", shape_path, 3.78827401738e-06, 10 ** -17) #========================================================================= # Create a shape imported from IGES #========================================================================= shape_path = getShapePath("Iges/bearing.igs") - testImport("IGES", shape_path, 1.3407098545036494e-08, 10 ** -25) - shape_path = shutil.copyfile(shape_path, os.path.join(tmp_dir, "bearing.iges")) testImport("IGS", shape_path, 1.3407098545036494e-08, 10 ** -25) + shape_path = shutil.copyfile(shape_path, os.path.join(tmp_dir, "bearing.iges")) + testImport("IGES", shape_path, 1.3407098545036494e-08, 10 ** -25) #========================================================================= # Create a shape imported from XAO #========================================================================= testImportXAO() + #========================================================================= + # End of test + #========================================================================= + + from salome.shaper import model + assert(model.checkPythonDump()) + #========================================================================= # Check import errors #========================================================================= @@ -164,10 +187,3 @@ if __name__ == '__main__': testImport("BREP", shape_path, 0, 10 ** -25, True) shape_path = getShapePath("Xao/wrong_file.xao") testImport("XAO", shape_path, 0, 10 ** -25, True) - - #========================================================================= - # End of test - #========================================================================= - - from salome.shaper import model - assert(model.checkPythonDump()) diff --git a/src/ExchangePlugin/doc/TUI_importFeature.rst b/src/ExchangePlugin/doc/TUI_importFeature.rst index 69ed88ab6..ff000831f 100644 --- a/src/ExchangePlugin/doc/TUI_importFeature.rst +++ b/src/ExchangePlugin/doc/TUI_importFeature.rst @@ -10,3 +10,13 @@ Import File :download:`Download this script ` + .. _tui_import_file_step: + +Import STEP File +================ + +.. literalinclude:: examples/importStep.py + :linenos: + :language: python + +:download:`Download this script ` diff --git a/src/ExchangePlugin/doc/examples/importStep.py b/src/ExchangePlugin/doc/examples/importStep.py new file mode 100644 index 000000000..0adc73a7a --- /dev/null +++ b/src/ExchangePlugin/doc/examples/importStep.py @@ -0,0 +1,11 @@ +from salome.shaper import model +import os + +model.begin() +file_path = os.path.join(os.getenv("DATA_DIR"),"Shapes","Step","black_and_white.step") +partSet = model.moduleDocument() +Part_1 = model.addPart(partSet) +Part_1_doc = Part_1.document() +Import_1 = model.addImportSTEP(Part_1_doc,file_path, True, True, True) +model.do() +model.end() diff --git a/src/ExchangePlugin/doc/images/FileImportedSTEP.png b/src/ExchangePlugin/doc/images/FileImportedSTEP.png new file mode 100644 index 000000000..d4f171d81 Binary files /dev/null and b/src/ExchangePlugin/doc/images/FileImportedSTEP.png differ diff --git a/src/ExchangePlugin/doc/images/ImportSTEP.png b/src/ExchangePlugin/doc/images/ImportSTEP.png new file mode 100644 index 000000000..457d02d8b Binary files /dev/null and b/src/ExchangePlugin/doc/images/ImportSTEP.png differ diff --git a/src/ExchangePlugin/doc/images/Import_panel.png b/src/ExchangePlugin/doc/images/Import_panel.png index c22176e77..4d610af44 100644 Binary files a/src/ExchangePlugin/doc/images/Import_panel.png and b/src/ExchangePlugin/doc/images/Import_panel.png differ diff --git a/src/ExchangePlugin/doc/importFeature.rst b/src/ExchangePlugin/doc/importFeature.rst index 4692ec669..64251ddb2 100644 --- a/src/ExchangePlugin/doc/importFeature.rst +++ b/src/ExchangePlugin/doc/importFeature.rst @@ -67,6 +67,8 @@ The following property panel will be opened: **Import property panel** +The first combobox provides the list of formats avalables (BREP, XAO, IGES or STEP). + The **Import to** combobox provides the list of destinations (one of existing Parts or a new Part). In this panel it is possible to enter a file name directly or press **'...'** button and browse it with help of import file dialog box: @@ -75,7 +77,11 @@ In this panel it is possible to enter a file name directly or press **'...'** bu :align: center **Dialog box to import CAD-neutral format** - + +Import BREP, XAO, IGES +"""""""""""""""""""""" +In case of first choice the format of imported file will be defined according to file extension. + **Apply** button imports the file. **Cancel** button cancels the operation. @@ -98,3 +104,45 @@ The Result of the operation depends on the imported file content. Import of BREP file. **See Also** a sample TUI Script of :ref:`tui_import_file` operation. + + +Import STEP +""""""""""" + +In this case, the following property panel will be opened: + +.. figure:: images/ImportSTEP.png + :align: center + + **Dialog box to import file in STEP format** + + +The file name and path can be defined in **Import file** field by direct input or browsing with ‘…’ button, which opens **Import file** dialog box. +The **Import to** combobox provides the list of destinations (one of existing Parts or a new Part). +**STEP options** provide the possibility to **Scale to International System Units** as well as to create groups from **Materials** and/or **Colors** if defined in assemblies of the file to import. + +**Apply** button imports the file. + +**Cancel** button cancels the operation. + +**TUI Command**: + +.. py:function:: model.addImportSTEP(Part_doc, FileNameString,scalInterUnits,materials,colors) + + :param part: The current part object + :param string: A file name string. + :param boolean: True if scale to UIS + :param boolean: True to create groups from materials + :param boolean: True to create groups from colors + +Result +"""""" + +The Result of the operation depends on the imported file content. + +.. figure:: images/FileImportedSTEP.png + :align: center + + Import of STEP file. + +**See Also** a sample TUI Script of :ref:`tui_import_file_step` operation. diff --git a/src/ExchangePlugin/plugin-Exchange.xml b/src/ExchangePlugin/plugin-Exchange.xml index 7f240ba69..8f2445633 100644 --- a/src/ExchangePlugin/plugin-Exchange.xml +++ b/src/ExchangePlugin/plugin-Exchange.xml @@ -4,19 +4,67 @@ - - - + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + @@ -75,4 +123,4 @@ - \ No newline at end of file + diff --git a/src/GeomAlgoAPI/CMakeLists.txt b/src/GeomAlgoAPI/CMakeLists.txt index 2d3df2aee..a03ae213f 100644 --- a/src/GeomAlgoAPI/CMakeLists.txt +++ b/src/GeomAlgoAPI/CMakeLists.txt @@ -45,6 +45,7 @@ SET(PROJECT_HEADERS GeomAlgoAPI_Placement.h GeomAlgoAPI_BREPImport.h GeomAlgoAPI_STEPImport.h + GeomAlgoAPI_STEPImportXCAF.h GeomAlgoAPI_IGESImport.h GeomAlgoAPI_BREPExport.h GeomAlgoAPI_STEPExport.h @@ -111,6 +112,7 @@ SET(PROJECT_SOURCES GeomAlgoAPI_Placement.cpp GeomAlgoAPI_BREPImport.cpp GeomAlgoAPI_STEPImport.cpp + GeomAlgoAPI_STEPImportXCAF.cpp GeomAlgoAPI_IGESImport.cpp GeomAlgoAPI_BREPExport.cpp GeomAlgoAPI_STEPExport.cpp @@ -178,6 +180,7 @@ INCLUDE_DIRECTORIES( ../GeomAlgoImpl ../ModelAPI ../XAO + ${PROJECT_SOURCE_DIR}/src/Locale ${OpenCASCADE_INCLUDE_DIR} ) diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_STEPImport.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_STEPImport.cpp index 3a824f106..7e557e32d 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_STEPImport.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_STEPImport.cpp @@ -18,6 +18,7 @@ // #include +#include #include #include @@ -31,6 +32,8 @@ #include #include #include + +#include #include #include #include @@ -54,17 +57,17 @@ #include #include #include -#include +#include // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC -#include -#include -#include // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC +//================================================================================================== std::shared_ptr STEPImport(const std::string& theFileName, const std::string& theFormatName, + const bool theScalInterUnits, std::string& theError) { + TopoDS_Shape aResShape; // Set "C" numeric locale to save numbers correctly @@ -89,7 +92,7 @@ std::shared_ptr STEPImport(const std::string& theFileName, if (status == IFSelect_RetDone) { // Regard or not the model units - if (theFormatName == "STEP_SCALE") { + if (!theScalInterUnits) { // set UnitFlag to units from file TColStd_SequenceOfAsciiString anUnitLengthNames; TColStd_SequenceOfAsciiString anUnitAngleNames; @@ -194,3 +197,87 @@ std::shared_ptr STEPImport(const std::string& theFileName, aGeomShape->setImpl(new TopoDS_Shape(aResShape)); return aGeomShape; } + +//================================================================================================== +GeomShapePtr STEPImportAttributs(const std::string& theFileName, + std::shared_ptr theResultBody, + const bool theScalInterUnits, + const bool theMaterials, + const bool theColor, + std::map< std::wstring, + std::list>& theMaterialShape, + std::string& theError) +{ + + STEPControl_Reader aReader; + std::shared_ptr aGeomShape(new GeomAPI_Shape); + + Interface_Static::SetCVal("xstep.cascade.unit","M"); + Interface_Static::SetIVal("read.step.ideas", 1); + Interface_Static::SetIVal("read.step.nonmanifold", 1); + + try { + OCC_CATCH_SIGNALS; + + IFSelect_ReturnStatus status = aReader.ReadFile(theFileName.c_str()); + + if (status == IFSelect_RetDone) { + + // Regard or not the model units + if (!theScalInterUnits) { + // set UnitFlag to units from file + TColStd_SequenceOfAsciiString anUnitLengthNames; + TColStd_SequenceOfAsciiString anUnitAngleNames; + TColStd_SequenceOfAsciiString anUnitSolidAngleNames; + aReader.FileUnits(anUnitLengthNames, anUnitAngleNames, anUnitSolidAngleNames); + if (anUnitLengthNames.Length() > 0) { + TCollection_AsciiString aLenUnits = anUnitLengthNames.First(); + if (aLenUnits == "millimetre") + Interface_Static::SetCVal("xstep.cascade.unit", "MM"); + else if (aLenUnits == "centimetre") + Interface_Static::SetCVal("xstep.cascade.unit", "CM"); + else if (aLenUnits == "metre" || aLenUnits.IsEmpty()) + Interface_Static::SetCVal("xstep.cascade.unit", "M"); + else if (aLenUnits == "INCH") + Interface_Static::SetCVal("xstep.cascade.unit", "INCH"); + else { + theError = "The file contains not supported units."; + aGeomShape->setImpl(new TopoDS_Shape()); + return aGeomShape; + } + // TODO (for other units than mm, cm, m or inch) + //else if (aLenUnits == "") + // Interface_Static::SetCVal("xstep.cascade.unit", "???"); + } + } + else { + //cout<<"need re-scale a model"<setImpl(new TopoDS_Shape()); + return aGeomShape; + } + + STEPCAFControl_Reader aCafreader; + aCafreader.SetColorMode(true); + aCafreader.SetNameMode(true); + aCafreader.SetMatMode(true); + + if(aCafreader.ReadFile(theFileName.c_str()) != IFSelect_RetDone) { + theError = "Wrong format of the imported file. Can't import file."; + std::shared_ptr aGeomShape(new GeomAPI_Shape); + aGeomShape->setImpl(new TopoDS_Shape()); + return aGeomShape; + } + + return readAttributes(aCafreader, + theResultBody, + theMaterials, + theMaterialShape, + theError); +} diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_STEPImport.h b/src/GeomAlgoAPI/GeomAlgoAPI_STEPImport.h index 470791a3b..5740fc520 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_STEPImport.h +++ b/src/GeomAlgoAPI/GeomAlgoAPI_STEPImport.h @@ -23,13 +23,27 @@ #include #include - #include +#include + + /// Implementation of the import STEP files algorithms GEOMALGOAPI_EXPORT std::shared_ptr STEPImport(const std::string& theFileName, const std::string& theFormatName, + const bool theScalInterUnits, std::string& theError); +/// Implementation of the import STEP files algorithms with Attributs (Name, Color, Materials) +GEOMALGOAPI_EXPORT +GeomShapePtr STEPImportAttributs(const std::string& theFileName, + std::shared_ptr theResultBody, + const bool theScalInterUnits, + const bool theMaterials, + const bool theColor, + std::map< std::wstring, + std::list>& theMaterialShape, + std::string& theError); + #endif /* GEOMALGOAPI_STEPIMPORT_H_ */ diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_STEPImportXCAF.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_STEPImportXCAF.cpp new file mode 100644 index 000000000..807d4f86d --- /dev/null +++ b/src/GeomAlgoAPI/GeomAlgoAPI_STEPImportXCAF.cpp @@ -0,0 +1,409 @@ +// Copyright (C) 2014-2020 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include + +#include + +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +//============================================================================= +TopoDS_Shape getShape(const Handle(Standard_Transient) &theEnti, + const Handle(Transfer_TransientProcess) &theTP) +{ + TopoDS_Shape aResult; + Handle(Transfer_Binder) aBinder = theTP->Find(theEnti); + + if (aBinder.IsNull()) { + return aResult; + } + + aResult = TransferBRep::ShapeResult(aBinder); + + return aResult; +} + +//============================================================================= +std::shared_ptr readAttributes(STEPCAFControl_Reader &theReader, + std::shared_ptr theResultBody, + const bool theIsMaterials, + std::map< std::wstring,std::list> &theMaterialShape, + std::string& theError) +{ + // dummy XCAF Application to handle the STEP XCAF Document + Handle(XCAFApp_Application) dummy_app = XCAFApp_Application::GetApplication(); + // XCAF Document to contain the STEP/IGES file itself + Handle(TDocStd_Document) adoc; + + dummy_app->NewDocument( TCollection_ExtendedString("MDTV-CAF"), adoc); + // transfer STEP/IGES into the document, and get the main label + theReader.Transfer(adoc); + TDF_Label mainLabel = adoc->Main(); + Handle_XCAFDoc_ShapeTool shapeTool = XCAFDoc_DocumentTool::ShapeTool(mainLabel); + Handle_XCAFDoc_ColorTool colorTool = XCAFDoc_DocumentTool::ColorTool(mainLabel); + Handle(XCAFDoc_MaterialTool) materialTool = XCAFDoc_DocumentTool::MaterialTool(mainLabel); + // traverse the labels recursively to set attributes on shapes + setShapeAttributes(shapeTool, colorTool, materialTool, mainLabel, + TopLoc_Location(),theResultBody,theMaterialShape,false); + + std::shared_ptr ageom = setgeom(shapeTool,mainLabel,theError); + + STEPControl_Reader aReader = theReader.ChangeReader(); + + // BEGIN: reading materials of sub-shapes from file + if ( theIsMaterials ) + { + TopTools_IndexedMapOfShape anIndices; + TopExp::MapShapes(ageom->impl(), anIndices); + + Handle(Interface_InterfaceModel) Model = aReader.WS()->Model(); + Handle(XSControl_TransferReader) TR = aReader.WS()->TransferReader(); + if (!TR.IsNull()) { + Handle(Transfer_TransientProcess) TP = TR->TransientProcess(); + + Standard_Integer nb = Model->NbEntities(); + + for (Standard_Integer ie = 1; ie <= nb; ie++) { + Handle(Standard_Transient) enti = Model->Value(ie); + + // Store materials. + storeMaterial(theResultBody,enti, anIndices, TP, mainLabel,theMaterialShape); + } + } + } + if (adoc->CanClose() == CDM_CCS_OK) + adoc->Close(); + return ageom; +} + +//============================================================================= +std::shared_ptr setgeom(const Handle(XCAFDoc_ShapeTool) &theShapeTool, + const TDF_Label &theLabel, + std::string& theError) +{ + BRep_Builder aB; + TopoDS_Compound aCompound; + aB.MakeCompound(aCompound); + + TDF_LabelSequence aFrshapes; + theShapeTool->GetShapes(aFrshapes); + + std::shared_ptr aGeomShape(new GeomAPI_Shape); + + if (aFrshapes.Length() == 0) { + aGeomShape->setImpl(new TopoDS_Shape()); + return aGeomShape; + } else if (aFrshapes.Length() == 1) { + TopoDS_Shape shape = theShapeTool->GetShape(aFrshapes.Value(1)); + aGeomShape->setImpl(new TopoDS_Shape(shape)); + return aGeomShape; + } else { + for (Standard_Integer i=1; iGetShape(aFrshapes.Value(i)); + TDF_Label aLabel = theShapeTool->FindShape(aS, Standard_False); + if ( (!aLabel.IsNull()) && (theShapeTool->IsShape(aLabel)) ) { + if (theShapeTool->IsFree(aLabel) ) { + if (aS.IsNull()) { + continue; + } else { + if (!theShapeTool->IsReference(aLabel) ){ + for(TDF_ChildIterator anIt(aLabel); anIt.More(); anIt.Next()) { + aB.Add(aCompound, theShapeTool->GetShape(anIt.Value()) ); + } + } else { + aB.Add(aCompound, aS); + } + } + } + } + } + + TopoDS_Shape aShape = aCompound; + // Check if any BRep entity has been read, there must be at least a vertex + if ( !TopExp_Explorer( aShape, TopAbs_VERTEX ).More() ) + { + theError = "No geometrical data in the imported file."; + std::shared_ptr aGeomShape(new GeomAPI_Shape); + aGeomShape->setImpl(new TopoDS_Shape()); + return aGeomShape; + } + + aGeomShape->setImpl(new TopoDS_Shape(aShape)); + return aGeomShape; + } +} +//============================================================================= +void setShapeAttributes(const Handle(XCAFDoc_ShapeTool) &theShapeTool, + const Handle(XCAFDoc_ColorTool) &theColorTool, + const Handle(XCAFDoc_MaterialTool) &theMaterialTool, + const TDF_Label &theLabel, + const TopLoc_Location &theLoc, + std::shared_ptr theResultBody, + std::map< std::wstring,std::list> &theMaterialShape, + bool theIsRef) +{ + std::wstring aShapeName; + Handle(TDataStd_Name) aN; + + if (theLabel.FindAttribute(TDataStd_Name::GetID(), aN)) { + TCollection_ExtendedString aName = aN->Get(); + + aShapeName = Locale::Convert::toWString(TCollection_AsciiString(aName).ToCString()) ; + } + + TopLoc_Location aPartLoc = theLoc; + Handle(XCAFDoc_Location) al; + if (theLabel.FindAttribute(XCAFDoc_Location::GetID(), al)) { + if (theIsRef) + aPartLoc = aPartLoc * al->Get(); + else + aPartLoc = al->Get(); + } + + TDF_Label aRef; + if (theShapeTool->IsReference(theLabel) && theShapeTool->GetReferredShape(theLabel, aRef)) { + + setShapeAttributes( theShapeTool, theColorTool, theMaterialTool, aRef, + aPartLoc,theResultBody,theMaterialShape,true); + } + + if (theShapeTool->IsSimpleShape(theLabel) && (theIsRef || theShapeTool->IsFree(theLabel))) { + + TopoDS_Shape aShape = theShapeTool->GetShape(theLabel); + + std::shared_ptr aShapeGeom(new GeomAPI_Shape); + if (!theLoc.IsIdentity()){ + aShape.Move(theLoc); + } + aShapeGeom->setImpl(new TopoDS_Shape(aShape)); + aShapeName = theResultBody->addShapeName(aShapeGeom, aShapeName); + + + aShape.Location(theIsRef ? theLoc : aPartLoc); + int aDim = + (aShape.ShapeType() == TopAbs_VERTEX) ? + 0 : + (aShape.ShapeType() == TopAbs_EDGE || aShape.ShapeType() == TopAbs_WIRE) ? + 1 : + (aShape.ShapeType() == TopAbs_FACE || + aShape.ShapeType() == TopAbs_SHELL) ? 2 :3; + + Handle(TCollection_HAsciiString) aMatName; + Handle(TCollection_HAsciiString) aMatDescription; + Standard_Real aMatDensity; + Handle(TCollection_HAsciiString) aMatDensName; + Handle(TCollection_HAsciiString) aMatDensValType; + + if (theMaterialTool->GetMaterial(theLabel, aMatName, aMatDescription, aMatDensity, + aMatDensName, aMatDensValType)) { + std::wstring aNameMaterial = Locale::Convert::toWString(aMatName->ToCString()); + + theMaterialShape[aNameMaterial].push_back(aShapeName); + } + + Quantity_Color aCol; + if (theColorTool->GetColor(theLabel, XCAFDoc_ColorGen, aCol)) { + double r = aCol.Red(), g = aCol.Green(), b = aCol.Blue(); + std::vector ColRGB = {int(r*255),int(g*255),int(b*255)}; + theResultBody->addShapeColor(aShapeName, ColRGB); + } else if (theColorTool->GetColor(theLabel, XCAFDoc_ColorSurf, aCol)) { + double r = aCol.Red(), g = aCol.Green(), b = aCol.Blue(); + std::vector aColRGB = {int(r*255),int(g*255),int(b*255)}; + theResultBody->addShapeColor(aShapeName, aColRGB); + } else if (theColorTool->GetColor(theLabel, XCAFDoc_ColorCurv, aCol)) { + double aR = aCol.Red(), aG = aCol.Green(), aB = aCol.Blue(); + std::vector aColRGB = {int(aR*255),int(aG*255),int(aB*255)}; + theResultBody->addShapeColor(aShapeName, aColRGB); + } + // check explicit coloring of boundary entities + if (aDim == 3) { + TopExp_Explorer aXp2(aShape, TopAbs_FACE); + while(aXp2.More()) { + if (theColorTool->GetColor(aXp2.Current(), XCAFDoc_ColorGen, aCol) || + theColorTool->GetColor(aXp2.Current(), XCAFDoc_ColorSurf, aCol) || + theColorTool->GetColor(aXp2.Current(), XCAFDoc_ColorCurv, aCol)) { + double aR = aCol.Red(), aG = aCol.Green(), aB = aCol.Blue(); + TopoDS_Face aFace = TopoDS::Face(aXp2.Current()); + std::vector aColRGB = {int(aR*255),int(aG*255),int(aB*255)}; + std::wstringstream aNameFace; + TopoDS_Shape aShapeface = aXp2.Current(); + if (!theLoc.IsIdentity()){ + aShapeface.Move(theLoc); + } + aShapeGeom->setImpl(new TopoDS_Shape(aShapeface)); + theResultBody->addShapeColor( + theResultBody->addShapeName(aShapeGeom , aNameFace.str()), aColRGB); + } + aXp2.Next(); + } + } + if (aDim == 2) { + TopExp_Explorer aXp1(aShape, TopAbs_EDGE); + while(aXp1.More()) { + if (theColorTool->GetColor(aXp1.Current(), XCAFDoc_ColorGen, aCol) || + theColorTool->GetColor(aXp1.Current(), XCAFDoc_ColorSurf, aCol) || + theColorTool->GetColor(aXp1.Current(), XCAFDoc_ColorCurv, aCol)) { + double aR = aCol.Red(), aG = aCol.Green(), aB = aCol.Blue(); + std::vector aColRGB = {int(aR*255),int(aG*255),int(aB*255)}; + std::wstringstream aNameEdge; + aNameEdge << L"Edge_"<< aShapeName; + aShapeGeom->setImpl(new TopoDS_Shape(aXp1.Current() )); + theResultBody->addShapeColor( + theResultBody->addShapeName(aShapeGeom , aNameEdge.str()), aColRGB); + } + aXp1.Next(); + } + } + } else { + if (!theShapeTool->IsReference(theLabel) ){ + TopoDS_Shape aShape = theShapeTool->GetShape(theLabel); + + std::shared_ptr aShapeGeom(new GeomAPI_Shape); + if (!theLoc.IsIdentity()){ + aShape.Move(theLoc); + } + aShapeGeom->setImpl(new TopoDS_Shape(aShape)); + aShapeName = theResultBody->addShapeName(aShapeGeom, aShapeName); + } + for(TDF_ChildIterator anIt(theLabel); anIt.More(); anIt.Next()) { + + setShapeAttributes( theShapeTool, theColorTool, theMaterialTool, + anIt.Value(), aPartLoc,theResultBody,theMaterialShape, theIsRef); + } + } +} + +//============================================================================= +void storeMaterial( std::shared_ptr theResultBody, + const Handle(Standard_Transient) &theEnti, + const TopTools_IndexedMapOfShape &theIndices, + const Handle(Transfer_TransientProcess) &theTP, + const TDF_Label &theShapeLabel, + std::map< std::wstring, std::list> &theMaterialShape ) +{ + // Treat Product Definition Shape only. + Handle(StepRepr_ProductDefinitionShape) aPDS = + Handle(StepRepr_ProductDefinitionShape)::DownCast(theEnti); + Handle(StepBasic_ProductDefinition) aProdDef; + + if (aPDS.IsNull() == Standard_False) { + // Product Definition Shape ==> Product Definition + aProdDef = aPDS->Definition().ProductDefinition(); + } + + if (aProdDef.IsNull() == Standard_False) { + // Product Definition ==> Property Definition + const Interface_Graph &aGraph = theTP->Graph(); + Interface_EntityIterator aSubs = aGraph.Sharings(aProdDef); + TopoDS_Shape aShape; + + for(aSubs.Start(); aSubs.More(); aSubs.Next()) { + Handle(StepRepr_PropertyDefinition) aPropD = + Handle(StepRepr_PropertyDefinition)::DownCast(aSubs.Value()); + + if (aPropD.IsNull() == Standard_False) { + // Property Definition ==> Representation. + Interface_EntityIterator aSubs1 = aGraph.Sharings(aPropD); + + for(aSubs1.Start(); aSubs1.More(); aSubs1.Next()) { + Handle(StepRepr_PropertyDefinitionRepresentation) aPDR = + Handle(StepRepr_PropertyDefinitionRepresentation):: + DownCast(aSubs1.Value()); + + if (aPDR.IsNull() == Standard_False) { + // Property Definition ==> Material Name. + Handle(StepRepr_Representation) aRepr = aPDR->UsedRepresentation(); + + if (aRepr.IsNull() == Standard_False) { + Standard_Integer anIr; + + for(anIr = 1; anIr <= aRepr->NbItems(); anIr++) { + Handle(StepRepr_RepresentationItem) aRI = aRepr->ItemsValue(anIr); + Handle(StepRepr_DescriptiveRepresentationItem) aDRI = + Handle(StepRepr_DescriptiveRepresentationItem)::DownCast(aRI); + + if (aDRI.IsNull() == Standard_False) { + // Get shape from Product Definition + Handle(TCollection_HAsciiString) aMatName = aDRI->Name(); + if (aMatName.IsNull() == Standard_False) { + TCollection_ExtendedString + aMatNameExt (aMatName->ToCString()); + + if (aShape.IsNull()) { + //Get the shape. + aShape = getShape(aProdDef, theTP); + if (aShape.IsNull()) { + return; + } + } + + // as PRODUCT can be included in the main shape + // several times, we look here for all iclusions. + Standard_Integer anISub, aNbSubs = theIndices.Extent(); + + for (anISub = 1; anISub <= aNbSubs; anISub++) { + TopoDS_Shape aSub = theIndices.FindKey(anISub); + + if (aSub.IsPartner(aShape)) { + std::shared_ptr aShapeGeom(new GeomAPI_Shape); + aShapeGeom->setImpl(new TopoDS_Shape(aSub)); + std::wstring aNom = theResultBody->findShapeName(aShapeGeom); + std::wstring aMName= Locale::Convert::toWString(aMatName->ToCString()); + theMaterialShape[aMName].push_back(aNom); + + } + } + } + } + } + } + } + } + } + } + } +} + diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_STEPImportXCAF.h b/src/GeomAlgoAPI/GeomAlgoAPI_STEPImportXCAF.h new file mode 100644 index 000000000..d43019068 --- /dev/null +++ b/src/GeomAlgoAPI/GeomAlgoAPI_STEPImportXCAF.h @@ -0,0 +1,66 @@ +// Copyright (C) 2014-2020 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifndef GEOMALGOAPI_STEPIMPORTXCAF_H_ +#define GEOMALGOAPI_STEPIMPORTXCAF_H_ + +#include + +#include +#include + +#include + +#include +#include + + /// read Attributs of step file + GEOMALGOAPI_EXPORT + std::shared_ptr readAttributes(STEPCAFControl_Reader &theReader, + std::shared_ptr theResultBody, + const bool theMaterials, + std::map< std::wstring,std::list> &theMaterialShape, + std::string& theError); +/// read attributs for label + GEOMALGOAPI_EXPORT + void setShapeAttributes(const Handle(XCAFDoc_ShapeTool) &theShapeTool, + const Handle(XCAFDoc_ColorTool) &theColorTool, + const Handle(XCAFDoc_MaterialTool) &TheMaterialTool, + const TDF_Label &theLabel, + const TopLoc_Location &theLoc, + std::shared_ptr theResultBody, + std::map< std::wstring, std::list> &theMaterialShape, + bool theIsRef); + +// read geometry +GEOMALGOAPI_EXPORT +std::shared_ptr setgeom(const Handle(XCAFDoc_ShapeTool) &shapeTool, + const TDF_Label &theLabel, + std::string& theError); + +// store Materiel for theShapeLabel in the map theMaterialShape +GEOMALGOAPI_EXPORT +void storeMaterial(std::shared_ptr theResultBody, + const Handle(Standard_Transient) &theEnti, + const TopTools_IndexedMapOfShape &theIndices, + const Handle(Transfer_TransientProcess) &theTP, + const TDF_Label &theShapeLabel, + std::map< std::wstring, std::list> &theMaterialShape); + +#endif /* GEOMALGOAPI_STEPIMPORTXCAF_H_ */ diff --git a/src/Model/Model_Objects.cpp b/src/Model/Model_Objects.cpp index 2c32988e2..c7ea99cb0 100644 --- a/src/Model/Model_Objects.cpp +++ b/src/Model/Model_Objects.cpp @@ -1226,7 +1226,8 @@ bool Model_Objects::hasCustomName(DataPtr theFeatureData, void Model_Objects::storeResult(std::shared_ptr theFeatureData, std::shared_ptr theResult, - const int theResultIndex) + const int theResultIndex, + const std::wstring& theNameShape) { theResult->init(); theResult->setDoc(myDoc); @@ -1240,11 +1241,15 @@ void Model_Objects::storeResult(std::shared_ptr theFeatureData, theResult->data()->setName(L""); } else { std::wstringstream aName; - aName << aNewName; - // if there are several results (issue #899: any number of result), - // add unique prefix starting from second - if (theResultIndex > 0 || theResult->groupName() == ModelAPI_ResultBody::group()) - aName << "_" << theResultIndex + 1; + if ( theNameShape != L"" ){ + aName << theNameShape; + } else { + aName << aNewName; + // if there are several results (issue #899: any number of result), + // add unique prefix starting from second + if (theResultIndex > 0 || theResult->groupName() == ModelAPI_ResultBody::group()) + aName << "_" << theResultIndex + 1; + } aNewName = aName.str(); } theResult->data()->setName(aNewName); @@ -1269,7 +1274,9 @@ std::shared_ptr Model_Objects::createConstruction( } std::shared_ptr Model_Objects::createBody( - const std::shared_ptr& theFeatureData, const int theIndex) + const std::shared_ptr& theFeatureData, + const int theIndex, + const std::wstring& theNameShape) { TDF_Label aLab = resultLabel(theFeatureData, theIndex); TDataStd_Comment::Set(aLab, ModelAPI_ResultBody::group().c_str()); @@ -1280,7 +1287,7 @@ std::shared_ptr Model_Objects::createBody( } if (!aResult.get()) { aResult = std::shared_ptr(new Model_ResultBody); - storeResult(theFeatureData, aResult, theIndex); + storeResult(theFeatureData, aResult, theIndex, theNameShape); } return aResult; } diff --git a/src/Model/Model_Objects.h b/src/Model/Model_Objects.h index c929be8ce..3ae6c713a 100644 --- a/src/Model/Model_Objects.h +++ b/src/Model/Model_Objects.h @@ -124,7 +124,8 @@ class Model_Objects const std::shared_ptr& theFeatureData, const int theIndex = 0); /// Creates a body result std::shared_ptr createBody( - const std::shared_ptr& theFeatureData, const int theIndex = 0); + const std::shared_ptr& theFeatureData, const int theIndex = 0, + const std::wstring& theNameShape = L""); /// Creates a part result std::shared_ptr createPart( const std::shared_ptr& theFeatureData, const int theIndex = 0); @@ -224,7 +225,8 @@ class Model_Objects //! (attaches 'data' of result to tree) void storeResult(std::shared_ptr theFeatureData, std::shared_ptr theResult, - const int theResultIndex = 0); + const int theResultIndex = 0, + const std::wstring& theNameShape = L""); //! returns the label of result by index; creates this label if it was not created before TDF_Label resultLabel(const std::shared_ptr& theFeatureData, diff --git a/src/Model/Model_ResultBody.cpp b/src/Model/Model_ResultBody.cpp index 7d6918c6a..c58ed7b06 100644 --- a/src/Model/Model_ResultBody.cpp +++ b/src/Model/Model_ResultBody.cpp @@ -30,6 +30,8 @@ #include #include #include +#include +#include #include #include @@ -233,6 +235,57 @@ void Model_ResultBody::updateConcealment() } } +void Model_ResultBody::addShapeColor( const std::wstring& theName,std::vector& color) { + + if (myColorsShape.find(theName) == myColorsShape.end()) + myColorsShape[ theName ] = color; +} + +std::wstring Model_ResultBody::addShapeName(std::shared_ptr theshape, + const std::wstring& theName ){ + + int indice = 1; + std::wstringstream aName; + aName << theName; + while(myNamesShape.find(aName.str()) != myNamesShape.end() ){ + aName.str(L""); + aName << theName << L"__" << indice; + indice++; + } + myNamesShape[ aName.str() ] = theshape; + + return aName.str(); +} + +std::wstring Model_ResultBody::findShapeName(std::shared_ptr theShape){ + + TopoDS_Shape aShape = theShape->impl(); + for (std::map< std::wstring, std::shared_ptr >::iterator it = + myNamesShape.begin(); + it != myNamesShape.end(); + ++it) + { + TopoDS_Shape curSelectedShape = (*it).second->impl(); + if ((aShape.IsSame(curSelectedShape))) { + return (*it).first; + } + } + return L"material not found" ; +} + +void Model_ResultBody::setShapeName( + std::map< std::wstring, std::shared_ptr>& theShapeName, + std::map< std::wstring, std::vector>& theColorsShape) +{ + myNamesShape = theShapeName; + myColorsShape = theColorsShape; +} + +void Model_ResultBody::clearShapeNameAndColor(){ + myNamesShape.clear(); + myColorsShape.clear(); +} + void Model_ResultBody::updateSubs(const std::shared_ptr& theThisShape, const bool theShapeChanged) { @@ -262,13 +315,33 @@ void Model_ResultBody::updateSubs(const std::shared_ptr& theThisS aShape->setImpl(new TopoDS_Shape(aShapesIter.Value())); ResultBodyPtr aSub; if (mySubs.size() <= aSubIndex) { // it is needed to create a new sub-result - aSub = anObjects->createBody(this->data(), aSubIndex); + std::wstring thenameshape = L""; + // find shape name read + for (std::map< std::wstring, std::shared_ptr >::iterator it = + myNamesShape.begin(); + it != myNamesShape.end(); + ++it) + { + TopoDS_Shape curSelectedShape = (*it).second->impl(); + if (!(aShapesIter.Value().IsSame(curSelectedShape))) continue; + thenameshape = (*it).first; + break; + } + aSub = anObjects->createBody(this->data(), aSubIndex,thenameshape); + //finf color read + std::map< std::wstring, std::vector>::iterator itColor = + myColorsShape.find(thenameshape); + if (itColor != myColorsShape.end()){ + ModelAPI_Tools::setColor(aSub,(*itColor).second); + } + aSub->setShapeName(myNamesShape,myColorsShape); mySubs.push_back(aSub); mySubsMap[aSub] = int(mySubs.size() - 1); if (isConcealed()) { // for issue #2579 note7 aSub->ModelAPI_ResultBody::setIsConcealed(true); std::dynamic_pointer_cast(aSub)->updateConcealment(); } + } else { // just update shape of this result aSub = mySubs[aSubIndex]; } diff --git a/src/Model/Model_ResultBody.h b/src/Model/Model_ResultBody.h index 94e9d9b7c..fff856c5f 100644 --- a/src/Model/Model_ResultBody.h +++ b/src/Model/Model_ResultBody.h @@ -126,7 +126,7 @@ protected: const GeomShapePtr& theThisShape, const std::list& theOlds, const std::shared_ptr theMakeShape, const bool isGenerated); - // Checks the state of children and parents to send events of creation/erase when needed + /// Checks the state of children and parents to send events of creation/erase when needed void updateConcealment(); /// Adds to theOldForSub only old shapes that where used for theSub creation @@ -134,6 +134,31 @@ protected: const std::list& theAllOlds, std::list& theOldForSub); friend class Model_Objects; + + /// Add shape Name for read shape in step file + std::wstring addShapeName(std::shared_ptr,const std::wstring& theName) override; + + /// Add color for shape Name read shape in step file + void addShapeColor( const std::wstring& theName,std::vector& color) override; + + /// Set the map of name and color read shape in step file + void setShapeName(std::map< std::wstring, + std::shared_ptr>& theShapeName, + std::map< std::wstring, + std::vector>& theColorsShape) override; + + /// find the name of shapp read in step file + std::wstring findShapeName(std::shared_ptr theShape) override; + + /// Clear the map of name and color read shape in step file + void clearShapeNameAndColor() override; + + /// map with the name read in step file and shape + std::map< std::wstring, std::shared_ptr > myNamesShape; + + /// map with the name contruct and color read + std::map< std::wstring, std::vector> myColorsShape; + }; #endif diff --git a/src/ModelAPI/CMakeLists.txt b/src/ModelAPI/CMakeLists.txt index 68b34a177..8d943e9c8 100644 --- a/src/ModelAPI/CMakeLists.txt +++ b/src/ModelAPI/CMakeLists.txt @@ -117,7 +117,6 @@ SET(PROJECT_SOURCES SET(PROJECT_LIBRARIES Config GeomAPI - Locale ) SET(CMAKE_SWIG_FLAGS -threads -w325,321,362,383,302,403,451,473) ADD_DEFINITIONS(-DMODELAPI_EXPORTS) @@ -131,6 +130,11 @@ INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/src/Config ${PROJECT_SOURCE_DIR}/src/GeomAPI ${PROJECT_SOURCE_DIR}/src/GeomAlgoAPI ${PROJECT_SOURCE_DIR}/src/Locale + ${OpenCASCADE_INCLUDE_DIR} + ${OpenCASCADE_DataExchange_LIBRARIES} + ${OpenCASCADE_ModelingAlgorithms_LIBRARIES} + ${OpenCASCADE_ApplicationFramework_LIBRARIES} + ) diff --git a/src/ModelAPI/ModelAPI_ResultBody.h b/src/ModelAPI/ModelAPI_ResultBody.h index c88fb08fc..f51233b6f 100644 --- a/src/ModelAPI/ModelAPI_ResultBody.h +++ b/src/ModelAPI/ModelAPI_ResultBody.h @@ -24,6 +24,8 @@ #include #include #include +#include +#include class ModelAPI_BodyBuilder; class GeomAlgoAPI_MakeShape; @@ -183,6 +185,26 @@ public: /// Cleans cash related to the already stored elements MODELAPI_EXPORT virtual void cleanCash() = 0; + /// Add shape Name for read shape in step file + MODELAPI_EXPORT virtual std::wstring addShapeName + (std::shared_ptr,const std::wstring& theName) = 0; + + /// Add color for shape Name read shape in step file + MODELAPI_EXPORT virtual void addShapeColor + (const std::wstring& theName,std::vector& theColor) = 0; + + /// Set the map of name and color read shape in step file + MODELAPI_EXPORT virtual void setShapeName + (std::map< std::wstring, std::shared_ptr > &theShapeName, + std::map< std::wstring, std::vector> & theColorsShape) = 0; + + /// Clear the map of name and color read shape in step file + MODELAPI_EXPORT virtual void clearShapeNameAndColor() = 0; + + /// find the name of shapp read in step file + MODELAPI_EXPORT virtual std::wstring findShapeName(std::shared_ptr theShape) = 0; + + protected: /// Default constructor accessible only from Model_Objects MODELAPI_EXPORT ModelAPI_ResultBody(); diff --git a/src/PythonAPI/model/exchange/__init__.py b/src/PythonAPI/model/exchange/__init__.py index 0e71bf080..800ab45f9 100644 --- a/src/PythonAPI/model/exchange/__init__.py +++ b/src/PythonAPI/model/exchange/__init__.py @@ -19,7 +19,7 @@ """Package for Exchange plugin for the Parametric Geometry API of the Modeler. """ -from ExchangeAPI import addImport, exportToFile, exportToXAO, exportToSTL +from ExchangeAPI import addImport, addImportSTEP, exportToFile, exportToXAO, exportToSTL from ExchangeAPI import exportPart, importPart from .tools import *