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