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