From: mpv Date: Tue, 18 Jan 2022 08:21:17 +0000 (+0300) Subject: Updates prepared for CAD Builder 1.3.0 version release X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=ea23472f1392c3c079255c7d04576baaf08466ac;p=modules%2Fshaper.git Updates prepared for CAD Builder 1.3.0 version release --- diff --git a/src/Config/Config_FeatureReader.cpp b/src/Config/Config_FeatureReader.cpp index 5f397d638..3d53a63d6 100644 --- a/src/Config/Config_FeatureReader.cpp +++ b/src/Config/Config_FeatureReader.cpp @@ -40,9 +40,11 @@ Config_FeatureReader::Config_FeatureReader(const std::string& theXmlFile, const std::string& theLibraryName, + const std::string& theDocSection, const char* theEventGenerated) : Config_XMLReader(theXmlFile), myLibraryName(theLibraryName), + myLibraryDocSection(theDocSection), myEventGenerated(theEventGenerated ? theEventGenerated : Config_FeatureMessage::GUI_EVENT()), myIsProcessWidgets(theEventGenerated != NULL) { @@ -176,8 +178,11 @@ void Config_FeatureReader::fillFeature(xmlNodePtr theFeatureNode, outFeatureMessage->setInternal(isInternal); std::string aHelpFile = getProperty(theFeatureNode, HELP_FILE); - if (!aHelpFile.empty()) - outFeatureMessage->setHelpFileName(myLibraryName + "/" + aHelpFile); + if (!aHelpFile.empty()) { + aHelpFile = + (myLibraryDocSection.empty() ? myLibraryName : myLibraryDocSection) + "/" + aHelpFile; + outFeatureMessage->setHelpFileName(aHelpFile); + } bool isHideFaces = getBooleanAttribute(theFeatureNode, HIDEFACES_PANEL, false); outFeatureMessage->setHideFacesPanel(isHideFaces); diff --git a/src/Config/Config_FeatureReader.h b/src/Config/Config_FeatureReader.h index 015090889..e3d1098f9 100644 --- a/src/Config/Config_FeatureReader.h +++ b/src/Config/Config_FeatureReader.h @@ -40,6 +40,7 @@ class Config_FeatureReader : public Config_XMLReader /// Constructor Config_FeatureReader(const std::string& theXmlFile, const std::string& theLibraryName, + const std::string& theDocSection = std::string(), const char* theEventGenerated = 0); virtual ~Config_FeatureReader(); /// Returns list of all features defined in reader's file @@ -61,6 +62,7 @@ class Config_FeatureReader : public Config_XMLReader private: std::string myLibraryName; + std::string myLibraryDocSection; std::list myFeatures; /// event generated on feature data sending, by default it is Config_FeatureMessage::GUI_EVENT() diff --git a/src/Config/Config_Keywords.h b/src/Config/Config_Keywords.h index 9774c3519..4149e3816 100644 --- a/src/Config/Config_Keywords.h +++ b/src/Config/Config_Keywords.h @@ -145,6 +145,8 @@ MAYBE_UNUSED const static char* PLUGIN_LIBRARY = "library"; MAYBE_UNUSED const static char* PLUGIN_SCRIPT = "script"; MAYBE_UNUSED const static char* PLUGIN_DEPENDENCY = "dependency"; MAYBE_UNUSED const static char* PLUGIN_USES = "uses"; +MAYBE_UNUSED const static char* PLUGIN_DOCSECTION = "docsection"; +MAYBE_UNUSED const static char* PLUGIN_LICENSE = "license"; /* * Hardcoded xml entities of dataModel.xml diff --git a/src/Config/Config_ModuleReader.cpp b/src/Config/Config_ModuleReader.cpp index ca2bd6d85..83ea39d23 100644 --- a/src/Config/Config_ModuleReader.cpp +++ b/src/Config/Config_ModuleReader.cpp @@ -62,6 +62,16 @@ const std::map& Config_ModuleReader::featuresInFiles() return myFeaturesInFiles; } +const std::map& Config_ModuleReader::proprietaryFeatures() const +{ + return myProprietaryFeatures; +} + +const std::set& Config_ModuleReader::proprietaryPlugins() const +{ + return myProprietaryPlugins; +} + const std::set& Config_ModuleReader::modulePluginFiles() const { return myPluginFiles; @@ -81,6 +91,10 @@ std::string Config_ModuleReader::getModuleName() void Config_ModuleReader::addFeature(const std::string& theFeatureName, const std::string& thePluginConfig) { + if (myProprietaryFeatures.count(theFeatureName)) { + myProprietaryFeatures.erase(theFeatureName); + } + if (myFeaturesInFiles.count(theFeatureName)) { std::string anErrorMsg = "Can not register feature '%1' in plugin '%2'." " There is a feature with the same ID."; @@ -92,6 +106,21 @@ void Config_ModuleReader::addFeature(const std::string& theFeatureName, myFeaturesInFiles[theFeatureName] = thePluginConfig; } +void Config_ModuleReader::addFeatureRequireLicense(const std::string& theFeatureName, + const std::string& thePluginConfig) +{ + if (myFeaturesInFiles.count(theFeatureName) || + myProprietaryFeatures.count(theFeatureName)) { + std::string anErrorMsg = "Can not register feature '%1' in plugin '%2'." + " There is a feature with the same ID."; + Events_InfoMessage("Config_ModuleReader", anErrorMsg) + .arg(theFeatureName).arg(thePluginConfig).send(); + return; + } + + myProprietaryFeatures[theFeatureName] = thePluginConfig; +} + void Config_ModuleReader::processNode(xmlNodePtr theNode) { if (isNode(theNode, NODE_PLUGIN, NULL)) { @@ -103,6 +132,7 @@ void Config_ModuleReader::processNode(xmlNodePtr theNode) std::string aPluginLibrary = getProperty(theNode, PLUGIN_LIBRARY); std::string aPluginScript = getProperty(theNode, PLUGIN_SCRIPT); std::string aPluginName = addPlugin(aPluginLibrary, aPluginScript, aPluginConf); + std::string aPluginDocSection = getProperty(theNode, PLUGIN_DOCSECTION); std::string aUsesPlugin = getProperty(theNode, PLUGIN_USES); if (!aUsesPlugin.empty()) { // send information about the plugin dependencies std::shared_ptr aMess(new Config_PluginMessage( @@ -111,10 +141,19 @@ void Config_ModuleReader::processNode(xmlNodePtr theNode) Events_Loop::loop()->send(aMess); } - std::list aFeatures = importPlugin(aPluginName, aPluginConf); + std::string aLicense = getProperty(theNode, PLUGIN_LICENSE); + std::transform(aLicense.begin(), aLicense.end(), aLicense.begin(), ::tolower); + bool isLicensed = aLicense == "true"; + if (isLicensed) + myProprietaryPlugins.insert(aPluginName); + + std::list aFeatures = importPlugin(aPluginName, aPluginConf, aPluginDocSection); std::list::iterator it = aFeatures.begin(); for (; it != aFeatures.end(); it++) { - addFeature(*it, aPluginConf); + if (isLicensed) + addFeatureRequireLicense(*it, aPluginConf); + else + addFeature(*it, aPluginConf); } } } @@ -137,7 +176,8 @@ bool Config_ModuleReader::hasRequiredModules(xmlNodePtr theNode) const } std::list Config_ModuleReader::importPlugin(const std::string& thePluginLibrary, - const std::string& thePluginXmlConf) + const std::string& thePluginXmlConf, + const std::string& thePluginDocSection) { if (thePluginXmlConf.empty()) { //probably a third party library loadLibrary(thePluginLibrary); @@ -146,6 +186,7 @@ std::list Config_ModuleReader::importPlugin(const std::string& theP Config_FeatureReader aReader = Config_FeatureReader(thePluginXmlConf, thePluginLibrary, + thePluginDocSection, myEventGenerated); aReader.readAll(); return aReader.features(); diff --git a/src/Config/Config_ModuleReader.h b/src/Config/Config_ModuleReader.h index b5533bda5..24ae9a3b1 100644 --- a/src/Config/Config_ModuleReader.h +++ b/src/Config/Config_ModuleReader.h @@ -49,6 +49,12 @@ class Config_ModuleReader : public Config_XMLReader /// Returns map that describes which file contains a feature /// (the feature is key, the file is value) CONFIG_EXPORT const std::map& featuresInFiles() const; + /// Returns map containing features, which have licensed. + /// The valid license should be confirmed first + /// (the feature is key, the file is value) + CONFIG_EXPORT const std::map& proprietaryFeatures() const; + /// Returns proprietary plugins + CONFIG_EXPORT const std::set& proprietaryPlugins() const; /// Returns list of module's xml files CONFIG_EXPORT const std::set& modulePluginFiles() const; /// Returns module name: an xml attribute from the root of the plugins.xml: @@ -77,7 +83,8 @@ class Config_ModuleReader : public Config_XMLReader bool hasRequiredModules(xmlNodePtr aNode) const; /// reads info about plugin's features from plugin xml description std::list importPlugin(const std::string& thePluginLibrary, - const std::string& thePluginFile); + const std::string& thePluginFile, + const std::string& thePluginDocSection); /// stores information about plugin in the internal cache std::string addPlugin(const std::string& aPluginLibrary, const std::string& aPluginScript, @@ -85,14 +92,22 @@ class Config_ModuleReader : public Config_XMLReader /// Save feature in myFeaturesInFiles. /// Generates an error if the feature name is already registered. void addFeature(const std::string& theFeatureName, const std::string& thePluginConfig); + /// Save feature in myFeaturesRequireLicense. + /// Generates an error if the feature name is already registered. + void addFeatureRequireLicense(const std::string& theFeatureName, + const std::string& thePluginConfig); private: std::map myFeaturesInFiles; ///< a feature name is key, a file is value + /// list of features, which need a license, and their config files + std::map myProprietaryFeatures; std::set myPluginFiles; ///< a feature name is key, a file is value /// a plugin name is key, a plugin type is value static std::map myPluginTypes; static std::set myDependencyModules; ///< set of loaded modules const char* myEventGenerated; ///< gives ability to send Feature_Messages to various listeners + + std::set myProprietaryPlugins; ///< list of plugins protected by license }; #endif /* CONFIG_XMLMODULEREADER_H_ */ diff --git a/src/ConnectorPlugin/ConnectorPlugin_ExportFeature.py b/src/ConnectorPlugin/ConnectorPlugin_ExportFeature.py index 3a714b066..da88d6c2a 100644 --- a/src/ConnectorPlugin/ConnectorPlugin_ExportFeature.py +++ b/src/ConnectorPlugin/ConnectorPlugin_ExportFeature.py @@ -68,8 +68,8 @@ class ExportFeature(ModelAPI.ModelAPI_Feature): for aResIndex in range(self.Part.size(aResultType)): anObject = self.Part.object(aResultType, aResIndex) aResult = model.objectToResult(anObject) - # do nt export picture - if aResult.hasTextureFile() is True: + # do not export picture + if aResult.hasTexture() is True: continue if not aResult is None: if (not aResult.shape() or aResult.shape().isNull()) and isPart: diff --git a/src/ConnectorPlugin/ConnectorPlugin_PublishToStudyFeature.py b/src/ConnectorPlugin/ConnectorPlugin_PublishToStudyFeature.py index 8da67a31e..a721ad73b 100644 --- a/src/ConnectorPlugin/ConnectorPlugin_PublishToStudyFeature.py +++ b/src/ConnectorPlugin/ConnectorPlugin_PublishToStudyFeature.py @@ -93,7 +93,7 @@ class PublishToStudyFeature(ModelAPI.ModelAPI_Feature): aResObject = aPartDoc.object(model.ModelAPI_ResultBody_group(), aResId) aRes = model.objectToResult(aResObject) #do not export images - if aRes.hasTextureFile() is True: + if aRes.hasTexture() is True: continue aResFeatureId = str(aPartDoc.feature(aRes).data().featureId()) if aResFeatureId in aFeaturesIndices: diff --git a/src/ExchangeAPI/CMakeLists.txt b/src/ExchangeAPI/CMakeLists.txt index d241e7fcb..33ac73255 100644 --- a/src/ExchangeAPI/CMakeLists.txt +++ b/src/ExchangeAPI/CMakeLists.txt @@ -18,6 +18,7 @@ # INCLUDE(Common) +INCLUDE(UseQtExt) SET(PROJECT_HEADERS ExchangeAPI.h @@ -34,6 +35,7 @@ SET(PROJECT_LIBRARIES ModelAPI ModelHighAPI GeomAlgoAPI + ${QT_LIBRARIES} ) INCLUDE_DIRECTORIES( @@ -41,6 +43,7 @@ INCLUDE_DIRECTORIES( ${PROJECT_SOURCE_DIR}/src/ModelAPI ${PROJECT_SOURCE_DIR}/src/ModelHighAPI ${PROJECT_SOURCE_DIR}/src/GeomAlgoAPI + ${QT_INCLUDES} ) # Plugin headers dependency @@ -51,6 +54,9 @@ INCLUDE_DIRECTORIES( ${PROJECT_SOURCE_DIR}/src/ExchangePlugin ) +# additional preprocessor / compiler flags +ADD_DEFINITIONS(${QT_DEFINITIONS}) + #TODO(spo): is ${OpenCASCADE_DEFINITIONS} necessary? ADD_DEFINITIONS(-DEXCHANGEAPI_EXPORTS ${OpenCASCADE_DEFINITIONS}) ADD_LIBRARY(ExchangeAPI SHARED ${PROJECT_SOURCES} ${PROJECT_HEADERS}) diff --git a/src/ExchangeAPI/ExchangeAPI_Import.cpp b/src/ExchangeAPI/ExchangeAPI_Import.cpp index cee25a91a..eae652434 100644 --- a/src/ExchangeAPI/ExchangeAPI_Import.cpp +++ b/src/ExchangeAPI/ExchangeAPI_Import.cpp @@ -26,11 +26,17 @@ #include //-------------------------------------------------------------------------------------- #include +#include #include #include #include //-------------------------------------------------------------------------------------- #include +//-------------------------------------------------------------------------------------- +#include +#include +#include +#include ExchangeAPI_Import::ExchangeAPI_Import( const std::shared_ptr & theFeature) @@ -245,7 +251,44 @@ void ExchangeAPI_Import_Image::dump(ModelHighAPI_Dumper& theDumper) const std::string aPartName = theDumper.name(aBase->document()); std::string aFilePath = - aBase->string(ExchangePlugin_Import_ImageFeature::FILE_PATH_ID())->value(); + aBase->string(ExchangePlugin_Import_ImageFeature::FILE_PATH_ID())->value(); + + // store image into a new file near the dumped python script + ResultPtr aResult = aBase->firstResult(); + std::string aNewImageDir = theDumper.getDumpDir(); + if (aResult.get() && aResult->hasTexture()) { + // get image data + int aWidth, aHeight; + std::string aFormat; + std::list aByteList; + AttributeImagePtr anImageAttr = + aResult->data()->image(ModelAPI_ResultBody::IMAGE_ID()); + anImageAttr->texture(aWidth, aHeight, aByteList, aFormat); + + // convert image data to QPixmap + uchar* arr = new uchar[aByteList.size()]; + std::copy(aByteList.begin(), aByteList.end(), arr); + QImage image (arr, aWidth, aHeight, QImage::Format_ARGB32); + QPixmap pixmap = QPixmap::fromImage( image ); + + // get new file name + std::wstring aName = aBase->name(); + std::string anImageName (aName.begin(), aName.end()); + std::string aNewImageFile = anImageName + "." + aFormat; + QFileInfo aNewFileInfo (QDir(aNewImageDir.c_str()), aNewImageFile.c_str()); + for (int ii = 1; QFile::exists(aNewFileInfo.absoluteFilePath()); ii++) { + // construct the new file name by adding the unique number + aNewImageFile = anImageName + "_" + std::to_string(ii) + "." + aFormat; + aNewFileInfo.setFile(QDir(aNewImageDir.c_str()), aNewImageFile.c_str()); + } + + // write image to a new file + if (pixmap.save(aNewFileInfo.absoluteFilePath())) { + // to dump new file name + aFilePath = aNewFileInfo.absoluteFilePath().toStdString(); + } + delete [] arr; + } theDumper << aBase << " = model.addImportImage(" << aPartName << ", \"" << aFilePath << "\")" << std::endl; diff --git a/src/ExchangePlugin/CMakeLists.txt b/src/ExchangePlugin/CMakeLists.txt index 7efb757ff..9ffa2d408 100755 --- a/src/ExchangePlugin/CMakeLists.txt +++ b/src/ExchangePlugin/CMakeLists.txt @@ -19,6 +19,7 @@ INCLUDE(Common) INCLUDE(UnitTest) +INCLUDE(UseQtExt) INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/src/Events ${PROJECT_SOURCE_DIR}/src/Config @@ -32,8 +33,12 @@ INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/src/Events ${PROJECT_SOURCE_DIR}/src/ConstructionPlugin ${PROJECT_SOURCE_DIR}/src/PartSetPlugin ${OpenCASCADE_INCLUDE_DIR} + ${QT_INCLUDES} ) +# additional preprocessor / compiler flags +ADD_DEFINITIONS(${QT_DEFINITIONS}) + SET(PROJECT_HEADERS ExchangePlugin.h ExchangePlugin_Plugin.h @@ -82,6 +87,7 @@ SET(PROJECT_LIBRARIES GeomAlgoAPI GeomValidators XAOShaper + ${QT_LIBRARIES} ) # default dump approaches (will be set if not initialized) diff --git a/src/ExchangePlugin/ExchangePlugin_Dump.cpp b/src/ExchangePlugin/ExchangePlugin_Dump.cpp index 418ab1370..b65b28970 100644 --- a/src/ExchangePlugin/ExchangePlugin_Dump.cpp +++ b/src/ExchangePlugin/ExchangePlugin_Dump.cpp @@ -24,11 +24,14 @@ #include #include #include +#include #include #include +#include + #ifdef EXCHANGEPLUGIN_DUMP_NAMING static const bool THE_DUMP_NAMING = true; #else @@ -67,11 +70,15 @@ void ExchangePlugin_Dump::initAttributes() data()->addAttribute(EXPORT_VARIABLES_ID(), ModelAPI_AttributeBoolean::typeId()); + data()->addAttribute(DUMP_DIR_ID(), ModelAPI_AttributeString::typeId()); + // default values boolean(TOPOLOGICAL_NAMING_DUMP_ID())->setValue(THE_DUMP_NAMING); boolean(GEOMETRIC_DUMP_ID())->setValue(THE_DUMP_GEO); boolean(WEAK_NAMING_DUMP_ID())->setValue(THE_DUMP_WEAK); boolean(EXPORT_VARIABLES_ID())->setValue(false); + + ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), DUMP_DIR_ID()); } void ExchangePlugin_Dump::execute() @@ -162,6 +169,14 @@ void ExchangePlugin_Dump::dump(const std::string& theFileName) aDumper->addCustomStorage(aWeakNamingStorage); } + // pass dump directory to the dumper + AttributeStringPtr aDumpDirAttr = + this->string(ExchangePlugin_Dump::DUMP_DIR_ID()); + std::string aDumpDir; + if (aDumpDirAttr.get() && !aDumpDirAttr->isInitialized()) + aDumpDir = GeomAlgoAPI_Tools::File_Tools::path(theFileName); + aDumper->setDumpDir(aDumpDir); + if (!aDumper->process(aDoc, theFileName)) { setError("An error occurred while dumping to " + theFileName); } else { diff --git a/src/ExchangePlugin/ExchangePlugin_Dump.h b/src/ExchangePlugin/ExchangePlugin_Dump.h index 1fa72d984..e9858a7f9 100644 --- a/src/ExchangePlugin/ExchangePlugin_Dump.h +++ b/src/ExchangePlugin/ExchangePlugin_Dump.h @@ -38,6 +38,12 @@ public: static const std::string MY_DUMP_ID("Dump"); return MY_DUMP_ID; } + /// attribute name of true dumping directory + inline static const std::string& DUMP_DIR_ID() + { + static const std::string MY_DUMP_DIR_ID("dump_dir"); + return MY_DUMP_DIR_ID; + } /// attribute name of file path inline static const std::string& FILE_PATH_ID() { diff --git a/src/ExchangePlugin/ExchangePlugin_ExportFeature.cpp b/src/ExchangePlugin/ExchangePlugin_ExportFeature.cpp index 6ae4199ec..1da829a6f 100644 --- a/src/ExchangePlugin/ExchangePlugin_ExportFeature.cpp +++ b/src/ExchangePlugin/ExchangePlugin_ExportFeature.cpp @@ -211,7 +211,7 @@ void ExchangePlugin_ExportFeature::exportFile(const std::string& theFileName, /// do not export pictures ResultPtr aBodyContext = std::dynamic_pointer_cast(anAttrSelection->context()); - if(aBodyContext->hasTextureFile()) + if (aBodyContext->hasTexture()) continue; std::shared_ptr aCurShape = anAttrSelection->value(); @@ -416,13 +416,13 @@ void ExchangePlugin_ExportFeature::exportXAO(const std::string& theFileName) AttributeSelectionListPtr aSelection = selectionList(XAO_SELECTION_LIST_ID()); bool aIsSelection = aSelection->isInitialized() && aSelection->size() > 0; if (aIsSelection) { // a mode for export to geom result by result - for(int a = 0; a < aSelection->size(); a++) { + for (int a = 0; a < aSelection->size(); a++) { AttributeSelectionPtr anAttr = aSelection->value(a); ResultPtr aBodyContext = std::dynamic_pointer_cast(anAttr->context()); if (aBodyContext.get() && !aBodyContext->isDisabled() && aBodyContext->shape().get()) { /// do not export pictures - if(aBodyContext->hasTextureFile()){ + if (aBodyContext->hasTexture()){ anExCludedIsImage = true; continue; } diff --git a/src/ExchangePlugin/ExchangePlugin_Import.cpp b/src/ExchangePlugin/ExchangePlugin_Import.cpp index 6178b2259..ef4b3b560 100644 --- a/src/ExchangePlugin/ExchangePlugin_Import.cpp +++ b/src/ExchangePlugin/ExchangePlugin_Import.cpp @@ -31,6 +31,7 @@ #include #include #include +#include static const std::wstring THE_NEW_PART_STR(L"New Part"); @@ -88,6 +89,23 @@ void ExchangePlugin_Import::initAttributes() 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()); + +#ifndef HAVE_SALOME + ModelAPI_Session::get()->validators()->registerNotObligatory( + getKind(), ExchangePlugin_Import::IMPORT_TYPE_ID()); + ModelAPI_Session::get()->validators()->registerNotObligatory( + getKind(), ExchangePlugin_Import::STEP_FILE_PATH_ID()); + ModelAPI_Session::get()->validators()->registerNotObligatory( + getKind(), ExchangePlugin_Import::STEP_TARGET_PART_ID()); + ModelAPI_Session::get()->validators()->registerNotObligatory( + getKind(), ExchangePlugin_Import::STEP_TARGET_PARTS_LIST_ID()); + ModelAPI_Session::get()->validators()->registerNotObligatory( + getKind(), ExchangePlugin_Import::STEP_MATERIALS_ID()); + ModelAPI_Session::get()->validators()->registerNotObligatory( + getKind(), ExchangePlugin_Import::STEP_COLORS_ID()); + ModelAPI_Session::get()->validators()->registerNotObligatory( + getKind(), ExchangePlugin_Import::STEP_SCALE_INTER_UNITS_ID()); +#endif } /* @@ -156,7 +174,7 @@ void ExchangePlugin_Import::execute() void ExchangePlugin_Import_Image::execute() { - AttributeStringPtr aFilePathAttr = string(ExchangePlugin_ImportBase::FILE_PATH_ID()); + AttributeStringPtr aFilePathAttr = string(ExchangePlugin_ImportBase::FILE_PATH_ID()); std::string aFilePath = aFilePathAttr->value(); if (aFilePath.empty()) { setError("File path is empty."); diff --git a/src/ExchangePlugin/ExchangePlugin_ImportFeature.cpp b/src/ExchangePlugin/ExchangePlugin_ImportFeature.cpp index 65045f228..e077e4ca7 100644 --- a/src/ExchangePlugin/ExchangePlugin_ImportFeature.cpp +++ b/src/ExchangePlugin/ExchangePlugin_ImportFeature.cpp @@ -45,6 +45,7 @@ #include #include #include +#include #include #include #include @@ -66,6 +67,7 @@ #include +#include /* * Request for initialization of data model of the feature: adding all attributes @@ -635,35 +637,50 @@ void ExchangePlugin_ImportFeatureBase::loadNamingDS( void ExchangePlugin_Import_ImageFeature::importFile(const std::string& theFileName) { - std::string anExtension = GeomAlgoAPI_Tools::File_Tools::extension(theFileName); - std::string theTextureFileName = ""; - // Perform the import std::string anError; - std::shared_ptr aGeomShape; - if (anExtension == "PNG" || anExtension == "GIF" || - anExtension == "TIFF" || anExtension == "JPE" || - anExtension == "JPG" || anExtension == "JPEG" || - anExtension == "BMP"|| anExtension == "PPM" - ) { - aGeomShape = ImageImport(theFileName, anError); - if(anError == "") - theTextureFileName = theFileName; - } else { - anError = "Unsupported format: " + anExtension; - } - // Check if shape is valid - if (!anError.empty()) { - setError("An error occurred while importing " + theFileName + ": " + anError); - return; - } + if (anExtension == "PNG" || anExtension == "GIF" || + anExtension == "TIFF" || anExtension == "JPE" || + anExtension == "JPEG" || anExtension == "JPG" || + anExtension == "BMP" || anExtension == "PPM" + ) { + // Perform the import + QPixmap px (theFileName.c_str()); + int aWidth = px.width(); + int aHeight = px.height(); + if (aWidth < 1 || aHeight < 1) { + setError("An error occurred while importing " + theFileName + ": invalid image"); + return; + } - // Pass the results into the model - std::string anObjectName = GeomAlgoAPI_Tools::File_Tools::name(theFileName); - data()->setName(Locale::Convert::toWString(anObjectName)); + std::shared_ptr aGeomShape = ImageImport(aWidth, aHeight, anError); + + // Check if shape is valid + if (!anError.empty()) { + setError("An error occurred while importing " + theFileName + ": " + anError); + return; + } + + // Pass the results into the model + std::string anObjectName = GeomAlgoAPI_Tools::File_Tools::name(theFileName); + data()->setName(Locale::Convert::toWString(anObjectName)); + + auto resultBody = createResultBody(aGeomShape); - auto resultBody = createResultBody(aGeomShape); - resultBody->setTextureFile(theTextureFileName); - setResult(resultBody); + // Store image in result body attribute + AttributeImagePtr anImageAttr = resultBody->data()->image(ModelAPI_ResultBody::IMAGE_ID()); + if (anImageAttr.get() != NULL) { + QImage aQImage = px.toImage(); + const uchar* aImageBytes = aQImage.bits(); + std::list aByteArray (aImageBytes, aImageBytes + aQImage.sizeInBytes()); + anImageAttr->setTexture(aWidth, aHeight, aByteArray, anExtension); + } + + setResult(resultBody); + } + else { + anError = "Unsupported format: " + anExtension; + setError("An error occurred while importing " + theFileName + ": " + anError); + } } diff --git a/src/ExchangePlugin/Test/TestImportImage_1.py b/src/ExchangePlugin/Test/TestImportImage_1.py index 327caf623..b26dcf5cd 100755 --- a/src/ExchangePlugin/Test/TestImportImage_1.py +++ b/src/ExchangePlugin/Test/TestImportImage_1.py @@ -66,6 +66,9 @@ tol=1e-06 assert(abs(dx-400) <= tol) assert(abs(dy-258.5) <= tol) assert(abs(dz-0) <= tol) +assert(ImportImage_1.result().resultSubShapePair()[0].hasTexture()) +assert(Translation_1.result().resultSubShapePair()[0].hasTexture()) +assert(Scale_1.result().resultSubShapePair()[0].hasTexture()) #============================================================================= # Change the image : @@ -95,7 +98,11 @@ tol=1e-06 assert(abs(dx-448) <= tol) assert(abs(dy-296.8) <= tol) assert(abs(dz-0) <= tol) +assert(ImportImage_1.result().resultSubShapePair()[0].hasTexture()) +assert(Translation_1.result().resultSubShapePair()[0].hasTexture()) +assert(Scale_1.result().resultSubShapePair()[0].hasTexture()) +assert(model.checkPythonDump()) # Close SALOME GUI import salome_utils diff --git a/src/ExchangePlugin/Test/TestImportImage_2.py b/src/ExchangePlugin/Test/TestImportImage_2.py index fa214c76b..9a4230f93 100755 --- a/src/ExchangePlugin/Test/TestImportImage_2.py +++ b/src/ExchangePlugin/Test/TestImportImage_2.py @@ -74,6 +74,9 @@ tol=1e-06 assert(abs(dx-400) <= tol) assert(abs(dy-258.5) <= tol) assert(abs(dz-0) <= tol) +assert(ImportImage_1.result().resultSubShapePair()[0].hasTexture()) +assert(Translation_1.result().resultSubShapePair()[0].hasTexture()) +assert(Scale_1.result().resultSubShapePair()[0].hasTexture()) #============================================================================= # Change the image : @@ -101,6 +104,9 @@ tol=1e-06 assert(abs(dx-560) <= tol) assert(abs(dy-361.9) <= tol) assert(abs(dz-0) <= tol) +assert(ImportImage_1.result().resultSubShapePair()[0].hasTexture()) +assert(Translation_1.result().resultSubShapePair()[0].hasTexture()) +assert(Scale_1.result().resultSubShapePair()[0].hasTexture()) # Close SALOME GUI diff --git a/src/ExchangePlugin/Test/TestImportImage_3.py b/src/ExchangePlugin/Test/TestImportImage_3.py new file mode 100755 index 000000000..221768bf3 --- /dev/null +++ b/src/ExchangePlugin/Test/TestImportImage_3.py @@ -0,0 +1,108 @@ +# Copyright (C) 2021 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 +# + +import os, inspect +from salome.shaper import model + +from PyQt5.Qt import QApplication + +import salome +salome.salome_init_without_session() +salome.salome_init(1) +if QApplication.instance() is None: + app = QApplication([]) + +from tempfile import TemporaryDirectory +from ModelAPI import * + +data_dir = os.path.join(os.path.dirname(inspect.getfile(lambda: None)), "data") + +model.begin() +partSet = model.moduleDocument() + +### Create Part +Part_1 = model.addPart(partSet) +Part_1_doc = Part_1.document() + +### Create ImportImage +ImportImage_1 = model.addImportImage(Part_1_doc, os.path.join(data_dir, "1.jpg")) +model.do() +ImportImage_1.setName("drawing") +ImportImage_1.result().setName("drawing") + +### Create Translation +Translation_1 = model.addTranslation(Part_1_doc, [model.selection("FACE", "drawing")], startPoint = model.selection("VERTEX", "[drawing/Shape_1]e[drawing/Shape_4]e"), endPoint = model.selection("VERTEX", "PartSet/Origin"), keepSubResults = True) +Translation_1.setName("translation") + +### Create Scale +Scale_1 = model.addScale(Part_1_doc, [model.selection("FACE", "drawing")] , model.selection("VERTEX", "PartSet/Origin"), 0.5, keepSubResults = True) +Scale_1.setName("scale") + +model.end() + +#============================================================================= +# Tests : +#============================================================================= +model.checkResult(Scale_1, model, 1, [0], [0], [1], [4], [8]) +r=Scale_1.defaultResult() +s=r.shape() +dim=s.computeSize() +dim=dim[1:] +dx=abs(dim[3]-dim[0]) +dy=abs(dim[4]-dim[1]) +dz=abs(dim[5]-dim[2]) +tol=1e-06 +assert(abs(dx-400) <= tol) +assert(abs(dy-258.5) <= tol) +assert(abs(dz-0) <= tol) +assert(ImportImage_1.result().resultSubShapePair()[0].hasTexture()) +assert(Translation_1.result().resultSubShapePair()[0].hasTexture()) +assert(Scale_1.result().resultSubShapePair()[0].hasTexture()) + +aDr = objectToFeature(Part_1_doc.objectByName("Features", "drawing")) +assert(aDr.firstResult().hasTexture()) + +# check save/load document with an image +with TemporaryDirectory() as tmp_dir: + aSession = ModelAPI_Session.get() + aFiles = StringList() + aSession.save(tmp_dir, aFiles) + aSession.closeAll() + assert(aSession.load(tmp_dir)) + model.begin() + partSet = model.moduleDocument() + assert(partSet.size("Features") == 1) + aPart = objectToFeature(partSet.object("Features", 0)) + aPartResult = modelAPI_ResultPart(aPart.results()[0]) + aPartResult.activate() + aPartDoc = aPartResult.partDoc() + aSession.setActiveDocument(aPartDoc, True) + model.end() + aDr = objectToFeature(aPartDoc.objectByName("Features", "drawing")) + aTr = objectToFeature(aPartDoc.objectByName("Features", "translation")) + aSc = objectToFeature(aPartDoc.objectByName("Features", "scale")) + assert(aDr.firstResult().hasTexture()) + assert(aTr.firstResult().hasTexture()) + assert(aSc.firstResult().hasTexture()) + +# Close SALOME GUI +import salome_utils +import subprocess +port = salome_utils.getPortNumber() +proc = subprocess.Popen(["killSalomeWithPort.py", "{}".format(port)]) diff --git a/src/ExchangePlugin/Test/tests_gui.set b/src/ExchangePlugin/Test/tests_gui.set index 0464ada42..b4cc706cf 100755 --- a/src/ExchangePlugin/Test/tests_gui.set +++ b/src/ExchangePlugin/Test/tests_gui.set @@ -20,4 +20,5 @@ SET(TEST_WITH_GUI_NAMES TestImportImage_1.py TestImportImage_2.py + TestImportImage_3.py ) \ No newline at end of file diff --git a/src/ExchangePlugin/doc/exportFeature.rst b/src/ExchangePlugin/doc/exportFeature.rst index e4deafb4f..1773c9bf9 100644 --- a/src/ExchangePlugin/doc/exportFeature.rst +++ b/src/ExchangePlugin/doc/exportFeature.rst @@ -136,7 +136,7 @@ In this case, the following property panel will be opened: **Dialog box to export in STL format** -The file name and path can be defined in **Export file** field by direct input or browsing with ‘…’ button, which opens Export file dialog box. +The file name and path can be defined in **Export file** field by direct input or browsing with '...' button, which opens Export file dialog box. **Object** field contains an exported object which can be selected in a viewer or object browser. diff --git a/src/ExchangePlugin/doc/images/ExportSTL.png b/src/ExchangePlugin/doc/images/ExportSTL.png index e69de29bb..dc96fbae1 100644 Binary files a/src/ExchangePlugin/doc/images/ExportSTL.png and b/src/ExchangePlugin/doc/images/ExportSTL.png differ diff --git a/src/ExchangePlugin/doc/importFeature.rst b/src/ExchangePlugin/doc/importFeature.rst index e76131a42..817c5c1cb 100644 --- a/src/ExchangePlugin/doc/importFeature.rst +++ b/src/ExchangePlugin/doc/importFeature.rst @@ -115,7 +115,7 @@ In this case, the following property panel will be opened: **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 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. diff --git a/src/FeaturesPlugin/FeaturesPlugin_Boolean.cpp b/src/FeaturesPlugin/FeaturesPlugin_Boolean.cpp index ed051dc00..e10cc331c 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Boolean.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Boolean.cpp @@ -111,7 +111,7 @@ void FeaturesPlugin_Boolean::storeResult( const GeomShapePtr theResultShape, int& theResultIndex, std::shared_ptr theMakeShapeList, - std::vector& theResultBaseAlgoList) + std::vector& theResultBaseAlgoList) { if (!theResultShape) return; @@ -119,7 +119,7 @@ void FeaturesPlugin_Boolean::storeResult( std::shared_ptr aResultBody = document()->createBody(data(), theResultIndex); - FeaturesPlugin_Tools::loadModifiedShapes(aResultBody, + ModelAPI_Tools::loadModifiedShapes(aResultBody, theObjects, theTools, theMakeShapeList, @@ -127,10 +127,10 @@ void FeaturesPlugin_Boolean::storeResult( setResult(aResultBody, theResultIndex++); // merge algorithms - FeaturesPlugin_Tools::ResultBaseAlgo aRBA; + ModelAPI_Tools::ResultBaseAlgo aRBA; aRBA.resultBody = aResultBody; aRBA.baseShape = theObjects.front(); - for (std::vector::iterator + for (std::vector::iterator aRBAIt = theResultBaseAlgoList.begin(); aRBAIt != theResultBaseAlgoList.end(); ++aRBAIt) { theMakeShapeList->appendAlgo(aRBAIt->makeShape); diff --git a/src/FeaturesPlugin/FeaturesPlugin_Boolean.h b/src/FeaturesPlugin/FeaturesPlugin_Boolean.h index f6bf52266..3a8986a24 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Boolean.h +++ b/src/FeaturesPlugin/FeaturesPlugin_Boolean.h @@ -75,7 +75,7 @@ protected: const GeomShapePtr theResultShape, int& theResultIndex, std::shared_ptr theMakeShapeList, - std::vector& theResultBaseAlgoList); + std::vector& theResultBaseAlgoList); private: OperationType myOperationType; diff --git a/src/FeaturesPlugin/FeaturesPlugin_BooleanCommon.cpp b/src/FeaturesPlugin/FeaturesPlugin_BooleanCommon.cpp index 085107edb..60b3581b3 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_BooleanCommon.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_BooleanCommon.cpp @@ -94,7 +94,7 @@ void FeaturesPlugin_BooleanCommon::execute() std::string anError; std::shared_ptr aMakeShapeList(new GeomAlgoAPI_MakeShapeList()); - std::vector aResultBaseAlgoList; + std::vector aResultBaseAlgoList; ListOfShape aResultShapesList; if (isSimpleMode) { @@ -128,7 +128,7 @@ void FeaturesPlugin_BooleanCommon::execute() ListOfShape anObjectList = anObjects.objects(); ListOfShape aToolsList; - FeaturesPlugin_Tools::loadModifiedShapes(aResultBody, + ModelAPI_Tools::loadModifiedShapes(aResultBody, anObjectList, aToolsList, aMakeShapeList, @@ -139,7 +139,7 @@ void FeaturesPlugin_BooleanCommon::execute() aResultIndex++; aToolsList = anObjectList; - FeaturesPlugin_Tools::ResultBaseAlgo aRBA; + ModelAPI_Tools::ResultBaseAlgo aRBA; aRBA.resultBody = aResultBody; aRBA.baseShape = aBaseShape; aRBA.makeShape = aMakeShapeList; @@ -194,7 +194,7 @@ void FeaturesPlugin_BooleanCommon::execute() // result shape has been deleted, but in another it was modified or stayed. if (!aResultCompound) aResultCompound = GeomAlgoAPI_CompoundBuilder::compound(aResultShapesList); - FeaturesPlugin_Tools::loadDeletedShapes(aResultBaseAlgoList, + ModelAPI_Tools::loadDeletedShapes(aResultBaseAlgoList, aTools.objects(), aResultCompound); diff --git a/src/FeaturesPlugin/FeaturesPlugin_BooleanCut.cpp b/src/FeaturesPlugin/FeaturesPlugin_BooleanCut.cpp index f24d6f78b..fe831bec3 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_BooleanCut.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_BooleanCut.cpp @@ -19,8 +19,6 @@ #include "FeaturesPlugin_BooleanCut.h" -#include "FeaturesPlugin_Tools.h" - #include #include #include @@ -67,7 +65,7 @@ void FeaturesPlugin_BooleanCut::execute() return; } - std::vector aResultBaseAlgoList; + std::vector aResultBaseAlgoList; ListOfShape aResultShapesList; std::string anError; @@ -120,7 +118,7 @@ void FeaturesPlugin_BooleanCut::execute() // result shape has been deleted, but in another it was modified or stayed. if (!aResultCompound) aResultCompound = GeomAlgoAPI_CompoundBuilder::compound(aResultShapesList); - FeaturesPlugin_Tools::loadDeletedShapes(aResultBaseAlgoList, + ModelAPI_Tools::loadDeletedShapes(aResultBaseAlgoList, aTools.objects(), aResultCompound); diff --git a/src/FeaturesPlugin/FeaturesPlugin_BooleanFill.cpp b/src/FeaturesPlugin/FeaturesPlugin_BooleanFill.cpp index de0c313ba..cbab08a64 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_BooleanFill.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_BooleanFill.cpp @@ -18,7 +18,6 @@ // #include "FeaturesPlugin_BooleanFill.h" -#include "FeaturesPlugin_Tools.h" #include #include @@ -78,7 +77,7 @@ void FeaturesPlugin_BooleanFill::execute() return; } - std::vector aResultBaseAlgoList; + std::vector aResultBaseAlgoList; ListOfShape aResultShapesList; std::shared_ptr aMakeShapeList(new GeomAlgoAPI_MakeShapeList()); @@ -122,7 +121,7 @@ void FeaturesPlugin_BooleanFill::execute() // result shape has been deleted, but in another it was modified or stayed. if (!aResultCompound) aResultCompound = GeomAlgoAPI_CompoundBuilder::compound(aResultShapesList); - FeaturesPlugin_Tools::loadDeletedShapes(aResultBaseAlgoList, + ModelAPI_Tools::loadDeletedShapes(aResultBaseAlgoList, aTools.objects(), aResultCompound); diff --git a/src/FeaturesPlugin/FeaturesPlugin_BooleanFuse.cpp b/src/FeaturesPlugin/FeaturesPlugin_BooleanFuse.cpp index 1214bb214..dd7f59d68 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_BooleanFuse.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_BooleanFuse.cpp @@ -19,8 +19,6 @@ #include "FeaturesPlugin_BooleanFuse.h" -#include "FeaturesPlugin_Tools.h" - #include #include #include @@ -271,19 +269,19 @@ void FeaturesPlugin_BooleanFuse::execute() ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex); ListOfShape anEmptyTools; - FeaturesPlugin_Tools::loadModifiedShapes(aResultBody, - anOriginalShapes, - anEmptyTools, - aMakeShapeList, - aShape); + ModelAPI_Tools::loadModifiedShapes(aResultBody, + anOriginalShapes, + anEmptyTools, + aMakeShapeList, + aShape); setResult(aResultBody, aResultIndex); aResultIndex++; - FeaturesPlugin_Tools::loadDeletedShapes(aResultBody, - GeomShapePtr(), - anOriginalShapes, - aMakeShapeList, - aShape); + ModelAPI_Tools::loadDeletedShapes(aResultBody, + GeomShapePtr(), + anOriginalShapes, + aMakeShapeList, + aShape); // remove the rest results if there were produced in the previous pass removeResults(aResultIndex); diff --git a/src/FeaturesPlugin/FeaturesPlugin_BooleanSmash.cpp b/src/FeaturesPlugin/FeaturesPlugin_BooleanSmash.cpp index 2eb3753cc..f8336b240 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_BooleanSmash.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_BooleanSmash.cpp @@ -19,8 +19,6 @@ #include "FeaturesPlugin_BooleanSmash.h" -#include "FeaturesPlugin_Tools.h" - #include #include #include @@ -175,20 +173,20 @@ void FeaturesPlugin_BooleanSmash::execute() std::shared_ptr aResultBody = document()->createBody(data(), aResultIndex); - FeaturesPlugin_Tools::loadModifiedShapes(aResultBody, - anOriginalShapes, - anOriginalShapes, - aMakeShapeList, - aShape); + ModelAPI_Tools::loadModifiedShapes(aResultBody, + anOriginalShapes, + anOriginalShapes, + aMakeShapeList, + aShape); setResult(aResultBody, aResultIndex); aResultIndex++; - FeaturesPlugin_Tools::loadDeletedShapes(aResultBody, - GeomShapePtr(), - anOriginalShapes, - aMakeShapeList, - aShape); + ModelAPI_Tools::loadDeletedShapes(aResultBody, + GeomShapePtr(), + anOriginalShapes, + aMakeShapeList, + aShape); // remove the rest results if there were produced in the previous pass removeResults(aResultIndex); diff --git a/src/FeaturesPlugin/FeaturesPlugin_Defeaturing.cpp b/src/FeaturesPlugin/FeaturesPlugin_Defeaturing.cpp index ac60462ce..47291b11d 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Defeaturing.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Defeaturing.cpp @@ -18,7 +18,6 @@ // #include -#include #include #include @@ -72,7 +71,7 @@ void FeaturesPlugin_Defeaturing::execute() int aResultIndex = 0; std::string anError; - std::vector aResultBaseAlgoList; + std::vector aResultBaseAlgoList; ListOfShape anOriginalShapesList, aResultShapesList; for (SolidFaces::iterator anIt = aBodiesAndFacesToRemove.begin(); @@ -90,13 +89,13 @@ void FeaturesPlugin_Defeaturing::execute() aBaseShapes.push_back(anExp.current()); std::shared_ptr aResultBody = document()->createBody(data(), aResultIndex); - FeaturesPlugin_Tools::loadModifiedShapes(aResultBody, aBaseShapes, ListOfShape(), - anAlgo, aResult, "Defeaturing"); + ModelAPI_Tools::loadModifiedShapes(aResultBody, aBaseShapes, ListOfShape(), + anAlgo, aResult, "Defeaturing"); setResult(aResultBody, aResultIndex); aResultIndex++; - FeaturesPlugin_Tools::ResultBaseAlgo aRBA; + ModelAPI_Tools::ResultBaseAlgo aRBA; aRBA.resultBody = aResultBody; aRBA.baseShape = aParent; aRBA.makeShape = anAlgo; @@ -108,7 +107,7 @@ void FeaturesPlugin_Defeaturing::execute() // Store deleted shapes after all results has been proceeded. This is to avoid issue when in one // result shape has been deleted, but in another it was modified or stayed. GeomShapePtr aResultShapesCompound = GeomAlgoAPI_CompoundBuilder::compound(aResultShapesList); - FeaturesPlugin_Tools::loadDeletedShapes(aResultBaseAlgoList, + ModelAPI_Tools::loadDeletedShapes(aResultBaseAlgoList, anOriginalShapesList, aResultShapesCompound); removeResults(aResultIndex); diff --git a/src/FeaturesPlugin/FeaturesPlugin_Extrusion.cpp b/src/FeaturesPlugin/FeaturesPlugin_Extrusion.cpp index aa95790a5..436462796 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Extrusion.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Extrusion.cpp @@ -18,13 +18,13 @@ // #include "FeaturesPlugin_Extrusion.h" -#include "FeaturesPlugin_Tools.h" #include #include #include #include #include +#include #include #include @@ -173,8 +173,8 @@ void FeaturesPlugin_Extrusion::storeResultWithBoundaries( ResultBodyPtr aResultBody = document()->createBody(data(), theIndex); // Store modified shapes. - FeaturesPlugin_Tools::loadModifiedShapes(aResultBody, theBoundaryShapes, ListOfShape(), - theMakeShape, theMakeShape->shape()); + ModelAPI_Tools::loadModifiedShapes(aResultBody, theBoundaryShapes, ListOfShape(), + theMakeShape, theMakeShape->shape()); // Store generated edges/faces. storeGenerationHistory(aResultBody, theBaseShape, theMakeShape); diff --git a/src/FeaturesPlugin/FeaturesPlugin_Fillet1D.cpp b/src/FeaturesPlugin/FeaturesPlugin_Fillet1D.cpp index b3b4b8493..e1145fb52 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Fillet1D.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Fillet1D.cpp @@ -18,7 +18,6 @@ // #include -#include #include #include @@ -33,6 +32,7 @@ #include #include #include +#include void sendMessageWithFailedShapes(const ListOfShape& theVertices) { @@ -190,8 +190,8 @@ bool FeaturesPlugin_Fillet1D::performFillet(const GeomShapePtr& theWire, ResultBodyPtr aResult = document()->createBody(data(), theResultIndex); ListOfShape anOriginal; anOriginal.push_back(theWire); - FeaturesPlugin_Tools::loadModifiedShapes(aResult, anOriginal, ListOfShape(), - aFilletBuilder, aFilletBuilder->shape(), THE_PREFIX); + ModelAPI_Tools::loadModifiedShapes(aResult, anOriginal, ListOfShape(), + aFilletBuilder, aFilletBuilder->shape(), THE_PREFIX); setResult(aResult, theResultIndex); // store new edges generated from vertices for (ListOfShape::const_iterator anIt = theVertices.begin(); anIt != theVertices.end(); ++anIt) diff --git a/src/FeaturesPlugin/FeaturesPlugin_FusionFaces.cpp b/src/FeaturesPlugin/FeaturesPlugin_FusionFaces.cpp index 1ded92cbe..b01ab3a49 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_FusionFaces.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_FusionFaces.cpp @@ -18,7 +18,6 @@ // #include "FeaturesPlugin_FusionFaces.h" -#include "FeaturesPlugin_Tools.h" #include #include @@ -26,6 +25,7 @@ #include #include #include +#include #include #include @@ -73,7 +73,7 @@ void FeaturesPlugin_FusionFaces::execute() ListOfShape aBaseShapesList; aBaseShapesList.push_back(aBaseShape); - FeaturesPlugin_Tools::loadModifiedShapes(aResultBody, aBaseShapesList, ListOfShape(), - anAlgo, aResultShape); + ModelAPI_Tools::loadModifiedShapes(aResultBody, aBaseShapesList, ListOfShape(), + anAlgo, aResultShape); setResult(aResultBody); } diff --git a/src/FeaturesPlugin/FeaturesPlugin_Intersection.cpp b/src/FeaturesPlugin/FeaturesPlugin_Intersection.cpp index aa95218e0..4a2c31715 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Intersection.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Intersection.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -84,19 +85,19 @@ void FeaturesPlugin_Intersection::execute() } std::shared_ptr aResultBody = document()->createBody(data(), aResultIndex); - FeaturesPlugin_Tools::loadModifiedShapes(aResultBody, - anObjects, - ListOfShape(), - aMakeShapeList, - aResShape); + ModelAPI_Tools::loadModifiedShapes(aResultBody, + anObjects, + ListOfShape(), + aMakeShapeList, + aResShape); setResult(aResultBody, aResultIndex); aResultIndex++; - FeaturesPlugin_Tools::loadDeletedShapes(aResultBody, - GeomShapePtr(), - anObjects, - aMakeShapeList, - aResShape); + ModelAPI_Tools::loadDeletedShapes(aResultBody, + GeomShapePtr(), + anObjects, + aMakeShapeList, + aResShape); // remove the rest results if there were produced in the previous pass removeResults(aResultIndex); diff --git a/src/FeaturesPlugin/FeaturesPlugin_MultiRotation.cpp b/src/FeaturesPlugin/FeaturesPlugin_MultiRotation.cpp index e8caba9bf..4e3d05ba2 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_MultiRotation.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_MultiRotation.cpp @@ -44,6 +44,7 @@ #include #include #include +#include #include #include @@ -166,9 +167,9 @@ void FeaturesPlugin_MultiRotation::performRotation1D() GeomAPI_ShapeHierarchy anObjects; std::list aParts; - std::string theTextureFile; - if (!FeaturesPlugin_Tools::shapesFromSelectionList( - anObjectsSelList, isKeepSubShapes, anObjects, aParts, theTextureFile)) + ResultPtr aTextureSource; + if (!FeaturesPlugin_Tools::shapesFromSelectionList + (anObjectsSelList, isKeepSubShapes, anObjects, aParts, aTextureSource)) return; // Parameters of rotation. @@ -223,9 +224,10 @@ void FeaturesPlugin_MultiRotation::performRotation1D() anObjects.topLevelObjects(aTopLevel); for (ListOfShape::iterator anIt = aTopLevel.begin(); anIt != aTopLevel.end(); ++anIt) { ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex); - FeaturesPlugin_Tools::loadModifiedShapes(aResultBody, anOriginalShapes, ListOfShape(), - aMakeShapeList, *anIt, "Rotated"); - aResultBody->setTextureFile(theTextureFile); + ModelAPI_Tools::loadModifiedShapes(aResultBody, anOriginalShapes, ListOfShape(), + aMakeShapeList, *anIt, "Rotated"); + // Copy image data, if any + ModelAPI_Tools::copyImageAttribute(aTextureSource, aResultBody); setResult(aResultBody, aResultIndex++); } diff --git a/src/FeaturesPlugin/FeaturesPlugin_MultiTranslation.cpp b/src/FeaturesPlugin/FeaturesPlugin_MultiTranslation.cpp index c507c7d50..8ee89a08f 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_MultiTranslation.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_MultiTranslation.cpp @@ -37,6 +37,7 @@ #include #include #include +#include #include @@ -91,9 +92,9 @@ void FeaturesPlugin_MultiTranslation::execute() GeomAPI_ShapeHierarchy anObjects; std::list aParts; - std::string theTextureFile; - if (!FeaturesPlugin_Tools::shapesFromSelectionList( - anObjectsSelList, isKeepSubShapes, anObjects, aParts, theTextureFile)) + ResultPtr aTextureSource; + if (!FeaturesPlugin_Tools::shapesFromSelectionList + (anObjectsSelList, isKeepSubShapes, anObjects, aParts, aTextureSource)) return; std::shared_ptr aFirstDir, aSecondDir; @@ -169,9 +170,10 @@ void FeaturesPlugin_MultiTranslation::execute() anObjects.topLevelObjects(aTopLevel); for (ListOfShape::iterator anIt = aTopLevel.begin(); anIt != aTopLevel.end(); ++anIt) { ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex); - FeaturesPlugin_Tools::loadModifiedShapes(aResultBody, anOriginalShapes, ListOfShape(), - aMakeShapeList, *anIt, "Translated"); - aResultBody->setTextureFile(theTextureFile); + ModelAPI_Tools::loadModifiedShapes(aResultBody, anOriginalShapes, ListOfShape(), + aMakeShapeList, *anIt, "Translated"); + // Copy image data, if any + ModelAPI_Tools::copyImageAttribute(aTextureSource, aResultBody); setResult(aResultBody, aResultIndex++); } diff --git a/src/FeaturesPlugin/FeaturesPlugin_Placement.cpp b/src/FeaturesPlugin/FeaturesPlugin_Placement.cpp index efc09092a..a357658f5 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Placement.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Placement.cpp @@ -71,10 +71,10 @@ void FeaturesPlugin_Placement::execute() // Getting objects. GeomAPI_ShapeHierarchy anObjects; std::list aParts; - std::string theTextureFile; + ResultPtr aTextureSource; AttributeSelectionListPtr anObjectsSelList = selectionList(OBJECTS_LIST_ID()); - if (!FeaturesPlugin_Tools::shapesFromSelectionList( - anObjectsSelList, isKeepSubShapes, anObjects, aParts, theTextureFile)) + if (!FeaturesPlugin_Tools::shapesFromSelectionList + (anObjectsSelList, isKeepSubShapes, anObjects, aParts, aTextureSource)) return; // Verify the start shape @@ -179,9 +179,10 @@ void FeaturesPlugin_Placement::execute() for (ListOfShape::iterator anIt = aTopLevel.begin(); anIt != aTopLevel.end(); ++anIt) { //LoadNamingDS ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex); - FeaturesPlugin_Tools::loadModifiedShapes(aResultBody, anOriginalShapes, ListOfShape(), - aMakeShapeList, *anIt, "Placed"); - aResultBody->setTextureFile(theTextureFile); + ModelAPI_Tools::loadModifiedShapes(aResultBody, anOriginalShapes, ListOfShape(), + aMakeShapeList, *anIt, "Placed"); + // Copy image data, if any + ModelAPI_Tools::copyImageAttribute(aTextureSource, aResultBody); setResult(aResultBody, aResultIndex++); } diff --git a/src/FeaturesPlugin/FeaturesPlugin_Rotation.cpp b/src/FeaturesPlugin/FeaturesPlugin_Rotation.cpp index 1fe9334eb..473d5964a 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Rotation.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Rotation.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -184,10 +185,10 @@ void FeaturesPlugin_Rotation::performRotation(const GeomTrsfPtr& theTrsf) // Getting objects. GeomAPI_ShapeHierarchy anObjects; std::list aParts; - std::string theTextureFile; + ResultPtr aTextureSource; AttributeSelectionListPtr anObjSelList = selectionList(OBJECTS_LIST_ID()); if (!FeaturesPlugin_Tools::shapesFromSelectionList( - anObjSelList, isKeepSubShapes, anObjects, aParts, theTextureFile)) + anObjSelList, isKeepSubShapes, anObjects, aParts, aTextureSource)) return; std::string anError; @@ -224,9 +225,10 @@ void FeaturesPlugin_Rotation::performRotation(const GeomTrsfPtr& theTrsf) anObjects.topLevelObjects(aTopLevel); for (ListOfShape::iterator anIt = aTopLevel.begin(); anIt != aTopLevel.end(); ++anIt) { ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex); - FeaturesPlugin_Tools::loadModifiedShapes(aResultBody, anOriginalShapes, ListOfShape(), - aMakeShapeList, *anIt, "Rotated"); - aResultBody->setTextureFile(theTextureFile); + ModelAPI_Tools::loadModifiedShapes(aResultBody, anOriginalShapes, ListOfShape(), + aMakeShapeList, *anIt, "Rotated"); + // Copy image data, if any + ModelAPI_Tools::copyImageAttribute(aTextureSource, aResultBody); setResult(aResultBody, aResultIndex++); } diff --git a/src/FeaturesPlugin/FeaturesPlugin_Scale.cpp b/src/FeaturesPlugin/FeaturesPlugin_Scale.cpp index 73cbd10bc..f53834fc5 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Scale.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Scale.cpp @@ -32,6 +32,7 @@ #include #include #include +#include static const std::string SCALE_VERSION_1("v9.5"); @@ -92,10 +93,10 @@ void FeaturesPlugin_Scale::performScaleByFactor() // Getting objects. GeomAPI_ShapeHierarchy anObjects; std::list aParts; - std::string theTextureFile; + ResultPtr aTextureSource; AttributeSelectionListPtr anObjSelList = selectionList(OBJECTS_LIST_ID()); if (!FeaturesPlugin_Tools::shapesFromSelectionList( - anObjSelList, isKeepSubShapes, anObjects, aParts, theTextureFile)) + anObjSelList, isKeepSubShapes, anObjects, aParts, aTextureSource)) return; // Getting the center point @@ -141,9 +142,10 @@ void FeaturesPlugin_Scale::performScaleByFactor() anObjects.topLevelObjects(aTopLevel); for (ListOfShape::iterator anIt = aTopLevel.begin(); anIt != aTopLevel.end(); ++anIt) { ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex); - FeaturesPlugin_Tools::loadModifiedShapes(aResultBody, anOriginalShapes, ListOfShape(), - aMakeShapeList, *anIt, "Scaled"); - aResultBody->setTextureFile(theTextureFile); + ModelAPI_Tools::loadModifiedShapes(aResultBody, anOriginalShapes, ListOfShape(), + aMakeShapeList, *anIt, "Scaled"); + // Copy image data, if any + ModelAPI_Tools::copyImageAttribute(aTextureSource, aResultBody); setResult(aResultBody, aResultIndex++); } @@ -159,10 +161,10 @@ void FeaturesPlugin_Scale::performScaleByDimensions() // Getting objects. GeomAPI_ShapeHierarchy anObjects; std::list aParts; - std::string theTextureFile; + ResultPtr aTextureSource; AttributeSelectionListPtr anObjSelList = selectionList(OBJECTS_LIST_ID()); if (!FeaturesPlugin_Tools::shapesFromSelectionList( - anObjSelList, isKeepSubShapes, anObjects, aParts, theTextureFile)) + anObjSelList, isKeepSubShapes, anObjects, aParts, aTextureSource)) return; // Getting the center point @@ -213,9 +215,10 @@ void FeaturesPlugin_Scale::performScaleByDimensions() anObjects.topLevelObjects(aTopLevel); for (ListOfShape::iterator anIt = aTopLevel.begin(); anIt != aTopLevel.end(); ++anIt) { ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex); - FeaturesPlugin_Tools::loadModifiedShapes(aResultBody, anOriginalShapes, ListOfShape(), - aMakeShapeList, *anIt, "Scaled"); - aResultBody->setTextureFile(theTextureFile); + ModelAPI_Tools::loadModifiedShapes(aResultBody, anOriginalShapes, ListOfShape(), + aMakeShapeList, *anIt, "Scaled"); + // Copy image data, if any + ModelAPI_Tools::copyImageAttribute(aTextureSource, aResultBody); setResult(aResultBody, aResultIndex++); } diff --git a/src/FeaturesPlugin/FeaturesPlugin_Symmetry.cpp b/src/FeaturesPlugin/FeaturesPlugin_Symmetry.cpp index e877c4016..5ad5d61a2 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Symmetry.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Symmetry.cpp @@ -41,6 +41,7 @@ #include #include #include +#include #include @@ -204,13 +205,14 @@ void FeaturesPlugin_Symmetry::buildResult( const std::shared_ptr& theAlgo, const std::list >& theOriginalShapes, std::shared_ptr theTargetShape, int& theResultIndex, - std::string & theTextureFile) + const ResultPtr& theTextureSource) { // Store and name the result. ResultBodyPtr aResultBody = document()->createBody(data(), theResultIndex); - FeaturesPlugin_Tools::loadModifiedShapes(aResultBody, theOriginalShapes, ListOfShape(), - theAlgo, theTargetShape, "Symmetried"); - aResultBody->setTextureFile(theTextureFile); + ModelAPI_Tools::loadModifiedShapes(aResultBody, theOriginalShapes, ListOfShape(), + theAlgo, theTargetShape, "Symmetried"); + // Copy image data, if any + ModelAPI_Tools::copyImageAttribute(theTextureSource, aResultBody); setResult(aResultBody, theResultIndex++); } @@ -281,10 +283,10 @@ void FeaturesPlugin_Symmetry::performSymmetry(GeomTrsfPtr theTrsf) // Getting objects. GeomAPI_ShapeHierarchy anObjects; std::list aParts; - std::string theTextureFile; + ResultPtr aTextureSource; AttributeSelectionListPtr anObjSelList = selectionList(OBJECTS_LIST_ID()); if (!FeaturesPlugin_Tools::shapesFromSelectionList( - anObjSelList, isKeepSubShapes, anObjects, aParts, theTextureFile)) + anObjSelList, isKeepSubShapes, anObjects, aParts, aTextureSource)) return; std::string anError; @@ -312,7 +314,7 @@ void FeaturesPlugin_Symmetry::performSymmetry(GeomTrsfPtr theTrsf) ListOfShape aTopLevel; anObjects.topLevelObjects(aTopLevel); for (ListOfShape::iterator anIt = aTopLevel.begin(); anIt != aTopLevel.end(); ++anIt) - buildResult(aMakeShapeList, anOriginalShapes, *anIt, aResultIndex, theTextureFile); + buildResult(aMakeShapeList, anOriginalShapes, *anIt, aResultIndex, aTextureSource); // Remove the rest results if there were produced in the previous pass. removeResults(aResultIndex); diff --git a/src/FeaturesPlugin/FeaturesPlugin_Symmetry.h b/src/FeaturesPlugin/FeaturesPlugin_Symmetry.h index 5d73f9ec8..814dcdb7b 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Symmetry.h +++ b/src/FeaturesPlugin/FeaturesPlugin_Symmetry.h @@ -23,6 +23,7 @@ #include #include +#include class GeomAPI_Trsf; class GeomAlgoAPI_MakeShapeList; @@ -137,7 +138,8 @@ private: void buildResult(const std::shared_ptr& theAlgo, const std::list >& theOriginalShapes, std::shared_ptr theTargetShape, - int& theResultIndex, std::string &theTextureFile); + int& theResultIndex, + const ResultPtr& theTextureSource); /// Create new result for the given part and transformation void buildResult(std::shared_ptr theOriginal, diff --git a/src/FeaturesPlugin/FeaturesPlugin_Tools.cpp b/src/FeaturesPlugin/FeaturesPlugin_Tools.cpp index 9a36609a4..a777af3b5 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Tools.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Tools.cpp @@ -33,126 +33,6 @@ #include -//================================================================================================== -void FeaturesPlugin_Tools::loadModifiedShapes(ResultBodyPtr theResultBody, - const ListOfShape& theBaseShapes, - const ListOfShape& theTools, - const GeomMakeShapePtr& theMakeShape, - const GeomShapePtr theResultShape, - const std::string& theNamePrefix) -{ - theResultBody->storeModified(theBaseShapes, theResultShape, theMakeShape); - - ListOfShape aShapes = theBaseShapes; - ListOfShape::const_iterator aToolIter = theTools.cbegin(); - for(; aToolIter != theTools.cend(); aToolIter++) - aShapes.push_back(*aToolIter); - - for (ListOfShape::const_iterator anIter = aShapes.begin(); anIter != aShapes.end(); ++anIter) - { - theResultBody->loadModifiedShapes(theMakeShape, *anIter, GeomAPI_Shape::VERTEX, theNamePrefix); - theResultBody->loadModifiedShapes(theMakeShape, *anIter, GeomAPI_Shape::EDGE, theNamePrefix); - theResultBody->loadModifiedShapes(theMakeShape, *anIter, GeomAPI_Shape::FACE, theNamePrefix); - } -} - -//================================================================================================== -void FeaturesPlugin_Tools::loadModifiedShapes(ResultBodyPtr theResultBody, - const GeomShapePtr& theBaseShape, - const GeomMakeShapePtr& theMakeShape, - const std::string theName) -{ - switch(theBaseShape->shapeType()) { - case GeomAPI_Shape::COMPOUND: { - for(GeomAPI_ShapeIterator anIt(theBaseShape); anIt.more(); anIt.next()) - { - loadModifiedShapes(theResultBody, - anIt.current(), - theMakeShape, - theName); - } - break; - } - case GeomAPI_Shape::COMPSOLID: - case GeomAPI_Shape::SOLID: - case GeomAPI_Shape::SHELL: { - theResultBody->loadModifiedShapes(theMakeShape, - theBaseShape, - GeomAPI_Shape::FACE, - theName); - } - case GeomAPI_Shape::FACE: - case GeomAPI_Shape::WIRE: { - theResultBody->loadModifiedShapes(theMakeShape, - theBaseShape, - GeomAPI_Shape::EDGE, - theName); - } - case GeomAPI_Shape::EDGE: { - theResultBody->loadModifiedShapes(theMakeShape, - theBaseShape, - GeomAPI_Shape::VERTEX, - theName); - } - default: // [to avoid compilation warning] - break; - } -} - -//================================================================================================== -void FeaturesPlugin_Tools::loadDeletedShapes(ResultBodyPtr theResultBody, - const GeomShapePtr theBaseShape, - const ListOfShape& theTools, - const GeomMakeShapePtr& theMakeShape, - const GeomShapePtr theResultShapesCompound) -{ - ListOfShape aShapes = theTools; - if (theBaseShape.get()) - aShapes.push_front(theBaseShape); - - for (ListOfShape::const_iterator anIter = aShapes.begin(); anIter != aShapes.end(); anIter++) - { - theResultBody->loadDeletedShapes(theMakeShape, - *anIter, - GeomAPI_Shape::VERTEX, - theResultShapesCompound); - theResultBody->loadDeletedShapes(theMakeShape, - *anIter, - GeomAPI_Shape::EDGE, - theResultShapesCompound); - theResultBody->loadDeletedShapes(theMakeShape, - *anIter, - GeomAPI_Shape::FACE, - theResultShapesCompound); - // store information about deleted solids because of unittest TestBooleanCommon_SolidsHistory - // on OCCT 7.4.0 : common produces modified compsolid, so, move to the end for removed solids - // starts to produce whole compsolid - theResultBody->loadDeletedShapes(theMakeShape, - *anIter, - GeomAPI_Shape::SOLID, - theResultShapesCompound); - } -} - -//================================================================================================== -void FeaturesPlugin_Tools::loadDeletedShapes( - std::vector& theResultBaseAlgoList, - const ListOfShape& theTools, - const GeomShapePtr theResultShapesCompound) -{ - for (std::vector::iterator anIt = theResultBaseAlgoList.begin(); - anIt != theResultBaseAlgoList.end(); - ++anIt) - { - ResultBaseAlgo& aRCA = *anIt; - loadDeletedShapes(aRCA.resultBody, - aRCA.baseShape, - theTools, - aRCA.makeShape, - theResultShapesCompound); - } -} - //================================================================================================== bool FeaturesPlugin_Tools::getShape(const AttributeSelectionListPtr theSelectionList, const bool theShareTopology, @@ -263,27 +143,21 @@ bool FeaturesPlugin_Tools::shapesFromSelectionList( const std::shared_ptr theSelectionList, const bool theStoreFullHierarchy, GeomAPI_ShapeHierarchy& theHierarchy, - std::list& theParts, std::string &theTextureFile) + std::list& theParts, ResultPtr& theTextureSource) { int aSize = theSelectionList->size(); - if(aSize == 1) - { + if (aSize == 1) { auto anObjectAttr = theSelectionList->value(0); - if(anObjectAttr.get()) - { + if (anObjectAttr.get()) { FeaturePtr aFeature = anObjectAttr->contextFeature(); - if(aFeature.get() && aFeature->results().size() == 1) - { - theTextureFile = aFeature->firstResult()->getTextureFile(); + if (aFeature.get() && aFeature->results().size() == 1) { + theTextureSource = aFeature->firstResult(); } - else - { - if(!aFeature.get()) - { - auto aResult = anObjectAttr->context(); - if(aResult.get()) - { - theTextureFile = aResult->getTextureFile(); + else { + if (!aFeature.get()) { + auto aResult = anObjectAttr->context(); + if (aResult.get()) { + theTextureSource = aResult; } } } diff --git a/src/FeaturesPlugin/FeaturesPlugin_Tools.h b/src/FeaturesPlugin/FeaturesPlugin_Tools.h index c9a138a37..306d00db8 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Tools.h +++ b/src/FeaturesPlugin/FeaturesPlugin_Tools.h @@ -28,36 +28,6 @@ class FeaturesPlugin_Tools { public: - struct ResultBaseAlgo { - ResultBodyPtr resultBody; - GeomShapePtr baseShape; - GeomMakeShapePtr makeShape; - }; - -public: - static void loadModifiedShapes(ResultBodyPtr theResultBody, - const ListOfShape& theBaseShapes, - const ListOfShape& theTools, - const GeomMakeShapePtr& theMakeShape, - const GeomShapePtr theResultShape, - const std::string& theNamePrefix = ""); - - static void loadModifiedShapes(ResultBodyPtr theResultBody, - const GeomShapePtr& theBaseShape, - const GeomMakeShapePtr& theMakeShape, - const std::string theName); - /// Stores deleted shapes. - static void loadDeletedShapes(ResultBodyPtr theResultBody, - const GeomShapePtr theBaseShape, - const ListOfShape& theTools, - const GeomMakeShapePtr& theMakeShape, - const GeomShapePtr theResultShapesCompound); - - /// Stores deleted shapes. - static void loadDeletedShapes(std::vector& theResultBaseAlgoList, - const ListOfShape& theTools, - const GeomShapePtr theResultShapesCompound); - /// Obtain shapes from the selection list attribute. static bool getShape(const std::shared_ptr theSelectionList, const bool theShareTopology, @@ -69,7 +39,8 @@ public: const std::shared_ptr theSelectionList, const bool theStoreFullHierarchy, GeomAPI_ShapeHierarchy& theHierarchy, - std::list& theParts, std::string& theTextureFile); + std::list& theParts, + ResultPtr& theTextureSource); }; #endif /* FeaturesPlugin_Tools_H_ */ diff --git a/src/FeaturesPlugin/FeaturesPlugin_Translation.cpp b/src/FeaturesPlugin/FeaturesPlugin_Translation.cpp index 11a0dca22..93aa595ed 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Translation.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Translation.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -197,10 +198,10 @@ void FeaturesPlugin_Translation::performTranslation(const GeomTrsfPtr& theTrsf) // Getting objects. GeomAPI_ShapeHierarchy anObjects; std::list aParts; - std::string theTextureFile; + ResultPtr aTextureSource; AttributeSelectionListPtr anObjectsSelList = selectionList(OBJECTS_LIST_ID()); - if (!FeaturesPlugin_Tools::shapesFromSelectionList( - anObjectsSelList, isKeepSubShapes, anObjects, aParts, theTextureFile)) + if (!FeaturesPlugin_Tools::shapesFromSelectionList + (anObjectsSelList, isKeepSubShapes, anObjects, aParts, aTextureSource)) return; std::string anError; @@ -239,9 +240,10 @@ void FeaturesPlugin_Translation::performTranslation(const GeomTrsfPtr& theTrsf) for (ListOfShape::iterator anIt = aTopLevel.begin(); anIt != aTopLevel.end(); ++anIt) { //LoadNamingDS ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex); - FeaturesPlugin_Tools::loadModifiedShapes(aResultBody, anOriginalShapes, ListOfShape(), - aMakeShapeList, *anIt, "Translated"); - aResultBody->setTextureFile(theTextureFile); + ModelAPI_Tools::loadModifiedShapes(aResultBody, anOriginalShapes, ListOfShape(), + aMakeShapeList, *anIt, "Translated"); + // Copy image data, if any + ModelAPI_Tools::copyImageAttribute(aTextureSource, aResultBody); setResult(aResultBody, aResultIndex++); } diff --git a/src/FeaturesPlugin/FeaturesPlugin_Union.cpp b/src/FeaturesPlugin/FeaturesPlugin_Union.cpp index ad7a638de..8120f025d 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Union.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Union.cpp @@ -62,7 +62,7 @@ void FeaturesPlugin_Union::execute() std::string anError; int aResultIndex = 0; - std::vector aResultBaseAlgoList; + std::vector aResultBaseAlgoList; ListOfShape aResultShapesList; GeomShapePtr aResultCompound = GeomAlgoAPI_CompoundBuilder::compound(ListOfShape()); @@ -93,7 +93,7 @@ void FeaturesPlugin_Union::execute() } std::shared_ptr aMakeShapeList(new GeomAlgoAPI_MakeShapeList()); - for (std::vector::iterator + for (std::vector::iterator aRBAIt = aResultBaseAlgoList.begin(); aRBAIt != aResultBaseAlgoList.end(); ++aRBAIt) { aMakeShapeList->appendAlgo(aRBAIt->makeShape); diff --git a/src/FeaturesPlugin/FeaturesPlugin_VersionedBoolean.cpp b/src/FeaturesPlugin/FeaturesPlugin_VersionedBoolean.cpp index 50dd45bcb..d2fe447f3 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_VersionedBoolean.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_VersionedBoolean.cpp @@ -123,7 +123,7 @@ bool FeaturesPlugin_VersionedBoolean::processObject( const ListOfShape& theTools, const ListOfShape& thePlanes, int& theResultIndex, - std::vector& theResultBaseAlgoList, + std::vector& theResultBaseAlgoList, ListOfShape& theResultShapesList, GeomShapePtr theResultCompound) { @@ -187,7 +187,7 @@ bool FeaturesPlugin_VersionedBoolean::processObject( ListOfShape aUsedTools = theTools; aUsedTools.insert(aUsedTools.end(), thePlanes.begin(), thePlanes.end()); - FeaturesPlugin_Tools::loadModifiedShapes(aResultBody, + ModelAPI_Tools::loadModifiedShapes(aResultBody, aListWithObject, aUsedTools, aMakeShapeList, @@ -197,7 +197,7 @@ bool FeaturesPlugin_VersionedBoolean::processObject( } - FeaturesPlugin_Tools::ResultBaseAlgo aRBA; + ModelAPI_Tools::ResultBaseAlgo aRBA; aRBA.resultBody = aResultBody; aRBA.baseShape = theObject; aRBA.makeShape = aMakeShapeList; @@ -215,7 +215,7 @@ bool FeaturesPlugin_VersionedBoolean::processCompsolid( const ListOfShape& theTools, const ListOfShape& thePlanes, int& theResultIndex, - std::vector& theResultBaseAlgoList, + std::vector& theResultBaseAlgoList, ListOfShape& theResultShapesList, GeomShapePtr theResultCompound) { @@ -283,7 +283,7 @@ bool FeaturesPlugin_VersionedBoolean::processCompsolid( ListOfShape aUsedTools = theTools; aUsedTools.insert(aUsedTools.end(), thePlanes.begin(), thePlanes.end()); - FeaturesPlugin_Tools::loadModifiedShapes(aResultBody, + ModelAPI_Tools::loadModifiedShapes(aResultBody, aCompSolidList, aUsedTools, aMakeShapeList, @@ -292,7 +292,7 @@ bool FeaturesPlugin_VersionedBoolean::processCompsolid( ++theResultIndex; } - FeaturesPlugin_Tools::ResultBaseAlgo aRBA; + ModelAPI_Tools::ResultBaseAlgo aRBA; aRBA.resultBody = aResultBody; aRBA.baseShape = theCompsolid; aRBA.makeShape = aMakeShapeList; @@ -309,7 +309,7 @@ bool FeaturesPlugin_VersionedBoolean::processCompound( const GeomShapePtr& theCompound, const ListOfShape& theTools, int& theResultIndex, - std::vector& theResultBaseAlgoList, + std::vector& theResultBaseAlgoList, ListOfShape& theResultShapesList, GeomShapePtr theResultCompound) { @@ -372,7 +372,7 @@ bool FeaturesPlugin_VersionedBoolean::processCompound( ListOfShape aCompoundList; aCompoundList.push_back(theCompound); - FeaturesPlugin_Tools::loadModifiedShapes(aResultBody, + ModelAPI_Tools::loadModifiedShapes(aResultBody, aCompoundList, theTools, aMakeShapeList, @@ -381,7 +381,7 @@ bool FeaturesPlugin_VersionedBoolean::processCompound( ++theResultIndex; } - FeaturesPlugin_Tools::ResultBaseAlgo aRBA; + ModelAPI_Tools::ResultBaseAlgo aRBA; aRBA.resultBody = aResultBody; aRBA.baseShape = theCompound; aRBA.makeShape = aMakeShapeList; diff --git a/src/FeaturesPlugin/FeaturesPlugin_VersionedBoolean.h b/src/FeaturesPlugin/FeaturesPlugin_VersionedBoolean.h index f244542b9..62fecd361 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_VersionedBoolean.h +++ b/src/FeaturesPlugin/FeaturesPlugin_VersionedBoolean.h @@ -27,6 +27,7 @@ #include #include +#include class ModelAPI_Attribute; class ModelAPI_Result; @@ -70,7 +71,7 @@ protected: const ListOfShape& theTools, const ListOfShape& thePlanes, int& theResultIndex, - std::vector& theResultBaseAlgoList, + std::vector& theResultBaseAlgoList, ListOfShape& theResultShapesList, GeomShapePtr theResulCompound = GeomShapePtr()); @@ -84,7 +85,7 @@ protected: const ListOfShape& theTools, const ListOfShape& thePlanes, int& theResultIndex, - std::vector& theResultBaseAlgoList, + std::vector& theResultBaseAlgoList, ListOfShape& theResultShapesList, GeomShapePtr theResulCompound = GeomShapePtr()); @@ -97,7 +98,7 @@ protected: const GeomShapePtr& theCompound, const ListOfShape& theTools, int& theResultIndex, - std::vector& theResultBaseAlgoList, + std::vector& theResultBaseAlgoList, ListOfShape& theResultShapesList, GeomShapePtr theResulCompound = GeomShapePtr()); diff --git a/src/FeaturesPlugin/FeaturesPlugin_VersionedChFi.cpp b/src/FeaturesPlugin/FeaturesPlugin_VersionedChFi.cpp index 7417bf570..0239b2221 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_VersionedChFi.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_VersionedChFi.cpp @@ -18,7 +18,6 @@ // #include "FeaturesPlugin_VersionedChFi.h" -#include "FeaturesPlugin_Tools.h" #include #include @@ -89,8 +88,8 @@ void FeaturesPlugin_VersionedChFi::execute() anObjectHierarchy.topLevelObjects(aTopLevel); for (ListOfShape::iterator anIt = aTopLevel.begin(); anIt != aTopLevel.end(); ++anIt) { ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex); - FeaturesPlugin_Tools::loadModifiedShapes(aResultBody, anOriginalSolids, ListOfShape(), - aMakeShapeList, *anIt, aPrefix); + ModelAPI_Tools::loadModifiedShapes(aResultBody, anOriginalSolids, ListOfShape(), + aMakeShapeList, *anIt, aPrefix); setResult(aResultBody, aResultIndex++); for (ListOfShape::iterator aEIt = anEdges.begin(); aEIt != anEdges.end(); ++aEIt) { @@ -99,8 +98,8 @@ void FeaturesPlugin_VersionedChFi::execute() aResultBody->loadGeneratedShapes(aMakeShapeList, aBase, GeomAPI_Shape::EDGE, aPrefix, true); } - FeaturesPlugin_Tools::loadDeletedShapes(aResultBody, GeomShapePtr(), anOriginalSolids, - aMakeShapeList, *anIt); + ModelAPI_Tools::loadDeletedShapes(aResultBody, GeomShapePtr(), anOriginalSolids, + aMakeShapeList, *anIt); } removeResults(aResultIndex); diff --git a/src/FeaturesPlugin/doc/examples/create_normal_to_face.py b/src/FeaturesPlugin/doc/examples/create_normal_to_face.py index c89e07c6b..f212f2ae1 100644 --- a/src/FeaturesPlugin/doc/examples/create_normal_to_face.py +++ b/src/FeaturesPlugin/doc/examples/create_normal_to_face.py @@ -1,11 +1,12 @@ from salome.shaper import model import os +### Create a Box model.begin() Box_1 = model.addBox(Part_1_doc, 10, 10, 10) model.do() - -### Create BoundingBox + +### Create a top face of the box normal Normal_1 = model.getNormal(Part_1_doc, model.selection("FACE", "Box_1_1/Top")) model.do() diff --git a/src/GeomAlgoAPI/CMakeLists.txt b/src/GeomAlgoAPI/CMakeLists.txt index 2fa736470..19ace76ed 100644 --- a/src/GeomAlgoAPI/CMakeLists.txt +++ b/src/GeomAlgoAPI/CMakeLists.txt @@ -173,7 +173,6 @@ SET(PROJECT_LIBRARIES ${OpenCASCADE_DataExchange_LIBRARIES} ${OpenCASCADE_ModelingAlgorithms_LIBRARIES} ${OpenCASCADE_ApplicationFramework_LIBRARIES} - ${QT_LIBRARIES} ) ADD_DEFINITIONS(-DGEOMALGOAPI_EXPORTS ${OpenCASCADE_DEFINITIONS}) @@ -184,10 +183,7 @@ SET(CMAKE_SWIG_FLAGS -w325,321,362,383,302) SET_SOURCE_FILES_PROPERTIES(GeomAlgoAPI.i PROPERTIES CPLUSPLUS ON) SET_SOURCE_FILES_PROPERTIES(GeomAlgoAPI.i PROPERTIES SWIG_DEFINITIONS "-shadow") -INCLUDE(UseQtExt) # additional include directories -INCLUDE_DIRECTORIES(${QT_INCLUDES}) - INCLUDE_DIRECTORIES( ../GeomAPI ../GeomAlgoImpl diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_ImageImport.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_ImageImport.cpp index 1f73aeef1..d0077871a 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_ImageImport.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_ImageImport.cpp @@ -19,7 +19,6 @@ #include -#include #include #include #include @@ -36,18 +35,13 @@ #include #include -std::shared_ptr ImageImport(const std::string& theFileName, - std::string& theError) +std::shared_ptr ImageImport(const int width, + const int height, + std::string& theError) { TopoDS_Shape aResShape; try { - QPixmap* pixmap = new QPixmap(theFileName.c_str()); - int height = pixmap->height(); - int width = pixmap->width(); - - delete pixmap; - TopoDS_Vertex aTriVertexes[4]; gp_Pnt aPnt1( -0.5*width, -0.5*height, 0); gp_Pnt aPnt2( 0.5*width, -0.5*height, 0); diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_ImageImport.h b/src/GeomAlgoAPI/GeomAlgoAPI_ImageImport.h index 4f9573b48..5a29f8fbf 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_ImageImport.h +++ b/src/GeomAlgoAPI/GeomAlgoAPI_ImageImport.h @@ -23,10 +23,11 @@ #include #include -#include + /// Implementation of the import STL files algorithms GEOMALGOAPI_EXPORT -std::shared_ptr ImageImport(const std::string& theFileName, - std::string& theError); +std::shared_ptr ImageImport(const int theWidth, + const int theHeight, + std::string& theError); #endif /* GEOMALGOAPI_IMAGEIMPORT_H_ */ diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_MakeShape.h b/src/GeomAlgoAPI/GeomAlgoAPI_MakeShape.h index c8b558e37..f928eedda 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_MakeShape.h +++ b/src/GeomAlgoAPI/GeomAlgoAPI_MakeShape.h @@ -149,15 +149,15 @@ public: protected: /// \brief Sets builder type. /// \param[in] theBuilderType new builder type. - void setBuilderType(const BuilderType theBuilderType); + GEOMALGOAPI_EXPORT void setBuilderType(const BuilderType theBuilderType); /// \brief Sets status of builder. /// \param[in] theFlag new status. - void setDone(const bool theFlag); + GEOMALGOAPI_EXPORT void setDone(const bool theFlag); /// \brief Sets result shape. /// \param[in] theShape new shape. - void setShape(const GeomShapePtr theShape); + GEOMALGOAPI_EXPORT void setShape(const GeomShapePtr theShape); /// \return true if passed shape is valid for history. bool isValidForHistory(const GeomShapePtr theShape); diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Tools.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_Tools.cpp index 3bdecb71d..a26b7257e 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_Tools.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Tools.cpp @@ -61,6 +61,14 @@ std::string File_Tools::name(const std::string& theFileName) return aPath.Name().ToCString(); } +std::string File_Tools::path(const std::string& theFileName) +{ + OSD_Path aPath (theFileName.c_str()); + Standard_Integer aTrekLen = + theFileName.size() - aPath.Extension().Length() - aPath.Name().Length(); + return theFileName.substr(0, aTrekLen); +} + bool AlgoError::isAlgorithmFailed(const GeomMakeShapePtr& theAlgorithm, const std::string& theFeature, std::string& theError) diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Tools.h b/src/GeomAlgoAPI/GeomAlgoAPI_Tools.h index d7020e68e..39081890a 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_Tools.h +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Tools.h @@ -63,6 +63,10 @@ public: * Returns a name of theFileName */ GEOMALGOAPI_EXPORT static std::string name(const std::string& theFileName); + /** + * Returns a directory path of theFileName + */ + GEOMALGOAPI_EXPORT static std::string path(const std::string& theFileName); }; /** \class AlgoError diff --git a/src/Model/CMakeLists.txt b/src/Model/CMakeLists.txt index 2f349c193..c270a9c13 100644 --- a/src/Model/CMakeLists.txt +++ b/src/Model/CMakeLists.txt @@ -34,6 +34,7 @@ SET(PROJECT_HEADERS Model_AttributeRefList.h Model_AttributeRefAttrList.h Model_AttributeBoolean.h + Model_AttributeImage.h Model_AttributeIntArray.h Model_AttributeString.h Model_AttributeStringArray.h @@ -72,6 +73,7 @@ SET(PROJECT_SOURCES Model_AttributeRefList.cpp Model_AttributeRefAttrList.cpp Model_AttributeBoolean.cpp + Model_AttributeImage.cpp Model_AttributeIntArray.cpp Model_AttributeString.cpp Model_AttributeStringArray.cpp diff --git a/src/Model/Model_AttributeImage.cpp b/src/Model/Model_AttributeImage.cpp new file mode 100644 index 000000000..c74e42945 --- /dev/null +++ b/src/Model/Model_AttributeImage.cpp @@ -0,0 +1,147 @@ +// Copyright (C) 2014-2021 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 + +void Model_AttributeImage::setTexture(const int theWidth, + const int theHeight, + const std::list& theByteArray, + const std::string& theFormat, + const bool sendUpdated) +{ + if (theWidth > 0 && theHeight > 0 && theByteArray.size() > 0) { // set new data + // Find or create attributes + Handle_TDataStd_ByteArray aByteArray = + TDataStd_ByteArray::Set(myLab, 0, theByteArray.size() - 1); + Handle_TDataStd_IntegerArray aDimensions = + TDataStd_IntegerArray::Set(myLab, 0, 1); + Handle_TDataStd_Comment aFormat = TDataStd_Comment::Set(myLab, theFormat.c_str()); + + // Dimensions + aDimensions->SetValue(0, theWidth); + aDimensions->SetValue(1, theHeight); + + // Texture + Handle(TColStd_HArray1OfByte) aNewArray = + new TColStd_HArray1OfByte(0, theByteArray.size() - 1); + std::list::const_iterator itBA = theByteArray.begin(); + for (int j = 0; itBA != theByteArray.end(); ++itBA, ++j) { + aNewArray->SetValue(j, (Standard_Byte)(*itBA)); + } + aByteArray->ChangeArray(aNewArray); + + if (sendUpdated) + owner()->data()->sendAttributeUpdated(this); + } + else { // size is zero => arrays must be erased + bool isForgotten1 = myLab.ForgetAttribute(TDataStd_ByteArray::GetID()); + bool isForgotten2 = myLab.ForgetAttribute(TDataStd_IntegerArray::GetID()); + bool isForgotten3 = myLab.ForgetAttribute(TDataStd_Comment::GetID()); + + if (sendUpdated && (isForgotten1 || isForgotten2 || isForgotten3)) + owner()->data()->sendAttributeUpdated(this); + } +} + +bool Model_AttributeImage::hasTexture() +{ + Handle_TDataStd_ByteArray aByteArray; + Handle_TDataStd_IntegerArray aDimensions; + if (myLab.FindAttribute(TDataStd_ByteArray::GetID(), aByteArray) == Standard_True && + myLab.FindAttribute(TDataStd_IntegerArray::GetID(), aDimensions) == Standard_True) { + + // Dimensions + if (aDimensions->Value(0) > 0 && aDimensions->Value(1) > 0) + // Byte array + return aByteArray->Length() > 0; + } + return false; +} + +bool Model_AttributeImage::texture(int& theWidth, + int& theHeight, + std::list& theByteArray, + std::string& theFormat) +{ + // Init return values + theWidth = 0; + theHeight = 0; + theByteArray.clear(); + theFormat = ""; + + Handle_TDataStd_ByteArray aByteArray; + Handle_TDataStd_IntegerArray aDimensions; + Handle_TDataStd_Comment aFormat; + if (myLab.FindAttribute(TDataStd_ByteArray::GetID(), aByteArray) == Standard_True && + myLab.FindAttribute(TDataStd_IntegerArray::GetID(), aDimensions) == Standard_True && + myLab.FindAttribute(TDataStd_Comment::GetID(), aFormat) == Standard_True) { + + // Dimensions + theWidth = aDimensions->Value(0); + theHeight = aDimensions->Value(1); + + // Texture + const Handle(TColStd_HArray1OfByte) byteArray = aByteArray->InternalArray(); + for (int j = byteArray->Lower(); j <= byteArray->Upper(); j++) { + theByteArray.push_back((unsigned char)byteArray->Value( j )); + } + + // Format + theFormat = TCollection_AsciiString(aFormat->Get()).ToCString(); + return true; + } + + return false; +} + +void Model_AttributeImage::copyTo(AttributeImagePtr theTarget) const +{ + std::shared_ptr aTarget = + std::dynamic_pointer_cast(theTarget); + if (aTarget) { + //Model_AttributeSelectionList::copyAttrs(myLab, aTarget->myLab); + TDF_CopyLabel aCopyAlgo (myLab, aTarget->myLab); + aCopyAlgo.Perform(); + aTarget->reinit(); + } +} + +Model_AttributeImage::Model_AttributeImage(TDF_Label& theLabel) +{ + myLab = theLabel; + reinit(); +} + +void Model_AttributeImage::reinit() +{ + myIsInitialized = myLab.IsAttribute(TDataStd_ByteArray::GetID()); +} diff --git a/src/Model/Model_AttributeImage.h b/src/Model/Model_AttributeImage.h new file mode 100644 index 000000000..c4827c322 --- /dev/null +++ b/src/Model/Model_AttributeImage.h @@ -0,0 +1,73 @@ +// Copyright (C) 2014-2021 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 MODEL_ATTRIBUTEIMAGE_H_ +#define MODEL_ATTRIBUTEIMAGE_H_ + +#include +#include + +#include + +#include + +/**\class Model_AttributeImage + * \ingroup DataModel + * \brief API for the attribute that contains image inside. + * Represented as the following OCCT attributes: + * TDataStd_ByteArray for the pixmap texture data, + * TDataStd_IntArray(2) for image dimensions (widht and height), + * TDataStd_String for image format. + */ + +class Model_AttributeImage : public ModelAPI_AttributeImage +{ + /// Stores the label as the only reference to all data + TDF_Label myLab; + + public: + /// Defines the value of the image attribute + MODEL_EXPORT virtual void setTexture(const int theWidth, + const int theHeight, + const std::list& theByteArray, + const std::string& theFormat, + const bool sendUpdated = true); + + /// Returns true, if texture width and height are non-zero + MODEL_EXPORT virtual bool hasTexture(); + + /// Returns the value of the image attribute + MODEL_EXPORT virtual bool texture(int& theWidth, + int& theHeight, + std::list& theByteArray, + std::string& theFormat); + + /// Copy the image data to the destination attribute + virtual void copyTo(std::shared_ptr theTarget) const; + + protected: + /// Initializes attibutes + Model_AttributeImage(TDF_Label& theLabel); + /// Reinitializes the internal state of the attribute (may be needed on undo/redo, abort, etc) + virtual void reinit(); + + friend class Model_Data; +}; + +#endif diff --git a/src/Model/Model_Data.cpp b/src/Model/Model_Data.cpp index 817a9e407..599c65086 100644 --- a/src/Model/Model_Data.cpp +++ b/src/Model/Model_Data.cpp @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -218,6 +219,8 @@ AttributePtr Model_Data::addAttribute( anAttr = new Model_AttributeDoubleArray(anAttrLab); } else if (theAttrType == ModelAPI_AttributeTables::typeId()) { anAttr = new Model_AttributeTables(anAttrLab); + } else if (theAttrType == ModelAPI_AttributeImage::typeId()) { + anAttr = new Model_AttributeImage(anAttrLab); } // create also GeomData attributes here because only here the OCAF structure is known else if (theAttrType == GeomData_Point::typeId()) { @@ -375,6 +378,7 @@ GET_ATTRIBUTE_BY_ID(ModelAPI_AttributeRefAttrList, refattrlist); GET_ATTRIBUTE_BY_ID(ModelAPI_AttributeIntArray, intArray); GET_ATTRIBUTE_BY_ID(ModelAPI_AttributeDoubleArray, realArray); GET_ATTRIBUTE_BY_ID(ModelAPI_AttributeTables, tables); +GET_ATTRIBUTE_BY_ID(ModelAPI_AttributeImage, image); std::shared_ptr Model_Data::attribute(const std::string& theID) { diff --git a/src/Model/Model_Data.h b/src/Model/Model_Data.h index df833acc0..bb073eb11 100644 --- a/src/Model/Model_Data.h +++ b/src/Model/Model_Data.h @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -155,6 +156,9 @@ class Model_Data : public ModelAPI_Data /// Returns the attribute that contains string values array MODEL_EXPORT virtual std::shared_ptr tables(const std::string& theID); + /// Returns the attribute that contains image + MODEL_EXPORT virtual std::shared_ptr + image(const std::string& theID); /// Returns the generic attribute by identifier /// \param theID identifier of the attribute diff --git a/src/Model/Model_ResultBody.cpp b/src/Model/Model_ResultBody.cpp index 65b687519..32f439df6 100644 --- a/src/Model/Model_ResultBody.cpp +++ b/src/Model/Model_ResultBody.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -56,6 +57,13 @@ Model_ResultBody::~Model_ResultBody() delete myBuilder; } +void Model_ResultBody::initAttributes() +{ + ModelAPI_Result::initAttributes(); + // append the image attribute. It is empty, the attribute will be filled by a request + data()->addAttribute(IMAGE_ID(), ModelAPI_AttributeImage::typeId())->setIsArgument(false); +} + bool Model_ResultBody::generated(const GeomShapePtr& theNewShape, const std::string& theName, const bool theCheckIsInResult) { @@ -408,17 +416,6 @@ void Model_ResultBody::updateSubs( myHistoryCash.Clear(); } -void Model_ResultBody::setTextureFile(const std::string & theTextureFile) -{ - ModelAPI_Result::setTextureFile(theTextureFile); - for( auto sub : mySubs){ - sub->setTextureFile(theTextureFile); - } - for(auto map : mySubsMap){ - map.first->setTextureFile(theTextureFile); - } -} - bool Model_ResultBody::isConnectedTopology() { TDF_Label aDataLab = std::dynamic_pointer_cast(data())->label(); @@ -448,6 +445,16 @@ void Model_ResultBody::cleanCash() } } +bool Model_ResultBody::hasTexture() +{ + AttributeImagePtr anImageAttr = + data()->image(ModelAPI_ResultBody::IMAGE_ID()); + if (anImageAttr.get()) { + return anImageAttr->hasTexture(); + } + return false; +} + // adds to the theSubSubs map all sub-shapes of theSub if it is compound of compsolid static void collectSubs( const GeomShapePtr theSub, TopTools_MapOfShape& theSubSubs, const bool theOneLevelMore) diff --git a/src/Model/Model_ResultBody.h b/src/Model/Model_ResultBody.h index 721312c3a..4a8479af5 100644 --- a/src/Model/Model_ResultBody.h +++ b/src/Model/Model_ResultBody.h @@ -58,6 +58,9 @@ public: /// Removes the stored builders MODEL_EXPORT virtual ~Model_ResultBody(); + /// Request for initialization of data model of the result body: adding all attributes + virtual void initAttributes(); + /// Records the subshape newShape which was generated during a topological construction. /// As an example, consider the case of a face generated in construction of a box. MODEL_EXPORT virtual bool generated(const GeomShapePtr& theNewShape, @@ -114,7 +117,7 @@ public: MODEL_EXPORT virtual void cleanCash() override; /// sets the texture file - MODEL_EXPORT virtual void setTextureFile(const std::string & theTextureFile) override; + MODEL_EXPORT virtual bool hasTexture() override; protected: diff --git a/src/Model/Model_Session.cpp b/src/Model/Model_Session.cpp index eb4ab5ff9..38ed84cfc 100644 --- a/src/Model/Model_Session.cpp +++ b/src/Model/Model_Session.cpp @@ -179,6 +179,11 @@ std::list Model_Session::redoList() return ROOT_DOC->redoList(); } +bool Model_Session::checkLicense(const std::string& thePluginName) +{ + return getPlugin(thePluginName); +} + ModelAPI_Plugin* Model_Session::getPlugin(const std::string& thePluginName) { if (myPluginObjs.find(thePluginName) == myPluginObjs.end()) { diff --git a/src/Model/Model_Session.h b/src/Model/Model_Session.h index 218659d5a..88397ec4c 100644 --- a/src/Model/Model_Session.h +++ b/src/Model/Model_Session.h @@ -127,6 +127,9 @@ class Model_Session : public ModelAPI_Session, public Events_Listener /// the plugin manager on call of the feature) MODEL_EXPORT virtual void registerPlugin(ModelAPI_Plugin* thePlugin); + /// Verifies the license for the plugin is valid + MODEL_EXPORT virtual bool checkLicense(const std::string& thePluginName); + /// Processes the configuration file reading MODEL_EXPORT virtual void processEvent(const std::shared_ptr& theMessage); diff --git a/src/ModelAPI/CMakeLists.txt b/src/ModelAPI/CMakeLists.txt index d2d565eee..bbef9d3e5 100644 --- a/src/ModelAPI/CMakeLists.txt +++ b/src/ModelAPI/CMakeLists.txt @@ -26,6 +26,7 @@ SET(PROJECT_HEADERS ModelAPI.h ModelAPI_Attribute.h ModelAPI_AttributeBoolean.h + ModelAPI_AttributeImage.h ModelAPI_AttributeIntArray.h ModelAPI_AttributeDocRef.h ModelAPI_AttributeDouble.h @@ -74,6 +75,7 @@ SET(PROJECT_HEADERS SET(PROJECT_SOURCES ModelAPI_Attribute.cpp ModelAPI_AttributeBoolean.cpp + ModelAPI_AttributeImage.cpp ModelAPI_AttributeIntArray.cpp ModelAPI_AttributeDocRef.cpp ModelAPI_AttributeDouble.cpp diff --git a/src/ModelAPI/ModelAPI_AttributeImage.cpp b/src/ModelAPI/ModelAPI_AttributeImage.cpp new file mode 100644 index 000000000..4caea4544 --- /dev/null +++ b/src/ModelAPI/ModelAPI_AttributeImage.cpp @@ -0,0 +1,35 @@ +// Copyright (C) 2014-2021 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 + + +std::string ModelAPI_AttributeImage::attributeType() +{ + return typeId(); +} + +/// To virtually destroy the fields of successors +ModelAPI_AttributeImage::~ModelAPI_AttributeImage() +{ +} + +ModelAPI_AttributeImage::ModelAPI_AttributeImage() +{ +} diff --git a/src/ModelAPI/ModelAPI_AttributeImage.h b/src/ModelAPI/ModelAPI_AttributeImage.h new file mode 100644 index 000000000..14fc1e717 --- /dev/null +++ b/src/ModelAPI/ModelAPI_AttributeImage.h @@ -0,0 +1,78 @@ +// Copyright (C) 2014-2021 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 ModelAPI_AttributeImage_H_ +#define ModelAPI_AttributeImage_H_ + +#include +#include + +#include +#include + + +/**\class ModelAPI_AttributeImage + * \ingroup DataModel + * \brief API for the attribute that contains binary data. + * Used for images storage for an example. By default size is one, zero-based. + */ + +class ModelAPI_AttributeImage : public ModelAPI_Attribute +{ + public: + /// Defines the value of the image attribute + MODELAPI_EXPORT virtual void setTexture(const int theWidth, + const int theHeight, + const std::list& theByteArray, + const std::string& theFormat, + const bool sendUpdated = true) = 0; + + /// Returns true, if texture width and height are non-zero + MODELAPI_EXPORT virtual bool hasTexture() = 0; + + /// Returns the value of the image attribute + MODELAPI_EXPORT virtual bool texture(int& theWidth, + int& theHeight, + std::list& theByteArray, + std::string& theFormat) = 0; + + /// Copy the image data to the destination attribute + virtual void copyTo(std::shared_ptr theTarget) const = 0; + + /// Returns the type of this class of attributes + MODELAPI_EXPORT static std::string typeId() + { + return "Image"; + } + + /// Returns the type of this class of attributes, not static method + MODELAPI_EXPORT virtual std::string attributeType(); + + /// To virtually destroy the fields of successors + MODELAPI_EXPORT virtual ~ModelAPI_AttributeImage(); + + protected: + /// Objects are created for features automatically + MODELAPI_EXPORT ModelAPI_AttributeImage(); +}; + +//! Pointer on image attribute +typedef std::shared_ptr AttributeImagePtr; + +#endif diff --git a/src/ModelAPI/ModelAPI_Data.h b/src/ModelAPI/ModelAPI_Data.h index a8f22355e..a5907974a 100644 --- a/src/ModelAPI/ModelAPI_Data.h +++ b/src/ModelAPI/ModelAPI_Data.h @@ -48,6 +48,7 @@ class ModelAPI_Feature; class ModelAPI_AttributeSelection; class ModelAPI_AttributeSelectionList; class ModelAPI_AttributeIntArray; +class ModelAPI_AttributeImage; class ModelAPI_AttributeTables; class ModelAPI_Object; class GeomAPI_Shape; @@ -113,6 +114,8 @@ class MODELAPI_EXPORT ModelAPI_Data virtual std::shared_ptr intArray(const std::string& theID) = 0; /// Returns the attribute that contains string values array virtual std::shared_ptr stringArray(const std::string& theID) = 0; + /// Returns the attribute that contains image + virtual std::shared_ptr image(const std::string& theID) = 0; /// Returns the attribute that contains tables virtual std::shared_ptr tables(const std::string& theID) = 0; diff --git a/src/ModelAPI/ModelAPI_Events.cpp b/src/ModelAPI/ModelAPI_Events.cpp index 506b26189..a34073894 100644 --- a/src/ModelAPI/ModelAPI_Events.cpp +++ b/src/ModelAPI/ModelAPI_Events.cpp @@ -469,3 +469,23 @@ const ListOfShape& ModelAPI_ShapesFailedMessage::shapes() const { return myShapes; } + + +// ===== ModelAPI_FeaturesLicenseValidMessage ===== +ModelAPI_FeaturesLicenseValidMessage::ModelAPI_FeaturesLicenseValidMessage( + const Events_ID theID, const void* theSender) + : Events_Message(theID, theSender) +{} + +ModelAPI_FeaturesLicenseValidMessage::~ModelAPI_FeaturesLicenseValidMessage() +{} + +void ModelAPI_FeaturesLicenseValidMessage::setFeatures(const std::set& theFeatures) +{ + myFeatures = theFeatures; +} + +const std::set& ModelAPI_FeaturesLicenseValidMessage::features() const +{ + return myFeatures; +} diff --git a/src/ModelAPI/ModelAPI_Events.h b/src/ModelAPI/ModelAPI_Events.h index 2ebd25b0f..b32ef747f 100644 --- a/src/ModelAPI/ModelAPI_Events.h +++ b/src/ModelAPI/ModelAPI_Events.h @@ -119,10 +119,12 @@ MAYBE_UNUSED static const char * EVENT_DOF_OBJECTS = "DoFObjects"; /// Event ID that requests updates visual attributes for presentations MAYBE_UNUSED static const char * EVENT_VISUAL_ATTRIBUTES = "UpdateVisualAttributes"; - /// Event ID that 1D-fillet failed (comes with ModelAPI_ShapesFailedMessage) MAYBE_UNUSED static const char * EVENT_OPERATION_SHAPES_FAILED = "OperationShapesFailed"; +/// Event ID that license of specified features is checked and valid +MAYBE_UNUSED static const char * EVENT_FEATURE_LICENSE_VALID = "FeaturesLicenseValid"; + /// Message that feature was changed (used for Object Browser update): moved, updated and deleted class MODELAPI_EXPORT ModelAPI_ObjectUpdatedMessage : public Events_MessageGroup { @@ -656,4 +658,28 @@ private: std::list< std::shared_ptr > myShapes; }; +/// Message that sends the features which license is checked and valid +class ModelAPI_FeaturesLicenseValidMessage : public Events_Message +{ +public: + /// Creates an message + MODELAPI_EXPORT + ModelAPI_FeaturesLicenseValidMessage(const Events_ID theID, const void* theSender = 0); + /// Default destructor + MODELAPI_EXPORT virtual ~ModelAPI_FeaturesLicenseValidMessage(); + /// Static. Returns EventID of the message. + MODELAPI_EXPORT static Events_ID eventId() + { + return Events_Loop::eventByName(EVENT_FEATURE_LICENSE_VALID); + } + + /// Sets list of features with valid license + MODELAPI_EXPORT void setFeatures(const std::set& theFeatures); + /// Returns list of features with valid license + MODELAPI_EXPORT const std::set& features() const; + +private: + std::set myFeatures; +}; + #endif diff --git a/src/ModelAPI/ModelAPI_Object.h b/src/ModelAPI/ModelAPI_Object.h index 5710af6f9..32e48bc40 100644 --- a/src/ModelAPI/ModelAPI_Object.h +++ b/src/ModelAPI/ModelAPI_Object.h @@ -45,7 +45,6 @@ class ModelAPI_Object: public ModelAPI_Entity { std::shared_ptr myData; ///< manager of the data model of a feature std::shared_ptr myDoc; ///< document this object belongs to - std::string textureFile = ""; public: #ifdef DEBUG_NAMES std::wstring myName; // name of this object @@ -101,19 +100,9 @@ class ModelAPI_Object: public ModelAPI_Entity /// signal. MODELAPI_EXPORT virtual void setDisplayed(const bool theDisplay); - MODELAPI_EXPORT bool hasTextureFile() + MODELAPI_EXPORT virtual bool hasTexture() { - return (textureFile != ""); - } - - MODELAPI_EXPORT virtual void setTextureFile(const std::string & theTextureFile) - { - textureFile = theTextureFile; - } - - MODELAPI_EXPORT const std::string & getTextureFile() - { - return textureFile; + return false; } protected: diff --git a/src/ModelAPI/ModelAPI_Result.h b/src/ModelAPI/ModelAPI_Result.h index 05e48d1de..1fc3c1ab8 100644 --- a/src/ModelAPI/ModelAPI_Result.h +++ b/src/ModelAPI/ModelAPI_Result.h @@ -39,7 +39,7 @@ class ModelAPI_Result : public ModelAPI_Object public: /// Reference to the color of the result. - /// The integer array is used. It contains tree values for red green and blue values. + /// The integer array is used. It contains three values for red, green and blue values. /// The values are in [0, 255] range inline static const std::string& COLOR_ID() { diff --git a/src/ModelAPI/ModelAPI_ResultBody.h b/src/ModelAPI/ModelAPI_ResultBody.h index 5c19f711c..ec323ac28 100644 --- a/src/ModelAPI/ModelAPI_ResultBody.h +++ b/src/ModelAPI/ModelAPI_ResultBody.h @@ -58,6 +58,13 @@ protected: public: MODELAPI_EXPORT virtual ~ModelAPI_ResultBody(); + /// Reference to the image attribute of the result body. + inline static const std::string& IMAGE_ID() + { + static const std::string MY_IMAGE_ID("Image"); + return MY_IMAGE_ID; + } + /// Returns the group identifier of this result MODELAPI_EXPORT virtual std::string groupName(); diff --git a/src/ModelAPI/ModelAPI_Session.h b/src/ModelAPI/ModelAPI_Session.h index 339263fb0..7a1b2f40d 100644 --- a/src/ModelAPI/ModelAPI_Session.h +++ b/src/ModelAPI/ModelAPI_Session.h @@ -97,6 +97,9 @@ class MODELAPI_EXPORT ModelAPI_Session /// the plugin manager on call of the feature) virtual void registerPlugin(ModelAPI_Plugin* thePlugin) = 0; + /// Verifies the license for the plugin is valid + virtual bool checkLicense(const std::string& thePluginName) = 0; + /// Returns the root document of the application (that may contains sub-documents) virtual std::shared_ptr moduleDocument() = 0; diff --git a/src/ModelAPI/ModelAPI_Tools.cpp b/src/ModelAPI/ModelAPI_Tools.cpp index f78af49b8..f93c8aa62 100644 --- a/src/ModelAPI/ModelAPI_Tools.cpp +++ b/src/ModelAPI/ModelAPI_Tools.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -39,6 +40,7 @@ #include #include +#include #include #include @@ -197,6 +199,125 @@ ObjectPtr objectByName(const DocumentPtr& theDocument, const std::string& theGro return ObjectPtr(); } +//================================================================================================== +void loadModifiedShapes(ResultBodyPtr theResultBody, + const ListOfShape& theBaseShapes, + const ListOfShape& theTools, + const GeomMakeShapePtr& theMakeShape, + const GeomShapePtr theResultShape, + const std::string& theNamePrefix) +{ + theResultBody->storeModified(theBaseShapes, theResultShape, theMakeShape); + + ListOfShape aShapes = theBaseShapes; + ListOfShape::const_iterator aToolIter = theTools.cbegin(); + for (; aToolIter != theTools.cend(); aToolIter++) + aShapes.push_back(*aToolIter); + + for (ListOfShape::const_iterator anIter = aShapes.begin(); anIter != aShapes.end(); ++anIter) + { + theResultBody->loadModifiedShapes(theMakeShape, *anIter, GeomAPI_Shape::VERTEX, theNamePrefix); + theResultBody->loadModifiedShapes(theMakeShape, *anIter, GeomAPI_Shape::EDGE, theNamePrefix); + theResultBody->loadModifiedShapes(theMakeShape, *anIter, GeomAPI_Shape::FACE, theNamePrefix); + } +} + +//================================================================================================== +void loadModifiedShapes(ResultBodyPtr theResultBody, + const GeomShapePtr& theBaseShape, + const GeomMakeShapePtr& theMakeShape, + const std::string theName) +{ + switch (theBaseShape->shapeType()) { + case GeomAPI_Shape::COMPOUND: { + for (GeomAPI_ShapeIterator anIt(theBaseShape); anIt.more(); anIt.next()) + { + loadModifiedShapes(theResultBody, + anIt.current(), + theMakeShape, + theName); + } + break; + } + case GeomAPI_Shape::COMPSOLID: + case GeomAPI_Shape::SOLID: + case GeomAPI_Shape::SHELL: { + theResultBody->loadModifiedShapes(theMakeShape, + theBaseShape, + GeomAPI_Shape::FACE, + theName); + } + case GeomAPI_Shape::FACE: + case GeomAPI_Shape::WIRE: { + theResultBody->loadModifiedShapes(theMakeShape, + theBaseShape, + GeomAPI_Shape::EDGE, + theName); + } + case GeomAPI_Shape::EDGE: { + theResultBody->loadModifiedShapes(theMakeShape, + theBaseShape, + GeomAPI_Shape::VERTEX, + theName); + } + default: // [to avoid compilation warning] + break; + } +} + +//================================================================================================== +void loadDeletedShapes(ResultBodyPtr theResultBody, + const GeomShapePtr theBaseShape, + const ListOfShape& theTools, + const GeomMakeShapePtr& theMakeShape, + const GeomShapePtr theResultShapesCompound) +{ + ListOfShape aShapes = theTools; + if (theBaseShape.get()) + aShapes.push_front(theBaseShape); + + for (ListOfShape::const_iterator anIter = aShapes.begin(); anIter != aShapes.end(); anIter++) + { + theResultBody->loadDeletedShapes(theMakeShape, + *anIter, + GeomAPI_Shape::VERTEX, + theResultShapesCompound); + theResultBody->loadDeletedShapes(theMakeShape, + *anIter, + GeomAPI_Shape::EDGE, + theResultShapesCompound); + theResultBody->loadDeletedShapes(theMakeShape, + *anIter, + GeomAPI_Shape::FACE, + theResultShapesCompound); + // store information about deleted solids because of unittest TestBooleanCommon_SolidsHistory + // on OCCT 7.4.0 : common produces modified compsolid, so, move to the end for removed solids + // starts to produce whole compsolid + theResultBody->loadDeletedShapes(theMakeShape, + *anIter, + GeomAPI_Shape::SOLID, + theResultShapesCompound); + } +} + +//================================================================================================== +void loadDeletedShapes(std::vector& theResultBaseAlgoList, + const ListOfShape& theTools, + const GeomShapePtr theResultShapesCompound) +{ + for (std::vector::iterator anIt = theResultBaseAlgoList.begin(); + anIt != theResultBaseAlgoList.end(); + ++anIt) + { + ResultBaseAlgo& aRCA = *anIt; + loadDeletedShapes(aRCA.resultBody, + aRCA.baseShape, + theTools, + aRCA.makeShape, + theResultShapesCompound); + } +} + bool findVariable(const DocumentPtr& theDocument, FeaturePtr theSearcher, const std::wstring& theName, double& outValue, ResultParameterPtr& theParam) { @@ -1025,6 +1146,30 @@ void copyVisualizationAttrs( } } + +void copyImageAttribute (std::shared_ptr theSource, + std::shared_ptr theDest) +{ + if (!theSource.get() || !theDest.get()) + return; + + // images allowed only for ResultBody + ResultBodyPtr aSourceBody = std::dynamic_pointer_cast(theSource); + ResultBodyPtr aDestBody = std::dynamic_pointer_cast(theDest); + if (!aSourceBody.get() || !aDestBody.get()) + return; + + AttributeImagePtr aSourceImage = + theSource->data()->image(ModelAPI_ResultBody::IMAGE_ID()); + if (aSourceImage.get() && aSourceImage->hasTexture()) { + AttributeImagePtr aDestImage = + theDest->data()->image(ModelAPI_ResultBody::IMAGE_ID()); + if (aDestImage.get()) { + aSourceImage->copyTo(aDestImage); + } + } +} + std::list referencedFeatures( std::shared_ptr theTarget, const std::string& theFeatureKind, const bool theSortResults) diff --git a/src/ModelAPI/ModelAPI_Tools.h b/src/ModelAPI/ModelAPI_Tools.h index 79d4f4a8b..7a8d2e482 100644 --- a/src/ModelAPI/ModelAPI_Tools.h +++ b/src/ModelAPI/ModelAPI_Tools.h @@ -29,6 +29,7 @@ class ModelAPI_Result; class ModelAPI_ResultParameter; class ModelAPI_ResultBody; +class GeomAlgoAPI_MakeShape; class GeomAPI_Shape; class GeomAPI_ShapeHierarchy; @@ -49,6 +50,35 @@ MODELAPI_EXPORT std::shared_ptr shape( */ MODELAPI_EXPORT std::string getFeatureError(const std::shared_ptr& theFeature); +MODELAPI_EXPORT struct ResultBaseAlgo { + std::shared_ptr resultBody; + std::shared_ptr baseShape; + std::shared_ptr makeShape; +}; + +MODELAPI_EXPORT void loadModifiedShapes(std::shared_ptr theResultBody, + const std::list>& theBaseShapes, + const std::list>& theTools, + const std::shared_ptr& theMakeShape, + const std::shared_ptr theResultShape, + const std::string& theNamePrefix = ""); + +MODELAPI_EXPORT void loadModifiedShapes(std::shared_ptr theResultBody, + const std::shared_ptr& theBaseShape, + const std::shared_ptr& theMakeShape, + const std::string theName); +/// Stores deleted shapes. +MODELAPI_EXPORT void loadDeletedShapes(std::shared_ptr theResultBody, + const std::shared_ptr theBaseShape, + const std::list>& theTools, + const std::shared_ptr& theMakeShape, + const std::shared_ptr theResultShapesCompound); + +/// Stores deleted shapes. +MODELAPI_EXPORT void loadDeletedShapes(std::vector& theResultBaseAlgoList, + const std::list>& theTools, + const std::shared_ptr theResultShapesCompound); + /*! * Searches for variable with name \param theName in \param theDocument. * If found, set it value in the \param outValue and returns true. @@ -294,6 +324,13 @@ MODELAPI_EXPORT void setTransparency(std::shared_ptr theResult, MODELAPI_EXPORT void copyVisualizationAttrs(std::shared_ptr theSource, std::shared_ptr theDest); +/*! Copies image attribute from one result to another. +* \param theSource a result that contains the image data +* \param theDest a destination result that takes the image data +*/ +MODELAPI_EXPORT void copyImageAttribute(std::shared_ptr theSource, + std::shared_ptr theDest); + /*! Produces list of features that reference to the given target (directly or through sub-results) * \param theTarget the referenced result * \param theFeatureKind the resulting features filter: the feature kind or all for the empty string diff --git a/src/ModelHighAPI/ModelHighAPI_Dumper.h b/src/ModelHighAPI/ModelHighAPI_Dumper.h index a75680380..f4dca43a2 100644 --- a/src/ModelHighAPI/ModelHighAPI_Dumper.h +++ b/src/ModelHighAPI/ModelHighAPI_Dumper.h @@ -169,6 +169,14 @@ public: MODELHIGHAPI_EXPORT bool process(const std::shared_ptr& theDoc, const std::string& theFileName); + /// Keep path to the true dumping directory. + /// It is used to store image files or any other external files + /// \param theDumpDir path to the true dumping directory + MODELHIGHAPI_EXPORT + void setDumpDir(const std::string& theDumpDir) { myDumpDir = theDumpDir; } + /// Return path to the true dumping directory + MODELHIGHAPI_EXPORT std::string getDumpDir() const { return myDumpDir; } + /// Add module to list of imported modules /// \param theModuleName name of the module to be imported MODELHIGHAPI_EXPORT @@ -455,6 +463,8 @@ private: std::list myPostponed; ///< list of postponed entities (sketch constraints or folders) bool myDumpPostponedInProgress; ///< processing postponed is in progress + std::string myDumpDir; + protected: /// list of entities, used by other features but not dumped yet std::set myNotDumpedEntities; diff --git a/src/ModelHighAPI/ModelHighAPI_FeatureStore.cpp b/src/ModelHighAPI/ModelHighAPI_FeatureStore.cpp index 330e61fe1..993defc44 100644 --- a/src/ModelHighAPI/ModelHighAPI_FeatureStore.cpp +++ b/src/ModelHighAPI/ModelHighAPI_FeatureStore.cpp @@ -241,7 +241,12 @@ std::string ModelHighAPI_FeatureStore::dumpAttr(const AttributePtr& theAttr) { } else if (aType == ModelAPI_AttributeString::typeId()) { AttributeStringPtr anAttr = std::dynamic_pointer_cast(theAttr); // do not dump solver DOF for sketch as it may be changed unexpectedly - if(anAttr->id() == "SolverDOF") { + if (anAttr->id() == "SolverDOF") { + return ""; + } + // do not dump file path for Image as it is changed after DumpPython + if (aFeatOwner->getKind() == "ImportImage" && + anAttr->id() == "file_path") { return ""; } aResult<value(); diff --git a/src/ModelHighAPI/ModelHighAPI_Tools.cpp b/src/ModelHighAPI/ModelHighAPI_Tools.cpp index 14ab98878..89f61b480 100644 --- a/src/ModelHighAPI/ModelHighAPI_Tools.cpp +++ b/src/ModelHighAPI/ModelHighAPI_Tools.cpp @@ -29,6 +29,8 @@ #include #include //-------------------------------------------------------------------------------------- +#include +//-------------------------------------------------------------------------------------- #include //-------------------------------------------------------------------------------------- #include @@ -529,6 +531,8 @@ static bool dumpToPython(SessionPtr theSession, if (aDump.get()) { aDump->string("file_path")->setValue(theFilename); aDump->string("file_format")->setValue("py"); + std::string aTrek = GeomAlgoAPI_Tools::File_Tools::path(theFilename); + aDump->string("dump_dir")->setValue(aTrek); aDump->boolean("topological_naming")->setValue((theSelectionType & CHECK_NAMING) != 0); aDump->boolean("geometric_selection")->setValue((theSelectionType & CHECK_GEOMETRICAL) != 0); aDump->boolean("weak_naming")->setValue((theSelectionType & CHECK_WEAK) != 0); diff --git a/src/ModuleBase/ModuleBase_IModule.cpp b/src/ModuleBase/ModuleBase_IModule.cpp index 678837a4d..90124f8d9 100644 --- a/src/ModuleBase/ModuleBase_IModule.cpp +++ b/src/ModuleBase/ModuleBase_IModule.cpp @@ -34,6 +34,7 @@ #include "ModuleBase_Dialog.h" #include "ModuleBase_IErrorMgr.h" +#include #include #include @@ -219,6 +220,33 @@ void ModuleBase_IModule::createFeatures() Config_ModuleReader aXMLReader = Config_ModuleReader(); aXMLReader.readAll(); myFeaturesInFiles = aXMLReader.featuresInFiles(); + myProprietaryFeatures = aXMLReader.proprietaryFeatures(); + myProprietaryPlugins = aXMLReader.proprietaryPlugins(); +} + +void ModuleBase_IModule::processProprietaryFeatures() +{ + std::set::iterator it = myFeaturesValidLicense.begin(); + while (it != myFeaturesValidLicense.end()) { + std::map::iterator aFound = myProprietaryFeatures.find(*it); + if (aFound == myProprietaryFeatures.end()) + ++it; + else { + myFeaturesInFiles[aFound->first] = aFound->second; + myProprietaryFeatures.erase(aFound); + std::set::iterator aRemoveIt = it++; + myFeaturesValidLicense.erase(aRemoveIt); + } + } +} + +void ModuleBase_IModule::loadProprietaryPlugins() +{ + for (std::set::const_iterator itP = myProprietaryPlugins.begin(); + itP != myProprietaryPlugins.end(); ++itP) { + if (!ModelAPI_Session::get()->checkLicense(*itP)) + Events_InfoMessage(*itP, "License of %1 plugin is not valid or not exist!").arg(*itP).send(); + } } diff --git a/src/ModuleBase/ModuleBase_IModule.h b/src/ModuleBase/ModuleBase_IModule.h index 3c3544e11..6ab1badf2 100644 --- a/src/ModuleBase/ModuleBase_IModule.h +++ b/src/ModuleBase/ModuleBase_IModule.h @@ -443,12 +443,24 @@ protected: /// Returns new instance of operation object (used in createOperation for customization) virtual ModuleBase_Operation* getNewOperation(const std::string& theFeatureId); + /// Load plugins required license + void loadProprietaryPlugins(); + + /// Collect features, which have valid license + void processProprietaryFeatures(); + protected: /// Reference to workshop ModuleBase_IWorkshop* myWorkshop; /// Map of features in XML std::map myFeaturesInFiles; + /// Map of features in XML, which require license but not confirmed yet + std::map myProprietaryFeatures; + /// Proprietary plugins + std::set myProprietaryPlugins; + /// Features, which have valid license + std::set myFeaturesValidLicense; std::map mySelectionFilters; diff --git a/src/PartSet/CMakeLists.txt b/src/PartSet/CMakeLists.txt index ebc905b42..915cbdabe 100644 --- a/src/PartSet/CMakeLists.txt +++ b/src/PartSet/CMakeLists.txt @@ -138,7 +138,6 @@ SET(PROJECT_LIBRARIES ${QT_LIBRARIES} ${OpenCASCADE_FoundationClasses_LIBRARIES} ${OpenCASCADE_ApplicationFramework_LIBRARIES} - ${OCCViewer} ) # sources / moc wrappings diff --git a/src/PartSet/PartSet_CustomPrs.cpp b/src/PartSet/PartSet_CustomPrs.cpp index 05f8d9b72..3da462996 100644 --- a/src/PartSet/PartSet_CustomPrs.cpp +++ b/src/PartSet/PartSet_CustomPrs.cpp @@ -171,9 +171,8 @@ bool PartSet_CustomPrs::displayPresentation( isModified = true; } else { - if (myFeature->firstResult().get() && myFeature->firstResult()->hasTextureFile()) - { - PartSet_Module::setTexture( myFeature->firstResult()->getTextureFile(), aPresentation); + if (myFeature->firstResult().get()) { + PartSet_Module::setTexture(aPresentation, myFeature->firstResult()); } anOperationPrs->Redisplay(); isModified = true; diff --git a/src/PartSet/PartSet_Module.cpp b/src/PartSet/PartSet_Module.cpp index 7c66e1748..4da6a7fde 100644 --- a/src/PartSet/PartSet_Module.cpp +++ b/src/PartSet/PartSet_Module.cpp @@ -82,6 +82,7 @@ #include #include #include +#include #include #include @@ -148,9 +149,6 @@ #include #include -#ifdef HAVE_SALOME -#include -#endif #define FEATURE_ITEM_COLOR "0,0,225" @@ -188,6 +186,7 @@ PartSet_Module::PartSet_Module(ModuleBase_IWorkshop* theWshop) Events_Loop* aLoop = Events_Loop::loop(); aLoop->registerListener(this, Events_Loop::eventByName(EVENT_DOCUMENT_CHANGED)); aLoop->registerListener(this, Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY)); + aLoop->registerListener(this, Events_Loop::eventByName(EVENT_FEATURE_LICENSE_VALID)); registerSelectionFilter(SF_GlobalFilter, new PartSet_GlobalFilter(myWorkshop)); registerSelectionFilter(SF_FilterInfinite, new PartSet_FilterInfinite(myWorkshop)); @@ -287,6 +286,7 @@ void PartSet_Module::createFeatures() ModuleBase_IModule::createFeatures(); myRoot = new PartSet_RootNode(); myRoot->setWorkshop(workshop()); + ModuleBase_IModule::loadProprietaryPlugins(); } @@ -1406,13 +1406,46 @@ double getResultTransparency(const ResultPtr& theResult) return aTransparency; } +static AttributeImagePtr findImage(const ObjectPtr& theResult) +{ + AttributeImagePtr anImageAttr; + + if (theResult.get()) { + ResultBodyPtr aResultBody = + std::dynamic_pointer_cast(theResult); + if (aResultBody.get()) { + anImageAttr = aResultBody->data()->image(ModelAPI_ResultBody::IMAGE_ID()); + if (!anImageAttr.get() || !anImageAttr->hasTexture()) { + // try to find an image attribute in parents + ObjectPtr aParent = theResult->document()->parent(theResult); + anImageAttr = findImage(aParent); + } + } + } + + return anImageAttr; +} + //****************************************************** -void PartSet_Module::setTexture(const std::string & theTextureFile, const AISObjectPtr& thePrs) +void PartSet_Module::setTexture(const AISObjectPtr& thePrs, + const ResultPtr& theResult) { -#ifdef HAVE_SALOME + ResultBodyPtr aResultBody = + std::dynamic_pointer_cast(theResult); + if (!aResultBody.get()) + return; + + AttributeImagePtr anImageAttr = findImage(theResult); + if (!anImageAttr.get() || !anImageAttr->hasTexture()) + return; + + int aWidth, aHeight; + std::string aFormat; + std::list aByteList; + anImageAttr->texture(aWidth, aHeight, aByteList, aFormat); + Handle(AIS_InteractiveObject) anAIS = thePrs->impl(); - if (!anAIS.IsNull()) - { + if (!anAIS.IsNull()) { /// set color to white and change material aspect, /// in order to keep a natural apect of the image. thePrs->setColor(255, 255, 255); @@ -1429,11 +1462,21 @@ void PartSet_Module::setTexture(const std::string & theTextureFile, const AISObj myDrawer->ShadingAspect()->Aspect()->SetFrontMaterial(aMatAspect); myDrawer->ShadingAspect()->Aspect()->SetBackMaterial(aMatAspect); - Handle(Image_PixMap) aPixmap; - QPixmap px(theTextureFile.c_str()); - - if (!px.isNull() ) - aPixmap = OCCViewer_Utilities::imageToPixmap( px.toImage()); + //aPixmap = OCCViewer_Utilities::imageToPixmap( px.toImage()); + Handle(Image_PixMap) aPixmap = new Image_PixMap(); + aPixmap->InitTrash(Image_PixMap::ImgBGRA, aWidth, aHeight); + std::list::iterator aByteIter = aByteList.begin(); + for (int aLine = 0; aLine < aHeight; ++aLine) { + // convert pixels from ARGB to renderer-compatible RGBA + for (int aByte = 0; aByte < aWidth; ++aByte) { + Image_ColorBGRA& aPixmapBytes = aPixmap->ChangeValue(aLine, aByte); + + aPixmapBytes.b() = (Standard_Byte) *aByteIter++; + aPixmapBytes.g() = (Standard_Byte) *aByteIter++; + aPixmapBytes.r() = (Standard_Byte) *aByteIter++; + aPixmapBytes.a() = (Standard_Byte) *aByteIter++; + } + } anAISShape->Attributes()->ShadingAspect()->Aspect()->SetTextureMap (new Graphic3d_Texture2Dmanual(aPixmap)); @@ -1442,7 +1485,6 @@ void PartSet_Module::setTexture(const std::string & theTextureFile, const AISObj anAISShape->SetDisplayMode(AIS_Shaded); } } -#endif } //****************************************************** @@ -1487,10 +1529,8 @@ void PartSet_Module::customizePresentation(const ObjectPtr& theObject, thePrs->setDeflection(getResultDeflection(aResult)); thePrs->setTransparency(getResultTransparency(aResult)); - /// set texture parameters - if(aResult->hasTextureFile()) { - setTexture(aResult->getTextureFile(), thePrs); - } + /// set texture parameters, if any + setTexture(thePrs, aResult); } if (aFeature.get() && (aFeature->getKind() == SketchPlugin_Sketch::ID())) { thePrs->setWidth(2); @@ -1711,6 +1751,12 @@ void PartSet_Module::processEvent(const std::shared_ptr& theMess mySketchMgr->previewSketchPlane()->createSketchPlane(aSketch, myWorkshop); } } + else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_FEATURE_LICENSE_VALID)) { + std::shared_ptr aMsg = + std::dynamic_pointer_cast(theMessage); + myFeaturesValidLicense.insert(aMsg->features().begin(), aMsg->features().end()); + processProprietaryFeatures(); + } } //****************************************************** diff --git a/src/PartSet/PartSet_Module.h b/src/PartSet/PartSet_Module.h index e47fabe9d..7a39b8998 100644 --- a/src/PartSet/PartSet_Module.h +++ b/src/PartSet/PartSet_Module.h @@ -400,7 +400,7 @@ public: virtual void createFeatures(); /// add texture - static void setTexture(const std::string &theTextureFile, const AISObjectPtr& thePrs); + static void setTexture(const AISObjectPtr& thePrs, const ResultPtr& theResult); public slots: /// Slolt called on object display diff --git a/src/PythonAPI/model/__init__.py b/src/PythonAPI/model/__init__.py index 6e2d15b70..a92957fdf 100644 --- a/src/PythonAPI/model/__init__.py +++ b/src/PythonAPI/model/__init__.py @@ -44,3 +44,14 @@ from .partset import * from .primitives import * from .gdml import * from .tests import * + +# Add-on features + +from .addons import * +# move functions from .addons to top level (model) package +import inspect +for attribute_name in dir(addons): + attribute = getattr(addons, attribute_name) + if inspect.isfunction(attribute): + globals()[attribute_name] = attribute +del inspect diff --git a/src/PythonAPI/model/addons/__init__.py b/src/PythonAPI/model/addons/__init__.py new file mode 100644 index 000000000..cd9117869 --- /dev/null +++ b/src/PythonAPI/model/addons/__init__.py @@ -0,0 +1,33 @@ +# Copyright (C) 2015-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 +# + +import pkgutil, inspect + +__all__ = [] +for loader, module_name, is_pkg in pkgutil.walk_packages(__path__): + __all__.append(module_name) + module = loader.find_module(module_name).load_module(module_name) + globals()[module_name] = module + + for attribute_name in dir(module): + attribute = getattr(module, attribute_name) + if inspect.isfunction(attribute): + globals()[attribute_name] = attribute + +del pkgutil, inspect \ No newline at end of file diff --git a/src/SHAPERGUI/SHAPERGUI_DataModel.cpp b/src/SHAPERGUI/SHAPERGUI_DataModel.cpp index 989771917..17bbb19a9 100644 --- a/src/SHAPERGUI/SHAPERGUI_DataModel.cpp +++ b/src/SHAPERGUI/SHAPERGUI_DataModel.cpp @@ -184,6 +184,14 @@ bool SHAPERGUI_DataModel::dumpPython(const QString& thePath, CAM_Study* theStudy ModelAPI_Session::get()->startOperation(ExchangePlugin_Dump::ID()); FeaturePtr aFeature = aDoc->addFeature(ExchangePlugin_Dump::ID()); if (aFeature.get()) { + // keep path to the true dumping directory for external files dumping + AttributeStringPtr aAttr = aFeature->string(ExchangePlugin_Dump::DUMP_DIR_ID()); + if (aAttr.get()) { + QString aDirPath = QFileInfo(thePath).path(); + aAttr->setValue(aDirPath.toStdString()); + } + + // tmp path to write the script std::string aTmpDir = aStudy->GetTmpDir(thePath.toStdString().c_str(), isMultiFile); std::string aFileName = aTmpDir + DUMP_NAME; @@ -191,7 +199,7 @@ bool SHAPERGUI_DataModel::dumpPython(const QString& thePath, CAM_Study* theStudy QFile::remove(aFileName.c_str()); } - AttributeStringPtr aAttr = aFeature->string(ExchangePlugin_Dump::FILE_PATH_ID()); + aAttr = aFeature->string(ExchangePlugin_Dump::FILE_PATH_ID()); if (aAttr.get()) aAttr->setValue(aFileName); @@ -206,7 +214,7 @@ bool SHAPERGUI_DataModel::dumpPython(const QString& thePath, CAM_Study* theStudy ModelAPI_Session::get()->finishOperation(); if (QFile::exists(aFileName.c_str())) { - QFile aInFile(aFileName.c_str()); + QFile aInFile(aFileName.c_str()); if (!aInFile.open(QIODevice::ReadOnly | QIODevice::Text)) return false; QTextStream aText(&aInFile);