7fd59977 |
1 | /*===================================================================== |
2 | |
3 | FONCTION : |
4 | ---------- |
5 | Classe Graphic2d_SetOfPolylines |
6 | |
7 | TEST : |
8 | ------ |
9 | |
10 | Voir TestG2D/TestG21 |
11 | |
12 | REMARQUES: |
13 | ---------- |
14 | |
15 | HISTORIQUE DES MODIFICATIONS : |
16 | -------------------------------- |
17 | |
18 | 27-01-98 : GG ; OPTIMISATION LOADER |
19 | Transformer les variables static globales en static |
20 | locales. |
21 | |
22 | 10-12-97 : GG ; Envoyer plutot des polylines que des segments lorsque |
23 | le type de trait n'est pas SOLID de maniere a assurer |
24 | la continuite. |
25 | |
26 | =====================================================================*/ |
27 | |
28 | // PRO13369 //GG_280498 |
29 | // Attention sous WNT |
30 | // MapPolylineFromTo() doit etre appele avec le |
31 | // nombre exacte de points |
32 | |
33 | #define G002 //GG_140400 Use SetPickedIndex method |
34 | |
35 | #include <Graphic2d_SetOfPolylines.ixx> |
36 | #include <Graphic2d_Vertex.hxx> |
37 | #include <Graphic2d_HSequenceOfVertex.hxx> |
38 | |
39 | Graphic2d_SetOfPolylines::Graphic2d_SetOfPolylines ( |
40 | const Handle(Graphic2d_GraphicObject)& aGraphicObject) |
41 | |
42 | : Graphic2d_Line (aGraphicObject) { |
43 | |
44 | } |
45 | |
46 | void Graphic2d_SetOfPolylines::Add( const Standard_Real X, |
47 | const Standard_Real Y, |
48 | const Standard_Boolean NewPolyline ) { |
49 | Standard_Integer n = myPolylines.Length(); |
50 | Standard_ShortReal x = Standard_ShortReal( X ), |
51 | y = Standard_ShortReal( Y ); |
52 | Graphic2d_Vertex V( x, y ); |
53 | |
54 | if( NewPolyline || (n == 0) ) { |
55 | Handle(Graphic2d_HSequenceOfVertex) P = |
56 | new Graphic2d_HSequenceOfVertex(); |
57 | P->Append(V); |
58 | myPolylines.Append(P); |
59 | } else { |
60 | Handle(Graphic2d_HSequenceOfVertex) P = myPolylines.Last(); |
61 | if( !V.IsEqual(P->Value(P->Length())) ) { |
62 | P->Append(V); |
63 | } |
64 | } |
65 | |
66 | myMinX = Min(myMinX,x); |
67 | myMinY = Min(myMinY,y); |
68 | myMaxX = Max(myMaxX,x); |
69 | myMaxY = Max(myMaxY,y); |
70 | } |
71 | |
72 | void Graphic2d_SetOfPolylines::Add( const Standard_Real X1, |
73 | const Standard_Real Y1, |
74 | const Standard_Real X2, |
75 | const Standard_Real Y2 ) { |
76 | |
77 | Standard_ShortReal x1 = Standard_ShortReal( X1 ), |
78 | y1 = Standard_ShortReal( Y1 ), |
79 | x2 = Standard_ShortReal( X2 ), |
80 | y2 = Standard_ShortReal( Y2 ); |
81 | Graphic2d_Vertex V1( x1, y1 ), |
82 | V2( x2, y2 ); |
83 | Standard_Integer np = myPolylines.Length(); |
84 | |
85 | if( !V1.IsEqual(V2) ) { |
86 | if( np == 0 ) { |
87 | Handle(Graphic2d_HSequenceOfVertex) P = |
88 | new Graphic2d_HSequenceOfVertex(); |
89 | if( (x1 > x2) || (y1 > y2) ) { |
90 | V1.SetCoord(x2,y2); // seg orientation |
91 | V2.SetCoord(x1,y1); |
92 | } |
93 | P->Append(V1); P->Append(V2); |
94 | myPolylines.Append(P); |
95 | } else { // Try to build a polyline |
96 | // Warning,take an aspirine before continue reading... |
97 | Handle(Graphic2d_HSequenceOfVertex) P,PP; |
98 | Standard_Integer ip,ipp,lv; |
99 | for( ip=np ; ip>0 ; ip-- ) { |
100 | P = myPolylines.Value(ip);//ref line to check |
101 | lv = P->Length(); //number of vertex in the ref line |
102 | if( V1.IsEqual(P->Value(lv)) ) { |
103 | //first vertex of segment is the same that the last vertex of the |
104 | //ref line |
105 | if( ip > 1 ) { //Try to concatenates ref line with others |
106 | for( ipp=1 ; ipp<ip ; ipp++ ) { |
107 | PP = myPolylines.Value(ipp); //other polyline |
108 | if( V2.IsEqual(PP->Value(1)) ) { |
109 | PP->Prepend(P); // Move the ref line before this |
110 | myPolylines.Remove(ip); // and destroy the ref line |
111 | ip = -1; break; |
112 | } else if( V2.IsEqual(PP->Value(PP->Length())) ) { |
113 | P->Reverse(); |
114 | PP->Append(P); // Reverse & Move the ref line after this |
115 | myPolylines.Remove(ip); // and destroy the ref line |
116 | ip = -1; break; |
117 | } |
118 | } |
119 | } |
120 | if( ip > 0 ) { |
121 | P->Append(V2); // Append new vertex to ref line |
122 | ip = -1; |
123 | } |
124 | } else if( V2.IsEqual(P->Value(lv)) ) { |
125 | //second vertex of segment is the same that the last vertex of the |
126 | //ref line |
127 | if( ip > 1 ) { //Try to concatenates ref line with others |
128 | for( ipp=1 ; ipp<ip ; ipp++ ) { |
129 | PP = myPolylines.Value(ipp); //other polyline |
130 | if( V1.IsEqual(PP->Value(1)) ) { |
131 | PP->Prepend(P); // Move the ref line before this |
132 | myPolylines.Remove(ip); // and destroy the ref line |
133 | ip = -1; break; |
134 | } else if( V1.IsEqual(PP->Value(PP->Length())) ) { |
135 | P->Reverse(); |
136 | PP->Append(P); // Reverse & Move the ref line after this |
137 | myPolylines.Remove(ip); // and destroy the ref line |
138 | ip = -1; break; |
139 | } |
140 | } |
141 | } |
142 | if( ip > 0 ) { |
143 | P->Append(V1); // Append new vertex to ref line |
144 | ip = -1; |
145 | } |
146 | } else if( V1.IsEqual(P->Value(1)) ) { |
147 | //first vertex of segment is the same that the first vertex of the |
148 | //ref line |
149 | if( ip > 1 ) { //Try to concatenates ref line with others |
150 | for( ipp=1 ; ipp<ip ; ipp++ ) { |
151 | PP = myPolylines.Value(ipp); //other polyline |
152 | if( V2.IsEqual(PP->Value(PP->Length())) ) { |
153 | P->Prepend(PP); // Move this line before the ref line |
154 | myPolylines.Remove(ipp); // and destroy this line |
155 | ip = -1; break; |
156 | } else if( V2.IsEqual(PP->Value(1)) ) { |
157 | PP->Reverse(); |
158 | P->Prepend(PP); // Reverse & Move this line before the ref line |
159 | myPolylines.Remove(ipp); // and destroy this line |
160 | ip = -1; break; |
161 | } |
162 | } |
163 | } |
164 | if( ip > 0 ) { |
165 | P->Prepend(V2); // Prepend new vertex to ref line |
166 | ip = -1; |
167 | } |
168 | } else if( V2.IsEqual(P->Value(1)) ) { |
169 | //second vertex of segment is the same that the first vertex of the |
170 | //ref line |
171 | if( ip > 1 ) { //Try to concatenates ref line with others |
172 | for( ipp=1 ; ipp<ip ; ipp++ ) { |
173 | PP = myPolylines.Value(ipp); //other polyline |
174 | if( V1.IsEqual(PP->Value(PP->Length())) ) { |
175 | P->Prepend(PP); // Move this line before the ref line |
176 | myPolylines.Remove(ipp); // and destroy this line |
177 | ip = -1; break; |
178 | } else if( V1.IsEqual(PP->Value(1)) ) { |
179 | PP->Reverse(); |
180 | P->Prepend(PP); // Reverse & Move this line before the ref line |
181 | myPolylines.Remove(ipp); // and destroy this line |
182 | ip = -1; break; |
183 | } |
184 | } |
185 | } |
186 | if( ip > 0 ) { |
187 | P->Prepend(V1); // Append new vertex to ref line |
188 | ip = -1; |
189 | } |
190 | } |
191 | } |
192 | //create new line |
193 | if( ip >= 0 ) { |
194 | Handle(Graphic2d_HSequenceOfVertex) P = |
195 | new Graphic2d_HSequenceOfVertex(); |
196 | if( (x1 > x2) || (y1 > y2) ) { |
197 | V1.SetCoord(x2,y2); // seg orientation |
198 | V2.SetCoord(x1,y1); |
199 | } |
200 | P->Append(V1); |
201 | P->Append(V2); |
202 | myPolylines.Append(P); |
203 | } |
204 | } |
205 | |
206 | myMinX = Min(myMinX,Min(x1,x2)); |
207 | myMinY = Min(myMinY,Min(y1,y2)); |
208 | myMaxX = Max(myMaxX,Max(x1,x2)); |
209 | myMaxY = Max(myMaxY,Max(y1,y2)); |
210 | } |
211 | } |
212 | |
213 | Standard_Integer Graphic2d_SetOfPolylines::Length () const { |
214 | return myPolylines.Length(); |
215 | } |
216 | |
217 | Standard_Integer Graphic2d_SetOfPolylines::Length (const Standard_Integer aPrank) const { |
218 | if( aPrank < 1 || aPrank > Length() ) |
219 | Standard_OutOfRange::Raise |
220 | ("the polyline rank is out of bounds in the set"); |
221 | return myPolylines.Value(aPrank)->Length(); |
222 | } |
223 | |
224 | void Graphic2d_SetOfPolylines::Values( const Standard_Integer aPrank, |
225 | const Standard_Integer aVrank, |
226 | Standard_Real &X, |
227 | Standard_Real &Y ) const { |
228 | |
229 | if( aPrank < 1 || aPrank > Length() ) |
230 | Standard_OutOfRange::Raise |
231 | ("the polyline rank is out of bounds in the set"); |
232 | if( aVrank < 1 || aVrank > Length(aPrank) ) |
233 | Standard_OutOfRange::Raise |
234 | ("the point rank is out of bounds in the polyline"); |
235 | |
236 | Graphic2d_Vertex V = myPolylines.Value(aPrank)->Value(aVrank); |
237 | X = V.X(); Y = V.Y(); |
238 | } |
239 | |
240 | void Graphic2d_SetOfPolylines::Draw (const Handle(Graphic2d_Drawer)& aDrawer) { |
241 | Standard_Integer np = myPolylines.Length(); |
242 | Standard_Boolean IsIn = Standard_False,transform = Standard_False; |
243 | |
244 | if( np <= 0 ) return; |
245 | |
246 | if (! myGOPtr->IsTransformed ()) |
247 | IsIn = aDrawer->IsIn (myMinX,myMaxX,myMinY,myMaxY); |
248 | else { |
249 | transform = Standard_True; |
250 | Standard_ShortReal minx, miny, maxx, maxy; |
251 | MinMax(minx,maxx,miny,maxy); |
252 | IsIn = aDrawer->IsIn (minx,maxx,miny,maxy); |
253 | } |
254 | |
255 | if ( IsIn ) { |
256 | static gp_GTrsf2d theTrsf; |
257 | Handle(Graphic2d_HSequenceOfVertex) P; |
258 | Standard_Real A, B; |
259 | Standard_ShortReal x1,y1,x2,y2; |
260 | Standard_Integer ip,lp,iv; |
261 | DrawLineAttrib(aDrawer); |
262 | if( transform ) theTrsf = myGOPtr->Transform (); |
263 | for( ip=1 ; ip<=np ; ip++ ) { |
264 | P = myPolylines.Value(ip); |
265 | lp = P->Length(); |
266 | if( lp > 2 ) { |
267 | P->Value(1).Coord(A,B); |
268 | if( transform ) theTrsf.Transforms(A,B); |
269 | x1 = Standard_ShortReal( A ); |
270 | y1 = Standard_ShortReal( B ); |
271 | aDrawer->MapPolylineFromTo(x1,y1,lp); |
272 | for( iv=2 ; iv<lp ; iv++ ) { |
273 | P->Value(iv).Coord(A,B); |
274 | if( transform ) theTrsf.Transforms(A,B); |
275 | x1 = Standard_ShortReal( A ); |
276 | y1 = Standard_ShortReal( B ); |
277 | aDrawer->MapPolylineFromTo(x1,y1,0); |
278 | } |
279 | P->Value(lp).Coord(A,B); |
280 | if( transform ) theTrsf.Transforms(A,B); |
281 | x1 = Standard_ShortReal( A ); |
282 | y1 = Standard_ShortReal( B ); |
283 | aDrawer->MapPolylineFromTo(x1,y1,-1); |
284 | } else if( lp > 1 ) { |
285 | P->Value(1).Coord(A,B); |
286 | if( transform ) theTrsf.Transforms(A,B); |
287 | x1 = Standard_ShortReal( A ); |
288 | y1 = Standard_ShortReal( B ); |
289 | P->Value(2).Coord(A,B); |
290 | if( transform ) theTrsf.Transforms(A,B); |
291 | x2 = Standard_ShortReal( A ); |
292 | y2 = Standard_ShortReal( B ); |
293 | aDrawer->MapSegmentFromTo(x1,y1,x2,y2); |
294 | } |
295 | } |
296 | } |
297 | } |
298 | |
299 | Standard_Boolean Graphic2d_SetOfPolylines::Pick (const Standard_ShortReal X, |
300 | const Standard_ShortReal Y, |
301 | const Standard_ShortReal aPrecision, |
302 | const Handle(Graphic2d_Drawer)& aDrawer) |
303 | { |
304 | Standard_Integer np = myPolylines.Length(); |
305 | Standard_ShortReal SRX = X, SRY = Y; |
306 | |
307 | if ( (np > 0) && IsInMinMax (X, Y, aPrecision)) { |
308 | if (myGOPtr->IsTransformed ()) { |
309 | gp_GTrsf2d theTrsf((myGOPtr->Transform ()).Inverted ()); |
310 | Standard_Real RX = Standard_Real (SRX), RY = Standard_Real (SRY); |
311 | theTrsf.Transforms (RX, RY); |
312 | SRX = Standard_ShortReal (RX); SRY = Standard_ShortReal (RY); |
313 | } |
314 | |
315 | Handle(Graphic2d_HSequenceOfVertex) P; |
316 | Standard_Integer ip,iv=0,lp; |
317 | Standard_ShortReal x1,y1,x2,y2; |
318 | Standard_Real A,B; |
319 | for( ip=1 ; ip<=np ; ip++ ) { |
320 | P = myPolylines.Value(ip); |
321 | lp = P->Length(); |
322 | if( lp > 1 ) { |
323 | for( iv=1 ; iv<lp ; iv++ ) { |
324 | P->Value(iv).Coord(A,B); |
325 | x1 = Standard_ShortReal( A ); |
326 | y1 = Standard_ShortReal( B ); |
327 | P->Value(iv+1).Coord(A,B); |
328 | x2 = Standard_ShortReal( A ); |
329 | y2 = Standard_ShortReal( B ); |
330 | if (IsOn (SRX, SRY, x1, y1, x2, y2, aPrecision) ) { |
331 | #ifdef G002 |
332 | SetPickedIndex((ip << 16) | iv); |
333 | #else |
334 | myPickedIndex = (ip << 16) | iv; |
335 | #endif |
336 | return Standard_True; |
337 | } |
338 | } |
339 | } |
340 | } |
341 | return Standard_False; |
342 | } |
343 | return Standard_False; |
344 | } |
345 | |
346 | void Graphic2d_SetOfPolylines::Save(Aspect_FStream& aFStream) const |
347 | { |
348 | } |