0022627: Change OCCT memory management defaults
[occt.git] / src / IntCurve / IntCurve_Polygon2dGen.gxx
CommitLineData
7fd59977 1// File: IntCurve_Polygon2dGen.gxx
2// Created: Mon Oct 12 17:17:30 1992
3// Author: Laurent BUCHARD
7fd59977 4
5#define TEST 0
6
7fd59977 7#include <Standard_ConstructionError.hxx>
8#include <Bnd_Box2d.hxx>
9#include <TColgp_Array1OfPnt2d.hxx>
10#include <gp_Lin2d.hxx>
11#include <gp_Vec2d.hxx>
12#include <gp_Dir2d.hxx>
13
14
7fd59977 15#define MAJORATION_DEFLECTION 1.5
16//======================================================================
17//== On echantillonne sur le Domain de la Curve NbPts Points
18//== a parametres constants.
19//==
20//== On estime la fleche maximum en prenant la distance maxi entre la
21//== droite Curve.Value(X(i))-->Curve.Value(X(i+1))
22//== et le point Curve.Value(X(i+1/2))
23//======================================================================
24// Modified by Sergey KHROMOV - Mon Mar 24 12:02:43 2003 Begin
25IntCurve_Polygon2dGen::IntCurve_Polygon2dGen(const TheCurve& C,
26 const Standard_Integer tNbPts,
27 const IntRes2d_Domain& D,
28 const Standard_Real Tol):
29// const Standard_Real ):
30// Modified by Sergey KHROMOV - Mon Mar 24 12:02:45 2003 End
31 ThePnts(1,(tNbPts<3)? 6 : (tNbPts+tNbPts)),
32 TheParams(1,(tNbPts<3)? 6 : (tNbPts+tNbPts)),
33 TheIndex(1,(tNbPts<3)? 6 : (tNbPts+tNbPts))
34{
35
36 Standard_Integer NbPts = (tNbPts<3)? 3 : tNbPts;
37 TheMaxNbPoints = NbPts+NbPts;
38 NbPntIn = NbPts;
39 //-----------------------------------------------------
40 //--- Initialisation du Brise a d_Parametre constant
41 //---
42 Binf = D.FirstParameter();
43 Bsup = D.LastParameter();
44 //-----------------------------------------------------
45 //-- IntRes2d Raise si HasFirst retourne False
46 //-- et Acces a First Parameter
47 //--
48 Standard_Real u=Binf;
49 Standard_Real u1=Bsup;
50 Standard_Real du=(u1-u)/(Standard_Real)(NbPts-1);
51// Standard_Integer ip1,i=1;
52 Standard_Integer i=1;
53
54 do {
55 gp_Pnt2d P=TheCurveTool::Value(C,u);
9530af27 56 myBox.Add(P);
7fd59977 57 TheIndex.SetValue(i,i);
58 ThePnts.SetValue(i,P);
59 TheParams.SetValue(i,u);
60 u+=du;
61 i++;
62 }
63 while(i<=NbPts);
64
65
66 //-----------------------------------------------------
67 //--- Calcul d un majorant de fleche approche
68 //---
69// Modified by Sergey KHROMOV - Mon Mar 24 12:03:05 2003 Begin
70// TheDeflection = 0.000000001;
71 TheDeflection = Min(0.000000001, Tol/100.);
72// Modified by Sergey KHROMOV - Mon Mar 24 12:03:05 2003 End
73 i=1;
74 u=D.FirstParameter();
75 u+=du * 0.5;
76
77 do {
78 gp_Pnt2d Pm = TheCurveTool::Value(C,u);
79 const gp_Pnt2d& P1 = ThePnts.Value(i);
80 const gp_Pnt2d& P2 = ThePnts.Value(i+1);
81
82 u+=du;
83 i++;
84
85
86 Standard_Real dx,dy,t=0;
87 dx=P1.X()-P2.X(); if(dx<0) dx=-dx;
88 dy=P1.Y()-P2.Y(); if(dy<0) dy=-dy;
89 if(dx+dy>1e-12) {
90 gp_Lin2d L(P1,gp_Dir2d(gp_Vec2d(P1,P2)));
91 t = L.Distance(Pm);
92 if(t>TheDeflection) {
93 TheDeflection = t;
94 }
95 }
96 }
97 while(i<NbPts);
98
9530af27 99 myBox.Enlarge(TheDeflection*MAJORATION_DEFLECTION);
7fd59977 100 ClosedPolygon = Standard_False;
101}
102//======================================================================
103// Modified by Sergey KHROMOV - Mon Mar 24 12:03:26 2003 Begin
104IntCurve_Polygon2dGen::IntCurve_Polygon2dGen(const TheCurve& C,
105 const Standard_Integer tNbPts,
106 const IntRes2d_Domain& D,
107 const Standard_Real Tol,
108 const Bnd_Box2d& BoxOtherPolygon):
109// Modified by Sergey KHROMOV - Mon Mar 24 12:03:28 2003 End
110 ThePnts(1,(tNbPts<3)? 6 : (tNbPts+tNbPts)),
111 TheParams(1,(tNbPts<3)? 6 : (tNbPts+tNbPts)),
112 TheIndex(1,(tNbPts<3)? 6 : (tNbPts+tNbPts))
113{
114 Standard_Integer NbPts = (tNbPts<3)? 3 : tNbPts;
115 TheMaxNbPoints = NbPts+NbPts;
116 NbPntIn = NbPts;
117 //-----------------------------------------------------
118 //--- Initialisation du Brise a d_Parametre constant
119 //---
120 Binf = D.FirstParameter();
121 Bsup = D.LastParameter();
122 //-----------------------------------------------------
123 Standard_Real u=Binf;
124 Standard_Real u1=Bsup;
125 Standard_Real du=(u1-u)/(Standard_Real)(NbPts-1);
126 Standard_Integer i=1;
127 do {
128 gp_Pnt2d P=TheCurveTool::Value(C,u);
9530af27 129 myBox.Add(P);
7fd59977 130 ThePnts.SetValue(i,P);
131 TheParams.SetValue(i,u);
132 TheIndex.SetValue(i,i);
133 u+=du;
134 i++;
135 }
136 while(i<=NbPts);
137
138
139 //-----------------------------------------------------
140 //--- Calcul d un majorant de fleche approche
141 //---
142// Modified by Sergey KHROMOV - Mon Mar 24 12:03:55 2003 Begin
143// TheDeflection = 0.0000001;
144 TheDeflection = Min(0.0000001, Tol/100.);
145// Modified by Sergey KHROMOV - Mon Mar 24 12:03:56 2003 End
146 i=1;
147 u=D.FirstParameter();
148 u+=du * 0.5;
149
150 do {
151 gp_Pnt2d Pm = TheCurveTool::Value(C,u);
152 const gp_Pnt2d& P1 = ThePnts.Value(i);
153 const gp_Pnt2d& P2 = ThePnts.Value(i+1);
154
155 Standard_Real dx,dy;
156 dx=P1.X()-P2.X(); if(dx<0) dx=-dx;
157 dy=P1.Y()-P2.Y(); if(dy<0) dy=-dy;
158 if(dx+dy>1e-12) {
159 gp_Lin2d L(P1,gp_Dir2d(gp_Vec2d(P1,P2)));
160 Standard_Real t = L.Distance(Pm);
161 if(t>TheDeflection) {
162 TheDeflection = t;
163 }
164 }
165 u+=du;
166 i++;
167 }
168 while(i<NbPts);
169
9530af27 170 myBox.Enlarge(TheDeflection*MAJORATION_DEFLECTION);
7fd59977 171 ClosedPolygon = Standard_False;
172 //-------------------------------------------------------
173 //-- On supprime les points alignes
174 //-- (Permet de diminuer le nombre total de points)
175 //-- (Dans le cas ou la courbe est "droite" )
176 Standard_Real DeflectionMaj = TheDeflection;
177 for(i=2;i<NbPntIn && NbPntIn>3;i++) {
178 Standard_Integer indexim1 = TheIndex.Value(i-1);
179 Standard_Integer indexi = TheIndex.Value(i);
180 Standard_Integer indexip1 = TheIndex.Value(i+1);
181 const gp_Pnt2d& Pim1 = ThePnts.Value(indexim1);
182 const gp_Pnt2d& Pi = ThePnts.Value(indexi);
183 const gp_Pnt2d& Pip1 = ThePnts.Value(indexip1);
184
185 Standard_Real dx,dy;
186 dx=Pim1.X()-Pip1.X(); if(dx<0) dx=-dx;
187 dy=Pim1.Y()-Pip1.Y(); if(dy<0) dy=-dy;
188 Standard_Real t=0;
189 if(dx+dy>1e-12) {
190 gp_Lin2d L(Pim1,gp_Dir2d(gp_Vec2d(Pim1,Pip1)));
191 t = L.Distance(Pi);
192 }
193 if(t<=DeflectionMaj) {
194 //-- On supprime le point i
195 for(Standard_Integer j = i; j<NbPntIn; j++) {
196 TheIndex.SetValue(j,TheIndex.Value(j+1));
197 }
198 NbPntIn--;
199 i--;
200 }
201 }
202
203 ComputeWithBox(C,BoxOtherPolygon);
204}
205//======================================================================
206void IntCurve_Polygon2dGen::ComputeWithBox(const TheCurve& C,
207 const Bnd_Box2d& BoxOtherPolygon) {
9530af27 208 if(myBox.IsOut(BoxOtherPolygon)) {
7fd59977 209 NbPntIn=2;
9530af27 210 myBox.SetVoid();
7fd59977 211 }
212 else {
213 Standard_Real bx0,bx1,by0,by1;
214 BoxOtherPolygon.Get(bx0,by0,bx1,by1);
215
216 bx0-=TheDeflection;
217 by0-=TheDeflection;
218 bx1+=TheDeflection;
219 by1+=TheDeflection;
220 Standard_Integer MaxIndexUsed = 1;
221 Standard_Integer i,nbp;
222 Standard_Integer Rprec,Ri;
223 Standard_Real x,y;
224
225 nbp = 0;
226 x = ThePnts.Value(TheIndex.Value(1)).X();
227 y = ThePnts.Value(TheIndex.Value(1)).Y();
228
229 Rprec = CalculRegion(x,y,bx0,bx1,by0,by1);
230 for(i = 2; i<=NbPntIn; i++) {
231 const gp_Pnt2d& P2d = ThePnts.Value(TheIndex.Value(i));
232 Ri = CalculRegion(P2d.X(),P2d.Y(),bx0,bx1,by0,by1);
233 if((Ri & Rprec)==0) {
234 if(nbp) {
235 if(TheIndex.Value(nbp) != TheIndex.Value(i-1)) {
236 nbp++;
237 TheIndex.SetValue(nbp,TheIndex.Value(i-1));
238 }
239 }
240 else {
241 nbp++;
242 TheIndex.SetValue(nbp,TheIndex.Value(i-1));
243 }
244 nbp++;
245 TheIndex.SetValue(nbp,TheIndex.Value(i));
246 if(TheIndex.Value(i) > MaxIndexUsed) MaxIndexUsed = TheIndex.Value(i);
247
248 Rprec = Ri;
249 }
250 else {
251 if((Ri & Rprec)==0) {
252 nbp++;
253 TheIndex.SetValue(nbp,TheIndex.Value(i));
254 if(TheIndex.Value(i) > MaxIndexUsed) MaxIndexUsed = TheIndex.Value(i);
255
256 Rprec = Ri;
257 }
258 }
259 Rprec = Ri;
260 }
261 if(nbp==1) {
262 NbPntIn=2;
9530af27 263 myBox.SetVoid();
7fd59977 264 }
265 else {
9530af27 266 myBox.SetVoid();
7fd59977 267 if(nbp) {
9530af27 268 myBox.Add(ThePnts.Value(TheIndex.Value(1)));
7fd59977 269 }
270 Standard_Real RatioDeflection;
271 Standard_Integer nbpassagedeflection = 0;
272// Standard_Integer PointHasBeenAdded = 0;
273 do {
274 nbpassagedeflection++;
275// Modified by Sergey KHROMOV - Mon Mar 24 12:05:28 2003 Begin
276// Standard_Real NewDeflection = 0.0000001;
277 Standard_Real NewDeflection = TheDeflection;
278// Modified by Sergey KHROMOV - Mon Mar 24 12:05:29 2003 End
279 for(i=2; i<=nbp; i++) {
280 Standard_Integer Ii = TheIndex.Value(i);
281 Standard_Integer Iim1= TheIndex.Value(i-1);
282 const gp_Pnt2d& Pi = ThePnts.Value(Ii);
283 const gp_Pnt2d& Pim1 = ThePnts.Value(Iim1);
9530af27 284 myBox.Add(Pi);
7fd59977 285 Standard_Integer Regi = CalculRegion(Pi.X(),Pi.Y(),bx0,bx1,by0,by1);
286 Standard_Integer Regim1 = CalculRegion(Pim1.X(),Pim1.Y(),bx0,bx1,by0,by1);
287 if((Regi & Regim1) == 0) {
288 Standard_Real u = 0.5*( TheParams.Value(Ii)
289 +TheParams.Value(Iim1));
290 gp_Pnt2d Pm = TheCurveTool::Value(C,u);
291 Standard_Real dx,dy,t=0;
292 dx=Pim1.X()-Pi.X(); if(dx<0) dx=-dx;
293 dy=Pim1.Y()-Pi.Y(); if(dy<0) dy=-dy;
294 if(dx+dy>1e-12) {
295 gp_Lin2d L(Pim1,gp_Dir2d(gp_Vec2d(Pim1,Pi)));
296 t = L.Distance(Pm);
297 if((MaxIndexUsed<(TheMaxNbPoints-1)) && (t>(TheDeflection * 0.5))) {
298 const gp_Pnt2d& P1=Pim1;
299 nbp++;
300 for(Standard_Integer j=nbp; j>=i+1; j--) {
301 TheIndex.SetValue(j,TheIndex.Value(j-1));
302 }
303 MaxIndexUsed++;
304 TheIndex.SetValue(i,MaxIndexUsed);
305 ThePnts.SetValue(MaxIndexUsed,Pm);
306 TheParams.SetValue(MaxIndexUsed,u);
307
308 Standard_Real u1m = 0.5*(u+TheParams.Value(TheIndex.Value(i-1)));
309 Standard_Real um2 = 0.5*(u+TheParams.Value(TheIndex.Value(i+1)));
310 gp_Pnt2d P1m = TheCurveTool::Value(C,u1m);
311#ifdef DEB
312 gp_Pnt2d Pm2 = TheCurveTool::Value(C,um2);
313#else
314 TheCurveTool::Value(C,um2);
315#endif
316 gp_Lin2d L1m(P1,gp_Dir2d(gp_Vec2d(P1,Pm)));
317#ifdef DEB
318 gp_Lin2d Lm2(Pm,gp_Dir2d(gp_Vec2d(Pm,ThePnts.Value(TheIndex.Value(i+1)))));
319#else
320 ThePnts.Value(TheIndex.Value(i+1));
321#endif
322 t = L1m.Distance(P1m);
323 i--;
324 }
325 }
326 else {
327 if(t>NewDeflection) {
328 NewDeflection = t;
329 }
330 }
331 }
332 }
333 if(NewDeflection)
334 RatioDeflection = TheDeflection / NewDeflection;
335 else RatioDeflection = 10.0;
336 TheDeflection = NewDeflection;
337 NbPntIn = nbp;
338 }
339 while((RatioDeflection<3.0)
340 && (nbpassagedeflection < 3)
341 && (MaxIndexUsed<(TheMaxNbPoints-2)));
342 }
343
344 TheDeflection*=MAJORATION_DEFLECTION;
9530af27 345 myBox.Enlarge(TheDeflection);
7fd59977 346 }
347 ClosedPolygon = Standard_False;
348 Dump();
349}
350
351
352Standard_Boolean IntCurve_Polygon2dGen::AutoIntersectionIsPossible() const {
353
354 gp_Vec2d VRef(ThePnts.Value(TheIndex.Value(1)),
355 ThePnts.Value(TheIndex.Value(2)));
356 for(Standard_Integer i=3; i<=NbPntIn; i++) {
357 gp_Vec2d V(ThePnts.Value(TheIndex.Value(i-1)),
358 ThePnts.Value(TheIndex.Value(i)));
359 if(V.Dot(VRef)<0.0) {
360 return(Standard_True);
361 }
362 }
363 return(Standard_False);
364}
365
366//======================================================================
367Standard_Real IntCurve_Polygon2dGen::ApproxParamOnCurve( const Standard_Integer Aindex
368 ,const Standard_Real TheParamOnLine)
369 const
370{
371 Standard_Integer Indexp1,Index = Aindex;
372 Standard_Real ParamOnLine = TheParamOnLine;
373 if (Index > NbPntIn) {
374 cout << "OutOfRange Polygon2d::ApproxParamOnCurve " <<endl;
375 }
376 if((Index == NbPntIn) && (ParamOnLine == 0.0)) {
377 Index--; ParamOnLine=1.0;
378 }
379 if(Index==0) {
380 Index=1;
381 ParamOnLine = 0.0;
382 }
383 Indexp1 = TheIndex.Value(Index+1);
384 Index = TheIndex.Value(Index);
385
386 Standard_Real du = TheParams.Value(Indexp1)-TheParams.Value(Index);
387 Standard_Real u = TheParams.Value(Index) + ParamOnLine * du;
388 return(u);
389}
390
391
392//======================================================================
393#if TEST
394
395extern Standard_Boolean DebugPolygon2d;
396extern void DrawSegmentBlanc(const gp_Pnt2d& _P1,const gp_Pnt2d& _P2);
397extern void DrawSegment(const gp_Pnt2d& _P1,const gp_Pnt2d& _P2);
398
399void IntCurve_Polygon2dGen::Dump(void) const {
400 if(!DebugPolygon2d) return;
401 Standard_Real bx0,bx1,by0,by1;
9530af27 402 if(myBox.IsVoid()) return;
403 myBox.Get(bx0,by0,bx1,by1);
7fd59977 404 DrawSegment(gp_Pnt2d(bx0,by0),gp_Pnt2d(bx1,by0));
405 DrawSegment(gp_Pnt2d(bx1,by0),gp_Pnt2d(bx1,by1));
406 DrawSegment(gp_Pnt2d(bx1,by1),gp_Pnt2d(bx0,by1));
407 DrawSegment(gp_Pnt2d(bx0,by1),gp_Pnt2d(bx0,by0));
408 Standard_Integer i;
409 if(NbPntIn<=1) return;
410 for(i=2;i<=NbPntIn; i++) {
411 DrawSegmentBlanc(ThePnts.Value(TheIndex.Value(i-1)),ThePnts.Value(TheIndex.Value(i)));
412 }
413}
414#else
415void IntCurve_Polygon2dGen::Dump(void) const {
416 static int debug = 0;
417 if(debug) {
418 Standard_Real bx0,bx1,by0,by1;
419
420 cout<<"\n ----- Dump de IntCurve_Polygon2dGen -----"<<endl;
9530af27 421 if(myBox.IsVoid()) {
7fd59977 422 cout<<" Polygone Vide "<<endl;
423 return;
424 }
9530af27 425 myBox.Get(bx0,by0,bx1,by1);
7fd59977 426 cout<<" bx0:"<<bx0 <<endl;
427 cout<<" by0:"<<by0<<endl;
428 cout<<" bx1:"<<bx1<<endl;
429 cout<<" by1:"<<by1<<endl;
430
431 Standard_Integer i;
432 for(i=1;i<=NbPntIn; i++) {
433 const gp_Pnt2d& P = ThePnts(TheIndex(i));
434 cout<<" ("<<i<<") u:"<<TheParams.Value(TheIndex(i))<<" X:"<<P.X()<<" Y:"<<P.Y()<<endl;
435 }
436 }
437}
438#endif
439//======================================================================
9530af27 440void IntCurve_Polygon2dGen::Segment(const Standard_Integer theIndex,
441 gp_Pnt2d &theBegin, gp_Pnt2d &theEnd) const
442{
443 Standard_Integer ind = theIndex;
444 theBegin = ThePnts(TheIndex(theIndex));
445 if (theIndex >= NbPntIn) {
446 if (!ClosedPolygon)
447 Standard_OutOfRange::Raise("IntCurve_Polygon2dGen::Segment!");
448 ind = 0;
449 }
450 theEnd = ThePnts(TheIndex(ind+1));
451}
7fd59977 452//======================================================================