Warning, /include/opencascade/ApproxInt_MultiLine.gxx is written in an unsupported language. File is not indexed.
0001 // Created on: 1993-03-22
0002 // Created by: Laurent BUCHARD
0003 // Copyright (c) 1993-1999 Matra Datavision
0004 // Copyright (c) 1999-2014 OPEN CASCADE SAS
0005 //
0006 // This file is part of Open CASCADE Technology software library.
0007 //
0008 // This library is free software; you can redistribute it and/or modify it under
0009 // the terms of the GNU Lesser General Public License version 2.1 as published
0010 // by the Free Software Foundation, with special exception defined in the file
0011 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
0012 // distribution for complete text of the license and disclaimer of any warranty.
0013 //
0014 // Alternatively, this file may be used under the terms of Open CASCADE
0015 // commercial license or contractual agreement.
0016
0017 #include <TColStd_Array1OfReal.hxx>
0018 #include <gp_Pnt2d.hxx>
0019 #include <gp_Pnt.hxx>
0020 #include <gp_Vec2d.hxx>
0021 #include <gp_Vec.hxx>
0022 #include <IntSurf_LineOn2S.hxx>
0023 #include <Precision.hxx>
0024 #include <math_Vector.hxx>
0025
0026 #ifdef DRAW
0027 #include <DrawTrSurf.hxx>
0028 #endif
0029
0030 //=======================================================================
0031 //function : Constructor
0032 //purpose :
0033 //=======================================================================
0034 ApproxInt_MultiLine::ApproxInt_MultiLine()
0035 {
0036 PtrOnmySvSurfaces = NULL;
0037 myLine = NULL;
0038 indicemin = 0;
0039 indicemax = 0;
0040 nbp3d = 0;
0041 nbp2d = 0;
0042 myApproxU1V1 = Standard_False;
0043 myApproxU2V2 = Standard_False;
0044 p2donfirst = Standard_True;
0045 Xo = 0.;
0046 Yo = 0.;
0047 Zo = 0.;
0048 U1o = 0.;
0049 V1o = 0.;
0050 U2o = 0.;
0051 V2o = 0.;
0052 }
0053
0054 //=======================================================================
0055 //function : Constructor
0056 //purpose :
0057 //=======================================================================
0058 ApproxInt_MultiLine::
0059 ApproxInt_MultiLine(const Handle_TheLine& line,
0060 const Standard_Address svsurf,
0061 const Standard_Integer NbP3d,
0062 const Standard_Integer NbP2d,
0063 const Standard_Boolean ApproxU1V1,
0064 const Standard_Boolean ApproxU2V2,
0065 const Standard_Real xo,
0066 const Standard_Real yo,
0067 const Standard_Real zo,
0068 const Standard_Real u1o,
0069 const Standard_Real v1o,
0070 const Standard_Real u2o,
0071 const Standard_Real v2o,
0072 const Standard_Boolean P2DOnFirst,
0073 const Standard_Integer IndMin,
0074 const Standard_Integer IndMax): PtrOnmySvSurfaces(svsurf),
0075 myLine(line),
0076 indicemin(Min(IndMin, IndMax)),
0077 indicemax(Max(IndMin, IndMax)),
0078 nbp3d(NbP3d), nbp2d(NbP2d),
0079 myApproxU1V1(ApproxU1V1),
0080 myApproxU2V2(ApproxU2V2),
0081 p2donfirst(P2DOnFirst),
0082 Xo(xo), Yo(yo), Zo(zo),
0083 U1o(u1o), V1o(v1o),
0084 U2o(u2o), V2o(v2o)
0085
0086 {
0087 #ifdef OCCT_DEBUG
0088 //if(indicemin == indicemax)
0089 //{
0090 // cout<<"ApproxInt_MultiLine: indicemin = indicemax = " << indicemin << endl;
0091 //}
0092 #endif
0093 }
0094
0095 //=======================================================================
0096 //function : Constructor
0097 //purpose :
0098 //=======================================================================
0099 ApproxInt_MultiLine::
0100 ApproxInt_MultiLine(const Handle_TheLine& line,
0101 const Standard_Integer NbP3d,
0102 const Standard_Integer NbP2d,
0103 const Standard_Boolean ApproxU1V1,
0104 const Standard_Boolean ApproxU2V2,
0105 const Standard_Real xo,
0106 const Standard_Real yo,
0107 const Standard_Real zo,
0108 const Standard_Real u1o,
0109 const Standard_Real v1o,
0110 const Standard_Real u2o,
0111 const Standard_Real v2o,
0112 const Standard_Boolean P2DOnFirst,
0113 const Standard_Integer IndMin,
0114 const Standard_Integer IndMax): PtrOnmySvSurfaces(0),
0115 myLine(line),
0116 indicemin(Min(IndMin, IndMax)),
0117 indicemax(Max(IndMin, IndMax)),
0118 nbp3d(NbP3d), nbp2d(NbP2d),
0119 myApproxU1V1(ApproxU1V1),
0120 myApproxU2V2(ApproxU2V2),
0121 p2donfirst(P2DOnFirst),
0122 Xo(xo), Yo(yo), Zo(zo),
0123 U1o(u1o), V1o(v1o),
0124 U2o(u2o), V2o(v2o)
0125 {
0126 #ifdef OCCT_DEBUG
0127 //if(indicemin == indicemax)
0128 //{
0129 // cout<<"ApproxInt_MultiLine: indicemin = indicemax = " << indicemin << endl;
0130 //}
0131 #endif
0132 }
0133
0134 //--------------------------------------------------------------------------------
0135 Standard_Integer ApproxInt_MultiLine::FirstPoint() const {
0136 return indicemin;
0137 }
0138 //--------------------------------------------------------------------------------
0139 Standard_Integer ApproxInt_MultiLine::LastPoint() const {
0140 return indicemax;
0141 }
0142 //--------------------------------------------------------------------------------
0143 Approx_Status ApproxInt_MultiLine::WhatStatus() const {
0144 if(PtrOnmySvSurfaces)
0145 return Approx_PointsAdded;
0146 else
0147 return Approx_NoPointsAdded;
0148 }
0149 //--------------------------------------------------------------------------------
0150 Standard_Integer ApproxInt_MultiLine::NbP3d() const {
0151 return nbp3d;
0152 }
0153 //--------------------------------------------------------------------------------
0154 Standard_Integer ApproxInt_MultiLine::NbP2d() const {
0155 return nbp2d;
0156 }
0157 //================================================================================
0158 void ApproxInt_MultiLine::Value(const Standard_Integer Index,
0159 TColgp_Array1OfPnt& TabPnt) const
0160 {
0161 const gp_Pnt aP = myLine->Point(Index).Value();
0162 TabPnt(1).SetCoord(aP.X()+Xo, aP.Y()+Yo, aP.Z()+Zo);
0163 }
0164
0165 //=======================================================================
0166 //function : Value
0167 //purpose :
0168 //=======================================================================
0169 void ApproxInt_MultiLine::Value(const Standard_Integer Index,
0170 TColgp_Array1OfPnt2d& TabPnt2d) const
0171 {
0172 IntSurf_PntOn2S POn2S(myLine->Point(Index));
0173 Standard_Real u1 = 0.0, u2 = 0.0, v1 = 0.0, v2 = 0.0;
0174 POn2S.Parameters(u1, v1, u2, v2);
0175 if(nbp2d==1)
0176 {
0177 if(p2donfirst)
0178 {
0179 TabPnt2d(1).SetCoord(u1+U1o, v1+V1o);
0180 }
0181 else
0182 {
0183 TabPnt2d(1).SetCoord(u2+U2o, v2+V2o);
0184 }
0185 }
0186 else
0187 {
0188 TabPnt2d(1).SetCoord(u1+U1o, v1+V1o);
0189 if(TabPnt2d.Length() >= 2)
0190 {
0191 TabPnt2d(2).SetCoord(u2+U2o, v2+V2o);
0192 }
0193 }
0194 }
0195
0196 //=======================================================================
0197 //function : Value
0198 //purpose :
0199 //=======================================================================
0200 void ApproxInt_MultiLine::Value(const Standard_Integer Index,
0201 TColgp_Array1OfPnt& TabPnt,
0202 TColgp_Array1OfPnt2d& TabPnt2d) const
0203 {
0204 Value(Index, TabPnt);
0205 Value(Index, TabPnt2d);
0206 }
0207
0208 //=======================================================================
0209 //function : Tangency
0210 //purpose :
0211 //=======================================================================
0212 Standard_Boolean ApproxInt_MultiLine::Tangency( const Standard_Integer Index,
0213 TColgp_Array1OfVec& TabVec) const
0214 {
0215 if(PtrOnmySvSurfaces==NULL)
0216 return Standard_False;
0217
0218 const IntSurf_PntOn2S& POn2S = myLine->Point(Index);
0219 Standard_Real u1 = 0.0, u2 = 0.0, v1 = 0.0, v2 = 0.0;
0220 POn2S.Parameters(u1,v1,u2,v2);
0221
0222 Standard_Boolean ret=
0223 ((TheSvSurfaces *)PtrOnmySvSurfaces)->Tangency(u1, v1, u2, v2, TabVec(1));
0224 if(!ret)
0225 {
0226 TabVec(1).SetCoord(0.0, 0.0, 0.0);
0227 }
0228
0229 return ret;
0230 }
0231
0232 //=======================================================================
0233 //function : Tangency
0234 //purpose :
0235 //=======================================================================
0236 Standard_Boolean ApproxInt_MultiLine::Tangency( const Standard_Integer Index,
0237 TColgp_Array1OfVec2d& TabVec2d) const
0238 {
0239 if(PtrOnmySvSurfaces==NULL)
0240 return Standard_False;
0241
0242 const IntSurf_PntOn2S& POn2S = myLine->Point(Index);
0243 Standard_Real u1 = 0.0, u2 = 0.0, v1 = 0.0, v2 = 0.0;
0244 POn2S.Parameters(u1,v1,u2,v2);
0245
0246 Standard_Boolean ret = Standard_False;
0247 if(nbp2d==1)
0248 {
0249 if(p2donfirst)
0250 {
0251 ret=((TheSvSurfaces *)PtrOnmySvSurfaces)->TangencyOnSurf1(u1, v1, u2, v2, TabVec2d(1));
0252 }
0253 else
0254 {
0255 ret=((TheSvSurfaces *)PtrOnmySvSurfaces)->TangencyOnSurf2(u1, v1, u2, v2, TabVec2d(1));
0256 }
0257 }
0258 else
0259 {
0260 ret=((TheSvSurfaces *)PtrOnmySvSurfaces)->TangencyOnSurf1(u1, v1, u2, v2, TabVec2d(1));
0261 if(ret)
0262 {
0263 if(TabVec2d.Length()>=2)
0264 {
0265 ret =
0266 (ret &&
0267 ((TheSvSurfaces *)PtrOnmySvSurfaces)->
0268 TangencyOnSurf2(u1, v1, u2, v2, TabVec2d(2)));
0269 }
0270 }
0271 }
0272
0273 if(!ret)
0274 {
0275 TabVec2d(1) = gp_Vec2d(0.0, 0.0);
0276 if(TabVec2d.Length() >= 2)
0277 {
0278 TabVec2d(2) = gp_Vec2d(0.0,0.0);
0279 }
0280 }
0281
0282 return ret;
0283 }
0284
0285 //=======================================================================
0286 //function : Tangency
0287 //purpose :
0288 //=======================================================================
0289 Standard_Boolean ApproxInt_MultiLine::Tangency( const Standard_Integer Index,
0290 TColgp_Array1OfVec& TabVec,
0291 TColgp_Array1OfVec2d& TabVec2d) const
0292 {
0293 return (Tangency(Index, TabVec) && Tangency(Index, TabVec2d));
0294 }
0295
0296 //=======================================================================
0297 //function : MakeMLBetween
0298 //purpose :
0299 //=======================================================================
0300 ApproxInt_MultiLine
0301 ApproxInt_MultiLine::MakeMLBetween( const Standard_Integer Low,
0302 const Standard_Integer High,
0303 const Standard_Integer aNbPntsToInsert) const
0304 {
0305 if(PtrOnmySvSurfaces==NULL) {
0306 //-- cout<<"\n Erreur dans : ApproxInt_MultiLine ApproxInt_MultiLine::MakeMLBetween "<<endl;
0307 Handle(IntSurf_LineOn2S) vide1 = new IntSurf_LineOn2S();
0308 Handle(TheLine) vide = new TheLine(vide1,Standard_False);
0309 return (ApproxInt_MultiLine(vide,
0310 NULL,
0311 nbp3d,
0312 nbp2d,
0313 myApproxU1V1, myApproxU2V2,
0314 Xo,Yo,Zo,U1o,V1o,U2o,V2o,
0315 p2donfirst,
0316 1,1));
0317 //-- return(*this);
0318 }
0319
0320 Standard_Boolean aSaveUseSolver = ((TheSvSurfaces *)PtrOnmySvSurfaces)->GetUseSolver();
0321 if (!aSaveUseSolver)
0322 {
0323 ((TheSvSurfaces *)PtrOnmySvSurfaces)->SetUseSolver(Standard_True);
0324 }
0325 Standard_Integer NbPntsToInsert=aNbPntsToInsert;
0326 if(NbPntsToInsert<(High-Low)) NbPntsToInsert=(High-Low);
0327 Standard_Integer NbPnts = NbPntsToInsert + High - Low + 1;
0328 Standard_Integer NbPntsmin = High-Low;
0329 NbPntsmin+=NbPntsmin;
0330
0331 if(NbPnts<NbPntsmin) NbPnts=NbPntsmin;
0332
0333
0334 gp_Vec T;
0335 gp_Vec2d TS1,TS2;
0336 gp_Pnt P;
0337
0338 //-----------------------l-------------------------------------------
0339 //-- Indice : Low Low+1 I I+1 High --
0340 //-- --
0341 //-- Abs.Curv. : S(Low) S(I) S(I+1) S(High) --
0342 //-- --
0343 //-- On echantillonne a abcisse curviligne --
0344 //-- constante. --
0345 //-- L abcisse est calculee sur les params U1,V1 --
0346 //------------------------------------------------------------------
0347 TColStd_Array1OfReal U1(Low,High);
0348 TColStd_Array1OfReal V1(Low,High);
0349 TColStd_Array1OfReal U2(Low,High);
0350 TColStd_Array1OfReal V2(Low,High);
0351 TColStd_Array1OfReal AC(Low,High);
0352 Standard_Real s,ds;
0353
0354 //------------------------------------------------------------
0355 //-- Creation des Tableaux U1 .. V2 et AC
0356 //--
0357 Standard_Real u1,v1,u2,v2;
0358 Standard_Integer i ;
0359 myLine->Point(Low).Parameters(u1,v1,u2,v2);
0360 U1(Low) = u1;
0361 V1(Low) = v1;
0362 U2(Low) = u2;
0363 V2(Low) = v2;
0364 AC(Low) =0.0;
0365
0366 #if 0
0367 for( i=Low+1; i<=High; i++) {
0368 myLine->Point(i).Parameters(u1,v1,u2,v2);
0369 U1(i) = u1;
0370 V1(i) = v1;
0371 U2(i) = u2;
0372 V2(i) = v2;
0373
0374 Standard_Real du1=u1-U1(i-1);
0375 Standard_Real dv1=v1-V1(i-1);
0376
0377 AC(i) = AC(i-1) + sqrt((du1*du1)+(dv1*dv1));
0378 }
0379 #else
0380 //-- Essai du 19 juin 96 (parametrage selon abs curv en XYZ)
0381 for( i=Low+1; i<=High; i++) {
0382 myLine->Point(i).Parameters(u1,v1,u2,v2);
0383 U1(i) = u1;
0384 V1(i) = v1;
0385 U2(i) = u2;
0386 V2(i) = v2;
0387 AC(i) = AC(i-1) + (myLine->Point(i-1).Value()).Distance(myLine->Point(i).Value());
0388 }
0389
0390 #endif
0391 //-------------------------------------------------------------
0392 //-- Creation des structures contenant les resultats
0393
0394 Handle(IntSurf_LineOn2S) ResultPntOn2SLine = new IntSurf_LineOn2S();
0395
0396 IntSurf_PntOn2S StartPOn2S;
0397 TColStd_Array1OfReal StartParams(1,4);
0398
0399 ds = AC(High) / (NbPnts-1);
0400 Standard_Integer Indice = Low;
0401 Standard_Boolean HasBeenInserted = Standard_False;
0402 Standard_Real dsmin = ds*0.3;
0403 Standard_Real smax = AC(High);
0404
0405 for(i=2,s=ds; (s < smax && Indice <= High-1); i++,s+=ds) {
0406 //----------------------------------------------------------
0407 //-- Recherche des indices des points --
0408 //-- Point : 2 i NbPnts-1 --
0409 //-- s s --
0410 //-- Current Indice tel que AC(Indice)<= s < AC(Indice+1) --
0411 //----------------------------------------------------------
0412 while(AC(Indice+1) <= s)
0413 {
0414 if(!HasBeenInserted)
0415 ResultPntOn2SLine->Add(myLine->Point(Indice));
0416
0417 HasBeenInserted = Standard_False;
0418 Indice++;
0419 if (Indice == High)
0420 break;
0421 }
0422
0423 if (Indice == High)
0424 break;
0425
0426 if(!HasBeenInserted && AC(Indice) <= s)
0427 {
0428 ResultPntOn2SLine->Add(myLine->Point(Indice));
0429 HasBeenInserted = Standard_True;
0430 }
0431
0432 Standard_Real a = s - AC(Indice);
0433 Standard_Real b = AC(Indice+1) - s;
0434 Standard_Real nab = 1.0/(a+b);
0435
0436 //----------------------------------------------------------
0437 //-- Verification : Si Dist au prochain point < dsmin --
0438 //-- Si Dist au precedent point < dsmin --
0439 //-- --
0440 //----------------------------------------------------------
0441 if((a>dsmin) && (b>dsmin))
0442 {
0443 u1 = (U1(Indice) * b + U1(Indice+1) * a) * nab;
0444 v1 = (V1(Indice) * b + V1(Indice+1) * a) * nab;
0445 u2 = (U2(Indice) * b + U2(Indice+1) * a) * nab;
0446 v2 = (V2(Indice) * b + V2(Indice+1) * a) * nab;
0447
0448 if(((TheSvSurfaces *)PtrOnmySvSurfaces)->Compute(u1,v1,u2,v2,P,T,TS1,TS2))
0449 {
0450 StartPOn2S.SetValue(P,u1,v1,u2,v2);
0451 //-- cout<<" Insertion du point calcule : "<<u1<<","<<v1<<","<<u2<<","<<v2<<",";
0452 //-- cout<<P.X()<<","<<P.Y()<<","<<P.Z()<<endl;
0453 ResultPntOn2SLine->Add(StartPOn2S);
0454 }
0455 else
0456 {
0457 //-- cout<<" Probleme Non Traite ds ApproxInt_ApproxIntIntersection "<<endl;
0458 }
0459 }
0460 else
0461 {
0462 //-- Point non situe a distance suffisante de 2 pts existants
0463 //-- avec le point p[indice] deja insere
0464
0465 if(b<0.0)
0466 {
0467 while(AC(Indice+1) <= s)
0468 {
0469 if(!HasBeenInserted)
0470 ResultPntOn2SLine->Add(myLine->Point(Indice));
0471
0472 //-- cout<<" Insertion du point :"<<Indice<<endl;
0473 HasBeenInserted = Standard_False;
0474 Indice++;
0475
0476 if (Indice == High)
0477 break;
0478 }
0479
0480 if(Indice == High)
0481 break;
0482
0483 if(!HasBeenInserted && AC(Indice) <= s)
0484 {
0485 ResultPntOn2SLine->Add(myLine->Point(Indice));
0486 HasBeenInserted = Standard_True;
0487 }
0488 }
0489 else
0490 {
0491 s+= (dsmin - ds);
0492 }
0493 }
0494 }
0495
0496 ResultPntOn2SLine->Add(myLine->Point(High)); //-- Point NbPnts
0497 Handle(TheLine) temp = new TheLine(ResultPntOn2SLine,Standard_False);
0498
0499 //-- Verification a posteriori
0500 //-- On verifie qu il n y a pas de virage trop important en 2d et en 3d
0501
0502 temp->Point(1).Parameters(u1,v1,u2,v2);
0503 gp_Pnt2d P1A(u1,v1);
0504 gp_Pnt2d P2A(u2,v2);
0505
0506 temp->Point(2).Parameters(u1,v1,u2,v2);
0507 gp_Pnt2d P1B(u1,v1);
0508 gp_Pnt2d P2B(u2,v2);
0509
0510 gp_Pnt2d P1C,P2C;
0511
0512 Standard_Integer CodeErreur=0;
0513
0514 for(i=3,NbPnts=temp->NbPnts();CodeErreur==0 && i<=NbPnts; i++)
0515 {
0516 Standard_Real d,du,dv,duv2;
0517 temp->Point(i).Parameters(u1,v1,u2,v2);
0518 //-- Virage P1A P1B P1C
0519 P1C.SetCoord(u1,v1);
0520 du = P1B.X()-P1A.X();
0521 dv = P1B.Y()-P1A.Y();
0522 duv2= 0.25*(du*du+dv*dv);
0523 u1 = P1B.X() + du;
0524 v1 = P1B.Y() + dv;
0525 du = P1C.X() - u1;
0526 dv = P1C.Y() - v1;
0527 d = du*du+dv*dv;
0528 if(d>duv2)
0529 {
0530 CodeErreur = 1;
0531 CodeErreur = 1;
0532 break;
0533 }
0534
0535 //-- Virage P2A P2B P2C
0536 P2C.SetCoord(u2,v2);
0537 du = P2B.X()-P2A.X();
0538 dv = P2B.Y()-P2A.Y();
0539 duv2= 0.25*(du*du+dv*dv);
0540 u2 = P2B.X() + du;
0541 v2 = P2B.Y() + dv;
0542 du = P2C.X() - u2;
0543 dv = P2C.Y() - v2;
0544 d = du*du+dv*dv;
0545 if(d>duv2)
0546 {
0547 CodeErreur = 2;
0548 break;
0549 }
0550
0551 P1A=P1B;
0552 P2A=P2B;
0553 P1B=P1C;
0554 P2B=P2C;
0555 }
0556
0557 #ifdef OCCT_DEBUG
0558 //if (temp->NbPnts() < NbPntsToInsert + High - Low + 1)
0559 //{
0560 // cout<<" *** Pas assez de points entre :"<<
0561 // Low<<" et "<<High<<" -> "<<temp->NbPnts()<<endl;
0562 //}
0563
0564 //if(CodeErreur)
0565 //{
0566 // cout<<" *** CodeErreur : "<<CodeErreur<<endl;
0567 //}
0568 #endif
0569
0570 if((temp->NbPnts() >= NbPntsToInsert + High - Low + 1) && (CodeErreur==0))
0571 {
0572 ((TheSvSurfaces *)PtrOnmySvSurfaces)->SetUseSolver(aSaveUseSolver);
0573 return (ApproxInt_MultiLine( temp,
0574 (High-Low>10)? PtrOnmySvSurfaces : NULL,
0575 nbp3d,
0576 nbp2d,
0577 myApproxU1V1, myApproxU2V2,
0578 Xo,Yo,Zo,
0579 U1o,V1o,
0580 U2o,V2o,
0581 p2donfirst,
0582 1,ResultPntOn2SLine->NbPoints()));
0583 }
0584 else
0585 {
0586 //-- cout<<" ApproxInt_MultiLine "<<endl;
0587 //-- cout<<" Pas de Rajout de points ds1min = "<<minds1<<" ds2min = "<<minds2<<endl;
0588 ((TheSvSurfaces *)PtrOnmySvSurfaces)->SetUseSolver(aSaveUseSolver);
0589 Handle(IntSurf_LineOn2S) vide1 = new IntSurf_LineOn2S();
0590 Handle(TheLine) vide = new TheLine(vide1,Standard_False);
0591 return (ApproxInt_MultiLine( vide,
0592 NULL,
0593 nbp3d,
0594 nbp2d,
0595 myApproxU1V1, myApproxU2V2,
0596 Xo,Yo,Zo,
0597 U1o,V1o,
0598 U2o,V2o,
0599 p2donfirst,
0600 1,1));
0601 }
0602 }
0603
0604 //=======================================================================
0605 //function : MakeMLOneMorePoint
0606 //purpose :
0607 //=======================================================================
0608 Standard_Boolean
0609 ApproxInt_MultiLine::MakeMLOneMorePoint(const Standard_Integer theLow,
0610 const Standard_Integer theHigh,
0611 const Standard_Integer theIndbad,
0612 ApproxInt_MultiLine& theNewMultiLine) const
0613 {
0614 Standard_Boolean OtherLineMade = Standard_False;
0615 if(PtrOnmySvSurfaces==NULL)
0616 return Standard_False;
0617
0618 Standard_Boolean aSaveUseSolver = ((TheSvSurfaces *)PtrOnmySvSurfaces)->GetUseSolver();
0619 if (!aSaveUseSolver)
0620 {
0621 ((TheSvSurfaces *)PtrOnmySvSurfaces)->SetUseSolver(Standard_True);
0622 }
0623
0624 const Standard_Real SqTol3d = Precision::SquareConfusion();
0625 math_Vector tolerance(1,2);
0626 tolerance(1) = tolerance(2) = 1.e-8;
0627
0628 Handle(IntSurf_LineOn2S) ResultPntOn2SLine = new IntSurf_LineOn2S();
0629 for (Standard_Integer Indice = theLow; Indice <= theHigh; Indice++)
0630 ResultPntOn2SLine->Add(myLine->Point(Indice));
0631
0632 //Insert new point between (theIndbad-1) and theIndbad
0633 //Using <thePtrSVSurf> for Rsnld: it may be ImpPrm or PrmPrm
0634 gp_Pnt PrevPnt = myLine->Point(theIndbad-1).Value();
0635 gp_Pnt CurPnt = myLine->Point(theIndbad).Value();
0636 Standard_Real uprev1, vprev1, uprev2, vprev2, ucur1, vcur1, ucur2, vcur2;
0637 myLine->Point(theIndbad-1).Parameters(uprev1, vprev1, uprev2, vprev2);
0638 myLine->Point(theIndbad).Parameters(ucur1, vcur1, ucur2, vcur2);
0639 Standard_Real umid1, vmid1, umid2, vmid2;
0640 umid1 = (uprev1 + ucur1)/2;
0641 vmid1 = (vprev1 + vcur1)/2;
0642 umid2 = (uprev2 + ucur2)/2;
0643 vmid2 = (vprev2 + vcur2)/2;
0644 IntSurf_PntOn2S MidPoint;
0645 Standard_Boolean IsNewPointInvalid = Standard_False;
0646 IsNewPointInvalid =
0647 myApproxU1V1 &&
0648 Abs(ucur1 - umid1) <= tolerance(1) &&
0649 Abs(vcur1 - vmid1) <= tolerance(2);
0650 if (!IsNewPointInvalid)
0651 {
0652 IsNewPointInvalid =
0653 myApproxU2V2 &&
0654 Abs(ucur2 - umid2) <= tolerance(1) &&
0655 Abs(vcur2 - vmid2) <= tolerance(2);
0656 if (!IsNewPointInvalid &&
0657 ((TheSvSurfaces *)PtrOnmySvSurfaces)->SeekPoint(umid1, vmid1, umid2, vmid2,
0658 MidPoint))
0659 {
0660 const gp_Pnt& NewPnt = MidPoint.Value();
0661 Standard_Real SqDistNewPrev = NewPnt.SquareDistance(PrevPnt);
0662 Standard_Real SqDistNewCur = NewPnt.SquareDistance(CurPnt);
0663 IsNewPointInvalid = (SqDistNewPrev <= SqTol3d ||
0664 SqDistNewCur <= SqTol3d);
0665 if (!IsNewPointInvalid)
0666 {
0667 Standard_Real unew1, vnew1, unew2, vnew2;
0668 MidPoint.Parameters(unew1, vnew1, unew2, vnew2);
0669 if (myApproxU1V1)
0670 {
0671 Standard_Real SqDistCurMid1 =
0672 (ucur1 - umid1)*(ucur1 - umid1)+(vcur1 - vmid1)*(vcur1 - vmid1);
0673 Standard_Real SqDistMidNew1 =
0674 (umid1 - unew1)*(umid1 - unew1)+(vmid1 - vnew1)*(vmid1 - vnew1);
0675 IsNewPointInvalid = (SqDistMidNew1 > SqDistCurMid1);
0676 }
0677 if (!IsNewPointInvalid)
0678 {
0679 if (myApproxU2V2)
0680 {
0681 Standard_Real SqDistCurMid2 =
0682 (ucur2 - umid2)*(ucur2 - umid2)+(vcur2 - vmid2)*(vcur2 - vmid2);
0683 Standard_Real SqDistMidNew2 =
0684 (umid2 - unew2)*(umid2 - unew2)+(vmid2 - vnew2)*(vmid2 - vnew2);
0685 IsNewPointInvalid = (SqDistMidNew2 > SqDistCurMid2);
0686 }
0687 if (!IsNewPointInvalid)
0688 {
0689 ResultPntOn2SLine->InsertBefore(theIndbad-theLow+1, MidPoint);
0690 OtherLineMade = Standard_True;
0691 }
0692 }
0693 }
0694 }
0695 }
0696
0697 if (!OtherLineMade)
0698 {
0699 ((TheSvSurfaces *)PtrOnmySvSurfaces)->SetUseSolver(aSaveUseSolver);
0700 return Standard_False;
0701 }
0702
0703 #ifdef DRAW
0704 char* name = new char[100];
0705 Standard_Integer indc = 1;
0706 Standard_Boolean onfirst = Standard_True;
0707 for (Standard_Integer i = 1; i <= ResultPntOn2SLine->NbPoints(); i++)
0708 {
0709 const IntSurf_PntOn2S& thePoint = ResultPntOn2SLine->Value(i);
0710 gp_Pnt curPnt = thePoint.Value();
0711 sprintf(name, "p%d_%d", indc, i);
0712 DrawTrSurf::Set(name, curPnt);
0713 gp_Pnt2d curPnt2d = thePoint.ValueOnSurface(onfirst);
0714 sprintf(name, "pp%d_%d", indc, i);
0715 DrawTrSurf::Set(name, curPnt2d);
0716 }
0717 #endif
0718 Handle(TheLine) temp = new TheLine(ResultPntOn2SLine,Standard_False);
0719 ((TheSvSurfaces *)PtrOnmySvSurfaces)->SetUseSolver(aSaveUseSolver);
0720 theNewMultiLine = ApproxInt_MultiLine( temp,
0721 PtrOnmySvSurfaces,
0722 nbp3d,
0723 nbp2d,
0724 myApproxU1V1,
0725 myApproxU2V2,
0726 Xo,Yo,Zo,
0727 U1o,V1o,
0728 U2o,V2o,
0729 p2donfirst,
0730 1,ResultPntOn2SLine->NbPoints());
0731 return Standard_True;
0732 }
0733
0734 //=======================================================================
0735 //function : Dump
0736 //purpose :
0737 //=======================================================================
0738 void ApproxInt_MultiLine::Dump() const
0739 {
0740 TColgp_Array1OfPnt anArr1(1, 1);
0741 TColgp_Array1OfPnt2d anArr2(1, 2);
0742
0743 const Standard_Integer anIndF = FirstPoint(),
0744 anIndL = LastPoint();
0745
0746 for(Standard_Integer ind = anIndF; ind <= anIndL; ind++)
0747 {
0748 Value(ind, anArr1, anArr2);
0749 printf("%4d [%+10.20f %+10.20f %+10.20f] "
0750 "[%+10.20f %+10.20f] [%+10.20f %+10.20f]\n",
0751 ind, anArr1(1).X(), anArr1(1).Y(), anArr1(1).Z(), anArr2(1).X(),
0752 anArr2(1).Y(),anArr2(2).X(),anArr2(2).Y());
0753 }
0754 }
0755