Back to home page

EIC code displayed by LXR

 
 

    


Warning, /include/opencascade/IntStart_SearchInside.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 #ifndef OCCT_DEBUG
0016 #define No_Standard_RangeError
0017 #define No_Standard_OutOfRange
0018 #endif
0019 
0020 
0021 
0022 #include <math_FunctionSetRoot.hxx>
0023 #include <Precision.hxx>
0024 #include <gp_Pnt2d.hxx>
0025 
0026 #include <TopAbs_State.hxx>
0027 
0028 IntStart_SearchInside::IntStart_SearchInside (): done(Standard_False)
0029 {}
0030 
0031 IntStart_SearchInside::IntStart_SearchInside (TheFunction& Func,
0032                                               const ThePSurface& PS,
0033                                               const Handle(TheTopolTool)& T,
0034                                               const Standard_Real Epsilon) {
0035 
0036   Perform(Func,PS,T,Epsilon);
0037 }
0038 
0039 
0040 //=======================================================================
0041 //function : Perform
0042 //purpose  : Search all inside points
0043 //=======================================================================
0044 
0045 void IntStart_SearchInside::Perform (TheFunction& Func,
0046                                      const ThePSurface& PS,
0047                                      const Handle(TheTopolTool)& T,
0048                                      const Standard_Real Epsilon) {
0049 
0050   done = Standard_False;
0051   list.Clear();
0052   Standard_Real aBinf[2], aBsup[2], aUVap[2], atoler[2];
0053   math_Vector Binf(aBinf,1,2), Bsup(aBsup,1,2), UVap(aUVap,1,2), toler(atoler,1,2);
0054   gp_Pnt psol;
0055   Standard_Boolean testpnt;
0056   Standard_Integer i,j,nbpt;
0057   TopAbs_State situ;
0058   Standard_Real umin,umax,vmin,vmax;
0059   Binf(1) = umin = ThePSurfaceTool::FirstUParameter(PS);
0060   Binf(2) = vmin = ThePSurfaceTool::FirstVParameter(PS);
0061   Bsup(1) = umax = ThePSurfaceTool::LastUParameter(PS);
0062   Bsup(2) = vmax = ThePSurfaceTool::LastVParameter(PS);
0063   
0064   Standard_Integer NbsampleU= T->NbSamplesU();
0065   Standard_Integer NbsampleV= T->NbSamplesV();
0066   Standard_Integer Nbsample = T->NbSamples();
0067   
0068   Standard_Real du = Bsup(1)-Binf(1);
0069   Standard_Real dv = Bsup(2)-Binf(2);  
0070   du/=(Standard_Real)NbsampleU*0.5;
0071   dv/=(Standard_Real)NbsampleV*0.5;
0072   
0073   Standard_Real toler1 = toler(1) = ThePSurfaceTool::UResolution(PS,Precision::Confusion());
0074   Standard_Real toler2 = toler(2) = ThePSurfaceTool::VResolution(PS,Precision::Confusion());
0075   Standard_Real Maxtoler1toler2 = toler1;
0076   if(toler2>Maxtoler1toler2) Maxtoler1toler2 = toler2;
0077 
0078   //-- lbr le 15 mai 97
0079   //-- on interdit aux points d'etre trop prets des restrictions 
0080   Maxtoler1toler2*=1000;
0081   if(Maxtoler1toler2>du*0.001) Maxtoler1toler2=du*0.001;
0082   if(Maxtoler1toler2>dv*0.001) Maxtoler1toler2=dv*0.001;
0083   
0084   
0085   Func.Set(PS);
0086   Standard_Real Tol = Func.Tolerance();
0087 
0088   math_FunctionSetRoot Rsnld(Func,toler);
0089 
0090   //-- lbr le 15 mai 97 
0091   umin+=du*0.01;
0092   vmin+=dv*0.01;
0093   umax-=du*0.01;
0094   vmax-=dv*0.01;
0095 
0096   //-- lbr le 30 octobre 97 : 
0097   //-- Si une surface vient tangenter 2 edges proche d un coin
0098   //-- il faut faire attention qu un point de depart soit trouve au 
0099   //-- voisinage du coin. Car ds le cas contraire, le cheminement ne
0100   //-- pourra pas passer au travers des frontieres : 
0101   //--
0102   //-- typiquement I est un cylindre (conge)
0103   //--
0104   //--                 PPPPPPPPPPPPPPPPPPPP*PPPPPPPPPPPPPPPP
0105   //--                 P               I     I
0106   //--                 P           I           I
0107   //--                 P        I
0108   //--                 P      #  il faut trouver un point ici
0109   //--                 P    I
0110   //--                 P  I
0111   //--                 PI
0112   //--                 *                    I
0113   //--                 PI                 I 
0114   //--                 P  I I I I I I I I
0115   //--
0116 
0117   
0118   for (i=1; i <= Nbsample+12; i++) {
0119     gp_Pnt2d s2d;
0120     gp_Pnt s3d;
0121     Standard_Boolean nepastester=Standard_False;
0122     if(i<=Nbsample) { 
0123       T->SamplePoint(i,s2d,s3d);      
0124       UVap(1)=s2d.X(); UVap(2)=s2d.Y();
0125       
0126       Standard_Real u1,v1,u2,v2;
0127       u1 = Binf(1) = Max(umin,UVap(1)-du);
0128       v1 = Binf(2) = Max(vmin,UVap(2)-dv);
0129       u2 = Bsup(1) = Min(umax,UVap(1)+du);
0130       v2 = Bsup(2) = Min(vmax,UVap(2)+dv);
0131       
0132       
0133       //-- gp_Pnt Pmilieu = ThePSurfaceTool::Value(PS,0.5*(u1+u2),0.5*(v1+v2));
0134       gp_Pnt Pextrm1 = ThePSurfaceTool::Value(PS,u1,v1);
0135       gp_Pnt Pextrm2 = ThePSurfaceTool::Value(PS,u2,v2);
0136       Standard_Real aValf[1];
0137       math_Vector Valf(aValf,1,1);
0138       Func.Value(UVap,Valf);
0139       Standard_Real rvalf = Valf(1);
0140       Standard_Real DistPP = Pextrm1.SquareDistance(Pextrm2);
0141       if(rvalf*rvalf > 3.0*DistPP) { 
0142         nepastester=Standard_True;
0143       }      
0144     }
0145     else { 
0146                  if(i==Nbsample+1) { s2d.SetCoord(umin+du*0.02,vmin+dv*0.02); }
0147       else       if(i==Nbsample+2) { s2d.SetCoord(umax-du*0.02,vmin+dv*0.02);  }
0148       else       if(i==Nbsample+3) { s2d.SetCoord(umin+du*0.02,vmax-dv*0.02); }
0149       else       if(i==Nbsample+4) { s2d.SetCoord(umax-du*0.02,vmax-dv*0.02);  }
0150 
0151       else       if(i==Nbsample+5) { s2d.SetCoord(umin+du*0.02,vmin+dv*0.02); }
0152       else       if(i==Nbsample+6) { s2d.SetCoord(umax-du*0.02,vmin+dv*0.02);  }
0153       else       if(i==Nbsample+7) { s2d.SetCoord(umin+du*0.02,vmax-dv*0.02); }
0154       else       if(i==Nbsample+8) { s2d.SetCoord(umax-du*0.02,vmax-dv*0.02);  }
0155 
0156       else       if(i==Nbsample+9) { s2d.SetCoord(umin+du*0.005,vmin+dv*0.005); }
0157       else       if(i==Nbsample+10){ s2d.SetCoord(umax-du*0.005,vmin+dv*0.005);  }
0158       else       if(i==Nbsample+11){ s2d.SetCoord(umin+du*0.005,vmax-dv*0.005); }
0159       else                         { s2d.SetCoord(umax-du*0.005,vmax-dv*0.005);  }
0160 
0161       UVap(1)=s2d.X(); UVap(2)=s2d.Y();
0162 
0163       Binf(1) = Max(umin,UVap(1)-du);
0164       Binf(2) = Max(vmin,UVap(2)-dv);
0165       Bsup(1) = Min(umax,UVap(1)+du);
0166       Bsup(2) = Min(vmax,UVap(2)+dv);      
0167     }
0168     
0169 
0170     if(nepastester==Standard_False) { 
0171       Rsnld.Perform(Func,UVap,Binf,Bsup);
0172       if (Rsnld.IsDone()) {
0173         if (Abs(Func.Root()) <= Tol) {
0174           if (!Func.IsTangent()) {
0175             psol = Func.Point();
0176             Rsnld.Root(UVap);
0177             // On regarde si le point trouve est bien un nouveau point.   
0178             j = 1;
0179             nbpt = list.Length();
0180             testpnt = (j <= nbpt);
0181             
0182             while (testpnt) {
0183               const IntSurf_InteriorPoint&  IPj = list(j);
0184               const gp_Pnt& Pj = IPj.Value();
0185               if (   (Abs(Pj.X()-psol.X()) <= Epsilon)
0186                   && (Abs(Pj.Y()-psol.Y()) <= Epsilon)
0187                   && (Abs(Pj.Z()-psol.Z()) <= Epsilon)
0188                   && (Abs(UVap(1)-IPj.UParameter()) <= toler1)
0189                   && (Abs(UVap(2)-IPj.VParameter()) <= toler2) ) {
0190                 testpnt = Standard_False;
0191               }
0192               else {
0193                 j = j+1;
0194                 testpnt = (j <= nbpt);
0195               }
0196             }
0197             if (j > nbpt) {
0198               //            situ = TheSITool::Classify(PS,UVap(1),UVap(2));
0199               situ = T->Classify(gp_Pnt2d(UVap(1),UVap(2)),
0200                                  Maxtoler1toler2,Standard_False);   //-- ,Standard_False pour ne pas recadrer on Periodic
0201               if (situ == TopAbs_IN) {
0202                 list.Append(IntSurf_InteriorPoint(psol,UVap(1),UVap(2),
0203                                                   Func.Direction3d(),
0204                                                   Func.Direction2d()));
0205               }
0206             }
0207           }
0208         }
0209       }
0210     }
0211   }
0212   //-- printf("\n Total : %d    Rejet : %d   RatioPointCalc : %g   nbpt =%d\n",REJET_OK+REJET_KO,REJET_OK,(double)(REJET_KO)/(double)(REJET_OK+REJET_KO),list.Length());
0213   done = Standard_True;
0214 }
0215 
0216 
0217 //=======================================================================
0218 //function : Perform
0219 //purpose  : Test the given inside point
0220 //=======================================================================
0221 
0222 void IntStart_SearchInside::Perform (TheFunction& Func,
0223                                      const ThePSurface& PS,
0224                                      const Standard_Real UStart,
0225                                      const Standard_Real VStart)
0226 {
0227   done = Standard_False;
0228   list.Clear();
0229   math_Vector Binf(1,2), Bsup(1,2), toler(1,2);
0230 
0231   Binf(1) = ThePSurfaceTool::FirstUParameter(PS);
0232   Binf(2) = ThePSurfaceTool::FirstVParameter(PS);
0233   Bsup(1) = ThePSurfaceTool::LastUParameter(PS);
0234   Bsup(2) = ThePSurfaceTool::LastVParameter(PS);
0235 
0236   toler(1) = ThePSurfaceTool::UResolution(PS,Precision::Confusion());
0237   toler(2) = ThePSurfaceTool::VResolution(PS,Precision::Confusion());
0238 
0239   if (UStart-Binf(1) > -toler(1) && UStart-Bsup(1) < toler(1) &&
0240       VStart-Binf(2) > -toler(2) && VStart-Bsup(2) < toler(2)) {
0241 
0242     Func.Set(PS);
0243     math_Vector UVap(1,2);
0244     UVap(1)=UStart; UVap(2)=VStart;
0245 
0246     math_FunctionSetRoot Rsnld(Func,toler);
0247     Rsnld.Perform(Func,UVap,Binf,Bsup);
0248     if (Rsnld.IsDone()) {
0249       Standard_Real tol = Func.Tolerance();
0250       Standard_Real valf = Func.Root();
0251       if (Abs(valf) <= tol && !Func.IsTangent()) {
0252         const gp_Pnt& psol = Func.Point();
0253         Rsnld.Root(UVap);
0254         IntSurf_InteriorPoint intp (psol,UVap(1),UVap(2),
0255                                     Func.Direction3d(),Func.Direction2d());
0256         list.Append(intp);
0257       }
0258     }
0259   }
0260 
0261   done = Standard_True;
0262 }