0026377: Passing Handle objects as arguments to functions as non-const reference...
[occt.git] / src / TNaming / TNaming_NamingTool.cxx
1 // Created on: 2000-02-14
2 // Created by: Denis PASCAL
3 // Copyright (c) 2000-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
17 #include <TDF_ChildIterator.hxx>
18 #include <TDF_Label.hxx>
19 #include <TNaming_Iterator.hxx>
20 #include <TNaming_NamedShape.hxx>
21 #include <TNaming_Naming.hxx>
22 #include <TNaming_NamingTool.hxx>
23 #include <TNaming_NewShapeIterator.hxx>
24 #include <TNaming_OldShapeIterator.hxx>
25 #include <TNaming_Tool.hxx>
26 #include <TopoDS_Shape.hxx>
27
28 #ifdef OCCT_DEBUG_DESC
29 #include <TCollection_AsciiString.hxx>
30 #include <TDF_Tool.hxx>
31 #include <BRepTools.hxx>
32 static void WriteS(const TopoDS_Shape& shape,
33                       const Standard_CString filename) 
34 {
35   char buf[256];
36   if(strlen(filename) > 255) return;
37 #ifdef _MSC_VER
38   strcpy_s (buf, filename);
39 #else
40   strcpy (buf, filename);
41 #endif
42   char* p = buf;
43   while (*p) {
44     if(*p == ':')
45       *p = '-';
46     p++;
47   }
48   ofstream save (buf);
49   if(!save) 
50     cout << "File " << buf << " was not created: rdstate = " << save.rdstate() << endl;
51   save << "DBRep_DrawableShape" << endl << endl;
52   if(!shape.IsNull()) BRepTools::Write(shape, save);
53   save.close();
54 }
55 #endif
56
57 //=======================================================================
58 //function : IsForbiden
59 //purpose  : ANaming voir NamingTool
60 //=======================================================================
61
62 static Standard_Boolean IsForbiden(const TDF_LabelMap& Forbiden,
63                                    const TDF_Label&    Lab)
64 {
65   if (Lab.IsRoot()) {
66     return Standard_False;
67   }
68   if (Forbiden.Contains(Lab)) 
69     return Standard_True;
70   else {
71     return IsForbiden(Forbiden,Lab.Father());
72   }
73 }
74
75 //=======================================================================
76 //function : LastModif 
77 //purpose  : ANaming 
78 //=======================================================================
79 static void LastModif(      TNaming_NewShapeIterator& it,
80                       const TopoDS_Shape&             S,
81                       TopTools_IndexedMapOfShape&     MS,
82                       const TDF_LabelMap&             Updated,
83                       const TDF_LabelMap&             Forbiden)
84
85   Standard_Boolean YaModif = Standard_False;
86   for (; it.More(); it.Next()) {
87     const TDF_Label&    Lab = it.Label();
88 #ifdef OCCT_DEBUG_DESC
89     TCollection_AsciiString entry;
90     TDF_Tool::Entry(Lab, entry);
91     cout << "NamingTool:: LastModif LabelEntry = "<< entry <<  endl;
92 #endif
93     if (!Updated.IsEmpty() && !Updated.Contains(Lab))  continue;
94     if (IsForbiden(Forbiden, Lab))                     continue; 
95     if (it.IsModification()) {
96       YaModif = Standard_True;
97       TNaming_NewShapeIterator it2(it);
98       if (!it2.More()) {
99         const TopoDS_Shape& aS   = it.Shape();
100         MS.Add (aS);  // Modified
101       }
102       else
103         LastModif(it2,it.Shape(),MS,Updated,Forbiden);
104     } 
105   }
106   if (!YaModif) 
107     MS.Add(S);    
108 }
109 //=======================================================================
110 static void ApplyOrientation (TopTools_IndexedMapOfShape& MS, 
111                               const TopAbs_Orientation OrientationToApply)
112 {
113 #ifdef OCCT_DEBUG_APPLY
114  if (!MS.IsEmpty ()) {
115    cout <<"OrientationToApply = " <<OrientationToApply <<endl;
116    for (Standard_Integer anItMS1 = 1; anItMS1 <= MS.Extent(); ++anItMS1) {
117      cout << "ApplyOrientation: TShape = " << MS (anItMS1).TShape()->This() << " OR = " << MS (anItMS1).Orientation() <<endl;
118    }
119  }
120 #endif
121   for (Standard_Integer anItMS = 1; anItMS <= MS.Extent(); ++anItMS)
122   {
123     MS.Substitute (anItMS, MS (anItMS).Oriented (OrientationToApply));
124   }
125 }
126 //=======================================================================
127 //function : CurrentShape
128 //purpose  : ANaming
129 //=======================================================================
130 void TNaming_NamingTool::CurrentShape(const TDF_LabelMap&               Valid,
131                                       const TDF_LabelMap&               Forbiden,
132                                       const Handle(TNaming_NamedShape)& Att,
133                                       TopTools_IndexedMapOfShape& MS)
134 {
135   TDF_Label Lab = Att->Label();
136 #ifdef OCCT_DEBUG_DESC
137     TCollection_AsciiString entry;
138     TDF_Tool::Entry(Lab, entry);
139     cout << "NamingTool:: LabelEntry = "<< entry <<  endl;
140 #endif
141   if (!Valid.IsEmpty() && !Valid.Contains(Lab)) {
142 #ifdef OCCT_DEBUG_DESC
143     TCollection_AsciiString entry;
144     TDF_Tool::Entry(Lab, entry);
145     cout << "NamingTool:: LabelEntry = "<< entry << " is out of Valid map" <<  endl;
146 #endif
147     return;
148   }
149
150   TNaming_Iterator itL (Att);
151   for (; itL.More(); itL.Next()) {
152     const TopoDS_Shape& S = itL.NewShape();
153     if (S.IsNull()) continue;
154 #ifdef OCCT_DEBUG_DESC
155     WriteS(S, "CS_NewShape.brep");
156     if(itL.OldShape().IsNull())
157       cout <<"OldShape is Null" <<endl;
158     else 
159         WriteS(itL.OldShape(), "CS_OldShape.brep");
160 #endif
161     Standard_Boolean YaOrientationToApply(Standard_False);
162     TopAbs_Orientation OrientationToApply(TopAbs_FORWARD);
163     if(Att->Evolution() == TNaming_SELECTED) {
164       if (itL.More() && itL.NewShape().ShapeType() != TopAbs_VERTEX) {//OR-N
165                 Handle (TNaming_Naming)  aNaming;
166                 Lab.FindAttribute(TNaming_Naming::GetID(), aNaming);
167                 if(!aNaming.IsNull()) {
168                   if(aNaming->GetName().Type() == TNaming_ORIENTATION) {
169                          OrientationToApply = aNaming->GetName().Orientation();
170                   } else {
171                 Handle (TNaming_Naming)  aNaming2;
172                         TDF_ChildIterator it(aNaming->Label());
173                         for(;it.More();it.Next()) {
174                           const TDF_Label& aLabel = it.Value();
175                           aLabel.FindAttribute(TNaming_Naming::GetID(), aNaming2);
176                   if(!aNaming2.IsNull()) {
177                             if(aNaming2->GetName().Type() == TNaming_ORIENTATION) {
178                                   OrientationToApply = aNaming2->GetName().Orientation();
179                                   break;
180                                 }
181                           }
182                         }
183                   }
184                   if(OrientationToApply == TopAbs_FORWARD || OrientationToApply == TopAbs_REVERSED)
185                         YaOrientationToApply = Standard_True;                   
186                 }
187           } //
188     }
189     TNaming_NewShapeIterator it(itL);
190     if (!it.More()) {
191       if (YaOrientationToApply)
192         MS.Add(S.Oriented(OrientationToApply));
193       else
194         MS.Add(S);
195     }
196     else {      
197 //     LastModif(it, S, MS, Valid, Forbiden);
198       TopTools_IndexedMapOfShape MS2; 
199       LastModif(it, S, MS2, Valid, Forbiden);
200       if (YaOrientationToApply) ApplyOrientation (MS2, OrientationToApply);//the solution to be refined
201       for (Standard_Integer anItMS2 = 1; anItMS2 <= MS2.Extent(); ++anItMS2)
202         MS.Add (MS2 (anItMS2));
203     }
204   }
205 }
206
207 //=======================================================================
208 //function : CurrentShapeFromShape
209 //purpose  : ANaming
210 //=======================================================================
211              
212 void TNaming_NamingTool::CurrentShapeFromShape(const TDF_LabelMap&               Valid,
213                                                const TDF_LabelMap&               Forbiden,
214                                                const TDF_Label&                  Acces,
215                                                const TopoDS_Shape&               S,
216                                                TopTools_IndexedMapOfShape&       MS)
217 {
218   TNaming_NewShapeIterator it(S,Acces);
219
220   Handle(TNaming_NamedShape) NS = it.NamedShape(); 
221   if(!NS.IsNull() && NS->Evolution() == TNaming_SELECTED)
222     MS.Add(TNaming_Tool::GetShape(NS));
223   else {
224     if (!it.More()) 
225       MS.Add(S);
226     else 
227       LastModif(it, S, MS, Valid, Forbiden);
228   }
229 }
230
231 //=======================================================================
232 //function : MakeDescendants
233 //purpose  : ANaming
234 //=======================================================================
235
236 static void MakeDescendants (TNaming_NewShapeIterator&         it,
237                              TDF_LabelMap&                     Descendants)
238 {
239   for (; it.More(); it.Next()) {
240     Descendants.Add(it.Label());
241 #ifdef OCCT_DEBUG_DESC
242     TCollection_AsciiString entry;
243     TDF_Tool::Entry(it.Label(), entry);
244     cout<< "MakeDescendants: Label = " <<entry <<endl;
245 #endif
246     if (!it.Shape().IsNull()) {
247       TNaming_NewShapeIterator it2(it);
248       MakeDescendants (it2,Descendants);
249     }
250   }
251 }
252 //=======================================================================
253 void BuildDescendants2 (const Handle(TNaming_NamedShape)& NS, const TDF_Label& ForbLab, TDF_LabelMap& Descendants)
254 {
255   if (NS.IsNull()) return;
256   TNaming_NewShapeIterator it(NS); 
257   for(;it.More();it.Next()) {
258     if(!it.NamedShape().IsNull()) {
259 #ifdef OCCT_DEBUG_DESC
260       TCollection_AsciiString entry;
261       TDF_Tool::Entry(it.Label(), entry);
262       cout<< "MakeDescendants2: Label = " <<entry <<endl;
263 #endif      
264       if(ForbLab == it.Label()) continue;
265       Descendants.Add(it.Label());
266       TNaming_NewShapeIterator it2(it); 
267       MakeDescendants (it2,Descendants); 
268     }
269   }
270 }
271 //=======================================================================
272 //function : BuildDescendants
273 //purpose  : ANaming
274 //=======================================================================
275
276 void TNaming_NamingTool::BuildDescendants (const Handle(TNaming_NamedShape)& NS,
277                                            TDF_LabelMap&                     Descendants)
278 {
279   if (NS.IsNull()) return;
280   Descendants.Add(NS->Label());
281   TNaming_NewShapeIterator it(NS); 
282 #ifdef OCCT_DEBUG_DESC
283     TCollection_AsciiString entry;
284     TDF_Tool::Entry(NS->Label(), entry);
285     cout<< "MakeDescendants: Label = " <<entry <<endl;
286 #endif
287   MakeDescendants (it,Descendants);
288   TNaming_OldShapeIterator it2(NS); 
289   for (; it2.More(); it2.Next()) {
290     if(!it2.Shape().IsNull()) {
291       Handle(TNaming_NamedShape) ONS = TNaming_Tool::NamedShape(it2.Shape(), NS->Label());
292       if(!ONS.IsNull()) {
293 #ifdef OCCT_DEBUG_DESC
294         TCollection_AsciiString entry;
295         TDF_Tool::Entry(ONS->Label(), entry);
296         cout<< "MakeDescendants_Old: Label = " <<entry <<endl;    
297 #endif
298         BuildDescendants2(ONS, NS->Label(), Descendants);
299       }
300     }  
301   }
302 }