// File: ApproxInt_MultiLine.gxx // Created: Wed Mar 22 9:55:23 1993 // Author: Laurent BUCHARD // #define DEBUG 0 #include #include #include #include #include #include ApproxInt_MultiLine::ApproxInt_MultiLine(const Handle_TheLine& line, const Standard_Address svsurf, const Standard_Integer NbP3d, const Standard_Integer NbP2d, const Standard_Real xo, const Standard_Real ax, const Standard_Real yo, const Standard_Real ay, const Standard_Real zo, const Standard_Real az, const Standard_Real u1o, const Standard_Real a1u, const Standard_Real v1o, const Standard_Real a1v, const Standard_Real u2o, const Standard_Real a2u, const Standard_Real v2o, const Standard_Real a2v, const Standard_Boolean P2DOnFirst, const Standard_Integer IndMin, const Standard_Integer IndMax): PtrOnmySvSurfaces(svsurf), myLine(line), indicemin(IndMin), indicemax(IndMax), nbp3d(NbP3d), nbp2d(NbP2d), p2donfirst(P2DOnFirst), Xo(xo),Ax(ax),Yo(yo),Ay(ay),Zo(zo),Az(az), U1o(u1o),A1u(a1u),V1o(v1o),A1v(a1v), U2o(u2o),A2u(a2u),V2o(v2o),A2v(a2v) { #if DEBUG if(indicemin>=indicemax) { cout<<"\n********************************************"; cout<<"\n***** ApproxInt_MultiLine ********"; cout<<"\n***** indicemin = indicemax = "<=indicemax) { #if DEBUG cout<<"\n********************************************"; cout<<"\n***** ApproxInt_MultiLine ********"; cout<<"\n***** indicemin = indicemax = "<Point(Index)); Standard_Real X = POn2S.Value().X(); Standard_Real Y = POn2S.Value().Y(); Standard_Real Z = POn2S.Value().Z(); TabPnt(1) = gp_Pnt(X*Ax + Xo, Y*Ay + Yo, Z*Az + Zo); } //-------------------------------------------------------------------------------- void ApproxInt_MultiLine::Value( const Standard_Integer Index ,TColgp_Array1OfPnt2d& TabPnt2d) const { IntSurf_PntOn2S POn2S(myLine->Point(Index)); Standard_Real u1,u2,v1,v2; POn2S.Parameters(u1,v1,u2,v2); if(nbp2d==1) { if(p2donfirst) { TabPnt2d(1) = gp_Pnt2d(u1 * A1u + U1o , v1 * A1v + V1o); } else { TabPnt2d(1) = gp_Pnt2d(u2 * A2u + U2o , v2 * A2v + V2o); } } else { TabPnt2d(1) = gp_Pnt2d(u1 * A1u + U1o , v1 * A1v + V1o); if(TabPnt2d.Length()>=2) { TabPnt2d(2) = gp_Pnt2d(u2 * A2u + U2o , v2 * A2v + V2o); } } } //-------------------------------------------------------------------------------- void ApproxInt_MultiLine::Value( const Standard_Integer Index ,TColgp_Array1OfPnt& TabPnt ,TColgp_Array1OfPnt2d& TabPnt2d) const { IntSurf_PntOn2S POn2S(myLine->Point(Index)); Standard_Real u1,u2,v1,v2; POn2S.Parameters(u1,v1,u2,v2); if(nbp2d==1) { if(p2donfirst) { TabPnt2d(1) = gp_Pnt2d(u1 * A1u + U1o , v1 * A1v + V1o); } else { TabPnt2d(1) = gp_Pnt2d(u2 * A2u + U2o , v2 * A2v + V2o); } } else { TabPnt2d(1) = gp_Pnt2d(u1 * A1u + U1o , v1 * A1v + V1o); if(TabPnt2d.Length()>=2) { TabPnt2d(2) = gp_Pnt2d(u2 * A2u + U2o , v2 * A2v + V2o); } } Standard_Real X = POn2S.Value().X(); Standard_Real Y = POn2S.Value().Y(); Standard_Real Z = POn2S.Value().Z(); TabPnt(1) = gp_Pnt(X * Ax + Xo, Y * Ay + Yo, Z * Az + Zo); } //-------------------------------------------------------------------------------- //-------------------------------------------------------------------------------- Standard_Boolean ApproxInt_MultiLine::Tangency( const Standard_Integer Index ,TColgp_Array1OfVec& TabVec) const { if(PtrOnmySvSurfaces==NULL) return(Standard_False); IntSurf_PntOn2S POn2S(myLine->Point(Index)); Standard_Real u1,u2,v1,v2; gp_Vec Tg; POn2S.Parameters(u1,v1,u2,v2); Standard_Boolean ret=((TheSvSurfaces *)PtrOnmySvSurfaces)->Tangency( u1,v1,u2,v2,Tg); if(ret) { Standard_Real X = Tg.X(); Standard_Real Y = Tg.Y(); Standard_Real Z = Tg.Z(); TabVec(1) = gp_Vec(X * Ax, Y * Ay, Z * Az); } else TabVec(1) = gp_Vec(0.0,0.0,0.0); return(ret); } //-------------------------------------------------------------------------------- Standard_Boolean ApproxInt_MultiLine::Tangency( const Standard_Integer Index ,TColgp_Array1OfVec2d& TabVec2d) const { if(PtrOnmySvSurfaces==NULL) return(Standard_False); IntSurf_PntOn2S POn2S(myLine->Point(Index)); Standard_Real u1,u2,v1,v2,U,V; gp_Vec2d Tg2d; Standard_Boolean ret; POn2S.Parameters(u1,v1,u2,v2); if(nbp2d==1) { Standard_Real Au = A1u; Standard_Real Av = A1v; if(p2donfirst) { ret=((TheSvSurfaces *)PtrOnmySvSurfaces)->TangencyOnSurf1( u1,v1,u2,v2,Tg2d); } else { ret=((TheSvSurfaces *)PtrOnmySvSurfaces)->TangencyOnSurf2( u1,v1,u2,v2,Tg2d); Au = A2u; Av = A2v; } if(ret) { U = Tg2d.X(); V = Tg2d.Y(); TabVec2d(1) = gp_Vec2d(U * Au, V * Av); } else { TabVec2d(1) = gp_Vec2d(0.0,0.0); } } else { ret=((TheSvSurfaces *)PtrOnmySvSurfaces)->TangencyOnSurf1( u1,v1,u2,v2,Tg2d); if(ret) { U = Tg2d.X(); V = Tg2d.Y(); TabVec2d(1) = gp_Vec2d(U * A1u, V * A1v); if(TabVec2d.Length()>=2) { ret&=((TheSvSurfaces *)PtrOnmySvSurfaces)->TangencyOnSurf2( u1,v1,u2,v2,Tg2d); U = Tg2d.X(); V = Tg2d.Y(); TabVec2d(2) = gp_Vec2d(U * A2u, V * A2v); } else { TabVec2d(1) = gp_Vec2d(0.0,0.0); if(TabVec2d.Length()>=2) { TabVec2d(2) = gp_Vec2d(0.0,0.0); } } } } return(ret); } //-------------------------------------------------------------------------------- Standard_Boolean ApproxInt_MultiLine::Tangency( const Standard_Integer Index ,TColgp_Array1OfVec& TabVec ,TColgp_Array1OfVec2d& TabVec2d) const { if(PtrOnmySvSurfaces==NULL) return(Standard_False); IntSurf_PntOn2S POn2S(myLine->Point(Index)); Standard_Real u1,u2,v1,v2,U,V; gp_Vec2d Tg2d; gp_Vec Tg; Standard_Boolean ret; POn2S.Parameters(u1,v1,u2,v2); if(nbp2d==1) { Standard_Real Au = A1u; Standard_Real Av = A1v; if(p2donfirst) { ret=((TheSvSurfaces *)PtrOnmySvSurfaces)->TangencyOnSurf1( u1,v1,u2,v2,Tg2d); } else { ret=((TheSvSurfaces *)PtrOnmySvSurfaces)->TangencyOnSurf2( u1,v1,u2,v2,Tg2d); Au = A2u; Av = A2v; } if(ret) { U = Tg2d.X(); V = Tg2d.Y(); TabVec2d(1) = gp_Vec2d(U * Au, V * Av); } else { TabVec2d(1) = gp_Vec2d(0.0,0.0); } } else { ret=((TheSvSurfaces *)PtrOnmySvSurfaces)->TangencyOnSurf1( u1,v1,u2,v2,Tg2d); if(ret) { U = Tg2d.X(); V = Tg2d.Y(); TabVec2d(1) = gp_Vec2d(U * A1u, V * A1v); if(TabVec2d.Length()>=2) { ret&=((TheSvSurfaces *)PtrOnmySvSurfaces)->TangencyOnSurf2( u1,v1,u2,v2,Tg2d); U = Tg2d.X(); V = Tg2d.Y(); TabVec2d(2) = gp_Vec2d(U * A2u, V * A2v); } } else { TabVec2d(1) = gp_Vec2d(0.0,0.0); if(TabVec2d.Length()>=2) { TabVec2d(2) = gp_Vec2d(0.0,0.0); } } } if(ret) { ret&=((TheSvSurfaces *)PtrOnmySvSurfaces)->Tangency( u1,v1,u2,v2,Tg); Standard_Real X = Tg.X(); Standard_Real Y = Tg.Y(); Standard_Real Z = Tg.Z(); TabVec(1) = gp_Vec(X * Ax, Y * Ay, Z * Az); } else { TabVec(1) = gp_Vec(0.0,0.0,0.0); } return(ret); } //-------------------------------------------------------------------------------- //================================================================================ ApproxInt_MultiLine ApproxInt_MultiLine::MakeMLBetween(const Standard_Integer Low, const Standard_Integer High, const Standard_Integer aNbPntsToInsert) const { if(PtrOnmySvSurfaces==NULL) { //-- cout<<"\n Erreur dans : ApproxInt_MultiLine ApproxInt_MultiLine::MakeMLBetween "<Point(Low).Parameters(u1,v1,u2,v2); U1(Low) = u1; V1(Low) = v1; U2(Low) = u2; V2(Low) = v2; AC(Low) =0.0; #if 0 for( i=Low+1; i<=High; i++) { myLine->Point(i).Parameters(u1,v1,u2,v2); U1(i) = u1; V1(i) = v1; U2(i) = u2; V2(i) = v2; Standard_Real du1=u1-U1(i-1); Standard_Real dv1=v1-V1(i-1); AC(i) = AC(i-1) + sqrt((du1*du1)+(dv1*dv1)); } #else //-- Essai du 19 juin 96 (parametrage selon abs curv en XYZ) for( i=Low+1; i<=High; i++) { myLine->Point(i).Parameters(u1,v1,u2,v2); U1(i) = u1; V1(i) = v1; U2(i) = u2; V2(i) = v2; AC(i) = AC(i-1) + (myLine->Point(i-1).Value()).Distance(myLine->Point(i).Value()); } #endif //------------------------------------------------------------- //-- Creation des structures contenant les resultats Handle(IntSurf_LineOn2S) ResultPntOn2SLine = new IntSurf_LineOn2S(); IntSurf_PntOn2S StartPOn2S; TColStd_Array1OfReal StartParams(1,4); ds = AC(High) / (NbPnts-1); Standard_Integer Indice = Low; Standard_Boolean HasBeenInserted = Standard_False; Standard_Real dsmin = ds*0.3; Standard_Real smax = AC(High); for(i=2,s=ds; (sAdd(myLine->Point(Indice)); HasBeenInserted = Standard_False; Indice++; } if(!HasBeenInserted && AC(Indice) <= s) { ResultPntOn2SLine->Add(myLine->Point(Indice)); HasBeenInserted = Standard_True; } Standard_Real a = s - AC(Indice); Standard_Real b = AC(Indice+1) - s; Standard_Real nab = 1.0/(a+b); //---------------------------------------------------------- //-- Verification : Si Dist au prochain point < dsmin -- //-- Si Dist au precedent point < dsmin -- //-- -- //---------------------------------------------------------- if((a>dsmin) && (b>dsmin)) { u1 = (U1(Indice) * b + U1(Indice+1) * a) * nab; v1 = (V1(Indice) * b + V1(Indice+1) * a) * nab; u2 = (U2(Indice) * b + U2(Indice+1) * a) * nab; v2 = (V2(Indice) * b + V2(Indice+1) * a) * nab; if(((TheSvSurfaces *)PtrOnmySvSurfaces)->Compute(u1,v1,u2,v2,P,T,TS1,TS2)) { StartPOn2S.SetValue(P,u1,v1,u2,v2); //-- cout<<" Insertion du point calcule : "<Add(StartPOn2S); } else { //-- cout<<" Probleme Non Traite ds ApproxInt_ApproxIntIntersection "<Add(myLine->Point(Indice)); //-- cout<<" Insertion du point :"<Add(myLine->Point(Indice)); HasBeenInserted = Standard_True; } } else { s+=dsmin - ds; } } } ResultPntOn2SLine->Add(myLine->Point(High)); //-- Point NbPnts Handle(TheLine) temp = new TheLine(ResultPntOn2SLine,Standard_False); //-- Verification a posteriori //-- On verifie qu il n y a pas de virage trop important en 2d et en 3d temp->Point(1).Parameters(u1,v1,u2,v2); gp_Pnt2d P1A(u1,v1); gp_Pnt2d P2A(u2,v2); temp->Point(2).Parameters(u1,v1,u2,v2); gp_Pnt2d P1B(u1,v1); gp_Pnt2d P2B(u2,v2); gp_Pnt2d P1C,P2C; Standard_Integer CodeErreur=0; for(i=3,NbPnts=temp->NbPnts();CodeErreur==0 && i<=NbPnts; i++) { Standard_Real d,du,dv,duv2; temp->Point(i).Parameters(u1,v1,u2,v2); //-- Virage P1A P1B P1C P1C.SetCoord(u1,v1); du = P1B.X()-P1A.X(); dv = P1B.Y()-P1A.Y(); duv2= 0.25*(du*du+dv*dv); u1 = P1B.X() + du; v1 = P1B.Y() + dv; du = P1C.X() - u1; dv = P1C.Y() - v1; d = du*du+dv*dv; if(d>duv2) { CodeErreur = 1; CodeErreur = 1; break; } //-- Virage P2A P2B P2C P2C.SetCoord(u2,v2); du = P2B.X()-P2A.X(); dv = P2B.Y()-P2A.Y(); duv2= 0.25*(du*du+dv*dv); u2 = P2B.X() + du; v2 = P2B.Y() + dv; du = P2C.X() - u2; dv = P2C.Y() - v2; d = du*du+dv*dv; if(d>duv2) { CodeErreur = 2; break; } P1A=P1B; P2A=P2B; P1B=P1C; P2B=P2C; } #if DEBUG if (temp->NbPnts() < NbPntsToInsert + High - Low + 1) { cout<<" *** Pas assez de points entre :"< "<NbPnts()<NbPnts() >= NbPntsToInsert + High - Low + 1) && (CodeErreur==0)) { return(ApproxInt_MultiLine(temp, (High-Low>10)? PtrOnmySvSurfaces : NULL, nbp3d, nbp2d, Xo,Ax,Yo,Ay,Zo,Az, U1o,A1u,V1o,A1v, U2o,A2u,V2o,A2v, p2donfirst, 1,ResultPntOn2SLine->NbPoints())); } else { //-- cout<<" ApproxInt_MultiLine "<