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