Salome HOME
Initial version
[modules/gui.git] / src / GLViewer / GLViewer_Object.cxx
1 // File:      GLViewer_Object.cxx
2 // Created:   November, 2004
3 // Author:    OCC team
4 // Copyright (C) CEA 2004
5
6 /***************************************************************************
7 **  Class:   GLViewer_Object
8 **  Descr:   OpenGL Object
9 **  Module:  GLViewer
10 **  Created: UI team, 02.09.02
11 ****************************************************************************/
12
13 #include "GLViewer_Object.h"
14 #include "GLViewer_Drawer.h"
15
16 #include "GLViewer_Group.h"
17
18 #include <qfontmetrics.h>
19 #include <qstringlist.h>
20
21 #include <cmath>
22 using namespace std;
23
24 #define CONSTANT_FOR_RECT 10
25
26 /***************************************************************************
27 **  Class:   GLViewer_Text
28 **  Descr:   Substitution of Prs3d_Text for OpenGL
29 **  Module:  GLViewer
30 **  Created: UI team, 10.07.03
31 ****************************************************************************/
32
33 GLViewer_Text::GLViewer_Text( const QString& text, float xPos, float yPos, const QColor& color )
34 {
35   myText = text;
36   myXPos = xPos;
37   myYPos = yPos;
38   myColor = color;
39   myQFont = QFont::defaultFont();
40   mySeparator = 2;
41   myDTF = DTF_BITMAP;
42 }
43
44 GLViewer_Text::GLViewer_Text( const QString& text, float xPos, float yPos, const QColor& color, QFont theFont, int theSeparator )
45 {
46   myText = text;
47   myXPos = xPos;
48   myYPos = yPos;
49   myColor = color;
50   myQFont = theFont;
51   mySeparator = theSeparator;
52   myDTF = DTF_BITMAP;
53 }
54
55 GLViewer_Text::~GLViewer_Text()
56 {
57 }
58
59 int GLViewer_Text::getWidth()
60 {
61     int aResult = 0;
62     QFontMetrics aFM( myQFont );
63     for( int i = 0; i < myText.length(); i++ )
64         aResult += aFM.width( myText[i] ) + mySeparator;
65     return aResult;
66 }
67
68 int GLViewer_Text::getHeight()
69 {
70     QFontMetrics aFM( myQFont );
71     return aFM.height();
72 }
73
74 QByteArray GLViewer_Text::getByteCopy() const
75 {
76     int i;
77     int aSize = 5*sizeof( int ) + myText.length();
78
79     int aR = myColor.red();
80     int aG = myColor.green();
81     int aB = myColor.blue();
82     const char* aStr = myText.data();
83
84     int anISize = sizeof( int );    
85     QByteArray aResult( aSize );
86
87     char* aPointer = (char*)&myXPos;
88     for( i = 0; i < anISize; i++, aPointer++ )
89         aResult[i] = *aPointer;
90     aPointer = (char*)&myYPos;
91     for( ; i < 2*anISize; i++, aPointer++ )
92         aResult[i] = *aPointer;
93
94     aPointer = (char*)&aR;
95     for( ; i < 3*anISize; i++, aPointer++ )
96         aResult[i] = *aPointer;
97     aPointer = (char*)&aG;
98     for( ; i < 4*anISize; i++, aPointer++ )
99         aResult[i] = *aPointer;
100     aPointer = (char*)&aB;
101     for( ; i < 5*anISize; i++, aPointer++ )
102         aResult[i] = *aPointer;
103
104     int aTextSize = myText.length();
105     aPointer = (char*)&aTextSize;
106     for( ; i < 6*anISize; i++, aPointer++ )
107         aResult[i] = *aPointer;
108
109     for( i = 0; i < aTextSize; i++ )
110         aResult[6*anISize + i] = aStr[i];
111
112     aPointer = (char*)&mySeparator;
113     for( ; i < 7*anISize + aTextSize; i++, aPointer++ )
114         aResult[i] = *aPointer;
115
116     const char* aFontStr = myQFont.toString().data();
117     int aFontSize = myQFont.toString().length();
118
119     for( i = 0; i < aFontSize; i++ )
120         aResult[7*anISize + aTextSize + i] = aFontStr[i];
121
122     return aResult;
123 }
124
125 GLViewer_Text* GLViewer_Text::fromByteCopy( QByteArray theBuf )
126 {
127     int i = 0;
128     int aSize = (int)theBuf.size();
129     int aR = 0, aG = 0, aB = 0;
130
131     int xPos = 0, yPos = 0;
132
133     int anISize = sizeof( int );
134     char* aPointer = (char*)&xPos;
135     for ( i = 0; i < anISize; i++, aPointer++ )
136         *aPointer = theBuf[i];
137
138     aPointer = (char*)&yPos;
139     for ( ; i < 2*anISize; i++, aPointer++ )
140         *aPointer = theBuf[i];
141
142     aPointer = (char*)&aR;
143     for( ; i < 3*anISize; i++, aPointer++ )
144         *aPointer = theBuf[i];
145     aPointer = (char*)&aG;
146     for( ; i < 4*anISize; i++, aPointer++ )
147         *aPointer = theBuf[i];
148     aPointer = (char*)&aB;
149     for( ; i < 5*anISize; i++, aPointer++ )
150         *aPointer = theBuf[i];
151
152     int aTextSize = 0;
153     aPointer = (char*)&aTextSize;
154     for( ; i < 6*anISize; i++, aPointer++ )
155         *aPointer = theBuf[i];
156
157     QString aText;
158     for( ; i < 6*anISize + aTextSize; i++ )
159     {
160         QChar aChar( theBuf[i] );
161         aText += aChar;
162     }
163
164     int aSeparator = 0;
165     aPointer = (char*)&aSeparator;
166     for( ; i < 7*anISize + aTextSize; i++, aPointer++ )
167         *aPointer = theBuf[i];
168
169     QString aFontStr;
170     for( ; i < aSize; i++ )
171     {
172         QChar aChar( theBuf[i] );
173         aFontStr += aChar;
174     }
175     QFont aFont;
176
177     if( !aFont.fromString( aFontStr ) )
178         return NULL;    
179
180     GLViewer_Text* aGlText = new GLViewer_Text( aText, xPos, yPos, QColor( aR,aG,aB ), aFont, aSeparator  );
181
182     return aGlText;    
183 }
184
185 /***************************************************************************
186 **  Class:   GLViewer_CoordSystem
187 **  Descr:   
188 **  Module:  GLViewer
189 **  Created: UI team, 03.09.02
190 ****************************************************************************/
191
192 GLViewer_CoordSystem::GLViewer_CoordSystem( CSType aType, double X0, double Y0, 
193                                             double XUnit, double YUnit, double Rotation )
194 {
195     setType( aType );
196     setOrigin( X0, Y0 );
197     setUnits( XUnit, YUnit );
198     setRotation( Rotation );
199 }
200
201 void GLViewer_CoordSystem::getOrigin( double& x, double& y ) const
202 {
203     x = myX0;
204     y = myY0;
205 }
206
207 void GLViewer_CoordSystem::setOrigin( double x, double y )
208 {
209     myX0 = x;
210     myY0 = y;
211 }
212
213 void GLViewer_CoordSystem::getUnits( double& x, double& y ) const
214 {
215     x = myXUnit;
216     y = myYUnit;
217 }
218
219 void GLViewer_CoordSystem::setUnits( double x, double y )
220 {
221     if( x>0 )
222         myXUnit = x;
223     else
224         myXUnit = 1.0;
225
226     if( y>0 )
227         myYUnit = y;
228     else
229         myYUnit = 1.0;
230 }
231
232 double GLViewer_CoordSystem::getRotation() const
233 {
234     return myRotation;
235 }
236
237 void GLViewer_CoordSystem::setRotation( double rotation )
238 {
239     myRotation = rotation;
240 }
241
242 GLViewer_CoordSystem::CSType GLViewer_CoordSystem::getType() const
243 {
244     return myType;
245 }
246
247 void GLViewer_CoordSystem::setType( CSType type )
248 {
249     myType = type;
250 }
251
252 void GLViewer_CoordSystem::toReference( double& x, double& y )
253 {
254     if( myType==Cartesian )
255     {
256         double newx = myX0 + myXUnit*x*cos(myRotation) - myYUnit*y*sin(myRotation),
257                newy = myY0 + myXUnit*x*sin(myRotation) + myYUnit*y*cos(myRotation);
258         x = newx;
259         y = newy;
260     }
261     else if( myType==Polar )
262     {
263         double r = x, phi = y;
264         x = myX0 + myXUnit*r*cos(phi+myRotation);
265         y = myY0 + myXUnit*r*sin(phi+myRotation);
266     }
267 }
268
269 void GLViewer_CoordSystem::fromReference( double& x, double& y )
270 {
271     x = (x - myX0) / myXUnit;
272     y = (y - myY0) / myYUnit;
273
274     if( myType==Cartesian )
275     {
276         double newx =  x*cos(myRotation) + y*sin(myRotation),
277                newy = -x*sin(myRotation) + y*cos(myRotation);
278         x = newx;
279         y = newy;
280     }
281     else if( myType==Polar )
282     {
283         double r = sqrt( x*x+y*y );
284         double phi = 0.0;
285         double eps = 1E-8, pi = 3.14159265;
286
287         if( r>eps )
288             if( fabs(x)>eps )
289             {
290                 double arg = y/x;
291                 phi = atan(arg);
292                 if( x<0 ) // 2-nd or 4-rd quarter
293                     phi+=pi;
294             }
295             else if( y>0 )
296                 phi = pi/2.0;
297             else
298                 phi = 3*pi/2.0;
299
300         x = r;
301         y = phi-myRotation;
302     }
303 }
304
305 void GLViewer_CoordSystem::transform( GLViewer_CoordSystem& aSystem, double& x, double& y )
306 {
307     toReference( x, y );
308     aSystem.fromReference( x, y );
309 }
310
311 void GLViewer_CoordSystem::getStretching( GLViewer_CoordSystem& aSystem, double& theX, double& theY )
312 {
313     theX = myXUnit / aSystem.myXUnit;
314     theY = myYUnit / aSystem.myYUnit;
315 }
316
317 /***************************************************************************
318 **  Class:   GLViewer_Object
319 **  Descr:   OpenGL Object
320 **  Module:  GLViewer
321 **  Created: UI team, 03.09.02
322 ****************************************************************************/
323 GLViewer_Object::GLViewer_Object()
324 {
325   myXScale = 1.0; 
326   myYScale = 1.0;
327   myXGap = 0;
328   myYGap = 0;
329   myZoom = 1.0;
330
331   myIsHigh = GL_FALSE;
332   myIsSel = GL_FALSE;
333   
334   myRect = new GLViewer_Rect(); 
335   myGLText = new GLViewer_Text( 0, 0, 0, QColor(0,0,0) );
336
337   myAspectLine = new GLViewer_AspectLine();
338   myType = "GLViewer_Object";
339
340   setOwner( NULL );
341   setDrawer( NULL );
342
343   myIsVisible = true;
344
345   isToolTipHTML = false;  
346
347   myGroup = NULL;
348 }
349
350 GLViewer_Object::~GLViewer_Object()
351 {
352   if( myRect )
353     delete myRect;
354
355   if( myGLText )
356     delete myGLText;
357
358   if( myAspectLine )
359     delete myAspectLine;
360 }
361
362 GLboolean GLViewer_Object::isInside( GLViewer_Rect theRect )
363 {
364     return theRect.toQRect()->contains( *(myRect->toQRect()) );
365 }
366
367 GLboolean GLViewer_Object::setZoom( GLfloat zoom, GLboolean )
368 {
369     if( myZoom == zoom )
370         return GL_FALSE;
371
372     myZoom = zoom;
373     return GL_TRUE;
374 }
375
376 GLboolean GLViewer_Object::updateZoom( bool zoomIn )
377 {
378     float newZoom;
379     float step = zoomIn ? 1 : -1;
380     double epsilon = 0.001;
381
382     if( myZoom - 1 > epsilon )
383         newZoom = ( myZoom * 2 + step ) / 2;
384     else if( 1 - myZoom > epsilon )
385         newZoom = 2 / ( 2 / myZoom - step );
386     else
387         newZoom = zoomIn ? 3./2. : 2./3.;
388
389     if( newZoom < 0.01 || newZoom > 100.0 )
390         return GL_FALSE;
391
392     setZoom( newZoom, GL_TRUE );
393     return GL_TRUE;
394 }
395
396 QByteArray GLViewer_Object::getByteCopy()
397 {
398     int i = 0;
399     int anISize = sizeof( int );
400     int aFSize = sizeof( GLfloat );
401
402     int aLeft = (int)myRect->left(),
403         aTop = (int)myRect->top(),
404         aRight = (int)myRect->right(),
405         aBottom = (int)myRect->bottom();
406
407     const char* aTypeStr = myType.data();
408     const char* aToolTipStr = myToolTipText.data();
409
410     int aTypeLength = myType.length();
411     int aToolTipLength = myToolTipText.length();
412
413
414     QByteArray aGLText = myGLText->getByteCopy();
415     QByteArray aAspect = myAspectLine->getByteCopy();
416     
417     QByteArray aResult( 2*anISize + 8*aFSize  + 
418                         aTypeLength + aToolTipLength +
419                         aGLText.size() + aAspect.size() );
420     
421     char* aPointer = (char*)&aLeft;
422     for( i = 0; i < aFSize; i++, aPointer++ )
423         aResult[i] = *aPointer;
424     aPointer = (char*)&aTop;
425     for( ; i < 2*aFSize; i++, aPointer++ )
426         aResult[i] = *aPointer;
427     aPointer = (char*)&aRight;
428     for( ; i < 3*aFSize; i++, aPointer++ )
429         aResult[i] = *aPointer;
430     aPointer = (char*)&aBottom;
431     for( ; i < 4*aFSize; i++, aPointer++ )
432         aResult[i] = *aPointer;
433
434     aPointer = (char*)&myXScale;
435     for( ; i < 5*aFSize; i++, aPointer++ )
436         aResult[i] = *aPointer;
437     aPointer = (char*)&myYScale;
438     for( ; i < 6*aFSize; i++, aPointer++ )
439         aResult[i] = *aPointer;
440     aPointer = (char*)&myXGap;
441     for( ; i < 7*aFSize; i++, aPointer++ )
442         aResult[i] = *aPointer;
443     aPointer = (char*)&myYGap;
444     for( ; i < 8*aFSize; i++, aPointer++ )
445         aResult[i] = *aPointer;
446
447     aPointer = (char*)&aTypeLength;
448     for( ; i < anISize + 8*aFSize; i++, aPointer++ )
449         aResult[i] = *aPointer;
450     for( ; i < anISize + 8*aFSize + aTypeLength; i++ )
451         aResult[i] = aTypeStr[i - anISize - 8*aFSize ];
452
453     aPointer = (char*)&aToolTipLength;
454     for( ; i < 2*anISize + 8*aFSize + aTypeLength; i++, aPointer++ )
455         aResult[i] = *aPointer;
456     for( ; i <  2*anISize + 8*aFSize + aTypeLength + aToolTipLength; i++ )
457         aResult[ i] = aToolTipStr[i - 2*anISize - 8*aFSize - aTypeLength];
458
459     int aCurPos = 2*anISize + 8*aFSize + aTypeLength + aToolTipLength;
460
461     for( i = aCurPos; i < aCurPos + aAspect.size(); i++ )
462         aResult[i] = aAspect[i - aCurPos];
463
464     aCurPos = aCurPos + aAspect.size();
465
466     for( i = aCurPos; i < aCurPos + aGLText.size(); i++ )
467         aResult[i] = aGLText[i - aCurPos];    
468
469     aCurPos += aGLText.size();
470
471     aPointer = (char*)&myOwner;
472     for( i = 0; i < sizeof( GLViewer_Owner* ); i++, aPointer++ )
473         aResult[ aCurPos+i ] = *aPointer;
474
475     return aResult;
476 }
477
478 bool GLViewer_Object::initializeFromByteCopy( QByteArray theArray )
479 {
480     int i = 0;
481     int anISize = sizeof( int );
482     int aFSize = sizeof( GLfloat );
483     
484     int aLeft = 0, aTop = 0, aRight = 0, aBottom = 0;    
485
486     //QString aTypeStr, aToolTipStr;
487     int aTypeLength = 0, aToolTipLength = 0;
488
489     int aSize = theArray.size();
490
491     GLViewer_Text* aGLText = new GLViewer_Text( 0, 0, 0, QColor(255,255,255));
492     int aGLTextMinSize = (aGLText->getByteCopy()).size();
493     GLViewer_AspectLine* aAspectLine = new GLViewer_AspectLine();
494     int aGLAspLineSize = (aAspectLine->getByteCopy()).size();
495
496     QByteArray aGLTextArray, aAspect( aGLAspLineSize );
497
498     if( aSize < 2*anISize + 8*aFSize + aGLTextMinSize + aGLAspLineSize )
499         return false;
500
501     char* aPointer = (char*)&aLeft;
502     for( i = 0; i < aFSize; i++, aPointer++ )
503         *aPointer = theArray[i];
504     aPointer = (char*)&aTop;
505     for( ; i < 2*aFSize; i++, aPointer++ )
506         *aPointer = theArray[i];
507     aPointer = (char*)&aRight;
508     for( ; i < 3*aFSize; i++, aPointer++ )
509         *aPointer = theArray[i];
510     aPointer = (char*)&aBottom;
511     for( ; i < 4*aFSize; i++, aPointer++ )
512         *aPointer = theArray[i];
513
514     //myRect = new QRect( aLeft, aTop, aRight - aLeft, aBottom - aTop );
515     myRect = new GLViewer_Rect( aLeft, aRight, aTop, aBottom );
516
517     aPointer = (char*)&myXScale;
518     for( ; i < 5*aFSize; i++, aPointer++ )
519         *aPointer = theArray[i];
520     aPointer = (char*)&myYScale;
521     for( ; i < 6*aFSize; i++, aPointer++ )
522         *aPointer = theArray[i];
523     aPointer = (char*)&myXGap;
524     for( ; i < 7*aFSize; i++, aPointer++ )
525         *aPointer = theArray[i];
526     aPointer = (char*)&myYGap;
527     for( ; i < 8*aFSize; i++, aPointer++ )
528         *aPointer = theArray[i];
529
530     myIsHigh = false;
531     myIsSel = false;
532     myIsVisible = true;
533
534     aPointer = (char*)&aTypeLength;
535     for( ; i < anISize + 8*aFSize; i++, aPointer++ )
536         *aPointer = theArray[i];
537     myType = "";
538     for( ; i < anISize + 8*aFSize + aTypeLength; i++ )
539     {
540         QChar aChar( theArray[i] );
541         myType += aChar;
542     }
543
544     aPointer = (char*)&aToolTipLength;
545     for( ; i < 2*anISize + 8*aFSize + aTypeLength; i++, aPointer++ )
546         *aPointer = theArray[i];
547     myToolTipText= "";
548     for( ; i < 2*anISize + 8*aFSize + aTypeLength + aToolTipLength; i++ )
549     {
550         QChar aChar( theArray[i] );
551         myToolTipText += aChar;
552     }
553     
554     int aCurPos = 2*anISize + 8*aFSize + aTypeLength + aToolTipLength;
555     if( aSize - aCurPos < aGLTextMinSize + aGLAspLineSize )
556         return false;
557
558     for( i = 0; i < aGLAspLineSize; i++ )
559         aAspect[i] = theArray[ aCurPos + i ];
560     myAspectLine = GLViewer_AspectLine::fromByteCopy( aAspect );
561
562     aCurPos = aCurPos + aGLAspLineSize;
563     aGLTextArray.resize( aSize - aCurPos );
564     for( i = 0; i + aCurPos < aSize; i++ )
565         aGLTextArray[i] = theArray[ aCurPos + i ];
566     // replace gl_text pointer by other
567     if ( myGLText )
568       delete myGLText;
569     myGLText = GLViewer_Text::fromByteCopy( aGLTextArray );
570     
571     
572     /*aCurPos += aSize - aCurPos;
573     aPointer = (char*)&myOwner;
574     for( i = 0; i < sizeof( GLViewer_Owner* ); i++, aPointer++ )
575     *aPointer = theArray[ aCurPos + i ];*/
576
577     return true;        
578 }
579
580 void GLViewer_Object::setGroup( GLViewer_Group* theGroup )
581 {
582   if( myGroup )
583     myGroup->removeObject( this );
584   
585   myGroup = theGroup;
586   if( theGroup )
587     myGroup->addObject( this );
588 }
589
590 GLViewer_Group* GLViewer_Object::getGroup() const
591 {
592   return myGroup;
593 }
594
595 GLViewer_Owner* GLViewer_Object::owner() const
596 {
597   return myOwner;
598 }
599
600 void GLViewer_Object::setOwner( GLViewer_Owner* owner )
601 {
602   myOwner = owner;
603 }
604
605
606 /***************************************************************************
607 **  Class:   GLViewer_MarkerSet
608 **  Descr:   OpenGL MarkerSet
609 **  Module:  GLViewer
610 **  Created: UI team, 03.09.02
611 ****************************************************************************/
612
613 GLViewer_MarkerSet::GLViewer_MarkerSet( int number, float size, const QString& toolTip ) :
614   GLViewer_Object(), myNumber( 0 ), myXCoord( 0 ), myYCoord( 0 )       
615 {
616     myMarkerSize = size;
617     myHNumbers.clear();
618     myUHNumbers.clear();
619     mySelNumbers.clear();
620     myUSelNumbers.clear();
621     myCurSelNumbers.clear();
622     myPrevHNumbers.clear();    
623
624     myType = "GLViewer_MarkerSet";
625     myToolTipText = toolTip;
626     
627     setNumMarkers( number );    
628 }
629
630 GLViewer_MarkerSet::~GLViewer_MarkerSet()
631 {
632     delete myRect;
633
634     if ( myXCoord )
635         delete[] myXCoord;
636     if ( myYCoord )
637         delete[] myYCoord;
638   
639     delete myAspectLine;
640 }
641
642 void AddCoordsToHPGL( QString& buffer, QString command, GLViewer_CoordSystem* aViewerCS, 
643                       GLViewer_CoordSystem* aPaperCS, double x, double y, bool NewLine = true )
644 {
645     if( aViewerCS && aPaperCS )
646         aViewerCS->transform( *aPaperCS, x, y );
647
648     QString temp = command + "%1, %2;";
649     buffer += temp.arg( x ).arg( y );
650     if( NewLine )
651         buffer += ";\n";
652 }
653
654 void AddCoordsToPS( QString& buffer, QString command, GLViewer_CoordSystem* aViewerCS, 
655                     GLViewer_CoordSystem* aPaperCS, double x, double y, bool NewLine = true )
656 {
657     if( aViewerCS && aPaperCS )
658         aViewerCS->transform( *aPaperCS, x, y );
659
660     QString temp = "%1 %2 "+command;    
661     buffer += temp.arg( x ).arg( y );
662     if( NewLine )
663         buffer += "\n";
664 }
665
666 void AddLineAspectToPS( QString& buffer, GLViewer_AspectLine* anAspect, 
667                         GLViewer_CoordSystem* aViewerCS, GLViewer_CoordSystem* aPaperCS )
668 {
669     if( anAspect )
670     {
671         QColor col1, col2, col3;
672         anAspect->getLineColors( col1, col2, col3 );
673
674         float aWidth = anAspect->getLineWidth();
675         int aLineType = anAspect->getLineType();
676
677         QString temp = "%1 %2 %3 setrgbcolor\n";
678         double rr = 1 - double( col1.red() ) / 255.0, //color inverting
679                gg = 1 - double( col1.green() ) / 255.0,
680                bb = 1 - double( col1.blue() ) / 255.0;
681
682         buffer += temp.arg( rr ).arg( gg ).arg( bb );
683
684         double x_stretch, y_stretch;
685         aViewerCS->getStretching( *aPaperCS, x_stretch, y_stretch );
686         buffer += temp.arg( x_stretch * aWidth )+" setlinewidth\n";
687
688         if( aLineType==0 ) //solid
689             buffer += "[] 0 setdash\n";
690         else if( aLineType==1 ) //strip
691             buffer += "[2] 0 setdash\n";
692     }
693 }
694
695 #ifdef WIN32
696 HPEN AddLineAspectToEMF( HDC hDC, GLViewer_AspectLine* anAspect, 
697                          GLViewer_CoordSystem* aViewerCS, GLViewer_CoordSystem* aPaperCS )
698 {
699     if( anAspect )
700     {
701         QColor col1, col2, col3;
702         anAspect->getLineColors( col1, col2, col3 );
703
704         double x_stretch, y_stretch;
705         aViewerCS->getStretching( *aPaperCS, x_stretch, y_stretch );
706
707         double aWidth = anAspect->getLineWidth()*x_stretch;
708         int aLineType = anAspect->getLineType();
709
710         return CreatePen( PS_SOLID, aWidth, RGB( 255-col1.red(), 255-col1.green(), 255-col1.blue() ) );
711     }
712     else
713         return NULL;
714 }
715 #endif
716
717 bool GLViewer_MarkerSet::translateToPS( QFile& hFile, GLViewer_CoordSystem* aViewerCS, GLViewer_CoordSystem* aPSCS )
718 {   
719     int noPoints = 20;
720
721     QString aBuffer = "newpath\n";
722
723     AddLineAspectToPS( aBuffer, getAspectLine(), aViewerCS, aPSCS );
724
725     for( int i=0; i<myNumber; i++ )
726     {       
727         aBuffer += "\n";
728
729         double x_stretch, y_stretch;
730         aViewerCS->getStretching( *aPSCS, x_stretch, y_stretch );
731
732         double x0 = myXCoord[i],
733                y0 = myYCoord[i],
734                r  = myMarkerSize,
735                x, y;
736
737         for( int j=0; j<=noPoints; j++ )
738         {
739             x = x0 + r*cos( double(j)*2*PI/double(noPoints) );
740             y = y0 + r*sin( double(j)*2*PI/double(noPoints) );          
741             if( j==0 )
742                 AddCoordsToPS( aBuffer, "moveto", aViewerCS, aPSCS, x, y, true );               
743             else
744                 AddCoordsToPS( aBuffer, "lineto", aViewerCS, aPSCS, x, y, true );
745         }
746     }
747     aBuffer+="closepath\nstroke\n";
748
749     hFile.writeBlock( aBuffer.ascii(), aBuffer.length() );
750
751     return true;
752 }
753
754 bool GLViewer_MarkerSet::translateToHPGL( QFile& hFile, GLViewer_CoordSystem* aViewerCS,
755                                        GLViewer_CoordSystem* aHPGLCS )
756 {
757     int noPoints = 20;
758     QString aBuffer;
759     for( int i=0; i<myNumber; i++ )
760     {
761         aBuffer = "";
762
763         double x_stretch, y_stretch;
764         aViewerCS->getStretching( *aHPGLCS, x_stretch, y_stretch );
765
766         double x0 = myXCoord[i],
767                y0 = myYCoord[i],
768                r  = myMarkerSize,
769                x, y;
770
771         AddCoordsToHPGL( aBuffer, "PA", aViewerCS, aHPGLCS, x0+r, y0 );
772         aBuffer+="PD;\n";
773         for( int j=1; j<=noPoints; j++ )
774         {
775             x = x0 + r*cos( double(j)*2*PI/double(noPoints) );
776             y = y0 + r*sin( double(j)*2*PI/double(noPoints) );
777             AddCoordsToHPGL( aBuffer, "PD", aViewerCS, aHPGLCS, x, y );
778         }
779         aBuffer+="PU;\n";
780
781         hFile.writeBlock( aBuffer.ascii(), aBuffer.length() );
782     }
783
784     return true;
785 }
786
787 #ifdef WIN32
788 bool GLViewer_MarkerSet::translateToEMF( HDC dc, GLViewer_CoordSystem* aViewerCS, GLViewer_CoordSystem* aEMFCS )
789 {
790     int noPoints = 20;
791     if( !aViewerCS || !aEMFCS )
792         return false;
793     
794     HPEN pen = AddLineAspectToEMF( dc, getAspectLine(), aViewerCS, aEMFCS );
795     HGDIOBJ old = SelectObject( dc, pen );
796
797     for( int i=0; i<myNumber; i++ )
798     {
799         double x0 = myXCoord[i],
800                y0 = myYCoord[i],
801                r  = myMarkerSize,
802                x, y;
803
804         for( int j=0; j<=noPoints; j++ )
805         {
806             x = x0 + r*cos( double(j)*2*PI/double(noPoints) );
807             y = y0 + r*sin( double(j)*2*PI/double(noPoints) );
808             aViewerCS->transform( *aEMFCS, x, y );
809             if( j==0 )
810                 MoveToEx( dc, x, y, NULL );
811             else
812                 LineTo( dc, x, y );
813         }
814     }
815
816     SelectObject( dc, old );
817     if( pen )
818         DeleteObject( pen );
819     return true;
820 }
821 #endif
822
823
824 void GLViewer_MarkerSet::compute()
825 {
826 //  cout << "GLViewer_MarkerSet::compute" << endl;
827   GLfloat xa = myXCoord[0]; 
828   GLfloat xb = myXCoord[0]; 
829   GLfloat ya = myYCoord[0]; 
830   GLfloat yb = myYCoord[0]; 
831
832   for ( int i = 0; i < myNumber; i++ )  
833   {
834     xa = QMIN( xa, myXCoord[i] );
835     xb = QMAX( xb, myXCoord[i] );
836     ya = QMIN( ya, myYCoord[i] );
837     yb = QMAX( yb, myYCoord[i] );
838   }
839   
840   myXGap = ( xb - xa ) / CONSTANT_FOR_RECT;
841   myYGap = ( yb - ya ) / CONSTANT_FOR_RECT;
842
843   myRect->setLeft( xa - myXGap );
844   myRect->setTop( yb + myYGap ); 
845   myRect->setRight( xb + myXGap );
846   myRect->setBottom( ya - myYGap );
847 }
848
849 GLViewer_Drawer* GLViewer_MarkerSet::createDrawer()
850 {
851 //  cout << "GLViewer_MarkerSet::createDrawer" << endl;
852   return myDrawer = new GLViewer_MarkerDrawer();
853 }
854
855
856 GLboolean GLViewer_MarkerSet::highlight( GLfloat x, GLfloat y, GLfloat tol, GLboolean isCircle )
857 {
858     if( !myIsVisible )
859         return false;
860 //  cout << "GLViewer_MarkerSet::highlight " << x <<" " << y << " " << tol << endl;
861   int count = 0;
862   GLfloat xdist, ydist, radius;
863   QValueList<int>::Iterator it;
864   QValueList<int> curHNumbers;
865   bool isFound;
866   GLboolean update;
867   int cnt = 0;
868
869   radius = tol - myMarkerSize / 2.;
870   
871   myUHNumbers += myHNumbers;
872   myHNumbers.clear();
873
874   for ( int i = 0; i < myNumber; i++ ) 
875   {
876     xdist = ( myXCoord[i] - x ) * myXScale;
877     ydist = ( myYCoord[i] - y ) * myYScale;
878
879 //    if ( isCircle && ( xdist * xdist + ydist * ydist <= radius * radius ) ||
880     if ( isCircle && ( xdist * xdist + ydist * ydist <= myMarkerSize * myMarkerSize ) ||
881     !isCircle && ( abs( xdist ) <= radius && abs( ydist ) <= radius ) )
882     {
883       isFound = FALSE;
884       count++;
885       for ( it = myCurSelNumbers.begin(); it != myCurSelNumbers.end(); ++it )
886         if( i == *it )
887         {
888           isFound = TRUE;
889           curHNumbers.append( i );
890         }
891       
892       if( !isFound )
893           myHNumbers.append( i );
894       else
895         cnt++;
896     }
897   }
898   myCurSelNumbers = curHNumbers;
899
900   myIsHigh = ( GLboolean )count;
901   update = ( GLboolean )( myHNumbers != myPrevHNumbers );
902
903   myPrevHNumbers = myHNumbers;
904
905   //cout << "GLViewer_MarkerSet::highlight complete with " << (int)myIsHigh << endl;
906   return update;
907 }
908
909 GLboolean GLViewer_MarkerSet::unhighlight()
910 {
911   if( !myHNumbers.isEmpty() )
912   {
913     myUHNumbers += myHNumbers;
914     myPrevHNumbers.clear();
915     myHNumbers.clear();
916     //??? myCurSelNumbers.clear();
917     return GL_TRUE;
918   }
919   
920   return GL_FALSE;
921 }
922
923 GLboolean GLViewer_MarkerSet::select( GLfloat x, GLfloat y, GLfloat tol, GLViewer_Rect rect, GLboolean isFull,
924                                       GLboolean isCircle, GLboolean isShift )
925 {
926     if( !myIsVisible )
927         return false;
928 //  cout << "GLViewer_MarkerSet::select " << x << " " << y << endl;
929   int count = 0;
930   GLfloat xdist, ydist, radius;
931   QValueList<int>::Iterator it;
932   QValueList<int>::Iterator it1;
933   QValueList<int>::Iterator remIt;
934   QValueList<int>::Iterator curIt;
935
936   radius = tol - myMarkerSize / 2.;
937
938   if( radius < myMarkerSize / 2.)
939     radius = myMarkerSize / 2.;
940
941   count = isShift ? mySelNumbers.count() : 0;
942
943   myUSelNumbers = mySelNumbers;
944
945   if ( !isShift )
946   {
947     mySelNumbers.clear();
948     myCurSelNumbers.clear();
949   }
950
951   for ( int i = 0; i < myNumber; i++ ) 
952   {
953     xdist = ( myXCoord[i] - x ) * myXScale;
954     ydist = ( myYCoord[i] - y ) * myYScale;
955
956     //if ( isCircle && ( xdist * xdist + ydist * ydist <= radius * radius ) ||
957     if ( isCircle && ( xdist * xdist + ydist * ydist <= myMarkerSize * myMarkerSize ) ||
958           !isCircle && ( abs( xdist ) <= radius && abs( ydist ) <= radius ) )
959     {
960       count++;
961       if ( isShift )
962       {
963         bool isFound = FALSE;
964           for( it = mySelNumbers.begin(); it != mySelNumbers.end(); ++it )
965             if ( *it == i )
966             {
967               myUSelNumbers.append( *it );
968             remIt = it;
969               isFound = TRUE;
970               break;
971             }
972
973           if ( !isFound )
974         {
975           mySelNumbers.append( i );
976             myCurSelNumbers.append( i );
977             for ( it1 = myHNumbers.begin(); it1 != myHNumbers.end(); ++it1 )
978               if( i == *it1 )
979               {
980                 myHNumbers.remove( it1 );
981                 break;
982               }
983       for ( it1 = myUHNumbers.begin(); it1 != myUHNumbers.end(); ++it1 )
984         if( i == *it1 )
985         {
986           myUHNumbers.remove( it1 );
987           break;
988         }
989         }
990     else
991         {
992       mySelNumbers.remove( remIt );
993       for ( curIt = myCurSelNumbers.begin(); curIt != myCurSelNumbers.end(); ++curIt )
994         if( *curIt == *remIt)
995         {
996           myCurSelNumbers.remove( curIt );
997           break;
998         }
999       for ( it1 = myHNumbers.begin(); it1 != myHNumbers.end(); ++it1 )
1000         if( i == *it1 )
1001         {
1002           myHNumbers.remove( it1 );
1003           break;
1004         }
1005       for ( it1 = myUHNumbers.begin(); it1 != myUHNumbers.end(); ++it1 )
1006         if( i == *it1 )
1007         {
1008           myUHNumbers.remove( it1 );
1009           break;
1010         }
1011         }
1012       }
1013       else
1014       {
1015     mySelNumbers.append( i );
1016     myCurSelNumbers.append( i );
1017     for ( it1 = myHNumbers.begin(); it1 != myHNumbers.end(); ++it1 )
1018       if( i == *it1 )
1019       {
1020         myHNumbers.remove( it1 );
1021         break;
1022       }
1023     for ( it1 = myUHNumbers.begin(); it1 != myUHNumbers.end(); ++it1 )
1024       if( i == *it1 )
1025           {
1026         myUHNumbers.remove( it1 );
1027         break;
1028       }        
1029       }     
1030     }
1031   }
1032
1033   for( it = mySelNumbers.begin(); it != mySelNumbers.end(); ++it )
1034     for( it1 = myUSelNumbers.begin(); it1 != myUSelNumbers.end(); ++it1 )
1035       if( *it == *it1 )
1036       {
1037         it1 = myUSelNumbers.remove( it1 );
1038         it1--;
1039       }
1040   
1041   myIsSel = (GLboolean)count;
1042
1043 //  cout << "GLViewer_MarkerSet::select complete with " << (int)myIsSel << endl;
1044   return myIsSel;
1045 }
1046
1047 GLboolean GLViewer_MarkerSet::unselect()
1048 {
1049   if( !mySelNumbers.isEmpty() )
1050   {
1051     myUSelNumbers = mySelNumbers;
1052     mySelNumbers.clear();
1053     myCurSelNumbers.clear();
1054     return GL_TRUE;
1055   }
1056
1057   return GL_FALSE;
1058 }
1059
1060 GLViewer_Rect* GLViewer_MarkerSet::getUpdateRect()
1061 {
1062   GLViewer_Rect* rect = new GLViewer_Rect();
1063   
1064   rect->setLeft( myRect->left() + myXGap - myMarkerSize / myXScale );
1065   rect->setTop( myRect->top() + myYGap + myMarkerSize / myYScale ); 
1066   rect->setRight( myRect->right() - myXGap + myMarkerSize / myXScale );
1067   rect->setBottom( myRect->bottom() - myYGap - myMarkerSize / myYScale );
1068   //cout << " Additional tolerance " << myMarkerSize / myYScale << endl;
1069   //rect->setLeft( myRect->left() - myMarkerSize / myXScale );
1070   //rect->setTop( myRect->top() - myMarkerSize / myYScale ); 
1071   //rect->setRight( myRect->right() + myMarkerSize / myXScale );
1072   //rect->setBottom( myRect->bottom() + myMarkerSize / myYScale );
1073   
1074   return rect;
1075 }
1076
1077
1078 void GLViewer_MarkerSet::setXCoord( GLfloat* xCoord, int size )
1079 {
1080   myXCoord = new GLfloat[ size ];
1081   for( int i = 0; i < size; i++ )
1082      myXCoord[i] = xCoord[i];
1083 }
1084
1085 void GLViewer_MarkerSet::setYCoord( GLfloat* yCoord, int size )
1086 {
1087   myYCoord = new GLfloat[ size ];
1088   for( int i = 0; i < size; i++ )
1089      myYCoord[i] = yCoord[i];
1090 }
1091
1092 void GLViewer_MarkerSet::setNumMarkers( GLint number )
1093 {
1094   if ( myNumber == number )
1095     return;
1096     
1097   if ( myXCoord && myYCoord )
1098   {
1099     delete[] myXCoord;
1100     delete[] myYCoord;
1101   }
1102
1103   myNumber = number;
1104   myXCoord = new GLfloat[ myNumber ];
1105   myYCoord = new GLfloat[ myNumber ];
1106 }
1107
1108 void GLViewer_MarkerSet::onSelectionDone( bool append)
1109 {
1110   mySelectedIndexes.Clear();
1111 /*
1112   QValueList<int>::Iterator it;
1113   for( it = myMarkers->mySelNumbers.begin(); it != myMarkers->mySelNumbers.end(); ++it )
1114   {
1115     mySelectedIndexes.Append( *it / 2 ); //!!!
1116   }
1117 */
1118   emit dvMarkersSelected( mySelectedIndexes );
1119 }
1120
1121 void GLViewer_MarkerSet::onSelectionCancel()
1122 {
1123   mySelectedIndexes.Clear();
1124   emit dvMarkersSelected( mySelectedIndexes );
1125 }
1126
1127 void GLViewer_MarkerSet::exportNumbers( QValueList<int>& highlight,
1128                      QValueList<int>& unhighlight,
1129                      QValueList<int>& select,
1130                      QValueList<int>& unselect )
1131 {
1132     highlight = myHNumbers;
1133     unhighlight = myUHNumbers;
1134     select = mySelNumbers;
1135     unselect = myUSelNumbers;
1136
1137     myUHNumbers = myHNumbers;
1138 }
1139
1140 bool GLViewer_MarkerSet::addOrRemoveSelected( int index )
1141 {
1142   if( index < 0 || index > myNumber )
1143     return FALSE;
1144
1145   int n = mySelNumbers.findIndex( index );
1146   if( n == -1 )
1147     mySelNumbers.append( index );
1148   else
1149   {
1150     QValueList<int>::Iterator it;
1151     it = mySelNumbers.at( n );
1152     mySelNumbers.remove( it );
1153     myUSelNumbers.append( index );
1154   }
1155   return TRUE;
1156 }
1157
1158 void GLViewer_MarkerSet::addSelected( const TColStd_SequenceOfInteger& seq )
1159 {
1160   for ( int i = 1; i <= seq.Length(); i++ )
1161     if( mySelNumbers.findIndex( seq.Value( i ) ) == -1 )
1162       mySelNumbers.append( seq.Value( i ) - 1 );
1163 }
1164
1165 void GLViewer_MarkerSet::setSelected( const TColStd_SequenceOfInteger& seq )
1166 {
1167 //   for( QValueList<int>::Iterator it = mySelNumbers.begin(); it != mySelNumbers.end(); ++it )
1168 //     if( myUSelNumbers.findIndex( *it ) == -1 )
1169 //       myUSelNumbers.append( *it );
1170
1171   myUSelNumbers = mySelNumbers;
1172   mySelNumbers.clear();
1173     
1174   for ( int i = 1; i <= seq.Length(); i++ )
1175     mySelNumbers.append( seq.Value( i ) - 1 );
1176 }
1177
1178 void GLViewer_MarkerSet::moveObject( float theX, float theY, bool fromGroup )
1179 {
1180     if( !fromGroup && myGroup)
1181     {
1182       myGroup->dragingObjects( theX, theY );
1183       return;
1184     }
1185     for( int i = 0; i < myNumber;  i++ )
1186     {
1187         myXCoord[i] = myXCoord[i] + theX;
1188         myYCoord[i] = myYCoord[i] + theY;
1189     }
1190     compute();    
1191 }
1192
1193 QByteArray GLViewer_MarkerSet::getByteCopy()
1194 {
1195     int i = 0;
1196     int anISize = sizeof( GLint );
1197     int aFSize = sizeof( GLfloat );
1198     
1199     QByteArray aObject = GLViewer_Object::getByteCopy();
1200
1201     QByteArray aResult( anISize + 2*aFSize*myNumber + aFSize + aObject.size());
1202
1203     char* aPointer = (char*)&myNumber;
1204     for( i = 0; i < anISize; i++, aPointer++ )
1205         aResult[i] = *aPointer;
1206
1207     aPointer = (char*)myXCoord;
1208     for( ; i < anISize + aFSize*myNumber; i++, aPointer++ )
1209         aResult[i] = *aPointer;
1210     aPointer = (char*)myYCoord;
1211     for( ; i < anISize + 2*aFSize*myNumber; i++, aPointer++ )
1212         aResult[i] = *aPointer;
1213     
1214     aPointer = (char*)&myMarkerSize;
1215     for( ; i < anISize + 2*aFSize*myNumber + aFSize; i++, aPointer++ )
1216         aResult[i] = *aPointer;
1217         
1218     
1219     for( ; i < aResult.size(); i++ )
1220         aResult[i] = aObject[i - anISize - 2*aFSize*myNumber - aFSize];
1221
1222     return aResult;
1223 }
1224
1225 bool GLViewer_MarkerSet::initializeFromByteCopy( QByteArray theArray )
1226 {
1227     int i = 0;
1228     int anISize = sizeof( GLint );
1229     int aFSize = sizeof( GLfloat );
1230     //int aBSize = sizeof( GLboolean );
1231
1232     char* aPointer = (char*)&myNumber;
1233     for( i = 0; i < anISize; i++, aPointer++ )
1234         *aPointer = theArray[i];
1235
1236     int aSize = theArray.size();
1237     if( aSize < anISize + 2*aFSize*myNumber + aFSize)
1238         return false;
1239
1240     myXCoord = new GLfloat[myNumber];
1241     myYCoord = new GLfloat[myNumber];
1242     aPointer = (char*)myXCoord;
1243     for( ; i < anISize + aFSize*myNumber; i++, aPointer++ )
1244         *aPointer = theArray[i];
1245     aPointer = (char*)myYCoord;
1246     for( ; i < anISize + 2*aFSize*myNumber; i++, aPointer++ )
1247         *aPointer = theArray[i];
1248
1249     aPointer = (char*)&myMarkerSize;
1250     for( ; i < anISize + 2*aFSize*myNumber + aFSize; i++, aPointer++ )
1251          *aPointer = theArray[i];
1252          
1253     int aCurIndex = anISize + 2*aFSize*myNumber + aFSize;
1254     QByteArray aObject( aSize - aCurIndex );
1255     for( ; i < aSize; i++ )
1256         aObject[i - aCurIndex] = theArray[i];
1257         
1258
1259     if( !GLViewer_Object::initializeFromByteCopy( aObject ) || myType != "GLViewer_MarkerSet" )
1260         return false;
1261
1262     myHNumbers.clear();
1263     myUHNumbers.clear();
1264     mySelNumbers.clear();
1265     myUSelNumbers.clear();
1266     myCurSelNumbers.clear();
1267     myPrevHNumbers.clear();
1268
1269     return true;        
1270 }
1271
1272 /***************************************************************************
1273 **  Class:   GLViewer_Polyline
1274 **  Descr:   OpenGL Polyline
1275 **  Module:  GLViewer
1276 **  Created: UI team, 03.09.02
1277 ****************************************************************************/
1278
1279 #define SECTIONS 100
1280 #define DISTANTION 5
1281
1282 GLViewer_Polyline::GLViewer_Polyline( int number, float size, const QString& toolTip ) :
1283   GLViewer_Object(), myNumber( 0 ), myXCoord( 0 ), myYCoord( 0 )       
1284 {
1285   myHighFlag = GL_TRUE;
1286
1287   myHNumbers.clear();
1288   myUHNumbers.clear();
1289   mySelNumbers.clear();
1290   myUSelNumbers.clear();
1291   myCurSelNumbers.clear();
1292   myPrevHNumbers.clear();
1293
1294   setNumber( number );
1295
1296   myType = "GLViewer_Polyline";
1297   myToolTipText = toolTip;
1298 }
1299
1300 GLViewer_Polyline::~GLViewer_Polyline()
1301 {
1302   delete myRect;
1303   if ( myXCoord )
1304     delete[] myXCoord;
1305   if ( myYCoord )
1306     delete[] myYCoord;
1307  
1308   delete myAspectLine;
1309 }
1310
1311 bool GLViewer_Polyline::translateToPS( QFile& hFile, GLViewer_CoordSystem* aViewerCS, GLViewer_CoordSystem* aPSCS )
1312 {
1313     QString aBuffer = "newpath\n";
1314
1315     AddLineAspectToPS( aBuffer, getAspectLine(), aViewerCS, aPSCS );
1316
1317     for( int i=0; i<myNumber; i++ )
1318         if( i==0 )
1319             AddCoordsToPS( aBuffer, "moveto", aViewerCS, aPSCS, myXCoord[i], myYCoord[i] );
1320         else
1321             AddCoordsToPS( aBuffer, "lineto", aViewerCS, aPSCS, myXCoord[i], myYCoord[i] );
1322
1323     if( myIsClosed )
1324         AddCoordsToPS( aBuffer, "lineto", aViewerCS, aPSCS, myXCoord[0], myYCoord[0] );
1325
1326     aBuffer+="closepath\nstroke\n";
1327     
1328     hFile.writeBlock( aBuffer.ascii(), aBuffer.length() );
1329
1330     return true;
1331 }
1332
1333 bool GLViewer_Polyline::translateToHPGL( QFile& hFile, GLViewer_CoordSystem* aViewerCS, GLViewer_CoordSystem* aHPGLCS )
1334 {
1335     QString aBuffer = "";
1336     for( int i=0; i<myNumber; i++ )
1337     {
1338         AddCoordsToHPGL( aBuffer, "PA", aViewerCS, aHPGLCS, myXCoord[i], myYCoord[i] );
1339         if( i==0 )
1340             aBuffer+="PD;\n";
1341     }
1342
1343     if( myIsClosed )
1344         AddCoordsToHPGL( aBuffer, "PA", aViewerCS, aHPGLCS, myXCoord[0], myYCoord[0] );
1345
1346     aBuffer+="PU;\n";
1347     
1348     hFile.writeBlock( aBuffer.ascii(), aBuffer.length() );
1349
1350     return true;
1351 }
1352
1353 #ifdef WIN32
1354 bool GLViewer_Polyline::translateToEMF( HDC dc, GLViewer_CoordSystem* aViewerCS, GLViewer_CoordSystem* aEMFCS )
1355 {
1356     if( !aViewerCS || !aEMFCS )
1357         return false;
1358     
1359     HPEN pen = AddLineAspectToEMF( dc, getAspectLine(), aViewerCS, aEMFCS );
1360     HGDIOBJ old = SelectObject( dc, pen );
1361
1362     double x, y;
1363     for( int i=0; i<myNumber; i++ )
1364     {
1365         x = myXCoord[i];
1366         y = myYCoord[i];
1367         aViewerCS->transform( *aEMFCS, x, y );
1368         if( i==0 )
1369             MoveToEx( dc, x, y, NULL );
1370         else
1371             LineTo( dc, x, y );
1372     }
1373
1374     if( myIsClosed )
1375     {
1376         x = myXCoord[0];
1377         y = myYCoord[0];
1378         aViewerCS->transform( *aEMFCS, x, y );
1379         LineTo( dc, x, y );
1380     }
1381
1382     SelectObject( dc, old );
1383     if( pen )
1384         DeleteObject( pen );
1385
1386     return true;
1387
1388     return true;
1389 }
1390 #endif
1391
1392 void GLViewer_Polyline::compute()
1393 {
1394 //  cout << "GLViewer_MarkerSet::compute" << endl;
1395   GLfloat xa = myXCoord[0]; 
1396   GLfloat xb = myXCoord[0]; 
1397   GLfloat ya = myYCoord[0]; 
1398   GLfloat yb = myYCoord[0]; 
1399
1400   for ( int i = 0; i < myNumber; i++ )  
1401   {
1402     xa = QMIN( xa, myXCoord[i] );
1403     xb = QMAX( xb, myXCoord[i] );
1404     ya = QMIN( ya, myYCoord[i] );
1405     yb = QMAX( yb, myYCoord[i] );
1406   }
1407
1408   GLfloat xGap = ( xb - xa ) / 10;
1409   GLfloat yGap = ( yb - ya ) / 10;
1410
1411   myRect->setLeft( xa - xGap );
1412   myRect->setTop( yb + yGap ); 
1413   myRect->setRight( xb + xGap );
1414   myRect->setBottom( ya - yGap );
1415 }
1416
1417 GLViewer_Rect* GLViewer_Polyline::getUpdateRect()
1418 {
1419     GLViewer_Rect* rect = new GLViewer_Rect();
1420
1421     rect->setLeft( myRect->left() - myXGap );
1422     rect->setTop( myRect->top() + myYGap ); 
1423     rect->setRight( myRect->right() + myXGap );
1424     rect->setBottom( myRect->bottom() - myYGap );
1425
1426     return rect;
1427 }
1428
1429 GLViewer_Drawer* GLViewer_Polyline::createDrawer()
1430 {
1431 //  cout << "GLViewer_MarkerSet::createDrawer" << endl;
1432     return myDrawer = new GLViewer_PolylineDrawer();
1433 }
1434
1435 GLboolean GLViewer_Polyline::highlight( GLfloat x, GLfloat y, GLfloat tol, GLboolean isCircle )
1436 {
1437     if( !myIsVisible )
1438         return false;
1439     GLfloat xa, xb, ya, yb, l;
1440     GLfloat rsin, rcos, r, ra, rb;
1441     GLboolean update;
1442     GLboolean highlighted = myIsHigh;
1443
1444     myIsHigh = GL_FALSE;
1445
1446     int c = 0;
1447     if( myIsClosed )
1448         c = 1;
1449
1450     for( int i = 0; i < myNumber-1+c; i++ ) 
1451     {
1452         xa = myXCoord[i];
1453         ya = myYCoord[i];
1454         if( i != myNumber-1 )
1455         {
1456               xb = myXCoord[i+1];
1457               yb = myYCoord[i+1];
1458         }
1459         else
1460         {    
1461               xb = myXCoord[0];      
1462               yb = myYCoord[0];
1463         }
1464
1465         l = sqrt( (xb-xa)*(xb-xa) + (yb-ya)*(yb-ya) );
1466         rsin = (yb-ya) / l;
1467         rcos = (xb-xa) / l;
1468         r = ( (x-xa)*(y-yb) - (x-xb)*(y-ya) ) / ( rsin*(ya-yb) + rcos*(xa-xb) );
1469         ra = sqrt( (x-xa)*(x-xa) + (y-ya)*(y-ya) );
1470         rb = sqrt( (x-xb)*(x-xb) + (y-yb)*(y-yb) );
1471         if( fabs( r ) * myXScale <= DISTANTION && ra <= l + DISTANTION && rb <= l + DISTANTION )
1472         {
1473             myIsHigh = GL_TRUE;
1474             break;
1475         }
1476     }
1477
1478     if( !myHighFlag && myIsHigh )
1479         myIsHigh = GL_FALSE;
1480     else
1481         myHighFlag = GL_TRUE;
1482
1483     update = ( GLboolean )( myIsHigh != highlighted );
1484
1485 //  cout << "GLViewer_Polyline::highlight complete with " << (int)myIsHigh << endl;
1486     return update;
1487 }
1488
1489 GLboolean GLViewer_Polyline::unhighlight()
1490 {
1491 //   if( !myHNumbers.isEmpty() )
1492 //   {
1493 //     myUHNumbers = myHNumbers;
1494 //     myHNumbers.clear();
1495 //     return GL_TRUE;
1496 //   }
1497
1498   if( myIsHigh )
1499   {
1500     myIsHigh = GL_FALSE;
1501     return GL_TRUE;
1502   }
1503
1504   return GL_FALSE;
1505 }
1506
1507 GLboolean GLViewer_Polyline::select( GLfloat x, GLfloat y, GLfloat tol, GLViewer_Rect rect, GLboolean isFull,
1508                                      GLboolean isCircle, GLboolean isShift )
1509 {
1510     if( !myIsVisible )
1511         return false;
1512     GLfloat xa, xb, ya, yb, l;
1513     GLfloat rsin, rcos, r, ra, rb;
1514     GLboolean update;
1515     GLboolean selected = myIsSel;
1516
1517     myIsSel = GL_FALSE;
1518
1519     int c = 0;
1520     if( myIsClosed )
1521         c = 1;
1522
1523     for( int i = 0; i < myNumber-1+c; i++ ) 
1524     {
1525         xa = myXCoord[i];
1526         ya = myYCoord[i];
1527         if( i != myNumber-1 )
1528         {
1529             xb = myXCoord[i+1];
1530             yb = myYCoord[i+1];
1531         }
1532         else
1533         {
1534             xb = myXCoord[0];
1535             yb = myYCoord[0];
1536         }
1537
1538         l = sqrt( (xb-xa)*(xb-xa) + (yb-ya)*(yb-ya) );
1539         rsin = (yb-ya) / l;
1540         rcos = (xb-xa) / l;
1541         r = ( (x-xa)*(y-yb) - (x-xb)*(y-ya) ) / ( rsin*(ya-yb) + rcos*(xa-xb) );
1542         ra = sqrt( (x-xa)*(x-xa) + (y-ya)*(y-ya) );
1543         rb = sqrt( (x-xb)*(x-xb) + (y-yb)*(y-yb) );
1544         if( fabs( r ) * myXScale <= DISTANTION && ra <= l + DISTANTION && rb <= l + DISTANTION )
1545         {
1546             myIsSel = GL_TRUE;
1547             break;
1548         }
1549     }
1550
1551     if ( myIsSel )
1552     {
1553         myHighFlag = GL_FALSE;
1554         myIsHigh = GL_FALSE;
1555     }
1556     else
1557         myHighFlag = GL_TRUE;
1558
1559     update = ( GLboolean )( myIsSel != selected );
1560
1561     //  cout << "GLViewer_Polyline::select complete with " << (int)myIsSel << endl;
1562
1563     //  return update;  !!!!!!!!!!!!!!!!!!!!!!!!!!! no here
1564     return myIsSel;
1565 }
1566
1567 GLboolean GLViewer_Polyline::unselect()
1568 {
1569 //   if( !mySelNumbers.isEmpty() )
1570 //   {
1571 //     myUSelNumbers = mySelNumbers;
1572 //     mySelNumbers.clear();
1573 //     myCurSelNumbers.clear();
1574 //     return GL_TRUE;
1575 //   }
1576
1577   if( myIsSel )
1578   {
1579     myIsSel = GL_FALSE;
1580     return GL_TRUE;
1581   }
1582
1583   return GL_FALSE;
1584 }
1585
1586 void GLViewer_Polyline::setXCoord( GLfloat* xCoord, int size )
1587 {
1588   myXCoord = new GLfloat[ size ];
1589   for( int i = 0; i < size; i++ )
1590      myXCoord[i] = xCoord[i];
1591 }
1592
1593 void GLViewer_Polyline::setYCoord( GLfloat* yCoord, int size )
1594 {
1595   myYCoord = new GLfloat[ size ];
1596   for( int i = 0; i < size; i++ )
1597      myYCoord[i] = yCoord[i];
1598 }
1599
1600 void GLViewer_Polyline::setNumber( GLint number )
1601 {
1602   if ( myNumber == number )
1603     return;
1604     
1605   if ( myXCoord && myYCoord )
1606   {
1607     delete[] myXCoord;
1608     delete[] myYCoord;
1609   }
1610
1611   myNumber = number;
1612   myXCoord = new GLfloat[ myNumber ];
1613   myYCoord = new GLfloat[ myNumber ];
1614 }
1615
1616 void GLViewer_Polyline::onSelectionDone( bool append)
1617 {
1618   mySelectedIndexes.Clear();
1619 /*
1620   QValueList<int>::Iterator it;
1621   for( it = myMarkers->mySelNumbers.begin(); it != myMarkers->mySelNumbers.end(); ++it )
1622   {
1623     mySelectedIndexes.Append( *it / 2 ); //!!!
1624   }
1625 */ 
1626 }
1627
1628 void GLViewer_Polyline::onSelectionCancel()
1629 {
1630   mySelectedIndexes.Clear();
1631 }
1632
1633 void GLViewer_Polyline::exportNumbers( QValueList<int>& highlight,
1634                      QValueList<int>& unhighlight,
1635                      QValueList<int>& select,
1636                      QValueList<int>& unselect )
1637 {
1638   highlight = myHNumbers;
1639   unhighlight = myUHNumbers;
1640   select = mySelNumbers;
1641   unselect = myUSelNumbers;
1642 }
1643
1644 void GLViewer_Polyline::moveObject( float theX, float theY, bool fromGroup )
1645 {
1646   if( !fromGroup && myGroup)
1647   {
1648     myGroup->dragingObjects( theX, theY );
1649     return;
1650   }
1651   for( int i = 0; i < myNumber;  i++ )
1652   {
1653     myXCoord[i] = myXCoord[i] + theX;
1654     myYCoord[i] = myYCoord[i] + theY;
1655   }
1656   compute();    
1657 }
1658
1659 QByteArray GLViewer_Polyline::getByteCopy()
1660 {
1661     int i = 0;
1662     int anISize = sizeof( GLint );
1663     int aFSize = sizeof( GLfloat );
1664     int aBSize = sizeof( GLboolean );
1665
1666     QByteArray aObject = GLViewer_Object::getByteCopy();
1667
1668     QByteArray aResult( aFSize*myNumber*2 + anISize + 2*aBSize + aObject.size());
1669
1670     char* aPointer = (char*)&myNumber;
1671     for( i = 0; i < anISize; i++, aPointer++ )
1672         aResult[i] = *aPointer;
1673
1674     aPointer = (char*)myXCoord;
1675     for( ; i < anISize + aFSize*myNumber; i++, aPointer++ )
1676         aResult[i] = *aPointer;
1677     aPointer = (char*)myYCoord;
1678     for( ; i < anISize + 2*aFSize*myNumber; i++, aPointer++ )
1679         aResult[i] = *aPointer;
1680     
1681     aPointer = (char*)&myIsClosed;
1682     for( ; i < anISize + 2*aFSize*myNumber + aBSize; i++, aPointer++ )
1683         aResult[i] = *aPointer;
1684     aPointer = (char*)&myHighSelAll;
1685     for( ; i < anISize + 2*aFSize*myNumber + 2*aBSize; i++, aPointer++ )
1686         aResult[i] = *aPointer;
1687
1688     for( ; i < aResult.size(); i++ )
1689         aResult[i] = aObject[i - anISize - 2*aFSize*myNumber - 2*aBSize];
1690
1691     return aResult;
1692 }
1693
1694
1695 bool GLViewer_Polyline::initializeFromByteCopy( QByteArray theArray )
1696 {
1697     int i = 0;
1698     int anISize = sizeof( GLint );
1699     int aFSize = sizeof( GLfloat );
1700     int aBSize = sizeof( GLboolean );
1701
1702     char* aPointer = (char*)&myNumber;
1703     for( i = 0; i < anISize; i++, aPointer++ )
1704         *aPointer = theArray[i];
1705
1706     int aSize = theArray.size();
1707     if( aSize < aFSize*myNumber*2 + anISize + 2*aBSize )
1708         return false;
1709
1710     myXCoord = new GLfloat[myNumber];
1711     myYCoord = new GLfloat[myNumber];
1712     aPointer = (char*)myXCoord;
1713     for( ; i < anISize + aFSize*myNumber; i++, aPointer++ )
1714         *aPointer = theArray[i];
1715     aPointer = (char*)myYCoord;
1716     for( ; i < anISize + 2*aFSize*myNumber; i++, aPointer++ )
1717         *aPointer = theArray[i];
1718
1719     aPointer = (char*)&myIsClosed;
1720     for( ; i < anISize + 2*aFSize*myNumber + aBSize; i++, aPointer++ )
1721          *aPointer = theArray[i];
1722     aPointer = (char*)&myHighSelAll;
1723     for( ; i < anISize + 2*aFSize*myNumber + 2*aBSize; i++, aPointer++ )
1724          *aPointer = theArray[i];
1725
1726     int aCurIndex = anISize + 2*aFSize*myNumber + 2*aBSize;
1727     QByteArray aObject( aSize - aCurIndex );
1728     for( ; i < aSize; i++ )
1729         aObject[i - aCurIndex] = theArray[i];
1730
1731     if( !GLViewer_Object::initializeFromByteCopy( aObject ) || myType != "GLViewer_Polyline" )
1732         return false;
1733
1734     myHNumbers.clear();
1735     myUHNumbers.clear();
1736     mySelNumbers.clear();
1737     myUSelNumbers.clear();
1738     myCurSelNumbers.clear();
1739     myPrevHNumbers.clear();
1740
1741     return true;        
1742 }
1743
1744 /***************************************************************************
1745 **  Class:   GLViewer_TextObject
1746 **  Descr:   Text as Object for OpenGL
1747 **  Module:  GLViewer
1748 **  Created: UI team, 12.02.04
1749 ****************************************************************************/
1750
1751 GLViewer_TextObject::GLViewer_TextObject( const QString& theStr, float xPos, float yPos, 
1752                                     const QColor& color, const QString& toolTip )
1753                                     : GLViewer_Object()
1754 {
1755     myGLText = new GLViewer_Text( theStr, xPos, yPos, color );
1756     myWidth = 0;
1757     myHeight = 0;
1758
1759     myHighFlag = GL_TRUE;
1760
1761     myType = "GLViewer_TextObject";
1762     myToolTipText = toolTip;
1763 }
1764 GLViewer_TextObject::~GLViewer_TextObject()
1765 {
1766   if ( myGLText )
1767     delete myGLText;
1768
1769   delete myRect;  
1770   delete myAspectLine;
1771 }
1772
1773 bool GLViewer_TextObject::translateToPS( QFile& hFile, GLViewer_CoordSystem* aViewerCS, GLViewer_CoordSystem* aPSCS )
1774 {
1775     QString aText = myGLText->getText();    
1776     float xPos, yPos;
1777     myGLText->getPosition( xPos, yPos );
1778
1779     QString aBuffer = "/Times-Roman findfont\n";
1780     aBuffer += "12 scalefont setfont\n";
1781
1782     AddCoordsToPS( aBuffer, "moveto", aViewerCS, aPSCS, double(xPos), double(yPos) );
1783     aBuffer += "(" + aText + ") show\n";
1784
1785     hFile.writeBlock( aBuffer.ascii(), aBuffer.length() );
1786
1787     return true;
1788 }
1789
1790 bool GLViewer_TextObject::translateToHPGL( QFile& hFile, GLViewer_CoordSystem* aViewerCS, GLViewer_CoordSystem* aHPGLCS )
1791 {
1792     QString aText = myGLText->getText();    
1793     float xPos, yPos;
1794     myGLText->getPosition( xPos, yPos );
1795
1796     QString aBuffer = "";
1797     AddCoordsToHPGL( aBuffer, "PA", aViewerCS, aHPGLCS, double(xPos), double(yPos) );
1798     
1799     aBuffer = "LB" + aText + "#;";
1800     
1801     hFile.writeBlock( aBuffer.ascii(), aBuffer.length() );
1802
1803     return true;
1804 }
1805
1806 #ifdef WIN32
1807 bool GLViewer_TextObject::translateToEMF( HDC dc, GLViewer_CoordSystem* aViewerCS, GLViewer_CoordSystem* aEMFCS )
1808 {
1809     QString aText = myGLText->getText();    
1810     float xPos, yPos;
1811     myGLText->getPosition( xPos, yPos );
1812
1813     double x = double( xPos ), 
1814            y = double( yPos );
1815
1816     aViewerCS->transform( *aEMFCS, x, y );
1817     const char* str = aText.ascii();
1818
1819     int nHeight = 35*14;       // height of font
1820     int nWidth = 35*12;        // average character width
1821     int nEscapement = 0;       // angle of escapement
1822     int nOrientation = 0;      // base-line orientation angle
1823     int fnWeight = FW_NORMAL;  // font weight
1824     DWORD fdwItalic = FALSE;    // italic attribute option
1825     DWORD fdwUnderline = FALSE; // underline attribute option
1826     DWORD fdwStrikeOut = FALSE; // strikeout attribute option
1827     DWORD fdwCharSet = ANSI_CHARSET; // character set identifier
1828     DWORD fdwOutputPrecision = OUT_DEFAULT_PRECIS;  // output precision
1829     DWORD fdwClipPrecision = CLIP_DEFAULT_PRECIS;    // clipping precision
1830     DWORD fdwQuality = PROOF_QUALITY;          // output quality
1831     DWORD fdwPitchAndFamily = FIXED_PITCH | FF_DONTCARE;   // pitch and family
1832     LPCTSTR lpszFace = NULL;         // typeface name
1833
1834
1835     HFONT aFont = CreateFont( nHeight, nWidth, nEscapement, nOrientation, fnWeight, fdwItalic,
1836                               fdwUnderline, fdwStrikeOut, fdwCharSet, fdwOutputPrecision, 
1837                               fdwClipPrecision, fdwQuality, fdwPitchAndFamily, lpszFace );
1838     LOGBRUSH aBrushData;
1839     aBrushData.lbStyle = BS_HOLLOW;
1840
1841     HBRUSH aBrush = CreateBrushIndirect( &aBrushData );
1842
1843     HGDIOBJ old1 = SelectObject( dc, aFont );
1844     HGDIOBJ old2 = SelectObject( dc, aBrush );
1845
1846     TextOut( dc, x, y, str, aText.length() );
1847
1848     SelectObject ( dc, old1 );
1849     SelectObject ( dc, old2 );
1850
1851     DeleteObject( aFont );
1852
1853     return true;
1854 }
1855 #endif
1856
1857 GLViewer_Drawer* GLViewer_TextObject::createDrawer()
1858 {
1859     myDrawer = new GLViewer_TextDrawer();
1860     compute();
1861     return myDrawer;
1862 }
1863
1864 void GLViewer_TextObject::compute()
1865 {
1866     float xPos, yPos;
1867     QString aStr = myGLText->getText();
1868     myGLText->getPosition( xPos, yPos );
1869
1870     myWidth = myGLText->getWidth();
1871     myHeight = myGLText->getHeight();
1872     myRect->setLeft( xPos );
1873     myRect->setTop( yPos + myHeight  ); 
1874     myRect->setRight( xPos + myWidth );
1875     myRect->setBottom( yPos );
1876 }
1877
1878 void GLViewer_TextObject::setDrawer( GLViewer_Drawer* theDrawer )
1879 {
1880     myDrawer = theDrawer;
1881     //compute();
1882 }
1883
1884 GLViewer_Rect* GLViewer_TextObject::getUpdateRect()
1885 {    
1886     GLViewer_Rect* rect = new GLViewer_Rect();
1887
1888     float xPos, yPos;
1889     QString aStr = myGLText->getText();
1890     myGLText->getPosition( xPos, yPos );
1891
1892     rect->setLeft( myRect->left() + myXGap - myWidth / myXScale );
1893     rect->setTop( myRect->top() + myYGap + myHeight / myYScale );
1894     rect->setRight( myRect->right() - myXGap + myWidth / myXScale );
1895     rect->setBottom( myRect->bottom() - myYGap - myHeight / myYScale );
1896
1897     return rect;
1898 }
1899
1900 GLboolean GLViewer_TextObject::highlight( GLfloat theX, GLfloat theY, GLfloat theTol, GLboolean isCircle )
1901 {
1902     if( !myIsVisible )
1903         return false;
1904
1905     float xPos, yPos;
1906     myGLText->getPosition( xPos, yPos );
1907
1908     QRect aRect;
1909     aRect.setLeft( (int)xPos );
1910     aRect.setRight( (int)(xPos + myWidth / myXScale) );
1911     aRect.setTop( (int)yPos );// - myHeight / myYScale );
1912     aRect.setBottom( (int)(yPos + myHeight / myYScale) );
1913
1914     //cout << "theX: " << theX << "  theY: " << theY << endl;
1915     //cout << "aRect.left(): " << aRect.left() << "  aRect.right(): " << aRect.right() << endl;
1916     //cout << "aRect.top(): " << aRect.top() << "  aRect.bottom(): " << aRect.bottom() << endl;
1917
1918     QRegion obj( aRect );
1919     QRegion intersection;
1920     QRect region;
1921
1922     int l = (int)(theX - theTol);
1923     int r = (int)(theX + theTol);
1924     int t = (int)(theY - theTol);
1925     int b = (int)(theY + theTol);
1926     region.setLeft( l );
1927     region.setRight( r );
1928     region.setTop( t );
1929     region.setBottom( b );
1930
1931     QRegion circle( l, t, (int)(2 * theTol), (int)(2 * theTol), QRegion::Ellipse );
1932     if( isCircle )
1933         intersection = obj.intersect( circle );
1934     else
1935         intersection = obj.intersect( region );
1936     
1937     if( intersection.isEmpty() )
1938         myIsHigh = false;
1939     else
1940         myIsHigh = true;
1941     
1942     if( !myHighFlag && myIsHigh )
1943         myIsHigh = GL_FALSE;
1944     else
1945         myHighFlag = GL_TRUE;
1946
1947     return myIsHigh;
1948 }
1949
1950 GLboolean GLViewer_TextObject::unhighlight()
1951 {
1952     if( myIsHigh )
1953     {
1954         myIsHigh = GL_FALSE;
1955         return GL_TRUE;
1956     }
1957
1958     return GL_FALSE;
1959 }
1960
1961 GLboolean GLViewer_TextObject::select( GLfloat theX, GLfloat theY, GLfloat theTol, GLViewer_Rect rect,
1962                                        GLboolean isFull, GLboolean isCircle, GLboolean isShift )
1963
1964     if( !myIsVisible )
1965         return false;
1966
1967     QRegion obj( *(myRect->toQRect()) );
1968     QRegion intersection;
1969     QRect region;
1970
1971     int l = (int)(theX - theTol);
1972     int r = (int)(theX + theTol);
1973     int t = (int)(theY - theTol);
1974     int b = (int)(theY + theTol);
1975     region.setLeft( l );
1976     region.setRight( r );
1977     region.setTop( t );
1978     region.setBottom( b );
1979
1980     QRegion circle( l, t, (int)(2 * theTol), (int)(2 * theTol), QRegion::Ellipse );
1981     if( isCircle )
1982         intersection = obj.intersect( circle );
1983     else
1984         intersection = obj.intersect( region );
1985     
1986     if( intersection.isEmpty() )
1987         myIsSel = false;
1988     else
1989         myIsSel = true;
1990
1991     if ( myIsSel )
1992     {
1993         myHighFlag = GL_FALSE;
1994         myIsHigh = GL_FALSE;
1995     }
1996     else
1997         myHighFlag = GL_TRUE;
1998
1999     return myIsSel;
2000 }
2001
2002 GLboolean GLViewer_TextObject::unselect()
2003 {
2004     if( myIsSel )
2005     {
2006         myIsSel = GL_FALSE;
2007         return GL_TRUE;
2008     }
2009
2010     return GL_FALSE;
2011 }
2012
2013 void GLViewer_TextObject::moveObject( float theX, float theY, bool fromGroup )
2014 {
2015   if( !fromGroup && myGroup)
2016   {
2017     myGroup->dragingObjects( theX, theY );
2018     return;
2019   }
2020   float aX, anY;
2021   myGLText->getPosition( aX, anY );
2022   aX += theX;
2023   anY += theY;
2024   myGLText->setPosition( aX, anY );
2025   compute();
2026 }
2027
2028 QByteArray GLViewer_TextObject::getByteCopy()
2029 {
2030     QByteArray aObject = GLViewer_Object::getByteCopy();
2031
2032     return aObject;
2033 }
2034
2035
2036 bool GLViewer_TextObject::initializeFromByteCopy( QByteArray theArray )
2037 {
2038     if( !GLViewer_Object::initializeFromByteCopy( theArray ) || myType != "GLViewer_TextObject" )
2039         return false;
2040
2041     myHighFlag = true;
2042     return true;        
2043 }
2044
2045
2046 /***************************************************************************
2047 **  Class:   GLViewer_AspectLine
2048 **  Descr:   Substitution of Prs2d_AspectLine for OpenGL
2049 **  Module:  GLViewer
2050 **  Created: UI team, 05.11.02
2051 ****************************************************************************/
2052
2053 GLViewer_AspectLine::GLViewer_AspectLine()
2054 {
2055     myNColor = QColor( 255, 255, 255 );
2056     myHColor = QColor( 0, 255, 255 );
2057     mySColor = QColor( 255, 0, 0 );
2058
2059     myLineWidth = 1.0;
2060     myLineType = 0;
2061 }
2062
2063 GLViewer_AspectLine::GLViewer_AspectLine( int type, float width )
2064 {
2065     myNColor = QColor( 255, 255, 255 );
2066     myHColor = QColor( 0, 255, 255 );
2067     mySColor = QColor( 255, 0, 0 );
2068
2069     myLineWidth = width;
2070     if( type == 1 || type == 0 )
2071         myLineType = type;
2072     else
2073         myLineType = 0;
2074 }
2075
2076 GLViewer_AspectLine::~GLViewer_AspectLine()
2077 {
2078 }
2079
2080 void GLViewer_AspectLine::setLineColors( QColor nc, QColor hc, QColor sc )
2081 {
2082     myNColor = nc;
2083     myHColor = hc;
2084     mySColor = sc;
2085 }
2086
2087 int GLViewer_AspectLine::setLineType( const int type )
2088 {
2089     if( type == 1 || type == 0 )
2090     {
2091         myLineType = type;
2092         return 0;
2093     }
2094     return 1;
2095 }
2096
2097 int GLViewer_AspectLine::setLineWidth( const float width )
2098 {
2099     if( width > 0 )
2100     {
2101         myLineWidth = width;
2102         return 0;
2103     }
2104     return 1;
2105 }
2106
2107 void GLViewer_AspectLine::getLineColors( QColor& nc, QColor& hc, QColor& sc ) const
2108 {
2109     nc = myNColor;
2110     hc = myHColor;
2111     sc = mySColor;
2112 }
2113
2114 QByteArray GLViewer_AspectLine::getByteCopy() const
2115 {
2116     int anISize = sizeof( int );
2117     int aFSize = sizeof( float );
2118     int aNR = myNColor.red(), aNG = myNColor.green(), aNB = myNColor.blue();
2119     int aHR = myHColor.red(), aHG = myHColor.green(), aHB = myHColor.blue();
2120     int aSR = mySColor.red(), aSG = mySColor.green(), aSB = mySColor.blue();
2121
2122     QByteArray aResult( anISize * 10 + aFSize );
2123
2124     int i = 0;
2125     
2126     char* aPointer = (char*)&aNR;
2127     for( i = 0; i < anISize; i++, aPointer++ )
2128         aResult[i] = *aPointer;
2129     aPointer = (char*)&aNG;
2130     for( ; i < 2*anISize; i++, aPointer++ )
2131         aResult[i] = *aPointer;
2132     aPointer = (char*)&aNB;
2133     for( ; i < 3*anISize; i++, aPointer++ )
2134         aResult[i] = *aPointer;
2135
2136     aPointer = (char*)&aHR;
2137     for( ; i < 4*anISize; i++, aPointer++ )
2138         aResult[i] = *aPointer;
2139     aPointer = (char*)&aHG;
2140     for( ; i < 5*anISize; i++, aPointer++ )
2141         aResult[i] = *aPointer;
2142     aPointer = (char*)&aHB;
2143     for( ; i < 6*anISize; i++, aPointer++ )
2144         aResult[i] = *aPointer;
2145
2146     aPointer = (char*)&aSR;
2147     for( ; i < 7*anISize; i++, aPointer++ )
2148         aResult[i] = *aPointer;
2149     aPointer = (char*)&aSG;
2150     for( ; i < 8*anISize; i++, aPointer++ )
2151         aResult[i] = *aPointer;
2152     aPointer = (char*)&aSB;
2153     for( ; i < 9*anISize; i++, aPointer++ )
2154         aResult[i] = *aPointer;
2155     
2156     aPointer = (char*)&myLineWidth;
2157     for( ; i < 9*anISize + aFSize; i++, aPointer++ )
2158         aResult[i] = *aPointer;
2159
2160     aPointer = (char*)&myLineType;
2161     for( ; i < 10*anISize + aFSize; i++, aPointer++ )
2162         aResult[i] = *aPointer;    
2163
2164     return aResult;
2165 }
2166
2167 GLViewer_AspectLine* GLViewer_AspectLine::fromByteCopy( QByteArray theBytes )
2168 {
2169
2170     int anISize = sizeof( int );
2171     int aFSize = sizeof( float );
2172     int aNR = 0, aNG = 0, aNB = 0;
2173     int aHR = 0, aHG = 0, aHB = 0;
2174     int aSR = 0, aSG = 0, aSB = 0;
2175     int aLineType = 0;
2176     float aLineWidth = 0;
2177
2178     int i = 0;
2179
2180     char* aPointer = (char*)&aNR;
2181     for( i = 0; i < anISize; i++, aPointer++ )
2182         *aPointer = theBytes[i];
2183     aPointer = (char*)&aNG;
2184     for( ; i < 2*anISize; i++, aPointer++ )
2185         *aPointer = theBytes[i];
2186     aPointer = (char*)&aNB;
2187     for( ; i < 3*anISize; i++, aPointer++ )
2188         *aPointer = theBytes[i];
2189
2190     aPointer = (char*)&aHR;
2191     for( ; i < 4*anISize; i++, aPointer++ )
2192         *aPointer = theBytes[i];
2193     aPointer = (char*)&aHG;
2194     for( ; i < 5*anISize; i++, aPointer++ )
2195         *aPointer = theBytes[i];
2196     aPointer = (char*)&aHB;
2197     for( ; i < 6*anISize; i++, aPointer++ )
2198         *aPointer = theBytes[i];
2199
2200     aPointer = (char*)&aSR;
2201     for( ; i < 7*anISize; i++, aPointer++ )
2202         *aPointer = theBytes[i];
2203     aPointer = (char*)&aSG;
2204     for( ; i < 8*anISize; i++, aPointer++ )
2205         *aPointer = theBytes[i];
2206     aPointer = (char*)&aSB;
2207     for( ; i < 9*anISize; i++, aPointer++ )
2208         *aPointer = theBytes[i];
2209
2210     aPointer = (char*)&aLineWidth;
2211     for( ; i < 9*anISize + aFSize; i++, aPointer++ )
2212         *aPointer = theBytes[i];
2213
2214     aPointer = (char*)&aLineType;
2215     for( ; i < 10*anISize + aFSize; i++, aPointer++ )
2216         *aPointer = theBytes[i];
2217
2218     GLViewer_AspectLine* anAspect = new GLViewer_AspectLine( aLineType, aLineWidth );
2219     anAspect->setLineColors( QColor( aNR, aNG, aNB ), 
2220                              QColor( aHR, aHG, aHB ), 
2221                              QColor( aSR, aSG, aSB ) );
2222     return anAspect;
2223 }
2224
2225 /***************************************************************************
2226 **  Class:   GLViewer_MimeSource
2227 **  Descr:   Needs for a work with QClipboard
2228 **  Module:  GLViewer
2229 **  Created: UI team, 22.03.04
2230 ****************************************************************************/
2231 GLViewer_MimeSource::~GLViewer_MimeSource()
2232 {
2233 }
2234
2235 bool GLViewer_MimeSource::setObjects( QValueList<GLViewer_Object*> theObjects )
2236 {
2237     if( !theObjects.empty() )
2238     {
2239         QStringList aObjectsType;
2240         QValueList<QByteArray> aObjects;
2241         QValueList<GLViewer_Object*>::const_iterator anIt = theObjects.begin();
2242         QValueList<GLViewer_Object*>::const_iterator anEndIt = theObjects.end();
2243
2244         int aObjByteSize = 0;
2245         for( ; anIt != anEndIt; anIt++ )
2246         {
2247             aObjects.append( (*anIt)->getByteCopy() );
2248             aObjByteSize += aObjects.last().size();
2249             aObjectsType.append( (*anIt)->getObjectType() );
2250         }
2251
2252         int anISize = sizeof( int );
2253         QString aTypes = aObjectsType.join("");
2254         int aStrByteSize = aTypes.length();
2255         int aObjNum = aObjects.count();
2256
2257         myByteArray = QByteArray( anISize * (1 + 2*aObjNum) + aStrByteSize + aObjByteSize );
2258
2259         int anIndex = 0, j = 0;
2260         char* aPointer = (char*)&aObjNum;
2261         for( anIndex = 0; anIndex < anISize; anIndex++, aPointer++ )
2262             myByteArray[anIndex] = *aPointer;
2263         
2264         QStringList::const_iterator aStrIt = aObjectsType.begin();
2265         QStringList::const_iterator aEndStrIt = aObjectsType.end();
2266         for( j = 1; aStrIt != aEndStrIt; aStrIt++, j++ )
2267         {
2268             int aStrLen = (*aStrIt).length();
2269             aPointer = (char*)&aStrLen;
2270             for( ; anIndex < anISize*( 1 + j ); anIndex++, aPointer++ )
2271                 myByteArray[anIndex] = *aPointer;
2272         }
2273
2274         int aCurIndex = anIndex;
2275         const char* aStr = aTypes.data();
2276
2277         for( j = 0 ; anIndex < aCurIndex + aStrByteSize; aPointer++, anIndex++, j++ )
2278             myByteArray[anIndex] = aStr[j];
2279
2280         aCurIndex = anIndex;
2281         QValueList<QByteArray>::iterator anObjIt = aObjects.begin();
2282         QValueList<QByteArray>::iterator anEndObjIt = aObjects.end();
2283         for( j = 1; anObjIt != anEndObjIt; anObjIt++, j++ )
2284         {
2285             int aObjLen = (int)((*anObjIt).size());
2286             aPointer = (char*)&aObjLen;
2287             for( ; anIndex < aCurIndex + anISize*j; anIndex++, aPointer++ )
2288                 myByteArray[anIndex] = *aPointer;
2289         }
2290
2291         aCurIndex = anIndex;
2292         anObjIt = aObjects.begin();
2293
2294         for( ; anObjIt != anEndObjIt; anObjIt++ )
2295         {
2296             int aObjLen = (int)((*anObjIt).size());
2297             for( j = 0 ; anIndex < aCurIndex + aObjLen; anIndex++, aPointer++, j++ )
2298                 myByteArray[anIndex] = (*anObjIt)[j];
2299             aCurIndex = anIndex;
2300         }
2301      
2302         return true;
2303     }
2304
2305     return false;
2306 }
2307 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!NOTE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2308 //If you want to use new class, following two method must be redefined
2309 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!NOTE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2310 GLViewer_Object* GLViewer_MimeSource::getObject( QByteArray theArray, QString theType )
2311 {
2312     if( !theArray.isEmpty() )
2313     {
2314         if( theType == "GLViewer_MarkerSet" )
2315         {
2316             GLViewer_MarkerSet* aObject = new GLViewer_MarkerSet(  0, (float)0.0, 0  );
2317             if( aObject->initializeFromByteCopy( theArray ) )
2318                 return aObject;
2319         }
2320         else if ( theType == "GLViewer_Polyline" )
2321         {
2322             GLViewer_Polyline* aObject = new GLViewer_Polyline( 0, (float)0.0, 0 );
2323             if( aObject->initializeFromByteCopy( theArray ) )
2324                 return aObject;
2325         }
2326         else if( theType == "GLViewer_TextObject" )
2327         {
2328             GLViewer_TextObject* aObject = new GLViewer_TextObject( 0, 0, 0, QColor(255,255,255), 0 );
2329             if( aObject->initializeFromByteCopy( theArray ) )
2330                 return aObject;
2331         }
2332     }        
2333     
2334     return NULL;
2335 }
2336
2337 QValueList<GLViewer_Object*> GLViewer_MimeSource::getObjects( QByteArray theArray, QString theType )
2338 {
2339     if( !theArray.isEmpty() )
2340     {
2341         int anISize = sizeof( int );
2342         if( theType == "GLViewer_Objects" )
2343         {
2344             QStringList aTypeList;
2345             QValueList<QByteArray> aObjects;
2346             QValueList<GLViewer_Object*> aObjectList;
2347
2348             QValueList<int> aTypeSizeList;
2349             QValueList<int> aObjSizeList;
2350             int aObjNum = 0;
2351             char* aPointer = (char*)&aObjNum;
2352
2353             int anIndex = 0, j = 0;
2354             for( anIndex = 0; anIndex < anISize; anIndex++, aPointer++ )
2355                 *aPointer = theArray[anIndex];
2356             
2357             for( j = 0; j < aObjNum; j++ )
2358             {
2359                 int aTempVal = 0;
2360                 aPointer = (char*)&aTempVal;
2361                 for( ; anIndex < anISize*(j+2); anIndex++, aPointer++ )
2362                     *aPointer = theArray[anIndex];
2363                 aTypeSizeList.append( aTempVal );
2364             }
2365             
2366             int aCurIndex = anIndex;
2367             for( j = 0; j < aObjNum; j++ )
2368             {
2369                 QString aTempStr;
2370                 for( ; anIndex < aCurIndex + aTypeSizeList[j]; anIndex++ )
2371                 {    
2372                     char aLetter = theArray[anIndex];
2373                     aTempStr.append( aLetter );
2374                 }
2375                 aTypeList.append( aTempStr );
2376                 aCurIndex = anIndex;
2377             }
2378
2379             for( j = 0; j < aObjNum; j++ )
2380             {
2381                 int aTempVal = 0;
2382                 aPointer = (char*)&aTempVal;
2383                 for( ; anIndex < aCurIndex + anISize*(j+1); anIndex++, aPointer++ )
2384                     *aPointer = theArray[anIndex];
2385                 aObjSizeList.append( aTempVal );
2386             }
2387
2388             aCurIndex = anIndex;
2389             for( j = 0; j < aObjNum; j++ )
2390             {
2391                 QByteArray aTempArray(aObjSizeList[j]);
2392                 for( ; anIndex < aCurIndex + aObjSizeList[j]; anIndex++ )
2393                     aTempArray[anIndex-aCurIndex] = theArray[anIndex];
2394                 aObjects.append( aTempArray );
2395                 aCurIndex = anIndex;
2396             }
2397             
2398             for( j = 0; j < aObjNum; j++ )
2399                 aObjectList.append( getObject( aObjects[j], aTypeList[j] ) );
2400
2401             return aObjectList;
2402         }
2403     }
2404     
2405     return QValueList<GLViewer_Object*>();    
2406 }
2407
2408 const char* GLViewer_MimeSource::format( int theIndex ) const
2409 {
2410     switch( theIndex )
2411     {
2412     case 0: return "GLViewer_Objects";
2413     //case 1: return "GLViewer_MarkerSet";
2414     //case 2: return "GLViewer_Polyline";
2415     //case 3: return "GLViewer_TextObject";
2416     default: return 0;
2417     }
2418
2419 }
2420
2421 QByteArray GLViewer_MimeSource::encodedData( const char* theObjectType ) const
2422 {
2423     if( theObjectType == "GLViewer_Objects" )
2424         return myByteArray;
2425     
2426     return QByteArray();
2427 }