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