X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FModelHighAPI%2FModelHighAPI_FeatureStore.cpp;h=e6b73dcdc5fd9c4ad596f67be66abbe6cda71bf4;hb=dbeb6b3dd9f673f8f34f2554f792188a3cc069e2;hp=97f65b4777012ade15dbb4499fd0e116e2667b39;hpb=7074394f8f08413d885f63be01df6bd5007b868c;p=modules%2Fshaper.git diff --git a/src/ModelHighAPI/ModelHighAPI_FeatureStore.cpp b/src/ModelHighAPI/ModelHighAPI_FeatureStore.cpp index 97f65b477..e6b73dcdc 100644 --- a/src/ModelHighAPI/ModelHighAPI_FeatureStore.cpp +++ b/src/ModelHighAPI/ModelHighAPI_FeatureStore.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 CEA/DEN, EDF R&D +// Copyright (C) 2014-2024 CEA, EDF // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -12,15 +12,15 @@ // // 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 +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// See http://www.salome-platform.org/ or -// email : webmaster.salome@opencascade.com +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // #include #include +#include #include #include #include @@ -44,50 +44,63 @@ #include #include #include +#include #include -#include -#include +#include #include #include +#include +#include -#define PRECISION 6 -#define TOLERANCE (1.e-7) +#define PRECISION 5 +#define TOLERANCE (1.e-6) -ModelHighAPI_FeatureStore::ModelHighAPI_FeatureStore(FeaturePtr theFeature) { - storeData(theFeature->data(), myAttrs); - // iterate results to store - std::list allResults; - ModelAPI_Tools::allResults(theFeature, allResults); - std::list::iterator aRes = allResults.begin(); - for(; aRes != allResults.end(); aRes++) { - std::map aResDump; - storeData((*aRes)->data(), aResDump); - myRes.push_back(aResDump); +ModelHighAPI_FeatureStore::ModelHighAPI_FeatureStore(ObjectPtr theObject) { + storeData(theObject->data(), myAttrs); + + FeaturePtr aFeature = std::dynamic_pointer_cast(theObject); + if (aFeature) { + // iterate results to store + std::list allResults; + ModelAPI_Tools::allResults(aFeature, allResults); + std::list::iterator aRes = allResults.begin(); + for(; aRes != allResults.end(); aRes++) { + std::map aResDump; + storeData((*aRes)->data(), aResDump); + myRes.push_back(aResDump); + } } } -std::string ModelHighAPI_FeatureStore::compare(FeaturePtr theFeature) { - std::string anError = compareData(theFeature->data(), myAttrs); +std::string ModelHighAPI_FeatureStore::compare(ObjectPtr theObject) { + std::string anError = compareData(theObject->data(), myAttrs); if (!anError.empty()) { - return "Features '" + theFeature->name() + "' differ:" + anError; - } - std::list allResults; - ModelAPI_Tools::allResults(theFeature, allResults); - std::list::iterator aRes = allResults.begin(); - std::list >::iterator aResIter = myRes.begin(); - for(; aRes != allResults.end() && aResIter != myRes.end(); aRes++, aResIter++) { - anError = compareData((*aRes)->data(), *aResIter); - if (!anError.empty()) - return "Results of feature '" + theFeature->name() + "' '" + (*aRes)->data()->name() + + return "Features '" + Locale::Convert::toString(theObject->data()->name()) + "' differ:" + anError; } - if (aRes != allResults.end()) { - return "Current model has more results '" + (*aRes)->data()->name() + "'"; - } - if (aResIter != myRes.end()) { - return "Original model had more results '" + (*aResIter)["__name__"] + "'"; + + FeaturePtr aFeature = std::dynamic_pointer_cast(theObject); + if (aFeature) { + std::list allResults; + ModelAPI_Tools::allResults(aFeature, allResults); + std::list::iterator aRes = allResults.begin(); + std::list >::iterator aResIter = myRes.begin(); + for(; aRes != allResults.end() && aResIter != myRes.end(); aRes++, aResIter++) { + anError = compareData((*aRes)->data(), *aResIter); + if (!anError.empty()) + return "Results of feature '" + Locale::Convert::toString(aFeature->name()) + + "' '" + Locale::Convert::toString((*aRes)->data()->name()) + + "' differ:" + anError; + } + if (aRes != allResults.end()) { + return "Current model has more results '" + + Locale::Convert::toString((*aRes)->data()->name()) + "'"; + } + if (aResIter != myRes.end()) { + return "Original model had more results '" + (*aResIter)["__name__"] + "'"; + } } return ""; // ok } @@ -96,7 +109,7 @@ void ModelHighAPI_FeatureStore::storeData(std::shared_ptr theData std::map& theAttrs) { // store name to keep also this information and output if needed - theAttrs["__name__"] = theData->name(); + theAttrs["__name__"] = Locale::Convert::toString(theData->name()); std::list > allAttrs = theData->attributes(""); std::list >::iterator anAttr = allAttrs.begin(); for(; anAttr != allAttrs.end(); anAttr++) { @@ -140,7 +153,7 @@ static void dumpArray(std::ostringstream& theOutput, const double theArray[], for (int i = 0; i < theSize; ++i) { if (i > 0) theOutput << " "; - theOutput << std::fixed << setprecision(thePrecision) + theOutput << std::fixed << std::setprecision(thePrecision) << (fabs(theArray[i]) < TOLERANCE ? 0.0 : theArray[i]); } } @@ -152,6 +165,14 @@ std::string ModelHighAPI_FeatureStore::dumpAttr(const AttributePtr& theAttr) { return "__notcase__"; } std::string aType = theAttr->attributeType(); + + // do not check selection of the filter, + // because there is neither parametric update nor dump support yet. + FiltersFeaturePtr aFilter = std::dynamic_pointer_cast(aFeatOwner); + if (aFilter && (aType == ModelAPI_AttributeSelection::typeId() || + aType == ModelAPI_AttributeSelectionList::typeId())) + return "__filter_selection__"; + std::ostringstream aResult; if (!theAttr->isInitialized()) { if (aType == ModelAPI_AttributeBoolean::typeId()) { @@ -173,19 +194,33 @@ std::string ModelHighAPI_FeatureStore::dumpAttr(const AttributePtr& theAttr) { if (anAttr->value() != aDoc) { ResultPtr aRes = ModelAPI_Tools::findPartResult(aDoc, anAttr->value()); if (aRes.get()) { - aResult<data()->name(); // Part result name (the same as saved file name) + // Part result name (the same as saved file name) + aResult<< Locale::Convert::toString(aRes->data()->name()); } } else { aResult<kind(); // PartSet } } else if (aType == ModelAPI_AttributeInteger::typeId()) { AttributeIntegerPtr anAttr = std::dynamic_pointer_cast(theAttr); + // do not dump a type of ConstraintAngle, because it can be changed due dumping + if (anAttr->id() == "AngleType" || anAttr->id() == "AngleTypePrevious") { + return ""; + } else if (anAttr->id() == "LocationType") { + return "__notinitialized__"; + } if (anAttr->text().empty()) aResult<value(); else - aResult<text(); + aResult << Locale::Convert::toString(anAttr->text()); } else if (aType == ModelAPI_AttributeDouble::typeId()) { AttributeDoublePtr anAttr = std::dynamic_pointer_cast(theAttr); + if (anAttr->id() == "ConstraintValue") { + // do not dump a value of constraint if it is ConstraintAngle, + // because this value depends on the angle type + FeaturePtr anOwner = ModelAPI_Feature::feature(anAttr->owner()); + if (anOwner && anOwner->getKind() == "SketchConstraintAngle") + return ""; + } int aPrecision = PRECISION; // Special case - precision for the arc angle. It is calculated with tolerance 1e-4, // so the value has only 4 correct digits @@ -195,14 +230,23 @@ std::string ModelHighAPI_FeatureStore::dumpAttr(const AttributePtr& theAttr) { double aVal = anAttr->value(); dumpArray(aResult, &aVal, 1, aPrecision); } else - aResult<text(); + aResult << Locale::Convert::toString(anAttr->text()); } else if (aType == ModelAPI_AttributeBoolean::typeId()) { AttributeBooleanPtr anAttr = std::dynamic_pointer_cast(theAttr); + // do not dump internal flags of ConstraintAngle + if (anAttr->id() == "AngleReversedLine1" || anAttr->id() == "AngleReversedLine2") { + return ""; + } aResult<value(); } 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(); @@ -210,28 +254,31 @@ std::string ModelHighAPI_FeatureStore::dumpAttr(const AttributePtr& theAttr) { AttributeReferencePtr anAttr = std::dynamic_pointer_cast(theAttr); if (anAttr->value().get()) { - aResult<value()->data()->name(); + aResult<< Locale::Convert::toString(anAttr->value()->data()->name()); } else { aResult<<"__empty__"; } } else if (aType == ModelAPI_AttributeSelection::typeId()) { AttributeSelectionPtr anAttr = std::dynamic_pointer_cast(theAttr); - aResult<namingName(); + if (anAttr->context().get()) + aResult<< Locale::Convert::toString(anAttr->namingName()); + else + aResult<<"__notinitialized__"; } else if (aType == ModelAPI_AttributeSelectionList::typeId()) { AttributeSelectionListPtr anAttr = std::dynamic_pointer_cast(theAttr); for(int a = 0; a < anAttr->size(); a++) { if (a != 0) aResult<<" "; - aResult<value(a)->namingName(); + aResult<< Locale::Convert::toString(anAttr->value(a)->namingName()); } } else if (aType == ModelAPI_AttributeRefAttr::typeId()) { AttributeRefAttrPtr anAttr = std::dynamic_pointer_cast(theAttr); ObjectPtr anObj = anAttr->isObject() ? anAttr->object() : anAttr->attr()->owner(); if (anObj.get()) { - aResult<data()->name(); + aResult<< Locale::Convert::toString(anObj->data()->name()); if (!anAttr->isObject()) { aResult<<" "<attr()->id(); } @@ -240,7 +287,7 @@ std::string ModelHighAPI_FeatureStore::dumpAttr(const AttributePtr& theAttr) { } } else if (aType == ModelAPI_AttributeRefList::typeId()) { AttributeRefListPtr anAttr = - std::dynamic_pointer_cast(theAttr); + std::dynamic_pointer_cast(theAttr); // for sketch sub-features the empty values may be skipped and order is not important bool isSketchFeatures = anAttr->id() == "Features" && std::dynamic_pointer_cast(anAttr->owner())->getKind() == "Sketch"; @@ -248,7 +295,16 @@ std::string ModelHighAPI_FeatureStore::dumpAttr(const AttributePtr& theAttr) { std::list aResList; // list of resulting strings for(std::list::iterator aL = aList.begin(); aL != aList.end(); aL++) { if (aL->get()) { - aResList.push_back((*aL)->data()->name()); + if (isSketchFeatures) { + // do not control construction features of an ellipse and other + FeaturePtr aFeature = ModelAPI_Feature::feature(*aL); + //if (aFeature->getKind() == "SketchConstraintCoincidenceInternal") + // continue; // skip internal constraints + std::string aStr = aFeature->getKind().substr(0, 16); + if (aStr == "SketchConstraint") + continue; // no need to dump and check constraints + } + aResList.push_back(Locale::Convert::toString((*aL)->data()->name())); } else if (!isSketchFeatures) { aResList.push_back("__empty__"); } @@ -268,7 +324,7 @@ std::string ModelHighAPI_FeatureStore::dumpAttr(const AttributePtr& theAttr) { aResult<<" "; ObjectPtr anObj = aL->second.get() ? aL->second->owner() : aL->first; if (anObj.get()) { - aResult<data()->name(); + aResult<< Locale::Convert::toString(anObj->data()->name()); if (aL->second.get()) { aResult<<" "<second->id(); } @@ -277,6 +333,12 @@ std::string ModelHighAPI_FeatureStore::dumpAttr(const AttributePtr& theAttr) { } } } else if (aType == ModelAPI_AttributeIntArray::typeId()) { + if (theAttr->id() == "Color") { + ResultConstructionPtr aResConstr = + std::dynamic_pointer_cast(theAttr->owner()); + if (aResConstr.get()) + return "__notinitialized__"; + } AttributeIntArrayPtr anAttr = std::dynamic_pointer_cast(theAttr); for(int a = 0; a < anAttr->size(); a++) @@ -320,13 +382,17 @@ std::string ModelHighAPI_FeatureStore::dumpAttr(const AttributePtr& theAttr) { double aValues[3] = {anAttr->x(), anAttr->y(), anAttr->z()}; dumpArray(aResult, aValues, 3); } else if (aType == GeomDataAPI_Dir::typeId()) { + if (theAttr->id() == "DistanceDirection") + return "__notcase__"; AttributeDirPtr anAttr = std::dynamic_pointer_cast(theAttr); double aValues[3] = {anAttr->x(), anAttr->y(), anAttr->z()}; dumpArray(aResult, aValues, 3); } else if (aType == GeomDataAPI_Point2D::typeId()) { - // do not dump flyout point for constraints as it may be changed unexpectedly - if (theAttr->id() == "ConstraintFlyoutValuePnt") - return ""; + // do not dump flyout point for constraints as it may be changed unexpectedly, + // also do not dump selection points controlled by GUI + if (theAttr->id() == "ConstraintFlyoutValuePnt" || + theAttr->id() == "SelectedPointA" || theAttr->id() == "SelectedPointB") + return "__notinitialized__"; AttributePoint2DPtr anAttr = std::dynamic_pointer_cast(theAttr); double aValues[2] = {anAttr->x(), anAttr->y()}; dumpArray(aResult, aValues, 2); @@ -337,24 +403,41 @@ std::string ModelHighAPI_FeatureStore::dumpAttr(const AttributePtr& theAttr) { } std::string ModelHighAPI_FeatureStore::dumpShape(std::shared_ptr& theShape) { - TopoDS_Shape aShape = theShape->impl(); - if (aShape.IsNull()) { + if (theShape->isNull()) { return "null"; } std::ostringstream aResult; // output the number of shapes of different types - TopAbs_ShapeEnum aType = TopAbs_COMPOUND; - for(; aType <= TopAbs_VERTEX; aType = TopAbs_ShapeEnum((int)aType + 1)) { - TopExp_Explorer anExp(aShape, aType); - int aCount = 0; - for(; anExp.More(); anExp.Next()) aCount++; - TopAbs::Print(aType, aResult); - aResult<<": "<shapeTypeStr(); + int aCount = 0; + for (; anExp.more(); anExp.next()) aCount++; + aResult << aTypeStr.c_str() << ": " << aCount << std::endl; + } } // output the main characteristics - if (GeomAlgoAPI_ShapeTools::volume(theShape) > 1.e-7) { - aResult<<"Volume: "<< - std::fixed< 1.e-5) { + aResult<<"Volume: "; + // volumes of too huge shapes write in the scientific format + if (aVolume >= 1.e5) + aResult< 1.e-5) { + aResult << "Area: "; + // volumes of too huge shapes write in the scientific format + if (anArea >= 1.e5) + aResult << std::scientific << std::setprecision(7); + else + aResult << std::fixed << std::setprecision(3); + aResult << anArea << std::endl; } std::shared_ptr aCenter = GeomAlgoAPI_ShapeTools::centreOfMass(theShape); aResult<<"Center of mass: ";