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