Back to home page

EIC code displayed by LXR

 
 

    


Warning, /include/opencascade/IntWalk_IWalking_5.gxx is written in an unsupported language. File is not indexed.

0001 // Copyright (c) 1995-1999 Matra Datavision
0002 // Copyright (c) 1999-2014 OPEN CASCADE SAS
0003 //
0004 // This file is part of Open CASCADE Technology software library.
0005 //
0006 // This library is free software; you can redistribute it and/or modify it under
0007 // the terms of the GNU Lesser General Public License version 2.1 as published
0008 // by the Free Software Foundation, with special exception defined in the file
0009 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
0010 // distribution for complete text of the license and disclaimer of any warranty.
0011 //
0012 // Alternatively, this file may be used under the terms of Open CASCADE
0013 // commercial license or contractual agreement.
0014 
0015 namespace {
0016   static const Standard_Real CosRef3D = 0.98;// rule by tests in U4 
0017                                              // correspond to  11.478 d
0018   static const Standard_Real CosRef2D = 0.88; // correspond to 25 d
0019   static const Standard_Integer MaxDivision = 60;  // max number of step division 
0020                                                    // because the angle is too great in 2d (U4)
0021 }
0022 
0023 IntWalk_StatusDeflection IntWalk_IWalking::TestDeflection
0024   (TheIWFunction& sp,
0025    const Standard_Boolean Finished,
0026    const math_Vector& UV,
0027    const IntWalk_StatusDeflection StatusPrecedent,
0028    Standard_Integer& NbDivision,
0029    Standard_Real& Step,
0030    const Standard_Integer StepSign)
0031 {
0032   // Check the step of advancement, AND recalculate this step :
0033   //
0034   // 1) test point confused
0035   //     if yes other tests are not done
0036   // 2) test angle 3d too great
0037   //     if yes divide the step and leave
0038   //     angle3d = angle ((previous point, calculated point),
0039   //                       previous tangent)
0040   // 3) check step of advancement in 2d
0041   // 4) test point confused
0042   // 5) test angle 2d too great
0043   // 6) test point of tangency 
0044   //     if yes leave
0045   // 7) calculate the tangent by u,v of the section 
0046   // 8) test angle 3d too great  
0047   //     angle3d = angle ((previous point, calculated point),  
0048   //                       new tangent)
0049   // 9) test angle 2d too great
0050   //10) test change of side (pass the tangent point not knowing it)
0051   //11) calculate the step of advancement depending on the vector
0052   //12) adjust the step depending on the previous steps 
0053   
0054   IntWalk_StatusDeflection aStatus = IntWalk_OK;
0055 
0056   //---------------------------------------------------------------------------------
0057   //-- lbr le 4 Avril 95 : it is possible that the status returns points confused
0058   //-- if epsilon is great enough (1e-11). In this case one loops 
0059   //-- without ever changing the values sent to Rsnld. 
0060   //---------------------------------------------------------------------------------
0061   Standard_Real Paramu = 0.0, Paramv = 0.0;
0062 
0063   if (!reversed) {
0064     previousPoint.ParametersOnS2(Paramu, Paramv);
0065   }
0066   else
0067   {
0068     previousPoint.ParametersOnS1(Paramu, Paramv);
0069   }
0070 
0071   const Standard_Real Du = UV(1) - Paramu;
0072   const Standard_Real Dv = UV(2) - Paramv;
0073   const Standard_Real Duv = Du * Du + Dv * Dv;
0074 
0075   gp_Vec Corde(previousPoint.Value(), sp.Point());
0076 
0077   const Standard_Real Norme = Corde.SquareMagnitude();
0078 
0079   if ((Norme <= 4.0*Precision::SquareConfusion()) && 
0080       ((Duv <= Precision::SquarePConfusion()) || (StatusPrecedent != IntWalk_OK)))
0081   { // the square is already taken in the constructor
0082     aStatus = IntWalk_PointConfondu;
0083     if (StatusPrecedent == IntWalk_PasTropGrand)
0084     {
0085       return IntWalk_ArretSurPointPrecedent;
0086     }
0087   }
0088   else
0089   {
0090     Standard_Real Cosi = Corde * previousd3d;
0091     Standard_Real Cosi2 = 0.0;
0092 
0093     if (Cosi*StepSign >= 0.) {// angle 3d <= pi/2 !!!!
0094       const Standard_Real aDiv = previousd3d.SquareMagnitude()*Norme;
0095       if(aDiv == 0)
0096         return aStatus;
0097       Cosi2 = Cosi * Cosi / aDiv;
0098     }
0099     if (Cosi2 < CosRef3D) { //angle 3d too great
0100       Step = Step /2.0;
0101       Standard_Real StepU = Abs(Step*previousd2d.X()),
0102                     StepV = Abs(Step*previousd2d.Y());
0103       if (StepU < tolerance(1) && StepV < tolerance(2)) 
0104         aStatus = IntWalk_ArretSurPointPrecedent;
0105       else 
0106         aStatus = IntWalk_PasTropGrand;
0107       return aStatus;
0108     }
0109   }
0110 
0111   const Standard_Real aMinTolU = 0.1*Abs(Step*previousd2d.X()),
0112                       aMinTolV = 0.1*Abs(Step*previousd2d.Y());
0113   const Standard_Real aTolU = (aMinTolU > 0.0) ? Min(tolerance(1), aMinTolU) : tolerance(1),
0114                       aTolV = (aMinTolV > 0.0) ? Min(tolerance(2), aMinTolV) : tolerance(2);
0115 
0116   //If aMinTolU==0.0 then (Abs(Du) < aMinTolU) is equivalent of (Abs(Du) < 0.0).
0117   //It is impossible. Therefore, this case should be processed separately.
0118   //Analogically for aMinTolV.
0119 
0120   if ((Abs(Du) < aTolU) && (Abs(Dv) < aTolV))
0121   {
0122     //Thin shapes (for which Ulast-Ufirst or/and Vlast-Vfirst is quite small)
0123     //exists (see bug #25820). In this case, step is quite small too.
0124     //Nevertheless, it not always means that we mark time. Therefore, Du and Dv
0125     //must consider step (aMinTolU and aMinTolV parameters).
0126 
0127     return IntWalk_ArretSurPointPrecedent; //confused point 2d
0128   }
0129 
0130   Standard_Real Cosi = StepSign * (Du * previousd2d.X() + Dv * previousd2d.Y());
0131 
0132   if (Cosi < 0 && aStatus == IntWalk_PointConfondu)
0133     return IntWalk_ArretSurPointPrecedent; // leave as step back  
0134                                            // with confused point
0135 
0136   if (sp.IsTangent()) 
0137     return IntWalk_ArretSurPoint;       
0138 
0139 //if during routing one has subdivided more than  MaxDivision for each
0140 //previous step, bug on the square; do nothing (experience U4)
0141 
0142   if ((NbDivision < MaxDivision) && (aStatus != IntWalk_PointConfondu) &&
0143     (StatusPrecedent!= IntWalk_PointConfondu))
0144   {
0145     Standard_Real Cosi2 = Cosi * Cosi / Duv;
0146     if (Cosi2 < CosRef2D || Cosi < 0  ) {
0147       Step = Step / 2.0;
0148       Standard_Real StepU = Abs(Step*previousd2d.X()),
0149                     StepV = Abs(Step*previousd2d.Y());
0150 
0151       if (StepU < tolerance(1) && StepV < tolerance(2))
0152         aStatus = IntWalk_ArretSurPointPrecedent;
0153       else 
0154         aStatus = IntWalk_PasTropGrand;
0155       NbDivision = NbDivision + 1;
0156       return aStatus;
0157     }
0158 
0159     Cosi = Corde * sp.Direction3d(); 
0160     Cosi2 = Cosi * Cosi / sp.Direction3d().SquareMagnitude() / Norme;
0161     if (Cosi2 < CosRef3D ){ //angle 3d too great
0162       Step = Step / 2.;
0163       Standard_Real StepU = Abs(Step*previousd2d.X()),
0164                     StepV = Abs(Step*previousd2d.Y());
0165       if (StepU < tolerance(1) && StepV < tolerance(2))
0166         aStatus = IntWalk_ArretSurPoint;
0167       else 
0168         aStatus = IntWalk_PasTropGrand;
0169       return aStatus;
0170     }
0171     Cosi = Du * sp.Direction2d().X() + 
0172       Dv * sp.Direction2d().Y();
0173     Cosi2 = Cosi * Cosi / Duv;
0174     if (Cosi2 < CosRef2D || 
0175       sp.Direction2d() * previousd2d < 0) {
0176         //angle 2d too great or change the side       
0177         Step  = Step / 2.;
0178         Standard_Real StepU = Abs(Step*previousd2d.X()),
0179                       StepV = Abs(Step*previousd2d.Y());
0180         if (StepU < tolerance(1) && StepV < tolerance(2))
0181           aStatus = IntWalk_ArretSurPointPrecedent;
0182         else 
0183           aStatus = IntWalk_PasTropGrand;
0184         return aStatus;
0185     }
0186   }
0187 
0188   if (!Finished) {
0189     if (aStatus == IntWalk_PointConfondu)
0190     {
0191       Standard_Real StepU = Min(Abs(1.5 * Du),pas*(UM-Um)),
0192                     StepV = Min(Abs(1.5 * Dv),pas*(VM-Vm));
0193 
0194       Standard_Real d2dx = Abs(previousd2d.X()); 
0195       Standard_Real d2dy = Abs(previousd2d.Y()); 
0196 
0197       if (d2dx < tolerance(1))
0198       {
0199         Step = StepV/d2dy;
0200       }
0201       else if (d2dy < tolerance(2))
0202       {
0203         Step = StepU/d2dx;
0204       }
0205       else
0206       {
0207         Step = Min(StepU/d2dx,StepV/d2dy);
0208       }
0209     }
0210     else
0211     {
0212       //   estimate the current vector.
0213       //   if vector/2<=current vector<= vector it is considered that the criterion
0214       //   is observed.
0215       //   otherwise adjust the step depending on the previous step 
0216 
0217       /*
0218         Standard_Real Dist = Sqrt(Norme)/3.;
0219         TColgp_Array1OfPnt Poles(1,4);
0220         gp_Pnt POnCurv,Milieu;
0221         Poles(1) = previousPoint.Value();
0222         Poles(4) = sp.Point();
0223         Poles(2) = Poles(1).XYZ() + 
0224       StepSign * Dist* previousd3d.Normalized().XYZ();
0225         Poles(3) = Poles(4).XYZ() - 
0226       StepSign * Dist*sp.Direction3d().Normalized().XYZ();
0227         BzCLib::PntPole(0.5,Poles,POnCurv);
0228         Milieu = (Poles(1).XYZ() + Poles(4).XYZ())*0.5;
0229       //      FlecheCourante = Milieu.Distance(POnCurv);
0230         Standard_Real FlecheCourante = Milieu.SquareDistance(POnCurv);
0231       */
0232 
0233         // Direct calculation : 
0234         // POnCurv=(((p1+p2)/2.+(p2+p3)/2.)/2. + ((p2+p3)/2.+(p3+P4)/2.)/2.)/2.
0235         // either POnCurv = p1/8. + 3.p2/8. + 3.p3/8. + p4/8.
0236         // Or p2 = p1 + lambda*d1 et p3 = p4 - lambda*d4
0237         // So POnCurv = (p1 + p4)/2. + 3.*(lambda d1 - lambda d4)/8.
0238         // Calculate the deviation with (p1+p4)/2. . So it is just necessary to calculate
0239         // the norm (square) of 3.*lambda (d1 - d4)/8.
0240         // either the norm of :
0241         //    3.*(Sqrt(Norme)/3.)*StepSign*(d1-d4)/8.
0242         // which produces, takin the square :
0243         //         Norme * (d1-d4).SquareMagnitude()/64.
0244 
0245       Standard_Real FlecheCourante = 
0246         (previousd3d.Normalized().XYZ()-sp.Direction3d().Normalized().XYZ()).SquareModulus()*Norme/64.;
0247 
0248   
0249 //      if (FlecheCourante <= 0.5*fleche) {
0250       if (FlecheCourante <= 0.25*fleche*fleche)
0251       {
0252         Standard_Real d2dx = Abs(sp.Direction2d().X()); 
0253         Standard_Real d2dy = Abs(sp.Direction2d().Y()); 
0254         
0255         Standard_Real StepU = Min(Abs(1.5*Du),pas*(UM-Um)),
0256                       StepV = Min(Abs(1.5*Dv),pas*(VM-Vm));
0257 
0258         if (d2dx < tolerance(1))
0259         {
0260           Step = StepV/d2dy;
0261         }
0262         else if (d2dy < tolerance(2))
0263         {
0264           Step = StepU/d2dx;
0265         }
0266         else
0267         {
0268           Step = Min(StepU/d2dx,StepV/d2dy);
0269         }       
0270       }
0271       else
0272       {
0273         //if (FlecheCourante > fleche) {  // step too great
0274         if (FlecheCourante > fleche*fleche)
0275         {  // step too great
0276           Step = Step /2.;
0277           Standard_Real StepU = Abs(Step*previousd2d.X()),
0278                         StepV = Abs(Step*previousd2d.Y());
0279           
0280           if (StepU < tolerance(1) && StepV < tolerance(2)) 
0281             aStatus = IntWalk_ArretSurPointPrecedent;
0282           else 
0283             aStatus = IntWalk_PasTropGrand;
0284         }
0285         else
0286         {
0287           Standard_Real d2dx = Abs(sp.Direction2d().X()); 
0288           Standard_Real d2dy = Abs(sp.Direction2d().Y()); 
0289           
0290           Standard_Real StepU = Min(Abs(1.5*Du),pas*(UM-Um)),
0291                         StepV = Min(Abs(1.5*Dv),pas*(VM-Vm));
0292 
0293           if (d2dx < tolerance(1))
0294           {
0295             Step = Min(Step,StepV/d2dy);
0296           }
0297           else if (d2dy < tolerance(2))
0298           {
0299             Step = Min(Step,StepU/d2dx);
0300           }
0301           else
0302           {
0303             Step = Min(Step,Min(StepU/d2dx,StepV/d2dy));
0304           }
0305         }
0306       }
0307     }
0308   }
0309   return aStatus;
0310 }