0022048: Visualization, AIS_InteractiveContext - single object selection should alway...
[occt.git] / src / TObj / TObj_CheckModel.cxx
CommitLineData
b311480e 1// Created on: 2007-04-17
2// Created by: Michael Sazonov
973c2be1 3// Copyright (c) 2007-2014 OPEN CASCADE SAS
b311480e 4//
973c2be1 5// This file is part of Open CASCADE Technology software library.
b311480e 6//
d5f74e42 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
973c2be1 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.
b311480e 12//
973c2be1 13// Alternatively, this file may be used under the terms of Open CASCADE
14// commercial license or contractual agreement.
b311480e 15
7fd59977 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
7fd59977 25
92efcf78 26IMPLEMENT_STANDARD_RTTIEXT(TObj_CheckModel,Message_Algorithm)
27
7fd59977 28//=======================================================================
29//function : Perform
30//purpose :
31//=======================================================================
32
33Standard_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
49Standard_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}