Integration of OCCT 6.5.0 from SVN
[occt.git] / src / Graphic2d / Graphic2d_SetOfPolylines.cxx
CommitLineData
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
39Graphic2d_SetOfPolylines::Graphic2d_SetOfPolylines (
40 const Handle(Graphic2d_GraphicObject)& aGraphicObject)
41
42 : Graphic2d_Line (aGraphicObject) {
43
44}
45
46void 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
72void 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
213Standard_Integer Graphic2d_SetOfPolylines::Length () const {
214 return myPolylines.Length();
215}
216
217Standard_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
224void 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
240void Graphic2d_SetOfPolylines::Draw (const Handle(Graphic2d_Drawer)& aDrawer) {
241Standard_Integer np = myPolylines.Length();
242Standard_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
299Standard_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{
304Standard_Integer np = myPolylines.Length();
305Standard_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
346void Graphic2d_SetOfPolylines::Save(Aspect_FStream& aFStream) const
347{
348}