From 658bdf0960445584a6dce55376afc7c5bdddf60d Mon Sep 17 00:00:00 2001 From: mpv Date: Mon, 12 Dec 2016 15:48:25 +0300 Subject: [PATCH] Correct working with default values in fields: store all not-selected entities with default values / restore entities with zero-values (default) as not selected. --- .../ExchangePlugin_ExportFeature.cpp | 57 ++++++++++++------- .../ExchangePlugin_ImportFeature.cpp | 41 +++++++++++-- src/Model/Model_AttributeSelectionList.cpp | 4 +- src/Model/Model_AttributeTables.cpp | 2 +- src/Model/Model_Data.cpp | 3 +- src/Model/Model_Document.cpp | 8 ++- src/Model/Model_Session.cpp | 2 +- 7 files changed, 86 insertions(+), 31 deletions(-) diff --git a/src/ExchangePlugin/ExchangePlugin_ExportFeature.cpp b/src/ExchangePlugin/ExchangePlugin_ExportFeature.cpp index 95b47c869..5a75630be 100644 --- a/src/ExchangePlugin/ExchangePlugin_ExportFeature.cpp +++ b/src/ExchangePlugin/ExchangePlugin_ExportFeature.cpp @@ -43,6 +43,7 @@ #include #include #include +#include #include @@ -175,6 +176,27 @@ void ExchangePlugin_ExportFeature::exportFile(const std::string& theFileName, } } +/// Returns XAO string by the value from the table +static std::string valToString(const ModelAPI_AttributeTables::Value& theVal, + const ModelAPI_AttributeTables::ValueType& theType) { + std::ostringstream aStr; // the resulting string value + switch(theType) { + case ModelAPI_AttributeTables::BOOLEAN: + aStr<<(theVal.myBool ? "true" : "false"); + break; + case ModelAPI_AttributeTables::INTEGER: + aStr<setStamp(aStampIndex); int aNumElements = isWholePart ? aXaoField->countElements() : aTables->rows(); int aNumComps = aTables->columns(); + std::set aFilledIDs; // to fill the rest by defaults // omit default values first row for(int aRow = isWholePart ? 0 : 1; aRow < aNumElements; aRow++) { for(int aCol = 0; aCol < aNumComps; aCol++) { @@ -300,37 +323,33 @@ void ExchangePlugin_ExportFeature::exportXAO(const std::string& theFileName) // complex conversion of reference id to element index int aReferenceID = aSelection->Id(); std::string aReferenceString = XAO::XaoUtils::intToString(aReferenceID); - int anElementID = + anElementID = aXao.getGeometry()->getElementIndexByReference(aFieldDimension, aReferenceString); } ModelAPI_AttributeTables::Value aVal = aTables->value( isWholePart ? 0 : aRow, aCol, aStepIndex); - std::ostringstream aStr; // string value - switch(aTables->type()) { - case ModelAPI_AttributeTables::BOOLEAN: - aStr<<(aVal.myBool ? "True" : "False"); - break; - case ModelAPI_AttributeTables::INTEGER: - aStr<type()); aStep->setStringValue(isWholePart ? aRow : anElementID, aCol, aStrVal); + aFilledIDs.insert(anElementID); + } + } + if (!isWholePart) { // fill the rest values by default ones + XAO::GeometricElementList::iterator allElem = aXao.getGeometry()->begin(aFieldDimension); + for(; allElem != aXao.getGeometry()->end(aFieldDimension); allElem++) { + if (aFilledIDs.find(allElem->first) != aFilledIDs.end()) + continue; + for(int aCol = 0; aCol < aNumComps; aCol++) { + ModelAPI_AttributeTables::Value aVal = aTables->value(0, aCol, aStepIndex); // default + std::string aStrVal = valToString(aVal, aTables->type()); + aStep->setStringValue(allElem->first, aCol, aStrVal); + } } } } } - // exporting - XAOExport(theFileName, &aXao, anError); if (!anError.empty()) { diff --git a/src/ExchangePlugin/ExchangePlugin_ImportFeature.cpp b/src/ExchangePlugin/ExchangePlugin_ImportFeature.cpp index 17a02d85e..def3e6e62 100644 --- a/src/ExchangePlugin/ExchangePlugin_ImportFeature.cpp +++ b/src/ExchangePlugin/ExchangePlugin_ImportFeature.cpp @@ -216,10 +216,9 @@ void ExchangePlugin_ImportFeature::importXAO(const std::string& theFileName) aSelectionList->setSelectionType(aSelectionType); // limitation: now in XAO fields are related to everything, so, iterate all sub-shapes to fill int aCountSelected = aXaoField->countElements(); - int aResults = document()->size(ModelAPI_ResultBody::group()); - for(int a = 0; a < aResults && aCountSelected; a++) { - ResultBodyPtr aBody = std::dynamic_pointer_cast( - document()->object(ModelAPI_ResultBody::group(), a)); + std::list::const_iterator aResIter = results().begin(); + for(; aResIter != results().end() && aCountSelected; aResIter++) { + ResultBodyPtr aBody = std::dynamic_pointer_cast(*aResIter); if (!aBody.get()) continue; // check that only results that were created before this field are used @@ -266,7 +265,7 @@ void ExchangePlugin_ImportFeature::importXAO(const std::string& theFileName) std::string aValStr = (*aStepIter)->getStringValue(aRow - 1, aCol); switch(aType) { case ModelAPI_AttributeTables::BOOLEAN: - aVal.myBool = aValStr == "True"; + aVal.myBool = aValStr == "true"; break; case ModelAPI_AttributeTables::INTEGER: aVal.myInt = atoi(aValStr.c_str()); @@ -282,6 +281,38 @@ void ExchangePlugin_ImportFeature::importXAO(const std::string& theFileName) } } } + // remove everything with zero-values: zeroes are treated as defaults + std::set aRowsToRemove; + for(int aRow = 1; aRow < aTables->rows(); aRow++) { + bool isZero = true; + for(int aCol = 0; aCol < aTables->columns() && isZero; aCol++) { + for(int aStepIndex = 0; aStepIndex != aTables->tables() && isZero; aStepIndex++) { + if (aTables->valueStr(aRow, aCol, aStepIndex) != aTables->valueStr(0, aCol, aStepIndex)) + isZero = false; + } + } + if (isZero) + aRowsToRemove.insert(aRow - 1); // -1 to make prepared for remove from SelectionList + } + if (!aRowsToRemove.empty()) { // move usefull rows on bottom to the up of the tables + // number of rows passed during going through: the current rows will + // be moved up for this value + int aRemovedPassed = 0; + for(int aRow = 1; aRow < aTables->rows(); aRow++) { + if (aRowsToRemove.find(aRow - 1) != aRowsToRemove.end()) { + aRemovedPassed++; + } else if (aRemovedPassed != 0) { // copy the line up + for(int aCol = 0; aCol < aTables->columns(); aCol++) { + for(int aTable = 0; aTable != aTables->tables(); aTable++) { + aTables->setValue( + aTables->value(aRow, aCol, aTable), aRow - aRemovedPassed, aCol, aTable); + } + } + } + } + aTables->setSize(aTables->rows() - aRemovedPassed, aTables->columns(), aTables->tables()); + aSelectionList->remove(aRowsToRemove); // remove also selected elements + } } // Top avoid problems in Object Browser update: issue #1647. ModelAPI_EventCreator::get()->sendReordered( diff --git a/src/Model/Model_AttributeSelectionList.cpp b/src/Model/Model_AttributeSelectionList.cpp index a6d25f7ad..d8ea9da5c 100644 --- a/src/Model/Model_AttributeSelectionList.cpp +++ b/src/Model/Model_AttributeSelectionList.cpp @@ -155,8 +155,8 @@ static void copyAttrs(TDF_Label theSource, TDF_Label theDestination) { // for named shape copy exact shapes (in NamedShape Paste method the CopyTool is used) Handle(TNaming_NamedShape) aNS = Handle(TNaming_NamedShape)::DownCast(anAttrIter.Value()); if (aNS.IsNull()) { - // no relocation, empty map - Handle(TDF_RelocationTable) aRelocTable = new TDF_RelocationTable(); + // no special relocation, empty map, but self-relocation is on: copy references w/o changes + Handle(TDF_RelocationTable) aRelocTable = new TDF_RelocationTable(Standard_True); anAttrIter.Value()->Paste(aTargetAttr, aRelocTable); } else { CopyNS(aNS, aTargetAttr); diff --git a/src/Model/Model_AttributeTables.cpp b/src/Model/Model_AttributeTables.cpp index b89e7446d..e7a5685b7 100644 --- a/src/Model/Model_AttributeTables.cpp +++ b/src/Model/Model_AttributeTables.cpp @@ -151,7 +151,7 @@ void Model_AttributeTables::setType(ModelAPI_AttributeTables::ValueType theType) // remove the old attr int aSize = myRows * myCols * myTables; if (aSize != 0) { - myLab.ForgetAttribute(MY_ARRAY_ID(theType)); + myLab.ForgetAttribute(MY_ARRAY_ID(myType)); myType = theType; int aTables = myTables; myTables = 0; // to let setSize know that there is no old array diff --git a/src/Model/Model_Data.cpp b/src/Model/Model_Data.cpp index c60d07cd3..750b9103b 100644 --- a/src/Model/Model_Data.cpp +++ b/src/Model/Model_Data.cpp @@ -629,7 +629,8 @@ static void copyAttrs(TDF_Label theSource, TDF_Label theDestination) { aTargetAttr = anAttrIter.Value()->NewEmpty(); theDestination.AddAttribute(aTargetAttr); } - Handle(TDF_RelocationTable) aRelocTable = new TDF_RelocationTable(); // no relocation, empty map + // no special relocation, empty map, but self-relocation is on: copy references w/o changes + Handle(TDF_RelocationTable) aRelocTable = new TDF_RelocationTable(Standard_True); anAttrIter.Value()->Paste(aTargetAttr, aRelocTable); } // copy the sub-labels content diff --git a/src/Model/Model_Document.cpp b/src/Model/Model_Document.cpp index d47d1ec0b..de77a7472 100755 --- a/src/Model/Model_Document.cpp +++ b/src/Model/Model_Document.cpp @@ -402,9 +402,13 @@ static bool isEqualContent(Handle(TDF_Attribute) theAttr1, Handle(TDF_Attribute) if (anArr1.IsNull() || anArr2.IsNull()) return false; if (anArr1->Lower() == anArr2->Lower() && anArr1->Upper() == anArr2->Upper()) { - for(int a = anArr1->Lower(); a <= anArr1->Upper(); a++) - if (a != 1 && anArr1->Value(a) != anArr2->Value(a)) // second is for display + for(int a = anArr1->Lower(); a <= anArr1->Upper(); a++) { + if (a == 1 && // second is for display + anArr2->Label().Tag() == 1 && (anArr2->Label().Depth() == 4 || anArr2->Label().Depth() == 6)) + continue; + if (anArr1->Value(a) != anArr2->Value(a)) return false; + } return true; } } else if (Standard_GUID::IsEqual(theAttr1->ID(), TDataStd_IntegerArray::GetID())) { diff --git a/src/Model/Model_Session.cpp b/src/Model/Model_Session.cpp index a68d98b0c..4c98ca450 100644 --- a/src/Model/Model_Session.cpp +++ b/src/Model/Model_Session.cpp @@ -324,7 +324,7 @@ std::shared_ptr Model_Session::copy( Handle(TDF_DataSet) aDS = new TDF_DataSet; aDS->AddLabel(aSourceRoot); TDF_ClosureTool::Closure(aDS); - Handle(TDF_RelocationTable) aRT = new TDF_RelocationTable; + Handle(TDF_RelocationTable) aRT = new TDF_RelocationTable(Standard_True); aRT->SetRelocation(aSourceRoot, aTargetRoot); TDF_CopyTool::Copy(aDS, aRT); -- 2.39.2