1 // Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // Author : OPEN CASCADE
23 //#include <GLViewerAfx.h>
25 #include "GLViewer_BaseObjects.h"
26 #include "GLViewer_BaseDrawers.h"
27 #include "GLViewer_AspectLine.h"
28 #include "GLViewer_CoordSystem.h"
29 #include "GLViewer_Text.h"
30 #include "GLViewer_Group.h"
32 #include "GLViewer_Drawer.h"
37 //using namespace std;
42 GLViewer_MarkerSet::GLViewer_MarkerSet( int number, float size, const QString& toolTip ) :
53 myUSelNumbers.clear();
54 myCurSelNumbers.clear();
55 myPrevHNumbers.clear();
57 myType = "GLViewer_MarkerSet";
58 myToolTipText = toolTip;
60 setNumMarkers( number );
66 GLViewer_MarkerSet::~GLViewer_MarkerSet()
75 Adds coords to text buffer in HPGL format
76 \param buffer - text buffer
77 \param command - command to be added with coords
78 \param aViewerCS - viewer co-ordinates system
79 \param aPaperCS - paper co-ordinates system
80 \param x - x co-ordinate
81 \param y - y co-ordinate
82 \param NewLine - adds new line to buffer
84 void AddCoordsToHPGL( QString& buffer, QString command, GLViewer_CoordSystem* aViewerCS,
85 GLViewer_CoordSystem* aPaperCS, double x, double y, bool NewLine = true )
87 if( aViewerCS && aPaperCS )
88 aViewerCS->transform( *aPaperCS, x, y );
90 QString temp = command + "%1, %2;";
91 buffer += temp.arg( x ).arg( y );
97 Adds coords to text buffer in PostScript format
98 \param buffer - text buffer
99 \param command - command to be added with coords
100 \param aViewerCS - viewer co-ordinates system
101 \param aPaperCS - paper co-ordinates system
102 \param x - x co-ordinate
103 \param y - y co-ordinate
104 \param NewLine - adds new line to buffer
106 void AddCoordsToPS( QString& buffer, QString command, GLViewer_CoordSystem* aViewerCS,
107 GLViewer_CoordSystem* aPaperCS, double x, double y, bool NewLine = true )
109 if( aViewerCS && aPaperCS )
110 aViewerCS->transform( *aPaperCS, x, y );
112 QString temp = "%1 %2 "+command;
113 buffer += temp.arg( x ).arg( y );
119 Adds line aspect description to text buffer in PostScript format
120 \param buffer - text buffer
121 \param anAspect - line aspect
122 \param aViewerCS - viewer co-ordinates system
123 \param aPaperCS - paper co-ordinates system
125 void AddLineAspectToPS( QString& buffer, GLViewer_AspectLine* anAspect,
126 GLViewer_CoordSystem* aViewerCS, GLViewer_CoordSystem* aPaperCS )
130 QColor col1, col2, col3;
131 anAspect->getLineColors( col1, col2, col3 );
133 float aWidth = anAspect->getLineWidth();
134 int aLineType = anAspect->getLineType();
136 QString temp = "%1 %2 %3 setrgbcolor\n";
137 double rr = 1 - double( col1.red() ) / 255.0, //color inverting
138 gg = 1 - double( col1.green() ) / 255.0,
139 bb = 1 - double( col1.blue() ) / 255.0;
141 buffer += temp.arg( rr ).arg( gg ).arg( bb );
143 double x_stretch, y_stretch;
144 aViewerCS->getStretching( *aPaperCS, x_stretch, y_stretch );
145 buffer += temp.arg( x_stretch * aWidth )+" setlinewidth\n";
147 if( aLineType==0 ) //solid
148 buffer += "[] 0 setdash\n";
149 else if( aLineType==1 ) //strip
150 buffer += "[2] 0 setdash\n";
156 Adds line aspect description EMF image
157 \param hDC - descriptor of EMF
158 \param anAspect - line aspect
159 \param aViewerCS - viewer co-ordinates system
160 \param aPaperCS - paper co-ordinates system
162 HPEN AddLineAspectToEMF( HDC hDC, GLViewer_AspectLine* anAspect,
163 GLViewer_CoordSystem* aViewerCS, GLViewer_CoordSystem* aPaperCS )
167 QColor col1, col2, col3;
168 anAspect->getLineColors( col1, col2, col3 );
170 double x_stretch, y_stretch;
171 aViewerCS->getStretching( *aPaperCS, x_stretch, y_stretch );
173 double aWidth = anAspect->getLineWidth()*x_stretch;
174 int aLineType = anAspect->getLineType();
176 return CreatePen( PS_SOLID, aWidth, RGB( 255-col1.red(), 255-col1.green(), 255-col1.blue() ) );
184 Saves to file PostScript set of markers
185 \param hFile - file instance
186 \param aViewerCS - viewer co-ordinates system
187 \param aPSCS - paper co-ordinates system
189 bool GLViewer_MarkerSet::translateToPS( QFile& hFile, GLViewer_CoordSystem* aViewerCS, GLViewer_CoordSystem* aPSCS )
193 QString aBuffer = "newpath\n";
195 AddLineAspectToPS( aBuffer, getAspectLine(), aViewerCS, aPSCS );
197 for( int i=0; i<myNumber; i++ )
201 double x_stretch, y_stretch;
202 aViewerCS->getStretching( *aPSCS, x_stretch, y_stretch );
204 double x0 = myXCoord[i],
209 for( int j=0; j<=noPoints; j++ )
211 x = x0 + r*cos( double(j)*2*PI/double(noPoints) );
212 y = y0 + r*sin( double(j)*2*PI/double(noPoints) );
214 AddCoordsToPS( aBuffer, "moveto", aViewerCS, aPSCS, x, y, true );
216 AddCoordsToPS( aBuffer, "lineto", aViewerCS, aPSCS, x, y, true );
219 aBuffer+="closepath\nstroke\n";
221 hFile.write( aBuffer.toAscii() );
227 Saves to file HPGL set of markers
228 \param hFile - file instance
229 \param aViewerCS - viewer co-ordinates system
230 \param aHPGLCS - paper co-ordinates system
232 bool GLViewer_MarkerSet::translateToHPGL( QFile& hFile, GLViewer_CoordSystem* aViewerCS,
233 GLViewer_CoordSystem* aHPGLCS )
237 for( int i=0; i<myNumber; i++ )
241 double x_stretch, y_stretch;
242 aViewerCS->getStretching( *aHPGLCS, x_stretch, y_stretch );
244 double x0 = myXCoord[i],
249 AddCoordsToHPGL( aBuffer, "PA", aViewerCS, aHPGLCS, x0+r, y0 );
251 for( int j=1; j<=noPoints; j++ )
253 x = x0 + r*cos( double(j)*2*PI/double(noPoints) );
254 y = y0 + r*sin( double(j)*2*PI/double(noPoints) );
255 AddCoordsToHPGL( aBuffer, "PD", aViewerCS, aHPGLCS, x, y );
259 hFile.write( aBuffer.toAscii() );
267 Saves to EMF image set of markers
268 \param dc - EMF image descriptor
269 \param aViewerCS - viewer co-ordinates system
270 \param aEMFCS - paper co-ordinates system
272 bool GLViewer_MarkerSet::translateToEMF( HDC dc, GLViewer_CoordSystem* aViewerCS, GLViewer_CoordSystem* aEMFCS )
275 if( !aViewerCS || !aEMFCS )
278 HPEN pen = AddLineAspectToEMF( dc, getAspectLine(), aViewerCS, aEMFCS );
279 HGDIOBJ old = SelectObject( dc, pen );
281 for( int i=0; i<myNumber; i++ )
283 double x0 = myXCoord[i],
288 for( int j=0; j<=noPoints; j++ )
290 x = x0 + r*cos( double(j)*2*PI/double(noPoints) );
291 y = y0 + r*sin( double(j)*2*PI/double(noPoints) );
292 aViewerCS->transform( *aEMFCS, x, y );
294 MoveToEx( dc, x, y, NULL );
300 SelectObject( dc, old );
308 Computes all necessary information about object for presentation in drawer
310 void GLViewer_MarkerSet::compute()
312 // cout << "GLViewer_MarkerSet::compute" << endl;
313 GLfloat xa = myXCoord[0];
314 GLfloat xb = myXCoord[0];
315 GLfloat ya = myYCoord[0];
316 GLfloat yb = myYCoord[0];
318 for ( int i = 0; i < myNumber; i++ )
320 xa = qMin( xa, myXCoord[i] );
321 xb = qMax( xb, myXCoord[i] );
322 ya = qMin( ya, myYCoord[i] );
323 yb = qMax( yb, myYCoord[i] );
326 myXGap = ( xb - xa ) / 10;
327 myYGap = ( yb - ya ) / 10;
329 myRect->setLeft( xa - myXGap );
330 myRect->setTop( yb + myYGap );
331 myRect->setRight( xb + myXGap );
332 myRect->setBottom( ya - myYGap );
336 Creates corresponding drawer
338 GLViewer_Drawer* GLViewer_MarkerSet::createDrawer()
340 // cout << "GLViewer_MarkerSet::createDrawer" << endl;
341 return myDrawer = new GLViewer_MarkerDrawer();
345 Computes highlight presentation
348 \param tol - tolerance of detecting
349 \param isCircle - true if sensitive area of detection is round
350 \return true if highlight status is changed
352 GLboolean GLViewer_MarkerSet::highlight( GLfloat x, GLfloat y, GLfloat tol, GLboolean isCircle )
356 // cout << "GLViewer_MarkerSet::highlight " << x <<" " << y << " " << tol << endl;
358 GLfloat xdist, ydist, radius;
359 QList<int>::Iterator it;
360 QList<int> curHNumbers;
365 radius = tol - myMarkerSize / 2.;
367 myUHNumbers += myHNumbers;
370 for ( int i = 0; i < myNumber; i++ )
372 xdist = ( myXCoord[i] - x ) * myXScale;
373 ydist = ( myYCoord[i] - y ) * myYScale;
375 // if ( isCircle && ( xdist * xdist + ydist * ydist <= radius * radius ) ||
376 if ( isCircle && ( xdist * xdist + ydist * ydist <= myMarkerSize * myMarkerSize ) ||
377 !isCircle && ( fabs( xdist ) <= radius && fabs( ydist ) <= radius ) )
381 for ( it = myCurSelNumbers.begin(); it != myCurSelNumbers.end(); ++it )
385 curHNumbers.append( i );
389 myHNumbers.append( i );
394 myCurSelNumbers = curHNumbers;
396 myIsHigh = ( GLboolean )count;
397 update = ( GLboolean )( myHNumbers != myPrevHNumbers );
399 myPrevHNumbers = myHNumbers;
401 //cout << "GLViewer_MarkerSet::highlight complete with " << (int)myIsHigh << endl;
408 GLboolean GLViewer_MarkerSet::unhighlight()
410 if( !myHNumbers.isEmpty() )
412 myUHNumbers += myHNumbers;
413 myPrevHNumbers.clear();
415 //??? myCurSelNumbers.clear();
424 /param x, y - co-ordinates of mouse
425 /param tol - tolerance
426 /param rect - rectangle (in case of rectangular selection)
427 /param isFull - if it is true, then object may selected only if it lays whole in selection zone
428 \param isCircle - true if sensitive area of detection is round
429 \param isShift - true if selection exec with append option
431 GLboolean GLViewer_MarkerSet::select( GLfloat x, GLfloat y, GLfloat tol, GLViewer_Rect rect, GLboolean isFull,
432 GLboolean isCircle, GLboolean isShift )
436 // cout << "GLViewer_MarkerSet::select " << x << " " << y << endl;
438 GLfloat xdist, ydist, radius;
439 QList<int>::Iterator it;
440 QList<int>::Iterator it1;
441 QList<int>::Iterator remIt;
442 QList<int>::Iterator curIt;
444 radius = tol - myMarkerSize / 2.;
446 if( radius < myMarkerSize / 2.)
447 radius = myMarkerSize / 2.;
449 count = isShift ? mySelNumbers.count() : 0;
451 myUSelNumbers = mySelNumbers;
455 mySelNumbers.clear();
456 myCurSelNumbers.clear();
459 for ( int i = 0; i < myNumber; i++ )
461 xdist = ( myXCoord[i] - x ) * myXScale;
462 ydist = ( myYCoord[i] - y ) * myYScale;
464 //if ( isCircle && ( xdist * xdist + ydist * ydist <= radius * radius ) ||
465 if ( isCircle && ( xdist * xdist + ydist * ydist <= myMarkerSize * myMarkerSize ) ||
466 !isCircle && ( fabs( xdist ) <= radius && fabs( ydist ) <= radius ) )
471 bool isFound = FALSE;
472 for( it = mySelNumbers.begin(); it != mySelNumbers.end(); ++it )
475 myUSelNumbers.append( *it );
483 mySelNumbers.append( i );
484 myCurSelNumbers.append( i );
485 for ( it1 = myHNumbers.begin(); it1 != myHNumbers.end(); ++it1 )
488 myHNumbers.erase( it1 );
491 for ( it1 = myUHNumbers.begin(); it1 != myUHNumbers.end(); ++it1 )
494 myUHNumbers.erase( it1 );
500 mySelNumbers.erase( remIt );
501 for ( curIt = myCurSelNumbers.begin(); curIt != myCurSelNumbers.end(); ++curIt )
502 if( *curIt == *remIt)
504 myCurSelNumbers.erase( curIt );
507 for ( it1 = myHNumbers.begin(); it1 != myHNumbers.end(); ++it1 )
510 myHNumbers.erase( it1 );
513 for ( it1 = myUHNumbers.begin(); it1 != myUHNumbers.end(); ++it1 )
516 myUHNumbers.erase( it1 );
523 mySelNumbers.append( i );
524 myCurSelNumbers.append( i );
525 for ( it1 = myHNumbers.begin(); it1 != myHNumbers.end(); ++it1 )
528 myHNumbers.erase( it1 );
531 for ( it1 = myUHNumbers.begin(); it1 != myUHNumbers.end(); ++it1 )
534 myUHNumbers.erase( it1 );
541 for( it = mySelNumbers.begin(); it != mySelNumbers.end(); ++it )
542 for( it1 = myUSelNumbers.begin(); it1 != myUSelNumbers.end(); ++it1 )
545 it1 = myUSelNumbers.erase( it1 );
549 myIsSel = (GLboolean)count;
551 // cout << "GLViewer_MarkerSet::select complete with " << (int)myIsSel << endl;
558 GLboolean GLViewer_MarkerSet::unselect()
560 if( !mySelNumbers.isEmpty() )
562 myUSelNumbers = mySelNumbers;
563 mySelNumbers.clear();
564 myCurSelNumbers.clear();
572 \return update object rectangle
573 Does not equal getRect() if object have a persistence to some viewer transformations
575 GLViewer_Rect* GLViewer_MarkerSet::getUpdateRect()
577 GLViewer_Rect* rect = new GLViewer_Rect();
579 rect->setLeft( myRect->left() + myXGap - myMarkerSize / myXScale );
580 rect->setTop( myRect->top() + myYGap + myMarkerSize / myYScale );
581 rect->setRight( myRect->right() - myXGap + myMarkerSize / myXScale );
582 rect->setBottom( myRect->bottom() - myYGap - myMarkerSize / myYScale );
583 //cout << " Additional tolerance " << myMarkerSize / myYScale << endl;
584 //rect->setLeft( myRect->left() - myMarkerSize / myXScale );
585 //rect->setTop( myRect->top() - myMarkerSize / myYScale );
586 //rect->setRight( myRect->right() + myMarkerSize / myXScale );
587 //rect->setBottom( myRect->bottom() + myMarkerSize / myYScale );
593 Sets array of x coords of points
594 \param xCoord - array of co-ordinates
595 \param size - array size
597 void GLViewer_MarkerSet::setXCoord( GLfloat* xCoord, int size )
599 myXCoord = new GLfloat[ size ];
600 for( int i = 0; i < size; i++ )
601 myXCoord[i] = xCoord[i];
605 Sets array of y coords of points
606 \param yCoord - array of co-ordinates
607 \param size - array size
609 void GLViewer_MarkerSet::setYCoord( GLfloat* yCoord, int size )
611 myYCoord = new GLfloat[ size ];
612 for( int i = 0; i < size; i++ )
613 myYCoord[i] = yCoord[i];
617 Sets number of markers
618 \param number - new number of markers
620 void GLViewer_MarkerSet::setNumMarkers( GLint number )
622 if ( myNumber == number )
625 if ( myXCoord && myYCoord )
632 myXCoord = new GLfloat[ myNumber ];
633 myYCoord = new GLfloat[ myNumber ];
638 Export numbers of highlighted/selected lines
640 void GLViewer_MarkerSet::exportNumbers( QList<int>& highlight,
641 QList<int>& unhighlight,
643 QList<int>& unselect )
645 highlight = myHNumbers;
646 unhighlight = myUHNumbers;
647 select = mySelNumbers;
648 unselect = myUSelNumbers;
650 myUHNumbers = myHNumbers;
654 Adds or remove selected number
655 \param index - selected index
657 bool GLViewer_MarkerSet::addOrRemoveSelected( int index )
659 if( index < 0 || index > myNumber )
662 int n = mySelNumbers.indexOf( index );
664 mySelNumbers.append( index );
667 mySelNumbers.removeAt(n);
668 myUSelNumbers.append( index );
674 Adds some selected numbers
675 \param seq - sequence of indices
677 void GLViewer_MarkerSet::addSelected( const TColStd_SequenceOfInteger& seq )
679 for ( int i = 1; i <= seq.Length(); i++ )
680 if( mySelNumbers.indexOf( seq.Value( i ) ) == -1 )
681 mySelNumbers.append( seq.Value( i ) - 1 );
685 Sets some numbers as selected
686 \param seq - sequence of indices
688 void GLViewer_MarkerSet::setSelected( const TColStd_SequenceOfInteger& seq )
690 // for( QList<int>::Iterator it = mySelNumbers.begin(); it != mySelNumbers.end(); ++it )
691 // if( myUSelNumbers.findIndex( *it ) == -1 )
692 // myUSelNumbers.append( *it );
694 myUSelNumbers = mySelNumbers;
695 mySelNumbers.clear();
697 for ( int i = 1; i <= seq.Length(); i++ )
698 mySelNumbers.append( seq.Value( i ) - 1 );
701 /*! Moves object by recomputing
702 \param dx - moving along X coord
703 \param dy - moving along Y coord
704 \param fromGroup - is true if this method called from group
706 void GLViewer_MarkerSet::moveObject( float theX, float theY, bool fromGroup )
708 if( !fromGroup && myGroup)
710 myGroup->dragingObjects( theX, theY );
713 for( int i = 0; i < myNumber; i++ )
715 myXCoord[i] = myXCoord[i] + theX;
716 myYCoord[i] = myYCoord[i] + theY;
722 Codes marker set as byte copy
725 QByteArray GLViewer_MarkerSet::getByteCopy()
728 int anISize = sizeof( GLint );
729 int aFSize = sizeof( GLfloat );
731 QByteArray aObject = GLViewer_Object::getByteCopy();
734 aResult.resize( anISize + 2*aFSize*myNumber + aFSize + aObject.size());
736 char* aPointer = (char*)&myNumber;
737 for( i = 0; i < anISize; i++, aPointer++ )
738 aResult[i] = *aPointer;
740 aPointer = (char*)myXCoord;
741 for( ; i < anISize + aFSize*myNumber; i++, aPointer++ )
742 aResult[i] = *aPointer;
743 aPointer = (char*)myYCoord;
744 for( ; i < anISize + 2*aFSize*myNumber; i++, aPointer++ )
745 aResult[i] = *aPointer;
747 aPointer = (char*)&myMarkerSize;
748 for( ; i < anISize + 2*aFSize*myNumber + aFSize; i++, aPointer++ )
749 aResult[i] = *aPointer;
752 for ( ; i < (int)aResult.size(); i++ )
753 aResult[i] = aObject[i - anISize - 2*aFSize*myNumber - aFSize];
759 Initialize marker set by byte array
760 \param theArray - byte array
762 bool GLViewer_MarkerSet::initializeFromByteCopy( QByteArray theArray )
765 int anISize = sizeof( GLint );
766 int aFSize = sizeof( GLfloat );
768 char* aPointer = (char*)&myNumber;
769 for( i = 0; i < anISize; i++, aPointer++ )
770 *aPointer = theArray[i];
772 int aSize = theArray.size();
773 if( aSize < anISize + 2*aFSize*myNumber + aFSize)
776 myXCoord = new GLfloat[myNumber];
777 myYCoord = new GLfloat[myNumber];
778 aPointer = (char*)myXCoord;
779 for( ; i < anISize + aFSize*myNumber; i++, aPointer++ )
780 *aPointer = theArray[i];
781 aPointer = (char*)myYCoord;
782 for( ; i < anISize + 2*aFSize*myNumber; i++, aPointer++ )
783 *aPointer = theArray[i];
785 aPointer = (char*)&myMarkerSize;
786 for( ; i < anISize + 2*aFSize*myNumber + aFSize; i++, aPointer++ )
787 *aPointer = theArray[i];
789 int aCurIndex = anISize + 2*aFSize*myNumber + aFSize;
791 aObject.resize( aSize - aCurIndex );
792 for( ; i < aSize; i++ )
793 aObject[i - aCurIndex] = theArray[i];
796 if( !GLViewer_Object::initializeFromByteCopy( aObject ) || myType != "GLViewer_MarkerSet" )
801 mySelNumbers.clear();
802 myUSelNumbers.clear();
803 myCurSelNumbers.clear();
804 myPrevHNumbers.clear();
810 \class GLViewer_Polyline
819 \param number - number of segments
820 \param size - size of polyline
821 \param toolTip - tool tip of polyline
823 GLViewer_Polyline::GLViewer_Polyline( int number, float size, const QString& toolTip ):
829 myHighFlag = GL_TRUE;
833 mySelNumbers.clear();
834 myUSelNumbers.clear();
835 myCurSelNumbers.clear();
836 myPrevHNumbers.clear();
840 myType = "GLViewer_Polyline";
841 myToolTipText = toolTip;
845 Destructor, destroys internal arrays of co-ordinates
847 GLViewer_Polyline::~GLViewer_Polyline()
856 Saves polyline to file PostScript
857 \param hFile - file instance
858 \param aViewerCS - viewer co-ordinates system
859 \param aPSCS - paper co-ordinates system
861 bool GLViewer_Polyline::translateToPS( QFile& hFile, GLViewer_CoordSystem* aViewerCS, GLViewer_CoordSystem* aPSCS )
863 QString aBuffer = "newpath\n";
865 AddLineAspectToPS( aBuffer, getAspectLine(), aViewerCS, aPSCS );
867 for( int i=0; i<myNumber; i++ )
869 AddCoordsToPS( aBuffer, "moveto", aViewerCS, aPSCS, myXCoord[i], myYCoord[i] );
871 AddCoordsToPS( aBuffer, "lineto", aViewerCS, aPSCS, myXCoord[i], myYCoord[i] );
874 AddCoordsToPS( aBuffer, "lineto", aViewerCS, aPSCS, myXCoord[0], myYCoord[0] );
876 aBuffer+="closepath\nstroke\n";
878 hFile.write( aBuffer.toAscii() );
884 Saves polyline to file HPGL
885 \param hFile - file instance
886 \param aViewerCS - viewer co-ordinates system
887 \param aHPGLCS - paper co-ordinates system
889 bool GLViewer_Polyline::translateToHPGL( QFile& hFile, GLViewer_CoordSystem* aViewerCS, GLViewer_CoordSystem* aHPGLCS )
891 QString aBuffer = "";
892 for( int i=0; i<myNumber; i++ )
894 AddCoordsToHPGL( aBuffer, "PA", aViewerCS, aHPGLCS, myXCoord[i], myYCoord[i] );
900 AddCoordsToHPGL( aBuffer, "PA", aViewerCS, aHPGLCS, myXCoord[0], myYCoord[0] );
904 hFile.write( aBuffer.toAscii() );
911 Saves polyline to EMF image
912 \param dc - EMF image descriptor
913 \param aViewerCS - viewer co-ordinates system
914 \param aEMFCS - paper co-ordinates system
916 bool GLViewer_Polyline::translateToEMF( HDC dc, GLViewer_CoordSystem* aViewerCS, GLViewer_CoordSystem* aEMFCS )
918 if( !aViewerCS || !aEMFCS )
921 HPEN pen = AddLineAspectToEMF( dc, getAspectLine(), aViewerCS, aEMFCS );
922 HGDIOBJ old = SelectObject( dc, pen );
925 for( int i=0; i<myNumber; i++ )
929 aViewerCS->transform( *aEMFCS, x, y );
931 MoveToEx( dc, x, y, NULL );
940 aViewerCS->transform( *aEMFCS, x, y );
944 SelectObject( dc, old );
953 Computes all necessary information about object for presentation in drawer
955 void GLViewer_Polyline::compute()
957 // cout << "GLViewer_MarkerSet::compute" << endl;
958 GLfloat xa = myXCoord[0];
959 GLfloat xb = myXCoord[0];
960 GLfloat ya = myYCoord[0];
961 GLfloat yb = myYCoord[0];
963 for ( int i = 0; i < myNumber; i++ )
965 xa = qMin( xa, myXCoord[i] );
966 xb = qMax( xb, myXCoord[i] );
967 ya = qMin( ya, myYCoord[i] );
968 yb = qMax( yb, myYCoord[i] );
971 GLfloat xGap = ( xb - xa ) / 10;
972 GLfloat yGap = ( yb - ya ) / 10;
974 myRect->setLeft( xa - xGap );
975 myRect->setTop( yb + yGap );
976 myRect->setRight( xb + xGap );
977 myRect->setBottom( ya - yGap );
981 \return update object rectangle
982 Does not equal getRect() if object have a persistence to some viewer transformations
984 GLViewer_Rect* GLViewer_Polyline::getUpdateRect()
986 GLViewer_Rect* rect = new GLViewer_Rect();
988 rect->setLeft( myRect->left() - myXGap );
989 rect->setTop( myRect->top() + myYGap );
990 rect->setRight( myRect->right() + myXGap );
991 rect->setBottom( myRect->bottom() - myYGap );
997 Creates corresponding drawer
999 GLViewer_Drawer* GLViewer_Polyline::createDrawer()
1001 // cout << "GLViewer_MarkerSet::createDrawer" << endl;
1002 return myDrawer = new GLViewer_PolylineDrawer();
1006 Computes highlight presentation
1009 \param tol - tolerance of detecting
1010 \param isCircle - true if sensitive area of detection is round
1011 \return true if highlight status is changed
1013 GLboolean GLViewer_Polyline::highlight( GLfloat x, GLfloat y, GLfloat tol, GLboolean isCircle )
1017 GLfloat xa, xb, ya, yb, l;
1018 GLfloat rsin, rcos, r, ra, rb;
1020 GLboolean highlighted = myIsHigh;
1022 myIsHigh = GL_FALSE;
1028 for( int i = 0; i < myNumber-1+c; i++ )
1032 if( i != myNumber-1 )
1043 l = sqrt( (xb-xa)*(xb-xa) + (yb-ya)*(yb-ya) );
1046 r = ( (x-xa)*(y-yb) - (x-xb)*(y-ya) ) / ( rsin*(ya-yb) + rcos*(xa-xb) );
1047 ra = sqrt( (x-xa)*(x-xa) + (y-ya)*(y-ya) );
1048 rb = sqrt( (x-xb)*(x-xb) + (y-yb)*(y-yb) );
1049 if( fabs( r ) * myXScale <= DISTANTION && ra <= l + DISTANTION && rb <= l + DISTANTION )
1056 if( !myHighFlag && myIsHigh )
1057 myIsHigh = GL_FALSE;
1059 myHighFlag = GL_TRUE;
1061 update = ( GLboolean )( myIsHigh != highlighted );
1063 // cout << "GLViewer_Polyline::highlight complete with " << (int)myIsHigh << endl;
1070 GLboolean GLViewer_Polyline::unhighlight()
1072 // if( !myHNumbers.isEmpty() )
1074 // myUHNumbers = myHNumbers;
1075 // myHNumbers.clear();
1081 myIsHigh = GL_FALSE;
1090 /param x, y - co-ordinates of mouse
1091 /param tol - tolerance
1092 /param rect - rectangle (in case of rectangular selection)
1093 /param isFull - if it is true, then object may selected only if it lays whole in selection zone
1094 \param isCircle - true if sensitive area of detection is round
1095 \param isShift - true if selection exec with append option
1097 GLboolean GLViewer_Polyline::select( GLfloat x, GLfloat y, GLfloat tol, GLViewer_Rect rect, GLboolean isFull,
1098 GLboolean isCircle, GLboolean isShift )
1102 GLfloat xa, xb, ya, yb, l;
1103 GLfloat rsin, rcos, r, ra, rb;
1105 GLboolean selected = myIsSel;
1113 for( int i = 0; i < myNumber-1+c; i++ )
1117 if( i != myNumber-1 )
1128 l = sqrt( (xb-xa)*(xb-xa) + (yb-ya)*(yb-ya) );
1131 r = ( (x-xa)*(y-yb) - (x-xb)*(y-ya) ) / ( rsin*(ya-yb) + rcos*(xa-xb) );
1132 ra = sqrt( (x-xa)*(x-xa) + (y-ya)*(y-ya) );
1133 rb = sqrt( (x-xb)*(x-xb) + (y-yb)*(y-yb) );
1134 if( fabs( r ) * myXScale <= DISTANTION && ra <= l + DISTANTION && rb <= l + DISTANTION )
1143 myHighFlag = GL_FALSE;
1144 myIsHigh = GL_FALSE;
1147 myHighFlag = GL_TRUE;
1149 update = ( GLboolean )( myIsSel != selected );
1151 // cout << "GLViewer_Polyline::select complete with " << (int)myIsSel << endl;
1153 // return update; !!!!!!!!!!!!!!!!!!!!!!!!!!! no here
1160 GLboolean GLViewer_Polyline::unselect()
1162 // if( !mySelNumbers.isEmpty() )
1164 // myUSelNumbers = mySelNumbers;
1165 // mySelNumbers.clear();
1166 // myCurSelNumbers.clear();
1180 Sets array of abscisses for points of polyline
1181 \param xCoord - array of of abscisses
1182 \param size - size of array
1184 void GLViewer_Polyline::setXCoord( GLfloat* xCoord, int size )
1186 myXCoord = new GLfloat[ size ];
1187 for( int i = 0; i < size; i++ )
1188 myXCoord[i] = xCoord[i];
1192 Sets array of ordinates for points of polyline
1193 \param xCoord - array of of ordinates
1194 \param size - size of array
1196 void GLViewer_Polyline::setYCoord( GLfloat* yCoord, int size )
1198 myYCoord = new GLfloat[ size ];
1199 for( int i = 0; i < size; i++ )
1200 myYCoord[i] = yCoord[i];
1204 Sets number of points
1205 \param number - new number of points
1207 void GLViewer_Polyline::setNumber( GLint number )
1209 if ( myNumber == number )
1212 if ( myXCoord && myYCoord )
1219 myXCoord = new GLfloat[ myNumber ];
1220 myYCoord = new GLfloat[ myNumber ];
1224 Export numbers of highlighted/selected lines
1226 void GLViewer_Polyline::exportNumbers( QList<int>& highlight,
1227 QList<int>& unhighlight,
1229 QList<int>& unselect )
1231 highlight = myHNumbers;
1232 unhighlight = myUHNumbers;
1233 select = mySelNumbers;
1234 unselect = myUSelNumbers;
1238 Moves object by recomputing
1239 \param dx - moving along X coord
1240 \param dy - moving along Y coord
1241 \param fromGroup - is true if this method called from group
1243 void GLViewer_Polyline::moveObject( float theX, float theY, bool fromGroup )
1245 if( !fromGroup && myGroup)
1247 myGroup->dragingObjects( theX, theY );
1250 for( int i = 0; i < myNumber; i++ )
1252 myXCoord[i] = myXCoord[i] + theX;
1253 myYCoord[i] = myYCoord[i] + theY;
1259 Codes polyline as byte copy
1262 QByteArray GLViewer_Polyline::getByteCopy()
1265 int anISize = sizeof( GLint );
1266 int aFSize = sizeof( GLfloat );
1267 int aBSize = sizeof( GLboolean );
1269 QByteArray aObject = GLViewer_Object::getByteCopy();
1272 aResult.resize( aFSize*myNumber*2 + anISize + 2*aBSize + aObject.size());
1274 char* aPointer = (char*)&myNumber;
1275 for( i = 0; i < anISize; i++, aPointer++ )
1276 aResult[i] = *aPointer;
1278 aPointer = (char*)myXCoord;
1279 for( ; i < anISize + aFSize*myNumber; i++, aPointer++ )
1280 aResult[i] = *aPointer;
1281 aPointer = (char*)myYCoord;
1282 for( ; i < anISize + 2*aFSize*myNumber; i++, aPointer++ )
1283 aResult[i] = *aPointer;
1285 aPointer = (char*)&myIsClosed;
1286 for( ; i < anISize + 2*aFSize*myNumber + aBSize; i++, aPointer++ )
1287 aResult[i] = *aPointer;
1288 aPointer = (char*)&myHighSelAll;
1289 for( ; i < anISize + 2*aFSize*myNumber + 2*aBSize; i++, aPointer++ )
1290 aResult[i] = *aPointer;
1292 for ( ; i < (int)aResult.size(); i++ )
1293 aResult[i] = aObject[i - anISize - 2*aFSize*myNumber - 2*aBSize];
1300 Initialize polyline by byte array
1301 \param theArray - byte array
1303 bool GLViewer_Polyline::initializeFromByteCopy( QByteArray theArray )
1306 int anISize = sizeof( GLint );
1307 int aFSize = sizeof( GLfloat );
1308 int aBSize = sizeof( GLboolean );
1310 char* aPointer = (char*)&myNumber;
1311 for( i = 0; i < anISize; i++, aPointer++ )
1312 *aPointer = theArray[i];
1314 int aSize = theArray.size();
1315 if( aSize < aFSize*myNumber*2 + anISize + 2*aBSize )
1318 myXCoord = new GLfloat[myNumber];
1319 myYCoord = new GLfloat[myNumber];
1320 aPointer = (char*)myXCoord;
1321 for( ; i < anISize + aFSize*myNumber; i++, aPointer++ )
1322 *aPointer = theArray[i];
1323 aPointer = (char*)myYCoord;
1324 for( ; i < anISize + 2*aFSize*myNumber; i++, aPointer++ )
1325 *aPointer = theArray[i];
1327 aPointer = (char*)&myIsClosed;
1328 for( ; i < anISize + 2*aFSize*myNumber + aBSize; i++, aPointer++ )
1329 *aPointer = theArray[i];
1330 aPointer = (char*)&myHighSelAll;
1331 for( ; i < anISize + 2*aFSize*myNumber + 2*aBSize; i++, aPointer++ )
1332 *aPointer = theArray[i];
1334 int aCurIndex = anISize + 2*aFSize*myNumber + 2*aBSize;
1336 aObject.resize( aSize - aCurIndex );
1337 for( ; i < aSize; i++ )
1338 aObject[i - aCurIndex] = theArray[i];
1340 if( !GLViewer_Object::initializeFromByteCopy( aObject ) || myType != "GLViewer_Polyline" )
1344 myUHNumbers.clear();
1345 mySelNumbers.clear();
1346 myUSelNumbers.clear();
1347 myCurSelNumbers.clear();
1348 myPrevHNumbers.clear();
1357 \param theStr - text string
1358 \param xPos - x position
1359 \param yPos - y position
1360 \param color - color of text
1361 \param toolTip - tooltip of text object
1363 GLViewer_TextObject::GLViewer_TextObject( const QString& theStr, float xPos, float yPos,
1364 const QColor& color, const QString& toolTip )
1367 myGLText = new GLViewer_Text( theStr, xPos, yPos, color );
1371 myHighFlag = GL_TRUE;
1373 myToolTipText = toolTip;
1379 GLViewer_TextObject::~GLViewer_TextObject()
1386 Saves text object to file PostScript
1387 \param hFile - file instance
1388 \param aViewerCS - viewer co-ordinates system
1389 \param aPSCS - paper co-ordinates system
1391 bool GLViewer_TextObject::translateToPS( QFile& hFile, GLViewer_CoordSystem* aViewerCS, GLViewer_CoordSystem* aPSCS )
1393 QString aText = myGLText->getText();
1395 myGLText->getPosition( xPos, yPos );
1397 QString aBuffer = "/Times-Roman findfont\n";
1398 aBuffer += "12 scalefont setfont\n";
1400 AddCoordsToPS( aBuffer, "moveto", aViewerCS, aPSCS, double(xPos), double(yPos) );
1401 aBuffer += "(" + aText + ") show\n";
1403 hFile.write( aBuffer.toAscii() );
1409 Saves text object to file HPGL
1410 \param hFile - file instance
1411 \param aViewerCS - viewer co-ordinates system
1412 \param aHPGLCS - paper co-ordinates system
1414 bool GLViewer_TextObject::translateToHPGL( QFile& hFile, GLViewer_CoordSystem* aViewerCS, GLViewer_CoordSystem* aHPGLCS )
1416 QString aText = myGLText->getText();
1418 myGLText->getPosition( xPos, yPos );
1420 QString aBuffer = "";
1421 AddCoordsToHPGL( aBuffer, "PA", aViewerCS, aHPGLCS, double(xPos), double(yPos) );
1423 aBuffer = "LB" + aText + "#;";
1425 hFile.write( aBuffer.toAscii() );
1432 Saves text object to EMF image
1433 \param dc - EMF image descriptor
1434 \param aViewerCS - viewer co-ordinates system
1435 \param aEMFCS - paper co-ordinates system
1437 bool GLViewer_TextObject::translateToEMF( HDC dc, GLViewer_CoordSystem* aViewerCS, GLViewer_CoordSystem* aEMFCS )
1439 QString aText = myGLText->getText();
1441 myGLText->getPosition( xPos, yPos );
1443 double x = double( xPos ),
1446 aViewerCS->transform( *aEMFCS, x, y );
1447 const char* str = aText.toAscii();
1449 int nHeight = 35*14; // height of font
1450 int nWidth = 35*12; // average character width
1451 int nEscapement = 0; // angle of escapement
1452 int nOrientation = 0; // base-line orientation angle
1453 int fnWeight = FW_NORMAL; // font weight
1454 DWORD fdwItalic = FALSE; // italic attribute option
1455 DWORD fdwUnderline = FALSE; // underline attribute option
1456 DWORD fdwStrikeOut = FALSE; // strikeout attribute option
1457 DWORD fdwCharSet = ANSI_CHARSET; // character set identifier
1458 DWORD fdwOutputPrecision = OUT_DEFAULT_PRECIS; // output precision
1459 DWORD fdwClipPrecision = CLIP_DEFAULT_PRECIS; // clipping precision
1460 DWORD fdwQuality = PROOF_QUALITY; // output quality
1461 DWORD fdwPitchAndFamily = FIXED_PITCH | FF_DONTCARE; // pitch and family
1462 LPCTSTR lpszFace = NULL; // typeface name
1465 HFONT aFont = CreateFont( nHeight, nWidth, nEscapement, nOrientation, fnWeight, fdwItalic,
1466 fdwUnderline, fdwStrikeOut, fdwCharSet, fdwOutputPrecision,
1467 fdwClipPrecision, fdwQuality, fdwPitchAndFamily, lpszFace );
1468 LOGBRUSH aBrushData;
1469 aBrushData.lbStyle = BS_HOLLOW;
1471 HBRUSH aBrush = CreateBrushIndirect( &aBrushData );
1473 HGDIOBJ old1 = SelectObject( dc, aFont );
1474 HGDIOBJ old2 = SelectObject( dc, aBrush );
1476 TextOut( dc, x, y, str, aText.length() );
1478 SelectObject ( dc, old1 );
1479 SelectObject ( dc, old2 );
1481 DeleteObject( aFont );
1488 Creates corresponding drawer
1490 GLViewer_Drawer* GLViewer_TextObject::createDrawer()
1492 myDrawer = new GLViewer_TextDrawer();
1498 Computes all necessary information about object for presentation in drawer
1500 void GLViewer_TextObject::compute()
1503 QString aStr = myGLText->getText();
1504 myGLText->getPosition( xPos, yPos );
1506 myWidth = myGLText->getWidth();
1507 myHeight = myGLText->getHeight();
1508 myRect->setLeft( xPos );
1509 myRect->setTop( yPos + myHeight );
1510 myRect->setRight( xPos + myWidth );
1511 myRect->setBottom( yPos );
1515 Installing already exist drawer with same type
1516 \param theDrawer - new drawer
1518 void GLViewer_TextObject::setDrawer( GLViewer_Drawer* theDrawer )
1520 myDrawer = theDrawer;
1525 \return update object rectangle
1526 Does not equal getRect() if object have a persistence to some viewer transformations
1528 GLViewer_Rect* GLViewer_TextObject::getUpdateRect()
1530 GLViewer_Rect* rect = new GLViewer_Rect();
1533 QString aStr = myGLText->getText();
1534 myGLText->getPosition( xPos, yPos );
1536 rect->setLeft( myRect->left() + myXGap - myWidth / myXScale );
1537 rect->setTop( myRect->top() + myYGap + myHeight / myYScale );
1538 rect->setRight( myRect->right() - myXGap + myWidth / myXScale );
1539 rect->setBottom( myRect->bottom() - myYGap - myHeight / myYScale );
1545 Computes highlight presentation
1548 \param tol - tolerance of detecting
1549 \param isCircle - true if sensitive area of detection is round
1550 \return true if highlight status is changed
1552 GLboolean GLViewer_TextObject::highlight( GLfloat theX, GLfloat theY, GLfloat theTol, GLboolean isCircle )
1558 myGLText->getPosition( xPos, yPos );
1561 aRect.setLeft( (int)xPos );
1562 aRect.setRight( (int)(xPos + myWidth / myXScale) );
1563 aRect.setTop( (int)yPos );// - myHeight / myYScale );
1564 aRect.setBottom( (int)(yPos + myHeight / myYScale) );
1566 //cout << "theX: " << theX << " theY: " << theY << endl;
1567 //cout << "aRect.left(): " << aRect.left() << " aRect.right(): " << aRect.right() << endl;
1568 //cout << "aRect.top(): " << aRect.top() << " aRect.bottom(): " << aRect.bottom() << endl;
1570 QRegion obj( aRect );
1571 QRegion intersection;
1574 region.setLeft( (int)(theX - theTol) );
1575 region.setRight( (int)(theX + theTol) );
1576 region.setTop( (int)(theY - theTol) );
1577 region.setBottom( (int)(theY + theTol) );
1579 QRegion circle( (int)(theX - theTol), (int)(theY - theTol),
1580 (int)(2 * theTol), (int)(2 * theTol), QRegion::Ellipse );
1582 intersection = obj.intersect( circle );
1584 intersection = obj.intersect( region );
1586 if( intersection.isEmpty() )
1591 if( !myHighFlag && myIsHigh )
1592 myIsHigh = GL_FALSE;
1594 myHighFlag = GL_TRUE;
1602 GLboolean GLViewer_TextObject::unhighlight()
1606 myIsHigh = GL_FALSE;
1615 /param x, y - co-ordinates of mouse
1616 /param tol - tolerance
1617 /param rect - rectangle (in case of rectangular selection)
1618 /param isFull - if it is true, then object may selected only if it lays whole in selection zone
1619 \param isCircle - true if sensitive area of detection is round
1620 \param isShift - true if selection exec with append option
1622 GLboolean GLViewer_TextObject::select( GLfloat theX, GLfloat theY, GLfloat theTol, GLViewer_Rect rect,
1623 GLboolean isFull, GLboolean isCircle, GLboolean isShift )
1628 QRegion obj( myRect->toQRect() );
1629 QRegion intersection;
1632 region.setLeft( (int)(theX - theTol) );
1633 region.setRight( (int)(theX + theTol) );
1634 region.setTop( (int)(theY - theTol) );
1635 region.setBottom( (int)(theY + theTol) );
1637 QRegion circle( (int)(theX - theTol), (int)(theY - theTol),
1638 (int)(2 * theTol), (int)(2 * theTol), QRegion::Ellipse );
1640 intersection = obj.intersect( circle );
1642 intersection = obj.intersect( region );
1644 if( intersection.isEmpty() )
1651 myHighFlag = GL_FALSE;
1652 myIsHigh = GL_FALSE;
1655 myHighFlag = GL_TRUE;
1661 Unselects text object
1663 GLboolean GLViewer_TextObject::unselect()
1675 Moves object by recomputing
1676 \param dx - moving along X coord
1677 \param dy - moving along Y coord
1678 \param fromGroup - is true if this method called from group
1680 void GLViewer_TextObject::moveObject( float theX, float theY, bool fromGroup )
1682 if( !fromGroup && myGroup)
1684 myGroup->dragingObjects( theX, theY );
1688 myGLText->getPosition( aX, anY );
1691 myGLText->setPosition( aX, anY );
1696 Codes text object as byte copy
1699 QByteArray GLViewer_TextObject::getByteCopy()
1701 QByteArray aObject = GLViewer_Object::getByteCopy();
1707 Initialize text object by byte array
1708 \param theArray - byte array
1710 bool GLViewer_TextObject::initializeFromByteCopy( QByteArray theArray )
1712 if( !GLViewer_Object::initializeFromByteCopy( theArray ) || myType != "GLViewer_TextObject" )