0022048: Visualization, AIS_InteractiveContext - single object selection should alway...
[occt.git] / src / ApproxInt / ApproxInt_MultiLine.gxx
CommitLineData
b311480e 1// Created on: 1993-03-22
2// Created by: Laurent BUCHARD
3// Copyright (c) 1993-1999 Matra Datavision
973c2be1 4// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 5//
973c2be1 6// This file is part of Open CASCADE Technology software library.
b311480e 7//
d5f74e42 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
973c2be1 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.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
7fd59977 16
7fd59977 17#include <TColStd_Array1OfReal.hxx>
7fd59977 18#include <gp_Pnt2d.hxx>
19#include <gp_Pnt.hxx>
20#include <gp_Vec2d.hxx>
21#include <gp_Vec.hxx>
4e14c88f 22#include <IntSurf_LineOn2S.hxx>
2c26a53d 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//=======================================================================
34ApproxInt_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}
7fd59977 53
4e14c88f 54//=======================================================================
55//function : Constructor
56//purpose :
57//=======================================================================
58ApproxInt_MultiLine::
59 ApproxInt_MultiLine(const Handle_TheLine& line,
60 const Standard_Address svsurf,
61 const Standard_Integer NbP3d,
62 const Standard_Integer NbP2d,
2c26a53d 63 const Standard_Boolean ApproxU1V1,
64 const Standard_Boolean ApproxU2V2,
4e14c88f 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),
2c26a53d 79 myApproxU1V1(ApproxU1V1),
80 myApproxU2V2(ApproxU2V2),
4e14c88f 81 p2donfirst(P2DOnFirst),
82 Xo(xo), Yo(yo), Zo(zo),
83 U1o(u1o), V1o(v1o),
84 U2o(u2o), V2o(v2o)
7fd59977 85
4e14c88f 86{
87#if OCCT_DEBUG
88 //if(indicemin == indicemax)
89 //{
90 // cout<<"ApproxInt_MultiLine: indicemin = indicemax = " << indicemin << endl;
91 //}
7fd59977 92#endif
93}
4e14c88f 94
95//=======================================================================
96//function : Constructor
97//purpose :
98//=======================================================================
99ApproxInt_MultiLine::
100 ApproxInt_MultiLine(const Handle_TheLine& line,
101 const Standard_Integer NbP3d,
102 const Standard_Integer NbP2d,
2c26a53d 103 const Standard_Boolean ApproxU1V1,
104 const Standard_Boolean ApproxU2V2,
4e14c88f 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),
2c26a53d 119 myApproxU1V1(ApproxU1V1),
120 myApproxU2V2(ApproxU2V2),
4e14c88f 121 p2donfirst(P2DOnFirst),
122 Xo(xo), Yo(yo), Zo(zo),
123 U1o(u1o), V1o(v1o),
124 U2o(u2o), V2o(v2o)
7fd59977 125{
4e14c88f 126#if OCCT_DEBUG
127 //if(indicemin == indicemax)
128 //{
129 // cout<<"ApproxInt_MultiLine: indicemin = indicemax = " << indicemin << endl;
130 //}
7fd59977 131#endif
7fd59977 132}
4e14c88f 133
7fd59977 134//--------------------------------------------------------------------------------
135Standard_Integer ApproxInt_MultiLine::FirstPoint() const {
2c26a53d 136 return indicemin;
7fd59977 137}
138//--------------------------------------------------------------------------------
139Standard_Integer ApproxInt_MultiLine::LastPoint() const {
2c26a53d 140 return indicemax;
7fd59977 141}
142//--------------------------------------------------------------------------------
143Approx_Status ApproxInt_MultiLine::WhatStatus() const {
144 if(PtrOnmySvSurfaces)
2c26a53d 145 return Approx_PointsAdded;
7fd59977 146 else
2c26a53d 147 return Approx_NoPointsAdded;
7fd59977 148}
149//--------------------------------------------------------------------------------
150Standard_Integer ApproxInt_MultiLine::NbP3d() const {
2c26a53d 151 return nbp3d;
7fd59977 152}
153//--------------------------------------------------------------------------------
154Standard_Integer ApproxInt_MultiLine::NbP2d() const {
2c26a53d 155 return nbp2d;
7fd59977 156}
157//================================================================================
158void ApproxInt_MultiLine::Value(const Standard_Integer Index,
4e14c88f 159 TColgp_Array1OfPnt& TabPnt) const
7fd59977 160{
4e14c88f 161 const gp_Pnt& aP = myLine->Point(Index).Value();
162 TabPnt(1).SetCoord(aP.X()+Xo, aP.Y()+Yo, aP.Z()+Zo);
7fd59977 163}
4e14c88f 164
165//=======================================================================
166//function : Value
167//purpose :
168//=======================================================================
169void ApproxInt_MultiLine::Value(const Standard_Integer Index,
170 TColgp_Array1OfPnt2d& TabPnt2d) const
7fd59977 171{
172 IntSurf_PntOn2S POn2S(myLine->Point(Index));
4e14c88f 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);
7fd59977 180 }
4e14c88f 181 else
182 {
183 TabPnt2d(1).SetCoord(u2+U2o, v2+V2o);
7fd59977 184 }
185 }
4e14c88f 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);
7fd59977 192 }
193 }
194}
4e14c88f 195
196//=======================================================================
197//function : Value
198//purpose :
199//=======================================================================
200void ApproxInt_MultiLine::Value(const Standard_Integer Index,
201 TColgp_Array1OfPnt& TabPnt,
202 TColgp_Array1OfPnt2d& TabPnt2d) const
7fd59977 203{
4e14c88f 204 Value(Index, TabPnt);
205 Value(Index, TabPnt2d);
7fd59977 206}
4e14c88f 207
208//=======================================================================
209//function : Tangency
210//purpose :
211//=======================================================================
212Standard_Boolean ApproxInt_MultiLine::Tangency( const Standard_Integer Index,
213 TColgp_Array1OfVec& TabVec) const
214{
7fd59977 215 if(PtrOnmySvSurfaces==NULL)
4e14c88f 216 return Standard_False;
7fd59977 217
4e14c88f 218 const IntSurf_PntOn2S& POn2S = myLine->Point(Index);
219 Standard_Real u1 = 0.0, u2 = 0.0, v1 = 0.0, v2 = 0.0;
7fd59977 220 POn2S.Parameters(u1,v1,u2,v2);
4e14c88f 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);
7fd59977 227 }
4e14c88f 228
229 return ret;
7fd59977 230}
4e14c88f 231
232//=======================================================================
233//function : Tangency
234//purpose :
235//=======================================================================
236Standard_Boolean ApproxInt_MultiLine::Tangency( const Standard_Integer Index,
237 TColgp_Array1OfVec2d& TabVec2d) const
238{
7fd59977 239 if(PtrOnmySvSurfaces==NULL)
4e14c88f 240 return Standard_False;
7fd59977 241
4e14c88f 242 const IntSurf_PntOn2S& POn2S = myLine->Point(Index);
243 Standard_Real u1 = 0.0, u2 = 0.0, v1 = 0.0, v2 = 0.0;
7fd59977 244 POn2S.Parameters(u1,v1,u2,v2);
4e14c88f 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));
7fd59977 252 }
4e14c88f 253 else
254 {
255 ret=((TheSvSurfaces *)PtrOnmySvSurfaces)->TangencyOnSurf2(u1, v1, u2, v2, TabVec2d(1));
7fd59977 256 }
7fd59977 257 }
4e14c88f 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)));
7fd59977 269 }
270 }
271 }
7fd59977 272
4e14c88f 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);
7fd59977 279 }
280 }
7fd59977 281
4e14c88f 282 return ret;
283}
7fd59977 284
4e14c88f 285//=======================================================================
286//function : Tangency
287//purpose :
288//=======================================================================
289Standard_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}
7fd59977 295
4e14c88f 296//=======================================================================
297//function : MakeMLBetween
298//purpose :
299//=======================================================================
300ApproxInt_MultiLine
301 ApproxInt_MultiLine::MakeMLBetween( const Standard_Integer Low,
302 const Standard_Integer High,
303 const Standard_Integer aNbPntsToInsert) const
304{
7fd59977 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);
2c26a53d 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));
7fd59977 317 //-- return(*this);
318 }
4e14c88f 319
7fd59977 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
7fd59977 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;
4e14c88f 382 AC(i) = AC(i-1) + (myLine->Point(i-1).Value()).Distance(myLine->Point(i).Value());
7fd59977 383 }
384
385#endif
386 //-------------------------------------------------------------
387 //-- Creation des structures contenant les resultats
388
4e14c88f 389 Handle(IntSurf_LineOn2S) ResultPntOn2SLine = new IntSurf_LineOn2S();
7fd59977 390
391 IntSurf_PntOn2S StartPOn2S;
4e14c88f 392 TColStd_Array1OfReal StartParams(1,4);
7fd59977 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
39408dc0 400 for(i=2,s=ds; (s < smax && Indice <= High-1); i++,s+=ds) {
7fd59977 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 //----------------------------------------------------------
4e14c88f 407 while(AC(Indice+1) <= s)
408 {
409 if(!HasBeenInserted)
410 ResultPntOn2SLine->Add(myLine->Point(Indice));
411
7fd59977 412 HasBeenInserted = Standard_False;
413 Indice++;
39408dc0
J
414 if (Indice == High)
415 break;
7fd59977 416 }
39408dc0
J
417
418 if (Indice == High)
419 break;
420
4e14c88f 421 if(!HasBeenInserted && AC(Indice) <= s)
422 {
7fd59977 423 ResultPntOn2SLine->Add(myLine->Point(Indice));
424 HasBeenInserted = Standard_True;
425 }
4e14c88f 426
7fd59977 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 //----------------------------------------------------------
4e14c88f 436 if((a>dsmin) && (b>dsmin))
437 {
7fd59977 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;
4e14c88f 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);
7fd59977 449 }
4e14c88f 450 else
451 {
452 //-- cout<<" Probleme Non Traite ds ApproxInt_ApproxIntIntersection "<<endl;
7fd59977 453 }
454 }
4e14c88f 455 else
456 {
7fd59977 457 //-- Point non situe a distance suffisante de 2 pts existants
458 //-- avec le point p[indice] deja insere
459
4e14c88f 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
39408dc0
J
471 if (Indice == High)
472 break;
4e14c88f 473 }
474
475 if(Indice == High)
39408dc0 476 break;
4e14c88f 477
478 if(!HasBeenInserted && AC(Indice) <= s)
479 {
480 ResultPntOn2SLine->Add(myLine->Point(Indice));
481 HasBeenInserted = Standard_True;
482 }
7fd59977 483 }
4e14c88f 484 else
485 {
486 s+= (dsmin - ds);
7fd59977 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
4e14c88f 509 for(i=3,NbPnts=temp->NbPnts();CodeErreur==0 && i<=NbPnts; i++)
510 {
7fd59977 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;
4e14c88f 523 if(d>duv2)
524 {
7fd59977 525 CodeErreur = 1;
526 CodeErreur = 1;
527 break;
528 }
4e14c88f 529
7fd59977 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;
4e14c88f 540 if(d>duv2)
541 {
7fd59977 542 CodeErreur = 2;
543 break;
544 }
4e14c88f 545
7fd59977 546 P1A=P1B;
547 P2A=P2B;
548 P1B=P1C;
549 P2B=P2C;
550 }
4e14c88f 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 //}
7fd59977 563#endif
4e14c88f 564
565 if((temp->NbPnts() >= NbPntsToInsert + High - Low + 1) && (CodeErreur==0))
566 {
2c26a53d 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()));
7fd59977 577 }
4e14c88f 578 else
579 {
7fd59977 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);
2c26a53d 584 return (ApproxInt_MultiLine( vide,
585 NULL,
586 nbp3d,
587 nbp2d,
588 myApproxU1V1, myApproxU2V2,
589 Xo,Yo,Zo,
590 U1o,V1o,
4e14c88f 591 U2o,V2o,
2c26a53d 592 p2donfirst,
593 1,1));
594 }
595}
596
597//=======================================================================
598//function : MakeMLOneMorePoint
599//purpose :
600//=======================================================================
601Standard_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);
7fd59977 700 }
2c26a53d 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;
7fd59977 715}
7fd59977 716
4e14c88f 717//=======================================================================
718//function : Dump
719//purpose :
720//=======================================================================
7c32c7c4 721void ApproxInt_MultiLine::Dump() const
722{
723 TColgp_Array1OfPnt anArr1(1, 1);
724 TColgp_Array1OfPnt2d anArr2(1, 2);
725
4e14c88f 726 const Standard_Integer anIndF = FirstPoint(),
727 anIndL = LastPoint();
728
729 for(Standard_Integer ind = anIndF; ind <= anIndL; ind++)
7c32c7c4 730 {
731 Value(ind, anArr1, anArr2);
4e14c88f 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());
7c32c7c4 736 }
737}
738