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