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