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