0030679: Attached model hangs most of OCCT common functionality
[occt.git] / src / ApproxInt / ApproxInt_MultiLine.gxx
1 // Created on: 1993-03-22
2 // Created by: Laurent BUCHARD
3 // Copyright (c) 1993-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 #include <TColStd_Array1OfReal.hxx>
18 #include <gp_Pnt2d.hxx>
19 #include <gp_Pnt.hxx>
20 #include <gp_Vec2d.hxx>
21 #include <gp_Vec.hxx>
22 #include <IntSurf_LineOn2S.hxx>
23 #include <Precision.hxx>
24 #include <math_Vector.hxx>
25
26 #ifdef DRAW
27 #include <DrawTrSurf.hxx>
28 #endif
29
30 //=======================================================================
31 //function : Constructor
32 //purpose  : 
33 //=======================================================================
34 ApproxInt_MultiLine::ApproxInt_MultiLine()
35 {
36   PtrOnmySvSurfaces = NULL;
37   myLine = NULL;
38   indicemin = 0;
39   indicemax = 0;
40   nbp3d = 0;
41   nbp2d = 0;
42   myApproxU1V1 = Standard_False;
43   myApproxU2V2 = Standard_False;
44   p2donfirst = Standard_True;
45   Xo = 0.;
46   Yo = 0.;
47   Zo = 0.;
48   U1o = 0.;
49   V1o = 0.;
50   U2o = 0.;
51   V2o = 0.;
52 }
53
54 //=======================================================================
55 //function : Constructor
56 //purpose  : 
57 //=======================================================================
58 ApproxInt_MultiLine::
59   ApproxInt_MultiLine(const Handle_TheLine& line,
60                       const Standard_Address svsurf,
61                       const Standard_Integer NbP3d,
62                       const Standard_Integer NbP2d,
63                       const Standard_Boolean ApproxU1V1,
64                       const Standard_Boolean ApproxU2V2,
65                       const Standard_Real xo,
66                       const Standard_Real yo,
67                       const Standard_Real zo,
68                       const Standard_Real u1o,
69                       const Standard_Real v1o,
70                       const Standard_Real u2o,
71                       const Standard_Real v2o,
72                       const Standard_Boolean P2DOnFirst,
73                       const Standard_Integer IndMin,
74                       const Standard_Integer IndMax): PtrOnmySvSurfaces(svsurf),
75                                                       myLine(line),
76                                                       indicemin(Min(IndMin, IndMax)),
77                                                       indicemax(Max(IndMin, IndMax)),
78                                                       nbp3d(NbP3d), nbp2d(NbP2d),
79                                                       myApproxU1V1(ApproxU1V1),
80                                                       myApproxU2V2(ApproxU2V2),
81                                                       p2donfirst(P2DOnFirst),
82                                                       Xo(xo), Yo(yo), Zo(zo),
83                                                       U1o(u1o), V1o(v1o),
84                                                       U2o(u2o), V2o(v2o)
85
86 {
87 #if OCCT_DEBUG 
88   //if(indicemin == indicemax)
89   //{
90   //  cout<<"ApproxInt_MultiLine: indicemin = indicemax = " << indicemin << endl;
91   //}
92 #endif
93 }
94
95 //=======================================================================
96 //function : Constructor
97 //purpose  : 
98 //=======================================================================
99 ApproxInt_MultiLine::
100   ApproxInt_MultiLine(const Handle_TheLine& line,
101                       const Standard_Integer NbP3d,
102                       const Standard_Integer NbP2d,
103                       const Standard_Boolean ApproxU1V1,
104                       const Standard_Boolean ApproxU2V2,
105                       const Standard_Real xo,
106                       const Standard_Real yo,
107                       const Standard_Real zo,
108                       const Standard_Real u1o,
109                       const Standard_Real v1o,
110                       const Standard_Real u2o,
111                       const Standard_Real v2o,
112                       const Standard_Boolean P2DOnFirst,
113                       const Standard_Integer IndMin,
114                       const Standard_Integer IndMax): PtrOnmySvSurfaces(0),
115                                                       myLine(line),
116                                                       indicemin(Min(IndMin, IndMax)),
117                                                       indicemax(Max(IndMin, IndMax)),
118                                                       nbp3d(NbP3d), nbp2d(NbP2d),
119                                                       myApproxU1V1(ApproxU1V1),
120                                                       myApproxU2V2(ApproxU2V2),
121                                                       p2donfirst(P2DOnFirst),
122                                                       Xo(xo), Yo(yo), Zo(zo),
123                                                       U1o(u1o), V1o(v1o),
124                                                       U2o(u2o), V2o(v2o)
125 {
126 #if OCCT_DEBUG
127   //if(indicemin == indicemax)
128   //{
129   //  cout<<"ApproxInt_MultiLine: indicemin = indicemax = " << indicemin << endl;
130   //}
131 #endif
132 }
133
134 //--------------------------------------------------------------------------------
135 Standard_Integer ApproxInt_MultiLine::FirstPoint() const { 
136   return indicemin;
137 }
138 //--------------------------------------------------------------------------------
139 Standard_Integer ApproxInt_MultiLine::LastPoint() const { 
140   return indicemax;
141 }
142 //--------------------------------------------------------------------------------
143 Approx_Status ApproxInt_MultiLine::WhatStatus() const { 
144   if(PtrOnmySvSurfaces)
145     return Approx_PointsAdded;
146   else 
147     return Approx_NoPointsAdded;
148 }
149 //--------------------------------------------------------------------------------
150 Standard_Integer ApproxInt_MultiLine::NbP3d() const { 
151   return nbp3d;
152 }
153 //--------------------------------------------------------------------------------
154 Standard_Integer ApproxInt_MultiLine::NbP2d() const { 
155   return nbp2d;
156 }
157 //================================================================================
158 void ApproxInt_MultiLine::Value(const Standard_Integer  Index,
159                                 TColgp_Array1OfPnt&     TabPnt)  const
160 {
161   const gp_Pnt aP = myLine->Point(Index).Value();
162   TabPnt(1).SetCoord(aP.X()+Xo, aP.Y()+Yo, aP.Z()+Zo);
163 }
164
165 //=======================================================================
166 //function : Value
167 //purpose  : 
168 //=======================================================================
169 void ApproxInt_MultiLine::Value(const Standard_Integer Index,
170                                 TColgp_Array1OfPnt2d&  TabPnt2d) const 
171 {
172   IntSurf_PntOn2S POn2S(myLine->Point(Index));
173   Standard_Real u1 = 0.0, u2 = 0.0, v1 = 0.0, v2 = 0.0;
174   POn2S.Parameters(u1, v1, u2, v2);
175   if(nbp2d==1)
176   { 
177     if(p2donfirst)
178     { 
179       TabPnt2d(1).SetCoord(u1+U1o, v1+V1o);
180     }
181     else
182     {
183       TabPnt2d(1).SetCoord(u2+U2o, v2+V2o);
184     }
185   }
186   else
187   {
188     TabPnt2d(1).SetCoord(u1+U1o, v1+V1o);
189     if(TabPnt2d.Length() >= 2)
190     { 
191       TabPnt2d(2).SetCoord(u2+U2o, v2+V2o);
192     } 
193   }
194 }
195
196 //=======================================================================
197 //function : Value
198 //purpose  : 
199 //=======================================================================
200 void ApproxInt_MultiLine::Value(const Standard_Integer Index,
201                                 TColgp_Array1OfPnt&    TabPnt,
202                                 TColgp_Array1OfPnt2d&  TabPnt2d)  const 
203
204     Value(Index, TabPnt);
205     Value(Index, TabPnt2d);
206 }
207
208 //=======================================================================
209 //function : Tangency
210 //purpose  : 
211 //=======================================================================
212 Standard_Boolean ApproxInt_MultiLine::Tangency( const Standard_Integer Index,
213                                                 TColgp_Array1OfVec&    TabVec) const 
214 {
215   if(PtrOnmySvSurfaces==NULL) 
216     return Standard_False;
217
218   const IntSurf_PntOn2S& POn2S = myLine->Point(Index);
219   Standard_Real u1 = 0.0, u2 = 0.0, v1 = 0.0, v2 = 0.0;
220   POn2S.Parameters(u1,v1,u2,v2);
221
222   Standard_Boolean ret=
223             ((TheSvSurfaces *)PtrOnmySvSurfaces)->Tangency(u1, v1, u2, v2, TabVec(1));
224   if(!ret)
225   {
226     TabVec(1).SetCoord(0.0, 0.0, 0.0);
227   }
228
229   return ret;
230 }
231
232 //=======================================================================
233 //function : Tangency
234 //purpose  : 
235 //=======================================================================
236 Standard_Boolean ApproxInt_MultiLine::Tangency( const Standard_Integer Index,
237                                                 TColgp_Array1OfVec2d&  TabVec2d) const 
238 {
239   if(PtrOnmySvSurfaces==NULL) 
240     return Standard_False;
241
242   const IntSurf_PntOn2S& POn2S = myLine->Point(Index);
243   Standard_Real u1 = 0.0, u2 = 0.0, v1 = 0.0, v2 = 0.0;
244   POn2S.Parameters(u1,v1,u2,v2);
245
246   Standard_Boolean ret = Standard_False;
247   if(nbp2d==1)
248   { 
249     if(p2donfirst)
250     {
251       ret=((TheSvSurfaces *)PtrOnmySvSurfaces)->TangencyOnSurf1(u1, v1, u2, v2, TabVec2d(1));
252     }
253     else
254     { 
255       ret=((TheSvSurfaces *)PtrOnmySvSurfaces)->TangencyOnSurf2(u1, v1, u2, v2, TabVec2d(1));
256     }
257   }
258   else
259   {
260     ret=((TheSvSurfaces *)PtrOnmySvSurfaces)->TangencyOnSurf1(u1, v1, u2, v2, TabVec2d(1));
261     if(ret)
262     { 
263       if(TabVec2d.Length()>=2)
264       {
265         ret = 
266               (ret && 
267               ((TheSvSurfaces *)PtrOnmySvSurfaces)->
268                                           TangencyOnSurf2(u1, v1, u2, v2, TabVec2d(2)));
269       }
270     }
271   }
272
273   if(!ret)
274   {
275     TabVec2d(1) = gp_Vec2d(0.0, 0.0);
276     if(TabVec2d.Length() >= 2)
277     {
278       TabVec2d(2) = gp_Vec2d(0.0,0.0);
279     }
280   }
281
282   return ret;
283 }
284
285 //=======================================================================
286 //function : Tangency
287 //purpose  : 
288 //=======================================================================
289 Standard_Boolean ApproxInt_MultiLine::Tangency( const Standard_Integer Index,
290                                                 TColgp_Array1OfVec& TabVec,
291                                                 TColgp_Array1OfVec2d& TabVec2d) const
292
293   return (Tangency(Index, TabVec) && Tangency(Index, TabVec2d));
294 }
295
296 //=======================================================================
297 //function : MakeMLBetween
298 //purpose  : 
299 //=======================================================================
300 ApproxInt_MultiLine
301   ApproxInt_MultiLine::MakeMLBetween( const Standard_Integer Low,
302                                       const Standard_Integer High,
303                                       const Standard_Integer aNbPntsToInsert) const
304
305   if(PtrOnmySvSurfaces==NULL) {
306     //-- cout<<"\n Erreur dans : ApproxInt_MultiLine  ApproxInt_MultiLine::MakeMLBetween "<<endl;
307     Handle(IntSurf_LineOn2S) vide1 = new IntSurf_LineOn2S();
308     Handle(TheLine) vide = new TheLine(vide1,Standard_False);
309     return (ApproxInt_MultiLine(vide,
310                                 NULL,
311                                 nbp3d,
312                                 nbp2d,
313                                 myApproxU1V1, myApproxU2V2,
314                                 Xo,Yo,Zo,U1o,V1o,U2o,V2o,
315                                 p2donfirst,
316                                 1,1));
317     //-- return(*this);
318   }
319
320   Standard_Integer NbPntsToInsert=aNbPntsToInsert;
321   if(NbPntsToInsert<(High-Low)) NbPntsToInsert=(High-Low);
322   Standard_Integer NbPnts = NbPntsToInsert + High - Low + 1;
323   Standard_Integer NbPntsmin = High-Low;
324   NbPntsmin+=NbPntsmin;
325   
326   if(NbPnts<NbPntsmin) NbPnts=NbPntsmin;
327
328
329   gp_Vec T;
330   gp_Vec2d TS1,TS2;
331   gp_Pnt P;
332   
333   //-----------------------l-------------------------------------------
334   //--  Indice     :   Low       Low+1     I    I+1         High    --
335   //--                                                              --
336   //--  Abs.Curv.  :  S(Low)              S(I)  S(I+1)      S(High) --
337   //--                                                              --
338   //--                On echantillonne a abcisse curviligne         --
339   //--                constante.                                    --
340   //--                L abcisse est calculee sur les params U1,V1   --
341   //------------------------------------------------------------------
342   TColStd_Array1OfReal U1(Low,High);
343   TColStd_Array1OfReal V1(Low,High);
344   TColStd_Array1OfReal U2(Low,High);
345   TColStd_Array1OfReal V2(Low,High);
346   TColStd_Array1OfReal AC(Low,High);
347   Standard_Real s,ds;
348   
349   //------------------------------------------------------------
350   //-- Creation des Tableaux U1 .. V2 et AC
351   //-- 
352   Standard_Real u1,v1,u2,v2;
353   Standard_Integer i ;
354   myLine->Point(Low).Parameters(u1,v1,u2,v2);
355   U1(Low) = u1;
356   V1(Low) = v1;
357   U2(Low) = u2;
358   V2(Low) = v2;
359   AC(Low) =0.0;
360   
361 #if 0 
362   for( i=Low+1; i<=High; i++) { 
363     myLine->Point(i).Parameters(u1,v1,u2,v2);
364     U1(i) = u1;
365     V1(i) = v1;
366     U2(i) = u2;
367     V2(i) = v2;
368     
369     Standard_Real du1=u1-U1(i-1);
370     Standard_Real dv1=v1-V1(i-1);
371     
372     AC(i) = AC(i-1) + sqrt((du1*du1)+(dv1*dv1));
373   }
374 #else 
375   //-- Essai du 19 juin 96 (parametrage selon abs curv en XYZ)
376   for( i=Low+1; i<=High; i++) { 
377     myLine->Point(i).Parameters(u1,v1,u2,v2);
378     U1(i) = u1;
379     V1(i) = v1;
380     U2(i) = u2;
381     V2(i) = v2;    
382     AC(i) = AC(i-1) + (myLine->Point(i-1).Value()).Distance(myLine->Point(i).Value());
383   }
384
385 #endif
386   //-------------------------------------------------------------
387   //-- Creation des structures contenant les resultats
388   
389   Handle(IntSurf_LineOn2S) ResultPntOn2SLine = new IntSurf_LineOn2S();
390   
391   IntSurf_PntOn2S StartPOn2S;  
392   TColStd_Array1OfReal StartParams(1,4);  
393   
394   ds = AC(High) / (NbPnts-1);
395   Standard_Integer Indice = Low;
396   Standard_Boolean HasBeenInserted = Standard_False;
397   Standard_Real dsmin = ds*0.3;
398   Standard_Real smax  = AC(High);
399   
400   for(i=2,s=ds; (s < smax && Indice <= High-1); i++,s+=ds) { 
401     //----------------------------------------------------------
402     //-- Recherche des indices des points                     --
403     //-- Point           :    2       i       NbPnts-1        --
404     //-- s                            s                       --
405     //-- Current Indice tel que AC(Indice)<= s < AC(Indice+1) --
406     //----------------------------------------------------------
407     while(AC(Indice+1) <= s)
408     { 
409       if(!HasBeenInserted)
410         ResultPntOn2SLine->Add(myLine->Point(Indice));
411
412       HasBeenInserted = Standard_False;
413       Indice++;
414       if (Indice == High)
415         break;
416     }
417     
418     if (Indice == High)
419       break;
420     
421     if(!HasBeenInserted  && AC(Indice) <= s)
422     { 
423       ResultPntOn2SLine->Add(myLine->Point(Indice));
424       HasBeenInserted = Standard_True;
425     }
426     
427     Standard_Real a = s - AC(Indice);
428     Standard_Real b = AC(Indice+1) - s;
429     Standard_Real nab = 1.0/(a+b);
430     
431     //----------------------------------------------------------
432     //-- Verification :  Si Dist au prochain  point < dsmin   --
433     //--                 Si Dist au precedent point < dsmin   --
434     //--                                                      --
435     //----------------------------------------------------------
436     if((a>dsmin) && (b>dsmin))
437     {
438       u1 = (U1(Indice) * b   +  U1(Indice+1) * a) * nab;
439       v1 = (V1(Indice) * b   +  V1(Indice+1) * a) * nab;
440       u2 = (U2(Indice) * b   +  U2(Indice+1) * a) * nab;
441       v2 = (V2(Indice) * b   +  V2(Indice+1) * a) * nab;
442             
443       if(((TheSvSurfaces *)PtrOnmySvSurfaces)->Compute(u1,v1,u2,v2,P,T,TS1,TS2))
444       {
445         StartPOn2S.SetValue(P,u1,v1,u2,v2);
446         //-- cout<<" Insertion du point calcule : "<<u1<<","<<v1<<","<<u2<<","<<v2<<",";
447         //-- cout<<P.X()<<","<<P.Y()<<","<<P.Z()<<endl;
448         ResultPntOn2SLine->Add(StartPOn2S);
449       }
450       else
451       {
452         //-- cout<<" Probleme Non Traite ds ApproxInt_ApproxIntIntersection "<<endl;
453       }
454     }
455     else
456     {
457       //-- Point non situe a distance suffisante de 2 pts existants
458       //-- avec le point p[indice] deja insere
459       
460       if(b<0.0)
461       {
462         while(AC(Indice+1) <= s)
463         {
464           if(!HasBeenInserted)
465             ResultPntOn2SLine->Add(myLine->Point(Indice));
466
467           //-- cout<<" Insertion du point :"<<Indice<<endl;
468           HasBeenInserted = Standard_False;
469           Indice++;
470
471           if (Indice == High)
472             break;
473         }
474
475         if(Indice == High)
476           break;
477
478         if(!HasBeenInserted  && AC(Indice) <= s)
479         {
480           ResultPntOn2SLine->Add(myLine->Point(Indice));
481           HasBeenInserted = Standard_True;
482         }
483       }
484       else
485       {
486         s+= (dsmin - ds);
487       }
488     }
489   }
490   
491   ResultPntOn2SLine->Add(myLine->Point(High));     //--  Point NbPnts
492   Handle(TheLine) temp = new TheLine(ResultPntOn2SLine,Standard_False);
493   
494   //-- Verification   a posteriori 
495   //-- On verifie qu il n y a pas de virage trop important en 2d et en 3d
496   
497   temp->Point(1).Parameters(u1,v1,u2,v2);
498   gp_Pnt2d P1A(u1,v1);
499   gp_Pnt2d P2A(u2,v2);
500
501   temp->Point(2).Parameters(u1,v1,u2,v2);
502   gp_Pnt2d P1B(u1,v1);
503   gp_Pnt2d P2B(u2,v2);
504
505   gp_Pnt2d P1C,P2C;
506
507   Standard_Integer CodeErreur=0; 
508   
509   for(i=3,NbPnts=temp->NbPnts();CodeErreur==0 &&  i<=NbPnts; i++)
510   {
511     Standard_Real d,du,dv,duv2;
512     temp->Point(i).Parameters(u1,v1,u2,v2);
513     //-- Virage P1A P1B P1C
514     P1C.SetCoord(u1,v1);
515     du  = P1B.X()-P1A.X();
516     dv  = P1B.Y()-P1A.Y();
517     duv2= 0.25*(du*du+dv*dv);
518     u1 = P1B.X() + du;
519     v1 = P1B.Y() + dv;
520     du = P1C.X() - u1;
521     dv = P1C.Y() - v1;
522     d = du*du+dv*dv;
523     if(d>duv2)
524     { 
525       CodeErreur = 1;
526       CodeErreur = 1;
527       break;
528     }
529     
530     //-- Virage P2A P2B P2C
531     P2C.SetCoord(u2,v2);
532     du  = P2B.X()-P2A.X();
533     dv  = P2B.Y()-P2A.Y();
534     duv2= 0.25*(du*du+dv*dv);
535     u2 = P2B.X() + du;
536     v2 = P2B.Y() + dv;
537     du = P2C.X() - u2;
538     dv = P2C.Y() - v2;
539     d = du*du+dv*dv;
540     if(d>duv2)
541     {
542       CodeErreur = 2;
543       break;
544     }
545     
546     P1A=P1B;
547     P2A=P2B;
548     P1B=P1C;
549     P2B=P2C;
550   }
551
552 #if OCCT_DEBUG
553   //if (temp->NbPnts() < NbPntsToInsert + High - Low + 1)
554   //{ 
555   //  cout<<" *** Pas assez de points entre :"<<
556   //            Low<<" et "<<High<<" -> "<<temp->NbPnts()<<endl;
557   //}
558
559   //if(CodeErreur)
560   //{ 
561   //  cout<<" *** CodeErreur : "<<CodeErreur<<endl;
562   //}
563 #endif
564
565   if((temp->NbPnts() >= NbPntsToInsert + High - Low + 1) && (CodeErreur==0))
566   {
567     return (ApproxInt_MultiLine( temp, 
568                                  (High-Low>10)? PtrOnmySvSurfaces : NULL,
569                                  nbp3d,
570                                  nbp2d,
571                                  myApproxU1V1, myApproxU2V2,
572                                  Xo,Yo,Zo,
573                                  U1o,V1o,
574                                  U2o,V2o,
575                                  p2donfirst,
576                                  1,ResultPntOn2SLine->NbPoints()));
577   }
578   else
579   {
580     //-- cout<<" ApproxInt_MultiLine "<<endl;
581     //-- cout<<" Pas de Rajout de points ds1min =  "<<minds1<<" ds2min = "<<minds2<<endl;
582     Handle(IntSurf_LineOn2S) vide1 = new IntSurf_LineOn2S();
583     Handle(TheLine) vide = new TheLine(vide1,Standard_False);
584     return (ApproxInt_MultiLine( vide,
585                                  NULL,
586                                  nbp3d,
587                                  nbp2d,
588                                  myApproxU1V1, myApproxU2V2,
589                                  Xo,Yo,Zo,
590                                  U1o,V1o,
591                                 U2o,V2o,
592                                  p2donfirst,
593                                  1,1));
594   }
595 }
596
597 //=======================================================================
598 //function : MakeMLOneMorePoint
599 //purpose  : 
600 //=======================================================================
601 Standard_Boolean
602   ApproxInt_MultiLine::MakeMLOneMorePoint(const Standard_Integer theLow,
603                                           const Standard_Integer theHigh,
604                                           const Standard_Integer theIndbad,
605                                           ApproxInt_MultiLine& theNewMultiLine) const
606 {
607   Standard_Boolean OtherLineMade = Standard_False;
608   if(PtrOnmySvSurfaces==NULL)
609     return Standard_False;
610   
611   const Standard_Real SqTol3d = Precision::SquareConfusion();
612   math_Vector tolerance(1,2);
613   tolerance(1) = tolerance(2) = 1.e-8;
614   
615   Handle(IntSurf_LineOn2S) ResultPntOn2SLine = new IntSurf_LineOn2S();
616   for (Standard_Integer Indice = theLow; Indice <= theHigh; Indice++)
617     ResultPntOn2SLine->Add(myLine->Point(Indice));
618
619   //Insert new point between (theIndbad-1) and theIndbad
620   //Using <thePtrSVSurf> for Rsnld: it may be ImpPrm or PrmPrm
621   gp_Pnt PrevPnt = myLine->Point(theIndbad-1).Value();
622   gp_Pnt CurPnt  = myLine->Point(theIndbad).Value();
623   Standard_Real uprev1, vprev1, uprev2, vprev2, ucur1, vcur1, ucur2, vcur2;
624   myLine->Point(theIndbad-1).Parameters(uprev1, vprev1, uprev2, vprev2);
625   myLine->Point(theIndbad).Parameters(ucur1, vcur1, ucur2, vcur2);
626   Standard_Real umid1, vmid1, umid2, vmid2;
627   umid1 = (uprev1 + ucur1)/2;
628   vmid1 = (vprev1 + vcur1)/2;
629   umid2 = (uprev2 + ucur2)/2;
630   vmid2 = (vprev2 + vcur2)/2;
631   IntSurf_PntOn2S MidPoint;
632   Standard_Boolean IsNewPointInvalid = Standard_False;
633   IsNewPointInvalid =
634     myApproxU1V1 &&
635     Abs(ucur1 - umid1) <= tolerance(1) &&
636     Abs(vcur1 - vmid1) <= tolerance(2);
637   if (!IsNewPointInvalid)
638   {
639     IsNewPointInvalid =
640       myApproxU2V2 &&
641       Abs(ucur2 - umid2) <= tolerance(1) &&
642       Abs(vcur2 - vmid2) <= tolerance(2);
643     if (!IsNewPointInvalid &&
644         ((TheSvSurfaces *)PtrOnmySvSurfaces)->SeekPoint(umid1, vmid1, umid2, vmid2,
645                                                         MidPoint))
646     {
647       const gp_Pnt& NewPnt = MidPoint.Value();
648       Standard_Real SqDistNewPrev = NewPnt.SquareDistance(PrevPnt);
649       Standard_Real SqDistNewCur  = NewPnt.SquareDistance(CurPnt);
650       IsNewPointInvalid = (SqDistNewPrev <= SqTol3d ||
651                            SqDistNewCur  <= SqTol3d);
652       if (!IsNewPointInvalid)
653       {
654         Standard_Real unew1, vnew1, unew2, vnew2;
655         MidPoint.Parameters(unew1, vnew1, unew2, vnew2);
656         if (myApproxU1V1)
657         {
658           Standard_Real SqDistCurMid1 =
659             (ucur1 - umid1)*(ucur1 - umid1)+(vcur1 - vmid1)*(vcur1 - vmid1);
660           Standard_Real SqDistMidNew1 =
661             (umid1 - unew1)*(umid1 - unew1)+(vmid1 - vnew1)*(vmid1 - vnew1);
662           IsNewPointInvalid = (SqDistMidNew1 > SqDistCurMid1);
663         }
664         if (!IsNewPointInvalid)
665         {
666           if (myApproxU2V2)
667           {
668             Standard_Real SqDistCurMid2 =
669               (ucur2 - umid2)*(ucur2 - umid2)+(vcur2 - vmid2)*(vcur2 - vmid2);
670             Standard_Real SqDistMidNew2 =
671               (umid2 - unew2)*(umid2 - unew2)+(vmid2 - vnew2)*(vmid2 - vnew2);
672             IsNewPointInvalid = (SqDistMidNew2 > SqDistCurMid2);
673           }
674           if (!IsNewPointInvalid)
675           {
676             ResultPntOn2SLine->InsertBefore(theIndbad-theLow+1, MidPoint);
677             OtherLineMade = Standard_True;
678           }
679         }
680       }
681     }
682   }
683
684   if (!OtherLineMade)
685     return Standard_False;
686
687 #ifdef DRAW
688   char* name = new char[100];
689   Standard_Integer indc = 1;
690   Standard_Boolean onfirst = Standard_True;
691   for (Standard_Integer i = 1; i <= ResultPntOn2SLine->NbPoints(); i++)
692   {
693     const IntSurf_PntOn2S& thePoint = ResultPntOn2SLine->Value(i);
694     gp_Pnt curPnt = thePoint.Value();
695     sprintf(name, "p%d_%d", indc, i);
696     DrawTrSurf::Set(name, curPnt);
697     gp_Pnt2d curPnt2d = thePoint.ValueOnSurface(onfirst);
698     sprintf(name, "pp%d_%d", indc, i);
699     DrawTrSurf::Set(name, curPnt2d);
700   }
701 #endif
702   Handle(TheLine) temp = new TheLine(ResultPntOn2SLine,Standard_False);
703   theNewMultiLine = ApproxInt_MultiLine( temp, 
704                                          PtrOnmySvSurfaces,
705                                          nbp3d,
706                                          nbp2d,
707                                          myApproxU1V1,
708                                          myApproxU2V2,
709                                          Xo,Yo,Zo,
710                                          U1o,V1o,
711                                          U2o,V2o,
712                                          p2donfirst,
713                                          1,ResultPntOn2SLine->NbPoints());
714   return Standard_True;
715 }
716
717 //=======================================================================
718 //function : Dump
719 //purpose  : 
720 //=======================================================================
721 void ApproxInt_MultiLine::Dump() const
722 {
723   TColgp_Array1OfPnt anArr1(1, 1);
724   TColgp_Array1OfPnt2d anArr2(1, 2);
725         
726   const Standard_Integer  anIndF = FirstPoint(),
727                           anIndL = LastPoint();
728         
729   for(Standard_Integer ind = anIndF; ind <= anIndL; ind++)
730   {
731     Value(ind, anArr1, anArr2);
732     printf("%4d  [%+10.20f %+10.20f %+10.20f]  "
733             "[%+10.20f %+10.20f]  [%+10.20f %+10.20f]\n",
734       ind, anArr1(1).X(), anArr1(1).Y(), anArr1(1).Z(), anArr2(1).X(),
735       anArr2(1).Y(),anArr2(2).X(),anArr2(2).Y());
736   }
737 }
738