bdb65c933b9270b4f5fcbad934f79575413a007d
[occt.git] / src / TObj / TObj_Model.cxx
1 // Created on: 2004-11-23
2 // Created by: Pavel TELKOV
3 // Copyright (c) 2004-2012 OPEN CASCADE SAS
4 //
5 // The content of this file is subject to the Open CASCADE Technology Public
6 // License Version 6.5 (the "License"). You may not use the content of this file
7 // except in compliance with the License. Please obtain a copy of the License
8 // at http://www.opencascade.org and read it completely before using this file.
9 //
10 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
12 //
13 // The Original Code and all software distributed under the License is
14 // distributed on an "AS IS" basis, without warranty of any kind, and the
15 // Initial Developer hereby disclaims all such warranties, including without
16 // limitation, any warranties of merchantability, fitness for a particular
17 // purpose or non-infringement. Please see the License for the specific terms
18 // and conditions governing the rights and limitations under the License.
19
20 // The original implementation Copyright: (C) RINA S.p.A
21
22 #include <TObj_Model.hxx>
23
24 #include <OSD_File.hxx>
25 #include <Precision.hxx>
26 #include <Standard_ErrorHandler.hxx>
27 #include <TCollection_ExtendedString.hxx>
28 #include <TCollection_HAsciiString.hxx>
29 #include <TDataStd_Integer.hxx>
30 #include <TDataStd_Real.hxx>
31 #include <TDF_Tool.hxx>
32 #include <TDF_ChildIterator.hxx>
33 #include <TDocStd_Document.hxx>
34 #include <TDocStd_Owner.hxx>
35
36 #include <TObj_Assistant.hxx>
37 #include <TObj_Application.hxx>
38 #include <TObj_CheckModel.hxx>
39 #include <TObj_HiddenPartition.hxx>
40 #include <TObj_LabelIterator.hxx>
41 #include <TObj_ModelIterator.hxx>
42 #include <TObj_Object.hxx>
43 #include <TObj_Partition.hxx>
44 #include <TObj_TObject.hxx>
45 #include <TObj_TModel.hxx>
46 #include <TObj_TNameContainer.hxx>
47 #include <Message_Msg.hxx>
48
49 #ifdef WNT
50   #include <io.h>
51 #else
52   #include <unistd.h>
53 #endif
54
55 IMPLEMENT_STANDARD_HANDLE(TObj_Model,MMgt_TShared)
56 IMPLEMENT_STANDARD_RTTIEXT(TObj_Model,MMgt_TShared)
57
58 //=======================================================================
59 //function : TObj_Model
60 //purpose  :
61 //=======================================================================
62
63 TObj_Model::TObj_Model ()
64 {
65   myMessenger = GetApplication()->Messenger();
66 }
67
68 //=======================================================================
69 //function : GetApplication
70 //purpose  :
71 //=======================================================================
72
73 const Handle(TObj_Application) TObj_Model::GetApplication()
74 {
75   return TObj_Application::GetInstance();
76 }
77
78 //=======================================================================
79 //function : Destructor
80 //purpose  :
81 //=======================================================================
82
83 TObj_Model::~TObj_Model ()
84 {
85   Close();
86 }
87
88 //=======================================================================
89 //function : CloseDocument
90 //purpose  : free OCAF document
91 //=======================================================================
92
93 void TObj_Model::CloseDocument (const Handle(TDocStd_Document)& theDoc)
94 {
95   // prevent Abort of the following modifs at document destruction if
96   // a transaction is open: see theDoc->myUndoTransaction.~()
97   if ( theDoc->HasOpenCommand() )
98     theDoc->AbortCommand();
99  
100   // Application
101   const Handle(TObj_Application) anApplication = GetApplication();
102
103   // just all other attributes
104   theDoc->Main().Root().ForgetAllAttributes(Standard_True);
105   anApplication->Close( theDoc );
106 }
107
108 //=======================================================================
109 //function : Load
110 //purpose  : Loads the model from the file
111 //=======================================================================
112
113 Standard_Boolean TObj_Model::Load (const char* theFile)
114 {
115   // Return status
116   Standard_Boolean aStatus = Standard_True;
117
118   // Document
119   Handle(TDocStd_Document) aDoc;
120
121   // Application
122   const Handle(TObj_Application) anApplication = GetApplication();
123
124   // Current model
125   const Handle(TObj_Model) me = this;
126   TObj_Assistant::SetCurrentModel( me );
127   TObj_Assistant::ClearTypeMap();
128
129   Standard_Boolean isFileEmpty = checkDocumentEmpty( theFile );
130   if ( isFileEmpty )
131   {
132     // theFile is empty, create new TDocStd_Document for this model
133     aStatus = anApplication->CreateNewDocument(aDoc, GetFormat());
134
135     if ( aStatus == Standard_True )
136     {
137       // Put model in a new attribute on root label
138       TDF_Label aLabel = aDoc->Main();
139       Handle(TObj_TModel) anAtr = new TObj_TModel;
140       aLabel.AddAttribute(anAtr);
141       anAtr->Set( me );
142       // Record that label in the model object, and initialise the new model
143       SetLabel(aLabel);
144     }
145   }
146   else
147   {
148     // retrieve TDocStd_Document from <theFile>
149     Messenger()->Send(Message_Msg("TObj_M_LoadDocument") << (Standard_CString)theFile,
150                              Message_Info);
151     aStatus = anApplication->LoadDocument(theFile,aDoc);
152
153     if ( aStatus == Standard_True )
154     {
155       // Check for validity of the model read:
156       // if it had wrong type, it has not been not properly restored
157       TDF_Label aLabel = GetLabel();
158       Standard_Boolean isValid = !aLabel.IsNull() && !aDoc.IsNull();
159       {
160         try
161         {
162           isValid = isValid && aLabel.Data() == aDoc->GetData();
163         }
164         catch (Standard_Failure)
165         {
166           isValid = Standard_False;
167         }
168       }
169       if (!isValid)
170       {
171         if (!aDoc.IsNull()) CloseDocument (aDoc);
172         myLabel.Nullify();
173         Messenger()->Send(Message_Msg("TObj_M_WrongFile") << (Standard_CString)theFile,
174                                  Message_Alarm);
175         aStatus = Standard_False;
176       }
177     }
178     else
179     {
180       // release document from session
181       // no message is needed as it has been put in anApplication->LoadDocument()
182       if (!aDoc.IsNull()) CloseDocument (aDoc);
183       myLabel.Nullify();
184     }
185   }
186   //    initialise the new model
187   if ( aStatus == Standard_True )
188   {
189     Standard_Boolean isInitOk = Standard_False;
190     {
191       try
192       {
193         isInitOk = initNewModel(isFileEmpty);
194       }
195       catch (Standard_Failure)
196       {
197 #if defined(_DEBUG) || defined(DEB)
198         Handle(Standard_Failure) anExc = Standard_Failure::Caught();
199         TCollection_ExtendedString aString(anExc->DynamicType()->Name());
200         aString = aString + ": " + anExc->GetMessageString();
201         Messenger()->Send(Message_Msg("TObj_Appl_Exception") << aString);
202 #endif
203         Messenger()->Send(Message_Msg("TObj_M_WrongFile") << (Standard_CString)theFile,
204                                  Message_Alarm);
205       }
206     }
207     if (!isInitOk )
208     {
209       if (!aDoc.IsNull()) CloseDocument (aDoc);
210       myLabel.Nullify();
211       aStatus = Standard_False;
212     }
213   }
214   TObj_Assistant::UnSetCurrentModel();
215   TObj_Assistant::ClearTypeMap();
216   return aStatus;
217 }
218
219 //=======================================================================
220 //function : GetFile
221 //purpose  : Returns the full file name this model is to be saved to, 
222 //           or null if the model was not saved yet
223 //=======================================================================
224
225 Handle(TCollection_HAsciiString) TObj_Model::GetFile() const
226 {
227   Handle(TDocStd_Document) aDoc = TDocStd_Document::Get(GetLabel());
228   if ( !aDoc.IsNull() ) {
229     TCollection_AsciiString anOldPath( aDoc->GetPath() );
230     if ( !anOldPath.IsEmpty() )
231       return new TCollection_HAsciiString( anOldPath );
232   }
233   return 0;
234 }
235
236 //=======================================================================
237 //function : Save
238 //purpose  : Save the model to the same file
239 //=======================================================================
240
241 Standard_Boolean TObj_Model::Save ()
242 {
243   Handle(TDocStd_Document) aDoc = TDocStd_Document::Get(GetLabel());
244   if ( aDoc.IsNull() )
245     return Standard_False;
246
247   TCollection_AsciiString anOldPath( aDoc->GetPath() );
248   if ( !anOldPath.IsEmpty() )
249     return SaveAs( anOldPath.ToCString() );
250   return Standard_True;
251 }
252
253 //=======================================================================
254 //function : SaveAs
255 //purpose  : Save the model to a file
256 //=======================================================================
257
258 Standard_Boolean TObj_Model::SaveAs (const char* theFile)
259 {
260   TObj_Assistant::ClearTypeMap();
261   // OCAF document
262   Handle(TDocStd_Document) aDoc = TDocStd_Document::Get(GetLabel());
263   if ( aDoc.IsNull() )
264     return Standard_False;
265
266   // checking that file is present on disk
267   /* do not check, because could try to save as new document to existent file 
268   if(!access(theFile, 0))
269   {
270     // checking that document has not been changed from last save
271     if(!aDoc->IsChanged())
272       return Standard_True;
273   }
274   */
275   // checking write access permission
276   FILE *aF = fopen (theFile, "w");
277   if (aF == NULL) {
278     Messenger()->Send (Message_Msg("TObj_M_NoWriteAccess") << (Standard_CString)theFile, 
279                               Message_Alarm);
280     return Standard_False;
281   }
282   else
283     fclose (aF);
284
285   // store transaction mode
286   Standard_Boolean aTrMode = aDoc->ModificationMode();
287   aDoc->SetModificationMode( Standard_False );
288   // store all trancienmt fields of object in OCAF document if any
289   Handle(TObj_ObjectIterator) anIterator;
290   for(anIterator = GetObjects(); anIterator->More(); anIterator->Next())
291   {
292     Handle(TObj_Object) anOCAFObj = anIterator->Value();
293     if (anOCAFObj.IsNull())
294       continue;
295     anOCAFObj->BeforeStoring();
296   } // end of for(anIterator = ...)
297   // set transaction mode back
298   aDoc->SetModificationMode( aTrMode );
299
300   // Application
301   const Handle(TObj_Application) anApplication = GetApplication();
302
303   // call Application->SaveAs()
304   Standard_Boolean aStatus = anApplication->SaveDocument (aDoc, theFile);
305
306   TObj_Assistant::ClearTypeMap();
307   return aStatus;
308 }
309
310 //=======================================================================
311 //function : Close
312 //purpose  : Close the model and free related OCAF document
313 //=======================================================================
314
315 Standard_Boolean TObj_Model::Close()
316 {
317   // OCAF document
318   TDF_Label aLabel = GetLabel();
319   if ( aLabel.IsNull() )
320     return Standard_False;
321   Handle(TDocStd_Document) aDoc = TDocStd_Document::Get(aLabel);
322   if ( aDoc.IsNull() )
323     return Standard_False;
324
325   CloseDocument (aDoc);
326
327   myLabel.Nullify();
328   return Standard_True;
329 }
330
331 //=======================================================================
332 //function : GetDocumentModel
333 //purpose  : returns model which contains a document with the label
334 //           returns NULL handle if label is NULL
335 //=======================================================================
336
337 Handle(TObj_Model) TObj_Model::GetDocumentModel
338                          (const TDF_Label& theLabel)
339 {
340   Handle(TObj_Model) aModel;
341   if(theLabel.IsNull())
342     return aModel;
343
344   Handle(TDocStd_Document) aDoc;
345   Handle(TDF_Data) aData = theLabel.Data();
346   TDF_Label aRootL = aData->Root();
347   if ( aRootL.IsNull())
348     return aModel;
349   Handle(TDocStd_Owner) aDocOwnerAtt;
350   if (aRootL.FindAttribute (TDocStd_Owner::GetID(), aDocOwnerAtt))
351     aDoc = aDocOwnerAtt->GetDocument();
352   
353   if ( aDoc.IsNull() )
354     return aModel;
355
356   TDF_Label aLabel = aDoc->Main();
357   Handle(TObj_TModel) anAttr;
358   if(aLabel.FindAttribute(TObj_TModel::GetID(), anAttr))
359     aModel = anAttr->Model();
360
361   return aModel;
362 }
363
364 //=======================================================================
365 //function : GetObjects
366 //purpose  :
367 //=======================================================================
368
369 Handle(TObj_ObjectIterator) TObj_Model::GetObjects() const
370 {
371   Handle(TObj_Model) me = this;
372   return new TObj_ModelIterator(me);
373 }
374
375 //=======================================================================
376 //function : GetChildren
377 //purpose  :
378 //=======================================================================
379
380 Handle(TObj_ObjectIterator) TObj_Model::GetChildren() const
381 {
382   Handle(TObj_Partition) aMainPartition = GetMainPartition();
383   if(aMainPartition.IsNull())
384     return 0;
385   return aMainPartition->GetChildren();
386 }
387
388 //=======================================================================
389 //function : FindObject
390 //purpose  :
391 //=======================================================================
392
393 Handle(TObj_Object) TObj_Model::FindObject
394        (const Handle(TCollection_HExtendedString)& theName,
395         const Handle(TObj_TNameContainer)& theDictionary ) const
396 {
397   Handle(TObj_TNameContainer) aDictionary = theDictionary;
398   if ( aDictionary.IsNull() )
399     aDictionary = GetDictionary();
400   Handle(TObj_Object) aResult;
401   //Check is object with given name is present in model
402   if( IsRegisteredName( theName, aDictionary ) )
403   {
404     TDF_Label aLabel = aDictionary->Get().Find( theName );
405     TObj_Object::GetObj( aLabel, aResult );
406   }
407
408   return aResult;
409 }
410
411 //=======================================================================
412 //function : GetRoot
413 //purpose  :
414 //=======================================================================
415
416 Handle(TObj_Object) TObj_Model::GetRoot() const
417 {
418   return getPartition(GetLabel());
419 }
420
421 //=======================================================================
422 //function : GetMainPartition
423 //purpose  :
424 //=======================================================================
425
426 Handle(TObj_Partition) TObj_Model::GetMainPartition() const
427 {
428   return getPartition( GetLabel() );
429 }
430
431 //=======================================================================
432 //function : SetNewName
433 //purpose  :
434 //=======================================================================
435
436 void TObj_Model::SetNewName(const Handle(TObj_Object)& theObject)
437 {
438   Handle(TObj_Partition) aPartition = TObj_Partition::GetPartition(theObject);
439
440   //sets name if partition is found
441   if(aPartition.IsNull()) return;
442
443   Handle(TCollection_HExtendedString) name = aPartition->GetNewName();
444   if ( ! name.IsNull() ) theObject->SetName(name);
445 }
446
447 //=======================================================================
448 //function : IsRegisteredName
449 //purpose  :
450 //=======================================================================
451
452 Standard_Boolean TObj_Model::IsRegisteredName(const Handle(TCollection_HExtendedString)& theName,
453                                                   const Handle(TObj_TNameContainer)& theDictionary ) const
454 {
455   Handle(TObj_TNameContainer) aDictionary = theDictionary;
456   if ( aDictionary.IsNull() )
457     aDictionary = GetDictionary();
458
459   if ( aDictionary.IsNull() )
460     return Standard_False;
461   return aDictionary->IsRegistered( theName );
462 }
463
464 //=======================================================================
465 //function : RegisterName
466 //purpose  :
467 //=======================================================================
468
469 void TObj_Model::RegisterName(const Handle(TCollection_HExtendedString)& theName,
470                                   const TDF_Label& theLabel,
471                                   const Handle(TObj_TNameContainer)& theDictionary ) const
472 {
473   Handle(TObj_TNameContainer) aDictionary = theDictionary;
474   if ( aDictionary.IsNull() )
475     aDictionary = GetDictionary();
476
477   if ( !aDictionary.IsNull() )
478     aDictionary->RecordName( theName, theLabel );
479 }
480
481 //=======================================================================
482 //function : UnRegisterName
483 //purpose  :
484 //=======================================================================
485
486 void TObj_Model::UnRegisterName(const Handle(TCollection_HExtendedString)& theName,
487                                     const Handle(TObj_TNameContainer)& theDictionary ) const
488 {
489   Handle(TObj_TNameContainer) aDictionary = theDictionary;
490   if ( aDictionary.IsNull() )
491     aDictionary = GetDictionary();
492
493   if ( !aDictionary.IsNull() )
494     aDictionary->RemoveName( theName );
495 }
496
497 //=======================================================================
498 //function : GetDictionary
499 //purpose  :
500 //=======================================================================
501
502 Handle(TObj_TNameContainer) TObj_Model::GetDictionary() const
503 {
504   Handle(TObj_TNameContainer) A;
505   TDF_Label aLabel = GetLabel();
506   if (!aLabel.IsNull())
507     aLabel.FindAttribute(TObj_TNameContainer::GetID(),A);
508   return A;
509 }
510
511 //=======================================================================
512 //function : getPartition
513 //purpose  :
514 //=======================================================================
515
516 Handle(TObj_Partition) TObj_Model::getPartition
517                          (const TDF_Label&       theLabel,
518                           const Standard_Boolean theHidden) const
519 {
520   Handle(TObj_Partition) aPartition;
521   if(theLabel.IsNull()) return aPartition;
522   Handle(TObj_TObject) A;
523
524   if (!theLabel.FindAttribute (TObj_TObject::GetID(), A))
525   {
526     if (theHidden)
527       aPartition = new TObj_HiddenPartition(theLabel);
528     else
529       aPartition = TObj_Partition::Create(theLabel);
530   }
531   else
532     aPartition = Handle(TObj_Partition)::DownCast(A->Get());
533
534   return aPartition;
535 }
536
537 //=======================================================================
538 //function : getPartition
539 //purpose  :
540 //=======================================================================
541
542 Handle(TObj_Partition) TObj_Model::getPartition
543                          (const TDF_Label&                  theLabel,
544                           const Standard_Integer            theIndex,
545                           const TCollection_ExtendedString& theName,
546                           const Standard_Boolean            theHidden) const
547 {
548   Handle(TObj_Partition) aPartition;
549   if(theLabel.IsNull()) return aPartition;
550
551   TDF_Label aLabel = theLabel.FindChild(theIndex,Standard_False);
552   Standard_Boolean isNew = Standard_False;
553   // defining is partition new
554   if ( aLabel.IsNull() )
555   {
556     aLabel = theLabel.FindChild(theIndex,Standard_True);
557     isNew = Standard_True;
558   }
559   // obtaining the partition
560   aPartition = getPartition( aLabel, theHidden );
561
562   //setting name to new partition
563   if(isNew)
564     aPartition->SetName(new TCollection_HExtendedString(theName));
565   return aPartition;
566 }
567
568
569 //=======================================================================
570 //function : getPartition
571 //purpose  :
572 //=======================================================================
573
574 Handle(TObj_Partition) TObj_Model::getPartition
575                          (const Standard_Integer            theIndex,
576                           const TCollection_ExtendedString& theName,
577                           const Standard_Boolean            theHidden) const
578 {
579   return getPartition (GetMainPartition()->GetChildLabel(),
580                        theIndex, theName, theHidden);
581 }
582
583 //=======================================================================
584 //function : initNewModel
585 //purpose  :
586 //=======================================================================
587
588 Standard_Boolean TObj_Model::initNewModel (const Standard_Boolean IsNew)
589 {
590   // set names map
591   TObj_TNameContainer::Set(GetLabel());
592
593   // do something for loaded model.
594   if (!IsNew)
595   {
596     // Register names of model in names map.
597     Handle(TObj_ObjectIterator) anIterator;
598     for(anIterator = GetObjects(); anIterator->More(); anIterator->Next())
599     {
600       Handle(TObj_Object) anOCAFObj = anIterator->Value();
601       if (anOCAFObj.IsNull())
602         continue;
603       anOCAFObj->AfterRetrieval();
604     } // end of for(anIterator = ...)
605     // update back references for loaded model by references
606     updateBackReferences( GetMainPartition() );
607
608     if ( isToCheck() )
609     {
610       // check model consistency
611       Handle(TObj_CheckModel) aCheck = GetChecker();
612       aCheck->Perform();
613       aCheck->SendMessages();
614       // tell that the model has been modified
615       SetModified(Standard_True);
616     }
617   }
618   return Standard_True;
619 }
620
621 //=======================================================================
622 //function : updateBackReferences
623 //purpose  :
624 //=======================================================================
625
626 void TObj_Model::updateBackReferences (const Handle(TObj_Object)& theObject)
627 {
628   // recursive update back references
629   if ( theObject.IsNull() )
630     return;
631   Handle(TObj_ObjectIterator) aChildren = theObject->GetChildren();
632   for(;aChildren->More() && aChildren->More(); aChildren->Next())
633   {
634     Handle(TObj_Object) aChild = aChildren->Value();
635     updateBackReferences( aChild );
636   }
637   // update back references of reference objects
638   Handle(TObj_LabelIterator) anIter =
639     Handle(TObj_LabelIterator)::DownCast(theObject->GetReferences());
640
641   if(anIter.IsNull()) // to avoid exception
642     return;
643
644   // LH3D15722. Remove all back references to make sure there will be no unnecessary
645   // duplicates, since some back references may already exist after model upgrading.
646   // (do not take care that object can be from other document, because 
647   // we do not modify document, all modifications are made in transient fields)
648   for( ; anIter->More() ; anIter->Next())
649   {
650     Handle(TObj_Object) anObject = anIter->Value();
651     if ( !anObject.IsNull() )
652       anObject->RemoveBackReference( theObject, Standard_False );
653   }
654   // and at last create back references
655   anIter = Handle(TObj_LabelIterator)::DownCast(theObject->GetReferences());
656   if(!anIter.IsNull())
657     for( ; anIter->More() ; anIter->Next())
658     {
659       Handle(TObj_Object) anObject = anIter->Value();
660       if ( !anObject.IsNull() )
661         anObject->AddBackReference( theObject );
662     }
663 }
664
665 //=======================================================================
666 //function : GetDocument
667 //purpose  :
668 //=======================================================================
669
670 Handle(TDocStd_Document) TObj_Model::GetDocument() const
671 {
672   Handle(TDocStd_Document) D;
673   TDF_Label aLabel = GetLabel();
674   if (!aLabel.IsNull())
675     D = TDocStd_Document::Get(aLabel);
676   return D;
677 }
678
679 //=======================================================================
680 //function : HasOpenCommand
681 //purpose  :
682 //=======================================================================
683
684 Standard_Boolean TObj_Model::HasOpenCommand() const
685 {
686   return GetDocument()->HasOpenCommand();
687 }
688
689 //=======================================================================
690 //function : OpenCommand
691 //purpose  :
692 //=======================================================================
693
694 void TObj_Model::OpenCommand() const
695 {
696   GetDocument()->OpenCommand();
697 }
698
699 //=======================================================================
700 //function : CommitCommand
701 //purpose  :
702 //=======================================================================
703
704 void TObj_Model::CommitCommand() const
705 {
706   GetDocument()->CommitCommand();
707 }
708
709 //=======================================================================
710 //function : AbortCommand
711 //purpose  :
712 //=======================================================================
713
714 void TObj_Model::AbortCommand() const
715 {
716   GetDocument()->AbortCommand();
717 }
718
719 //=======================================================================
720 //function : IsModified
721 //purpose  : Status of modification
722 //=======================================================================
723
724 Standard_Boolean TObj_Model::IsModified () const
725 {
726   Handle(TDocStd_Document) aDoc = GetDocument();
727   return aDoc.IsNull() ? Standard_False : aDoc->IsChanged();
728 }
729
730 //=======================================================================
731 //function : SetModified
732 //purpose  : Status of modification
733 //=======================================================================
734
735 void TObj_Model::SetModified (const Standard_Boolean theModified)
736 {
737   Handle(TDocStd_Document) aDoc = GetDocument();
738   if (!aDoc.IsNull())
739   {
740     Standard_Integer aSavedTime = aDoc->GetData()->Time();
741     if (theModified)
742       --aSavedTime;
743     aDoc->SetSavedTime (aSavedTime);
744   }
745 }
746
747 //=======================================================================
748 //function : checkDocumentEmpty
749 //purpose  : Check whether the document contains the Ocaf data
750 //=======================================================================
751
752 Standard_Boolean TObj_Model::checkDocumentEmpty (const char* theFile)
753 {
754   if (!theFile)
755     return Standard_True;
756
757   TCollection_AsciiString aFile ((Standard_CString) theFile);
758   if (aFile.IsEmpty())
759     return Standard_True;
760
761   OSD_Path aPath (aFile);
762   OSD_File osdfile (aPath);
763   if ( !osdfile.Exists() )
764     return Standard_True;
765   
766   FILE* f = fopen( theFile, "r" );
767   if ( f )
768   {
769     Standard_Boolean isZeroLengh = Standard_False;
770     fseek( f, 0, SEEK_END );
771     if ( ftell( f ) == 0 )
772       isZeroLengh = Standard_True;
773
774     fclose( f );
775     return isZeroLengh;
776   }
777   return Standard_False;
778 }
779
780 //=======================================================================
781 //function : GetGUID
782 //purpose  :
783 //=======================================================================
784
785 Standard_GUID TObj_Model::GetGUID() const
786 {
787   Standard_GUID aGUID("3bbefb49-e618-11d4-ba38-0060b0ee18ea");
788   return aGUID;
789 }
790
791 //=======================================================================
792 //function : GetFormat
793 //purpose  :
794 //=======================================================================
795
796 TCollection_ExtendedString TObj_Model::GetFormat() const
797 {
798   return TCollection_ExtendedString ("TObjBin");
799 }
800
801 //=======================================================================
802 //function : GetFormatVersion
803 //purpose  :
804 //=======================================================================
805
806 Standard_Integer TObj_Model::GetFormatVersion() const
807 {
808   TDF_Label aLabel = GetDataLabel().FindChild(DataTag_FormatVersion,Standard_False);
809   if(aLabel.IsNull())
810     return -1;
811
812   Handle(TDataStd_Integer) aNum;
813   if(!aLabel.FindAttribute ( TDataStd_Integer::GetID(), aNum ))
814     return -1;
815   else
816     return aNum->Get();
817 }
818
819 //=======================================================================
820 //function : SetFormatVersion
821 //purpose  :
822 //=======================================================================
823
824 void TObj_Model::SetFormatVersion(const Standard_Integer theVersion)
825 {
826   TDF_Label aLabel = GetDataLabel().FindChild(DataTag_FormatVersion,Standard_True);
827   TDataStd_Integer::Set(aLabel,theVersion);
828 }
829
830
831 //=======================================================================
832 //function : GetDataLabel
833 //purpose  :
834 //=======================================================================
835
836 TDF_Label TObj_Model::GetDataLabel() const
837 {
838   return GetMainPartition()->GetDataLabel();
839 }
840
841 //=======================================================================
842 //function : Paste
843 //purpose  :
844 //=======================================================================
845
846 Standard_Boolean TObj_Model::Paste (Handle(TObj_Model)      theModel,
847                                         Handle(TDF_RelocationTable) theRelocTable)
848 {
849   if(theModel.IsNull()) return Standard_False;
850   // clearing dictionary of objects names
851 //  theModel->GetDictionary()->NewEmpty()->Paste(theModel->GetDictionary(),
852 //                                               new TDF_RelocationTable);
853 //  theModel->GetLabel().ForgetAllAttributes(Standard_True);
854   TObj_TNameContainer::Set(theModel->GetLabel());
855   GetMainPartition()->Clone(theModel->GetLabel(), theRelocTable);
856   return Standard_True;
857 }
858
859 //=======================================================================
860 //function : CopyReferences
861 //purpose  :
862 //=======================================================================
863
864 void TObj_Model::CopyReferences(const Handle(TObj_Model)& theTarget,
865                                     const Handle(TDF_RelocationTable)& theRelocTable)
866 {
867   Handle(TObj_Object) aMyRoot = GetMainPartition();
868   Handle(TObj_Object) aTargetRoot = theTarget->GetMainPartition();
869   aMyRoot->CopyReferences(aTargetRoot, theRelocTable);
870 }
871
872 //=======================================================================
873 //function : GetModelName
874 //purpose  : Returns the name of the model
875 //           by default returns TObj
876 //=======================================================================
877
878 Handle(TCollection_HExtendedString) TObj_Model::GetModelName() const
879 {
880   Handle(TCollection_HExtendedString) aName =
881     new TCollection_HExtendedString("TObj");
882   return aName;
883 }
884
885 //=======================================================================
886 //function : Update
887 //purpose  : default implementation is empty
888 //=======================================================================
889
890 Standard_Boolean TObj_Model::Update ()
891 {
892   return Standard_True;
893 }
894
895 //=======================================================================
896 //function : GetChecker
897 //purpose  :
898 //=======================================================================
899
900 Handle(TObj_CheckModel) TObj_Model::GetChecker() const
901 {
902   return new TObj_CheckModel (this);
903 }