0023948: Wrong intersection between a surface of revolution and a plane.
[occt.git] / src / Interface / Interface_CheckIterator.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 #include <Interface_CheckIterator.ixx> 
15 #include <Standard_NoSuchObject.hxx>
16 #include <TCollection_HAsciiString.hxx>
17
18
19 static const Handle(Interface_Check)& nulcheck ()
20 {
21   static Handle(Interface_Check) nulch = new Interface_Check;
22   return nulch;
23 }
24
25
26 //=======================================================================
27 //function : Interface_CheckIterator
28 //purpose  : 
29 //=======================================================================
30
31 Interface_CheckIterator::Interface_CheckIterator ()
32 {
33   Clear();
34 }
35
36
37 //=======================================================================
38 //function : Interface_CheckIterator
39 //purpose  : 
40 //=======================================================================
41
42 Interface_CheckIterator::Interface_CheckIterator(const Standard_CString name)
43      : thename (name)
44 {
45   Clear();
46 }
47
48
49 //=======================================================================
50 //function : SetName
51 //purpose  : 
52 //=======================================================================
53
54 void Interface_CheckIterator::SetName (const Standard_CString name)
55 {
56   thename.Clear();
57   if (name[0] != '\0') thename.AssignCat(name);
58 }
59
60
61 //=======================================================================
62 //function : Name
63 //purpose  : 
64 //=======================================================================
65
66 Standard_CString Interface_CheckIterator::Name () const
67 {
68   return thename.ToCString();
69 }
70
71
72 //=======================================================================
73 //function : SetModel
74 //purpose  : 
75 //=======================================================================
76
77 void Interface_CheckIterator::SetModel(const Handle(Interface_InterfaceModel)& model)
78 {
79   themod = model;
80 }
81
82
83 //=======================================================================
84 //function : Model
85 //purpose  : 
86 //=======================================================================
87
88 Handle(Interface_InterfaceModel) Interface_CheckIterator::Model() const
89 {
90   return themod;
91 }
92
93
94 //=======================================================================
95 //function : Clear
96 //purpose  : 
97 //=======================================================================
98
99 void Interface_CheckIterator::Clear ()
100 {
101   thelist = new Interface_HSequenceOfCheck();
102   thenums = new TColStd_HSequenceOfInteger();
103   thecurr = new Interface_IntVal;
104   thecurr->CValue() = 1;
105 }
106
107
108 //=======================================================================
109 //function : Merge
110 //purpose  : 
111 //=======================================================================
112
113 void Interface_CheckIterator::Merge (Interface_CheckIterator& other)
114 {
115   themod = other.Model();
116   for (other.Start(); other.More(); other.Next())
117     Add (other.Value(),other.Number());
118 }
119
120
121 //=======================================================================
122 //function : Add
123 //purpose  : 
124 //=======================================================================
125
126 void Interface_CheckIterator::Add(const Handle(Interface_Check)& ach,
127                                   const Standard_Integer num)
128 {
129   //  Add <meme num que le dernier> -> cumul des Checks
130   if (ach->NbWarnings() + ach->NbFails() == 0) return;
131   Standard_Integer nm = num;
132   if (num <= 0 && ach->HasEntity()) {
133     if (!themod.IsNull()) {
134       nm = themod->Number (ach->Entity());
135       if (nm <= 0) nm = -1;
136     }
137     else nm = -1;
138   }
139   if (nm >= 0 && nm <= - (thecurr->Value()) ) {
140     Standard_Integer i , numpos = 0 , nb = thelist->Length();
141     for (i = nb; i > 0; i --)
142       if (thenums->Value(i) == nm) {  numpos = i; break;  }
143     if (numpos > 0 && nm >= 0) {
144       Handle(Interface_Check) lch = thelist->ChangeValue(numpos);
145       lch->GetMessages (ach);
146     }
147     //  Cas normal : on ajoute en fin de liste
148     else  {  thelist->Append(ach);  thenums->Append(nm);  }
149   }
150   //  Pas encore vu passe : inutile de chercher
151   else  {  thelist->Append(ach);  thenums->Append(nm);  thecurr->CValue() = -nm;  }
152 }
153
154
155 //=======================================================================
156 //function : Check
157 //purpose  : 
158 //=======================================================================
159
160 const Handle(Interface_Check)& Interface_CheckIterator::Check
161        (const Standard_Integer num) const
162 {
163   Standard_Integer i, nb = thelist->Length();
164   for (i = 1; i <= nb; i ++) {
165     if (num == thenums->Value(i)) return thelist->Value(i);
166   }
167   return nulcheck();
168 }
169
170
171 //=======================================================================
172 //function : Check
173 //purpose  : 
174 //=======================================================================
175
176 const Handle(Interface_Check)& Interface_CheckIterator::Check
177   (const Handle(Standard_Transient)& ent) const
178 {
179   Standard_Integer num = -1;
180   if (!themod.IsNull()) num = themod->Number(ent);
181   if (num > 0) return Check(num);
182
183   Standard_Integer i, nb = thelist->Length();
184   for (i = 1; i <= nb; i ++) {
185     if (ent == thelist->Value(i)->Entity()) return thelist->Value(i);
186   }
187   return nulcheck();
188 }
189
190
191 //=======================================================================
192 //function : CCheck
193 //purpose  : 
194 //=======================================================================
195
196 Handle(Interface_Check)& Interface_CheckIterator::CCheck
197        (const Standard_Integer num)
198 {
199   Standard_Integer i, nb = thenums->Length();
200   for (i = 1; i <= nb; i ++) {
201     if (num == thenums->Value(i)) return thelist->ChangeValue(i);
202   }
203   Handle(Interface_Check) ach = new Interface_Check;
204   thelist->Append(ach);  thenums->Append(num);
205   return thelist->ChangeValue (thelist->Length());
206 }
207
208
209 //=======================================================================
210 //function : CCheck
211 //purpose  : 
212 //=======================================================================
213
214 Handle(Interface_Check)& Interface_CheckIterator::CCheck
215        (const Handle(Standard_Transient)& ent)
216 {
217   Standard_Integer num = -1;
218   if (!themod.IsNull()) num = themod->Number(ent);
219   if (num > 0) return CCheck(num);
220
221   Standard_Integer i, nb = thelist->Length();
222   for (i = 1; i <= nb; i ++) {
223     if (ent == thelist->Value(i)->Entity()) return thelist->ChangeValue(i);
224   }
225
226   Handle(Interface_Check) ach = new Interface_Check;
227   thelist->Append(ach);  thenums->Append(num);
228   return thelist->ChangeValue (thelist->Length());
229 }
230
231
232 //=======================================================================
233 //function : IsEmpty
234 //purpose  : 
235 //=======================================================================
236
237 Standard_Boolean Interface_CheckIterator::IsEmpty
238   (const Standard_Boolean failsonly) const
239 {
240   if (thelist->IsEmpty()) return Standard_True;
241   if (!failsonly) return Standard_False;
242   Standard_Integer i, nb = thelist->Length();
243   for (i = 1; i <= nb; i ++) {
244     if (thelist->Value(i)->HasFailed()) return Standard_False;
245   }
246   return Standard_True;
247 }
248
249
250 //=======================================================================
251 //function : Status
252 //purpose  : 
253 //=======================================================================
254
255 Interface_CheckStatus Interface_CheckIterator::Status () const
256 {
257   Interface_CheckStatus stat = Interface_CheckOK;
258   Standard_Integer i, nb = thelist->Length();
259   for (i = 1; i <= nb; i ++) {
260     const Handle(Interface_Check) ach = thelist->Value(i);
261     if (ach->HasFailed()) return Interface_CheckFail;
262     if (ach->NbWarnings() > 0) stat = Interface_CheckWarning;
263   }
264   return stat;
265 }
266
267
268 //=======================================================================
269 //function : Complies
270 //purpose  : 
271 //=======================================================================
272
273 Standard_Boolean Interface_CheckIterator::Complies
274   (const Interface_CheckStatus stat) const
275 {
276   Standard_Boolean res = Standard_False;
277   if (stat == Interface_CheckNoFail) res = Standard_True;
278   Standard_Integer i, nb = thelist->Length();
279   for (i = 1; i <= nb; i ++) {
280     const Handle(Interface_Check) ach = thelist->Value(i);
281     Standard_Integer nbf = ach->NbFails(), nbw = ach->NbWarnings();
282     switch (stat) {
283     case Interface_CheckOK      : if (nbf + nbw > 0) return Standard_False; break;
284     case Interface_CheckWarning : if (nbf > 0) return Standard_False;
285                                   if (nbw > 0) res  = Standard_True;  break;
286     case Interface_CheckFail    : if (nbf > 0) return Standard_True;  break;
287     case Interface_CheckAny     : return Standard_True;
288     case Interface_CheckMessage : if (nbf + nbw > 0) return Standard_True;  break;
289     case Interface_CheckNoFail  : if (nbf > 0) return Standard_False;  break;
290     default : break;
291     }
292   }
293   return res;
294 }
295
296
297 //=======================================================================
298 //function : Extract
299 //purpose  : 
300 //=======================================================================
301
302 Interface_CheckIterator Interface_CheckIterator::Extract
303   (const Interface_CheckStatus stat) const
304 {
305   Interface_CheckIterator res;
306   res.SetModel (themod);  res.SetName (thename.ToCString());
307   Standard_Integer i, nb = thelist->Length();
308   for (i = 1; i <= nb; i ++) {
309     const Handle(Interface_Check) ach = thelist->Value(i);
310     Standard_Integer nbf = ach->NbFails(), nbw = ach->NbWarnings();
311     Standard_Boolean prend = Standard_False;
312     switch (stat) {
313     case Interface_CheckOK      : prend = (nbf + nbw == 0);       break;
314     case Interface_CheckWarning : prend = (nbf == 0 && nbw > 0);  break;
315     case Interface_CheckFail    : prend = (nbf >  0);             break;
316     case Interface_CheckAny     : prend = Standard_True;          break;
317     case Interface_CheckMessage : prend = (nbf + nbw >  0);       break;
318     case Interface_CheckNoFail  : prend = (nbf == 0);             break;
319     default : break;
320     }
321     if (prend) res.Add (ach,thenums->Value(i));
322   }
323   return res;
324 }
325
326
327 //=======================================================================
328 //function : Extract
329 //purpose  : 
330 //=======================================================================
331
332 Interface_CheckIterator Interface_CheckIterator::Extract
333   (const Standard_CString mess,
334    const Standard_Integer incl, const Interface_CheckStatus stat) const
335 {
336   Handle(TCollection_HAsciiString) str = new TCollection_HAsciiString (mess);
337   Interface_CheckIterator res;
338   res.SetModel (themod);  res.SetName (thename.ToCString());
339   Standard_Integer i, nb = thelist->Length();
340   for (i = 1; i <= nb; i ++) {
341     const Handle(Interface_Check) ach = thelist->Value(i);
342     if (ach->Complies(str,incl,stat)) res.Add (ach,thenums->Value(i));
343   }
344   return res;
345 }
346
347
348 //=======================================================================
349 //function : Remove
350 //purpose  : 
351 //=======================================================================
352
353 Standard_Boolean Interface_CheckIterator::Remove(const Standard_CString mess,
354                                                  const Standard_Integer incl,
355                                                  const Interface_CheckStatus stat)
356 {
357   Handle(TCollection_HAsciiString) str = new TCollection_HAsciiString (mess);
358   Standard_Boolean res = Standard_False;
359   Standard_Integer i, nb = thelist->Length();
360   for (i = 1; i <= nb; i ++) {
361     Handle(Interface_Check) ach = thelist->ChangeValue(i);
362     if (ach->Remove (str,incl,stat)) res = Standard_True;
363   }
364   return res;
365 }
366
367
368 //=======================================================================
369 //function : Checkeds
370 //purpose  : 
371 //=======================================================================
372
373 Handle(TColStd_HSequenceOfTransient) Interface_CheckIterator::Checkeds
374   (const Standard_Boolean failsonly, const Standard_Boolean global) const
375 {
376   Handle(TColStd_HSequenceOfTransient) list;
377   if (themod.IsNull()) return list;
378   list = new TColStd_HSequenceOfTransient();
379   Standard_Integer num, i, nb = thelist->Length();
380   for (i = 1; i <= nb; i ++) {
381     const Handle(Interface_Check) chk = thelist->Value(i);
382     if (failsonly && !chk->HasFailed()) continue;
383     if (chk->NbWarnings() == 0) continue;
384     num = thenums->Value(i);
385     if (num == 0 && global) list->Append (themod);
386     else if (num > 0) list->Append (themod->Value(num));
387   }
388   return list;
389 }
390
391
392 //=======================================================================
393 //function : Start
394 //purpose  : 
395 //=======================================================================
396
397 void Interface_CheckIterator::Start () const
398 {
399   thecurr->CValue() = 1;
400 }
401
402
403 //=======================================================================
404 //function : More
405 //purpose  : 
406 //=======================================================================
407
408 Standard_Boolean Interface_CheckIterator::More () const
409 {
410   if (thecurr->Value() < 0) thecurr->CValue() = 1;
411   return (thecurr->Value() <= thelist->Length());
412 }
413
414
415 //=======================================================================
416 //function : Next
417 //purpose  : 
418 //=======================================================================
419
420 void Interface_CheckIterator::Next () const
421 {
422   if (thecurr->Value() < 0) thecurr->CValue() = 1;
423   thecurr->CValue() ++;
424 }
425
426
427 //=======================================================================
428 //function : Value
429 //purpose  : 
430 //=======================================================================
431
432 const Handle(Interface_Check)& Interface_CheckIterator::Value () const 
433 {
434   if (thecurr->Value() > thelist->Length()) Standard_NoSuchObject::Raise
435     ("Interface Check Iterator : Value");
436   return thelist->Value(thecurr->Value());
437 }
438
439
440 //=======================================================================
441 //function : Number
442 //purpose  : 
443 //=======================================================================
444
445 Standard_Integer Interface_CheckIterator::Number () const 
446 {
447   if (thecurr->Value() > thenums->Length()) Standard_NoSuchObject::Raise
448     ("Interface Check Iterator : Value");
449   return thenums->Value(thecurr->Value());
450 }
451
452
453 //=======================================================================
454 //function : Print
455 //purpose  : 
456 //=======================================================================
457
458 void Interface_CheckIterator::Print(const Handle(Message_Messenger)& S,
459                                     const Standard_Boolean failsonly,
460                                     const Standard_Integer final) const
461 {
462   Print (S,themod,failsonly,final);
463 }
464
465
466 //=======================================================================
467 //function : Print
468 //purpose  : 
469 //=======================================================================
470
471 void Interface_CheckIterator::Print(const Handle(Message_Messenger)& S,
472                                     const Handle(Interface_InterfaceModel)& model,
473                                     const Standard_Boolean failsonly,
474                                     const Standard_Integer /*final*/) const
475 {
476   Standard_Boolean titre = Standard_False;
477   /*Standard_CString mesnum;
478     Standard_CString mesnum0 = ":";
479     Standard_CString mesnum1 = " (original):";
480     Standard_CString mesnum2 = " (computed):";    */
481   Standard_Integer i, nbch = 0, nb = thelist->Length();//,j; svv #2
482   Standard_Boolean yamod = !model.IsNull();
483   for (i = 1; i <= nb; i ++) {
484     const Handle(Interface_Check) ach = thelist->Value(i);
485     Standard_Integer nbw = 0, nbf = ach->NbFails();
486     if (!failsonly)  nbw = ach->NbWarnings();
487     if (nbf + nbw == 0) continue;
488     Handle(Standard_Transient) ent = ach->Entity();
489     Standard_Integer nm0 = thenums->Value(i);
490     Standard_Boolean entnul = ent.IsNull();
491     Standard_Integer num = nm0;
492     if (nm0 <= 0 && !entnul && yamod) num = model->Number(ent);
493     if (nm0 <= 0 && entnul) num = -1;    // Global
494 //  mesnum = mesnum0;
495 //    if (yamod) mesnum = (nm0 > 0 ? mesnum1 : mesnum2);
496
497     if (!titre)        S<<" **  " << Name() << "  **"<<endl;
498     titre = Standard_True;
499     S<<"Check:"; if(nb > 9 && i < 10) S<<" "; if (nb > 99 && i < 100) S<<" ";
500     S<<i;
501     if      (num <  0) S<<" -- Global Check"<<endl;
502     else if (num == 0) S<<" -- Entity n0 ??:";
503     else {
504       if (yamod) { S<<" -- Entity (n0:id) "; model->Print (ent,S); }
505       else       S<<" -- Entity n0 "<<num;
506 //      S<<" -- Entity n0 "<<num<<mesnum;
507 //      if (yamod) model->PrintLabel(ent,S);
508     }
509     if      (num >= 0 &&  entnul) S<<" (unknown Type)"<<endl;
510     else if (num >= 0 && !entnul) {
511       if (yamod) S<<"   Type:"<<model->TypeName(ent)<<endl;
512       else       S<<"   Type:"<<ent->DynamicType()->Name()<<endl;
513     }
514
515     nbch ++;
516     ach->Print (S, (failsonly ? 1 : 3));
517   }
518 //  if (nbch > 0)  S<<" ----  Checks : "<<nbch<<"  ----"<<endl;
519 }
520
521
522 //=======================================================================
523 //function : Destroy
524 //purpose  : 
525 //=======================================================================
526
527 void Interface_CheckIterator::Destroy ()
528 {
529   thecurr.Nullify();
530 }    // redevient standard