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