0023952: Improving thread-safety of intersections, approximations and other modeling...
[occt.git] / src / IntPatch / IntPatch_RstInt.cxx
1 // Created on: 1993-05-07
2 // Created by: Jacques GOUSSARD
3 // Copyright (c) 1993-1999 Matra Datavision
4 // Copyright (c) 1999-2012 OPEN CASCADE SAS
5 //
6 // The content of this file is subject to the Open CASCADE Technology Public
7 // License Version 6.5 (the "License"). You may not use the content of this file
8 // except in compliance with the License. Please obtain a copy of the License
9 // at http://www.opencascade.org and read it completely before using this file.
10 //
11 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13 //
14 // The Original Code and all software distributed under the License is
15 // distributed on an "AS IS" basis, without warranty of any kind, and the
16 // Initial Developer hereby disclaims all such warranties, including without
17 // limitation, any warranties of merchantability, fitness for a particular
18 // purpose or non-infringement. Please see the License for the specific terms
19 // and conditions governing the rights and limitations under the License.
20
21
22 // ----------------------------------------------------------------------
23 //-- lbr: Modifs importantes du 16-17 Nov 95
24 //--      - Chercher APointOnRstStillExist et OnDifferentRst
25 //--      On veut pouvoir creer un Vtx (A1 sur S1, A2    sur S2)
26 //--                         et le Vtx (A1 sur S1, A2bis sur S2)
27 //--      ce qui revient a distinguer un point deja pose sur une 
28 //--      restriction de S avec un point pose sur une nouvelle
29 //--       restriction de S.
30 //--      - Pour rester coherent avec cette facon de faire, 
31 //--      Chercher(Nbvtx++). 
32
33 #include <IntPatch_RstInt.ixx>
34
35 #include <IntSurf.hxx>
36
37 #include <TColgp_SequenceOfPnt.hxx>
38 #include <TColgp_SequenceOfPnt2d.hxx>
39 #include <Intf_SectionPoint.hxx>
40 #include <Intf_TangentZone.hxx>
41 #include <gp_Pnt2d.hxx>
42 #include <Precision.hxx>
43
44 #include <Adaptor2d_HCurve2d.hxx>
45 #include <IntPatch_WLine.hxx>
46 #include <IntPatch_RLine.hxx>
47 #include <IntPatch_HInterTool.hxx>
48 #include <IntPatch_SearchPnt.hxx>
49 #include <IntPatch_PolyLine.hxx>
50 #include <IntPatch_PolyArc.hxx>
51 #include <IntPatch_CSFunction.hxx>
52 #include <IntPatch_CurvIntSurf.hxx>
53
54
55 static void Recadre(GeomAbs_SurfaceType typeS1,
56                     GeomAbs_SurfaceType typeS2,
57                     const Handle(IntPatch_WLine)& wlin,
58                     Standard_Integer Param,
59                     Standard_Real& U1,
60                     Standard_Real& V1,
61                     Standard_Real& U2,
62                     Standard_Real& V2)
63 {
64   Standard_Integer nbpnts = wlin->NbPnts();
65   if(Param<1) Param=1; else if(Param>nbpnts) Param=nbpnts;
66   Standard_Real U1p,V1p,U2p,V2p;
67
68   wlin->Point(Param).Parameters(U1p,V1p,U2p,V2p);
69   switch(typeS1) { 
70   case GeomAbs_Cylinder:
71   case GeomAbs_Cone:
72   case GeomAbs_Sphere:
73   case GeomAbs_Torus:
74     while(U1<(U1p-1.5*M_PI)) U1+=M_PI+M_PI;
75     while(U1>(U1p+1.5*M_PI)) U1-=M_PI+M_PI;
76     break;
77   default: 
78     break;
79   }
80   if(typeS1==GeomAbs_Torus) { 
81     while(V1<(V1p-1.5*M_PI)) V1+=M_PI+M_PI;
82     while(V1>(V1p+1.5*M_PI)) V1-=M_PI+M_PI;
83   }
84   
85   switch(typeS2) { 
86   case GeomAbs_Cylinder:
87   case GeomAbs_Cone:
88   case GeomAbs_Sphere:
89   case GeomAbs_Torus:
90     while(U2<(U2p-1.5*M_PI)) U2+=M_PI+M_PI;
91     while(U2>(U2p+1.5*M_PI)) U2-=M_PI+M_PI;
92     break;
93   default: 
94     break;
95   }
96   if(typeS2==GeomAbs_Torus) { 
97     while(V2<(V1p-1.5*M_PI)) V2+=M_PI+M_PI;
98     while(V2>(V2p+1.5*M_PI)) V2-=M_PI+M_PI;
99   }
100 }
101
102 const Standard_Real Confusion = Precision::Confusion();
103
104 inline Standard_Real Tol3d (const Handle(Adaptor3d_HVertex)& vtx,
105                             const Handle(Adaptor3d_TopolTool)& Domain,
106                             const Standard_Real tolDef = 0.)
107 {
108   return (Domain->Has3d() ? Domain->Tol3d(vtx)
109           : tolDef < Confusion ? Confusion
110           : tolDef);
111 }
112
113 inline Standard_Real Tol3d (const Handle(Adaptor2d_HCurve2d)& arc,
114                             const Handle(Adaptor3d_TopolTool)& Domain,
115                             const Standard_Real tolDef = 0.)
116 {
117   return (Domain->Has3d() ? Domain->Tol3d(arc)
118           : tolDef < Confusion ? Confusion
119           : tolDef);
120 }
121
122 static Standard_Boolean CoincideOnArc(const gp_Pnt& Ptsommet,
123                                       const Handle(Adaptor2d_HCurve2d)& A,
124                                       const Handle(Adaptor3d_HSurface)& Surf,
125                                       const Standard_Real Toler,
126                                       const Handle(Adaptor3d_TopolTool)& Domain,
127                                       Handle(Adaptor3d_HVertex)& Vtx)
128 {
129   Standard_Real distmin = RealLast();
130   Standard_Real tolarc = Max(Toler,Tol3d(A,Domain));
131
132   Domain->Initialize(A);
133   Domain->InitVertexIterator();
134   while (Domain->MoreVertex()) {
135     Handle(Adaptor3d_HVertex) vtx1 = Domain->Vertex();
136     Standard_Real prm = IntPatch_HInterTool::Parameter(vtx1,A);
137     gp_Pnt2d p2d = A->Value(prm);
138     gp_Pnt point = Surf->Value(p2d.X(),p2d.Y());
139     const Standard_Real dist = point.Distance(Ptsommet);
140     Standard_Real tol = Max (tolarc, Tol3d(vtx1,Domain));
141
142     if (dist <= tol && dist <= distmin) { // the best coincidence
143       distmin = dist;
144       Vtx = vtx1;
145     }
146     Domain->NextVertex();
147   }
148   return distmin < RealLast();
149 }
150
151
152 static void VerifyTgline(const Handle(IntPatch_WLine)& wlin,
153                          const Standard_Integer param,
154                          const Standard_Real Tol,
155                          gp_Vec& Tgl) { 
156   
157   if(   Abs(Tgl.X())<Tol 
158      && Abs(Tgl.Y())<Tol
159      && Abs(Tgl.Z())<Tol) { 
160     //-- On construit une tangente plus grande
161     //-- (Eviter des points tres proches ds Walking)                
162     Standard_Integer i, n, nbpt=wlin->NbPnts();
163     Standard_Boolean forward = (nbpt-param) >= (param-1);
164     for (n = 2; n > 0; n--, forward = !forward) {
165       if (forward) {
166         for(i=param+1; i<=nbpt; i++) { 
167           gp_Vec T(wlin->Point(param).Value(),wlin->Point(i).Value());
168           if(   Abs(T.X())>=Tol 
169              || Abs(T.Y())>=Tol
170              || Abs(T.Z())>=Tol) { 
171             Tgl = T ; 
172             return;
173           }
174         }
175       }
176       else {
177         for(i=param-1; i>=1; i--) { 
178           gp_Vec T(wlin->Point(i).Value(),wlin->Point(param).Value());
179           if(   Abs(T.X())>=Tol 
180              || Abs(T.Y())>=Tol
181              || Abs(T.Z())>=Tol) { 
182             Tgl = T ; 
183             return;
184           }
185         }
186       }
187     }
188   }
189 }  
190
191 static void GetLinePoint2d (const Handle(IntPatch_Line)& L,
192                             const Standard_Real param,
193                             const Standard_Boolean OnFirst,
194                             Standard_Real& U, Standard_Real& V)
195 {
196   IntPatch_IType typL = L->ArcType();
197   const Handle(IntPatch_WLine)& wlin = (const Handle(IntPatch_WLine)&)L;
198   const Handle(IntPatch_RLine)& rlin = (const Handle(IntPatch_RLine)&)L;
199   Standard_Integer Nbptlin = (typL == IntPatch_Walking
200                               ? wlin->NbPnts()
201                               : rlin->NbPnts());
202
203   Standard_Real par = IntegerPart(param);
204   Standard_Integer Irang = Standard_Integer(par);
205   if (Irang == Nbptlin) {
206     Irang--;
207     par = 1.0;
208   }
209   else
210     par = Abs(param-par);
211
212   Standard_Real us1,vs1,us2,vs2;
213   if (typL == IntPatch_Walking) {
214     if (OnFirst) {
215       wlin->Point(Irang).ParametersOnS1(us1,vs1);
216       wlin->Point(Irang+1).ParametersOnS1(us2,vs2);
217     }
218     else {
219       wlin->Point(Irang).ParametersOnS2(us1,vs1);
220       wlin->Point(Irang+1).ParametersOnS2(us2,vs2);
221     }
222   }
223   else {
224     if (OnFirst) {
225       rlin->Point(Irang).ParametersOnS1(us1,vs1);
226       rlin->Point(Irang+1).ParametersOnS1(us2,vs2);
227     }
228     else {
229       rlin->Point(Irang).ParametersOnS2(us1,vs1);
230       rlin->Point(Irang+1).ParametersOnS2(us2,vs2);
231     }
232   }
233
234   U = (1.-par)*us1+par*us2;
235   V = (1.-par)*vs1+par*vs2;
236 }
237
238 static void GetWLinePoint (const Handle(IntPatch_WLine)& wlin,
239                           const Standard_Real param,
240                           Standard_Real& U1, Standard_Real& V1,
241                           Standard_Real& U2, Standard_Real& V2,
242                           gp_Pnt& P)
243 {
244   Standard_Integer Nbptlin = wlin->NbPnts();
245   Standard_Real par = IntegerPart(param);
246   Standard_Integer Irang = Standard_Integer(par);
247   if (Irang == Nbptlin) {
248     Irang--;
249     par = 1.0;
250   }
251   else
252     par = Abs(param-par);
253
254   const IntSurf_PntOn2S& p2s1 = wlin->Point(Irang);
255   const IntSurf_PntOn2S& p2s2 = wlin->Point(Irang+1);
256   const gp_Pnt& p1 = p2s1.Value();
257   const gp_Pnt& p2 = p2s2.Value();
258   P.ChangeCoord().SetLinearForm(1.-par, p1.XYZ(), par, p2.XYZ());
259
260   Standard_Real us1,vs1,us2,vs2;
261   p2s1.ParametersOnS1(us1,vs1);
262   p2s2.ParametersOnS1(us2,vs2);
263   U1 = (1.-par)*us1+par*us2;
264   V1 = (1.-par)*vs1+par*vs2;
265
266   p2s1.ParametersOnS2(us1,vs1);
267   p2s2.ParametersOnS2(us2,vs2);
268   U2 = (1.-par)*us1+par*us2;
269   V2 = (1.-par)*vs1+par*vs2;
270 }
271
272 static Standard_Boolean FindParameter(const Handle(IntPatch_Line)& L,
273                                       const Handle(Adaptor3d_HSurface)& OtherSurf,
274                                       const Standard_Real Tol,
275                                       const gp_Pnt& Ptsom,
276                                       const gp_Pnt2d& Ptsom2d,
277                                       Standard_Real& Param,
278                                       gp_Vec& Tgl,
279                                       const Standard_Integer ParamApproche,
280                                       const Standard_Boolean OnFirst)
281
282 {
283   // MSV 28.03.2002: find parameter on WLine in 2d space
284
285   //Si la ligne est de type restriction, c est qu on provient necessairement
286   // du cas implicite/parametree, et que la ligne est restriction de
287   // la surface bi-parametree. Cette surface bi-parametree est necessairement
288   // passee en argument a PutVertexOnline dans la variable OtherSurf.
289
290   // Dans le cas d une ligne de cheminement, il faudrait voir la projection
291   // et le calcul de la tangente.
292
293   const Handle(IntPatch_RLine)&  rlin = (*((Handle(IntPatch_RLine)*)&L)); //-- aucune verification n est 
294   const Handle(IntPatch_WLine)&  wlin = (*((Handle(IntPatch_WLine)*)&L)); //-- faite au cast. 
295   gp_Pnt ptbid;
296   gp_Vec d1u,d1v;
297   gp_Pnt2d p2d;
298   gp_Vec2d d2d;
299   Standard_Real Tol2 = Tol*Tol;
300   IntPatch_IType typL = L->ArcType();
301   Tgl.SetCoord(0.0,0.0,0.0);
302
303   if ( typL == IntPatch_Restriction) {
304     if     (!OnFirst && rlin->IsArcOnS1()) { 
305       IntPatch_HInterTool::Project(rlin->ArcOnS1(),Ptsom2d,Param,p2d);
306       rlin->ArcOnS1()->D1(Param,p2d,d2d);
307     }
308     else if (OnFirst && rlin->IsArcOnS2()) { 
309       IntPatch_HInterTool::Project(rlin->ArcOnS2(),Ptsom2d,Param,p2d);
310       rlin->ArcOnS2()->D1(Param,p2d,d2d);
311     }
312     else { 
313       return(Standard_False);
314     }
315     OtherSurf->D1(p2d.X(),p2d.Y(),ptbid,d1u,d1v);
316     if (ptbid.SquareDistance(Ptsom) > Tol2) {
317       return Standard_False;
318     }
319     Tgl.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
320     return(Standard_True);
321   }
322
323   else if (typL == IntPatch_Walking) {
324     Standard_Integer i, is, nbpt=wlin->NbPnts();
325     Standard_Real norm1,norm2;
326     Standard_Integer ParamSearchInf=1;
327     Standard_Integer ParamSearchSup=nbpt;
328
329     if((ParamApproche-2) > ParamSearchInf) { 
330       ParamSearchInf = ParamApproche-2;
331     }
332     if((ParamApproche+2) < ParamSearchSup) { 
333       ParamSearchSup = ParamApproche+2;
334     }
335
336     Standard_Integer inf[3],sup[3];
337     // first search inside close bounding around ParamApproche;
338     // then search to the nearest end of line;
339     // and then search to the farest end of line.
340     inf[0] = ParamSearchInf; sup[0] = ParamSearchSup;
341     if (ParamSearchInf-1 < nbpt-ParamSearchSup) {
342       inf[1] = 1;              sup[1] = ParamSearchInf;
343       inf[2] = ParamSearchSup; sup[2] = nbpt;
344     }
345     else {
346       inf[1] = ParamSearchSup; sup[1] = nbpt;
347       inf[2] = 1;              sup[2] = ParamSearchInf;
348     }
349
350     Standard_Boolean found = Standard_False;
351     for (is=0; is < 3 && !found; is++) {
352       gp_Vec v1,v2;
353       gp_Pnt p1,p2;
354       p1 = wlin->Point(inf[is]).Value();
355       v1 = gp_Vec (Ptsom,p1);
356       norm1 = v1.SquareMagnitude();
357       Standard_Real normmin = Tol2;
358       Standard_Integer ibest = 0;
359       if (norm1 <= normmin) {
360         normmin = norm1;
361         ibest = inf[is];
362       }
363       for (i=inf[is]+1; i <= sup[is] && !found; i++) {
364         p2 = wlin->Point(i).Value();
365         v2 = gp_Vec (Ptsom,p2);
366         norm2 = v2.SquareMagnitude();
367         if (v1.Dot(v2) < 0.) {
368           Param = (Standard_Real)(i-1) + 1./(1.+Sqrt(norm2/norm1));
369           Tgl = gp_Vec (p1,p2);
370           found = Standard_True;
371         }
372         else if (norm2 < normmin) {
373           normmin = norm2;
374           ibest = i;
375         }
376         v1 = v2; p1 = p2; norm1 = norm2;
377       }
378       if (!found && ibest) {
379         Param = (Standard_Real)ibest;
380         found = Standard_True;
381       }
382     }
383     if (found) return Standard_True;
384   }
385   else {
386     Standard_DomainError::Raise();
387   }
388   return Standard_False;
389 }
390
391 inline Standard_Boolean ArePnt2dEqual(const gp_Pnt2d& p1, const gp_Pnt2d& p2,
392                                       const Standard_Real tolU,
393                                       const Standard_Real tolV)
394 {
395   return Abs(p1.X()-p2.X()) < tolU && Abs(p1.Y()-p2.Y()) < tolV;
396 }
397
398 static gp_Pnt2d GetPointOnPolygo(const IntPatch_Polygo& Pol,
399                                  const Standard_Real param)
400 {
401   Standard_Real par = IntegerPart(param);
402   Standard_Integer irang = Standard_Integer(par) + 1;
403   if (irang == Pol.NbPoints()) {
404     irang--;
405     par = 1.;
406   }
407   else {
408     par = Abs(param-par);
409   }
410   gp_Pnt2d p1 = Pol.Point(irang);
411   gp_Pnt2d p2 = Pol.Point(irang+1);
412   gp_Pnt2d p;
413   p.ChangeCoord().SetLinearForm(1.-par,p1.XY(),par,p2.XY());
414   return p;
415 }
416
417 static Standard_Boolean IsSegment2dSmall(const IntPatch_Polygo& Pol,
418                                          const Standard_Real parmin,
419                                          const Standard_Real parmax,
420                                          const Standard_Real URes,
421                                          const Standard_Real VRes)
422 {
423   Standard_Integer irang1 = Standard_Integer(IntegerPart(parmin)) + 2;
424   Standard_Integer irang2 = Standard_Integer(IntegerPart(parmax)) + 1;
425   gp_Pnt2d p1,p2;
426   Standard_Real du=0.,dv=0.;
427   p1 = GetPointOnPolygo(Pol,parmin);
428   for (Standard_Integer i=irang1; i <= irang2 && du <= URes && dv <= VRes; i++) {
429     p2 = Pol.Point(i);
430     du += Abs(p2.X()-p1.X());
431     dv += Abs(p2.Y()-p1.Y());
432     p1 = p2;
433   }
434   if (du <= URes && dv <= VRes) {
435     p2 = GetPointOnPolygo(Pol,parmax);
436     du += Abs(p2.X()-p1.X());
437     dv += Abs(p2.Y()-p1.Y());
438   }
439   return du <= URes && dv <= VRes;
440 }
441
442 //=======================================================================
443 //function : PutVertexOnLine
444 //purpose  : 
445 //=======================================================================
446
447 void IntPatch_RstInt::PutVertexOnLine (Handle(IntPatch_Line)& L,
448                                        const Handle(Adaptor3d_HSurface)& Surf,
449                                        const Handle(Adaptor3d_TopolTool)& Domain,
450                                        const Handle(Adaptor3d_HSurface)& OtherSurf,
451                                        const Standard_Boolean OnFirst,
452                                        const Standard_Real Tol )
453  {
454
455 // Domain est le domaine de restriction de la surface Surf.
456 // On intersectera un arc de Surf avec la surface OtherSurf.
457 // Si OnFirst = True, c est que la surface Surf correspond a la 1ere
458 // surface donnee aux algo d intersection.
459
460   IntPatch_SearchPnt Commun;
461
462   Standard_Real U,V,W;
463   Standard_Real U1,V1,U2,V2;
464   Standard_Real paramarc=0.,paramline=0.;
465   Standard_Integer i,j,k;
466   TColgp_SequenceOfPnt locpt;
467   TColgp_SequenceOfPnt2d locpt2;
468   const Handle(IntPatch_RLine)&  rlin = (*((Handle(IntPatch_RLine)*)&L)); //-- aucune verification n est 
469   const Handle(IntPatch_WLine)&  wlin = (*((Handle(IntPatch_WLine)*)&L)); //-- faite au cast. 
470   Standard_Integer Nbvtx =0; 
471   Standard_Integer Nbptlin =0;
472   Standard_Real tolPLin = Surf->UResolution(Precision::Confusion());
473   tolPLin = Max (tolPLin, Surf->VResolution(Precision::Confusion()));
474   tolPLin = Min (tolPLin, Precision::Confusion());
475   IntPatch_PolyLine PLin(tolPLin);
476
477   Standard_Real PFirst,PLast;
478   Standard_Integer NbEchant;
479   gp_Pnt ptsommet, ptbid;
480   gp_Vec tgline, tgrst, d1u, d1v, normsurf;
481
482   gp_Pnt2d p2d;
483   gp_Vec2d d2d;
484
485   IntPatch_Point Sommet, ptline;
486   Handle(Adaptor3d_HVertex) vtxarc,vtxline;
487   Handle(Adaptor2d_HCurve2d) arc;
488   Standard_Boolean VtxOnArc, duplicate, found;
489   IntSurf_Transition transarc,transline;
490
491   IntPatch_IType typL = L->ArcType();
492   if (typL == IntPatch_Walking) {
493     Nbvtx = wlin->NbVertex();
494     PLin.SetWLine(OnFirst,wlin);
495     Nbptlin = wlin->NbPnts();
496   }
497   else if ( typL == IntPatch_Restriction) {
498     Nbvtx = rlin->NbVertex();
499     PLin.SetRLine(OnFirst,rlin);
500     Nbptlin = rlin->NbPnts();
501   }
502   else {
503     Standard_DomainError::Raise();
504   }
505   if (!Domain->Has3d())
506     // don't use computed deflection in the mode of pure geometric intersection
507     PLin.ResetError();
508
509   const Standard_Boolean SurfaceIsUClosed = Surf->IsUClosed();
510   const Standard_Boolean SurfaceIsVClosed = Surf->IsVClosed();
511   const Standard_Boolean OSurfaceIsUClosed = OtherSurf->IsUClosed();
512   const Standard_Boolean OSurfaceIsVClosed = OtherSurf->IsVClosed();
513   const Standard_Boolean possiblyClosed = (SurfaceIsUClosed || SurfaceIsVClosed ||
514                                            OSurfaceIsUClosed || OSurfaceIsVClosed);
515   Standard_Real tolUClosed=0., tolVClosed=0., tolOUClosed=0., tolOVClosed=0.;
516   if (possiblyClosed) {
517     if (SurfaceIsUClosed)
518       tolUClosed = (Surf->LastUParameter() - Surf->FirstUParameter()) * 0.01;
519     if (SurfaceIsVClosed)
520       tolVClosed = (Surf->LastVParameter() - Surf->FirstVParameter()) * 0.01;
521     if (OSurfaceIsUClosed)
522       tolOUClosed = (OtherSurf->LastUParameter() - OtherSurf->FirstUParameter()) * 0.01;
523     if (OSurfaceIsVClosed)
524       tolOVClosed = (OtherSurf->LastVParameter() - OtherSurf->FirstVParameter()) * 0.01;
525   }
526
527   //------------------------------------------------------------------------
528   //-- On traite le cas ou la surface est periodique                      --
529   //-- il faut dans ce cas considerer la restriction                      --
530   //--                                la restriction decalee de +-2PI     --
531   //------------------------------------------------------------------------
532   const Handle(Adaptor3d_HSurface)& Surf1 = (OnFirst ? Surf : OtherSurf);
533   const Handle(Adaptor3d_HSurface)& Surf2 = (OnFirst ? OtherSurf : Surf);
534   GeomAbs_SurfaceType TypeS1 = Surf1->GetType();
535   GeomAbs_SurfaceType TypeS2 = Surf2->GetType();
536   Standard_Boolean SurfaceIsPeriodic   = Standard_False;
537   Standard_Boolean SurfaceIsBiPeriodic = Standard_False;
538   GeomAbs_SurfaceType surfacetype = (OnFirst ? TypeS1 : TypeS2);
539   if(   surfacetype == GeomAbs_Cylinder
540      || surfacetype == GeomAbs_Cone
541      || surfacetype == GeomAbs_Torus
542      || surfacetype == GeomAbs_Sphere) { 
543     SurfaceIsPeriodic = Standard_True;
544     if(surfacetype == GeomAbs_Torus) { 
545       SurfaceIsBiPeriodic = Standard_True;
546     }
547   }
548   
549   Standard_Integer NumeroEdge=0;
550   Domain->Init();
551   while (Domain->More()) {
552     NumeroEdge++;
553     arc = Domain->Value();
554
555     // MSV Oct 15, 2001: use tolerance of this edge if possible
556     Standard_Real edgeTol = Tol3d(arc,Domain,Tol);
557     Standard_Real URes = Surf->UResolution(edgeTol);
558     Standard_Real VRes = Surf->VResolution(edgeTol);
559
560     IntPatch_HInterTool::Bounds(arc,PFirst,PLast);
561     if (Precision::IsNegativeInfinite(PFirst) || 
562         Precision::IsPositiveInfinite(PLast)) { 
563       //-- cout<<" IntPatch_RstInt::PutVertexOnLine  ---> Restrictions Infinies :"<<endl;
564       return; 
565     }
566
567     Standard_Boolean isVFirst = Standard_False, isVLast = Standard_False;
568     gp_Pnt2d p2dFirst,p2dLast;
569     Standard_Real tolUFirst=0.,tolVFirst=0.,tolULast=0.,tolVLast=0.;
570     Domain->Initialize(arc);
571     for (Domain->InitVertexIterator(); Domain->MoreVertex(); Domain->NextVertex()) {
572       Handle(Adaptor3d_HVertex) vtx = Domain->Vertex();
573       Standard_Real prm = IntPatch_HInterTool::Parameter(vtx,arc);
574       if (Abs(prm - PFirst) < Precision::PConfusion()) {
575         arc->D0(PFirst,p2dFirst);
576         Standard_Real tol3d = Max (Tol3d(vtx,Domain), edgeTol);
577         tolUFirst = Surf->UResolution(tol3d);
578         tolVFirst = Surf->VResolution(tol3d);
579         isVFirst = Standard_True;
580       }
581       else if (Abs(prm - PLast) < Precision::PConfusion()) {
582         arc->D0(PLast,p2dLast);
583         Standard_Real tol3d = Max (edgeTol, Tol3d(vtx,Domain));
584         tolULast = Surf->UResolution(tol3d);
585         tolVLast = Surf->VResolution(tol3d);
586         isVLast = Standard_True;
587       }
588     }
589
590     Bnd_Box2d BPLin = PLin.Bounding();
591
592     if(SurfaceIsPeriodic) { 
593       Standard_Real xmin,ymin,xmax,ymax,g;
594       BPLin.Get(xmin,ymin,xmax,ymax);
595       g = BPLin.GetGap();
596       BPLin.SetVoid();
597       BPLin.Update(xmin-M_PI-M_PI,ymin,
598                    xmax+M_PI+M_PI,ymax);
599       BPLin.SetGap(g);
600     }
601     if(SurfaceIsBiPeriodic) { 
602       Standard_Real xmin,ymin,xmax,ymax,g;
603       BPLin.Get(xmin,ymin,xmax,ymax);
604       g = BPLin.GetGap();
605       BPLin.SetVoid();
606       BPLin.Update(xmin,ymin-M_PI-M_PI,
607                    xmax,ymax+M_PI+M_PI);
608       BPLin.SetGap(g);
609     }
610
611     switch(arc->GetType())
612     { 
613       case GeomAbs_Line: NbEchant=10; break;
614       case GeomAbs_BezierCurve:
615       {
616         NbEchant = (3 + arc->NbPoles());
617             if(NbEchant<10) NbEchant=10;
618         else if(NbEchant>50) NbEchant=50;
619       }
620           break;
621       case GeomAbs_BSplineCurve:
622       { 
623         //szv:const Standard_Real nbs = (arc->NbKnots() * arc->Degree())*(arc->LastParameter() - arc->FirstParameter())/(PLast-PFirst);
624         const Standard_Real nbs = (arc->NbKnots() * arc->Degree())*(PLast-PFirst)/(arc->LastParameter() - arc->FirstParameter());
625                 NbEchant = (nbs < 2.0 ? 2 : (Standard_Integer)nbs);
626             if(NbEchant<10) NbEchant=10;
627         else if (NbEchant>50) NbEchant=50;
628       }
629       break;
630       default:
631       {
632             NbEchant = 25;
633       }
634     }
635
636     IntPatch_PolyArc Brise(arc,NbEchant,PFirst,PLast,BPLin);
637
638     Standard_Integer IndiceOffsetBiPeriodic = 0;    
639     Standard_Integer IndiceOffsetPeriodic   = 0;    
640     Standard_Real OffsetV = 0.0;
641     Standard_Real OffsetU = 0.0;
642     
643     do { 
644       if(IndiceOffsetBiPeriodic == 1) 
645         OffsetV = -M_PI-M_PI;
646       else if(IndiceOffsetBiPeriodic == 2) 
647         OffsetV = M_PI+M_PI;
648       
649       do { 
650         if(IndiceOffsetPeriodic == 1) 
651           OffsetU = -M_PI-M_PI;
652         else if(IndiceOffsetPeriodic == 2) 
653           OffsetU = M_PI+M_PI;
654         
655         Brise.SetOffset(OffsetU,OffsetV);
656         
657         static int debug_polygon2d =0;
658         if(debug_polygon2d) { 
659           cout<<" ***** Numero Restriction : "<<NumeroEdge<<" *****"<<endl;
660           PLin.Dump();
661           Brise.Dump();
662         }
663         
664         Commun.Perform(PLin,Brise);
665         locpt.Clear();
666         locpt2.Clear();
667         Standard_Integer Commun_NbSectionPoints = Commun.NbSectionPoints();
668         Standard_Integer Commun_NbTangentZones  = Commun.NbTangentZones();
669         Standard_Integer Commun_Section_Tangent = Commun_NbSectionPoints
670           + Commun_NbTangentZones;
671         for (i=1;i<=Commun_Section_Tangent;i++) {
672           Standard_Real W1[2],W2[2];
673           Standard_Boolean refine[2],useWL[2];
674           Standard_Integer nbpt = 1;
675           if(i<=Commun_NbSectionPoints) { 
676             // intersection point
677             W1[0] = Commun.PntValue(i).ParamOnFirst();
678             W2[0] = Commun.PntValue(i).ParamOnSecond();
679             refine[0] = Standard_True;
680           }
681           else { 
682             // tangent zone
683             Standard_Real UMinCh,UMaxCh;  //-- ligne de cheminement 0..(Nbptlin-1)
684             Standard_Real UMinAr,UMaxAr;  //-- polyline of arc 0..(NbEchant-1)
685             Commun.ZoneValue(i-Commun_NbSectionPoints).ParamOnFirst(UMinCh,UMaxCh);
686             Commun.ZoneValue(i-Commun_NbSectionPoints).ParamOnSecond(UMinAr,UMaxAr);
687             gp_Pnt2d p1Ar = GetPointOnPolygo(Brise,UMinAr);
688             gp_Pnt2d p2Ar = GetPointOnPolygo(Brise,UMaxAr);
689             Standard_Real tolU = URes*2.;
690             Standard_Real tolV = VRes*2.;
691             if (isVFirst && ArePnt2dEqual(p1Ar,p2dFirst,tolUFirst,tolVFirst)) {
692               tolU = Max(tolUFirst,tolU); tolV = Max(tolVFirst,tolV);
693             }
694             if (isVLast && ArePnt2dEqual(p2Ar,p2dLast,tolULast,tolVLast)) {
695               tolU = Max(tolULast,tolU); tolV = Max(tolVLast,tolV);
696             }
697             Standard_Real nptCh = UMaxCh-UMinCh;
698             Standard_Boolean isNptLow = nptCh < 10. && nptCh < Nbptlin/100. ||
699               !Domain->Has3d() && Standard_Integer(nptCh)+1 < Nbptlin;
700             if (!isNptLow && !IsSegment2dSmall(Brise,UMinAr,UMaxAr,tolU,tolV)) {
701               // treat both ends
702               Standard_Real UMinChP,UMaxChP,UMinArP,UMaxArP;
703               UMinChP = IntegerPart(UMinCh); UMinArP = IntegerPart(UMinAr);
704               UMaxChP = IntegerPart(UMaxCh); UMaxArP = IntegerPart(UMaxAr);
705               Standard_Integer irangCh1,irangCh2,irangAr1,irangAr2;
706               irangCh1 = Standard_Integer(UMinChP)+1; irangCh2 = Standard_Integer(UMaxChP)+1;
707               irangAr1 = Standard_Integer(UMinArP)+1; irangAr2 = Standard_Integer(UMaxArP)+1;
708               UMinChP = UMinCh - UMinChP; UMinArP = UMinAr - UMinArP;
709               //UMaxChP = UMaxCh - UMaxChP; UMaxArP = UMaxAr - UMaxArP;
710               const Standard_Real eps = 1e-10;
711 //            Standard_Boolean isChExtr1 = irangCh1==1 && UMinChP<eps;
712 //            Standard_Boolean isChExtr2 = irangCh2==Nbptlin;
713               Standard_Boolean isArExtr1 = irangAr1==1 && UMinArP<eps;
714               Standard_Boolean isArExtr2 = irangAr2==NbEchant;
715               // detect orientation
716               gp_Pnt2d p1Ch = GetPointOnPolygo(PLin,UMinCh);
717               Standard_Real d11 = p1Ch.SquareDistance(p1Ar);
718               Standard_Real d12 = p1Ch.SquareDistance(p2Ar);
719               Standard_Boolean sameOri = d11 < d12;
720               if (!sameOri) {
721                 Standard_Boolean itmp=isArExtr1; isArExtr1=isArExtr2; isArExtr2=itmp;
722                 Standard_Real dtmp=UMinAr; UMinAr=UMaxAr; UMaxAr=dtmp;
723               }
724               W1[0] = UMinCh; W1[1] = UMaxCh;
725               W2[0] = UMinAr; W2[1] = UMaxAr;
726               //refine[0] = ! (isChExtr1 || isArExtr1);
727               //refine[1] = ! (isChExtr2 || isArExtr2);
728               refine[0] = refine[1] = Standard_False;
729               useWL[0] = !isArExtr1;
730               useWL[1] = !isArExtr2;
731               nbpt = 2;
732             }
733             else {
734               // treat the middle point as an intersection point
735               W1[0] = 0.5*(UMinCh+UMaxCh);
736               W2[0] = 0.5*(UMinAr+UMaxAr);
737               refine[0] = Standard_True;
738             }
739           }
740
741           Standard_Boolean nbTreated = 0;
742           for (Standard_Integer ip=0; ip < nbpt; ip++) {
743             GetLinePoint2d (L, W1[ip]+1, !OnFirst, U,V);
744
745             if (!refine[ip] && useWL[ip]) {
746               Standard_Real aU1,aV1;
747               GetLinePoint2d (L, W1[ip]+1, OnFirst, aU1,aV1);
748               p2d.SetCoord(aU1,aV1);
749               Standard_Real paramProj;
750               if (!IntPatch_HInterTool::Project(arc,p2d,paramProj,p2d)) continue;
751               W = paramProj;
752             }
753             else {
754               Standard_Real par = IntegerPart(W2[ip]);
755               Standard_Integer Irang = Standard_Integer(par) + 1;
756               if (Irang == Brise.NbPoints()) {
757                 Irang--;
758                 par = 1.;
759               }
760               else {
761                 par =Abs(W2[ip]-par);
762               }
763               W = (1.-par)*Brise.Parameter(Irang) + par*Brise.Parameter(Irang+1);
764             }
765
766             Standard_Boolean refined = Standard_False;
767             if (refine[ip]) {
768               //------------------------------------------------------------------------
769               //-- On a trouve un point 2d approche Ua,Va  intersection de la ligne
770               //-- de cheminement et de la restriction. 
771               //--
772               //-- On injecte ce point ds les intersections Courbe-Surface
773               //-- 
774               IntPatch_CSFunction thefunc(OtherSurf,arc,Surf);
775               // MSV: extend UV bounds to not miss solution near the boundary
776               Standard_Real margCoef = 0.004;
777               IntPatch_CurvIntSurf IntCS(U,V,W,thefunc,edgeTol,margCoef);
778               if (IntCS.IsDone()) {
779                 if (!IntCS.IsEmpty()) {
780                   ptsommet = IntCS.Point();
781                   IntCS.ParameterOnSurface(U2,V2);
782                   paramarc = IntCS.ParameterOnCurve();
783                   refined = Standard_True;
784                 }
785               }
786             }
787             else {
788               U2 = U; V2 = V;
789               paramarc = W;
790               arc->D0(paramarc,p2d);
791               Surf->D0(p2d.X(),p2d.Y(),ptsommet);
792             }
793
794             if (!refine[ip] || refined) {
795               duplicate = Standard_False;
796               for (j=1; j<=locpt.Length();j++) {
797                 if (ptsommet.Distance(locpt(j)) <= edgeTol) {
798                   if (possiblyClosed) {
799                     locpt2(j).Coord(U,V);
800                     if (OSurfaceIsUClosed && Abs(U-U2) > tolOUClosed ||
801                         OSurfaceIsVClosed && Abs(V-V2) > tolOVClosed)
802                       continue;
803                   }
804                   duplicate = Standard_True;
805                   break;
806                 }
807               }
808
809               if (!duplicate) {
810                 Standard_Integer ParamApproxOnLine = Standard_Integer(W1[ip])+1;
811
812                 arc->D1(paramarc,p2d,d2d);
813                 U1 = p2d.X(); V1 = p2d.Y();
814                 if (typL == IntPatch_Walking && SurfaceIsPeriodic)
815                   if (OnFirst)
816                     Recadre(TypeS1,TypeS2,wlin,ParamApproxOnLine,U1,V1,U2,V2);
817                   else
818                     Recadre(TypeS1,TypeS2,wlin,ParamApproxOnLine,U2,V2,U1,V1);
819
820                 locpt.Append(ptsommet);
821                 locpt2.Append(gp_Pnt2d(U2,V2));
822
823                 found = FindParameter(L,OtherSurf,edgeTol,ptsommet,gp_Pnt2d(U2,V2),
824                                       paramline,tgline,ParamApproxOnLine,OnFirst);
825
826                 if (typL == IntPatch_Walking && found && possiblyClosed) {
827                   // check in 2d
828                   if (SurfaceIsUClosed || SurfaceIsVClosed) {
829                     GetLinePoint2d (L, paramline, OnFirst, U,V);
830                     if (SurfaceIsUClosed && Abs(U-U1) > tolUClosed ||
831                         SurfaceIsVClosed && Abs(V-V1) > tolVClosed)
832                       found = Standard_False;
833                   }
834                   if (found && (OSurfaceIsUClosed || OSurfaceIsVClosed)) {
835                     GetLinePoint2d (L, paramline, !OnFirst, U,V);
836                     if (OSurfaceIsUClosed && Abs(U-U2) > tolOUClosed ||
837                         OSurfaceIsVClosed && Abs(V-V2) > tolOVClosed)
838                       found = Standard_False;
839                   }
840                 }
841                 if (!found) {
842                   continue;
843                 }
844
845                 VtxOnArc = CoincideOnArc(ptsommet,arc,Surf,edgeTol,Domain,vtxarc);
846                 Standard_Real vtxTol;
847                 if (VtxOnArc) {
848                   vtxTol = Tol3d(vtxarc,Domain);
849                   if (edgeTol > vtxTol) vtxTol = edgeTol;
850                 }
851                 else vtxTol = edgeTol;
852
853                 //-- It is necessary to test that the point does not already exist
854                 //--   - It can be already a point on arc
855                 //--        BUT on a different arc
856                 // MSV 27.03.2002: find the nearest point; add check in 2d
857                 Standard_Integer ivtx = 0;
858                 Standard_Real dmin = RealLast();
859                 for (j=1; j<=Nbvtx; j++) {
860                   const IntPatch_Point& Rptline = (typL == IntPatch_Walking
861                                              ? wlin->Vertex(j)
862                                              : rlin->Vertex(j));
863                   Standard_Boolean APointOnRstStillExist =
864                     (OnFirst  && Rptline.IsOnDomS1() && Rptline.ArcOnS1() == arc ||
865                      !OnFirst && Rptline.IsOnDomS2() && Rptline.ArcOnS2() == arc);
866                   if(!APointOnRstStillExist) {
867                     if (possiblyClosed) {
868                       if (SurfaceIsUClosed || SurfaceIsVClosed) {
869                         if (OnFirst) Rptline.ParametersOnS1(U,V);
870                         else         Rptline.ParametersOnS2(U,V);
871                         if (SurfaceIsUClosed && Abs(U-U1) > tolUClosed ||
872                             SurfaceIsVClosed && Abs(V-V1) > tolVClosed)
873                           continue;
874                       }
875                       if (OSurfaceIsUClosed || OSurfaceIsVClosed) {
876                         if (OnFirst) Rptline.ParametersOnS2(U,V);
877                         else         Rptline.ParametersOnS1(U,V);
878                         if (OSurfaceIsUClosed && Abs(U-U2) > tolOUClosed ||
879                             OSurfaceIsVClosed && Abs(V-V2) > tolOVClosed)
880                           continue;
881                       }
882                     }
883                     Standard_Real dist = ptsommet.Distance(Rptline.Value());
884                     Standard_Real dt = Max(vtxTol, Rptline.Tolerance());
885                     if (dist < dmin) {
886                       if (dist <= dt) {
887                         ptline = Rptline;
888                         ivtx = j;
889                         if( surfacetype == GeomAbs_Cone ) {
890                           ivtx = 0;
891                         }
892                       }
893                       else {
894                         // cancel previous solution because this point is better
895                         // but its tolerance is not large enough
896                         ivtx = 0;
897                       }
898                       dmin = dist;
899                     } 
900                   }
901                 }
902                 if (ivtx) {
903                   if (ptline.Tolerance() > vtxTol) {
904                     vtxTol = ptline.Tolerance();
905                     if (!VtxOnArc) {
906                       // now we should repeat attempt to coincide on a bound of arc
907                       VtxOnArc = CoincideOnArc(ptsommet,arc,Surf,vtxTol,Domain,vtxarc);
908                       if (VtxOnArc) {
909                         Standard_Real tol = Tol3d(vtxarc,Domain);
910                         if (tol > vtxTol) vtxTol = tol;
911                       }
912                     }
913                   }
914                 }
915
916                 if (typL == IntPatch_Walking)
917                   VerifyTgline(wlin,(Standard_Integer)paramline,edgeTol,tgline);
918
919                 Surf->D1(U1,V1,ptbid,d1u,d1v);
920                 tgrst.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
921
922                 normsurf = d1u.Crossed(d1v);
923                 if (normsurf.Magnitude() < gp::Resolution()) {
924                   transline.SetValue(Standard_True,IntSurf_Undecided);
925                   transarc.SetValue(Standard_True,IntSurf_Undecided);
926                 }
927                 else
928                   IntSurf::MakeTransition(tgline,tgrst,normsurf,transline,transarc);
929
930                 if (typL == IntPatch_Walking && !refine[ip]) {
931                   // for new vertex use coordinates from Line
932                   if (OnFirst)
933                     GetWLinePoint (wlin, paramline, U1,V1,U2,V2,ptsommet);
934                   else
935                     GetWLinePoint (wlin, paramline, U2,V2,U1,V1,ptsommet);
936                 }
937
938                 nbTreated++;
939                 if (!ivtx) {
940                   Sommet.SetValue(ptsommet,vtxTol,Standard_False); // pour tangence
941                   if (OnFirst)
942                     Sommet.SetParameters(U1,V1,U2,V2);
943                   else
944                     Sommet.SetParameters(U2,V2,U1,V1);
945
946                   if (VtxOnArc)
947                     Sommet.SetVertex(OnFirst,vtxarc);
948
949                   //---------------------------------------------------------
950                   //-- lbr : On remplace le point d indice paramline sur la -
951                   //-- ligne par le vertex .                                -
952                   //---------------------------------------------------------
953                   Sommet.SetParameter(paramline); // sur ligne d intersection
954                   Sommet.SetArc(OnFirst,arc,paramarc,transline,transarc);
955
956                   if (typL == IntPatch_Walking) {
957                     wlin->AddVertex(Sommet);
958                     Nbvtx++;
959                   }
960                   else {
961                     rlin->AddVertex(Sommet);
962                     Nbvtx++;
963                   }
964                 }
965                 else {
966                   // CAS DE FIGURE : en appelant s1 la surf sur laquelle on 
967                   //   connait les pts sur restriction, et s2 celle sur laquelle
968                   //   on les cherche. Le point trouve verifie necessairement
969                   //   IsOnDomS1 = True.
970                   //  Pas vtxS1, pas vtxS2 :
971                   //   on recupere le point et on applique SetArcOnS2 et
972                   //   eventuellement SetVertexOnS2. Si on a deja IsOnDomS2,
973                   //   on considere que le point est deja traite, mais ne devrait
974                   //   pas se produire.
975                   //  vtxS1, pas vtxS2     :
976                   //   si pas IsOnDomS2 : pour chaque occurrence, faire SetArcOnS2,
977                   //   et eventuellement SetVertexOnS2.
978                   //   si IsOnDomS2 : impossible, on doit avoir IsVtxOnS2.
979                   //  vtxS1,vtxS2          :
980                   //   on doit avoir VtxOnArc = True. On duplique chaque occurrence
981                   //   "sur S1" du point en changeant ArcOnS2.
982                   //  pas vtxS1, vtxS2     :
983                   //   on doit avoir VtxOnArc = True. On duplique le point sur S1
984                   //   en changeant ArcOnS2.
985                   Standard_Boolean OnDifferentRst =
986                     (OnFirst  && ptline.IsOnDomS1() && ptline.ArcOnS1() != arc ||
987                      !OnFirst && ptline.IsOnDomS2() && ptline.ArcOnS2() != arc);
988                   ptline.SetTolerance(vtxTol);
989                   if (   (!ptline.IsVertexOnS1() &&  OnFirst) 
990                       || (!ptline.IsVertexOnS2() && !OnFirst) 
991                       || (OnDifferentRst))  {
992                     if (  (!ptline.IsOnDomS2() && !OnFirst)
993                         ||(!ptline.IsOnDomS1() &&  OnFirst)
994                         ||(OnDifferentRst)) {
995                       ptline.SetArc(OnFirst,arc,paramarc,transline,transarc);
996                       //ptline.SetParameter(paramline); //-- rajout lbr le 20 nov 97
997                       if (VtxOnArc)
998                         ptline.SetVertex(OnFirst,vtxarc);
999                       if (typL == IntPatch_Walking) {
1000                         if(OnDifferentRst) { 
1001                           wlin->AddVertex(ptline); 
1002                           Nbvtx++;
1003                         }
1004                         else { 
1005                           wlin->Replace(ivtx,ptline);
1006                         }
1007                       }
1008                       else {
1009                         if(OnDifferentRst) { 
1010                           rlin->AddVertex(ptline);
1011                           Nbvtx++;
1012                         }
1013                         else {
1014                           rlin->Replace(ivtx,ptline);
1015                         }
1016                       }
1017                     }
1018                     else if (  ( OnFirst && ptline.IsVertexOnS2())
1019                              ||(!OnFirst && ptline.IsVertexOnS1())) {
1020                       Sommet = ptline;
1021                       Sommet.SetArc(OnFirst,arc,paramarc,transline,transarc);
1022                       if (VtxOnArc)
1023                         Sommet.SetVertex(OnFirst,vtxarc);
1024                       if (typL == IntPatch_Walking) {
1025                         wlin->AddVertex(Sommet);
1026                         Nbvtx++;
1027                       }
1028                       else {
1029                         rlin->AddVertex(Sommet);
1030                         Nbvtx++;
1031                       }
1032                     }
1033                     else {
1034                       //-- cout << "pb dans RstInt  Type 1 " << endl;
1035                     }
1036                   }
1037                   else {
1038                     Handle(Adaptor3d_HVertex) vtxref = (OnFirst)? (ptline.VertexOnS1()) : (ptline.VertexOnS2()) ;
1039                     if (  ( OnFirst && !ptline.IsOnDomS2())
1040                         ||(!OnFirst && !ptline.IsOnDomS1())) {
1041                       ptline.SetArc(OnFirst,arc,paramarc,transline,transarc);
1042                       if (VtxOnArc)
1043                         ptline.SetVertex(OnFirst,vtxarc);
1044                       if (typL == IntPatch_Walking) {
1045                         wlin->Replace(ivtx,ptline);
1046                       }
1047                       else {
1048                         rlin->Replace(ivtx,ptline);
1049                       }
1050
1051                       for (k=1; k<=Nbvtx; k++) if (k != ivtx) {
1052                         if (typL == IntPatch_Walking) {
1053                           ptline = wlin->Vertex(k);
1054                         }
1055                         else {
1056                           ptline = rlin->Vertex(k);
1057                         }
1058                         if (   ( OnFirst && ptline.IsVertexOnS1()) 
1059                             || (!OnFirst && ptline.IsVertexOnS2())) {
1060                           if (Domain->Identical(vtxref, (OnFirst)? (ptline.VertexOnS1()) : (ptline.VertexOnS2()))) { 
1061                             if (ptline.Tolerance() < vtxTol) ptline.SetTolerance(vtxTol);
1062                             ptline.SetArc(OnFirst,arc,paramarc,transline,transarc);
1063                             if (VtxOnArc)
1064                               ptline.SetVertex(OnFirst,vtxarc);
1065                             if (typL == IntPatch_Walking) {
1066                               wlin->Replace(k,ptline);
1067                             }
1068                             else {
1069                               rlin->Replace(k,ptline);
1070                             }
1071                           }
1072                         }
1073                       }
1074                     }
1075                     else if(   ( OnFirst && ptline.IsVertexOnS2()) 
1076                             || (!OnFirst && ptline.IsVertexOnS1())) {
1077                       //                on doit avoir vtxons2 = vtxarc... pas de verif...
1078                       Sommet = ptline;
1079                       Sommet.SetArc(OnFirst,arc,paramarc,transline,transarc);
1080                       if (typL == IntPatch_Walking) {
1081                         wlin->AddVertex(Sommet);
1082                         Nbvtx++;
1083                       }
1084                       else {
1085                         rlin->AddVertex(Sommet);
1086                         Nbvtx++;
1087                       }
1088                       for (k=1; k<=Nbvtx; k++) if (k != ivtx) {
1089                         if (typL == IntPatch_Walking) {
1090                           ptline = wlin->Vertex(k);
1091                         }
1092                         else {
1093                           ptline = rlin->Vertex(k);
1094                         }
1095                         if (  ( OnFirst && ptline.IsVertexOnS1())
1096                             ||(!OnFirst && ptline.IsVertexOnS2())) {
1097                           if (Domain->Identical(vtxref,(OnFirst)? (ptline.VertexOnS1()) : (ptline.VertexOnS2()))) { 
1098                             if (ptline.Tolerance() < vtxTol) ptline.SetTolerance(vtxTol);
1099                             Sommet = ptline;
1100                             Sommet.SetArc(OnFirst,arc,paramarc,transline,transarc);
1101                             if (typL == IntPatch_Walking) {
1102                               wlin->Replace(k,ptline);
1103                               wlin->AddVertex(Sommet);
1104                               Nbvtx++;                        
1105                             }
1106                             else {
1107                               rlin->Replace(k,ptline);
1108                               rlin->AddVertex(Sommet);
1109                               Nbvtx++;                        
1110                             }
1111                           }
1112                         }
1113                       }
1114
1115                     }
1116                     else {
1117                       //-- cout << "pb dans RstInt  Type 2 " << endl;
1118                     }
1119                   }
1120                 }
1121               }
1122             }
1123           }
1124           if (nbTreated == 2 && typL == IntPatch_Walking) {
1125             // We processed a tangent zone, and both ends have been treated.
1126             // So mark WLine as having arc
1127             if(OnFirst) wlin->SetArcOnS1(arc);
1128             else        wlin->SetArcOnS2(arc);
1129           }
1130         }
1131         
1132         IndiceOffsetPeriodic++;
1133       }
1134       while(SurfaceIsPeriodic && IndiceOffsetPeriodic<=2);
1135       
1136       IndiceOffsetBiPeriodic++;
1137     }
1138     while(SurfaceIsBiPeriodic && IndiceOffsetBiPeriodic<=2);
1139     Domain->Next(); 
1140   }
1141   
1142   //--------------------------------------------------------------------------------
1143   //-- On reprend la ligne et on recale les parametres des vertex.
1144   //-- 
1145   if (typL == IntPatch_Walking) {
1146     Standard_Real pu1,pv1,pu2,pv2;
1147     pu1=pv1=pu2=pv2=0.0;
1148     switch(TypeS1) { 
1149     case GeomAbs_Cylinder:
1150     case GeomAbs_Cone:
1151     case GeomAbs_Sphere:
1152       pu1=M_PI+M_PI;
1153       break;
1154     case GeomAbs_Torus:
1155       pu1=pv1=M_PI+M_PI;
1156       break;
1157     default:
1158       {
1159         if(   Surf1->IsUPeriodic())  {
1160           pu1=Surf1->UPeriod();
1161         }
1162         else if(Surf1->IsUClosed()) { 
1163           pu1=Surf1->LastUParameter() - Surf1->FirstUParameter();
1164           //cout<<" UClosed1 "<<pu1<<endl;
1165         }
1166         if(   Surf1->IsVPeriodic()) {
1167           pv1=Surf1->VPeriod();
1168         }
1169         else if(Surf1->IsVClosed()) { 
1170           pv1=Surf1->LastVParameter() - Surf1->FirstVParameter();
1171           //cout<<" VClosed1 "<<pv1<<endl;
1172         }
1173
1174         break;
1175       }      
1176     }
1177     
1178     switch(TypeS2) { 
1179     case GeomAbs_Cylinder:
1180     case GeomAbs_Cone:
1181     case GeomAbs_Sphere:
1182
1183       pu2=M_PI+M_PI;
1184       break;
1185     case GeomAbs_Torus:
1186       pu2=pv2=M_PI+M_PI;
1187       break;
1188     default:
1189       { 
1190         if(   Surf2->IsUPeriodic()) {  
1191           pu2=Surf2->UPeriod(); 
1192         }
1193         else if(Surf2->IsUClosed()) { 
1194           pu2=Surf2->LastUParameter() - Surf2->FirstUParameter();
1195           //cout<<" UClosed2 "<<pu2<<endl;
1196         }
1197
1198         if(   Surf2->IsVPeriodic())  {
1199           pv2=Surf2->VPeriod();
1200         }
1201         else if(Surf2->IsVClosed()) { 
1202           pv2=Surf2->LastVParameter() - Surf2->FirstVParameter();
1203           //cout<<" VClosed2 "<<pv2<<endl;
1204         }
1205
1206         break;
1207       }
1208     }
1209
1210 /*
1211     if(pu1==0) { 
1212       pu1=Surf1->LastUParameter() - Surf1->FirstUParameter();
1213       pu1+=pu1;
1214     }
1215     if(pu2==0) { 
1216       pu2=Surf2->LastUParameter() - Surf2->FirstUParameter();
1217       pu2+=pu2;
1218     }
1219     if(pv1==0) { 
1220       pv1=Surf1->LastVParameter() - Surf1->FirstVParameter();
1221       pv1+=pv1;
1222     }
1223     if(pv2==0) { 
1224       pv2=Surf2->LastVParameter() - Surf2->FirstVParameter();
1225       pv2+=pv2;
1226     } 
1227 */
1228
1229     wlin->SetPeriod(pu1,pv1,pu2,pv2);
1230     wlin->ComputeVertexParameters(Tol);
1231   }
1232   else {
1233 #ifdef DEB
1234     //if(rlin->NbVertex()==0) { 
1235     //  cout<<" \n *** IntPatch RstInt.gxx  : nbvtx = 0 sur rline *** \n"<<endl;
1236     //}
1237 #endif
1238     rlin->ComputeVertexParameters(Tol);
1239   }
1240 }