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