0026586: Eliminate compile warnings obtained by building occt with vc14: declaration...
[occt.git] / src / TNaming / TNaming_Selector.cxx
1 // Created on: 1999-09-30
2 // Created by: Denis PASCAL
3 // Copyright (c) 1999-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17
18 #include <TDF_ChildIterator.hxx>
19 #include <TDF_IDFilter.hxx>
20 #include <TDF_Label.hxx>
21 #include <TDF_Tool.hxx>
22 #include <TNaming.hxx>
23 #include <TNaming_Builder.hxx>
24 #include <TNaming_Identifier.hxx>
25 #include <TNaming_NamedShape.hxx>
26 #include <TNaming_NameType.hxx>
27 #include <TNaming_Naming.hxx>
28 #include <TNaming_NamingTool.hxx>
29 #include <TNaming_NewShapeIterator.hxx>
30 #include <TNaming_Selector.hxx>
31 #include <TopoDS_Iterator.hxx>
32 #include <TopoDS_Shape.hxx>
33 #include <TopTools_IndexedMapOfShape.hxx>
34 #include <TopTools_ListIteratorOfListOfShape.hxx>
35
36 //#define MDTV_DEB_SEL
37 #ifdef OCCT_DEBUG_SEL
38 //#define MDTV_DEB_BNP
39 #include <TopExp_Explorer.hxx>
40 #include <TCollection_AsciiString.hxx>
41 #include <TNaming_Tool.hxx>
42 #include <BRep_Tool.hxx>
43 #include <TopoDS.hxx>
44 #include <TNaming_UsedShapes.hxx>
45 void PrintEntry(const TDF_Label&       label, const Standard_Boolean allLevels)
46 {
47   TCollection_AsciiString entry;
48   TDF_Tool::Entry(label, entry);
49   cout << "LabelEntry = "<< entry << endl;
50   if(allLevels) {
51     TDF_ChildIterator it (label, allLevels);
52     for (; it.More(); it.Next()) {
53       TDF_Tool::Entry(it.Value(), entry);
54         cout << "ChildLabelEntry = "<< entry << endl;
55       }
56   }
57 }
58 #include <BRepTools.hxx>
59 static void Write(const TopoDS_Shape& shape,
60                       const Standard_CString filename) 
61 {
62   char buf[256];
63   if(strlen(filename) > 255) return;
64 #if defined WNT
65   strcpy_s (buf, filename);
66 #else
67   strcpy (buf, filename);
68 #endif
69   char* p = buf;
70   while (*p) {
71     if(*p == ':')
72       *p = '-';
73     p++;
74   }
75   ofstream save (buf);
76   if(!save) 
77     cout << "File " << buf << " was not created: rdstate = " << save.rdstate() << endl;
78   save << "DBRep_DrawableShape" << endl << endl;
79   if(!shape.IsNull()) BRepTools::Write(shape, save);
80   save.close();
81 }
82 #endif
83
84 #define ORIENTATION_DSOPT
85 #ifdef ORIENTATION_DSOPT
86 #include <TopTools_MapOfOrientedShape.hxx>
87 #include <TopTools_MapIteratorOfMapOfOrientedShape.hxx>
88 #include <TDF_ChildIDIterator.hxx>
89 #include <TNaming_Tool.hxx>
90 #include <TNaming_Iterator.hxx>
91 #include <TNaming_OldShapeIterator.hxx>
92 #include <TNaming_NamedShape.hxx>
93 //==========================================================================================
94 inline static void MapOfOrientedShapes(const TopoDS_Shape& S, TopTools_MapOfOrientedShape& M) 
95 {
96   M.Add(S);
97   TopoDS_Iterator It(S,Standard_True,Standard_True);
98   while (It.More()) {
99     MapOfOrientedShapes(It.Value(),M);
100     It.Next();
101   }
102 }
103 //=======================================================================
104 static void BuildAtomicMap(const TopoDS_Shape& S, TopTools_MapOfOrientedShape& M)
105 {
106   if(S.ShapeType() > TopAbs_COMPSOLID) return;
107   TopoDS_Iterator it(S);
108   for(;it.More();it.Next()) {
109     if(it.Value().ShapeType() > TopAbs_COMPSOLID) 
110       M.Add(it.Value());
111     else 
112       BuildAtomicMap(it.Value(), M);   
113   }
114 }
115
116 //==========================================================================================
117 static const Handle(TNaming_NamedShape) FindPrevNDS(const Handle(TNaming_NamedShape)& CNS)
118 {
119   Handle(TNaming_NamedShape) aNS;
120   TNaming_Iterator it(CNS);
121   if(it.More()) {
122     if(!it.OldShape().IsNull()) {
123       aNS = TNaming_Tool::NamedShape(it.OldShape(), CNS->Label());
124       return aNS;
125     }
126   }
127   return aNS;
128 }
129
130 //==========================================================================================
131 // Purpose: checks correspondens between orientation of sub-shapes of Context and orientation
132 //          of sub-shapes registered in DF and put under result label
133 //==========================================================================================
134 static Standard_Boolean IsSpecificCase(const  TDF_Label& F, const TopoDS_Shape& Context)
135 {
136   Standard_Boolean isFound(Standard_False);
137   TopTools_MapOfOrientedShape shapesOfContext;
138   MapOfOrientedShapes(Context,shapesOfContext);
139   Handle(TNaming_NamedShape) CNS = TNaming_Tool::NamedShape(Context, F);
140 #ifdef OCCT_DEBUG_BNP
141   PrintEntry (CNS->Label(),0);
142 #endif
143   if(!CNS.IsNull()) {
144     TNaming_ListOfNamedShape aLNS;
145     TDF_ChildIDIterator cit(CNS->Label(), TNaming_NamedShape::GetID(), Standard_False);
146     if(!cit.More()) {
147       // Naming data structure is empty - no sub-shapes under resulting shape
148       const Handle(TNaming_NamedShape) aNS = FindPrevNDS(CNS); //look to old shape data structure if exist
149       if(!aNS.IsNull()) {
150 #ifdef OCCT_DEBUG_BNP
151         PrintEntry (aNS->Label(),0);
152 #endif
153         cit.Initialize(aNS->Label(), TNaming_NamedShape::GetID(), Standard_False);
154       } else
155         return Standard_True;
156     }
157
158     for(;cit.More();cit.Next()) {
159       Handle(TNaming_NamedShape) NS (Handle(TNaming_NamedShape)::DownCast(cit.Value())); 
160       if(!NS.IsNull()) {  
161         TopoDS_Shape aS = TNaming_Tool::CurrentShape(NS);
162         if(aS.IsNull()) continue;
163 #ifdef OCCT_DEBUG_BNP
164         PrintEntry(NS->Label(), 0);
165         cout <<"ShapeType =" << aS.ShapeType() <<endl;
166         Write (aS, "BNProblem.brep");
167 #endif  
168         if(aS.ShapeType() != TopAbs_COMPOUND) {//single shape at the child label
169           if(!shapesOfContext.Contains(aS)) {
170             isFound = Standard_True;
171             break;
172           }
173         }
174         else {
175           TopTools_MapOfOrientedShape M;
176           BuildAtomicMap(aS, M); 
177           TopTools_MapIteratorOfMapOfOrientedShape it(M);
178           for(;it.More();it.Next()) {         
179             if(!shapesOfContext.Contains(it.Key())) {
180 #ifdef OCCT_DEBUG_BNP
181               cout <<"BNProblem: ShapeType in AtomicMap = " << it.Key().ShapeType() << " TShape = " <<it.Key().TShape() <<" OR = " <<it.Key().Orientation()  <<endl;
182               Write (it.Key(), "BNProblem_AtomicMap_Item.brep");              
183               TopTools_MapIteratorOfMapOfOrientedShape itC(shapesOfContext);
184               for(;itC.More(); itC.Next())
185                 cout <<" ShapeType = " << itC.Key().ShapeType() << " TShape = " << itC.Key().TShape() << " OR = " << itC.Key().Orientation() << endl;
186               
187 #endif  
188               isFound = Standard_True;
189               break;
190             }
191             if(isFound) break;
192           }
193         }
194       }
195     }
196   }
197   return isFound;
198 }
199
200 //==========================================================================================
201 static Standard_Boolean IsSpecificCase2(const  TDF_Label& F, const TopoDS_Shape& Selection)
202 {
203   Standard_Boolean isTheCase(Standard_False);
204   if(Selection.ShapeType() == TopAbs_EDGE) {
205     Handle(TNaming_NamedShape) aNS = TNaming_Tool::NamedShape(Selection, F);
206     if(!aNS.IsNull()) { //presented in DF
207 #ifdef OCCT_DEBUG_BNP
208       PrintEntry (aNS->Label(),0);
209 #endif
210       const TopoDS_Shape& aS = TNaming_Tool::CurrentShape(aNS);
211       if(!aS.IsNull() && aS.ShapeType() == Selection.ShapeType()) {
212         if(Selection.Orientation() != aS.Orientation()) {
213           isTheCase = Standard_True;
214         }
215       }
216     }
217   }
218   return isTheCase;
219 }
220 #endif
221 //=======================================================================
222 //function : FindGenerated
223 //purpose  : Finds all generated from the <S>
224 //=======================================================================
225
226 static void FindGenerated(const Handle(TNaming_NamedShape)& NS, const TopoDS_Shape& S, 
227                                 TopTools_ListOfShape& theList)
228
229 {
230   const TDF_Label& LabNS = NS->Label();
231   for (TNaming_NewShapeIterator it (S, LabNS); it.More(); it.Next()) {
232     if (it.Label() == LabNS) {
233       theList.Append(it.Shape());
234     }
235   }
236 }
237 //=======================================================================
238 //function : IsIdentified
239 //purpose  : 
240 //=======================================================================
241 Standard_Boolean TNaming_Selector::IsIdentified (const TDF_Label& L,
242                                                  const TopoDS_Shape& Selection, 
243                                                  Handle(TNaming_NamedShape)& NS,
244                                                  const Standard_Boolean Geometry)
245 {  
246   TopoDS_Shape Context;
247   Standard_Boolean OnlyOne =!Geometry;
248   TNaming_Identifier Ident(L,Selection,Context,OnlyOne);   
249   if (Ident.IsFeature()) {  
250     if   (!OnlyOne)  return Standard_False;
251     else {
252       NS =   Ident.FeatureArg();
253
254       // mpv : external condition
255       TDF_LabelMap Forbiden,Valid;
256       TopTools_IndexedMapOfShape MS;
257       TNaming_NamingTool::CurrentShape(Valid,Forbiden,NS,MS);
258       return (MS.Contains(Selection) && MS.Extent() == 1);
259     }
260   }
261   else if(Ident.Type() == TNaming_GENERATION) {
262     NS = Ident.NamedShapeOfGeneration();
263     if(!NS.IsNull()) {
264       TDF_LabelMap Forbiden,Valid;
265       TopTools_IndexedMapOfShape MS;
266       TNaming_NamingTool::CurrentShape(Valid,Forbiden,NS,MS);
267       if(MS.Contains(Selection) && MS.Extent() == 1) {
268         const TopoDS_Shape& aS = Ident.ShapeArg();
269         TopTools_ListOfShape aList;
270         FindGenerated(NS, aS, aList);
271         Ident.NextArg();
272         while(Ident.MoreArgs()) {
273           const TopoDS_Shape& aShape = Ident.ShapeArg();
274           FindGenerated(NS, aShape, aList);
275           Ident.NextArg();
276         }
277         const TopoDS_Shape& aC = MS (1);
278         Standard_Boolean isEq(Standard_False);
279         TopTools_ListIteratorOfListOfShape itl(aList);
280         for(;itl.More();itl.Next()) {
281           if(itl.Value() == aC) 
282             isEq = Standard_True;
283           else {
284             isEq = Standard_False;
285             break;
286           }
287         }
288         return isEq;
289       }
290     } else 
291       return Standard_False;
292   }
293   return Standard_False;
294 }
295
296 //=======================================================================
297 //function : TNaming_Selector
298 //purpose  : 
299 //=======================================================================
300
301 TNaming_Selector::TNaming_Selector (const TDF_Label& L) 
302 {
303   myLabel = L;
304 }
305
306 //=======================================================================
307 //function : Select
308 //purpose  : 
309 //=======================================================================
310 Standard_Boolean TNaming_Selector::Select (const TopoDS_Shape& Selection, 
311                                            const TopoDS_Shape& Context,
312                                            const Standard_Boolean Geometry,
313                                            const Standard_Boolean KeepOrientation) const
314 {
315   myLabel.ForgetAllAttributes();  
316   Handle(TNaming_NamedShape)NS;
317   Standard_Boolean aKeepOrientation((Selection.ShapeType() == TopAbs_VERTEX) ? Standard_False : KeepOrientation);
318   if(Selection.ShapeType() == TopAbs_COMPOUND) {
319     Standard_Boolean isVertex(Standard_True);
320     TopoDS_Iterator it(Selection);
321     for(;it.More();it.Next())
322       if(it.Value().ShapeType() != TopAbs_VERTEX) {
323         isVertex = Standard_False;
324         break;
325       }
326     if(isVertex) aKeepOrientation = Standard_False;
327   }
328   /* 
329  // for debug opposite orientation
330  TopoDS_Shape selection;                                                 
331  Standard_Boolean found(Standard_False);
332  TopExp_Explorer exp(Context,TopAbs_EDGE);
333  for(;exp.More();exp.Next()) {
334    TopoDS_Shape E = exp.Current(); 
335    if(E.IsSame(Selection) && E.Orientation() != Selection.Orientation()) {
336      selection = E;
337    found = Standard_True;
338    cout <<" FOUND: Entity orientation = " << selection.Orientation() <<endl;
339    }
340  }
341  if (!found)
342    selection = Selection;
343   */
344
345 #ifdef OCCT_DEBUG_SEL
346   cout << "SELECTION ORIENTATION = " << Selection.Orientation() <<", TShape = " << Selection.TShape() <<endl;
347   //cout << "SELECTION ORIENTATION = " << selection.Orientation() <<", TShape = " << selection.TShape() <<endl;
348   PrintEntry(myLabel, 0);
349   TNaming::Print(myLabel, cout);
350 #endif
351
352   if(aKeepOrientation) {
353 #ifdef ORIENTATION_DSOPT
354     const Standard_Boolean aBNproblem = IsSpecificCase(myLabel, Context) || IsSpecificCase2(myLabel, Selection);
355
356     NS = TNaming_Naming::Name (myLabel,Selection,Context,Geometry,aKeepOrientation,aBNproblem);
357 #else
358       NS = TNaming_Naming::Name (myLabel,Selection,Context,Geometry,aKeepOrientation);
359 #endif    
360   }
361   else
362     if (!IsIdentified (myLabel,Selection,NS,Geometry)) { 
363       NS = TNaming_Naming::Name (myLabel,Selection,Context,Geometry,aKeepOrientation);
364     }
365   if (NS.IsNull()) return Standard_False; 
366   //
367   // namedshape with SELECTED Evolution
368   //
369   TNaming_Builder B (myLabel);
370   // mpv: if oldShape for selection is some shape from used map of shapes,
371   //      then naming structure becomes more complex, can be cycles
372   const TopoDS_Shape& aSelection = TNaming_Tool::CurrentShape(NS); //szy
373 #ifdef OCCT_DEBUG_CHECK_TYPE
374   if(!Selection.IsSame(aSelection) && Selection.ShapeType() != TopAbs_COMPOUND) {
375     TCollection_AsciiString entry;
376     TDF_Tool::Entry(NS->Label(), entry);
377     cout << "Selection is Not Same (NSLabel = " <<entry<<"): " << "TShape1 = " << 
378       Selection.TShape()->This() << " TShape2 = " <<aSelection.TShape()->This() <<endl;
379   }
380 #endif
381   if(aSelection.ShapeType() == TopAbs_COMPOUND && aSelection.ShapeType() != Selection.ShapeType())
382     B.Select(aSelection,aSelection); // type migration
383   else
384     B.Select(Selection,Selection);
385   //
386   // naming with IDENTITY NameType
387   //
388   Handle(TNaming_Naming) N = new TNaming_Naming (); 
389   N->ChangeName().Type(TNaming_IDENTITY);  
390   N->ChangeName().Append(NS);
391   N->ChangeName().Orientation(Selection.Orientation());
392 // inserted by vro 06.09.00:
393   N->ChangeName().ShapeType(Selection.ShapeType());
394
395   myLabel.AddAttribute(N);  
396   return Standard_True; 
397 }
398
399 //=======================================================================
400 //function : Select
401 //purpose  : 
402 //=======================================================================
403 Standard_Boolean TNaming_Selector::Select (const TopoDS_Shape& Selection,
404                                            const Standard_Boolean Geometry,
405                                            const Standard_Boolean KeepOrientation) const
406 {  
407   // we give a Null shape. How to guess what is the good context ?
408   TopoDS_Shape Context;
409 //  return Select (Selection,Context,Geometry);
410 // temporary!!!
411   return Select (Selection,Selection,Geometry, KeepOrientation);
412
413 }
414
415 //=======================================================================
416 //function : Solve
417 //purpose  : 
418 //=======================================================================
419 Standard_Boolean TNaming_Selector::Solve (TDF_LabelMap& Valid) const
420 {
421   Handle(TNaming_Naming) name;
422 #ifdef OCCT_DEBUG_SEL
423         cout <<"TNaming_Selector::Solve==> "; 
424         PrintEntry(myLabel,0);
425 #endif
426   if (myLabel.FindAttribute(TNaming_Naming::GetID(),name)) {
427     return name->Solve(Valid);
428   }
429   return Standard_False;
430 }
431
432 //=======================================================================
433 //function : Arguments
434 //purpose  : 
435 //=======================================================================
436 void TNaming_Selector::Arguments (TDF_AttributeMap& args) const
437 {  
438   TDF_Tool::OutReferences(myLabel,args);
439 }
440
441 //=======================================================================
442 //function : TNaming_Selector
443 //purpose  : 
444 //=======================================================================
445
446 Handle(TNaming_NamedShape) TNaming_Selector::NamedShape() const
447 {
448   Handle(TNaming_NamedShape) NS;
449   myLabel.FindAttribute(TNaming_NamedShape::GetID(),NS);
450   return NS;
451 }