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 //======================================================================