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