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