0030895: Coding Rules - specify std namespace explicitly for std::cout and streams
[occt.git] / src / IntCurve / IntCurve_Polygon2dGen.gxx
CommitLineData
b311480e 1// Created on: 1992-10-12
2// Created by: Laurent BUCHARD
3// Copyright (c) 1992-1999 Matra Datavision
973c2be1 4// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 5//
973c2be1 6// This file is part of Open CASCADE Technology software library.
b311480e 7//
d5f74e42 8// This library is free software; you can redistribute it and/or modify it under
9// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 10// by the Free Software Foundation, with special exception defined in the file
11// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12// distribution for complete text of the license and disclaimer of any warranty.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
7fd59977 16
17#define TEST 0
18
7fd59977 19#include <Standard_ConstructionError.hxx>
20#include <Bnd_Box2d.hxx>
21#include <TColgp_Array1OfPnt2d.hxx>
22#include <gp_Lin2d.hxx>
23#include <gp_Vec2d.hxx>
24#include <gp_Dir2d.hxx>
25
26
7fd59977 27#define MAJORATION_DEFLECTION 1.5
28//======================================================================
1d19db8d 29//== We take samples on the Domain of the Curve NbPts Points
30//== with constant parameters.
7fd59977 31//==
1d19db8d 32//== We estimate the maximum deflection taking the max distance between the
33//== right Curve.Value(X(i))-->Curve.Value(X(i+1))
34//== and the point Curve.Value(X(i+1/2))
7fd59977 35//======================================================================
36// Modified by Sergey KHROMOV - Mon Mar 24 12:02:43 2003 Begin
37IntCurve_Polygon2dGen::IntCurve_Polygon2dGen(const TheCurve& C,
38 const Standard_Integer tNbPts,
39 const IntRes2d_Domain& D,
40 const Standard_Real Tol):
7fd59977 41// Modified by Sergey KHROMOV - Mon Mar 24 12:02:45 2003 End
42 ThePnts(1,(tNbPts<3)? 6 : (tNbPts+tNbPts)),
43 TheParams(1,(tNbPts<3)? 6 : (tNbPts+tNbPts)),
44 TheIndex(1,(tNbPts<3)? 6 : (tNbPts+tNbPts))
45{
46
47 Standard_Integer NbPts = (tNbPts<3)? 3 : tNbPts;
48 TheMaxNbPoints = NbPts+NbPts;
49 NbPntIn = NbPts;
50 //-----------------------------------------------------
1d19db8d 51 //--- Initialization of the breaking with d_Parametre constant
7fd59977 52 //---
53 Binf = D.FirstParameter();
54 Bsup = D.LastParameter();
55 //-----------------------------------------------------
1d19db8d 56 //-- IntRes2d Raise if HasFirst returns False
57 //-- and accesses First Parameter
7fd59977 58 //--
59 Standard_Real u=Binf;
60 Standard_Real u1=Bsup;
61 Standard_Real du=(u1-u)/(Standard_Real)(NbPts-1);
62// Standard_Integer ip1,i=1;
63 Standard_Integer i=1;
64
65 do {
66 gp_Pnt2d P=TheCurveTool::Value(C,u);
9530af27 67 myBox.Add(P);
7fd59977 68 TheIndex.SetValue(i,i);
69 ThePnts.SetValue(i,P);
70 TheParams.SetValue(i,u);
71 u+=du;
72 i++;
73 }
74 while(i<=NbPts);
75
76
77 //-----------------------------------------------------
1d19db8d 78 //--- Calculate a maximal deflection
7fd59977 79 //---
80// Modified by Sergey KHROMOV - Mon Mar 24 12:03:05 2003 Begin
81// TheDeflection = 0.000000001;
82 TheDeflection = Min(0.000000001, Tol/100.);
83// Modified by Sergey KHROMOV - Mon Mar 24 12:03:05 2003 End
84 i=1;
85 u=D.FirstParameter();
86 u+=du * 0.5;
87
88 do {
89 gp_Pnt2d Pm = TheCurveTool::Value(C,u);
90 const gp_Pnt2d& P1 = ThePnts.Value(i);
91 const gp_Pnt2d& P2 = ThePnts.Value(i+1);
92
93 u+=du;
94 i++;
95
96
97 Standard_Real dx,dy,t=0;
98 dx=P1.X()-P2.X(); if(dx<0) dx=-dx;
99 dy=P1.Y()-P2.Y(); if(dy<0) dy=-dy;
100 if(dx+dy>1e-12) {
101 gp_Lin2d L(P1,gp_Dir2d(gp_Vec2d(P1,P2)));
102 t = L.Distance(Pm);
103 if(t>TheDeflection) {
104 TheDeflection = t;
105 }
106 }
107 }
108 while(i<NbPts);
109
9530af27 110 myBox.Enlarge(TheDeflection*MAJORATION_DEFLECTION);
7fd59977 111 ClosedPolygon = Standard_False;
112}
113//======================================================================
7fd59977 114void IntCurve_Polygon2dGen::ComputeWithBox(const TheCurve& C,
115 const Bnd_Box2d& BoxOtherPolygon) {
9530af27 116 if(myBox.IsOut(BoxOtherPolygon)) {
7fd59977 117 NbPntIn=2;
9530af27 118 myBox.SetVoid();
7fd59977 119 }
120 else {
121 Standard_Real bx0,bx1,by0,by1;
122 BoxOtherPolygon.Get(bx0,by0,bx1,by1);
123
124 bx0-=TheDeflection;
125 by0-=TheDeflection;
126 bx1+=TheDeflection;
127 by1+=TheDeflection;
128 Standard_Integer MaxIndexUsed = 1;
129 Standard_Integer i,nbp;
130 Standard_Integer Rprec,Ri;
131 Standard_Real x,y;
132
133 nbp = 0;
134 x = ThePnts.Value(TheIndex.Value(1)).X();
135 y = ThePnts.Value(TheIndex.Value(1)).Y();
136
137 Rprec = CalculRegion(x,y,bx0,bx1,by0,by1);
138 for(i = 2; i<=NbPntIn; i++) {
139 const gp_Pnt2d& P2d = ThePnts.Value(TheIndex.Value(i));
140 Ri = CalculRegion(P2d.X(),P2d.Y(),bx0,bx1,by0,by1);
141 if((Ri & Rprec)==0) {
1d19db8d 142 if(nbp) {
143 if(TheIndex.Value(nbp) != TheIndex.Value(i-1)) {
144 nbp++;
145 TheIndex.SetValue(nbp,TheIndex.Value(i-1));
146 }
147 }
148 else {
149 nbp++;
150 TheIndex.SetValue(nbp,TheIndex.Value(i-1));
151 }
152 nbp++;
153 TheIndex.SetValue(nbp,TheIndex.Value(i));
154 if(TheIndex.Value(i) > MaxIndexUsed) MaxIndexUsed = TheIndex.Value(i);
7fd59977 155
1d19db8d 156 Rprec = Ri;
157 }//if((Ri & Rprec)==0) condition
7fd59977 158
7fd59977 159 Rprec = Ri;
160 }
161 if(nbp==1) {
162 NbPntIn=2;
9530af27 163 myBox.SetVoid();
7fd59977 164 }
165 else {
9530af27 166 myBox.SetVoid();
7fd59977 167 if(nbp) {
9530af27 168 myBox.Add(ThePnts.Value(TheIndex.Value(1)));
7fd59977 169 }
170 Standard_Real RatioDeflection;
171 Standard_Integer nbpassagedeflection = 0;
172// Standard_Integer PointHasBeenAdded = 0;
173 do {
174 nbpassagedeflection++;
175// Modified by Sergey KHROMOV - Mon Mar 24 12:05:28 2003 Begin
176// Standard_Real NewDeflection = 0.0000001;
177 Standard_Real NewDeflection = TheDeflection;
178// Modified by Sergey KHROMOV - Mon Mar 24 12:05:29 2003 End
179 for(i=2; i<=nbp; i++) {
180 Standard_Integer Ii = TheIndex.Value(i);
181 Standard_Integer Iim1= TheIndex.Value(i-1);
182 const gp_Pnt2d& Pi = ThePnts.Value(Ii);
183 const gp_Pnt2d& Pim1 = ThePnts.Value(Iim1);
9530af27 184 myBox.Add(Pi);
7fd59977 185 Standard_Integer Regi = CalculRegion(Pi.X(),Pi.Y(),bx0,bx1,by0,by1);
186 Standard_Integer Regim1 = CalculRegion(Pim1.X(),Pim1.Y(),bx0,bx1,by0,by1);
187 if((Regi & Regim1) == 0) {
188 Standard_Real u = 0.5*( TheParams.Value(Ii)
189 +TheParams.Value(Iim1));
190 gp_Pnt2d Pm = TheCurveTool::Value(C,u);
191 Standard_Real dx,dy,t=0;
192 dx=Pim1.X()-Pi.X(); if(dx<0) dx=-dx;
193 dy=Pim1.Y()-Pi.Y(); if(dy<0) dy=-dy;
194 if(dx+dy>1e-12) {
195 gp_Lin2d L(Pim1,gp_Dir2d(gp_Vec2d(Pim1,Pi)));
196 t = L.Distance(Pm);
197 if((MaxIndexUsed<(TheMaxNbPoints-1)) && (t>(TheDeflection * 0.5))) {
198 const gp_Pnt2d& P1=Pim1;
199 nbp++;
200 for(Standard_Integer j=nbp; j>=i+1; j--) {
201 TheIndex.SetValue(j,TheIndex.Value(j-1));
202 }
203 MaxIndexUsed++;
204 TheIndex.SetValue(i,MaxIndexUsed);
205 ThePnts.SetValue(MaxIndexUsed,Pm);
206 TheParams.SetValue(MaxIndexUsed,u);
207
208 Standard_Real u1m = 0.5*(u+TheParams.Value(TheIndex.Value(i-1)));
7fd59977 209 gp_Pnt2d P1m = TheCurveTool::Value(C,u1m);
96a95605
DB
210 gp_Lin2d L1m(P1,gp_Dir2d(gp_Vec2d(P1,Pm)));
211 t = L1m.Distance(P1m);
7fd59977 212 i--;
213 }
214 }
215 else {
216 if(t>NewDeflection) {
217 NewDeflection = t;
218 }
219 }
220 }
221 }
222 if(NewDeflection)
223 RatioDeflection = TheDeflection / NewDeflection;
224 else RatioDeflection = 10.0;
225 TheDeflection = NewDeflection;
226 NbPntIn = nbp;
227 }
228 while((RatioDeflection<3.0)
229 && (nbpassagedeflection < 3)
230 && (MaxIndexUsed<(TheMaxNbPoints-2)));
231 }
232
233 TheDeflection*=MAJORATION_DEFLECTION;
9530af27 234 myBox.Enlarge(TheDeflection);
7fd59977 235 }
236 ClosedPolygon = Standard_False;
237 Dump();
238}
239
240
241Standard_Boolean IntCurve_Polygon2dGen::AutoIntersectionIsPossible() const {
242
243 gp_Vec2d VRef(ThePnts.Value(TheIndex.Value(1)),
244 ThePnts.Value(TheIndex.Value(2)));
245 for(Standard_Integer i=3; i<=NbPntIn; i++) {
246 gp_Vec2d V(ThePnts.Value(TheIndex.Value(i-1)),
247 ThePnts.Value(TheIndex.Value(i)));
248 if(V.Dot(VRef)<0.0) {
249 return(Standard_True);
250 }
251 }
252 return(Standard_False);
253}
254
255//======================================================================
256Standard_Real IntCurve_Polygon2dGen::ApproxParamOnCurve( const Standard_Integer Aindex
257 ,const Standard_Real TheParamOnLine)
258 const
259{
260 Standard_Integer Indexp1,Index = Aindex;
261 Standard_Real ParamOnLine = TheParamOnLine;
262 if (Index > NbPntIn) {
04232180 263 std::cout << "OutOfRange Polygon2d::ApproxParamOnCurve " <<std::endl;
7fd59977 264 }
265 if((Index == NbPntIn) && (ParamOnLine == 0.0)) {
266 Index--; ParamOnLine=1.0;
267 }
268 if(Index==0) {
269 Index=1;
270 ParamOnLine = 0.0;
271 }
272 Indexp1 = TheIndex.Value(Index+1);
273 Index = TheIndex.Value(Index);
274
275 Standard_Real du = TheParams.Value(Indexp1)-TheParams.Value(Index);
276 Standard_Real u = TheParams.Value(Index) + ParamOnLine * du;
277 return(u);
278}
279
280
281//======================================================================
282#if TEST
283
284extern Standard_Boolean DebugPolygon2d;
285extern void DrawSegmentBlanc(const gp_Pnt2d& _P1,const gp_Pnt2d& _P2);
286extern void DrawSegment(const gp_Pnt2d& _P1,const gp_Pnt2d& _P2);
287
288void IntCurve_Polygon2dGen::Dump(void) const {
289 if(!DebugPolygon2d) return;
290 Standard_Real bx0,bx1,by0,by1;
9530af27 291 if(myBox.IsVoid()) return;
292 myBox.Get(bx0,by0,bx1,by1);
7fd59977 293 DrawSegment(gp_Pnt2d(bx0,by0),gp_Pnt2d(bx1,by0));
294 DrawSegment(gp_Pnt2d(bx1,by0),gp_Pnt2d(bx1,by1));
295 DrawSegment(gp_Pnt2d(bx1,by1),gp_Pnt2d(bx0,by1));
296 DrawSegment(gp_Pnt2d(bx0,by1),gp_Pnt2d(bx0,by0));
297 Standard_Integer i;
298 if(NbPntIn<=1) return;
299 for(i=2;i<=NbPntIn; i++) {
300 DrawSegmentBlanc(ThePnts.Value(TheIndex.Value(i-1)),ThePnts.Value(TheIndex.Value(i)));
301 }
302}
303#else
304void IntCurve_Polygon2dGen::Dump(void) const {
305 static int debug = 0;
306 if(debug) {
307 Standard_Real bx0,bx1,by0,by1;
308
04232180 309 std::cout<<"\n ----- Dump of IntCurve_Polygon2dGen -----"<<std::endl;
9530af27 310 if(myBox.IsVoid()) {
04232180 311 std::cout<<" Polygone Vide "<<std::endl;
7fd59977 312 return;
313 }
9530af27 314 myBox.Get(bx0,by0,bx1,by1);
04232180 315 std::cout<<" bx0:"<<bx0 <<std::endl;
316 std::cout<<" by0:"<<by0<<std::endl;
317 std::cout<<" bx1:"<<bx1<<std::endl;
318 std::cout<<" by1:"<<by1<<std::endl;
7fd59977 319
320 Standard_Integer i;
321 for(i=1;i<=NbPntIn; i++) {
322 const gp_Pnt2d& P = ThePnts(TheIndex(i));
04232180 323 std::cout<<" ("<<i<<") u:"<<TheParams.Value(TheIndex(i))<<" X:"<<P.X()<<" Y:"<<P.Y()<<std::endl;
7fd59977 324 }
325 }
326}
327#endif
328//======================================================================
9530af27 329void IntCurve_Polygon2dGen::Segment(const Standard_Integer theIndex,
330 gp_Pnt2d &theBegin, gp_Pnt2d &theEnd) const
331{
332 Standard_Integer ind = theIndex;
333 theBegin = ThePnts(TheIndex(theIndex));
334 if (theIndex >= NbPntIn) {
335 if (!ClosedPolygon)
9775fa61 336 throw Standard_OutOfRange("IntCurve_Polygon2dGen::Segment!");
9530af27 337 ind = 0;
338 }
339 theEnd = ThePnts(TheIndex(ind+1));
340}
7fd59977 341//======================================================================