X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FModelHighAPI%2FModelHighAPI_Dumper.cpp;h=20e8ff20f36c221f489705c00c7b8ca20b1eb388;hb=6b615b773dd6e6901cd246ecb55003a9941e2365;hp=442e0383a9f16d1793d16828f3da726c23060cdc;hpb=0a24b0758dc7d946175bb11f8a96b534c8b146da;p=modules%2Fshaper.git diff --git a/src/ModelHighAPI/ModelHighAPI_Dumper.cpp b/src/ModelHighAPI/ModelHighAPI_Dumper.cpp index 442e0383a..20e8ff20f 100644 --- a/src/ModelHighAPI/ModelHighAPI_Dumper.cpp +++ b/src/ModelHighAPI/ModelHighAPI_Dumper.cpp @@ -1,10 +1,23 @@ -// Copyright (C) 2016-20xx CEA/DEN, EDF R&D --> +// Copyright (C) 2014-2017 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 +// -// File: ModelHighAPI_Dumper.cpp -// Created: 1 August 2016 -// Author: Artem ZHIDKOV - -//-------------------------------------------------------------------------------------- #include "ModelHighAPI_Dumper.h" #include @@ -28,14 +41,18 @@ #include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include +#include #include @@ -79,6 +96,9 @@ void ModelHighAPI_Dumper::clear(bool bufferOnly) myFeatureCount.clear(); while (!myEntitiesStack.empty()) myEntitiesStack.pop(); + + myPostponed.clear(); + myDumpPostponedInProgress = false; } } @@ -87,6 +107,18 @@ void ModelHighAPI_Dumper::clearNotDumped() myNotDumpedEntities.clear(); } +// Convert string to integer. If the string is not a number, return -1 +static int toInt(const std::string& theString) +{ + std::string::const_iterator aChar = theString.begin(); + for (; aChar != theString.end(); ++aChar) + if (!std::isdigit(*aChar)) + break; + if (aChar != theString.end()) + return -1; // not a number + return std::stoi(theString); +} + const std::string& ModelHighAPI_Dumper::name(const EntityPtr& theEntity, bool theSaveNotDumped, bool theUseEntityName) @@ -96,21 +128,33 @@ const std::string& ModelHighAPI_Dumper::name(const EntityPtr& theEntity, return aFound->second.myCurrentName; // entity is not found, store it - std::string aName; + std::string aName, aKind; bool isDefaultName = false; + bool isSaveNotDumped = theSaveNotDumped; std::ostringstream aDefaultName; FeaturePtr aFeature = std::dynamic_pointer_cast(theEntity); if (aFeature) { aName = aFeature->name(); - const std::string& aKind = aFeature->getKind(); - DocumentPtr aDoc = aFeature->document(); + aKind = aFeature->getKind(); + } else { + FolderPtr aFolder = std::dynamic_pointer_cast(theEntity); + if (aFolder) { + aName = aFolder->data()->name(); + aKind = ModelAPI_Folder::ID(); + isSaveNotDumped = false; + } + } + + ObjectPtr anObject = std::dynamic_pointer_cast(theEntity); + if (anObject) { + DocumentPtr aDoc = anObject->document(); int& aNbFeatures = myFeatureCount[aDoc][aKind]; aNbFeatures += 1; size_t anIndex = aName.find(aKind); if (anIndex == 0 && aName[aKind.length()] == '_') { // name starts with "FeatureKind_" std::string anIdStr = aName.substr(aKind.length() + 1); - int anId = std::stoi(anIdStr); + int anId = toInt(anIdStr); // Check number of already registered objects of such kind. Index of current object // should be the same to identify feature's name as automatically generated. @@ -136,7 +180,7 @@ const std::string& ModelHighAPI_Dumper::name(const EntityPtr& theEntity, } myNames[theEntity] = EntityName(aDefaultName.str(), aName, isDefaultName); - if (theSaveNotDumped) + if (isSaveNotDumped) myNotDumpedEntities.insert(theEntity); // store names of results @@ -164,32 +208,36 @@ const std::string& ModelHighAPI_Dumper::parentName(const FeaturePtr& theEntity) void ModelHighAPI_Dumper::saveResultNames(const FeaturePtr& theFeature) { // Default name of the feature - const std::string& aKind = theFeature->getKind(); - DocumentPtr aDoc = theFeature->document(); - int aNbFeatures = myFeatureCount[aDoc][aKind]; - std::ostringstream aNameStream; - aNameStream << aKind << "_" << aNbFeatures; - std::string aFeatureName = aNameStream.str(); + bool isFeatureDefaultName = myNames[theFeature].myIsDefault; // Save only names of results which is not correspond to default feature name const std::list& aResults = theFeature->results(); std::list::const_iterator aResIt = aResults.begin(); - for (int i = 1; aResIt != aResults.end(); ++aResIt, ++i) { - bool isUserDefined = true; + for (int i = 0; aResIt != aResults.end(); ++aResIt, ++i) { + std::pair aName = ModelAPI_Tools::getDefaultName(*aResIt, i); + std::string aDefaultName = aName.first; std::string aResName = (*aResIt)->data()->name(); - size_t anIndex = aResName.find(aFeatureName); - if (anIndex == 0) { - std::string aSuffix = aResName.substr(aFeatureName.length()); - if (aSuffix.empty() && i == 1) // first result may not constain index in the name - isUserDefined = false; - else { - if (aSuffix[0] == '_' && std::stoi(aSuffix.substr(1)) == i) - isUserDefined = false; - } - } + + bool isUserDefined = !(isFeatureDefaultName && aDefaultName == aResName); myNames[*aResIt] = EntityName(aResName, (isUserDefined ? aResName : std::string()), !isUserDefined); + + // check names of sub-results for CompSolid + ResultCompSolidPtr aCompSolid = std::dynamic_pointer_cast(*aResIt); + if (aCompSolid) { + int aNbSubs = aCompSolid->numberOfSubs(); + for (int j = 0; j < aNbSubs; ++j) { + ResultPtr aSub = aCompSolid->subResult(j); + std::string aSubName = aSub->data()->name(); + aName = ModelAPI_Tools::getDefaultName(aSub, j); + aDefaultName = aName.first; + + bool isUserDefinedSubName = isUserDefined || aDefaultName != aSubName; + myNames[aSub] = EntityName(aSubName, + (isUserDefinedSubName ? aSubName : std::string()), !isUserDefinedSubName); + } + } } } @@ -208,32 +256,51 @@ bool ModelHighAPI_Dumper::process(const std::shared_ptr& theD bool ModelHighAPI_Dumper::process(const std::shared_ptr& theDoc) { bool isOk = true; - std::list aFeatures = theDoc->allFeatures(); - std::list::const_iterator aFeatIt = aFeatures.begin(); + std::list anObjects = theDoc->allObjects(); + std::list::const_iterator anObjIt = anObjects.begin(); // firstly, dump all parameters - for (; aFeatIt != aFeatures.end(); ++ aFeatIt) - dumpParameter(*aFeatIt); + for (; anObjIt != anObjects.end(); ++ anObjIt) { + FeaturePtr aFeature = std::dynamic_pointer_cast(*anObjIt); + if (aFeature) + dumpParameter(aFeature); + } // dump all other features - for (aFeatIt = aFeatures.begin(); aFeatIt != aFeatures.end(); ++aFeatIt) { - CompositeFeaturePtr aCompFeat = std::dynamic_pointer_cast(*aFeatIt); + for (anObjIt = anObjects.begin(); anObjIt != anObjects.end(); ++anObjIt) { + CompositeFeaturePtr aCompFeat = std::dynamic_pointer_cast(*anObjIt); if (aCompFeat) // iteratively process composite features isOk = process(aCompFeat) && isOk; - else if (!isDumped(*aFeatIt)) // dump common feature - dumpFeature(*aFeatIt); + else if (!isDumped(EntityPtr(*anObjIt))) { + // dump folder + FolderPtr aFolder = std::dynamic_pointer_cast(*anObjIt); + if (aFolder) + dumpFolder(aFolder); + else { + FeaturePtr aFeature = std::dynamic_pointer_cast(*anObjIt); + if (aFeature) // dump common feature + dumpFeature(aFeature); + } + } } + // dump folders if any + dumpPostponed(true); return isOk; } -bool ModelHighAPI_Dumper::process(const std::shared_ptr& theComposite, bool isForce) +bool ModelHighAPI_Dumper::process(const std::shared_ptr& theComposite, + bool isForce) { // increase composite features stack ++gCompositeStackDepth; // dump composite itself - if (!isDumped(theComposite) || isForce) + if (!isDumped(EntityPtr(theComposite)) || isForce) dumpFeature(FeaturePtr(theComposite), isForce); // sub-part is processed independently, because it provides separate document if (theComposite->getKind() == PartSetPlugin_Part::ID()) { + // dump name of the part if it is different from default + if (!myEntitiesStack.empty()) + dumpEntitySetName(); + // decrease composite features stack because we run into separate document --gCompositeStackDepth; @@ -252,7 +319,9 @@ bool ModelHighAPI_Dumper::process(const std::shared_ptr& theComposite, - bool theDumpModelDo) +bool ModelHighAPI_Dumper::processSubs( + const std::shared_ptr& theComposite, + bool theDumpModelDo) { bool isOk = true; // dump all sub-features; @@ -272,7 +344,7 @@ bool ModelHighAPI_Dumper::processSubs(const std::shared_ptrnumberOfSubs(); for (int anIndex = 0; anIndex < aNbSubs; ++anIndex) { FeaturePtr aFeature = theComposite->subFeature(anIndex); - if (isDumped(aFeature)) + if (isDumped(EntityPtr(aFeature))) continue; isSubDumped = true; @@ -297,9 +369,48 @@ bool ModelHighAPI_Dumper::processSubs(const std::shared_ptr aPostponedCopy = myPostponed; + myPostponed.clear(); + + // iterate over postponed entities and try to dump them + std::list::const_iterator anIt = aPostponedCopy.begin(); + for (; anIt != aPostponedCopy.end(); ++anIt) { + FolderPtr aFolder = std::dynamic_pointer_cast(*anIt); + if (aFolder) { + if (theDumpFolders) + dumpFolder(aFolder); + else + myPostponed.push_back(*anIt); + } + else { + FeaturePtr aFeature = std::dynamic_pointer_cast(*anIt); + if (aFeature) + dumpFeature(aFeature); + } + } + myDumpPostponedInProgress = false; +} + void ModelHighAPI_Dumper::dumpSubFeatureNameAndColor(const std::string theSubFeatureGet, const FeaturePtr& theSubFeature) { @@ -333,7 +444,7 @@ bool ModelHighAPI_Dumper::exportTo(const std::string& theFileName) for (ModulesMap::const_iterator aModIt = myModules.begin(); aModIt != myModules.end(); ++aModIt) { aFile << "from " << aModIt->first << " import "; - if (aModIt->second.empty() || + if (aModIt->second.empty() || aModIt->second.find(std::string()) != aModIt->second.end()) aFile << "*"; // import whole module else { @@ -348,7 +459,7 @@ bool ModelHighAPI_Dumper::exportTo(const std::string& theFileName) if (!myModules.empty()) aFile << std::endl; - aFile << "import model" << std::endl << std::endl; + aFile << "from salome.shaper import model" << std::endl << std::endl; aFile << "model.begin()" << std::endl; // dump collected data @@ -408,21 +519,56 @@ void ModelHighAPI_Dumper::dumpEntitySetName() } // set result deflection if (!isDefaultDeflection(*aResIt)) { - AttributeDoublePtr aDeflectionAttr = (*aResIt)->data()->real(ModelAPI_Result::DEFLECTION_ID()); + AttributeDoublePtr aDeflectionAttr = + (*aResIt)->data()->real(ModelAPI_Result::DEFLECTION_ID()); if(aDeflectionAttr.get() && aDeflectionAttr->isInitialized()) { *this << *aResIt; myDumpBuffer << ".setDeflection(" << aDeflectionAttr->value() << ")" << std::endl; } } + // set result transparency + if (!isDefaultTransparency(*aResIt)) { + AttributeDoublePtr aTransparencyAttr = + (*aResIt)->data()->real(ModelAPI_Result::TRANSPARENCY_ID()); + if(aTransparencyAttr.get() && aTransparencyAttr->isInitialized()) { + *this << *aResIt; + myDumpBuffer << ".setTransparency(" << aTransparencyAttr->value() << ")" << std::endl; + } + } } + myNames[aLastDumped.myEntity].myIsDumped = true; myEntitiesStack.pop(); } bool ModelHighAPI_Dumper::isDumped(const EntityPtr& theEntity) const { EntityNameMap::const_iterator aFound = myNames.find(theEntity); - return aFound != myNames.end(); + FeaturePtr aFeature = std::dynamic_pointer_cast(theEntity); + return (aFound != myNames.end() && aFound->second.myIsDumped) || + myFeaturesToSkip.find(aFeature) != myFeaturesToSkip.end(); +} + +bool ModelHighAPI_Dumper::isDumped(const AttributeRefAttrPtr& theRefAttr) const +{ + FeaturePtr aFeature; + if (theRefAttr->isObject()) + aFeature = ModelAPI_Feature::feature(theRefAttr->object()); + else + aFeature = ModelAPI_Feature::feature(theRefAttr->attr()->owner()); + return aFeature && isDumped(EntityPtr(aFeature)); +} + +bool ModelHighAPI_Dumper::isDumped(const AttributeRefListPtr& theRefList) const +{ + std::list aRefs = theRefList->list(); + std::list::iterator anIt = aRefs.begin(); + for (; anIt != aRefs.end(); ++anIt) { + FeaturePtr aFeature = ModelAPI_Feature::feature(*anIt); + if (aFeature && !isDumped(EntityPtr(aFeature))) + return false; + } + return true; } bool ModelHighAPI_Dumper::isDefaultColor(const ResultPtr& theResult) const @@ -465,15 +611,22 @@ bool ModelHighAPI_Dumper::isDefaultDeflection(const ResultPtr& theResult) const } } if (isConstruction) - aDefault = Config_PropManager::real("Visualization", "construction_deflection", - ModelAPI_ResultConstruction::DEFAULT_DEFLECTION()); + aDefault = Config_PropManager::real("Visualization", "construction_deflection"); else - aDefault = Config_PropManager::real("Visualization", "body_deflection", - ModelAPI_ResultBody::DEFAULT_DEFLECTION()); + aDefault = Config_PropManager::real("Visualization", "body_deflection"); return fabs(aCurrent - aDefault) < 1.e-12; } +bool ModelHighAPI_Dumper::isDefaultTransparency(const ResultPtr& theResult) const +{ + AttributeDoublePtr anAttribute = theResult->data()->real(ModelAPI_Result::TRANSPARENCY_ID()); + if(!anAttribute || !anAttribute->isInitialized()) { + return true; + } + return fabs(anAttribute->value()) < 1.e-12; +} + ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<(const char theChar) { myDumpBuffer << theChar; @@ -602,20 +755,44 @@ ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<( return *this; } +ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<(const FolderPtr& theFolder) +{ + myDumpBuffer << name(theFolder); + return *this; +} + ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<(const FeaturePtr& theEntity) { myDumpBuffer << name(theEntity); - bool isUserDefinedName = !myNames[theEntity].myIsDefault; - // store results if they have user-defined names or colors - std::list aResultsWithNameOrColor; - const std::list& aResults = theEntity->results(); - std::list::const_iterator aResIt = aResults.begin(); - for (; aResIt != aResults.end(); ++aResIt) - if (!myNames[*aResIt].myIsDefault || !isDefaultColor(*aResIt) || !isDefaultDeflection(*aResIt)) - aResultsWithNameOrColor.push_back(*aResIt); - // store just dumped entity to stack - myEntitiesStack.push(LastDumpedEntity(theEntity, isUserDefinedName, aResultsWithNameOrColor)); + if (!myNames[theEntity].myIsDumped) { + bool isUserDefinedName = !myNames[theEntity].myIsDefault; + // store results if they have user-defined names or colors + std::list aResultsWithNameOrColor; + const std::list& aResults = theEntity->results(); + std::list::const_iterator aResIt = aResults.begin(); + for (; aResIt != aResults.end(); ++aResIt) { + if (!myNames[*aResIt].myIsDefault || !isDefaultColor(*aResIt) || + !isDefaultDeflection(*aResIt) || !isDefaultTransparency(*aResIt)) + aResultsWithNameOrColor.push_back(*aResIt); + + ResultCompSolidPtr aCompSolid = + std::dynamic_pointer_cast(*aResIt); + if (aCompSolid) { + int aNbSubs = aCompSolid->numberOfSubs(); + for (int i = 0; i < aNbSubs; ++i) { + ResultPtr aCurRes = aCompSolid->subResult(i); + if (!myNames[aCurRes].myIsDefault || !isDefaultColor(aCurRes) || + !isDefaultDeflection(aCurRes) || !isDefaultTransparency(aCurRes)) + aResultsWithNameOrColor.push_back(aCurRes); + } + } + } + // store just dumped entity to stack + if (myEntitiesStack.empty() || myEntitiesStack.top().myEntity != theEntity) + myEntitiesStack.push( + LastDumpedEntity(theEntity, isUserDefinedName, aResultsWithNameOrColor)); + } // remove entity from the list of not dumped items myNotDumpedEntities.erase(theEntity); @@ -626,13 +803,35 @@ ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<(const ResultPtr& theResult) { FeaturePtr aFeature = ModelAPI_Feature::feature(theResult); int anIndex = 0; + int aSubIndex = -1; std::list aResults = aFeature->results(); - for(std::list::const_iterator anIt = aResults.cbegin(); anIt != aResults.cend(); ++anIt, ++anIndex) { + for(std::list::const_iterator + anIt = aResults.cbegin(); anIt != aResults.cend(); ++anIt, ++anIndex) { if(theResult->isSame(*anIt)) { break; } + + ResultCompSolidPtr aCompSolid = std::dynamic_pointer_cast(*anIt); + if (aCompSolid) { + int aNbSubs = aCompSolid->numberOfSubs(); + for (aSubIndex = 0; aSubIndex < aNbSubs; ++aSubIndex) + if (theResult->isSame(aCompSolid->subResult(aSubIndex))) + break; + if (aSubIndex < aNbSubs) + break; + aSubIndex = -1; + } + } + + myDumpBuffer << name(aFeature); + if(anIndex == 0) { + myDumpBuffer << ".result()"; + } else { + myDumpBuffer << ".results()[" << anIndex << "]"; + } + if (aSubIndex >= 0) { + myDumpBuffer << ".subResult(" << aSubIndex << ")"; } - myDumpBuffer << name(aFeature) << ".result()[" << anIndex << "]"; return *this; } @@ -768,7 +967,8 @@ ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<( return *this; } - myDumpBuffer << "\"" << aShape->shapeTypeStr() << "\", \"" << theAttrSelect->namingName() << "\")"; + myDumpBuffer << "\"" << aShape->shapeTypeStr() << "\", \"" << + theAttrSelect->namingName() << "\")"; return *this; } @@ -786,7 +986,9 @@ ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<( AttributeSelectionPtr anAttribute = theAttrSelList->value(anIndex); aShape = anAttribute->value(); if(!aShape.get()) { - aShape = anAttribute->context()->shape(); + ResultPtr aContext = anAttribute->context(); + if (aContext.get()) + aShape = aContext->shape(); } if(!aShape.get()) { @@ -798,28 +1000,54 @@ ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<( } else { isAdded = true; } - myDumpBuffer << "model.selection(\"" << aShape->shapeTypeStr() << "\", \"" << anAttribute->namingName() << "\")"; + myDumpBuffer << "model.selection(\"" << + aShape->shapeTypeStr() << "\", \"" << anAttribute->namingName() << "\")"; } myDumpBuffer << "]"; return *this; } +ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<( + const std::shared_ptr& theArray) +{ + myDumpBuffer<<"["; + for(int anIndex = 0; anIndex < theArray->size(); ++anIndex) { + if (anIndex != 0) + myDumpBuffer<<", "; + + myDumpBuffer<<"\""<value(anIndex)<<"\""; + } + + myDumpBuffer<<"]"; + return *this; +} + /// Dump std::endl -MODELHIGHAPI_EXPORT ModelHighAPI_Dumper& operator<<(ModelHighAPI_Dumper& theDumper, std::basic_ostream& (*theEndl)(std::basic_ostream&)) { theDumper.myDumpBuffer << theEndl; if (!theDumper.myEntitiesStack.empty()) { - // Name for composite feature is dumped when all sub-entities are dumped - // (see method ModelHighAPI_Dumper::processSubs). - const ModelHighAPI_Dumper::LastDumpedEntity& aLastDumped = theDumper.myEntitiesStack.top(); - CompositeFeaturePtr aComposite = - std::dynamic_pointer_cast(aLastDumped.myEntity); - if (!aComposite) - theDumper.dumpEntitySetName(); + bool isCopy; + // all copies have been stored into stack, pop them all + do { + isCopy = false; + // Name for composite feature is dumped when all sub-entities are dumped + // (see method ModelHighAPI_Dumper::processSubs). + const ModelHighAPI_Dumper::LastDumpedEntity& aLastDumped = theDumper.myEntitiesStack.top(); + CompositeFeaturePtr aComposite = + std::dynamic_pointer_cast(aLastDumped.myEntity); + if (!aComposite) { + theDumper.dumpEntitySetName(); + FeaturePtr aFeature = std::dynamic_pointer_cast(aLastDumped.myEntity); + if (aFeature) { + AttributeBooleanPtr aCopyAttr = aFeature->boolean("Copy"); + isCopy = aCopyAttr.get() && aCopyAttr->value(); + } + } + } while (isCopy && !theDumper.myEntitiesStack.empty()); } // store all not-dumped entities first @@ -836,6 +1064,20 @@ ModelHighAPI_Dumper& operator<<(ModelHighAPI_Dumper& theDumper, else { FeaturePtr aFeature = std::dynamic_pointer_cast(*anIt); theDumper.dumpFeature(aFeature, true); + // dump the Projection feature which produces this "Copy" entity + AttributeBooleanPtr aCopyAttr = aFeature->boolean("Copy"); + if (aCopyAttr.get() && aCopyAttr->value()) + { + const std::set& aRefs = aFeature->data()->refsToMe(); + std::set::iterator aRefIt = aRefs.begin(); + for (; aRefIt != aRefs.end(); ++aRefIt) + if ((*aRefIt)->id() == "ProjectedFeature") + { // process projection only + FeaturePtr anOwner = ModelAPI_Feature::feature((*aRefIt)->owner()); + if (anOwner && !theDumper.isDumped(EntityPtr(anOwner))) + theDumper.dumpFeature(anOwner, true); + } + } } } @@ -846,5 +1088,8 @@ ModelHighAPI_Dumper& operator<<(ModelHighAPI_Dumper& theDumper, // then store currently dumped string theDumper.myFullDump << aBufCopy; + // now, store all postponed features + theDumper.dumpPostponed(); + return theDumper; }