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