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