Commit | Line | Data |
---|---|---|
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 | |
37 | IntCurve_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 | 114 | void 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 | ||
241 | Standard_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 | //====================================================================== | |
256 | Standard_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) { | |
263 | cout << "OutOfRange Polygon2d::ApproxParamOnCurve " <<endl; | |
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 | ||
284 | extern Standard_Boolean DebugPolygon2d; | |
285 | extern void DrawSegmentBlanc(const gp_Pnt2d& _P1,const gp_Pnt2d& _P2); | |
286 | extern void DrawSegment(const gp_Pnt2d& _P1,const gp_Pnt2d& _P2); | |
287 | ||
288 | void 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 | |
304 | void IntCurve_Polygon2dGen::Dump(void) const { | |
305 | static int debug = 0; | |
306 | if(debug) { | |
307 | Standard_Real bx0,bx1,by0,by1; | |
308 | ||
1d19db8d | 309 | cout<<"\n ----- Dump of IntCurve_Polygon2dGen -----"<<endl; |
9530af27 | 310 | if(myBox.IsVoid()) { |
7fd59977 | 311 | cout<<" Polygone Vide "<<endl; |
312 | return; | |
313 | } | |
9530af27 | 314 | myBox.Get(bx0,by0,bx1,by1); |
7fd59977 | 315 | cout<<" bx0:"<<bx0 <<endl; |
316 | cout<<" by0:"<<by0<<endl; | |
317 | cout<<" bx1:"<<bx1<<endl; | |
318 | cout<<" by1:"<<by1<<endl; | |
319 | ||
320 | Standard_Integer i; | |
321 | for(i=1;i<=NbPntIn; i++) { | |
322 | const gp_Pnt2d& P = ThePnts(TheIndex(i)); | |
323 | cout<<" ("<<i<<") u:"<<TheParams.Value(TheIndex(i))<<" X:"<<P.X()<<" Y:"<<P.Y()<<endl; | |
324 | } | |
325 | } | |
326 | } | |
327 | #endif | |
328 | //====================================================================== | |
9530af27 | 329 | void 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 | //====================================================================== |