e8da3d78d68ef17b90ae206bc6a1053c0a47a8cd
[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                                               const Standard_Boolean hasBeenAdded)
260 {
261   // MSV Oct 15, 2001: use tolerance of vertex instead of RTol where 
262   //                   it is possible
263
264   Standard_Integer i,j,k,nbvtx,nbponline;
265   Standard_Integer indicevertexonline;
266   Standard_Real    indicevertex;
267
268   Standard_Boolean APointDeleted = Standard_False;
269   //----------------------------------------------------------
270   //--     F i l t r e   s u r   r e s t r i c t i o n s   --
271   //----------------------------------------------------------
272   //-- deux vertex sur la meme restriction et seulement 
273   //-- sur celle ci ne doivent pas avoir le meme parametre
274   //--
275   Standard_Real Tol=RTol;
276   nbvtx = NbVertex();
277
278 #if DEBUGV  
279   cout<<"\n----------- avant ComputeVertexParameters -------------"<<endl;
280   for(i=1;i<=nbvtx;i++) { 
281     Vertex(i).Dump();
282     Standard_Real  polr = Vertex(i).ParameterOnLine();
283     Standard_Real pol = (Standard_Integer)polr;
284     if(pol>=1 && pol<=nbvtx) { 
285       cout<<"----> IntSurf_PntOn2S : "<<polr<<"  Pnt ("<<Vertex(pol).Value().X()
286         <<","<<Vertex(pol).Value().Y()
287           <<","<<Vertex(pol).Value().Z()<<")"<<endl;
288     }
289   }
290   cout<<"\n----------------------------------------------------------"<<endl;
291 #endif  
292
293   
294   //-- ----------------------------------------------------------------------
295   //-- Traitement des aretes de couture : On duplique les points situes
296   //-- sur des restrictions differentes
297   //-- 
298   //-- Phase Creation de nouveaux points sur S1 
299   Standard_Boolean encoreunefois;
300   do { 
301     nbvtx=NbVertex();
302     encoreunefois=Standard_False;
303     for(i=1; i<=nbvtx && encoreunefois==Standard_False; i++) { 
304       IntPatch_Point& VTXi   = svtx.ChangeValue(i);
305       for(j=1; j<=nbvtx && encoreunefois==Standard_False; j++) { 
306         if(i!=j) { 
307           IntPatch_Point& VTXj   = svtx.ChangeValue(j);
308           if(VTXi.ParameterOnLine() != VTXj.ParameterOnLine()) { 
309             Standard_Real d = VTXi.Value().Distance(VTXj.Value());
310             Standard_Real toli = VTXi.Tolerance();
311             Standard_Real tolj = VTXj.Tolerance();
312             Standard_Real maxtol = Max(toli,tolj);
313             // MSV Oct 30, 2001: compare in 2D space also;
314             //                   increase tolerances
315             if (d < maxtol ||
316                CompareVerticesOnS1(VTXi,VTXj) || CompareVerticesOnS2(VTXi,VTXj)) { 
317               //-- Creation Vtx (REF:S1(i)  S2(j))    (On Garde S1(i))
318               Standard_Real newtoli = Max (toli, tolj+d*1.01);
319               Standard_Real newtolj = Max (tolj, toli+d*1.01);
320               Standard_Boolean acreer=Standard_False;
321               if(VTXi.IsOnDomS1()) { 
322                 if(VTXj.IsOnDomS1()) { 
323                   if(VTXj.ArcOnS1() != VTXi.ArcOnS1()) { 
324                     acreer=Standard_True;
325                   }
326                 }
327                 else { 
328                   acreer=Standard_True;
329                 }
330               }
331               if(acreer) { 
332                 IntPatch_Point vtx;
333                 vtx = VTXj;
334                 vtx.SetArc(Standard_True,
335                            VTXi.ArcOnS1(),
336                            VTXi.ParameterOnArc1(),
337                            VTXi.TransitionLineArc1(),
338                            VTXi.TransitionOnS1());
339                 for(k=1; encoreunefois==Standard_False && k<=nbvtx; k++) { 
340                   const IntPatch_Point& VTXk   = svtx.Value(k);
341                   if(SameVtxRst(VTXk,vtx)) { 
342                     encoreunefois=Standard_True;
343                   }
344                 }
345                 if(encoreunefois==Standard_False) {
346                   VTXi.SetTolerance(newtoli);
347                   VTXj.SetTolerance(newtolj);
348                   vtx.SetTolerance(newtolj);
349                   svtx.Append(vtx);
350                   encoreunefois=Standard_True;
351                 }
352                 else { 
353                   encoreunefois=Standard_False;
354                 }
355               }
356               //-- -----------------------------------------------------
357               //-- Creation Vtx (REF:S2(i)  S1(j))    (On Garde S2(i))
358               acreer=Standard_False;
359               if(VTXi.IsOnDomS2()) { 
360                 if(VTXj.IsOnDomS2()) { 
361                   if(VTXj.ArcOnS2() != VTXi.ArcOnS2()) { 
362                     acreer=Standard_True;
363                   }
364                 }
365                 else { 
366                   acreer=Standard_True;
367                 }
368               }
369               if(acreer) { 
370                 IntPatch_Point vtx;
371                 vtx = VTXj;
372                 vtx.SetArc(Standard_False,
373                            VTXi.ArcOnS2(),
374                            VTXi.ParameterOnArc2(),
375                            VTXi.TransitionLineArc2(),
376                            VTXi.TransitionOnS2());
377                 for(k=1; encoreunefois==Standard_False && k<=nbvtx; k++) { 
378                   const IntPatch_Point& VTXk   = svtx.Value(k);
379                   if(SameVtxRst(VTXk,vtx)) { 
380                     encoreunefois=Standard_True;
381                   }
382                 }
383                 if(encoreunefois==Standard_False) {
384                   VTXi.SetTolerance(newtoli);
385                   VTXj.SetTolerance(newtolj);
386                   vtx.SetTolerance(newtolj);
387                   svtx.Append(vtx);
388                   encoreunefois=Standard_True;
389                 }
390                 else { 
391                   encoreunefois=Standard_False;
392                 }
393               }     
394             }
395           }
396         }
397       }
398     }
399   }
400   while(encoreunefois);
401   
402   
403
404   //-- ----------------------------------------------------------------------
405
406
407
408   do { 
409     APointDeleted = Standard_False;
410     for(i=1; (i<=nbvtx) && (APointDeleted==Standard_False) ;i++) { 
411       const IntPatch_Point& VTXi   = svtx.Value(i);
412       if(VTXi.Tolerance() > Tol)        Tol = VTXi.Tolerance(); //-- 9 oct 97 
413       if((VTXi.IsOnDomS1()==Standard_True) && (VTXi.IsOnDomS2()==Standard_False)) { 
414         for(j=1; (j<=nbvtx) && (APointDeleted==Standard_False) ;j++) {
415           if(i!=j) { 
416             const IntPatch_Point& VTXj   = svtx.Value(j);
417             if((VTXj.IsOnDomS1()==Standard_True) && (VTXj.IsOnDomS2()==Standard_False)) {
418               if(VTXi.ParameterOnLine() == VTXj.ParameterOnLine()) { 
419                 if(VTXi.ArcOnS1() == VTXj.ArcOnS1()) { 
420                   svtx.Remove(j);
421                   nbvtx--;
422                   if(lapt) { if(indl>=j) indl--; } 
423                   if(fipt) { if(indf>=j) indf--; } 
424                   APointDeleted = Standard_True;
425                 }
426               }
427             }
428           }
429         }
430       }
431     }
432   }
433   while(APointDeleted == Standard_True);
434
435
436   do { 
437     APointDeleted = Standard_False;
438     for(i=1; (i<=nbvtx) && (APointDeleted==Standard_False) ;i++) { 
439       const IntPatch_Point& VTXi   = svtx.Value(i);
440       if((VTXi.IsOnDomS2()==Standard_True) && (VTXi.IsOnDomS1()==Standard_False)) { 
441         for(j=1; (j<=nbvtx) && (APointDeleted==Standard_False) ;j++) {
442           if(i!=j) { 
443             const IntPatch_Point& VTXj   = svtx.Value(j);
444             if((VTXj.IsOnDomS2()==Standard_True) && (VTXj.IsOnDomS1()==Standard_False)) {
445               if(VTXi.ParameterOnLine() == VTXj.ParameterOnLine()) { 
446                 if(VTXi.ArcOnS2() == VTXj.ArcOnS2()) { 
447                   svtx.Remove(j);
448                   nbvtx--;
449                   if(lapt) { if(indl>=j) indl--; } 
450                   if(fipt) { if(indf>=j) indf--; } 
451                   APointDeleted = Standard_True;
452                 }
453               }
454             }
455           }
456         }
457       }
458     }
459   }
460   while(APointDeleted == Standard_True);
461         
462   nbvtx     = NbVertex();
463   nbponline = NbPnts();
464
465   //----------------------------------------------------
466   //-- On trie les Vertex 
467   Standard_Boolean SortIsOK;
468   do { 
469     SortIsOK = Standard_True;
470     for(i=2; i<=nbvtx; i++) { 
471       if(svtx.Value(i-1).ParameterOnLine()  > svtx.Value(i).ParameterOnLine()) { 
472         SortIsOK = Standard_False;
473         svtx.Exchange(i-1,i);
474       }
475     }
476   }
477   while(!SortIsOK);
478   
479   //----------------------------------------------------
480   //-- On detecte les points confondus dans la LineOn2S
481   Standard_Real dmini = Precision::Confusion();
482   dmini*=dmini;
483   for(i=2; i<=nbponline; i++) { 
484     const IntSurf_PntOn2S& aPnt1=curv->Value(i-1);
485     const IntSurf_PntOn2S& aPnt2=curv->Value(i);
486     Standard_Real d = (aPnt1.Value()).SquareDistance((aPnt2.Value()));
487     if(d < dmini) { 
488       curv->RemovePoint(i);
489       nbponline--;
490       //----------------------------------------------
491       //-- On recadre les Vertex si besoin 
492       //-- 
493       for(j=1; j<=nbvtx; j++) { 
494         indicevertex = svtx.Value(j).ParameterOnLine();
495         if(indicevertex >= i) {
496           svtx.ChangeValue(j).SetParameter(indicevertex-1.0);
497         }
498       }
499       //modified by NIZNHY-PKV Mon Feb 11 09:28:02 2002 f
500       i--;
501       //modified by NIZNHY-PKV Mon Feb 11 09:28:04 2002 t
502     }
503   }
504   //----------------------------------------------------
505   for(i=1; i<=nbvtx; i++) {
506     const gp_Pnt& P    = svtx.Value(i).Value();
507     Standard_Real vTol = svtx.Value(i).Tolerance();
508     
509     if(hasBeenAdded)
510     {
511       if(nbvtx == 2)
512       {
513         if(i == nbvtx)
514         {
515           indicevertex = curv->NbPoints();
516         }
517         else
518         {
519           indicevertex = svtx.Value(i).ParameterOnLine();
520         }
521       }
522       else
523       {
524         indicevertex = svtx.Value(i).ParameterOnLine();
525       }
526     }
527     else
528     {
529       indicevertex = svtx.Value(i).ParameterOnLine();
530     }
531     
532     indicevertexonline = (Standard_Integer)indicevertex;
533     //--------------------------------------------------
534     //-- On Compare le vertex avec les points de la ligne
535     //-- d indice   indicevertexOnLine-1
536     //--            indicevertexOnLine
537     //--            indicevertexOnLine+1
538     //--------------------------------------------------
539     if(indicevertexonline<1) { 
540       if(CompareVertexAndPoint(P,curv->Value(1).Value(),vTol)) {
541         //-------------------------------------------------------
542         //-- On remplace le point cheminement(1) par vertex(i)
543         //-- et   vertex(i) prend pour parametre 1
544         //-------------------------------------------------------
545         
546         IntSurf_PntOn2S POn2S = svtx.Value(i).PntOn2S();
547         RecadreMemePeriode(POn2S,curv->Value(1),U1Period(),V1Period(),U2Period(),V2Period());
548         curv->Value(1,POn2S);
549
550         //--curv->Value(1,svtx.Value(i).PntOn2S());
551         svtx.ChangeValue(i).SetParameter(1.0);
552       }
553       else { 
554         //-------------------------------------------------------
555         //-- On insere le point de cheminement Vertex(i)
556         //-- On recadre les parametres des autres vertex
557         //-------------------------------------------------------
558         IntSurf_PntOn2S POn2S = svtx.Value(i).PntOn2S();
559         RecadreMemePeriode(POn2S,curv->Value(1),U1Period(),V1Period(),U2Period(),V2Period());
560         curv->InsertBefore(1,POn2S);
561
562         //-- curv->InsertBefore(1,svtx.Value(i).PntOn2S());
563         svtx.ChangeValue(i).SetParameter(1.0);
564         nbponline++;
565         for(j=1;j<=nbvtx;j++) {
566           if(j!=1) { 
567             Standard_Real t = svtx.Value(j).ParameterOnLine();
568             if(t>1.0) { 
569               svtx.ChangeValue(j).SetParameter(t+1.0);
570             }
571           }
572         }
573       }
574     } //--- fin : if(indicevertexonline<1) 
575     else { 
576       //---------------------------------------------------------
577       //-- vertex(i)   ==   cheminement (indicevertexonline-1)
578       //-- vertex(i)   ==   cheminement (indicevertexonline)
579       //-- vertex(i)   ==   cheminement (indicevertexonline+1)
580       //---------------------------------------------------------
581       Standard_Boolean Substitution = Standard_False;
582       //-- for(k=indicevertexonline+1; !Substitution && k>=indicevertexonline-1;k--) {   avant le 9 oct 97 
583       for(k=indicevertexonline+1; k>=indicevertexonline-1;k--) { 
584         if(k>0 && k<=nbponline) { 
585           if(CompareVertexAndPoint(P,curv->Value(k).Value(),vTol)) {
586             //-------------------------------------------------------
587             //-- On remplace le point cheminement(k) 
588             //-- par vertex(i)  et vertex(i) prend pour parametre k
589             //-------------------------------------------------------
590             IntSurf_PntOn2S POn2S = svtx.Value(i).PntOn2S();
591             RecadreMemePeriode(POn2S,curv->Value(k),U1Period(),V1Period(),U2Period(),V2Period());
592             curv->Value(k,POn2S);
593             Standard_Real mu1,mv1,mu2,mv2;
594             POn2S.Parameters(mu1,mv1,mu2,mv2);
595             svtx.ChangeValue(i).SetParameter(k);
596             svtx.ChangeValue(i).SetParameters(mu1,mv1,mu2,mv2);
597             Substitution = Standard_True;
598           }
599         }
600       }
601
602       //Remove duplicating points
603       if (Substitution)
604       {
605         Standard_Integer ind_point;
606         for(ind_point = 2; (ind_point <= nbponline && nbponline > 2); ind_point++) { 
607           Standard_Real d = (curv->Value(ind_point-1).Value()).SquareDistance((curv->Value(ind_point).Value()));
608           if(d < dmini) { 
609             curv->RemovePoint(ind_point);
610             nbponline--;
611             //----------------------------------------------
612             //-- On recadre les Vertex si besoin 
613             //-- 
614             for(j=1; j<=nbvtx; j++) { 
615               indicevertex = svtx.Value(j).ParameterOnLine();
616               if(indicevertex >= ind_point) {
617                 svtx.ChangeValue(j).SetParameter(indicevertex-1.0);
618               }
619             }
620             //modified by NIZNHY-PKV Mon Feb 11 09:28:02 2002 f
621             ind_point--;
622             //modified by NIZNHY-PKV Mon Feb 11 09:28:04 2002 t
623           }
624         }
625       }
626       
627       //--static int deb6nov98=1;    Ne resout rien (a part partiellement BUC60409)
628       //--if(deb6nov98) { 
629       //--Substitution=Standard_True;
630       //-- }
631       
632       if(Substitution==Standard_False) { 
633         //-------------------------------------------------------
634         //-- On insere le point de cheminement Vertex(i)
635         //-- On recadre les parametres des autres vertex
636         //-------------------------------------------------------
637         IntSurf_PntOn2S POn2S = svtx.Value(i).PntOn2S();
638         if(indicevertexonline >= nbponline) { 
639           RecadreMemePeriode(POn2S,curv->Value(nbponline),U1Period(),V1Period(),U2Period(),V2Period());
640           curv->Add(POn2S);
641         }
642         else { 
643           RecadreMemePeriode(POn2S,curv->Value(indicevertexonline+1),U1Period(),V1Period(),U2Period(),V2Period());
644           curv->InsertBefore(indicevertexonline+1,POn2S);
645         }
646         //-- curv->InsertBefore(indicevertexonline+1,svtx.Value(i).PntOn2S());
647         svtx.ChangeValue(i).SetParameter(indicevertexonline+1);
648         nbponline++;
649         for(j=1;j<=nbvtx;j++) { 
650           if(j!=i) { 
651             Standard_Real t = svtx.Value(j).ParameterOnLine();
652             if(t>(Standard_Real)indicevertexonline) { 
653               svtx.ChangeValue(j).SetParameter(t+1.0);
654             }
655           }
656         }
657       } //-- Substitution
658     } //-- indicevertexonline>=1
659
660   } //-- boucle i sur vertex
661
662   
663   
664   
665   do {  
666     APointDeleted = Standard_False;
667     for(i=1; i<=nbvtx && (APointDeleted == Standard_False); i++) { 
668       const IntPatch_Point& VTX   = svtx.Value(i);      
669       for(j=1; j<=nbvtx && (APointDeleted == Standard_False) ; j++) { 
670         if(i!=j) { 
671           const IntPatch_Point& VTXM1 = svtx.Value(j);
672           
673           Standard_Boolean kill   = Standard_False;
674           Standard_Boolean killm1 = Standard_False;
675           if(VTXM1.ParameterOnLine() == VTX.ParameterOnLine()) { 
676             if(VTXM1.IsOnDomS1() && VTX.IsOnDomS1()) {  //-- OnS1    OnS1
677               if(VTXM1.ArcOnS1() == VTX.ArcOnS1()) {    //-- OnS1 == OnS1
678                 if(VTXM1.IsOnDomS2()) {                 //-- OnS1 == OnS1  OnS2  
679                   if(VTX.IsOnDomS2()==Standard_False) {   //-- OnS1 == OnS1  OnS2 PasOnS2
680                     kill=Standard_True;   
681                   }
682                   else {
683                     if(VTXM1.ArcOnS2() == VTX.ArcOnS2()) { //-- OnS1 == OnS1  OnS2 == OnS2
684                       kill=Standard_True;
685                     }
686                   }
687                 }
688                 else {                                  //-- OnS1 == OnS1  PasOnS2  
689                   if(VTX.IsOnDomS2()) {                 //-- OnS1 == OnS1  PasOnS2  OnS2
690                     killm1=Standard_True;
691                   }
692                 }
693               }
694             }
695             
696             if(!(kill || killm1)) {
697               if(VTXM1.IsOnDomS2() && VTX.IsOnDomS2()) {  //-- OnS2    OnS2
698                 if(VTXM1.ArcOnS2() == VTX.ArcOnS2()) {    //-- OnS2 == OnS2
699                   if(VTXM1.IsOnDomS1()) {                 //-- OnS2 == OnS2  OnS1  
700                     if(VTX.IsOnDomS1()==Standard_False) {   //-- OnS2 == OnS2  OnS1 PasOnS1
701                       kill=Standard_True;   
702                     }
703                     else {
704                       if(VTXM1.ArcOnS1() == VTX.ArcOnS1()) { //-- OnS2 == OnS2  OnS1 == OnS1
705                         kill=Standard_True;
706                       }
707                     }
708                   }
709                   else {                                  //-- OnS2 == OnS2  PasOnS1  
710                     if(VTX.IsOnDomS1()) {                 //-- OnS2 == OnS2  PasOnS1  OnS1
711                       killm1=Standard_True;
712                     }
713                   }
714                 }
715               }
716             }
717             if(kill) { 
718               APointDeleted = Standard_True;
719               svtx.Remove(i);
720               nbvtx--;
721             }
722             else if(killm1) { 
723               APointDeleted = Standard_True;
724               svtx.Remove(j);
725               nbvtx--; 
726             }
727           }
728         }
729       }
730     }
731   }
732   while(APointDeleted == Standard_True);
733   
734   do {  
735     SortIsOK = Standard_True;
736     for(i=2; i<=nbvtx && SortIsOK; i++) {
737       const IntPatch_Point& Pim1=svtx.Value(i-1);
738       const IntPatch_Point& Pii  =svtx.Value(i);
739       if(Pim1.ParameterOnLine()==Pii.ParameterOnLine()) { 
740         if(   (Pii.IsOnDomS1() == Standard_False)
741            && (Pii.IsOnDomS2() == Standard_False)) { 
742           SortIsOK = Standard_False;
743           svtx.Remove(i);
744           nbvtx--;
745         }
746         else {
747           if(   (Pim1.IsOnDomS1() == Standard_False)
748              && (Pim1.IsOnDomS2() == Standard_False)) { 
749             SortIsOK = Standard_False;
750             svtx.Remove(i-1);
751             nbvtx--;
752           }       
753         }
754       }
755     }
756   }
757   while(!SortIsOK);
758   //-- ----------------------------------------------------------------------------
759   //-- On ajoute les vertex de debut et de fin de ligne s il ne sont pas presents.
760   //-- 
761   //-- Existe t il un vertex de debut de ligne, de fin .
762   //--
763   //-- Si Besoin : il faudra dedoubler les points de debut et de fin sur les periodiques ??????
764
765
766
767   
768   Standard_Boolean bFirst = Standard_False;
769   Standard_Boolean bLast  = Standard_False;
770   nbponline = NbPnts();
771   for(i=1;i<=nbvtx;i++) { 
772     Standard_Real pol = svtx.Value(i).ParameterOnLine();
773     if(pol==1.0)       {
774       bFirst = fipt = Standard_True;
775       indf   = i;
776     }
777     if(pol==nbponline) {
778       bLast = lapt = Standard_True;
779       indl  = i;
780     }
781   }
782   if(bFirst == Standard_False) { 
783     Standard_Real pu1,pv1,pu2,pv2;
784     Standard_Boolean vtxfound = Standard_False;
785     IntPatch_Point vtx;
786     curv->Value(1).Parameters(pu1,pv1,pu2,pv2);
787     for(i=1;
788         (vtxfound==Standard_False) && (i<=nbvtx);i++) { 
789       const IntPatch_Point&  V = svtx.Value(i);
790       //jgv: to avoid loops
791       //Standard_Real vTol = V.Tolerance();
792       if(CompareVertexAndPoint(V.Value(), curv->Value(1).Value(), Precision::Confusion()/*vTol*/)) { 
793         vtx = V;
794         vtx.SetParameters(pu1,pv1,pu2,pv2);
795         vtxfound = Standard_True;
796       }
797     }
798     if(vtxfound == Standard_False)  { 
799       vtx.SetValue(curv->Value(1).Value(),Tol,Standard_False);
800       vtx.SetParameters(pu1,pv1,pu2,pv2);
801     }
802     vtx.SetParameter(1);
803     svtx.Prepend(vtx);    nbvtx++;
804     fipt = Standard_True;
805     indf = 1;
806   }
807   if(bLast == Standard_False) { 
808     Standard_Real pu1,pv1,pu2,pv2;
809     Standard_Boolean vtxfound = Standard_False;    
810     IntPatch_Point vtx;
811     curv->Value(nbponline).Parameters(pu1,pv1,pu2,pv2);   
812     for(i=1;
813         (vtxfound==Standard_False) && (i<=nbvtx);i++) { 
814       const IntPatch_Point&  V = svtx.Value(i);
815       //jgv: to avoid loops
816       //Standard_Real vTol = V.Tolerance();
817       if(CompareVertexAndPoint(V.Value(), curv->Value(nbponline).Value(), Precision::Confusion()/*vTol*/)) { 
818         vtx = V;
819         vtx.SetParameters(pu1,pv1,pu2,pv2);
820         vtxfound = Standard_True;
821       }
822     }
823     if(vtxfound == Standard_False)  {     
824       vtx.SetValue(curv->Value(nbponline).Value(),Tol,Standard_False);
825       vtx.SetParameters(pu1,pv1,pu2,pv2);
826     }
827     vtx.SetParameter(nbponline);
828     svtx.Append(vtx); nbvtx++;
829     lapt = Standard_True;
830     indl = nbvtx; 
831   }
832   
833
834
835
836   //--------------------------------------------------------------
837   //-- ** Detection de points trouves sur une meme restriction 
838   //--    avec la meme transition et avec des params on line 
839   //--    voisins.   
840   //-- ** Dans ce cas (-> donnerait un baillemenmt) on supprime 
841   //--    le point 'intermediaire'. 
842   //-- ** (exemple Vtx(1)  .....  Vtx(204) Vtx(205))
843   //--    on supprime le Vtx(204)
844   //-- ** (exemple Vtx(1) Vtx(2)  .....  Vtx(205))
845   //--    on supprime le Vtx(2)
846   //-- ** (exemple Vtx(1)  ...  Vtx(100) Vtx(101) ... Vtx(205))
847   //--    on supprime le Vtx(100)  (Vtx(100)et101 sur m restr)
848
849   //--------------------------------------------------------------
850   nbvtx = NbVertex();
851   do { 
852     APointDeleted = Standard_False;
853     for(i=1; (i<=nbvtx) && (APointDeleted==Standard_False) ;i++) { 
854       const IntPatch_Point& VTXi   = svtx.Value(i);
855       if((VTXi.IsOnDomS1()==Standard_True) && (VTXi.IsOnDomS2()==Standard_False)) { 
856         for(j=1; (j<=nbvtx) && (APointDeleted==Standard_False) ;j++) {
857           if(i!=j) { 
858             const IntPatch_Point& VTXj   = svtx.Value(j);
859             if((VTXj.IsOnDomS1()==Standard_True) && (VTXj.IsOnDomS2()==Standard_False)) {
860               if(   (VTXi.ParameterOnLine() == VTXj.ParameterOnLine()+1)
861                  || (VTXi.ParameterOnLine() == VTXj.ParameterOnLine()-1)) { 
862                 if(VTXi.ArcOnS1() == VTXj.ArcOnS1()) { 
863                   IntSurf_Transition t1 = VTXi.TransitionLineArc1();
864                   IntSurf_Transition t2 = VTXj.TransitionLineArc1();
865                   if(t1.TransitionType()==t2.TransitionType()) { 
866                     if((VTXj.ParameterOnLine()!=1) && (VTXj.ParameterOnLine()!=NbPnts())) {   
867                       svtx.Remove(j);
868                       nbvtx--;
869                       if(lapt) { if(indl>=j) indl--; } 
870                       if(fipt) { if(indf>=j) indf--; } 
871                       APointDeleted = Standard_True;
872                     }
873                   }
874                 }
875               }
876             }
877           }
878         }
879       }
880     }
881   }
882   
883   //-- meme traitement sur les restrictions du second shape
884
885   while(APointDeleted == Standard_True);
886   nbvtx = NbVertex();
887   do { 
888     APointDeleted = Standard_False;
889     for(i=1; (i<=nbvtx) && (APointDeleted==Standard_False) ;i++) { 
890       const IntPatch_Point& VTXi   = svtx.Value(i);
891       if((VTXi.IsOnDomS1()==Standard_False) && (VTXi.IsOnDomS2()==Standard_True)) { 
892         for(j=1; (j<=nbvtx) && (APointDeleted==Standard_False) ;j++) {
893           if(i!=j) { 
894             const IntPatch_Point& VTXj   = svtx.Value(j);
895             if((VTXj.IsOnDomS1()==Standard_False) && (VTXj.IsOnDomS2()==Standard_True)) {
896               if(   (VTXi.ParameterOnLine() == VTXj.ParameterOnLine()+1)
897                  || (VTXi.ParameterOnLine() == VTXj.ParameterOnLine()-1)) { 
898                 if(VTXi.ArcOnS2() == VTXj.ArcOnS2()) { 
899                   IntSurf_Transition t1 = VTXi.TransitionLineArc2();
900                   IntSurf_Transition t2 = VTXj.TransitionLineArc2();
901                   if(t1.TransitionType()==t2.TransitionType()) { 
902                     if((VTXj.ParameterOnLine()!=1) && (VTXj.ParameterOnLine()!=NbPnts())) {   
903                       svtx.Remove(j);
904                       nbvtx--;
905                       if(lapt) { if(indl>=j) indl--; } 
906                       if(fipt) { if(indf>=j) indf--; } 
907                       APointDeleted = Standard_True;
908                     }
909                   }
910                 }
911               }
912             }
913           }
914         }
915       }
916     }
917   }
918   while(APointDeleted == Standard_True);
919   //--------------------------------------------------------------
920
921   //--------------------------------------------------------------
922   //-- dans le cas de lignes periodiques du type : 
923   //--    Un point sur restriction R1 de param p1  -> P3d1   Vtx1
924   //--    Un point sur restriction R2 de param p2  -> P3d1   Vtx2
925   //--    
926   //--    Un point sur restriction R1 de param p1  -> P3d1   Vtx3
927   //--    pas de point sur R2 
928   //--
929   //-- On doit dans ce cas creer un nouveau Vtx4 = Vtx3 sur la 
930   //-- restriction R2
931   //--
932   //-- Ce cas se produit qd on a corrige un baillement avec le filtre
933   //-- precedent
934   //-- 
935   
936
937
938
939   
940
941   nbvtx = NbVertex();
942   do { 
943     SortIsOK = Standard_True;
944     for(i=2; i<=nbvtx; i++) { 
945       if(svtx.Value(i-1).ParameterOnLine()  > svtx.Value(i).ParameterOnLine()) { 
946         SortIsOK = Standard_False;
947         svtx.Exchange(i-1,i);
948       }
949     }
950   }
951   while(!SortIsOK);
952   
953   //-- Dump();
954
955 #if DEBUGV  
956   cout<<"\n----------- apres ComputeVertexParameters -------------"<<endl;
957   for(i=1;i<=nbvtx;i++) { 
958     Vertex(i).Dump();
959     Standard_Real  polr = Vertex(i).ParameterOnLine();
960     Standard_Real pol = (Standard_Integer)polr;
961     if(pol>=1 && pol<=nbvtx) { 
962       cout<<"----> IntSurf_PntOn2S : "<<polr<<"  Pnt ("<<Vertex(pol).Value().X()
963         <<","<<Vertex(pol).Value().Y()
964           <<","<<Vertex(pol).Value().Z()<<")"<<endl;
965     }
966   }
967   cout<<"\n----------------------------------------------------------"<<endl;
968 #endif  
969
970
971 }
972
973
974
975 Standard_Boolean IntPatch_WLine::IsOutSurf1Box(const gp_Pnt2d& P1uv)  { 
976   if(Buv1.IsWhole()) {
977     Standard_Integer n=NbPnts();
978     Standard_Real pu1,pu2,pv1,pv2;
979     Buv1.SetVoid();
980     for(Standard_Integer i=1;i<=n;i++) { 
981       curv->Value(i).Parameters(pu1,pv1,pu2,pv2);
982       Buv1.Add(gp_Pnt2d(pu1,pv1));
983     }
984     Buv1.Get(pu1,pv1,pu2,pv2);
985     pu2-=pu1;
986     pv2-=pv1;
987     if(pu2>pv2) { 
988       Buv1.Enlarge(pu2*0.01);
989     }
990     else { 
991       Buv1.Enlarge(pv2*0.01);
992     }
993   }
994   Standard_Boolean out=Buv1.IsOut(P1uv);
995   return(out);
996 }
997
998 Standard_Boolean IntPatch_WLine::IsOutSurf2Box(const gp_Pnt2d& P2uv)  { 
999   if(Buv2.IsWhole()) { 
1000     Standard_Integer n=NbPnts();
1001     Standard_Real pu1,pu2,pv1,pv2;
1002     Buv2.SetVoid();
1003     for(Standard_Integer i=1;i<=n;i++) { 
1004       curv->Value(i).Parameters(pu1,pv1,pu2,pv2);
1005       Buv2.Add(gp_Pnt2d(pu2,pv2));
1006     }
1007     Buv2.Get(pu1,pv1,pu2,pv2);
1008     pu2-=pu1;
1009     pv2-=pv1;
1010     if(pu2>pv2) { 
1011       Buv2.Enlarge(pu2*0.01);
1012     }
1013     else { 
1014       Buv2.Enlarge(pv2*0.01);
1015     }    
1016   }
1017   Standard_Boolean out=Buv2.IsOut(P2uv);
1018   return(out);
1019 }
1020
1021 Standard_Boolean IntPatch_WLine::IsOutBox(const gp_Pnt& Pxyz)  { 
1022   if(Bxyz.IsWhole()) { 
1023     Standard_Integer n=NbPnts();
1024     Bxyz.SetVoid();
1025     for(Standard_Integer i=1;i<=n;i++) { 
1026       gp_Pnt P=curv->Value(i).Value();
1027       Bxyz.Add(P);
1028     }
1029     Standard_Real x0,y0,z0,x1,y1,z1;
1030     Bxyz.Get(x0,y0,z0,x1,y1,z1);
1031     x1-=x0; y1-=y0; z1-=z0;
1032     if(x1>y1) {
1033       if(x1>z1) {
1034         Bxyz.Enlarge(x1*0.01);
1035       }
1036       else { 
1037         Bxyz.Enlarge(z1*0.01);
1038       }
1039     }
1040     else { 
1041       if(y1>z1) { 
1042         Bxyz.Enlarge(y1*0.01);
1043       }
1044       else { 
1045         Bxyz.Enlarge(z1*0.01);
1046       }
1047     }
1048   }
1049   Standard_Boolean out=Bxyz.IsOut(Pxyz);
1050   return(out);
1051 }
1052
1053
1054 Standard_Boolean IntPatch_WLine::HasArcOnS1() const  {
1055   return(hasArcOnS1);
1056 }
1057
1058 void IntPatch_WLine::SetArcOnS1(const Handle(Adaptor2d_HCurve2d)& A) { 
1059   hasArcOnS1=Standard_True;
1060   theArcOnS1=A;
1061 }
1062
1063 const Handle(Adaptor2d_HCurve2d)& IntPatch_WLine::GetArcOnS1() const  { 
1064   return(theArcOnS1);
1065 }
1066
1067 Standard_Boolean IntPatch_WLine::HasArcOnS2() const  {
1068   return(hasArcOnS2);
1069 }
1070
1071 void IntPatch_WLine::SetArcOnS2(const Handle(Adaptor2d_HCurve2d)& A) { 
1072   hasArcOnS2=Standard_True;
1073   theArcOnS2=A;
1074 }
1075
1076 const Handle(Adaptor2d_HCurve2d)& IntPatch_WLine::GetArcOnS2() const  { 
1077   return(theArcOnS2);
1078 }
1079
1080
1081 void IntPatch_WLine::Dump(const Standard_Integer theMode) const
1082
1083   cout<<" ----------- D u m p    I n t P a t c h  _  W L i n e  -(begin)------"<<endl;
1084   const Standard_Integer aNbPoints = NbPnts();
1085   const Standard_Integer aNbVertex = NbVertex();
1086
1087   switch(theMode)
1088   {
1089   case 0:
1090     printf("Num    [X  Y  Z]     [U1  V1]   [U2  V2]\n");
1091     for(Standard_Integer i=1; i<=aNbPoints; i++)
1092     {
1093       Standard_Real u1,v1,u2,v2;
1094       Point(i).Parameters(u1,v1,u2,v2);
1095       printf("%4d  [%+10.20f %+10.20f %+10.20f]  [%+10.20f %+10.20f]  [%+10.20f %+10.20f]\n",
1096               i,Point(i).Value().X(),Point(i).Value().Y(),Point(i).Value().Z(),
1097               u1,v1,u2,v2);
1098     }
1099     
1100     for(Standard_Integer i=1;i<=aNbVertex;i++)
1101     {
1102       Vertex(i).Dump();
1103       Standard_Real  polr = Vertex(i).ParameterOnLine();
1104       Standard_Integer pol = static_cast<Standard_Integer>(polr);
1105
1106       if(pol>=1 && pol<=aNbVertex)
1107       {
1108         cout<<"----> IntSurf_PntOn2S : "<<
1109                       polr <<", Pnt (" << Vertex(pol).Value().X() << "," <<
1110                                           Vertex(pol).Value().Y() << "," <<
1111                                           Vertex(pol).Value().Z() <<")" <<endl;
1112       }
1113     }
1114
1115     break;
1116   case 1:
1117     for(Standard_Integer i = 1; i <= aNbPoints; i++)
1118     {
1119       Standard_Real u1,v1,u2,v2;
1120       Point(i).Parameters(u1,v1,u2,v2);
1121       printf("point p%d %+10.20f %+10.20f %+10.20f\n",
1122               i,Point(i).Value().X(),Point(i).Value().Y(),Point(i).Value().Z());
1123     }
1124
1125     break;
1126   case 2:
1127     for(Standard_Integer i = 1; i <= aNbPoints; i++)
1128     {
1129       Standard_Real u1,v1,u2,v2;
1130       Point(i).Parameters(u1,v1,u2,v2);
1131       printf("point p%d %+10.20f %+10.20f\n", i, u1, v1);
1132     }
1133
1134     break;
1135   default:
1136     for(Standard_Integer i = 1; i <= aNbPoints; i++)
1137     {
1138       Standard_Real u1,v1,u2,v2;
1139       Point(i).Parameters(u1,v1,u2,v2);
1140       printf("point p%d %+10.20f %+10.20f\n", i, u2, v2);
1141     }
1142
1143     break;
1144   }
1145   cout<<"\n--------------------------------------------------- (end) -------"<<endl;  
1146 }
1147