0025416: Wrong section curve
[occt.git] / src / IntPatch / IntPatch_WLine.cxx
1 // Created on: 1991-05-27
2 // Created by: Isabelle GRIGNON
3 // Copyright (c) 1991-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 #include <IntPatch_WLine.ixx>
18
19 #define DEBUG 0
20 #define DEBUGV 0
21
22 #include <IntSurf_PntOn2S.hxx>
23 #include <Precision.hxx>
24 #include <stdio.h>
25
26
27 IntPatch_WLine::IntPatch_WLine (const Handle(IntSurf_LineOn2S)& Line,
28                                 const Standard_Boolean Tang,
29                                 const IntSurf_TypeTrans Trans1,
30                                 const IntSurf_TypeTrans Trans2) :
31   IntPatch_PointLine(Tang,Trans1,Trans2),fipt(Standard_False),lapt(Standard_False),
32   hasArcOnS1(Standard_False),hasArcOnS2(Standard_False)
33 {
34   typ = IntPatch_Walking;
35   curv = Line;
36   Buv1.SetWhole();
37   Buv2.SetWhole();
38   Bxyz.SetWhole();
39   u1period=v1period=u2period=v2period=0.0;
40 }
41
42
43 IntPatch_WLine::IntPatch_WLine (const Handle(IntSurf_LineOn2S)& Line,
44                                 const Standard_Boolean Tang,
45                                 const IntSurf_Situation Situ1,
46                                 const IntSurf_Situation Situ2) :
47   IntPatch_PointLine(Tang,Situ1,Situ2),fipt(Standard_False),lapt(Standard_False),
48   hasArcOnS1(Standard_False),hasArcOnS2(Standard_False)
49 {
50   typ = IntPatch_Walking;
51   curv = Line;
52   Buv1.SetWhole();
53   Buv2.SetWhole();
54   Bxyz.SetWhole();
55   u1period=v1period=u2period=v2period=0.0;
56 }
57
58
59 IntPatch_WLine::IntPatch_WLine (const Handle(IntSurf_LineOn2S)& Line,
60                                 const Standard_Boolean Tang) :
61   IntPatch_PointLine(Tang),fipt(Standard_False),lapt(Standard_False),
62   hasArcOnS1(Standard_False),hasArcOnS2(Standard_False)
63 {
64   typ = IntPatch_Walking;
65   curv = Line;
66   Buv1.SetWhole();
67   Buv2.SetWhole();
68   Bxyz.SetWhole();
69   u1period=v1period=u2period=v2period=0.0;
70 }
71
72
73 void IntPatch_WLine::SetPoint(const Standard_Integer Index,
74                               const IntPatch_Point& thepoint)
75 {
76   curv->Value(Index,thepoint.PntOn2S());
77 }
78
79
80 Handle(IntSurf_LineOn2S) IntPatch_WLine::Curve() const
81
82   return(curv);
83 }
84
85 static void RecadreMemePeriode(Standard_Real& u1,Standard_Real& v1,
86                                Standard_Real& u2,Standard_Real& v2,
87                                const Standard_Real anu1,const Standard_Real anv1,
88                                const Standard_Real anu2,const Standard_Real anv2,
89                                const Standard_Real U1Period,const Standard_Real V1Period,
90                                const Standard_Real U2Period,const Standard_Real V2Period) { 
91   if(U1Period) { 
92     while(anu1-u1 > 0.8*U1Period) { u1+=U1Period; }
93     while(u1-anu1 > 0.8*U1Period) { u1-=U1Period; }
94   }
95   if(U2Period) { 
96     while(anu2-u2 > 0.8*U2Period) { u2+=U2Period; }
97     while(u2-anu2 > 0.8*U2Period) { u2-=U2Period; }
98   }
99   if(V1Period) { 
100     while(anv1-v1 > 0.8*V1Period) { v1+=V1Period; }
101     while(v1-anv1 > 0.8*V1Period) { v1-=V1Period; }
102   }
103   if(V2Period) { 
104     while(anv2-v2 > 0.8*V2Period) { v2+=V2Period; }
105     while(v2-anv2 > 0.8*V2Period) { v2-=V2Period; }
106   }
107
108 }
109
110 static void RecadreMemePeriode(IntSurf_PntOn2S& POn2S,const IntSurf_PntOn2S& RefPOn2S,
111                                const Standard_Real up1,
112                                const Standard_Real vp1,
113                                const Standard_Real up2,
114                                const Standard_Real vp2) { 
115   Standard_Real u1,v1,u2,v2,pu1,pv1,pu2,pv2;
116   POn2S.Parameters(u1,v1,u2,v2);
117   RefPOn2S.Parameters(pu1,pv1,pu2,pv2);
118   RecadreMemePeriode(u1,v1,u2,v2,pu1,pv1,pu2,pv2,up1,vp1,up2,vp2);
119   POn2S.SetValue(u1,v1,u2,v2);
120 }
121
122 static Standard_Boolean CompareVertexAndPoint(const gp_Pnt& V, const gp_Pnt& P, const Standard_Real& Tol) { 
123   return (V.Distance(P) <= Tol);
124 }
125
126 void IntPatch_WLine::SetPeriod(const Standard_Real pu1,
127                                const Standard_Real pv1,
128                                const Standard_Real pu2,
129                                const Standard_Real pv2) { 
130   u1period=pu1; v1period=pv1; u2period=pu2; v2period=pv2;
131 }
132 Standard_Real IntPatch_WLine::U1Period() const {    return(u1period); }
133 Standard_Real IntPatch_WLine::V1Period() const {    return(v1period); }
134 Standard_Real IntPatch_WLine::U2Period() const {    return(u2period); }
135 Standard_Real IntPatch_WLine::V2Period() const {    return(v2period); }
136
137
138 //------------------------------------------------------------------------
139 //--  En Entree : Une ligne de cheminement     +    Une Liste de Vetex
140 //--
141 //--   LineOn2S   :       1------2-------3-------4-----5---- ----nbp
142 //-- 
143 //--   Vertex     :   a     b c          d    e      f
144 //--
145 //--
146 //--  En Sortie 
147 //--
148 //--                  1--2-3-4--5--------6----7--8--9--10--------
149 //--
150 //--  avec   a de parametre 1 
151 //--         b              3
152 //--
153 //--   etc ...
154 //--
155 //--
156 //-- !!!!!!!!!!!!!!! On considere que deux vertex ne peuvent pas etre 
157 //-- !!!!!!!!!!!!!!!  a une distance inferieure a Tol
158 //------------------------------------------------------------------------
159 //--
160 //-- On Teste si la LineOn2S contient des points confondus. 
161 //-- Dans ce cas, on remove ces points.
162 //--
163 //------------------------------------------------------------------------
164
165 Standard_Boolean SameVtxRst(const IntPatch_Point& vtx1,const IntPatch_Point& vtx2) { 
166   if(vtx1.IsOnDomS1()) { 
167     if(vtx2.IsOnDomS1()) { 
168       if(vtx1.ArcOnS1() == vtx2.ArcOnS1()) { 
169         if(vtx1.ParameterOnArc1() == vtx2.ParameterOnArc1()) { 
170           
171         }
172         else { 
173           return(Standard_False);
174         }
175       }
176       else { 
177         return(Standard_False); 
178       }
179     }
180     else { 
181       return(Standard_False);
182     }
183   }
184   else { 
185     if(vtx2.IsOnDomS1()) { 
186       return(Standard_False);
187     }
188   }
189   if(vtx1.IsOnDomS2()) { 
190     if(vtx2.IsOnDomS2()) { 
191       if(vtx1.ArcOnS2() == vtx2.ArcOnS2()) { 
192         if(vtx1.ParameterOnArc2() == vtx2.ParameterOnArc2()) { 
193           
194         }
195         else { 
196           return(Standard_False);
197         }
198       }
199       else { 
200         return(Standard_False); 
201       }
202     }
203     else { 
204       return(Standard_False);
205     }
206   }
207   else {
208     if(vtx2.IsOnDomS2()) {
209       return(Standard_False);
210     }
211   }
212   return(Standard_True);
213 }
214
215
216 static Standard_Boolean CompareVerticesOnSurf(const IntPatch_Point& vtx1,
217                                               const IntPatch_Point& vtx2,
218                                               const Standard_Boolean onFirst)
219 {
220   Standard_Real u1,v1,u2,v2, tolU, tolV;
221   if (onFirst) {
222     vtx1.ParametersOnS1(u1,v1);
223     vtx2.ParametersOnS1(u2,v2);
224   }
225   else {
226     vtx1.ParametersOnS2(u1,v1);
227     vtx2.ParametersOnS2(u2,v2);
228   }
229   tolU = Precision::PConfusion();
230   tolV = Precision::PConfusion();
231   return (Abs(u1-u2) <= tolU && Abs(v1-v2) <= tolV);
232 }
233
234 inline Standard_Boolean CompareVerticesOnS1(const IntPatch_Point& vtx1, const IntPatch_Point& vtx2)
235 {return CompareVerticesOnSurf (vtx1, vtx2, Standard_True);}
236
237 inline Standard_Boolean CompareVerticesOnS2(const IntPatch_Point& vtx1, const IntPatch_Point& vtx2)
238 {return CompareVerticesOnSurf (vtx1, vtx2, Standard_False);}
239
240
241 void IntPatch_WLine::ComputeVertexParameters( const Standard_Real RTol,
242                                               const Standard_Boolean hasBeenAdded)
243 {
244   // MSV Oct 15, 2001: use tolerance of vertex instead of RTol where 
245   //                   it is possible
246
247   Standard_Integer i,j,k,nbvtx,nbponline;
248   Standard_Integer indicevertexonline;
249   Standard_Real    indicevertex;
250
251   Standard_Boolean APointDeleted = Standard_False;
252   //----------------------------------------------------------
253   //--     F i l t r e   s u r   r e s t r i c t i o n s   --
254   //----------------------------------------------------------
255   //-- deux vertex sur la meme restriction et seulement 
256   //-- sur celle ci ne doivent pas avoir le meme parametre
257   //--
258   Standard_Real Tol=RTol;
259   nbvtx = NbVertex();
260
261 #if DEBUGV  
262   cout<<"\n----------- avant ComputeVertexParameters -------------"<<endl;
263   for(i=1;i<=nbvtx;i++) { 
264     Vertex(i).Dump();
265     Standard_Real  polr = Vertex(i).ParameterOnLine();
266     Standard_Real pol = (Standard_Integer)polr;
267     if(pol>=1 && pol<=nbvtx) { 
268       cout<<"----> IntSurf_PntOn2S : "<<polr<<"  Pnt ("<<Vertex(pol).Value().X()
269         <<","<<Vertex(pol).Value().Y()
270           <<","<<Vertex(pol).Value().Z()<<")"<<endl;
271     }
272   }
273   cout<<"\n----------------------------------------------------------"<<endl;
274 #endif  
275
276   
277   //-- ----------------------------------------------------------------------
278   //-- Traitement des aretes de couture : On duplique les points situes
279   //-- sur des restrictions differentes
280   //-- 
281   //-- Phase Creation de nouveaux points sur S1 
282   Standard_Boolean encoreunefois;
283   do { 
284     nbvtx=NbVertex();
285     encoreunefois=Standard_False;
286     for(i=1; i<=nbvtx && encoreunefois==Standard_False; i++) { 
287       IntPatch_Point& VTXi   = svtx.ChangeValue(i);
288       for(j=1; j<=nbvtx && encoreunefois==Standard_False; j++) { 
289         if(i!=j) { 
290           IntPatch_Point& VTXj   = svtx.ChangeValue(j);
291           if(VTXi.ParameterOnLine() != VTXj.ParameterOnLine()) { 
292             Standard_Real d = VTXi.Value().Distance(VTXj.Value());
293             Standard_Real toli = VTXi.Tolerance();
294             Standard_Real tolj = VTXj.Tolerance();
295             Standard_Real maxtol = Max(toli,tolj);
296             // MSV Oct 30, 2001: compare in 2D space also;
297             //                   increase tolerances
298             if (d < maxtol ||
299                CompareVerticesOnS1(VTXi,VTXj) || CompareVerticesOnS2(VTXi,VTXj)) { 
300               //-- Creation Vtx (REF:S1(i)  S2(j))    (On Garde S1(i))
301               Standard_Real newtoli = Max (toli, tolj+d*1.01);
302               Standard_Real newtolj = Max (tolj, toli+d*1.01);
303               Standard_Boolean acreer=Standard_False;
304               if(VTXi.IsOnDomS1()) { 
305                 if(VTXj.IsOnDomS1()) { 
306                   if(VTXj.ArcOnS1() != VTXi.ArcOnS1()) { 
307                     acreer=Standard_True;
308                   }
309                 }
310                 else { 
311                   acreer=Standard_True;
312                 }
313               }
314               if(acreer) { 
315                 IntPatch_Point vtx;
316                 vtx = VTXj;
317                 vtx.SetArc(Standard_True,
318                            VTXi.ArcOnS1(),
319                            VTXi.ParameterOnArc1(),
320                            VTXi.TransitionLineArc1(),
321                            VTXi.TransitionOnS1());
322                 for(k=1; encoreunefois==Standard_False && k<=nbvtx; k++) { 
323                   const IntPatch_Point& VTXk   = svtx.Value(k);
324                   if(SameVtxRst(VTXk,vtx)) { 
325                     encoreunefois=Standard_True;
326                   }
327                 }
328                 if(encoreunefois==Standard_False) {
329                   VTXi.SetTolerance(newtoli);
330                   VTXj.SetTolerance(newtolj);
331                   vtx.SetTolerance(newtolj);
332                   svtx.Append(vtx);
333                   encoreunefois=Standard_True;
334                 }
335                 else { 
336                   encoreunefois=Standard_False;
337                 }
338               }
339               //-- -----------------------------------------------------
340               //-- Creation Vtx (REF:S2(i)  S1(j))    (On Garde S2(i))
341               acreer=Standard_False;
342               if(VTXi.IsOnDomS2()) { 
343                 if(VTXj.IsOnDomS2()) { 
344                   if(VTXj.ArcOnS2() != VTXi.ArcOnS2()) { 
345                     acreer=Standard_True;
346                   }
347                 }
348                 else { 
349                   acreer=Standard_True;
350                 }
351               }
352               if(acreer) { 
353                 IntPatch_Point vtx;
354                 vtx = VTXj;
355                 vtx.SetArc(Standard_False,
356                            VTXi.ArcOnS2(),
357                            VTXi.ParameterOnArc2(),
358                            VTXi.TransitionLineArc2(),
359                            VTXi.TransitionOnS2());
360                 for(k=1; encoreunefois==Standard_False && k<=nbvtx; k++) { 
361                   const IntPatch_Point& VTXk   = svtx.Value(k);
362                   if(SameVtxRst(VTXk,vtx)) { 
363                     encoreunefois=Standard_True;
364                   }
365                 }
366                 if(encoreunefois==Standard_False) {
367                   VTXi.SetTolerance(newtoli);
368                   VTXj.SetTolerance(newtolj);
369                   vtx.SetTolerance(newtolj);
370                   svtx.Append(vtx);
371                   encoreunefois=Standard_True;
372                 }
373                 else { 
374                   encoreunefois=Standard_False;
375                 }
376               }     
377             }
378           }
379         }
380       }
381     }
382   }
383   while(encoreunefois);
384   
385   
386
387   //-- ----------------------------------------------------------------------
388
389
390
391   do { 
392     APointDeleted = Standard_False;
393     for(i=1; (i<=nbvtx) && (APointDeleted==Standard_False) ;i++) { 
394       const IntPatch_Point& VTXi   = svtx.Value(i);
395       if(VTXi.Tolerance() > Tol)        Tol = VTXi.Tolerance(); //-- 9 oct 97 
396       if((VTXi.IsOnDomS1()==Standard_True) && (VTXi.IsOnDomS2()==Standard_False)) { 
397         for(j=1; (j<=nbvtx) && (APointDeleted==Standard_False) ;j++) {
398           if(i!=j) { 
399             const IntPatch_Point& VTXj   = svtx.Value(j);
400             if((VTXj.IsOnDomS1()==Standard_True) && (VTXj.IsOnDomS2()==Standard_False)) {
401               if(VTXi.ParameterOnLine() == VTXj.ParameterOnLine()) { 
402                 if(VTXi.ArcOnS1() == VTXj.ArcOnS1()) { 
403                   svtx.Remove(j);
404                   nbvtx--;
405                   if(lapt) { if(indl>=j) indl--; } 
406                   if(fipt) { if(indf>=j) indf--; } 
407                   APointDeleted = Standard_True;
408                 }
409               }
410             }
411           }
412         }
413       }
414     }
415   }
416   while(APointDeleted == Standard_True);
417
418
419   do { 
420     APointDeleted = Standard_False;
421     for(i=1; (i<=nbvtx) && (APointDeleted==Standard_False) ;i++) { 
422       const IntPatch_Point& VTXi   = svtx.Value(i);
423       if((VTXi.IsOnDomS2()==Standard_True) && (VTXi.IsOnDomS1()==Standard_False)) { 
424         for(j=1; (j<=nbvtx) && (APointDeleted==Standard_False) ;j++) {
425           if(i!=j) { 
426             const IntPatch_Point& VTXj   = svtx.Value(j);
427             if((VTXj.IsOnDomS2()==Standard_True) && (VTXj.IsOnDomS1()==Standard_False)) {
428               if(VTXi.ParameterOnLine() == VTXj.ParameterOnLine()) { 
429                 if(VTXi.ArcOnS2() == VTXj.ArcOnS2()) { 
430                   svtx.Remove(j);
431                   nbvtx--;
432                   if(lapt) { if(indl>=j) indl--; } 
433                   if(fipt) { if(indf>=j) indf--; } 
434                   APointDeleted = Standard_True;
435                 }
436               }
437             }
438           }
439         }
440       }
441     }
442   }
443   while(APointDeleted == Standard_True);
444         
445   nbvtx     = NbVertex();
446   nbponline = NbPnts();
447
448   //----------------------------------------------------
449   //-- On trie les Vertex 
450   Standard_Boolean SortIsOK;
451   do { 
452     SortIsOK = Standard_True;
453     for(i=2; i<=nbvtx; i++) { 
454       if(svtx.Value(i-1).ParameterOnLine()  > svtx.Value(i).ParameterOnLine()) { 
455         SortIsOK = Standard_False;
456         svtx.Exchange(i-1,i);
457       }
458     }
459   }
460   while(!SortIsOK);
461   
462   //----------------------------------------------------
463   //-- On detecte les points confondus dans la LineOn2S
464   Standard_Real dmini = Precision::Confusion();
465   dmini*=dmini;
466   for(i=2; i<=nbponline; i++) { 
467     const IntSurf_PntOn2S& aPnt1=curv->Value(i-1);
468     const IntSurf_PntOn2S& aPnt2=curv->Value(i);
469     Standard_Real d = (aPnt1.Value()).SquareDistance((aPnt2.Value()));
470     if(d < dmini) { 
471       curv->RemovePoint(i);
472       nbponline--;
473       //----------------------------------------------
474       //-- On recadre les Vertex si besoin 
475       //-- 
476       for(j=1; j<=nbvtx; j++) { 
477         indicevertex = svtx.Value(j).ParameterOnLine();
478         if(indicevertex >= i) {
479           svtx.ChangeValue(j).SetParameter(indicevertex-1.0);
480         }
481       }
482       //modified by NIZNHY-PKV Mon Feb 11 09:28:02 2002 f
483       i--;
484       //modified by NIZNHY-PKV Mon Feb 11 09:28:04 2002 t
485     }
486   }
487   //----------------------------------------------------
488   for(i=1; i<=nbvtx; i++) {
489     const gp_Pnt& P    = svtx.Value(i).Value();
490     Standard_Real vTol = svtx.Value(i).Tolerance();
491     
492     if(hasBeenAdded)
493     {
494       if(nbvtx == 2)
495       {
496         if(i == nbvtx)
497         {
498           indicevertex = curv->NbPoints();
499         }
500         else
501         {
502           indicevertex = svtx.Value(i).ParameterOnLine();
503         }
504       }
505       else
506       {
507         indicevertex = svtx.Value(i).ParameterOnLine();
508       }
509     }
510     else
511     {
512       indicevertex = svtx.Value(i).ParameterOnLine();
513     }
514     
515     indicevertexonline = (Standard_Integer)indicevertex;
516     //--------------------------------------------------
517     //-- On Compare le vertex avec les points de la ligne
518     //-- d indice   indicevertexOnLine-1
519     //--            indicevertexOnLine
520     //--            indicevertexOnLine+1
521     //--------------------------------------------------
522     if(indicevertexonline<1) { 
523       if(CompareVertexAndPoint(P,curv->Value(1).Value(),vTol)) {
524         //-------------------------------------------------------
525         //-- On remplace le point cheminement(1) par vertex(i)
526         //-- et   vertex(i) prend pour parametre 1
527         //-------------------------------------------------------
528         
529         IntSurf_PntOn2S POn2S = svtx.Value(i).PntOn2S();
530         RecadreMemePeriode(POn2S,curv->Value(1),U1Period(),V1Period(),U2Period(),V2Period());
531         curv->Value(1,POn2S);
532
533         //--curv->Value(1,svtx.Value(i).PntOn2S());
534         svtx.ChangeValue(i).SetParameter(1.0);
535       }
536       else { 
537         //-------------------------------------------------------
538         //-- On insere le point de cheminement Vertex(i)
539         //-- On recadre les parametres des autres vertex
540         //-------------------------------------------------------
541         IntSurf_PntOn2S POn2S = svtx.Value(i).PntOn2S();
542         RecadreMemePeriode(POn2S,curv->Value(1),U1Period(),V1Period(),U2Period(),V2Period());
543         curv->InsertBefore(1,POn2S);
544
545         //-- curv->InsertBefore(1,svtx.Value(i).PntOn2S());
546         svtx.ChangeValue(i).SetParameter(1.0);
547         nbponline++;
548         for(j=1;j<=nbvtx;j++) {
549           if(j!=1) { 
550             Standard_Real t = svtx.Value(j).ParameterOnLine();
551             if(t>1.0) { 
552               svtx.ChangeValue(j).SetParameter(t+1.0);
553             }
554           }
555         }
556       }
557     } //--- fin : if(indicevertexonline<1) 
558     else { 
559       //---------------------------------------------------------
560       //-- vertex(i)   ==   cheminement (indicevertexonline-1)
561       //-- vertex(i)   ==   cheminement (indicevertexonline)
562       //-- vertex(i)   ==   cheminement (indicevertexonline+1)
563       //---------------------------------------------------------
564       Standard_Boolean Substitution = Standard_False;
565       //-- for(k=indicevertexonline+1; !Substitution && k>=indicevertexonline-1;k--) {   avant le 9 oct 97 
566       for(k=indicevertexonline+1; k>=indicevertexonline-1;k--) { 
567         if(k>0 && k<=nbponline) { 
568           if(CompareVertexAndPoint(P,curv->Value(k).Value(),vTol)) {
569             //-------------------------------------------------------
570             //-- On remplace le point cheminement(k) 
571             //-- par vertex(i)  et vertex(i) prend pour parametre k
572             //-------------------------------------------------------
573             IntSurf_PntOn2S POn2S = svtx.Value(i).PntOn2S();
574             RecadreMemePeriode(POn2S,curv->Value(k),U1Period(),V1Period(),U2Period(),V2Period());
575             curv->Value(k,POn2S);
576             Standard_Real mu1,mv1,mu2,mv2;
577             POn2S.Parameters(mu1,mv1,mu2,mv2);
578             svtx.ChangeValue(i).SetParameter(k);
579             svtx.ChangeValue(i).SetParameters(mu1,mv1,mu2,mv2);
580             Substitution = Standard_True;
581           }
582         }
583       }
584
585       //Remove duplicating points
586       if (Substitution)
587       {
588         Standard_Integer ind_point;
589         for(ind_point = 2; (ind_point <= nbponline && nbponline > 2); ind_point++) { 
590           Standard_Real d = (curv->Value(ind_point-1).Value()).SquareDistance((curv->Value(ind_point).Value()));
591           if(d < dmini) { 
592             curv->RemovePoint(ind_point);
593             nbponline--;
594             //----------------------------------------------
595             //-- On recadre les Vertex si besoin 
596             //-- 
597             for(j=1; j<=nbvtx; j++) { 
598               indicevertex = svtx.Value(j).ParameterOnLine();
599               if(indicevertex >= ind_point) {
600                 svtx.ChangeValue(j).SetParameter(indicevertex-1.0);
601               }
602             }
603             //modified by NIZNHY-PKV Mon Feb 11 09:28:02 2002 f
604             ind_point--;
605             //modified by NIZNHY-PKV Mon Feb 11 09:28:04 2002 t
606           }
607         }
608       }
609       
610       //--static int deb6nov98=1;    Ne resout rien (a part partiellement BUC60409)
611       //--if(deb6nov98) { 
612       //--Substitution=Standard_True;
613       //-- }
614       
615       if(Substitution==Standard_False) { 
616         //-------------------------------------------------------
617         //-- On insere le point de cheminement Vertex(i)
618         //-- On recadre les parametres des autres vertex
619         //-------------------------------------------------------
620         IntSurf_PntOn2S POn2S = svtx.Value(i).PntOn2S();
621         if(indicevertexonline >= nbponline) { 
622           RecadreMemePeriode(POn2S,curv->Value(nbponline),U1Period(),V1Period(),U2Period(),V2Period());
623           curv->Add(POn2S);
624         }
625         else { 
626           RecadreMemePeriode(POn2S,curv->Value(indicevertexonline+1),U1Period(),V1Period(),U2Period(),V2Period());
627           curv->InsertBefore(indicevertexonline+1,POn2S);
628         }
629         //-- curv->InsertBefore(indicevertexonline+1,svtx.Value(i).PntOn2S());
630         svtx.ChangeValue(i).SetParameter(indicevertexonline+1);
631         nbponline++;
632         for(j=1;j<=nbvtx;j++) { 
633           if(j!=i) { 
634             Standard_Real t = svtx.Value(j).ParameterOnLine();
635             if(t>(Standard_Real)indicevertexonline) { 
636               svtx.ChangeValue(j).SetParameter(t+1.0);
637             }
638           }
639         }
640       } //-- Substitution
641     } //-- indicevertexonline>=1
642
643   } //-- boucle i sur vertex
644
645   
646   
647   
648   do {  
649     APointDeleted = Standard_False;
650     for(i=1; i<=nbvtx && (APointDeleted == Standard_False); i++) { 
651       const IntPatch_Point& VTX   = svtx.Value(i);      
652       for(j=1; j<=nbvtx && (APointDeleted == Standard_False) ; j++) { 
653         if(i!=j) { 
654           const IntPatch_Point& VTXM1 = svtx.Value(j);
655           
656           Standard_Boolean kill   = Standard_False;
657           Standard_Boolean killm1 = Standard_False;
658           if(VTXM1.ParameterOnLine() == VTX.ParameterOnLine()) { 
659             if(VTXM1.IsOnDomS1() && VTX.IsOnDomS1()) {  //-- OnS1    OnS1
660               if(VTXM1.ArcOnS1() == VTX.ArcOnS1()) {    //-- OnS1 == OnS1
661                 if(VTXM1.IsOnDomS2()) {                 //-- OnS1 == OnS1  OnS2  
662                   if(VTX.IsOnDomS2()==Standard_False) {   //-- OnS1 == OnS1  OnS2 PasOnS2
663                     kill=Standard_True;   
664                   }
665                   else {
666                     if(VTXM1.ArcOnS2() == VTX.ArcOnS2()) { //-- OnS1 == OnS1  OnS2 == OnS2
667                       kill=Standard_True;
668                     }
669                   }
670                 }
671                 else {                                  //-- OnS1 == OnS1  PasOnS2  
672                   if(VTX.IsOnDomS2()) {                 //-- OnS1 == OnS1  PasOnS2  OnS2
673                     killm1=Standard_True;
674                   }
675                 }
676               }
677             }
678             
679             if(!(kill || killm1)) {
680               if(VTXM1.IsOnDomS2() && VTX.IsOnDomS2()) {  //-- OnS2    OnS2
681                 if(VTXM1.ArcOnS2() == VTX.ArcOnS2()) {    //-- OnS2 == OnS2
682                   if(VTXM1.IsOnDomS1()) {                 //-- OnS2 == OnS2  OnS1  
683                     if(VTX.IsOnDomS1()==Standard_False) {   //-- OnS2 == OnS2  OnS1 PasOnS1
684                       kill=Standard_True;   
685                     }
686                     else {
687                       if(VTXM1.ArcOnS1() == VTX.ArcOnS1()) { //-- OnS2 == OnS2  OnS1 == OnS1
688                         kill=Standard_True;
689                       }
690                     }
691                   }
692                   else {                                  //-- OnS2 == OnS2  PasOnS1  
693                     if(VTX.IsOnDomS1()) {                 //-- OnS2 == OnS2  PasOnS1  OnS1
694                       killm1=Standard_True;
695                     }
696                   }
697                 }
698               }
699             }
700             if(kill) { 
701               APointDeleted = Standard_True;
702               svtx.Remove(i);
703               nbvtx--;
704             }
705             else if(killm1) { 
706               APointDeleted = Standard_True;
707               svtx.Remove(j);
708               nbvtx--; 
709             }
710           }
711         }
712       }
713     }
714   }
715   while(APointDeleted == Standard_True);
716   
717   do {  
718     SortIsOK = Standard_True;
719     for(i=2; i<=nbvtx && SortIsOK; i++) {
720       const IntPatch_Point& Pim1=svtx.Value(i-1);
721       const IntPatch_Point& Pii  =svtx.Value(i);
722       if(Pim1.ParameterOnLine()==Pii.ParameterOnLine()) { 
723         if(   (Pii.IsOnDomS1() == Standard_False)
724            && (Pii.IsOnDomS2() == Standard_False)) { 
725           SortIsOK = Standard_False;
726           svtx.Remove(i);
727           nbvtx--;
728         }
729         else {
730           if(   (Pim1.IsOnDomS1() == Standard_False)
731              && (Pim1.IsOnDomS2() == Standard_False)) { 
732             SortIsOK = Standard_False;
733             svtx.Remove(i-1);
734             nbvtx--;
735           }       
736         }
737       }
738     }
739   }
740   while(!SortIsOK);
741   //-- ----------------------------------------------------------------------------
742   //-- On ajoute les vertex de debut et de fin de ligne s il ne sont pas presents.
743   //-- 
744   //-- Existe t il un vertex de debut de ligne, de fin .
745   //--
746   //-- Si Besoin : il faudra dedoubler les points de debut et de fin sur les periodiques ??????
747
748
749
750   
751   Standard_Boolean bFirst = Standard_False;
752   Standard_Boolean bLast  = Standard_False;
753   nbponline = NbPnts();
754   for(i=1;i<=nbvtx;i++) { 
755     Standard_Real pol = svtx.Value(i).ParameterOnLine();
756     if(pol==1.0)       {
757       bFirst = fipt = Standard_True;
758       indf   = i;
759     }
760     if(pol==nbponline) {
761       bLast = lapt = Standard_True;
762       indl  = i;
763     }
764   }
765   if(bFirst == Standard_False) { 
766     Standard_Real pu1,pv1,pu2,pv2;
767     Standard_Boolean vtxfound = Standard_False;
768     IntPatch_Point vtx;
769     curv->Value(1).Parameters(pu1,pv1,pu2,pv2);
770     for(i=1;
771         (vtxfound==Standard_False) && (i<=nbvtx);i++) { 
772       const IntPatch_Point&  V = svtx.Value(i);
773       //jgv: to avoid loops
774       //Standard_Real vTol = V.Tolerance();
775       if(CompareVertexAndPoint(V.Value(), curv->Value(1).Value(), Precision::Confusion()/*vTol*/)) { 
776         vtx = V;
777         vtx.SetParameters(pu1,pv1,pu2,pv2);
778         vtxfound = Standard_True;
779       }
780     }
781     if(vtxfound == Standard_False)  { 
782       vtx.SetValue(curv->Value(1).Value(),Tol,Standard_False);
783       vtx.SetParameters(pu1,pv1,pu2,pv2);
784     }
785     vtx.SetParameter(1);
786     svtx.Prepend(vtx);    nbvtx++;
787     fipt = Standard_True;
788     indf = 1;
789   }
790   if(bLast == Standard_False) { 
791     Standard_Real pu1,pv1,pu2,pv2;
792     Standard_Boolean vtxfound = Standard_False;    
793     IntPatch_Point vtx;
794     curv->Value(nbponline).Parameters(pu1,pv1,pu2,pv2);   
795     for(i=1;
796         (vtxfound==Standard_False) && (i<=nbvtx);i++) { 
797       const IntPatch_Point&  V = svtx.Value(i);
798       //jgv: to avoid loops
799       //Standard_Real vTol = V.Tolerance();
800       if(CompareVertexAndPoint(V.Value(), curv->Value(nbponline).Value(), Precision::Confusion()/*vTol*/)) { 
801         vtx = V;
802         vtx.SetParameters(pu1,pv1,pu2,pv2);
803         vtxfound = Standard_True;
804       }
805     }
806     if(vtxfound == Standard_False)  {     
807       vtx.SetValue(curv->Value(nbponline).Value(),Tol,Standard_False);
808       vtx.SetParameters(pu1,pv1,pu2,pv2);
809     }
810     vtx.SetParameter(nbponline);
811     svtx.Append(vtx); nbvtx++;
812     lapt = Standard_True;
813     indl = nbvtx; 
814   }
815   
816
817
818
819   //--------------------------------------------------------------
820   //-- ** Detection de points trouves sur une meme restriction 
821   //--    avec la meme transition et avec des params on line 
822   //--    voisins.   
823   //-- ** Dans ce cas (-> donnerait un baillemenmt) on supprime 
824   //--    le point 'intermediaire'. 
825   //-- ** (exemple Vtx(1)  .....  Vtx(204) Vtx(205))
826   //--    on supprime le Vtx(204)
827   //-- ** (exemple Vtx(1) Vtx(2)  .....  Vtx(205))
828   //--    on supprime le Vtx(2)
829   //-- ** (exemple Vtx(1)  ...  Vtx(100) Vtx(101) ... Vtx(205))
830   //--    on supprime le Vtx(100)  (Vtx(100)et101 sur m restr)
831
832   //--------------------------------------------------------------
833   nbvtx = NbVertex();
834   do { 
835     APointDeleted = Standard_False;
836     for(i=1; (i<=nbvtx) && (APointDeleted==Standard_False) ;i++) { 
837       const IntPatch_Point& VTXi   = svtx.Value(i);
838       if((VTXi.IsOnDomS1()==Standard_True) && (VTXi.IsOnDomS2()==Standard_False)) { 
839         for(j=1; (j<=nbvtx) && (APointDeleted==Standard_False) ;j++) {
840           if(i!=j) { 
841             const IntPatch_Point& VTXj   = svtx.Value(j);
842             if((VTXj.IsOnDomS1()==Standard_True) && (VTXj.IsOnDomS2()==Standard_False)) {
843               if(   (VTXi.ParameterOnLine() == VTXj.ParameterOnLine()+1)
844                  || (VTXi.ParameterOnLine() == VTXj.ParameterOnLine()-1)) { 
845                 if(VTXi.ArcOnS1() == VTXj.ArcOnS1()) { 
846                   IntSurf_Transition t1 = VTXi.TransitionLineArc1();
847                   IntSurf_Transition t2 = VTXj.TransitionLineArc1();
848                   if(t1.TransitionType()==t2.TransitionType()) { 
849                     if((VTXj.ParameterOnLine()!=1) && (VTXj.ParameterOnLine()!=NbPnts())) {   
850                       svtx.Remove(j);
851                       nbvtx--;
852                       if(lapt) { if(indl>=j) indl--; } 
853                       if(fipt) { if(indf>=j) indf--; } 
854                       APointDeleted = Standard_True;
855                     }
856                   }
857                 }
858               }
859             }
860           }
861         }
862       }
863     }
864   }
865   
866   //-- meme traitement sur les restrictions du second shape
867
868   while(APointDeleted == Standard_True);
869   nbvtx = NbVertex();
870   do { 
871     APointDeleted = Standard_False;
872     for(i=1; (i<=nbvtx) && (APointDeleted==Standard_False) ;i++) { 
873       const IntPatch_Point& VTXi   = svtx.Value(i);
874       if((VTXi.IsOnDomS1()==Standard_False) && (VTXi.IsOnDomS2()==Standard_True)) { 
875         for(j=1; (j<=nbvtx) && (APointDeleted==Standard_False) ;j++) {
876           if(i!=j) { 
877             const IntPatch_Point& VTXj   = svtx.Value(j);
878             if((VTXj.IsOnDomS1()==Standard_False) && (VTXj.IsOnDomS2()==Standard_True)) {
879               if(   (VTXi.ParameterOnLine() == VTXj.ParameterOnLine()+1)
880                  || (VTXi.ParameterOnLine() == VTXj.ParameterOnLine()-1)) { 
881                 if(VTXi.ArcOnS2() == VTXj.ArcOnS2()) { 
882                   IntSurf_Transition t1 = VTXi.TransitionLineArc2();
883                   IntSurf_Transition t2 = VTXj.TransitionLineArc2();
884                   if(t1.TransitionType()==t2.TransitionType()) { 
885                     if((VTXj.ParameterOnLine()!=1) && (VTXj.ParameterOnLine()!=NbPnts())) {   
886                       svtx.Remove(j);
887                       nbvtx--;
888                       if(lapt) { if(indl>=j) indl--; } 
889                       if(fipt) { if(indf>=j) indf--; } 
890                       APointDeleted = Standard_True;
891                     }
892                   }
893                 }
894               }
895             }
896           }
897         }
898       }
899     }
900   }
901   while(APointDeleted == Standard_True);
902   //--------------------------------------------------------------
903
904   //--------------------------------------------------------------
905   //-- dans le cas de lignes periodiques du type : 
906   //--    Un point sur restriction R1 de param p1  -> P3d1   Vtx1
907   //--    Un point sur restriction R2 de param p2  -> P3d1   Vtx2
908   //--    
909   //--    Un point sur restriction R1 de param p1  -> P3d1   Vtx3
910   //--    pas de point sur R2 
911   //--
912   //-- On doit dans ce cas creer un nouveau Vtx4 = Vtx3 sur la 
913   //-- restriction R2
914   //--
915   //-- Ce cas se produit qd on a corrige un baillement avec le filtre
916   //-- precedent
917   //-- 
918   
919
920
921
922   
923
924   nbvtx = NbVertex();
925   do { 
926     SortIsOK = Standard_True;
927     for(i=2; i<=nbvtx; i++) { 
928       if(svtx.Value(i-1).ParameterOnLine()  > svtx.Value(i).ParameterOnLine()) { 
929         SortIsOK = Standard_False;
930         svtx.Exchange(i-1,i);
931       }
932     }
933   }
934   while(!SortIsOK);
935   
936   //-- Dump();
937
938 #if DEBUGV  
939   cout<<"\n----------- apres ComputeVertexParameters -------------"<<endl;
940   for(i=1;i<=nbvtx;i++) { 
941     Vertex(i).Dump();
942     Standard_Real  polr = Vertex(i).ParameterOnLine();
943     Standard_Real pol = (Standard_Integer)polr;
944     if(pol>=1 && pol<=nbvtx) { 
945       cout<<"----> IntSurf_PntOn2S : "<<polr<<"  Pnt ("<<Vertex(pol).Value().X()
946         <<","<<Vertex(pol).Value().Y()
947           <<","<<Vertex(pol).Value().Z()<<")"<<endl;
948     }
949   }
950   cout<<"\n----------------------------------------------------------"<<endl;
951 #endif  
952
953
954 }
955
956
957
958 Standard_Boolean IntPatch_WLine::IsOutSurf1Box(const gp_Pnt2d& P1uv)  { 
959   if(Buv1.IsWhole()) {
960     Standard_Integer n=NbPnts();
961     Standard_Real pu1,pu2,pv1,pv2;
962     Buv1.SetVoid();
963     for(Standard_Integer i=1;i<=n;i++) { 
964       curv->Value(i).Parameters(pu1,pv1,pu2,pv2);
965       Buv1.Add(gp_Pnt2d(pu1,pv1));
966     }
967     Buv1.Get(pu1,pv1,pu2,pv2);
968     pu2-=pu1;
969     pv2-=pv1;
970     if(pu2>pv2) { 
971       Buv1.Enlarge(pu2*0.01);
972     }
973     else { 
974       Buv1.Enlarge(pv2*0.01);
975     }
976   }
977   Standard_Boolean out=Buv1.IsOut(P1uv);
978   return(out);
979 }
980
981 Standard_Boolean IntPatch_WLine::IsOutSurf2Box(const gp_Pnt2d& P2uv)  { 
982   if(Buv2.IsWhole()) { 
983     Standard_Integer n=NbPnts();
984     Standard_Real pu1,pu2,pv1,pv2;
985     Buv2.SetVoid();
986     for(Standard_Integer i=1;i<=n;i++) { 
987       curv->Value(i).Parameters(pu1,pv1,pu2,pv2);
988       Buv2.Add(gp_Pnt2d(pu2,pv2));
989     }
990     Buv2.Get(pu1,pv1,pu2,pv2);
991     pu2-=pu1;
992     pv2-=pv1;
993     if(pu2>pv2) { 
994       Buv2.Enlarge(pu2*0.01);
995     }
996     else { 
997       Buv2.Enlarge(pv2*0.01);
998     }    
999   }
1000   Standard_Boolean out=Buv2.IsOut(P2uv);
1001   return(out);
1002 }
1003
1004 Standard_Boolean IntPatch_WLine::IsOutBox(const gp_Pnt& Pxyz)  { 
1005   if(Bxyz.IsWhole()) { 
1006     Standard_Integer n=NbPnts();
1007     Bxyz.SetVoid();
1008     for(Standard_Integer i=1;i<=n;i++) { 
1009       gp_Pnt P=curv->Value(i).Value();
1010       Bxyz.Add(P);
1011     }
1012     Standard_Real x0,y0,z0,x1,y1,z1;
1013     Bxyz.Get(x0,y0,z0,x1,y1,z1);
1014     x1-=x0; y1-=y0; z1-=z0;
1015     if(x1>y1) {
1016       if(x1>z1) {
1017         Bxyz.Enlarge(x1*0.01);
1018       }
1019       else { 
1020         Bxyz.Enlarge(z1*0.01);
1021       }
1022     }
1023     else { 
1024       if(y1>z1) { 
1025         Bxyz.Enlarge(y1*0.01);
1026       }
1027       else { 
1028         Bxyz.Enlarge(z1*0.01);
1029       }
1030     }
1031   }
1032   Standard_Boolean out=Bxyz.IsOut(Pxyz);
1033   return(out);
1034 }
1035
1036
1037 Standard_Boolean IntPatch_WLine::HasArcOnS1() const  {
1038   return(hasArcOnS1);
1039 }
1040
1041 void IntPatch_WLine::SetArcOnS1(const Handle(Adaptor2d_HCurve2d)& A) { 
1042   hasArcOnS1=Standard_True;
1043   theArcOnS1=A;
1044 }
1045
1046 const Handle(Adaptor2d_HCurve2d)& IntPatch_WLine::GetArcOnS1() const  { 
1047   return(theArcOnS1);
1048 }
1049
1050 Standard_Boolean IntPatch_WLine::HasArcOnS2() const  {
1051   return(hasArcOnS2);
1052 }
1053
1054 void IntPatch_WLine::SetArcOnS2(const Handle(Adaptor2d_HCurve2d)& A) { 
1055   hasArcOnS2=Standard_True;
1056   theArcOnS2=A;
1057 }
1058
1059 const Handle(Adaptor2d_HCurve2d)& IntPatch_WLine::GetArcOnS2() const  { 
1060   return(theArcOnS2);
1061 }
1062
1063
1064 void IntPatch_WLine::Dump() const { 
1065   
1066   cout<<" ----------- D u m p    I n t P a t c h  _  W L i n e  --------------"<<endl;
1067   Standard_Integer i;
1068   Standard_Integer nbp = NbPnts();
1069   printf("Num    [X  Y  Z]     [U1  V1]   [U2  V2]\n");
1070 //  for(Standard_Integer i=1;i<=nbp;i++) { 
1071   for(i=1;i<=nbp;i++) {
1072     Standard_Real u1,v1,u2,v2;
1073     Point(i).Parameters(u1,v1,u2,v2);
1074     printf("%4d  [%+10.20f %+10.20f %+10.20f]  [%+10.20f %+10.20f]  [%+10.20f %+10.20f]\n",
1075            i,
1076            Point(i).Value().X(),
1077            Point(i).Value().Y(),
1078            Point(i).Value().Z(),
1079            u1,v1,u2,v2);
1080     
1081     
1082     //cout<<"IntSurf_PntOn2S : "<<i<<"  Pnt ("<<curv->Value(i).Value().X()
1083     //  <<","<<curv->Value(i).Value().Y()
1084     //  <<","<<curv->Value(i).Value().Z()<<")"<<endl;
1085     //cout<<"                :   u1("<<u1<<")   v1("<<v1<<")   u2("<<u2<<")   v2("<<v2<<")"<<endl; 
1086   }
1087   nbp = NbVertex();
1088   for(i=1;i<=nbp;i++) { 
1089     Vertex(i).Dump();
1090     Standard_Real  polr = Vertex(i).ParameterOnLine();
1091     Standard_Integer pol = (Standard_Integer)polr;
1092     if(pol>=1 && pol<=nbp) { 
1093       cout<<"----> IntSurf_PntOn2S : "<<polr<<"  Pnt ("<<Vertex(pol).Value().X()
1094         <<","<<Vertex(pol).Value().Y()
1095           <<","<<Vertex(pol).Value().Z()<<")"<<endl;
1096     }
1097   }
1098   cout<<"\n----------------------------------------------------------"<<endl;  
1099 }
1100