0025266: Debug statements in the source are getting flushed on to the console
[occt.git] / src / HLRBRep / HLRBRep_Data.cxx
1 // Created on: 1997-04-17
2 // Created by: Christophe MARION
3 // Copyright (c) 1997-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 //#define No_Standard_OutOfRange
18
19 #define OCC191 // jfa 26/02/2002 Bug of cone display
20
21 #include <HLRBRep_Data.ixx>
22
23 #include <StdFail_UndefinedDerivative.hxx>
24 #include <Precision.hxx>
25 #include <gp_Dir.hxx>
26 #include <Geom2d_Curve.hxx>
27 #include <IntRes2d_IntersectionPoint.hxx>
28 #include <IntRes2d_IntersectionSegment.hxx>
29 #include <IntCurveSurface_IntersectionPoint.hxx>
30 #include <IntCurveSurface_TransitionOnCurve.hxx>
31 #include <TColStd_ListIteratorOfListOfInteger.hxx>
32 #include <HLRAlgo.hxx>
33 #include <HLRAlgo_ListIteratorOfInterferenceList.hxx>
34 #include <HLRBRep_EdgeFaceTool.hxx>
35 #include <ElCLib.hxx>
36 #include <gp.hxx>
37 #include <stdio.h>
38 #include <BRepTopAdaptor_Tool.hxx>
39
40 Standard_Integer nbOkIntersection;
41 Standard_Integer nbPtIntersection;
42 Standard_Integer nbSegIntersection;
43 Standard_Integer nbClassification;
44 Standard_Integer nbCal1Intersection; // pairs of unrejected edges
45 Standard_Integer nbCal2Intersection; // true intersections (not vertex)
46 Standard_Integer nbCal3Intersection; // Curve-Surface intersections
47
48 static const Standard_Real CutLar = 2.e-1;
49 static const Standard_Real CutBig = 1.e-1;
50
51 //-- voir HLRAlgo.cxx 
52
53 #define MinShap1 ((Standard_Integer*)MinMaxShap)[ 0]
54 #define MinShap2 ((Standard_Integer*)MinMaxShap)[ 1]
55 #define MinShap3 ((Standard_Integer*)MinMaxShap)[ 2]
56 #define MinShap4 ((Standard_Integer*)MinMaxShap)[ 3]
57 #define MinShap5 ((Standard_Integer*)MinMaxShap)[ 4]
58 #define MinShap6 ((Standard_Integer*)MinMaxShap)[ 5]
59 #define MinShap7 ((Standard_Integer*)MinMaxShap)[ 6]
60 #define MinShap8 ((Standard_Integer*)MinMaxShap)[ 7]
61
62 #define MaxShap1 ((Standard_Integer*)MinMaxShap)[ 8]
63 #define MaxShap2 ((Standard_Integer*)MinMaxShap)[ 9]
64 #define MaxShap3 ((Standard_Integer*)MinMaxShap)[10]
65 #define MaxShap4 ((Standard_Integer*)MinMaxShap)[11]
66 #define MaxShap5 ((Standard_Integer*)MinMaxShap)[12]
67 #define MaxShap6 ((Standard_Integer*)MinMaxShap)[13]
68 #define MaxShap7 ((Standard_Integer*)MinMaxShap)[14]
69 #define MaxShap8 ((Standard_Integer*)MinMaxShap)[15]
70
71 #define MinFace1 ((Standard_Integer*)iFaceMinMax)[ 0]
72 #define MinFace2 ((Standard_Integer*)iFaceMinMax)[ 1]
73 #define MinFace3 ((Standard_Integer*)iFaceMinMax)[ 2]
74 #define MinFace4 ((Standard_Integer*)iFaceMinMax)[ 3]
75 #define MinFace5 ((Standard_Integer*)iFaceMinMax)[ 4]
76 #define MinFace6 ((Standard_Integer*)iFaceMinMax)[ 5]
77 #define MinFace7 ((Standard_Integer*)iFaceMinMax)[ 6]
78 #define MinFace8 ((Standard_Integer*)iFaceMinMax)[ 7]
79
80 #define MaxFace1 ((Standard_Integer*)iFaceMinMax)[ 8]
81 #define MaxFace2 ((Standard_Integer*)iFaceMinMax)[ 9]
82 #define MaxFace3 ((Standard_Integer*)iFaceMinMax)[10]
83 #define MaxFace4 ((Standard_Integer*)iFaceMinMax)[11]
84 #define MaxFace5 ((Standard_Integer*)iFaceMinMax)[12]
85 #define MaxFace6 ((Standard_Integer*)iFaceMinMax)[13]
86 #define MaxFace7 ((Standard_Integer*)iFaceMinMax)[14]
87 #define MaxFace8 ((Standard_Integer*)iFaceMinMax)[15]
88
89 #define MinWire1 ((Standard_Integer*)MinMaxWire)[ 0]
90 #define MinWire2 ((Standard_Integer*)MinMaxWire)[ 1]
91 #define MinWire3 ((Standard_Integer*)MinMaxWire)[ 2]
92 #define MinWire4 ((Standard_Integer*)MinMaxWire)[ 3]
93 #define MinWire5 ((Standard_Integer*)MinMaxWire)[ 4]
94 #define MinWire6 ((Standard_Integer*)MinMaxWire)[ 5]
95 #define MinWire7 ((Standard_Integer*)MinMaxWire)[ 6]
96 #define MinWire8 ((Standard_Integer*)MinMaxWire)[ 7]
97
98 #define MaxWire1 ((Standard_Integer*)MinMaxWire)[ 8]
99 #define MaxWire2 ((Standard_Integer*)MinMaxWire)[ 9]
100 #define MaxWire3 ((Standard_Integer*)MinMaxWire)[10]
101 #define MaxWire4 ((Standard_Integer*)MinMaxWire)[11]
102 #define MaxWire5 ((Standard_Integer*)MinMaxWire)[12]
103 #define MaxWire6 ((Standard_Integer*)MinMaxWire)[13]
104 #define MaxWire7 ((Standard_Integer*)MinMaxWire)[14]
105 #define MaxWire8 ((Standard_Integer*)MinMaxWire)[15]
106
107 #define MinLEdg1 ((Standard_Integer*)myLEMinMax)[ 0]
108 #define MinLEdg2 ((Standard_Integer*)myLEMinMax)[ 1]
109 #define MinLEdg3 ((Standard_Integer*)myLEMinMax)[ 2]
110 #define MinLEdg4 ((Standard_Integer*)myLEMinMax)[ 3]
111 #define MinLEdg5 ((Standard_Integer*)myLEMinMax)[ 4]
112 #define MinLEdg6 ((Standard_Integer*)myLEMinMax)[ 5]
113 #define MinLEdg7 ((Standard_Integer*)myLEMinMax)[ 6]
114 #define MinLEdg8 ((Standard_Integer*)myLEMinMax)[ 7]
115
116 #define MaxLEdg1 ((Standard_Integer*)myLEMinMax)[ 8]
117 #define MaxLEdg2 ((Standard_Integer*)myLEMinMax)[ 9]
118 #define MaxLEdg3 ((Standard_Integer*)myLEMinMax)[10]
119 #define MaxLEdg4 ((Standard_Integer*)myLEMinMax)[11]
120 #define MaxLEdg5 ((Standard_Integer*)myLEMinMax)[12]
121 #define MaxLEdg6 ((Standard_Integer*)myLEMinMax)[13]
122 #define MaxLEdg7 ((Standard_Integer*)myLEMinMax)[14]
123 #define MaxLEdg8 ((Standard_Integer*)myLEMinMax)[15]
124
125 #define MinFEdg1 ((Standard_Integer*)MinMaxFEdg)[ 0]
126 #define MinFEdg2 ((Standard_Integer*)MinMaxFEdg)[ 1]
127 #define MinFEdg3 ((Standard_Integer*)MinMaxFEdg)[ 2]
128 #define MinFEdg4 ((Standard_Integer*)MinMaxFEdg)[ 3]
129 #define MinFEdg5 ((Standard_Integer*)MinMaxFEdg)[ 4]
130 #define MinFEdg6 ((Standard_Integer*)MinMaxFEdg)[ 5]
131 #define MinFEdg7 ((Standard_Integer*)MinMaxFEdg)[ 6]
132 #define MinFEdg8 ((Standard_Integer*)MinMaxFEdg)[ 7]
133
134 #define MaxFEdg1 ((Standard_Integer*)MinMaxFEdg)[ 8]
135 #define MaxFEdg2 ((Standard_Integer*)MinMaxFEdg)[ 9]
136 #define MaxFEdg3 ((Standard_Integer*)MinMaxFEdg)[10]
137 #define MaxFEdg4 ((Standard_Integer*)MinMaxFEdg)[11]
138 #define MaxFEdg5 ((Standard_Integer*)MinMaxFEdg)[12]
139 #define MaxFEdg6 ((Standard_Integer*)MinMaxFEdg)[13]
140 #define MaxFEdg7 ((Standard_Integer*)MinMaxFEdg)[14]
141 #define MaxFEdg8 ((Standard_Integer*)MinMaxFEdg)[15]
142
143 #define MinVert1 MinMaxVert[ 0]
144 #define MinVert2 MinMaxVert[ 1]
145 #define MinVert3 MinMaxVert[ 2]
146 #define MinVert4 MinMaxVert[ 3]
147 #define MinVert5 MinMaxVert[ 4]
148 #define MinVert6 MinMaxVert[ 5]
149 #define MinVert7 MinMaxVert[ 6]
150 #define MinVert8 MinMaxVert[ 7]
151 #define MaxVert1 MinMaxVert[ 8]
152 #define MaxVert2 MinMaxVert[ 9]
153 #define MaxVert3 MinMaxVert[10]
154 #define MaxVert4 MinMaxVert[11]
155 #define MaxVert5 MinMaxVert[12]
156 #define MaxVert6 MinMaxVert[13]
157 #define MaxVert7 MinMaxVert[14]
158 #define MaxVert8 MinMaxVert[15]
159
160 #define DERIVEE_PREMIERE_NULLE  0.000000000001
161
162 //-- ======================================================================
163 //--  
164
165 #include <IntRes2d_TypeTrans.hxx>
166 #include <IntRes2d_Position.hxx>
167 #include <IntRes2d_IntersectionPoint.hxx>
168 #include <IntRes2d_Transition.hxx>
169
170 static long unsigned Mask32[32] = { 1,2,4,8,  16,32,64,128,  256,512,1024,2048,
171                                  4096,8192,16384,32768,
172                                  65536,131072,262144,524288,
173                                  1048576,2097152,4194304,8388608,
174                                  16777216,33554432,67108864,134217728,
175                                  268435456,536870912,1073741824,2147483648U};
176
177 #define SIZEUV 8
178
179 class TableauRejection { 
180 public:
181   Standard_Real **UV;               //-- UV[i][j]     contient le param (U sur Ci) de l intersection de Ci avec C(IndUV[j])
182   Standard_Integer **IndUV;         //-- IndUV[i][j]  = J0   -> Intersection entre i et J0
183   Standard_Integer *nbUV;           //-- nbUV[i][j]   nombre de valeurs pour la ligne i
184   Standard_Integer N;
185   
186   long unsigned **TabBit;
187   Standard_Integer nTabBit;
188
189 #ifdef DEB  
190   Standard_Integer StNbLect,StNbEcr,StNbMax,StNbMoy,StNbMoyNonNul; //-- STAT
191 #endif
192
193 public:
194   //-- ============================================================
195   TableauRejection() { 
196     N=0; nTabBit=0;  UV=NULL;  nbUV=NULL;  IndUV=NULL; TabBit=NULL;
197 #ifdef DEB
198     StNbLect=StNbEcr=StNbMax=StNbMoy=StNbMoyNonNul=0;
199 #endif
200   }
201   //-- ============================================================
202   void SetDim(const Standard_Integer n) {
203 #ifdef HLRBREP_DEB
204     cout<<"\n@#@#@#@#@# SetDim "<<n<<endl;
205 #endif
206     if(UV) 
207       Destroy();
208 #ifdef DEB
209     StNbLect=StNbEcr=StNbMax=StNbMoy=0;
210 #endif
211     N=n;
212     UV   = (Standard_Real **)       malloc(N*sizeof(Standard_Real *));
213     IndUV = (Standard_Integer **)   malloc(N*sizeof(Standard_Integer *));
214     nbUV = (Standard_Integer *)     malloc(N*sizeof(Standard_Integer));
215 //    for(Standard_Integer i=0;i<N;i++) { 
216     Standard_Integer i;
217     for( i=0;i<N;i++) { 
218       UV[i]=(Standard_Real *)       malloc(SIZEUV*sizeof(Standard_Real));
219     }
220     for(i=0;i<N;i++) {
221       IndUV[i]=(Standard_Integer *) malloc(SIZEUV*sizeof(Standard_Integer));
222       for(Standard_Integer k=0;k<SIZEUV;k++) { 
223         IndUV[i][k]=-1;
224       }
225       nbUV[i]=SIZEUV;
226     }
227     InitTabBit(n);
228   }
229   //-- ============================================================
230   ~TableauRejection() { 
231     //-- cout<<"\n Destructeur TableauRejection"<<endl;
232     Destroy(); 
233   } 
234   //-- ============================================================
235   void Destroy() {
236 #ifdef DEB
237     if(N) { 
238       Standard_Integer nnn=0;
239       StNbMoy=StNbMoyNonNul=0;
240       StNbMax=0;
241       for(Standard_Integer i=0; i<N; i++) { 
242         Standard_Integer nb=0;
243         for(Standard_Integer j=0; IndUV[i][j]!=-1 && j<nbUV[i]; j++,nb++);
244         if(nb>StNbMax) StNbMax=nb;
245         StNbMoy+=nb;
246         if(nb) { StNbMoyNonNul+=nb; nnn++; } 
247       }
248       
249       printf("\n----------------------------------------");
250       printf("\nNbLignes  : %10d",N);
251       printf("\nNbLect    : %10d",StNbLect);
252       printf("\nNbEcr     : %10d",StNbEcr);
253       printf("\nNbMax     : %10d",StNbMax);
254       printf("\nNbMoy     : %10d / %10d -> %d",StNbMoy,N,StNbMoy/N);
255       if(nnn) { 
256         printf("\nNbMoy !=0 : %10d / %10d -> %d",StNbMoyNonNul,nnn,StNbMoyNonNul/nnn);
257       }
258       printf("\n----------------------------------------\n");
259     }
260 #endif
261     if(N) { 
262       ResetTabBit(N);
263 //      for(Standard_Integer i=0;i<N;i++) { 
264       Standard_Integer i;
265       for(i=0;i<N;i++) { 
266         if(IndUV[i]) { 
267           free(IndUV[i]);
268           IndUV[i]=NULL;
269         }
270         else { cout<<" IndUV ~~~~~~~~~~~~~~~~~~~~~~~~~~~~"<<endl; } 
271                
272       }
273       for(i=0;i<N;i++) { 
274         if(UV[i]) { 
275           free(UV[i]);
276           UV[i]=NULL;
277         }
278         else { cout<<" UV ~~~~~~~~~~~~~~~~~~~~~~~~~~~~"<<endl; } 
279       }
280       
281       if(nbUV)  { free(nbUV);  nbUV=NULL; } else { cout<<" nbUV ~~~~~~~~~~~~~~~~~~~~~~~~~~~~"<<endl; } 
282       if(IndUV) { free(IndUV); IndUV=NULL;} else { cout<<" IndUV ~~~~~~~~~~~~~~~~~~~~~~~~~~~~"<<endl; } 
283       if(UV)    { free(UV);    UV=NULL; }  else { cout<<" UV ~~~~~~~~~~~~~~~~~~~~~~~~~~~~"<<endl; } 
284       N=0;
285     }
286   }
287   //-- ============================================================
288   void Set(Standard_Integer i0,Standard_Integer j0,const Standard_Real u) { 
289     i0--; j0--;
290 #ifdef DEB
291     StNbEcr++;
292 #endif
293     Standard_Integer k=-1;
294 //    for(Standard_Integer i=0; k==-1 && i<nbUV[i0]; i++) { 
295     Standard_Integer i;
296     for( i=0; k==-1 && i<nbUV[i0]; i++) { 
297       if(IndUV[i0][i]==-1) { 
298         k=i;
299       }
300     }
301     if(k==-1) { //-- on agrandit le tableau
302       //--
303       //-- declaration de la Nv ligne de taille : ancienne taille + SIZEUV
304       //-- 
305       
306       //-- cout<<" \n alloc nbUV["<<i0<<"]="<<nbUV[i0];
307
308       Standard_Real    *NvLigneUV  = (Standard_Real *)   malloc((nbUV[i0]+SIZEUV)*sizeof(Standard_Real));
309       Standard_Integer *NvLigneInd = (Standard_Integer *)malloc((nbUV[i0]+SIZEUV)*sizeof(Standard_Integer));
310       //--
311       //-- Recopie des anciennes valeurs ds la nouvelle ligne 
312       //-- 
313       for(i=0;i<nbUV[i0];i++) { 
314         NvLigneUV[i]=UV[i0][i];
315         NvLigneInd[i]=IndUV[i0][i];     
316       }
317       
318       //-- mise a jour de la nouvelle dimension   ;  free des anciennes lignes et affectation
319       k=nbUV[i0];
320       nbUV[i0]+=SIZEUV;
321       free(UV[i0]);
322       free(IndUV[i0]);
323       UV[i0]=NvLigneUV;
324       IndUV[i0]=NvLigneInd;
325       for(Standard_Integer kk=k ; kk<nbUV[i0];kk++) { 
326         IndUV[i0][kk]=-1;
327       }
328     }
329     IndUV[i0][k]=j0;
330     UV[i0][k]=u;
331     
332     //-- tri par ordre decroissant
333     Standard_Boolean TriOk;
334     do { 
335       TriOk=Standard_True;
336       Standard_Integer im1=0;
337       for(i=1; IndUV[i0][i]!=-1 && i<nbUV[i0]; i++,im1++) { 
338         if(IndUV[i0][i]>IndUV[i0][im1]) { 
339           TriOk=Standard_False;
340           k=IndUV[i0][i]; IndUV[i0][i]=IndUV[i0][im1]; IndUV[i0][im1]=k;
341           Standard_Real t=UV[i0][i]; UV[i0][i]=UV[i0][im1]; UV[i0][im1]=t;
342         }
343       }
344     }
345     while(TriOk==Standard_False);   
346   }
347   //-- ============================================================
348   Standard_Real Get(Standard_Integer i0,Standard_Integer j0) { 
349     i0--; j0--;
350 #ifdef DEB
351     StNbLect++;
352 #endif
353
354 //--    for(Standard_Integer i=0; IndUV[i0][i]!=-1 && i<nbUV[i0]; i++) { 
355 //--      if(IndUV[i0][i]==j0) { 
356 //--    return(UV[i0][i]);
357 //--      }
358 //--    }
359     //-- ordre decroissant
360     Standard_Integer a=0,b=nbUV[i0]-1,ab;
361     if(IndUV[i0][a]==-1) return(RealLast());
362     if(IndUV[i0][a]==j0) return(UV[i0][a]);
363     if(IndUV[i0][b]==j0) return(UV[i0][b]);
364     while((IndUV[i0][a]>j0) && (IndUV[i0][b]<j0)) { 
365       ab=(a+b)>>1;
366       if(IndUV[i0][ab] < j0)      { if(b==ab) return(RealLast()); else b=ab; }
367       else if(IndUV[i0][ab] > j0) { if(a==ab) return(RealLast()); else a=ab; } 
368       else { return(UV[i0][ab]); } 
369     }
370
371     return(RealLast());
372   }
373   //-- ============================================================
374   void ResetTabBit(const Standard_Integer nbedgs) { 
375     //-- cout<<"\n ResetTabBit"<<endl;
376     if(TabBit) { 
377       for(Standard_Integer i=0;i<nbedgs;i++) { 
378         if(TabBit[i]) {
379           free(TabBit[i]);
380           TabBit[i]=NULL;
381         }
382       }
383       free(TabBit);
384       TabBit=NULL;
385       nTabBit=0;
386     }
387   }
388   //-- ============================================================
389   void InitTabBit(const Standard_Integer nbedgs) { 
390     //--  cout<<"\n InitTabBit"<<endl;
391     if(TabBit && nTabBit) { 
392       ResetTabBit(nTabBit);
393     }
394     TabBit = (long unsigned **) malloc((nbedgs)*sizeof(long unsigned *));
395     nTabBit=nbedgs;
396     Standard_Integer n=1+(nbedgs>>5);
397     
398     for(Standard_Integer i=0;i<nbedgs;i++) { 
399       TabBit[i]=(long unsigned *) malloc(n*sizeof(long unsigned));
400       for(Standard_Integer j=0;j<n;j++) { 
401         TabBit[i][j]=0;
402       }
403     }
404   }
405   //-- ============================================================
406   void SetNoIntersection(Standard_Integer i0,Standard_Integer i1) {
407     //  cout<<" SetNoIntersection : "<<i0<<" "<<i1<<endl;
408     i0--;
409     i1--;
410     if(i0>i1) { 
411       Standard_Integer t = i0; i0=i1; i1=t;
412     }
413     Standard_Integer c=i1>>5;
414     Standard_Integer o=i1 & 31;
415     TabBit[i0][c] |=  Mask32[o];
416   }
417   //-- ============================================================
418   Standard_Boolean NoIntersection(Standard_Integer i0,Standard_Integer i1) { 
419     //  cout<<" ??NoIntersection : "<<i0<<" "<<i1<<" ";
420     i0--;
421     i1--;
422     if(i0>i1) { 
423       Standard_Integer t = i0; i0=i1; i1=t;
424     }
425     Standard_Integer c=i1>>5;
426     Standard_Integer o=i1 & 31;
427     if(TabBit[i0][c] & Mask32[o]) { 
428       //--    cout<<" TRUE "<<endl;
429       return(Standard_True);
430     }
431     //--  cout<<" FALSE "<<endl;
432     return(Standard_False);
433   }
434   //-- ============================================================
435   void SetIntersection(Standard_Integer i0,
436                        Standard_Integer i1,
437                        const IntRes2d_IntersectionPoint& IP) { 
438     const IntRes2d_Transition& T1=IP.TransitionOfFirst();
439     const IntRes2d_Transition& T2=IP.TransitionOfSecond();
440     if(T1.PositionOnCurve()==IntRes2d_Middle) { 
441       if(T2.PositionOnCurve()==IntRes2d_Middle) { 
442         if(   T1.TransitionType()==IntRes2d_In 
443            || T1.TransitionType()==IntRes2d_Out) { 
444           Set(i0,i1,IP.ParamOnFirst());
445           Set(i1,i0,IP.ParamOnSecond());
446         }
447       }
448     }
449   }
450   //-- ============================================================
451   void GetSingleIntersection(Standard_Integer i0,Standard_Integer i1,
452                              Standard_Real& u,Standard_Real& v ) { 
453     u=Get(i0,i1);
454     if(u!=RealLast()) { 
455       v=Get(i1,i0);
456     }
457     else { 
458       v=RealLast();
459     }
460   }
461 };
462  
463 //-- ================================================================================
464
465
466 //=======================================================================
467 //function : AdjustParameter
468 //purpose  : 
469 //=======================================================================
470
471 static void AdjustParameter (HLRBRep_EdgeData* E,
472                              const Standard_Boolean h,
473                              Standard_Real& p,
474                              Standard_ShortReal& t)
475 {
476   Standard_Real p1,p2;
477   Standard_ShortReal t1,t2;
478   if (h) {
479     E->Status().Bounds(p,t,p2,t2);
480     if (E->VerAtSta()) p = p + (p2 - p) * CutBig;
481   }
482   else {
483     E->Status().Bounds(p1,t1,p,t);
484     if (E->VerAtEnd()) p = p - (p - p1) * CutBig;
485   }
486 }
487
488 //=======================================================================
489 //function : Data
490 //purpose  : 
491 //=======================================================================
492
493 HLRBRep_Data::HLRBRep_Data (const Standard_Integer NV,
494                             const Standard_Integer NE,
495                             const Standard_Integer NF) :
496                             myNbVertices   (NV),
497                             myNbEdges      (NE),
498                             myNbFaces      (NF),
499                             myEData      (0,NE),
500                             myFData      (0,NF),
501                             myEdgeIndices(0,NE),
502                             myToler((Standard_ShortReal)1e-5),
503                             myLLProps(2,Epsilon(1.)),
504                             myFLProps(2,Epsilon(1.)),
505                             mySLProps(2,Epsilon(1.)),
506                             myHideCount(0)
507 {
508   myReject=(void *)(new TableauRejection());
509   ((TableauRejection *)myReject)->SetDim(myNbEdges);
510 }
511
512 void HLRBRep_Data::Destroy() { 
513   //-- cout<<"\n HLRBRep_Data::~HLRBRep_Data()"<<endl;
514   ((TableauRejection *)myReject)->Destroy();
515   delete ((TableauRejection *)myReject);
516 }
517 //=======================================================================
518 //function : Write
519 //purpose  : 
520 //=======================================================================
521
522 void HLRBRep_Data::Write (const Handle(HLRBRep_Data)& DS,
523                           const Standard_Integer dv,
524                           const Standard_Integer de,
525                           const Standard_Integer df)
526 {
527   Standard_Integer n1edge = DS->NbEdges();
528   Standard_Integer n1face = DS->NbFaces();
529
530   HLRBRep_EdgeData* ed = &(myEData         .ChangeValue(de));
531   HLRBRep_EdgeData* e1 = &(DS->EDataArray().ChangeValue(0 ));
532   ed++;
533   e1++;
534
535   HLRBRep_FaceData* fd = &(myFData         .ChangeValue(df));
536   HLRBRep_FaceData* f1 = &(DS->FDataArray().ChangeValue(0 ));
537   fd++;
538   f1++;
539
540   for (Standard_Integer iedge = 1; iedge <= n1edge; iedge++) {
541     *ed = *e1;
542
543     if (dv != 0) {
544       ed->VSta(ed->VSta() + dv);
545       ed->VEnd(ed->VEnd() + dv);
546     }
547
548     myEMap.Add(DS->EdgeMap().FindKey(iedge));
549
550     ed++;
551     e1++;
552   } 
553
554   for (Standard_Integer iface = 1; iface <= n1face; iface++) {
555     *fd = *f1;
556
557     if (de != 0) {
558       const Handle(HLRAlgo_WiresBlock)& wb = fd->Wires();
559       Standard_Integer nw = wb->NbWires();
560
561       for (Standard_Integer iw = 1; iw <= nw; iw++) {
562         const Handle(HLRAlgo_EdgesBlock)& eb = wb->Wire(iw);
563         Standard_Integer ne = eb->NbEdges();
564
565         for (Standard_Integer ie = 1; ie <= ne; ie++)
566           eb->Edge(ie,eb->Edge(ie) + de);
567       }
568     }
569
570     myFMap.Add(DS->FaceMap().FindKey(iface));
571
572     fd++;
573     f1++;
574   } 
575 }
576
577 //=======================================================================
578 //function : Update
579 //purpose  : 
580 //=======================================================================
581
582 void HLRBRep_Data::Update (const HLRAlgo_Projector& P)
583 {
584   myProj = P;
585   const gp_Trsf& T = myProj.Transformation();
586   Standard_Integer i;
587   Standard_Real tolMinMax = 0;
588
589   Standard_Integer FaceMin[16],FaceMax[16],MinMaxFace[16];
590   Standard_Integer WireMin[16],WireMax[16],MinMaxWire[16];
591   Standard_Integer EdgeMin[16],EdgeMax[16],MinMaxEdge[16];
592   Standard_Real TotMin[16],TotMax[16];
593   HLRAlgo::InitMinMax(Precision::Infinite(),
594                       (Standard_Address)TotMin,
595                       (Standard_Address)TotMax);
596   HLRBRep_EdgeData* ed;
597   HLRBRep_FaceData* fd;
598   ed = &(myEData.ChangeValue(1));
599
600   // compute the global MinMax
601   // *************************
602 //  for (Standard_Integer edge = 1; edge <= myNbEdges; edge++) {
603   Standard_Integer edge;
604   for ( edge = 1; edge <= myNbEdges; edge++) {
605     HLRBRep_Curve& EC = ed->ChangeGeometry();
606     EC.Projector(&myProj);
607     Standard_Real enl =EC.Update((Standard_Address)TotMin,
608                                  (Standard_Address)TotMax);
609     if (enl > tolMinMax) tolMinMax = enl;
610     ed++;
611   }
612   HLRAlgo::EnlargeMinMax(tolMinMax,
613                          (Standard_Address)TotMin,
614                          (Standard_Address)TotMax);
615   Standard_Real d[16];
616   Standard_Real precad = -Precision::Infinite();
617
618   for (i = 0; i <= 15; i++) {
619     d[i] = TotMax[i] - TotMin[i];
620     if (precad < d[i]) precad = d[i];
621   }
622   myBigSize = precad;
623   precad = precad * 0.0005;
624
625   for (i = 0; i <= 15; i++)
626     mySurD[i] = 0x00007fff / (d[i] + precad);
627   precad = precad * 0.5;
628
629   for (i = 0; i <= 15; i++)
630     myDeca[i] = - TotMin[i] + precad;
631
632   Standard_Real tol;
633   Standard_Boolean ver1,ver2;
634
635   ed = &(myEData.ChangeValue(1));
636   fd = &(myFData.ChangeValue(1));
637
638   // update the edges
639   // ****************
640   
641   for (edge = 1; edge <= myNbEdges; edge++) {
642
643     HLRBRep_Curve& EC = ed->ChangeGeometry();
644     HLRAlgo::InitMinMax(Precision::Infinite(),
645                         (Standard_Address)TotMin,
646                         (Standard_Address)TotMax);
647     tolMinMax = EC.UpdateMinMax((Standard_Address)TotMin,
648                                 (Standard_Address)TotMax);
649     tol = (Standard_Real)(ed->Tolerance());
650     ed->Vertical(TotMax[0] - TotMin[0] < tol &&
651                  TotMax[1] - TotMin[1] < tol &&
652                  TotMax[2] - TotMin[2] < tol &&
653                  TotMax[3] - TotMin[3] < tol &&
654                  TotMax[4] - TotMin[4] < tol &&
655                  TotMax[5] - TotMin[5] < tol &&
656                  TotMax[6] - TotMin[6] < tol );
657     HLRAlgo::EnlargeMinMax(tolMinMax,
658                            (Standard_Address)TotMin,
659                            (Standard_Address)TotMax);
660 // Linux warning :  assignment to `int' from `double'. Cast has been added.
661     EdgeMin[ 0] = (Standard_Integer)( (myDeca[ 0] + TotMin[ 0]) * mySurD[ 0]);
662     EdgeMax[ 0] = (Standard_Integer)( (myDeca[ 0] + TotMax[ 0]) * mySurD[ 0]);
663     EdgeMin[ 1] = (Standard_Integer)( (myDeca[ 1] + TotMin[ 1]) * mySurD[ 1]);
664     EdgeMax[ 1] = (Standard_Integer)( (myDeca[ 1] + TotMax[ 1]) * mySurD[ 1]);
665     EdgeMin[ 2] = (Standard_Integer)( (myDeca[ 2] + TotMin[ 2]) * mySurD[ 2]);
666     EdgeMax[ 2] = (Standard_Integer)( (myDeca[ 2] + TotMax[ 2]) * mySurD[ 2]);
667     EdgeMin[ 3] = (Standard_Integer)( (myDeca[ 3] + TotMin[ 3]) * mySurD[ 3]);
668     EdgeMax[ 3] = (Standard_Integer)( (myDeca[ 3] + TotMax[ 3]) * mySurD[ 3]);
669     EdgeMin[ 4] = (Standard_Integer)( (myDeca[ 4] + TotMin[ 4]) * mySurD[ 4]);
670     EdgeMax[ 4] = (Standard_Integer)( (myDeca[ 4] + TotMax[ 4]) * mySurD[ 4]);
671     EdgeMin[ 5] = (Standard_Integer)( (myDeca[ 5] + TotMin[ 5]) * mySurD[ 5]);
672     EdgeMax[ 5] = (Standard_Integer)( (myDeca[ 5] + TotMax[ 5]) * mySurD[ 5]);
673     EdgeMin[ 6] = (Standard_Integer)( (myDeca[ 6] + TotMin[ 6]) * mySurD[ 6]);
674     EdgeMax[ 6] = (Standard_Integer)( (myDeca[ 6] + TotMax[ 6]) * mySurD[ 6]);
675     EdgeMin[ 7] = (Standard_Integer)( (myDeca[ 7] + TotMin[ 7]) * mySurD[ 7]);
676     EdgeMax[ 7] = (Standard_Integer)( (myDeca[ 7] + TotMax[ 7]) * mySurD[ 7]);
677     EdgeMin[ 8] = (Standard_Integer)( (myDeca[ 8] + TotMin[ 8]) * mySurD[ 8]);
678     EdgeMax[ 8] = (Standard_Integer)( (myDeca[ 8] + TotMax[ 8]) * mySurD[ 8]);
679     EdgeMin[ 9] = (Standard_Integer)( (myDeca[ 9] + TotMin[ 9]) * mySurD[ 9]);
680     EdgeMax[ 9] = (Standard_Integer)( (myDeca[ 9] + TotMax[ 9]) * mySurD[ 9]);
681     EdgeMin[10] = (Standard_Integer)( (myDeca[10] + TotMin[10]) * mySurD[10]);
682     EdgeMax[10] = (Standard_Integer)( (myDeca[10] + TotMax[10]) * mySurD[10]);
683     EdgeMin[11] = (Standard_Integer)( (myDeca[11] + TotMin[11]) * mySurD[11]);
684     EdgeMax[11] = (Standard_Integer)( (myDeca[11] + TotMax[11]) * mySurD[11]);
685     EdgeMin[12] = (Standard_Integer)( (myDeca[12] + TotMin[12]) * mySurD[12]);
686     EdgeMax[12] = (Standard_Integer)( (myDeca[12] + TotMax[12]) * mySurD[12]);
687     EdgeMin[13] = (Standard_Integer)( (myDeca[13] + TotMin[13]) * mySurD[13]);
688     EdgeMax[13] = (Standard_Integer)( (myDeca[13] + TotMax[13]) * mySurD[13]);
689     EdgeMin[14] = (Standard_Integer)( (myDeca[14] + TotMin[14]) * mySurD[14]);
690     EdgeMax[14] = (Standard_Integer)( (myDeca[14] + TotMax[14]) * mySurD[14]);
691     EdgeMin[15] = (Standard_Integer)( (myDeca[15] + TotMin[15]) * mySurD[15]);
692     EdgeMax[15] = (Standard_Integer)( (myDeca[15] + TotMax[15]) * mySurD[15]);
693
694     HLRAlgo::EncodeMinMax((Standard_Address)EdgeMin,
695                           (Standard_Address)EdgeMax,
696                           (Standard_Address)MinMaxEdge);
697     ed->UpdateMinMax((Standard_Address)MinMaxEdge);
698     if (ed->Vertical()) {
699       ver1 = Standard_True;
700       ver2 = Standard_True;
701       Standard_Integer vsta = ed->VSta();
702       Standard_Integer vend = ed->VEnd();
703       Standard_Boolean vout = ed->OutLVSta() || ed->OutLVEnd();
704       Standard_Boolean vcut = ed->CutAtSta() || ed->CutAtEnd();
705       HLRBRep_EdgeData* eb = &(myEData.ChangeValue(1));
706       
707       for (Standard_Integer ebis = 1; ebis <= myNbEdges; ebis++) {
708         if      (vsta == eb->VSta()) {
709           eb->VSta    (vend);
710           eb->OutLVSta(vout);
711           eb->CutAtSta(vcut);
712         }
713         else if (vsta == eb->VEnd()) {
714           eb->VEnd    (vend);
715           eb->OutLVEnd(vout);
716           eb->CutAtEnd(vcut);
717         }
718         eb++;
719       }
720     }
721     else {
722       gp_Pnt Pt;
723       gp_Vec Tg1,Tg2;
724       EC.D1(EC.Parameter3d(EC.FirstParameter()),Pt,Tg1);
725       EC.D1(EC.Parameter3d(EC.LastParameter ()),Pt,Tg2);
726       Tg1.Transform(T);
727       Tg2.Transform(T);
728       if (Abs(Tg1.X()) + Abs(Tg1.Y()) < myToler * 10) ver1 = Standard_True;
729       else {
730         gp_Dir Dir1(Tg1);
731         ver1 = Abs(Dir1.X()) + Abs(Dir1.Y()) < myToler * 10;
732       }
733       if (Abs(Tg2.X()) + Abs(Tg2.Y()) < myToler * 10) ver2 = Standard_True;
734       else {
735         gp_Dir Dir2(Tg2);
736         ver2 = Abs(Dir2.X()) + Abs(Dir2.Y()) < myToler * 10;
737       }
738     }
739     ed->VerAtSta(ed->Vertical() || ver1);
740     ed->VerAtEnd(ed->Vertical() || ver2);
741     ed->AutoIntersectionDone(Standard_True);
742     ed->Simple(Standard_True);
743     ed++;
744   }
745   
746   // update the faces
747   // ****************
748   
749   for (Standard_Integer face = 1; face <= myNbFaces; face++) {
750
751     HLRBRep_Surface& FS = fd->Geometry();
752     iFaceGeom = &(fd->Geometry());
753     mySLProps.SetSurface(iFaceGeom);
754     FS.Projector(&myProj);
755     iFaceType = FS.GetType();
756
757     // Is the face cut by an outline
758
759     Standard_Boolean cut      = Standard_False;
760     Standard_Boolean withOutL = Standard_False;
761     
762     for (myFaceItr1.InitEdge(*fd);
763          myFaceItr1.MoreEdge() && !cut && !withOutL;
764          myFaceItr1.NextEdge()) {
765       if (myFaceItr1.Internal()) {
766         withOutL = Standard_True;
767         cut      = Standard_True;
768       }
769       else if (myFaceItr1.OutLine()) {
770         withOutL = Standard_True;
771         if (myFaceItr1.Double()) cut = Standard_True;
772       }
773     }
774     fd->Cut     (cut);
775     fd->WithOutL(withOutL);
776
777     // Is the face simple = no auto-hiding
778     // not cut and simple surface
779
780     if (!withOutL && 
781         (iFaceType == GeomAbs_Plane    ||
782          iFaceType == GeomAbs_Cylinder ||
783          iFaceType == GeomAbs_Cone     ||
784          iFaceType == GeomAbs_Sphere   ||
785          iFaceType == GeomAbs_Torus )) fd->Simple(Standard_True );
786     else                               fd->Simple(Standard_False);
787
788     fd->Plane   (iFaceType == GeomAbs_Plane   );
789     fd->Cylinder(iFaceType == GeomAbs_Cylinder);
790     fd->Cone    (iFaceType == GeomAbs_Cone    );
791     fd->Sphere  (iFaceType == GeomAbs_Sphere  );
792     fd->Torus   (iFaceType == GeomAbs_Torus   );
793     tol = (Standard_Real)(fd->Tolerance());
794     fd->Side(FS.IsSide(tol,myToler*10));
795     Standard_Boolean inverted = Standard_False;
796     if (fd->WithOutL() && !fd->Side()) {
797       //inverted = OrientOutLine(face,*fd);
798       OrientOthEdge(face,*fd);
799     }
800     if (fd->Side()) {
801       fd->Hiding(Standard_False);
802       fd->Back(Standard_False);
803     }
804     else if (!fd->WithOutL()) {
805       Standard_Real p,pu,pv,r;
806       fd->Back(Standard_False);
807       Standard_Boolean found = Standard_False;
808
809       for (myFaceItr1.InitEdge(*fd);
810            myFaceItr1.MoreEdge() && !found;
811            myFaceItr1.NextEdge()) {
812         myFE         = myFaceItr1.Edge       ();
813         myFEOri      = myFaceItr1.Orientation();
814         myFEOutLine  = myFaceItr1.OutLine    ();
815         myFEInternal = myFaceItr1.Internal   ();
816         myFEDouble   = myFaceItr1.Double     ();
817         HLRBRep_EdgeData* ed = &(myEData(myFE));
818         if (!myFEDouble &&
819             (myFEOri == TopAbs_FORWARD ||
820              myFEOri == TopAbs_REVERSED)) {
821           myFEGeom = &(ed->ChangeGeometry());
822           const HLRBRep_Curve& EC = ed->Geometry();
823           p = EC.Parameter3d((EC.LastParameter () +
824                               EC.FirstParameter()) / 2);
825           if (HLRBRep_EdgeFaceTool::UVPoint(p,myFEGeom,iFaceGeom,pu,pv)) {
826             mySLProps.SetParameters(pu,pv);
827             gp_Pnt Pt;
828             Pt = EC.Value3D(p);
829 #ifdef OCC191
830             if (mySLProps.IsNormalDefined())
831 #endif
832             {
833               gp_Vec Nm = mySLProps.Normal();
834               Pt.Transform(T);
835               Nm.Transform(T);
836               if (myProj.Perspective()) {
837                 r = Nm.Z() * myProj.Focus() - 
838                   ( Nm.X() * Pt.X() + Nm.Y() * Pt.Y() + Nm.Z() * Pt.Z() );
839               }
840               else r = Nm.Z();
841               if (Abs(r) > myToler*10) {
842                 fd->Back( r < 0 );
843                 found = Standard_True;
844                 break;
845               }
846             }
847           }
848         }
849       }
850
851       if (!found) {
852         fd->Side(Standard_True);
853         fd->Hiding(Standard_False);
854         fd->Back(Standard_False);
855       }
856       else if (fd->Closed()) {
857         switch (fd->Orientation()) {
858         case TopAbs_REVERSED : fd->Hiding( fd->Back()   ); break;
859         case TopAbs_FORWARD  : fd->Hiding(!fd->Back()   ); break;
860         case TopAbs_EXTERNAL : fd->Hiding(Standard_True ); break;
861         case TopAbs_INTERNAL : fd->Hiding(Standard_False); break;
862         }
863       }
864       else fd->Hiding(Standard_True);
865     }
866     else {
867       if (inverted) {
868         fd->Hiding(Standard_False);
869         fd->Back(Standard_True);
870       }
871       else {
872         fd->Hiding(Standard_True);
873         fd->Back(Standard_False);
874       }
875     }
876
877     Standard_Boolean FirstTime = Standard_True;
878
879     for (myFaceItr1.InitEdge(*fd);
880          myFaceItr1.MoreEdge();
881          myFaceItr1.NextEdge()) {
882       myFE = myFaceItr1.Edge();
883       HLRBRep_EdgeData* ed = &(myEData(myFE));
884       if (!fd->Simple()) ed->AutoIntersectionDone(Standard_False);
885       HLRAlgo::DecodeMinMax(ed->MinMax(),
886                             (Standard_Address)EdgeMin,
887                             (Standard_Address)EdgeMax);
888       if (myFaceItr1.BeginningOfWire())
889         HLRAlgo::CopyMinMax((Standard_Address)EdgeMin,
890                             (Standard_Address)EdgeMax,
891                             (Standard_Address)WireMin,
892                             (Standard_Address)WireMax);
893       else
894         HLRAlgo::AddMinMax((Standard_Address)EdgeMin,
895                            (Standard_Address)EdgeMax,
896                            (Standard_Address)WireMin,
897                            (Standard_Address)WireMax);
898       if (myFaceItr1.EndOfWire()) {
899         HLRAlgo::EncodeMinMax((Standard_Address)WireMin,
900                               (Standard_Address)WireMax,
901                               (Standard_Address)MinMaxWire);
902         myFaceItr1.Wire()->UpdateMinMax((Standard_Address)MinMaxWire);
903         if (FirstTime) {
904           FirstTime = Standard_False;
905           HLRAlgo::CopyMinMax((Standard_Address)WireMin,
906                               (Standard_Address)WireMax,
907                               (Standard_Address)FaceMin,
908                               (Standard_Address)FaceMax);
909         }
910         else
911           HLRAlgo::AddMinMax((Standard_Address)WireMin,
912                              (Standard_Address)WireMax,
913                              (Standard_Address)FaceMin,
914                              (Standard_Address)FaceMax);
915       }
916     }
917     HLRAlgo::EncodeMinMax((Standard_Address)FaceMin,
918                           (Standard_Address)FaceMax,
919                           (Standard_Address)MinMaxFace);
920     fd->Wires()->UpdateMinMax((Standard_Address)MinMaxFace);  
921     fd->Size(HLRAlgo::SizeBox(FaceMin,FaceMax));
922     fd++;
923   }
924 }
925
926 //=======================================================================
927 //function : InitBoundSort
928 //purpose  : 
929 //=======================================================================
930
931 void 
932 HLRBRep_Data::InitBoundSort (const Standard_Address MinMaxTot,
933                              const Standard_Integer e1,
934                              const Standard_Integer e2)
935 {
936   myNbrSortEd = 0;
937   HLRBRep_EdgeData* ed = &(myEData(e1));
938   Standard_Address MinMaxShap = MinMaxTot;
939
940   for (Standard_Integer e = e1; e <= e2; e++) {
941     if (!ed->Status().AllHidden()) {
942       myLEMinMax = ed->MinMax();
943       if (((MaxShap1 - MinLEdg1) & 0x80008000) == 0 &&
944           ((MaxLEdg1 - MinShap1) & 0x80008000) == 0 &&
945           ((MaxShap2 - MinLEdg2) & 0x80008000) == 0 &&
946           ((MaxLEdg2 - MinShap2) & 0x80008000) == 0 &&
947           ((MaxShap3 - MinLEdg3) & 0x80008000) == 0 &&
948           ((MaxLEdg3 - MinShap3) & 0x80008000) == 0 &&
949           ((MaxShap4 - MinLEdg4) & 0x80008000) == 0 &&
950           ((MaxLEdg4 - MinShap4) & 0x80008000) == 0 &&
951           ((MaxShap5 - MinLEdg5) & 0x80008000) == 0 &&
952           ((MaxLEdg5 - MinShap5) & 0x80008000) == 0 &&
953           ((MaxShap6 - MinLEdg6) & 0x80008000) == 0 &&
954           ((MaxLEdg6 - MinShap6) & 0x80008000) == 0 &&
955           ((MaxShap7 - MinLEdg7) & 0x80008000) == 0 &&
956           ((MaxLEdg7 - MinShap7) & 0x80008000) == 0 &&
957           ((MaxShap8 - MinLEdg8) & 0x80008000) == 0) {  //- rejection en z 
958         myNbrSortEd++;
959         myEdgeIndices(myNbrSortEd) = e;
960       }
961     }
962     ed++;
963   }
964 }
965
966 //=======================================================================
967 //function : InitEdge
968 //purpose  : 
969 //=======================================================================
970 void HLRBRep_Data::InitEdge (const Standard_Integer FI,
971                              BRepTopAdaptor_MapOfShapeTool& MST)
972 {
973   myHideCount++;
974   myHideCount++;
975
976   iFace       = FI;
977   iFaceData   = &myFData(iFace);
978   iFaceGeom   = &(((HLRBRep_FaceData*)iFaceData)->Geometry());
979   iFaceBack   =   ((HLRBRep_FaceData*)iFaceData)->Back();
980   iFaceSimp   =   ((HLRBRep_FaceData*)iFaceData)->Simple();
981   iFaceMinMax =   ((HLRBRep_FaceData*)iFaceData)->Wires()->MinMax();
982   iFaceType   =   ((HLRBRep_Surface*)iFaceGeom)->GetType();
983   iFaceTest   = !iFaceSimp;
984   mySLProps.SetSurface(iFaceGeom);
985   myIntersector.Load(iFaceGeom);
986
987
988   HLRBRep_Surface  *p1 = (HLRBRep_Surface*)iFaceGeom;
989   const BRepAdaptor_Surface& bras=p1->Surface();
990   
991
992   const TopoDS_Face& topodsface=bras.Face();
993   
994
995   
996
997   if(MST.IsBound(topodsface)) {  
998     BRepTopAdaptor_Tool& BRT = MST.ChangeFind(topodsface);
999     myClassifier  = BRT.GetTopolTool();
1000   }
1001   else { 
1002     BRepTopAdaptor_Tool BRT(topodsface,Precision::PConfusion());
1003     MST.Bind(topodsface,BRT);
1004     myClassifier = BRT.GetTopolTool();
1005   }
1006   
1007   if (iFaceTest) {
1008     iFaceSmpl = !((HLRBRep_FaceData*)iFaceData)->Cut();
1009     myFaceItr2.InitEdge(*((HLRBRep_FaceData*)iFaceData));
1010   }
1011   else {
1012
1013     for (myFaceItr1.InitEdge(*((HLRBRep_FaceData*)iFaceData));
1014          myFaceItr1.MoreEdge();
1015          myFaceItr1.NextEdge()) {
1016       myFE = myFaceItr1.Edge();               // edges of a simple hiding
1017       myEData(myFE).HideCount(myHideCount-1); // face must be jumped.
1018     }
1019     myCurSortEd = 1;
1020   }
1021   NextEdge(Standard_False);
1022 }
1023
1024 //=======================================================================
1025 //function : MoreEdge
1026 //purpose  : 
1027 //=======================================================================
1028
1029 Standard_Boolean HLRBRep_Data::MoreEdge ()
1030 {
1031
1032
1033   if (iFaceTest) {
1034     if (myFaceItr2.MoreEdge()) {            // all edges must be tested if
1035       myLE         = myFaceItr2.Edge    (); // the face is not a simple
1036       myLEOutLine  = myFaceItr2.OutLine (); // one. 
1037       myLEInternal = myFaceItr2.Internal();
1038       myLEDouble   = myFaceItr2.Double  ();
1039       myLEIsoLine  = myFaceItr2.IsoLine ();
1040       myLEData     = &myEData(myLE);
1041       myLEGeom     = &(((HLRBRep_EdgeData*)myLEData)->ChangeGeometry());
1042       myLEMinMax   =   ((HLRBRep_EdgeData*)myLEData)->MinMax();
1043       myLETol      =   ((HLRBRep_EdgeData*)myLEData)->Tolerance();
1044       myLEType     =   ((HLRBRep_Curve   *)myLEGeom)->GetType();
1045       if (!myLEDouble)
1046         ((HLRBRep_EdgeData*)myLEData)->HideCount(myHideCount-1);
1047       return Standard_True;
1048     }
1049     else {
1050       iFaceTest = Standard_False;      // at the end of the test
1051       iFaceSimp = iFaceSmpl;           // we know if it is a simple face
1052       ((HLRBRep_FaceData*)iFaceData)->Simple(iFaceSimp);
1053       myCurSortEd = 1;
1054       NextEdge(Standard_False);
1055     }
1056   }
1057   return myCurSortEd <= myNbrSortEd;
1058 }
1059 //=======================================================================
1060 //function : NextEdge
1061 //purpose  : 
1062 //=======================================================================
1063
1064 void HLRBRep_Data::NextEdge (const Standard_Boolean skip)
1065 {
1066
1067   if (skip) {
1068     if (iFaceTest) myFaceItr2.NextEdge();
1069     else           myCurSortEd++;
1070   }
1071   if (!MoreEdge()) return;
1072   if (iFaceTest) {
1073     myLE         = myFaceItr2.Edge    ();
1074     myLEOutLine  = myFaceItr2.OutLine ();
1075     myLEInternal = myFaceItr2.Internal();
1076     myLEDouble   = myFaceItr2.Double  ();
1077     myLEIsoLine  = myFaceItr2.IsoLine ();
1078     myLEData     = &myEData(myLE);
1079     myLEGeom     = &(((HLRBRep_EdgeData*)myLEData)->ChangeGeometry());
1080     myLEMinMax   =   ((HLRBRep_EdgeData*)myLEData)->MinMax();
1081     myLETol      =   ((HLRBRep_EdgeData*)myLEData)->Tolerance();
1082     myLEType     =   ((HLRBRep_Curve   *)myLEGeom)->GetType();
1083     if (((HLRBRep_EdgeData*)myLEData)->Vertical() ||
1084         (myLEDouble &&
1085          ((HLRBRep_EdgeData*)myLEData)->HideCount() == myHideCount-1))
1086       NextEdge();
1087     ((HLRBRep_EdgeData*)myLEData)->HideCount(myHideCount-1);
1088     return;
1089   }
1090   else {
1091     myLE         = Edge();
1092     myLEOutLine  = Standard_False;
1093     myLEInternal = Standard_False;
1094     myLEDouble   = Standard_False;
1095     myLEIsoLine  = Standard_False;
1096     myLEData     = &myEData(myLE);
1097     myLEGeom     = &(((HLRBRep_EdgeData*)myLEData)->ChangeGeometry());
1098     myLEMinMax   =   ((HLRBRep_EdgeData*)myLEData)->MinMax();
1099     myLETol      =   ((HLRBRep_EdgeData*)myLEData)->Tolerance();
1100     myLEType     =   ((HLRBRep_Curve   *)myLEGeom)->GetType();
1101   }
1102   if (((HLRBRep_EdgeData*)myLEData)->Vertical()) {
1103     NextEdge();
1104     return;
1105   }
1106   if (((HLRBRep_EdgeData*)myLEData)->HideCount() > myHideCount-2) {
1107     NextEdge();
1108     return;
1109   }
1110   if (((HLRBRep_EdgeData*)myLEData)->Status().AllHidden()) {
1111     NextEdge();
1112     return;
1113   }
1114   if (((MaxFace1 - MinLEdg1) & 0x80008000) != 0 ||
1115       ((MaxLEdg1 - MinFace1) & 0x80008000) != 0 ||
1116       ((MaxFace2 - MinLEdg2) & 0x80008000) != 0 ||
1117       ((MaxLEdg2 - MinFace2) & 0x80008000) != 0 ||
1118       ((MaxFace3 - MinLEdg3) & 0x80008000) != 0 ||
1119       ((MaxLEdg3 - MinFace3) & 0x80008000) != 0 ||
1120       ((MaxFace4 - MinLEdg4) & 0x80008000) != 0 ||
1121       ((MaxLEdg4 - MinFace4) & 0x80008000) != 0 ||
1122       ((MaxFace5 - MinLEdg5) & 0x80008000) != 0 ||
1123       ((MaxLEdg5 - MinFace5) & 0x80008000) != 0 ||
1124       ((MaxFace6 - MinLEdg6) & 0x80008000) != 0 ||
1125       ((MaxLEdg6 - MinFace6) & 0x80008000) != 0 ||
1126       ((MaxFace7 - MinLEdg7) & 0x80008000) != 0 ||
1127       ((MaxLEdg7 - MinFace7) & 0x80008000) != 0 ||
1128       ((MaxFace8 - MinLEdg8) & 0x80008000) != 0) { //-- rejection en z 
1129     NextEdge();
1130     return;
1131   }
1132   if (((HLRBRep_Surface*)iFaceGeom)->IsAbove
1133       (iFaceBack,myLEGeom,(Standard_Real)myLETol)) {
1134     NextEdge();
1135     return;
1136   }
1137   return;               // edge is OK
1138 }
1139
1140 //=======================================================================
1141 //function : Edge
1142 //purpose  : 
1143 //=======================================================================
1144
1145 Standard_Integer HLRBRep_Data::Edge () const
1146 {
1147   if (iFaceTest) return myFaceItr2.Edge();
1148   else           return myEdgeIndices(myCurSortEd);
1149 }
1150
1151 //=======================================================================
1152 //function : InitInterference
1153 //purpose  : 
1154 //=======================================================================
1155
1156 void HLRBRep_Data::InitInterference ()
1157 {
1158   myLLProps.SetCurve(myLEGeom);
1159   myFaceItr1.InitEdge(*((HLRBRep_FaceData*)iFaceData));
1160   myNbPoints = myNbSegments = iInterf = 0;
1161   NextInterference();
1162 }
1163
1164 //=======================================================================
1165 //function : NextInterference
1166 //purpose  : 
1167 //=======================================================================
1168
1169 void HLRBRep_Data::NextInterference ()
1170 {
1171   // are there more intersections on the current edge
1172   iInterf++;
1173 //  Standard_Integer miniWire1,miniWire2;
1174 //  Standard_Integer maxiWire1,maxiWire2,maxiWire3,maxiWire4;
1175
1176   while (!MoreInterference() && myFaceItr1.MoreEdge()) {
1177     
1178     // rejection of current wire
1179     if (myFaceItr1.BeginningOfWire()) {
1180       Standard_Address MinMaxWire = myFaceItr1.Wire()->MinMax();
1181       if (((MaxWire1 - MinLEdg1) & 0x80008000) != 0 ||
1182           ((MaxLEdg1 - MinWire1) & 0x80008000) != 0 ||
1183           ((MaxWire2 - MinLEdg2) & 0x80008000) != 0 ||
1184           ((MaxLEdg2 - MinWire2) & 0x80008000) != 0 ||
1185           ((MaxWire3 - MinLEdg3) & 0x80008000) != 0 ||
1186           ((MaxLEdg3 - MinWire3) & 0x80008000) != 0 ||
1187           ((MaxWire4 - MinLEdg4) & 0x80008000) != 0 ||
1188           ((MaxLEdg4 - MinWire4) & 0x80008000) != 0 ||
1189           ((MaxWire5 - MinLEdg5) & 0x80008000) != 0 ||
1190           ((MaxLEdg5 - MinWire5) & 0x80008000) != 0 ||
1191           ((MaxWire6 - MinLEdg6) & 0x80008000) != 0 ||
1192           ((MaxLEdg6 - MinWire6) & 0x80008000) != 0 ||
1193           ((MaxWire7 - MinLEdg7) & 0x80008000) != 0 ||
1194           ((MaxLEdg7 - MinWire7) & 0x80008000) != 0 ||
1195           ((MaxWire8 - MinLEdg8) & 0x80008000) != 0) { //-- Rejection en Z
1196         myFaceItr1.SkipWire();
1197         continue;
1198       }
1199     }
1200     myFE         = myFaceItr1.Edge();
1201     myFEOri      = myFaceItr1.Orientation();
1202     myFEOutLine  = myFaceItr1.OutLine    ();
1203     myFEInternal = myFaceItr1.Internal   ();
1204     myFEDouble   = myFaceItr1.Double     ();
1205     myFEData = &myEData(myFE);
1206     myFEGeom = &(((HLRBRep_EdgeData*)myFEData)->ChangeGeometry());
1207     myFETol  =   ((HLRBRep_EdgeData*)myFEData)->Tolerance();
1208     myFEType =   ((HLRBRep_Curve   *)myFEGeom)->GetType();
1209
1210     
1211     if (myFEOri == TopAbs_FORWARD ||
1212         myFEOri == TopAbs_REVERSED) {
1213       // Edge from the boundary
1214       if (!((HLRBRep_EdgeData*)myFEData)->Vertical() && !myFEDouble) {
1215         // not a vertical edge and not a double Edge
1216         Standard_Address MinMaxFEdg = ((HLRBRep_EdgeData*)myFEData)->MinMax();
1217         //-- -----------------------------------------------------------------------
1218         //-- Max - Min doit etre positif pour toutes les directions 
1219         //--
1220         //-- Rejection 1   (FEMax-LEMin)& 0x80008000  !=0
1221         //--
1222         //--                   FE Min ...........  FE Max 
1223         //--                                                LE Min ....   LE Max   
1224         //-- 
1225         //-- Rejection 2   (LEMax-FEMin)& 0x80008000  !=0
1226         //--                            FE Min ...........  FE Max 
1227         //--     LE Min ....   LE Max
1228         //-- ----------------------------------------------------------------------     
1229
1230         if(((TableauRejection *)myReject)->
1231            NoIntersection(myLE,myFE) == Standard_False) { 
1232
1233           
1234           if (((MaxFEdg1 - MinLEdg1) & 0x80008000) == 0 &&
1235               ((MaxLEdg1 - MinFEdg1) & 0x80008000) == 0 &&
1236               ((MaxFEdg2 - MinLEdg2) & 0x80008000) == 0 &&
1237               ((MaxLEdg2 - MinFEdg2) & 0x80008000) == 0 &&
1238               ((MaxFEdg3 - MinLEdg3) & 0x80008000) == 0 &&
1239               ((MaxLEdg3 - MinFEdg3) & 0x80008000) == 0 &&
1240               ((MaxFEdg4 - MinLEdg4) & 0x80008000) == 0 &&
1241               ((MaxLEdg4 - MinFEdg4) & 0x80008000) == 0 &&
1242               ((MaxFEdg5 - MinLEdg5) & 0x80008000) == 0 &&
1243               ((MaxLEdg5 - MinFEdg5) & 0x80008000) == 0 &&
1244               ((MaxFEdg6 - MinLEdg6) & 0x80008000) == 0 &&
1245               ((MaxLEdg6 - MinFEdg6) & 0x80008000) == 0 &&
1246               ((MaxFEdg7 - MinLEdg7) & 0x80008000) == 0 && 
1247               ((MaxLEdg7 - MinFEdg7) & 0x80008000) == 0 && 
1248               ((MaxFEdg8 - MinLEdg8) & 0x80008000) == 0) {   //-- Rejection en Z
1249             // not rejected perform intersection
1250             Standard_Boolean rej = Standard_False;
1251             if (myLE == myFE) { // test if an auto-intersection is not usefull
1252               if (((HLRBRep_EdgeData*)myLEData)->AutoIntersectionDone()) {
1253                 ((HLRBRep_EdgeData*)myLEData)->
1254                   AutoIntersectionDone(Standard_True);
1255                 if (((HLRBRep_EdgeData*)myLEData)->Simple()) {
1256                   rej = Standard_True;
1257                 }
1258               }
1259             }
1260             if (!rej) {
1261               nbCal1Intersection++;
1262               Standard_Boolean h1 = Standard_False;
1263               Standard_Boolean e1 = Standard_False;
1264               Standard_Boolean h2 = Standard_False;
1265               Standard_Boolean e2 = Standard_False;
1266               mySameVertex = Standard_False;
1267               
1268               if (myLE == myFE) {
1269                 myIntersected = Standard_True;
1270                 mySameVertex  = Standard_False;
1271               }
1272               else {
1273                 myIntersected = Standard_True;
1274                 if (SameVertex(Standard_True ,Standard_True )) {
1275                   mySameVertex = Standard_True;
1276                   h1           = Standard_True;
1277                   h2           = Standard_True;
1278                 }
1279                 if (SameVertex(Standard_True ,Standard_False)) {
1280                   mySameVertex = Standard_True;
1281                   h1           = Standard_True;
1282                   e2           = Standard_True;
1283                 }
1284                 if (SameVertex(Standard_False,Standard_True )) {
1285                   mySameVertex = Standard_True;
1286                   e1           = Standard_True;
1287                   h2           = Standard_True;
1288                 }
1289                 if (SameVertex(Standard_False,Standard_False)) {
1290                   mySameVertex = Standard_True;
1291                   e1           = Standard_True;
1292                   e2           = Standard_True;
1293                 }
1294               }
1295               
1296               myNbPoints = myNbSegments = 0;
1297               iInterf = 1;
1298               
1299               if (myIntersected) {           // compute real intersection
1300                 nbCal2Intersection++;
1301                 
1302                 Standard_Real da1 = 0;
1303                 Standard_Real db1 = 0;
1304                 Standard_Real da2 = 0;
1305                 Standard_Real db2 = 0;
1306                 
1307                 if (mySameVertex || myLE == myFE) {
1308                   if (h1) da1 = CutLar;
1309                   if (e1) db1 = CutLar;
1310                   if (h2) da2 = CutLar;
1311                   if (e2) db2 = CutLar;
1312                 }
1313                 Standard_Integer NoInter=0;
1314                 if (myLE == myFE) {
1315                   myIntersector.Perform(myLEData,da1,db1);
1316                 }
1317                 else {
1318                   Standard_Real su,sv;
1319                   ((TableauRejection *)myReject)->
1320                     GetSingleIntersection(myLE,myFE,su,sv);
1321                   if(su!=RealLast()) { 
1322                     myIntersector.SimulateOnePoint(myLEData,su,myFEData,sv);
1323                     //-- cout<<"p";
1324                   }
1325                   else { 
1326                     myIntersector.Perform
1327                       (myLE,myLEData,da1,db1,
1328                        myFE,myFEData,da2,db2,mySameVertex);
1329                     if(myIntersector.IsDone()) { 
1330                       if(myIntersector.NbPoints() == 1 &&
1331                          myIntersector.NbSegments()==0) { 
1332                           ((TableauRejection *)myReject)->
1333                             SetIntersection(myLE,myFE,myIntersector.Point(1));
1334                       }
1335                     }
1336                   }
1337                   NoInter=0;
1338                 }         
1339                 if(NoInter) { 
1340                   myNbPoints = myNbSegments = 0;
1341                 }
1342                 else { 
1343                   if (myIntersector.IsDone()) {
1344                     myNbPoints   = myIntersector.NbPoints();
1345                     myNbSegments = myIntersector.NbSegments();
1346                     if ((myNbSegments + myNbPoints) > 0) { 
1347                       nbOkIntersection++;
1348                     }
1349                     else { 
1350                       ((TableauRejection *)myReject)->
1351                         SetNoIntersection(myLE,myFE);
1352                     }
1353                   }
1354                   else {
1355                     myNbPoints = myNbSegments = 0;
1356 #ifdef HLRBREP_DEB
1357                     cout << "HLRBRep_Data::NextInterference : "; 
1358                     if (myLE == myFE) 
1359                       cout << "Edge " << myLE 
1360                         << " : Intersection not done" << endl;
1361                     else
1362                       cout << "Edges " << myLE << " , " << myFE
1363                         << " : Intersection not done" << endl;
1364 #endif
1365                   }
1366                 }
1367               }
1368               nbPtIntersection  += myNbPoints;
1369               nbSegIntersection += myNbSegments;
1370             }
1371           }
1372           else { 
1373 #if 0
1374             printf("\n Rejection myFE:%5d   myLE:%5d\n",myFE,myLE);
1375 #endif
1376           }
1377         }
1378         else { 
1379           //-- cout<<"+";
1380         }
1381       }
1382     }
1383     // next edge in face
1384     myFaceItr1.NextEdge();
1385   }
1386 }
1387
1388 //=======================================================================
1389 //function : RejectedInterference
1390 //purpose  : 
1391 //=======================================================================
1392
1393 Standard_Boolean HLRBRep_Data::RejectedInterference ()
1394 {
1395   if (iInterf <= myNbPoints) {
1396     return RejectedPoint(myIntersector.Point(iInterf),
1397                          TopAbs_EXTERNAL,0);
1398   }
1399   else {
1400     Standard_Integer n = iInterf - myNbPoints;
1401     Standard_Boolean firstPoint = (n & 1) != 0;
1402     Standard_Integer nseg=n>>1;
1403     if (firstPoint)
1404       nseg++;
1405     Standard_Real pf = ((HLRBRep_Curve*)myLEGeom)->Parameter3d
1406       (myIntersector.Segment(nseg).FirstPoint().ParamOnFirst());
1407     Standard_Real pl = ((HLRBRep_Curve*)myLEGeom)->Parameter3d
1408       (myIntersector.Segment(nseg).LastPoint ().ParamOnFirst());
1409     if (pf > pl)
1410       firstPoint = !firstPoint;
1411
1412     if (firstPoint) { 
1413       Standard_Boolean ret1 = RejectedPoint
1414         (myIntersector.Segment(nseg).FirstPoint(),TopAbs_FORWARD,nseg);      
1415       return(ret1);
1416     }
1417     else { 
1418       Standard_Boolean ret2 = RejectedPoint
1419         (myIntersector.Segment(nseg).LastPoint (),TopAbs_REVERSED,-nseg);
1420       return(ret2);
1421     }
1422   }
1423 }
1424
1425 //=======================================================================
1426 //function : AboveInterference
1427 //purpose  : 
1428 //=======================================================================
1429
1430 Standard_Boolean HLRBRep_Data::AboveInterference ()
1431 { return myAboveIntf; }
1432
1433 //=======================================================================
1434 //function : LocalLEGeometry2D
1435 //purpose  : 
1436 //=======================================================================
1437
1438 void HLRBRep_Data::LocalLEGeometry2D (const Standard_Real Param,
1439                                       gp_Dir2d& Tg,
1440                                       gp_Dir2d& Nm,
1441                                       Standard_Real& Cu)
1442 {
1443   myLLProps.SetParameter(Param);
1444   if (!myLLProps.IsTangentDefined())
1445     Standard_Failure::Raise("HLRBRep_Data::LocalGeometry2D");
1446   myLLProps.Tangent(Tg);
1447   Cu = myLLProps.Curvature();
1448   if (Cu > Epsilon(1.) && !Precision::IsInfinite(Cu)) myLLProps.Normal(Nm);
1449   else Nm = gp_Dir2d(-Tg.Y(),Tg.X());
1450 }
1451
1452 //=======================================================================
1453 //function : LocalFEGeometry2D
1454 //purpose  : 
1455 //=======================================================================
1456
1457 void HLRBRep_Data::LocalFEGeometry2D (const Standard_Integer FE,
1458                                       const Standard_Real Param,
1459                                       gp_Dir2d& Tg,
1460                                       gp_Dir2d& Nm,
1461                                       Standard_Real& Cu)
1462 {
1463   myFLProps.SetCurve(&(myEData(FE).ChangeGeometry()));
1464   myFLProps.SetParameter(Param);
1465   if (!myFLProps.IsTangentDefined())
1466     Standard_Failure::Raise("HLRBRep_Data::LocalGeometry2D");
1467   myFLProps.Tangent(Tg);
1468   Cu = myFLProps.Curvature();
1469   if (Cu > Epsilon(1.) && !Precision::IsInfinite(Cu)) myFLProps.Normal(Nm);
1470   else Nm = gp_Dir2d(-Tg.Y(),Tg.X());
1471 }
1472
1473 //=======================================================================
1474 //function : EdgeState
1475 //purpose  : 
1476 //=======================================================================
1477
1478 void HLRBRep_Data::EdgeState (const Standard_Real p1,
1479                               const Standard_Real p2,
1480                               TopAbs_State& stbef,
1481                               TopAbs_State& staft)
1482 {
1483   // compute the state of The Edge near the Intersection
1484   // this method should give the states before and after
1485   // it should get the parameters on the surface
1486
1487   Standard_Real pu,pv;
1488   if (HLRBRep_EdgeFaceTool::UVPoint(p2,myFEGeom,iFaceGeom,pu,pv))
1489   {
1490     mySLProps.SetParameters(pu,pv);
1491     if (mySLProps.IsNormalDefined())
1492     {
1493       gp_Dir NrmFace  = mySLProps.Normal();
1494
1495       gp_Pnt Pbid;
1496       gp_Vec TngEdge;
1497       ((HLRBRep_Curve*)myLEGeom)->D1(p1,Pbid,TngEdge);
1498
1499       const gp_Trsf& TI = myProj.InvertedTransformation();
1500       gp_Dir V;
1501       if (myProj.Perspective()) {
1502         gp_Pnt2d P2d;
1503         myProj.Project(Pbid,P2d);
1504         V = gp_Dir(P2d.X(),P2d.Y(),-myProj.Focus());
1505       }
1506       else {
1507         V = gp_Dir(0,0,-1);
1508       }
1509       V.Transform(TI);
1510       if (NrmFace.Dot(V) > 0.)
1511         NrmFace.Reverse();
1512     
1513       const Standard_Real scal = (TngEdge.SquareMagnitude()>1.e-10)? NrmFace.Dot(gp_Dir(TngEdge)) : 0.;
1514
1515       if      (scal >  myToler*10) {stbef = TopAbs_IN ;staft = TopAbs_OUT;}
1516       else if (scal < -myToler*10) {stbef = TopAbs_OUT;staft = TopAbs_IN ;}
1517       else                         {stbef = TopAbs_ON ;staft = TopAbs_ON ;}
1518     }
1519     else {
1520       stbef = TopAbs_OUT;
1521       staft = TopAbs_OUT;
1522 #ifdef HLRBREP_DEB
1523     cout << "HLRBRep_Data::EdgeState : undefined" << endl;
1524 #endif
1525     }
1526   }
1527   else {
1528     stbef = TopAbs_OUT;
1529     staft = TopAbs_OUT; 
1530 #ifdef HLRBREP_DEB
1531     cout << "HLRBRep_Data::EdgeState : undefined" << endl;
1532 #endif
1533   }
1534 }
1535
1536 //=======================================================================
1537 //function : HidingStartLevel
1538 //purpose  : 
1539 //=======================================================================
1540
1541 Standard_Integer 
1542 HLRBRep_Data::HidingStartLevel (const Standard_Integer E,
1543                                 const HLRBRep_EdgeData& ED,
1544                                 const HLRAlgo_InterferenceList& IL)
1545 {
1546   Standard_Boolean Loop;
1547   HLRAlgo_ListIteratorOfInterferenceList It;
1548   const HLRBRep_Curve& EC = ED.Geometry();
1549   Standard_Real sta = EC.Parameter3d(EC.FirstParameter());
1550   Standard_Real end = EC.Parameter3d(EC.LastParameter());
1551   Standard_Real tolpar = (end - sta) * 0.01;
1552   Standard_Real param;
1553   Loop = Standard_True;
1554   It.Initialize(IL);
1555   
1556   while(It.More() && Loop) {
1557     param = It.Value().Intersection().Parameter();
1558     if (param > end)
1559       Loop = Standard_False;
1560     else {
1561       if (Abs(param-sta) > Abs(param-end))
1562         end = param;
1563       else
1564         sta = param;
1565     }
1566     It.Next();
1567   }
1568   param = 0.5 * (sta + end);
1569   Standard_Integer level = 0;
1570   /*TopAbs_State st = */Classify(E,ED,Standard_True,level,param);
1571   Loop = Standard_True;
1572   It.Initialize(IL);
1573
1574   while(It.More() && Loop) {
1575     HLRAlgo_Interference& Int = It.Value();
1576     Standard_Real p = Int.Intersection().Parameter();
1577     if (p < param - tolpar) {
1578       switch (Int.Transition()) {
1579         
1580       case TopAbs_FORWARD  :
1581         level -= Int.Intersection().Level();
1582         break;
1583       case TopAbs_REVERSED :
1584         level += Int.Intersection().Level();
1585         break;
1586       case TopAbs_EXTERNAL :
1587       case TopAbs_INTERNAL :
1588           default :
1589             break;
1590       }
1591     }
1592     else if (p > param + tolpar)
1593       Loop = Standard_False;
1594     else {
1595 #ifdef HLRBREP_DEB  
1596       cout << "HLRBRep_Data::HidingStartLevel : ";
1597       cout << "Bad Parameter." << endl;
1598 #endif
1599     }
1600     It.Next();
1601   }
1602   return level;
1603 }
1604
1605 //=======================================================================
1606 //function : Compare
1607 //purpose  : 
1608 //=======================================================================
1609
1610 TopAbs_State HLRBRep_Data::Compare (const Standard_Integer E,
1611                                     const HLRBRep_EdgeData& ED)
1612 {
1613   Standard_Integer level = 0;
1614   Standard_Real parbid = 0.;
1615   return Classify(E,ED,Standard_False,level,parbid);
1616 }
1617
1618 //=======================================================================
1619 //function : OrientOutLine
1620 //purpose  : 
1621 //=======================================================================
1622
1623
1624 Standard_Boolean HLRBRep_Data::OrientOutLine (const Standard_Integer I, HLRBRep_FaceData& FD)
1625 {
1626   (void)I; // avoid compiler warning
1627
1628   const Handle(HLRAlgo_WiresBlock)& wb = FD.Wires();
1629   Standard_Integer nw = wb->NbWires();
1630   Standard_Integer iw1,ie1,ne1;
1631   const gp_Trsf& T  = myProj.Transformation();
1632   const gp_Trsf& TI = myProj.InvertedTransformation();
1633   Standard_Boolean inverted       = Standard_False;
1634   Standard_Boolean FirstInversion = Standard_True;
1635   
1636   for (iw1 = 1; iw1 <= nw; iw1++) {
1637     const Handle(HLRAlgo_EdgesBlock)& eb1 = wb->Wire(iw1);
1638     ne1 = eb1->NbEdges();
1639     
1640     for (ie1 = 1; ie1 <= ne1; ie1++) {
1641       myFE = eb1->Edge(ie1);
1642       HLRBRep_EdgeData* ed1 = &(myEData(myFE));
1643       if (eb1->Double (ie1) ||
1644           eb1->IsoLine(ie1) ||
1645           ed1->Vertical()) ed1->Used(Standard_True );
1646       else                 ed1->Used(Standard_False);
1647       if ((eb1->OutLine(ie1) || eb1->Internal(ie1)) &&
1648           !ed1->Vertical()) {
1649         Standard_Real p,pu,pv,r;
1650         myFEGeom = &(ed1->ChangeGeometry());
1651         const HLRBRep_Curve& EC = ed1->Geometry();
1652         Standard_Integer vsta = ed1->VSta();
1653         Standard_Integer vend = ed1->VEnd();
1654         if      (vsta == 0 &&
1655                  vend == 0) p = 0;
1656         else if (vsta == 0) p = EC.Parameter3d(EC.LastParameter ());
1657         else if (vend == 0) p = EC.Parameter3d(EC.FirstParameter());
1658         else                p = EC.Parameter3d((EC.LastParameter () +
1659                                                 EC.FirstParameter()) / 2);
1660         if (HLRBRep_EdgeFaceTool::UVPoint(p,myFEGeom,iFaceGeom,pu,pv)) {
1661           gp_Pnt Pt;
1662           gp_Vec Tg;
1663           mySLProps.SetParameters(pu,pv);
1664           EC.D1(p,Pt,Tg);
1665           gp_Dir V;
1666           if (myProj.Perspective()) {
1667             gp_Pnt2d P2d;
1668             myProj.Project(Pt,P2d);
1669             V = gp_Dir(P2d.X(),P2d.Y(),-myProj.Focus());
1670           }
1671           else {
1672             V = gp_Dir(0,0,-1);
1673           }
1674           V.Transform(TI);
1675           Standard_Real curv = HLRBRep_EdgeFaceTool::CurvatureValue
1676             (iFaceGeom,pu,pv,V);
1677           gp_Vec Nm = mySLProps.Normal();
1678           if (curv == 0) {
1679 #ifdef HLRBREP_DEB  
1680             cout << "HLRBRep_Data::OrientOutLine " << I;
1681             cout << " Edge " << myFE << " : ";
1682             cout << "CurvatureValue == 0." << endl;
1683 #endif
1684           }
1685           if (curv > 0)
1686             Nm.Reverse();
1687           Tg.Transform(T);
1688           Pt.Transform(T);
1689           Nm.Transform(T);
1690           Nm.Cross(Tg);
1691           if (Tg.Magnitude() < gp::Resolution()) {
1692 #ifdef HLRBREP_DEB  
1693             cout << "HLRBRep_Data::OrientOutLine " << I;
1694             cout << " Edge " << myFE << " : ";
1695             cout << "Tg.Magnitude() == 0." << endl;
1696 #endif  
1697           }
1698           if (myProj.Perspective())
1699             r = Nm.Z() * myProj.Focus() - 
1700               ( Nm.X() * Pt.X() + Nm.Y() * Pt.Y() + Nm.Z() * Pt.Z() );
1701           else
1702             r = Nm.Z();
1703           myFEOri = (r > 0) ? TopAbs_FORWARD : TopAbs_REVERSED;
1704           if (!FD.Cut() && FD.Closed() && FirstInversion) {
1705             if ((eb1->Orientation(ie1) == myFEOri) != 
1706                 (FD.Orientation() == TopAbs_FORWARD)) {
1707               FirstInversion = Standard_False;
1708               inverted = Standard_True;
1709             }
1710           }
1711           eb1->Orientation(ie1,myFEOri);
1712         }
1713         else {
1714 #ifdef HLRBREP_DEB  
1715           cout << "HLRBRep_Data::OrientOutLine " << I;
1716           cout << " Edge " << myFE << " : ";
1717           cout << "UVPoint not found, OutLine not Oriented" << endl;
1718 #endif
1719         }
1720         ed1->Used(Standard_True);
1721       }
1722     }
1723   }
1724   return inverted;
1725 }
1726
1727 //=======================================================================
1728 //function : OrientOthEdge
1729 //purpose  : 
1730 //=======================================================================
1731
1732 void HLRBRep_Data::OrientOthEdge (const Standard_Integer I,
1733                                   HLRBRep_FaceData& FD)
1734 {
1735   Standard_Real p,pu,pv,r;
1736   const Handle(HLRAlgo_WiresBlock)& wb = FD.Wires();
1737   Standard_Integer nw = wb->NbWires();
1738   Standard_Integer iw1,ie1,ne1;
1739   const gp_Trsf& T = myProj.Transformation();
1740   
1741   for (iw1 = 1; iw1 <= nw; iw1++) {
1742     const Handle(HLRAlgo_EdgesBlock)& eb1 = wb->Wire(iw1);
1743     ne1 = eb1->NbEdges();
1744     
1745     for (ie1 = 1; ie1 <= ne1; ie1++) {
1746       myFE    = eb1->Edge       (ie1);
1747       myFEOri = eb1->Orientation(ie1);
1748       HLRBRep_EdgeData* ed1 = &(myEData(myFE));
1749       
1750       if (!ed1->Used()) {
1751         ed1->Used(Standard_True);
1752         myFEGeom = &(ed1->ChangeGeometry());
1753         const HLRBRep_Curve& EC = ed1->Geometry();
1754         p = EC.Parameter3d((EC.LastParameter () +
1755                             EC.FirstParameter()) / 2);
1756         if (HLRBRep_EdgeFaceTool::UVPoint(p,myFEGeom,iFaceGeom,pu,pv)) {
1757           gp_Pnt Pt = EC.Value3D(p);
1758           mySLProps.SetParameters(pu,pv);
1759           gp_Vec Nm = mySLProps.Normal();
1760           Pt.Transform(T);
1761           Nm.Transform(T);
1762           if (myProj.Perspective()) {
1763             r = Nm.Z() * myProj.Focus() - 
1764               ( Nm.X() * Pt.X() + Nm.Y() * Pt.Y() + Nm.Z() * Pt.Z() );
1765           }
1766           else {
1767             r = Nm.Z();
1768           }
1769           if (r < 0) {
1770             myFEOri = TopAbs::Reverse(myFEOri);
1771             eb1->Orientation(ie1,myFEOri);
1772           }
1773         }
1774         else {
1775           cout << "HLRBRep_Data::OrientOthEdge " << I;
1776           cout << " Edge " << myFE << " : ";
1777           cout << "UVPoint not found, Edge not Oriented" << endl;
1778         }
1779       }
1780     }
1781   }
1782 }
1783
1784 //=======================================================================
1785 //function : Classify
1786 //purpose  : 
1787 //=======================================================================
1788
1789 #define REJECT1    \
1790     VertMin[ 0] = (Standard_Integer)((myDeca[ 0]+TotMin[ 0])*mySurD[ 0]); \
1791     VertMax[ 0] = (Standard_Integer)((myDeca[ 0]+TotMax[ 0])*mySurD[ 0]); \
1792     VertMin[ 1] = (Standard_Integer)((myDeca[ 1]+TotMin[ 1])*mySurD[ 1]); \
1793     VertMax[ 1] = (Standard_Integer)((myDeca[ 1]+TotMax[ 1])*mySurD[ 1]); \
1794     VertMin[ 2] = (Standard_Integer)((myDeca[ 2]+TotMin[ 2])*mySurD[ 2]); \
1795     VertMax[ 2] = (Standard_Integer)((myDeca[ 2]+TotMax[ 2])*mySurD[ 2]); \
1796     VertMin[ 3] = (Standard_Integer)((myDeca[ 3]+TotMin[ 3])*mySurD[ 3]); \
1797     VertMax[ 3] = (Standard_Integer)((myDeca[ 3]+TotMax[ 3])*mySurD[ 3]); \
1798     VertMin[ 4] = (Standard_Integer)((myDeca[ 4]+TotMin[ 4])*mySurD[ 4]); \
1799     VertMax[ 4] = (Standard_Integer)((myDeca[ 4]+TotMax[ 4])*mySurD[ 4]); \
1800     VertMin[ 5] = (Standard_Integer)((myDeca[ 5]+TotMin[ 5])*mySurD[ 5]); \
1801     VertMax[ 5] = (Standard_Integer)((myDeca[ 5]+TotMax[ 5])*mySurD[ 5]); \
1802     VertMin[ 6] = (Standard_Integer)((myDeca[ 6]+TotMin[ 6])*mySurD[ 6]); \
1803     VertMax[ 6] = (Standard_Integer)((myDeca[ 6]+TotMax[ 6])*mySurD[ 6]); \
1804     VertMin[ 7] = (Standard_Integer)((myDeca[ 7]+TotMin[ 7])*mySurD[ 7]); \
1805     VertMax[ 7] = (Standard_Integer)((myDeca[ 7]+TotMax[ 7])*mySurD[ 7]); \
1806     VertMin[ 8] = (Standard_Integer)((myDeca[ 8]+TotMin[ 8])*mySurD[ 8]); \
1807     VertMax[ 8] = (Standard_Integer)((myDeca[ 8]+TotMax[ 8])*mySurD[ 8]); \
1808     VertMin[ 9] = (Standard_Integer)((myDeca[ 9]+TotMin[ 9])*mySurD[ 9]); \
1809     VertMax[ 9] = (Standard_Integer)((myDeca[ 9]+TotMax[ 9])*mySurD[ 9]); \
1810     VertMin[10] = (Standard_Integer)((myDeca[10]+TotMin[10])*mySurD[10]); \
1811     VertMax[10] = (Standard_Integer)((myDeca[10]+TotMax[10])*mySurD[10]); \
1812     VertMin[11] = (Standard_Integer)((myDeca[11]+TotMin[11])*mySurD[11]); \
1813     VertMax[11] = (Standard_Integer)((myDeca[11]+TotMax[11])*mySurD[11]); \
1814     VertMin[12] = (Standard_Integer)((myDeca[12]+TotMin[12])*mySurD[12]); \
1815     VertMax[12] = (Standard_Integer)((myDeca[12]+TotMax[12])*mySurD[12]); \
1816     VertMin[13] = (Standard_Integer)((myDeca[13]+TotMin[13])*mySurD[13]); \
1817     VertMax[13] = (Standard_Integer)((myDeca[13]+TotMax[13])*mySurD[13]); \
1818     VertMin[14] = (Standard_Integer)((myDeca[14]+TotMin[14])*mySurD[14]); \
1819     VertMax[14] = (Standard_Integer)((myDeca[14]+TotMax[14])*mySurD[14]); \
1820     VertMin[15] = (Standard_Integer)((myDeca[15]+TotMin[15])*mySurD[15]); \
1821     VertMax[15] = (Standard_Integer)((myDeca[15]+TotMax[15])*mySurD[15]); 
1822
1823 TopAbs_State 
1824 HLRBRep_Data::Classify (const Standard_Integer /*E*/,
1825                         const HLRBRep_EdgeData& ED,
1826                         const Standard_Boolean LevelFlag,
1827                         Standard_Integer& Level,
1828                         const Standard_Real param)
1829 {
1830   nbClassification++;
1831   Standard_Integer VertMin[16],VertMax[16],MinMaxVert[16];
1832   Standard_Real TotMin[16],TotMax[16];
1833   
1834   Standard_Integer i;
1835   Level = 0;
1836   TopAbs_State state = TopAbs_OUT;
1837 //  Standard_Boolean rej = Standard_False;
1838   const HLRBRep_Curve& EC = ED.Geometry();
1839   Standard_Real sta,xsta,ysta,zsta,end,xend,yend,zend;
1840   Standard_Real tol = (Standard_Real)(ED.Tolerance());
1841   
1842   if (LevelFlag) {
1843     sta = param;
1844     myProj.Project(EC.Value3D(sta),xsta,ysta,zsta);
1845     
1846     //-- les rejections sont faites dans l intersecteur a moindre frais 
1847     //-- puisque la surface sera chargee
1848     HLRAlgo::InitMinMax(Precision::Infinite(),
1849                         (Standard_Address)TotMin,
1850                         (Standard_Address)TotMax);
1851     HLRAlgo::UpdateMinMax(xsta,ysta,zsta,
1852                           (Standard_Address)TotMin,
1853                           (Standard_Address)TotMax);
1854     HLRAlgo::EnlargeMinMax(tol,
1855                            (Standard_Address)TotMin,
1856                            (Standard_Address)TotMax);
1857     REJECT1;
1858
1859     HLRAlgo::EncodeMinMax((Standard_Address)VertMin,
1860                           (Standard_Address)VertMax,
1861                           (Standard_Address)MinMaxVert);
1862     if (((MaxFace1 - MinVert1) & 0x80008000) != 0 ||
1863         ((MaxVert1 - MinFace1) & 0x80008000) != 0 ||
1864         ((MaxFace2 - MinVert2) & 0x80008000) != 0 ||
1865         ((MaxVert2 - MinFace2) & 0x80008000) != 0 ||
1866         ((MaxFace3 - MinVert3) & 0x80008000) != 0 ||
1867         ((MaxVert3 - MinFace3) & 0x80008000) != 0 ||
1868         ((MaxFace4 - MinVert4) & 0x80008000) != 0 ||
1869         ((MaxVert4 - MinFace4) & 0x80008000) != 0 ||
1870         ((MaxFace5 - MinVert5) & 0x80008000) != 0 ||
1871         ((MaxVert5 - MinFace5) & 0x80008000) != 0 ||
1872         ((MaxFace6 - MinVert6) & 0x80008000) != 0 ||
1873         ((MaxVert6 - MinFace6) & 0x80008000) != 0 ||
1874         ((MaxFace7 - MinVert7) & 0x80008000) != 0 ||
1875         ((MaxVert7 - MinFace7) & 0x80008000) != 0 ||
1876         ((MaxFace8 - MinVert8) & 0x80008000) != 0) { //-- Rejection en Z 
1877       return state;
1878     }
1879   }
1880   else {
1881     sta  = EC.Parameter3d(EC.FirstParameter());
1882     myProj.Project(EC.Value3D(sta),xsta,ysta,zsta);
1883     
1884     //-- les rejections sont faites dans l intersecteur a moindre frais 
1885     //-- puisque la surface sera chargee
1886     HLRAlgo::InitMinMax(Precision::Infinite(),
1887                         (Standard_Address)TotMin,
1888                         (Standard_Address)TotMax);
1889     HLRAlgo::UpdateMinMax(xsta,ysta,zsta,
1890                           (Standard_Address)TotMin,
1891                           (Standard_Address)TotMax);
1892     HLRAlgo::EnlargeMinMax(tol,
1893                            (Standard_Address)TotMin,
1894                            (Standard_Address)TotMax);
1895
1896     REJECT1; 
1897
1898     HLRAlgo::EncodeMinMax((Standard_Address)VertMin,
1899                           (Standard_Address)VertMax,
1900                           (Standard_Address)MinMaxVert);
1901     if (((MaxFace1 - MinVert1) & 0x80008000) != 0 ||
1902         ((MaxVert1 - MinFace1) & 0x80008000) != 0 ||
1903         ((MaxFace2 - MinVert2) & 0x80008000) != 0 ||
1904         ((MaxVert2 - MinFace2) & 0x80008000) != 0 ||
1905         ((MaxFace3 - MinVert3) & 0x80008000) != 0 ||
1906         ((MaxVert3 - MinFace3) & 0x80008000) != 0 ||
1907         ((MaxFace4 - MinVert4) & 0x80008000) != 0 ||
1908         ((MaxVert4 - MinFace4) & 0x80008000) != 0 ||
1909         ((MaxFace5 - MinVert5) & 0x80008000) != 0 ||
1910         ((MaxVert5 - MinFace5) & 0x80008000) != 0 ||
1911         ((MaxFace6 - MinVert6) & 0x80008000) != 0 ||
1912         ((MaxVert6 - MinFace6) & 0x80008000) != 0 ||
1913         ((MaxFace7 - MinVert7) & 0x80008000) != 0 ||
1914         ((MaxVert7 - MinFace7) & 0x80008000) != 0 ||
1915         ((MaxFace8 - MinVert8) & 0x80008000) != 0) { //-- Rejection en Z 
1916       return state;
1917     }
1918     end = EC.Parameter3d(EC.LastParameter());
1919     myProj.Project(EC.Value3D(end),xend,yend,zend);
1920     
1921     HLRAlgo::InitMinMax(Precision::Infinite(),
1922                         (Standard_Address)TotMin,
1923                         (Standard_Address)TotMax);
1924     HLRAlgo::UpdateMinMax(xend,yend,zend,
1925                           (Standard_Address)TotMin,
1926                           (Standard_Address)TotMax);
1927     HLRAlgo::EnlargeMinMax(tol,
1928                            (Standard_Address)TotMin,
1929                            (Standard_Address)TotMax);
1930
1931     REJECT1;
1932
1933     HLRAlgo::EncodeMinMax((Standard_Address)VertMin,
1934                           (Standard_Address)VertMax,
1935                           (Standard_Address)MinMaxVert);
1936     if (((MaxFace1 - MinVert1) & 0x80008000) != 0 ||
1937         ((MaxVert1 - MinFace1) & 0x80008000) != 0 ||
1938         ((MaxFace2 - MinVert2) & 0x80008000) != 0 ||
1939         ((MaxVert2 - MinFace2) & 0x80008000) != 0 ||
1940         ((MaxFace3 - MinVert3) & 0x80008000) != 0 ||
1941         ((MaxVert3 - MinFace3) & 0x80008000) != 0 ||
1942         ((MaxFace4 - MinVert4) & 0x80008000) != 0 ||
1943         ((MaxVert4 - MinFace4) & 0x80008000) != 0 ||
1944         ((MaxFace5 - MinVert5) & 0x80008000) != 0 ||
1945         ((MaxVert5 - MinFace5) & 0x80008000) != 0 ||
1946         ((MaxFace6 - MinVert6) & 0x80008000) != 0 ||
1947         ((MaxVert6 - MinFace6) & 0x80008000) != 0 ||
1948         ((MaxFace7 - MinVert7) & 0x80008000) != 0 ||
1949         ((MaxVert7 - MinFace7) & 0x80008000) != 0 ||
1950         ((MaxFace8 - MinVert8) & 0x80008000) != 0) { //-- Rejection en Z 
1951       return state;
1952     }
1953     sta = 0.4 * sta + 0.6 * end; // dangerous if it is the middle
1954     myProj.Project(EC.Value3D(sta),xsta,ysta,zsta);
1955     
1956     //-- les rejections sont faites dans l intersecteur a moindre frais 
1957     //-- puisque la surface sera chargee
1958     HLRAlgo::InitMinMax(Precision::Infinite(),
1959                         (Standard_Address)TotMin,
1960                         (Standard_Address)TotMax);
1961     HLRAlgo::UpdateMinMax(xsta,ysta,zsta,
1962                           (Standard_Address)TotMin,
1963                           (Standard_Address)TotMax);
1964     HLRAlgo::EnlargeMinMax(tol,
1965                            (Standard_Address)TotMin,
1966                            (Standard_Address)TotMax);
1967     REJECT1;
1968
1969     HLRAlgo::EncodeMinMax((Standard_Address)VertMin,
1970                           (Standard_Address)VertMax,
1971                           (Standard_Address)MinMaxVert);
1972
1973
1974
1975 #if 0 
1976         {
1977           Standard_Integer qwe,qwep8,q,q1,q2;
1978           printf("\n E:%d -------\n",E);
1979           for(qwe=0; qwe<8; qwe++) {
1980             q1 = (((Standard_Integer*)iFaceMinMax)[qwe   ]) & 0x0000FFFF;
1981             q2 = (((Standard_Integer*)iFaceMinMax)[qwe+8]) & 0x0000FFFF; 
1982             printf("\nFace: %3d    %6d  ->  %6d    delta : %6d ",qwe,q1,q2,q2-q1);
1983             
1984             q1 = (((Standard_Integer*)MinMaxVert)[qwe   ]) & 0x0000FFFF;
1985             q2 = (((Standard_Integer*)MinMaxVert)[qwe+8]) & 0x0000FFFF; 
1986             printf("  |  Vtx: %3d    %6d  ->  %6d    delta : %6d ",qwe,q1,q2,q2-q1);
1987             
1988             q1 = ((((Standard_Integer*)iFaceMinMax)[qwe  ])>>16) & 0x0000FFFF;
1989             q2 = ((((Standard_Integer*)iFaceMinMax)[qwe+8])>>16) & 0x0000FFFF; 
1990             printf("\nFace: %3d    %6d  ->  %6d    delta : %6d ",qwe,q1,q2,q2-q1);
1991             
1992             q1 = ((((Standard_Integer*)MinMaxVert)[qwe  ])>>16) & 0x0000FFFF;
1993             q2 = ((((Standard_Integer*)MinMaxVert)[qwe+8])>>16) & 0x0000FFFF; 
1994             printf("  |  Vtx: %3d    %6d  ->  %6d    delta : %6d ",qwe,q1,q2,q2-q1);
1995           }
1996           printf("\n");
1997
1998
1999           for(qwe=0,qwep8=8; qwe<8; qwe++,qwep8++) { 
2000             q = ((Standard_Integer*)iFaceMinMax)[qwep8]- ((Standard_Integer*)MinMaxVert)[qwe];
2001             q1 = q>>16;
2002             q2 = (q& 0x0000FFFF);
2003             printf("\nmot: %3d    q1 = %+10d    q2=%+10d    Mask : %d",qwe,(q1>32768)? (32768-q1) : q1,(q2>32768)? (32768-q2) : q2,q&0x80008000);
2004           }
2005           for(qwe=0,qwep8=8; qwe<8; qwe++,qwep8++) { 
2006             q = ((Standard_Integer*)MinMaxVert)[qwep8]- ((Standard_Integer*)iFaceMinMax)[qwe];
2007             q1 = q>>16;
2008             q2 = (q& 0x0000FFFF);
2009             printf("\nmot: %3d    q1 = %+10d    q2=%+10d    Mask : %d",qwe+8,(q1>32768)? (32768-q1) : q1,(q2>32768)? (32768-q2) : q2,q&0x80008000);
2010           }
2011           cout<<endl;
2012         }
2013  #endif
2014
2015
2016
2017
2018     if (((MaxFace1 - MinVert1) & 0x80008000) != 0 ||
2019         ((MaxVert1 - MinFace1) & 0x80008000) != 0 ||
2020         ((MaxFace2 - MinVert2) & 0x80008000) != 0 ||
2021         ((MaxVert2 - MinFace2) & 0x80008000) != 0 ||
2022         ((MaxFace3 - MinVert3) & 0x80008000) != 0 ||
2023         ((MaxVert3 - MinFace3) & 0x80008000) != 0 ||
2024         ((MaxFace4 - MinVert4) & 0x80008000) != 0 ||
2025         ((MaxVert4 - MinFace4) & 0x80008000) != 0 ||
2026         ((MaxFace5 - MinVert5) & 0x80008000) != 0 ||
2027         ((MaxVert5 - MinFace5) & 0x80008000) != 0 ||
2028         ((MaxFace6 - MinVert6) & 0x80008000) != 0 ||
2029         ((MaxVert6 - MinFace6) & 0x80008000) != 0 ||
2030         ((MaxFace7 - MinVert7) & 0x80008000) != 0 ||
2031         ((MaxVert7 - MinFace7) & 0x80008000) != 0 ||
2032         ((MaxFace8 - MinVert8) & 0x80008000) != 0) { //-- Rejection en Z 
2033       return state;
2034     }
2035   }
2036
2037   nbCal3Intersection++;
2038   gp_Pnt   PLim;
2039   gp_Pnt2d Psta;
2040   Psta = EC.Value  (sta);
2041   PLim = EC.Value3D(sta);
2042   
2043
2044   static int aff=0;
2045   if(aff) {
2046     static Standard_Integer nump1=0;
2047     printf("\npoint PNR%d  %g %g %g",++nump1,PLim.X(),PLim.Y(),PLim.Z());
2048   }
2049   
2050   gp_Lin L = myProj.Shoot(Psta.X(),Psta.Y());
2051   Standard_Real wLim = ElCLib::Parameter(L,PLim);
2052   myIntersector.Perform(L,wLim);
2053   if (myIntersector.IsDone()) {
2054     Standard_Integer nbPoints = myIntersector.NbPoints();
2055     if (nbPoints > 0) {
2056       Standard_Real TolZ = myBigSize * 0.000001;
2057       if (iFaceTest) {
2058         if (!myLEOutLine && !myLEInternal) TolZ = myBigSize * 0.001;
2059         else                               TolZ = myBigSize * 0.01;
2060       }
2061       wLim -= TolZ;
2062       Standard_Real PeriodU,PeriodV,UMin =0.,UMax =0.,VMin =0.,VMax =0.;
2063       if (((HLRBRep_Surface*)iFaceGeom)->IsUPeriodic()) { 
2064         PeriodU = ((HLRBRep_Surface*)iFaceGeom)->UPeriod();
2065         UMin = ((HLRBRep_Surface*)iFaceGeom)->FirstUParameter();
2066         UMax = ((HLRBRep_Surface*)iFaceGeom)->LastUParameter();
2067       }
2068       else 
2069         PeriodU = 0.;
2070       if (((HLRBRep_Surface*)iFaceGeom)->IsVPeriodic()) { 
2071         PeriodV = ((HLRBRep_Surface*)iFaceGeom)->VPeriod();
2072         VMin = ((HLRBRep_Surface*)iFaceGeom)->FirstVParameter();
2073         VMax = ((HLRBRep_Surface*)iFaceGeom)->LastVParameter();
2074       }
2075       else 
2076         PeriodV = 0;
2077       gp_Pnt PInter;
2078       Standard_Real u,v,w;
2079       IntCurveSurface_TransitionOnCurve Tr;
2080       
2081       for (i = 1; i <= nbPoints; i++) {
2082         Standard_Boolean InsideRestriction = Standard_False;
2083         myIntersector.CSPoint(i).Values(PInter,u,v,w,Tr);
2084         if (w < wLim) {
2085           if (PeriodU)
2086             while (u > UMin) 
2087               u -= PeriodU;
2088           if (PeriodV)
2089             while (v > VMin)
2090               v -= PeriodV;
2091 //        Standard_Real UInit = u;
2092           Standard_Real VInit = v;
2093           
2094           do {
2095             v = VInit;
2096             
2097             do {
2098               gp_Pnt2d pnt2d(u,v);
2099               if (myClassifier->Classify(pnt2d,0.0)!=TopAbs_OUT) {
2100                 InsideRestriction = Standard_True;
2101                 state = TopAbs_IN;
2102                 Level++;
2103                 if (!LevelFlag) {
2104                   return state;
2105                 }
2106               }
2107               v += PeriodV;
2108             }
2109             while (PeriodV && v < VMax && !InsideRestriction);
2110             u += PeriodU;
2111           }
2112           while (PeriodU && u < UMax && !InsideRestriction);
2113         }
2114       }
2115     }
2116   }
2117   return state;
2118 }
2119
2120
2121 //=======================================================================
2122 //function : SimplClassify
2123 //purpose  : 
2124 //=======================================================================
2125
2126 TopAbs_State HLRBRep_Data::SimplClassify (const Standard_Integer /*E*/,
2127                                           const HLRBRep_EdgeData& ED,
2128                                           const Standard_Integer Nbp,
2129                                           const Standard_Real p1,
2130                                           const Standard_Real p2)
2131 {
2132   nbClassification++;
2133   Standard_Integer VertMin[16],VertMax[16],MinMaxVert[16];
2134   Standard_Real TotMin[16],TotMax[16];
2135   
2136   Standard_Integer i;
2137   TopAbs_State state = TopAbs_IN;
2138 //  Standard_Boolean rej = Standard_False;
2139   const HLRBRep_Curve& EC = ED.Geometry();
2140   Standard_Real sta,xsta,ysta,zsta, dp;
2141   Standard_Real tol = (Standard_Real)(ED.Tolerance());
2142
2143   dp = (p2 - p1)/(Nbp+1);
2144
2145   for(sta = p1+dp,i = 1; i <= Nbp; ++i, sta += dp) {
2146     myProj.Project(EC.Value3D(sta),xsta,ysta,zsta);
2147     
2148     //-- les rejections sont faites dans l intersecteur a moindre frais 
2149     //-- puisque la surface sera chargee
2150     HLRAlgo::InitMinMax(Precision::Infinite(),
2151                         (Standard_Address)TotMin,
2152                         (Standard_Address)TotMax);
2153     HLRAlgo::UpdateMinMax(xsta,ysta,zsta,
2154                           (Standard_Address)TotMin,
2155                           (Standard_Address)TotMax);
2156     HLRAlgo::EnlargeMinMax(tol,
2157                            (Standard_Address)TotMin,
2158                            (Standard_Address)TotMax);
2159     REJECT1;
2160
2161     HLRAlgo::EncodeMinMax((Standard_Address)VertMin,
2162                           (Standard_Address)VertMax,
2163                           (Standard_Address)MinMaxVert);
2164     if (((MaxFace1 - MinVert1) & 0x80008000) != 0 ||
2165         ((MaxVert1 - MinFace1) & 0x80008000) != 0 ||
2166         ((MaxFace2 - MinVert2) & 0x80008000) != 0 ||
2167         ((MaxVert2 - MinFace2) & 0x80008000) != 0 ||
2168         ((MaxFace3 - MinVert3) & 0x80008000) != 0 ||
2169         ((MaxVert3 - MinFace3) & 0x80008000) != 0 ||
2170         ((MaxFace4 - MinVert4) & 0x80008000) != 0 ||
2171         ((MaxVert4 - MinFace4) & 0x80008000) != 0 ||
2172         ((MaxFace5 - MinVert5) & 0x80008000) != 0 ||
2173         ((MaxVert5 - MinFace5) & 0x80008000) != 0 ||
2174         ((MaxFace6 - MinVert6) & 0x80008000) != 0 ||
2175         ((MaxVert6 - MinFace6) & 0x80008000) != 0 ||
2176         ((MaxFace7 - MinVert7) & 0x80008000) != 0 ||
2177         ((MaxVert7 - MinFace7) & 0x80008000) != 0 ||
2178         ((MaxFace8 - MinVert8) & 0x80008000) != 0) { //-- Rejection en Z 
2179       return TopAbs_OUT;
2180     }
2181   }
2182   return state;
2183 }
2184
2185 //=======================================================================
2186 //function : RejectedPoint
2187 //purpose  : build an interference if non Rejected intersection point
2188 //=======================================================================
2189
2190 Standard_Boolean 
2191 HLRBRep_Data::RejectedPoint (const IntRes2d_IntersectionPoint& PInter,
2192                              const TopAbs_Orientation BoundOri,
2193                              const Standard_Integer NumSeg)
2194 {
2195   Standard_Integer Ind = 0;
2196   Standard_Integer decal;
2197   Standard_Real p1,p2,dz;
2198   Standard_ShortReal t1,t2;
2199   TopAbs_State st;
2200   TopAbs_Orientation Orie =TopAbs_FORWARD ;
2201   TopAbs_Orientation Or2 = TopAbs_INTERNAL;
2202   Standard_Boolean inverted = Standard_False;
2203   const IntRes2d_Transition* Tr1;
2204   const IntRes2d_Transition* Tr2;
2205   Standard_Real TolZ = myBigSize * 0.00001;
2206
2207   p1 = ((HLRBRep_Curve*)myLEGeom)->Parameter3d(PInter.ParamOnFirst ());
2208   p2 = ((HLRBRep_Curve*)myFEGeom)->Parameter3d(PInter.ParamOnSecond());
2209   dz = ((HLRBRep_Curve*)myLEGeom)->Z(p1)-((HLRBRep_Curve*)myFEGeom)->Z(p2);
2210
2211   if (myLE == myFE) {            // auto intersection can be inverted
2212     if (dz >=  TolZ) {
2213       inverted = Standard_True;
2214       Standard_Real p = p1;
2215       p1 = p2;
2216       p2 = p;
2217       dz = -dz;
2218     }
2219   }
2220
2221   if (dz >=  TolZ) {
2222     myAboveIntf = Standard_True;
2223     return Standard_True;
2224   }
2225   myAboveIntf = Standard_False;
2226   st = (dz <= -TolZ) ? TopAbs_IN : TopAbs_ON;
2227
2228   if (inverted) {
2229     Tr1 = &(PInter.TransitionOfSecond());
2230     Tr2 = &(PInter.TransitionOfFirst ());
2231   }
2232   else {
2233     Tr1 = &(PInter.TransitionOfFirst ());
2234     Tr2 = &(PInter.TransitionOfSecond());
2235   }
2236
2237   if (iFaceTest) {
2238     if (myLE == myFE) {
2239       if (st == TopAbs_IN)
2240         ((HLRBRep_EdgeData*)myLEData)->Simple(Standard_False);
2241     }
2242     else {
2243       if (mySameVertex) {
2244         if ((st == TopAbs_ON)                           ||
2245             (Tr1->PositionOnCurve() != IntRes2d_Middle) ||
2246             (Tr2->PositionOnCurve() != IntRes2d_Middle))
2247           return Standard_True;
2248       }
2249     }
2250     if (st == TopAbs_IN) iFaceSmpl = Standard_False;
2251   }
2252
2253   switch (Tr1->TransitionType()) {                 // compute the transition
2254   case IntRes2d_In :
2255     if (myFEOri == TopAbs_REVERSED)   Orie = TopAbs_REVERSED;
2256     else                              Orie = TopAbs_FORWARD ; break;
2257   case IntRes2d_Out :
2258     if (myFEOri == TopAbs_REVERSED)   Orie = TopAbs_FORWARD ;
2259     else                              Orie = TopAbs_REVERSED; break;
2260   case IntRes2d_Touch :
2261     switch (Tr1->Situation()) {
2262     case IntRes2d_Inside :
2263       if (myFEOri == TopAbs_REVERSED) Orie = TopAbs_EXTERNAL;
2264       else                            Orie = TopAbs_INTERNAL; break;
2265     case IntRes2d_Outside :
2266       if (myFEOri == TopAbs_REVERSED) Orie = TopAbs_INTERNAL;
2267       else                            Orie = TopAbs_EXTERNAL; break;
2268     case IntRes2d_Unknown :
2269       return Standard_True;
2270     }                                                         break;
2271   case IntRes2d_Undecided :
2272     return Standard_True;
2273   }
2274
2275   if (iFaceBack) Orie = TopAbs::Complement(Orie);  // change the transition
2276   TopAbs_Orientation Ori = TopAbs_FORWARD;
2277   switch (Tr1->PositionOnCurve()) {
2278   case IntRes2d_Head   : Ori = TopAbs_FORWARD ; break;
2279   case IntRes2d_Middle : Ori = TopAbs_INTERNAL; break;
2280   case IntRes2d_End    : Ori = TopAbs_REVERSED; break;
2281   }
2282
2283   if (st != TopAbs_OUT) {
2284     if (Tr2->PositionOnCurve() != IntRes2d_Middle) { // correction de la transition  sur myFE
2285       if (mySameVertex) return Standard_True;        // si intersection a une extremite verticale !
2286
2287       Standard_Boolean douteux = Standard_False;
2288       Standard_Real psav = p2;
2289       gp_Pnt2d Ptsav;
2290       gp_Vec2d Tgsav,Nmsav;
2291       if (Tr2->PositionOnCurve() == IntRes2d_Head) {
2292         Ind = ((HLRBRep_EdgeData*)myFEData)->VSta();
2293         Or2 = TopAbs_FORWARD ;
2294         AdjustParameter((HLRBRep_EdgeData*)myFEData,Standard_True ,p2,t2);
2295         if (((HLRBRep_EdgeData*)myFEData)->VerAtSta()) {
2296           douteux = Standard_True;
2297           ((HLRBRep_Curve*)myFEGeom)->D2(psav,Ptsav,Tgsav,Nmsav);
2298           if (Tgsav.SquareMagnitude() <= DERIVEE_PREMIERE_NULLE)
2299             Tgsav = Nmsav;
2300         }
2301       }
2302       else {
2303         Ind = ((HLRBRep_EdgeData*)myFEData)->VEnd();
2304         Or2 = TopAbs_REVERSED;
2305         AdjustParameter((HLRBRep_EdgeData*)myFEData,Standard_False,p2,t2);
2306         if (((HLRBRep_EdgeData*)myFEData)->VerAtEnd()) {
2307           douteux = Standard_True;
2308           ((HLRBRep_Curve*)myFEGeom)->D2(psav,Ptsav,Tgsav,Nmsav);
2309           if (Tgsav.SquareMagnitude() <= DERIVEE_PREMIERE_NULLE)
2310             Tgsav = Nmsav;
2311         }
2312       }
2313       gp_Vec2d TgFE;
2314       ((HLRBRep_Curve*)myFEGeom)->D1(p2,Ptsav,TgFE);
2315       if (douteux) {
2316         if (TgFE.XY().Dot(Tgsav.XY()) < 0.0) {
2317           if      (Orie == TopAbs_FORWARD ) Orie = TopAbs_REVERSED;
2318           else if (Orie == TopAbs_REVERSED) Orie = TopAbs_FORWARD ;
2319         }
2320       }
2321       myIntf.ChangeBoundary().Set2D(myFE,p2);
2322     }
2323     if (Ori != TopAbs_INTERNAL) {                 // correction de la transition  sur myLE
2324       Standard_Boolean douteux = Standard_False;  // si intersection a une extremite verticale !
2325       Standard_Real psav = p1;
2326       gp_Pnt2d Ptsav;
2327       gp_Vec2d Tgsav,Nmsav;
2328       if (Ori == TopAbs_FORWARD) {
2329         AdjustParameter((HLRBRep_EdgeData*)myLEData,Standard_True ,p1,t1);
2330         if (((HLRBRep_EdgeData*)myLEData)->VerAtSta()) {
2331           douteux = Standard_True;
2332           ((HLRBRep_Curve*)myLEGeom)->D2(psav,Ptsav,Tgsav,Nmsav);
2333           if (Tgsav.SquareMagnitude() <= DERIVEE_PREMIERE_NULLE)
2334             Tgsav=Nmsav;
2335         }
2336       }
2337       else {
2338         AdjustParameter((HLRBRep_EdgeData*)myLEData,Standard_False,p1,t1);
2339         if (((HLRBRep_EdgeData*)myLEData)->VerAtEnd()) {
2340           douteux = Standard_True;
2341           ((HLRBRep_Curve*)myLEGeom)->D2(psav,Ptsav,Tgsav,Nmsav);
2342           if (Tgsav.SquareMagnitude() <= DERIVEE_PREMIERE_NULLE)
2343             Tgsav=Nmsav;
2344         }
2345       }
2346       if (douteux) {
2347         gp_Vec2d TgLE;
2348         ((HLRBRep_Curve*)myLEGeom)->D1(p1,Ptsav,TgLE);
2349         if (TgLE.XY().Dot(Tgsav.XY()) < 0.0) {
2350           if      (Orie == TopAbs_FORWARD ) Orie = TopAbs_REVERSED;
2351           else if (Orie == TopAbs_REVERSED) Orie = TopAbs_FORWARD ;
2352         }
2353       }
2354     }
2355     if (st == TopAbs_ON) {
2356       TopAbs_State stbef,staft;
2357       EdgeState(p1,p2,stbef,staft);
2358       myIntf.ChangeBoundary().SetState3D(stbef,staft);
2359     }
2360   }
2361
2362   if (myFEInternal) {
2363     decal = 2;
2364   }
2365   else {
2366     decal = 1;
2367     if (st == TopAbs_IN &&
2368         Ori == TopAbs_FORWARD &&
2369         Orie == TopAbs_FORWARD)
2370       decal = 0;
2371   }
2372   HLRAlgo_Intersection& inter = myIntf.ChangeIntersection();
2373   inter.Orientation(Ori);
2374   inter.Level(decal);
2375   inter.SegIndex(NumSeg);
2376   inter.Index(Ind);
2377   inter.Parameter(p1);
2378   inter.Tolerance(myLETol);
2379   inter.State(st);
2380   myIntf.Orientation(Or2);
2381   myIntf.Transition(Orie);
2382   myIntf.BoundaryTransition(BoundOri);
2383   myIntf.ChangeBoundary().Set2D(myFE,p2);
2384   return Standard_False;
2385 }
2386
2387 //=======================================================================
2388 //function : SameVertex
2389 //purpose  : 
2390 //=======================================================================
2391
2392 Standard_Boolean 
2393 HLRBRep_Data::SameVertex (const Standard_Boolean h1,
2394                           const Standard_Boolean h2)
2395 {
2396   Standard_Integer v1,v2;
2397   if (h1) v1 = ((HLRBRep_EdgeData*)myLEData)->VSta();
2398   else    v1 = ((HLRBRep_EdgeData*)myLEData)->VEnd();
2399   if (h2) v2 = ((HLRBRep_EdgeData*)myFEData)->VSta();
2400   else    v2 = ((HLRBRep_EdgeData*)myFEData)->VEnd();
2401   Standard_Boolean SameV = v1 == v2;
2402   if (SameV) {
2403     myIntersected = Standard_True; // compute the intersections
2404     if ((myLEType == GeomAbs_Line    ||
2405          myLEType == GeomAbs_Circle  ||
2406          myLEType == GeomAbs_Ellipse ) &&
2407         (myFEType == GeomAbs_Line    ||
2408          myFEType == GeomAbs_Circle  ||
2409          myFEType == GeomAbs_Ellipse ))
2410       myIntersected = Standard_False;    // no other intersection
2411
2412     Standard_Boolean otherCase = Standard_True;
2413
2414     if (( h1 && ((HLRBRep_EdgeData*)myLEData)->OutLVSta()) ||
2415         (!h1 && ((HLRBRep_EdgeData*)myLEData)->OutLVEnd())) {
2416       if (iFaceTest || myLEInternal)
2417         otherCase = Standard_False;
2418     }
2419     else if (iFaceTest)
2420       otherCase = Standard_False;
2421
2422     if (otherCase) {
2423       if (( h1 && ((HLRBRep_EdgeData*)myLEData)->CutAtSta()) ||
2424           (!h1 && ((HLRBRep_EdgeData*)myLEData)->CutAtEnd())) {
2425         myIntersected = Standard_False; // two connected OutLines do not
2426       }                                 // intersect themselves.
2427     }
2428   }
2429   return SameV;
2430 }