0022627: Change OCCT memory management defaults
[occt.git] / src / TObj / TObj_Object.cxx
CommitLineData
7fd59977 1// File: TObj_Object.cxx
2// Created: Mon Nov 22 15:06 2004
3// Author: Pavel TELKOV
4// Copyright: Open CASCADE 2007
5// The original implementation Copyright: (C) RINA S.p.A
6
7#include <TObj_Object.hxx>
8
9#include <TObj_Assistant.hxx>
10#include <TObj_LabelIterator.hxx>
11#include <TObj_Model.hxx>
12#include <TObj_ObjectIterator.hxx>
13#include <TObj_OcafObjectIterator.hxx>
14#include <TObj_Persistence.hxx>
15#include <TObj_ReferenceIterator.hxx>
16#include <TObj_SequenceIterator.hxx>
17#include <TDataStd_AsciiString.hxx>
18#include <TObj_TModel.hxx>
19#include <TObj_TNameContainer.hxx>
20#include <TObj_TObject.hxx>
21#include <TObj_TReference.hxx>
22
23#include <TCollection_HAsciiString.hxx>
24#include <TColStd_HArray1OfInteger.hxx>
25#include <TColStd_HArray1OfReal.hxx>
26#include <TColStd_HArray1OfExtendedString.hxx>
27#include <TColStd_SequenceOfInteger.hxx>
28#include <TDF_AttributeIterator.hxx>
29#include <TDF_ChildIDIterator.hxx>
30#include <TDF_ChildIterator.hxx>
31#include <TDF_CopyLabel.hxx>
32#include <TDF_Data.hxx>
33#include <TDF_RelocationTable.hxx>
34#include <TDF_Tool.hxx>
35#include <TDataStd_ExtStringArray.hxx>
36#include <TDataStd_Integer.hxx>
37#include <TDataStd_IntegerArray.hxx>
38#include <TDataStd_Name.hxx>
39#include <TDataStd_Real.hxx>
40#include <TDataStd_RealArray.hxx>
41#include <TDocStd_Document.hxx>
42#include <TDocStd_Owner.hxx>
43
44
45IMPLEMENT_STANDARD_HANDLE(TObj_Object,MMgt_TShared)
46IMPLEMENT_STANDARD_RTTIEXT(TObj_Object,MMgt_TShared)
47
48//=======================================================================
49//function : Constructor
50//purpose :
51//=======================================================================
52
53TObj_Object::TObj_Object(const TDF_Label& theLabel,
54 const Standard_Boolean theSetName)
55 : myLabel(theLabel)
56{
57 Handle(TObj_Object) aMe = this;
58 TObj_TObject::Set(myLabel, aMe);
59 if (theSetName)
60 TObj_Model::SetNewName(aMe);
61}
62
63//=======================================================================
64//function : GetModel
65//purpose :
66//=======================================================================
67
68Handle(TObj_Model) TObj_Object::GetModel() const
69{
70 Handle(TObj_Model) aModel;
71 // if object label is null object is not alive
72 if ( myLabel.IsNull() )
73 return aModel;
74
75 //TDF_Label aLabel = TDocStd_Document::Get(myLabel)->Main();
76 Handle(TDF_Data) aData = myLabel.Data();
77 if (aData.IsNull())
78 return aModel;
79
80 // try get the document from owner attribute manually
81 TDF_Label aLabel = aData->Root();
82 Handle(TDocStd_Owner) anOwnerAttr;
83 Handle(TDocStd_Document) aTDoc;
84 if ( !aLabel.IsNull() && aLabel.FindAttribute( TDocStd_Owner::GetID(), anOwnerAttr ) )
85 aTDoc = anOwnerAttr->GetDocument();
86 if (aTDoc.IsNull())
87 return aModel;
88
89 // use main label of the document to find TObj model attribute
90 aLabel = aTDoc->Main();
91 Handle(TObj_TModel) aModelAttr;
92 if (!aLabel.IsNull() && aLabel.FindAttribute(TObj_TModel::GetID(), aModelAttr))
93 aModel = aModelAttr->Model();
94
95 return aModel;
96}
97
98//=======================================================================
99//function : GetChildren
100//purpose : Returns iterator for the child objects.
101// This method provides tree-like view of the objects hierarchy.
102// The references to other objects are not considered as children.
103// theType narrows a variety of iterated objects
104//=======================================================================
105
106static void addObjToOrderSequence( const Handle(TObj_Object)& theObj,
107 const Standard_Integer theOrder,
108 Handle(TObj_HSequenceOfObject)& theHSeqOfObj,
109 const Standard_Integer theHSeqLength,
110 Standard_Integer& theLastIndex,
111 Standard_Integer& theLastOrder )
112{
113 if ( theOrder > theLastOrder )
114 {
115 while ( theOrder > theLastOrder )
116 {
117 // get next object and compare with them
118 if ( ++theLastIndex > theHSeqLength )
119 {
120 theHSeqOfObj->Append( theObj );
121 theLastIndex = theHSeqLength + 1;
122 theLastOrder = theOrder;
123 return;
124 }
125 Handle(TObj_Object) aNext = theHSeqOfObj->Value(theLastIndex);
126 theLastOrder = aNext->GetOrder();
127 }
128 // add before current position
129 theHSeqOfObj->InsertBefore( theLastIndex, theObj );
130 theLastOrder = theOrder;
131 }
132 else
133 {
134 while ( theOrder < theLastOrder )
135 {
136 if ( --theLastIndex < 1 )
137 {
138 theHSeqOfObj->InsertBefore( 1, theObj );
139 theLastIndex = 1;
140 theLastOrder = theOrder;
141 return;
142 }
143 // get next object and compare with them
144 Handle(TObj_Object) aNext = theHSeqOfObj->Value(theLastIndex);
145 theLastOrder = aNext->GetOrder();
146 }
147 // add object after current position
148 theHSeqOfObj->InsertAfter( theLastIndex, theObj );
149 theLastIndex++;
150 theLastOrder = theOrder;
151 return;
152 }
153}
154
155Handle(TObj_ObjectIterator) TObj_Object::GetChildren
156 (const Handle(Standard_Type)& theType) const
157{
158 Handle(TObj_ObjectIterator) anItr =
159 new TObj_OcafObjectIterator(GetChildLabel(), theType, Standard_True);
160 if ( !TestFlags( ObjectState_Ordered ) )
161 return anItr;
162 // return object according to their order
163 Standard_Integer aLastIndex = 0;
164 Standard_Integer aLastOrder = 0;
165 Handle(TObj_HSequenceOfObject) aHSeqOfObj = new TObj_HSequenceOfObject();
166 for ( ; anItr->More(); anItr->Next() )
167 {
168 Handle(TObj_Object) anObj = anItr->Value();
169 if ( anObj.IsNull() )
170 continue;
171 Standard_Integer anOrder = anObj->GetOrder();
172 if ( !aLastIndex )
173 {
174 aHSeqOfObj->Append( anObj );
175 aLastIndex = 1;
176 aLastOrder = anOrder;
177 }
178 else
179 addObjToOrderSequence( anObj, anOrder, aHSeqOfObj, aHSeqOfObj->Length(),
180 aLastIndex, aLastOrder );
181 }
182 return new TObj_SequenceIterator( aHSeqOfObj );
183}
184
185//=======================================================================
186//function : getLabelByRank
187//purpose : Auxiliary function to get a label and attache a name to it
188// Used in debug mode only
189//=======================================================================
190
191#ifdef DFBROWSE
192static TDF_Label getLabelByRank(const TDF_Label& theL,
193 const Standard_Integer theRank,
194 const Standard_CString theName)
195{
196 TDF_Label L = theL.FindChild(theRank,Standard_False);
197 if ( L.IsNull() )
198 {
199 L = theL.FindChild(theRank,Standard_True);
200 TDataStd_Name::Set(L, theName);
201 }
202 return L;
203}
204#endif
205
206//=======================================================================
207//function : GetChildLabel
208//purpose :
209//=======================================================================
210
211TDF_Label TObj_Object::GetChildLabel() const
212{
213#ifdef DFBROWSE
214 return getLabelByRank(GetLabel(),4,"Children");
215#else
216 return GetLabel().FindChild ( 4, Standard_True );
217#endif
218}
219
220//=======================================================================
221//function : getChildLabel
222//purpose :
223//=======================================================================
224
225TDF_Label TObj_Object::getChildLabel(const Standard_Integer theRank) const
226{
227 TDF_Label aLabel = GetChildLabel();
228 if ( theRank > 0 )
229 aLabel = aLabel.FindChild( theRank, Standard_True );
230 return aLabel;
231}
232
233//=======================================================================
234//function : GetLabel
235//purpose :
236//=======================================================================
237
238TDF_Label TObj_Object::GetLabel() const
239{
240 return myLabel;
241}
242
243//=======================================================================
244//function : SetName
245//purpose :
246//=======================================================================
247
248Standard_Boolean TObj_Object::SetName(const Handle(TCollection_HExtendedString)& theName) const
249{
250 // check if the name is exactly the same
251 Handle(TCollection_HExtendedString) anOldName = GetName();
252 if( !anOldName.IsNull() && theName->String().IsEqual(anOldName->String()) )
253 return Standard_True;
254
255 // check if name is already registered and do nothing in that case
256 const Handle(TObj_TNameContainer) aDictionary = GetDictionary();
257 Handle(TObj_Model) aModel = GetModel();
258 if( aModel->IsRegisteredName( theName, aDictionary ) )
259 return Standard_False;
260
261 // change name and update registry
262 if (!anOldName.IsNull())
263 aModel->UnRegisterName( anOldName, aDictionary );
264 if ( theName.IsNull() )
265 GetLabel().ForgetAttribute ( TDataStd_Name::GetID() );
266 else
267 {
268 aModel->RegisterName( theName, GetLabel(), aDictionary );
269 TDataStd_Name::Set(GetLabel(),theName->String());
270 }
271 return Standard_True;
272}
273
274//=======================================================================
275//function : SetName
276//purpose :
277//=======================================================================
278
279Standard_Boolean TObj_Object::SetName(const Handle(TCollection_HAsciiString)& theName) const
280{
281 return SetName( new TCollection_HExtendedString ( theName ) );
282}
283
284//=======================================================================
285//function : SetName
286//purpose :
287//=======================================================================
288
289Standard_Boolean TObj_Object::SetName(const Standard_CString theName) const
290{
291 return SetName ( new TCollection_HExtendedString ( theName ) );
292}
293
294//=======================================================================
295//function : GetName
296//purpose :
297//=======================================================================
298
299Handle(TCollection_HExtendedString) TObj_Object::GetName() const
300{
301 Handle(TCollection_HExtendedString) aName;
302 Handle(TDataStd_Name) A;
303 if (GetLabel().FindAttribute (TDataStd_Name::GetID(), A))
304 aName = new TCollection_HExtendedString(A->Get());
305 else aName = new TCollection_HExtendedString("");
306 return aName;
307}
308
309//=======================================================================
310//function : GetName
311//purpose :
312//=======================================================================
313
314Standard_Boolean TObj_Object::GetName(TCollection_ExtendedString& theStr) const
315{
316 Handle(TCollection_HExtendedString) aName = GetName();
317 theStr = aName->String();
318 return theStr.Length() != 0;
319}
320
321//=======================================================================
322//function : GetName
323//purpose :
324//=======================================================================
325
326Standard_Boolean TObj_Object::GetName(TCollection_AsciiString& theName) const
327{
328 Handle(TCollection_HExtendedString) aName = GetName();
329 if(aName.IsNull())
330 return Standard_False;
331 theName = TCollection_AsciiString (aName->String());
332 return theName.Length() != 0;
333}
334
335//=======================================================================
336//function : HasReference
337//purpose :
338//=======================================================================
339
340Standard_Boolean TObj_Object::HasReference
341 (const Handle(TObj_Object)& theObject) const
342{
343 if ( theObject.IsNull() )
344 return Standard_False;
345 Handle(TObj_ObjectIterator) anItr = GetReferences(theObject->DynamicType());
346 if ( anItr.IsNull() || !anItr->More() )
347 return Standard_False;
348 for ( ; anItr->More(); anItr->Next() )
349 if ( anItr->Value() == theObject )
350 return Standard_True;
351 return Standard_False;
352}
353
354//=======================================================================
355//function : GetReferences
356//purpose :
357//=======================================================================
358
359Handle(TObj_ObjectIterator) TObj_Object::GetReferences
360 (const Handle(Standard_Type)& theType) const
361{
362 return new TObj_ReferenceIterator(GetReferenceLabel(), theType);
363}
364
365//=======================================================================
366//function : RemoveAllReferences
367//purpose :
368//=======================================================================
369
370void TObj_Object::RemoveAllReferences()
371{
372 GetReferenceLabel().ForgetAllAttributes();
373 // other implementation may be get all reference by iterator
374 // and replace all of them by null handle with help of ::ReplaceReference
375}
376
377//=======================================================================
378//function : AddBackReference
379//purpose :
380//=======================================================================
381
382void TObj_Object::AddBackReference (const Handle(TObj_Object)& theObject)
383{
384 if (myHSeqBackRef.IsNull())
385 myHSeqBackRef = new TObj_HSequenceOfObject;
386
387 myHSeqBackRef->Append( theObject );
388}
389
390//=======================================================================
391//function : RemoveBackReference
392//purpose :
393//=======================================================================
394
395void TObj_Object::RemoveBackReference (const Handle(TObj_Object)& theObject,
396 const Standard_Boolean theSingleOnly)
397{
398 if (myHSeqBackRef.IsNull()) // to avoid exception.
399 return;
400
401 for (Standard_Integer i = 1; i <= myHSeqBackRef->Length(); i++)
402 {
403 if (theObject != myHSeqBackRef->Value(i))
404 continue;
405
406 myHSeqBackRef->Remove(i--);
407 if (theSingleOnly)
408 break;
409 }
410 if (myHSeqBackRef->Length() < 1)
411 myHSeqBackRef.Nullify(); // do not need to store empty sequence.
412}
413//=======================================================================
414//function : GetBackReferences
415//purpose :
416//=======================================================================
417
418Handle(TObj_ObjectIterator) TObj_Object::GetBackReferences
419 (const Handle(Standard_Type)& theType) const
420{
421 return new TObj_SequenceIterator( myHSeqBackRef, theType );
422}
423
424//=======================================================================
425//function : ClearBackReferences
426//purpose :
427//=======================================================================
428
429void TObj_Object::ClearBackReferences ()
430{
431 myHSeqBackRef.Nullify();
432}
433
434//=======================================================================
435//function : HasBackReferences
436//purpose :
437//=======================================================================
438
439Standard_Boolean TObj_Object::HasBackReferences() const
440{
441 Handle(TObj_ObjectIterator) anItr = GetBackReferences();
442 if ( anItr.IsNull() || !anItr->More() )
443 return Standard_False;
444 return Standard_True;
445}
446
447//=======================================================================
448//function : CanRemoveReference
449//purpose :
450//=======================================================================
451
452Standard_Boolean TObj_Object::CanRemoveReference
453 (const Handle(TObj_Object)& /*theObject*/) const
454{
455 return Standard_False;
456}
457
458//=======================================================================
459//function : RemoveReference
460//purpose :
461//=======================================================================
462
463void TObj_Object::RemoveReference (const Handle(TObj_Object)& theObject)
464{
465 Handle(TObj_Object) aNullObj;
466 ReplaceReference (theObject, aNullObj);
467}
468
469//=======================================================================
470//function : CanDetach
471//purpose :
472//=======================================================================
473 Standard_Boolean TObj_Object::CanDetach(const TObj_DeletingMode theMode )
474{
475 if( !IsAlive() )
476 return Standard_False;
477
478 Handle(TObj_ObjectIterator) aRefs = GetBackReferences();
479
480 // Free Object can be deleted in any Mode
481 if ( aRefs.IsNull() || ! aRefs->More() )
482 return Standard_True;
483
484 if( theMode == TObj_FreeOnly )
485 return Standard_False;
486
487 if( theMode == TObj_Forced )
488 return Standard_True;
489
490 // check the last KeepDepending mode
491 Handle(TObj_Object) aMe = this;
492 for( ; aRefs->More(); aRefs->Next())
493 {
494 Handle(TObj_Object) anObject = aRefs->Value();
495 if (! anObject->CanRemoveReference(aMe) )
496 return Standard_False; // one of objects could not be unlinked
497 }
498
499 return Standard_True;
500}
501
502//=======================================================================
503//function : Detach
504//purpose :
505//=======================================================================
506
507Standard_Boolean TObj_Object::Detach(const TObj_DeletingMode theMode)
508{
509 if( !IsAlive() )
510 return Standard_False;
511
512 // if object can not be deleted returns False
513 if(!RemoveBackReferences(theMode))
514 return Standard_False;
515
516 Handle(TCollection_HExtendedString) anOldName = GetName();
517
518 // detaching childs
519 Handle(TObj_ObjectIterator) aChildren = GetChildren();
520
521 for(;aChildren->More(); aChildren->Next())
522 aChildren->Value()->Detach(theMode);
523
524 // Clearing its own data
525 GetReferenceLabel().ForgetAllAttributes();
526 // clear back references container
527 ClearBackReferences();
528 // remove data
529 GetDataLabel().ForgetAllAttributes();
530
531 if (!anOldName.IsNull())
532 {
533 const Handle(TObj_TNameContainer) aDictionary = GetDictionary();
534 // unregister only it is registered to me.
535 if ( !aDictionary.IsNull() && aDictionary->IsRegistered( anOldName ) )
536 {
537 TDF_Label aRegisteredLabel = aDictionary->Get().Find( anOldName );
538 if ( !aRegisteredLabel.IsNull() && aRegisteredLabel == GetLabel() )
539 aDictionary->RemoveName( anOldName );
540 }
541 }
542 GetLabel().ForgetAllAttributes();
543
544 return Standard_True;
545}
546
547//=======================================================================
548//function : Detach
549//purpose : public static method
550//=======================================================================
551
552Standard_Boolean TObj_Object::Detach(const TDF_Label& theLabel,
553 const TObj_DeletingMode theMode)
554{
555 Handle(TObj_Object) anObject;
556 if( GetObj(theLabel, anObject) )
557 return anObject->Detach(theMode);
558 return Standard_True;
559}
560
561//=======================================================================
562//function : GetObj
563//purpose :
564//=======================================================================
565
566Standard_Boolean TObj_Object::GetObj(const TDF_Label& theLabel,
567 Handle(TObj_Object)& theResult,
568 const Standard_Boolean isSuper)
569{
570 if(theLabel.IsNull())
571 return Standard_False;
572
573 Handle(TObj_TObject) A;
574
575 // find on the current label
576 if ( theLabel.FindAttribute(TObj_TObject::GetID(), A) )
577 theResult = A->Get();
578 else
579 theResult.Nullify();
580
581 if( !theResult.IsNull() )
582 {
583 if( !theResult->myLabel.IsNull() )
584 return Standard_True;
585
586 // if the object is not allive then it is a wrong data in the Data Model
587 theResult.Nullify();
588 }
589 else if( isSuper )
590 {
591 // try to get object from the father label
592 return GetObj(theLabel.Father(),theResult,isSuper);
593 }
594
595 return Standard_False;
596}
597
598//=======================================================================
599//function : GetFatherObject
600//purpose : Returns the father object, which may be NULL
601// theType gives type of father object to search
602//=======================================================================
603
604Handle(TObj_Object) TObj_Object::GetFatherObject
605 (const Handle(Standard_Type)& theType) const
606{
607 Handle(TObj_Object) aFather, aSon(this);
608
609 while ( aSon->GetObj( aSon->GetLabel().Father(), aFather, Standard_True ) )
610 {
611 if (theType.IsNull() || aFather->IsKind( theType ))
612 break;
613 else
614 {
615 aSon = aFather;
616 aFather.Nullify();
617 }
618 }
619
620 return aFather;
621}
622
623
624//=======================================================================
625//function : AfterRetrieval
626//purpose :
627//=======================================================================
628
629void TObj_Object::AfterRetrieval()
630{
631 // Register the name
632 Handle(TObj_Model) aModel = GetModel();
633 if ( !aModel.IsNull() )
634 aModel->RegisterName( GetName(), GetLabel(), GetDictionary() );
635}
636
637//=======================================================================
638//function : BeforeStoring
639//purpose : base implementation
640//=======================================================================
641
642void TObj_Object::BeforeStoring()
643{
644}
645
646//=======================================================================
647//function : GetReferenceLabel
648//purpose :
649//=======================================================================
650
651TDF_Label TObj_Object::GetReferenceLabel() const
652{
653#ifdef DFBROWSE
654 return getLabelByRank(GetLabel(),1,"References");
655#else
656 return GetLabel().FindChild ( 1, Standard_True );
657#endif
658}
659
660//=======================================================================
661//function : GetDataLabel
662//purpose :
663//=======================================================================
664
665TDF_Label TObj_Object::GetDataLabel() const
666{
667#ifdef DFBROWSE
668 return getLabelByRank(GetLabel(),3,"Data");
669#else
670 return GetLabel().FindChild ( 3, Standard_True );
671#endif
672}
673
674//=======================================================================
675//function : getDataLabel
676//purpose :
677//=======================================================================
678
679TDF_Label TObj_Object::getDataLabel (const Standard_Integer theRank1,
680 const Standard_Integer theRank2) const
681{
682 TDF_Label aLabel;
683 if ( theRank1 > 0 ) // protection
684 {
685 aLabel = GetDataLabel().FindChild ( theRank1, Standard_True );
686 if ( theRank2 > 0 )
687 aLabel = aLabel.FindChild ( theRank2, Standard_True );
688 }
689 return aLabel;
690}
691
692//=======================================================================
693//function : getReferenceLabel
694//purpose :
695//=======================================================================
696
697TDF_Label TObj_Object::getReferenceLabel (const Standard_Integer theRank1,
698 const Standard_Integer theRank2) const
699{
700 TDF_Label aLabel;
701 if ( theRank1 > 0 ) // protection
702 {
703 aLabel = GetReferenceLabel().FindChild ( theRank1, Standard_True );
704 if ( theRank2 > 0 )
705 aLabel = aLabel.FindChild ( theRank2, Standard_True );
706 }
707 return aLabel;
708}
709
710//=======================================================================
711//function : isDataAttribute
712//purpose : Returns True if there is an attribute having theGUID on the
713// theRank2-th sublabel of theRank1-th sublabel of the Data
714// label of the object.
715// If theRank2 is 0 (default), label theRank1 is supposed, not
716// its sublabel
717//=======================================================================
718
719Standard_Boolean TObj_Object::isDataAttribute
720 (const Standard_GUID& theGUID,
721 const Standard_Integer theRank1,
722 const Standard_Integer theRank2) const
723{
724 return getDataLabel(theRank1,theRank2).IsAttribute(theGUID);
725}
726
727//=======================================================================
728//function : getReal
729//purpose :
730//=======================================================================
731
732Standard_Real TObj_Object::getReal (const Standard_Integer theRank1,
733 const Standard_Integer theRank2) const
734{
735 TDF_Label aLabel = getDataLabel(theRank1,theRank2);
736
737 Handle(TDataStd_Real) aReal;
738 aLabel.FindAttribute ( TDataStd_Real::GetID(), aReal );
739 return aReal.IsNull() ? 0. : aReal->Get();
740}
741
742//=======================================================================
743//function : setReal
744//purpose :
745//=======================================================================
746
747Standard_Boolean TObj_Object::setReal (const Standard_Real theValue,
748 const Standard_Integer theRank1,
749 const Standard_Integer theRank2,
750 const Standard_Real theTolerance) const
751{
752 TDF_Label aLabel = getDataLabel(theRank1,theRank2);
753
754 // check that value is actually changed
755 Handle(TDataStd_Real) A;
756 if ( aLabel.FindAttribute(TDataStd_Real::GetID(), A) &&
757 fabs ( A->Get() - theValue ) <= theTolerance ) return Standard_False;
758
759 TDataStd_Real::Set ( aLabel, theValue );
760 return Standard_True;
761}
762
763//=======================================================================
764//function : getExtString
765//purpose :
766//=======================================================================
767
768Handle(TCollection_HExtendedString) TObj_Object::getExtString
769 (const Standard_Integer theRank1,
770 const Standard_Integer theRank2) const
771{
772 TDF_Label aLabel = getDataLabel(theRank1,theRank2);
773
774 Handle(TDataStd_Name) aName;
775 aLabel.FindAttribute ( TDataStd_Name::GetID(), aName );
776 return aName.IsNull() ? 0 : new TCollection_HExtendedString(aName->Get());
777}
778
779//=======================================================================
780//function : setExtString
781//purpose :
782//=======================================================================
783
784void TObj_Object::setExtString
785 (const Handle(TCollection_HExtendedString)& theValue,
786 const Standard_Integer theRank1,
787 const Standard_Integer theRank2) const
788{
789 TDF_Label aLabel = getDataLabel(theRank1,theRank2);
790 if ( !theValue.IsNull() )
791 TDataStd_Name::Set ( aLabel, theValue->String() );
792 else
793 aLabel.ForgetAttribute( TDataStd_Name::GetID() );
794}
795
796//=======================================================================
797//function : getAsciiString
798//purpose :
799//=======================================================================
800
801Handle(TCollection_HAsciiString) TObj_Object::getAsciiString
802 (const Standard_Integer theRank1,
803 const Standard_Integer theRank2) const
804{
805 TDF_Label aLabel = getDataLabel(theRank1,theRank2);
806
807 Handle(TDataStd_AsciiString) aStrAttr;
808 aLabel.FindAttribute ( TDataStd_AsciiString::GetID(), aStrAttr );
809 return aStrAttr.IsNull() ? 0 : new TCollection_HAsciiString( aStrAttr->Get() );
810}
811
812//=======================================================================
813//function : setAsciiString
814//purpose :
815//=======================================================================
816
817void TObj_Object::setAsciiString
818 (const Handle(TCollection_HAsciiString)& theValue,
819 const Standard_Integer theRank1,
820 const Standard_Integer theRank2) const
821{
822 TDF_Label aLabel = getDataLabel(theRank1,theRank2);
823 if ( !theValue.IsNull() )
824 TDataStd_AsciiString::Set ( aLabel, theValue->String() );
825 else
826 aLabel.ForgetAttribute( TDataStd_AsciiString::GetID() );
827}
828
829//=======================================================================
830//function : getInteger
831//purpose :
832//=======================================================================
833
834Standard_Integer TObj_Object::getInteger (const Standard_Integer theRank1,
835 const Standard_Integer theRank2) const
836{
837 TDF_Label aLabel = getDataLabel(theRank1,theRank2);
838
839 Handle(TDataStd_Integer) aNum;
840 aLabel.FindAttribute ( TDataStd_Integer::GetID(), aNum );
841 return aNum.IsNull() ? 0 : aNum->Get();
842}
843
844//=======================================================================
845//function : setInteger
846//purpose :
847//=======================================================================
848
849Standard_Boolean TObj_Object::setInteger (const Standard_Integer theValue,
850 const Standard_Integer theRank1,
851 const Standard_Integer theRank2) const
852{
853 TDF_Label aLabel = getDataLabel(theRank1,theRank2);
854
855 // check that value is actually changed
856 Handle(TDataStd_Integer) A;
857 if ( aLabel.FindAttribute(TDataStd_Integer::GetID(), A) &&
858 A->Get() == theValue ) return Standard_False;
859
860 TDataStd_Integer::Set ( aLabel, theValue );
861 return Standard_True;
862}
863
864//=======================================================================
865//function : getReference
866//purpose :
867//=======================================================================
868
869Handle(TObj_Object) TObj_Object::getReference (const Standard_Integer theRank1,
870 const Standard_Integer theRank2) const
871{
872 TDF_Label aLabel = getReferenceLabel(theRank1,theRank2);
873
874 Handle(TObj_TReference) aRef;
875 aLabel.FindAttribute ( TObj_TReference::GetID(), aRef );
876 return aRef.IsNull() ? Handle(TObj_Object)() : aRef->Get();
877}
878
879//=======================================================================
880//function : setReference
881//purpose :
882//=======================================================================
883
884Standard_Boolean TObj_Object::setReference (const Handle(TObj_Object) & theObject,
885 const Standard_Integer theRank1,
886 const Standard_Integer theRank2)
887{
888 TDF_Label aLabel = getReferenceLabel(theRank1,theRank2);
889
890 if ( theObject.IsNull() )
891 return aLabel.ForgetAttribute ( TObj_TReference::GetID() );
892
893 // check that reference is actually changed
894 Handle(TObj_TReference) A;
895 if ( aLabel.FindAttribute(TObj_TReference::GetID(), A) &&
896 A->Get() == theObject ) return Standard_False;
897
898 // 27.07.05, PTv: remove reference attribute before create new reference (for Undo/Redo)
899 aLabel.ForgetAttribute( TObj_TReference::GetID() );
900
901 Handle(TObj_Object) me = this;
902 TObj_TReference::Set ( aLabel, theObject, me);
903 return Standard_True;
904}
905
906//=======================================================================
907//function : addReference
908//purpose :
909//=======================================================================
910
911TDF_Label TObj_Object::addReference (const Standard_Integer theRank1,
912 const Handle(TObj_Object) & theObject)
913{
914 TDF_Label aRefLabel = GetReferenceLabel();
915 if ( theRank1 > 0 )
916 aRefLabel = aRefLabel.FindChild ( theRank1, Standard_True );
917
918 TDF_TagSource aTag;
919 TDF_Label aLabel = aTag.NewChild(aRefLabel);
920
921 Handle(TObj_Object) me = this;
922 TObj_TReference::Set ( aLabel, theObject, me);
923 return aLabel;
924}
925
926//=======================================================================
927//function : getRealArray
928//purpose : Returns an existing or create a new real array on theRank2-th
929// sublabel of theRank1-th sublabel of the Data label of the object.
930// If theRank2 is 0 (default), label theRank1 is supposed (not its sublabel).
931// A newly created array has 1 and theLength bounds and is initialized
932// with zero
933//WARNING : call setArray() after array contents modification
934// in order to assure Undo work
935//=======================================================================
936
937Handle(TColStd_HArray1OfReal) TObj_Object::getRealArray
938 (const Standard_Integer theLength,
939 const Standard_Integer theRank1,
940 const Standard_Integer theRank2,
941 const Standard_Real theInitialValue) const
942{
943 TDF_Label aLabel = getDataLabel(theRank1,theRank2);
944 Handle(TDataStd_RealArray) anArrAttribute;
945 if (!aLabel.FindAttribute(TDataStd_RealArray::GetID(), anArrAttribute))
946 if ( theLength > 0 )
947 {
948 anArrAttribute = TDataStd_RealArray::Set (aLabel, 1, theLength);
949 anArrAttribute->Array()->Init( theInitialValue );
950 }
951 Handle(TColStd_HArray1OfReal) anArr;
952 if ( !anArrAttribute.IsNull() )
953 anArr = anArrAttribute->Array();
954 return anArr;
955}
956
957//=======================================================================
958//function : getIntegerArray
959//purpose : Returns an existing or create a new integer array on theRank2-th
960// sublabel of theRank1-th sublabel of the Data label of the object.
961// If theRank2 is 0 (default), label theRank1 is supposed (not its sublabel).
962// A newly created array has 1 and theLength bounds and is initialized
963// with zero
964//WARNING : call setArray() after array contents modification
965// in order to assure Undo work
966//=======================================================================
967
968Handle(TColStd_HArray1OfInteger) TObj_Object::getIntegerArray
969 (const Standard_Integer theLength,
970 const Standard_Integer theRank1,
971 const Standard_Integer theRank2,
972 const Standard_Integer theInitialValue) const
973{
974 TDF_Label aLabel = getDataLabel(theRank1,theRank2);
975 Handle(TDataStd_IntegerArray) anArrAttribute;
976 if (!aLabel.FindAttribute(TDataStd_IntegerArray::GetID(), anArrAttribute))
977 if ( theLength > 0 )
978 {
979 anArrAttribute = TDataStd_IntegerArray::Set (aLabel, 1, theLength);
980 anArrAttribute->Array()->Init( theInitialValue );
981 }
982 Handle(TColStd_HArray1OfInteger) anArr;
983 if ( !anArrAttribute.IsNull() )
984 anArr = anArrAttribute->Array();
985 return anArr;
986}
987
988//=======================================================================
989//function : getExtStringArray
990//purpose : Returns an existing or create a new string array on theRank2-th
991// sublabel of theRank1-th sublabel of the Data label of the object.
992// If theRank2 is 0 (default), label theRank1 is supposed (not its sublabel).
993// A newly created array has 1 and theLength bounds
994// NOTE: new created array is NOT initialized.
995//WARNING : call setArray() after array contents modification
996// in order to assure Undo work
997//=======================================================================
998
999Handle(TColStd_HArray1OfExtendedString) TObj_Object::getExtStringArray
1000 (const Standard_Integer theLength,
1001 const Standard_Integer theRank1,
1002 const Standard_Integer theRank2) const
1003{
1004 TDF_Label aLabel = getDataLabel(theRank1,theRank2);
1005 Handle(TDataStd_ExtStringArray) anArrAttribute;
1006 if (!aLabel.FindAttribute(TDataStd_ExtStringArray::GetID(), anArrAttribute))
1007 if ( theLength > 0 )
1008 anArrAttribute = TDataStd_ExtStringArray::Set (aLabel, 1, theLength);
1009
1010 Handle(TColStd_HArray1OfExtendedString) anArr;
1011 if ( !anArrAttribute.IsNull() )
1012 anArr = anArrAttribute->Array();
1013 return anArr;
1014}
1015
1016//=======================================================================
1017//function : setArray
1018//purpose : Store theArray on theRank2-th sublabel of theRank1-th sublabel
1019// of the Data label of the object.
1020// If theRank2 is 0 (default), label theRank1 is supposed (not its sublabel).
1021//=======================================================================
1022
1023void TObj_Object::setArray (const Handle(TColStd_HArray1OfReal)& theArray,
1024 const Standard_Integer theRank1,
1025 const Standard_Integer theRank2)
1026{
1027 TDF_Label aLabel = getDataLabel(theRank1,theRank2);
1028 Handle(TDataStd_RealArray) anArrAttribute;
1029 if (!aLabel.FindAttribute(TDataStd_RealArray::GetID(), anArrAttribute) &&
1030 !theArray.IsNull())
1031 anArrAttribute = TDataStd_RealArray::Set (aLabel, 1, 1);
1032
1033 if (theArray.IsNull()) {
1034 // deletion mode
1035 if (!anArrAttribute.IsNull())
1036 aLabel.ForgetAttribute(anArrAttribute);
1037 return;
1038 }
1039
1040 if (anArrAttribute->Array() == theArray)
1041 // Backup wont happen but we want it
1042 anArrAttribute->Init(1,1);
1043
1044 anArrAttribute->ChangeArray( theArray );
1045}
1046
1047//=======================================================================
1048//function : setArray
1049//purpose : Store theArray on theRank2-th sublabel of theRank1-th sublabel
1050// of the Data label of the object.
1051// If theRank2 is 0 (default), label theRank1 is supposed (not its sublabel).
1052//=======================================================================
1053
1054void TObj_Object::setArray (const Handle(TColStd_HArray1OfInteger)& theArray,
1055 const Standard_Integer theRank1,
1056 const Standard_Integer theRank2)
1057{
1058 TDF_Label aLabel = getDataLabel(theRank1,theRank2);
1059 Handle(TDataStd_IntegerArray) anArrAttribute;
1060 if (!aLabel.FindAttribute(TDataStd_IntegerArray::GetID(), anArrAttribute) &&
1061 !theArray.IsNull())
1062 anArrAttribute = TDataStd_IntegerArray::Set (aLabel, 1, 1);
1063
1064 if (theArray.IsNull()) {
1065 // deletion mode
1066 if (!anArrAttribute.IsNull())
1067 aLabel.ForgetAttribute(anArrAttribute);
1068 return;
1069 }
1070
1071 if (anArrAttribute->Array() == theArray)
1072 // Backup wont happen but we want it
1073 anArrAttribute->Init(1,1);
1074
1075 anArrAttribute->ChangeArray( theArray );
1076}
1077
1078//=======================================================================
1079//function : setArray
1080//purpose : Store theArray on theRank2-th sublabel of theRank1-th sublabel
1081// of the Data label of the object.
1082// If theRank2 is 0 (default), label theRank1 is supposed (not its sublabel).
1083//=======================================================================
1084
1085void TObj_Object::setArray (const Handle(TColStd_HArray1OfExtendedString)& theArray,
1086 const Standard_Integer theRank1,
1087 const Standard_Integer theRank2)
1088{
1089 TDF_Label aLabel = getDataLabel(theRank1,theRank2);
1090 Handle(TDataStd_ExtStringArray) anArrAttribute;
1091 if (!aLabel.FindAttribute(TDataStd_ExtStringArray::GetID(), anArrAttribute) &&
1092 !theArray.IsNull())
1093 anArrAttribute = TDataStd_ExtStringArray::Set (aLabel, 1, 1);
1094
1095 if (theArray.IsNull()) {
1096 // deletion mode
1097 if (!anArrAttribute.IsNull())
1098 aLabel.ForgetAttribute(anArrAttribute);
1099 return;
1100 }
1101
1102 if (anArrAttribute->Array() == theArray)
1103 // Backup wont happen but we want it
1104 anArrAttribute->Init(1,1);
1105
1106 anArrAttribute->ChangeArray( theArray );
1107}
1108
1109//=======================================================================
1110//function : Clone
1111//purpose : method.
1112//=======================================================================
1113
1114Handle(TObj_Object) TObj_Object::Clone
1115 (const TDF_Label& theTargetLabel,
1116 Handle(TDF_RelocationTable) theRelocTable)
1117{
1118 Handle(TDF_RelocationTable) aRelocTable = theRelocTable;
1119 if (theRelocTable.IsNull())
1120 aRelocTable = new TDF_RelocationTable;
1121 Handle(TObj_Object) aNewObj;
1122 // take current model for restoring it after creating object.
1123 const Handle(TObj_Model)& aCurrentModel = TObj_Assistant::GetCurrentModel();
1124
1125 // take target model
1126 Handle(TObj_Model) aTargetModel;
1127 TDF_Label aLabel = TDocStd_Document::Get(theTargetLabel)->Main();
1128 Handle(TObj_TModel) aModelAttr;
1129 if (aLabel.FindAttribute(TObj_TModel::GetID(), aModelAttr))
1130 aTargetModel = aModelAttr->Model();
1131
1132 if (aCurrentModel != aTargetModel)
1133 TObj_Assistant::SetCurrentModel (aTargetModel);
1134 // crete new object
1135 aNewObj = TObj_Persistence::CreateNewObject (DynamicType()->Name(), theTargetLabel);
1136
1137 if (!aNewObj.IsNull())
1138 {
1139 TObj_TObject::Set(theTargetLabel,aNewObj);
1140
1141 // adding a record to the reloation table
1142 aRelocTable->SetRelocation(GetLabel(), theTargetLabel);
1143
1144 // now set name of object.
1145 const Handle(TCollection_HExtendedString) aCloneName = GetNameForClone( aNewObj );
1146 if( !aCloneName.IsNull() && !aCloneName->IsEmpty() )
1147 aNewObj->SetName( new TCollection_HExtendedString( aCloneName ) );
1148
1149 // copy the data
1150 copyData (aNewObj);
1151
1152 // copy the references
1153 // changed by van // copyReferences (aNewObj);
1154 // references have to be coped after coping all objects and models
1155
1156 TDF_Label aTargetLabel = aNewObj->GetChildLabel();
1157 CopyChildren(aTargetLabel, aRelocTable);
1158
1159 // copy TagSource for the children
1160 TDF_Label aChildLabel = GetChildLabel();
1161 Handle(TDF_Attribute) anAttr;
1162 if(aChildLabel.FindAttribute(TDF_TagSource::GetID(), anAttr))
1163 {
1164 Handle(TDF_TagSource) aTagSource = Handle(TDF_TagSource)::DownCast(anAttr);
1165 Handle(TDF_TagSource) aTargetTagSource = TDF_TagSource::Set(aTargetLabel);
1166 aTargetTagSource->Set(aTagSource->Get());
1167 }
1168
1169 if(theRelocTable.IsNull())
1170 CopyReferences(aNewObj, aRelocTable);
1171 }
1172
1173 // restore the model for persistence.
1174 if (aCurrentModel != aTargetModel)
1175 TObj_Assistant::SetCurrentModel (aCurrentModel);
1176
1177 return aNewObj;
1178}
1179
1180//=======================================================================
1181//function : copyData
1182//purpose : protected
1183//=======================================================================
1184
1185Standard_Boolean TObj_Object::copyData
1186 (const Handle(TObj_Object)& theTargetObject)
1187{
1188 Standard_Boolean IsDone = Standard_False;
1189 if ( !theTargetObject->DynamicType()->SubType( DynamicType() ) )
1190 return IsDone;
1191 // init the copier by labels.
1192 TDF_Label aDataLabel = GetDataLabel();
1193 TDF_Label aNewDataLabel = theTargetObject->GetDataLabel();
1194 // check if object has any data.
1195 if (aDataLabel.IsNull() || aNewDataLabel.IsNull())
1196 return IsDone;
1197
1198 TDF_CopyLabel aCopier(aDataLabel, aNewDataLabel);
1199 aCopier.Perform();
1200
1201 return aCopier.IsDone();
1202}
1203
1204//=======================================================================
1205//function : CopyChildren
1206//purpose :
1207//=======================================================================
1208
1209void TObj_Object::CopyChildren
1210 (TDF_Label& theTargetLabel,
1211 const Handle(TDF_RelocationTable)& theRelocTable)
1212{
1213 Handle(TObj_ObjectIterator) aChildren = /*TObj_Object::*/GetChildren();
1214 // to support childs on sublabels of sublabel of child label
1215 //new TObj_ObjectIterator(GetChildLabel(), NULL, Standard_True);
1216 TDF_Label aSourceChildLabel = GetChildLabel();
1217 for(;aChildren->More(); aChildren->Next())
1218 {
1219 Handle(TObj_Object) aChild = aChildren->Value();
1220 if(!aChild.IsNull())
1221 {
1222 /* only for one sub level of children
1223 TDF_Label aChildLabel =
1224 theTargetLabel.FindChild(aChild->GetLabel().Tag(), Standard_True);
1225 aChild->Clone(aChildLabel, theRelocTable);
1226 // to support childs on sublabels of sublabel of child label
1227 */
1228 // to support childs on sublabels of sublabel of child label
1229 TColStd_SequenceOfInteger aTags;
1230 TDF_Label aCurChildLab = aChild->GetLabel();
1231 while ( !aCurChildLab.IsNull() && aCurChildLab != aSourceChildLabel )
1232 {
1233 aTags.Append( aCurChildLab.Tag() );
1234 aCurChildLab = aCurChildLab.Father();
1235 }
1236 TDF_Label aChildLabel = theTargetLabel;
1237 for ( Standard_Integer i = aTags.Length(); i > 0 ; i-- )
1238 aChildLabel = aChildLabel.FindChild( aTags.Value( i ), Standard_True );
1239
1240 aChild->Clone(aChildLabel, theRelocTable);
1241 }
1242 }
1243}
1244
1245//=======================================================================
1246//function : CopyReferences
1247//purpose :
1248//=======================================================================
1249
1250void TObj_Object::CopyReferences
1251 (const Handle(TObj_Object)& theTargetObject,
1252 const Handle(TDF_RelocationTable)& theRelocTable)
1253{
1254 // recursive copy of references
1255 Handle(TObj_ObjectIterator) aSrcChildren = //GetChildren();
1256 // to support childs on sublabels of sublabel of child label
1257 new TObj_OcafObjectIterator(GetChildLabel(), NULL, Standard_True);
1258 for(; aSrcChildren->More(); aSrcChildren->Next())
1259 {
1260 Handle(TObj_Object) aSrcChild =
1261 Handle(TObj_Object)::DownCast(aSrcChildren->Value());
1262 TDF_Label aSrcL = aSrcChild->GetLabel();
1263 TDF_Label aDestLabel;
1264 if( !theRelocTable->HasRelocation(aSrcL, aDestLabel) )
1265 continue;
1266 Handle(TObj_Object) aDstChild;
1267 if ( !TObj_Object::GetObj( aDestLabel, aDstChild ) )
1268 continue;
1269 if ( aDstChild.IsNull() || !aDstChild->IsAlive() || aSrcChild->DynamicType() != aDstChild->DynamicType() )
1270 continue; // should not be with relocation table
1271
1272 aSrcChild->CopyReferences(aDstChild, theRelocTable);
1273 }
1274 // copy of my references
1275 theTargetObject->GetReferenceLabel().ForgetAllAttributes(Standard_True);
1276
1277 TDF_Label aTargetLabel = theTargetObject->GetReferenceLabel();
1278 copyReferences(GetReferenceLabel(), aTargetLabel, theRelocTable);
1279}
1280
1281//=======================================================================
1282//function : copyReferences
1283//purpose : protected
1284//=======================================================================
1285
1286void TObj_Object::copyReferences
1287 (const TDF_Label& theSourceLabel,
1288 TDF_Label& theTargetLabel,
1289 const Handle(TDF_RelocationTable)& theRelocTable)
1290{
1291 TDF_AttributeIterator anIter(theSourceLabel);
1292 for(; anIter.More(); anIter.Next())
1293 {
1294 Handle(TDF_Attribute) anAttr = anIter.Value()->NewEmpty();
1295 theTargetLabel.AddAttribute(anAttr);
1296 anIter.Value()->Paste(anAttr, theRelocTable);
1297
1298 }
1299 TDF_ChildIterator aLI(theSourceLabel);
1300 TDF_Label aTargetLabel;
1301 for(; aLI.More(); aLI.Next())
1302 {
1303 aTargetLabel = theTargetLabel.FindChild(aLI.Value().Tag(), Standard_True);
1304 copyReferences(aLI.Value(), aTargetLabel, theRelocTable);
1305 }
1306}
1307
1308//=======================================================================
1309//function : ReplaceReference
1310//purpose :
1311//=======================================================================
1312
1313void TObj_Object::ReplaceReference (const Handle(TObj_Object)& theOldObject,
1314 const Handle(TObj_Object)& theNewObject)
1315{
1316 Handle(TObj_LabelIterator) anItr =
1317 Handle(TObj_LabelIterator)::DownCast( GetReferences() );
1318 if (anItr.IsNull())
1319 return;
1320 // iterates on references.
1321 for (; anItr->More(); anItr->Next() )
1322 {
1323 Handle(TObj_Object) anObj = anItr->Value();
1324 if (anObj != theOldObject)
1325 continue;
1326
1327 TDF_Label aRefLabel = anItr->LabelValue();
1328 // if new object is null then simple remove reference.
1329 if (theNewObject.IsNull())
1330 {
1331 aRefLabel.ForgetAllAttributes();
1332 break;
1333 }
1334 // set reference to new object.
1335 Handle(TObj_Object) me = this;
1336 TObj_TReference::Set ( aRefLabel, theNewObject, me);
1337 break;
1338 }
1339}
1340
1341//=======================================================================
1342//function : IsAlive
1343//purpose :
1344//=======================================================================
1345
1346Standard_Boolean TObj_Object::IsAlive() const
1347{
1348 if (myLabel.IsNull())
1349 return Standard_False;
1350
1351 Handle(TObj_Object) anObj;
1352 if ( !GetObj( myLabel, anObj ) )
1353 return Standard_False;
1354
1355 return Standard_True;
1356}
1357
1358//=======================================================================
1359//function : GetFlags
1360//purpose :
1361//=======================================================================
1362
1363Standard_Integer TObj_Object::GetFlags() const
1364{
1365 return getInteger(DataTag_Flags);
1366}
1367
1368//=======================================================================
1369//function : SetFlags
1370//purpose :
1371//=======================================================================
1372
1373void TObj_Object::SetFlags(const Standard_Integer theMask)
1374{
1375 Standard_Integer aFlags = getInteger(DataTag_Flags);
1376 aFlags = aFlags | theMask;
1377 setInteger(aFlags, DataTag_Flags);
1378}
1379
1380//=======================================================================
1381//function : TestFlags
1382//purpose :
1383//=======================================================================
1384
1385Standard_Boolean TObj_Object::TestFlags(const Standard_Integer theMask) const
1386{
1387 Standard_Integer aFlags = getInteger(DataTag_Flags);
1388 return aFlags & theMask;
1389}
1390
1391//=======================================================================
1392//function : ClearFlags
1393//purpose :
1394//=======================================================================
1395
1396void TObj_Object::ClearFlags(const Standard_Integer theMask)
1397{
1398 Standard_Integer aFlags = getInteger(DataTag_Flags);
1399 aFlags = aFlags & (~theMask);
1400 setInteger(aFlags, DataTag_Flags);
1401}
1402
1403//=======================================================================
1404//function : RemoveBackReferences
1405//purpose :
1406//=======================================================================
1407
1408Standard_Boolean TObj_Object::RemoveBackReferences(const TObj_DeletingMode theMode)
1409{
1410 Handle(TObj_ObjectIterator) aRefs = GetBackReferences();
1411
1412 // Free Object can be deleted in any Mode
1413 if ( aRefs.IsNull() || !aRefs->More()) return Standard_True;
1414
1415 if( theMode == TObj_FreeOnly) return Standard_False;
1416
1417 // Defining the sequence of objects which are referenced to this one. The
1418 // first sequence stores containers the second one object with strong
1419 // relation.
1420 TObj_SequenceOfObject aContainers;
1421 TObj_SequenceOfObject aStrongs;
1422 Handle(TObj_Object) aMe = this;
1423
1424 // Sorting the referencing objects
1425 for( ; aRefs->More() ; aRefs->Next())
1426 {
1427 Handle(TObj_Object) anObject = aRefs->Value();
1428 if ( anObject.IsNull() || !anObject->IsAlive() )
1429 continue;
1430 if ( anObject->CanRemoveReference(aMe) )
1431 aContainers.Append(anObject);
1432 else
1433 aStrongs.Append(anObject);
1434 }
1435 // Can not be removed without deletion of referenced objects mode
1436 if( theMode == TObj_KeepDepending && aStrongs.Length() > 0 )
1437 return Standard_False;
1438 // Delete or link off the referencing objects
1439 Standard_Integer i;
1440 Handle(TDF_Data) anOwnData = GetLabel().Data();
1441 for (i = 1; i <= aContainers.Length(); i++)
1442 {
1443 Handle(TObj_Object) anObj = aContainers(i);
1444 if ( anObj.IsNull() || anObj->GetLabel().IsNull() )
1445 continue; // undead object on dead label
1446 Handle(TDF_Data) aData = anObj->GetLabel().Data();
1447 Standard_Boolean aModifMode = aData->IsModificationAllowed();
1448 if ( anOwnData != aData )
1449 aData->AllowModification( Standard_True );
1450 anObj->RemoveReference(aMe);
1451 if ( anOwnData != aData )
1452 aData->AllowModification( aModifMode );
1453 }
1454 /* PTv 21.11.2006
1455 object from other document refers to current object and must be killed
1456 when current object become dead for just want to remove references to it
1457 if ( theMode != TObj_Forced ) // cause leads to exception when
1458 // try to remove objects during close document
1459 */
1460 for (i = 1; i <= aStrongs.Length(); i++)
1461 {
1462 Handle(TObj_Object) anObj = aStrongs(i);
1463 if ( anObj.IsNull() || anObj->GetLabel().IsNull() )
1464 continue; // undead object on dead label
1465 Handle(TDF_Data) aData = anObj->GetLabel().Data();
1466 Standard_Boolean aModifMode = aData->IsModificationAllowed();
1467 if ( anOwnData != aData )
1468 aData->AllowModification( Standard_True );
1469 anObj->Detach(theMode);
1470 if ( anOwnData != aData )
1471 aData->AllowModification( aModifMode );
1472 }
1473
1474 return Standard_True;
1475}
1476
1477//=======================================================================
1478//function : RelocateReferences
1479//purpose : Make that each reference pointing to a descendant label of
1480// theFromRoot to point to an equivalent label under theToRoot.
1481// Return False if a resulting reference does not point to
1482// an TObj_Object
1483//Example :
1484// a referred object label = 0:3:24:7:2:7
1485// theFromRoot = 0:3:24
1486// theToRoot = 0:2
1487// a new referred label = 0:2:7:2:7
1488//=======================================================================
1489
1490Standard_Boolean TObj_Object::RelocateReferences
1491 (const TDF_Label& theFromRoot,
1492 const TDF_Label& theToRoot,
1493 const Standard_Boolean theUpdateBackRefs)
1494{
1495 TDF_ChildIDIterator aRefIt (GetReferenceLabel(),
1496 TObj_TReference::GetID(),
1497 Standard_True );
1498 Handle(TObj_Object) anObj;
1499 for ( ; aRefIt.More(); aRefIt.Next() )
1500 {
1501 Handle(TObj_TReference) aRef =
1502 Handle(TObj_TReference)::DownCast( aRefIt.Value() );
1503
1504 TDF_Label aNewLabel, aLabel = aRef->GetLabel();
1505 if ( aLabel.Data() != theFromRoot.Data() ||
1506 aLabel.IsDescendant( theToRoot ))
1507 continue; // need not to relocate
1508
1509 TDF_Tool::RelocateLabel( aLabel, theFromRoot, theToRoot, aNewLabel );
1510 if ( aNewLabel.IsNull() || !TObj_Object::GetObj( aNewLabel, anObj ))
1511 return Standard_False;
1512
1513 // care of back references
1514 if (theUpdateBackRefs)
1515 {
1516 Handle(TObj_Object) me = this;
1517 // a new referred object
1518 anObj->AddBackReference( me );
1519 // an old object
1520 anObj = aRef->Get();
1521 if (!anObj.IsNull())
1522 anObj->RemoveBackReference( me );
1523 }
1524
1525 aRef->Set( aNewLabel, aRef->GetMasterLabel() );
1526 }
1527
1528 return Standard_True;
1529}
1530
1531//=======================================================================
1532//function : GetBadReference
1533//purpose :
1534//=======================================================================
1535
1536Standard_Boolean TObj_Object::GetBadReference
1537 (const TDF_Label& theRoot,
1538 TDF_Label& theBadReference) const
1539{
1540 TDF_ChildIDIterator aRefIt (GetReferenceLabel(),
1541 TObj_TReference::GetID(),
1542 Standard_True );
1543 Handle(TObj_Object) anObj;
1544 for ( ; aRefIt.More(); aRefIt.Next() )
1545 {
1546 Handle(TObj_TReference) aRef =
1547 Handle(TObj_TReference)::DownCast( aRefIt.Value() );
1548
1549 TDF_Label aLabel = aRef->GetLabel();
1550 if ( aLabel.Data() == theRoot.Data() &&
1551 !aLabel.IsDescendant( theRoot ))
1552 {
1553 theBadReference = aLabel;
1554 return Standard_True;
1555 }
1556 }
1557
1558 return Standard_False;
1559}
1560
1561//=======================================================================
1562//function : TypeFlags
1563//purpose :
1564//=======================================================================
1565
1566Standard_Integer TObj_Object::GetTypeFlags() const
1567{
1568 return Visible;
1569}
1570
1571//=======================================================================
1572//function : GetDictionary
1573//purpose : default implementation
1574//=======================================================================
1575
1576Handle(TObj_TNameContainer) TObj_Object::GetDictionary() const
1577{
1578 Handle(TObj_Model) aModel = GetModel();
1579 if ( !aModel.IsNull() )
1580 return aModel->GetDictionary();
1581 return NULL;
1582}
1583
1584//=======================================================================
1585//function : SetOrder
1586//purpose :
1587//=======================================================================
1588
1589Standard_Boolean TObj_Object::SetOrder( const Standard_Integer& theIndx )
1590{
1591 setInteger( theIndx, DataTag_Order );
1592 return Standard_True;
1593}
1594
1595//=======================================================================
1596//function : GetOrder
1597//purpose :
1598//=======================================================================
1599
1600Standard_Integer TObj_Object::GetOrder() const
1601{
1602 Standard_Integer order = getInteger( DataTag_Order );
1603 if ( !order )
1604 order = GetLabel().Tag();
1605 return order;
1606}