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