#include <Selector_NameGenerator.h>
#include <Selector_NExplode.h>
-#include <TDF_ChildIDIterator.hxx>
#include <TopoDS_Iterator.hxx>
#include <TopoDS_Builder.hxx>
#include <TopoDS.hxx>
#include <TopTools_MapOfShape.hxx>
#include <BRep_Tool.hxx>
+#include <TDF_ChildIDIterator.hxx>
+#include <TDF_Tool.hxx>
#include <TDataStd_Integer.hxx>
#include <TDataStd_ReferenceArray.hxx>
#include <TDataStd_IntegerArray.hxx>
#include <TDataStd_Name.hxx>
#include <TDataStd_UAttribute.hxx>
+#include <TDataStd_ExtStringList.hxx>
#include <list>
// reference attribute that contains the reference to labels where the "from" or "base" shapes
// of selection are located
static const Standard_GUID kBASE_ARRAY("7c515b1a-9549-493d-9946-a4933a22f45f");
+// if the base array contains reference to the root label, this means that it refers to an
+// external document and this list contains a tag in the document
+static const Standard_GUID kBASE_LIST("7c515b1a-9549-493d-9946-a4933a22f45a");
// array of the neighbor levels
static const Standard_GUID kLEVELS_ARRAY("ee4c4b45-e859-4e86-aa4f-6eac68e0ca1f");
// weak index (integer) of the sub-shape
return false;
}
+/// Stores the array of references to the label: references to elements of ref-list, then the last
+static void storeBaseArray(const TDF_Label& theLab,
+ const TDF_LabelList& theRef, const TDF_Label& theLast)
+{
+ Handle(TDataStd_ReferenceArray) anArray =
+ TDataStd_ReferenceArray::Set(theLab, kBASE_ARRAY, 0, theRef.Extent());
+ Handle(TDataStd_ExtStringList) anEntries; // entries of references to external document
+ const TDF_Label aThisDocRoot = theLab.Root();
+ TDF_LabelList::Iterator aBIter(theRef);
+ for(int anIndex = 0; true; aBIter.Next(), anIndex++) {
+ const TDF_Label& aLab = aBIter.More() ? aBIter.Value() : theLast;
+ // check this is a label of this document
+ if (aLab.Root().IsEqual(aThisDocRoot)) {
+ anArray->SetValue(anIndex, aLab);
+ } else { // store reference to external document as an entry-string
+ if (anEntries.IsNull()) {
+ anEntries = TDataStd_ExtStringList::Set(theLab, kBASE_LIST);
+ }
+ TCollection_AsciiString anEntry;
+ TDF_Tool::Entry(aLab, anEntry);
+ anEntries->Append(anEntry);
+ anArray->SetValue(anIndex, aThisDocRoot); // stored root means it is external reference
+ }
+ if (!aBIter.More())
+ break;
+ }
+}
+
void Selector_Selector::store()
{
+ static const TDF_LabelList anEmptyRefList;
myLab.ForgetAllAttributes(true); // remove old naming data
TDataStd_Integer::Set(myLab, kSEL_TYPE, (int)myType);
if (myGeometricalNaming)
break;
}
case SELTYPE_PRIMITIVE: {
- Handle(TDataStd_ReferenceArray) anArray =
- TDataStd_ReferenceArray::Set(myLab, kBASE_ARRAY, 0, 0);
- anArray->SetValue(0, myFinal);
+ storeBaseArray(myLab, anEmptyRefList, myFinal);
break;
}
case SELTYPE_MODIFICATION: {
- Handle(TDataStd_ReferenceArray) anArray =
- TDataStd_ReferenceArray::Set(myLab, kBASE_ARRAY, 0, myBases.Extent());
- TDF_LabelList::Iterator aBIter(myBases);
- for(int anIndex = 0; aBIter.More(); aBIter.Next(), anIndex++) {
- anArray->SetValue(anIndex, aBIter.Value());
- }
- anArray->SetValue(myBases.Extent(), myFinal); // final is in the end of array
+ storeBaseArray(myLab, myBases, myFinal);
if (myWeakIndex != -1) {
TDataStd_Integer::Set(myLab, kWEAK_INDEX, myWeakIndex);
}
case SELTYPE_WEAK_NAMING: {
TDataStd_Integer::Set(myLab, kWEAK_INDEX, myWeakIndex);
TDataStd_Integer::Set(myLab, kSHAPE_TYPE, (int)myShapeType);
- // store myFinal in the base array
if (!myFinal.IsNull()) {
- Handle(TDataStd_ReferenceArray) anArray =
- TDataStd_ReferenceArray::Set(myLab, kBASE_ARRAY, 0, 0);
- anArray->SetValue(0, myFinal);
+ storeBaseArray(myLab, anEmptyRefList, myFinal);
}
break;
}
}
}
+/// Restores references to the labels: references to elements of ref-list, then the last
+static bool restoreBaseArray(const TDF_Label& theLab, const TDF_Label& theBaseDocumetnLab,
+ TDF_LabelList& theRef, TDF_Label& theLast)
+{
+ const TDF_Label aThisDocRoot = theLab.Root();
+ Handle(TDataStd_ExtStringList) anEntries; // entries of references to external document
+ TDataStd_ListOfExtendedString::Iterator anIter;
+ Handle(TDataStd_ReferenceArray) anArray;
+ if (theLab.FindAttribute(kBASE_ARRAY, anArray)) {
+ int anUpper = anArray->Upper();
+ for(int anIndex = anArray->Lower(); anIndex <= anUpper; anIndex++) {
+ TDF_Label aLab = anArray->Value(anIndex);
+ if (aLab.IsEqual(aThisDocRoot)) { // external document reference
+ if (theBaseDocumetnLab.IsNull())
+ return false;
+ if (anEntries.IsNull()) {
+ if (!theLab.FindAttribute(kBASE_LIST, anEntries))
+ return false;
+ anIter.Initialize(anEntries->List());
+ }
+ if (!anIter.More())
+ return false;
+ TDF_Tool::Label(theBaseDocumetnLab.Data(), anIter.Value(), aLab);
+ anIter.Next();
+ }
+ if (anIndex == anUpper) {
+ theLast = aLab;
+ } else {
+ theRef.Append(aLab);
+ }
+ }
+ return true;
+ }
+ return false;
+}
+
+
bool Selector_Selector::restore()
{
Handle(TDataStd_Integer) aTypeAttr;
return aSubResult;
}
case SELTYPE_PRIMITIVE: {
- Handle(TDataStd_ReferenceArray) anArray;
- if (myLab.FindAttribute(kBASE_ARRAY, anArray)) {
- myFinal = anArray->Value(0);
- return true;
- }
- return false;
+ return restoreBaseArray(myLab, myBaseDocumentLab, myBases, myFinal);
}
case SELTYPE_MODIFICATION: {
- Handle(TDataStd_ReferenceArray) anArray;
- if (myLab.FindAttribute(kBASE_ARRAY, anArray)) {
- int anUpper = anArray->Upper();
- for(int anIndex = 0; anIndex < anUpper; anIndex++) {
- myBases.Append(anArray->Value(anIndex));
- }
- myFinal = anArray->Value(anUpper);
+ if (restoreBaseArray(myLab, myBaseDocumentLab, myBases, myFinal)) {
Handle(TDataStd_Integer) aWeakInt;
if (myLab.FindAttribute(kWEAK_INDEX, aWeakInt)) {
myWeakIndex = aWeakInt->Get();
if (!myLab.FindAttribute(kSHAPE_TYPE, aShapeTypeAttr))
return false;
myShapeType = TopAbs_ShapeEnum(aShapeTypeAttr->Get());
- Handle(TDataStd_ReferenceArray) anArray;
- if (myLab.FindAttribute(kBASE_ARRAY, anArray)) {
- myFinal = anArray->Value(0);
- }
+ if (!restoreBaseArray(myLab, myBaseDocumentLab, myBases, myFinal))
+ return false;
return true;
}
default: { // unknown case