0023510: Integration of test grid "vis" into the new testing system
[occt.git] / src / Graphic2d / Graphic2d_SetOfPolylines.cxx
CommitLineData
b311480e 1// Copyright (c) 1998-1999 Matra Datavision
2// Copyright (c) 1999-2012 OPEN CASCADE SAS
3//
4// The content of this file is subject to the Open CASCADE Technology Public
5// License Version 6.5 (the "License"). You may not use the content of this file
6// except in compliance with the License. Please obtain a copy of the License
7// at http://www.opencascade.org and read it completely before using this file.
8//
9// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
10// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
11//
12// The Original Code and all software distributed under the License is
13// distributed on an "AS IS" basis, without warranty of any kind, and the
14// Initial Developer hereby disclaims all such warranties, including without
15// limitation, any warranties of merchantability, fitness for a particular
16// purpose or non-infringement. Please see the License for the specific terms
17// and conditions governing the rights and limitations under the License.
18
7fd59977 19/*=====================================================================
20
21 FONCTION :
22 ----------
23 Classe Graphic2d_SetOfPolylines
24
25 TEST :
26 ------
27
28 Voir TestG2D/TestG21
29
7fd59977 30
7fd59977 31
32=====================================================================*/
33
34// PRO13369 //GG_280498
81bba717 35// MapPolylineFromTo() should be called with exact number of points
7fd59977 36
37#define G002 //GG_140400 Use SetPickedIndex method
38
39#include <Graphic2d_SetOfPolylines.ixx>
40#include <Graphic2d_Vertex.hxx>
41#include <Graphic2d_HSequenceOfVertex.hxx>
42
43Graphic2d_SetOfPolylines::Graphic2d_SetOfPolylines (
44 const Handle(Graphic2d_GraphicObject)& aGraphicObject)
45
46 : Graphic2d_Line (aGraphicObject) {
47
48}
49
50void Graphic2d_SetOfPolylines::Add( const Standard_Real X,
51 const Standard_Real Y,
52 const Standard_Boolean NewPolyline ) {
53 Standard_Integer n = myPolylines.Length();
54 Standard_ShortReal x = Standard_ShortReal( X ),
55 y = Standard_ShortReal( Y );
56 Graphic2d_Vertex V( x, y );
57
58 if( NewPolyline || (n == 0) ) {
59 Handle(Graphic2d_HSequenceOfVertex) P =
60 new Graphic2d_HSequenceOfVertex();
61 P->Append(V);
62 myPolylines.Append(P);
63 } else {
64 Handle(Graphic2d_HSequenceOfVertex) P = myPolylines.Last();
65 if( !V.IsEqual(P->Value(P->Length())) ) {
66 P->Append(V);
67 }
68 }
69
70 myMinX = Min(myMinX,x);
71 myMinY = Min(myMinY,y);
72 myMaxX = Max(myMaxX,x);
73 myMaxY = Max(myMaxY,y);
74}
75
76void Graphic2d_SetOfPolylines::Add( const Standard_Real X1,
77 const Standard_Real Y1,
78 const Standard_Real X2,
79 const Standard_Real Y2 ) {
80
81 Standard_ShortReal x1 = Standard_ShortReal( X1 ),
82 y1 = Standard_ShortReal( Y1 ),
83 x2 = Standard_ShortReal( X2 ),
84 y2 = Standard_ShortReal( Y2 );
85 Graphic2d_Vertex V1( x1, y1 ),
86 V2( x2, y2 );
87 Standard_Integer np = myPolylines.Length();
88
89 if( !V1.IsEqual(V2) ) {
90 if( np == 0 ) {
91 Handle(Graphic2d_HSequenceOfVertex) P =
92 new Graphic2d_HSequenceOfVertex();
93 if( (x1 > x2) || (y1 > y2) ) {
94 V1.SetCoord(x2,y2); // seg orientation
95 V2.SetCoord(x1,y1);
96 }
97 P->Append(V1); P->Append(V2);
98 myPolylines.Append(P);
99 } else { // Try to build a polyline
100 // Warning,take an aspirine before continue reading...
101 Handle(Graphic2d_HSequenceOfVertex) P,PP;
102 Standard_Integer ip,ipp,lv;
103 for( ip=np ; ip>0 ; ip-- ) {
104 P = myPolylines.Value(ip);//ref line to check
105 lv = P->Length(); //number of vertex in the ref line
106 if( V1.IsEqual(P->Value(lv)) ) {
107 //first vertex of segment is the same that the last vertex of the
108 //ref line
81bba717 109 if( ip > 1 ) { //Try to concatenate ref line with others
7fd59977 110 for( ipp=1 ; ipp<ip ; ipp++ ) {
111 PP = myPolylines.Value(ipp); //other polyline
112 if( V2.IsEqual(PP->Value(1)) ) {
113 PP->Prepend(P); // Move the ref line before this
114 myPolylines.Remove(ip); // and destroy the ref line
115 ip = -1; break;
116 } else if( V2.IsEqual(PP->Value(PP->Length())) ) {
117 P->Reverse();
118 PP->Append(P); // Reverse & Move the ref line after this
119 myPolylines.Remove(ip); // and destroy the ref line
120 ip = -1; break;
121 }
122 }
123 }
124 if( ip > 0 ) {
125 P->Append(V2); // Append new vertex to ref line
126 ip = -1;
127 }
128 } else if( V2.IsEqual(P->Value(lv)) ) {
129 //second vertex of segment is the same that the last vertex of the
130 //ref line
81bba717 131 if( ip > 1 ) { //Try to concatenate ref line with others
7fd59977 132 for( ipp=1 ; ipp<ip ; ipp++ ) {
133 PP = myPolylines.Value(ipp); //other polyline
134 if( V1.IsEqual(PP->Value(1)) ) {
135 PP->Prepend(P); // Move the ref line before this
136 myPolylines.Remove(ip); // and destroy the ref line
137 ip = -1; break;
138 } else if( V1.IsEqual(PP->Value(PP->Length())) ) {
139 P->Reverse();
140 PP->Append(P); // Reverse & Move the ref line after this
141 myPolylines.Remove(ip); // and destroy the ref line
142 ip = -1; break;
143 }
144 }
145 }
146 if( ip > 0 ) {
147 P->Append(V1); // Append new vertex to ref line
148 ip = -1;
149 }
150 } else if( V1.IsEqual(P->Value(1)) ) {
151 //first vertex of segment is the same that the first vertex of the
152 //ref line
81bba717 153 if( ip > 1 ) { //Try to concatenate ref line with others
7fd59977 154 for( ipp=1 ; ipp<ip ; ipp++ ) {
155 PP = myPolylines.Value(ipp); //other polyline
156 if( V2.IsEqual(PP->Value(PP->Length())) ) {
157 P->Prepend(PP); // Move this line before the ref line
158 myPolylines.Remove(ipp); // and destroy this line
159 ip = -1; break;
160 } else if( V2.IsEqual(PP->Value(1)) ) {
161 PP->Reverse();
162 P->Prepend(PP); // Reverse & Move this line before the ref line
163 myPolylines.Remove(ipp); // and destroy this line
164 ip = -1; break;
165 }
166 }
167 }
168 if( ip > 0 ) {
169 P->Prepend(V2); // Prepend new vertex to ref line
170 ip = -1;
171 }
172 } else if( V2.IsEqual(P->Value(1)) ) {
173 //second vertex of segment is the same that the first vertex of the
174 //ref line
81bba717 175 if( ip > 1 ) { //Try to concatenate ref line with others
7fd59977 176 for( ipp=1 ; ipp<ip ; ipp++ ) {
177 PP = myPolylines.Value(ipp); //other polyline
178 if( V1.IsEqual(PP->Value(PP->Length())) ) {
179 P->Prepend(PP); // Move this line before the ref line
180 myPolylines.Remove(ipp); // and destroy this line
181 ip = -1; break;
182 } else if( V1.IsEqual(PP->Value(1)) ) {
183 PP->Reverse();
184 P->Prepend(PP); // Reverse & Move this line before the ref line
185 myPolylines.Remove(ipp); // and destroy this line
186 ip = -1; break;
187 }
188 }
189 }
190 if( ip > 0 ) {
191 P->Prepend(V1); // Append new vertex to ref line
192 ip = -1;
193 }
194 }
195 }
196 //create new line
197 if( ip >= 0 ) {
198 Handle(Graphic2d_HSequenceOfVertex) P =
199 new Graphic2d_HSequenceOfVertex();
200 if( (x1 > x2) || (y1 > y2) ) {
201 V1.SetCoord(x2,y2); // seg orientation
202 V2.SetCoord(x1,y1);
203 }
204 P->Append(V1);
205 P->Append(V2);
206 myPolylines.Append(P);
207 }
208 }
209
210 myMinX = Min(myMinX,Min(x1,x2));
211 myMinY = Min(myMinY,Min(y1,y2));
212 myMaxX = Max(myMaxX,Max(x1,x2));
213 myMaxY = Max(myMaxY,Max(y1,y2));
214 }
215}
216
217Standard_Integer Graphic2d_SetOfPolylines::Length () const {
218 return myPolylines.Length();
219}
220
221Standard_Integer Graphic2d_SetOfPolylines::Length (const Standard_Integer aPrank) const {
222 if( aPrank < 1 || aPrank > Length() )
223 Standard_OutOfRange::Raise
224 ("the polyline rank is out of bounds in the set");
225 return myPolylines.Value(aPrank)->Length();
226}
227
228void Graphic2d_SetOfPolylines::Values( const Standard_Integer aPrank,
229 const Standard_Integer aVrank,
230 Standard_Real &X,
231 Standard_Real &Y ) const {
232
233 if( aPrank < 1 || aPrank > Length() )
234 Standard_OutOfRange::Raise
235 ("the polyline rank is out of bounds in the set");
236 if( aVrank < 1 || aVrank > Length(aPrank) )
237 Standard_OutOfRange::Raise
238 ("the point rank is out of bounds in the polyline");
239
240 Graphic2d_Vertex V = myPolylines.Value(aPrank)->Value(aVrank);
241 X = V.X(); Y = V.Y();
242}
243
244void Graphic2d_SetOfPolylines::Draw (const Handle(Graphic2d_Drawer)& aDrawer) {
245Standard_Integer np = myPolylines.Length();
246Standard_Boolean IsIn = Standard_False,transform = Standard_False;
247
248 if( np <= 0 ) return;
249
250 if (! myGOPtr->IsTransformed ())
251 IsIn = aDrawer->IsIn (myMinX,myMaxX,myMinY,myMaxY);
252 else {
253 transform = Standard_True;
254 Standard_ShortReal minx, miny, maxx, maxy;
255 MinMax(minx,maxx,miny,maxy);
256 IsIn = aDrawer->IsIn (minx,maxx,miny,maxy);
257 }
258
259 if ( IsIn ) {
260 static gp_GTrsf2d theTrsf;
261 Handle(Graphic2d_HSequenceOfVertex) P;
262 Standard_Real A, B;
263 Standard_ShortReal x1,y1,x2,y2;
264 Standard_Integer ip,lp,iv;
265 DrawLineAttrib(aDrawer);
266 if( transform ) theTrsf = myGOPtr->Transform ();
267 for( ip=1 ; ip<=np ; ip++ ) {
268 P = myPolylines.Value(ip);
269 lp = P->Length();
270 if( lp > 2 ) {
271 P->Value(1).Coord(A,B);
272 if( transform ) theTrsf.Transforms(A,B);
273 x1 = Standard_ShortReal( A );
274 y1 = Standard_ShortReal( B );
275 aDrawer->MapPolylineFromTo(x1,y1,lp);
276 for( iv=2 ; iv<lp ; iv++ ) {
277 P->Value(iv).Coord(A,B);
278 if( transform ) theTrsf.Transforms(A,B);
279 x1 = Standard_ShortReal( A );
280 y1 = Standard_ShortReal( B );
281 aDrawer->MapPolylineFromTo(x1,y1,0);
282 }
283 P->Value(lp).Coord(A,B);
284 if( transform ) theTrsf.Transforms(A,B);
285 x1 = Standard_ShortReal( A );
286 y1 = Standard_ShortReal( B );
287 aDrawer->MapPolylineFromTo(x1,y1,-1);
288 } else if( lp > 1 ) {
289 P->Value(1).Coord(A,B);
290 if( transform ) theTrsf.Transforms(A,B);
291 x1 = Standard_ShortReal( A );
292 y1 = Standard_ShortReal( B );
293 P->Value(2).Coord(A,B);
294 if( transform ) theTrsf.Transforms(A,B);
295 x2 = Standard_ShortReal( A );
296 y2 = Standard_ShortReal( B );
297 aDrawer->MapSegmentFromTo(x1,y1,x2,y2);
298 }
299 }
300 }
301}
302
303Standard_Boolean Graphic2d_SetOfPolylines::Pick (const Standard_ShortReal X,
304 const Standard_ShortReal Y,
305 const Standard_ShortReal aPrecision,
306 const Handle(Graphic2d_Drawer)& aDrawer)
307{
308Standard_Integer np = myPolylines.Length();
309Standard_ShortReal SRX = X, SRY = Y;
310
311 if ( (np > 0) && IsInMinMax (X, Y, aPrecision)) {
312 if (myGOPtr->IsTransformed ()) {
313 gp_GTrsf2d theTrsf((myGOPtr->Transform ()).Inverted ());
314 Standard_Real RX = Standard_Real (SRX), RY = Standard_Real (SRY);
315 theTrsf.Transforms (RX, RY);
316 SRX = Standard_ShortReal (RX); SRY = Standard_ShortReal (RY);
317 }
318
319 Handle(Graphic2d_HSequenceOfVertex) P;
320 Standard_Integer ip,iv=0,lp;
321 Standard_ShortReal x1,y1,x2,y2;
322 Standard_Real A,B;
323 for( ip=1 ; ip<=np ; ip++ ) {
324 P = myPolylines.Value(ip);
325 lp = P->Length();
326 if( lp > 1 ) {
327 for( iv=1 ; iv<lp ; iv++ ) {
328 P->Value(iv).Coord(A,B);
329 x1 = Standard_ShortReal( A );
330 y1 = Standard_ShortReal( B );
331 P->Value(iv+1).Coord(A,B);
332 x2 = Standard_ShortReal( A );
333 y2 = Standard_ShortReal( B );
334 if (IsOn (SRX, SRY, x1, y1, x2, y2, aPrecision) ) {
335#ifdef G002
336 SetPickedIndex((ip << 16) | iv);
337#else
338 myPickedIndex = (ip << 16) | iv;
339#endif
340 return Standard_True;
341 }
342 }
343 }
344 }
345 return Standard_False;
346 }
347 return Standard_False;
348}
349
350void Graphic2d_SetOfPolylines::Save(Aspect_FStream& aFStream) const
351{
352}