0029915: Porting to VC 2017 : Regressions in Modeling Algorithms on VC 2017
[occt.git] / src / TObj / TObj_CheckModel.cxx
1 // Created on: 2007-04-17
2 // Created by: Michael Sazonov
3 // Copyright (c) 2007-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_CheckModel.hxx>
19
20 #include <TObj_ObjectIterator.hxx>
21 #include <Message_Msg.hxx>
22 #include <Message_Status.hxx>
23 #include <Message_Messenger.hxx>
24
25
26 IMPLEMENT_STANDARD_RTTIEXT(TObj_CheckModel,Message_Algorithm)
27
28 //=======================================================================
29 //function : Perform
30 //purpose  : 
31 //=======================================================================
32
33 Standard_Boolean TObj_CheckModel::Perform()
34 {
35   ClearStatus();
36   if (myModel.IsNull() || myModel->GetLabel().IsNull())
37   {
38     SetStatus (Message_Fail1);
39     return Standard_False;
40   }
41   return checkReferences();
42 }
43
44 //=======================================================================
45 //function : checkReferences
46 //purpose  : 
47 //=======================================================================
48
49 Standard_Boolean TObj_CheckModel::checkReferences()
50 {
51   // iterate by all objects in the model
52   Handle(TObj_ObjectIterator) anIt;
53   for(anIt = myModel->GetObjects(); anIt->More(); anIt->Next()) 
54   {
55     Handle(TObj_Object) anObj = anIt->Value();
56     if (anObj.IsNull()) 
57     {
58       SetStatus (Message_Alarm1, anIt->DynamicType()->Name());
59       continue;
60     }
61     
62     // Check references    
63     Handle(TObj_ObjectIterator) aRefIter;
64     for ( aRefIter = anObj->GetReferences(); aRefIter->More(); aRefIter->Next()) 
65     {
66       Handle(TObj_Object) aReferred = aRefIter->Value();
67       if (aReferred.IsNull() || ! aReferred->IsAlive())
68       {
69         SetStatus (Message_Alarm2, anObj->GetName());
70         continue;
71       }
72
73       // check availability of corresponding back reference
74       Handle(TObj_ObjectIterator) aBackIter = aReferred->GetBackReferences();
75       if ( aBackIter.IsNull() )
76         continue; // object does not support back references
77
78       for ( ; aBackIter->More(); aBackIter->Next() ) 
79         if ( aBackIter->Value() == anObj ) break;
80       if ( aBackIter->More() ) 
81         continue; // ok, back reference found
82
83       if ( IsToFix() ) 
84       {
85         SetStatus (Message_Warn1, anObj->GetName());
86         aReferred->AddBackReference (anObj);
87       }
88       else
89         SetStatus (Message_Alarm4, anObj->GetName());
90     }
91       
92     // Checking back references 
93     aRefIter = anObj->GetBackReferences();
94     if ( aRefIter.IsNull() )
95       continue; // object does not support back references
96     TObj_SequenceOfObject aBadBackRefs;
97     for ( ; aRefIter->More(); aRefIter->Next()) 
98     {
99       Handle(TObj_Object) aReferring = aRefIter->Value();
100       if (aReferring.IsNull() || ! aReferring->IsAlive())
101       {
102         SetStatus (Message_Alarm3, anObj->GetName());
103         continue;
104       }
105
106       Handle(TObj_ObjectIterator) aForwIter = aReferring->GetReferences();
107       for ( ; aForwIter->More(); aForwIter->Next()) 
108         if ( aForwIter->Value() == anObj ) break;
109       if ( aForwIter->More() ) 
110         continue; // ok, reference found
111
112       if ( IsToFix() ) 
113       {
114         SetStatus (Message_Warn2, anObj->GetName());
115         aBadBackRefs.Append (aReferring);
116       }
117       else
118         SetStatus (Message_Alarm5, anObj->GetName());
119     }
120
121     // remove back references to objects that are not referenced actually
122     for ( int i=1; i <= aBadBackRefs.Length(); i++ )
123       anObj->RemoveBackReference (aBadBackRefs(i));
124   }
125
126   return ! GetStatus().IsAlarm() && ! GetStatus().IsFail();
127 }