0025828: BRepAlgoAPI_Section fails for a solid and a face depending on order of arguments
[occt.git] / src / IntPatch / IntPatch_PrmPrmIntersection.cxx
1 // Created on: 1993-02-02
2 // Created by: Laurent BUCHARD
3 // Copyright (c) 1993-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 // modified by Edward AGAPOV (eap) Tue Jan 22 12:29:55 2002
18 // modified by Oleg FEDYAED  (ofv) Fri Nov 29 16:08:02 2002
19
20 #include <IntPatch_PrmPrmIntersection.ixx>
21
22 #include <IntPatch_InterferencePolyhedron.hxx>
23 #include <IntWalk_PWalking.hxx>
24 #include <IntPatch_WLine.hxx>
25 #include <IntPatch_RstInt.hxx>
26
27 #include <IntPatch_Line.hxx>
28
29 #include <IntSurf_PntOn2S.hxx>
30 #include <IntSurf_LineOn2S.hxx>
31 #include <TColStd_Array1OfReal.hxx>
32 #include <Intf_PIType.hxx>
33 #include <Intf_SectionLine.hxx>
34 #include <Intf_TangentZone.hxx>
35 #include <Intf_SectionPoint.hxx>
36 #include <gp_Pnt.hxx>
37 #include <gp_Dir.hxx>
38 #include <IntPolyh_Intersection.hxx>
39
40 #include <TColStd_SequenceOfInteger.hxx>
41 #include <IntSurf_ListIteratorOfListOfPntOn2S.hxx>
42 #include <TColStd_HArray1OfReal.hxx>
43
44 static void SectionPointToParameters(const Intf_SectionPoint& Sp,
45                                      const IntPatch_Polyhedron& Surf1,
46                                      const IntPatch_Polyhedron& Surf2,
47                                      Standard_Real& u1,
48                                      Standard_Real& v1,
49                                      Standard_Real& u2,
50                                      Standard_Real& v2);
51
52
53 static 
54 void AdjustOnPeriodic(const Handle(Adaptor3d_HSurface)& Surf1,
55                       const Handle(Adaptor3d_HSurface)& Surf2,
56                       IntPatch_SequenceOfLine& aSLin);
57
58 static
59 IntSurf_PntOn2S MakeNewPoint(const IntSurf_PntOn2S& replacePnt,
60                              const IntSurf_PntOn2S& oldPnt,
61                              const Standard_Real* Periods);
62
63 static Standard_Boolean IsPointOnLine(const IntSurf_PntOn2S        &thePOn2S,
64                                       const Handle(IntPatch_WLine) &theWLine,
65                                       const Standard_Real           Deflection);
66
67 static void AddWLine(IntPatch_SequenceOfLine      &theLines,
68                      const Handle(IntPatch_WLine) &theWLine,
69                      const Standard_Real           Deflection);
70
71 //=======================================================================
72 //function : DublicateOfLinesProcessing
73 //purpose  : Decides, if rejecting current line is necessary
74 //=======================================================================
75 static void DublicateOfLinesProcessing( const IntWalk_PWalking& thePW,
76                                         const Standard_Integer theWLID,
77                                         IntPatch_SequenceOfLine& theLines,
78                                         Standard_Boolean& theIsRejectReq)
79 {
80   const Handle(IntPatch_WLine)& anExistWL =
81                       *((Handle(IntPatch_WLine)*)&theLines.Value(theWLID));
82   const Standard_Integer aNbPrevPoints = anExistWL->NbPnts();
83   const Standard_Integer aNbCurrPoints = thePW.NbPoints();
84
85   if(aNbPrevPoints < aNbCurrPoints)
86   {//Remove preview line
87     theLines.Remove(theWLID);
88     theIsRejectReq = Standard_False;
89   }
90   else if(aNbPrevPoints == aNbCurrPoints)
91   {
92     Standard_Real aLPrev = 0.0, aLCurr = 0.0;
93     for(Standard_Integer aNbPP = 1; aNbPP < aNbPrevPoints; aNbPP++)
94     {
95       const gp_Pnt  aP1prev(anExistWL->Point(aNbPP).Value()),
96         aP2prev(anExistWL->Point(aNbPP+1).Value());
97       const gp_Pnt  aP1curr(thePW.Value(aNbPP).Value()),
98         aP2curr(thePW.Value(aNbPP+1).Value());
99
100       aLPrev += aP1prev.Distance(aP2prev);
101       aLCurr += aP1curr.Distance(aP2curr);
102     }
103
104     if(aLPrev < aLCurr)
105     {//Remove preview line
106       theLines.Remove(theWLID);
107       theIsRejectReq = Standard_False;
108     }
109   }
110 }
111
112 //==================================================================================
113 // function : 
114 // purpose  : 
115 //==================================================================================
116 IntPatch_PrmPrmIntersection::IntPatch_PrmPrmIntersection(): done(Standard_False)
117 {
118 }
119
120 //==================================================================================
121 // function : Perform
122 // purpose  : 
123 //==================================================================================
124 void IntPatch_PrmPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)&   Surf1,
125                                            const Handle(Adaptor3d_TopolTool)& D1,
126                                            const Standard_Real  TolTangency,
127                                            const Standard_Real  Epsilon,
128                                            const Standard_Real  Deflection,
129                                            const Standard_Real  Increment)
130
131   IntPatch_Polyhedron Poly1( Surf1, D1->NbSamplesU(), D1->NbSamplesV() );
132   Perform( Surf1, Poly1, D1, TolTangency, Epsilon, Deflection, Increment );
133 }
134
135 //==================================================================================
136 // function : Perform
137 // purpose  : 
138 //==================================================================================
139 void IntPatch_PrmPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)&   Surf1,
140                                            const IntPatch_Polyhedron& Poly1,
141                                            const Handle(Adaptor3d_TopolTool)& D1,
142                                            const Handle(Adaptor3d_HSurface)&   Surf2,
143                                            const Handle(Adaptor3d_TopolTool)& D2,
144                                            const Standard_Real  TolTangency,
145                                            const Standard_Real  Epsilon,
146                                            const Standard_Real  Deflection,
147                                            const Standard_Real  Increment)
148
149   IntPatch_Polyhedron Poly2( Surf2 );
150   Perform( Surf1, Poly1, D1, Surf2, Poly2, D2, TolTangency, Epsilon, Deflection, Increment);
151 }
152
153 //==================================================================================
154 // function : Perform
155 // purpose  : 
156 //==================================================================================
157 void IntPatch_PrmPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)&   Surf1,
158                                            const Handle(Adaptor3d_TopolTool)& D1,
159                                            const Handle(Adaptor3d_HSurface)&   Surf2,
160                                            const IntPatch_Polyhedron& Poly2,
161                                            const Handle(Adaptor3d_TopolTool)& D2,
162                                            const Standard_Real  TolTangency,
163                                            const Standard_Real  Epsilon,
164                                            const Standard_Real  Deflection,
165                                            const Standard_Real  Increment)
166
167   IntPatch_Polyhedron Poly1( Surf1 );    
168   Perform( Surf1, Poly1, D1, Surf2, Poly2, D2, TolTangency, Epsilon, Deflection, Increment );
169 }
170
171 //==================================================================================
172 // function : Perform
173 // purpose  : 
174 //==================================================================================
175 void IntPatch_PrmPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)&    Surf1,
176                                            const IntPatch_Polyhedron&  Poly1,
177                                            const Handle(Adaptor3d_TopolTool)& D1,
178                                            const Handle(Adaptor3d_HSurface)&    Surf2,
179                                            const IntPatch_Polyhedron&  Poly2,
180                                            const Handle(Adaptor3d_TopolTool)& D2,
181                                            const Standard_Real   TolTangency,
182                                            const Standard_Real   Epsilon,
183                                            const Standard_Real   Deflection,
184                                            const Standard_Real   Increment)
185
186   IntPatch_InterferencePolyhedron Interference(Poly1,Poly2);
187   empt = Standard_True;
188   done = Standard_True;
189   SLin.Clear();  
190
191   Standard_Integer nbLigSec = Interference.NbSectionLines();
192   Standard_Integer nbTanZon = Interference.NbTangentZones();
193
194   Standard_Integer NbLigCalculee = 0;
195
196   Standard_Real U1,U2,V1,V2;
197   Standard_Real pu1,pu2,pv1,pv2;
198
199   TColStd_Array1OfReal StartParams(1,4);
200
201   IntWalk_PWalking PW( Surf1, Surf2, TolTangency, Epsilon, Deflection, Increment );
202
203   Standard_Real    SeuildPointLigne = 15.0 * Increment * Increment; //-- 10 est insuffisant
204   Standard_Real    incidence;
205   Standard_Real    dminiPointLigne;
206
207   Standard_Boolean HasStartPoint,RejetLigne;
208
209   IntSurf_PntOn2S StartPOn2S;
210
211   Standard_Integer ver;
212
213   gp_Pnt Point3dDebut,Point3dFin;
214
215   if( nbLigSec >= 1 ) {
216     Standard_Integer *TabL = new Standard_Integer [nbLigSec+1];
217     Standard_Integer ls;
218     for( ls = 1; ls <= nbLigSec; ls++ )
219       TabL[ls]=ls;
220
221     Standard_Boolean triok;
222     do { 
223       triok=Standard_True;
224       for(Standard_Integer b=2; b<=nbLigSec; b++) {
225         Standard_Integer nb_B = Interference.LineValue(TabL[b]).NumberOfPoints();
226         Standard_Integer nb_A = Interference.LineValue(TabL[b-1]).NumberOfPoints();
227         if( nb_B > nb_A ) { 
228           Standard_Integer tyu=TabL[b]; 
229           TabL[b]=TabL[b-1];
230           TabL[b-1]=tyu;
231           triok=Standard_False;
232         }
233       }
234     } while( triok==Standard_False );
235
236     for( ls = 1; ls <= nbLigSec; ls++) {
237       const Intf_SectionLine& LineSec=Interference.LineValue(TabL[ls]);
238       Standard_Integer nbp = LineSec.NumberOfPoints();
239
240       Standard_Integer *TabPtDep = new Standard_Integer [nbp+1];
241       Standard_Integer ilig;
242       for( ilig = 1; ilig <= nbp; ilig++) 
243         TabPtDep[ilig]=0;
244
245       Standard_Real UminLig1,VminLig1,UmaxLig1,VmaxLig1;
246       Standard_Real UminLig2,VminLig2,UmaxLig2,VmaxLig2;
247
248       SectionPointToParameters(LineSec.GetPoint(1),Poly1,Poly2,UminLig1,VminLig1,UminLig2,VminLig2);
249
250       UmaxLig1=UminLig1;
251       VmaxLig1=VminLig1;
252       UmaxLig2=UminLig2;
253       VmaxLig2=VminLig2;
254
255       for( ilig = 2; ilig <= nbp; ilig++ ) { 
256         SectionPointToParameters(LineSec.GetPoint(ilig),Poly1,Poly2,U1,V1,U2,V2);
257
258         if(U1>UmaxLig1) UmaxLig1=U1;
259         if(V1>VmaxLig1) VmaxLig1=V1;
260         if(U2>UmaxLig2) UmaxLig2=U2;
261         if(V2>VmaxLig2) VmaxLig2=V2;
262
263         if(U1<UminLig1) UminLig1=U1;
264         if(V1<VminLig1) VminLig1=V1;
265         if(U2<UminLig2) UminLig2=U2;
266         if(V2<VminLig2) VminLig2=V2;
267       }
268
269       Standard_Integer nbps2 = (nbp>3)? (nbp/2) :  1;
270       Standard_Integer NombreDePointsDeDepartDuCheminement = 0;
271       Standard_Integer IndicePointdeDepart1 = 0,IndicePointdeDepart2 = 0;
272       Standard_Boolean lignetrouvee=Standard_False;
273
274       do { 
275         NombreDePointsDeDepartDuCheminement++;
276         if(NombreDePointsDeDepartDuCheminement == 1) { 
277           incidence=3.0;
278           Standard_Integer nbp1_4=nbp/4;
279           Standard_Integer nbp3_4=nbp-nbp1_4;
280
281           Standard_Integer nsp;
282           for(nsp=nbp/2; nsp<nbp3_4; nsp++) { 
283             Standard_Real CurrentIncidence =  LineSec.GetPoint(nsp).Incidence();
284             if(CurrentIncidence < incidence) { 
285               nbps2 = nsp;
286               incidence = 0.9*CurrentIncidence;
287             }
288           }
289
290           for(nsp=nbp/2; nsp>nbp1_4; nsp--) { 
291             Standard_Real CurrentIncidence =  LineSec.GetPoint(nsp).Incidence();
292             if(CurrentIncidence < incidence) { 
293               nbps2 = nsp;
294               incidence = 0.9*CurrentIncidence;
295             }
296           }
297
298           if(nbp<3) 
299             NombreDePointsDeDepartDuCheminement=3;
300
301           IndicePointdeDepart1 = nbps2;
302         }
303         else if(NombreDePointsDeDepartDuCheminement == 2) { 
304           if(IndicePointdeDepart1 == 1) { 
305             nbps2 = nbp/2;
306             IndicePointdeDepart2 = nbps2;
307           }
308           else { 
309             nbps2 = 1;
310             IndicePointdeDepart2 = 1;
311           }
312         }
313         else if(NombreDePointsDeDepartDuCheminement == 3) {
314           if(IndicePointdeDepart1 == nbp)
315             nbps2 = (IndicePointdeDepart1+IndicePointdeDepart2)/2;
316           else
317             nbps2 = nbp;
318         }
319         else { 
320           nbps2 = NombreDePointsDeDepartDuCheminement-3;
321           NombreDePointsDeDepartDuCheminement++;
322         } 
323
324         if(TabPtDep[nbps2]==0) { 
325           TabPtDep[nbps2]=1;
326           SectionPointToParameters(LineSec.GetPoint(nbps2),Poly1,Poly2,U1,V1,U2,V2);
327
328           StartParams(1) = U1;
329           StartParams(2) = V1;
330           StartParams(3) = U2;
331           StartParams(4) = V2;
332
333           HasStartPoint = PW.PerformFirstPoint(StartParams,StartPOn2S);
334           dminiPointLigne = SeuildPointLigne + SeuildPointLigne;
335
336           if(HasStartPoint) { 
337             StartPOn2S.Parameters(pu1,pv1,pu2,pv2);
338             NbLigCalculee = SLin.Length();
339             Standard_Integer l;
340             for( l=1; (l <= NbLigCalculee) && (dminiPointLigne >= SeuildPointLigne); l++) { 
341               const Handle(IntPatch_WLine)& testwline = *((Handle(IntPatch_WLine)*)&SLin.Value(l));
342
343               if (IsPointOnLine(StartPOn2S, testwline, Deflection)) {
344                 dminiPointLigne = 0.0;
345               }
346             } // for ( l ...
347
348             if(dminiPointLigne > SeuildPointLigne) { 
349               PW.Perform(StartParams,UminLig1,VminLig1,UminLig2,VminLig2,UmaxLig1,VmaxLig1,UmaxLig2,VmaxLig2);
350               if(PW.IsDone()) {
351                 if(PW.NbPoints()>2) { 
352                   RejetLigne = Standard_False;
353                   Point3dDebut = PW.Value(1).Value();
354                   const IntSurf_PntOn2S& PointFin = PW.Value(PW.NbPoints());
355                   Point3dFin   = PointFin.Value();
356                   for( ver = 1 ; (!RejetLigne) && (ver<= NbLigCalculee) ; ver++) { 
357                     const Handle(IntPatch_WLine)& verwline = *((Handle(IntPatch_WLine)*)&SLin.Value(ver));
358
359                     // Check end point if it is on existing line.
360                     // Start point is checked before.
361                     if (IsPointOnLine(PointFin, verwline, Deflection)) {
362                       RejetLigne = Standard_True; 
363                       break;
364                     }
365
366                     const IntSurf_PntOn2S& verPointDebut = verwline->Point(1);
367                     const IntSurf_PntOn2S& verPointFin = verwline->Point(verwline->NbPnts());
368                     if( Point3dDebut.Distance(verPointDebut.Value()) <= TolTangency ) { 
369                       if(Point3dFin.Distance(verPointFin.Value()) <= TolTangency)
370                         RejetLigne = Standard_True; 
371                     }
372                   }
373
374                   if(RejetLigne)
375                   {
376                     DublicateOfLinesProcessing(PW, ver, SLin, RejetLigne);
377                   }
378
379                   if(!RejetLigne) { 
380                     // Calculation transition
381                     IntSurf_TypeTrans trans1,trans2;
382                     Standard_Real locu,locv;
383                     gp_Vec norm1,norm2,d1u,d1v;
384                     gp_Pnt ptbid;
385                     Standard_Integer indextg;
386                     gp_Vec tgline(PW.TangentAtLine(indextg));
387                     PW.Line()->Value(indextg).ParametersOnS1(locu,locv);
388                     Surf1->D1(locu,locv,ptbid,d1u,d1v);
389                     norm1 = d1u.Crossed(d1v);
390                     PW.Line()->Value(indextg).ParametersOnS2(locu,locv);
391                     Surf2->D1(locu,locv,ptbid,d1u,d1v);
392                     norm2 = d1u.Crossed(d1v);
393                     if(tgline.DotCross(norm2,norm1)>0.) {
394                       trans1 = IntSurf_Out;
395                       trans2 = IntSurf_In;
396                     }
397                     else {
398                       trans1 = IntSurf_In;
399                       trans2 = IntSurf_Out;
400                     }
401
402                     Standard_Real TolTang = TolTangency;
403                     Handle(IntPatch_WLine) wline = new IntPatch_WLine(PW.Line(),Standard_False,trans1,trans2);
404                     IntPatch_RstInt::PutVertexOnLine(wline,Surf1,D1,Surf2,Standard_True,TolTang);
405                     IntPatch_RstInt::PutVertexOnLine(wline,Surf2,D2,Surf1,Standard_False,TolTang);
406
407                     if(wline->NbVertex() == 0) {
408                       IntPatch_Point vtx;
409                       IntSurf_PntOn2S POn2S = PW.Line()->Value(1);
410                       POn2S.Parameters(pu1,pv1,pu2,pv2);
411                       vtx.SetValue(Point3dDebut,TolTang,Standard_False);
412                       vtx.SetParameters(pu1,pv1,pu2,pv2);
413                       vtx.SetParameter(1);
414                       wline->AddVertex(vtx);
415
416                       POn2S = PW.Line()->Value(wline->NbPnts());
417                       POn2S.Parameters(pu1,pv1,pu2,pv2);
418                       vtx.SetValue(Point3dFin,TolTang,Standard_False);
419                       vtx.SetParameters(pu1,pv1,pu2,pv2);
420                       vtx.SetParameter(wline->NbPnts());
421                       wline->AddVertex(vtx);
422                     }
423
424                     lignetrouvee = Standard_True;
425                     AddWLine(SLin, wline, Deflection);
426                     empt = Standard_False;
427                   }// !RejetLigne
428                 }// PW.NbPoints()>2
429               }// done is True
430             }// dminiPointLigne > SeuildPointLigne
431           }// HasStartPoint
432         }// TabPtDep[nbps2]==0
433       } while( nbp>5 && ( !( ( (NombreDePointsDeDepartDuCheminement >= 3) && lignetrouvee ) || 
434         ( (NombreDePointsDeDepartDuCheminement-3>=nbp) && !lignetrouvee ) ) ) );
435
436       delete [] TabPtDep;
437     }// for( ls ...
438
439     delete [] TabL;
440   }// nbLigSec >= 1
441
442   Standard_Real UminLig1,VminLig1,UmaxLig1,VmaxLig1;
443   Standard_Real UminLig2,VminLig2,UmaxLig2,VmaxLig2;
444
445   UminLig1=VminLig1=UminLig2=VminLig2=RealLast();
446   UmaxLig1=VmaxLig1=UmaxLig2=VmaxLig2=-UminLig1;
447
448   Standard_Integer z;
449   for(z=1; z <= nbTanZon; z++) { 
450     const Intf_TangentZone& TangentZone=Interference.ZoneValue(z);
451     for(Standard_Integer pz=1; pz<=TangentZone.NumberOfPoints(); pz++) { 
452       SectionPointToParameters(TangentZone.GetPoint(pz),Poly1,Poly2,U1,V1,U2,V2);
453
454       if(U1>UmaxLig1) UmaxLig1=U1;
455       if(V1>VmaxLig1) VmaxLig1=V1;
456       if(U2>UmaxLig2) UmaxLig2=U2;
457       if(V2>VmaxLig2) VmaxLig2=V2;
458
459       if(U1<UminLig1) UminLig1=U1;
460       if(V1<VminLig1) VminLig1=V1;
461       if(U2<UminLig2) UminLig2=U2;
462       if(V2<VminLig2) VminLig2=V2;
463     }
464   }
465
466   for(z=1; z <= nbTanZon; z++) {
467     const Intf_TangentZone& TangentZone=Interference.ZoneValue(z);
468     Standard_Integer pz;
469     for( pz=1; pz<=TangentZone.NumberOfPoints(); pz++) { 
470       SectionPointToParameters(TangentZone.GetPoint(pz),Poly1,Poly2,U1,V1,U2,V2);
471
472       StartParams(1) = U1;
473       StartParams(2) = V1;
474       StartParams(3) = U2;
475       StartParams(4) = V2;
476
477       HasStartPoint = PW.PerformFirstPoint(StartParams,StartPOn2S);
478       if(HasStartPoint) { 
479         StartPOn2S.Parameters(pu1,pv1,pu2,pv2);
480         NbLigCalculee = SLin.Length();
481         dminiPointLigne = SeuildPointLigne + SeuildPointLigne; 
482         Standard_Integer l;
483         for( l = 1; (l <= NbLigCalculee) && (dminiPointLigne >= SeuildPointLigne); l++) { 
484           const Handle(IntPatch_WLine)& testwline = *((Handle(IntPatch_WLine)*)&SLin.Value(l));
485
486           if (IsPointOnLine(StartPOn2S, testwline, Deflection)) {
487             dminiPointLigne = 0.0;
488           }
489         }// for( l ...
490
491         if(dminiPointLigne > SeuildPointLigne) { 
492           PW.Perform(StartParams,UminLig1,VminLig1,UminLig2,VminLig2,UmaxLig1,VmaxLig1,UmaxLig2,VmaxLig2);
493           if(PW.IsDone()) {
494             if(PW.NbPoints()>2) { 
495               RejetLigne = Standard_False;
496               Point3dDebut = PW.Value(1).Value();
497               const IntSurf_PntOn2S& PointFin = PW.Value(PW.NbPoints());
498               Point3dFin   = PointFin.Value();
499               for(ver=1 ; (!RejetLigne) && (ver<= NbLigCalculee) ; ver++) { 
500                 const Handle(IntPatch_WLine)& verwline = *((Handle(IntPatch_WLine)*)&SLin.Value(ver));
501
502                 // Check end point if it is on existing line.
503                 // Start point is checked before.
504                 if (IsPointOnLine(PointFin, verwline, Deflection)) {
505                   RejetLigne = Standard_True; 
506                   break;
507                 }
508
509                 const IntSurf_PntOn2S& verPointDebut = verwline->Point(1);
510                 const IntSurf_PntOn2S& verPointFin   = verwline->Point(verwline->NbPnts());
511                 if(Point3dDebut.Distance(verPointDebut.Value()) < TolTangency)
512                   RejetLigne = Standard_True; 
513                 else { 
514                   if(Point3dFin.Distance(verPointFin.Value()) < TolTangency)
515                     RejetLigne = Standard_True; 
516                 }
517               }
518
519               if(RejetLigne)
520               {
521                 DublicateOfLinesProcessing(PW, ver, SLin, RejetLigne);
522               }
523
524               if(!RejetLigne) { 
525                 IntSurf_TypeTrans trans1,trans2;
526                 Standard_Real locu,locv;
527                 gp_Vec norm1,norm2,d1u,d1v;
528                 gp_Pnt ptbid;
529                 Standard_Integer indextg;
530                 gp_Vec tgline(PW.TangentAtLine(indextg));
531                 PW.Line()->Value(indextg).ParametersOnS1(locu,locv);
532                 Surf1->D1(locu,locv,ptbid,d1u,d1v);
533                 norm1 = d1u.Crossed(d1v);
534                 PW.Line()->Value(indextg).ParametersOnS2(locu,locv);
535                 Surf2->D1(locu,locv,ptbid,d1u,d1v);
536                 norm2 = d1u.Crossed(d1v);
537                 if(tgline.DotCross(norm2,norm1)>0.) {
538                   trans1 = IntSurf_Out;
539                   trans2 = IntSurf_In;
540                 }
541                 else {
542                   trans1 = IntSurf_In;
543                   trans2 = IntSurf_Out;
544                 }
545
546                 Standard_Real TolTang = TolTangency;
547                 Handle(IntPatch_WLine) wline = new IntPatch_WLine(PW.Line(),Standard_False,trans1,trans2);
548                 IntPatch_RstInt::PutVertexOnLine(wline,Surf1,D1,Surf2,Standard_True,TolTang);
549                 IntPatch_RstInt::PutVertexOnLine(wline,Surf2,D2,Surf1,Standard_False,TolTang);
550
551                 if(wline->NbVertex() == 0) {
552                   IntPatch_Point vtx;
553                   IntSurf_PntOn2S POn2S = PW.Line()->Value(1);
554                   POn2S.Parameters(pu1,pv1,pu2,pv2);
555                   vtx.SetValue(Point3dDebut,TolTang,Standard_False);
556                   vtx.SetParameters(pu1,pv1,pu2,pv2);
557                   vtx.SetParameter(1);
558                   wline->AddVertex(vtx);
559
560                   POn2S = PW.Line()->Value(wline->NbPnts());
561                   POn2S.Parameters(pu1,pv1,pu2,pv2);
562                   vtx.SetValue(Point3dFin,TolTang,Standard_False);
563                   vtx.SetParameters(pu1,pv1,pu2,pv2);
564                   vtx.SetParameter(wline->NbPnts());
565                   wline->AddVertex(vtx);
566                 }
567
568                 AddWLine(SLin, wline, Deflection);
569                 empt = Standard_False;
570               }// if !RejetLigne
571             }// PW.NbPoints()>2
572           }// done is True
573         }// dminiPointLigne > SeuildPointLigne
574       }// HasStartPoint
575     }// for( pz ...
576   }// for( z ...
577 }
578
579 //==================================================================================
580 // function : Perform
581 // purpose  : 
582 //==================================================================================
583 void IntPatch_PrmPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)&    Surf1,
584                                            const IntPatch_Polyhedron&  Poly1,
585                                            const Handle(Adaptor3d_TopolTool)& D1,
586                                            const Standard_Real   TolTangency,
587                                            const Standard_Real   Epsilon,
588                                            const Standard_Real   Deflection,
589                                            const Standard_Real   Increment)
590
591   IntPatch_InterferencePolyhedron Interference(Poly1);
592   empt = Standard_True;
593   done = Standard_True;
594   SLin.Clear();  
595
596   Standard_Integer nbLigSec = Interference.NbSectionLines();
597   Standard_Integer nbTanZon = Interference.NbTangentZones();
598
599   Standard_Integer NbPntOn2SOnLine;
600   Standard_Integer NbLigCalculee = 0;
601
602   Standard_Real U1,U2,V1,V2;
603   Standard_Real pu1,pu2,pv1,pv2;
604
605   TColStd_Array1OfReal StartParams(1,4);
606   IntWalk_PWalking PW(Surf1,Surf1,TolTangency,Epsilon,Deflection,Increment);
607
608   Standard_Real    SeuildPointLigne = 15.0 * Increment * Increment; //-- 10 est insuffisant
609   Standard_Real    incidence;
610   Standard_Real    dminiPointLigne;
611
612   Standard_Boolean HasStartPoint,RejetLigne;
613
614   IntSurf_PntOn2S StartPOn2S;
615
616   Standard_Integer ver;
617
618   gp_Pnt Point3dDebut,Point3dFin;
619
620   if(nbLigSec>=1) {
621     Standard_Integer ls;
622     for( ls = 1; ls <= nbLigSec; ls++) {
623       const Intf_SectionLine& LineSec=Interference.LineValue(ls);
624       Standard_Integer nbp = LineSec.NumberOfPoints();
625       Standard_Integer nbps2 = (nbp>3)? (nbp/2) :  1;
626       Standard_Integer NombreDePointsDeDepartDuCheminement = 0;
627       Standard_Integer IndicePointdeDepart1 = 0, IndicePointdeDepart2 = 0;
628       do { 
629         NombreDePointsDeDepartDuCheminement++;
630         if(NombreDePointsDeDepartDuCheminement == 1) { 
631           incidence = 0.0;
632           Standard_Integer nsp1;
633           for( nsp1= nbp/2; nsp1 >= 1; nsp1--) { 
634             SectionPointToParameters(LineSec.GetPoint(nsp1),Poly1,Poly1,U1,V1,U2,V2);
635             Standard_Real CurrentIncidence =  Abs(U1-U2)+Abs(V1-V2);
636             if(CurrentIncidence > incidence) { 
637               nbps2 = nsp1;
638               incidence = CurrentIncidence;
639             }
640           }
641           for( nsp1 = nbp/2; nsp1 <= nbp; nsp1++) { 
642             SectionPointToParameters(LineSec.GetPoint(nsp1),Poly1,Poly1,U1,V1,U2,V2);
643             Standard_Real CurrentIncidence =  Abs(U1-U2)+Abs(V1-V2);
644             if(CurrentIncidence > incidence) { 
645               nbps2 = nsp1;
646               incidence = CurrentIncidence;
647             }
648           }
649
650           if(nbp<3) 
651             NombreDePointsDeDepartDuCheminement=3;
652
653           IndicePointdeDepart1 = nbps2;
654         }
655         else if(NombreDePointsDeDepartDuCheminement == 2) { 
656           if(IndicePointdeDepart1 == 1) { 
657             nbps2 = nbp/2;
658             IndicePointdeDepart2 = nbps2;
659           }
660           else { 
661             nbps2 = 1;
662             IndicePointdeDepart2 = 1;
663           }
664         }
665         else {
666           if(IndicePointdeDepart1 == nbp)
667             nbps2 = (IndicePointdeDepart1+IndicePointdeDepart2)/2;
668           else
669             nbps2 = nbp;
670         }
671
672         SectionPointToParameters(LineSec.GetPoint(nbps2),Poly1,Poly1,U1,V1,U2,V2);
673
674         StartParams(1) = U1;
675         StartParams(2) = V1;
676         StartParams(3) = U2;
677         StartParams(4) = V2;
678
679         HasStartPoint = PW.PerformFirstPoint(StartParams,StartPOn2S);
680         dminiPointLigne = SeuildPointLigne + SeuildPointLigne;
681         if(HasStartPoint) { 
682           StartPOn2S.Parameters(pu1,pv1,pu2,pv2);
683           if(Abs(pu1-pu2)>1e-7 || Abs(pv1-pv2)>1e-7) { 
684             NbLigCalculee = SLin.Length();
685             Standard_Integer l;
686             for( l = 1; (l <= NbLigCalculee) && (dminiPointLigne >= SeuildPointLigne); l++) { 
687               const Handle(IntPatch_WLine)& testwline = *((Handle(IntPatch_WLine)*)&SLin.Value(l));
688               if( (testwline->IsOutSurf1Box(gp_Pnt2d(pu1,pv1))==Standard_False) &&
689                 (testwline->IsOutSurf2Box(gp_Pnt2d(pu2,pv2))==Standard_False) &&
690                 (testwline->IsOutBox(StartPOn2S.Value())==Standard_False) ) { 
691                   NbPntOn2SOnLine = testwline->NbPnts();
692                   Standard_Integer ll;
693                   for( ll=1; (ll < NbPntOn2SOnLine) && (dminiPointLigne >= SeuildPointLigne); ll++) { 
694                     Standard_Real t,Au1,Av1,Au2,Av2,Bu1,Bv1,Bu2,Bv2;
695                     testwline->Point(ll).Parameters(Au1,Av1,Au2,Av2);
696                     testwline->Point(ll+1).Parameters(Bu1,Bv1,Bu2,Bv2);
697                     if(Au1>Bu1) {
698                       t=Au1;
699                       Au1=Bu1;
700                       Bu1=t;
701                     } 
702                     if(Av1>Bv1) {
703                       t=Av1;
704                       Av1=Bv1;
705                       Bv1=t;
706                     } 
707                     Au1-=1.0e-7;
708                     Av1-=1.0e-7;
709                     Bu1+=1.0e-7;
710                     Bv1+=1.0e-7;
711
712                     if((pu1>=Au1) && (pu1<=Bu1) && (pv1>=Av1) && (pv1<=Bv1))
713                       dminiPointLigne = 0.0; 
714                     else { 
715                       if((pu2>=Au1) && (pu2<=Bu1) && (pv2>=Av1) && (pv2<=Bv1))
716                         dminiPointLigne = 0.0;
717                     }
718                   }// for( ll ...
719               }// if ...
720             }// for( l ...
721
722             if(dminiPointLigne > SeuildPointLigne) { 
723               PW.Perform(StartParams);
724               if(PW.IsDone()) {
725                 if(PW.NbPoints()>2) { 
726                   RejetLigne = Standard_False;
727                   Point3dDebut = PW.Value(1).Value();
728                   Point3dFin   = PW.Value(PW.NbPoints()).Value();
729                   for(ver=1 ; (!RejetLigne) && (ver<= NbLigCalculee) ; ver++) { 
730                     const Handle(IntPatch_WLine)& verwline = *((Handle(IntPatch_WLine)*)&SLin.Value(ver));
731                     const IntSurf_PntOn2S& verPointDebut = verwline->Point(1);
732                     const IntSurf_PntOn2S& verPointFin = verwline->Point(verwline->NbPnts());
733                     if(Point3dDebut.Distance(verPointDebut.Value()) < TolTangency)
734                       RejetLigne = Standard_True; 
735                     else { 
736                       if(Point3dFin.Distance(verPointFin.Value()) < TolTangency)
737                         RejetLigne = Standard_True; 
738                     }
739                   }
740
741                   if(RejetLigne)
742                   {
743                     DublicateOfLinesProcessing(PW, ver, SLin, RejetLigne);
744                   }
745
746                   if(!RejetLigne) { 
747                     IntSurf_TypeTrans trans1,trans2;
748                     Standard_Real locu,locv;
749                     gp_Vec norm1,norm2,d1u,d1v;
750                     gp_Pnt ptbid;
751                     Standard_Integer indextg;
752                     gp_Vec tgline(PW.TangentAtLine(indextg));
753                     PW.Line()->Value(indextg).ParametersOnS1(locu,locv);
754                     Surf1->D1(locu,locv,ptbid,d1u,d1v);
755                     norm1 = d1u.Crossed(d1v);
756                     PW.Line()->Value(indextg).ParametersOnS2(locu,locv);
757                     Surf1->D1(locu,locv,ptbid,d1u,d1v);
758                     norm2 = d1u.Crossed(d1v);
759                     if (tgline.DotCross(norm2,norm1)>0.) {
760                       trans1 = IntSurf_Out;
761                       trans2 = IntSurf_In;
762                     }
763                     else {
764                       trans1 = IntSurf_In;
765                       trans2 = IntSurf_Out;
766                     }
767
768                     IntSurf_LineOn2S LineOn2S;
769                     Standard_Integer nbpw,imin,imax,i;
770                     nbpw = PW.Line()->NbPoints();
771                     Standard_Real u1,v1,u2,v2;
772                     i=0;
773                     do { 
774                       i++;
775                       imin=i;
776                       const IntSurf_PntOn2S& Pi   = PW.Line()->Value(i);
777                       Pi.Parameters(u1,v1,u2,v2);
778                     } while((i<nbpw)&&(Abs(u1-u2)<=1e-6 && Abs(v1-v2)<=1e-6));
779
780                     if(imin>2)
781                       imin--;
782
783                     i=nbpw+1;
784                     do { 
785                       i--;
786                       imax=i;
787                       const IntSurf_PntOn2S& Pi   = PW.Line()->Value(i);
788                       Pi.Parameters(u1,v1,u2,v2);
789                     } while((i>2)&&(Abs(u1-u2)<=1e-6 && Abs(v1-v2)<=1e-6));
790
791                     if(imax<nbpw)
792                       imax++;
793
794                     if(imin<imax) { 
795                       Handle(IntSurf_LineOn2S) PWLine = new IntSurf_LineOn2S();
796                       for(i=imin;i<=imax;i++) 
797                         PWLine->Add(PW.Line()->Value(i));
798
799                       Standard_Real TolTang = TolTangency;
800                       Handle(IntPatch_WLine) wline = new IntPatch_WLine(PWLine,Standard_False,trans1,trans2);
801                       const IntSurf_PntOn2S& POn2SDeb = wline->Point(1);
802                       const IntSurf_PntOn2S& POn2SFin = wline->Point(wline->NbPnts());
803                       if((POn2SDeb.Value()).Distance(POn2SFin.Value()) <= TolTangency) { 
804                         Standard_Real u1t,v1t,u2t,v2t; 
805                         POn2SDeb.Parameters(u1t,v1t,u2t,v2t);
806                         IntPatch_Point vtx;
807                         vtx.SetValue(POn2SDeb.Value(),TolTang,Standard_False);
808                         vtx.SetParameters(u2t,v2t,u1t,v1t);
809                         vtx.SetParameter(wline->NbPnts());
810                         wline->SetPoint(wline->NbPnts(),vtx);
811                       }
812                       IntPatch_RstInt::PutVertexOnLine(wline,Surf1,D1,Surf1,Standard_True,TolTang);
813                       if(wline->NbVertex() == 0) {
814                         IntPatch_Point vtx;
815                         IntSurf_PntOn2S POn2S = PW.Line()->Value(1);
816                         POn2S.Parameters(pu1,pv1,pu2,pv2);
817                         vtx.SetValue(Point3dDebut,TolTang,Standard_False);
818                         vtx.SetParameters(pu1,pv1,pu2,pv2);
819                         vtx.SetParameter(1);
820                         wline->AddVertex(vtx);
821
822                         POn2S = PW.Line()->Value(wline->NbPnts());
823                         POn2S.Parameters(pu1,pv1,pu2,pv2);
824                         vtx.SetValue(Point3dFin,TolTang,Standard_False);
825                         vtx.SetParameters(pu1,pv1,pu2,pv2);
826                         vtx.SetParameter(wline->NbPnts());
827                         wline->AddVertex(vtx);
828                       }
829                       SLin.Append(wline);
830                       empt = Standard_False;
831                     }// imin<imax
832                   }// !RejetLigne
833                 }// PW.NbPoints()>2
834               }// done is True
835             }// dminiPointLigne > SeuildPointLigne
836           }// Abs || Abs
837         }// HasStartPoint
838       } while(nbp>5 && NombreDePointsDeDepartDuCheminement<3);
839     }// for( ls ...
840   }// nbLigSec>=1
841
842   Standard_Integer z;
843   for( z = 1; z <= nbTanZon; z++) { 
844     const Intf_TangentZone& TangentZone=Interference.ZoneValue(z);
845     for(Standard_Integer pz=1; pz<=TangentZone.NumberOfPoints(); pz++) { 
846       SectionPointToParameters(TangentZone.GetPoint(pz),Poly1,Poly1,U1,V1,U2,V2);
847
848       StartParams(1) = U1;
849       StartParams(2) = V1;
850       StartParams(3) = U2;
851       StartParams(4) = V2;
852
853       HasStartPoint = PW.PerformFirstPoint(StartParams,StartPOn2S);     
854       if(HasStartPoint) { 
855         StartPOn2S.Parameters(pu1,pv1,pu2,pv2);
856         if(Abs(pu1-pu2)>1e-7 || Abs(pv1-pv2)>1e-7) { 
857           NbLigCalculee = SLin.Length();
858           dminiPointLigne = SeuildPointLigne + SeuildPointLigne; 
859           Standard_Integer l;
860           for( l = 1; (l <= NbLigCalculee) && (dminiPointLigne >= SeuildPointLigne); l++) { 
861             const Handle(IntPatch_WLine)& testwline = *((Handle(IntPatch_WLine)*)&SLin.Value(l));
862             if( (testwline->IsOutSurf1Box(gp_Pnt2d(pu1,pv1))==Standard_False) &&
863               (testwline->IsOutSurf2Box(gp_Pnt2d(pu2,pv2))==Standard_False) &&
864               (testwline->IsOutBox(StartPOn2S.Value())==Standard_False) ) { 
865                 NbPntOn2SOnLine = testwline->NbPnts();
866                 Standard_Integer ll;
867                 for( ll = 1; (ll < NbPntOn2SOnLine) && (dminiPointLigne >= SeuildPointLigne); ll++) { 
868                   Standard_Real t,Au1,Av1,Au2,Av2,Bu1,Bv1,Bu2,Bv2;
869                   testwline->Point(ll).Parameters(Au1,Av1,Au2,Av2);
870                   testwline->Point(ll+1).Parameters(Bu1,Bv1,Bu2,Bv2);
871                   if(Au1>Bu1) {
872                     t=Au1;
873                     Au1=Bu1;
874                     Bu1=t;
875                   } 
876                   if(Av1>Bv1) {
877                     t=Av1;
878                     Av1=Bv1;
879                     Bv1=t;
880                   } 
881                   Au1-=1.0e-7;
882                   Av1-=1.0e-7;
883                   Bu1+=1.0e-7;
884                   Bv1+=1.0e-7;
885                   if((pu1>=Au1) && (pu1<=Bu1) && (pv1>=Av1) && (pv1<=Bv1))
886                     dminiPointLigne = 0.0; 
887                   else { 
888                     if((pu2>=Au1) && (pu2<=Bu1) && (pv2>=Av1) && (pv2<=Bv1))
889                       dminiPointLigne = 0.0;
890                   }
891                 }// for( ll ...
892             }// if ...
893           }// for( l ...
894
895           if(dminiPointLigne > SeuildPointLigne) { 
896             PW.Perform(StartParams);
897             if(PW.IsDone()) {
898               if(PW.NbPoints()>2) { 
899                 RejetLigne = Standard_False;
900                 Point3dDebut = PW.Value(1).Value();
901                 Point3dFin   = PW.Value(PW.NbPoints()).Value();
902                 for( ver = 1 ; (!RejetLigne) && (ver<= NbLigCalculee) ; ver++) { 
903                   const Handle(IntPatch_WLine)& verwline = *((Handle(IntPatch_WLine)*)&SLin.Value(ver));
904                   const IntSurf_PntOn2S& verPointDebut = verwline->Point(1);
905                   const IntSurf_PntOn2S& verPointFin = verwline->Point(verwline->NbPnts());
906                   if(Point3dDebut.Distance(verPointDebut.Value()) < TolTangency)
907                     RejetLigne = Standard_True; 
908                   else { 
909                     if(Point3dFin.Distance(verPointFin.Value()) < TolTangency)
910                       RejetLigne = Standard_True; 
911                   }
912                 }
913
914                 if(RejetLigne)
915                 {
916                   DublicateOfLinesProcessing(PW, ver, SLin, RejetLigne);
917                 }
918
919                 if(!RejetLigne) { 
920                   IntSurf_TypeTrans trans1,trans2;
921                   Standard_Real locu,locv;
922                   gp_Vec norm1,norm2,d1u,d1v;
923                   gp_Pnt ptbid;
924                   Standard_Integer indextg;
925                   gp_Vec tgline(PW.TangentAtLine(indextg));
926                   PW.Line()->Value(indextg).ParametersOnS1(locu,locv);
927                   Surf1->D1(locu,locv,ptbid,d1u,d1v);
928                   norm1 = d1u.Crossed(d1v);
929                   PW.Line()->Value(indextg).ParametersOnS2(locu,locv);
930                   Surf1->D1(locu,locv,ptbid,d1u,d1v);
931                   norm2 = d1u.Crossed(d1v);
932                   if(tgline.DotCross(norm2,norm1)>0.) {
933                     trans1 = IntSurf_Out;
934                     trans2 = IntSurf_In;
935                   }
936                   else {
937                     trans1 = IntSurf_In;
938                     trans2 = IntSurf_Out;
939                   }
940
941                   IntSurf_LineOn2S LineOn2S;
942                   Standard_Integer nbp,imin,imax,i;
943                   nbp = PW.Line()->NbPoints();
944                   Standard_Real u1,v1,u2,v2;
945                   i=0;
946                   do { 
947                     i++;
948                     imin=i;
949                     const IntSurf_PntOn2S& Pi   = PW.Line()->Value(i);
950                     Pi.Parameters(u1,v1,u2,v2);
951                   } while((i<nbp)&&(Abs(u1-u2)<=1e-6 && Abs(v1-v2)<=1e-6));
952
953                   if(imin>2)
954                     imin--;
955
956                   i=nbp+1;
957                   do { 
958                     i--;
959                     imax=i;
960                     const IntSurf_PntOn2S& Pi   = PW.Line()->Value(i);
961                     Pi.Parameters(u1,v1,u2,v2);
962                   } while((i>2)&&(Abs(u1-u2)<=1e-6 && Abs(v1-v2)<=1e-6));
963
964                   if(imax<nbp)
965                     imax++;
966
967                   if(imin<imax) { 
968                     Handle(IntSurf_LineOn2S) PWLine = new IntSurf_LineOn2S();
969                     for(i=imin;i<=imax;i++)
970                       PWLine->Add(PW.Line()->Value(i));
971
972                     Standard_Real TolTang = TolTangency;
973                     Handle(IntPatch_WLine) wline = new IntPatch_WLine(PWLine,Standard_False,trans1,trans2);
974                     const IntSurf_PntOn2S& POn2SDeb = wline->Point(1);
975                     const IntSurf_PntOn2S& POn2SFin = wline->Point(wline->NbPnts());
976                     if((POn2SDeb.Value()).Distance(POn2SFin.Value()) <= TolTangency) { 
977                       Standard_Real u1t,v1t,u2t,v2t; 
978                       POn2SDeb.Parameters(u1t,v1t,u2t,v2t);
979                       IntPatch_Point vtx;
980                       vtx.SetValue(POn2SDeb.Value(),TolTang,Standard_False);
981                       vtx.SetParameters(u2t,v2t,u1t,v1t);
982                       vtx.SetParameter(wline->NbPnts());
983                       wline->SetPoint(wline->NbPnts(),vtx);
984                     }
985
986                     IntPatch_RstInt::PutVertexOnLine(wline,Surf1,D1,Surf1,Standard_True,TolTang);
987
988                     if(wline->NbVertex() == 0) {
989                       IntPatch_Point vtx;
990                       IntSurf_PntOn2S POn2S = PW.Line()->Value(1);
991                       POn2S.Parameters(pu1,pv1,pu2,pv2);
992                       vtx.SetValue(Point3dDebut,TolTang,Standard_False);
993                       vtx.SetParameters(pu1,pv1,pu2,pv2);
994                       vtx.SetParameter(1);
995                       wline->AddVertex(vtx);
996
997                       POn2S = PW.Line()->Value(wline->NbPnts());
998                       POn2S.Parameters(pu1,pv1,pu2,pv2);
999                       vtx.SetValue(Point3dFin,TolTang,Standard_False);
1000                       vtx.SetParameters(pu1,pv1,pu2,pv2);
1001                       vtx.SetParameter(wline->NbPnts());
1002                       wline->AddVertex(vtx);
1003                     }
1004
1005                     SLin.Append(wline);
1006                     empt = Standard_False;
1007                   }// imin<imax
1008                 }// !RejetLigne
1009               }// PW.NbPoints()>2
1010             }// done a True
1011           }// dminiPointLigne > SeuildPointLigne
1012         }// Abs || Abs
1013       }// HasStartPoint
1014     }// for ( pz ...
1015   }// for( z ...
1016 }
1017
1018 //==================================================================================
1019 // function : NewLine
1020 // purpose  : 
1021 //==================================================================================
1022 Handle(IntPatch_Line) IntPatch_PrmPrmIntersection::NewLine (const Handle(Adaptor3d_HSurface)&    Surf1,
1023                                                            const Handle(Adaptor3d_HSurface)&    Surf2,
1024                                                            const Standard_Integer NumLine,
1025                                                            const Standard_Integer Low,
1026                                                            const Standard_Integer High,
1027                                                            const Standard_Integer NbPntsToInsert) const 
1028
1029   Standard_Integer NbPnts = NbPntsToInsert + High - Low;
1030   if(NumLine>NbLines() || NumLine<1  || Low>=High ) 
1031     Standard_OutOfRange::Raise(" IntPatch_PrmPrmIntersection NewLine "); 
1032   //------------------------------------------------------------------
1033   //--  Indice     :   Low       Low+1     I    I+1         High    --
1034   //--                                                              --
1035   //--  Abs.Curv.  :  S(Low)              S(I)  S(I+1)      S(High) --
1036   //--                                                              --
1037   //--                On echantillonne a abcisse curviligne         --
1038   //--                constante.                                    --
1039   //--                L abcisse est calculee sur les params U1,V1   --
1040   //------------------------------------------------------------------
1041   TColStd_Array1OfReal U1(Low,High);
1042   TColStd_Array1OfReal V1(Low,High);
1043   TColStd_Array1OfReal U2(Low,High);
1044   TColStd_Array1OfReal V2(Low,High);
1045   TColStd_Array1OfReal AC(Low,High);
1046
1047   Standard_Real s,ds;
1048   Handle(IntPatch_WLine) TheLine = Handle(IntPatch_WLine)::DownCast(Line(NumLine));
1049   const IntSurf_PntOn2S& Point=TheLine->Point(Low);
1050   Standard_Real u1,v1,u2,v2;
1051   Point.Parameters(u1,v1,u2,v2);
1052   U1(Low) = u1;
1053   V1(Low) = v1;
1054   U2(Low) = u2;
1055   V2(Low) = v2;
1056   AC(Low) =0.0;
1057
1058   IntWalk_PWalking PW(Surf1,Surf2,0.000001,0.000001,0.001,0.001);
1059
1060   Standard_Integer i;
1061   for(i=Low+1; i<=High; i++)
1062   {
1063     const IntSurf_PntOn2S& Pointi=TheLine->Point(i);
1064     Pointi.Parameters(u1,v1,u2,v2);
1065     U1(i) = u1;
1066     V1(i) = v1;
1067     U2(i) = u2;
1068     V2(i) = v2;
1069
1070     Standard_Real du1=u1-U1(i-1);
1071     Standard_Real dv1=v1-V1(i-1);
1072
1073     AC(i) = AC(i-1) + Sqrt((du1*du1)+(dv1*dv1));
1074   }
1075
1076   Handle(IntSurf_LineOn2S) ResultPntOn2SLine = new IntSurf_LineOn2S();
1077
1078   IntSurf_PntOn2S StartPOn2S;  
1079   TColStd_Array1OfReal StartParams(1,4);
1080
1081   ResultPntOn2SLine->Add(TheLine->Point(Low));
1082
1083   ds = AC(High) / (NbPnts-1);
1084   Standard_Integer Indice = Low;
1085
1086   Standard_Real dsmin = ds*0.3;
1087   Standard_Real smax  = AC(High);
1088
1089   for(i=2,s=ds; (i<NbPnts)&&(s<smax); i++,s+=ds)
1090   { 
1091     while(AC(Indice+1) <= s)
1092     { 
1093       ResultPntOn2SLine->Add(TheLine->Point(Indice));
1094       Indice++;
1095     }
1096     Standard_Real a = s - AC(Indice);
1097     Standard_Real b = AC(Indice+1) - s;
1098     Standard_Real nab = 1.0/(a+b);
1099     //----------------------------------------------------------
1100     //-- Verification :  Si Dist au prochain  point < dsmin   --
1101     //--                 Si Dist au precedent point < dsmin   --
1102     //--                                                      --
1103     //----------------------------------------------------------
1104     if((nab > ds)&&(a>dsmin)&&(b>dsmin))
1105     {
1106       StartParams(1) = (U1(Indice) * b   +  U1(Indice+1) * a) * nab;
1107       StartParams(2) = (V1(Indice) * b   +  V1(Indice+1) * a) * nab;
1108       StartParams(3) = (U2(Indice) * b   +  U2(Indice+1) * a) * nab;
1109       StartParams(4) = (V2(Indice) * b   +  V2(Indice+1) * a) * nab;
1110
1111       Standard_Boolean HasStartPoint = PW.PerformFirstPoint(StartParams,StartPOn2S);
1112       if(HasStartPoint)
1113         ResultPntOn2SLine->Add(StartPOn2S);
1114     }
1115     else
1116       s+=dsmin; 
1117   }
1118
1119   ResultPntOn2SLine->Add(TheLine->Point(High));
1120
1121   return(new IntPatch_WLine(ResultPntOn2SLine,Standard_False));
1122 }
1123
1124 //==================================================================================
1125 // function : SectionPointToParameters
1126 // purpose  : 
1127 //==================================================================================
1128 void SectionPointToParameters(const Intf_SectionPoint& Sp,
1129                               const IntPatch_Polyhedron& Poly1,
1130                               const IntPatch_Polyhedron& Poly2,
1131                               Standard_Real& u1,
1132                               Standard_Real& v1,
1133                               Standard_Real& u2,
1134                               Standard_Real& v2)
1135 {
1136   Intf_PIType       typ;
1137   Standard_Integer  Adr1,Adr2;
1138   Standard_Real     Param,u,v;
1139   gp_Pnt P(Sp.Pnt());
1140
1141   Standard_Integer Pt1,Pt2,Pt3;
1142
1143   Sp.InfoFirst(typ,Adr1,Adr2,Param);
1144   switch(typ) { 
1145   case Intf_VERTEX:   //-- Adr1 est le numero du vertex
1146     {
1147       Poly1.Parameters(Adr1,u1,v1);
1148       break;
1149     }
1150   case Intf_EDGE:
1151     {
1152       Poly1.Parameters(Adr1,u1,v1);    
1153       Poly1.Parameters(Adr2,u,v);
1154       u1+= Param * (u-u1);
1155       v1+= Param * (v-v1);
1156       break;
1157     }
1158   case Intf_FACE:
1159     {
1160       Standard_Real ua,va,ub,vb,uc,vc,ca,cb,cc,cabc;
1161       Poly1.Triangle(Adr1,Pt1,Pt2,Pt3);
1162       gp_Pnt PA(Poly1.Point(Pt1));
1163       gp_Pnt PB(Poly1.Point(Pt2));
1164       gp_Pnt PC(Poly1.Point(Pt3));
1165       Poly1.Parameters(Pt1,ua,va);
1166       Poly1.Parameters(Pt2,ub,vb);
1167       Poly1.Parameters(Pt3,uc,vc);
1168       gp_Vec Normale(gp_Vec(PA,PB).Crossed(gp_Vec(PA,PC)));
1169       cc = (gp_Vec(PA,PB).Crossed(gp_Vec(PA,P))).Dot(Normale);
1170       ca = (gp_Vec(PB,PC).Crossed(gp_Vec(PB,P))).Dot(Normale);
1171       cb = (gp_Vec(PC,PA).Crossed(gp_Vec(PC,P))).Dot(Normale);
1172       cabc = ca + cb + cc;
1173
1174       ca/=cabc;     cb/=cabc;       cc/=cabc;
1175
1176       u1 = ca * ua + cb * ub + cc * uc;
1177       v1 = ca * va + cb * vb + cc * vc;
1178       break;
1179     }
1180   default: 
1181     {
1182       //-- cout<<" Default dans SectionPointToParameters "<<endl;
1183       break;
1184     }
1185   }
1186
1187
1188   Sp.InfoSecond(typ,Adr1,Adr2,Param);
1189   switch(typ) { 
1190   case Intf_VERTEX:   //-- Adr1 est le numero du vertex
1191     {
1192       Poly2.Parameters(Adr1,u2,v2);
1193       break;
1194     }
1195   case Intf_EDGE:
1196     {
1197       Poly2.Parameters(Adr1,u2,v2);    
1198       Poly2.Parameters(Adr2,u,v);
1199       u2+= Param * (u-u2);
1200       v2+= Param * (v-v2);
1201       break;
1202     }
1203   case Intf_FACE:
1204     {
1205       Standard_Real ua,va,ub,vb,uc,vc,ca,cb,cc,cabc;
1206       Poly2.Triangle(Adr1,Pt1,Pt2,Pt3);
1207       gp_Pnt PA(Poly2.Point(Pt1));
1208       gp_Pnt PB(Poly2.Point(Pt2));
1209       gp_Pnt PC(Poly2.Point(Pt3));
1210       Poly2.Parameters(Pt1,ua,va);
1211       Poly2.Parameters(Pt2,ub,vb);
1212       Poly2.Parameters(Pt3,uc,vc);
1213       gp_Vec Normale(gp_Vec(PA,PB).Crossed(gp_Vec(PA,PC)));
1214       cc = (gp_Vec(PA,PB).Crossed(gp_Vec(PA,P))).Dot(Normale);
1215       ca = (gp_Vec(PB,PC).Crossed(gp_Vec(PB,P))).Dot(Normale);
1216       cb = (gp_Vec(PC,PA).Crossed(gp_Vec(PC,P))).Dot(Normale);
1217       cabc = ca + cb + cc;
1218
1219       ca/=cabc;     cb/=cabc;       cc/=cabc;
1220
1221       u2 = ca * ua + cb * ub + cc * uc;
1222       v2 = ca * va + cb * vb + cc * vc;
1223       break;
1224     }
1225   default: 
1226     {
1227       //-- cout<<" Default dans SectionPointToParameters "<<endl;
1228       break;
1229     }
1230   }
1231
1232
1233 //==================================================================================
1234 // function : RemplitLin
1235 // purpose  : 
1236 //==================================================================================
1237 void IntPatch_PrmPrmIntersection::RemplitLin(const Standard_Integer x1,
1238                                              const Standard_Integer y1,
1239                                              const Standard_Integer z1,
1240                                              const Standard_Integer x2,
1241                                              const Standard_Integer y2,
1242                                              const Standard_Integer z2,
1243                                              IntPatch_PrmPrmIntersection_T3Bits& Map) const 
1244 {
1245   int xg,yg,zg;
1246   xg=x1-x2; if(xg<0) xg=-xg; 
1247   yg=y1-y2; if(yg<0) yg=-yg; 
1248   zg=z1-z2; if(zg<0) zg=-zg; 
1249   if(DansGrille(x1) && DansGrille(y1) && DansGrille(z1)) { 
1250     Standard_Integer t = GrilleInteger(x1,y1,z1); 
1251     Map.Add(t);
1252   }
1253   if(xg<=1 && yg<=1 && zg<=1) return;
1254   xg = (x1+x2)>>1;
1255   yg = (y1+y2)>>1;
1256   zg = (z1+z2)>>1;
1257   RemplitLin(x1,y1,z1,xg,yg,zg,Map);
1258   RemplitLin(x2,y2,z2,xg,yg,zg,Map);
1259 }
1260
1261 //==================================================================================
1262 // function : RemplitTri
1263 // purpose  : 
1264 //==================================================================================
1265 void IntPatch_PrmPrmIntersection::RemplitTri(const Standard_Integer x1,
1266                                              const Standard_Integer y1,
1267                                              const Standard_Integer z1,
1268                                              const Standard_Integer x2,
1269                                              const Standard_Integer y2,
1270                                              const Standard_Integer z2,
1271                                              const Standard_Integer x3,
1272                                              const Standard_Integer y3,
1273                                              const Standard_Integer z3,
1274                                              IntPatch_PrmPrmIntersection_T3Bits& Map) const 
1275
1276   if(x1==x2 && x1==x3 && y1==y2 && y1==y3 && z1==z2 && z1==z3) {
1277     if(DansGrille(x1) && DansGrille(y1) && DansGrille(z1)) { 
1278       Standard_Integer t = GrilleInteger(x1,y1,z1); 
1279       Map.Add(t);
1280     }
1281     return;
1282   }
1283   else { 
1284     Standard_Integer xg=(x1+x2+x3)/3;
1285     Standard_Integer yg=(y1+y2+y3)/3;
1286     Standard_Integer zg=(z1+z2+z3)/3;
1287     if(xg==x1 && yg==y1 && zg==z1) { 
1288       RemplitLin(x1,y1,z1,x2,y2,z2,Map);
1289       RemplitLin(x1,y1,z1,x3,y3,z3,Map);
1290       return;
1291     }
1292     if(xg==x2 && yg==y2 && zg==z2) { 
1293       RemplitLin(x2,y2,z2,x1,y1,z1,Map);
1294       RemplitLin(x2,y2,z2,x3,y3,z3,Map);
1295       return;
1296     }
1297     if(xg==x3 && yg==y3 && zg==z3) { 
1298       RemplitLin(x3,y3,z3,x2,y2,z2,Map);
1299       RemplitLin(x3,y3,z3,x1,y1,z1,Map);
1300       return;
1301     }
1302     if(DansGrille(xg) && DansGrille(yg) && DansGrille(zg)) {
1303       Standard_Integer t = GrilleInteger(xg,yg,zg); 
1304       Map.Add(t);
1305     }
1306     if(xg!=x3 || yg!=y3 || zg!=z3) RemplitTri(x1,y1,z1, x2,y2,z2, xg,yg,zg, Map);
1307     if(xg!=x1 || yg!=y1 || zg!=z1) RemplitTri(xg,yg,zg, x2,y2,z2, x3,y3,z3, Map);
1308     if(xg!=x2 || yg!=y2 || zg!=z2) RemplitTri(x1,y1,z1, xg,yg,zg, x3,y3,z3, Map);
1309   }
1310 }
1311
1312 //==================================================================================
1313 // function : Remplit
1314 // purpose  : 
1315 //==================================================================================
1316 void IntPatch_PrmPrmIntersection::Remplit(const Standard_Integer a,
1317                                           const Standard_Integer b,
1318                                           const Standard_Integer c,
1319                                           IntPatch_PrmPrmIntersection_T3Bits& Map) const 
1320
1321   int iax,iay,iaz,ibx,iby,ibz,icx,icy,icz;
1322   if(a!=-1) Map.Add(a);
1323   if(b!=-1) Map.Add(b);
1324   if(c!=-1) Map.Add(c);
1325
1326   if(a!=-1 && b!=-1 && c!=-1 ) { 
1327     IntegerGrille(a,iax,iay,iaz);
1328     IntegerGrille(b,ibx,iby,ibz);
1329     IntegerGrille(c,icx,icy,icz);
1330     RemplitTri(iax,iay,iaz,ibx,iby,ibz,icx,icy,icz,Map);
1331   }
1332 }
1333
1334
1335
1336 //=======================================================================
1337 //function : Perform
1338 //purpose  : 
1339 //=======================================================================
1340 void IntPatch_PrmPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)&    Surf1,
1341                                            const Handle(Adaptor3d_TopolTool)& D1,
1342                                            const Handle(Adaptor3d_HSurface)&    Surf2,
1343                                            const Handle(Adaptor3d_TopolTool)& D2,
1344                                            const Standard_Real   TolTangency,
1345                                            const Standard_Real   Epsilon,
1346                                            const Standard_Real   Deflection,
1347                                            const Standard_Real   Increment,
1348                                            IntSurf_ListOfPntOn2S& LOfPnts,
1349                                            const Standard_Boolean RestrictLine)
1350 {
1351   if (LOfPnts.IsEmpty()){
1352     done = Standard_True;
1353     return;
1354   }
1355
1356   empt = Standard_True;
1357   SLin.Clear();  
1358
1359   Standard_Real UminLig1,VminLig1,UmaxLig1,VmaxLig1;
1360   Standard_Real UminLig2,VminLig2,UmaxLig2,VmaxLig2;
1361   Standard_Real U1,U2,V1,V2;
1362
1363   UminLig1 = Surf1->FirstUParameter();
1364   VminLig1 = Surf1->FirstVParameter();
1365   UmaxLig1 = Surf1->LastUParameter();
1366   VmaxLig1 = Surf1->LastVParameter();
1367   UminLig2 = Surf2->FirstUParameter();
1368   VminLig2 = Surf2->FirstVParameter();
1369   UmaxLig2 = Surf2->LastUParameter();
1370   VmaxLig2 = Surf2->LastVParameter();
1371
1372   Standard_Real Periods [4];
1373   Periods[0] = (Surf1->IsUPeriodic())? Surf1->UPeriod() : 0.;
1374   Periods[1] = (Surf1->IsVPeriodic())? Surf1->VPeriod() : 0.;
1375   Periods[2] = (Surf2->IsUPeriodic())? Surf2->UPeriod() : 0.;
1376   Periods[3] = (Surf2->IsVPeriodic())? Surf2->VPeriod() : 0.;
1377
1378   IntSurf_ListIteratorOfListOfPntOn2S IterLOP1(LOfPnts);
1379   if (Surf1->IsUClosed() || Surf1->IsVClosed() ||
1380       Surf2->IsUClosed() || Surf2->IsVClosed())
1381   {
1382     Standard_Real TolPar = Precision::PConfusion();
1383     IntSurf_ListOfPntOn2S AdditionalPnts;
1384     Standard_Real NewU1, NewV1, NewU2, NewV2;
1385     for(; IterLOP1.More(); IterLOP1.Next())
1386     {
1387       IntSurf_PntOn2S Pnt = IterLOP1.Value();
1388       Pnt.Parameters(U1, V1, U2, V2);
1389       IntSurf_PntOn2S NewPnt;
1390       if (Surf1->IsUClosed())
1391       {
1392         if (Abs(U1 - Surf1->FirstUParameter()) <= TolPar)
1393         {
1394           NewU1 = Surf1->LastUParameter();
1395           NewPnt.SetValue( NewU1, V1, U2, V2 );
1396           AdditionalPnts.Append(NewPnt);
1397         }
1398         else if (Abs(U1 - Surf1->LastUParameter()) <= TolPar)
1399         {
1400           NewU1 = Surf1->FirstUParameter();
1401           NewPnt.SetValue( NewU1, V1, U2, V2 );
1402           AdditionalPnts.Append(NewPnt);
1403         }
1404       }
1405       if (Surf1->IsVClosed())
1406       {
1407         if (Abs(V1 - Surf1->FirstVParameter()) <= TolPar)
1408         {
1409           NewV1 = Surf1->LastVParameter();
1410           NewPnt.SetValue( U1, NewV1, U2, V2 );
1411           AdditionalPnts.Append(NewPnt);
1412         }
1413         else if (Abs(V1 - Surf1->LastVParameter()) <= TolPar)
1414         {
1415           NewV1 = Surf1->FirstVParameter();
1416           NewPnt.SetValue( U1, NewV1, U2, V2 );
1417           AdditionalPnts.Append(NewPnt);
1418         }
1419       }
1420       if (Surf2->IsUClosed())
1421       {
1422         if (Abs(U2 - Surf2->FirstUParameter()) <= TolPar)
1423         {
1424           NewU2 = Surf2->LastUParameter();
1425           NewPnt.SetValue( U1, V1, NewU2, V2);
1426           AdditionalPnts.Append(NewPnt);
1427         }
1428         else if (Abs(U2 - Surf2->LastUParameter()) <= TolPar)
1429         {
1430           NewU2 = Surf2->FirstUParameter();
1431           NewPnt.SetValue( U1, V1, NewU2, V2);
1432           AdditionalPnts.Append(NewPnt);
1433         }
1434       }
1435       if (Surf2->IsVClosed())
1436       {
1437         if (Abs(V2 - Surf2->FirstVParameter()) <= TolPar)
1438         {
1439           NewV2 = Surf2->LastVParameter();
1440           NewPnt.SetValue( U1, V1, U2, NewV2 );
1441           AdditionalPnts.Append(NewPnt);
1442         }
1443         else if (Abs(V2 - Surf2->LastVParameter()) <= TolPar)
1444         {
1445           NewV2 = Surf2->FirstVParameter();
1446           NewPnt.SetValue( U1, V1, U2, NewV2 );
1447           AdditionalPnts.Append(NewPnt);
1448         }
1449       }
1450     }
1451     //Cut repeated points
1452     for (IterLOP1.Initialize(LOfPnts); IterLOP1.More(); IterLOP1.Next())
1453     {
1454       IntSurf_PntOn2S aPnt = IterLOP1.Value();
1455       aPnt.Parameters(U1, V1, U2, V2);
1456       IntSurf_ListIteratorOfListOfPntOn2S iter2(AdditionalPnts);
1457       while (iter2.More())
1458       {
1459         IntSurf_PntOn2S aNewPnt = iter2.Value();
1460         aNewPnt.Parameters(NewU1, NewV1, NewU2, NewV2);
1461         if (Abs(U1 - NewU1) <= TolPar &&
1462             Abs(V1 - NewV1) <= TolPar &&
1463             Abs(U2 - NewU2) <= TolPar &&
1464             Abs(V2 - NewV2) <= TolPar)
1465           AdditionalPnts.Remove(iter2);
1466         else
1467           iter2.Next();
1468       }
1469     }
1470
1471     LOfPnts.Append(AdditionalPnts);
1472   }
1473
1474   for(IterLOP1.Initialize(LOfPnts); IterLOP1.More(); IterLOP1.Next()){
1475     IntSurf_PntOn2S Pnt = IterLOP1.Value();
1476     Pnt.Parameters(U1, V1, U2, V2);
1477     if(U1>UmaxLig1) UmaxLig1=U1;
1478     if(V1>VmaxLig1) VmaxLig1=V1;
1479     if(U2>UmaxLig2) UmaxLig2=U2;
1480     if(V2>VmaxLig2) VmaxLig2=V2;
1481
1482     if(U1<UminLig1) UminLig1=U1;
1483     if(V1<VminLig1) VminLig1=V1;
1484     if(U2<UminLig2) UminLig2=U2;
1485     if(V2<VminLig2) VminLig2=V2; 
1486   }
1487
1488   Standard_Real SeuildPointLigne = 15.0 * Increment * Increment;
1489
1490   Standard_Integer NbLigCalculee = 0, ver;
1491   Standard_Real pu1,pu2,pv1,pv2, dminiPointLigne;
1492   Standard_Boolean HasStartPoint,RejetLigne;
1493   IntSurf_PntOn2S StartPOn2S;
1494   gp_Pnt Point3dDebut,Point3dFin;
1495
1496   TColStd_Array1OfReal StartParams(1,4);
1497   IntWalk_PWalking PW(Surf1,Surf2,TolTangency,Epsilon,Deflection,Increment);  
1498
1499   IntSurf_ListIteratorOfListOfPntOn2S IterLOP2(LOfPnts);
1500   for(; IterLOP2.More(); IterLOP2.Next() ){
1501
1502     IntSurf_PntOn2S cPnt = IterLOP2.Value();
1503     cPnt.Parameters(U1, V1, U2, V2);
1504
1505     StartParams(1) = U1;
1506     StartParams(2) = V1;
1507     StartParams(3) = U2;
1508     StartParams(4) = V2;
1509
1510     HasStartPoint = PW.PerformFirstPoint(StartParams,StartPOn2S);
1511     dminiPointLigne = SeuildPointLigne + SeuildPointLigne;
1512     if(HasStartPoint) {
1513       StartPOn2S.Parameters(pu1,pv1,pu2,pv2);
1514       NbLigCalculee = SLin.Length();
1515       Standard_Integer l;
1516       for( l = 1; (l <= NbLigCalculee) && (dminiPointLigne >= SeuildPointLigne); l++) { 
1517         const Handle(IntPatch_WLine)& testwline = *((Handle(IntPatch_WLine)*)&SLin.Value(l));
1518
1519         if (IsPointOnLine(StartPOn2S, testwline, Deflection)) {
1520           dminiPointLigne = 0.0;
1521         }
1522       }// for( l ...
1523
1524       if(dminiPointLigne > SeuildPointLigne) {
1525         PW.Perform(StartParams,UminLig1,VminLig1,UminLig2,VminLig2,UmaxLig1,VmaxLig1,UmaxLig2,VmaxLig2);
1526         if(PW.IsDone()) {
1527           if(PW.NbPoints()>2)
1528           {
1529             //Try to extend the intersection line to boundary, if it is possibly
1530             Standard_Boolean hasBeenAdded = PW.PutToBoundary(Surf1, Surf2);
1531
1532             RejetLigne = Standard_False;
1533             Point3dDebut = PW.Value(1).Value();
1534             const IntSurf_PntOn2S& PointFin = PW.Value(PW.NbPoints());
1535             Point3dFin   = PointFin.Value();
1536             for( ver = 1 ; (!RejetLigne) && (ver<= NbLigCalculee) ; ver++) { 
1537               const Handle(IntPatch_WLine)& verwline = *((Handle(IntPatch_WLine)*)&SLin.Value(ver));
1538
1539               // Check end point if it is on existing line.
1540               // Start point is checked before.
1541               if (IsPointOnLine(PointFin, verwline, Deflection)) {
1542                 RejetLigne = Standard_True; 
1543                 break;
1544               }
1545
1546               const IntSurf_PntOn2S& verPointDebut = verwline->Point(1);
1547               const IntSurf_PntOn2S& verPointFin = verwline->Point(verwline->NbPnts());
1548               if(Point3dDebut.Distance(verPointDebut.Value()) <= TolTangency) { 
1549                 if(Point3dFin.Distance(verPointFin.Value()) <= TolTangency)
1550                   RejetLigne = Standard_True; 
1551               }
1552             }
1553
1554             if(RejetLigne)
1555             {
1556               DublicateOfLinesProcessing(PW, ver, SLin, RejetLigne);
1557             }
1558
1559             if(!RejetLigne) {
1560               IntSurf_TypeTrans trans1,trans2;
1561               Standard_Real locu,locv;
1562               gp_Vec norm1,norm2,d1u,d1v;
1563               gp_Pnt ptbid;
1564               Standard_Integer indextg;
1565               gp_Vec tgline(PW.TangentAtLine(indextg));
1566               PW.Line()->Value(indextg).ParametersOnS1(locu,locv);
1567               Surf1->D1(locu,locv,ptbid,d1u,d1v);
1568               norm1 = d1u.Crossed(d1v);
1569               PW.Line()->Value(indextg).ParametersOnS2(locu,locv);
1570               Surf2->D1(locu,locv,ptbid,d1u,d1v);
1571               norm2 = d1u.Crossed(d1v);
1572               if( tgline.DotCross(norm2,norm1) >= 0. ) {
1573                 trans1 = IntSurf_Out;
1574                 trans2 = IntSurf_In;
1575               }
1576               else {
1577                 trans1 = IntSurf_In;
1578                 trans2 = IntSurf_Out;
1579               }
1580
1581               Standard_Real TolTang = TolTangency;
1582               Handle(IntPatch_WLine) wline = new IntPatch_WLine(PW.Line(),Standard_False,trans1,trans2);
1583               if (RestrictLine){
1584                 IntPatch_RstInt::PutVertexOnLine(wline,Surf1,D1,Surf2,Standard_True,TolTang,hasBeenAdded);
1585                 IntPatch_RstInt::PutVertexOnLine(wline,Surf2,D2,Surf1,Standard_False,TolTang,hasBeenAdded);
1586               }
1587
1588               if(wline->NbVertex() == 0) {
1589                 IntPatch_Point vtx;
1590                 IntSurf_PntOn2S POn2S = PW.Line()->Value(1);
1591                 POn2S.Parameters(pu1,pv1,pu2,pv2);
1592                 vtx.SetValue(Point3dDebut,TolTang,Standard_False);
1593                 vtx.SetParameters(pu1,pv1,pu2,pv2);
1594                 vtx.SetParameter(1);
1595                 wline->AddVertex(vtx);
1596
1597                 POn2S = PW.Line()->Value(wline->NbPnts());
1598                 POn2S.Parameters(pu1,pv1,pu2,pv2);
1599                 vtx.SetValue(Point3dFin,TolTang,Standard_False);
1600                 vtx.SetParameters(pu1,pv1,pu2,pv2);
1601                 vtx.SetParameter(wline->NbPnts());
1602                 wline->AddVertex(vtx);
1603               }              
1604
1605               Standard_Integer slinlen = SLin.Length();
1606               if( slinlen > 0 ) {
1607                 Standard_Integer cnbV = wline->NbVertex();
1608                 Standard_Integer ciV;
1609                 for( ciV = 1; ciV <= cnbV; ciV++ ) {
1610                   Standard_Real pntDMin = 1.e+100;
1611                   Standard_Integer VDMin = 0;
1612                   Standard_Integer WLDMin = 0;
1613                   gp_Pnt cPV = wline->Vertex(ciV).Value();
1614                   Standard_Integer iL;
1615                   for( iL = 1; iL <= slinlen; iL++) {
1616                     const Handle(IntPatch_Line)& aSLine = SLin.Value(iL);
1617                     IntPatch_IType aType = aSLine->ArcType();
1618                     if( aType != IntPatch_Walking)
1619                       continue;
1620                     const Handle(IntPatch_WLine)&  aWLine = (*((Handle(IntPatch_WLine)*)&aSLine));
1621                     Standard_Integer tnbV = aWLine->NbVertex();
1622                     Standard_Integer tiV;
1623                     for( tiV = 1; tiV <= tnbV; tiV++ ) {
1624                       gp_Pnt tPV = aWLine->Vertex(tiV).Value();
1625                       Standard_Real tDistance = cPV.Distance(tPV);
1626                       Standard_Real uRs1 = Surf1->Surface().UResolution(tDistance);
1627                       Standard_Real vRs1 = Surf1->Surface().VResolution(tDistance);
1628                       Standard_Real uRs2 = Surf2->Surface().UResolution(tDistance);
1629                       Standard_Real vRs2 = Surf2->Surface().VResolution(tDistance);
1630                       Standard_Real RmaxS1 = Max(uRs1,vRs1);
1631                       Standard_Real RmaxS2 = Max(uRs2,vRs2);
1632                       if(RmaxS1 < 1.e-4 && RmaxS2 < 1.e-4) {
1633                         if( pntDMin > tDistance && tDistance > 1.e-9) {
1634                           pntDMin = tDistance;
1635                           VDMin = tiV;
1636                           WLDMin = iL;
1637                         }
1638                       }
1639                     }
1640                   }
1641
1642                   if( VDMin != 0 ) {
1643                     const Handle(IntPatch_Line)& aSLine = SLin.Value(WLDMin);
1644                     const Handle(IntPatch_WLine)&  aWLine = (*((Handle(IntPatch_WLine)*)&aSLine));
1645                     Standard_Integer tiVpar = (Standard_Integer)aWLine->Vertex(VDMin).ParameterOnLine();
1646                     Standard_Integer ciVpar = (Standard_Integer)wline->Vertex(ciV).ParameterOnLine();
1647                     Standard_Real u11 = 0., u12 = 0., v11 = 0., v12 = 0.;
1648                     Standard_Real u21 = 0., u22 = 0., v21 = 0., v22 = 0.;
1649                     wline->Point(ciVpar).Parameters(u11,v11,u12,v12);
1650                     aWLine->Point(tiVpar).Parameters(u21,v21,u22,v22);
1651
1652                     Handle(IntSurf_LineOn2S) newL2s = new IntSurf_LineOn2S();
1653                     IntSurf_PntOn2S replacePnt = aWLine->Point(tiVpar);
1654                     Standard_Integer cNbP = wline->NbPnts();
1655
1656                     TColStd_SequenceOfInteger VPold;
1657                     Standard_Integer iPo;
1658                     for( iPo = 1; iPo <= cnbV; iPo++ ) {
1659                       Standard_Real Po = wline->Vertex(iPo).ParameterOnLine();
1660                       Standard_Integer IPo = (Standard_Integer) Po;
1661                       VPold.Append(IPo);
1662                     }
1663
1664                     Standard_Boolean removeNext = Standard_False;
1665                     Standard_Boolean removePrev = Standard_False;
1666                     if( ciV == 1) {
1667                       Standard_Integer dPar = Abs( VPold.Value(ciV) - VPold.Value(ciV+1));
1668                       if(dPar > 10) {
1669                         removeNext = Standard_True;
1670                         for( iPo = (ciV+1); iPo <= cnbV; iPo++ )
1671                           VPold.SetValue(iPo, VPold.Value(iPo) - 1 );
1672                       }
1673                     }
1674                     else if( ciV == cnbV) {
1675                       Standard_Integer dPar = Abs( VPold.Value(ciV) - VPold.Value(ciV-1));
1676                       if(dPar > 10) {
1677                         removePrev = Standard_True;
1678                         VPold.SetValue(ciV, VPold.Value(ciV) - 1 );
1679                       }
1680                     }
1681                     else {
1682                       Standard_Integer dParMi = Abs( VPold.Value(ciV) - VPold.Value(ciV-1));
1683                       Standard_Integer dParMa = Abs( VPold.Value(ciV) - VPold.Value(ciV+1));
1684                       if(dParMi > 10) {
1685                         removePrev = Standard_True;
1686                         VPold.SetValue(ciV, VPold.Value(ciV) - 1 );
1687                       }
1688                       if(dParMa > 10) {
1689                         removeNext = Standard_True;
1690                         for( iPo = (ciV+1); iPo <= cnbV; iPo++ ) {
1691                           if(dParMi > 10)
1692                             VPold.SetValue(iPo, VPold.Value(iPo) - 2 );
1693                           else
1694                             VPold.SetValue(iPo, VPold.Value(iPo) - 1 );
1695                         }
1696                       }
1697                       else {
1698                         if(dParMi > 10)
1699                           for( iPo = (ciV+1); iPo <= cnbV; iPo++ )
1700                             VPold.SetValue(iPo, VPold.Value(iPo) - 1 );
1701                       } 
1702                     }
1703                     Standard_Integer pI = (Standard_Integer) ciVpar;
1704
1705                     Standard_Integer iP;
1706                     for( iP = 1; iP <= cNbP; iP++) {
1707                       if( pI == iP )
1708                       {
1709                         IntSurf_PntOn2S newPnt = MakeNewPoint(replacePnt, wline->Point(iP), Periods);
1710                         newL2s->Add(newPnt);
1711                       }
1712                       else if(removeNext && iP == (pI + 1))
1713                         continue;
1714                       else if(removePrev && iP == (pI - 1))
1715                         continue;
1716                       else
1717                         newL2s->Add(wline->Point(iP));
1718                     }
1719
1720                     IntPatch_Point newVtx;
1721                     gp_Pnt Pnt3dV = aWLine->Vertex(VDMin).Value();
1722                     newVtx.SetValue(Pnt3dV,TolTang,Standard_False);
1723                     newVtx.SetParameters(u21,v21,u22,v22);
1724                     newVtx.SetParameter(VPold.Value(ciV));
1725
1726                     Handle(IntPatch_WLine) NWLine = new IntPatch_WLine(newL2s,Standard_False,trans1,trans2);
1727
1728                     Standard_Integer iV;
1729                     for( iV = 1; iV <= cnbV; iV++ ) {
1730                       if( iV == ciV )
1731                         NWLine->AddVertex(newVtx);
1732                       else {
1733                         IntPatch_Point theVtx = wline->Vertex(iV);
1734                         theVtx.SetParameter(VPold.Value(iV));
1735                         NWLine->AddVertex(theVtx);
1736                       }
1737                     }
1738
1739                     wline = NWLine;
1740                   }
1741                 }
1742               }// SLin.Length > 0
1743
1744               AddWLine(SLin, wline, Deflection);
1745               empt = Standard_False;
1746             }// !RejetLigne
1747           }// PW points > 2
1748         }// done is True
1749       }// dminiPointLigne > SeuildPointLigne
1750     }// HasStartPoint  
1751   }// for( IterLOP ...
1752   done = Standard_True;
1753   return;      
1754 }
1755 //=======================================================================
1756 //function : Perform
1757 //purpose  : 
1758 //=======================================================================
1759 void IntPatch_PrmPrmIntersection::Perform(const Handle(Adaptor3d_HSurface)&    Surf1,
1760                                           const Handle(Adaptor3d_TopolTool)& D1,
1761                                           const Handle(Adaptor3d_HSurface)&    Surf2,
1762                                           const Handle(Adaptor3d_TopolTool)& D2,
1763                                           const Standard_Real   U1Depart,
1764                                           const Standard_Real   V1Depart,
1765                                           const Standard_Real   U2Depart,
1766                                           const Standard_Real   V2Depart,
1767                                           const Standard_Real   TolTangency,
1768                                           const Standard_Real   Epsilon,
1769                                           const Standard_Real   Deflection,
1770                                           const Standard_Real   Increment)
1771 {
1772   //    Standard_Integer NbU1 = D1->NbSamplesU();
1773   //    Standard_Integer NbV1 = D1->NbSamplesV();
1774   //    Standard_Integer NbU2 = D2->NbSamplesU();
1775   //    Standard_Integer NbV2 = D2->NbSamplesV();
1776
1777   //-- Traitement des Lignes de sections
1778   empt = Standard_True;
1779   done = Standard_True;
1780   SLin.Clear();  
1781
1782   //------------------------------------------------------------
1783
1784   Standard_Real pu1,pu2,pv1,pv2;
1785
1786   TColStd_Array1OfReal StartParams(1,4);
1787
1788   //    Standard_Integer MaxOscill = NbU1;
1789   //    if(MaxOscill < NbU2) MaxOscill=NbU2;
1790   //    if(MaxOscill < NbV1) MaxOscill=NbV1;
1791   //    if(MaxOscill < NbV2) MaxOscill=NbV2;
1792
1793   //    Standard_Real nIncrement=Increment;
1794   //    if(MaxOscill>10) { 
1795   //  #ifdef OCCT_DEBUG
1796   //      cout<<"\n IntPatch_PrmPrmIntersection.gxx : Increment:"<<Increment<<" -> "<<Increment/(0.5*MaxOscill)<<endl;
1797   //  #endif
1798   //      nIncrement/=0.5*MaxOscill;
1799   //    }
1800
1801   IntWalk_PWalking PW(Surf1,Surf2,
1802     TolTangency,
1803     Epsilon,
1804     Deflection,
1805     Increment); //nIncrement);
1806
1807
1808   //Standard_Real    SeuildPointLigne = 15.0 * Increment * Increment; //-- 10 est insuffisant
1809   //Standard_Real    incidence;
1810   //Standard_Real    dminiPointLigne;
1811
1812   Standard_Boolean HasStartPoint;//,RejetLigne;
1813
1814   IntSurf_PntOn2S StartPOn2S;
1815
1816   //Standard_Integer ver;
1817
1818   gp_Pnt Point3dDebut,Point3dFin;
1819
1820   //------------------------------------------------------------
1821
1822   StartParams(1) = U1Depart;
1823   StartParams(2) = V1Depart;
1824   StartParams(3) = U2Depart;
1825   StartParams(4) = V2Depart;
1826
1827   //-----------------------------------------------------------------------
1828   //-- Calcul du premier point de cheminement a partir du point approche --
1829   //-----------------------------------------------------------------------
1830   HasStartPoint = PW.PerformFirstPoint(StartParams,StartPOn2S); 
1831   if(HasStartPoint) { 
1832     //-------------------------------------------------
1833     //-- Un point a ete trouve                       --
1834     //-- On verifie qu il n appartient pas           --
1835     //--  a une ligne de cheminement deja calculee.  --
1836     //-------------------------------------------------
1837
1838     PW.Perform(StartParams);
1839     if(PW.IsDone()) {
1840
1841       Point3dDebut = PW.Value(1).Value();
1842       Point3dFin   = PW.Value(PW.NbPoints()).Value();
1843
1844       IntSurf_TypeTrans trans1,trans2;
1845       Standard_Real locu,locv;
1846       gp_Vec norm1,norm2,d1u,d1v;
1847       gp_Pnt ptbid;
1848       Standard_Integer indextg;
1849       gp_Vec tgline(PW.TangentAtLine(indextg));
1850       PW.Line()->Value(indextg).ParametersOnS1(locu,locv);
1851       Surf1->D1(locu,locv,ptbid,d1u,d1v);
1852       norm1 = d1u.Crossed(d1v);
1853       PW.Line()->Value(indextg).ParametersOnS2(locu,locv);
1854       Surf2->D1(locu,locv,ptbid,d1u,d1v);
1855       norm2 = d1u.Crossed(d1v);
1856       if (tgline.DotCross(norm2,norm1)>0.) {
1857         trans1 = IntSurf_Out;
1858         trans2 = IntSurf_In;
1859       }
1860       else {
1861         trans1 = IntSurf_In;
1862         trans2 = IntSurf_Out;
1863       }
1864
1865
1866
1867       Standard_Real TolTang = TolTangency;
1868       Handle(IntPatch_WLine) wline = new IntPatch_WLine(PW.Line(),Standard_False,trans1,trans2);
1869       IntPatch_RstInt::PutVertexOnLine(wline,Surf1,D1,Surf2,Standard_True,TolTang);
1870       IntPatch_RstInt::PutVertexOnLine(wline,Surf2,D2,Surf1,Standard_False,TolTang);
1871
1872       //---------------
1873       if(wline->NbVertex() == 0) {
1874         IntPatch_Point vtx;
1875         IntSurf_PntOn2S POn2S = PW.Line()->Value(1);
1876         POn2S.Parameters(pu1,pv1,pu2,pv2);
1877         vtx.SetValue(Point3dDebut,TolTang,Standard_False);
1878         vtx.SetParameters(pu1,pv1,pu2,pv2);
1879         vtx.SetParameter(1);
1880         wline->AddVertex(vtx);
1881
1882         POn2S = PW.Line()->Value(wline->NbPnts());
1883         POn2S.Parameters(pu1,pv1,pu2,pv2);
1884         vtx.SetValue(Point3dFin,TolTang,Standard_False);
1885         vtx.SetParameters(pu1,pv1,pu2,pv2);
1886         vtx.SetParameter(wline->NbPnts());
1887         wline->AddVertex(vtx);
1888       }
1889
1890       //---------------
1891       SLin.Append(wline);
1892       empt = Standard_False;
1893
1894     }
1895   }
1896 }
1897 //==================================================================================
1898 // function : AdjustOnPeriodic
1899 // purpose  : 
1900 //==================================================================================
1901 void AdjustOnPeriodic(const Handle(Adaptor3d_HSurface)& Surf1,
1902                       const Handle(Adaptor3d_HSurface)& Surf2,
1903                       IntPatch_SequenceOfLine& aSLin)
1904 {
1905   Standard_Boolean bIsPeriodic[4], bModified, bIsNull, bIsPeriod;
1906   Standard_Integer i, j, k, aNbLines, aNbPx, aIndx, aIndq;
1907   Standard_Real aPeriod[4], dPeriod[4], ux[4], uq[4], aEps, du;
1908   //
1909   aEps=Precision::Confusion();
1910   //
1911   for (k=0; k<4; ++k) {
1912     aPeriod[k]=0.;
1913   }
1914   //
1915   bIsPeriodic[0]=Surf1->IsUPeriodic();
1916   bIsPeriodic[1]=Surf1->IsVPeriodic();
1917   bIsPeriodic[2]=Surf2->IsUPeriodic();
1918   bIsPeriodic[3]=Surf2->IsVPeriodic();
1919   //
1920   if (bIsPeriodic[0]){
1921     aPeriod[0]=Surf1->UPeriod();
1922   }
1923   if (bIsPeriodic[1]){
1924     aPeriod[1]=Surf1->VPeriod();
1925   }
1926   if (bIsPeriodic[2]){
1927     aPeriod[2]=Surf2->UPeriod();
1928   }
1929   if (bIsPeriodic[3]){
1930     aPeriod[3]=Surf2->VPeriod();
1931   }
1932   //
1933   for (k=0; k<4; ++k) {
1934     dPeriod[k]=0.25*aPeriod[k];
1935   }
1936   //
1937   aNbLines=aSLin.Length();
1938   for (i=1; i<=aNbLines; ++i) {
1939     Handle(IntPatch_WLine) aIL=Handle(IntPatch_WLine)::DownCast(aSLin.Value(i));
1940     Handle(IntSurf_LineOn2S) aL=aIL->Curve();
1941
1942     aNbPx=aL->NbPoints();
1943     if (aNbPx<10) {
1944       continue;
1945     }
1946     //
1947     for (j=0; j<2; ++j) {
1948       bModified=Standard_False;
1949       aIndx=1;
1950       aIndq=2;
1951       if (j) {
1952         aIndx=aNbPx;
1953         aIndq=aNbPx-1;
1954       }
1955       //
1956       const IntSurf_PntOn2S& aPSx=aL->Value(aIndx);
1957       const IntSurf_PntOn2S& aPSq=aL->Value(aIndq);
1958       //
1959       aPSx.Parameters(ux[0], ux[1], ux[2], ux[3]);
1960       aPSq.Parameters(uq[0], uq[1], uq[2], uq[3]);
1961       //
1962       for (k=0; k<4; ++k) {
1963         bIsNull=Standard_False;
1964         bIsPeriod=Standard_False;
1965         //
1966         if (!bIsPeriodic[k]) {
1967           continue;
1968         }
1969         //
1970         if (fabs(ux[k])<aEps) {
1971           bModified=Standard_True;
1972           bIsNull=Standard_True;
1973         }
1974         //
1975         else if (fabs(ux[k]-aPeriod[k])<aEps) {
1976           bModified=Standard_True;
1977           bIsPeriod=Standard_True;
1978         }
1979         //
1980         if (bModified) {
1981           du=fabs(ux[k]-uq[k]);
1982           if (du > dPeriod[k]) {
1983             if(bIsNull){
1984               ux[k]=aPeriod[k];
1985             }
1986             if(bIsPeriod) {
1987               ux[k]=0.;
1988             }
1989           }
1990         }
1991       }//for (k=0; k<4; ++k) 
1992       if (bModified) {
1993         IntSurf_PntOn2S aPntOn2S;
1994         //
1995         aPntOn2S=aPSx;  
1996         aPntOn2S.SetValue(ux[0], ux[1], ux[2], ux[3]);
1997         aL->Value(aIndx, aPntOn2S);
1998       }
1999     }//for (j=0; j<1; ++j) {
2000   }//for (i=1; i<=aNbLines; ++i)
2001 }
2002
2003 //==================================================================================
2004 // function : MakeNewPoint
2005 // purpose  : 
2006 //==================================================================================
2007 IntSurf_PntOn2S MakeNewPoint(const IntSurf_PntOn2S& replacePnt,
2008                              const IntSurf_PntOn2S& oldPnt,
2009                              const Standard_Real* Periods)
2010 {
2011   IntSurf_PntOn2S NewPoint;
2012   NewPoint.SetValue(replacePnt.Value());
2013
2014   Standard_Real OldParams[4], NewParams[4];
2015   oldPnt.Parameters(OldParams[0], OldParams[1], OldParams[2], OldParams[3]);
2016   replacePnt.Parameters(NewParams[0], NewParams[1], NewParams[2], NewParams[3]);
2017
2018   Standard_Integer i;
2019   for (i = 0; i < 4; i++)
2020     if (Periods[i] != 0.)
2021     {
2022       if (Abs(NewParams[i] - OldParams[i]) >= 0.5*Periods[i])
2023       {
2024         if (NewParams[i] < OldParams[i])
2025           NewParams[i] += Periods[i];
2026         else
2027           NewParams[i] -= Periods[i];
2028       }
2029     }
2030
2031     NewPoint.SetValue(NewParams[0], NewParams[1], NewParams[2], NewParams[3]);
2032     return NewPoint;
2033 }
2034
2035 //==================================================================================
2036 // function : Perform
2037 // purpose  : base SS Int. function
2038 //==================================================================================
2039 void IntPatch_PrmPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)& Surf1,
2040                                            const Handle(Adaptor3d_TopolTool)& D1,
2041                                            const Handle(Adaptor3d_HSurface)& Surf2,
2042                                            const Handle(Adaptor3d_TopolTool)& D2,
2043                                            const Standard_Real   TolTangency,
2044                                            const Standard_Real   Epsilon,
2045                                            const Standard_Real   Deflection,
2046                                            const Standard_Real   Increment,
2047                                            const Standard_Boolean ClearFlag) 
2048 {
2049   Standard_Integer Limit = 2500;
2050   Standard_Integer NbU1 = 10, NbV1 = 10, NbU2 = 10, NbV2 = 10;
2051   //
2052   D1->SamplePnts(Deflection, NbU1, NbV1);
2053   D2->SamplePnts(Deflection, NbU2, NbV2);
2054   //
2055   NbU1 = D1->NbSamplesU();
2056   NbV1 = D1->NbSamplesV();
2057   NbU2 = D2->NbSamplesU();
2058   NbV2 = D2->NbSamplesV();
2059
2060   TColStd_Array1OfReal anUpars1(1, NbU1), aVpars1(1, NbV1);
2061   TColStd_Array1OfReal anUpars2(1, NbU2), aVpars2(1, NbV2);
2062   //
2063   D1->UParameters(anUpars1); 
2064   D1->VParameters(aVpars1);
2065   D2->UParameters(anUpars2); 
2066   D2->VParameters(aVpars2);
2067
2068   Standard_Real Periods [4];
2069   Periods[0] = (Surf1->IsUPeriodic())? Surf1->UPeriod() : 0.;
2070   Periods[1] = (Surf1->IsVPeriodic())? Surf1->VPeriod() : 0.;
2071   Periods[2] = (Surf2->IsUPeriodic())? Surf2->UPeriod() : 0.;
2072   Periods[3] = (Surf2->IsVPeriodic())? Surf2->VPeriod() : 0.;
2073
2074   //---------------------------------------------
2075   if((NbU1*NbV1<=Limit && NbV2*NbU2<=Limit))
2076   {
2077     empt = Standard_True;
2078     if (ClearFlag)
2079     {
2080       SLin.Clear();
2081     }
2082     //
2083     IntPolyh_Intersection* pInterference = NULL;
2084
2085     if ( D1->IsUniformSampling() || D2->IsUniformSampling() )
2086     {
2087       pInterference = new IntPolyh_Intersection(Surf1,NbU1,NbV1,Surf2,NbU2,NbV2);
2088     }
2089     else
2090     {
2091       pInterference = new IntPolyh_Intersection(Surf1, anUpars1, aVpars1, 
2092         Surf2, anUpars2, aVpars2 );
2093     }
2094
2095     if ( !pInterference )
2096     {
2097       done = Standard_False;
2098       return;
2099     }
2100     //
2101     IntPolyh_Intersection& Interference = *pInterference;
2102     //
2103     done = Interference.IsDone();
2104     if( !done )
2105     {
2106       if (pInterference)
2107       {
2108         delete pInterference;
2109         pInterference = NULL;
2110       }
2111
2112       return;
2113     }
2114
2115     Standard_Integer nbLigSec = Interference.NbSectionLines();
2116     Standard_Integer nbTanZon = Interference.NbTangentZones();
2117     Standard_Real SeuildPointLigne = 15.0 * Increment * Increment;
2118
2119     Standard_Integer NbLigCalculee = 0, ver;
2120     Standard_Real pu1,pu2,pv1,pv2, incidence, dminiPointLigne;
2121     Standard_Boolean HasStartPoint = Standard_False, RejectLine = Standard_False;
2122     IntSurf_PntOn2S StartPOn2S;
2123     gp_Pnt Point3dDebut,Point3dFin;
2124
2125     TColStd_Array1OfReal StartParams(1,4);
2126     IntWalk_PWalking PW(Surf1,Surf2,TolTangency,Epsilon,Deflection,Increment);
2127
2128     if(nbLigSec>=1)
2129     {
2130       Standard_Integer *TabL = new Standard_Integer [nbLigSec+1];
2131       for(Standard_Integer ls=1; ls<=nbLigSec; ++ls)
2132       {
2133         TabL[ls]=ls;
2134       }
2135       //----------------------------------------1.1
2136       {
2137         Standard_Boolean triok;
2138         Standard_Integer nb_A, nb_B, tyu;
2139         do
2140         {
2141           triok=Standard_True;
2142           for(Standard_Integer b = 2; b <= nbLigSec; ++b )
2143           {
2144             nb_B = Interference.NbPointsInLine(TabL[b]);
2145             nb_A = Interference.NbPointsInLine(TabL[b-1]);
2146
2147             if( nb_B > nb_A )
2148             {
2149               tyu=TabL[b];
2150               TabL[b]=TabL[b-1];
2151               TabL[b-1]=tyu;
2152               triok=Standard_False;
2153             }
2154           }
2155         }
2156         while(triok==Standard_False);
2157       }
2158
2159       //----------------------------------------
2160       // 1.2 For the line "ls" get 2D-bounds U,V for surfaces 1,2
2161       //
2162       for(Standard_Integer ls = 1; ls <= nbLigSec; ++ls)
2163       {
2164         Standard_Integer nbp = Interference.NbPointsInLine(TabL[ls]);
2165         if (!nbp)
2166         {
2167           continue;
2168         }
2169         //
2170         Standard_Integer *TabPtDep = new Standard_Integer [nbp+1];
2171         for(Standard_Integer ilig = 1; ilig <= nbp; ++ilig )
2172         {
2173           TabPtDep[ilig]=0;
2174         }
2175         //
2176         Standard_Real UminLig1,VminLig1,UmaxLig1,VmaxLig1;
2177         Standard_Real UminLig2,VminLig2,UmaxLig2,VmaxLig2;
2178         Standard_Real _x,_y,_z;
2179         //
2180         Interference.GetLinePoint(TabL[ls], 1, _x, _y, _z,
2181           UminLig1, VminLig1, UminLig2, VminLig2, 
2182           incidence);
2183
2184         UmaxLig1=UminLig1;
2185         VmaxLig1=VminLig1;
2186         UmaxLig2=UminLig2;
2187         VmaxLig2=VminLig2;
2188         //
2189         for(Standard_Integer ilig = 2; ilig <= nbp; ilig++ )
2190         {
2191           Standard_Real U1, U2, V1, V2;
2192           Interference.GetLinePoint(TabL[ls],ilig,_x,_y,_z,U1,V1,U2,V2,incidence);
2193           //
2194           if(U1>UmaxLig1) UmaxLig1=U1;
2195           if(V1>VmaxLig1) VmaxLig1=V1;
2196           if(U2>UmaxLig2) UmaxLig2=U2;
2197           if(V2>VmaxLig2) VmaxLig2=V2;
2198           //
2199           if(U1<UminLig1) UminLig1=U1;
2200           if(V1<VminLig1) VminLig1=V1;
2201           if(U2<UminLig2) UminLig2=U2;
2202           if(V2<VminLig2) VminLig2=V2;
2203         }//for( ilig = 2; ilig <= nbp; ilig++ ) { 
2204         //
2205         //----------------------------------------
2206         // 1.3
2207         Standard_Integer nbps2 = (nbp>3)? (nbp/2) :  1;
2208         Standard_Integer NombreDePointsDeDepartDuCheminement = 0;
2209         Standard_Boolean lignetrouvee=Standard_False;
2210         const Standard_Integer NbDePointsDeDepartDuChmLimit = 5;
2211         //
2212         do
2213         {
2214           NombreDePointsDeDepartDuCheminement++;
2215           switch (NombreDePointsDeDepartDuCheminement)
2216           {
2217           case 1:
2218             nbps2 = (nbp > 1) ? nbp/2 : 1;
2219             if(nbp<3) 
2220               NombreDePointsDeDepartDuCheminement = NbDePointsDeDepartDuChmLimit;
2221
2222             break;
2223           case 2:
2224             nbps2 = 1;
2225             break;
2226           case 3:
2227             nbps2 = nbp-1;
2228             break;
2229
2230           case 4:
2231             nbps2 = 3 * nbp / 4;
2232             break;
2233
2234           case 5:
2235             nbps2 = nbp / 4;
2236             break;
2237           default:
2238             nbps2 = NombreDePointsDeDepartDuCheminement-3;
2239             NombreDePointsDeDepartDuCheminement++;
2240           }
2241
2242           //
2243           if(TabPtDep[nbps2] == 0)
2244           {
2245             Standard_Real U1, U2, V1, V2;
2246
2247             TabPtDep[nbps2] = 1;
2248             Interference.GetLinePoint(TabL[ls],nbps2,_x,_y,_z,U1,V1,U2,V2,incidence);
2249
2250             StartParams(1) = U1;
2251             StartParams(2) = V1;
2252             StartParams(3) = U2;
2253             StartParams(4) = V2;
2254
2255             HasStartPoint = PW.PerformFirstPoint(StartParams,StartPOn2S);
2256             dminiPointLigne = SeuildPointLigne + SeuildPointLigne;
2257             if(HasStartPoint)
2258             {
2259               StartPOn2S.Parameters(pu1,pv1,pu2,pv2);
2260               NbLigCalculee = SLin.Length();
2261               Standard_Integer l;
2262               for( l = 1; (l <= NbLigCalculee) && (dminiPointLigne >= SeuildPointLigne); l++)
2263               {
2264                 const Handle(IntPatch_WLine)& testwline = *((Handle(IntPatch_WLine)*)&SLin.Value(l));
2265
2266                 if (IsPointOnLine(StartPOn2S, testwline, Deflection))
2267                 {
2268                   dminiPointLigne = 0.0;
2269                 }
2270               }// for( l ...
2271
2272               if(dminiPointLigne > SeuildPointLigne)
2273               {
2274                 PW.Perform(StartParams, UminLig1, VminLig1, UminLig2, VminLig2,
2275                   UmaxLig1, VmaxLig1, UmaxLig2, VmaxLig2);
2276
2277                 //
2278                 Standard_Boolean bPWIsDone;
2279                 Standard_Integer iPWNbPoints, aNbPointsVer;
2280                 Standard_Real aD11, aD12, aD21, aD22, aDx;
2281                 //
2282                 bPWIsDone=PW.IsDone();
2283
2284                 if(bPWIsDone)
2285                 {
2286                   iPWNbPoints=PW.NbPoints();
2287                   //
2288                   if( iPWNbPoints > 2 )
2289                   {
2290                     //Try to extend the intersection line to boundary, if it is possibly
2291                     Standard_Boolean hasBeenAdded = PW.PutToBoundary(Surf1, Surf2);
2292
2293                     const Standard_Integer aMinNbPoints = 40;
2294                     if(iPWNbPoints < aMinNbPoints)
2295                     {
2296                       hasBeenAdded = 
2297                         PW.SeekAdditionalPoints(Surf1, Surf2, aMinNbPoints) || hasBeenAdded;
2298                       iPWNbPoints = PW.NbPoints();
2299                     }
2300                     
2301                     RejectLine = Standard_False;
2302                     Point3dDebut = PW.Value(1).Value();
2303                     Point3dFin   = PW.Value(iPWNbPoints).Value();
2304                     for( ver = 1; (!RejectLine) && (ver<= NbLigCalculee); ++ver)
2305                     {
2306                       const Handle(IntPatch_WLine)& verwline = *((Handle(IntPatch_WLine)*)&SLin.Value(ver));
2307                       //
2308                       aNbPointsVer=verwline->NbPnts();
2309                       if (aNbPointsVer<3)
2310                       {
2311                         continue;
2312                       }
2313                       //
2314                       const IntSurf_PntOn2S& verPointDebut = verwline->Point(1);
2315                       const IntSurf_PntOn2S& verPointFin = verwline->Point(verwline->NbPnts());
2316                       //xf
2317                       const gp_Pnt& aP21=verPointDebut.Value();
2318                       const gp_Pnt& aP22=verPointFin.Value();
2319                       //
2320                       aD11=Point3dDebut.Distance(aP21);
2321                       aD12=Point3dDebut.Distance(aP22);
2322                       aD21=Point3dFin.Distance(aP21);
2323                       aD22=Point3dFin.Distance(aP22);
2324                       //
2325                       if((aD11<=TolTangency && aD22<=TolTangency) ||
2326                         (aD12<=TolTangency && aD21<=TolTangency))
2327                       {
2328                         Standard_Integer m, mx;
2329                         //
2330                         mx=aNbPointsVer/2;
2331                         if (aNbPointsVer%2)
2332                         {
2333                           ++mx; 
2334                         }
2335                         //
2336                         const gp_Pnt& aPx=verwline->Point(mx).Value();
2337                         for(m=1; m<iPWNbPoints; ++m)
2338                         {
2339                           const gp_Pnt& aP1=PW.Value(m).Value();
2340                           const gp_Pnt& aP2=PW.Value(m+1).Value();
2341                           gp_Vec aVec12(aP1, aP2);
2342                           if (aVec12.SquareMagnitude()<1.e-20)
2343                           {
2344                             continue;
2345                           }
2346
2347                           //
2348                           gp_Dir aDir12(aVec12);
2349                           gp_Lin aLin12(aP1, aDir12);
2350                           aDx=aLin12.Distance(aPx);
2351
2352                           //modified by NIZNHY-PKV Tue May 10 11:08:07 2011f
2353                           if (aDx<=2.*Epsilon)
2354                           {
2355                             //if (aDx<=TolTangency) {
2356                             //modified by NIZNHY-PKV Tue May 10 11:08:13 2011t
2357
2358                             RejectLine = Standard_True;
2359                             break;
2360                           }
2361                         }//for(m=1; m<iPWNbPoints; ++m){
2362                       }//if((aD11<=TolTangency && aD22<=TolTangency) ||...
2363                     }// for( ver = 1 ; (!RejetLigne) && (ver<= NbLigCalculee) ; ver++) { 
2364                     //
2365
2366                     if(RejectLine)
2367                     {
2368                       DublicateOfLinesProcessing(PW, ver, SLin, RejectLine);
2369                     }
2370
2371                     if(!RejectLine)
2372                     {
2373                       IntSurf_TypeTrans trans1,trans2;
2374                       Standard_Real locu,locv;
2375                       gp_Vec norm1,norm2,d1u,d1v;
2376                       gp_Pnt ptbid;
2377                       Standard_Integer indextg;
2378                       gp_Vec tgline(PW.TangentAtLine(indextg));
2379                       PW.Line()->Value(indextg).ParametersOnS1(locu,locv);
2380                       Surf1->D1(locu,locv,ptbid,d1u,d1v);
2381                       norm1 = d1u.Crossed(d1v);
2382                       PW.Line()->Value(indextg).ParametersOnS2(locu,locv);
2383                       Surf2->D1(locu,locv,ptbid,d1u,d1v);
2384                       norm2 = d1u.Crossed(d1v);
2385                       if( tgline.DotCross(norm2,norm1) >= 0. )
2386                       {
2387                         trans1 = IntSurf_Out;
2388                         trans2 = IntSurf_In;
2389                       }
2390                       else
2391                       {
2392                         trans1 = IntSurf_In;
2393                         trans2 = IntSurf_Out;
2394                       }
2395
2396                       Standard_Real TolTang = TolTangency;
2397                       Handle(IntPatch_WLine) wline = new IntPatch_WLine(PW.Line(),Standard_False,trans1,trans2);
2398                       IntPatch_RstInt::PutVertexOnLine(wline,Surf1,D1,Surf2,Standard_True,TolTang,hasBeenAdded);
2399                       IntPatch_RstInt::PutVertexOnLine(wline,Surf2,D2,Surf1,Standard_False,TolTang,hasBeenAdded);
2400
2401                       if(wline->NbVertex() == 0)
2402                       {
2403                         IntPatch_Point vtx;
2404                         IntSurf_PntOn2S POn2S = PW.Line()->Value(1);
2405                         POn2S.Parameters(pu1,pv1,pu2,pv2);
2406                         vtx.SetValue(Point3dDebut,TolTang,Standard_False);
2407                         vtx.SetParameters(pu1,pv1,pu2,pv2);
2408                         vtx.SetParameter(1);
2409                         wline->AddVertex(vtx);
2410
2411                         POn2S = PW.Line()->Value(wline->NbPnts());
2412                         POn2S.Parameters(pu1,pv1,pu2,pv2);
2413                         vtx.SetValue(Point3dFin,TolTang,Standard_False);
2414                         vtx.SetParameters(pu1,pv1,pu2,pv2);
2415                         vtx.SetParameter(wline->NbPnts());
2416                         wline->AddVertex(vtx);
2417                       }
2418
2419                       lignetrouvee = Standard_True;
2420
2421                       Standard_Integer slinlen = SLin.Length();
2422                       if( slinlen > 0 )
2423                       {
2424                         Standard_Integer cnbV = wline->NbVertex();
2425                         Standard_Integer ciV;
2426                         for( ciV = 1; ciV <= cnbV; ciV++ )
2427                         {
2428                           Standard_Real pntDMin = 1.e+100;
2429                           Standard_Integer VDMin = 0;
2430                           Standard_Integer WLDMin = 0;
2431                           gp_Pnt cPV = wline->Vertex(ciV).Value();
2432                           Standard_Integer iL;
2433                           for( iL = 1; iL <= slinlen; iL++)
2434                           {
2435                             const Handle(IntPatch_Line)& aSLine = SLin.Value(iL);
2436                             IntPatch_IType aType = aSLine->ArcType();
2437                             if( aType != IntPatch_Walking)
2438                               continue;
2439                             const Handle(IntPatch_WLine)&  aWLine = (*((Handle(IntPatch_WLine)*)&aSLine));
2440                             Standard_Integer tnbV = aWLine->NbVertex();
2441                             Standard_Integer tiV;
2442                             for( tiV = 1; tiV <= tnbV; tiV++ )
2443                             {
2444                               gp_Pnt tPV = aWLine->Vertex(tiV).Value();
2445                               Standard_Real tDistance = cPV.Distance(tPV);
2446                               Standard_Real uRs1 = Surf1->Surface().UResolution(tDistance);
2447                               Standard_Real vRs1 = Surf1->Surface().VResolution(tDistance);
2448                               Standard_Real uRs2 = Surf2->Surface().UResolution(tDistance);
2449                               Standard_Real vRs2 = Surf2->Surface().VResolution(tDistance);
2450                               Standard_Real RmaxS1 = Max(uRs1,vRs1);
2451                               Standard_Real RmaxS2 = Max(uRs2,vRs2);
2452                               if(RmaxS1 < 1.e-4 && RmaxS2 < 1.e-4)
2453                               {
2454                                 if( pntDMin > tDistance && tDistance > 1.e-9)
2455                                 {
2456                                   pntDMin = tDistance;
2457                                   VDMin = tiV;
2458                                   WLDMin = iL;
2459                                 }
2460                               }
2461                             }
2462                           }
2463
2464                           if( VDMin != 0 )
2465                           {
2466                             const Handle(IntPatch_Line)& aSLine = SLin.Value(WLDMin);
2467                             const Handle(IntPatch_WLine)&  aWLine = (*((Handle(IntPatch_WLine)*)&aSLine));
2468                             Standard_Integer tiVpar = (Standard_Integer)aWLine->Vertex(VDMin).ParameterOnLine();
2469                             Standard_Integer ciVpar = (Standard_Integer)wline->Vertex(ciV).ParameterOnLine();
2470                             Standard_Real u11 = 0., u12 = 0., v11 = 0., v12 = 0.;
2471                             Standard_Real u21 = 0., u22 = 0., v21 = 0., v22 = 0.;
2472                             wline->Point(ciVpar).Parameters(u11,v11,u12,v12);
2473                             aWLine->Point(tiVpar).Parameters(u21,v21,u22,v22);
2474
2475                             Handle(IntSurf_LineOn2S) newL2s = new IntSurf_LineOn2S();
2476                             IntSurf_PntOn2S replacePnt = aWLine->Point(tiVpar);
2477                             Standard_Integer cNbP = wline->NbPnts();
2478
2479                             TColStd_SequenceOfInteger VPold;
2480                             Standard_Integer iPo;
2481                             for( iPo = 1; iPo <= cnbV; iPo++ )
2482                             {
2483                               Standard_Real Po = wline->Vertex(iPo).ParameterOnLine();
2484                               Standard_Integer IPo = (Standard_Integer) Po;
2485                               VPold.Append(IPo);
2486                             }
2487
2488                             Standard_Boolean removeNext = Standard_False;
2489                             Standard_Boolean removePrev = Standard_False;
2490                             if( ciV == 1)
2491                             {
2492                               Standard_Integer dPar = Abs( VPold.Value(ciV) - VPold.Value(ciV+1));
2493                               if(dPar > 10)
2494                               {
2495                                 removeNext = Standard_True;
2496                                 for( iPo = (ciV+1); iPo <= cnbV; iPo++ )
2497                                   VPold.SetValue(iPo, VPold.Value(iPo) - 1 );
2498                               }
2499                             }
2500                             else if( ciV == cnbV)
2501                             {
2502                               Standard_Integer dPar = Abs( VPold.Value(ciV) - VPold.Value(ciV-1));
2503                               if(dPar > 10)
2504                               {
2505                                 removePrev = Standard_True;
2506                                 VPold.SetValue(ciV, VPold.Value(ciV) - 1 );
2507                               }
2508                             }
2509                             else
2510                             {
2511                               Standard_Integer dParMi = Abs( VPold.Value(ciV) - VPold.Value(ciV-1));
2512                               Standard_Integer dParMa = Abs( VPold.Value(ciV) - VPold.Value(ciV+1));
2513                               if(dParMi > 10)
2514                               {
2515                                 removePrev = Standard_True;
2516                                 VPold.SetValue(ciV, VPold.Value(ciV) - 1 );
2517                               }
2518
2519                               if(dParMa > 10)
2520                               {
2521                                 removeNext = Standard_True;
2522                                 for( iPo = (ciV+1); iPo <= cnbV; iPo++ )
2523                                 {
2524                                   if(dParMi > 10)
2525                                     VPold.SetValue(iPo, VPold.Value(iPo) - 2 );
2526                                   else
2527                                     VPold.SetValue(iPo, VPold.Value(iPo) - 1 );
2528                                 }
2529                               }
2530                               else
2531                               {
2532                                 if(dParMi > 10)
2533                                   for( iPo = (ciV+1); iPo <= cnbV; iPo++ )
2534                                     VPold.SetValue(iPo, VPold.Value(iPo) - 1 );
2535                               } 
2536                             }
2537
2538                             Standard_Integer pI = ciVpar;
2539
2540                             Standard_Integer iP;
2541                             for( iP = 1; iP <= cNbP; iP++)
2542                             {
2543                               if( pI == iP )
2544                               {
2545                                 IntSurf_PntOn2S newPnt = MakeNewPoint(replacePnt, wline->Point(iP), Periods);
2546                                 newL2s->Add(newPnt);
2547                               }
2548                               else if(removeNext && iP == (pI + 1))
2549                                 continue;
2550                               else if(removePrev && iP == (pI - 1))
2551                                 continue;
2552                               else
2553                                 newL2s->Add(wline->Point(iP));
2554                             }
2555
2556                             IntPatch_Point newVtx;
2557                             gp_Pnt Pnt3dV = aWLine->Vertex(VDMin).Value();
2558                             newVtx.SetValue(Pnt3dV,TolTang,Standard_False);
2559                             newVtx.SetParameters(u21,v21,u22,v22);
2560                             newVtx.SetParameter(VPold.Value(ciV));
2561
2562                             Handle(IntPatch_WLine) NWLine = new IntPatch_WLine(newL2s,Standard_False,trans1,trans2);
2563
2564                             Standard_Integer iV;
2565                             for( iV = 1; iV <= cnbV; iV++ )
2566                             {
2567                               if( iV == ciV )
2568                                 NWLine->AddVertex(newVtx);
2569                               else
2570                               {
2571                                 IntPatch_Point theVtx = wline->Vertex(iV);
2572                                 theVtx.SetParameter(VPold.Value(iV));
2573                                 NWLine->AddVertex(theVtx);
2574                               }
2575                             }
2576
2577                             wline = NWLine;
2578                           }//if( VDMin != 0 )
2579                         }//for( ciV = 1; ciV <= cnbV; ciV++ )
2580                       }// SLin.Length > 0
2581
2582                       AddWLine(SLin, wline, Deflection);
2583                       empt = Standard_False;
2584                     }// !RejetLigne
2585                   }// PW points > 2
2586                 }// done is True
2587               }// dminiPointLigne > SeuildPointLigne
2588             }// HasStartPoint
2589           }// if TabPtDep[nbps2] == 0
2590         } while(nbp>5 && !( (NombreDePointsDeDepartDuCheminement >= NbDePointsDeDepartDuChmLimit && lignetrouvee) || 
2591           (NombreDePointsDeDepartDuCheminement-3 >= nbp && (!lignetrouvee))));
2592         delete [] TabPtDep;
2593       }// for( ls ...
2594
2595       delete [] TabL;
2596
2597     }// if nbLigSec >= 1
2598     //
2599     AdjustOnPeriodic(Surf1, Surf2, SLin);
2600     //
2601
2602     //--------------------------------------------------------------------
2603     //-- Calcul des parametres approches a partir des Zones De Tangence --
2604     //--------------------------------------------------------------------
2605     Standard_Real UminLig1,VminLig1,UmaxLig1,VmaxLig1;
2606     Standard_Real UminLig2,VminLig2,UmaxLig2,VmaxLig2;
2607
2608     UminLig1=VminLig1=UminLig2=VminLig2=RealLast();
2609     UmaxLig1=VmaxLig1=UmaxLig2=VmaxLig2=-UminLig1;
2610
2611     // NbPointsInTangentZone always == 1 (eap)
2612
2613     Standard_Integer z;
2614     for( z=1; z <= nbTanZon; z++)
2615     { 
2616       //Standard_Integer NbPointsInTangentZone=Interference.NbPointsInTangentZone(z);
2617       //for(Standard_Integer pz=1; pz<=NbPointsInTangentZone; pz++) {
2618       Standard_Integer pz=1;
2619       Standard_Real _x,_y,_z;
2620       Standard_Real U1, U2, V1, V2;
2621       Interference.GetTangentZonePoint(z,pz,_x,_y,_z,U1,V1,U2,V2);
2622
2623       if(U1>UmaxLig1) UmaxLig1=U1;
2624       if(V1>VmaxLig1) VmaxLig1=V1;
2625       if(U2>UmaxLig2) UmaxLig2=U2;
2626       if(V2>VmaxLig2) VmaxLig2=V2;
2627
2628       if(U1<UminLig1) UminLig1=U1;
2629       if(V1<VminLig1) VminLig1=V1;
2630       if(U2<UminLig2) UminLig2=U2;
2631       if(V2<VminLig2) VminLig2=V2;
2632       //}
2633     }
2634
2635     for(z=1; z <= nbTanZon; z++)
2636     {
2637       //Standard_Integer NbPointsInTangentZone=Interference.NbPointsInTangentZone(z);
2638       //for(Standard_Integer pz=1; pz<=NbPointsInTangentZone; pz++) { 
2639       Standard_Integer pz=1;
2640       Standard_Real _x,_y,_z;
2641       Standard_Real U1, U2, V1, V2;
2642       Interference.GetTangentZonePoint(z,pz,_x,_y,_z,U1,V1,U2,V2);
2643
2644       StartParams(1) = U1;
2645       StartParams(2) = V1;
2646       StartParams(3) = U2;
2647       StartParams(4) = V2;
2648
2649       //-----------------------------------------------------------------------
2650       //-- Calcul du premier point de cheminement a partir du point approche --
2651       //-----------------------------------------------------------------------
2652       HasStartPoint = PW.PerformFirstPoint(StartParams,StartPOn2S);     
2653       if(HasStartPoint)
2654       {
2655         //-------------------------------------------------
2656         //-- Un point a ete trouve                       --
2657         //-- On verifie qu il n appartient pas           --
2658         //--  a une ligne de cheminement deja calculee.  --
2659         //-------------------------------------------------
2660         StartPOn2S.Parameters(pu1,pv1,pu2,pv2);
2661
2662         NbLigCalculee = SLin.Length();
2663         dminiPointLigne = SeuildPointLigne + SeuildPointLigne; 
2664
2665         for(Standard_Integer l=1; 
2666           (l <= NbLigCalculee) && (dminiPointLigne >= SeuildPointLigne); 
2667           l++)
2668         {
2669           const Handle(IntPatch_WLine)& testwline = *((Handle(IntPatch_WLine)*)&SLin.Value(l));
2670
2671           if (IsPointOnLine(StartPOn2S, testwline, Deflection))
2672           {
2673             dminiPointLigne = 0.0;
2674           }
2675         }
2676
2677         //-- Fin d exploration des lignes
2678         if(dminiPointLigne > SeuildPointLigne)
2679         {
2680           //---------------------------------------------------
2681           //-- Le point de depart du nouveau cheminement     --
2682           //-- n est present dans aucune ligne deja calculee.--
2683           //---------------------------------------------------
2684           PW.Perform(StartParams,UminLig1,VminLig1,UminLig2,VminLig2,
2685             UmaxLig1,VmaxLig1,UmaxLig2,VmaxLig2);
2686
2687           if(PW.IsDone())
2688           {
2689             if(PW.NbPoints()>2)
2690             { 
2691               const Standard_Integer aMinNbPoints = 40;
2692               if(PW.NbPoints() < aMinNbPoints)
2693               {
2694                 PW.SeekAdditionalPoints(Surf1, Surf2, aMinNbPoints);
2695               }
2696
2697               //-----------------------------------------------
2698               //-- Verification a posteriori : 
2699               //-- On teste si le point de depart et de fin de 
2700               //-- la ligne de cheminement est present dans une 
2701               //-- autre ligne . 
2702               //-----------------------------------------------
2703               RejectLine = Standard_False;
2704               Point3dDebut = PW.Value(1).Value();
2705               const IntSurf_PntOn2S& PointFin = PW.Value(PW.NbPoints());
2706               Point3dFin   = PointFin.Value();
2707
2708               for(ver=1 ; (!RejectLine) && (ver<= NbLigCalculee) ; ver++)
2709               {
2710                 const Handle(IntPatch_WLine)& verwline = *((Handle(IntPatch_WLine)*)&SLin.Value(ver));
2711                 //-- Handle(IntPatch_WLine) verwline=Handle(IntPatch_WLine)::DownCast(SLin.Value(ver));
2712
2713                 // Check end point if it is on existing line.
2714                 // Start point is checked before.
2715                 if (IsPointOnLine(PointFin, verwline, Deflection))
2716                 {
2717                   RejectLine = Standard_True; 
2718                   break;
2719                 }
2720
2721                 const IntSurf_PntOn2S& verPointDebut = verwline->Point(1);
2722                 const IntSurf_PntOn2S& verPointFin   = verwline->Point(verwline->NbPnts());
2723                 if(Point3dDebut.Distance(verPointDebut.Value()) < TolTangency)
2724                 {
2725                   RejectLine = Standard_True; 
2726                 }
2727                 else
2728                 {
2729                   if(Point3dFin.Distance(verPointFin.Value()) < TolTangency)
2730                   {
2731                     RejectLine = Standard_True; 
2732                   }
2733                 }
2734               }
2735
2736               if(!RejectLine)
2737               { 
2738                 IntSurf_TypeTrans trans1,trans2;
2739                 Standard_Real locu,locv;
2740                 gp_Vec norm1,norm2,d1u,d1v;
2741                 gp_Pnt ptbid;
2742                 Standard_Integer indextg;
2743                 gp_Vec tgline(PW.TangentAtLine(indextg));
2744                 PW.Line()->Value(indextg).ParametersOnS1(locu,locv);
2745                 Surf1->D1(locu,locv,ptbid,d1u,d1v);
2746                 norm1 = d1u.Crossed(d1v);
2747                 PW.Line()->Value(indextg).ParametersOnS2(locu,locv);
2748                 Surf2->D1(locu,locv,ptbid,d1u,d1v);
2749                 norm2 = d1u.Crossed(d1v);
2750                 if (tgline.DotCross(norm2,norm1)>0.)
2751                 {
2752                   trans1 = IntSurf_Out;
2753                   trans2 = IntSurf_In;
2754                 }
2755                 else
2756                 {
2757                   trans1 = IntSurf_In;
2758                   trans2 = IntSurf_Out;
2759                 }
2760
2761                 Standard_Real TolTang = TolTangency;
2762                 Handle(IntPatch_WLine) wline = new IntPatch_WLine(PW.Line(),Standard_False,trans1,trans2);
2763                 IntPatch_RstInt::PutVertexOnLine(wline,Surf1,D1,Surf2,Standard_True,TolTang);
2764                 IntPatch_RstInt::PutVertexOnLine(wline,Surf2,D2,Surf1,Standard_False,TolTang);
2765
2766                 //---------------
2767                 if(wline->NbVertex() == 0)
2768                 {
2769                   IntPatch_Point vtx;
2770                   IntSurf_PntOn2S POn2S = PW.Line()->Value(1);
2771                   POn2S.Parameters(pu1,pv1,pu2,pv2);
2772                   vtx.SetValue(Point3dDebut,TolTang,Standard_False);
2773                   vtx.SetParameters(pu1,pv1,pu2,pv2);
2774                   vtx.SetParameter(1);
2775                   wline->AddVertex(vtx);
2776
2777                   POn2S = PW.Line()->Value(wline->NbPnts());
2778                   POn2S.Parameters(pu1,pv1,pu2,pv2);
2779                   vtx.SetValue(Point3dFin,TolTang,Standard_False);
2780                   vtx.SetParameters(pu1,pv1,pu2,pv2);
2781                   vtx.SetParameter(wline->NbPnts());
2782                   wline->AddVertex(vtx);
2783                 }
2784
2785                 //---------------
2786                 AddWLine(SLin, wline, Deflection);
2787                 empt = Standard_False;
2788               }
2789               else
2790               {
2791                 //-- cout<<" ----- REJET DE LIGNE (POINT DE DEPART) ----- "<<endl;
2792               }
2793               //------------------------------------------------------------            
2794             }
2795           }  //--  le cheminement a reussi (done a True)
2796         }  //--  le point approche ne renvoie pas sur une ligne existante
2797       } //-- Si HasStartPoint
2798       //} //-- Boucle Sur les Points de la Tangent Zone
2799     } //-- Boucle sur Les Tangent Zones
2800
2801     if ( pInterference )
2802     {
2803       delete pInterference;
2804       pInterference = NULL;
2805     }
2806
2807     return;
2808   }// if((NbU1*NbV1<=Limit && NbV2*NbU2<=Limit)) {  
2809
2810   Handle(IntSurf_LineOn2S) LOn2S = new IntSurf_LineOn2S();
2811   PointDepart( LOn2S, Surf1, NbU1, NbV1, Surf2, NbU2, NbV2 );
2812   empt = Standard_True;
2813   done = Standard_True;
2814   SLin.Clear();  
2815
2816   Standard_Integer NbLigCalculee = 0;
2817   Standard_Real U1,U2,V1,V2;
2818   Standard_Real pu1,pu2,pv1,pv2;
2819
2820   TColStd_Array1OfReal StartParams(1,4);
2821   Standard_Integer MaxOscill = NbU1;
2822   if(MaxOscill < NbU2) MaxOscill=NbU2;
2823   if(MaxOscill < NbV1) MaxOscill=NbV1;
2824   if(MaxOscill < NbV2) MaxOscill=NbV2;
2825
2826   Standard_Real nIncrement=Increment;
2827   //if(MaxOscill>10)
2828   //nIncrement/=0.5*MaxOscill;
2829
2830   IntWalk_PWalking PW(Surf1,Surf2,TolTangency,Epsilon,Deflection,nIncrement);
2831   Standard_Real    SeuildPointLigne = 15.0 * Increment * Increment; //-- 10 est insuffisant
2832   Standard_Real    dminiPointLigne;
2833   Standard_Boolean HasStartPoint,RejetLigne;
2834   IntSurf_PntOn2S StartPOn2S;
2835   Standard_Integer ver;
2836   gp_Pnt Point3dDebut,Point3dFin;
2837
2838   //------------------------------------------------------------
2839   //-- Calcul des parametres approches a partir des Zones De Tangence --
2840   //--------------------------------------------------------------------
2841   Standard_Integer nbTanZon = LOn2S->NbPoints();
2842   for(Standard_Integer z=1; z <= nbTanZon; z++) { 
2843     const IntSurf_PntOn2S& POn2S = LOn2S->Value(z);
2844     POn2S.Parameters(U1,V1,U2,V2);
2845     StartParams(1) = U1;
2846     StartParams(2) = V1;
2847     StartParams(3) = U2;
2848     StartParams(4) = V2;
2849
2850     //-----------------------------------------------------------------------
2851     //-- Calcul du premier point de cheminement a partir du point approche --
2852     //-----------------------------------------------------------------------
2853     HasStartPoint = PW.PerformFirstPoint(StartParams,StartPOn2S);       
2854     if(HasStartPoint)
2855     { 
2856       //-------------------------------------------------
2857       //-- Un point a ete trouve                       --
2858       //-- On verifie qu il n appartient pas           --
2859       //--  a une ligne de cheminement deja calculee.  --
2860       //-------------------------------------------------
2861       StartPOn2S.Parameters(pu1,pv1,pu2,pv2);
2862
2863       NbLigCalculee = SLin.Length();
2864       dminiPointLigne = SeuildPointLigne + SeuildPointLigne; 
2865
2866       for(Standard_Integer l=1; 
2867         (l <= NbLigCalculee) && (dminiPointLigne >= SeuildPointLigne); 
2868         l++)
2869       {
2870         const Handle(IntPatch_WLine)& testwline = *((Handle(IntPatch_WLine)*)&SLin.Value(l));
2871
2872         if (IsPointOnLine(StartPOn2S, testwline, Deflection))
2873         {
2874           dminiPointLigne = 0.0;
2875         }
2876       }
2877
2878       //-- Fin d exploration des lignes
2879       if(dminiPointLigne > SeuildPointLigne)
2880       { 
2881         //---------------------------------------------------
2882         //-- Le point de depart du nouveau cheminement     --
2883         //-- n est present dans aucune ligne deja calculee.--
2884         //---------------------------------------------------
2885         PW.Perform(StartParams);
2886         if(PW.IsDone())
2887         {
2888           if(PW.NbPoints()>2)
2889           {
2890             //-----------------------------------------------
2891             //-- Verification a posteriori : 
2892             //-- On teste si le point de depart et de fin de 
2893             //-- la ligne de cheminement est present dans une 
2894             //-- autre ligne . 
2895             //-----------------------------------------------
2896             RejetLigne = Standard_False;
2897             Point3dDebut = PW.Value(1).Value();
2898             const IntSurf_PntOn2S& PointFin = PW.Value(PW.NbPoints());
2899             Point3dFin   = PointFin.Value();
2900
2901             for(ver=1 ; (!RejetLigne) && (ver<= NbLigCalculee) ; ver++)
2902             {
2903               const Handle(IntPatch_WLine)& verwline = *((Handle(IntPatch_WLine)*)&SLin.Value(ver));
2904               //-- Handle(IntPatch_WLine) verwline=Handle(IntPatch_WLine)::DownCast(SLin.Value(ver));
2905
2906               // Check end point if it is on existing line.
2907               // Start point is checked before.
2908               if (IsPointOnLine(PointFin, verwline, Deflection))
2909               {
2910                 RejetLigne = Standard_True; 
2911                 break;
2912               }
2913
2914               const IntSurf_PntOn2S& verPointDebut = verwline->Point(1);
2915               const IntSurf_PntOn2S& verPointFin   = verwline->Point(verwline->NbPnts());
2916               if(Point3dDebut.Distance(verPointDebut.Value()) < TolTangency)
2917               {
2918                 RejetLigne = Standard_True; 
2919               }
2920               else
2921               {
2922                 if(Point3dFin.Distance(verPointFin.Value()) < TolTangency)
2923                 {
2924                   RejetLigne = Standard_True; 
2925                 }
2926               }
2927             }
2928
2929             if(RejetLigne)
2930             {
2931               DublicateOfLinesProcessing(PW, ver, SLin, RejetLigne);
2932             }
2933
2934             if(!RejetLigne)
2935             {
2936               IntSurf_TypeTrans trans1,trans2;
2937               Standard_Real locu,locv;
2938               gp_Vec norm1,norm2,d1u,d1v;
2939               gp_Pnt ptbid;
2940               Standard_Integer indextg;
2941               gp_Vec tgline(PW.TangentAtLine(indextg));
2942               PW.Line()->Value(indextg).ParametersOnS1(locu,locv);
2943               Surf1->D1(locu,locv,ptbid,d1u,d1v);
2944               norm1 = d1u.Crossed(d1v);
2945               PW.Line()->Value(indextg).ParametersOnS2(locu,locv);
2946               Surf2->D1(locu,locv,ptbid,d1u,d1v);
2947               norm2 = d1u.Crossed(d1v);
2948               if (tgline.DotCross(norm2,norm1)>0.)
2949               {
2950                 trans1 = IntSurf_Out;
2951                 trans2 = IntSurf_In;
2952               }
2953               else {
2954                 trans1 = IntSurf_In;
2955                 trans2 = IntSurf_Out;
2956               }
2957
2958               Standard_Real TolTang = TolTangency;
2959               Handle(IntPatch_WLine) wline = new IntPatch_WLine(PW.Line(),Standard_False,trans1,trans2);
2960               IntPatch_RstInt::PutVertexOnLine(wline,Surf1,D1,Surf2,Standard_True,TolTang);
2961               IntPatch_RstInt::PutVertexOnLine(wline,Surf2,D2,Surf1,Standard_False,TolTang);
2962
2963               //---------------
2964               if(wline->NbVertex() == 0)
2965               {
2966                 IntPatch_Point vtx;
2967                 const IntSurf_PntOn2S& POn2Sf = PW.Line()->Value(1);
2968                 POn2Sf.Parameters(pu1,pv1,pu2,pv2);
2969                 vtx.SetValue(Point3dDebut,TolTang,Standard_False);
2970                 vtx.SetParameters(pu1,pv1,pu2,pv2);
2971                 vtx.SetParameter(1);
2972                 wline->AddVertex(vtx);
2973
2974                 const IntSurf_PntOn2S& POn2Sl = PW.Line()->Value(wline->NbPnts());
2975                 POn2Sl.Parameters(pu1,pv1,pu2,pv2);
2976                 vtx.SetValue(Point3dFin,TolTang,Standard_False);
2977                 vtx.SetParameters(pu1,pv1,pu2,pv2);
2978                 vtx.SetParameter(wline->NbPnts());
2979                 wline->AddVertex(vtx);
2980               }
2981
2982               //---------------
2983               AddWLine(SLin, wline, Deflection);
2984               empt = Standard_False;
2985             }
2986             else
2987             { 
2988               //-- cout<<" ----- REJET DE LIGNE (POINT DE DEPART) ----- "<<endl;
2989             }
2990             //------------------------------------------------------------              
2991           }
2992         }  //--  le cheminement a reussi (done a True)
2993       }  //--  le point approche ne renvoie pas sur une ligne existante
2994     } //-- Si HasStartPoint
2995   } //-- Boucle sur Les Tangent Zones
2996 }
2997 //modified by NIZNHY-PKV Wed May 25 09:39:07 2011f
2998 //=======================================================================
2999 //class : IntPatch_InfoPD
3000 //purpose  : 
3001 //=======================================================================
3002 class IntPatch_InfoPD {
3003 public:
3004   //----------------------------------------C-tor
3005   IntPatch_InfoPD(const Standard_Integer aNBI) {
3006     Standard_Integer aNBI2, i, j;
3007     myNBI=aNBI;
3008     //
3009     aNBI2=aNBI*aNBI;
3010     myP1DS2=new char[aNBI2];
3011     myP2DS1=new char[aNBI2];
3012     myIP1=new Standard_Integer[aNBI2]; 
3013     myIP2=new Standard_Integer[aNBI2];
3014     myP1=new gp_Pnt[aNBI2];
3015     myP2=new gp_Pnt[aNBI2];
3016     //
3017     for (i=0; i<myNBI; ++i) {
3018       for (j=0; j<myNBI; ++j) {
3019         xP1DS2(i, j)=0;
3020         xP2DS1(i, j)=0;
3021         xIP1(i, j)=0;
3022         xIP2(i, j)=0;
3023         xP1(i, j).SetCoord(0., 0., 0.);
3024         xP2(i, j).SetCoord(0., 0., 0.);
3025       }
3026     }
3027   };
3028   //---------------------------------------- D-tor
3029   ~IntPatch_InfoPD() {
3030     delete [] (char*) myP1DS2;
3031     delete [] (char*) myP2DS1;
3032     delete [] (Standard_Integer*) myIP1;
3033     delete [] (Standard_Integer*) myIP2; 
3034     delete [] (gp_Pnt*)myP1;
3035     delete [] (gp_Pnt*)myP2;
3036   };
3037   //---------------------------------------- Index
3038   Standard_Integer Index(const Standard_Integer i,
3039     const Standard_Integer j) const { 
3040       return i*myNBI+j;
3041   };
3042   //---------------------------------------- NBI
3043   Standard_Integer NBI() const { 
3044     return myNBI;
3045   };
3046   //----------------------------------------xP1DS2
3047   char& xP1DS2(const Standard_Integer i,
3048     const Standard_Integer j) { 
3049       return myP1DS2[Index(i,j)];
3050   };
3051   //----------------------------------------xP2DS1
3052   char& xP2DS1(const Standard_Integer i,
3053     const Standard_Integer j) { 
3054       return myP2DS1[Index(i,j)];
3055   };
3056   //----------------------------------------xIP1
3057   Standard_Integer& xIP1(const Standard_Integer i,
3058     const Standard_Integer j) { 
3059       return myIP1[Index(i,j)];
3060   };
3061   //----------------------------------------xIP2
3062   Standard_Integer& xIP2(const Standard_Integer i,
3063     const Standard_Integer j) { 
3064       return myIP2[Index(i,j)];
3065   };
3066   //----------------------------------------xP1
3067   gp_Pnt& xP1(const Standard_Integer i,
3068     const Standard_Integer j) { 
3069       return myP1[Index(i,j)];
3070   };
3071   //----------------------------------------xP1
3072   gp_Pnt& xP2(const Standard_Integer i,
3073     const Standard_Integer j) { 
3074       return myP2[Index(i,j)];
3075   };
3076
3077 private:
3078
3079   IntPatch_InfoPD (const IntPatch_InfoPD&);
3080   IntPatch_InfoPD& operator=(const IntPatch_InfoPD&);
3081
3082 private:
3083
3084   Standard_Integer myNBI;
3085   char *myP1DS2;
3086   char *myP2DS1;
3087   Standard_Integer *myIP1;
3088   Standard_Integer *myIP2;
3089   gp_Pnt *myP1;
3090   gp_Pnt *myP2;
3091 }; 
3092 //modified by NIZNHY-PKV Tue May 24 11:38:55 2011t
3093 //==================================================================================
3094 // function : PointDepart
3095 // purpose  : 
3096 //==================================================================================
3097 void IntPatch_PrmPrmIntersection::PointDepart(Handle(IntSurf_LineOn2S)& LineOn2S,
3098                                               const Handle(Adaptor3d_HSurface)& S1,
3099                                               const Standard_Integer SU_1,
3100                                               const Standard_Integer SV_1,
3101                                               const Handle(Adaptor3d_HSurface)& S2,
3102                                               const Standard_Integer SU_2,
3103                                               const Standard_Integer SV_2) const 
3104
3105   Standard_Integer i, j, xNBI;
3106   //modified by NIZNHY-PKV Tue May 24 11:37:38 2011f
3107   xNBI=200;
3108   IntPatch_InfoPD aIPD(xNBI);
3109   //modified by NIZNHY-PKV Wed May 25 06:47:12 2011t
3110   Standard_Integer iC15, SU1, SV1, SU2, SV2;
3111   Standard_Real U0, U1, V0, V1, U, V;
3112   Standard_Real resu0,resv0;
3113   Standard_Real  du1,du2,dv1,dv2, dmaxOn1, dmaxOn2;
3114   Standard_Real x0,y0,z0, x1,y1,z1,d;
3115   Bnd_Box Box1, Box2;
3116   //
3117   iC15=15;
3118   SU1 =iC15*SU_1 ;
3119   SV1 =iC15*SV_1 ;
3120   SU2 =iC15*SU_2 ;
3121   SV2 =iC15*SV_2 ;
3122   //
3123   if(xNBI<SU1) {
3124     SU1 = xNBI;
3125   }
3126   if(xNBI<SV1){
3127     SV1 = xNBI;
3128   }
3129   if(xNBI<SU2){
3130     SU2 = xNBI;
3131   }
3132   if(xNBI<SV2){
3133     SV2 = xNBI;
3134   }
3135   //
3136   U0 = S1->FirstUParameter();
3137   U1 = S1->LastUParameter();
3138   V0 = S1->FirstVParameter();
3139   V1 = S1->LastVParameter();
3140   //
3141   resu0=U0;
3142   resv0=V0;
3143   //
3144   dmaxOn1 = 0.0;
3145   dmaxOn2 = 0.0;
3146   //-----
3147   du1 = (U1-U0)/(SU1-1);
3148   dv1 = (V1-V0)/(SV1-1);
3149   for(U=U0,i=0; i<SU1; i++,U+=du1) { 
3150     for(V=V0,j=0; j<SV1; V+=dv1,j++) { 
3151       aIPD.xP1(i, j)= S1->Value(U,V);
3152       Box1.Add(aIPD.xP1(i, j));
3153       if(i>0 && j>0) { 
3154         aIPD.xP1(i, j)    .Coord(x0,y0,z0);
3155         aIPD.xP1(i-1, j-1).Coord(x1,y1,z1);
3156         //
3157         d=Abs(x1-x0)+Abs(y1-y0)+Abs(z1-z0);
3158         if(d>dmaxOn1) {
3159           dmaxOn1 = d;
3160         }
3161       }
3162     }
3163   }
3164   Box1.Enlarge(1.e-8);
3165   //
3166   U0 = S2->FirstUParameter();
3167   U1 = S2->LastUParameter();
3168   V0 = S2->FirstVParameter();
3169   V1 = S2->LastVParameter();
3170   //
3171   du2 = (U1-U0)/(SU2-1);  
3172   dv2 = (V1-V0)/(SV2-1);
3173   for(U=U0,i=0; i<SU2; i++,U+=du2) { 
3174     for(V=V0,j=0; j<SV2; V+=dv2,j++) { 
3175       aIPD.xP2(i, j) = S2->Value(U,V);
3176       Box2.Add(aIPD.xP2(i, j));
3177       if(i>0 && j>0) { 
3178         aIPD.xP2(i, j)    .Coord(x0,y0,z0);
3179         aIPD.xP2(i-1, j-1).Coord(x1,y1,z1);
3180         d =  Abs(x1-x0)+Abs(y1-y0)+Abs(z1-z0);
3181         if(d>dmaxOn2) {
3182           dmaxOn2 = d;
3183         }
3184       }
3185     }
3186   }
3187   Box2.Enlarge(1.e-8);
3188   //--------
3189   //
3190   if(Box1.IsOut(Box2)) {
3191
3192     return;
3193   }
3194   //
3195   Standard_Integer aNbPG;
3196   Standard_Real x10,y10,z10,x11,y11,z11;
3197   Standard_Real x20,y20,z20,x21,y21,z21;
3198   Standard_Real dx, dy, dz, dmax;
3199   Standard_Real dx2, dy2, dz2;
3200   //
3201   Box1.Get(x10,y10,z10,x11,y11,z11);
3202   Box2.Get(x20,y20,z20,x21,y21,z21);
3203   //
3204   x0 = (x10>x20)? x10 : x20;
3205   y0 = (y10>y20)? y10 : y20;
3206   z0 = (z10>z20)? z10 : z20;
3207   //
3208   x1 = (x11<x21)? x11 : x21;
3209   y1 = (y11<y21)? y11 : y21;
3210   z1 = (z11<z21)? z11 : z21;
3211   //
3212   if(dmaxOn2 > dmaxOn1) {
3213     dmaxOn1 = dmaxOn2;
3214   }
3215   //
3216   dmaxOn1+=dmaxOn1;
3217   x0-=dmaxOn1;
3218   y0-=dmaxOn1;
3219   z0-=dmaxOn1;
3220   x1+=dmaxOn1;
3221   y1+=dmaxOn1;
3222   z1+=dmaxOn1;
3223   //
3224   x10-=dmaxOn1;   y10-=dmaxOn1;   z10-=dmaxOn1; 
3225   x11+=dmaxOn1;   y11+=dmaxOn1;   z11+=dmaxOn1; 
3226
3227   x20-=dmaxOn1;   y20-=dmaxOn1;   z20-=dmaxOn1; 
3228   x21+=dmaxOn1;   y21+=dmaxOn1;   z21+=dmaxOn1; 
3229
3230   aNbPG=NbPointsGrille();
3231   dx = (x1-x0)/aNbPG;
3232   dy = (y1-y0)/aNbPG;
3233   dz = (z1-z0)/aNbPG;
3234   //
3235   dmax = dx;
3236   if(dy>dmax) {
3237     dmax = dy;
3238   }
3239   if(dz>dmax){
3240     dmax = dz;
3241   }
3242   //
3243   if(dx<dmax*0.01) {
3244     dx = dmax*0.01;
3245   }
3246   if(dy<dmax*0.01) {
3247     dy = dmax*0.01;
3248   }
3249   if(dz<dmax*0.01) {
3250     dz = dmax*0.01;
3251   }
3252   //
3253   dx2 = dx*0.5;
3254   dy2 = dy*0.5;
3255   dz2 = dz*0.5 ;
3256   //
3257   IntPatch_PrmPrmIntersection_T3Bits M1(_BASE);
3258   IntPatch_PrmPrmIntersection_T3Bits M2(_BASE);
3259   //
3260   for(i=0;i<SU1;i++) { 
3261     for(j=0;j<SV1;j++) { 
3262       aIPD.xIP1(i, j)=-1;
3263       const gp_Pnt& P=aIPD.xP1(i, j);
3264       aIPD.xP1DS2(i, j) = (char)CodeReject(x20,y20,z20,x21,y21,z21,P.X(),P.Y(),P.Z());
3265       int ix = (int)((P.X()-x0  + dx2 )/dx);
3266       if(DansGrille(ix)) { 
3267         int iy = (int)((P.Y()-y0 + dy2)/dy);
3268         if(DansGrille(iy)) {
3269           int iz = (int)((P.Z()-z0 + dz2)/dz);
3270           if(DansGrille(iz)) {
3271             aIPD.xIP1(i, j) = GrilleInteger(ix,iy,iz);
3272           }
3273         }
3274       }
3275     }
3276   }
3277   //-- cout<<" Grille  du 1 fini "<<endl;
3278   for(i=0;i<SU2;i++) { 
3279     for(j=0;j<SV2;j++) { 
3280       aIPD.xIP2(i, j)=-1;
3281       const gp_Pnt& P=aIPD.xP2(i, j);
3282       aIPD.xP2DS1(i, j) = (char)CodeReject(x10,y10,z10,x11,y11,z11,P.X(),P.Y(),P.Z());
3283       int ix = (int)((P.X()-x0 + dx2)/dx);
3284       if(DansGrille(ix)) { 
3285         int iy = (int)((P.Y()-y0 + dy2)/dy);
3286         if(DansGrille(iy)) {
3287           int iz = (int)((P.Z()-z0 + dz2)/dz);
3288           if(DansGrille(iz)) {
3289             aIPD.xIP2(i, j) =  GrilleInteger(ix,iy,iz);
3290           }
3291         }
3292       }
3293     }
3294   }
3295   //
3296   for(i=0;i<SU1-1;i+=1) {
3297     for(j=0;j<SV1-1;j+=1) { 
3298       if(!((aIPD.xP1DS2(i, j) & aIPD.xP1DS2(i+1, j)) || 
3299         (aIPD.xP1DS2(i, j) & aIPD.xP1DS2(i+1, j+1)))){
3300           Remplit(aIPD.xIP1(i, j),
3301             aIPD.xIP1(i+1, j),
3302             aIPD.xIP1(i+1, j+1),
3303             M1);
3304       }
3305       if(!((aIPD.xP1DS2(i, j) & aIPD.xP1DS2(i, j+1)) || 
3306         (aIPD.xP1DS2(i, j) & aIPD.xP1DS2(i+1, j+1)))) {
3307           Remplit(aIPD.xIP1(i, j),
3308             aIPD.xIP1(i, j+1),
3309             aIPD.xIP1(i+1, j+1),
3310             M1);        
3311       }
3312     }
3313   }     
3314   //
3315   for(i=0;i<SU2-1;i+=1) {
3316     for(j=0;j<SV2-1;j+=1) { 
3317       if(!((aIPD.xP2DS1(i, j) & aIPD.xP2DS1(i+1, j)) ||
3318         (aIPD.xP2DS1(i, j) & aIPD.xP2DS1(i+1, j+1)))){
3319           Remplit(aIPD.xIP2(i, j),
3320             aIPD.xIP2(i+1, j),
3321             aIPD.xIP2(i+1, j+1),
3322             M2);
3323       }
3324       if(!((aIPD.xP2DS1(i, j) & aIPD.xP2DS1(i, j+1)) || 
3325         (aIPD.xP2DS1(i, j) & aIPD.xP2DS1(i+1, j+1)))){
3326           Remplit(aIPD.xIP2(i, j),
3327             aIPD.xIP2(i, j+1),
3328             aIPD.xIP2(i+1, j+1),
3329             M2);        
3330       }
3331     }
3332   }     
3333   //
3334   M1.ResetAnd();
3335   M2.ResetAnd();
3336   //
3337   int newind=0;
3338   long unsigned Compt=0;
3339   int ok=0;
3340   int indicepointtraite = 0;
3341   Standard_Integer k,nu,nv;
3342   //
3343   do { 
3344     indicepointtraite--;
3345     ok = M1.And(M2,newind);
3346     if(ok) { 
3347       IntegerGrille(newind,i,j,k);
3348       int nb=0;
3349       int LIM=3;
3350       if(   DansGrille(i-1) && DansGrille(j-1) && DansGrille(k-1) 
3351         && DansGrille(i+1) && DansGrille(j+1) && DansGrille(k+1)) { 
3352           int si,sj,sk;
3353           for(si=-1; si<= 1 && nb<LIM; si++) { 
3354             for(sj=-1; sj<= 1 && nb<LIM; sj++) { 
3355               for(sk=-1; sk<= 1 && nb<LIM; sk++) { 
3356                 long unsigned lu=GrilleInteger(i+si,j+sj,k+sk);
3357                 if(M1.Val(lu) && M2.Val(lu)) { 
3358                   nb++;
3359                 }
3360               }
3361             }
3362           }
3363           if(nb>=LIM) { 
3364             for(si=-1; si<= 1; si++) { 
3365               for(sj=-1; sj<= 1; sj++) { 
3366                 for(sk=-1; sk<= 1; sk++) { 
3367                   if(si || sj || sk) { 
3368                     long unsigned lu=GrilleInteger(i+si,j+sj,k+sk);
3369                     M1.Raz(lu);
3370                   }
3371                 }
3372               }
3373             }
3374           }
3375       }
3376       //
3377       gp_Pnt P(dx*i + x0, dy*j + y0, dz*k+z0);
3378       //
3379       Standard_Integer nu1=-1,nu2=-1;
3380       Standard_Integer nv1=0, nv2=0;
3381       int nbsur1 = 0;
3382       for(nu=0;nu1<0 && nu<SU1;nu++) { 
3383         for(nv=0;nu1<0 && nv<SV1;nv++) { 
3384           if( aIPD.xIP1(nu, nv) ==(Standard_Integer) newind )  { 
3385             nbsur1++;
3386             aIPD.xIP1(nu, nv)=indicepointtraite;
3387             nu1=nu; nv1=nv;
3388           }
3389         }
3390       }
3391       if(nu1>=0) { 
3392         int nbsur2 = 0;
3393         for(nu=0;nu2<0 && nu<SU2;nu++) { 
3394           for(nv=0;nu2<0 && nv<SV2;nv++) { 
3395             if( aIPD.xIP2(nu, nv)==(Standard_Integer) newind )  { 
3396               nbsur2++;
3397               aIPD.xIP2(nu, nv)=indicepointtraite;
3398               nu2=nu; nv2=nv;
3399             }
3400           }
3401         }
3402       }
3403       if(nu1>=0 && nu2>=0) { 
3404         IntSurf_PntOn2S POn2S;
3405         POn2S.SetValue(P, 
3406           S1->FirstUParameter()+nu1*du1,
3407           S1->FirstVParameter()+nv1*dv1,
3408           S2->FirstUParameter()+nu2*du2,
3409           S2->FirstVParameter()+nv2*dv2);
3410         LineOn2S->Add(POn2S);
3411         Compt++;
3412       }
3413       else { 
3414         //-- aucun point du triangle n a ete trouve assez proche
3415         //-- on recherche les 3 points les plus proches de P 
3416         //-- dans chacun des tableaux 
3417         Standard_Real Dist3[3],u3[3] = { 0.0, 0.0, 0.0 },v3[3] = { 0.0, 0.0, 0.0 };
3418         Dist3[0]=Dist3[1]=Dist3[2]=RealLast();
3419         for(U=resu0,i=0; i<SU1; i++,U+=du1) { 
3420           for(V=resv0,j=0; j<SV1; V+=dv1,j++) {       
3421             //-- On place les 3 meilleures valeurs dans Dist1,Dist2,Dist3
3422             Standard_Real t = aIPD.xP1(i, j).SquareDistance(P);
3423             //-- On remplace la plus grande valeur ds Dist[.] par la val courante
3424             if(Dist3[0]<Dist3[1]) { 
3425               Standard_Real z;
3426               z=Dist3[0]; Dist3[0]=Dist3[1]; Dist3[1]=z;
3427               z=u3[0]; u3[0]=u3[1]; u3[1]=z;
3428               z=v3[0]; v3[0]=v3[1]; v3[1]=z;
3429             }
3430             if(Dist3[1]<Dist3[2]) { 
3431               Standard_Real z;
3432               z=Dist3[1]; Dist3[1]=Dist3[2]; Dist3[2]=z;
3433               z=u3[1]; u3[1]=u3[2]; u3[2]=z;
3434               z=v3[1]; v3[1]=v3[2]; v3[2]=z;
3435             }
3436             if(Dist3[0]<Dist3[1]) { 
3437               Standard_Real z;
3438               z=Dist3[0]; Dist3[0]=Dist3[1]; Dist3[1]=z;
3439               z=u3[0]; u3[0]=u3[1]; u3[1]=z;
3440               z=v3[0]; v3[0]=v3[1]; v3[1]=z;
3441             }
3442             //-- la plus grande valeur est dans Dist3[0]
3443             if(t<Dist3[0]) { 
3444               Dist3[0]=t; u3[0]=U; v3[0]=V;
3445             }
3446           }
3447         }
3448         //
3449         Standard_Real U1_3 = (u3[0]+u3[1]+u3[2])/3.0;
3450         Standard_Real V1_3 = (v3[0]+v3[1]+v3[2])/3.0;
3451
3452         Dist3[0]=Dist3[1]=Dist3[2]=RealLast();
3453         for(U=U0,i=0; i<SU2; i++,U+=du2) { 
3454           for(V=V0,j=0; j<SV2; V+=dv2,j++) {       
3455             //-- On place les 3 meilleures valeurs dans Dist1,Dist2,Dist3
3456             Standard_Real t = aIPD.xP2(i, j).SquareDistance(P);
3457             //-- On remplace la plus grande valeur ds Dist3[.] par la val courante
3458             if(Dist3[0]<Dist3[1]) { 
3459               Standard_Real z;
3460               z=Dist3[0]; Dist3[0]=Dist3[1]; Dist3[1]=z;
3461               z=u3[0]; u3[0]=u3[1]; u3[1]=z;
3462               z=v3[0]; v3[0]=v3[1]; v3[1]=z;
3463             }
3464             if(Dist3[1]<Dist3[2]) { 
3465               Standard_Real z;
3466               z=Dist3[1]; Dist3[1]=Dist3[2]; Dist3[2]=z;
3467               z=u3[1]; u3[1]=u3[2]; u3[2]=z;
3468               z=v3[1]; v3[1]=v3[2]; v3[2]=z;
3469             }
3470             if(Dist3[0]<Dist3[1]) { 
3471               Standard_Real z;
3472               z=Dist3[0]; Dist3[0]=Dist3[1]; Dist3[1]=z;
3473               z=u3[0]; u3[0]=u3[1]; u3[1]=z;
3474               z=v3[0]; v3[0]=v3[1]; v3[1]=z;
3475             }
3476             //-- la plus grande valeur est dans Dist3[0]
3477             if(t<Dist3[0]) { 
3478               Dist3[0]=t; u3[0]=U; v3[0]=V;
3479             }
3480           }
3481         }
3482         //
3483         Standard_Real U2_3 = (u3[0]+u3[1]+u3[2])/3.0;
3484         Standard_Real V2_3 = (v3[0]+v3[1]+v3[2])/3.0;
3485         //
3486         IntSurf_PntOn2S POn2S;
3487         POn2S.SetValue(P,U1_3,V1_3,U2_3,V2_3);
3488         LineOn2S->Add(POn2S);
3489         Compt++;        
3490       }
3491     }
3492   }
3493   while(ok);
3494 }
3495
3496 //==================================================================================
3497 // function : IsPointOnLine
3498 // purpose  : 
3499 //==================================================================================
3500
3501 Standard_Boolean IsPointOnLine(const IntSurf_PntOn2S        &thePOn2S,
3502                                const Handle(IntPatch_WLine) &theWLine,
3503                                const Standard_Real           Deflection)
3504 {
3505   Standard_Boolean isOnLine = Standard_False;
3506   Standard_Real Deflection2 = Deflection*Deflection;
3507   Standard_Real pu1, pu2, pv1, pv2;
3508
3509   thePOn2S.Parameters(pu1, pv1, pu2, pv2);
3510
3511   if ((theWLine->IsOutSurf1Box(gp_Pnt2d(pu1, pv1)) == Standard_False) &&
3512     (theWLine->IsOutSurf2Box(gp_Pnt2d(pu2, pv2)) == Standard_False) &&
3513     (theWLine->IsOutBox(thePOn2S.Value())        == Standard_False)) {
3514       const Standard_Integer NbPntOn2SOnLine = theWLine->NbPnts();
3515       Standard_Integer ll;
3516
3517       for (ll=1; ll < NbPntOn2SOnLine && !isOnLine; ll++) {
3518         const gp_Pnt &Pa     = theWLine->Point(ll).Value();
3519         const gp_Pnt &Pb     = theWLine->Point(ll+1).Value();
3520         const gp_Pnt &PStart = thePOn2S.Value();
3521         const gp_Vec  AM(Pa, PStart);
3522         const gp_Vec  MB(PStart,Pb);
3523         const Standard_Real AMMB = AM.Dot(MB);
3524
3525         if(AMMB > 0.0) {
3526           gp_Dir ABN(Pb.X() - Pa.X(), Pb.Y() - Pa.Y(), Pb.Z() - Pa.Z());
3527           Standard_Real lan =  ABN.X()*AM.X() + ABN.Y()*AM.Y() + ABN.Z()*AM.Z();
3528           gp_Vec AH(lan*ABN.X(), lan*ABN.Y(), lan*ABN.Z());
3529           gp_Vec HM(AM.X() - AH.X(), AM.Y() - AH.Y(), AM.Z() - AH.Z());
3530           Standard_Real d = 0.0;
3531
3532           if(HM.X() < Deflection) {
3533             d += HM.X()*HM.X();
3534
3535             if(HM.Y() < Deflection) {
3536               d += HM.Y()*HM.Y();
3537
3538               if(HM.Z() < Deflection) {
3539                 d += HM.Z()*HM.Z();
3540               } else {
3541                 d = Deflection2;
3542               }
3543             } else {
3544               d = Deflection2;
3545             }
3546           } else {
3547             d = Deflection2;
3548           }
3549
3550           if(d < Deflection2) {
3551             isOnLine = Standard_True;
3552           }
3553         } else {
3554           Standard_Real dab = Pa.SquareDistance(Pb);
3555           Standard_Real dap = Pa.SquareDistance(PStart);
3556
3557           if(dap < dab) {
3558             isOnLine = Standard_True;
3559           } else {
3560             Standard_Real dbp = Pb.SquareDistance(PStart);
3561
3562             if(dbp < dab) {
3563               isOnLine = Standard_True;
3564             }
3565           }
3566         }
3567       }
3568   }
3569
3570   return isOnLine;
3571 }
3572
3573 //==================================================================================
3574 // function : AddWLine
3575 // purpose  : 
3576 //==================================================================================
3577
3578 void AddWLine(IntPatch_SequenceOfLine      &theLines,
3579               const Handle(IntPatch_WLine) &theWLine,
3580               const Standard_Real           Deflection)
3581 {
3582   Standard_Integer i = 1;
3583   Standard_Integer aNbLines = theLines.Length();
3584   Standard_Boolean isToRemove;
3585
3586   // Check each line of theLines if it is on theWLine.
3587   while (i <= aNbLines) {
3588     Handle(IntPatch_WLine) aWLine =
3589       Handle(IntPatch_WLine)::DownCast(theLines.Value(i));
3590
3591     isToRemove = Standard_False;
3592
3593     if (aWLine.IsNull() == Standard_False) {
3594       // Check the middle point.
3595       Standard_Integer aMidIndex = (aWLine->NbPnts() + 1)/2;
3596
3597       if (aMidIndex > 0) {
3598         const IntSurf_PntOn2S &aPnt = aWLine->Point(aMidIndex);
3599
3600         if (IsPointOnLine(aPnt, theWLine, Deflection)) {
3601           // Middle point is on theWLine. Check vertices.
3602           isToRemove = Standard_True;
3603
3604           Standard_Integer j;
3605           const Standard_Integer aNbVtx = aWLine->NbVertex();
3606
3607           for (j = 1; j <= aNbVtx; j++) {
3608             const IntPatch_Point &aPoint = aWLine->Vertex(j);
3609
3610             if (!IsPointOnLine(aPoint.PntOn2S(), theWLine, Deflection)) {
3611               isToRemove = Standard_False;
3612               break;
3613             }
3614           }
3615         }
3616       }
3617     }
3618
3619     if (isToRemove) {
3620       theLines.Remove(i);
3621       aNbLines--;
3622     } else {
3623       i++;
3624     }
3625   }
3626
3627   // Add theWLine to the sequence of lines.
3628   theLines.Append(theWLine);
3629 }