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