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