0023119: TNaming_Selector::Solve() fails (changes from single face to compound of...
[occt.git] / src / DNaming / DNaming_SelectionCommands.cxx
1 // Created on: 1997-10-20
2 // Created by: Yves FRICAUD
3 // Copyright (c) 1997-1999 Matra Datavision
4 // Copyright (c) 1999-2012 OPEN CASCADE SAS
5 //
6 // The content of this file is subject to the Open CASCADE Technology Public
7 // License Version 6.5 (the "License"). You may not use the content of this file
8 // except in compliance with the License. Please obtain a copy of the License
9 // at http://www.opencascade.org and read it completely before using this file.
10 //
11 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13 //
14 // The Original Code and all software distributed under the License is
15 // distributed on an "AS IS" basis, without warranty of any kind, and the
16 // Initial Developer hereby disclaims all such warranties, including without
17 // limitation, any warranties of merchantability, fitness for a particular
18 // purpose or non-infringement. Please see the License for the specific terms
19 // and conditions governing the rights and limitations under the License.
20
21
22
23 #include <DNaming.hxx>
24
25 #include <DDF.hxx>
26
27 #include <TNaming_NamedShape.hxx>
28 #include <TNaming_ListOfNamedShape.hxx>
29 #include <TNaming_ListIteratorOfListOfNamedShape.hxx>
30 #include <TNaming_Tool.hxx>
31 #include <TDF_Label.hxx>
32 #include <TDF_AttributeMap.hxx>
33 #include <TDF_MapIteratorOfAttributeMap.hxx>
34 #include <TDF_ChildIterator.hxx>
35 #include <TDF_Tool.hxx>
36 #include <TNaming_Name.hxx>
37 #include <TNaming.hxx>
38 #include <TNaming_Naming.hxx>
39 #include <TNaming_NamingTool.hxx>
40 #include <TNaming_MapOfNamedShape.hxx>
41 #include <TNaming_MapIteratorOfMapOfNamedShape.hxx>
42 #include <TDF_ChildIterator.hxx>
43 #include <TNaming_Selector.hxx>
44 #include <TopoDS_Shape.hxx>
45 #include <TopAbs.hxx>
46 #include <TCollection_AsciiString.hxx>
47 #include <TDF_LabelMap.hxx>
48 #include <TDF_MapIteratorOfLabelMap.hxx>
49
50 #include <DBRep.hxx>
51 #include <Draw_Appli.hxx>
52 #include <Draw.hxx>
53 #include <Draw_Interpretor.hxx>
54 #include <Draw_Drawable3D.hxx>
55 #include <DBRep.hxx>
56 #include <DBRep_DrawableShape.hxx>
57 #include <stdio.h>
58
59 //=======================================================================
60 //function : Display
61 //purpose  : 
62 //=======================================================================
63
64 static void Display (const Standard_CString Name, const TopoDS_Shape& S)
65 {  
66   //char* name = Name;
67   static Standard_Integer nbIsos  = 2;
68   static Standard_Real size    = 100.;
69   static Standard_Integer discret = 30;
70
71   Handle(DBRep_DrawableShape) D = new DBRep_DrawableShape(S,
72                                                           Draw_jaune,
73                                                           Draw_vert,
74                                                           Draw_bleu,
75                                                           Draw_rouge,
76                                                           size,
77                                                           nbIsos,
78                                                           discret);
79   Draw::Set(Name,D);
80 }
81
82 //=======================================================================
83 //function : DumpNaming
84 //purpose  : 
85 //=======================================================================
86
87 //static void DumpNaming (const Handle(TNaming_Naming)& naming) 
88 static void DumpNaming (const Handle(TNaming_Naming)& naming, Draw_Interpretor& di) 
89 {
90   TCollection_AsciiString Entry;
91   const TNaming_Name& AName = naming->GetName();
92   //TNaming::Print(AName.Type(),cout);
93   Standard_SStream aStream1;
94   TNaming::Print(AName.Type(),aStream1);
95   di << aStream1;
96   di << " ";
97   //TopAbs::Print(AName.ShapeType(),cout);
98   Standard_SStream aStream2;
99   TopAbs::Print(AName.ShapeType(),aStream2);
100   di << aStream2;
101   const TNaming_ListOfNamedShape& NSS = AName.Arguments();
102   for (TNaming_ListIteratorOfListOfNamedShape it(NSS); it.More(); it.Next()) {
103     TDF_Tool::Entry(it.Value()->Label(),Entry); 
104     di << " " << Entry.ToCString();
105   }
106   if(!AName.StopNamedShape().IsNull()) {
107     TDF_Tool::Entry(AName.StopNamedShape()->Label(),Entry); 
108     di << " Stop " << Entry.ToCString();
109   }
110 }
111
112 //=======================================================================
113 //function : SelectShape ou SelectGeometry
114 //purpose  : "Select DF entry shape [context [orient]]", 
115 //=======================================================================
116
117 static Standard_Integer DNaming_Select (Draw_Interpretor& di, Standard_Integer n, const char** a)
118 {
119   if (n > 3) {
120     Standard_Boolean geometry = !(strcmp(a[0],"SelectGeometry")); 
121     Handle(TDF_Data) DF;
122     if(!DDF::GetDF(a[1], DF))  return 1;
123     TDF_Label L;
124     DDF::AddLabel(DF,a[2],L);
125     TNaming_Selector SL (L);
126     if (n == 4) {
127       TopoDS_Shape S = DBRep::Get(a[3], TopAbs_SHAPE);  
128       SL.Select (S, geometry); 
129     }
130     if (n > 4) {  
131       Standard_Boolean Orient(Standard_False);
132       if(n == 6) Orient = (Standard_Boolean)atoi(a[5]);
133       TopoDS_Shape S = DBRep::Get(a[3], TopAbs_SHAPE);
134       TopoDS_Shape C = DBRep::Get(a[4], TopAbs_SHAPE);
135       SL.Select (S, C, geometry, Orient);       
136     }
137     return 0;  
138   }
139   di << "DNaming_Select : Error" << "\n";
140   return 1;
141 }
142 // #define DEB_SELN 1
143 //=======================================================================
144 //function : FillValidMap
145 //purpose  : 
146 //=======================================================================
147
148 Standard_Boolean FillValidMap(const TDF_Label& theLabel, TDF_LabelMap& theValidMap)
149 {
150   Standard_Boolean extRefFound = Standard_False;
151   TDF_AttributeMap anExtMap;
152 #ifdef DEB_SELN
153           TCollection_AsciiString entr1;
154       TDF_Tool::Entry(theLabel, entr1);  
155       cout<<"\tNaming Attribute at = "<< entr1 <<endl;
156 #endif
157   TDF_ChildIterator itr(theLabel, Standard_True);
158   for ( ;itr.More(); itr.Next()) {
159           const TDF_Label& aLabel = itr.Value();
160           Handle(TNaming_Naming) aNaming;
161           if(!aLabel.IsNull()) 
162                   aLabel.FindAttribute(TNaming_Naming::GetID(), aNaming);
163           if(aNaming.IsNull()) continue;
164 #ifdef DEB_SELN   
165       TDF_Tool::Entry(aLabel, entr1);  
166       cout<<"\tNaming Attribute at = "<< entr1 <<endl;
167 #endif
168           TDF_Tool::OutReferences(aLabel,anExtMap);
169           for (TDF_MapIteratorOfAttributeMap attMItr(anExtMap);attMItr.More(); attMItr.Next()) {
170         Handle(TDF_Attribute) att = attMItr.Key();
171 #ifdef DEB_SELN
172         TDF_Tool::Entry(att->Label(), entr1);
173             cout<<"## References attribute dynamic type = "<<att->DynamicType()<<" at Label = "<<entr1 <<endl;
174 #endif  
175             if (att->Label().IsDifferent(aLabel) && !att->Label().IsDescendant(theLabel)) {
176         theValidMap.Add(att->Label());
177                 Handle(TNaming_NamedShape) aNS;
178                 att->Label().FindAttribute(TNaming_NamedShape::GetID(), aNS);
179                 if(!aNS.IsNull())
180                   TNaming_NamingTool::BuildDescendants(aNS, theValidMap);
181         extRefFound = Standard_True;
182            }     
183         }
184   }
185   return extRefFound;
186 }
187
188 //=======================================================================
189 //function : SolveSelection
190 //purpose  : "SolveSelection DF entry", 
191 //=======================================================================
192
193 static Standard_Integer DNaming_SolveSelection (Draw_Interpretor& di, Standard_Integer n, const char** a)
194 {
195   if (n == 3) {
196     char name[100];
197     Handle(TDF_Data) DF;
198     if(!DDF::GetDF(a[1], DF))  return 1;
199     TDF_Label L;
200     DDF::AddLabel(DF,a[2],L);
201
202     Handle(TNaming_Naming) naming;    
203     if (!L.FindAttribute(TNaming_Naming::GetID(),naming)) {  
204       cout <<"DNaming__SolveSelection  : not a selection" << endl;
205       return 1;
206     }
207         TDF_LabelMap aValidMap;
208     if(!FillValidMap(L,aValidMap)) 
209                 di << "Valid map is empty" << "\n";
210 #ifdef DEB_SELN
211         cout<<"== Valid Label map =="<<endl;
212         for (TDF_MapIteratorOfLabelMap mapItr(aValidMap);mapItr.More(); mapItr.Next()) {
213       const TDF_Label& aLab = mapItr.Key();
214
215        TCollection_AsciiString entr1;
216        TDF_Tool::Entry(aLab, entr1);
217            cout<<"  Label = "<<entr1 <<endl;
218         }
219 #endif
220
221     TNaming_Selector SL (L);
222     Standard_Boolean isSolved = SL.Solve(aValidMap);
223         if(!isSolved)
224                 di << "!!! Solver is failed" <<"\n";
225     TopoDS_Shape Res = TNaming_Tool::CurrentShape(SL.NamedShape());
226     sprintf (name,"%s_%s","new",a[2]);
227     Display (name,Res);
228     return 0;
229   }
230   di << "DNaming_SolveSelection : Error" << "\n";
231   return 1;
232 }
233
234
235 //=======================================================================
236 //function : DumpSelection
237 //purpose  : DumpSelection DF entry (R)"
238 //=======================================================================
239 static Standard_Integer DNaming_DumpSelection (Draw_Interpretor& di, 
240                                               Standard_Integer n, const char** a)
241 {
242   if (n == 3 || n == 4) { 
243     Handle(TDF_Data) DF;
244     if (!DDF::GetDF(a[1],DF)) return 1;  
245     TDF_Label L;
246     if (!DDF::FindLabel(DF,a[2],L)) return 1;
247     Handle(TNaming_Naming) naming;
248     if (!L.FindAttribute(TNaming_Naming::GetID(),naming)) {  
249       di <<"DNaming_DumpSelection : not a selection" << "\n";
250       return 1;
251     }
252     DumpNaming(naming, di);
253     di << "\n";
254     if (n == 4) { 
255       Standard_Integer depth = L.Depth();  
256       Standard_Integer curdepth = 0;
257       TCollection_AsciiString Entry;
258       TDF_ChildIterator it (naming->Label(),Standard_True);
259       for (;it.More();it.Next()) {
260         if (it.Value().FindAttribute(TNaming_Naming::GetID(),naming)) { 
261           curdepth = (naming->Label().Depth()- depth);
262           for (Standard_Integer i = 1; i <= curdepth; i++) di << " ";    
263           TDF_Tool::Entry (naming->Label(),Entry); 
264           di << Entry.ToCString() << " "; 
265           DumpNaming(naming, di);
266           di << "\n";
267         }
268       }
269     }
270     return 0;
271   }
272   di << "DNaming_DumpSelection : Error" << "\n";
273   return 1;  
274 }
275
276
277 //=======================================================================
278 //function : ArgsSelection
279 //purpose  : ArgsSelection DF entry"
280 //=======================================================================
281 static Standard_Integer DNaming_ArgsSelection (Draw_Interpretor& di, 
282                                               Standard_Integer n, const char** a)
283 {
284   if (n == 3) { 
285     Handle(TDF_Data) DF;
286     if (!DDF::GetDF(a[1],DF)) return 1;  
287     TDF_Label L;
288     if (!DDF::FindLabel(DF,a[2],L)) return 1;
289     Handle(TNaming_Naming) naming;
290     if (!L.FindAttribute(TNaming_Naming::GetID(),naming)) {  
291       di <<"DNaming_DumpSelection : not a selection" << "\n";
292       return 1;
293     }  
294     TCollection_AsciiString Entry;
295     TNaming_Selector SL (L);
296     di <<" Selection Arguments : ";
297     TDF_AttributeMap args;
298     SL.Arguments(args);
299     for (TDF_MapIteratorOfAttributeMap it(args); it.More(); it.Next()) {
300       TDF_Tool::Entry(it.Key()->Label(),Entry); 
301       di << Entry.ToCString() << " ";
302     }
303     di << "\n";
304     return 0;
305   }
306   di << "DNaming_ArgsSelection : Error" << "\n";
307   return 1;  
308 }
309
310
311 //=======================================================================
312 //function : CollectAttachment
313 //purpose  : 
314 //=======================================================================
315
316 static void CollectAttachment (const TDF_Label& root,
317                                const Handle(TNaming_Naming)& naming, 
318                                TNaming_MapOfNamedShape& attachment)
319 {
320   TNaming_ListIteratorOfListOfNamedShape itarg;
321   const TNaming_ListOfNamedShape& args = naming->GetName().Arguments();
322   for (itarg.Initialize(args);itarg.More();itarg.Next()) {
323     if (!itarg.Value()->Label().IsDescendant(root)) attachment.Add(itarg.Value());
324   }  
325   Handle(TNaming_Naming) subnaming; 
326   for (TDF_ChildIterator it(naming->Label(),Standard_True);it.More();it.Next()) {
327     if (it.Value().FindAttribute(TNaming_Naming::GetID(),subnaming)) {   
328       const TNaming_ListOfNamedShape& subargs = subnaming->GetName().Arguments();
329       for (itarg.Initialize(subargs);itarg.More();itarg.Next()) {
330         if (!itarg.Value()->Label().IsDescendant(root)) attachment.Add(itarg.Value());
331       }
332     }
333   }
334 }  
335
336
337
338 //=======================================================================
339 //function : Attachment
340 //purpose  : Attachment DF entry"
341 //=======================================================================
342
343 static Standard_Integer DNaming_Attachment (Draw_Interpretor& di, 
344                                             Standard_Integer n, 
345                                             const char** a)
346 {
347   if (n == 3) { 
348     Handle(TDF_Data) DF;
349     if (!DDF::GetDF(a[1],DF)) return 1;  
350     TDF_Label L;
351     if (!DDF::FindLabel(DF,a[2],L)) return 1;  
352     Handle(TNaming_Naming) naming; 
353     TNaming_MapOfNamedShape attachment;
354     if (L.FindAttribute(TNaming_Naming::GetID(),naming)) {
355       CollectAttachment (L,naming,attachment);
356     }
357     else {
358       for (TDF_ChildIterator it (L,Standard_True); it.More();it.Next()) {
359         if (it.Value().FindAttribute(TNaming_Naming::GetID(),naming)) {
360           CollectAttachment (L,naming,attachment);
361           it.NextBrother();
362         }
363       }
364     }
365     TCollection_AsciiString Entry;   
366     TDF_Tool::Entry(L,Entry); 
367     di << " Attachment of " << Entry.ToCString();
368     di << "\n";
369     for (TNaming_MapIteratorOfMapOfNamedShape ita (attachment); ita.More(); ita.Next()) {
370       TDF_Tool::Entry (ita.Key()->Label(),Entry); 
371       di << Entry.ToCString() << " ";
372     }
373     di << "\n";
374     return 0;
375   }
376   di << "DNaming_Attachment : Error" << "\n";
377   return 1;  
378 }
379
380 //=======================================================================
381 //function : SelectionCommands
382 //purpose  : 
383 //=======================================================================
384
385 void DNaming::SelectionCommands(Draw_Interpretor& theCommands) 
386 {
387   
388   static Standard_Boolean done = Standard_False;
389   if (done) return;
390   done = Standard_True;
391   
392   const char* g = "Naming data commands";
393
394   theCommands.Add("SelectShape",
395                   "SelectShape DF entry shape [context [Orient]]", 
396                   __FILE__, DNaming_Select, g);
397   
398   theCommands.Add("SelectGeometry",
399                   "SelectGeometry DF entry shape [context]", 
400                   __FILE__, DNaming_Select, g);
401   
402   theCommands.Add("DumpSelection",         
403                   "DumpSelected DF entry", 
404                   __FILE__, DNaming_DumpSelection, g);    
405
406   theCommands.Add("ArgsSelection",         
407                   "ArgsSelection DF entry", 
408                   __FILE__, DNaming_ArgsSelection, g);  
409
410   theCommands.Add("SolveSelection",         
411                   "DumpSelection DF entry", 
412                   __FILE__, DNaming_SolveSelection, g);  
413
414   theCommands.Add("Attachment",         
415                   "Attachment DF entry", 
416                   __FILE__, DNaming_Attachment, g);
417 }