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