0029915: Porting to VC 2017 : Regressions in Modeling Algorithms on VC 2017
[occt.git] / src / Interface / Interface_ShareTool.cxx
1 // Copyright (c) 1999-2014 OPEN CASCADE SAS
2 //
3 // This file is part of Open CASCADE Technology software library.
4 //
5 // This library is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU Lesser General Public License version 2.1 as published
7 // by the Free Software Foundation, with special exception defined in the file
8 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9 // distribution for complete text of the license and disclaimer of any warranty.
10 //
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
13
14
15 #include <Interface_EntityIterator.hxx>
16 #include <Interface_GeneralLib.hxx>
17 #include <Interface_GeneralModule.hxx>
18 #include <Interface_Graph.hxx>
19 #include <Interface_GTool.hxx>
20 #include <Interface_HGraph.hxx>
21 #include <Interface_InterfaceError.hxx>
22 #include <Interface_InterfaceModel.hxx>
23 #include <Interface_IntList.hxx>
24 #include <Interface_Protocol.hxx>
25 #include <Interface_ShareTool.hxx>
26 #include <Message_Messenger.hxx>
27 #include <Standard_DomainError.hxx>
28 #include <Standard_Transient.hxx>
29 #include <TColStd_HArray1OfInteger.hxx>
30 #include <TColStd_HSequenceOfTransient.hxx>
31
32 Interface_ShareTool::Interface_ShareTool (const Handle(Interface_InterfaceModel)& amodel,
33                                           const Interface_GeneralLib& lib)
34 {
35   theHGraph = new Interface_HGraph(amodel,lib);
36 }
37
38 Interface_ShareTool::Interface_ShareTool (const Handle(Interface_InterfaceModel)& amodel,
39                                           const Handle(Interface_GTool)& gtool)
40 {
41   theHGraph = new Interface_HGraph(amodel,gtool);
42 }
43
44 Interface_ShareTool::Interface_ShareTool (const Handle(Interface_InterfaceModel)& amodel,
45                                           const Handle(Interface_Protocol)& protocol)
46 {
47   theHGraph = new Interface_HGraph(amodel,protocol);
48 }
49
50 Interface_ShareTool::Interface_ShareTool (const Handle(Interface_InterfaceModel)& amodel)
51 {
52   theHGraph = new Interface_HGraph(amodel);
53 }
54
55 Interface_ShareTool::Interface_ShareTool (const Interface_Graph& agraph)
56 {
57   theHGraph = new Interface_HGraph(agraph.Model());
58 }
59
60 Interface_ShareTool::Interface_ShareTool (const Handle(Interface_HGraph)& ahgraph)
61 {
62   theHGraph = ahgraph;
63 }
64
65 //    Ajout des "Implied" sur toutes les Entites du Graphe
66 /*void Interface_ShareTool::AddImplied (const Handle(Interface_GTool)& gtool)
67 {
68   Interface_Graph& thegraph = theHGraph->CGraph();
69   Standard_Integer nb = thegraph.Size();
70   Standard_Boolean yena = Standard_False;
71   for (Standard_Integer i = 1; i <= nb; i ++) {
72     Handle(Standard_Transient) ent = thegraph.Entity(i);
73     if (ent.IsNull()) continue;
74     Handle(Interface_GeneralModule) module;  Standard_Integer CN;
75     if (gtool->Select(ent,module,CN)) {
76       Interface_EntityIterator iter;
77       module->ListImpliedCase(CN,ent,iter);
78       if (iter.NbEntities() == 0) continue;
79       yena = Standard_True;
80       thegraph.SetShare(ent);
81       for (iter.Start(); iter.More(); iter.Next())
82         thegraph.AddShared(ent,iter.Value());
83     }
84   }
85   if (yena) thegraph.EvalSharings();
86 }*/
87
88
89     Handle(Interface_InterfaceModel) Interface_ShareTool::Model () const
90       {  return theHGraph->Graph().Model();  }
91
92     const Interface_Graph& Interface_ShareTool::Graph () const
93       {  return theHGraph->Graph();  }
94
95     Interface_EntityIterator  Interface_ShareTool::RootEntities () const
96       {  return theHGraph->Graph().RootEntities();  }
97
98     Standard_Boolean  Interface_ShareTool::IsShared
99   (const Handle(Standard_Transient)& ent) const
100 {
101   const Interface_Graph& thegraph = theHGraph->Graph();
102   Handle(TColStd_HSequenceOfTransient) list =
103     thegraph.GetShareds (ent);
104   return (!list.IsNull() && list->Length() > 0);
105 }
106
107     Interface_EntityIterator  Interface_ShareTool::Shareds
108   (const Handle(Standard_Transient)& ent) const
109       {  return theHGraph->Graph().Shareds(ent);  }
110
111     Interface_EntityIterator  Interface_ShareTool::Sharings
112   (const Handle(Standard_Transient)& ent) const
113       {  return theHGraph->Graph().Sharings(ent);  }
114
115
116     Standard_Integer Interface_ShareTool::NbTypedSharings
117   (const Handle(Standard_Transient)& ent,
118    const Handle(Standard_Type)& atype) const
119 {
120   Interface_Graph& thegraph = theHGraph->CGraph();
121   Handle(TColStd_HSequenceOfTransient) list = thegraph.GetSharings (ent);
122   if(list.IsNull())
123     return 0;
124
125   Standard_Integer result = 0;
126   Standard_Integer n = list->Length();
127   for (Standard_Integer i = 1; i <= n; i ++) {
128     Handle(Standard_Transient) entsh = list->Value(i);
129     if (entsh.IsNull()) continue;
130     if (entsh->IsKind(atype)) result ++;
131   }
132   return result;
133 }
134
135     Handle(Standard_Transient) Interface_ShareTool::TypedSharing
136   (const Handle(Standard_Transient)& ent,
137    const Handle(Standard_Type)& atype) const
138 {
139   Interface_Graph& thegraph = theHGraph->CGraph();
140   Handle(TColStd_HSequenceOfTransient) list = thegraph.GetSharings(ent);
141   if(list.IsNull())
142     return 0;
143   Handle(Standard_Transient) entresult;
144   Standard_Integer result = 0;
145   Standard_Integer n = list->Length();
146   for (Standard_Integer i = 1; i <= n; i ++) {
147     Handle(Standard_Transient) entsh = list->Value(i);
148     if (entsh.IsNull()) continue;
149     if (entsh->IsKind(atype)) {
150       entresult = entsh;
151       result ++;
152       if (result > 1)  throw Interface_InterfaceError("Interface ShareTool : TypedSharing, more than one found");
153     }
154   }
155   if (result == 0) throw Interface_InterfaceError("Interface ShareTool : TypedSharing, not found");
156   return entresult;
157 }
158
159     Interface_EntityIterator  Interface_ShareTool::All
160 (const Handle(Standard_Transient)& ent, const Standard_Boolean rootlast) const
161 {
162   Handle(Interface_InterfaceModel) model = Model();
163   Interface_EntityIterator list;
164   Standard_Integer i, n0 = 0, nb = model->NbEntities();
165   Handle(TColStd_HArray1OfInteger) fl = new TColStd_HArray1OfInteger (0,nb);
166   fl->Init(0);
167   if (ent == model) {
168 //    On passe les racines en revue (l ordre de base est conserve)
169     Interface_EntityIterator roots = RootEntities();
170     for (roots.Start(); roots.More(); roots.Next()) {
171       Interface_EntityIterator subl = All(roots.Value(),rootlast);
172       for (subl.Start(); subl.More(); subl.Next()) {
173         Standard_Integer nm = model->Number(subl.Value());
174         if (fl->Value(nm) > 0) continue;
175         n0 ++;  fl->SetValue(nm,n0);
176       }
177     }
178 //    Attention, y a t il des oublis ?      
179     for (i = 1; i <= nb; i ++)
180       if (fl->Value(i) == 0)  {  n0 ++;  fl->SetValue(i,n0);  }
181   } else {
182     Handle(TColStd_HSequenceOfTransient) sq = new TColStd_HSequenceOfTransient();
183     sq->Append(ent);
184 //    processus de type file
185     for (i = 1; i <= sq->Length(); i ++) {    // Length croit
186       Handle(Standard_Transient) en = sq->Value(i);
187       Standard_Integer num = model->Number(en);
188       if (fl->Value(num) != 0) continue;  // deja vu
189       n0 ++;  fl->SetValue (num,n0);
190       Interface_EntityIterator sh = Shareds(en);
191       sq->Append (sh.Content());
192     }
193   }
194 //    Reste a constituer la liste, retourner si necessaire
195   Handle(TColStd_HArray1OfInteger) ord = new TColStd_HArray1OfInteger (0,nb);
196   ord->Init(0);
197   for (i = 1; i <= nb; i ++)  {  n0 = fl->Value(i);  ord->SetValue (n0,i);  }
198   if (rootlast && ent != model)    for (i = 1; i <= nb; i ++)
199       {  if (ord->Value(i) != 0) list.AddItem (model->Value(ord->Value(i)));  }
200   else                             for (i = nb; i  > 0; i --)
201       {  if (ord->Value(i) != 0) list.AddItem (model->Value(ord->Value(i)));  }
202
203   return list;
204 }
205
206     void  Interface_ShareTool::Print
207   (const Interface_EntityIterator& iter, const Handle(Message_Messenger)& S) const
208 {
209   S << " Nb.Entities : " << iter.NbEntities() << " : ";
210   for (iter.Start(); iter.More(); iter.Next()) {
211     Handle(Standard_Transient) ent = iter.Value();
212     S << " n0/id:"; Model()->Print(ent,S);
213   }
214   S<<endl;
215 }