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