Back to home page

EIC code displayed by LXR

 
 

    


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

0001 // Created on: 1992-10-12
0002 // Created by: Laurent BUCHARD
0003 // Copyright (c) 1992-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 #define TEST 0
0018 
0019 #include <Standard_ConstructionError.hxx>
0020 #include <Bnd_Box2d.hxx>
0021 #include <TColgp_Array1OfPnt2d.hxx>
0022 #include <gp_Lin2d.hxx>
0023 #include <gp_Vec2d.hxx>
0024 #include <gp_Dir2d.hxx>
0025 
0026 
0027 #define MAJORATION_DEFLECTION 1.5
0028 //======================================================================
0029 //== We take samples on the Domain of the Curve  NbPts Points 
0030 //== with constant parameters.
0031 //== 
0032 //== We estimate the maximum deflection taking the max distance between the
0033 //== right Curve.Value(X(i))-->Curve.Value(X(i+1)) 
0034 //== and the point Curve.Value(X(i+1/2))
0035 //======================================================================
0036 //  Modified by Sergey KHROMOV - Mon Mar 24 12:02:43 2003 Begin
0037 IntCurve_Polygon2dGen::IntCurve_Polygon2dGen(const TheCurve&        C,
0038                                              const Standard_Integer tNbPts,
0039                                              const IntRes2d_Domain& D,
0040                                              const Standard_Real    Tol):
0041 //  Modified by Sergey KHROMOV - Mon Mar 24 12:02:45 2003 End
0042        ThePnts(1,(tNbPts<3)? 6 : (tNbPts+tNbPts)),
0043        TheParams(1,(tNbPts<3)? 6 : (tNbPts+tNbPts)),
0044        TheIndex(1,(tNbPts<3)? 6 : (tNbPts+tNbPts))
0045 { 
0046          
0047   Standard_Integer NbPts = (tNbPts<3)? 3 : tNbPts;
0048   TheMaxNbPoints = NbPts+NbPts;
0049   NbPntIn = NbPts;
0050   //----------------------------------------------------- 
0051   //--- Initialization of the breaking with d_Parametre constant
0052   //---
0053   Binf = D.FirstParameter();
0054   Bsup = D.LastParameter();
0055   //-----------------------------------------------------
0056   //-- IntRes2d Raise if HasFirst returns False
0057   //-- and accesses First Parameter
0058   //-- 
0059   Standard_Real u=Binf; 
0060   Standard_Real u1=Bsup;
0061   Standard_Real du=(u1-u)/(Standard_Real)(NbPts-1);
0062 //  Standard_Integer ip1,i=1;
0063   Standard_Integer i=1;
0064   
0065   do {
0066     gp_Pnt2d P=TheCurveTool::Value(C,u);
0067     myBox.Add(P);
0068     TheIndex.SetValue(i,i);
0069     ThePnts.SetValue(i,P); 
0070     TheParams.SetValue(i,u);
0071     u+=du;
0072     i++;
0073   }
0074   while(i<=NbPts);
0075 
0076 
0077   //-----------------------------------------------------
0078   //--- Calculate a maximal deflection
0079   //---
0080 //  Modified by Sergey KHROMOV - Mon Mar 24 12:03:05 2003 Begin
0081 //   TheDeflection = 0.000000001;
0082   TheDeflection = Min(0.000000001, Tol/100.);
0083 //  Modified by Sergey KHROMOV - Mon Mar 24 12:03:05 2003 End
0084   i=1;
0085   u=D.FirstParameter();
0086   u+=du * 0.5;
0087   
0088   do {
0089     gp_Pnt2d Pm = TheCurveTool::Value(C,u);
0090     const gp_Pnt2d& P1 = ThePnts.Value(i);
0091     const gp_Pnt2d& P2 = ThePnts.Value(i+1);
0092 
0093     u+=du;
0094     i++;
0095 
0096 
0097     Standard_Real dx,dy,t=0;    
0098     dx=P1.X()-P2.X(); if(dx<0) dx=-dx;
0099     dy=P1.Y()-P2.Y(); if(dy<0) dy=-dy;
0100     if(dx+dy>1e-12) { 
0101       gp_Lin2d L(P1,gp_Dir2d(gp_Vec2d(P1,P2)));
0102       t = L.Distance(Pm);
0103       if(t>TheDeflection) {
0104         TheDeflection = t;
0105       }
0106     }
0107   }
0108   while(i<NbPts);
0109 
0110   myBox.Enlarge(TheDeflection*MAJORATION_DEFLECTION);
0111   ClosedPolygon = Standard_False;
0112 }
0113 //======================================================================
0114 void IntCurve_Polygon2dGen::ComputeWithBox(const TheCurve&        C,
0115                                            const Bnd_Box2d& BoxOtherPolygon) {
0116   if(myBox.IsOut(BoxOtherPolygon)) { 
0117     NbPntIn=2;
0118     myBox.SetVoid();
0119   }
0120   else { 
0121      Standard_Real bx0,bx1,by0,by1;
0122      BoxOtherPolygon.Get(bx0,by0,bx1,by1);
0123 
0124     bx0-=TheDeflection; 
0125     by0-=TheDeflection; 
0126     bx1+=TheDeflection; 
0127     by1+=TheDeflection;
0128     Standard_Integer MaxIndexUsed = 1;
0129     Standard_Integer i,nbp;
0130     Standard_Integer Rprec,Ri;
0131     Standard_Real x,y;
0132     
0133     nbp = 0;
0134     x = ThePnts.Value(TheIndex.Value(1)).X();
0135     y = ThePnts.Value(TheIndex.Value(1)).Y();
0136     
0137     Rprec = CalculRegion(x,y,bx0,bx1,by0,by1);
0138     for(i = 2; i<=NbPntIn; i++) { 
0139       const gp_Pnt2d& P2d = ThePnts.Value(TheIndex.Value(i));
0140       Ri = CalculRegion(P2d.X(),P2d.Y(),bx0,bx1,by0,by1);
0141       if((Ri & Rprec)==0) { 
0142         if(nbp) { 
0143           if(TheIndex.Value(nbp) != TheIndex.Value(i-1)) { 
0144             nbp++;
0145             TheIndex.SetValue(nbp,TheIndex.Value(i-1));
0146           }
0147         }
0148         else {
0149           nbp++;
0150           TheIndex.SetValue(nbp,TheIndex.Value(i-1)); 
0151         }
0152         nbp++;
0153         TheIndex.SetValue(nbp,TheIndex.Value(i));
0154         if(TheIndex.Value(i) > MaxIndexUsed) MaxIndexUsed = TheIndex.Value(i);
0155 
0156         Rprec = Ri;
0157       }//if((Ri & Rprec)==0) condition
0158 
0159       Rprec = Ri;
0160     }
0161     if(nbp==1) { 
0162       NbPntIn=2;
0163       myBox.SetVoid();
0164     }
0165     else {
0166       myBox.SetVoid();
0167       if(nbp) { 
0168         myBox.Add(ThePnts.Value(TheIndex.Value(1)));
0169       }
0170       Standard_Real    RatioDeflection;
0171       Standard_Integer nbpassagedeflection = 0;
0172 //      Standard_Integer PointHasBeenAdded = 0;
0173       do { 
0174         nbpassagedeflection++;
0175 //  Modified by Sergey KHROMOV - Mon Mar 24 12:05:28 2003 Begin
0176 //      Standard_Real NewDeflection = 0.0000001;
0177         Standard_Real NewDeflection = TheDeflection;
0178 //  Modified by Sergey KHROMOV - Mon Mar 24 12:05:29 2003 End
0179         for(i=2; i<=nbp; i++) { 
0180           Standard_Integer Ii  = TheIndex.Value(i);
0181           Standard_Integer Iim1= TheIndex.Value(i-1);
0182           const gp_Pnt2d& Pi   = ThePnts.Value(Ii);
0183           const gp_Pnt2d& Pim1 = ThePnts.Value(Iim1);
0184           myBox.Add(Pi);
0185           Standard_Integer Regi   = CalculRegion(Pi.X(),Pi.Y(),bx0,bx1,by0,by1);
0186           Standard_Integer Regim1 = CalculRegion(Pim1.X(),Pim1.Y(),bx0,bx1,by0,by1); 
0187           if((Regi & Regim1) == 0) {  
0188             Standard_Real u = 0.5*( TheParams.Value(Ii)
0189                                    +TheParams.Value(Iim1));
0190             gp_Pnt2d Pm = TheCurveTool::Value(C,u);
0191             Standard_Real dx,dy,t=0;    
0192             dx=Pim1.X()-Pi.X(); if(dx<0) dx=-dx;
0193             dy=Pim1.Y()-Pi.Y(); if(dy<0) dy=-dy;
0194             if(dx+dy>1e-12)  {
0195               gp_Lin2d L(Pim1,gp_Dir2d(gp_Vec2d(Pim1,Pi)));
0196               t = L.Distance(Pm);
0197               if((MaxIndexUsed<(TheMaxNbPoints-1)) && (t>(TheDeflection * 0.5))) {
0198                 const gp_Pnt2d& P1=Pim1;
0199                 nbp++;
0200                 for(Standard_Integer j=nbp; j>=i+1; j--) { 
0201                   TheIndex.SetValue(j,TheIndex.Value(j-1));
0202                 }
0203                 MaxIndexUsed++;
0204                 TheIndex.SetValue(i,MaxIndexUsed);
0205                 ThePnts.SetValue(MaxIndexUsed,Pm);
0206                 TheParams.SetValue(MaxIndexUsed,u);
0207                 
0208                 Standard_Real u1m = 0.5*(u+TheParams.Value(TheIndex.Value(i-1)));
0209                 gp_Pnt2d P1m = TheCurveTool::Value(C,u1m);
0210         gp_Lin2d L1m(P1,gp_Dir2d(gp_Vec2d(P1,Pm)));
0211         t = L1m.Distance(P1m);
0212                 i--; 
0213               }
0214             }
0215             else { 
0216               if(t>NewDeflection) { 
0217                 NewDeflection = t; 
0218               }
0219             }
0220           }
0221         }
0222         if(NewDeflection) 
0223           RatioDeflection = TheDeflection / NewDeflection; 
0224         else RatioDeflection = 10.0;
0225         TheDeflection = NewDeflection;
0226         NbPntIn = nbp;
0227       }
0228       while((RatioDeflection<3.0)
0229             && (nbpassagedeflection < 3) 
0230             && (MaxIndexUsed<(TheMaxNbPoints-2)));
0231     }
0232 
0233     TheDeflection*=MAJORATION_DEFLECTION;
0234     myBox.Enlarge(TheDeflection);
0235   }
0236   ClosedPolygon = Standard_False;
0237   Dump();
0238 }
0239 
0240 
0241 Standard_Boolean IntCurve_Polygon2dGen::AutoIntersectionIsPossible() const { 
0242 
0243   gp_Vec2d VRef(ThePnts.Value(TheIndex.Value(1)),
0244                 ThePnts.Value(TheIndex.Value(2)));
0245   for(Standard_Integer i=3; i<=NbPntIn; i++) { 
0246     gp_Vec2d V(ThePnts.Value(TheIndex.Value(i-1)),
0247                 ThePnts.Value(TheIndex.Value(i)));
0248     if(V.Dot(VRef)<0.0) {
0249       return(Standard_True);
0250     }
0251   }
0252   return(Standard_False); 
0253 }
0254 
0255 //======================================================================
0256 Standard_Real IntCurve_Polygon2dGen::ApproxParamOnCurve( const Standard_Integer Aindex
0257                                                         ,const Standard_Real TheParamOnLine) 
0258      const 
0259 {
0260   Standard_Integer Indexp1,Index = Aindex;
0261   Standard_Real    ParamOnLine = TheParamOnLine;
0262   if (Index > NbPntIn) {
0263     std::cout << "OutOfRange Polygon2d::ApproxParamOnCurve " <<std::endl;
0264   }
0265   if((Index == NbPntIn) && (ParamOnLine == 0.0)) { 
0266     Index--; ParamOnLine=1.0;
0267   }
0268   if(Index==0) { 
0269     Index=1; 
0270     ParamOnLine = 0.0;
0271   }
0272   Indexp1 = TheIndex.Value(Index+1);
0273   Index   = TheIndex.Value(Index);
0274 
0275   Standard_Real du = TheParams.Value(Indexp1)-TheParams.Value(Index);
0276   Standard_Real u  = TheParams.Value(Index) + ParamOnLine * du;
0277   return(u);
0278 }
0279 
0280 
0281 //======================================================================
0282 #if TEST
0283 
0284 extern Standard_Boolean DebugPolygon2d;
0285 extern void DrawSegmentBlanc(const gp_Pnt2d& _P1,const gp_Pnt2d& _P2);
0286 extern void DrawSegment(const gp_Pnt2d& _P1,const gp_Pnt2d& _P2);
0287 
0288 void IntCurve_Polygon2dGen::Dump(void) const {
0289   if(!DebugPolygon2d) return;
0290   Standard_Real bx0,bx1,by0,by1;
0291   if(myBox.IsVoid()) return;
0292   myBox.Get(bx0,by0,bx1,by1);
0293   DrawSegment(gp_Pnt2d(bx0,by0),gp_Pnt2d(bx1,by0));
0294   DrawSegment(gp_Pnt2d(bx1,by0),gp_Pnt2d(bx1,by1));
0295   DrawSegment(gp_Pnt2d(bx1,by1),gp_Pnt2d(bx0,by1));
0296   DrawSegment(gp_Pnt2d(bx0,by1),gp_Pnt2d(bx0,by0));    
0297   Standard_Integer i;
0298   if(NbPntIn<=1) return;
0299   for(i=2;i<=NbPntIn; i++) { 
0300     DrawSegmentBlanc(ThePnts.Value(TheIndex.Value(i-1)),ThePnts.Value(TheIndex.Value(i)));
0301   }
0302 }
0303 #else
0304 void IntCurve_Polygon2dGen::Dump(void) const { 
0305   static int debug = 0;
0306   if(debug) { 
0307     Standard_Real bx0,bx1,by0,by1;
0308     
0309     std::cout<<"\n ----- Dump of IntCurve_Polygon2dGen -----"<<std::endl;
0310     if(myBox.IsVoid()) { 
0311       std::cout<<"  Polygone Vide "<<std::endl;
0312       return;
0313     }
0314     myBox.Get(bx0,by0,bx1,by1);
0315     std::cout<<"  bx0:"<<bx0  <<std::endl;
0316     std::cout<<"  by0:"<<by0<<std::endl;
0317     std::cout<<"  bx1:"<<bx1<<std::endl;
0318     std::cout<<"  by1:"<<by1<<std::endl;
0319     
0320     Standard_Integer i;
0321     for(i=1;i<=NbPntIn; i++) { 
0322       const gp_Pnt2d& P = ThePnts(TheIndex(i));
0323       std::cout<<"  ("<<i<<") u:"<<TheParams.Value(TheIndex(i))<<" X:"<<P.X()<<"  Y:"<<P.Y()<<std::endl;
0324     }
0325   }
0326 } 
0327 #endif
0328 //======================================================================
0329 void IntCurve_Polygon2dGen::Segment(const Standard_Integer theIndex,
0330                                     gp_Pnt2d &theBegin, gp_Pnt2d &theEnd) const
0331 {
0332   Standard_Integer ind = theIndex;
0333   theBegin = ThePnts(TheIndex(theIndex));
0334   if (theIndex >= NbPntIn) {
0335     if (!ClosedPolygon)
0336       throw Standard_OutOfRange("IntCurve_Polygon2dGen::Segment!");
0337     ind = 0;
0338   }
0339   theEnd = ThePnts(TheIndex(ind+1));
0340 }
0341 //======================================================================