From: admin Date: Tue, 8 Nov 2005 09:00:26 +0000 (+0000) Subject: This commit was generated by cvs2git to create branch 'BR-D5-38-2003'. X-Git-Tag: TG-D5-38-2003_D2005-29-12~31 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=59083520db4c768b19c77db7c2e9177fa25dd510;p=modules%2Fgui.git This commit was generated by cvs2git to create branch 'BR-D5-38-2003'. Cherrypick from master 2005-11-08 09:00:25 UTC asl 'Removing dependencies on CORBA': src/GLViewer/GLViewer.h src/GLViewer/GLViewer_AspectLine.cxx src/GLViewer/GLViewer_AspectLine.h src/GLViewer/GLViewer_BaseDrawers.cxx src/GLViewer/GLViewer_BaseDrawers.h src/GLViewer/GLViewer_BaseObjects.cxx src/GLViewer/GLViewer_BaseObjects.h src/GLViewer/GLViewer_Compass.cxx src/GLViewer/GLViewer_Compass.h src/GLViewer/GLViewer_Context.h src/GLViewer/GLViewer_CoordSystem.cxx src/GLViewer/GLViewer_CoordSystem.h src/GLViewer/GLViewer_Defs.h src/GLViewer/GLViewer_Geom.cxx src/GLViewer/GLViewer_Grid.cxx src/GLViewer/GLViewer_Grid.h src/GLViewer/GLViewer_Group.cxx src/GLViewer/GLViewer_Group.h src/GLViewer/GLViewer_MimeSource.cxx src/GLViewer/GLViewer_MimeSource.h src/GLViewer/GLViewer_Object.cxx src/GLViewer/GLViewer_Object.h src/GLViewer/GLViewer_Selector.cxx src/GLViewer/GLViewer_Selector.h src/GLViewer/GLViewer_Selector2d.cxx src/GLViewer/GLViewer_Selector2d.h src/GLViewer/GLViewer_Text.cxx src/GLViewer/GLViewer_Text.h src/GLViewer/GLViewer_ToolTip.cxx src/GLViewer/GLViewer_ToolTip.h src/GLViewer/GLViewer_Tools.cxx src/GLViewer/GLViewer_Tools.h src/GLViewer/GLViewer_ViewFrame.cxx src/GLViewer/GLViewer_ViewFrame.h src/GLViewer/GLViewer_ViewManager.cxx src/GLViewer/GLViewer_ViewManager.h src/GLViewer/GLViewer_ViewPort.cxx src/GLViewer/GLViewer_ViewPort.h src/GLViewer/GLViewer_ViewPort2d.cxx src/GLViewer/GLViewer_ViewPort2d.h src/GLViewer/GLViewer_Viewer.cxx src/GLViewer/GLViewer_Viewer.h src/GLViewer/GLViewer_Viewer2d.h src/GLViewer/GLViewer_Widget.cxx src/GLViewer/GLViewer_Widget.h src/LightApp/LightApp_AboutDlg.cxx src/LightApp/LightApp_AboutDlg.h src/LightApp/LightApp_DataModel.cxx src/LightApp/LightApp_DataModel.h src/LightApp/LightApp_ModuleDlg.h src/LightApp/LightApp_NameDlg.h src/LightApp/LightApp_OBSelector.cxx src/LightApp/LightApp_OBSelector.h src/LightApp/LightApp_Operation.cxx src/LightApp/LightApp_Operation.h src/LightApp/LightApp_UpdateFlags.h src/LightApp/LightApp_VTKSelector.cxx src/LightApp/LightApp_VTKSelector.h src/LightApp/resources/LightApp.ini src/LightApp/resources/LightApp_images.po src/Plot2d/Makefile.in src/Prs/Makefile.in src/PyInterp/Makefile.in src/SOCC/Makefile.in src/SPlot2d/Makefile.in src/SalomeApp/Makefile.in src/SalomeApp/SalomeApp_DataModel.cxx src/SalomeApp/SalomeApp_DataModel.h src/SalomeApp/SalomeApp_PyInterp.h src/SalomeApp/resources/SalomeApp.ini src/SalomeApp/resources/SalomeApp_images.po src/VTKViewer/VTKViewer_ConvexTool.cxx src/VTKViewer/VTKViewer_InteractorStyle.cxx src/VTKViewer/VTKViewer_ShrinkFilter.cxx --- diff --git a/src/GLViewer/GLViewer.h b/src/GLViewer/GLViewer.h new file mode 100644 index 000000000..2f4ed3dcc --- /dev/null +++ b/src/GLViewer/GLViewer.h @@ -0,0 +1,37 @@ +// Copyright (C) 2005 OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// Author : OPEN CASCADE +// + +// File: GLViewer.h +// Created: November, 2004 + +//! Macro for exports +#ifdef WNT + +#ifdef GLVIEWER_EXPORTS +#define GLVIEWER_API __declspec(dllexport) +#else +#define GLVIEWER_API __declspec(dllimport) +#endif + +#else +#define GLVIEWER_API +#endif // WNT + diff --git a/src/GLViewer/GLViewer_AspectLine.cxx b/src/GLViewer/GLViewer_AspectLine.cxx new file mode 100644 index 000000000..4df6041b3 --- /dev/null +++ b/src/GLViewer/GLViewer_AspectLine.cxx @@ -0,0 +1,237 @@ +// Copyright (C) 2005 OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// Author : OPEN CASCADE +// + +// File: GLViewer_AspectLine.cxx +// Created: 26/05/2005 3:17:00 PM + +//================================================================ +// Class : GLViewer_AspectLine +// Description : Substitution of Prs2d_AspectLine for OpenGL +//================================================================ +#include "GLViewer_AspectLine.h" + +//======================================================================= +// Function: GLViewer_AspectLine +// Purpose : +//======================================================================= +GLViewer_AspectLine::GLViewer_AspectLine() +{ + myNColor = QColor( 255, 255, 255 ); + myHColor = QColor( 0, 255, 255 ); + mySColor = QColor( 255, 0, 0 ); + + myLineWidth = 1.0; + myLineType = 0; +} + +//======================================================================= +// Function: GLViewer_AspectLine +// Purpose : +//======================================================================= +GLViewer_AspectLine::GLViewer_AspectLine( int type, float width ) +{ + myNColor = QColor( 255, 255, 255 ); + myHColor = QColor( 0, 255, 255 ); + mySColor = QColor( 255, 0, 0 ); + + myLineWidth = width; + if( type == 1 || type == 0 ) + myLineType = type; + else + myLineType = 0; +} + +//======================================================================= +// Function: ~GLViewer_AspectLine +// Purpose : +//======================================================================= +GLViewer_AspectLine::~GLViewer_AspectLine() +{ +} + +//======================================================================= +// Function: setLineColors +// Purpose : +//======================================================================= +void GLViewer_AspectLine::setLineColors( QColor nc, QColor hc, QColor sc ) +{ + myNColor = nc; + myHColor = hc; + mySColor = sc; +} + +//======================================================================= +// Function: setLineType +// Purpose : +//======================================================================= +int GLViewer_AspectLine::setLineType( const int type ) +{ + if( type == 1 || type == 0 ) + { + myLineType = type; + return 0; + } + return 1; +} + +//======================================================================= +// Function: setLineWidth +// Purpose : +//======================================================================= +int GLViewer_AspectLine::setLineWidth( const float width ) +{ + if( width > 0 ) + { + myLineWidth = width; + return 0; + } + return 1; +} + +//======================================================================= +// Function: getLineColors +// Purpose : +//======================================================================= +void GLViewer_AspectLine::getLineColors( QColor& nc, QColor& hc, QColor& sc ) const +{ + nc = myNColor; + hc = myHColor; + sc = mySColor; +} + +//======================================================================= +// Function: getByteCopy +// Purpose : +//======================================================================= +QByteArray GLViewer_AspectLine::getByteCopy() const +{ + int anISize = sizeof( int ); + int aFSize = sizeof( float ); + int aNR = myNColor.red(), aNG = myNColor.green(), aNB = myNColor.blue(); + int aHR = myHColor.red(), aHG = myHColor.green(), aHB = myHColor.blue(); + int aSR = mySColor.red(), aSG = mySColor.green(), aSB = mySColor.blue(); + + QByteArray aResult( anISize * 10 + aFSize ); + + int i = 0; + + char* aPointer = (char*)&aNR; + for( i = 0; i < anISize; i++, aPointer++ ) + aResult[i] = *aPointer; + aPointer = (char*)&aNG; + for( ; i < 2*anISize; i++, aPointer++ ) + aResult[i] = *aPointer; + aPointer = (char*)&aNB; + for( ; i < 3*anISize; i++, aPointer++ ) + aResult[i] = *aPointer; + + aPointer = (char*)&aHR; + for( ; i < 4*anISize; i++, aPointer++ ) + aResult[i] = *aPointer; + aPointer = (char*)&aHG; + for( ; i < 5*anISize; i++, aPointer++ ) + aResult[i] = *aPointer; + aPointer = (char*)&aHB; + for( ; i < 6*anISize; i++, aPointer++ ) + aResult[i] = *aPointer; + + aPointer = (char*)&aSR; + for( ; i < 7*anISize; i++, aPointer++ ) + aResult[i] = *aPointer; + aPointer = (char*)&aSG; + for( ; i < 8*anISize; i++, aPointer++ ) + aResult[i] = *aPointer; + aPointer = (char*)&aSB; + for( ; i < 9*anISize; i++, aPointer++ ) + aResult[i] = *aPointer; + + aPointer = (char*)&myLineWidth; + for( ; i < 9*anISize + aFSize; i++, aPointer++ ) + aResult[i] = *aPointer; + + aPointer = (char*)&myLineType; + for( ; i < 10*anISize + aFSize; i++, aPointer++ ) + aResult[i] = *aPointer; + + return aResult; +} + +//======================================================================= +// Function: fromByteCopy +// Purpose : +//======================================================================= +GLViewer_AspectLine* GLViewer_AspectLine::fromByteCopy( QByteArray theBytes ) +{ + + int anISize = sizeof( int ); + int aFSize = sizeof( float ); + int aNR = 0, aNG = 0, aNB = 0; + int aHR = 0, aHG = 0, aHB = 0; + int aSR = 0, aSG = 0, aSB = 0; + int aLineType = 0; + float aLineWidth = 0; + + int i = 0; + + char* aPointer = (char*)&aNR; + for( i = 0; i < anISize; i++, aPointer++ ) + *aPointer = theBytes[i]; + aPointer = (char*)&aNG; + for( ; i < 2*anISize; i++, aPointer++ ) + *aPointer = theBytes[i]; + aPointer = (char*)&aNB; + for( ; i < 3*anISize; i++, aPointer++ ) + *aPointer = theBytes[i]; + + aPointer = (char*)&aHR; + for( ; i < 4*anISize; i++, aPointer++ ) + *aPointer = theBytes[i]; + aPointer = (char*)&aHG; + for( ; i < 5*anISize; i++, aPointer++ ) + *aPointer = theBytes[i]; + aPointer = (char*)&aHB; + for( ; i < 6*anISize; i++, aPointer++ ) + *aPointer = theBytes[i]; + + aPointer = (char*)&aSR; + for( ; i < 7*anISize; i++, aPointer++ ) + *aPointer = theBytes[i]; + aPointer = (char*)&aSG; + for( ; i < 8*anISize; i++, aPointer++ ) + *aPointer = theBytes[i]; + aPointer = (char*)&aSB; + for( ; i < 9*anISize; i++, aPointer++ ) + *aPointer = theBytes[i]; + + aPointer = (char*)&aLineWidth; + for( ; i < 9*anISize + aFSize; i++, aPointer++ ) + *aPointer = theBytes[i]; + + aPointer = (char*)&aLineType; + for( ; i < 10*anISize + aFSize; i++, aPointer++ ) + *aPointer = theBytes[i]; + + GLViewer_AspectLine* anAspect = new GLViewer_AspectLine( aLineType, aLineWidth ); + anAspect->setLineColors( QColor( aNR, aNG, aNB ), + QColor( aHR, aHG, aHB ), + QColor( aSR, aSG, aSB ) ); + return anAspect; +} diff --git a/src/GLViewer/GLViewer_AspectLine.h b/src/GLViewer/GLViewer_AspectLine.h new file mode 100644 index 000000000..800b166bb --- /dev/null +++ b/src/GLViewer/GLViewer_AspectLine.h @@ -0,0 +1,120 @@ +// Copyright (C) 2005 OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// Author : OPEN CASCADE +// + +// File: GLViewer_AspectLine.h +// Created: November, 2004 + +#ifndef GLVIEWER_ASPECTLINE_H +#define GLVIEWER_ASPECTLINE_H + +#include "GLViewer.h" + +#include + +#ifdef WNT +#pragma warning( disable:4251 ) +#endif + +/*! + * Class GLViewer_AspectLine + * Substitution of Prs2d_AspectLine for OpenGL + */ + +class GLVIEWER_API GLViewer_AspectLine +{ +public: + //! A default constructor + /* Line is Non strip + * Normal color is white + * Highlight color is cyan + * Select color is red + */ + GLViewer_AspectLine(); + //! A conctructor by type and width of line + /*! + \param theType equals 0 for normal line and 1 for strip line + \param theWidth is a width of new line + */ + GLViewer_AspectLine( int theType, float theWidth ); + + //! A destructor + ~GLViewer_AspectLine(); + + //! A function for installing the line colors + /*! + \param nc is normal color + \param hc is highlight color + \param sc is select color + */ + void setLineColors( QColor nc = Qt::black, + QColor hc = Qt::cyan, + QColor sc = Qt::red ); + //! A function for installing the line width + int setLineWidth( const float theWidth ); + //! A function for installing the line type + /*! + \param theType equals 0 for normal line and 1 for strip line + */ + int setLineType( const int theType ); + + //! A function for getting line colors information + /*! + \param theNC is normal color + \param theHC is highlight color + \param theSC is select color + */ + void getLineColors( QColor& theNC, QColor& theHC, QColor& theSC ) const; + //! A function for getting information about line width + float getLineWidth() const { return myLineWidth; }; + //! A function for getting information about line type + int getLineType() const { return myLineType; }; + + //! A function for coding object to the byte copy + /*! + A function is used for copy-past technollogy in copy method + */ + QByteArray getByteCopy() const; + + //! A function for decoding object from the byte copy + /*! + A function is used for copy-past technollogy in past method + */ + static GLViewer_AspectLine* fromByteCopy( QByteArray ); + +protected: + //! A normal color + QColor myNColor; + //! A highlight color + QColor myHColor; + //! A select color + QColor mySColor; + //! A line width + float myLineWidth; + //! A line type + /*! equals 0 for normal line and 1 for strip line */ + int myLineType; +}; + +#ifdef WNT +#pragma warning ( default:4251 ) +#endif + +#endif diff --git a/src/GLViewer/GLViewer_BaseDrawers.cxx b/src/GLViewer/GLViewer_BaseDrawers.cxx new file mode 100644 index 000000000..a43a5930e --- /dev/null +++ b/src/GLViewer/GLViewer_BaseDrawers.cxx @@ -0,0 +1,306 @@ +// Copyright (C) 2005 OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// Author : OPEN CASCADE +// + +// File: GLViewer_BaseDrawers.cxx +// Created: November, 2004 + +//#include +#include "GLViewer_BaseDrawers.h" +#include "GLViewer_Object.h" +#include "GLViewer_Text.h" +#include "GLViewer_AspectLine.h" +#include "GLViewer_BaseObjects.h" + +#ifndef WIN32 +#include +#endif + +/*************************************************************************** +** Class: GLViewer_MarkerDrawer +** Descr: Drawer for GLViewer_MarkerSet +** Module: GLViewer +** Created: UI team, 03.10.01 +****************************************************************************/ + +GLfloat sin_table[SEGMENTS]; +GLfloat cos_table[SEGMENTS]; + +GLViewer_MarkerDrawer::GLViewer_MarkerDrawer() +: GLViewer_Drawer() +{ + GLfloat angle = 0.0; + for ( int i = 0; i < SEGMENTS; i++ ) + { + sin_table[i] = sin( angle ); + cos_table[i] = cos( angle ); + angle += float( STEP ); + } + myObjectType = "GLViewer_MarkerSet"; +} + +GLViewer_MarkerDrawer::~GLViewer_MarkerDrawer() +{ +} + +void GLViewer_MarkerDrawer::create( float xScale, float yScale, bool onlyUpdate ) +{ + QValueList::Iterator it; + QValueList::Iterator EndIt; + QValueList::Iterator anObjectIt = myObjects.begin(); + QValueList::Iterator anEndObjectIt = myObjects.end(); + + myXScale = xScale; + myYScale = yScale; + + QColor colorN, colorH, colorS; + + GLViewer_MarkerSet* aMarkerSet = NULL; + GLViewer_AspectLine* anAspectLine = NULL; + + for( ; anObjectIt != anEndObjectIt; anObjectIt++ ) + { + aMarkerSet = ( GLViewer_MarkerSet* )(*anObjectIt); + anAspectLine = aMarkerSet->getAspectLine(); + anAspectLine->getLineColors( colorN, colorH, colorS ); + + float* aXCoord = aMarkerSet->getXCoord(); + float* anYCoord = aMarkerSet->getYCoord(); + float aRadius = aMarkerSet->getMarkerSize(); + + QValueList aHNumbers, anUHNumbers, aSelNumbers, anUSelNumbers; + aMarkerSet->exportNumbers( aHNumbers, anUHNumbers, aSelNumbers, anUSelNumbers ); + + if( onlyUpdate ) + { + EndIt = anUHNumbers.end(); + for( it = anUHNumbers.begin(); it != EndIt; ++it ) + { + drawMarker( aXCoord[*it], anYCoord[*it], aRadius, colorN, anAspectLine ); + } + + EndIt = anUSelNumbers.end(); + for( it = anUSelNumbers.begin(); it != EndIt; ++it ) + drawMarker( aXCoord[*it], anYCoord[*it], aRadius, colorN, anAspectLine ); + + EndIt = aSelNumbers.end(); + for( it = aSelNumbers.begin(); it != EndIt; ++it ) + drawMarker( aXCoord[*it], anYCoord[*it], aRadius, colorS, anAspectLine ); + + EndIt = aHNumbers.end(); + for( it = aHNumbers.begin(); it != EndIt; ++it ) + { + drawMarker( aXCoord[*it], anYCoord[*it], aRadius, colorH, anAspectLine ); + } + } + else + { + int aNumber = aMarkerSet->getNumMarkers(); + for( int i = 0; i < aNumber; i++ ) + drawMarker( aXCoord[i], anYCoord[i], aRadius, colorN, anAspectLine ); + + EndIt = anUSelNumbers.end(); + for( it = anUSelNumbers.begin(); it != EndIt; ++it ) + drawMarker( aXCoord[*it], anYCoord[*it], aRadius, colorN, anAspectLine ); + + EndIt = aSelNumbers.end(); + for( it = aSelNumbers.begin(); it != EndIt; ++it ) + drawMarker( aXCoord[*it], anYCoord[*it], aRadius, colorS, anAspectLine ); + } + if( aMarkerSet->getGLText()->getText() != "" ) + { + //float aXPos = 0, anYPos = 0; + //aMarkerSet->getGLText()->getPosition( aXPos, anYPos ); + //drawText( aMarkerSet->getGLText()->getText(), aXPos, anYPos, colorN, &aMarkerSet->getGLText()->getFont(), aMarkerSet->getGLText()->getSeparator() ); + drawText( aMarkerSet ); + } + } +} + +void GLViewer_MarkerDrawer::drawMarker( float& theXCoord, float& theYCoord, + float& theRadius, QColor& theColor, GLViewer_AspectLine* theAspectLine ) +{ + glColor3f( ( GLfloat )theColor.red() / 255, + ( GLfloat )theColor.green() / 255, + ( GLfloat )theColor.blue() / 255 ); + + glLineWidth( theAspectLine->getLineWidth() ); + + if ( theAspectLine->getLineType() == 0 ) + glBegin( GL_LINE_LOOP ); + else + glBegin( GL_LINE_STRIP); + + for ( int i = 0; i < SEGMENTS; i++ ) + glVertex2f( theXCoord + cos_table[i] * theRadius / myXScale, + theYCoord + sin_table[i] * theRadius / myYScale ); + glEnd(); +} + +/*************************************************************************** +** Class: GLViewer_PolylineDrawer +** Descr: Drawer for GLViewer_Polyline +** Module: GLViewer +** Created: UI team, 03.10.01 +****************************************************************************/ + +GLViewer_PolylineDrawer::GLViewer_PolylineDrawer() +:GLViewer_Drawer() +{ + myObjectType = "GLViewer_Polyline"; +} + +GLViewer_PolylineDrawer::~GLViewer_PolylineDrawer() +{ +} + +void GLViewer_PolylineDrawer::create( float xScale, float yScale, bool onlyUpdate ) +{ + QValueList::Iterator aObjectIt = myObjects.begin(); + QValueList::Iterator aObjectEndIt = myObjects.end(); + + myXScale = xScale; + myYScale = yScale; + + QColor color, colorN, colorH, colorS; + GLViewer_AspectLine* anAspect = NULL; + GLViewer_Polyline* aPolyline = NULL; + for( ; aObjectIt != aObjectEndIt; aObjectIt++ ) + { + anAspect = (*aObjectIt)->getAspectLine(); + aPolyline = (GLViewer_Polyline*)(*aObjectIt); + + + anAspect->getLineColors( colorN, colorH, colorS ); + if( onlyUpdate ) + { + if( aPolyline->isHighlighted() ) + color = colorH; + else if( aPolyline->isSelected() ) + color = colorS; + else + color = colorN; + } + else + { + if( aPolyline->isSelected() ) + color = colorS; + else + color = colorN; + } + + float* aXCoord = aPolyline->getXCoord(); + float* anYCoord = aPolyline->getYCoord(); + int aSize = aPolyline->getNumber(); + + glColor3f( ( GLfloat )color.red() / 255, + ( GLfloat )color.green() / 255, + ( GLfloat )color.blue() / 255 ); + + glLineWidth( anAspect->getLineWidth() ); + + if ( anAspect->getLineType() == 0 ) + glBegin( GL_LINE_LOOP ); + else + glBegin( GL_LINE_STRIP); + + for( int i = 0; i < aSize ; i++ ) + glVertex2f( aXCoord[ i ], anYCoord[ i ] ); + + if( aPolyline->isClosed() ) + glVertex2f( aXCoord[ 0 ], anYCoord[ 0 ] ); + + glEnd(); + + if( aPolyline->getGLText()->getText() != "" ) + { + //float aXPos = 0, anYPos = 0; + //aPolyline->getGLText()->getPosition( aXPos, anYPos ); + //drawText( aPolyline->getGLText()->getText(), aXPos, anYPos, color, &aPolyline->getGLText()->getFont(), aPolyline->getGLText()->getSeparator() ); + drawText( aPolyline ); + } + } +} + +/*************************************************************************** +** Class: GLViewer_TextDrawer +** Descr: +** Module: GLViewer +** Created: UI team, 27.02.04 +****************************************************************************/ + +GLViewer_TextDrawer::GLViewer_TextDrawer() +: GLViewer_Drawer() +{ + myObjectType = "GLViewer_TextObject"; +} + +GLViewer_TextDrawer::~GLViewer_TextDrawer() +{ +} + +void GLViewer_TextDrawer::create( float xScale, float yScale, bool onlyUpdate ) +{ + QValueList::Iterator aObjectIt = myObjects.begin(); + QValueList::Iterator aObjectEndIt = myObjects.end(); + + myXScale = xScale; + myYScale = yScale; + + QColor color, colorN, colorH, colorS; + GLViewer_AspectLine* anAspect = NULL; + GLViewer_TextObject* anObject = NULL; + //float aXPos = 0, anYPos = 0; + for( ; aObjectIt != aObjectEndIt; aObjectIt++ ) + { + anObject = (GLViewer_TextObject*)(*aObjectIt); + anAspect = anObject->getAspectLine(); + + anAspect->getLineColors( colorN, colorH, colorS ); + if( onlyUpdate ) + { + if( anObject->isHighlighted() ) + color = colorH; + else if( anObject->isSelected() ) + color = colorS; + else + color = colorN; + } + else + { + if( anObject->isSelected() ) + color = colorS; + else + color = colorN; + } + + //anObject->getGLText()->getPosition( aXPos, anYPos ); + //drawText( anObject->getGLText()->getText(), aXPos, anYPos, color, &(anObject->getGLText()->getFont()), anObject->getGLText()->getSeparator() ); + drawText( anObject ); + } +} + +void GLViewer_TextDrawer::updateObjects() +{ + QValueList::Iterator aObjectIt = myObjects.begin(); + QValueList::Iterator aObjectEndIt = myObjects.end(); + for( ; aObjectIt != aObjectEndIt; aObjectIt++ ) + (*aObjectIt)->compute(); +} diff --git a/src/GLViewer/GLViewer_BaseDrawers.h b/src/GLViewer/GLViewer_BaseDrawers.h new file mode 100644 index 000000000..ce98aa867 --- /dev/null +++ b/src/GLViewer/GLViewer_BaseDrawers.h @@ -0,0 +1,95 @@ +// Copyright (C) 2005 OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// Author : OPEN CASCADE +// + +// File: GLViewer_BaseDrawers.h +// Created: November, 2004 + +#ifndef GLVIEWER_BASEDRAWERS_H +#define GLVIEWER_BASEDRAWERS_H + +#include +#include +#include +#include +#include + +#include "GLViewer.h" +#include "GLViewer_Drawer.h" + +class GLViewer_AspectLine; + +#ifdef WNT +#pragma warning( disable:4251 ) +#endif + +/*! Class GLViewer_MarkerDrawer +* Drawer for GLViewer_MarkerSet + */ + +class GLVIEWER_API GLViewer_MarkerDrawer : public GLViewer_Drawer +{ +public: + GLViewer_MarkerDrawer(); + ~GLViewer_MarkerDrawer(); + + //! Redefined method + virtual void create( float, float, bool ); + +private: + //! Draws marker in point (x,y) of \param radius with \param color and \param aspect + void drawMarker( float& x, float& y, float& radius, QColor& color, GLViewer_AspectLine* aspect ); +}; + +/*! Class GLViewer_PolylineDrawer +* Drawer for GLViewer_Polyline +*/ + +class GLVIEWER_API GLViewer_PolylineDrawer : public GLViewer_Drawer +{ +public: + GLViewer_PolylineDrawer(); + ~GLViewer_PolylineDrawer(); + //! Redefined method + virtual void create( float, float, bool ); +}; + +/* Class GLViewer_TextDrawer +* Drawer for GLViewer_Text +*/ + +class GLVIEWER_API GLViewer_TextDrawer: public GLViewer_Drawer +{ + +public: + GLViewer_TextDrawer(); + ~GLViewer_TextDrawer(); + + //! Redefined method + virtual void create( float, float, bool ); + //! Updates objects after updating font + void updateObjects(); +}; + +#ifdef WNT +#pragma warning ( default:4251 ) +#endif + +#endif diff --git a/src/GLViewer/GLViewer_BaseObjects.cxx b/src/GLViewer/GLViewer_BaseObjects.cxx new file mode 100644 index 000000000..79c32e3f8 --- /dev/null +++ b/src/GLViewer/GLViewer_BaseObjects.cxx @@ -0,0 +1,1458 @@ +// Copyright (C) 2005 OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// Author : OPEN CASCADE +// + +/*************************************************************************** +** Class: GLViewer_BaseObjects +** Descr: Internal OpenGL Objects +** Module: GLViewer +** Created: UI team, 02.09.02 +****************************************************************************/ + +//#include +#include "GLViewer_BaseObjects.h" +#include "GLViewer_BaseDrawers.h" +#include "GLViewer_AspectLine.h" +#include "GLViewer_CoordSystem.h" +#include "GLViewer_Text.h" +#include "GLViewer_Group.h" + +#include "GLViewer_Drawer.h" + +//#include +//using namespace std; + +/*************************************************************************** +** Class: GLViewer_MarkerSet +** Descr: OpenGL MarkerSet +** Module: GLViewer +** Created: UI team, 03.09.02 +****************************************************************************/ + +GLViewer_MarkerSet::GLViewer_MarkerSet( int number, float size, const QString& toolTip ) : + GLViewer_Object(), + myNumber( 0 ), + myXCoord( 0 ), + myYCoord( 0 ) +{ + + myMarkerSize = size; + myHNumbers.clear(); + myUHNumbers.clear(); + mySelNumbers.clear(); + myUSelNumbers.clear(); + myCurSelNumbers.clear(); + myPrevHNumbers.clear(); + + myType = "GLViewer_MarkerSet"; + myToolTipText = toolTip; + + setNumMarkers( number ); +} + +GLViewer_MarkerSet::~GLViewer_MarkerSet() +{ + if ( myXCoord ) + delete[] myXCoord; + if ( myYCoord ) + delete[] myYCoord; +} + +void AddCoordsToHPGL( QString& buffer, QString command, GLViewer_CoordSystem* aViewerCS, + GLViewer_CoordSystem* aPaperCS, double x, double y, bool NewLine = true ) +{ + if( aViewerCS && aPaperCS ) + aViewerCS->transform( *aPaperCS, x, y ); + + QString temp = command + "%1, %2;"; + buffer += temp.arg( x ).arg( y ); + if( NewLine ) + buffer += ";\n"; +} + +void AddCoordsToPS( QString& buffer, QString command, GLViewer_CoordSystem* aViewerCS, + GLViewer_CoordSystem* aPaperCS, double x, double y, bool NewLine = true ) +{ + if( aViewerCS && aPaperCS ) + aViewerCS->transform( *aPaperCS, x, y ); + + QString temp = "%1 %2 "+command; + buffer += temp.arg( x ).arg( y ); + if( NewLine ) + buffer += "\n"; +} + +void AddLineAspectToPS( QString& buffer, GLViewer_AspectLine* anAspect, + GLViewer_CoordSystem* aViewerCS, GLViewer_CoordSystem* aPaperCS ) +{ + if( anAspect ) + { + QColor col1, col2, col3; + anAspect->getLineColors( col1, col2, col3 ); + + float aWidth = anAspect->getLineWidth(); + int aLineType = anAspect->getLineType(); + + QString temp = "%1 %2 %3 setrgbcolor\n"; + double rr = 1 - double( col1.red() ) / 255.0, //color inverting + gg = 1 - double( col1.green() ) / 255.0, + bb = 1 - double( col1.blue() ) / 255.0; + + buffer += temp.arg( rr ).arg( gg ).arg( bb ); + + double x_stretch, y_stretch; + aViewerCS->getStretching( *aPaperCS, x_stretch, y_stretch ); + buffer += temp.arg( x_stretch * aWidth )+" setlinewidth\n"; + + if( aLineType==0 ) //solid + buffer += "[] 0 setdash\n"; + else if( aLineType==1 ) //strip + buffer += "[2] 0 setdash\n"; + } +} + +#ifdef WIN32 +HPEN AddLineAspectToEMF( HDC hDC, GLViewer_AspectLine* anAspect, + GLViewer_CoordSystem* aViewerCS, GLViewer_CoordSystem* aPaperCS ) +{ + if( anAspect ) + { + QColor col1, col2, col3; + anAspect->getLineColors( col1, col2, col3 ); + + double x_stretch, y_stretch; + aViewerCS->getStretching( *aPaperCS, x_stretch, y_stretch ); + + double aWidth = anAspect->getLineWidth()*x_stretch; + int aLineType = anAspect->getLineType(); + + return CreatePen( PS_SOLID, aWidth, RGB( 255-col1.red(), 255-col1.green(), 255-col1.blue() ) ); + } + else + return NULL; +} +#endif + +bool GLViewer_MarkerSet::translateToPS( QFile& hFile, GLViewer_CoordSystem* aViewerCS, GLViewer_CoordSystem* aPSCS ) +{ + int noPoints = 20; + + QString aBuffer = "newpath\n"; + + AddLineAspectToPS( aBuffer, getAspectLine(), aViewerCS, aPSCS ); + + for( int i=0; igetStretching( *aPSCS, x_stretch, y_stretch ); + + double x0 = myXCoord[i], + y0 = myYCoord[i], + r = myMarkerSize, + x, y; + + for( int j=0; j<=noPoints; j++ ) + { + x = x0 + r*cos( double(j)*2*PI/double(noPoints) ); + y = y0 + r*sin( double(j)*2*PI/double(noPoints) ); + if( j==0 ) + AddCoordsToPS( aBuffer, "moveto", aViewerCS, aPSCS, x, y, true ); + else + AddCoordsToPS( aBuffer, "lineto", aViewerCS, aPSCS, x, y, true ); + } + } + aBuffer+="closepath\nstroke\n"; + + hFile.writeBlock( aBuffer.ascii(), aBuffer.length() ); + + return true; +} + +bool GLViewer_MarkerSet::translateToHPGL( QFile& hFile, GLViewer_CoordSystem* aViewerCS, + GLViewer_CoordSystem* aHPGLCS ) +{ + int noPoints = 20; + QString aBuffer; + for( int i=0; igetStretching( *aHPGLCS, x_stretch, y_stretch ); + + double x0 = myXCoord[i], + y0 = myYCoord[i], + r = myMarkerSize, + x, y; + + AddCoordsToHPGL( aBuffer, "PA", aViewerCS, aHPGLCS, x0+r, y0 ); + aBuffer+="PD;\n"; + for( int j=1; j<=noPoints; j++ ) + { + x = x0 + r*cos( double(j)*2*PI/double(noPoints) ); + y = y0 + r*sin( double(j)*2*PI/double(noPoints) ); + AddCoordsToHPGL( aBuffer, "PD", aViewerCS, aHPGLCS, x, y ); + } + aBuffer+="PU;\n"; + + hFile.writeBlock( aBuffer.ascii(), aBuffer.length() ); + } + + return true; +} + +#ifdef WIN32 +bool GLViewer_MarkerSet::translateToEMF( HDC dc, GLViewer_CoordSystem* aViewerCS, GLViewer_CoordSystem* aEMFCS ) +{ + int noPoints = 20; + if( !aViewerCS || !aEMFCS ) + return false; + + HPEN pen = AddLineAspectToEMF( dc, getAspectLine(), aViewerCS, aEMFCS ); + HGDIOBJ old = SelectObject( dc, pen ); + + for( int i=0; itransform( *aEMFCS, x, y ); + if( j==0 ) + MoveToEx( dc, x, y, NULL ); + else + LineTo( dc, x, y ); + } + } + + SelectObject( dc, old ); + if( pen ) + DeleteObject( pen ); + return true; +} +#endif + + +void GLViewer_MarkerSet::compute() +{ +// cout << "GLViewer_MarkerSet::compute" << endl; + GLfloat xa = myXCoord[0]; + GLfloat xb = myXCoord[0]; + GLfloat ya = myYCoord[0]; + GLfloat yb = myYCoord[0]; + + for ( int i = 0; i < myNumber; i++ ) + { + xa = QMIN( xa, myXCoord[i] ); + xb = QMAX( xb, myXCoord[i] ); + ya = QMIN( ya, myYCoord[i] ); + yb = QMAX( yb, myYCoord[i] ); + } + + myXGap = ( xb - xa ) / 10; + myYGap = ( yb - ya ) / 10; + + myRect->setLeft( xa - myXGap ); + myRect->setTop( yb + myYGap ); + myRect->setRight( xb + myXGap ); + myRect->setBottom( ya - myYGap ); +} + +GLViewer_Drawer* GLViewer_MarkerSet::createDrawer() +{ +// cout << "GLViewer_MarkerSet::createDrawer" << endl; + return myDrawer = new GLViewer_MarkerDrawer(); +} + + +GLboolean GLViewer_MarkerSet::highlight( GLfloat x, GLfloat y, GLfloat tol, GLboolean isCircle ) +{ + if( !myIsVisible ) + return false; +// cout << "GLViewer_MarkerSet::highlight " << x <<" " << y << " " << tol << endl; + int count = 0; + GLfloat xdist, ydist, radius; + QValueList::Iterator it; + QValueList curHNumbers; + bool isFound; + GLboolean update; + int cnt = 0; + + radius = tol - myMarkerSize / 2.; + + myUHNumbers += myHNumbers; + myHNumbers.clear(); + + for ( int i = 0; i < myNumber; i++ ) + { + xdist = ( myXCoord[i] - x ) * myXScale; + ydist = ( myYCoord[i] - y ) * myYScale; + +// if ( isCircle && ( xdist * xdist + ydist * ydist <= radius * radius ) || + if ( isCircle && ( xdist * xdist + ydist * ydist <= myMarkerSize * myMarkerSize ) || + !isCircle && ( fabs( xdist ) <= radius && fabs( ydist ) <= radius ) ) + { + isFound = FALSE; + count++; + for ( it = myCurSelNumbers.begin(); it != myCurSelNumbers.end(); ++it ) + if( i == *it ) + { + isFound = TRUE; + curHNumbers.append( i ); + } + + if( !isFound ) + myHNumbers.append( i ); + else + cnt++; + } + } + myCurSelNumbers = curHNumbers; + + myIsHigh = ( GLboolean )count; + update = ( GLboolean )( myHNumbers != myPrevHNumbers ); + + myPrevHNumbers = myHNumbers; + + //cout << "GLViewer_MarkerSet::highlight complete with " << (int)myIsHigh << endl; + return update; +} + +GLboolean GLViewer_MarkerSet::unhighlight() +{ + if( !myHNumbers.isEmpty() ) + { + myUHNumbers += myHNumbers; + myPrevHNumbers.clear(); + myHNumbers.clear(); + //??? myCurSelNumbers.clear(); + return GL_TRUE; + } + + return GL_FALSE; +} + +GLboolean GLViewer_MarkerSet::select( GLfloat x, GLfloat y, GLfloat tol, GLViewer_Rect rect, GLboolean isFull, + GLboolean isCircle, GLboolean isShift ) +{ + if( !myIsVisible ) + return false; +// cout << "GLViewer_MarkerSet::select " << x << " " << y << endl; + int count = 0; + GLfloat xdist, ydist, radius; + QValueList::Iterator it; + QValueList::Iterator it1; + QValueList::Iterator remIt; + QValueList::Iterator curIt; + + radius = tol - myMarkerSize / 2.; + + if( radius < myMarkerSize / 2.) + radius = myMarkerSize / 2.; + + count = isShift ? mySelNumbers.count() : 0; + + myUSelNumbers = mySelNumbers; + + if ( !isShift ) + { + mySelNumbers.clear(); + myCurSelNumbers.clear(); + } + + for ( int i = 0; i < myNumber; i++ ) + { + xdist = ( myXCoord[i] - x ) * myXScale; + ydist = ( myYCoord[i] - y ) * myYScale; + + //if ( isCircle && ( xdist * xdist + ydist * ydist <= radius * radius ) || + if ( isCircle && ( xdist * xdist + ydist * ydist <= myMarkerSize * myMarkerSize ) || + !isCircle && ( fabs( xdist ) <= radius && fabs( ydist ) <= radius ) ) + { + count++; + if ( isShift ) + { + bool isFound = FALSE; + for( it = mySelNumbers.begin(); it != mySelNumbers.end(); ++it ) + if ( *it == i ) + { + myUSelNumbers.append( *it ); + remIt = it; + isFound = TRUE; + break; + } + + if ( !isFound ) + { + mySelNumbers.append( i ); + myCurSelNumbers.append( i ); + for ( it1 = myHNumbers.begin(); it1 != myHNumbers.end(); ++it1 ) + if( i == *it1 ) + { + myHNumbers.remove( it1 ); + break; + } + for ( it1 = myUHNumbers.begin(); it1 != myUHNumbers.end(); ++it1 ) + if( i == *it1 ) + { + myUHNumbers.remove( it1 ); + break; + } + } + else + { + mySelNumbers.remove( remIt ); + for ( curIt = myCurSelNumbers.begin(); curIt != myCurSelNumbers.end(); ++curIt ) + if( *curIt == *remIt) + { + myCurSelNumbers.remove( curIt ); + break; + } + for ( it1 = myHNumbers.begin(); it1 != myHNumbers.end(); ++it1 ) + if( i == *it1 ) + { + myHNumbers.remove( it1 ); + break; + } + for ( it1 = myUHNumbers.begin(); it1 != myUHNumbers.end(); ++it1 ) + if( i == *it1 ) + { + myUHNumbers.remove( it1 ); + break; + } + } + } + else + { + mySelNumbers.append( i ); + myCurSelNumbers.append( i ); + for ( it1 = myHNumbers.begin(); it1 != myHNumbers.end(); ++it1 ) + if( i == *it1 ) + { + myHNumbers.remove( it1 ); + break; + } + for ( it1 = myUHNumbers.begin(); it1 != myUHNumbers.end(); ++it1 ) + if( i == *it1 ) + { + myUHNumbers.remove( it1 ); + break; + } + } + } + } + + for( it = mySelNumbers.begin(); it != mySelNumbers.end(); ++it ) + for( it1 = myUSelNumbers.begin(); it1 != myUSelNumbers.end(); ++it1 ) + if( *it == *it1 ) + { + it1 = myUSelNumbers.remove( it1 ); + it1--; + } + + myIsSel = (GLboolean)count; + +// cout << "GLViewer_MarkerSet::select complete with " << (int)myIsSel << endl; + return myIsSel; +} + +GLboolean GLViewer_MarkerSet::unselect() +{ + if( !mySelNumbers.isEmpty() ) + { + myUSelNumbers = mySelNumbers; + mySelNumbers.clear(); + myCurSelNumbers.clear(); + return GL_TRUE; + } + + return GL_FALSE; +} + +GLViewer_Rect* GLViewer_MarkerSet::getUpdateRect() +{ + GLViewer_Rect* rect = new GLViewer_Rect(); + + rect->setLeft( myRect->left() + myXGap - myMarkerSize / myXScale ); + rect->setTop( myRect->top() + myYGap + myMarkerSize / myYScale ); + rect->setRight( myRect->right() - myXGap + myMarkerSize / myXScale ); + rect->setBottom( myRect->bottom() - myYGap - myMarkerSize / myYScale ); + //cout << " Additional tolerance " << myMarkerSize / myYScale << endl; + //rect->setLeft( myRect->left() - myMarkerSize / myXScale ); + //rect->setTop( myRect->top() - myMarkerSize / myYScale ); + //rect->setRight( myRect->right() + myMarkerSize / myXScale ); + //rect->setBottom( myRect->bottom() + myMarkerSize / myYScale ); + + return rect; +} + + +void GLViewer_MarkerSet::setXCoord( GLfloat* xCoord, int size ) +{ + myXCoord = new GLfloat[ size ]; + for( int i = 0; i < size; i++ ) + myXCoord[i] = xCoord[i]; +} + +void GLViewer_MarkerSet::setYCoord( GLfloat* yCoord, int size ) +{ + myYCoord = new GLfloat[ size ]; + for( int i = 0; i < size; i++ ) + myYCoord[i] = yCoord[i]; +} + +void GLViewer_MarkerSet::setNumMarkers( GLint number ) +{ + if ( myNumber == number ) + return; + + if ( myXCoord && myYCoord ) + { + delete[] myXCoord; + delete[] myYCoord; + } + + myNumber = number; + myXCoord = new GLfloat[ myNumber ]; + myYCoord = new GLfloat[ myNumber ]; +} +/* +void GLViewer_MarkerSet::onSelectionDone( bool append) +{ + mySelectedIndexes.Clear(); + QValueList::Iterator it; + //for( it = myMarkers->mySelNumbers.begin(); it != myMarkers->mySelNumbers.end(); ++it ) + // mySelectedIndexes.Append( *it / 2 ); //!!! + + emit dvMarkersSelected( mySelectedIndexes ); +} + +void GLViewer_MarkerSet::onSelectionCancel() +{ + mySelectedIndexes.Clear(); + emit dvMarkersSelected( mySelectedIndexes ); +} +*/ +void GLViewer_MarkerSet::exportNumbers( QValueList& highlight, + QValueList& unhighlight, + QValueList& select, + QValueList& unselect ) +{ + highlight = myHNumbers; + unhighlight = myUHNumbers; + select = mySelNumbers; + unselect = myUSelNumbers; + + myUHNumbers = myHNumbers; +} + +bool GLViewer_MarkerSet::addOrRemoveSelected( int index ) +{ + if( index < 0 || index > myNumber ) + return FALSE; + + int n = mySelNumbers.findIndex( index ); + if( n == -1 ) + mySelNumbers.append( index ); + else + { + QValueList::Iterator it; + it = mySelNumbers.at( n ); + mySelNumbers.remove( it ); + myUSelNumbers.append( index ); + } + return TRUE; +} + +void GLViewer_MarkerSet::addSelected( const TColStd_SequenceOfInteger& seq ) +{ + for ( int i = 1; i <= seq.Length(); i++ ) + if( mySelNumbers.findIndex( seq.Value( i ) ) == -1 ) + mySelNumbers.append( seq.Value( i ) - 1 ); +} + +void GLViewer_MarkerSet::setSelected( const TColStd_SequenceOfInteger& seq ) +{ +// for( QValueList::Iterator it = mySelNumbers.begin(); it != mySelNumbers.end(); ++it ) +// if( myUSelNumbers.findIndex( *it ) == -1 ) +// myUSelNumbers.append( *it ); + + myUSelNumbers = mySelNumbers; + mySelNumbers.clear(); + + for ( int i = 1; i <= seq.Length(); i++ ) + mySelNumbers.append( seq.Value( i ) - 1 ); +} + +void GLViewer_MarkerSet::moveObject( float theX, float theY, bool fromGroup ) +{ + if( !fromGroup && myGroup) + { + myGroup->dragingObjects( theX, theY ); + return; + } + for( int i = 0; i < myNumber; i++ ) + { + myXCoord[i] = myXCoord[i] + theX; + myYCoord[i] = myYCoord[i] + theY; + } + compute(); +} + +QByteArray GLViewer_MarkerSet::getByteCopy() +{ + int i = 0; + int anISize = sizeof( GLint ); + int aFSize = sizeof( GLfloat ); + + QByteArray aObject = GLViewer_Object::getByteCopy(); + + QByteArray aResult( anISize + 2*aFSize*myNumber + aFSize + aObject.size()); + + char* aPointer = (char*)&myNumber; + for( i = 0; i < anISize; i++, aPointer++ ) + aResult[i] = *aPointer; + + aPointer = (char*)myXCoord; + for( ; i < anISize + aFSize*myNumber; i++, aPointer++ ) + aResult[i] = *aPointer; + aPointer = (char*)myYCoord; + for( ; i < anISize + 2*aFSize*myNumber; i++, aPointer++ ) + aResult[i] = *aPointer; + + aPointer = (char*)&myMarkerSize; + for( ; i < anISize + 2*aFSize*myNumber + aFSize; i++, aPointer++ ) + aResult[i] = *aPointer; + + + for( ; i < aResult.size(); i++ ) + aResult[i] = aObject[i - anISize - 2*aFSize*myNumber - aFSize]; + + return aResult; +} + +bool GLViewer_MarkerSet::initializeFromByteCopy( QByteArray theArray ) +{ + int i = 0; + int anISize = sizeof( GLint ); + int aFSize = sizeof( GLfloat ); + + char* aPointer = (char*)&myNumber; + for( i = 0; i < anISize; i++, aPointer++ ) + *aPointer = theArray[i]; + + int aSize = theArray.size(); + if( aSize < anISize + 2*aFSize*myNumber + aFSize) + return false; + + myXCoord = new GLfloat[myNumber]; + myYCoord = new GLfloat[myNumber]; + aPointer = (char*)myXCoord; + for( ; i < anISize + aFSize*myNumber; i++, aPointer++ ) + *aPointer = theArray[i]; + aPointer = (char*)myYCoord; + for( ; i < anISize + 2*aFSize*myNumber; i++, aPointer++ ) + *aPointer = theArray[i]; + + aPointer = (char*)&myMarkerSize; + for( ; i < anISize + 2*aFSize*myNumber + aFSize; i++, aPointer++ ) + *aPointer = theArray[i]; + + int aCurIndex = anISize + 2*aFSize*myNumber + aFSize; + QByteArray aObject( aSize - aCurIndex ); + for( ; i < aSize; i++ ) + aObject[i - aCurIndex] = theArray[i]; + + + if( !GLViewer_Object::initializeFromByteCopy( aObject ) || myType != "GLViewer_MarkerSet" ) + return false; + + myHNumbers.clear(); + myUHNumbers.clear(); + mySelNumbers.clear(); + myUSelNumbers.clear(); + myCurSelNumbers.clear(); + myPrevHNumbers.clear(); + + return true; +} + +/*************************************************************************** +** Class: GLViewer_Polyline +** Descr: OpenGL Polyline +** Module: GLViewer +** Created: UI team, 03.09.02 +****************************************************************************/ + +#define SECTIONS 100 +#define DISTANTION 5 + +GLViewer_Polyline::GLViewer_Polyline( int number, float size, const QString& toolTip ): + GLViewer_Object(), + myNumber( 0 ), + myXCoord( 0 ), + myYCoord( 0 ) +{ + myHighFlag = GL_TRUE; + + myHNumbers.clear(); + myUHNumbers.clear(); + mySelNumbers.clear(); + myUSelNumbers.clear(); + myCurSelNumbers.clear(); + myPrevHNumbers.clear(); + + setNumber( number ); + + myType = "GLViewer_Polyline"; + myToolTipText = toolTip; +} + +GLViewer_Polyline::~GLViewer_Polyline() +{ + if ( myXCoord ) + delete[] myXCoord; + if ( myYCoord ) + delete[] myYCoord; +} + +bool GLViewer_Polyline::translateToPS( QFile& hFile, GLViewer_CoordSystem* aViewerCS, GLViewer_CoordSystem* aPSCS ) +{ + QString aBuffer = "newpath\n"; + + AddLineAspectToPS( aBuffer, getAspectLine(), aViewerCS, aPSCS ); + + for( int i=0; itransform( *aEMFCS, x, y ); + if( i==0 ) + MoveToEx( dc, x, y, NULL ); + else + LineTo( dc, x, y ); + } + + if( myIsClosed ) + { + x = myXCoord[0]; + y = myYCoord[0]; + aViewerCS->transform( *aEMFCS, x, y ); + LineTo( dc, x, y ); + } + + SelectObject( dc, old ); + if( pen ) + DeleteObject( pen ); + + return true; +} +#endif + +void GLViewer_Polyline::compute() +{ +// cout << "GLViewer_MarkerSet::compute" << endl; + GLfloat xa = myXCoord[0]; + GLfloat xb = myXCoord[0]; + GLfloat ya = myYCoord[0]; + GLfloat yb = myYCoord[0]; + + for ( int i = 0; i < myNumber; i++ ) + { + xa = QMIN( xa, myXCoord[i] ); + xb = QMAX( xb, myXCoord[i] ); + ya = QMIN( ya, myYCoord[i] ); + yb = QMAX( yb, myYCoord[i] ); + } + + GLfloat xGap = ( xb - xa ) / 10; + GLfloat yGap = ( yb - ya ) / 10; + + myRect->setLeft( xa - xGap ); + myRect->setTop( yb + yGap ); + myRect->setRight( xb + xGap ); + myRect->setBottom( ya - yGap ); +} + +GLViewer_Rect* GLViewer_Polyline::getUpdateRect() +{ + GLViewer_Rect* rect = new GLViewer_Rect(); + + rect->setLeft( myRect->left() - myXGap ); + rect->setTop( myRect->top() + myYGap ); + rect->setRight( myRect->right() + myXGap ); + rect->setBottom( myRect->bottom() - myYGap ); + + return rect; +} + +GLViewer_Drawer* GLViewer_Polyline::createDrawer() +{ +// cout << "GLViewer_MarkerSet::createDrawer" << endl; + return myDrawer = new GLViewer_PolylineDrawer(); +} + +GLboolean GLViewer_Polyline::highlight( GLfloat x, GLfloat y, GLfloat tol, GLboolean isCircle ) +{ + if( !myIsVisible ) + return false; + GLfloat xa, xb, ya, yb, l; + GLfloat rsin, rcos, r, ra, rb; + GLboolean update; + GLboolean highlighted = myIsHigh; + + myIsHigh = GL_FALSE; + + int c = 0; + if( myIsClosed ) + c = 1; + + for( int i = 0; i < myNumber-1+c; i++ ) + { + xa = myXCoord[i]; + ya = myYCoord[i]; + if( i != myNumber-1 ) + { + xb = myXCoord[i+1]; + yb = myYCoord[i+1]; + } + else + { + xb = myXCoord[0]; + yb = myYCoord[0]; + } + + l = sqrt( (xb-xa)*(xb-xa) + (yb-ya)*(yb-ya) ); + rsin = (yb-ya) / l; + rcos = (xb-xa) / l; + r = ( (x-xa)*(y-yb) - (x-xb)*(y-ya) ) / ( rsin*(ya-yb) + rcos*(xa-xb) ); + ra = sqrt( (x-xa)*(x-xa) + (y-ya)*(y-ya) ); + rb = sqrt( (x-xb)*(x-xb) + (y-yb)*(y-yb) ); + if( fabs( r ) * myXScale <= DISTANTION && ra <= l + DISTANTION && rb <= l + DISTANTION ) + { + myIsHigh = GL_TRUE; + break; + } + } + + if( !myHighFlag && myIsHigh ) + myIsHigh = GL_FALSE; + else + myHighFlag = GL_TRUE; + + update = ( GLboolean )( myIsHigh != highlighted ); + +// cout << "GLViewer_Polyline::highlight complete with " << (int)myIsHigh << endl; + return update; +} + +GLboolean GLViewer_Polyline::unhighlight() +{ +// if( !myHNumbers.isEmpty() ) +// { +// myUHNumbers = myHNumbers; +// myHNumbers.clear(); +// return GL_TRUE; +// } + + if( myIsHigh ) + { + myIsHigh = GL_FALSE; + return GL_TRUE; + } + + return GL_FALSE; +} + +GLboolean GLViewer_Polyline::select( GLfloat x, GLfloat y, GLfloat tol, GLViewer_Rect rect, GLboolean isFull, + GLboolean isCircle, GLboolean isShift ) +{ + if( !myIsVisible ) + return false; + GLfloat xa, xb, ya, yb, l; + GLfloat rsin, rcos, r, ra, rb; + GLboolean update; + GLboolean selected = myIsSel; + + myIsSel = GL_FALSE; + + int c = 0; + if( myIsClosed ) + c = 1; + + for( int i = 0; i < myNumber-1+c; i++ ) + { + xa = myXCoord[i]; + ya = myYCoord[i]; + if( i != myNumber-1 ) + { + xb = myXCoord[i+1]; + yb = myYCoord[i+1]; + } + else + { + xb = myXCoord[0]; + yb = myYCoord[0]; + } + + l = sqrt( (xb-xa)*(xb-xa) + (yb-ya)*(yb-ya) ); + rsin = (yb-ya) / l; + rcos = (xb-xa) / l; + r = ( (x-xa)*(y-yb) - (x-xb)*(y-ya) ) / ( rsin*(ya-yb) + rcos*(xa-xb) ); + ra = sqrt( (x-xa)*(x-xa) + (y-ya)*(y-ya) ); + rb = sqrt( (x-xb)*(x-xb) + (y-yb)*(y-yb) ); + if( fabs( r ) * myXScale <= DISTANTION && ra <= l + DISTANTION && rb <= l + DISTANTION ) + { + myIsSel = GL_TRUE; + break; + } + } + + if ( myIsSel ) + { + myHighFlag = GL_FALSE; + myIsHigh = GL_FALSE; + } + else + myHighFlag = GL_TRUE; + + update = ( GLboolean )( myIsSel != selected ); + + // cout << "GLViewer_Polyline::select complete with " << (int)myIsSel << endl; + + // return update; !!!!!!!!!!!!!!!!!!!!!!!!!!! no here + return myIsSel; +} + +GLboolean GLViewer_Polyline::unselect() +{ +// if( !mySelNumbers.isEmpty() ) +// { +// myUSelNumbers = mySelNumbers; +// mySelNumbers.clear(); +// myCurSelNumbers.clear(); +// return GL_TRUE; +// } + + if( myIsSel ) + { + myIsSel = GL_FALSE; + return GL_TRUE; + } + + return GL_FALSE; +} + +void GLViewer_Polyline::setXCoord( GLfloat* xCoord, int size ) +{ + myXCoord = new GLfloat[ size ]; + for( int i = 0; i < size; i++ ) + myXCoord[i] = xCoord[i]; +} + +void GLViewer_Polyline::setYCoord( GLfloat* yCoord, int size ) +{ + myYCoord = new GLfloat[ size ]; + for( int i = 0; i < size; i++ ) + myYCoord[i] = yCoord[i]; +} + +void GLViewer_Polyline::setNumber( GLint number ) +{ + if ( myNumber == number ) + return; + + if ( myXCoord && myYCoord ) + { + delete[] myXCoord; + delete[] myYCoord; + } + + myNumber = number; + myXCoord = new GLfloat[ myNumber ]; + myYCoord = new GLfloat[ myNumber ]; +} +/* +void GLViewer_Polyline::onSelectionDone( bool append) +{ + mySelectedIndexes.Clear(); + QValueList::Iterator it; + //for( it = myMarkers->mySelNumbers.begin(); it != myMarkers->mySelNumbers.end(); ++it ) + // mySelectedIndexes.Append( *it / 2 ); //!!! +} + +void GLViewer_Polyline::onSelectionCancel() +{ + mySelectedIndexes.Clear(); +} +*/ +void GLViewer_Polyline::exportNumbers( QValueList& highlight, + QValueList& unhighlight, + QValueList& select, + QValueList& unselect ) +{ + highlight = myHNumbers; + unhighlight = myUHNumbers; + select = mySelNumbers; + unselect = myUSelNumbers; +} + +void GLViewer_Polyline::moveObject( float theX, float theY, bool fromGroup ) +{ + if( !fromGroup && myGroup) + { + myGroup->dragingObjects( theX, theY ); + return; + } + for( int i = 0; i < myNumber; i++ ) + { + myXCoord[i] = myXCoord[i] + theX; + myYCoord[i] = myYCoord[i] + theY; + } + compute(); +} + +QByteArray GLViewer_Polyline::getByteCopy() +{ + int i = 0; + int anISize = sizeof( GLint ); + int aFSize = sizeof( GLfloat ); + int aBSize = sizeof( GLboolean ); + + QByteArray aObject = GLViewer_Object::getByteCopy(); + + QByteArray aResult( aFSize*myNumber*2 + anISize + 2*aBSize + aObject.size()); + + char* aPointer = (char*)&myNumber; + for( i = 0; i < anISize; i++, aPointer++ ) + aResult[i] = *aPointer; + + aPointer = (char*)myXCoord; + for( ; i < anISize + aFSize*myNumber; i++, aPointer++ ) + aResult[i] = *aPointer; + aPointer = (char*)myYCoord; + for( ; i < anISize + 2*aFSize*myNumber; i++, aPointer++ ) + aResult[i] = *aPointer; + + aPointer = (char*)&myIsClosed; + for( ; i < anISize + 2*aFSize*myNumber + aBSize; i++, aPointer++ ) + aResult[i] = *aPointer; + aPointer = (char*)&myHighSelAll; + for( ; i < anISize + 2*aFSize*myNumber + 2*aBSize; i++, aPointer++ ) + aResult[i] = *aPointer; + + for( ; i < aResult.size(); i++ ) + aResult[i] = aObject[i - anISize - 2*aFSize*myNumber - 2*aBSize]; + + return aResult; +} + + +bool GLViewer_Polyline::initializeFromByteCopy( QByteArray theArray ) +{ + int i = 0; + int anISize = sizeof( GLint ); + int aFSize = sizeof( GLfloat ); + int aBSize = sizeof( GLboolean ); + + char* aPointer = (char*)&myNumber; + for( i = 0; i < anISize; i++, aPointer++ ) + *aPointer = theArray[i]; + + int aSize = theArray.size(); + if( aSize < aFSize*myNumber*2 + anISize + 2*aBSize ) + return false; + + myXCoord = new GLfloat[myNumber]; + myYCoord = new GLfloat[myNumber]; + aPointer = (char*)myXCoord; + for( ; i < anISize + aFSize*myNumber; i++, aPointer++ ) + *aPointer = theArray[i]; + aPointer = (char*)myYCoord; + for( ; i < anISize + 2*aFSize*myNumber; i++, aPointer++ ) + *aPointer = theArray[i]; + + aPointer = (char*)&myIsClosed; + for( ; i < anISize + 2*aFSize*myNumber + aBSize; i++, aPointer++ ) + *aPointer = theArray[i]; + aPointer = (char*)&myHighSelAll; + for( ; i < anISize + 2*aFSize*myNumber + 2*aBSize; i++, aPointer++ ) + *aPointer = theArray[i]; + + int aCurIndex = anISize + 2*aFSize*myNumber + 2*aBSize; + QByteArray aObject( aSize - aCurIndex ); + for( ; i < aSize; i++ ) + aObject[i - aCurIndex] = theArray[i]; + + if( !GLViewer_Object::initializeFromByteCopy( aObject ) || myType != "GLViewer_Polyline" ) + return false; + + myHNumbers.clear(); + myUHNumbers.clear(); + mySelNumbers.clear(); + myUSelNumbers.clear(); + myCurSelNumbers.clear(); + myPrevHNumbers.clear(); + + return true; +} + +/*************************************************************************** +** Class: GLViewer_TextObject +** Descr: Text as Object for OpenGL +** Module: GLViewer +** Created: UI team, 12.02.04 +****************************************************************************/ + +GLViewer_TextObject::GLViewer_TextObject( const QString& theStr, float xPos, float yPos, + const QColor& color, const QString& toolTip ) + : GLViewer_Object() +{ + myGLText = new GLViewer_Text( theStr, xPos, yPos, color ); + myWidth = 0; + myHeight = 0; + + myHighFlag = GL_TRUE; + + myToolTipText = toolTip; +} +GLViewer_TextObject::~GLViewer_TextObject() +{ + if ( myGLText ) + delete myGLText; +} + +bool GLViewer_TextObject::translateToPS( QFile& hFile, GLViewer_CoordSystem* aViewerCS, GLViewer_CoordSystem* aPSCS ) +{ + QString aText = myGLText->getText(); + float xPos, yPos; + myGLText->getPosition( xPos, yPos ); + + QString aBuffer = "/Times-Roman findfont\n"; + aBuffer += "12 scalefont setfont\n"; + + AddCoordsToPS( aBuffer, "moveto", aViewerCS, aPSCS, double(xPos), double(yPos) ); + aBuffer += "(" + aText + ") show\n"; + + hFile.writeBlock( aBuffer.ascii(), aBuffer.length() ); + + return true; +} + +bool GLViewer_TextObject::translateToHPGL( QFile& hFile, GLViewer_CoordSystem* aViewerCS, GLViewer_CoordSystem* aHPGLCS ) +{ + QString aText = myGLText->getText(); + float xPos, yPos; + myGLText->getPosition( xPos, yPos ); + + QString aBuffer = ""; + AddCoordsToHPGL( aBuffer, "PA", aViewerCS, aHPGLCS, double(xPos), double(yPos) ); + + aBuffer = "LB" + aText + "#;"; + + hFile.writeBlock( aBuffer.ascii(), aBuffer.length() ); + + return true; +} + +#ifdef WIN32 +bool GLViewer_TextObject::translateToEMF( HDC dc, GLViewer_CoordSystem* aViewerCS, GLViewer_CoordSystem* aEMFCS ) +{ + QString aText = myGLText->getText(); + float xPos, yPos; + myGLText->getPosition( xPos, yPos ); + + double x = double( xPos ), + y = double( yPos ); + + aViewerCS->transform( *aEMFCS, x, y ); + const char* str = aText.ascii(); + + int nHeight = 35*14; // height of font + int nWidth = 35*12; // average character width + int nEscapement = 0; // angle of escapement + int nOrientation = 0; // base-line orientation angle + int fnWeight = FW_NORMAL; // font weight + DWORD fdwItalic = FALSE; // italic attribute option + DWORD fdwUnderline = FALSE; // underline attribute option + DWORD fdwStrikeOut = FALSE; // strikeout attribute option + DWORD fdwCharSet = ANSI_CHARSET; // character set identifier + DWORD fdwOutputPrecision = OUT_DEFAULT_PRECIS; // output precision + DWORD fdwClipPrecision = CLIP_DEFAULT_PRECIS; // clipping precision + DWORD fdwQuality = PROOF_QUALITY; // output quality + DWORD fdwPitchAndFamily = FIXED_PITCH | FF_DONTCARE; // pitch and family + LPCTSTR lpszFace = NULL; // typeface name + + + HFONT aFont = CreateFont( nHeight, nWidth, nEscapement, nOrientation, fnWeight, fdwItalic, + fdwUnderline, fdwStrikeOut, fdwCharSet, fdwOutputPrecision, + fdwClipPrecision, fdwQuality, fdwPitchAndFamily, lpszFace ); + LOGBRUSH aBrushData; + aBrushData.lbStyle = BS_HOLLOW; + + HBRUSH aBrush = CreateBrushIndirect( &aBrushData ); + + HGDIOBJ old1 = SelectObject( dc, aFont ); + HGDIOBJ old2 = SelectObject( dc, aBrush ); + + TextOut( dc, x, y, str, aText.length() ); + + SelectObject ( dc, old1 ); + SelectObject ( dc, old2 ); + + DeleteObject( aFont ); + + return true; +} +#endif + +GLViewer_Drawer* GLViewer_TextObject::createDrawer() +{ + myDrawer = new GLViewer_TextDrawer(); + compute(); + return myDrawer; +} + +void GLViewer_TextObject::compute() +{ + float xPos, yPos; + QString aStr = myGLText->getText(); + myGLText->getPosition( xPos, yPos ); + + myWidth = myGLText->getWidth(); + myHeight = myGLText->getHeight(); + myRect->setLeft( xPos ); + myRect->setTop( yPos + myHeight ); + myRect->setRight( xPos + myWidth ); + myRect->setBottom( yPos ); +} + +void GLViewer_TextObject::setDrawer( GLViewer_Drawer* theDrawer ) +{ + myDrawer = theDrawer; + //compute(); +} + +GLViewer_Rect* GLViewer_TextObject::getUpdateRect() +{ + GLViewer_Rect* rect = new GLViewer_Rect(); + + float xPos, yPos; + QString aStr = myGLText->getText(); + myGLText->getPosition( xPos, yPos ); + + rect->setLeft( myRect->left() + myXGap - myWidth / myXScale ); + rect->setTop( myRect->top() + myYGap + myHeight / myYScale ); + rect->setRight( myRect->right() - myXGap + myWidth / myXScale ); + rect->setBottom( myRect->bottom() - myYGap - myHeight / myYScale ); + + return rect; +} + +GLboolean GLViewer_TextObject::highlight( GLfloat theX, GLfloat theY, GLfloat theTol, GLboolean isCircle ) +{ + if( !myIsVisible ) + return false; + + float xPos, yPos; + myGLText->getPosition( xPos, yPos ); + + QRect aRect; + aRect.setLeft( (int)xPos ); + aRect.setRight( (int)(xPos + myWidth / myXScale) ); + aRect.setTop( (int)yPos );// - myHeight / myYScale ); + aRect.setBottom( (int)(yPos + myHeight / myYScale) ); + + //cout << "theX: " << theX << " theY: " << theY << endl; + //cout << "aRect.left(): " << aRect.left() << " aRect.right(): " << aRect.right() << endl; + //cout << "aRect.top(): " << aRect.top() << " aRect.bottom(): " << aRect.bottom() << endl; + + QRegion obj( aRect ); + QRegion intersection; + QRect region; + + region.setLeft( (int)(theX - theTol) ); + region.setRight( (int)(theX + theTol) ); + region.setTop( (int)(theY - theTol) ); + region.setBottom( (int)(theY + theTol) ); + + QRegion circle( (int)(theX - theTol), (int)(theY - theTol), + (int)(2 * theTol), (int)(2 * theTol), QRegion::Ellipse ); + if( isCircle ) + intersection = obj.intersect( circle ); + else + intersection = obj.intersect( region ); + + if( intersection.isEmpty() ) + myIsHigh = false; + else + myIsHigh = true; + + if( !myHighFlag && myIsHigh ) + myIsHigh = GL_FALSE; + else + myHighFlag = GL_TRUE; + + return myIsHigh; +} + +GLboolean GLViewer_TextObject::unhighlight() +{ + if( myIsHigh ) + { + myIsHigh = GL_FALSE; + return GL_TRUE; + } + + return GL_FALSE; +} + +GLboolean GLViewer_TextObject::select( GLfloat theX, GLfloat theY, GLfloat theTol, GLViewer_Rect rect, + GLboolean isFull, GLboolean isCircle, GLboolean isShift ) +{ + if( !myIsVisible ) + return false; + + QRegion obj( myRect->toQRect() ); + QRegion intersection; + QRect region; + + region.setLeft( (int)(theX - theTol) ); + region.setRight( (int)(theX + theTol) ); + region.setTop( (int)(theY - theTol) ); + region.setBottom( (int)(theY + theTol) ); + + QRegion circle( (int)(theX - theTol), (int)(theY - theTol), + (int)(2 * theTol), (int)(2 * theTol), QRegion::Ellipse ); + if( isCircle ) + intersection = obj.intersect( circle ); + else + intersection = obj.intersect( region ); + + if( intersection.isEmpty() ) + myIsSel = false; + else + myIsSel = true; + + if ( myIsSel ) + { + myHighFlag = GL_FALSE; + myIsHigh = GL_FALSE; + } + else + myHighFlag = GL_TRUE; + + return myIsSel; +} + +GLboolean GLViewer_TextObject::unselect() +{ + if( myIsSel ) + { + myIsSel = GL_FALSE; + return GL_TRUE; + } + + return GL_FALSE; +} + +void GLViewer_TextObject::moveObject( float theX, float theY, bool fromGroup ) +{ + if( !fromGroup && myGroup) + { + myGroup->dragingObjects( theX, theY ); + return; + } + float aX, anY; + myGLText->getPosition( aX, anY ); + aX += theX; + anY += theY; + myGLText->setPosition( aX, anY ); + compute(); +} + +QByteArray GLViewer_TextObject::getByteCopy() +{ + QByteArray aObject = GLViewer_Object::getByteCopy(); + + return aObject; +} + +bool GLViewer_TextObject::initializeFromByteCopy( QByteArray theArray ) +{ + if( !GLViewer_Object::initializeFromByteCopy( theArray ) || myType != "GLViewer_TextObject" ) + return false; + + myHighFlag = true; + return true; +} diff --git a/src/GLViewer/GLViewer_BaseObjects.h b/src/GLViewer/GLViewer_BaseObjects.h new file mode 100644 index 000000000..6e464ef04 --- /dev/null +++ b/src/GLViewer/GLViewer_BaseObjects.h @@ -0,0 +1,256 @@ +// Copyright (C) 2005 OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// Author : OPEN CASCADE +// + +// File: GLViewer_BaseObjects.h +// Created: November, 2004 + +#ifndef GLVIEWER_BASEOBJECTS_H +#define GLVIEWER_BASEOBJECTS_H + +#include "GLViewer.h" +#include "GLViewer_Object.h" + +#include +#include + +#include + +#ifdef WNT +#pragma warning( disable:4251 ) +#endif + +/*! + * Class GLViewer_MarkerSet + * OpenGL MarkerSet + */ + +class GLVIEWER_API GLViewer_MarkerSet : public GLViewer_Object +{ +public: + //! A constructor + GLViewer_MarkerSet( int number = 1, float size = 5.0, const QString& toolTip = "GLMarker" ); + //! A destructor + ~GLViewer_MarkerSet(); + + // redefined methods + virtual void compute(); + virtual GLViewer_Drawer* createDrawer(); + + virtual GLboolean highlight( GLfloat x, GLfloat y, GLfloat tol = 15.0, GLboolean isCircle = GL_FALSE ); + virtual GLboolean unhighlight(); + virtual GLboolean select( GLfloat x, GLfloat y, GLfloat tol, GLViewer_Rect rect, GLboolean isFull = GL_FALSE, + GLboolean isCircle = GL_FALSE, GLboolean isShift = GL_FALSE ); + virtual GLboolean unselect(); + + virtual GLViewer_Rect* getUpdateRect(); + + virtual void moveObject( float, float, bool fromGroup = false ); + + virtual QByteArray getByteCopy(); + virtual bool initializeFromByteCopy( QByteArray ); + + virtual bool translateToPS( QFile& hFile, GLViewer_CoordSystem* aViewerCS, GLViewer_CoordSystem* aPSCS ); + virtual bool translateToHPGL( QFile& hFile, GLViewer_CoordSystem* aViewerCS, GLViewer_CoordSystem* aHPGLCS ); + +#ifdef WIN32 + virtual bool translateToEMF( HDC dc, GLViewer_CoordSystem* aViewerCS, GLViewer_CoordSystem* aEMFCS ); +#endif + + //! Sets array of x coords of markers + void setXCoord( GLfloat* xCoord, int size ); + //! Sets array of y coords of markers + void setYCoord( GLfloat* yCoord, int size ); + //! Returns x coords + GLfloat* getXCoord() const { return myXCoord; } + //! Returns y coords + GLfloat* getYCoord() const { return myYCoord; } + + //! Sets markers number + void setNumMarkers( GLint ); + //! returns markers number + GLint getNumMarkers() const { return myNumber; }; + //! Sets merker radius + void setMarkerSize( const float size ) { myMarkerSize = size; } + //! Returns merker radius + float getMarkerSize() const { return myMarkerSize; } + + //! Export numbers of heghlighted/selected markers + void exportNumbers( QValueList& high, QValueList& unhigh, + QValueList& sel, QValueList& unsel ); + + //! Returns selected numbers + QValueList getSelectedElements() { return mySelNumbers; } + //! Adds or remove selected number + bool addOrRemoveSelected( int index ); + //! Adds selected numbers + void addSelected( const TColStd_SequenceOfInteger& ); + //! Sets selected nembers + void setSelected( const TColStd_SequenceOfInteger& ); + +protected: + GLint myNumber; + GLfloat* myXCoord; + GLfloat* myYCoord; + GLfloat myMarkerSize; + QValueList myHNumbers; + QValueList myUHNumbers; + QValueList mySelNumbers; + QValueList myCurSelNumbers; + QValueList myUSelNumbers; + QValueList myPrevHNumbers; + TColStd_SequenceOfInteger mySelectedIndexes; +}; + +/*! + * Class GLViewer_Polyline + * OpenGL Polyline + */ + +class GLVIEWER_API GLViewer_Polyline: public GLViewer_Object +{ +public: + GLViewer_Polyline( int number = 1, float size = 5.0, const QString& toolTip = "GLPolyline" ); + ~GLViewer_Polyline(); + + // redefined methods + virtual void compute(); + virtual GLViewer_Drawer* createDrawer(); + + virtual GLboolean highlight( GLfloat x, GLfloat y, GLfloat tol = 15.0, GLboolean isCircle = GL_FALSE ); + virtual GLboolean unhighlight(); + virtual GLboolean select( GLfloat x, GLfloat y, GLfloat tol, GLViewer_Rect rect, GLboolean isFull = GL_FALSE, + GLboolean isCircle = GL_FALSE, GLboolean isShift = GL_FALSE ); + virtual GLboolean unselect(); + + virtual GLViewer_Rect* getUpdateRect(); + + virtual void moveObject( float, float, bool fromGroup = false ); + + virtual QByteArray getByteCopy(); + virtual bool initializeFromByteCopy( QByteArray ); + + virtual bool translateToPS( QFile& hFile, GLViewer_CoordSystem* aViewerCS, GLViewer_CoordSystem* aPSCS ); + virtual bool translateToHPGL( QFile& hFile, GLViewer_CoordSystem* aViewerCS, GLViewer_CoordSystem* aHPGLCS ); + +#ifdef WIN32 + virtual bool translateToEMF( HDC dc, GLViewer_CoordSystem* aViewerCS, GLViewer_CoordSystem* aEMFCS ); +#endif + + //! Sets array of x coords of points + void setXCoord( GLfloat* xCoord, int size ); + //! Sets array of y coords of points + void setYCoord( GLfloat* yCoord, int size ); + //! Returns x coords + GLfloat* getXCoord() const { return myXCoord; } + //! Returns y coords + GLfloat* getYCoord() const { return myYCoord; } + + //! SetS number of points + void setNumber( GLint ); + //! Returns number of points + GLint getNumber() const { return myNumber; }; + + //! On/off closed status of polyline + void setClosed( GLboolean closed ) { myIsClosed = closed; } + //! Checks closed status of polyline + GLboolean isClosed() const { return myIsClosed; } + + //! On/off highlight as whole object status + void setHighSelAll( GLboolean highSelAll ) { myHighSelAll = highSelAll; } + //! Checks highlight as whole object status + GLboolean isHighSelAll() const { return myHighSelAll; } + + //! Export numbers of heghlighted/selected lines + void exportNumbers( QValueList& high, QValueList& unhigh, + QValueList& sel, QValueList& unsel ); + + //! Returns numbers of selected lines + QValueList getSelectedElements() { return mySelNumbers; } + +protected: + GLfloat* myXCoord; + GLfloat* myYCoord; + GLint myNumber; + GLboolean myIsClosed; + GLboolean myHighSelAll; + + QValueList myHNumbers; + QValueList myUHNumbers; + QValueList mySelNumbers; + QValueList myUSelNumbers; + QValueList myCurSelNumbers; + QValueList myPrevHNumbers; + TColStd_SequenceOfInteger mySelectedIndexes; + + GLboolean myHighFlag; +}; + +// Class: GLViewer_TextObject +// Descr: Text as Object for OpenGL + +class GLVIEWER_API GLViewer_TextObject : public GLViewer_Object +{ +public: + GLViewer_TextObject( const QString&, float xPos = 0, float yPos = 0, + const QColor& color = QColor( 0, 255, 0 ), const QString& toolTip = "GLText" ); + ~GLViewer_TextObject(); + + virtual void compute(); + virtual GLViewer_Drawer* createDrawer(); + + virtual void setDrawer( GLViewer_Drawer* theDrawer ); + + virtual GLboolean highlight( GLfloat x, GLfloat y, GLfloat tol, GLboolean isCircle = GL_FALSE ); + virtual GLboolean unhighlight(); + virtual GLboolean select( GLfloat x, GLfloat y, GLfloat tol, GLViewer_Rect rect, GLboolean isFull = GL_FALSE, + GLboolean isCircle = GL_FALSE, GLboolean isShift = GL_FALSE ); + virtual GLboolean unselect(); + + virtual GLViewer_Rect* getUpdateRect(); + + virtual void moveObject( float, float, bool fromGroup = false ); + + virtual QByteArray getByteCopy(); + virtual bool initializeFromByteCopy( QByteArray ); + + virtual bool translateToPS( QFile& hFile, GLViewer_CoordSystem* aViewerCS, GLViewer_CoordSystem* aPSCS ); + virtual bool translateToHPGL( QFile& hFile, GLViewer_CoordSystem* aViewerCS, GLViewer_CoordSystem* aHPGLCS ); + +#ifdef WIN32 + virtual bool translateToEMF( HDC dc, GLViewer_CoordSystem* aViewerCS, GLViewer_CoordSystem* aEMFCS ); +#endif + + int getWidth(){ return myWidth; } + int getHeight(){ return myWidth; } + void setWidth( int w ){ myWidth=w; } + void setHeight( int h ){ myHeight=h; } + +protected: + bool myHighFlag; + int myWidth; + int myHeight; +}; + +#ifdef WNT +#pragma warning ( default:4251 ) +#endif + +#endif diff --git a/src/GLViewer/GLViewer_Compass.cxx b/src/GLViewer/GLViewer_Compass.cxx new file mode 100644 index 000000000..919641e7c --- /dev/null +++ b/src/GLViewer/GLViewer_Compass.cxx @@ -0,0 +1,160 @@ +// Copyright (C) 2005 OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// Author : OPEN CASCADE +// + +// File: GLViewer_Compass.cxx +// Created: November, 2004 + +//================================================================ +// Class : GLViewer_Compass +// Description : Class implement representatiof of compass in one of corner in GLViewer +//================================================================ + +#include "GLViewer_Compass.h" +#include "GLViewer_Drawer.h" + +//======================================================================= +// Function: GLViewer_Compass +// Purpose : +//======================================================================= +GLViewer_Compass::GLViewer_Compass ( const QColor& color, const int size, const Position pos, + const int WidthTop, const int WidthBottom, const int HeightTop, + const int HeightBottom ) +{ + myCol = color; + mySize = size; + myPos = pos; + myArrowWidthTop = WidthTop; + myArrowWidthBottom = WidthBottom; + myArrowHeightTop = HeightTop; + myArrowHeightBottom = HeightBottom; + myIsVisible = true; + QFont* aFont = new QFont("Times",16); + myFont = new GLViewer_TexFont( aFont ); + isGenereted = false; + //myFont->generateTexture(); +} + +//======================================================================= +// Function: ~GLViewer_Compass +// Purpose : +//======================================================================= +GLViewer_Compass::~GLViewer_Compass() +{ + delete myFont; +} + +//======================================================================= +// Function: setCompass +// Purpose : +//======================================================================= +void GLViewer_Compass::setCompass( const QColor& color, const int size, const Position pos ) +{ + myCol = color; + mySize = size; + myPos = pos; +} + +//======================================================================= +// Function: setVisible +// Purpose : +//======================================================================= +void GLViewer_Compass::setVisible( const bool vis ) +{ + myIsVisible = vis; +} + +//======================================================================= +// Function: setSize +// Purpose : +//======================================================================= +void GLViewer_Compass::setSize( const int size ) +{ + if( size > 0 ) + mySize=size; +} + +//======================================================================= +// Function: setArrowWidthTop +// Purpose : +//======================================================================= +void GLViewer_Compass::setArrowWidthTop( const int WidthTop ) +{ + if( WidthTop < myArrowWidthBottom || WidthTop > mySize ) + return; + myArrowWidthTop=WidthTop; +} + +//======================================================================= +// Function: setArrowWidthBottom +// Purpose : +//======================================================================= +void GLViewer_Compass::setArrowWidthBottom( const int WidthBot ) +{ + if( WidthBot > myArrowWidthTop || WidthBot < 1 ) + return; + myArrowWidthBottom=WidthBot; +} + +//======================================================================= +// Function: setArrowHeightTop +// Purpose : +//======================================================================= +void GLViewer_Compass::setArrowHeightTop( const int HeightTop ) +{ + if( HeightTop > (2*mySize-myArrowHeightBottom ) || HeightTop < 1 ) + return; + myArrowHeightTop=HeightTop; +} + +//======================================================================= +// Function: setArrowHeightBottom +// Purpose : +//======================================================================= +void GLViewer_Compass::setArrowHeightBottom( const int HeightBot ) +{ + if( HeightBot > ( 2*mySize-myArrowHeightTop ) || HeightBot < 1) + return; + myArrowHeightBottom=HeightBot; +} + +//======================================================================= +// Function: getFont +// Purpose : +//======================================================================= +GLViewer_TexFont* GLViewer_Compass::getFont() +{ + if(!isGenereted) + { + myFont->generateTexture(); + isGenereted = true; + } + return myFont; +} + +//======================================================================= +// Function: setFont +// Purpose : +//======================================================================= +void GLViewer_Compass::setFont( QFont theFont ) +{ + delete myFont; + myFont = new GLViewer_TexFont( &theFont ); +} diff --git a/src/GLViewer/GLViewer_Compass.h b/src/GLViewer/GLViewer_Compass.h new file mode 100644 index 000000000..abdec0e01 --- /dev/null +++ b/src/GLViewer/GLViewer_Compass.h @@ -0,0 +1,150 @@ +// Copyright (C) 2005 OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// Author : OPEN CASCADE +// + +// File: GLViewer_Compass.h +// Created: November, 2004 + +#ifndef GLVIEWER_COMPASS_H +#define GLVIEWER_COMPASS_H + +#include "GLViewer.h" + +#include + +#ifdef WNT +#pragma warning( disable:4251 ) +#endif + +/*! Class GLViewer_Compass + * Class implement representatiof of compass in one of corner in GLViewer. + * Compass it's a some round visual pointer rotated with view window and + * located in fixed place (in one fixed corner) + */ + +class GLViewer_TexFont; + +class GLVIEWER_API GLViewer_Compass +{ +public: + //! Position of compass + enum Position + { + TopLeft, + TopRight, + BottomLeft, + BottomRight + }; + + //! A constructor + /*! + *\param color - a color of compass + *\param size - a diameter of compass + *\param pos - a position + *\param WidthTop - width of wide part of arrow + *\param WidthBottom - width of base part of arrow + *\param HeightTop - height of arrow header + *\param HeightBottom - height of arrow cut on bottom + */ + GLViewer_Compass( const QColor& color = QColor ( 0, 255, 0 ), + const int size = 60, + const Position pos = TopRight, + const int WidthTop = 20, + const int WidthBottom = 10, + const int HeightTop = 25, + const int HeightBottom = 7 ); + //! A destructor + ~GLViewer_Compass(); + + //! A function installing main parameters of compass + void setCompass( const QColor& color, const int size, const Position pos ); + //! A function installing a visible status + void setVisible( const bool vis = true ); + //! Returns visible status + bool getVisible(){ return myIsVisible; }; + + //! A function installing diameter + void setSize( const int size ); + //! Returns diameter + int getSize(){ return mySize; } + + //! A function installing position + void setPos( const Position pos ){ myPos = pos; } + //! Returns position + int getPos(){ return myPos; } + + //! A function installing color + void setColor( const QColor& color ){ myCol = color; } + //! Returns color + QColor getColor(){ return myCol; } + + //! A function installing width of wide part of arrow + void setArrowWidthTop( const int WidthTop ); + //! Returns width of wide part of arrow + int getArrowWidthTop(){ return myArrowWidthTop; } + + //! A function installing width of base part of arrow + void setArrowWidthBottom( const int WidthBot ); + //! Returns width of base part of arrow + int getArrowWidthBottom(){return myArrowWidthBottom;}; + + //! A function installing height of arrow header + void setArrowHeightTop( const int HeightTop ); + //! Returns height of arrow header + int getArrowHeightTop(){return myArrowHeightTop;}; + + //! A function installing height of arrow cut on bottom + void setArrowHeightBottom( const int HeightBot ); + //! Returns height of arrow cut on bottom + int getArrowHeightBottom(){return myArrowHeightBottom;}; + + //! A function installing + void setFont( QFont theFont ); + //! Returns + GLViewer_TexFont* getFont(); + +protected: + //! Compass color + QColor myCol; + //! Compass diameter + int mySize; + //! Compass position + int myPos; + //! Compass invisible status + bool myIsVisible; + //! Width of wide part of arrow + int myArrowWidthTop; + //! Width of base part of arrow + int myArrowWidthBottom; + //! Height of arrow header + int myArrowHeightTop; + //! Height of arrow cut on bottom + int myArrowHeightBottom; + //! Compass font + GLViewer_TexFont* myFont; + //! Status of generated font + bool isGenereted; +}; + +#ifdef WNT +#pragma warning ( default:4251 ) +#endif + +#endif diff --git a/src/GLViewer/GLViewer_Context.h b/src/GLViewer/GLViewer_Context.h new file mode 100644 index 000000000..f8c76eb50 --- /dev/null +++ b/src/GLViewer/GLViewer_Context.h @@ -0,0 +1,211 @@ +// Copyright (C) 2005 OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// Author : OPEN CASCADE +// + +// File: GLViewer_Context.h +// Created: November, 2004 + + +/*! Class GLViewer_Context + * Class for manage of presentations in GLViewer + */ + +#ifndef GLVIEWER_CONTEXT_H +#define GLVIEWER_CONTEXT_H + +#ifdef WNT +#include "windows.h" +#endif + +#include "GLViewer_Defs.h" +#include "GLViewer_Object.h" + +#include +#include +#include + +#include +#include + +#include + +class GLViewer_Viewer2d; + +#ifdef WNT +#pragma warning( disable:4251 ) +#endif + +class GLVIEWER_API GLViewer_Context +{ +public: + //! A constructor + GLViewer_Context( GLViewer_Viewer2d* ); + //! A desructor + ~GLViewer_Context(); + + //! A function installing update flag in highlighting technology + void setUpdateAll( bool on ) { myUpdateAll = on; } + //! Returns update flag in highlighting technology + bool isUpdateAll() const { return myUpdateAll; } + + //! Main interactive method. Trace mouse in viewer window + /*! + *\param x - X coord of mouse cursor + *\param y - Y coord of mouse cursor + *\paran byCircle - true if needs round sensitive area around mouse cursor, else rectangle + *function search object rectangle which intersect with sensitive area and call object highlight method + */ + int MoveTo( int x, int y, bool byCircle = FALSE ); + //! A function selecting already highlighting object by calling object method select + /*! + *\param Append - true if new selection will be append to existing selection, false - another + *\param byCircle - true if needs round selection area in complex object + */ + int Select( bool Append = FALSE, bool byCircle = FALSE ); + //! A function selecting objects on scene by rectangle + /*! + *\param theRect - rectangle of selection + *\param Append - true if new selection will be append to existing selection, false - another + *function search object rectangle which intersect with theRect and call object select method + */ + int SelectByRect( const QRect& theRect, bool Append = FALSE ); + + //! A function installing highlight color for all presentation (does not work) + void SetHighlightColor( Quantity_NameOfColor aCol ); + //! A function installing select color for all presentation (does not work) + void SetSelectionColor( Quantity_NameOfColor aCol ); + //! Returns highlight color + Quantity_NameOfColor HighlightColor() { return myHighlightColor; } + //! Returns select color + Quantity_NameOfColor SelectionColor() { return mySelectionColor; } + + //! Returns number of objects in current selection + int NbSelected(); + //! A function set iterator of selected objects on first object + void InitSelected(); + //! Retuns true if iterator of selected objects is not set on last object + bool MoreSelected(); + //! Increment of iterator of selected objects + bool NextSelected(); + //! Returns object corresponding the current iterator of selected objects + GLViewer_Object* SelectedObject(); + + //! Returns true if theObject is selected + bool isSelected( GLViewer_Object* theObject ); + + //! Insert new object in context + /*! + *\param theObject - inserting object + *\param display - true if needs display object immediatly after inserting, else false + *\param isActive - true if needs inserting object in active list + */ + int insertObject( GLViewer_Object* theObject, bool display = false, bool isActive = true ); + //! Replacing objects in context + /*! + * Function search activ and incative objects + */ + bool replaceObject( GLViewer_Object* oldObject, GLViewer_Object* newObject ); + //! A function updating scales of all objects in context + void updateScales( GLfloat theX, GLfloat theY ); + //! A function installing tolerance in window pixels for highlghting and selection methods + void setTolerance( int tol ) { myTolerance = tol; } + + //! Returns list of context objects + /*! + * Returns active objects if isActive = true, else inactive objects + */ + const ObjList& getObjects( bool isActive = true ) + { return isActive ? myActiveObjects : myInactiveObjects; } + + //! Returns first active object + GLViewer_Object* getFirstObject() { return *( myActiveObjects.begin() ); } + + //! A function clear highlighted object information + void clearHighlighted( bool updateViewer ); + //! A function clear selection object information + void clearSelected( bool updateViewer ); + //! A function make theObject as selected object and update viewer if updateViewer = true + void setSelected( GLViewer_Object* theObject, bool updateViewer ); + //! A function make theObject as unselected object and update viewer if updateViewer = true + void remSelected( GLViewer_Object* theObject, bool updateViewer ); + + //! Returns highlighted object + GLViewer_Object* getCurrentObject() { return myLastPicked; } + //! Returns true if after last MoveTo method calling highlight object is changed + bool currentObjectIsChanged() { return myLastPickedChanged; } + + //! A function installing to theObject invisible status and update viewer if updateViewer = true + void eraseObject( GLViewer_Object* theObject, bool updateViewer = true ); + //! A function remove theObject from context and update viewer if updateViewer = true + void deleteObject( GLViewer_Object* theObject, bool updateViewer = true ); + + //! A function installing to theObject active status + bool setActive( GLViewer_Object* theObject ); + //! A function installing to theObject inactive status + bool setInactive( GLViewer_Object* theObject ); + +protected: + //! Flag of updating viewer after highlight + /*! + * if = true, the viewer update all objects after change of highlight object, + * else - only highlight object + */ + bool myUpdateAll; + + GLViewer_Viewer2d* myGLViewer2d; + //! Highlighted object + GLViewer_Object* myLastPicked; + //! = true if after last MoveTo method calling highlight object is changed + bool myLastPickedChanged; + + //! List of active object + /*!Active objects if consider in highlight and select methods*/ + ObjList myActiveObjects; + //! List of inactive object + /*!Active objects isn't consider in highlight and select methods*/ + ObjList myInactiveObjects; + + //! List of selected objects + ObjList mySelectedObjects; + //! Selected object iterator + int mySelCurIndex; + + //! X coordinate of mouse cursor + GLfloat myXhigh; + //! Y coordinate of mouse cursor + GLfloat myYhigh; + + //! Color for highlight + Quantity_NameOfColor myHighlightColor; + //! Color for selection + Quantity_NameOfColor mySelectionColor; + //! If = false - moveTo method is not any highlighting + GLboolean myHFlag; + //! If = false - select method is not any select + GLboolean mySFlag; + //! Tolerance in window pixels for highlghting and selection methods + int myTolerance; +}; + +#ifdef WNT +#pragma warning ( default:4251 ) +#endif + +#endif diff --git a/src/GLViewer/GLViewer_CoordSystem.cxx b/src/GLViewer/GLViewer_CoordSystem.cxx new file mode 100644 index 000000000..947ac6036 --- /dev/null +++ b/src/GLViewer/GLViewer_CoordSystem.cxx @@ -0,0 +1,206 @@ +// Copyright (C) 2005 OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// Author : OPEN CASCADE +// + +// File: GLViewer_Context.cxx +// Created: November, 2004 + +//================================================================ +// Class : GLViewer_CoordSystem +// Description : Class implementing mathematical model of 2D coordinate system +//================================================================ +#include "GLViewer_CoordSystem.h" +#include + +//======================================================================= +// Function: GLViewer_CoordSystem +// Purpose : +//======================================================================= +GLViewer_CoordSystem::GLViewer_CoordSystem( CSType aType, double X0, double Y0, + double XUnit, double YUnit, double Rotation ) +{ + setType( aType ); + setOrigin( X0, Y0 ); + setUnits( XUnit, YUnit ); + setRotation( Rotation ); +} + +//======================================================================= +// Function: getOrigin +// Purpose : +//======================================================================= +void GLViewer_CoordSystem::getOrigin( double& x, double& y ) const +{ + x = myX0; + y = myY0; +} + +//======================================================================= +// Function: setOrigin +// Purpose : +//======================================================================= +void GLViewer_CoordSystem::setOrigin( double x, double y ) +{ + myX0 = x; + myY0 = y; +} + +//======================================================================= +// Function: getUnits +// Purpose : +//======================================================================= +void GLViewer_CoordSystem::getUnits( double& x, double& y ) const +{ + x = myXUnit; + y = myYUnit; +} + +//======================================================================= +// Function: setUnits +// Purpose : +//======================================================================= +void GLViewer_CoordSystem::setUnits( double x, double y ) +{ + if( x>0 ) + myXUnit = x; + else + myXUnit = 1.0; + + if( y>0 ) + myYUnit = y; + else + myYUnit = 1.0; +} +//======================================================================= +// Function: getRotation +// Purpose : +//======================================================================= +double GLViewer_CoordSystem::getRotation() const +{ + return myRotation; +} + +//======================================================================= +// Function: setRotation +// Purpose : +//======================================================================= +void GLViewer_CoordSystem::setRotation( double rotation ) +{ + myRotation = rotation; +} + +//======================================================================= +// Function: getType +// Purpose : +//======================================================================= +GLViewer_CoordSystem::CSType GLViewer_CoordSystem::getType() const +{ + return myType; +} + +//======================================================================= +// Function: setType +// Purpose : +//======================================================================= +void GLViewer_CoordSystem::setType( CSType type ) +{ + myType = type; +} + +//======================================================================= +// Function: toReference +// Purpose : +//======================================================================= +void GLViewer_CoordSystem::toReference( double& x, double& y ) +{ + if( myType==Cartesian ) + { + double newx = myX0 + myXUnit*x*cos(myRotation) - myYUnit*y*sin(myRotation), + newy = myY0 + myXUnit*x*sin(myRotation) + myYUnit*y*cos(myRotation); + x = newx; + y = newy; + } + else if( myType==Polar ) + { + double r = x, phi = y; + x = myX0 + myXUnit*r*cos(phi+myRotation); + y = myY0 + myXUnit*r*sin(phi+myRotation); + } +} + +//======================================================================= +// Function: fromReference +// Purpose : +//======================================================================= +void GLViewer_CoordSystem::fromReference( double& x, double& y ) +{ + x = (x - myX0) / myXUnit; + y = (y - myY0) / myYUnit; + + if( myType==Cartesian ) + { + double newx = x*cos(myRotation) + y*sin(myRotation), + newy = -x*sin(myRotation) + y*cos(myRotation); + x = newx; + y = newy; + } + else if( myType==Polar ) + { + double r = sqrt( x*x+y*y ); + double phi = 0.0; + double eps = 1E-8, pi = 3.14159265; + + if( r>eps ) + if( fabs(x)>eps ) + { + double arg = y/x; + phi = atan(arg); + if( x<0 ) // 2-nd or 4-rd quarter + phi+=pi; + } + else if( y>0 ) + phi = pi/2.0; + else + phi = 3*pi/2.0; + + x = r; + y = phi-myRotation; + } +} + +//======================================================================= +// Function: transform +// Purpose : +//======================================================================= +void GLViewer_CoordSystem::transform( GLViewer_CoordSystem& aSystem, double& x, double& y ) +{ + toReference( x, y ); + aSystem.fromReference( x, y ); +} + +//======================================================================= +// Function: getStretching +// Purpose : +//======================================================================= +void GLViewer_CoordSystem::getStretching( GLViewer_CoordSystem& aSystem, double& theX, double& theY ) +{ + theX = myXUnit / aSystem.myXUnit; + theY = myYUnit / aSystem.myYUnit; +} diff --git a/src/GLViewer/GLViewer_CoordSystem.h b/src/GLViewer/GLViewer_CoordSystem.h new file mode 100644 index 000000000..ca571daab --- /dev/null +++ b/src/GLViewer/GLViewer_CoordSystem.h @@ -0,0 +1,103 @@ +// Copyright (C) 2005 OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// Author : OPEN CASCADE +// + +// File: GLViewer_CoordSystem.h +// Created: November, 2004 + +/*! Class GLViewer_CoordSystem + * Class implementing mathematical model of 2D coordinate system + */ + +#ifndef GLVIEWER_COORDSYSTEM_H +#define GLVIEWER_COORDSYSTEM_H + +#include "GLViewer.h" + +#ifdef WNT +#pragma warning( disable:4251 ) +#endif + +class GLVIEWER_API GLViewer_CoordSystem +{ +public: + //! A type of coordinate system + enum CSType + { + Cartesian, + Polar + }; + +private: + //! The coordinates of origin in the reference CS + double myX0, myY0; + //! The lengths of axis units in the reference unit + double myXUnit, myYUnit; + //! The rotation in radians relative to reference CS + double myRotation; + + //! In the polar CS myYUnit is ignored, but myXUnit is the unit of polar radius + CSType myType; + +public: + //! A constructor ( by default new system is identical to reference ) + GLViewer_CoordSystem( CSType aType, double X0 = 0.0, double Y0 = 0.0, + double XUnit = 1.0, double YUnit = 1.0, double Rotation = 0.0 ); + + //! Returns the origin in reference system + void getOrigin( double& x, double& y ) const; + //! A function installing the origin in reference system + void setOrigin( double x, double y ); + + //! Returns units along axes + void getUnits( double& x, double& y ) const; + //! A function installing units along axes + void setUnits( double x, double y ); + + //! Returns rotation angle of axes in reference system + double getRotation() const; + //! A function installing rotation angle of axes in reference system + void setRotation( double rotation ); + + //! Returns type of system + CSType getType() const; + //! A function installing type of system + void setType( CSType type ); + + //! Transform the coordinates x, y from current CS to aSystem + void transform( GLViewer_CoordSystem& aSystem, double& x, double& y ); + + + //! Return how many times line width in aSystem system bigger than in current + virtual void getStretching( GLViewer_CoordSystem& aSystem, double& theX, double& theY ); + + +protected: + //! A function transforms system coords to coords in reference system + virtual void toReference( double& x, double& y ); + //! A function transforms from coords in reference system to system coords + virtual void fromReference( double& x, double& y ); +}; + +#ifdef WNT +#pragma warning ( default:4251 ) +#endif + +#endif diff --git a/src/GLViewer/GLViewer_Defs.h b/src/GLViewer/GLViewer_Defs.h new file mode 100644 index 000000000..68d1f7d3f --- /dev/null +++ b/src/GLViewer/GLViewer_Defs.h @@ -0,0 +1,66 @@ +// Copyright (C) 2005 OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// Author : OPEN CASCADE +// + +// File: GLViewer_Defs.h +// Created: March, 2005 + +#ifndef GLVIEWER_DEFS_H +#define GLVIEWER_DEFS_H + +#include +#include + +class GLViewer_Object; +//Selection staus +enum SelectionChangeStatus +{ + SCS_Invalid, + SCS_Local, + SCS_Global +}; + +//! Fit Selection Rectangle +static const int SELECTION_RECT_GAP = 50; + +//! Display Text Format of Objects +enum DisplayTextFormat +{ + DTF_TEXTURE = 0, + DTF_TEXTURE_SCALABLE = 1, + DTF_BITMAP = 2 +}; + +enum SelectionStatus +{ + SS_Invalid, + SS_LocalChanged, + SS_GlobalChanged, + SS_NoChanged +}; + +typedef QMap ObjectMap; +typedef QValueList ObjList; + +#define SEGMENTS 32 +#define PI 3.14159265359 +#define STEP ( float )( 2 * PI / SEGMENTS ) + +#endif// GLVIEWER_DEFS_H diff --git a/src/GLViewer/GLViewer_Geom.cxx b/src/GLViewer/GLViewer_Geom.cxx new file mode 100644 index 000000000..cd0ef5cae --- /dev/null +++ b/src/GLViewer/GLViewer_Geom.cxx @@ -0,0 +1,249 @@ +// Copyright (C) 2005 OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// Author : OPEN CASCADE +// + +/*************************************************************************** +** Class: GLViewer_Geom +** Descr: +** Module: GLViewer +** Created: UI team, 16.11.04 +****************************************************************************/ + +//#include +#include + +#define FAR_POINT 1e10 // Value used as a "very distant" co-ordinate +#define TOLERANCE 1e-3 + +//================================================================ +// Function : GLViewer_Segment +// Purpose : constructs a real segment bounded by two points +//================================================================ +GLViewer_Segment::GLViewer_Segment( const GLViewer_Pnt& thePnt1, + const GLViewer_Pnt& thePnt2 ) +: myPnt1( thePnt1 ), + myPnt2( thePnt2 ) +{ + myA = myPnt1.y() - myPnt2.y(); + myB = myPnt2.x() - myPnt1.x(); + myC = myPnt1.x() * myPnt2.y() - myPnt2.x() * myPnt1.y(); +} + +//================================================================ +// Function : GLViewer_Segment +// Purpose : constructs a ray starting at and directed +// along positive X axis direction (or Y axis if vertical ) +//================================================================ +GLViewer_Segment::GLViewer_Segment( const GLViewer_Pnt& thePnt, + const GLfloat theA, + const GLfloat theB, + const GLfloat theC ) +: myPnt1( thePnt ), + myA( theA ), + myB( theB ), + myC( theC ) +{ + if ( fabs( myB ) < TOLERANCE ) + myPnt2 = GLViewer_Pnt( myPnt1.x(), FAR_POINT ); + else + myPnt2 = GLViewer_Pnt( FAR_POINT, - myA / myB * FAR_POINT - myC / myB ); +} + +//================================================================ +// Function : GLViewer_Segment +// Purpose : destructor, does nothing +//================================================================ +GLViewer_Segment::~GLViewer_Segment() +{ +} + +//================================================================ +// Function : HasIntersection +// Purpose : detects intersection with segment +//================================================================ +bool GLViewer_Segment::HasIntersection( const GLViewer_Segment& theOther ) const +{ + bool aRes = false; + GLfloat aDiv = myA * theOther.myB - myB * theOther.myA; + if ( fabs( aDiv ) > TOLERANCE ) + { + GLfloat aX = ( myB * theOther.myC - theOther.myB * myC ) / aDiv; + GLfloat aX11 = myPnt1.x() > myPnt2.x() ? myPnt2.x() : myPnt1.x(); + GLfloat aX12 = myPnt1.x() > myPnt2.x() ? myPnt1.x() : myPnt2.x(); + GLfloat aX21 = theOther.myPnt1.x() > theOther.myPnt2.x() ? theOther.myPnt2.x() : theOther.myPnt1.x(); + GLfloat aX22 = theOther.myPnt1.x() > theOther.myPnt2.x() ? theOther.myPnt1.x() : theOther.myPnt2.x(); + + GLfloat aY = ( myC * theOther.myA - theOther.myC * myA ) / aDiv; + GLfloat aY11 = myPnt1.y() > myPnt2.y() ? myPnt2.y() : myPnt1.y(); + GLfloat aY12 = myPnt1.y() > myPnt2.y() ? myPnt1.y() : myPnt2.y(); + GLfloat aY21 = theOther.myPnt1.y() > theOther.myPnt2.y() ? theOther.myPnt2.y() : theOther.myPnt1.y(); + GLfloat aY22 = theOther.myPnt1.y() > theOther.myPnt2.y() ? theOther.myPnt1.y() : theOther.myPnt2.y(); + + if ( fabs( aX11 - aX12 ) > TOLERANCE ) + aRes = aX11 < aX && aX < aX12; + else + aRes = aY11 < aY && aY < aY12; + + if ( aRes ) + { + if ( fabs( aX21 - aX22 ) > TOLERANCE ) + aRes = aX21 < aX && aX < aX22; + else + aRes = aY21 < aY && aY < aY22; + } + } + + return aRes; +} + +//================================================================ +// Function : GLViewer_Poly +// Purpose : constructs a closed polygon from the given ordered list of points +//================================================================ +GLViewer_Poly::GLViewer_Poly( const GLViewer_PntList* thePoints ) +: myPoints( (GLViewer_PntList*)thePoints ) +{ +} + +//================================================================ +// Function : ~GLViewer_Poly +// Purpose : destructor, mustn't be deleted here! +//================================================================ +GLViewer_Poly::~GLViewer_Poly() +{ +} + +//================================================================ +// Function : IsIn +// Purpose : returns true if lies within this polygon +//================================================================ +bool GLViewer_Poly::IsIn( const GLViewer_Pnt& thePnt ) const +{ + if ( !myPoints ) + return false; + + //cout << thePnt.x() << endl; + //cout << thePnt.y() << endl << endl; + + int aNbInter = 0; + GLViewer_Segment aRay( thePnt, 0., 1., -thePnt.y() ); + + GLViewer_PntList::const_iterator it1 = myPoints->begin(); + GLViewer_PntList::const_iterator it2 = myPoints->begin(); + ++it2; + for ( ; it1 != myPoints->end(); ++it1, ++it2 ) + { + if ( it2 == myPoints->end() ) + it2 = myPoints->begin(); + + if ( aRay.HasIntersection( GLViewer_Segment( *it1, *it2 ) ) ) + aNbInter++; + } + + return ( aNbInter % 2 == 1 ); +} +/* +//================================================================ +// Function : IsIn +// Purpose : returns true if lies within this polygon +//================================================================ +bool GLViewer_Poly::IsIn( const GLViewer_Pnt& thePnt, const float tolerance ) const +{ + if ( !myPoints ) + return false; + + float x = thePnt.x(); + float y = thePnt.y(); + bool res = false; + + GLViewer_Pnt p1( x - tolerance, y - tolerance ); + GLViewer_Pnt p2( x - tolerance, y + tolerance ); + GLViewer_Pnt p3( x + tolerance, y - tolerance ); + GLViewer_Pnt p4( x + tolerance, y + tolerance ); + + res = ( IsInPnt( thePnt ) || + IsInPnt( p1 ) || IsInPnt( p2 ) || IsInPnt( p3 ) || IsInPnt( p4 ) ); + + return res; +} +*/ +//================================================================ +// Function : IsCovers +// Purpose : returns true if covers this polygon +//================================================================ +bool GLViewer_Poly::IsCovers( const GLViewer_Poly& thePoly ) const +{ + if ( !myPoints || !thePoly.Count() ) + return false; + + GLViewer_PntList::const_iterator it = myPoints->begin(); + + for ( ; it != myPoints->end(); ++it ) + { + if( !thePoly.IsIn( *it ) ) + return false; + } + + return true; +} + +//================================================================ +// Function : IsCovers +// Purpose : returns true if covers this polygon +//================================================================ +bool GLViewer_Poly::IsCovers( const GLViewer_Rect& theRect ) const +{ + if ( !myPoints ) //needs check for + return false; + + GLViewer_PntList aList; + GLViewer_PntList::iterator it = aList.begin(); + + aList.insert( it, GLViewer_Pnt( theRect.left(), theRect.top() ) ); + aList.insert( it, GLViewer_Pnt( theRect.right(), theRect.top() ) ); + aList.insert( it, GLViewer_Pnt( theRect.right(), theRect.bottom() ) ); + aList.insert( it, GLViewer_Pnt( theRect.left(), theRect.bottom() ) ); + + return IsCovers( GLViewer_Poly( &aList ) ); +} + +//================================================================ +// Function : HasIntersection +// Purpose : looks for any +//================================================================ +bool GLViewer_Poly::HasIntersection( const GLViewer_Segment& theSegment ) const +{ + if ( !myPoints ) + return false; + + bool aRes = false; + GLViewer_PntList::const_iterator it1 = myPoints->begin(); + GLViewer_PntList::const_iterator it2 = myPoints->begin(); + ++it2; + for ( ; !aRes && it1 != myPoints->end(); ++it1, ++it2 ) + { + if ( it2 == myPoints->end() ) + it2 = myPoints->begin(); + + aRes = theSegment.HasIntersection( GLViewer_Segment( *it1, *it2 ) ); + } + + return aRes; +} diff --git a/src/GLViewer/GLViewer_Grid.cxx b/src/GLViewer/GLViewer_Grid.cxx new file mode 100644 index 000000000..85dfac4ba --- /dev/null +++ b/src/GLViewer/GLViewer_Grid.cxx @@ -0,0 +1,280 @@ +// Copyright (C) 2005 OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// Author : OPEN CASCADE +// + +// File: GLViewer_Grid.cxx +// Created: November, 2004 + +//#include +#include "GLViewer_Grid.h" +#include "GLViewer_Defs.h" + +#include +#include + +GLViewer_Grid::GLViewer_Grid() : + myGridList( 0 ), myGridHeight( (GLfloat)0.0 ), myGridWidth( (GLfloat)0.0 ), + myWinW( (GLfloat)0.0 ), myWinH( (GLfloat)0.0 ), myXSize( (GLfloat)0.0 ), myYSize( (GLfloat)0.0 ), + myXPan( (GLfloat)0.0 ), myYPan( (GLfloat)0.0 ), myXScale( (GLfloat)1.0 ), myYScale( (GLfloat)1.0 ), + myLineWidth( (GLfloat)0.05 ), myCenterWidth( (GLfloat)1.5 ), myCenterRadius( (GLfloat)5.0 ), + myScaleFactor( 10 ), myIsUpdate( GL_FALSE ) +{ + myGridColor[0] = 0.5; + myGridColor[1] = 0.5; + myGridColor[2] = 0.5; + myAxisColor[0] = 0.75; + myAxisColor[1] = 0.75; + myAxisColor[2] = 0.75; +} + +GLViewer_Grid::GLViewer_Grid( GLfloat width, GLfloat height, + GLfloat winW, GLfloat winH, + GLfloat xSize, GLfloat ySize, + GLfloat xPan, GLfloat yPan, + GLfloat xScale, GLfloat yScale ) : + myGridList( 0 ), myGridHeight( (GLfloat)0.0 ), myGridWidth( (GLfloat)0.0 ), + myWinW( (GLfloat)0.0 ), myWinH( (GLfloat)0.0 ), myXSize( (GLfloat)0.0 ), myYSize( (GLfloat)0.0 ), + myXPan( (GLfloat)0.0 ), myYPan( (GLfloat)0.0 ), myXScale( (GLfloat)1.0 ), myYScale( (GLfloat)1.0 ), + myLineWidth( (GLfloat)0.05 ), myCenterWidth( (GLfloat)1.5 ), myCenterRadius( (GLfloat)5.0 ), + myScaleFactor( 10 ), myIsUpdate( GL_FALSE ) +{ + myGridColor[0] = 0.5; + myGridColor[1] = 0.5; + myGridColor[2] = 0.5; + myAxisColor[0] = 0.75; + myAxisColor[1] = 0.75; + myAxisColor[2] = 0.75; +} + +GLViewer_Grid::~GLViewer_Grid() +{ +} + +void GLViewer_Grid::draw() +{ + if ( myGridList == 0 || myIsUpdate ) + initList(); + + glCallList( myGridList ); +} + +void GLViewer_Grid::setGridColor( GLfloat r, GLfloat g, GLfloat b ) +{ + if( myGridColor[0] == r && myGridColor[1] == g && myGridColor[2] == b ) + return; + + myGridColor[0] = r; + myGridColor[1] = g; + myGridColor[2] = b; + myIsUpdate = GL_TRUE; +} + +void GLViewer_Grid::setAxisColor( GLfloat r, GLfloat g, GLfloat b ) +{ + if( myAxisColor[0] == r && myAxisColor[1] == g && myAxisColor[2] == b ) + return; + + myAxisColor[0] = r; + myAxisColor[1] = g; + myAxisColor[2] = b; + myIsUpdate = GL_TRUE; +} + +void GLViewer_Grid::setGridWidth( float w ) +{ + if( myGridWidth == w ) + return; + + myGridWidth = w; + myIsUpdate = GL_TRUE; +} + +void GLViewer_Grid::setCenterRadius( int r ) +{ + if( myCenterRadius == r ) + return; + + myCenterRadius = r; + myIsUpdate = GL_TRUE; +} + +void GLViewer_Grid::setSize( float xSize, float ySize ) +{ + if( myXSize == xSize && myYSize == ySize ) + return; + + myXSize = xSize; + myYSize = ySize; + myIsUpdate = GL_TRUE; +} + +void GLViewer_Grid::setPan( float xPan, float yPan ) +{ + if( myXPan == xPan && myYPan == yPan ) + return; + + myXPan = xPan; + myYPan = yPan; + myIsUpdate = GL_TRUE; +} + +bool GLViewer_Grid::setZoom( float zoom ) +{ + if( zoom == 1.0 ) + return true; + + //backup values + float bXScale = myXScale; + float bYScale = myYScale; + + myXScale /= zoom; + myYScale /= zoom; + + if( fabs(myXScale) < Precision::Confusion() || fabs(myYScale) < Precision::Confusion() ) + { //undo + myXScale = bXScale; + myYScale = bYScale; + return false; + } + + myGridWidth /= zoom; + myGridHeight /= zoom; + myIsUpdate = GL_TRUE; + return true; +} + +void GLViewer_Grid::setResize( float WinW, float WinH, float zoom ) +{ + if( myWinW == WinW && myWinH == WinH && zoom == 1.0 ) + return; + + myGridWidth = myGridWidth + ( WinW - myWinW ) * myXScale; + myGridHeight = myGridHeight + ( WinH - myWinH ) * myYScale; + myWinW = WinW; + myWinH = WinH; + setZoom( zoom ); + myIsUpdate = GL_TRUE; +} + +void GLViewer_Grid::getSize( float& xSize, float& ySize ) const +{ + xSize = myXSize; + ySize = myYSize; +} + +void GLViewer_Grid::getPan( float& xPan, float& yPan ) const +{ + xPan = myXPan; + yPan = myYPan; +} + +void GLViewer_Grid::getScale( float& xScale, float& yScale ) const +{ + xScale = myXScale; + yScale = myYScale; +} + +bool GLViewer_Grid::initList() +{ + myIsUpdate = GL_FALSE; + + if( myXSize == (GLfloat)0.0 ) + myXSize = (GLfloat)0.1; + if( myYSize == (GLfloat)0.0 ) + myYSize = (GLfloat)0.1; + +label: + if( ( myXSize >= myGridWidth/5 ) && ( myYSize >= myGridHeight/5 ) ) + { //zoom in + myXSize /= myScaleFactor; + myYSize /= myScaleFactor; + goto label; + } + else if( ( myXSize * myScaleFactor < myGridWidth/5 ) + || ( myYSize * myScaleFactor < myGridHeight/5 ) ) + { //zoom out + myXSize *= myScaleFactor; + myYSize *= myScaleFactor; + goto label; + } + + //int n = myGridWidth / myXSize; + //int m = myGridHeight / myYSize; + // do not initialise integer by float + //if( ( n != 0 ) || ( m != 0 ) ) + if( ( myGridWidth > 0.5 * myXSize ) || ( myGridHeight > 0.5 * myYSize ) ) + { + if ( myGridList != 0 ) + { + glDeleteLists( myGridList, 1 ); + if ( glGetError() != GL_NO_ERROR ) + return FALSE; + } + + float xLoc = (int)(myXPan / myXSize) * myXSize; + float yLoc = (int)(myYPan / myYSize) * myYSize; + + myGridList = glGenLists( 1 ); + glNewList( myGridList, GL_COMPILE ); + + glColor3f( myGridColor[0], myGridColor[1], myGridColor[2] ); + glLineWidth( myLineWidth ); + + glBegin( GL_LINES ); + for( int j = 0; ( j-1 ) * myXSize <= myGridWidth / 2 ; j++ ) + { + glVertex2d( -myXSize * j - xLoc, -myGridHeight / 2 - myYSize - yLoc ); + glVertex2d( -myXSize * j - xLoc, myGridHeight / 2 + myYSize - yLoc ); + glVertex2d( myXSize * j - xLoc, -myGridHeight / 2 - myYSize - yLoc ); + glVertex2d( myXSize * j - xLoc, myGridHeight / 2 + myYSize - yLoc ); + } + for( int i = 0; ( i-1 ) * myYSize <= myGridHeight / 2 ; i++) + { + glVertex2d( -myGridWidth / 2 - myXSize - xLoc, -myYSize * i - yLoc ); + glVertex2d( myGridWidth / 2 + myXSize - xLoc, -myYSize * i - yLoc ); + glVertex2d( -myGridWidth / 2 - myXSize - xLoc, myYSize * i - yLoc ); + glVertex2d( myGridWidth / 2 + myXSize - xLoc, myYSize * i - yLoc ); + } + glEnd(); + + glColor3f( myAxisColor[0], myAxisColor[1], myAxisColor[2] ); + glLineWidth( myCenterWidth ); + + glBegin( GL_LINES ); + glVertex2d( myGridWidth / 2 + myXSize - xLoc, 0); + glVertex2d( -myGridWidth / 2 - myXSize - xLoc, 0); + glVertex2d( 0, myGridHeight / 2 + myYSize - yLoc ); + glVertex2d( 0, -myGridHeight / 2 - myYSize - yLoc ); + glEnd(); + + glBegin( GL_LINE_LOOP ); + double angle = 0.0; + for ( int k = 0; k < SEGMENTS; k++ ) + { + glVertex2f( cos(angle) * myCenterRadius * myXScale, + sin(angle) * myCenterRadius * myYScale ); + angle += STEP; + } + glEnd(); + + glEndList(); + } + return TRUE; +} diff --git a/src/GLViewer/GLViewer_Grid.h b/src/GLViewer/GLViewer_Grid.h new file mode 100644 index 000000000..39858916b --- /dev/null +++ b/src/GLViewer/GLViewer_Grid.h @@ -0,0 +1,122 @@ +// Copyright (C) 2005 OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// Author : OPEN CASCADE +// + +// File: GLViewer_Grid.h +// Created: November, 2004 + +#ifndef GLVIEWER_GRID_H +#define GLVIEWER_GRID_H + +#ifdef WNT +#include "windows.h" +#endif + +#include "GLViewer.h" + +#include +#include + +#ifdef WNT +#pragma warning( disable:4251 ) +#endif + +/*! Class GLViewer_Grid + 2D rectangular grid for GLViewer + Grid is adapt cells for current view +*/ + +class GLVIEWER_API GLViewer_Grid +{ +public: + //! A default constructor + GLViewer_Grid(); + //! A constructor + /* + * \param width and \param height - width and height of grid + * \param winW and \param winH - width and height of window + * \param xSize and \param ySize - steps along x and y direction + * \param xPan and \param yPan - offsets along x and y direction + * \param xScale and \param yScal - scale factors along x and y direction + */ + GLViewer_Grid( GLfloat width, GLfloat height, + GLfloat winW, GLfloat winH, + GLfloat xSize, GLfloat ySize, + GLfloat xPan, GLfloat yPan, + GLfloat xScale, GLfloat yScale ); + ~GLViewer_Grid(); + + //! Draws grid + void draw(); + + //! Sets color of grid in RGB format + void setGridColor( GLfloat r, GLfloat g, GLfloat b ); + //! Sets color of grid axes in RGB format + void setAxisColor( GLfloat r, GLfloat g, GLfloat b ); + void setGridWidth( float ); + //! Sets Radius of center point( begin coords ) + void setCenterRadius( int ); + + //! Sets steps along x and y directions + void setSize( float xs, float ys ); + //! Sets offset along x and y direction + void setPan( float xp, float yp ); + //! Sets common scale factor along x and y direction + bool setZoom( float zoom ); + //! Recomputes grid in new size and scale of view + void setResize( float winW, float winH, float Zoom ); + + void getSize( float&, float& ) const; + void getPan( float&, float& ) const; + void getScale( float&, float& ) const; + + //! Sets step of scale + void setScaleFactor( int ); + int getScaleFactor(); + +protected: + //! Initialize grid display list + bool initList(); + + GLuint myGridList; + GLfloat myGridColor[3]; + GLfloat myAxisColor[3]; + GLfloat myGridHeight; + GLfloat myGridWidth; + GLfloat myWinW; + GLfloat myWinH; + GLfloat myXSize; + GLfloat myYSize; + GLfloat myXPan; + GLfloat myYPan; + GLfloat myXScale; + GLfloat myYScale; + GLfloat myLineWidth; + GLfloat myCenterWidth; + GLint myCenterRadius; + GLint myScaleFactor; + GLboolean myIsUpdate; +}; + +#ifdef WNT +#pragma warning ( default:4251 ) +#endif + +#endif diff --git a/src/GLViewer/GLViewer_Group.cxx b/src/GLViewer/GLViewer_Group.cxx new file mode 100644 index 000000000..6377e9ecd --- /dev/null +++ b/src/GLViewer/GLViewer_Group.cxx @@ -0,0 +1,171 @@ +// Copyright (C) 2005 OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// Author : OPEN CASCADE +// + +// File: GLViewer_Group.xx +// Created: March, 2005 + +//#include "GLViewerAfx.h" +#include "GLViewer_Group.h" +#include "GLViewer_Object.h" + +/*************************************************************************** +** Class: GLViewer_Group +** Descr: Group of GLViewer_Objects +** Module: GLViewer +** Created: UI team, 25.03.05 +****************************************************************************/ + +//-------------------------------------------------------------------------- +//Function: GLViewer_Group() +//Description: constructor +//-------------------------------------------------------------------------- +GLViewer_Group::GLViewer_Group() +{ + mySelObjNum = 0; +} + +//-------------------------------------------------------------------------- +//Function: GLViewer_Group() +//Description: destructor +//-------------------------------------------------------------------------- +GLViewer_Group::~GLViewer_Group() +{ +} + +//-------------------------------------------------------------------------- +//Function: isEmpty +//Description: detection of empty group +//-------------------------------------------------------------------------- +bool GLViewer_Group::isEmpty() +{ + return myList.empty(); +} + +//-------------------------------------------------------------------------- +//Function: count +//Description: number of elements +//-------------------------------------------------------------------------- +int GLViewer_Group::count() +{ + return myList.size(); +} + +//-------------------------------------------------------------------------- +//Function: contains +//Description: return the position of object, else -1 +//-------------------------------------------------------------------------- +int GLViewer_Group::contains( GLViewer_Object* theObject ) +{ + if( !theObject ) + return -1; + + OGIterator it = myList.begin(); + OGIterator end_it = myList.end(); + for( int i = 0; it != end_it; ++it, i++ ) + if( *it == theObject ) + return i; + + return -1; +} + +//-------------------------------------------------------------------------- +//Function: addObject +//Description: adding object to group +//-------------------------------------------------------------------------- +int GLViewer_Group::addObject( GLViewer_Object* theObject ) +{ + if( theObject && contains( theObject ) == -1 ) + { + myList.push_back( theObject ); + theObject->setGroup( this ); + } + return count(); +} + +//-------------------------------------------------------------------------- +//Function: removeObject +//Description: removing object from group +//-------------------------------------------------------------------------- +int GLViewer_Group::removeObject( GLViewer_Object* theObject ) +{ + if( theObject ) + { + myList.remove( theObject ); + //theObject->setGroup( NULL ); + } + + + if( isEmpty() ) + { + this->~GLViewer_Group(); + return -1; + } + else + return count(); +} + +//-------------------------------------------------------------------------- +//Function: dragingObjects +//Description: +//-------------------------------------------------------------------------- +void GLViewer_Group::dragingObjects( float x, float y, bool once ) +{ + if( !once ) + { + if( !mySelObjNum ) + { + OGIterator it = myList.begin(); + OGIterator end_it = myList.end(); + for( int i = 0; it != end_it; ++it, i++ ) + if( (*it)->isSelected() ) + mySelObjNum++; + + if( mySelObjNum ) + mySelObjNum--; + } + else + { + mySelObjNum--; + return; + } + } + + OGIterator it = myList.begin(); + OGIterator end_it = myList.end(); + for( int i = 0; it != end_it; ++it, i++ ) + (*it)->moveObject( x, y, true ); +} + +//-------------------------------------------------------------------------- +//Function: updateZoom +//Description: +//-------------------------------------------------------------------------- +void GLViewer_Group::updateZoom( GLViewer_Object* sender, float zoom ) +{ + OGIterator it = myList.begin(); + OGIterator end_it = myList.end(); + for( int i = 0; it != end_it; ++it, i++ ) + { + GLViewer_Object* anObject = *it; + if( anObject != sender ) + anObject->setZoom( zoom, true, true ); + } +} diff --git a/src/GLViewer/GLViewer_Group.h b/src/GLViewer/GLViewer_Group.h new file mode 100644 index 000000000..8856166a5 --- /dev/null +++ b/src/GLViewer/GLViewer_Group.h @@ -0,0 +1,76 @@ +// Copyright (C) 2005 OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// Author : OPEN CASCADE +// + +// File: GLViewer_Group.h +// Created: March, 2005 + +#ifndef GLVIEWER_GROUP_H +#define GLVIEWER_GROUP_H + +#include +#include "GLViewer.h" + +#ifdef WNT +#pragma warning( disable:4251 ) +#endif + +class GLViewer_Object; + +typedef std::list OGList; +typedef std::list::iterator OGIterator; + +/*! Class GLViewer_Group +* Group of GLViewer_Objects for synchronized moving. +* If you move one or more objects from group, than all objects from group is moved +* If group is empty, it must be deleted +*/ + +class GLVIEWER_API GLViewer_Group +{ +public: + GLViewer_Group(); + ~GLViewer_Group(); + + bool isEmpty(); + //! Returns number ob objects + int count(); + + //! Returns index of position, else -1 + int contains( GLViewer_Object* ); + int addObject( GLViewer_Object* ); + int removeObject( GLViewer_Object* ); + + OGList getObjects() const { return myList; } + + //! Dragging operation + /*! Once = true, if this operation calls only one time for all object*/ + void dragingObjects( float x, float y, bool once = false ); + //!\warning it is for ouv + void updateZoom( GLViewer_Object* sender, float zoom ); + +private: + //! List of objects + OGList myList; + //! This number needs for synchranization group with viewport drag methods + int mySelObjNum; +}; + +#endif //GLVIEWER_GROUP_H diff --git a/src/GLViewer/GLViewer_MimeSource.cxx b/src/GLViewer/GLViewer_MimeSource.cxx new file mode 100644 index 000000000..e43ee5f51 --- /dev/null +++ b/src/GLViewer/GLViewer_MimeSource.cxx @@ -0,0 +1,232 @@ +// Copyright (C) 2005 OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// Author : OPEN CASCADE +// + +/*************************************************************************** +** Class: GLViewer_MimeSource +** Descr: Needs for a work with QClipboard +** Module: GLViewer +** Created: UI team, 22.03.04 +****************************************************************************/ + +//#include +#include "GLViewer_MimeSource.h" +#include "GLViewer_BaseObjects.h" + +//#include +//using namespace std; + +GLViewer_MimeSource::~GLViewer_MimeSource() +{ +} + +bool GLViewer_MimeSource::setObjects( QValueList theObjects ) +{ + if( !theObjects.empty() ) + { + QStringList aObjectsType; + QValueList aObjects; + QValueList::const_iterator anIt = theObjects.begin(); + QValueList::const_iterator anEndIt = theObjects.end(); + + int aObjByteSize = 0; + for( ; anIt != anEndIt; anIt++ ) + { + aObjects.append( (*anIt)->getByteCopy() ); + aObjByteSize += aObjects.last().size(); + aObjectsType.append( (*anIt)->getObjectType() ); + } + + int anISize = sizeof( int ); + QString aTypes = aObjectsType.join(""); + int aStrByteSize = aTypes.length(); + int aObjNum = aObjects.count(); + + myByteArray = QByteArray( anISize * (1 + 2*aObjNum) + aStrByteSize + aObjByteSize ); + + int anIndex = 0, j = 0; + char* aPointer = (char*)&aObjNum; + for( anIndex = 0; anIndex < anISize; anIndex++, aPointer++ ) + myByteArray[anIndex] = *aPointer; + + QStringList::const_iterator aStrIt = aObjectsType.begin(); + QStringList::const_iterator aEndStrIt = aObjectsType.end(); + for( j = 1; aStrIt != aEndStrIt; aStrIt++, j++ ) + { + int aStrLen = (*aStrIt).length(); + aPointer = (char*)&aStrLen; + for( ; anIndex < anISize*( 1 + j ); anIndex++, aPointer++ ) + myByteArray[anIndex] = *aPointer; + } + + int aCurIndex = anIndex; + const char* aStr = aTypes.data(); + + for( j = 0 ; anIndex < aCurIndex + aStrByteSize; aPointer++, anIndex++, j++ ) + myByteArray[anIndex] = aStr[j]; + + aCurIndex = anIndex; + QValueList::iterator anObjIt = aObjects.begin(); + QValueList::iterator anEndObjIt = aObjects.end(); + for( j = 1; anObjIt != anEndObjIt; anObjIt++, j++ ) + { + int aObjLen = (int)((*anObjIt).size()); + aPointer = (char*)&aObjLen; + for( ; anIndex < aCurIndex + anISize*j; anIndex++, aPointer++ ) + myByteArray[anIndex] = *aPointer; + } + + aCurIndex = anIndex; + anObjIt = aObjects.begin(); + + for( ; anObjIt != anEndObjIt; anObjIt++ ) + { + int aObjLen = (int)((*anObjIt).size()); + for( j = 0 ; anIndex < aCurIndex + aObjLen; anIndex++, aPointer++, j++ ) + myByteArray[anIndex] = (*anObjIt)[j]; + aCurIndex = anIndex; + } + + return true; + } + + return false; +} +//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!NOTE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +//If you want to use new class, following two method must be redefined +//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!NOTE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +GLViewer_Object* GLViewer_MimeSource::getObject( QByteArray theArray, QString theType ) +{ + if( !theArray.isEmpty() ) + { + if( theType == "GLViewer_MarkerSet" ) + { + GLViewer_MarkerSet* aObject = new GLViewer_MarkerSet( 0, (float)0.0, 0 ); + if( aObject->initializeFromByteCopy( theArray ) ) + return aObject; + } + else if ( theType == "GLViewer_Polyline" ) + { + GLViewer_Polyline* aObject = new GLViewer_Polyline( 0, (float)0.0, 0 ); + if( aObject->initializeFromByteCopy( theArray ) ) + return aObject; + } + else if( theType == "GLViewer_TextObject" ) + { + GLViewer_TextObject* aObject = new GLViewer_TextObject( 0, 0, 0, QColor(255,255,255), 0 ); + if( aObject->initializeFromByteCopy( theArray ) ) + return aObject; + } + } + + return NULL; +} + +QValueList GLViewer_MimeSource::getObjects( QByteArray theArray, QString theType ) +{ + if( !theArray.isEmpty() ) + { + int anISize = sizeof( int ); + if( theType == "GLViewer_Objects" ) + { + QStringList aTypeList; + QValueList aObjects; + QValueList aObjectList; + + QValueList aTypeSizeList; + QValueList aObjSizeList; + int aObjNum = 0; + char* aPointer = (char*)&aObjNum; + + int anIndex = 0, j = 0; + for( anIndex = 0; anIndex < anISize; anIndex++, aPointer++ ) + *aPointer = theArray[anIndex]; + + for( j = 0; j < aObjNum; j++ ) + { + int aTempVal = 0; + aPointer = (char*)&aTempVal; + for( ; anIndex < anISize*(j+2); anIndex++, aPointer++ ) + *aPointer = theArray[anIndex]; + aTypeSizeList.append( aTempVal ); + } + + int aCurIndex = anIndex; + for( j = 0; j < aObjNum; j++ ) + { + QString aTempStr; + for( ; anIndex < aCurIndex + aTypeSizeList[j]; anIndex++ ) + { + char aLetter = theArray[anIndex]; + aTempStr.append( aLetter ); + } + aTypeList.append( aTempStr ); + aCurIndex = anIndex; + } + + for( j = 0; j < aObjNum; j++ ) + { + int aTempVal = 0; + aPointer = (char*)&aTempVal; + for( ; anIndex < aCurIndex + anISize*(j+1); anIndex++, aPointer++ ) + *aPointer = theArray[anIndex]; + aObjSizeList.append( aTempVal ); + } + + aCurIndex = anIndex; + for( j = 0; j < aObjNum; j++ ) + { + QByteArray aTempArray(aObjSizeList[j]); + for( ; anIndex < aCurIndex + aObjSizeList[j]; anIndex++ ) + aTempArray[anIndex-aCurIndex] = theArray[anIndex]; + aObjects.append( aTempArray ); + aCurIndex = anIndex; + } + + for( j = 0; j < aObjNum; j++ ) + aObjectList.append( getObject( aObjects[j], aTypeList[j] ) ); + + return aObjectList; + } + } + + return QValueList(); +} + +const char* GLViewer_MimeSource::format( int theIndex ) const +{ + switch( theIndex ) + { + case 0: return "GLViewer_Objects"; + //case 1: return "GLViewer_MarkerSet"; + //case 2: return "GLViewer_Polyline"; + //case 3: return "GLViewer_TextObject"; + default: return 0; + } + +} + +QByteArray GLViewer_MimeSource::encodedData( const char* theObjectType ) const +{ + if( theObjectType == "GLViewer_Objects" ) + return myByteArray; + + return QByteArray(); +} diff --git a/src/GLViewer/GLViewer_MimeSource.h b/src/GLViewer/GLViewer_MimeSource.h new file mode 100644 index 000000000..4fca3c9d7 --- /dev/null +++ b/src/GLViewer/GLViewer_MimeSource.h @@ -0,0 +1,74 @@ +// Copyright (C) 2005 OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// Author : OPEN CASCADE +// + +// File: GLViewer_MimeSource.h +// Created: November, 2004 + +#ifndef GLVIEWER_MIMESOURCE_H +#define GLVIEWER_MIMESOURCE_H + +#ifdef WNT +#include +#endif + +#include "GLViewer.h" + +#include +#include + +#ifdef WNT +#pragma warning( disable:4251 ) +#endif + +class GLViewer_Object; + +/*! Class GLViewer_MimeSource +* Needs for a work with QClipboard +*/ + +class GLVIEWER_API GLViewer_MimeSource: public QMimeSource +{ +public: + GLViewer_MimeSource():QMimeSource(){}; + ~GLViewer_MimeSource(); + + //! Translate objects to byte array + bool setObjects( QValueList ); + //! Gets objects from byte array + /*If you want to use new class, following two method must be redefined*/ + static QValueList getObjects( QByteArray, QString theType); + //! Get object from byte array + /*If you want to use new class, following two method must be redefined*/ + static GLViewer_Object* getObject( QByteArray, QString theType); + + // Redefined methods + virtual const char* format( int theIndex = 0 ) const; + virtual QByteArray encodedData( const char* ) const; + +private: + QByteArray myByteArray; +}; + +#ifdef WNT +#pragma warning ( default:4251 ) +#endif + +#endif diff --git a/src/GLViewer/GLViewer_Object.cxx b/src/GLViewer/GLViewer_Object.cxx new file mode 100644 index 000000000..d2aaf4e97 --- /dev/null +++ b/src/GLViewer/GLViewer_Object.cxx @@ -0,0 +1,297 @@ +// Copyright (C) 2005 OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// Author : OPEN CASCADE +// + +/*************************************************************************** +** Class: GLViewer_Object +** Descr: OpenGL Object +** Module: GLViewer +** Created: UI team, 03.09.02 +****************************************************************************/ + +//#include +#include "GLViewer_Object.h" +#include "GLViewer_Drawer.h" +#include "GLViewer_AspectLine.h" +#include "GLViewer_Geom.h" +#include "GLViewer_Text.h" +#include "GLViewer_Group.h" + +//#include +//using namespace std; + +GLViewer_Object::GLViewer_Object() +{ + myXScale = 1.0; + myYScale = 1.0; + myXGap = 0; + myYGap = 0; + myZoom = 1.0; + + myIsHigh = GL_FALSE; + myIsSel = GL_FALSE; + + myRect = new GLViewer_Rect();; + myUpdateRect = new GLViewer_Rect();; + myGLText = new GLViewer_Text( 0, 0, 0, QColor(0,0,0) ); + + myAspectLine = new GLViewer_AspectLine(); + myType = "GLViewer_Object"; + + myOwner = NULL; + myDrawer = NULL; + + myIsVisible = true; + + isToolTipHTML = false; + + myGroup = NULL; +} + +GLViewer_Object::~GLViewer_Object() +{ + if( myRect ) + delete myRect; + + if( myUpdateRect ) + delete myUpdateRect; + + if( myGLText ) + delete myGLText; + + if( myAspectLine ) + delete myAspectLine; +} + +int GLViewer_Object::getPriority() const +{ + return myDrawer ? myDrawer->getPriority() : 0; +} + +GLboolean GLViewer_Object::isInside( GLViewer_Rect theRect ) +{ + return theRect.toQRect().contains( myRect->toQRect() ); +} + +GLboolean GLViewer_Object::setZoom( GLfloat zoom, bool, bool ) +{ + if( myZoom == zoom ) + return GL_FALSE; + + myZoom = zoom; + return GL_TRUE; +} + +GLboolean GLViewer_Object::updateZoom( bool zoomIn ) +{ + float newZoom; + float step = zoomIn ? 1 : -1; + double epsilon = 0.001; + + if( myZoom - 1 > epsilon ) + newZoom = ( myZoom * 2 + step ) / 2; + else if( 1 - myZoom > epsilon ) + newZoom = 2 / ( 2 / myZoom - step ); + else + newZoom = zoomIn ? 3./2. : 2./3.; + + if( newZoom < 0.01 || newZoom > 100.0 ) + return GL_FALSE; + + return setZoom( newZoom, true ); +} + +QByteArray GLViewer_Object::getByteCopy() +{ + int i = 0; + int anISize = sizeof( int ); + + const char* aTypeStr = myType.data(); + const char* aToolTipStr = myToolTipText.data(); + + int aTypeLength = myType.length(); + int aToolTipLength = myToolTipText.length(); + + + QByteArray aGLText = myGLText->getByteCopy(); + QByteArray aAspect = myAspectLine->getByteCopy(); + + float aRectData[8]; + aRectData[ 0 ] = myRect->left(); + aRectData[ 1 ] = myRect->top(); + aRectData[ 2 ] = myRect->right(); + aRectData[ 3 ] = myRect->bottom(); + aRectData[ 4 ] = myXScale; + aRectData[ 5 ] = myYScale; + aRectData[ 6 ] = myXGap; + aRectData[ 7 ] = myYGap; + + int sizeOf8Float = sizeof( aRectData ); + + QByteArray aResult( 2*anISize + sizeOf8Float + + aTypeLength + aToolTipLength + + aGLText.size() + aAspect.size() ); + // puts 8 float values into the byte array + char* aPointer = (char*)&aRectData; + for( i = 0; i < sizeOf8Float; i++, aPointer++ ) + aResult[i] = *aPointer; + // puts length of type string + aPointer = (char*)&aTypeLength; + for( ; i < anISize + sizeOf8Float; i++, aPointer++ ) + aResult[i] = *aPointer; + // puts type string + for( ; i < anISize + sizeOf8Float + aTypeLength; i++ ) + aResult[i] = aTypeStr[i - anISize - sizeOf8Float ]; + // puts length of tooltiptext string + aPointer = (char*)&aToolTipLength; + for( ; i < 2*anISize + sizeOf8Float + aTypeLength; i++, aPointer++ ) + aResult[i] = *aPointer; + // puts tooltiptext string + for( ; i < 2*anISize + sizeOf8Float + aTypeLength + aToolTipLength; i++ ) + aResult[ i] = aToolTipStr[i - 2*anISize - sizeOf8Float - aTypeLength]; + + int aCurPos = 2*anISize + sizeOf8Float + aTypeLength + aToolTipLength; + // adds aspect byte array + for( i = aCurPos; i < aCurPos + aAspect.size(); i++ ) + aResult[i] = aAspect[i - aCurPos]; + + aCurPos = aCurPos + aAspect.size(); + // adds GL text byte array + for( i = aCurPos; i < aCurPos + aGLText.size(); i++ ) + aResult[i] = aGLText[i - aCurPos]; + + aCurPos += aGLText.size(); + aPointer = (char*)&myOwner; + for( i = 0; i < sizeof( GLViewer_Owner* ); i++, aPointer++ ) + aResult[ aCurPos + i ] = *aPointer; + + return aResult; +} + +bool GLViewer_Object::initializeFromByteCopy( QByteArray theArray ) +{ + int i = 0; + int anISize = sizeof( int ); + int aFSize = sizeof( GLfloat ); + + float aLeft = 0, aTop = 0, aRight = 0, aBottom = 0; + + //QString aTypeStr, aToolTipStr; + int aTypeLength = 0, aToolTipLength = 0; + + int aSize = theArray.size(); + + GLViewer_Text* aGLText = new GLViewer_Text( 0, 0, 0, QColor(255,255,255)); + int aGLTextMinSize = (aGLText->getByteCopy()).size(); + GLViewer_AspectLine* aAspectLine = new GLViewer_AspectLine(); + int aGLAspLineSize = (aAspectLine->getByteCopy()).size(); + + QByteArray aGLTextArray, aAspect( aGLAspLineSize ); + + if( aSize < 2*anISize + 8*aFSize + aGLTextMinSize + aGLAspLineSize ) + return false; + + char* aPointer = (char*)&aLeft; + for( i = 0; i < aFSize; i++, aPointer++ ) + *aPointer = theArray[i]; + aPointer = (char*)&aTop; + for( ; i < 2*aFSize; i++, aPointer++ ) + *aPointer = theArray[i]; + aPointer = (char*)&aRight; + for( ; i < 3*aFSize; i++, aPointer++ ) + *aPointer = theArray[i]; + aPointer = (char*)&aBottom; + for( ; i < 4*aFSize; i++, aPointer++ ) + *aPointer = theArray[i]; + + //myRect = new QRect( aLeft, aTop, aRight - aLeft, aBottom - aTop ); + myRect = new GLViewer_Rect( aLeft, aRight, aTop, aBottom ); + + aPointer = (char*)&myXScale; + for( ; i < 5*aFSize; i++, aPointer++ ) + *aPointer = theArray[i]; + aPointer = (char*)&myYScale; + for( ; i < 6*aFSize; i++, aPointer++ ) + *aPointer = theArray[i]; + aPointer = (char*)&myXGap; + for( ; i < 7*aFSize; i++, aPointer++ ) + *aPointer = theArray[i]; + aPointer = (char*)&myYGap; + for( ; i < 8*aFSize; i++, aPointer++ ) + *aPointer = theArray[i]; + + myIsHigh = false; + myIsSel = false; + myIsVisible = true; + + aPointer = (char*)&aTypeLength; + for( ; i < anISize + 8*aFSize; i++, aPointer++ ) + *aPointer = theArray[i]; + myType = ""; + for( ; i < anISize + 8*aFSize + aTypeLength; i++ ) + { + QChar aChar( theArray[i] ); + myType += aChar; + } + + aPointer = (char*)&aToolTipLength; + for( ; i < 2*anISize + 8*aFSize + aTypeLength; i++, aPointer++ ) + *aPointer = theArray[i]; + myToolTipText= ""; + for( ; i < 2*anISize + 8*aFSize + aTypeLength + aToolTipLength; i++ ) + { + QChar aChar( theArray[i] ); + myToolTipText += aChar; + } + + int aCurPos = 2*anISize + 8*aFSize + aTypeLength + aToolTipLength; + if( aSize - aCurPos < aGLTextMinSize + aGLAspLineSize ) + return false; + + for( i = 0; i < aGLAspLineSize; i++ ) + aAspect[i] = theArray[ aCurPos + i ]; + myAspectLine = GLViewer_AspectLine::fromByteCopy( aAspect ); + + aCurPos = aCurPos + aGLAspLineSize; + aGLTextArray.resize( aSize - aCurPos ); + for( i = 0; i + aCurPos < aSize; i++ ) + aGLTextArray[i] = theArray[ aCurPos + i ]; + // replace gl_text pointer by other + if ( myGLText ) + delete myGLText; + myGLText = GLViewer_Text::fromByteCopy( aGLTextArray ); + + return true; +} + +void GLViewer_Object::setGroup( GLViewer_Group* theGroup ) +{ + if( myGroup ) + myGroup->removeObject( this ); + + myGroup = theGroup; + if( theGroup ) + myGroup->addObject( this ); +} + +GLViewer_Group* GLViewer_Object::getGroup() const +{ + return myGroup; +} diff --git a/src/GLViewer/GLViewer_Object.h b/src/GLViewer/GLViewer_Object.h new file mode 100644 index 000000000..39c9d9883 --- /dev/null +++ b/src/GLViewer/GLViewer_Object.h @@ -0,0 +1,324 @@ +// Copyright (C) 2005 OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// Author : OPEN CASCADE +// + +// File: GLViewer_Object.h +// Created: November, 2004 + +#ifndef GLVIEWER_OBJECT_H +#define GLVIEWER_OBJECT_H + +#ifdef WNT +#include +#endif + +#include "GLViewer.h" +#include "GLViewer_Defs.h" +#include "GLViewer_Geom.h" + +#include + +#include + +#include +#include +#include + +#ifdef WNT +#pragma warning( disable:4251 ) +#endif + +/*! + * Class GLViewer_Object + * Base Object for GLViewer + */ +class GLViewer_Drawer; +class GLViewer_AspectLine; +class GLViewer_Group; +class GLViewer_CoordSystem; +class GLViewer_Text; +class GLViewer_Owner; + +class GLVIEWER_API GLViewer_Object +{ +public: + //! A constructor + GLViewer_Object(); + //! A destructor + virtual ~GLViewer_Object(); + + //! Main method. Computes all needed information about object for presentation in drawer + virtual void compute() = 0; + //! Creates correspond drawer + virtual GLViewer_Drawer* createDrawer() = 0; + + //! Installing already exist drawer with same type + virtual void setDrawer( GLViewer_Drawer* theDrawer ) { myDrawer = theDrawer; } + //! Returns current drawer + GLViewer_Drawer* getDrawer() const { return myDrawer; } + + //! Computes highlight presentation + /*! + *\param x - x coord + *\param y - y coord + *\param tol - tolerance of detecting + *\param isCircle - = true if sensitive area of detection is round + */ + virtual GLboolean highlight( GLfloat x, + GLfloat y, + GLfloat tol, + GLboolean isCircle = GL_FALSE ) = 0; + //! Clears all highlight information + virtual GLboolean unhighlight() = 0; + + //! Computes select presentation + /*! + *\param x - x coord + *\param y - y coord + *\param tol - tolerance of detecting + *\param rect - Non empty for rectangle selection + *\param isFull - = true if + *\param isCircle - = true if sensitive area of detection is round + *\param isShift - = true if selection exec with append option + */ + virtual GLboolean select( GLfloat x, + GLfloat y, + GLfloat tol, + GLViewer_Rect rect, + GLboolean isFull = GL_FALSE, + GLboolean isCircle = GL_FALSE, + GLboolean isShift = GL_FALSE ) = 0; + //! Clears all select information + virtual GLboolean unselect() = 0; + + //! Returns if theRect inside object + virtual GLboolean isInside( GLViewer_Rect theRect); + + //!\warning It is for ouv + virtual bool portContains( GLViewer_Pnt ) { return false; } + //!\warning It is for ouv + virtual bool startPulling( GLViewer_Pnt ) { return false; } + //!\warning It is for ouv + virtual void pull( GLViewer_Pnt, GLViewer_Object* ) {} + //!\warning It is for ouv + virtual void finishPulling() {} + //!\warning It is for ouv + virtual bool isPulling() { return false; } + //!\warning It is for ouv + virtual GLViewer_Rect getPullingRect() const { return GLViewer_Rect( + myRect->left(), myRect->right(), myRect->top(), myRect->bottom() ); } + + //! Installs object rectangle + virtual void setRect( GLViewer_Rect* rect) { myRect = rect; } + //! Returns object rectungle + virtual GLViewer_Rect* getRect() const { return myRect; } + //! Returns update object rectangle + /*! Does not equal getRect() if object have a persistence to some viewer transformations*/ + virtual GLViewer_Rect* getUpdateRect() = 0; + + //! Installs scale factors + virtual void setScale( GLfloat xScale, GLfloat yScale ) { myXScale = xScale; myYScale = yScale; } + //! Returns scale factors + virtual void getScale( GLfloat& xScale, GLfloat& yScale ) const { xScale = myXScale; yScale = myYScale;} + + //!\warning It is for ouv + virtual GLboolean setZoom( GLfloat zoom, bool recompute, bool fromGroup = false ); + //!\warning It is for ouv + virtual GLfloat getZoom() const { return myZoom; } + //!\warning It is for ouv + virtual GLboolean updateZoom( bool zoomIn ); + + //! Returns true if object is highlighted + virtual GLboolean isHighlighted() const { return myIsHigh; } + //! Returns true if object is selected + virtual GLboolean isSelected() const { return myIsSel; } + //! Installs select status to object + virtual void setSelected( GLboolean state ) { myIsSel = state; } + + //! Installs GLText to object + void setGLText( GLViewer_Text* glText ) { myGLText = glText; } + //! Returns object GLText + GLViewer_Text* getGLText() const { return myGLText; } + + //! Installs acpect line for object presentation + virtual void setAspectLine ( GLViewer_AspectLine* aspect ) { myAspectLine = aspect; } + //! Returns acpect line of object presentation + virtual GLViewer_AspectLine* getAspectLine() const { return myAspectLine; } + + //! Returns object type + /*! Needs for GLViewer_Drawer*/ + QString getObjectType() const { return myType; } + + //! Installs object name + void setName( QString name ) { myName = name; } + //! Returns object name + QString getName() const { return myName; } + + //! Returns object priority + virtual int getPriority() const; + + //! Moves object per by recomputing + /*! + *\param dx - moving along X coord + *\param dy - moving along Y coord + *\param fromGroup - = true if this method called from group + */ + virtual void moveObject( float dx, float dy, bool fromGroup = false ) = 0; + //! Finaly recomputing object after moving + virtual bool finishMove() { return true; } + + //! Returns visible object status + bool getVisible() const { return myIsVisible; } + //! Installs visible object status + virtual void setVisible( bool theStatus ) { myIsVisible = theStatus; } + + //! Installs onject tool tip text + void setToolTipText( QString str ){ myToolTipText = str; } + //! Returns onject tool tip text + virtual QString getToolTipText(){ return myToolTipText; } + + //! Returns true if tool tip contains HTML tags + bool isTooTipHTML() const { return isToolTipHTML; } + //! Installs tool tip supporting of HTML tags + void setToolTipFormat( bool isHTML ) { isToolTipHTML = isHTML; } + + //! A function for coding object to the byte copy + /*! A function is used for copy-past technollogy in copy method */ + virtual QByteArray getByteCopy(); + //! A function for decoding object from the byte copy + /*! A function is used for copy-past technollogy in past method */ + virtual bool initializeFromByteCopy( QByteArray ); + + //! A function translate object in to PostScript file on disk + /*! + *\param hFile the name of PostScript file chosen by user + *\param aViewerCS the GLViewer_CoordSystem of window + *\param aPSCS the GLViewer_CoordSystem of PostScript page + */ + virtual bool translateToPS( QFile& hFile, GLViewer_CoordSystem* aViewerCS, GLViewer_CoordSystem* aPSCS ) = 0; + //! A function translate object in to HPGL file on disk + /*! + *\param hFile the name of PostScript file chosen by user + *\param aViewerCS the GLViewer_CoordSystem of window + *\param aHPGLCS the GLViewer_CoordSystem of PostScript page + */ + virtual bool translateToHPGL( QFile& hFile, GLViewer_CoordSystem* aViewerCS, GLViewer_CoordSystem* aHPGLCS ) = 0; + +#ifdef WIN32 + //! A function translate object in to EMF file on disk + /*! + *\warning WIN32 only + * + *\param dc the name of HDC associated with file chosen by user + *\param aViewerCS the GLViewer_CoordSystem of window + *\param aEMFCS the GLViewer_CoordSystem of EMF page + */ + virtual bool translateToEMF( HDC dc, GLViewer_CoordSystem* aViewerCS, GLViewer_CoordSystem* aEMFCS ) = 0; +#endif + //!\warning It is for ouv + GLViewer_Owner* owner() const { return myOwner; } + //!\warning It is for ouv + void setOwner( GLViewer_Owner* owner ) { myOwner = owner; } + + //! Adds object to group theGroup + void setGroup( GLViewer_Group* theGroup ); + //! Returns object group + GLViewer_Group* getGroup() const; + + //!\warning It is for ouv + virtual GLViewer_Object* getOwner() { return this; } + + //! Returns true if object can be selected + virtual bool isSelectable() { return true; } + //!\warning It is for ouv + virtual bool isScalable() { return true; } + +protected: + //! Object name + QString myName; + //! Object type + QString myType; + + //! Object base rect + GLViewer_Rect* myRect; + //! Update object rect (after some viewer transformations) + GLViewer_Rect* myUpdateRect; + //! Object GLText + GLViewer_Text* myGLText; + + //! X scale factor + GLfloat myXScale; + //! Y scale factor + GLfloat myYScale; + //! Gap for X direction of rect + GLfloat myXGap; + //! Gap for Y direction of rect + GLfloat myYGap; + + //!\warning It is for ouv + GLfloat myZoom; + + //! Highlight status + /*! = true after right highlighting*/ + GLboolean myIsHigh; + //! Selectt status + /*! = true after right selection*/ + GLboolean myIsSel; + + //! Object drawer + GLViewer_Drawer* myDrawer; + //! Line aspect for object presentation + GLViewer_AspectLine* myAspectLine; + + //! Objet tool tip text + QString myToolTipText; + //! HTML object tool tip status + /*! = true if tool tip text contains HTML tags */ + bool isToolTipHTML; + + //! Object visibke status + bool myIsVisible; + + //!\warning It is for ouv + GLViewer_Owner* myOwner; + + //! Object Group + GLViewer_Group* myGroup; +}; + + +//!\warning It is for ouv +class GLVIEWER_API GLViewer_Owner : public SUIT_DataOwner +{ +public: + //!\warning It is for ouv + GLViewer_Owner() : SUIT_DataOwner() {} + //!\warning It is for ouv + ~GLViewer_Owner() {} + +protected: + +}; + +#ifdef WNT +#pragma warning ( default:4251 ) +#endif + +#endif diff --git a/src/GLViewer/GLViewer_Selector.cxx b/src/GLViewer/GLViewer_Selector.cxx new file mode 100644 index 000000000..5df29eb89 --- /dev/null +++ b/src/GLViewer/GLViewer_Selector.cxx @@ -0,0 +1,75 @@ +// Copyright (C) 2005 OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// Author : OPEN CASCADE +// + +// File: GLViewer_Selector.cxx +// Created: November, 2004 + +/**************************************************************************** +** Class: GLViewer_Selector +** Descr: Base class for object selection in QAD-based application +** Module: GLViewer +** Created: UI team, 22.09.00 +*****************************************************************************/ + +//#include +#include "GLViewer_Selector.h" + +#include "GLViewer_Viewer.h" + +int GLViewer_Selector::apppendKey = Qt::ShiftButton; + +/*! + Constructor +*/ +GLViewer_Selector::GLViewer_Selector( GLViewer_Viewer* viewer ) +: QObject( 0 ), +myViewer( viewer ), +myLocked( false ), +myMinRectSize( 1, 1 ) +{ +} + +/*! + Destructor +*/ +GLViewer_Selector::~GLViewer_Selector() +{ +} + +/*! + Sets the min size of rectangle to treat it as a rectangle for multiple + selection( sensitivity ). If a rectangle size is less than that min size, + the right-bottom point of the rectangle will be used for single selection. + The default min size is ( 1,1 ). [ public ] +*/ +void GLViewer_Selector::setMinRectSize( const QSize& minSize ) +{ + myMinRectSize = minSize; +} + +/*! + Locks / unlocks the selector. If locked, nothing can be selected + regadless of the selection mode. [ public ] +*/ +void GLViewer_Selector::lock( bool locked ) +{ + myLocked = locked; +} diff --git a/src/GLViewer/GLViewer_Selector.h b/src/GLViewer/GLViewer_Selector.h new file mode 100644 index 000000000..ad40ab124 --- /dev/null +++ b/src/GLViewer/GLViewer_Selector.h @@ -0,0 +1,99 @@ +// Copyright (C) 2005 OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// Author : OPEN CASCADE +// + +// File: GLViewer_Selector.h +// Created: November, 2004 + +/**************************************************************************** +** Class: GLViewer_Selector +** Descr: Base class for object selection in QAD-based application +** Module: GLViewer +** Created: UI team, 22.09.00 +*****************************************************************************/ +#ifndef GLVIEWER_SELECTOR_H +#define GLVIEWER_SELECTOR_H + +#include "GLViewer.h" +#include "GLViewer_Defs.h" + +#include +#include + +#include + +class GLViewer_Viewer; + +/*! Class GLViewer_Selector +* Based select manager for GLViewer +*/ + +class GLVIEWER_API GLViewer_Selector : public QObject +{ + Q_OBJECT + +public: + GLViewer_Selector( GLViewer_Viewer* ); + ~GLViewer_Selector(); + +public: + //! Sets lock status (enable/disable interavtive) + void lock( bool ); + void setMinRectSize( const QSize& minSize ); + + //! Highlights in point (x,y) + virtual void detect( int x, int y ) = 0; + virtual void undetectAll() = 0; + + //! Selects highlight objects + virtual void select( bool append = false ) = 0; + //! Selects by rect + virtual void select( const QRect&, bool append = false ) = 0; + virtual void unselectAll() = 0; + virtual int numSelected() const = 0; + + virtual void setHilightColor( Quantity_NameOfColor ) = 0; + virtual void setSelectColor( Quantity_NameOfColor ) = 0; + //!Checks selection state and emits 'selSelectionDone' or 'selSelectionCancel' + /*!Should be called by after non-interactive selection. */ + virtual void checkSelection( int, bool, int ) = 0; + + /*! Sets/returns the key for appending selected objects ( SHIFT by default ) */ + static int appendKey() { return apppendKey; } + static void setAppendKey( int k ) { apppendKey = k; } + +signals: + void selSelectionCancel(); + void selSelectionDone( bool append, SelectionChangeStatus status ); + +protected: +// void setStatus( SelectionChangeStatus theStatus ){ myStatus = theStatus; } +// SelectionChangeStatus status( return myStatus; } + + GLViewer_Viewer* myViewer; + bool myLocked; + QSize myMinRectSize; + +private: +// SelectionChangeStatus myStatus; + static int apppendKey; +}; + +#endif diff --git a/src/GLViewer/GLViewer_Selector2d.cxx b/src/GLViewer/GLViewer_Selector2d.cxx new file mode 100644 index 000000000..e8a414d46 --- /dev/null +++ b/src/GLViewer/GLViewer_Selector2d.cxx @@ -0,0 +1,165 @@ +// Copyright (C) 2005 OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// Author : OPEN CASCADE +// + +// File: GLViewer_Selector2d.cxx +// Created: November, 2004 + +/**************************************************************************** +** Class: GLViewer_Selector2d +** Descr: OpenGL Selector 2D +** Module: GLViewer +** Created: UI team, 20.09.02 +*****************************************************************************/ + +//#include +#include "GLViewer_Selector2d.h" +#include "GLViewer_Viewer2d.h" +#include "GLViewer_Context.h" +#include "GLViewer_ViewPort2d.h" + +GLViewer_Selector2d::GLViewer_Selector2d( GLViewer_Viewer2d* v2d, GLViewer_Context* glc ) : +GLViewer_Selector( v2d ), +myGLContext( glc ) +{ +// myGLContext->SetHighlightColor( Quantity_NOC_CYAN1 ); +// myGLContext->SetSelectionColor( Quantity_NOC_RED ); +} + +GLViewer_Selector2d::~GLViewer_Selector2d() +{ +} + +void GLViewer_Selector2d::setHilightColor( Quantity_NameOfColor color ) +{ + myGLContext->SetHighlightColor( color ); +} + +void GLViewer_Selector2d::setSelectColor( Quantity_NameOfColor color ) +{ + myGLContext->SetSelectionColor( color ); +} + +void GLViewer_Selector2d::detect( int x, int y ) +{ + //cout << "GLViewer_Selector2d : detect ( " << x << " , " << y << " )" << endl; + if ( myLocked || !myGLContext || !myViewer || !myViewer->getActiveView() || + myViewer->getSelectionMode() == GLViewer_Viewer::NoSelection ) + return; + + GLViewer_ViewPort* vp = myViewer->getActiveView()->getViewPort(); + if( !vp->inherits( "GLViewer_ViewPort2d" ) ) + return; + + myGLContext->MoveTo( x, y ); +} + +void GLViewer_Selector2d::undetectAll() +{ + if ( myLocked || !myGLContext || !myViewer || !myViewer->getActiveView() || + myViewer->getSelectionMode() == GLViewer_Viewer::NoSelection ) + return; + + GLViewer_ViewPort* vp = myViewer->getActiveView()->getViewPort(); + if( !vp->inherits( "GLViewer_ViewPort2d" ) ) + return; + + myGLContext->clearHighlighted( true ); +} + +void GLViewer_Selector2d::select( bool append ) +{ + //cout << "GLViewer_Selector2d : select ( " << (int)append << " )" << endl; + GLViewer_Viewer::SelectionMode selMode = myViewer->getSelectionMode(); + if ( myLocked || !myGLContext || !myViewer || !myViewer->getActiveView() || + selMode == GLViewer_Viewer::NoSelection ) + return; + + int selBefore = numSelected(); + if ( selBefore && append && selMode != GLViewer_Viewer::Multiple ) + return; + + GLViewer_ViewPort* vp = myViewer->getActiveView()->getViewPort(); + if( !vp->inherits( "GLViewer_ViewPort2d" ) ) + return; + + int status = myGLContext->Select( append ); + checkSelection( selBefore, append, status ); +} + +void GLViewer_Selector2d::select( const QRect& selRect, bool append ) +{ + GLViewer_Viewer::SelectionMode selMode = myViewer->getSelectionMode(); + if ( myLocked || !myGLContext || !myViewer || !myViewer->getActiveView() || + selMode == GLViewer_Viewer::NoSelection ) + return; + + int selBefore = numSelected(); + if ( selBefore && append && selMode != GLViewer_Viewer::Multiple ) + return; + + GLViewer_ViewPort* vp = myViewer->getActiveView()->getViewPort(); + if( !vp->inherits( "GLViewer_ViewPort2d" ) ) + return; + + int aStatus = myGLContext->SelectByRect( selRect, append ); + checkSelection( selBefore, append, aStatus ); +} + +void GLViewer_Selector2d::unselectAll() +{ + if ( myLocked || !myViewer ) + return; + +// bool updateViewer = true; + bool hadSelection = ( numSelected() > 0 ); + +// bool lcOpen = ( myAISContext->IndexOfCurrentLocal() != -1 ); +// lcOpen ? myAISContext->ClearSelected( updateViewer ) : +// myAISContext->ClearCurrent( updateViewer ); + if ( hadSelection ) emit selSelectionCancel(); +} + +/* Checks selection state and emits 'selSelectionDone' or 'selSelectionCancel' + Should be called by after non-interactive selection. */ +void GLViewer_Selector2d::checkSelection( int selBefore, bool append, int aStatus ) +{ + int selAfter = numSelected(); + if ( selBefore > 0 && selAfter < 1 ) + emit selSelectionCancel(); + else if ( selAfter > 0 ) + { + switch( aStatus ) + { + case SS_LocalChanged: + emit selSelectionDone( selAfter > 1, SCS_Local ); + break; + case SS_GlobalChanged: + emit selSelectionDone( selAfter > 1, SCS_Global ); + break; + } + } +} + +int GLViewer_Selector2d::numSelected() const +{ + return myGLContext->NbSelected(); +} + diff --git a/src/GLViewer/GLViewer_Selector2d.h b/src/GLViewer/GLViewer_Selector2d.h new file mode 100644 index 000000000..cce3cc37e --- /dev/null +++ b/src/GLViewer/GLViewer_Selector2d.h @@ -0,0 +1,79 @@ +// Copyright (C) 2005 OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// Author : OPEN CASCADE +// + +// File: GLViewer_Selector2d.h +// Created: November, 2004 + +/**************************************************************************** +** Class: GLViewer_Selector2d +** Descr: OpenGL Selector 2D +** Module: GLViewer +** Created: UI team, 20.09.02 +*****************************************************************************/ +#ifndef GLVIEWER_SELECTOR2D_H +#define GLVIEWER_SELECTOR2D_H + +#ifdef WNT +#include "windows.h" +#endif + +#include "GLViewer_Selector.h" + +#include + +class GLViewer_Viewer2d; +class GLViewer_Context; + +/*! Class GLViewer_Selector2d +* 2D select manager for GLViewer +*/ +class GLVIEWER_API GLViewer_Selector2d : public GLViewer_Selector +{ + Q_OBJECT + +public: + GLViewer_Selector2d( GLViewer_Viewer2d*, GLViewer_Context* ); + ~GLViewer_Selector2d(); + +public: + //! Sets context from Viewer2d + void setContext( GLViewer_Context* glc ) { myGLContext = glc; } + GLViewer_Context* getContext() const { return myGLContext; } + + // Redefined methods + virtual void setHilightColor( Quantity_NameOfColor ); + virtual void setSelectColor( Quantity_NameOfColor ); + + virtual void detect( int, int ); + virtual void undetectAll(); + + virtual void select( bool append = false ); + virtual void select( const QRect&, bool append = false ); + virtual void unselectAll(); + virtual int numSelected() const; + + virtual void checkSelection( int, bool, int ); + +protected: + GLViewer_Context* myGLContext; +}; + +#endif diff --git a/src/GLViewer/GLViewer_Text.cxx b/src/GLViewer/GLViewer_Text.cxx new file mode 100644 index 000000000..bafa33ec1 --- /dev/null +++ b/src/GLViewer/GLViewer_Text.cxx @@ -0,0 +1,182 @@ +// Copyright (C) 2005 OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// Author : OPEN CASCADE +// + +/*************************************************************************** +** Class: GLViewer_Text +** Descr: Substitution of Prs3d_Text for OpenGL +** Module: GLViewer +** Created: UI team, 10.07.03 +****************************************************************************/ + +//#include +#include "GLViewer_Text.h" + +GLViewer_Text::GLViewer_Text( const QString& text, float xPos, float yPos, const QColor& color ) +{ + myText = text; + myXPos = xPos; + myYPos = yPos; + myColor = color; + myQFont = QFont::defaultFont(); + mySeparator = 2; + myDTF = DTF_BITMAP; +} + +GLViewer_Text::GLViewer_Text( const QString& text, float xPos, float yPos, const QColor& color, QFont theFont, int theSeparator ) +{ + myText = text; + myXPos = xPos; + myYPos = yPos; + myColor = color; + myQFont = theFont; + mySeparator = theSeparator; + myDTF = DTF_BITMAP; +} + +GLViewer_Text::~GLViewer_Text() +{ +} + +int GLViewer_Text::getWidth() +{ + int aResult = 0; + QFontMetrics aFM( myQFont ); + for( uint i = 0; i < myText.length(); i++ ) + aResult += aFM.width( myText.at(i) ) + mySeparator; + return aResult; +} + +int GLViewer_Text::getHeight() +{ + QFontMetrics aFM( myQFont ); + return aFM.height(); +} + +QByteArray GLViewer_Text::getByteCopy() const +{ + int i; + int aSize = 5*sizeof( int ) + myText.length(); + + int aR = myColor.red(); + int aG = myColor.green(); + int aB = myColor.blue(); + const char* aStr = myText.data(); + + int anISize = sizeof( int ); + QByteArray aResult( aSize ); + + char* aPointer = (char*)&myXPos; + for( i = 0; i < anISize; i++, aPointer++ ) + aResult[i] = *aPointer; + aPointer = (char*)&myYPos; + for( ; i < 2*anISize; i++, aPointer++ ) + aResult[i] = *aPointer; + + aPointer = (char*)&aR; + for( ; i < 3*anISize; i++, aPointer++ ) + aResult[i] = *aPointer; + aPointer = (char*)&aG; + for( ; i < 4*anISize; i++, aPointer++ ) + aResult[i] = *aPointer; + aPointer = (char*)&aB; + for( ; i < 5*anISize; i++, aPointer++ ) + aResult[i] = *aPointer; + + int aTextSize = myText.length(); + aPointer = (char*)&aTextSize; + for( ; i < 6*anISize; i++, aPointer++ ) + aResult[i] = *aPointer; + + for( i = 0; i < aTextSize; i++ ) + aResult[6*anISize + i] = aStr[i]; + + aPointer = (char*)&mySeparator; + for( ; i < 7*anISize + aTextSize; i++, aPointer++ ) + aResult[i] = *aPointer; + + const char* aFontStr = myQFont.toString().data(); + int aFontSize = myQFont.toString().length(); + + for( i = 0; i < aFontSize; i++ ) + aResult[7*anISize + aTextSize + i] = aFontStr[i]; + + return aResult; +} + +GLViewer_Text* GLViewer_Text::fromByteCopy( QByteArray theBuf ) +{ + int i = 0; + int aSize = (int)theBuf.size(); + int aR = 0, aG = 0, aB = 0; + + int xPos = 0, yPos = 0; + + int anISize = sizeof( int ); + char* aPointer = (char*)&xPos; + for ( i = 0; i < anISize; i++, aPointer++ ) + *aPointer = theBuf[i]; + + aPointer = (char*)&yPos; + for ( ; i < 2*anISize; i++, aPointer++ ) + *aPointer = theBuf[i]; + + aPointer = (char*)&aR; + for( ; i < 3*anISize; i++, aPointer++ ) + *aPointer = theBuf[i]; + aPointer = (char*)&aG; + for( ; i < 4*anISize; i++, aPointer++ ) + *aPointer = theBuf[i]; + aPointer = (char*)&aB; + for( ; i < 5*anISize; i++, aPointer++ ) + *aPointer = theBuf[i]; + + int aTextSize = 0; + aPointer = (char*)&aTextSize; + for( ; i < 6*anISize; i++, aPointer++ ) + *aPointer = theBuf[i]; + + QString aText; + for( ; i < 6*anISize + aTextSize; i++ ) + { + QChar aChar( theBuf[i] ); + aText += aChar; + } + + int aSeparator = 0; + aPointer = (char*)&aSeparator; + for( ; i < 7*anISize + aTextSize; i++, aPointer++ ) + *aPointer = theBuf[i]; + + QString aFontStr; + for( ; i < aSize; i++ ) + { + QChar aChar( theBuf[i] ); + aFontStr += aChar; + } + QFont aFont; + + if( !aFont.fromString( aFontStr ) ) + return NULL; + + GLViewer_Text* aGlText = new GLViewer_Text( aText, xPos, yPos, QColor( aR,aG,aB ), aFont, aSeparator ); + + return aGlText; +} diff --git a/src/GLViewer/GLViewer_Text.h b/src/GLViewer/GLViewer_Text.h new file mode 100644 index 000000000..ef3512ca9 --- /dev/null +++ b/src/GLViewer/GLViewer_Text.h @@ -0,0 +1,113 @@ +// Copyright (C) 2005 OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// Author : OPEN CASCADE +// + +// File: GLViewer_Text.h +// Created: November, 2004 + +#ifndef GLVIEWER_TEXT_H +#define GLVIEWER_TEXT_H + +#ifdef WNT +#include +#endif + +#include "GLViewer.h" +#include "GLViewer_Defs.h" + +#include + +#include +#include +#include +#include + +#ifdef WNT +#pragma warning( disable:4251 ) +#endif + +/* Class GLViewer_Text +* Substitution of Prs3d_Text for OpenGL */ + +class GLVIEWER_API GLViewer_Text +{ +public: + GLViewer_Text( const QString&, float xPos = 0.0, float yPos = 0.0, const QColor& color = QColor( 0, 255, 0 ) ); + GLViewer_Text( const QString&, float xPos, float yPos, const QColor& , QFont theFont, int theSeparator); + ~GLViewer_Text(); + + //! Sets text + void setText( const QString& text ) { myText = text; } + //! Returns text + QString getText() const { return myText; } + + //! Sets text position + void setPosition( float xPos, float yPos ) { myXPos = xPos; myYPos = yPos; } + //! Returns text position + void getPosition( float& xPos, float& yPos ) { xPos = myXPos; yPos = myYPos; } + + //! Sets text color + void setColor( const QColor& color ) { myColor = color; } + //! Returns text color + QColor getColor() const { return myColor; } + + //! Sets text font + void setFont( const QFont theQFont) { myQFont = theQFont; } + //! Returns text font + QFont getFont() const { return myQFont; } + + //! Returns text separator + int getSeparator(){ return mySeparator; } + //! Sets text separator + void setSeparator( int theSep ){ mySeparator = theSep; } + + //! Returns text width + int getWidth(); + //! Returns text height + int getHeight(); + + //! A function for coding object to the byte copy + /*! A function is used for copy-past technollogy in copy method */ + QByteArray getByteCopy() const; + + //! A function for decoding object from the byte copy + /*! A function is used for copy-past technollogy in past method */ + static GLViewer_Text* fromByteCopy( QByteArray ); + + //! Sets text format BITMAP or TEXTURE + DisplayTextFormat getDisplayTextFormat() const { return myDTF; } + //! Returns text format BITMAP or TEXTURE + void setTextDisplayFormat( DisplayTextFormat theDTF ) { myDTF = theDTF; } + +protected: + QString myText; + float myXPos; + float myYPos; + QColor myColor; + QFont myQFont; + int mySeparator; + DisplayTextFormat myDTF; +}; + +#ifdef WNT +#pragma warning ( default:4251 ) +#endif + +#endif diff --git a/src/GLViewer/GLViewer_ToolTip.cxx b/src/GLViewer/GLViewer_ToolTip.cxx new file mode 100644 index 000000000..0521ff19f --- /dev/null +++ b/src/GLViewer/GLViewer_ToolTip.cxx @@ -0,0 +1,226 @@ +// Copyright (C) 2005 OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// Author : OPEN CASCADE +// + +// File: GLViewer_ToolTip.xx +// Created: March, 2005 + +//#include "GLViewerAfx.h" +#include "GLViewer_Context.h" +#include "GLViewer_ToolTip.h" +#include "GLViewer_Viewer2d.h" +#include "GLViewer_ViewPort2d.h" + +#include +#include +#include +#include +#include + +/*************************************************************************** +** Class: GLViewer_ToolTip +** Descr: ToolTip of GLViewer_Objects +** Module: GLViewer +** Created: UI team, 25.03.05 +****************************************************************************/ + +//-------------------------------------------------------------------------- +//Function: GLViewer_ToolTip() +//Description: constructor +//-------------------------------------------------------------------------- +GLViewer_ObjectTip::GLViewer_ObjectTip( GLViewer_ViewPort2d* theParent ) +:QObject(), + myText(), + myPoint( -1, -1 ) +{ + mypViewPort = theParent; + //mypLabel = NULL; + mypLabel = new QLabel( "Test", NULL, "ObjectTipText", + WStyle_StaysOnTop | WStyle_Customize | WStyle_NoBorder | WStyle_Tool | WX11BypassWM ); + mypLabel->setMargin( 1 ); + mypLabel->setAutoMask( FALSE ); + mypLabel->setFrameStyle( QFrame::Plain | QFrame::Box ); + mypLabel->setLineWidth( 1 ); + mypLabel->setAlignment( AlignAuto | AlignTop ); + mypLabel->setIndent( 0 ); + mypLabel->polish(); + + //mypLabel->setPalette( QToolTip::palette() ); + + mypTimer = new QTimer( this ); + + connect( mypTimer, SIGNAL( timeout() ), this, SLOT( showTip() ) ); +} + +//-------------------------------------------------------------------------- +//Function: GLViewer_ToolTip() +//Description: destructor +//-------------------------------------------------------------------------- +GLViewer_ObjectTip::~GLViewer_ObjectTip() +{ +// delete mypRect; + if( mypLabel ) + delete mypLabel; + + //if( mypPoint ) + // delete mypPoint; + + //if( mypTimer ) + // delete mypTimer; +} + + +//-------------------------------------------------------------------------- +//Function: GLViewer_ToolTip() +//Description: destructor +//-------------------------------------------------------------------------- +bool GLViewer_ObjectTip::maybeTip( const QPoint &p ) +{ + + + GLViewer_Context* aContext = ((GLViewer_Viewer2d*)mypViewPort->getViewFrame()->getViewer())->getGLContext(); + + /*if( !aContext->currentObjectIsChanged() ) + return false; + else + return true; + if( myPoint.x() == -1 && myPoint.y() == -1 || aContext->currentObjectIsChanged()) + { + myPoint = p; + } + else/if( abs(myPoint.y() - p.y()) < 16 ) + { + return; + } + else // > 16 + { + myPoint = p; + } +*/ + GLViewer_Object* anObj = aContext->getCurrentObject(); + if( anObj ) + { + setText( anObj->getName() ); + return true; + } + + return false; + /*if( anObj ) + { + //GLViewer_Rect* aRect = anObj->getRect(); + //QRect aWinRect = mypViewPort->GLV2win( *aRect ); + tip( QRect( p.x(), p.y(), 1, 1 ), anObj->getName() ); + //QFontMetrics aFM( font() ); + //showTip( aWinRect, anObj->getName(), QRect( 0, 0, aFM.width( anObj->getName() + " " ), aFM.height()*1.5 ) ); + //tip( aWinRect, anObj->getName(), aWinRect( aFM.width( anObj->getName() + " " ), aFM.height()*1.5 ) ); + } +// else +// clear(); + + //tip( QRect( 0, 0, mypViewPort->getGLWidget()->width(),mypViewPort->getGLWidget()->height() ) , "test Tool tip" ); + */ +} + +bool GLViewer_ObjectTip::eventFilter( QObject* theObj, QEvent* e ) +{ + hideTipAndSleep(); + switch( e->type() ) + { + /*case QEvent::MouseButtonPress: + case QEvent::MouseButtonRelease: + case QEvent::MouseButtonDblClick: + case QEvent::KeyPress: + case QEvent::KeyRelease: + // input - turn off tool tip mode + hideTipAndSleep(); + break;*/ + case QEvent::MouseMove: + { + //hideTipAndSleep(); + /*if( mypTimer->isActive() ) + { + mypTimer->Stop(); + wakeUp(); + }*/ + QWidget* aWidget = (QWidget*) theObj; + if( aWidget == mypViewPort->getGLWidget() ) + { + wakeup(); + QMouseEvent* m = (QMouseEvent *)e; + //if( !mypPoint ) + // mypPoint = new QPoint(); + + myPoint.setX( m->x() ); + myPoint.setY( m->y() ); + } + } + } + return false; +} + + +void GLViewer_ObjectTip::hideTipAndSleep() +{ + //if( mypPoint ) + // delete mypPoint; + myPoint.setX(-1); + myPoint.setY(-1); + + if( mypLabel ) + { + mypLabel->hide(); + //delete mypLabel; + } + mypTimer->stop(); +} + +void GLViewer_ObjectTip::showTip() +{ + if( maybeTip( myPoint ) ) + { + + mypLabel->setText( myText ); + mypLabel->adjustSize( ); + + QPoint pos = mypViewPort->getGLWidget()->mapToGlobal( myPoint ); + + //mypLabel->show(); + int cur_height = 24; + QCursor* aCursor = QApplication::overrideCursor(); + if( aCursor ) + { + const QBitmap* aBitmap = aCursor->bitmap(); + if( aBitmap ) + cur_height = aBitmap->height(); + } + mypLabel->setGeometry( pos.x(), pos.y() + cur_height, mypLabel->width(), mypLabel->height() ); + mypLabel->setPalette( QToolTip::palette() ); + + mypLabel->show(); + + } +} + +void GLViewer_ObjectTip::wakeup( int theTime ) +{ + if( mypTimer->isActive() ) + mypTimer->stop(); + mypTimer->start( theTime ); +} diff --git a/src/GLViewer/GLViewer_ToolTip.h b/src/GLViewer/GLViewer_ToolTip.h new file mode 100644 index 000000000..9dcb71f68 --- /dev/null +++ b/src/GLViewer/GLViewer_ToolTip.h @@ -0,0 +1,81 @@ +// Copyright (C) 2005 OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// Author : OPEN CASCADE +// + +// File: GLViewer_ToolTip.h +// Created: March, 2005 + +#ifndef GLVIEWER_TOOLTIP_H +#define GLVIEWER_TOOLTIP_H + +#include "GLViewer.h" + +//#include +//#include +#include + +#define TIP_TIME 1000 + +class GLViewer_ViewPort2d; +class QLabel; +/*************************************************************************** +** Class: GLViewer_ObjectTip +** Descr: ToolTip of GLViewer_Objects +** Module: GLViewer +** Created: UI team, 28.03.05 +****************************************************************************/ +class GLVIEWER_API GLViewer_ObjectTip: public QObject//QToolTip//QtxToolTip +{ + Q_OBJECT +public: + GLViewer_ObjectTip( GLViewer_ViewPort2d* ); + ~GLViewer_ObjectTip(); + +//protected: +// virtual void maybeTip( const QPoint& p ); + virtual bool eventFilter( QObject*, QEvent* ); + + virtual bool maybeTip( const QPoint&); + + void setText( const QString& theText ){ myText = theText; } + QString getText() const { return myText; } + +protected: + void timeIsOut(); + +private: + + void hideTipAndSleep(); + void wakeup( int mseconds = TIP_TIME ); + +private slots: + void showTip(); + +private: + GLViewer_ViewPort2d* mypViewPort; + + QTimer* mypTimer; + QPoint myPoint; + QLabel* mypLabel; + + QString myText; +}; + +#endif //GLVIEWER_TOOLTIP_H diff --git a/src/GLViewer/GLViewer_Tools.cxx b/src/GLViewer/GLViewer_Tools.cxx new file mode 100644 index 000000000..a54ad837f --- /dev/null +++ b/src/GLViewer/GLViewer_Tools.cxx @@ -0,0 +1,1085 @@ +// Copyright (C) 2005 OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// Author : OPEN CASCADE +// + +// File: GLViewer_Tools.cxx +// Created: April, 2005 + +//#include "GLViewerAfx.h" +#include "GLViewer_Tools.h" + +#include + +#include + +/**************************************************************************** +** Class: GLViewer_LineList +** Descr: Tools for distinct line +** Module: GLViewer +** Created: UI team, 27.10.05 +*****************************************************************************/ +GLViewer_LineList::GLViewer_LineList( int size ) +{ + myRealSize = 2*size; + mySegmentNumber = 0; + myMainCoord = 0.0; + + myArray = new double[myRealSize]; + + if( !myArray ) + { + cout << "Can't allocate memory: " << size << endl; + myRealSize = 0; + } + else + memset( myArray, 0, myRealSize*sizeof(double) ); +} + +GLViewer_LineList::~GLViewer_LineList() +{ + delete myArray; +} + +bool GLViewer_LineList::addSegment( double coord1, double coord2 ) +{ + if( coord1 > coord2 ) + { + double temp = coord1; + coord1 = coord2; + coord2 = temp; + } + + if( 2*mySegmentNumber == myRealSize || !myArray ) + return false; + + int index = 0; + double c1, c2; + while( index < mySegmentNumber) + { + readSegment( index, c1, c2 ); + if( coord1 < c1 && coord2 < c1 ) + { + for( int i = mySegmentNumber; i > index - 1; i--) + { + myArray[2*i] = myArray[2*i-2]; //2*(i-1) + myArray[2*i+1] = myArray[2*i-1];//2*(i-1)+1 + } + myArray[0] = coord1; + myArray[1] = coord2; + // mySegmentNumber; what is means ? + return true; + } + else if( coord1 < c1 && coord2 < c2 ) + { + myArray[index*2] = coord1; + return true; + } + else if( c1 < coord1 && coord2 < c2 ) + { + return true; + } + else if( coord1 < c2 && c2 < coord2 ) + { + if( c1 > coord1 ) + myArray[2*index] = coord1; + + if( index != mySegmentNumber - 1 ) + { + for( int i = index+1; i < mySegmentNumber; i++ ) + { + if( coord2 < myArray[2*i] ) + { + myArray[2*index+1] = coord2; + if( index+1 != i ) + { + for( int j = 0; i+j < mySegmentNumber;j++ ) + { + myArray[2*(index+1+j)] = myArray[2*(i+j)]; + myArray[2*(index+1+j)+1] = myArray[2*(i+j)+1]; + } + for( int k = 0; k < mySegmentNumber - i; k++ ) + { + myArray[2*(mySegmentNumber - 1- k)] = 0.0; + myArray[2*(mySegmentNumber - 1- k)+1] = 0.0; + } + mySegmentNumber -= i - index-1; + } + return true; + } + else if( coord2 < myArray[2*i+1] ) + { + myArray[2*index+1] = myArray[2*i+1]; + + for( int j = index+1; j < mySegmentNumber-1;j++ ) + { + myArray[2*j] = myArray[2*(i+j-index)]; + myArray[2*j+1] = myArray[2*(i+j-index)+1]; + } + for( int k = 0; k < mySegmentNumber - i-1; k++ ) + { + myArray[2*(mySegmentNumber - 1- k)] = 0.0; + myArray[2*(mySegmentNumber - 1- k)+1] = 0.0; + } + mySegmentNumber -= i - index; + return true; + } + } + } + else + { + myArray[2*index+1] = coord2; + return true; + } + } + index++; + } + + myArray[mySegmentNumber*2] = coord1; + myArray[mySegmentNumber*2+1] = coord2; + mySegmentNumber++; + + return true; +} + +bool GLViewer_LineList::readSegment( int theIndex, double& coord1, double& coord2 ) +{ + if( theIndex > mySegmentNumber || !myArray) + return false; + + coord1 = myArray[theIndex*2]; + coord2 = myArray[theIndex*2+1]; + + return true; +} + +int GLViewer_LineList::contains( double thePoint ) const +{ + if( !myArray || mySegmentNumber == 0 ) + return -1; + + for( int i = 0; i < mySegmentNumber; i++ ) + if( myArray[2*i] <= thePoint && thePoint <= myArray[2*i+1] ) + return i; + + return -1; + +} + +bool GLViewer_LineList::removeSegment( int theIndex ) +{ + if( theIndex > mySegmentNumber || !myArray) + return false; + + for( int i = theIndex; i < mySegmentNumber; i++ ) + { + myArray[i*2] = myArray[(i+1)*2]; + myArray[i*2+1] = myArray[(i+1)*2+1]; + } + mySegmentNumber--; + myArray[mySegmentNumber*2] = 0.0; + myArray[mySegmentNumber*2+1] = 0.0; + return true; +} + +bool GLViewer_LineList::removeSegment( double coord1, double coord2 ) +{ + if( coord1 > coord2 ) + { + double temp = coord1; + coord1 = coord2; + coord2 = temp; + } + + if( 2*mySegmentNumber == myRealSize || !myArray ) + return false; + + int index = 0; + double c1, c2; + while( index < mySegmentNumber) + { + readSegment( index, c1, c2 ); + if( coord1 < c1 && coord2 < c1 ) + { + //nothing + return true; + } + else if( coord1 < c1 && coord2 < c2 ) + { + myArray[index*2] = coord2; + return true; + } + else if( c1 < coord1 && coord2 < c2 ) + { + if( 2*mySegmentNumber == myRealSize ) + return false; + for( int i = mySegmentNumber; i > index + 1; i-- ) + { + myArray[2*i] = myArray[2*(i-1)]; + myArray[2*i+1] = myArray[2*(i-1)+1]; + } + myArray[2*(index+1)+1] = myArray[2*index+1]; + myArray[2*(index+1)] = coord2; + myArray[2*index+1] = coord1; + mySegmentNumber++; + return true; + } + else if( coord1 < c2 && c2 < coord2 ) + { + if( c1 < coord1 ) + { + myArray[2*index+1] = coord1; + } + + if( index != mySegmentNumber - 1 ) + { + for( int i = index+1; i < mySegmentNumber; i++ ) + { + if( coord2 < myArray[2*i] ) + { + if( index+1 != i ) + { + for( int j = 1; i+j-1 < mySegmentNumber;j++ ) + { + myArray[2*(index+j)] = myArray[2*(i+j-1)]; + myArray[2*(index+j)+1] = myArray[2*(i+j-1)+1]; + } + for( int k = 0; k < mySegmentNumber - i; k++ ) + { + myArray[2*(mySegmentNumber - 1- k)] = 0.0; + myArray[2*(mySegmentNumber - 1- k)+1] = 0.0; + } + mySegmentNumber -= i - index -1; + } + else + { + if( !(c1 < coord1) ) + { + for( int j = 0; index + j + 1 < mySegmentNumber;j++ ) + { + myArray[2*(index+j)] = myArray[2*(index+j+1)]; + myArray[2*(index+j)+1] = myArray[2*(index+j+1)+1]; + } + + myArray[2*(mySegmentNumber - 1)] = 0.0; + myArray[2*(mySegmentNumber - 1)+1] = 0.0; + + mySegmentNumber --; + } + + } + + return true; + + } + else if( coord2 < myArray[2*i+1] ) + { + if( index+1 != i ) + { + if( c1 < coord1 ) + index++; + + myArray[2*index] = coord2; + myArray[2*index+1] = myArray[2*i+1]; + + for( int j = 1; i+j < mySegmentNumber;j++ ) + { + myArray[2*(index+j)] = myArray[2*(i+j)]; + myArray[2*(index+j)+1] = myArray[2*(i+j)+1]; + } + for( int k = 0; k < mySegmentNumber - i - 1; k++ ) + { + myArray[2*(mySegmentNumber - 1- k)] = 0.0; + myArray[2*(mySegmentNumber - 1- k)+1] = 0.0; + } + mySegmentNumber -= i - index; + } + else + { + if( c1 < coord1 ) + { + myArray[2*(index+1)] = coord2; + return true; + } + else + { + myArray[2*(index)] = coord2; + myArray[2*(index)+1] = myArray[2*(index+1)+1]; + for( int j = index+1; j < mySegmentNumber-1; j++ ) + { + myArray[2*j] = myArray[2*(j+1)]; + myArray[2*j+1] = myArray[2*(j+1)+1]; + } + mySegmentNumber--; + myArray[2*mySegmentNumber] = 0.0; + myArray[2*mySegmentNumber+1] = 0.0; + } + } + return true; + } + } + } + else + { + if( !(c1 < coord1) ) + { + mySegmentNumber--; + myArray[2*index] = 0.0; + myArray[2*index+1] = 0.0; + } + } + } + index++; + } + return true; +} + +void GLViewer_LineList::clear() +{ + if( myArray ) + memset( myArray, 0, myRealSize*sizeof(double) ); +} + +void GLViewer_LineList::print() +{ + cout << "MainCoord: " << myMainCoord <<" SIZE: " << myRealSize << " ENum: " << mySegmentNumber << " :::"; + for( int i = 0; i < mySegmentNumber; i++ ) + cout << " " << myArray[2*i] << " " << myArray[2*i+1] << " | "; + + cout << endl; +} + +void GLViewer_LineList::show( FieldDim theDim ) +{ + if( !myArray ) + return; + + glColor3f( 1.0, 0.0, 1.0 ); + if( theDim == FD_X ) + { + glBegin( GL_LINES ); + for( int i = 0; i < mySegmentNumber; i++ ) + { + glVertex2d( myArray[2*i], myMainCoord ); + glVertex2d( myArray[2*i+1], myMainCoord ); + } + glEnd(); + } + else if( theDim == FD_Y ) + { + glBegin( GL_LINES ); + for( int i = 0; i < mySegmentNumber; i++ ) + { + glVertex2d( myMainCoord, myArray[2*i] ); + glVertex2d( myMainCoord, myArray[2*i+1] ); + } + glEnd(); + } +} + +/**************************************************************************** +** Class: GLViewer_LineField +** Descr: Tools for solving +** Module: GLViewer +** Created: UI team, 27.10.05 +*****************************************************************************/ +GLViewer_LineField::GLViewer_LineField() +{ + myCurArrayIndex = 0; + myGraphArray1 = NULL; + myGraphArray2 = NULL; + + myCurCount = 0; + + myXSize = 0; + myYSize = 0; + myXLineArray = NULL; + myYLineArray = NULL; +} +GLViewer_LineField::GLViewer_LineField( const int theMAXSize, const int theXN, const int theYN ) +{ + myCurArrayIndex = 0; + myGraphArray1 = NULL; + myGraphArray2 = NULL; + + myCurCount = 0; + + if( theXN <= 0 || theYN <= 0 ) + { + myXSize = 0; + myYSize = 0; + myXLineArray = NULL; + myYLineArray = NULL; + } + else + { + myXLineArray = new GLViewer_LineList*[theXN]; + myYLineArray = new GLViewer_LineList*[theYN]; + + for( int i = 0; i < theXN; i++ ) + myXLineArray[i] = new GLViewer_LineList( theMAXSize ); + + for( int j = 0; j < theYN; j++ ) + myYLineArray[j] = new GLViewer_LineList( theMAXSize ); + + myXSize = theXN; + myYSize = theYN; + } +} + +GLViewer_LineField::~GLViewer_LineField() +{ + if( myXLineArray ) + { + for( int i = 0; i < myXSize; i++ ) + delete myXLineArray[i]; + + delete myXLineArray; + } + + if( myYLineArray ) + { + for( int j = 0; j < myYSize; j++ ) + delete myYLineArray[j]; + + delete myYLineArray; + } + + if( myGraphArray1 ) + delete myGraphArray1; + + if( myGraphArray2 ) + delete myGraphArray2; +} + +void GLViewer_LineField::addLine( FieldDim theDim, GLViewer_LineList* ) +{ + //not implemented +} + +void GLViewer_LineField:: addLine( FieldDim theDim, double theMC, double theBegin, double theEnd ) +{ + GLViewer_LineList* aLL = new GLViewer_LineList( 1 ); + aLL->addSegment( theBegin, theEnd ); + aLL->setMainCoord( theMC ); + addLine( theDim, aLL ); +} + + +int GLViewer_LineField::insertLine( FieldDim theDim, GLViewer_LineList* theLL, int thePosition ) +{ + if( !myXLineArray || !myYLineArray ) + return -1; + + GLViewer_LineList** anArray = getLLArray( theDim ); + if( !anArray ) + return -1; + + int size = getDimSize( theDim ); + + if( thePosition >= size ) + return -1; + else if( thePosition < 0 ) + { + if( anArray[size-1]->count() != 0 ) // no more space + return -1; + + for( int i = 0; i < size; i++ ) + { + if( anArray[i]->count() == 0 ) + { + delete anArray[i]; + anArray[i] = theLL; + return i; + } + + double cur_mc = anArray[i]->mainCoord(); + if( theLL->mainCoord() < cur_mc ) + { + for( int j = 0; j+i+1 < size; j++ ) + { + delete anArray[size-j-1]; + anArray[size-j-1] = anArray[size-j-2]; + } + delete anArray[i]; + anArray[i] = theLL; + return i; + } + } + } + else + { + delete anArray[thePosition]; + anArray[thePosition] = theLL; + return thePosition; + } + + return -1; +} + +int GLViewer_LineField::insertLine( FieldDim theDim, double theMainCoord, double theBegin, double theEnd, int thePosition ) +{ + GLViewer_LineList* aLL = new GLViewer_LineList( 1 ); + aLL->addSegment( theBegin, theEnd ); + aLL->setMainCoord( theMainCoord ); + return insertLine( theDim, aLL, thePosition ); +} + + +FieldDim GLViewer_LineField::invertDim( FieldDim theFD ) +{ + if( theFD == FD_X ) + return FD_Y; + else + return FD_X; +} + +GLViewer_LineList* GLViewer_LineField::getLine( int theIndex, FieldDim theFD ) +{ + if( !myXLineArray || !myYLineArray ) + return NULL; + + if( theFD == FD_X ) + { + if( theIndex > myXSize ) + return NULL; + + return myXLineArray[theIndex]; + } + else if( theFD == FD_Y ) + { + if( theIndex > myYSize ) + return NULL; + + return myYLineArray[theIndex]; + } + + return NULL; +} + +void GLViewer_LineField::setBorders( double X1, double X2, double Y1, double Y2 ) +{ + if( !myXLineArray || !myYLineArray ) + return; + + for( int i = 0; i < myXSize; i++ ) + { + myXLineArray[i]->clear(); + myXLineArray[i]->addSegment( X1, X2 ); + myXLineArray[i]->setMainCoord( Y1 + (Y2-Y1)*(double(i)/(myXSize-1)) ); + } + + for( int j = 0; j < myYSize; j++ ) + { + myYLineArray[j]->clear(); + myYLineArray[j]->addSegment( Y1, Y2 ); + myYLineArray[j]->setMainCoord( X1 + (X2-X1)*(double(j)/(myYSize-1)) ); + } +} + +void GLViewer_LineField::addRectangle( double top, double right, double bottom, double left ) +{ + if( !myXLineArray || !myYLineArray ) + return; + for( int i = 0; i < myXSize; i++ ) + { + double mainCoord = myXLineArray[i]->mainCoord(); + if( mainCoord < top && mainCoord > bottom ) + myXLineArray[i]->removeSegment( left, right ); + } + + for( int j = 0; j < myYSize; j++ ) + { + double mainCoord = myYLineArray[j]->mainCoord(); + if( mainCoord < right && mainCoord > left ) + myYLineArray[j]->removeSegment( bottom, top ); + } +} + +void GLViewer_LineField::print() +{ + cout << "My X matrix Number: " << myXSize << endl; + for( int i = 0; i < myXSize; i++ ) + myXLineArray[i]->print(); + + cout << "My Y matrix Number: " << myYSize << endl; + for( int j = 0; j < myYSize; j++ ) + myYLineArray[j]->print(); +} + +void GLViewer_LineField::show() +{ + for( int i = 0; i < myXSize; i++ ) + getLine( i, FD_X )->show( FD_X ); + + for( int j = 0; j < myYSize; j++ ) + getLine( j, FD_Y )->show( FD_Y ); + int count = 0; + double* anArray = solution( count ); + glColor3f( 1.0, 0.0, 0.0 ); + glBegin( GL_LINES ); + for( int k = 0; k < count; k++ ) + { + glVertex2d( anArray[4*k], anArray[4*k+1] ); + glVertex2d( anArray[4*k+2], anArray[4*k+3] ); + } + glEnd(); + delete[] anArray; + cout << "Show function" << endl; +} + +int GLViewer_LineField::getDimSize( FieldDim theDim ) +{ + if( theDim == FD_X ) + return myXSize; + else if( theDim == FD_Y ) + return myYSize; + + return -1; +} + +int* GLViewer_LineField::intersectIndexes( FieldDim theDim, int theIndex, const GLViewer_LineList* theLL, int& theSize ) +{ + theSize = 0; + if( !myXLineArray || !myYLineArray ) + return NULL; + + int aDimSize = getDimSize( theDim ); + int* anArray = new int[aDimSize*2 ]; + + for( int i = 0; i < aDimSize; i++ ) + { + GLViewer_LineList* aLL = getLine( i, theDim ); + int index = aLL->contains( theLL->mainCoord() ); + if( index != -1 && theLL->contains( aLL->mainCoord() ) == theIndex ) + { + anArray[theSize*2] = i; + anArray[theSize*2+1] = index; + theSize++; + } + } + + return anArray; +} + + +bool GLViewer_LineField::setPoint( FieldPoint thePoint, double theX, double theY ) +{ + if( !myXLineArray || !myYLineArray ) + return false; + + int i = -1, j = -1; + int xSeg = -1, ySeg = -1; + for( i = 0; i < myXSize; i++ ) + { + GLViewer_LineList* aLL = getLine( i, FD_X ); + if( aLL->mainCoord() == theY ) + { + xSeg = aLL->contains( theX ); + break; + } + } + + for( j = 0; j < myYSize; j++ ) + { + GLViewer_LineList* aLL = getLine( j, FD_Y ); + if( aLL->mainCoord() == theX ) + { + ySeg = aLL->contains( theY ); + break; + } + } + + if( xSeg != -1 && ySeg != -1 ) + { + if( thePoint == FP_Start ) + { + myStartPoint.myXLineIndex = i; + myStartPoint.myXSegmentIndex = xSeg; + myStartPoint.myYLineIndex = j; + myStartPoint.myYSegmentIndex = ySeg; + myStartPoint.mySolveIndex = -1; + } + else + { + myEndPoint.myXLineIndex = i; + myEndPoint.myXSegmentIndex = xSeg; + myEndPoint.myYLineIndex = j; + myEndPoint.myYSegmentIndex = ySeg; + myEndPoint.mySolveIndex = -1; + } + return true; + } + else + return false; +} + +int GLViewer_LineField::segmentNumber() +{ + if( !(myXLineArray || myYLineArray) ) + return -1; + + int aNumber = 0; + for( int aDim = 0; aDim < 2; aDim++ ) + for( int i = 0, n = getDimSize( (FieldDim)aDim ); i < n; i++ ) + aNumber += getLine( i, (FieldDim)aDim )->count(); + + return aNumber; +} + +void GLViewer_LineField::optimize() +{ + if( !myXLineArray || !myYLineArray ) + return; + + for( int aDim = 0; aDim < 2; aDim++ ) + { + for( int i = 0, n = getDimSize( (FieldDim)aDim ); i < n; i++ ) + { + GLViewer_LineList* aLL = getLine( i, (FieldDim)aDim ); + for( int k =0, aSegNum = aLL->count(); k < aSegNum; k++ ) + { + // int index = i; unused + double a1, a2; + aLL->readSegment( k, a1, a2 ); + for( int l = i+1, m = getDimSize( (FieldDim)aDim ); l < m; l++ ) + { + int end = -1; + GLViewer_LineList* aCurLL = getLine( l, (FieldDim)aDim ); + for( int j = 0, count = aCurLL->count(); j < count; j++ ) + { + double c1, c2; + aCurLL->readSegment( j, c1, c2 ); + if( a1 == c1 && a2 == c2 ) + { + if( !(aDim == 0 && myStartPoint.myXLineIndex == l && myStartPoint.myXSegmentIndex == j) && + !(aDim == 0 && myEndPoint.myXLineIndex == l && myEndPoint.myXSegmentIndex == j) && + !(aDim == 1 && myStartPoint.myYLineIndex == l && myStartPoint.myYSegmentIndex == j) && + !(aDim == 1 && myEndPoint.myYLineIndex == l && myEndPoint.myYSegmentIndex == j) ) + aCurLL->removeSegment( j ); + end = 0; + break; + } + if( a1 < c1 ) + { + end = 1; + break; + } + } + if( end == -1 || end == 1) + break; + } + } + } + } +} + +void GLViewer_LineField::initialize() +{ + if( !myXLineArray || !myYLineArray ) + return; + + int size = segmentNumber(); + + myCurArrayIndex = 0; + myCurCount = 0; + + myGraphArray1 = new GraphNode[size]; + myGraphArray2 = new GraphNode[size]; + + int index = 0; + bool isXSet = false, + isYSet = false; + for( int aDim = 0; aDim < 2; aDim++ ) + { + for( int i = 0, n = getDimSize( (FieldDim)aDim ); i < n; i++ ) + { + GLViewer_LineList* aLL = getLine( i, (FieldDim)aDim ); + for( int k =0, aSegNum = aLL->count(); k < aSegNum; k++ ) + { + myGraphArray1[index].myCount = size; + myGraphArray1[index].myDim = (FieldDim)aDim; + myGraphArray1[index].myLineIndex = i; + myGraphArray1[index].mySegmentindex = k; + myGraphArray1[index].prevNodeIndex = -1; + + myGraphArray2[index].myCount = size; + myGraphArray2[index].myDim = (FieldDim)aDim; + myGraphArray2[index].myLineIndex = i; + myGraphArray2[index].mySegmentindex = k; + myGraphArray2[index].prevNodeIndex = -1; + + if( !isXSet && aDim == FD_X && myStartPoint.myXLineIndex == i && myStartPoint.myXSegmentIndex == k ) + { + myGraphArray1[index].myCount = 0; + isXSet = true; + } + + if( aDim == FD_Y && !isYSet && myStartPoint.myYLineIndex == i && myStartPoint.myYSegmentIndex == k ) + { + myGraphArray1[index].myCount = 0; + isYSet = true; + } + + index++; + } + } + } +} + +void GLViewer_LineField::iteration() +{ + int aParam = myCurCount; + myCurCount++; + + int* aNodes = findByCount( aParam ); + GraphNode* aCurArray = getCurArray(); + + for( int i = 0; i < aParam; i++ ) + { + GraphNode aCurNode = aCurArray[aNodes[i]]; + int aSize = 0; + int* aInterNodes = intersectIndexes( invertDim( aCurNode.myDim ), aCurNode.mySegmentindex, + getLine( aCurNode.myLineIndex, aCurNode.myDim ), aSize ); + for( int j = 0; j < aSize; j++ ) + { + int index = findBySegment( invertDim( aCurNode.myDim ), aInterNodes[2*j], aInterNodes[2*j+1], false ); + if( index != -1 ) + if( aCurArray[index].myCount > myCurCount ) + { + aCurArray[index].myCount = myCurCount; + aCurArray[index].prevNodeIndex = aNodes[i]; + } + } + + delete[] aInterNodes; + } + + delete[] aNodes; +} + +GLViewer_LineField::IterationStatus GLViewer_LineField::checkComplete() +{ + if( !myXLineArray || !myYLineArray || !myGraphArray1 || !myGraphArray2 ) + return IS_ERROR; + + int count = 0; + GraphNode* aCurArray = getCurArray(), + * aSecArray = getSecArray(); + + for( int i = 0, n = segmentNumber(); i < n; i++ ) + { + if( aCurArray[i].myCount != aSecArray[i].myCount ) + { + if( aCurArray[i].myDim == FD_X && + aCurArray[i].myLineIndex == myEndPoint.myXLineIndex && + aCurArray[i].mySegmentindex == myEndPoint.myXSegmentIndex ) + { + cout << "Algorithm complete X!!!!!!!" << endl; + myEndPoint.mySolveIndex = i; + return IS_SOLVED; + } + else if( aCurArray[i].myDim == FD_Y && + aCurArray[i].myLineIndex == myEndPoint.myYLineIndex && + aCurArray[i].mySegmentindex == myEndPoint.myYSegmentIndex ) + { + cout << "Algorithm complete Y!!!!!!!" << endl; + myEndPoint.mySolveIndex = i; + return IS_SOLVED; + } + else + { + count++; + aSecArray[i].myCount = aCurArray[i].myCount; + aSecArray[i].prevNodeIndex = aCurArray[i].prevNodeIndex; + } + } + } + + if( myCurArrayIndex == 0) + myCurArrayIndex = 1; + else + myCurArrayIndex = 0; + + cout << "Number of ways: " << count << endl; + if( count == 0 ) + return IS_LOOP; + + return IS_NOT_SOLVED; +} + +int* GLViewer_LineField::findByCount( int& theParam ) +{ + if( !myXLineArray || !myYLineArray || !myGraphArray1 || !myGraphArray2 ) + return NULL; + + int count = segmentNumber(); + int* anArray = new int[count]; + int aSize = 0; + + GraphNode* aCurArray = getCurArray(); + for( int i = 0; i < count; i++ ) + { + GraphNode aCurNode = aCurArray[i]; + if( aCurNode.myCount == theParam ) + { + anArray[aSize] = i; + aSize++; + } + } + + theParam = aSize; + return anArray; +} + +int GLViewer_LineField::findBySegment( FieldDim theDim, int theLineIndex, int theSegment, bool inCurArray ) +{ + if( !myXLineArray || !myYLineArray || !myGraphArray1 || !myGraphArray2 || getDimSize( theDim ) <= theLineIndex ) + return -1; + + GraphNode* aCurArray; + if( inCurArray ) + aCurArray = getCurArray(); + else + aCurArray = getSecArray(); + + for( int i = 0, n = segmentNumber(); i < n; i++ ) + { + GraphNode aCurNode = aCurArray[i]; + if( aCurNode.myDim == theDim && aCurNode.myLineIndex == theLineIndex && aCurNode.mySegmentindex == theSegment ) + return i; + } + + return -1; +} + +GLViewer_LineField::EndStatus GLViewer_LineField::startAlgorithm() +{ + if( !myXLineArray || !myYLineArray || !myGraphArray1 || !myGraphArray2 ) + return ES_ERROR; + + while( true ) + { + cout << "-----------Iteration #" << myCurCount << "-------------" << endl; + iteration(); + + IterationStatus is = checkComplete(); + if( is == IS_ERROR ) + return ES_ERROR; + else if( is == IS_LOOP ) + return ES_LOOP; + else if( is == IS_SOLVED ) + return ES_SOLVED; + } + return ES_SOLVED; +} + +double* GLViewer_LineField::solution( int& theSize ) +{ + if( !myXLineArray || !myYLineArray || !myGraphArray1 || !myGraphArray2 ) + return NULL; + + if( myEndPoint.mySolveIndex == -1 ) + return NULL; + + theSize = myCurCount+1; + double* anArray = new double[theSize*4]; + + GraphNode* aCurArray = getCurArray(); + + int index = myEndPoint.mySolveIndex; + for( int i = 0; i <= myCurCount; i++ ) + { + if( index == -1 ) + break; + double c1, c2; + GLViewer_LineList* aLL = getLine( aCurArray[index].myLineIndex, aCurArray[index].myDim ); + aLL->readSegment( aCurArray[index].mySegmentindex, c1, c2 ); + + if( aCurArray[index].myDim == FD_X ) + { + anArray[i*4] = c1; + anArray[i*4+1] = aLL->mainCoord(); + anArray[i*4+2] = c2; + anArray[i*4+3] = aLL->mainCoord(); + } + else + { + anArray[i*4] = aLL->mainCoord(); + anArray[i*4+1] = c1; + anArray[i*4+2] = aLL->mainCoord(); + anArray[i*4+3] = c2; + } + + index = aCurArray[index].prevNodeIndex; + } + + return anArray; +} + +GraphNode* GLViewer_LineField::getCurArray() +{ + if( !myGraphArray1 || !myGraphArray2 ) + return NULL; + + if( myCurArrayIndex == 0) + return myGraphArray1; + else + return myGraphArray2; +} + +GraphNode* GLViewer_LineField::getSecArray() +{ + if( !myGraphArray1 || !myGraphArray2 ) + return NULL; + + if( myCurArrayIndex == 0) + return myGraphArray2; + else + return myGraphArray1; +} + +int GLViewer_LineField::maxSegmentNum() +{ + if( !myXLineArray || !myYLineArray ) + return -1; + + int max_num = -1; + for( int aDim = 0; aDim < 2; aDim++ ) + { + for( int i = 0, n = getDimSize( (FieldDim)aDim ); i < n; i++ ) + { + int count = getLine( i, (FieldDim)aDim )->count(); + if( count > max_num ) + max_num = count; + } + } + + return max_num; +} + +GLViewer_LineList** GLViewer_LineField::getLLArray( FieldDim theDim ) +{ + if( theDim == FD_X ) + return myXLineArray; + else if( theDim == FD_Y ) + return myYLineArray; + else + return NULL; +} diff --git a/src/GLViewer/GLViewer_Tools.h b/src/GLViewer/GLViewer_Tools.h new file mode 100644 index 000000000..3acdd879b --- /dev/null +++ b/src/GLViewer/GLViewer_Tools.h @@ -0,0 +1,247 @@ +// Copyright (C) 2005 OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// Author : OPEN CASCADE +// + +// File: GLViewer_Tools.h +// Created: April, 2005 + +#ifndef GLVIEWER_TOOLS_H +#define GLVIEWER_TOOLS_H + +#ifdef WNT +#include "windows.h" +#endif + +#include "GLViewer.h" +#include "GLViewer_Defs.h" + +class GLViewer_LineField; + +/**************************************************************************** +** Class: GLViewer_Tools +** Descr: Tools for Viewer +** Module: GLViewer +** Created: UI team, 27.10.05 +*****************************************************************************/ +class GLVIEWER_API GLViewer_Tools +{ +public: + //GLViewer_Tools(); + //virtual ~GLViewer_Tools(); + //static + +}; + +//! Dimension of line +enum FieldDim +{ + FD_X = 0, /*along x axis*/ + FD_Y /*along y axis*/ +}; + +/*! + Class GLViewer_LineList + Tools for distinct line + This class implmented interface for segment operations: + add, cut, remove and etc. + Memory does not changed and allocated only one time +*/ +class GLViewer_LineList +{ +public: + GLViewer_LineList( int ); + virtual ~GLViewer_LineList(); + + //! Returns number of segments + int count() const { return mySegmentNumber; } + //! Returns real size + int size() const { return myRealSize; } + + bool addSegment( double coord1, double coord2 ); + bool removeSegment( int index ); + bool removeSegment( double coord1, double coord2 ); + + bool readSegment( int index, double& coord1, double& coord2 ); + + //! Returns index of segment, else -1 + int contains( double thePoint ) const; + + //! Sets level of segments + void setMainCoord( double theVal ) { myMainCoord = theVal; } + double mainCoord() const { return myMainCoord; } + + void clear(); + void print(); + + void show( FieldDim ); + + GLViewer_LineList& operator = ( GLViewer_LineList ); + +private: + double* myArray; + int myRealSize; + int mySegmentNumber; + + double myMainCoord; +}; + +/*! struct GraphNode describe node in algorithm on rare grid*/ +struct GraphNode +{ + int myCount; + FieldDim myDim; + int myLineIndex; + int mySegmentindex; + int prevNodeIndex; //feedback for searching for solution +}; + +/*! struct SearchPoint describe node for solving algorithm*/ +struct SearchPoint +{ + int myXLineIndex; + int myXSegmentIndex; + int myYLineIndex; + int myYSegmentIndex; + int mySolveIndex; +}; + +/*! Class GLViewer_LineField +* Tools for solving algorithm of finding shortest path on rare grid with minimum of +* line turns number +*/ +class GLViewer_LineField +{ +public: + //!Searched point + enum FieldPoint + { + FP_Start = 0, + FP_End = 1 + }; + + //! Status of interation + enum IterationStatus + { + IS_ERROR = 0, + IS_LOOP, + IS_NOT_SOLVED, + IS_SOLVED + }; + + //! Final status of solving + enum EndStatus + { + ES_ERROR = 0, + ES_LOOP, + ES_SOLVED + }; + + GLViewer_LineField(); + GLViewer_LineField( const int theMAXSize, const int xn, const int yn ); + virtual ~GLViewer_LineField(); + + //! Adds new line + /*!best way, if line is already sorted*/ + void addLine( FieldDim, GLViewer_LineList* ); + //! Calls previous + void addLine( FieldDim theDim, double theMC, double theBegin, double theEnd ); + + //! Adds new line and sorted field + /*! Returns position*/ + int insertLine( FieldDim theDim, GLViewer_LineList*, int thePosition ); + //! Calls previous + int insertLine( FieldDim theDim, double theMC, double theBegin, double theEnd, int thePosition ); + + //! Returns other dimension + static FieldDim invertDim( FieldDim ); + + //! Returns line by index and dimension + GLViewer_LineList* getLine( int index, FieldDim ); + + //! Nullifys field and sets same continued segments + void setBorders( double X1, double X2, double Y1, double Y2 ); + //! Cut rectangle in grid + void addRectangle( double top, double right, double bottom, double left ); + + //! returns arrey of intersects indexes with \param theLL + int* intersectIndexes( FieldDim theDim, int theIndex, const GLViewer_LineList* theLL , int& theSize ); + + void print(); + + void show(); + + int getDimSize( FieldDim ); + //! Returns number of segment + int segmentNumber(); + + //! Sets start/end search point + bool setPoint( FieldPoint, double x, double y ); + + //! Optimize field + /*! Removes all multiple segments*/ + void optimize(); + //! Some prepare actions + /*! Needs call setPoint before*/ + void initialize(); + //! Main method + EndStatus startAlgorithm(); + + //! Returns solution and size of solution + double* solution( int& size ); + +protected: + //! One iteration of algorithm + void iteration(); + //! Checks for complete status + IterationStatus checkComplete(); + + //! Finds LileList by counts and returns indexes + int* findByCount( int& theParam ); + //! Finds LileList by segment and dimension + int findBySegment( FieldDim, int coord1, int coord2, bool inCurArray = true ); + + //! Returns current solution array + GraphNode* getCurArray(); + //! Returns + GraphNode* getSecArray(); + + //! Returns maximum segment number + int maxSegmentNum(); + + //! Returns list of LileList by dimension + GLViewer_LineList** getLLArray( FieldDim ); + +private: + GLViewer_LineList** myXLineArray, + ** myYLineArray; + + int myXSize, + myYSize; + + GraphNode* myGraphArray1, + * myGraphArray2; + int myCurArrayIndex; + + SearchPoint myStartPoint, + myEndPoint; + int myCurCount; +}; + +#endif //GLVIEWER_TOOLS_H diff --git a/src/GLViewer/GLViewer_ViewFrame.cxx b/src/GLViewer/GLViewer_ViewFrame.cxx new file mode 100644 index 000000000..6600bb35f --- /dev/null +++ b/src/GLViewer/GLViewer_ViewFrame.cxx @@ -0,0 +1,549 @@ +// Copyright (C) 2005 OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// Author : OPEN CASCADE +// + +// File: GLViewer_ViewFrame.cxx +// Created: November, 2004 + +/*************************************************************************** +** Class: GLViewer_ViewFrame +** Descr: Frame window for viewport in QAD-based application +** Module: QAD +** Created: UI team, 05.09.00 +****************************************************************************/ + +//#include +#include "GLViewer_ViewFrame.h" +#include "GLViewer_Viewer.h" +#include "GLViewer_Viewer2d.h" +#include "GLViewer_ViewPort2d.h" + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +/*! + Constructor +*/ +GLViewer_ViewFrame::GLViewer_ViewFrame( SUIT_Desktop* d, GLViewer_Viewer* vw ) +: SUIT_ViewWindow( d ), +myViewer( vw ), +myVP( 0 ) +{ + QFrame* client = new QFrame( this ); + setCentralWidget( client ); + + QBoxLayout* layout = new QHBoxLayout( client, 1, 1 ); + layout->setAutoAdd( true ); + + GLViewer_ViewPort2d* vp = new GLViewer_ViewPort2d( client, this ); + //vp->turnGrid( true ); + //vp->turnCompass( true ); + //vp->enablePopup( false ); + setViewPort( vp ); + setBackgroundColor( Qt::white ); + + myToolBar = new QToolBar(this); + myToolBar->setCloseMode(QDockWindow::Undocked); + myToolBar->setLabel(tr("LBL_TOOLBAR_LABEL")); + createActions(); + createToolBar(); +} + +/*! + Destructor +*/ +GLViewer_ViewFrame::~GLViewer_ViewFrame() +{ +} + +//================================================================ +// Function : createActions +// Purpose : +//================================================================ +void GLViewer_ViewFrame::createActions() +{ + if (!myActionsMap.isEmpty()) return; + SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr(); + QAction* aAction; + + // Dump view + aAction = new QAction(tr("MNU_DUMP_VIEW"), aResMgr->loadPixmap( "GLViewer", tr( "ICON_GL_DUMP" ) ), + tr( "MNU_DUMP_VIEW" ), 0, this); + aAction->setStatusTip(tr("DSC_DUMP_VIEW")); + connect(aAction, SIGNAL(activated()), this, SLOT(onViewDump())); + myActionsMap[ DumpId ] = aAction; + + // FitAll + aAction = new QAction(tr("MNU_FITALL"), aResMgr->loadPixmap( "GLViewer", tr( "ICON_GL_FITALL" ) ), + tr( "MNU_FITALL" ), 0, this); + aAction->setStatusTip(tr("DSC_FITALL")); + connect(aAction, SIGNAL(activated()), this, SLOT(onViewFitAll())); + myActionsMap[ FitAllId ] = aAction; + + // FitRect + aAction = new QAction(tr("MNU_FITRECT"), aResMgr->loadPixmap( "GLViewer", tr( "ICON_GL_FITAREA" ) ), + tr( "MNU_FITRECT" ), 0, this); + aAction->setStatusTip(tr("DSC_FITRECT")); + connect(aAction, SIGNAL(activated()), this, SLOT(onViewFitArea())); + myActionsMap[ FitRectId ] = aAction; + + // FitSelect + aAction = new QAction(tr("MNU_FITSELECT"), aResMgr->loadPixmap( "GLViewer", tr( "ICON_GL_FITSELECT" ) ), + tr( "MNU_FITSELECT" ), 0, this); + aAction->setStatusTip(tr("DSC_FITSELECT")); + connect(aAction, SIGNAL(activated()), this, SLOT(onViewFitSelect())); + myActionsMap[ FitSelectId ] = aAction; + + // Zoom + aAction = new QAction(tr("MNU_ZOOM_VIEW"), aResMgr->loadPixmap( "GLViewer", tr( "ICON_GL_ZOOM" ) ), + tr( "MNU_ZOOM_VIEW" ), 0, this); + aAction->setStatusTip(tr("DSC_ZOOM_VIEW")); + connect(aAction, SIGNAL(activated()), this, SLOT(onViewZoom())); + myActionsMap[ ZoomId ] = aAction; + + // Panning + aAction = new QAction(tr("MNU_PAN_VIEW"), aResMgr->loadPixmap( "GLViewer", tr( "ICON_GL_PAN" ) ), + tr( "MNU_PAN_VIEW" ), 0, this); + aAction->setStatusTip(tr("DSC_PAN_VIEW")); + connect(aAction, SIGNAL(activated()), this, SLOT(onViewPan())); + myActionsMap[ PanId ] = aAction; + + // Global Panning + aAction = new QAction(tr("MNU_GLOBALPAN_VIEW"), aResMgr->loadPixmap( "GLViewer", tr( "ICON_GL_GLOBALPAN" ) ), + tr( "MNU_GLOBALPAN_VIEW" ), 0, this); + aAction->setStatusTip(tr("DSC_GLOBALPAN_VIEW")); + connect(aAction, SIGNAL(activated()), this, SLOT(onViewGlobalPan())); + myActionsMap[ GlobalPanId ] = aAction; + + aAction = new QAction(tr("MNU_RESET_VIEW"), aResMgr->loadPixmap( "GLViewer", tr( "ICON_GL_RESET" ) ), + tr( "MNU_RESET_VIEW" ), 0, this); + aAction->setStatusTip(tr("DSC_RESET_VIEW")); + connect(aAction, SIGNAL(activated()), this, SLOT(onViewReset())); + myActionsMap[ ResetId ] = aAction; +} + +//================================================================ +// Function : createToolBar +// Purpose : +//================================================================ +void GLViewer_ViewFrame::createToolBar() +{ + myActionsMap[DumpId]->addTo(myToolBar); + + SUIT_ToolButton* aScaleBtn = new SUIT_ToolButton(myToolBar); + aScaleBtn->AddAction(myActionsMap[FitAllId]); + aScaleBtn->AddAction(myActionsMap[FitRectId]); + aScaleBtn->AddAction(myActionsMap[FitSelectId]); + aScaleBtn->AddAction(myActionsMap[ZoomId]); + + SUIT_ToolButton* aPanBtn = new SUIT_ToolButton(myToolBar); + aPanBtn->AddAction(myActionsMap[PanId]); + aPanBtn->AddAction(myActionsMap[GlobalPanId]); + + myActionsMap[ResetId]->addTo(myToolBar); +} + +/*! + Sets the viewport for this frame +*/ +void GLViewer_ViewFrame::setViewPort( GLViewer_ViewPort* vp ) +{ + if ( myVP == vp ) + return; + + if ( myVP ) + { + disconnect( myVP, SIGNAL( vpDrawExternal( QPainter* ) ), this, SIGNAL( vfDrawExternal( QPainter* ) ) ); + disconnect( myVP, SIGNAL( vpMouseEvent( QMouseEvent* ) ), this, SLOT( mouseEvent( QMouseEvent* ) ) ); + disconnect( myVP, SIGNAL( vpKeyEvent( QKeyEvent* ) ), this, SLOT( keyEvent( QKeyEvent* ) ) ); + disconnect( myVP, SIGNAL( vpWheelEvent( QWheelEvent* ) ), this, SLOT( wheelEvent( QWheelEvent* ) ) ); + disconnect( myVP, SIGNAL( contextMenuRequested( QContextMenuEvent* ) ), + this, SIGNAL( contextMenuRequested( QContextMenuEvent* ) ) ); + } + myVP = vp; + if ( myVP ) + { + connect( myVP, SIGNAL( vpDrawExternal( QPainter* ) ), this, SIGNAL( vfDrawExternal( QPainter* ) ) ); + connect( myVP, SIGNAL( vpMouseEvent( QMouseEvent* ) ), this, SLOT( mouseEvent( QMouseEvent* ) ) ); + connect( myVP, SIGNAL( vpKeyEvent( QKeyEvent* ) ), this, SLOT( keyEvent( QKeyEvent* ) ) ); + connect( myVP, SIGNAL( vpWheelEvent( QWheelEvent* ) ), this, SLOT( wheelEvent( QWheelEvent* ) ) ); + connect( myVP, SIGNAL( contextMenuRequested( QContextMenuEvent* ) ), + this, SIGNAL( contextMenuRequested( QContextMenuEvent* ) ) ); + } +} + +/*! + Returns the viewport of this frame. [ public ] +*/ +GLViewer_ViewPort* GLViewer_ViewFrame::getViewPort() const +{ + return myVP; +} + +/*! + Set background of the viewport. [ public ] +*/ +void GLViewer_ViewFrame::setBackgroundColor( const QColor& color ) +{ + if ( myVP ) + myVP->setBackgroundColor( color ); +} + +/*! + Returns background of the viewport. [ public ] +*/ +QColor GLViewer_ViewFrame::backgroundColor() const +{ + if ( myVP ) + return myVP->backgroundColor(); + return QMainWindow::backgroundColor(); +} + +/*! + Sets the viewer for this view. [ public ] +*/ +void GLViewer_ViewFrame::setViewer( GLViewer_Viewer* v ) +{ + myViewer = v; +} + +/*! + Returns the viewer of this view. [ public ] +*/ +GLViewer_Viewer* GLViewer_ViewFrame::getViewer() const +{ + return myViewer; +} + +/*! + Returns the preferred view size. [ virtual public ] +*/ +QSize GLViewer_ViewFrame::sizeHint() const +{ + QWidget* p = parentWidget(); + if ( p && p->inherits( "QWorkspaceChild" ) ) + p = p->parentWidget(); /* QWorkspaceChild: internal impl class in QWorkspace */ + if ( !p ) + return QMainWindow::sizeHint(); + return QSize( 9 * p->width() / 10 , 9 * p->height() / 10 ); +} + +/*! + Called by viewer's 'update()' method. Does nothing by default [ virtual public ] +*/ +void GLViewer_ViewFrame::onUpdate( int ) +{ +} + +//#include + +void GLViewer_ViewFrame::onViewDump() +{ + GLViewer_Widget* aWidget = ((GLViewer_ViewPort2d*)myVP)->getGLWidget(); + int width, height; + width = aWidget->width(); + height = aWidget->height(); + + int imageSize = width*height*3; + unsigned char* imageBits = NULL; + + int reserve_bytes = width % 4; //32 bits platform + imageSize = (width+reserve_bytes)*height*3; + imageBits = new unsigned char[imageSize]; + + +#ifdef WNT + + int num; + HBITMAP hBmp; + HDC hdc_old, hdc; + HGLRC hglrc_old, hglrc; + + BITMAPINFO bi; + + hglrc_old = wglGetCurrentContext(); + hdc_old = wglGetCurrentDC(); + + hdc = CreateCompatibleDC( hdc_old ); + if( !hdc ) + { + cout << "Can't create compatible DC. Last Error Code: " << GetLastError() << endl; + return; + } + + int sizeBmi = Standard_Integer( sizeof(BITMAPINFO) + sizeof(RGBQUAD)*3 ); + PBITMAPINFO pBmi = (PBITMAPINFO)( new char[sizeBmi] ); + ZeroMemory( pBmi, sizeBmi ); + + pBmi->bmiHeader.biSize = sizeof( BITMAPINFOHEADER ); //sizeBmi + pBmi->bmiHeader.biWidth = width; + pBmi->bmiHeader.biHeight = height; + pBmi->bmiHeader.biPlanes = 1; + pBmi->bmiHeader.biBitCount = 24; + pBmi->bmiHeader.biCompression = BI_RGB; + + LPVOID ppvBits; + hBmp = CreateDIBSection ( hdc, pBmi, DIB_RGB_COLORS, &ppvBits, NULL, 0 ); + SelectObject ( hdc, hBmp ); + delete[] pBmi; + + PIXELFORMATDESCRIPTOR pfd; + ZeroMemory( &pfd, sizeof( PIXELFORMATDESCRIPTOR ) ); + pfd.nSize = sizeof( PIXELFORMATDESCRIPTOR ); + pfd.nVersion = 1; + pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_BITMAP; + pfd.iPixelType = PFD_TYPE_RGBA; + pfd.cColorBits = 24; + pfd.cDepthBits = 32; + pfd.iLayerType = PFD_MAIN_PLANE; + + int iPf = ChoosePixelFormat( hdc, &pfd); + if( iPf == 0 ) + { + if ( !DescribePixelFormat ( hdc, iPf, sizeof(PIXELFORMATDESCRIPTOR), &pfd ) ) + { + cout << "Can't describe Pixel Format. Last Error Code: " << GetLastError() << endl; + } + } + if ( !SetPixelFormat(hdc, iPf, &pfd) ) + { + cout << "Can't set Pixel Format. Last Error Code: " << GetLastError() << endl; + } + + hglrc = wglCreateContext( hdc ); + if( !hglrc ) + { + cout << "Can't create new GL Context. Last Error Code: " << GetLastError() << endl; + return; + } + if( !wglMakeCurrent( hdc, hglrc) ) + { + cout << "Can't make current new context!" << endl; + return; + } + + glViewport( 0, 0, width, height ); + + glMatrixMode( GL_PROJECTION ); + glLoadIdentity(); + GLfloat w_c = width / 2., h_c = height / 2.; + + gluOrtho2D( -w_c, w_c, -h_c, h_c ); + + glMatrixMode( GL_MODELVIEW ); + glLoadIdentity(); + + //set background + QColor aColor = ((GLViewer_ViewPort2d*)myVP)->backgroundColor(); + glClearColor( ( GLfloat )aColor.red() / 255, + ( GLfloat )aColor.green() / 255, + ( GLfloat )aColor.blue() / 255, + 1.0 ); + + aWidget->exportRepaint(); + + memset(&bi, 0, sizeof(BITMAPINFOHEADER)); + bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + bi.bmiHeader.biPlanes = 1; + bi.bmiHeader.biBitCount = 24; + bi.bmiHeader.biHeight = -height; + bi.bmiHeader.biWidth = width; + bi.bmiHeader.biCompression = BI_RGB; + + num = GetDIBits(hdc, hBmp, 0, height, imageBits, &bi, DIB_RGB_COLORS); + + wglMakeCurrent( hdc_old, hglrc_old ); + wglDeleteContext( hglrc ); + + +#else //XWindows +#endif + + unsigned int* aPix = NULL; + QImage anImage( width, height, 32 ); + for( int i = 0; i < height; i++ ) + { + memset( anImage.scanLine( i ), 0, sizeof(unsigned int)*width ); + unsigned char* pos; + for( int j = 0; j < width; j++ ) + { + pos = imageBits + i*width*3 + j*3 + reserve_bytes*i; + aPix = (unsigned int*)anImage.scanLine(i)+j; + *aPix = qRgb( *pos, *(pos+1), *(pos+2) ); + } + } + + delete [] imageBits; + + QString aFilter( "*.bmp\n*.png" ); + + QFileDialog aFileDlg( QDir::current().absPath(), aFilter, this ); + aFileDlg.setCaption( tr( "DUMP_VIEW_SAVE_FILE_DLG_CAPTION" ) ); + aFileDlg.setMode( QFileDialog::AnyFile ); + + if( !aFileDlg.exec() ) + return; + + QString aFileName = aFileDlg.selectedFile(); + QString aFileExt = aFileDlg.selectedFilter(); + + if( aFileName.isEmpty() ) + { + SUIT_MessageBox::error1( this, + tr( "DUMP_VIEW_ERROR_DLG_CAPTION" ), + tr( "DUMP_VIEW_ERROR_DLG_TEXT" ), + tr( "BUT_OK" ) ); + } + + QString aSaveOp = "BMP"; + QString aTypedFileExt = QFileInfo( aFileName ).extension( false ).lower(); + + if( aFileExt == "*.bmp" ) + { + if( aTypedFileExt.isEmpty() ) + aFileName += ".bmp"; + aSaveOp = "BMP"; + } + else if( aFileExt == "*.png" ) + if( aTypedFileExt.isEmpty() ) + aFileName += ".png"; + aSaveOp = "PNG"; + +//#ifdef WNT +// if( !anImage.save( aFileName, aSaveOp ) ) +//#else + if( !aWidget->grabFrameBuffer().save( aFileName, aSaveOp ) ) +//#endif + { + SUIT_MessageBox::error1( this, + tr( "DUMP_VIEW_ERROR_DLG_CAPTION" ), + tr( "DUMP_VIEW_ERROR_DLG_TEXT" ), + tr( "BUT_OK" ) ); + } +} + +void GLViewer_ViewFrame::onViewPan() +{ + myViewer->activateTransform( GLViewer_Viewer::Pan ); +} + +void GLViewer_ViewFrame::onViewZoom() +{ + myViewer->activateTransform( GLViewer_Viewer::Zoom ); +} + +void GLViewer_ViewFrame::onViewFitAll() +{ + myViewer->activateTransform( GLViewer_Viewer::FitAll ); +} + +void GLViewer_ViewFrame::onViewFitArea() +{ + myViewer->activateTransform( GLViewer_Viewer::FitRect ); +} + +void GLViewer_ViewFrame::onViewFitSelect() +{ + myViewer->activateTransform( GLViewer_Viewer::FitSelect ); +} + +void GLViewer_ViewFrame::onViewGlobalPan() +{ + myViewer->activateTransform( GLViewer_Viewer::PanGlobal ); +} + +void GLViewer_ViewFrame::onViewRotate() +{ + //myViewer->activateTransform( GLViewer_Viewer::Rotate ); +} + +void GLViewer_ViewFrame::onViewReset() +{ + myViewer->activateTransform( GLViewer_Viewer::Reset ); +} + +//================================================================ +// Function : mouseEvent +// Purpose : dispatches mouse events +//================================================================ +void GLViewer_ViewFrame::mouseEvent( QMouseEvent* e ) +{ + switch ( e->type() ) + { + case QEvent::MouseButtonPress: + emit mousePressed( this, e ); + break; + case QEvent::MouseButtonRelease: + emit mouseReleased( this, e ); + break; + case QEvent::MouseButtonDblClick: + emit mouseDoubleClicked( this, e ); + break; + case QEvent::MouseMove: + emit mouseMoving( this, e ); + break; + default: + break; + } +} + +//================================================================ +// Function : keyEvent +// Purpose : dispatches key events +//================================================================ +void GLViewer_ViewFrame::keyEvent( QKeyEvent* e ) +{ + switch ( e->type() ) + { + case QEvent::KeyPress: + emit keyPressed( this, e ); + break; + case QEvent::KeyRelease: + emit keyReleased( this, e ); + break; + default: + break; + } +} + +//================================================================ +// Function : wheelEvent +// Purpose : dispatches wheel events +//================================================================ +void GLViewer_ViewFrame::wheelEvent( QWheelEvent* e ) +{ + switch ( e->type() ) + { + case QEvent::Wheel: + emit wheeling( this, e ); + break; + default: + break; + } +} diff --git a/src/GLViewer/GLViewer_ViewFrame.h b/src/GLViewer/GLViewer_ViewFrame.h new file mode 100644 index 000000000..d90dfd3f5 --- /dev/null +++ b/src/GLViewer/GLViewer_ViewFrame.h @@ -0,0 +1,130 @@ +// Copyright (C) 2005 OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// Author : OPEN CASCADE +// + +// File: GLViewer_ViewFrame.h +// Created: November, 2004 + +/*************************************************************************** +** Class: GLViewer_ViewFrame +** Descr: Frame window for viewport in QAD-based application +** Module: QAD +** Created: UI team, 05.09.00 +****************************************************************************/ +#ifndef GLVIEWER_VIEWFRAME_H +#define GLVIEWER_VIEWFRAME_H + +#include "SUIT_ViewWindow.h" +#include "GLViewer.h" + +class QColor; + +class SUIT_Desktop; + +class GLViewer_Viewer; +class GLViewer_ViewPort; + +#include + +#ifdef WNT +#pragma warning( disable:4251 ) +#endif + +/*! Class GLViewer_ViewFrame +* Frame window for viewport in GLViewer +*/ + +class GLVIEWER_API GLViewer_ViewFrame: public SUIT_ViewWindow +{ + Q_OBJECT + +public: + GLViewer_ViewFrame( SUIT_Desktop* , GLViewer_Viewer* ); + ~GLViewer_ViewFrame(); + +public: + void setViewer( GLViewer_Viewer* ); + GLViewer_Viewer* getViewer() const; + + void setViewPort( GLViewer_ViewPort* ); + GLViewer_ViewPort* getViewPort() const; + + void setBackgroundColor( const QColor& ); + QColor backgroundColor() const; + + QSize sizeHint() const; + + virtual void onUpdate( int ); + +signals: + void vfDrawExternal( QPainter* ); + void vfViewClosing( QCloseEvent* ); + +protected: + GLViewer_Viewer* myViewer; + GLViewer_ViewPort* myVP; + +public: + //ViewType getTypeView() const { return VIEW_GL; }; + QWidget* getViewWidget() { return ( QWidget* )getViewPort(); }; + +protected slots: + void onViewDump(); + void onViewPan(); + void onViewZoom(); + void onViewFitAll(); + void onViewFitArea(); + void onViewFitSelect(); + void onViewGlobalPan(); + void onViewRotate(); + void onViewReset(); + void onViewFront() {}; + void onViewBack() {}; + void onViewRight() {}; + void onViewLeft() {}; + void onViewBottom() {}; + void onViewTop() {}; + void onViewTrihedron() {}; + +private slots: + void keyEvent( QKeyEvent* ); + void mouseEvent( QMouseEvent* ); + void wheelEvent( QWheelEvent* ); + +private: + void createActions(); + void createToolBar(); + +private: + //! Actions ID + enum { DumpId, FitAllId, FitRectId, FitSelectId, ZoomId, PanId, GlobalPanId, ResetId }; + typedef QMap ActionsMap; + +private: + ActionsMap myActionsMap; + QToolBar* myToolBar; +}; + + +#ifdef WNT +#pragma warning ( default:4251 ) +#endif + +#endif diff --git a/src/GLViewer/GLViewer_ViewManager.cxx b/src/GLViewer/GLViewer_ViewManager.cxx new file mode 100644 index 000000000..91150147a --- /dev/null +++ b/src/GLViewer/GLViewer_ViewManager.cxx @@ -0,0 +1,59 @@ +// Copyright (C) 2005 OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// Author : OPEN CASCADE +// + +// File: GLViewer_ViewManager.cxx +// Created: November, 2004 + +//#include +#include "GLViewer_ViewManager.h" +#include "GLViewer_ViewFrame.h" +#include "GLViewer_Viewer2d.h" +#include "SUIT_Desktop.h" + +int GLViewer_ViewManager::myMaxId = 0; + +//*************************************************************** +GLViewer_ViewManager::GLViewer_ViewManager( SUIT_Study* theStudy, SUIT_Desktop* theDesktop ) +: SUIT_ViewManager( theStudy, theDesktop ) +{ + myId = ++myMaxId; + setViewModel( new GLViewer_Viewer2d( "GLViewer" ) ); +} + +//*************************************************************** +GLViewer_ViewManager::~GLViewer_ViewManager() +{ +} + +//*************************************************************** +void GLViewer_ViewManager::setViewName(SUIT_ViewWindow* theView) +{ + int aPos = myViews.find(theView); + theView->setCaption( QString( "GL scene:%1 - viewer:%2" ).arg(myId).arg(aPos+1)); +} + +//*************************************************************** +void GLViewer_ViewManager::contextMenuPopup( QPopupMenu* popup ) +{ + SUIT_ViewManager::contextMenuPopup( popup ); + // if it is necessary invoke method CreatePopup of ViewPort + // be sure that existing QPopupMenu menu is used for that. +} diff --git a/src/GLViewer/GLViewer_ViewManager.h b/src/GLViewer/GLViewer_ViewManager.h new file mode 100644 index 000000000..82038d8d6 --- /dev/null +++ b/src/GLViewer/GLViewer_ViewManager.h @@ -0,0 +1,53 @@ +// Copyright (C) 2005 OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// Author : OPEN CASCADE +// + +// File: GLViewer_ViewManager.h +// Created: November, 2004 + +#ifndef GLVIEWER_VIEWMANAGER_H +#define GLVIEWER_VIEWMANAGER_H + +#include "GLViewer.h" +#include "SUIT_ViewManager.h" +#include "GLViewer_Viewer.h" + +class SUIT_Desktop; + +class GLVIEWER_API GLViewer_ViewManager : public SUIT_ViewManager +{ + Q_OBJECT +public: + GLViewer_ViewManager( SUIT_Study* theStudy, SUIT_Desktop* theDesktop ); + ~GLViewer_ViewManager(); + + GLViewer_Viewer* getGLViewer() { return (GLViewer_Viewer*) myViewModel; } + + virtual void contextMenuPopup( QPopupMenu* ); + +protected: + void setViewName(SUIT_ViewWindow* theView); + +protected: + static int myMaxId; + int myId; +}; + +#endif // GLVIEWER_VIEWMANAGER_H diff --git a/src/GLViewer/GLViewer_ViewPort.cxx b/src/GLViewer/GLViewer_ViewPort.cxx new file mode 100644 index 000000000..973342f84 --- /dev/null +++ b/src/GLViewer/GLViewer_ViewPort.cxx @@ -0,0 +1,594 @@ +// Copyright (C) 2005 OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// Author : OPEN CASCADE +// + +// File: GLViewer_ViewPort.cxx +// Created: November, 2004 + +/*************************************************************************** +** Class: GLViewer_ViewPort +** Descr: Visualisation canvas of QAD-based application +** Module: QAD +** Created: UI team, 05.09.00 +****************************************************************************/ + +//#include + +#if !defined WNT +#define QT_CLEAN_NAMESPACE /* avoid definition of INT32 and INT8 */ +#endif + +#include "GLViewer_ViewPort.h" + +#include "SUIT_ResourceMgr.h" +#include "SUIT_Session.h" + +#include +#include +#include +#include +#include +#include +#include + +#include + +#if !defined WNT +#include +#include +#include +#include +#include +#undef QT_CLEAN_NAMESPACE +#include +#include + +struct CMapEntry +{ + CMapEntry(); + ~CMapEntry(); + Colormap cmap; + bool alloc; + XStandardColormap scmap; +}; + +CMapEntry::CMapEntry() +{ + cmap = 0; + alloc = false; + scmap.colormap = 0; +} + +CMapEntry::~CMapEntry() +{ + if ( alloc ) + XFreeColormap( QPaintDevice::x11AppDisplay(), cmap ); +} + +static QIntDict *cmap_dict = 0; +static bool mesa_gl = false; + +static void cleanup_cmaps() +{ + if ( !cmap_dict ) + return; + cmap_dict->setAutoDelete( true ); + delete cmap_dict; + cmap_dict = 0; +} + +static Colormap choose_cmap( Display *dpy, XVisualInfo *vi ) +{ + if ( !cmap_dict ) + { + cmap_dict = new QIntDict; + const char *v = glXQueryServerString( dpy, vi->screen, GLX_VERSION ); + mesa_gl = strstr( v,"Mesa" ) != 0; + qAddPostRoutine( cleanup_cmaps ); + } + + CMapEntry *x = cmap_dict->find( (long)vi->visualid ); + if ( x ) // found colormap for visual + return x->cmap; + + x = new CMapEntry(); + + XStandardColormap *c; + int n, i; + +#ifdef DEBUG + cout << "Choosing cmap for vID = " << vi->visualid << endl; +#endif + + if ( vi->visualid == XVisualIDFromVisual( (Visual*)QPaintDevice::x11AppVisual() ) ) + { +#ifdef DEBUG + cout << "Using x11AppColormap" << endl; +#endif + return QPaintDevice::x11AppColormap(); + } + + if ( mesa_gl ) + { + Atom hp_cmaps = XInternAtom( dpy, "_HP_RGB_SMOOTH_MAP_LIST", true ); + if ( hp_cmaps && vi->visual->c_class == TrueColor && vi->depth == 8 ) + { + if ( XGetRGBColormaps( dpy, RootWindow( dpy, vi->screen ), &c, &n, hp_cmaps ) ) + { + i = 0; + while ( i < n && x->cmap == 0 ) + { + if ( c[i].visualid == vi->visual->visualid ) + { + x->cmap = c[i].colormap; + x->scmap = c[i]; + } + i++; + } + XFree( (char*)c ); + } + } + } +#if !defined( _OS_SOLARIS_ ) + if ( !x->cmap ) + { + if ( XmuLookupStandardColormap( dpy, vi->screen, vi->visualid, vi->depth, XA_RGB_DEFAULT_MAP, false, true ) ) + { + if ( XGetRGBColormaps( dpy, RootWindow( dpy, vi->screen ), &c, &n, XA_RGB_DEFAULT_MAP ) ) + { + i = 0; + while ( i < n && x->cmap == 0 ) + { + if ( c[i].visualid == vi->visualid ) + { + x->cmap = c[i].colormap; + x->scmap = c[i]; + } + i++; + } + XFree( (char *)c ); + } + } + } +#endif + if ( !x->cmap ) + { + // no shared cmap found + x->cmap = XCreateColormap( dpy, RootWindow( dpy, vi->screen ), vi->visual, AllocNone ); + x->alloc = true; + } + + cmap_dict->insert( (long)vi->visualid, x ); // associate cmap with visualid + return x->cmap; +} +#endif + +int GLViewer_ViewPort::nCounter = 0; +QCursor* GLViewer_ViewPort::defCursor = 0; +QCursor* GLViewer_ViewPort::panglCursor = 0; +QCursor* GLViewer_ViewPort::handCursor = 0; +QCursor* GLViewer_ViewPort::panCursor = 0; +QCursor* GLViewer_ViewPort::zoomCursor = 0; +QCursor* GLViewer_ViewPort::rotCursor = 0; +QCursor* GLViewer_ViewPort::sketchCursor = 0; + +/*! + Creates the necessary viewport cursors. [ static ] +*/ +void GLViewer_ViewPort::createCursors () +{ + defCursor = new QCursor( ArrowCursor ); + panglCursor = new QCursor( CrossCursor ); + handCursor = new QCursor( PointingHandCursor ); + panCursor = new QCursor( SizeAllCursor ); + + SUIT_ResourceMgr* rmgr = SUIT_Session::session()->resourceMgr(); + zoomCursor = new QCursor( rmgr->loadPixmap( "GLViewer", tr( "ICON_GL_CURSOR_ZOOM" ) ) ); + rotCursor = new QCursor( rmgr->loadPixmap( "GLViewer", tr( "ICON_GL_CURSOR_ROTATE" ) ) ); + sketchCursor = new QCursor( rmgr->loadPixmap( "GLViewer", tr( "ICON_GL_CURSOR_SKETCH" ) ) ); +} + +/*! + Destroys the viewport cursors. [ static ] +*/ +void GLViewer_ViewPort::destroyCursors() +{ + delete defCursor; defCursor = 0; + delete panglCursor; panglCursor = 0; + delete handCursor; handCursor = 0; + delete panCursor; panCursor = 0; + delete zoomCursor; zoomCursor = 0; + delete rotCursor; rotCursor = 0; + delete sketchCursor; sketchCursor = 0; +} + +/*! + Sets new default cursor. [ static ] +*/ +void GLViewer_ViewPort::setDefaultCursor( const QCursor& newCursor ) +{ + if ( !defCursor ) + defCursor = new QCursor(); + *defCursor = newCursor; +} + +/*! + Sets new cursor for drawing rectangle in the viewport. [ static ] +*/ +void GLViewer_ViewPort::setHandCursor( const QCursor& newCursor ) +{ + if ( !handCursor ) + handCursor = new QCursor(); + *handCursor = newCursor; +} + +/*! + Sets new cursor for panning. [ static ] +*/ +void GLViewer_ViewPort::setPanCursor( const QCursor& newCursor ) +{ + if ( !panCursor ) + panCursor = new QCursor(); + *panCursor = newCursor; +} + +/*! + Sets new cursor for global panning. [ static ] +*/ +void GLViewer_ViewPort::setPanglCursor( const QCursor& newCursor ) +{ + if ( !panglCursor ) + panglCursor = new QCursor(); + *panglCursor = newCursor; +} + +/*! + Sets new cursor for zooming. [ static ] +*/ +void GLViewer_ViewPort::setZoomCursor( const QCursor& newCursor ) +{ + if ( !zoomCursor ) + zoomCursor = new QCursor(); + *zoomCursor = newCursor; +} + +/*! + Sets new cursor for rotating. [ static ] +*/ +void GLViewer_ViewPort::setRotCursor( const QCursor& newCursor ) +{ + if ( !rotCursor ) + rotCursor = new QCursor(); + *rotCursor = newCursor; +} + +/*! + Sets new cursor for rotating. [ static ] +*/ +void GLViewer_ViewPort::setSketchCursor( const QCursor& newCursor ) +{ + if ( !rotCursor ) + sketchCursor = new QCursor(); + *sketchCursor = newCursor; +} + +/*! + Constructor +*/ +GLViewer_ViewPort::GLViewer_ViewPort( QWidget* parent ) +: QWidget( parent, 0, WRepaintNoErase | WResizeNoErase ) +{ + initialize(); +} + +/*! + Destructor +*/ +GLViewer_ViewPort::~GLViewer_ViewPort() +{ + cleanup(); +} + +/*! + Initializes viewport. [ private ] +*/ +void GLViewer_ViewPort::initialize() +{ + if ( nCounter++ == 0 ) + createCursors(); + + //myPopupActions.setAutoDelete( true ); + myPaintersRedrawing = false; + myEnableSketching = false; + myEnableTransform = true; + + setMouseTracking( true ); + setBackgroundMode( NoBackground ); + + setFocusPolicy( StrongFocus ); +} + +/*! + Cleans up the viewport. [ private ] +*/ +void GLViewer_ViewPort::cleanup() +{ + if ( --nCounter == 0 ) + destroyCursors(); +} + +/*! + Selects visual ID for OpenGL window ( X11 specific ). [ protected ] +*/ +void GLViewer_ViewPort::selectVisualId( ViewType type ) +{ +#if !defined WNT + XVisualInfo* pVisualInfo; + if ( x11Display() ) + { + /* Initialization with the default VisualID */ + //Visual *v = DefaultVisual( x11Display(), DefaultScreen( x11Display() ) ); + // int visualID = XVisualIDFromVisual( v ); unused + + /* Here we use the settings from Optimizer_ViewInfo::TxglCreateWindow() */ + int visualAttr[] = { GLX_RGBA, GLX_DEPTH_SIZE, 1, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, + GLX_BLUE_SIZE, 1, GLX_DOUBLEBUFFER, None }; + + pVisualInfo = ::glXChooseVisual( x11Display(), DefaultScreen( x11Display() ), visualAttr ); + + if ( isVisible() ) + hide(); + + XSetWindowAttributes a; + + a.colormap = choose_cmap( x11Display(), pVisualInfo ); /* find best colormap */ + a.background_pixel = backgroundColor().pixel(); + a.border_pixel = black.pixel(); + Window p = RootWindow( x11Display(), DefaultScreen( x11Display() ) ); + if ( parentWidget() ) + p = parentWidget()->winId(); + + Window w; + if ( type == Type2D ) // creating simple X window for 2d + { + unsigned long xbackground = + BlackPixel( x11Display(), DefaultScreen( x11Display() ) ); + unsigned long xforeground = + WhitePixel( x11Display(), DefaultScreen( x11Display() ) ); + + w = XCreateSimpleWindow ( x11Display(), p, x(), y(), width(), + height(), 0, xforeground, xbackground ); + } + else if ( type == Type3D ) + { + w = XCreateWindow( x11Display(), p, x(), y(), width(), height(), + 0, pVisualInfo->depth, InputOutput, pVisualInfo->visual, + CWBackPixel | CWBorderPixel | CWColormap, &a ); + } + else + return; + + Window *cmw; + Window *cmwret; + int count; + if ( XGetWMColormapWindows( x11Display(), topLevelWidget()->winId(), &cmwret, &count ) ) + { + cmw = new Window[count+1]; + memcpy( (char*)cmw, (char*)cmwret, sizeof(Window) * count ); + XFree( (char*)cmwret ); + int i; + + for ( i = 0; i < count; i++ ) + { + if ( cmw[i] == winId() ) /* replace old window */ + { + cmw[i] = w; + break; + } + } + + if ( i >= count ) /* append new window */ + cmw[count++] = w; + } + else + { + count = 1; + cmw = new Window[count]; + cmw[0] = w; + } + + /* Creating new window (with good VisualID) for this widget */ + create(w); + XSetWMColormapWindows( x11Display(), topLevelWidget()->winId(), cmw, count ); + delete[] cmw; + + if ( isVisible() ) + show(); + + if ( pVisualInfo ) + { + XFree( (char *)pVisualInfo ); + } + XFlush( x11Display() ); + } +#endif +} + +/*! + Sets the background 'color'. [ virtual ] +*/ +void GLViewer_ViewPort::setBackgroundColor( const QColor& color ) +{ + QPalette pal = palette(); + pal.setColor( QColorGroup::Background, color ); + setPalette( pal ); + repaint(); +} + +/*! + Returns the background color. [ virtual ] +*/ +QColor GLViewer_ViewPort::backgroundColor() const +{ + return palette().active().background(); +} + +/*! + Returns 'true' if sketching is enabled in this viewport. [ public ] +*/ +bool GLViewer_ViewPort::isSketchingEnabled() const +{ + return myEnableSketching; +} + +/*! + Enables / disables sketching [ public ] +*/ +void GLViewer_ViewPort::setSketchingEnabled( bool enable ) +{ + myEnableSketching = enable; +} + +/*! + Returns 'true' if transformations ( rotation, zoom etc. ) + are enabled in this viewport. [ public ] +*/ +bool GLViewer_ViewPort::isTransformEnabled() const +{ + return myEnableTransform; +} + +/*! + Enables / disables transformations. [ public ] +*/ +void GLViewer_ViewPort::setTransformEnabled( bool enable ) +{ + myEnableTransform = enable; +} + +/*! + Emits 'mouseEvent' signal. [ virtual protected ] +*/ +void GLViewer_ViewPort::mousePressEvent( QMouseEvent *e ) +{ + emit vpMouseEvent( e ); +} + +/*! + Emits 'mouseEvent' signal. [ virtual protected ] +*/ +void GLViewer_ViewPort::mouseMoveEvent( QMouseEvent* e ) +{ + emit vpMouseEvent( e ); +} + +/*! + Emits 'mouseEvent' signal. [ virtual protected ] +*/ +void GLViewer_ViewPort::mouseReleaseEvent( QMouseEvent *e ) +{ + emit vpMouseEvent( e ); + + /* show popup menu */ + if ( e->button() == Qt::RightButton ) + { + //QPopupMenu* popup = createPopup(); + //if ( popup && popup->count() ) + // popup->exec( QCursor::pos() ); + //destroyPopup( /*popup*/ ); + } +} + +/*! + Emits 'mouseEvent' signal. [ virtual protected ] +*/ +void GLViewer_ViewPort::mouseDoubleClickEvent( QMouseEvent *e ) +{ + emit vpMouseEvent( e ); +} + +/*! + Emits 'keyEvent' signal. [ virtual protected ] +*/ +void GLViewer_ViewPort::keyPressEvent( QKeyEvent *e ) +{ + emit vpKeyEvent( e ); +} + +/*! + Emits 'keyEvent' signal. [ virtual protected ] +*/ +void GLViewer_ViewPort::keyReleaseEvent( QKeyEvent *e ) +{ + emit vpKeyEvent( e ); +} + +/*! + Emits 'mouseEvent' signal. [ virtual protected ] +*/ +void GLViewer_ViewPort::wheelEvent( QWheelEvent *e ) +{ + emit vpWheelEvent( e ); +} + +/*! + Repaints the viewport. [ virtual protected ] +*/ +void GLViewer_ViewPort::paintEvent( QPaintEvent* ) +{ + if ( myPaintersRedrawing ) + { + QPainter p( this ); + emit vpDrawExternal( &p ); + myPaintersRedrawing = false; + } +} + +/*! + Forces to redraw the viewport by an external painter. [ public ] +*/ +void GLViewer_ViewPort::redrawPainters() +{ + myPaintersRedrawing = true; + repaint(); +} + +/*! + Updates this view. Does nothing by default. [ virtual public ] +*/ +void GLViewer_ViewPort::onUpdate() +{ +} + +/*! + Sets the background color with color selection dialog. [ virtual protected slot ] +*/ +void GLViewer_ViewPort::onChangeBgColor() +{ + QColor selColor = QColorDialog::getColor ( backgroundColor(), this ); + if ( selColor.isValid() ) + setBackgroundColor( selColor ); +} + +void GLViewer_ViewPort::contextMenuEvent( QContextMenuEvent* e ) +{ + //if ( e->reason() != QContextMenuEvent::Mouse ) + emit contextMenuRequested( e ); +} diff --git a/src/GLViewer/GLViewer_ViewPort.h b/src/GLViewer/GLViewer_ViewPort.h new file mode 100644 index 000000000..02ef4edaf --- /dev/null +++ b/src/GLViewer/GLViewer_ViewPort.h @@ -0,0 +1,182 @@ +// Copyright (C) 2005 OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// Author : OPEN CASCADE +// + +// File: GLViewer_ViewPort.h +// Created: November, 2004 + +/*************************************************************************** +** Class: GLViewer_ViewPort +** Descr: Visualisation canvas of GLViewer +** Created: UI team, 05.09.04 +****************************************************************************/ +#ifndef GLVIEWER_VIEWPORT_H +#define GLVIEWER_VIEWPORT_H + +#include "GLViewer.h" + +#include +#include +#include +#include + +#include + +class QRect; +class QCursor; +class QPainter; +class GLViewer_ViewSketcher; +class GLViewer_ViewTransformer; + +#ifdef WNT +#pragma warning( disable:4251 ) +#endif + +enum BlockStatus +{ + BS_NoBlock = 0x0000, + BS_Highlighting = 0x0001, + BS_Selection = 0x0002, + BS_Dragging = 0x0004 +}; + +/*! + * Class GLViewer_ViewPort + * Visualisation canvas of GLViewer + */ +class GLVIEWER_API GLViewer_ViewPort: public QWidget +{ + Q_OBJECT + friend class GLViewer_ViewSketcher; + friend class GLViewer_ViewTransformer; + +public: + GLViewer_ViewPort( QWidget* parent ); + ~GLViewer_ViewPort(); + +public: + //! Activates/deactivates sketching + void setSketchingEnabled( bool ); + //! Checks active status of sketcher + bool isSketchingEnabled() const; + //! Activates/deactivates transformer + void setTransformEnabled( bool ); + //! Checks active status of transformer + bool isTransformEnabled() const; + + //! Returns background color + virtual QColor backgroundColor() const; + //! Sets background color + virtual void setBackgroundColor( const QColor& ); + + //! Redraw external pa inters + void redrawPainters(); + + //! Updates view + virtual void onUpdate(); + + //! Returns blocking status for current started operations + virtual BlockStatus currentBlock(){ return BS_NoBlock; } + +protected: + enum ViewType { Type2D, Type3D }; + void selectVisualId( ViewType ); + + virtual QPaintDevice* getPaintDevice() { return this; } + virtual void contextMenuEvent( QContextMenuEvent * e ); + +//! STATICS + static void createCursors(); + static void destroyCursors(); + static QCursor* getHandCursor() { return handCursor; } + static void setHandCursor( const QCursor& newCursor ); + static QCursor* getPanCursor() { return panCursor; } + static void setPanCursor( const QCursor& newCursor ); + static QCursor* getPanglCursor() { return panglCursor; } + static void setPanglCursor( const QCursor& newCursor ); + static QCursor* getZoomCursor() { return zoomCursor; } + static void setZoomCursor( const QCursor& newCursor ); + +public://ouv + static QCursor* getDefaultCursor() { return defCursor; } + static void setDefaultCursor( const QCursor& newCursor ); + static QCursor* getRotCursor() { return rotCursor; } + static void setRotCursor( const QCursor& newCursor ); + static QCursor* getSketchCursor() { return sketchCursor; } + static void setSketchCursor( const QCursor& newCursor ); + +protected: +//! EVENTS + virtual void paintEvent( QPaintEvent *); + virtual void mouseMoveEvent( QMouseEvent *); + virtual void mouseReleaseEvent( QMouseEvent *); + virtual void mousePressEvent( QMouseEvent *); + virtual void mouseDoubleClickEvent( QMouseEvent *); + virtual void keyPressEvent( QKeyEvent *); + virtual void keyReleaseEvent( QKeyEvent *); + virtual void wheelEvent( QWheelEvent *); + +//! TO BE REDEFINED + virtual void reset() = 0; + virtual void pan( int, int ) = 0; + virtual void setCenter( int, int ) = 0; + virtual void zoom( int, int, int, int ) = 0; + virtual void fitRect( const QRect& ) = 0; + virtual void fitSelect() = 0; + virtual void fitAll( bool keepScale = false, bool withZ = true ) = 0; + +protected slots: + virtual void onChangeBgColor(); + +signals: + void vpKeyEvent( QKeyEvent* ); + void vpMouseEvent( QMouseEvent* ); + void vpWheelEvent( QWheelEvent* ); + void vpDrawExternal( QPainter* ); + + void contextMenuRequested( QContextMenuEvent* ); + +private: + void initialize(); + void cleanup(); + +protected: + //Handle(Aspect_Window) myWindow; + bool myEnableSketching; + bool myEnableTransform; + bool myPaintersRedrawing; /* set to draw externally */ + //QList myPopupActions; + +private: + static int nCounter; /* objects counter */ + static QCursor* defCursor; + static QCursor* panglCursor; + static QCursor* handCursor; + static QCursor* panCursor; + static QCursor* zoomCursor; + static QCursor* rotCursor; + static QCursor* sketchCursor; +}; + +#ifdef WNT +#pragma warning ( default:4251 ) +#endif + +#endif diff --git a/src/GLViewer/GLViewer_ViewPort2d.cxx b/src/GLViewer/GLViewer_ViewPort2d.cxx new file mode 100644 index 000000000..17d9d68da --- /dev/null +++ b/src/GLViewer/GLViewer_ViewPort2d.cxx @@ -0,0 +1,1264 @@ +// Copyright (C) 2005 OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// Author : OPEN CASCADE +// + +// File: GLViewer_ViewPort2d.cxx +// Created: November, 2004 + +/* GLViewer_ViewPort2d Source File */ + +//#include +#include "GLViewer_ViewPort2d.h" +#include "GLViewer_Viewer2d.h" +#include "GLViewer_ViewFrame.h" +#include "GLViewer_MimeSource.h" +#include "GLViewer_Context.h" +#include "GLViewer_Compass.h" +#include "GLViewer_Grid.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define WIDTH 640 +#define HEIGHT 480 +#define MARGIN 100 + +#define GRID_XSIZE 100 +#define GRID_YSIZE 100 + +int static aLastViewPostId = 0; + +void rotate_point( float& theX, float& theY, float theAngle ) +{ + float aTempX = theX * cos(theAngle) - theY * sin(theAngle); + float aTempY = theX * sin(theAngle) + theY * cos(theAngle); + theX = aTempX; + theY = aTempY; +} + +GLViewer_ViewPort2d::GLViewer_ViewPort2d( QWidget* parent, GLViewer_ViewFrame* theViewFrame ) : + GLViewer_ViewPort( parent ), + myMargin( MARGIN ), myWidth( WIDTH ), myHeight( HEIGHT ), + myXScale( 1.0 ), myYScale( 1.0 ), myXOldScale( 1.0 ), myYOldScale( 1.0 ), + myXPan( 0.0 ), myYPan( 0.0 ), + myIsMouseReleaseBlock( false ) +{ + if( theViewFrame == NULL ) + myViewFrame = ( GLViewer_ViewFrame* )parent; + else + myViewFrame = theViewFrame; + + myGrid = 0; + myCompass = 0; + myBorder = new GLViewer_Rect(); + + QBoxLayout* qbl = new QHBoxLayout( this ); + myGLWidget = new GLViewer_Widget( this, 0 ) ; + qbl->addWidget( myGLWidget ); + myGLWidget->setFocusProxy( this ); + setMouseTracking( TRUE ); + + myIsDragProcess = noDrag; + //myCurDragMousePos = QPoint(); + myCurDragPosX = NULL; + myCurDragPosY = NULL; + + myIsPulling = false; + + myViewPortId = aLastViewPostId; + aLastViewPostId++; + + mypFirstPoint = NULL; + mypLastPoint = NULL; + + myObjectTip = new QtxToolTip( myGLWidget );///GLViewer_ObjectTip( this ); + myObjectTip->setShowDelayTime( 60000 ); + connect( myObjectTip, SIGNAL( maybeTip( QPoint, QString&, QFont&, QRect&, QRect& ) ), + this, SLOT( onMaybeTip( QPoint, QString&, QFont&, QRect&, QRect& ) ) ); +// myGLWidget->installEventFilter( myObjectTip ); +} + +GLViewer_ViewPort2d::~GLViewer_ViewPort2d() +{ + if( myCompass ) + delete myCompass; + + if( myGrid ) + delete myGrid; + + delete myBorder; + delete myGLWidget; +} + +void GLViewer_ViewPort2d::onStartDragObject( ) +{ + if( myIsDragProcess == noDrag ) + { + myIsDragProcess = initDrag; + QCursor::setPos( (int)(*myCurDragPosX), (int)(*myCurDragPosY) ); + //myCurDragMousePos = QPoint( 0, 0 ); + delete myCurDragPosX; + delete myCurDragPosY; + myCurDragPosX = NULL; + myCurDragPosY = NULL; + return; + } +} + +void GLViewer_ViewPort2d::onCutObject() +{ + /*GLViewer_Object* aMovingObject = ((GLViewer_Viewer2d*)getViewFrame()->getViewer())->getGLContext()->getCurrentObject(); + if( aMovingObject ) + { + GLViewer_MimeSource* aMimeSource = new GLViewer_MimeSource(); + aMimeSource->setObject( aMovingObject ); + + QClipboard *aClipboard = QApplication::clipboard(); + aClipboard->clear(); + aClipboard->setData( aMimeSource ); + + ((GLViewer_Viewer2d*)getViewFrame()->getViewer())->getGLContext()->deleteObject( aMovingObject ); + }*/ + GLViewer_Context* aContext = ((GLViewer_Viewer2d*)getViewFrame()->getViewer())->getGLContext(); + int aObjNum = aContext->NbSelected(); + if( aObjNum > 0 ) + { + QValueList aObjects; + GLViewer_MimeSource* aMimeSource = new GLViewer_MimeSource(); + aContext->InitSelected(); + for( ; aContext->MoreSelected(); aContext->NextSelected() ) + aObjects.append( aContext->SelectedObject() ); + + //aMimeSource->setObjects( aObjects ); ouv 6.05.04 + + QClipboard *aClipboard = QApplication::clipboard(); + aClipboard->clear(); + aClipboard->setData( aMimeSource ); + + for( int i = 0; i < aObjNum; i++ ) + aContext->deleteObject( aObjects[i] ); + } +} + +void GLViewer_ViewPort2d::onCopyObject() +{ + /*GLViewer_Object* aMovingObject = ((GLViewer_Viewer2d*)getViewFrame()->getViewer())->getGLContext()->getCurrentObject(); + if( aMovingObject ) + { + GLViewer_MimeSource* aMimeSource = new GLViewer_MimeSource(); + aMimeSource->setObject( aMovingObject ); + + QClipboard *aClipboard = QApplication::clipboard(); + aClipboard->clear(); + aClipboard->setData( aMimeSource ); + } + */ + GLViewer_Context* aContext = ((GLViewer_Viewer2d*)getViewFrame()->getViewer())->getGLContext(); + int aObjNum = aContext->NbSelected(); + if( aObjNum > 0 ) + { + QValueList aObjects; + GLViewer_MimeSource* aMimeSource = new GLViewer_MimeSource(); + aContext->InitSelected(); + for( ; aContext->MoreSelected(); aContext->NextSelected() ) + aObjects.append( aContext->SelectedObject() ); + + //aMimeSource->setObjects( aObjects ); ouv 6.05.04 + + QClipboard *aClipboard = QApplication::clipboard(); + aClipboard->clear(); + aClipboard->setData( aMimeSource ); + } +} + +void GLViewer_ViewPort2d::onPasteObject() +{ + /*QClipboard *aClipboard = QApplication::clipboard(); + QMimeSource* aMimeSource = aClipboard->data(); + if( aMimeSource->provides( "GLViewer_Object" ) ) + { + const char* aType; + int i = 1; + QByteArray anArray; + do + { + aType = aMimeSource->format( i ); + anArray = aMimeSource->encodedData( aType ); + if( anArray.size() != 0 ) + break; + i++; + } + while( aType != 0 ); + if( anArray.size() == 0 ) + return; + + GLViewer_Object* aObject = GLViewer_MimeSource::getObject( anArray, aType ); + if( !aObject ) + return; + + ((GLViewer_Viewer2d*)getViewFrame()->getViewer())->getGLContext()->insertObject( aObject, true ); + } + */ + /* ouv 6.05.04 + QClipboard *aClipboard = QApplication::clipboard(); + + QMimeSource* aMimeSource = aClipboard->data(); + if( aMimeSource->provides( "GLViewer_Objects" ) ) + { + QByteArray anArray = aMimeSource->encodedData( "GLViewer_Objects" ); + QValueList aObjects = GLViewer_MimeSource::getObjects( anArray, "GLViewer_Objects" ); + if( aObjects.empty() ) + return; + GLViewer_Context* aContext = ((GLViewer_Viewer2d*)getViewFrame()->getViewer())->getGLContext(); + for( int i = 0; i < aObjects.count(); i++ ) + aContext->insertObject( aObjects[i], true ); + } + */ +} + +void GLViewer_ViewPort2d::onDragObject( QMouseEvent* e ) +{ + //cout << "---GLViewer_ViewPort2d::onDragObject()---" << endl; + GLViewer_Viewer2d* aViewer = (GLViewer_Viewer2d*)getViewFrame()->getViewer(); + GLViewer_Context* aContext = aViewer->getGLContext(); + GLViewer_Object* anObject = aContext->getCurrentObject(); + + if( !aContext ) + return; + + float aX = e->pos().x(); + float anY = e->pos().y(); + aViewer->transPoint( aX, anY ); + + if( myCurDragPosX == NULL && myCurDragPosY == NULL ) + { + myCurDragPosX = new float(aX); + myCurDragPosY = new float(anY); + return; + } + + //QPoint aNewPos = e->pos(); + //GLViewer_Viewer2d* aViewer = (GLViewer_Viewer2d*)getViewFrame()->getViewer(); + + if( anObject && (e->state() & LeftButton ) ) + { + if( aContext->isSelected( anObject ) ) + { + for( aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected() ) + { + GLViewer_Object* aMovingObject = aContext->SelectedObject(); + if( aMovingObject ) + aMovingObject->moveObject( aX - *myCurDragPosX, anY - *myCurDragPosY); + } + } + else + anObject->moveObject( aX - *myCurDragPosX, anY - *myCurDragPosY); + } + else if( aContext->NbSelected() && (e->state() & MidButton ) ) + for( aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected() ) + (aContext->SelectedObject())->moveObject( aX - *myCurDragPosX, anY - *myCurDragPosY); + + delete myCurDragPosX; + delete myCurDragPosY; + myCurDragPosX = new float(aX); + myCurDragPosY = new float(anY); + + myGLWidget->updateGL(); +} + +/*! + Emits 'mouseEvent' signal. [ virtual protected ] +*/ +void GLViewer_ViewPort2d::mousePressEvent( QMouseEvent* e ) +{ + emit vpMouseEvent( e ); + + GLViewer_Viewer2d* aViewer = (GLViewer_Viewer2d*)getViewFrame()->getViewer(); + GLViewer_Context* aContext = aViewer->getGLContext(); + + GLViewer_Object* anObject = NULL; + if( aContext ) + anObject = aContext->getCurrentObject(); + + bool accel = e->state() & GLViewer_ViewTransformer::accelKey(); + if( ( anObject && !( accel || e->button() == Qt::RightButton ) ) || + ( aContext->NbSelected() && !accel && e->button() == Qt::MidButton ) ) + { + myIsDragProcess = inDrag; + } +} + +/*! + Emits 'mouseEvent' signal. [ virtual protected ] +*/ +void GLViewer_ViewPort2d::mouseMoveEvent( QMouseEvent* e ) +{ + emit vpMouseEvent( e ); + + if( myIsDragProcess == inDrag ) + onDragObject( e ); + + /*GLViewer_Viewer2d* aViewer = (GLViewer_Viewer2d*)getViewFrame()->getViewer(); + GLViewer_Context* aContext = aViewer->getGLContext(); + + GLViewer_Object* anObj = aContext->getCurrentObject(); + if( anObj && aContext->currentObjectIsChanged() ) + { + //cout << "GLViewer_ViewPort2d::mouseMoveEvent{QToolTip::add}" << endl; + //QToolTip::remove( myGLWidget ); + QRect* aRect = (aViewer->getWinObjectRect(anObj)); + //QToolTip::add( myGLWidget, *aRect, anObj->getToolTipText() ); + myGLWidget->addToolTip( anObj->getToolTipText(), *aRect ); + } + if(!anObj) + { + //cout << "GLViewer_ViewPort2d::mouseMoveEvent{QToolTip::remove}" << endl; + //QRect* aRect = (aViewer->getWinObjectRect(anObj)); + //QToolTip::remove( myGLWidget, *aRect ); + myGLWidget->removeToolTip(); + }*/ +} + +/*! + Emits 'mouseEvent' signal. [ virtual protected ] +*/ +void GLViewer_ViewPort2d::mouseReleaseEvent( QMouseEvent* e ) +{ + if ( myIsMouseReleaseBlock ) + { + // skip mouse release after double click + myIsMouseReleaseBlock = false; + return; + } + + /* show popup menu */ + if ( e->button() == Qt::RightButton ) + { + //QPopupMenu* popup = createPopup(); + //if ( popup && popup->count() ) + // popup->exec( QCursor::pos() ); + //destroyPopup( /*popup*/ ); + } + emit vpMouseEvent( e ); + + if( myIsDragProcess == inDrag ) + { + bool isAnyMoved = false; + GLViewer_Viewer2d* aViewer = (GLViewer_Viewer2d*)getViewFrame()->getViewer(); + GLViewer_Context* aContext = aViewer->getGLContext(); + GLViewer_Object* aMovingObject; + for( aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected() ) + { + aMovingObject = aContext->SelectedObject(); + if( aMovingObject ) + isAnyMoved = aMovingObject->finishMove() || isAnyMoved; + } + + aMovingObject = aContext->getCurrentObject(); + if( aMovingObject ) + isAnyMoved = aMovingObject->finishMove() || isAnyMoved; + + myIsDragProcess = noDrag; + //myCurDragMousePos.setX( 0 ); + //myCurDragMousePos.setY( 0 ); + delete myCurDragPosX; + delete myCurDragPosY; + myCurDragPosX = NULL; + myCurDragPosY = NULL; + + if( isAnyMoved ) + { + emit objectMoved(); + aViewer->updateBorders(); + } + } +} + +void GLViewer_ViewPort2d::mouseDoubleClickEvent( QMouseEvent * e ) +{ + //redefined to block mouse release after mouse double click + myIsMouseReleaseBlock = true; + // invoke base implementation + GLViewer_ViewPort::mouseDoubleClickEvent( e ); +} + +void GLViewer_ViewPort2d::turnCompass( GLboolean on ) +{ + if( on ) + myCompass = new GLViewer_Compass( Qt::green, 30, GLViewer_Compass::TopRight, 10, 5, 12, 3 ); + else if( myCompass ) + delete myCompass; +} + +void GLViewer_ViewPort2d::turnGrid( GLboolean on ) +{ + if( on ) + { + myGrid = new GLViewer_Grid( 2*WIDTH, 2*HEIGHT, + 2*WIDTH, 2*HEIGHT, + GRID_XSIZE, GRID_YSIZE, + myXPan, myYPan, + myXScale, myYScale ); + } + else if( myGrid ) + delete myGrid; +} + +void GLViewer_ViewPort2d::setGridColor( const QColor gridColor, const QColor axisColor ) +{ + if( myGrid ) + { + myGrid->setGridColor( ( GLfloat )gridColor.red() / 255, + ( GLfloat )gridColor.green() / 255, + ( GLfloat )gridColor.blue() / 255 ); + myGrid->setAxisColor( ( GLfloat )axisColor.red() / 255, + ( GLfloat )axisColor.green() / 255, + ( GLfloat )axisColor.blue() / 255 ); + } +} + +void GLViewer_ViewPort2d::setBackgroundColor( const QColor& color ) +{ + GLViewer_ViewPort::setBackgroundColor( color ); + myGLWidget->makeCurrent(); + glClearColor( ( GLfloat )color.red() / 255, + ( GLfloat )color.green() / 255, + ( GLfloat )color.blue() / 255, 1.0 ); + myGLWidget->repaint(); +} + +QColor GLViewer_ViewPort2d::backgroundColor() const +{ + return GLViewer_ViewPort::backgroundColor(); +} + +void GLViewer_ViewPort2d::initResize( int x, int y ) +{ + float xa, xb, ya, yb; + xa = myBorder->left() - myMargin; + xb = myBorder->right() + myMargin; + ya = myBorder->top() - myMargin; + yb = myBorder->bottom() + myMargin; + + GLfloat zoom, xzoom, yzoom; + GLfloat w = x; + GLfloat h = y; + bool max = FALSE; + + xzoom = (GLfloat)x / myWidth; + yzoom = (GLfloat)y / myHeight; + + if ( ( xzoom < yzoom ) && ( xzoom < 1 ) ) + zoom = xzoom; + else if ( ( yzoom < xzoom ) && ( yzoom < 1 ) ) + zoom = yzoom; + else + { + max = TRUE; + zoom = xzoom > yzoom ? xzoom : yzoom; + } + + if ( !max && ( ! ( ( ( myXPan + w/2 ) < xb * myXScale * zoom ) || + ( ( myXPan - w/2 ) > xa * myXScale * zoom ) || + ( ( myYPan + h/2 ) < yb * myYScale * zoom ) || + ( ( myYPan - h/2 ) > ya * myYScale * zoom ) ) ) ) + zoom = 1; + + if ( max && ( ( ( myXPan + w/2 ) < xb * myXScale * zoom ) || + ( ( myXPan - w/2 ) > xa * myXScale * zoom ) || + ( ( myYPan + h/2 ) < yb * myYScale * zoom ) || + ( ( myYPan - h/2 ) > ya * myYScale * zoom ) ) ) + zoom = 1; + + myWidth = x; + myHeight = y; + + myXScale *= zoom; + myYScale = myXScale; + + if ( myGrid ) + myGrid->setResize( 2*x, 2*y, zoom ); + + myGLWidget->setScale( myXScale, myYScale, 1.0 ); +} + +void GLViewer_ViewPort2d::paintEvent( QPaintEvent* e ) +{ + //cout << "GLViewer_ViewPort2d::paintEvent" << endl; + myGLWidget->updateGL(); + GLViewer_ViewPort::paintEvent( e ); +} + +void GLViewer_ViewPort2d::resizeEvent( QResizeEvent* e ) +{ + //cout << "GLViewer_ViewPort2d::resizeEvent" << endl; + GLViewer_ViewPort::resizeEvent( e ); +} + +void GLViewer_ViewPort2d::reset() +{ + //cout << "GLViewer_ViewPort2d::reset" << endl; + + GLint val[4]; + GLint vpWidth, vpHeight; + + myGLWidget->makeCurrent(); + glGetIntegerv( GL_VIEWPORT, val ); + vpWidth = val[2]; + vpHeight = val[3]; + + GLint w = myGLWidget->getWidth(); + GLint h = myGLWidget->getHeight(); + GLfloat zoom = vpWidth / ( GLfloat )w < vpHeight / ( GLfloat )h ? + vpWidth / ( GLfloat )w : vpHeight / ( GLfloat )h; + + if( myGrid ) + { + myGrid->setPan( 0.0, 0.0 ); + myGrid->setZoom( zoom / myXScale ); + } + + myXPan = 0.0; + myYPan = 0.0; + myXScale = zoom; + myYScale = zoom; + + myGLWidget->setPan( myXPan, myYPan, 0.0 ); + myGLWidget->setScale( myXScale, myYScale, 1.0 ); + myGLWidget->setRotationAngle( 0.0 ); + myGLWidget->setRotation( 0.0, 0.0, 0.0, 1.0 ); + myGLWidget->updateGL(); +} + +void GLViewer_ViewPort2d::pan( int dx, int dy ) +{ + //cout << "GLViewer_ViewPort2d::pan " << dx << " " << dy << endl; + + /*myXPan += dx / myXScale; + myYPan += dy / myYScale; + + float ra, rx, ry, rz; + myGLWidget->getRotation( ra, rx, ry, rz ); + GLfloat angle = ra * PI / 180.; + + if( myGrid ) + myGrid->setPan( myXPan*cos(angle) + myYPan*sin(angle), + -myXPan*sin(angle) + myYPan*cos(angle) ); + + */ + float ra, rx, ry, rz; + myGLWidget->getRotation( ra, rx, ry, rz ); + GLfloat angle = ra * PI / 180.; + + myXPan += (dx*cos(angle) + dy*sin(angle)) / myXScale; + myYPan += (-dx*sin(angle) + dy*cos(angle)) / myXScale; + + if( myGrid ) + myGrid->setPan( myXPan, myYPan ); + + myGLWidget->setPan( myXPan, myYPan, 0.0 ); + myGLWidget->setScale( myXScale, myYScale, 1.0 ); + myGLWidget->updateGL(); +} + +void GLViewer_ViewPort2d::setCenter( int x, int y ) +{ + //cout << "GLViewer_ViewPort2d::setCenter" << endl; + + GLint val[4]; + GLint vpWidth, vpHeight; + + myGLWidget->makeCurrent(); + glGetIntegerv( GL_VIEWPORT, val ); + vpWidth = val[2]; + vpHeight = val[3]; + + myXPan -= ( x - vpWidth/2 ) / myXScale; + myYPan += ( y - vpHeight/2 ) / myYScale; + + if( myGrid ) + { + myGrid->setPan( myXPan, myYPan ); + myGrid->setZoom( myXOldScale / myXScale ); + } + + myXScale = myXOldScale; + myYScale = myYOldScale; + + myGLWidget->setPan( myXPan, myYPan, 0.0 ); + myGLWidget->setScale( myXScale, myYScale, 1.0 ); + myGLWidget->updateGL(); +} + +void GLViewer_ViewPort2d::zoom( int x0, int y0, int x, int y ) +{ + //cout << "GLViewer_ViewPort2d::zoom" << endl; + + float dx, dy, zm; + dx = x - x0; + dy = y - y0; + + if ( dx == 0. && dy == 0. ) + return; + + zm = sqrt(dx * dx + dy * dy) / 100. + 1; + zm = (dx > 0.) ? zm : 1. / zm; + + //backup values + float bX = myXScale; + float bY = myYScale; + myXScale *= zm; + myYScale *= zm; + + if( myGrid ) + { + if( myGrid->setZoom( zm ) ) + { + myGLWidget->setPan( myXPan, myYPan, 0.0 ); + myGLWidget->setScale( myXScale, myYScale, 1.0 ); + myGLWidget->updateGL(); + } + else + {// undo + myXScale = bX; + myYScale = bY; + } + } + else + { + myGLWidget->setPan( myXPan, myYPan, 0.0 ); + myGLWidget->setScale( myXScale, myYScale, 1.0 ); + myGLWidget->updateGL(); + } +} + +void GLViewer_ViewPort2d::fitRect( const QRect& rect ) +{ + float x0, x1, y0, y1; + float dx, dy, zm, centerX, centerY; + + GLint val[4]; + GLint vpWidth, vpHeight; + + myGLWidget->makeCurrent(); + glGetIntegerv( GL_VIEWPORT, val ); + vpWidth = val[2]; + vpHeight = val[3]; + + x0 = rect.left(); + x1 = rect.right(); + y0 = rect.top(); + y1 = rect.bottom(); + + dx = fabs( x1 - x0 ); + dy = fabs( y1 - y0 ); + centerX = ( x0 + x1 ) / 2.; + centerY = ( y0 + y1 ) / 2.; + + if ( dx == 0. || dy == 0. ) + return; + + zm = vpWidth / dx < vpHeight / dy ? vpWidth / dx : vpHeight / dy; + + float aDX = ( vpWidth / 2. - centerX ) / myXScale; + float aDY = ( vpHeight / 2. - centerY ) / myYScale; + + float ra, rx, ry, rz; + myGLWidget->getRotation( ra, rx, ry, rz ); + GLfloat angle = ra * PI / 180.; + + myXPan += (aDX*cos(angle) - aDY*sin(angle)); + myYPan -= (aDX*sin(angle) + aDY*cos(angle)); + + if( myGrid ) + myGrid->setPan( myXPan, myYPan ); + + myXScale *= zm; + myYScale = myXScale; + + if( myGrid ) + myGrid->setZoom( zm ); + + myGLWidget->setPan( myXPan, myYPan, 0.0 ); + myGLWidget->setScale( myXScale, myYScale, 1.0 ); + myGLWidget->updateGL(); +} + +void GLViewer_ViewPort2d::fitSelect() +{ + GLViewer_Viewer2d* aViewer = (GLViewer_Viewer2d*)getViewFrame()->getViewer(); + GLViewer_Context* aContext = aViewer->getGLContext(); + if( !aContext ) + return; + + QRect aSelRect; + for( aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected() ) + aSelRect |= *(aViewer->getWinObjectRect( aContext->SelectedObject() )); + + if( aSelRect.isValid() ) + { + aSelRect.setTop( aSelRect.top() - SELECTION_RECT_GAP ); + aSelRect.setBottom( aSelRect.bottom() + SELECTION_RECT_GAP ); + aSelRect.setLeft( aSelRect.left() - SELECTION_RECT_GAP ); + aSelRect.setRight( aSelRect.right() + SELECTION_RECT_GAP ); + fitRect( aSelRect ); + } +} + +void GLViewer_ViewPort2d::fitAll( bool keepScale, bool withZ ) +{ + //cout << "GLViewer_ViewPort2d::fitAll" << endl; + + float xa, xb, ya, yb; + float dx, dy, zm; + float xScale, yScale; + + myMargin = QMAX( myBorder->width(), myBorder->height() ) / 5; + + xa = myBorder->left() - myMargin; + xb = myBorder->right() + myMargin; + ya = myBorder->bottom() - myMargin; + yb = myBorder->top() + myMargin; + + float aPoints[8] = { xa, ya, xb, ya, xa, yb, xb, yb }; + + float ra, rx, ry, rz; + myGLWidget->getRotation( ra, rx, ry, rz ); + float angle = ra * PI / 180.; + + int i; + for( i = 0; i < 7; i = i + 2 ) + rotate_point( aPoints[i], aPoints[i+1], angle ); + + float aBorders[4] = { aPoints[0], aPoints[0], aPoints[1], aPoints[1] }; + + for( i = 2; i < 7; i = i + 2 ) + { + if( aBorders[0] < aPoints[i] ) + aBorders[0] = aPoints[i]; + if( aBorders[1] > aPoints[i] ) + aBorders[1] = aPoints[i]; + + if( aBorders[2] < aPoints[i+1] ) + aBorders[2] = aPoints[i+1]; + if( aBorders[3] > aPoints[i+1] ) + aBorders[3] = aPoints[i+1]; + } + + GLint val[4]; + GLint vpWidth, vpHeight; + + myGLWidget->makeCurrent(); + glGetIntegerv( GL_VIEWPORT, val ); + vpWidth = val[2]; + vpHeight = val[3]; + + dx = fabs( aBorders[1] - aBorders[0] ); + dy = fabs( aBorders[3] - aBorders[2] ); + + myXPan = -( aBorders[0] + aBorders[1] ) / 2; + myYPan = -( aBorders[2] + aBorders[3] ) / 2; + + + if( keepScale ) + { + myXOldScale = myXScale; + myYOldScale = myYScale; + } + + xScale = myXScale; + yScale = myYScale; + if( dx && dy ) + zm = vpWidth / dx < vpHeight / dy ? vpWidth / dx : vpHeight / dy; + else + zm = 1.0; + myXScale = zm; + myYScale = zm; + + + if( myGrid ) + { + myGrid->setPan( myXPan, myYPan ); + if( dx > dy ) + myGrid->setZoom( zm / xScale ); + else + myGrid->setZoom( zm / yScale ); + } + + myGLWidget->setPan( myXPan, myYPan, 0.0 ); + myGLWidget->setScale( myXScale, myYScale, 1.0 ); + myGLWidget->updateGL(); + + if( keepScale ) + emit vpUpdateValues(); +} + +void GLViewer_ViewPort2d::startRotation( int x, int y ) +{ + myGLWidget->setRotationStart( x, y, 1.0 ); +} + +void GLViewer_ViewPort2d::rotate( int intX, int intY ) +{ + GLint val[4]; + GLint vpWidth, vpHeight; + + myGLWidget->makeCurrent(); + glGetIntegerv( GL_VIEWPORT, val ); + vpWidth = val[2]; + vpHeight = val[3]; + + float x = intX, y = intY; + float x0 = vpWidth/2; + float y0 = vpHeight/2; + + float xs, ys, zs, dx, dy; + myGLWidget->getRotationStart( xs, ys, zs ); + + xs = xs - x0; + x = x - x0; + dx = x - xs; + ys = y0 - ys; + y = y0 - y; + dy = y - ys; + + float l1 = pow( double( xs*xs + ys*ys ), 0.5 ); + float l2 = pow( double( x*x + y*y ), 0.5 ); + float l = pow( double( dx*dx + dy*dy ), 0.5 ); + + double mult = xs * y - x * ys; + short sign; + if( mult > 0 ) sign = 1; + else if( mult < 0 ) sign = -1; + else sign = 0; + + float anglePrev = myGLWidget->getRotationAngle(); + float angleNew = sign * acos( ( l1*l1 + l2*l2 - l*l ) / ( 2 * l1 * l2 )) * 180. / PI; + float angle = anglePrev + angleNew; + + // GLfloat anAngle = angle * PI / 180.; unused + + float ra, rx, ry, rz; + myGLWidget->getRotation( ra, rx, ry, rz ); + myGLWidget->setRotation( angle, rx, ry, rz ); + myGLWidget->updateGL(); +} + +void GLViewer_ViewPort2d::endRotation() +{ + float ra, rx, ry, rz; + myGLWidget->getRotation( ra, rx, ry, rz ); + myGLWidget->setRotationAngle( ra ); +} + +void GLViewer_ViewPort2d::drawCompass() +{ + if( !myCompass->getVisible() ) + return; + + GLfloat xScale, yScale, xPan, yPan; + + int xPos = getWidth(); + int yPos = getHeight(); + + int cPos = myCompass->getPos(); + int cSize = myCompass->getSize(); + QColor cCol = myCompass->getColor(); + int cWidthTop = myCompass->getArrowWidthTop(); + int cWidthBot = myCompass->getArrowWidthBottom(); + int cHeightTop = myCompass->getArrowHeightTop(); + int cHeightBot = myCompass->getArrowHeightBottom(); + + GLfloat colorR = (cCol.red())/255; + GLfloat colorG = (cCol.green())/255; + GLfloat colorB = (cCol.blue())/255; + + float delX = cSize * 0.5; + float delY = cSize * 0.5; + + getScale( xScale, yScale ); + getPan( xPan, yPan); + + float centerX = (xPos/2 - delX - cSize)/xScale; + float centerY = (yPos/2 - delY - cSize)/yScale; + + switch ( cPos ) + { + case GLViewer_Compass::TopLeft: + centerX = -centerX; + break; + case GLViewer_Compass::BottomLeft: + centerX = -centerX; + centerY = -centerY; + break; + case GLViewer_Compass::BottomRight: + centerY = -centerY; + break; + default: break; + } + + float ra, rx, ry, rz; + myGLWidget->getRotation( ra, rx, ry, rz ); + GLfloat angle = ra * PI / 180.; + GLfloat /*r = 0.0,*/ x = 0.0 , y = 0.0; + + rotate_point( centerX, centerY, -angle ); + + centerX -= xPan; + centerY -= yPan; + + glColor3f( colorR, colorG, colorB ); + glBegin( GL_POLYGON ); + //arrow + x = centerX; y = centerY + cSize / yScale; + glVertex2f( x, y ); + //point #2 + x = centerX + cWidthTop / xScale; y = centerY + ( cSize - cHeightTop ) / yScale ; + glVertex2f( x, y ); + //point #3 + x = centerX + cWidthBot / xScale; y = centerY + ( cSize - cHeightTop ) / yScale ; + glVertex2f( x, y ); + //point #4 + x = centerX + cWidthBot / xScale; y = centerY - cSize/yScale; + glVertex2f( x, y ); + //point #5 + x = centerX; y = centerY - (cSize - cHeightBot) / yScale ; + glVertex2f( x, y ); + //point #6 + x = centerX - cWidthBot / xScale; y = centerY - cSize/yScale; + glVertex2f( x, y ); + //point #7 + x = centerX - cWidthBot / xScale; y = centerY + ( cSize - cHeightTop ) / yScale ; + glVertex2f( x, y ); + //point #8 + x = centerX - cWidthTop / xScale; y = centerY + ( cSize - cHeightTop ) / yScale ; + glVertex2f( x, y ); + glEnd(); + glLineWidth( 2.0 ); + glEnable( GL_LINE_SMOOTH ); + glBegin(GL_LINE_LOOP); + //circle + float aCircAngle = 0; + for ( int i = 0; i < 20 * SEGMENTS + 1; i++ ) + { + x = centerX + cos(aCircAngle) * cSize / xScale; + y = centerY + sin(aCircAngle) * cSize / yScale; + glVertex2f( x, y ); + aCircAngle += float( STEP ) / 2; + } + glEnd(); + + GLdouble modelMatrix[16], projMatrix[16]; + GLint viewport[4]; + GLdouble winxN, winyN, winz; + GLdouble winxE, winyE; + GLdouble winxS, winyS; + GLdouble winxW, winyW; + GLuint aTextList; + + GLViewer_TexFont* aFont = myCompass->getFont(); + float widN = (float)aFont->getStringWidth( "N" ); + float widW = (float)aFont->getStringWidth( "W" ); + float widS = (float)aFont->getStringWidth( "S" ); + float widE = (float)aFont->getStringWidth( "E" ); + float heightL = (float)aFont->getStringHeight(); + + float xGapN = - widN/2 *( 1.0 + sin(angle) ); + float xGapS = - widS/2 *( 1.0 - sin(angle) ); + float xGapW = - widW/2 *( 1.0 + cos(angle) ); + float xGapE = - widE/2 *( 1.0 - cos(angle) ); + + float yGapN = - heightL/2 *( 1.0 - cos(angle) ) * 0.75; + float yGapS = - heightL/2 *( 1.0 + cos(angle) ) * 0.75; + float yGapW = - heightL/2 *( 1.0 + sin(angle) ) * 0.75; + float yGapE = - heightL/2 *( 1.0 - sin(angle) ) * 0.75; + + glGetIntegerv (GL_VIEWPORT, viewport); + glGetDoublev (GL_MODELVIEW_MATRIX, modelMatrix); + glGetDoublev (GL_PROJECTION_MATRIX, projMatrix); + + gluProject (centerX, centerY + cSize / yScale, 0, modelMatrix, projMatrix, viewport, &winxN, &winyN, &winz); + gluProject (centerX + cSize / xScale, centerY, 0, modelMatrix, projMatrix, viewport, &winxE, &winyE, &winz); + gluProject (centerX, centerY - cSize / yScale, 0, modelMatrix, projMatrix, viewport, &winxS, &winyS, &winz); + gluProject (centerX - cSize / xScale, centerY, 0, modelMatrix, projMatrix, viewport, &winxW, &winyW, &winz); + + glColor3f( 1.0, 1.0, 1.0 ); + + aTextList = glGenLists( 1 ); + glNewList( aTextList, GL_COMPILE ); + + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glOrtho(0,viewport[2],0,viewport[3],-100,100); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + + aFont->drawString( "N", winxN + xGapN, winyN + yGapN ); + aFont->drawString( "E", winxE + xGapE, winyE + yGapE ); + aFont->drawString( "S", winxS + xGapS, winyS + yGapS ); + aFont->drawString( "W", winxW + xGapW, winyW + yGapW ); + + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + + glEndList(); + + if ( aTextList != -1 ) + glCallList( aTextList ); +} + +BlockStatus GLViewer_ViewPort2d::currentBlock() +{ + if( myIsDragProcess == inDrag && myCurDragPosX != NULL && myCurDragPosY != NULL) + return BlockStatus(BS_Highlighting | BS_Selection); + + if( mypFirstPoint && mypLastPoint ) + return BlockStatus(BS_Highlighting | BS_Selection); + + return BS_NoBlock; +} + +void GLViewer_ViewPort2d::startSelectByRect( int x, int y ) +{ + if( !mypFirstPoint && !mypLastPoint ) + { + mypFirstPoint = new QPoint( x, y ); + mypLastPoint = new QPoint( x, y ); + } +} +void GLViewer_ViewPort2d::drawSelectByRect( int x, int y ) +{ + if( mypFirstPoint && mypLastPoint ) + { + + QPainter p( getPaintDevice() ); + p.setPen( Qt::white ); + p.setRasterOp( Qt::XorROP ); + + p.drawRect( selectionRect() ); /* erase */ + + mypLastPoint->setX( x ); + mypLastPoint->setY( y ); + + p.drawRect( selectionRect() ); /* draw */ + } + +} +void GLViewer_ViewPort2d::finishSelectByRect() +{ + if( mypFirstPoint && mypLastPoint ) + { + + QPainter p( getPaintDevice() ); + p.setPen( Qt::white ); + p.setRasterOp( Qt::XorROP ); + + p.drawRect( selectionRect() ); /* erase */ + + delete mypFirstPoint; + delete mypLastPoint; + + mypFirstPoint = NULL; + mypLastPoint = NULL; + } +} + +QRect GLViewer_ViewPort2d::selectionRect() +{ + QRect aRect; + if( mypFirstPoint && mypLastPoint ) + { + aRect.setLeft( QMIN( mypFirstPoint->x(), mypLastPoint->x() ) ); + aRect.setTop( QMIN( mypFirstPoint->y(), mypLastPoint->y() ) ); + aRect.setRight( QMAX( mypFirstPoint->x(), mypLastPoint->x() ) ); + aRect.setBottom( QMAX( mypFirstPoint->y(), mypLastPoint->y() ) ); + } + + return aRect; +} + +bool GLViewer_ViewPort2d::startPulling( GLViewer_Pnt point ) +{ + GLViewer_Viewer2d* aViewer = (GLViewer_Viewer2d*)getViewFrame()->getViewer(); + GLViewer_Context* aContext = aViewer->getGLContext(); + ObjList anObjects = aContext->getObjects(); + + for( ObjList::Iterator it = anObjects.begin(); it != anObjects.end(); ++it ) + { + GLViewer_Object* anObject = *it; + GLViewer_Rect aRect = anObject->getPullingRect(); + + if( aRect.contains( point ) && anObject->startPulling( point ) ) + { + myIsPulling = true; + myPullingObject = anObject; + setCursor( *getHandCursor() ); + return true; + } + } + + return false; +} + +void GLViewer_ViewPort2d::drawPulling( GLViewer_Pnt point ) +{ + GLViewer_Viewer2d* aViewer = (GLViewer_Viewer2d*)getViewFrame()->getViewer(); + GLViewer_Context* aContext = aViewer->getGLContext(); + ObjList anObjects = aContext->getObjects(); + + GLViewer_Object* aLockedObject = 0; + for( ObjList::Iterator it = anObjects.begin(); it != anObjects.end(); ++it ) + { + GLViewer_Object* anObject = *it; + if( !anObject->getVisible() ) + continue; + + GLViewer_Rect aRect = anObject->getPullingRect(); + + if( aRect.contains( point ) && anObject->portContains( point ) ) + { + aLockedObject = anObject; + break; + } + } + + myPullingObject->pull( point, aLockedObject ); +} + +void GLViewer_ViewPort2d::finishPulling() +{ + myIsPulling = false; + myPullingObject->finishPulling(); + setCursor( *getDefaultCursor() ); +} + +GLViewer_Rect GLViewer_ViewPort2d::win2GLV( const QRect& theRect ) const +{ + GLViewer_Rect aRect; + + GLdouble modelMatrix[16], projMatrix[16]; + GLint viewport[4]; + + GLdouble objx1, objy1; + GLdouble objx2, objy2; + GLdouble objz; + + glGetIntegerv (GL_VIEWPORT, viewport); + glGetDoublev (GL_MODELVIEW_MATRIX, modelMatrix); + glGetDoublev (GL_PROJECTION_MATRIX, projMatrix); + + gluUnProject( theRect.left(), viewport[3] - theRect.top(), 0, modelMatrix, projMatrix, viewport, &objx1, &objy1, &objz ); + gluUnProject( theRect.right(), viewport[3] - theRect.bottom(), 0, modelMatrix, projMatrix, viewport, &objx2, &objy2, &objz ); + + aRect.setLeft( objx1 ); + aRect.setTop( objy1 ); + aRect.setRight( objx2 ); + aRect.setBottom( objy2 ); + + return aRect; +} + +QRect GLViewer_ViewPort2d::GLV2win( const GLViewer_Rect& theRect ) const +{ + QRect aRect; + + GLdouble modelMatrix[16], projMatrix[16]; + GLint viewport[4]; + + GLdouble winx1, winy1; + GLdouble winx2, winy2; + GLdouble winz; + + glGetIntegerv (GL_VIEWPORT, viewport); + glGetDoublev (GL_MODELVIEW_MATRIX, modelMatrix); + glGetDoublev (GL_PROJECTION_MATRIX, projMatrix); + + gluProject( theRect.left(), theRect.top(), 0, modelMatrix, projMatrix, viewport, &winx1, &winy1, &winz ); + gluProject( theRect.right(), theRect.bottom(), 0, modelMatrix, projMatrix, viewport, &winx2, &winy2, &winz ); + + aRect.setLeft( (int)winx1 ); + aRect.setTop( viewport[3] - (int)winy1 ); + aRect.setRight( (int)winx2 ); + aRect.setBottom( viewport[3] - (int)winy2 ); + + return aRect; +} + +void GLViewer_ViewPort2d::onMaybeTip( QPoint thePoint, QString& theText, QFont& theFont, QRect& theTextReg, QRect& theRegion ) +{ + GLViewer_Context* aContext = ((GLViewer_Viewer2d*)getViewFrame()->getViewer())->getGLContext(); + + GLViewer_Object* anObj = aContext->getCurrentObject(); + if( anObj ) + { + theText = anObj->getToolTipText(); + if( theText.isEmpty() ) + theText = anObj->getName(); + + QStringList aList; + if( anObj->isTooTipHTML() ) + aList = QStringList::split( "
", theText ); + else + aList = QStringList::split( "\n", theText ); + + if( !aList.isEmpty() ) + { + int index = 0; + int str_size = aList.first().length(); + for( int i = 1, size = aList.count(); i < size; i++ ) + { + if( str_size < aList[i].length() ) + { + index = i; + str_size = aList[i].length(); + } + } + theFont = font(); + int cur_height = 24; + QCursor* aCursor = QApplication::overrideCursor(); + if( aCursor ) + { + const QBitmap* aBitmap = aCursor->bitmap(); + if( aBitmap ) + cur_height = aBitmap->height(); + } + + //temp + QSize aSize = QLabel( theText, 0 ).sizeHint(); + theTextReg = QRect( thePoint.x(), thePoint.y() + cur_height, + aSize.width(), aSize.height() ); + theRegion = QRect( thePoint.x(), thePoint.y(), 1, 1 ); + } + } +} diff --git a/src/GLViewer/GLViewer_ViewPort2d.h b/src/GLViewer/GLViewer_ViewPort2d.h new file mode 100644 index 000000000..128cdbe06 --- /dev/null +++ b/src/GLViewer/GLViewer_ViewPort2d.h @@ -0,0 +1,246 @@ +// Copyright (C) 2005 OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// Author : OPEN CASCADE +// + +// File: GLViewer_ViewPort2d.h +// Created: November, 2004 + +#ifndef GLVIEWER_VIEWPORT2D_H +#define GLVIEWER_VIEWPORT2D_H + +#ifdef WNT +#include +#endif + +#include +#include + +#include "GLViewer_ViewPort.h" +#include "GLViewer_Widget.h" +#include "GLViewer_Geom.h" + +#include +#include +#include +#include + +#ifdef WNT +#pragma warning( disable:4251 ) +#endif + +class GLViewer_Compass; +class GLViewer_Grid; +class GLViewer_Object; +class GLViewer_ViewFrame; + +class QtxToolTip; +/*! + * Class GLViewer_ViewPort + * 2D visualisation canvas of GLViewer + */ +class GLViewer_ViewPort2d: public GLViewer_ViewPort +{ + Q_OBJECT + + //! Dragging states + enum vpDragState{ noDrag, initDrag, inDrag }; + +public: + GLViewer_ViewPort2d( QWidget* parent, GLViewer_ViewFrame* theViewFrame = NULL ); + ~GLViewer_ViewPort2d(); + + //! On/off rectangular grid + void turnGrid( GLboolean on ); + //! Returns rectangular grid + GLViewer_Grid* getGrid() const { return myGrid; } + //! Returns grid color + void setGridColor( const QColor gridColor, const QColor axisColor ); + + //! Returns parent window + GLViewer_ViewFrame* getViewFrame() const { return myViewFrame; } + //! Returns painted widget + GLViewer_Widget* getGLWidget() const { return myGLWidget; } + virtual QPaintDevice* getPaintDevice() { return myGLWidget; } + + //! Sets background color + void setBackgroundColor( const QColor& color); + //! Returns background color + QColor backgroundColor() const; + + //! Sets borders of scene + void setBorder( GLViewer_Rect* border ) { myBorder = border; } + //! Get current borders of scene + GLViewer_Rect* getBorder() const { return myBorder; } + + //! Sets margin of borders + void setMargin( GLfloat margin ) { myMargin = margin; } + //! Returns margin of borders + GLfloat getMargin() const { return myMargin; } + + //! Returns width of view + int getWidth() const { return myWidth; } + //! Returns height of view + int getHeight() const { return myHeight; } + + + //! Returns scale factors + void getScale( GLfloat& xSc, GLfloat& ySc ) const { xSc = myXScale; ySc = myYScale; } + //! returns offsets + void getPan( GLfloat& xPan, GLfloat& yPan ) const { xPan = myXPan; yPan = myYPan; } + + //! Resize view + void initResize( int width, int height ); + + //! Begins rotation + void startRotation( int, int ); + //! Process rotation + void rotate( int, int ); + //! Completes rotation + void endRotation(); + + //! Checks of dragging process state + bool isDragProcess(){ return myIsDragProcess; } + + //! On/off compass + void turnCompass( GLboolean on ); + //! Draws compass + void drawCompass(); + + //! Returns unique ID of ViewPort + int getViewPortId(){ return myViewPortId; } + + //! Redefined method + virtual BlockStatus currentBlock(); + + //! Initializes before selecting by rect + void startSelectByRect( int x, int y ); + //! Draw selecting rectandle + void drawSelectByRect( int x, int y ); + //! Pass rect into selector and update + void finishSelectByRect(); + + //! \warnign It is for ouv + bool startPulling( GLViewer_Pnt ); + //! \warnign It is for ouv + void drawPulling( GLViewer_Pnt ); + //! \warnign It is for ouv + void finishPulling(); + //! \warnign It is for ouv + bool isPulling() const { return myIsPulling; } + + //! Returns selection by rect + QRect selectionRect(); + + //! Transforms window rect to global rect + GLViewer_Rect win2GLV( const QRect& ) const; + //! Transforms global rect to window rect + QRect GLV2win( const GLViewer_Rect& ) const; + +signals: + //! Emits after any transformation + void vpUpdateValues(); + + void objectMoved(); + +protected: + void onDragObject( QMouseEvent* ); + + virtual void mouseMoveEvent( QMouseEvent *); + virtual void mousePressEvent( QMouseEvent *); + virtual void mouseReleaseEvent( QMouseEvent *); + virtual void mouseDoubleClickEvent( QMouseEvent *); + + virtual void paintEvent( QPaintEvent* ); + virtual void resizeEvent( QResizeEvent* ); + + //! Returns view to begin state + virtual void reset(); + //! Sets offset to view + virtual void pan( int dx, int dy ); + //! Sets view center in global coords + virtual void setCenter( int x, int y ); + //! Process zoming transformation with mouse tracking from ( x0, y0 ) to ( x1, y1 ) + virtual void zoom( int x0, int y0, int x1, int y1 ); + //! Transforms view by certangle + virtual void fitRect( const QRect& ); + //! Transforms view by selection + virtual void fitSelect(); + //! Transform view by view borders ( if \param keepScale = true, zoom does not change ) + virtual void fitAll( bool keepScale = false, bool withZ = true ); + +protected slots: + //! Initializes drag process + void onStartDragObject(); + //! Pastes object from clipboard + void onPasteObject(); + //! Cuts object to clipboard + void onCutObject(); + //! Copies object to clipboard + void onCopyObject(); + + //! Sets tool tip with \param text to \param theTextReg and on \param theViewReg whan mouse is on \param thePoint + void onMaybeTip( QPoint thePoint, QString& text, QFont& font, QRect& theTextReg, QRect& theViewReg ); + +protected: + GLViewer_ViewFrame* myViewFrame; + GLViewer_Widget* myGLWidget; + GLViewer_Rect* myBorder; + QColor myBackgroundColor; + + GLfloat myMargin; + int myHeight; + int myWidth; + + GLfloat myXScale; + GLfloat myYScale; + GLfloat myXOldScale; + GLfloat myYOldScale; + GLfloat myXPan; + GLfloat myYPan; + + GLViewer_Grid* myGrid; + GLViewer_Compass* myCompass; + + //dragging + int myIsDragProcess; + float* myCurDragPosX; + float* myCurDragPosY; + + //selection by rect + QPoint* mypFirstPoint; + QPoint* mypLastPoint; + + //pulling + bool myIsPulling; + GLViewer_Object* myPullingObject; + + int myViewPortId; + + //GLViewer_ObjectTip* myObjectTip; + QtxToolTip* myObjectTip; + //! flag to block mouse release event just after mouse double-click + bool myIsMouseReleaseBlock; +}; + +#ifdef WNT +#pragma warning ( default:4251 ) +#endif + +#endif diff --git a/src/GLViewer/GLViewer_Viewer.cxx b/src/GLViewer/GLViewer_Viewer.cxx new file mode 100644 index 000000000..9ca9ed73e --- /dev/null +++ b/src/GLViewer/GLViewer_Viewer.cxx @@ -0,0 +1,876 @@ +// Copyright (C) 2005 OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// Author : OPEN CASCADE +// + +// File: GLViewer_Viewer.cxx +// Created: November, 2004 + +/*************************************************************************** +** Class: GLViewer_Viewer +** Descr: Viewer for QAD-based application +** Module: QAD +** Created: UI team, 05.09.00 +****************************************************************************/ + +//#include +#include "GLViewer_Viewer.h" +#include "GLViewer_Selector.h" +#include "GLViewer_ViewPort.h" +#include "GLViewer_ViewFrame.h" + +#include "SUIT_Desktop.h" +#include "SUIT_ViewWindow.h" + +#include +#include +#include +#include + +/* used for sketching */ +static QEvent* l_mbPressEvent = 0; + +/*! + Constructor +*/ +GLViewer_Viewer::GLViewer_Viewer( const QString& title ) +: SUIT_ViewModel(), +mySelector( 0 ), +mySketcher( 0 ), +myTransformer( 0 ), +mySelMode( NoSelection ) +{ +} + +/*! + Destructor +*/ +GLViewer_Viewer::~GLViewer_Viewer() +{ + delete mySelector; +} + +//================================================================ +// Function : setViewManager +// Purpose : +//================================================================ +void GLViewer_Viewer::setViewManager(SUIT_ViewManager* theViewManager) +{ + SUIT_ViewModel::setViewManager(theViewManager); + if (theViewManager) + { + connect(theViewManager, SIGNAL(mousePress(SUIT_ViewWindow*, QMouseEvent*)), + this, SLOT(onMouseEvent(SUIT_ViewWindow*, QMouseEvent*))); + + connect(theViewManager, SIGNAL(mouseMove(SUIT_ViewWindow*, QMouseEvent*)), + this, SLOT(onMouseEvent(SUIT_ViewWindow*, QMouseEvent*))); + + connect(theViewManager, SIGNAL(mouseRelease(SUIT_ViewWindow*, QMouseEvent*)), + this, SLOT(onMouseEvent(SUIT_ViewWindow*, QMouseEvent*))); + + connect(theViewManager, SIGNAL(wheel(SUIT_ViewWindow*, QWheelEvent*)), + this, SLOT(onWheelEvent(SUIT_ViewWindow*, QWheelEvent*))); + } +} + +//================================================================ +// Function : contextMenuPopup +// Purpose : +//================================================================ +void GLViewer_Viewer::contextMenuPopup( QPopupMenu* thePopup ) +{ + if( thePopup->count() > 0 ) + thePopup->insertSeparator(); + + thePopup->insertItem( tr( "CHANGE_BGCOLOR" ), this, SLOT( onChangeBgColor() ) ); +} + +/*! + Sets the background color with color selection dialog. [ virtual protected slot ] +*/ +void GLViewer_Viewer::onChangeBgColor() +{ + GLViewer_ViewPort* vp = getActiveView()->getViewPort(); + QColor selColor = QColorDialog::getColor( vp->backgroundColor() ); + + if( selColor.isValid() ) + vp->setBackgroundColor( selColor ); +} + +/*! + Returns the active view. [ public ] +*/ +GLViewer_ViewFrame* GLViewer_Viewer::getActiveView() const +{ + SUIT_ViewManager* aMgr = getViewManager(); + return (GLViewer_ViewFrame*)( aMgr != 0 ? aMgr->getActiveView() : 0 ); +} + + +/*! + Sets the selection mode for this viewer. [ public ] +*/ +void GLViewer_Viewer::setSelectionMode( GLViewer_Viewer::SelectionMode mode ) +{ + if ( mySelMode != mode ) + { + mySelMode = mode; + onSelectionModeChanged(); + } +} + +/*! + Returns selector of this viewer. [ public ] +*/ +GLViewer_Selector* GLViewer_Viewer::getSelector() const +{ + if ( !mySelector ) + { + GLViewer_Viewer* mthis = (GLViewer_Viewer*)this; + mthis->mySelector = mthis->createSelector(); + if ( mySelector ) + { + connect( mySelector, SIGNAL( selSelectionDone( bool, SelectionChangeStatus ) ), SLOT( onSelectionDone( bool, SelectionChangeStatus ) ) ); + connect( mySelector, SIGNAL( selSelectionCancel() ), SLOT( onSelectionCancel() ) ); + } + } + return mySelector; +} + +/*! + Returns the selection mode of this viewer. [ public ] +*/ +GLViewer_Viewer::SelectionMode GLViewer_Viewer::getSelectionMode() const +{ + return mySelMode; +} + +/*! + Handles requests for sketching in the active view. [ virtual public ] +*/ +void GLViewer_Viewer::activateSketching( int type ) +{ + GLViewer_ViewPort* vp = 0; + if ( !getActiveView() || !( vp = getActiveView()->getViewPort() ) ) + return; + + if ( !vp->isSketchingEnabled() ) + return; + + /* Finish current sketching */ + if ( type == NoSketching ) + { + if ( mySketcher ) + { + onSketchingFinished(); + delete mySketcher; + mySketcher = 0; + } + } + /* Activate new sketching */ + else + { + activateSketching( NoSketching ); /* concurrency not suported */ + mySketcher = createSketcher( type ); + onSketchingStarted(); + } +} + +/*! + Handles requests for transformations in the active view. [ virtual public ] +*/ +void GLViewer_Viewer::activateTransform( int type ) +{ + GLViewer_ViewPort* vp = 0; + if ( !getActiveView() || !( vp = getActiveView()->getViewPort() ) ) + return; + + if ( !vp->isTransformEnabled() ) + return; + + /* Finish current transform */ + if ( type == NoTransform ) + { + if ( myTransformer ) + { + onTransformationFinished(); + delete myTransformer; + myTransformer = 0; + } + } + /* Activate new transform */ + else + { + activateTransform( NoTransform ); /* concurrency not suported */ + myTransformer = createTransformer( type ); + onTransformationStarted(); + myTransformer->exec(); + } +} + +/*! + Creates default transformer. [ virtual protected ] +*/ +GLViewer_ViewTransformer* GLViewer_Viewer::createTransformer( int type ) +{ + return new GLViewer_ViewTransformer( this, type ); +} + +/*! + Creates default sketcher. [ virtual protected ] +*/ +GLViewer_ViewSketcher* GLViewer_Viewer::createSketcher( int type ) +{ + return new GLViewer_ViewSketcher( this, type ); +} + +/*! + Returns null by default. [ virtual protected ] +*/ +GLViewer_Selector* GLViewer_Viewer::createSelector() +{ + return 0; +} + +/*! + Unhilights detected entities, lock selection, sets event filter + on the whole application. [ virtual protected ] +*/ +void GLViewer_Viewer::onTransformationStarted() +{ + unhilightDetected(); + if ( getSelector() ) + getSelector()->lock( true ); /* disable selection */ + + /* Watch events: any mouse/key event outside the + viewport will be considered as the end of + transform */ + if( !myTransformer ) + return; + qApp->installEventFilter( this ); +} + +/*! + Unlock selection, removes event filter. [ virtual protected ] +*/ +void GLViewer_Viewer::onTransformationFinished() +{ + if ( getSelector() ) + getSelector()->lock( false ); /* enable selection */ + + /* Stop watch events */ + if( !myTransformer ) + return; + qApp->removeEventFilter( this ); +} + +/*! + Unhilights detected entities. [ virtual protected ] +*/ +void GLViewer_Viewer::onSketchingStarted() +{ + unhilightDetected(); +} + +/*! + Selection by rectangle. [ virtual protected ] +*/ +void GLViewer_Viewer::onSketchingFinished() +{ + if ( !getSelector() ) + return; + + if( !mySketcher ) + return; + if ( mySketcher->type() == Rect ) + { + QRect* selRect = (QRect*)mySketcher->data(); + if ( selRect ) + { + bool append = bool( mySketcher->buttonState() & GLViewer_Selector::appendKey() ); + getSelector()->select( *selRect, append ); + } + } +} + +/*! + Installed while 'fit area' and 'global panning' operations are active. [ virtual protected ] +*/ +bool GLViewer_Viewer::eventFilter( QObject* o, QEvent* e ) +{ + if( !getActiveView() ) + return false; + + if( getActiveView()->getViewPort() == o->parent() ) + o = o->parent(); + + bool mouseClickedOutside = ( e->type() == QEvent::MouseButtonPress && + o != getActiveView()->getViewPort() ); + bool anyKeyPressed = ( e->type() == QEvent::KeyPress ); + if ( mouseClickedOutside || anyKeyPressed ) + { /* terminate all */ + activateTransform( NoTransform ); + activateSketching( NoSketching ); + //cout << "mouseClickedOutside || anyKeyPressed" << endl; + } + return QObject::eventFilter( o, e ); +} + +/*! + Called when smth is selected in this viewer. [ virtual protected slot ] +*/ +void GLViewer_Viewer::onSelectionDone( bool bAdded, SelectionChangeStatus status ) +{ + emit selectionChanged( status ); +} + +/*! + Called when selection is cleared in this viewer. [ virtual protected slot ] +*/ +void GLViewer_Viewer::onSelectionCancel() +{ + emit selectionChanged( SCS_Invalid ); +} + +/*! + Listens to key events of the active view. [ virtual protected slot ] +*/ +void GLViewer_Viewer::onKeyEvent( SUIT_ViewWindow*, QKeyEvent* ) +{ +} + +/*! + Listens to mouse events of the active view. [ virtual protected slot ] +*/ +void GLViewer_Viewer::onMouseEvent( SUIT_ViewWindow*, QMouseEvent* e ) +{ + //cout << "GLViewer_Viewer::onMouseEvent" << endl; + switch( e->type() ) + { + case QEvent::MouseButtonPress: + handleMousePress( e ); + break; + case QEvent::MouseMove: + handleMouseMove( e ); + break; + case QEvent::MouseButtonRelease: + handleMouseRelease( e ); + break; + default: break; + } +} + +/*! + Listens to mouse events of the active view. [ virtual protected slot ] +*/ +void GLViewer_Viewer::onWheelEvent( SUIT_ViewWindow*, QWheelEvent* e ) +{ + //cout << "GLViewer_Viewer::onMouseEvent" << endl; + switch( e->type() ) + { + case QEvent::Wheel: + handleWheel( e ); + break; + default: break; + } +} + +/*! + Enables / disables rectangle sketching. [ virtual protected ] +*/ +void GLViewer_Viewer::onSelectionModeChanged() +{ + bool enable = ( mySelMode == Multiple ); + QPtrVector views = getViewManager()->getViews(); + for ( int i = 0, n = views.count(); i < n; i++ ) + { + GLViewer_ViewPort* vp = ((GLViewer_ViewFrame*)views[i])->getViewPort(); + if ( vp ) + vp->setSketchingEnabled( enable ); + } +} + +/*! + Updates all views of this viewer. Use 'flags' to customize update process. [ virtual public ] +*/ +void GLViewer_Viewer::update( int flags ) +{ + QPtrVector views = getViewManager()->getViews(); + for ( int i = 0, n = views.count(); i < n; i++ ) + ((GLViewer_ViewFrame*)views[i])->onUpdate( flags ); +} + +/*! + Unhilights the currect detected objects. [ virtual private ] +*/ +void GLViewer_Viewer::unhilightDetected() +{ + if ( getSelector() ) + getSelector()->undetectAll(); +} + +/*! + Mouse press handler. If 'accelKey()' is pressed, activates default + transformations( Zoom or Pan ) in the active viewport. [ private ] +*/ +void GLViewer_Viewer::handleMousePress( QMouseEvent* e ) +{ + /* test accel for transforms */ + if ( e->state() & GLViewer_ViewTransformer::accelKey() ) + { + ButtonState bs = e->button(); + if ( bs == GLViewer_ViewTransformer::zoomButton() ) + activateTransform( Zoom ); + else if ( bs == GLViewer_ViewTransformer::panButton() ) + activateTransform( Pan ); + } + else + { + //checking for other operations before selection in release event + startOperations( e ); + } + + /* we may need it for sketching... */ + l_mbPressEvent = new QMouseEvent( *e ); + + //checking for other operations before selection in release event +// startOperations( e ); + + /*e->button() == LeftButton && getSelector() ) + { + bool append = bool ( e->state() & GLViewer_Selector::appendKey() ); + getSelector()->select( append ); + }*/ +} + +/*! + Mouse move handler. If dragged with MB1, activates rectangle sketching in + the active viewport, otherwise highlights the selectable entities. [ private ] +*/ +void GLViewer_Viewer::handleMouseMove( QMouseEvent* e ) +{ + /* Highlight for selection */ + bool dragged = ( e->state() & ( LeftButton | MidButton | RightButton ) ); + if ( !dragged ) + { + if ( getSelector() ) + getSelector()->detect( e->x(), e->y() ); + } + /* Try to activate default sketching + */ + else if ( e->state() == GLViewer_ViewSketcher::sketchButton() ) + { + activateSketching( Rect ); + if ( mySketcher ) + { + /* Activated OK. We should not forget initial mousepress + event and this mousemove event to start sketching from + the point of initial click */ + if ( l_mbPressEvent ) + { + QApplication::sendEvent( getActiveView()->getViewPort(), l_mbPressEvent ); + delete l_mbPressEvent; + l_mbPressEvent = 0; + } + QApplication::sendEvent( getActiveView()->getViewPort(), e ); + } + } + + //Try to activate other operations + updateOperations( e ); +} + +/*! + Mouse move handler. Activates popup of the active view. [ private ] +*/ +void GLViewer_Viewer::handleMouseRelease( QMouseEvent* e ) +{ + /* selection */ + /* tmp - in handleMousePress*/ + if( e->button() == LeftButton && !(getActiveView()->getViewPort()->currentBlock() & BS_Selection) ) + { + if ( getSelector() ) + { + bool append = bool ( e->state() & GLViewer_Selector::appendKey() ); + getSelector()->select( append ); + } + } + + //Try to done active operations + finishOperations( e ); + + if ( l_mbPressEvent ) + { + delete l_mbPressEvent; + l_mbPressEvent = 0; + } +} + +/*! + Wheel rolling handler +*/ +void GLViewer_Viewer::handleWheel( QWheelEvent* e ) +{ + startOperations( e ); +} + +/**************************************************************** +** Class: GLViewer_ViewTransformer +** Level: Public +*****************************************************************/ +int GLViewer_ViewTransformer::panBtn = Qt::MidButton; +int GLViewer_ViewTransformer::zoomBtn = Qt::LeftButton; +int GLViewer_ViewTransformer::fitRectBtn = Qt::LeftButton; +int GLViewer_ViewTransformer::panGlobalBtn = Qt::LeftButton; +int GLViewer_ViewTransformer::acccelKey = Qt::ControlButton; + +/*! + Constructor +*/ +GLViewer_ViewTransformer::GLViewer_ViewTransformer( GLViewer_Viewer* v, int type ) +: QObject( 0 ), +myViewer( v ), +myType( type ), +myMajorBtn( NoButton ), +myButtonState( 0 ) +{ + if ( myType == GLViewer_Viewer::Pan || + myType == GLViewer_Viewer::Zoom || + myType == GLViewer_Viewer::PanGlobal || + myType == GLViewer_Viewer::FitRect ) + { + /* 'long' transforms need this */ + initTransform( true ); + } +} + +/*! + Destructor +*/ +GLViewer_ViewTransformer::~GLViewer_ViewTransformer() +{ + if ( myType == GLViewer_Viewer::Pan || + myType == GLViewer_Viewer::Zoom || + myType == GLViewer_Viewer::PanGlobal || + myType == GLViewer_Viewer::FitRect ) + { + /* 'long' transforms need this */ + initTransform( false ); + } + + //QAD_Application::getDesktop()->clearInfo(); +} + +/*! + Inits long transformations ( Zoom, Pan etc ) [ protected ] + + Saves viewport state( cursor etc ) and installs event filter to process + mouse events if 'init' is true. Restores viewport state if 'init' is false. +*/ +void GLViewer_ViewTransformer::initTransform( bool init ) +{ + GLViewer_ViewPort* avp = myViewer->getActiveView()->getViewPort(); + if ( init ) + { + mySavedCursor = avp->cursor(); + mySavedMouseTrack = avp->hasMouseTracking(); + avp->setMouseTracking( false ); + avp->installEventFilter( this ); + } + else + { + avp->removeEventFilter( this ); + avp->setMouseTracking( mySavedMouseTrack ); + avp->setCursor( mySavedCursor ); + } +} + +/*! + Runs transfomation. Redefine to add your own 'instant' transforms + ( for ex., 'FitAll' is an instant transform ). [ virtual public ] +*/ +void GLViewer_ViewTransformer::exec() +{ + GLViewer_ViewPort* avp = myViewer->getActiveView()->getViewPort(); + if( !avp ) + return; + + switch( myType ) + { + case GLViewer_Viewer::Zoom: + myMajorBtn = zoomButton(); + avp->setCursor( *avp->getZoomCursor() ); + break; + case GLViewer_Viewer::Pan: + myMajorBtn = panButton(); + avp->setCursor( *avp->getPanCursor() ); + break; + case GLViewer_Viewer::PanGlobal: + myMajorBtn = panGlobalButton(); + avp->setCursor( *avp->getPanglCursor() ); + avp->fitAll( true, false ); /* view is ready now */ + break; + case GLViewer_Viewer::FitRect: + myMajorBtn = fitRectButton(); + avp->setCursor( *avp->getHandCursor() ); + break; + case GLViewer_Viewer::Reset: + avp->reset(); onTransform( Fin ); + break; + case GLViewer_Viewer::FitAll: + avp->fitAll(); onTransform( Fin ); + break; + case GLViewer_Viewer::FitSelect: + avp->fitSelect(); onTransform( Fin ); + break; + default: break; + } +} + +/*! + Catches mouse events for the viewport. [ virtual protected ] +*/ +bool GLViewer_ViewTransformer::eventFilter( QObject* o, QEvent* e ) +{ + switch ( e->type() ) + { + case QEvent::MouseMove: + case QEvent::MouseButtonPress: + case QEvent::MouseButtonRelease: + { + TransformState state = EnTrain; + QMouseEvent* me = ( QMouseEvent* )e; + + myButtonState = me->state(); + if ( e->type() == QEvent::MouseButtonPress ) + myButtonState |= me->button(); /* add pressed button */ + + int mouseOnlyState = ( myButtonState & ( LeftButton | MidButton | RightButton ) ); + if ( myStart.isNull() ) + { + state = Debut; + myStart = me->pos(); + myMajorBtn = mouseOnlyState; + } + + if ( e->type() == QEvent::MouseButtonRelease && mouseOnlyState == myMajorBtn ) + { + state = Fin; + } + myCurr = me->pos(); + onTransform( state ); + return true; + } + default: break; + } + return QObject::eventFilter( o, e ); +} + +/*! + Transforms the viewport. Used for 'non-instant' transforms + only( ex. Rotate, Pan etc ). [ virtual protected ] +*/ +void GLViewer_ViewTransformer::onTransform( TransformState state ) +{ + GLViewer_ViewPort* avp = myViewer->getActiveView()->getViewPort(); + bool doTrsf = ( myButtonState & myMajorBtn ); + switch ( myType ) + { + case GLViewer_Viewer::Zoom: + if ( state != Fin && doTrsf ) + { + avp->zoom( myStart.x(), myStart.y(), myCurr.x(), myCurr.y() ); + myStart = myCurr; + } + break; + case GLViewer_Viewer::Pan: + if ( state != Fin && doTrsf ) + { + avp->pan( myCurr.x() - myStart.x(), myStart.y() - myCurr.y() ); + myStart = myCurr; + } + break; + case GLViewer_Viewer::PanGlobal: + { + if ( state == Fin ) + avp->setCenter( myCurr.x(), myCurr.y() ); + break; + } + case GLViewer_Viewer::FitRect: + { + if ( doTrsf ) + { + QRect rect( QMIN( myStart.x(), myCurr.x() ), QMIN( myStart.y(), myCurr.y() ), + QABS( myStart.x() - myCurr.x() ), QABS( myStart.y() - myCurr.y() ) ); + if ( !rect.isEmpty() ) + { + switch ( state ) + { + case Fin: + avp->fitRect( rect ); + break; + default: + { + QPainter p( avp->getPaintDevice() ); // for QAD_GLWidget + p.setPen( Qt::white ); + p.setRasterOp( Qt::XorROP ); + if ( !myDrawRect.isEmpty() ) + p.drawRect( myDrawRect ); /* erase */ + p.drawRect( rect ); + myDrawRect = rect; + break; + } + } + } + } + break; + } + default: + break; + } + + if ( state == Fin ) + myViewer->activateTransform( GLViewer_Viewer::NoTransform ); +} + +/*! + Returns the type of the transformer. [ public ] +*/ +int GLViewer_ViewTransformer::type() const +{ + return myType; +} + + +/**************************************************************** +** Class: GLViewer_ViewSketcher +** Level: Public +*****************************************************************/ +int GLViewer_ViewSketcher::sketchBtn = LeftButton; + +/*! + Constructor +*/ +GLViewer_ViewSketcher::GLViewer_ViewSketcher( GLViewer_Viewer* viewer, int type ) +: QObject( 0 ), +myViewer( viewer ), +myData( 0 ), +myType( type ) +{ + if( !myViewer ) + return; + GLViewer_ViewPort* avp = myViewer->getActiveView()->getViewPort(); + if( !avp ) + return; + + mySavedCursor = avp->cursor(); + avp->setCursor( *GLViewer_ViewPort::getHandCursor() ); + avp->installEventFilter( this ); + + if ( myType == GLViewer_Viewer::Rect ) + myData = new QRect(); +} + +/*! + Destructor +*/ +GLViewer_ViewSketcher::~GLViewer_ViewSketcher() +{ + GLViewer_ViewPort* avp = myViewer->getActiveView()->getViewPort(); + avp->removeEventFilter( this ); + avp->setCursor( mySavedCursor ); + + if ( myType == GLViewer_Viewer::Rect ) + delete ( QRect* ) myData; +} + +/*! + Catches mouse events for the viewport. [ virtual protected ] +*/ +bool GLViewer_ViewSketcher::eventFilter( QObject* o, QEvent* e ) +{ + switch ( e->type() ) + { + case QEvent::MouseMove: + case QEvent::MouseButtonPress: + case QEvent::MouseButtonRelease: + { + SketchState state = EnTrain; + QMouseEvent* me = (QMouseEvent*)e; + + myButtonState = me->state(); + if ( e->type() == QEvent::MouseButtonPress ) + myButtonState |= me->button(); /* add pressed button */ + + if ( myStart.isNull() ) + { + state = Debut; + myStart = me->pos(); + } + + int mouseOnlyState = ( myButtonState & ( LeftButton | MidButton | RightButton ) ); + if ( e->type() == QEvent::MouseButtonRelease && mouseOnlyState == sketchButton() ) + { + state = Fin; + } + myCurr = me->pos(); + onSketch( state ); + return true; + } + default: break; + } + return QObject::eventFilter( o, e ); +} + +/*! + Draws in the viewport. [ virtual protected ] +*/ +void GLViewer_ViewSketcher::onSketch( SketchState state ) +{ + GLViewer_ViewPort* avp = myViewer->getActiveView()->getViewPort(); + if( !avp ) + return; + + if( myType == GLViewer_Viewer::Rect ) + { + QRect* sketchRect = ( QRect* )data(); + if ( myButtonState & sketchButton() ) + { + QRect rect( QMIN( myStart.x(), myCurr.x() ), QMIN( myStart.y(), myCurr.y() ), + QABS( myStart.x() - myCurr.x() ), QABS( myStart.y() - myCurr.y() ) ); + if ( !rect.isEmpty() ) + { + QPainter p( avp ); + p.setPen( Qt::white ); + p.setRasterOp( Qt::XorROP ); + if ( !sketchRect->isEmpty() ) + p.drawRect( *sketchRect ); /* erase */ + *sketchRect = rect; + if ( state != Fin ) + p.drawRect( *sketchRect ); + } + } + } + + if ( state == Fin ) + { + QApplication::syncX(); /* force rectangle redrawing */ + myViewer->activateSketching( GLViewer_Viewer::NoSketching ); + } +} diff --git a/src/GLViewer/GLViewer_Viewer.h b/src/GLViewer/GLViewer_Viewer.h new file mode 100644 index 000000000..dfd16c2fa --- /dev/null +++ b/src/GLViewer/GLViewer_Viewer.h @@ -0,0 +1,235 @@ +// Copyright (C) 2005 OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// Author : OPEN CASCADE +// + +// File: GLViewer_Viewer.h +// Created: November, 2004 + +#ifndef GLVIEWER_VIEWER_H +#define GLVIEWER_VIEWER_H + +#include "GLViewer_Defs.h" +#include "GLViewer_ViewFrame.h" +#include + +#include +#include +#include +#include + +class GLViewer_Selector; +class GLViewer_ViewSketcher; +class GLViewer_ViewTransformer; + +class SUIT_Desktop; +class SUIT_ViewWindow; + +#ifdef WNT +#pragma warning( disable:4251 ) +#endif + +/*! + * Class GLViewer_Object + * Base Viewer for GLViewer + */ +class GLVIEWER_API GLViewer_Viewer: public SUIT_ViewModel +{ + Q_OBJECT + +public: + enum SelectionMode { NoSelection, Single, Multiple }; + enum TransformType { NoTransform, Reset, FitAll, FitRect, FitSelect, + Zoom, PanGlobal, Pan, Rotate, UserTransform = 100 }; + enum SketchingType { NoSketching, Rect, UserSketching = 100 }; + +public: + GLViewer_Viewer( const QString& title ); + ~GLViewer_Viewer(); + +public: + virtual void setViewManager( SUIT_ViewManager* theViewManager ); + virtual QString getType() const { return Type(); } + static QString Type() { return "GLViewer_ViewModel"; } + + virtual void contextMenuPopup( QPopupMenu* ); + +public: + void setSelectionMode( SelectionMode ); + SelectionMode getSelectionMode() const; + GLViewer_Selector* getSelector() const; + + virtual void update( int = 0 ); + + void activateTransform( int ); + void activateSketching( int ); + + GLViewer_ViewFrame* getActiveView() const; + +signals: + void selectionChanged( SelectionChangeStatus ); + +protected: + virtual void onSketchingStarted(); + virtual void onSketchingFinished(); + virtual void onTransformationStarted(); + virtual void onTransformationFinished(); + virtual void onSelectionModeChanged(); + + virtual void unhilightDetected(); + virtual bool eventFilter( QObject*, QEvent* ); + + /* virtual constructors */ + virtual GLViewer_ViewTransformer* createTransformer( int ); + virtual GLViewer_ViewSketcher* createSketcher( int ); + virtual GLViewer_Selector* createSelector(); + + virtual void startOperations( QMouseEvent* ) {} + virtual bool updateOperations( QMouseEvent* ) { return false; } + virtual void finishOperations( QMouseEvent* ) {} + virtual void startOperations( QWheelEvent* ) {} + +protected slots: + virtual void onKeyEvent( SUIT_ViewWindow*, QKeyEvent* ); + virtual void onMouseEvent( SUIT_ViewWindow*, QMouseEvent* ); + virtual void onWheelEvent( SUIT_ViewWindow*, QWheelEvent* ); + + virtual void onSelectionCancel(); + virtual void onSelectionDone( bool add, SelectionChangeStatus status ); + + virtual void onChangeBgColor(); + +private: + void handleMouseMove( QMouseEvent* ); + void handleMousePress( QMouseEvent* ); + void handleMouseRelease( QMouseEvent* ); + void handleWheel( QWheelEvent* ); + +protected: + GLViewer_Selector* mySelector; /* selector */ + SelectionMode mySelMode; /* current selection mode */ + GLViewer_ViewSketcher* mySketcher; /* sketch manipulator */ + GLViewer_ViewTransformer* myTransformer; /* transform manipulator */ +}; + +/**************************************************************** +** Class: GLViewer_ViewTransformer +** +*****************************************************************/ +class GLVIEWER_API GLViewer_ViewTransformer : public QObject +{ +public: + GLViewer_ViewTransformer( GLViewer_Viewer*, int type ); + ~GLViewer_ViewTransformer(); + +public: + /*! Returns transformer type */ + int type() const; + + /*! Sets/returns acceleration key ( CTRL by default ) */ + static int accelKey() { return acccelKey; } + static void setAccelKey( int k ) { acccelKey = k; } + + /*! Sets/returns mouse button used for zooming ( MB1 by default ) */ + static int zoomButton() { return zoomBtn; } + static void setZoomButton( int b ) { zoomBtn = b; } + + /*! Sets/returns mouse button used for panning ( MB2 by default ) */ + static int panButton() { return panBtn; } + static void setPanButton( int b ) { panBtn = b; } + + /*! Sets/returns mouse button used for global pan ( MB1 by default ) */ + static int panGlobalButton() { return panGlobalBtn; } + static void setPanGlobalButton( int b ) { panGlobalBtn = b; } + + /*! Sets/returns mouse button used for fit area ( MB1 by default ) */ + static int fitRectButton() { return fitRectBtn; } + static void setFitRectButton( int b ) { fitRectBtn = b; } + + virtual void exec(); + virtual bool eventFilter( QObject*, QEvent* ); + +protected: + enum TransformState { Debut, EnTrain, Fin }; + virtual void onTransform( TransformState ); + void initTransform( bool ); + +protected: + static int panBtn; + static int zoomBtn; + static int fitRectBtn; + static int panGlobalBtn; + + static int acccelKey; + + GLViewer_Viewer* myViewer; + int myType; + QCursor mySavedCursor; + bool mySavedMouseTrack; + QPoint myStart, myCurr; + int myButtonState; + QRect myDrawRect; + int myMajorBtn; +}; + +/**************************************************************** +** Class: GLViewer_ViewSketcher +** +*****************************************************************/ +class GLVIEWER_API GLViewer_ViewSketcher : public QObject +{ +public: + GLViewer_ViewSketcher( GLViewer_Viewer*, int type ); + ~GLViewer_ViewSketcher(); + +public: + /*! Returns sketcher type */ + int type() const { return myType; } + + /*! Returns result of sketching */ + void* data() const { return myData; } + + /*! Returns current state of mouse/sys kbd buttons */ + int buttonState() const { return myButtonState; } + + /*! Sets/returns mouse button used for sketching ( MB1 by default ) */ + static int sketchButton() { return sketchBtn; } + static void setSketchButton( int b ) { sketchBtn = b; } + + virtual bool eventFilter( QObject*, QEvent* ); + +protected: + enum SketchState { Debut, EnTrain, Fin }; + virtual void onSketch( SketchState ); + +protected: + static int sketchBtn; + GLViewer_Viewer* myViewer; + int myType; + void* myData; + QCursor mySavedCursor; + QPoint myStart, myCurr; + int myButtonState; +}; + +#ifdef WNT +#pragma warning ( default:4251 ) +#endif + +#endif diff --git a/src/GLViewer/GLViewer_Viewer2d.h b/src/GLViewer/GLViewer_Viewer2d.h new file mode 100644 index 000000000..94a5bd254 --- /dev/null +++ b/src/GLViewer/GLViewer_Viewer2d.h @@ -0,0 +1,258 @@ +// Copyright (C) 2005 OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// Author : OPEN CASCADE +// + +// File: GLViewer_Viewer2d.h +// Created: November, 2004 + +/*************************************************************************** +** Class: GLViewer_Viewer2d +** Descr: OpenGL Viewer 2D +** Module: GLViewer +** Created: UI team, 04.09.04 +****************************************************************************/ +#ifndef GLVIEWER_VIEWER2D_H +#define GLVIEWER_VIEWER2D_H + +#ifdef WNT +#include +#endif + +#include +#include + +#include "GLViewer_Viewer.h" +#include "GLViewer_Object.h" +#include "GLViewer_ViewFrame.h" +#include "GLViewer_Drawer.h" + +#include + +#include + +class GLViewer_Object; +class GLViewer_Context; +class GLViewer_Selector2d; +//class GLViewer_Sketcher; + +class SUIT_Desktop; +class SUIT_ViewWindow; + +//! Paper sizes array +const double Sizes[2*5] = { + /* A1 */ 594.0, 840.0, + /* A2 */ 420.0, 594.0, + /* A3 */ 297.0, 420.0, + /* A4 */ 210.0, 297.0, + /* A5 */ 148.5, 210.0 +}; + +#ifdef WNT +#pragma warning( disable:4251 ) +#endif + +/*! + * Class GLViewer_Object + * 2D viewer for GLViewer + */ +class GLVIEWER_API GLViewer_Viewer2d : public GLViewer_Viewer +{ + Q_OBJECT + +public: + //! Type of sketcher operation + enum GLSketchingType + { + None, + Polyline, + Arc, + Curve, + Scribble, + Oval, + Rectangle + }; + //! Type of export vector file + enum VectorFileType + { + POST_SCRIPT, + HPGL +#ifdef WIN32 + , ENH_METAFILE +#endif + }; + + //! Type of paper for export to vector format + enum PaperType + { + A1=0, + A2, + A3, + A4, + A5 + }; + +public: + //! A constructor + GLViewer_Viewer2d( const QString& title ); + //! A destructor + ~GLViewer_Viewer2d(); + +public: + //! Redefined method + /*Returns GLViewer_ViewFrame*/ + virtual SUIT_ViewWindow* createView( SUIT_Desktop* ); + + //! Adds item for change background color + void addPopupItems( QPopupMenu* ); + + //void activateGLSketching( int ); + + //! Returns all drawers + const QValueList& getDrawers() const { return myDrawers; } + + //! Returns context + GLViewer_Context* getGLContext() const { return myGLContext; } + //! Updates colors for all drawers (does not work) + void updateColors( QColor colorH, QColor colorS ); + + //! Updates rect of global scene by adding new rect + void updateBorders( GLViewer_Rect* theRect ); + //! Recomputes global scene rect + void updateBorders(); + + //! Redraws all active objects by updating all drawers in all views + void updateAll(); + //! Updates all drawers with new scale factor + /* \param onlyUpdate is passed to method activateAllDrawersdrawers*/ + void updateDrawers( GLboolean onlyUpdate, GLfloat scX = 0.0, GLfloat scY = 0.0 ); + //! Activates drawers for objects from list \param theObjects only + void activateDrawers( QValueList& theObjects, bool onlyUpdate, GLboolean swap = GL_FALSE ); + //! Activates drawer for \param theObject + void activateDrawer( GLViewer_Object* theObject, bool onlyUpdate, GLboolean swap = GL_FALSE ); + //! Updates all drawers with new scale factor + /* \param onlyUpdate is passed to drawers*/ + void activateAllDrawers( bool onlyUpdate, GLboolean swap = GL_FALSE ); + + //! Translates point (x,y) from global CS to curreent viewer CS + void transPoint( GLfloat& x, GLfloat& y ); + //! Returns object rect in window CS + QRect* getWinObjectRect( GLViewer_Object* theObject); + + //! Translates rect in window CS to rect in global CS + GLViewer_Rect getGLVRect( const QRect& ) const; + //! Translates rect in global CS to rect in window CS + QRect getQRect( const GLViewer_Rect& ) const; + + //! Inserts common text lines starting file of \param aType + virtual void insertHeader( VectorFileType aType, QFile& hFile ); + //! Inserts common text lines ending file of \param aType + virtual void insertEnding( VectorFileType aType, QFile& hFile ); + //! Translates current view content to vector file + /* Translates current view content to vector file with type \param aType, name \param FileName, + * output paper size \param aPType, with margins in mm + */ + virtual bool translateTo( VectorFileType aType, QString FileName, PaperType aPType, + double mmLeft, double mmRight, double mmTop, double mmBottom ); + + //bool isSketchingActive(); + //int getSketchingType(); + + //virtual void startSketching(); + //virtual void finishSketching(); + + //! Repaints view \param theView. If \param theView = NULL repaints all views. + void repaintView( GLViewer_ViewFrame* theView = NULL, bool makeCurrent = false ); + +public slots: + //void onSketchDelObject(); + //void onSketchUndoLast(); + //void onSketchFinish(); + + //! Changes background color + void onChangeBgColor(); + //! Creates set of marker number \param number and radius = \param size + void onCreateGLMarkers( int number = 1000, int size = 5 ); + //! Creates set of polyline number \param number, number of angles = \param angles and diameter = \param size + void onCreateGLPolyline( int number = 100, int angles = 10, int size = 100 ); + //! Creates set of text number \param number and with text = \param text + void onCreateGLText( QString text = "Text", int number = 1 ); + +protected: + //! Returns new selector + GLViewer_Selector* createSelector(); + //! Returns new Transformer with type \param type + GLViewer_ViewTransformer* createTransformer( int type); + + //! Transforms point (x,y) in Viewer CS to Post Script CS + void transformCoordsToPS( double& x, double& y ); + //! Transforms point (x,y) in Viewer CS to HPGL CS + void transformCoordsToHPGL( double& x, double& y ); + + //! Starts any operations on mouse event + virtual void startOperations( QMouseEvent* ); + //! Updates started operations on mouse event + virtual bool updateOperations( QMouseEvent* ); + //! Completes started operations on mouse event + virtual void finishOperations( QMouseEvent* ); + //! Starts any operations on mouse wheel event + virtual void startOperations( QWheelEvent* ); + +protected slots: + void onMouseEvent( SUIT_ViewWindow*, QMouseEvent* ); + +private: + //! Rotation transformation + bool testRotation( QMouseEvent* ); +protected: + //! Current context + GLViewer_Context* myGLContext; + //! Map of active drawers + QValueList myDrawers; + + //GLViewer_Sketcher* myGLSketcher; +}; + +/**************************************************************** +** Class: GLViewer_View2dTransformer +** +*****************************************************************/ +class GLVIEWER_API GLViewer_View2dTransformer : public GLViewer_ViewTransformer +{ +public: + GLViewer_View2dTransformer( GLViewer_Viewer*, int ); + ~GLViewer_View2dTransformer(); + + virtual void exec(); + + /*! Sets/returns mouse butto which will be used for rotation ( MB1 by default ) */ + static int rotateButton() { return rotateBtn; } + static void setRotateButton( int b ) { rotateBtn = b; } + +protected: + void onTransform( TransformState ); + + static int rotateBtn; +}; + +#ifdef WNT +#pragma warning ( default:4251 ) +#endif + +#endif diff --git a/src/GLViewer/GLViewer_Widget.cxx b/src/GLViewer/GLViewer_Widget.cxx new file mode 100644 index 000000000..b29a9fb52 --- /dev/null +++ b/src/GLViewer/GLViewer_Widget.cxx @@ -0,0 +1,723 @@ +// Copyright (C) 2005 OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// Author : OPEN CASCADE +// + +// File: GLViewer_Widget.cxx +// Created: November, 2004 + +//================================================================ +// Class : GLViewer_Widget +// Description : OpenGL QWidget for GLViewer +//================================================================ + +#include "GLViewer_Widget.h" +#include "GLViewer_ViewPort2d.h" +#include "GLViewer_Viewer2d.h" +#include "GLViewer_Compass.h" +#include "GLViewer_Grid.h" +#include "GLViewer_Object.h" +#include "GLViewer_CoordSystem.h" + +#include +using namespace std; + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +//======================================================================= +// Function: GLViewer_Widget +// Purpose : +//======================================================================= +GLViewer_Widget::GLViewer_Widget( QWidget* parent, const char* name ): +QGLWidget( parent, 0/*, WRepaintNoErase | WResizeNoErase*/ ) +{ + myViewPort = ( GLViewer_ViewPort2d* )parent; + + myXPan = 0.0; + myYPan = 0.0; + myZPan = 0.0; + myXScale = 1.0; + myYScale = 1.0; + myZScale = 1.0; + myRotationAngle = 0.0; + myRotationCenterX = 0.0; + myRotationCenterY = 0.0; + myRotationCenterZ = 1.0; + myRotationAnglePrev = 0.0; + + myStart = GL_TRUE; + + isExportMode = false; + + //init(); + setMouseTracking( true ); +} + +//======================================================================= +// Function: GLViewer_Widget +// Purpose : +//======================================================================= +GLViewer_Widget::~GLViewer_Widget() +{ +} + +//======================================================================= +// Function: ~GLViewer_Widget +// Purpose : +//======================================================================= +void GLViewer_Widget::getPan( GLfloat& xPan, GLfloat& yPan, GLfloat& zPan ) +{ + xPan = myXPan; + yPan = myYPan; + zPan = myZPan; +} + +//======================================================================= +// Function: setPan +// Purpose : +//======================================================================= +void GLViewer_Widget::setPan( GLfloat xPan, GLfloat yPan, GLfloat zPan ) +{ + myXPan = xPan; + myYPan = yPan; + myZPan = zPan; +} + +//======================================================================= +// Function: getScale +// Purpose : +//======================================================================= +void GLViewer_Widget::getScale( GLfloat& xScale, GLfloat& yScale, GLfloat& zScale ) +{ + xScale = myXScale; + yScale = myYScale; + zScale = myZScale; +} + +//======================================================================= +// Function: setScale +// Purpose : +//======================================================================= +void GLViewer_Widget::setScale( GLfloat xScale, GLfloat yScale, GLfloat zScale ) +{ + if ( xScale > 0 && yScale > 0 && zScale > 0 ) + { + myXScale = xScale; + myYScale = yScale; + myZScale = zScale; + } +} + +//======================================================================= +// Function: getRotationStart +// Purpose : +//======================================================================= +void GLViewer_Widget::getRotationStart( GLfloat& rotationStartX, + GLfloat& rotationStartY, + GLfloat& rotationStartZ ) +{ + rotationStartX = myRotationStartX; + rotationStartY = myRotationStartY; + rotationStartZ = myRotationStartZ; +} + +//======================================================================= +// Function: setRotationStart +// Purpose : +//======================================================================= +void GLViewer_Widget::setRotationStart( GLfloat rotationStartX, + GLfloat rotationStartY, + GLfloat rotationStartZ ) +{ + myRotationStartX = rotationStartX; + myRotationStartY = rotationStartY; + myRotationStartZ = rotationStartZ; +} + +//======================================================================= +// Function: getRotation +// Purpose : +//======================================================================= +void GLViewer_Widget::getRotation( GLfloat& rotationAngle, + GLfloat& rotationCenterX, + GLfloat& rotationCenterY, + GLfloat& rotationCenterZ ) +{ + rotationAngle = myRotationAngle; + rotationCenterX = myRotationCenterX; + rotationCenterY = myRotationCenterY; + rotationCenterZ = myRotationCenterZ; +} + +//======================================================================= +// Function: setRotation +// Purpose : +//======================================================================= +void GLViewer_Widget::setRotation( GLfloat rotationAngle, + GLfloat rotationCenterX, + GLfloat rotationCenterY, + GLfloat rotationCenterZ ) +{ + myRotationAngle = rotationAngle; + myRotationCenterX = rotationCenterX; + myRotationCenterY = rotationCenterY; + myRotationCenterZ = rotationCenterZ; +} + +//======================================================================= +// Function: setBackground +// Purpose : +//======================================================================= +void GLViewer_Widget::setBackground( QString filename ) +{ + + //get image + QImage buf; + if ( !filename.isEmpty() && buf.load( filename ) ) + { // Load first image from file + isLoadBackground = true; + myBackgroundFile = filename; + + myIW = buf.width(); + myIH = buf.height(); + + myBackgroundSize = 64; + while( myBackgroundSize < myIW || myBackgroundSize < myIH) + myBackgroundSize = myBackgroundSize * 2; + + GLubyte* pixels = new GLubyte[myBackgroundSize * myBackgroundSize * 4]; + + for( int i = 0; i < myBackgroundSize; i++ ) + { + for( int j = 0; j < myBackgroundSize; j++ ) + { + if( j < myIW && i < myIH ) + { + pixels[i * myBackgroundSize * 4 + j * 4] = (GLubyte)qRed( buf.pixel(j,myIH - i - 1) ); + pixels[i * myBackgroundSize * 4 + j * 4 + 1]= (GLubyte)qGreen( buf.pixel(j,myIH - i - 1) ); + pixels[i * myBackgroundSize * 4 + j * 4 + 2] = (GLubyte)qBlue( buf.pixel(j,myIH - i - 1) ); + } + else + { + pixels[i * myBackgroundSize * 4 + j * 4] = (GLubyte)0; + pixels[i * myBackgroundSize * 4 + j * 4 + 1] = (GLubyte)0; + pixels[i * myBackgroundSize * 4 + j * 4 + 2] = (GLubyte)0; + } + pixels[i * myBackgroundSize* 4 + j * 4 + 3] = (GLubyte)255; + } + } + + //initialize texture + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glGenTextures(1, &texName); + glBindTexture(GL_TEXTURE_2D, texName); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, myBackgroundSize , myBackgroundSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, + pixels); + + delete[] pixels; + } +} + +//======================================================================= +// Function: addToolTip +// Purpose : +//======================================================================= +void GLViewer_Widget::addToolTip( QString theString, QRect theRect ) +{ + myToolTipRect = theRect; + QToolTip::add( this, myToolTipRect, theString ); +} + +//======================================================================= +// Function: removeToolTip +// Purpose : +//======================================================================= +void GLViewer_Widget::removeToolTip() +{ + QToolTip::remove( this, myToolTipRect ); +} + +//======================================================================= +// Function: initializeGL +// Purpose : +//======================================================================= +void GLViewer_Widget::initializeGL() +{ + setAutoBufferSwap( true ); + + glShadeModel(GL_FLAT); + + //get image + QImage buf; + QString aPicturePath = getenv("GLViewer__Background_Picture"); + + if ( !aPicturePath.isEmpty() && buf.load( aPicturePath ) ) + { // Load first image from file + isLoadBackground = true; + setBackground( aPicturePath ); + + } + + else + isLoadBackground = false; +} + +//======================================================================= +// Function: paintGL +// Purpose : +//======================================================================= +void GLViewer_Widget::paintGL() +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glMatrixMode( GL_MODELVIEW ); + glLoadIdentity(); + + glRotatef( myRotationAngle, myRotationCenterX, myRotationCenterY, myRotationCenterZ ); + glScalef( myXScale, myYScale, myZScale ); + glTranslatef( myXPan, myYPan, myZPan ); + + if( isLoadBackground ) + { + glEnable(GL_TEXTURE_2D); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); + glBindTexture(GL_TEXTURE_2D, texName); + glBegin(GL_QUADS); + + glTexCoord2f( 0.0, 0.0); glVertex3f( -myIW/2, -myIH/2, 0.0); + glTexCoord2f( 0.0, (float)myIH/myBackgroundSize ); glVertex3f( -myIW/2, myIH/2, 0.0); + glTexCoord2f( (float)myIW/myBackgroundSize, (float)myIH/myBackgroundSize ); glVertex3f( myIW/2, myIH/2, 0.0); + glTexCoord2f( (float)myIW/myBackgroundSize, 0.0); glVertex3f( myIW/2, -myIH/2, 0.0); + + glEnd(); + glFlush(); + glDisable(GL_TEXTURE_2D); + + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + } + + + GLViewer_Grid* grid = myViewPort->getGrid(); + if( grid ) + grid->draw(); + + GLViewer_Viewer2d* v = ( GLViewer_Viewer2d* )getViewPort()->getViewFrame()->getViewer(); + if( !isExportMode ) + v->updateDrawers( GL_FALSE, myXScale, myYScale ); + else + v->repaintView( getViewPort()->getViewFrame() ); +} + +//======================================================================= +// Function: resizeGL +// Purpose : +//======================================================================= +void GLViewer_Widget::resizeGL( int w, int h ) +{ + + if( h < 1 ) h = 1; + if( w < 1 ) w = 1; + glViewport( 0, 0, w, h); + + if( myStart ) + { + myWidth = w; + myHeight = h; + myStart = GL_FALSE; + } + + myViewPort->initResize( w, h ); + + glMatrixMode( GL_PROJECTION ); + glLoadIdentity(); + GLfloat w_c = w / 2., h_c = h / 2.; + + gluOrtho2D( -w_c, w_c, -h_c, h_c ); + + glMatrixMode( GL_MODELVIEW ); + glLoadIdentity(); +} + +//======================================================================= +// Function: exportRepaint +// Purpose : +//======================================================================= +void GLViewer_Widget::exportRepaint() +{ + isExportMode = true; + + paintGL(); + + isExportMode = false; +} + +//======================================================================= +// Function: paintEvent +// Purpose : +//======================================================================= +void GLViewer_Widget::paintEvent( QPaintEvent* e ) +{ + QApplication::sendEvent( myViewPort, e ); +} + +//======================================================================= +// Function: mouseMoveEvent +// Purpose : +//======================================================================= +void GLViewer_Widget::mouseMoveEvent( QMouseEvent* e ) +{ + QApplication::sendEvent( myViewPort, e ); +} + +//======================================================================= +// Function: mousePressEvent +// Purpose : +//======================================================================= +void GLViewer_Widget::mousePressEvent( QMouseEvent* e ) +{ + QApplication::sendEvent( myViewPort, e ); +} + +//======================================================================= +// Function: mouseReleaseEvent +// Purpose : +//======================================================================= +void GLViewer_Widget::mouseReleaseEvent( QMouseEvent* e ) +{ + QApplication::sendEvent( myViewPort, e ); +} + +//======================================================================= +// Function: enterEvent +// Purpose : +//======================================================================= +void GLViewer_Widget::enterEvent( QEvent* e ) +{ + updateGL(); +} + +//======================================================================= +// Function: leaveEvent +// Purpose : +//======================================================================= +void GLViewer_Widget::leaveEvent( QEvent* e ) +{ + updateGL(); +} + + +//======================================================================= +//! Function: hex +//! Purpose : Returns the hex code of digit < 16 +//======================================================================= +inline char hex( uchar c ) +{ + if( c<=9 ) + return '0'+c; + else if( c < 16 ) + return 'a' + c - 10; + + return ' '; +} + +//======================================================================= +//! Function: AddImagePart +//! Purpose : Translates path of image to PS format +/*! Image inside rectangle from w1 to w2 and from h2 to h1*/ +//======================================================================= +void AddImagePart( QFile& hFile, QImage& image, int w1, int w2, int h1, int h2, + GLViewer_CoordSystem* aViewerCS, GLViewer_CoordSystem* aPSCS, + double a, double b, double c, double d, double dw, double dh ) +{ + if( aViewerCS && aPSCS ) + { + double width = w2-w1+1, height = h2-h1+1; + QString aBuffer = "", temp = "%1 %2 8 [ %3 %4 %5 %6 %7 %8 ]\n"; + aBuffer += temp.arg( width ).arg( height ). + arg( a ).arg( b ).arg( c ).arg( d ). + arg( dw ).arg( dh ); + aBuffer += "<\n"; + + char line[81]; line[80] = '\0'; int cur_index = 0; + int full = 0; + for( int i=h2; i>=h1; i-- ) + { + uchar* theCurLine = image.scanLine( i ), cur; + for( int j=w1; j<=w2; j++ ) + for( int k=0; k<3; k++ ) + { + cur = *(theCurLine+4*j+2-k); + *(line+cur_index) = hex( cur/16 ); //HI + *(line+cur_index+1) = hex( cur%16 ); //LO + full++; + cur_index+=2; + if( cur_index>=80 ) + { + aBuffer += line; + aBuffer += "\n"; + cur_index = 0; + } + } + } + + aBuffer += "> false 3 colorimage\n\n"; + + hFile.writeBlock( aBuffer.ascii(), aBuffer.length() ); + } +} + +//======================================================================= +// Function: getBackgroundRectInViewerCS +// Purpose : +//======================================================================= +void GLViewer_Widget::getBackgroundRectInViewerCS( double& left, double& top, double& right, double& bottom ) +{ + left = -myIW/2; right = myIW/2; + top = myIH/2; bottom = -myIH/2; +} + +//======================================================================= +// Function: translateBackgroundToPS +// Purpose : +//======================================================================= +void GLViewer_Widget::translateBackgroundToPS( QFile& hFile, GLViewer_CoordSystem* aViewerCS, GLViewer_CoordSystem* aPSCS ) +{ + QImage buf; + + if( aViewerCS && aPSCS && isLoadBackground && buf.load( myBackgroundFile ) ) + { + double a, b, c, d, dx, dy; //The preparation of transformation matrix + + double width = buf.width(), height = buf.height(); + + double left, top, right, bottom; + getBackgroundRectInViewerCS( left, top, right, bottom ); + + double aax = left, aay = bottom, + bbx = right, bby = bottom, + ccx = left, ccy = top; + + aViewerCS->transform( *aPSCS, aax, aay ); + aViewerCS->transform( *aPSCS, bbx, bby ); + aViewerCS->transform( *aPSCS, ccx, ccy ); + + a = ( bbx - aax ) / width; + b = ( ccx - aax ) / height; + c = ( bby - aay ) / width; + d = ( ccy - aay ) / height; + + //Now we must find invert matrix + double det = a*d-b*c, + newa = d/det, + newb = -c/det, + newc = -b/det, + newd = a/det; + + a = newa; b = newb; c = newc; d = newd; + + dx = -(a*aax+c*aay); + dy = -(b*aax+d*aay); //according to PS specification of coordinate transformation + + const int max = 133000; //The maximum length of string in PS + int dh = int( floor( double( max ) / ( 3.0*2.0*width ) ) ); + for( int k=buf.height()-1; k>=0; k-=dh ) + AddImagePart( hFile, buf, 0, buf.width()-1, QMAX( k-dh+1, 0 ), k, + aViewerCS, aPSCS, a, b, c, d, dx, dy-(buf.height()-1-k) ); + } +} + +//======================================================================= +//! Function: DecodeScanLine +//! Purpose : Translate image line with one color depth to line wiht other depth +//======================================================================= +void DecodeScanLine( int width, uchar* dest, int dest_depth, uchar* source, int source_depth ) +{ +#ifndef WIN32 +typedef unsigned int WORD; +#endif + + int aSize = width*dest_depth, + dw = aSize % 8; + + if( dw ) + aSize+=dw; + + if( dest_depth==source_depth ) + memcpy( dest, source, aSize/8 ); + else + { + double r, g, b; WORD color; + for( int i=0; i> 5 ) / 63.0; + r = double( ( color & 0xF800 ) >> 11 ) / 31.0; + break; + case 24: + b = double( *(source + 3*i) ) / 255.0; + g = double( *(source + 3*i+1) ) / 255.0; + r = double( *(source + 3*i+2) ) / 255.0; + break; + case 32: + b = double( *(source + 4*i) ) / 255.0; + g = double( *(source + 4*i+1) ) / 255.0; + r = double( *(source + 4*i+2) ) / 255.0; + break; + } + switch( dest_depth ) + { + case 16: + color = WORD(b*31.0); + color += (WORD(g*63.0)<<5); + color += (WORD(r*31.0)<<11); + memcpy( dest + 2*i, &color, 2 ); + break; + case 24: + *( dest + 3*i ) = (uchar)(255*b); + *( dest + 3*i+1 ) = (uchar)(255*g); + *( dest + 3*i+2 ) = (uchar)(255*r); + break; + case 32: + *( dest + 4*i ) = (uchar)(255*b); + *( dest + 4*i+1 ) = (uchar)(255*g); + *( dest + 4*i+2 ) = (uchar)(255*r); + *( dest + 4*i+3 ) = 0; + break; + } + } + } +} + +//======================================================================= +// Function: translateBackgroundToEMF +// Purpose : +//======================================================================= +#ifdef WIN32 +void GLViewer_Widget::translateBackgroundToEMF( HDC dc, GLViewer_CoordSystem* aViewerCS, GLViewer_CoordSystem* aEMFCS ) +{ + QImage buf; + + if( aViewerCS && aEMFCS && isLoadBackground && buf.load( myBackgroundFile ) ) + { + double left, top, right, bottom; + getBackgroundRectInViewerCS( left, top, right, bottom ); + + double aRot = aViewerCS->getRotation(); + + double lx = left, ly = top; + aViewerCS->transform( *aEMFCS, lx, ly ); + + aViewerCS->setRotation( 0.0 ); //we switch off the rotation of CS + + aViewerCS->transform( *aEMFCS, left, top ); + aViewerCS->transform( *aEMFCS, right, bottom ); + + int w = buf.width(), + h = buf.height(); + + HDC aScrDC = GetDC( 0 ); + HDC aCompDC = CreateCompatibleDC( aScrDC ); + HBITMAP aBMP = CreateCompatibleBitmap( aScrDC, w, h ); + + BITMAP aBitInfo; + GetObject ( aBMP, sizeof(BITMAP), &aBitInfo ); + int depth = aBitInfo.bmBitsPixel; //how many bits represent a color of one pixel + + int aLineSize = w*depth; + int dw = aLineSize % 32; //scanline word aligning + + if( dw ) + aLineSize += 32-dw; + + aLineSize /= 8; + + BYTE* bits = new BYTE[aLineSize*h]; + memset( bits, 0, aLineSize*h ); + uchar* aLine = NULL; + + for( int i=0; i(lx,ly) - + aRotTrans.eDy = ly -(b*left+d*top); //the real image of left-top corner of picture + + SetWorldTransform( dc, &aRotTrans ); + int res = StretchBlt( dc, left, top, right-left, bottom-top, aCompDC, 0, 0, w, h, SRCCOPY ); + SetWorldTransform( dc, &aTrans ); + + SelectObject( aCompDC, old ); + + ReleaseDC( 0, aScrDC ); + DeleteDC( aCompDC ); + DeleteObject( aBMP ); + delete[] bits; + + aViewerCS->setRotation( aRot ); + } +} +#endif diff --git a/src/GLViewer/GLViewer_Widget.h b/src/GLViewer/GLViewer_Widget.h new file mode 100644 index 000000000..c580a9a84 --- /dev/null +++ b/src/GLViewer/GLViewer_Widget.h @@ -0,0 +1,209 @@ +// Copyright (C) 2005 OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// Author : OPEN CASCADE +// + +// File: GLViewer_Widget.h +// Created: November, 2004 + +/*! Class GLViewer_Widget + * Class for visualization OpenGL scene (widget) for GLViewer + */ +#ifndef GLVIEWER_WIDGET_H +#define GLVIEWER_WIDGET_H + +#include "GLViewer.h" + +#include +#include + +class GLViewer_ViewPort2d; +class GLViewer_CoordSystem; + +class GLVIEWER_API GLViewer_Widget : public QGLWidget +{ + Q_OBJECT + +public: + //! A constructor + /*! Parameters using for QOGLWidget as is + */ + GLViewer_Widget( QWidget* theParent, const char* theName = 0 ); + + //! A destructor + ~GLViewer_Widget(); + + //! Returns parent GLViewer_ViewPort2d + /*! ViewPort2d because this class is not use for 3D Viewer */ + GLViewer_ViewPort2d* getViewPort() const { return myViewPort; } + //! Returns width of OpenGl Window + GLint getWidth() const { return myWidth; } + //! Returns height of OpenGl Window + GLint getHeight() const { return myHeight; } + + //! Returns scales on OpenGL scene along 3 directions + /*! in 2d scene zScale = 1.0 */ + void getScale( GLfloat& xScale, + GLfloat& yScale, + GLfloat& zScale ); + //! A function for installing the scales of OpenGL scene + void setScale( GLfloat xScale, + GLfloat yScale, + GLfloat zScaleGLfloat ); + + //! Returns offset parameters of Window in OpenGL global scene + void getPan( GLfloat& xPan, GLfloat& yPan, GLfloat& zPan ); + //! A function for installing the offset parameters of Window in OpenGL global scene + void setPan( GLfloat xPan, GLfloat yPan, GLfloat zPan ); + + //! Returns rotation angle of Window in OpenGL global scene in degree + /*! Only in 2D */ + GLfloat getRotationAngle() const { return myRotationAnglePrev; } + //! A function for installing the rotation angle of Window in OpenGL global scene in degree + /*! Only in 2D */ + void setRotationAngle( GLfloat a ) { myRotationAnglePrev = a; } + + //! Returns start point of curren rotation of Window in OpenGL global scene + void getRotationStart( GLfloat& rotationStartX, + GLfloat& rotationStartY, + GLfloat& rotationStartZ ); + //! A function for installing the start point of curren rotation of Window in OpenGL global scene + void setRotationStart( GLfloat rotationStartX, + GLfloat rotationStartY, + GLfloat rotationStartZ ); + //! Returns parameters of current rotation + void getRotation( GLfloat& rotationAngle, + GLfloat& rotationCenterX, + GLfloat& rotationCenterY, + GLfloat& rotationCenterZ ); + //! A function for installing the parameters of current rotation + void setRotation( GLfloat, GLfloat, GLfloat, GLfloat ); + + //! A function load picture from file with name theFileName and post it in center of global OpenGL scene + void setBackground( QString theFileName ); + + //! A function add the tool tip with text theTTText on theTTRect rect to the widget window + void addToolTip( QString theTTText, QRect theTTRect ); + //! A function remove tool tip form widget window + void removeToolTip(); + + //! A function translate background of window in to PostScript file on disk + /*! + *\param hFile the name of PostScript file chosen by user + *\param aViewerCS the GLViewer_CoordSystem of window + *\param aPSCS the GLViewer_CoordSystem of PostScript page + */ + virtual void translateBackgroundToPS( QFile& hFile, GLViewer_CoordSystem* aViewerCS, GLViewer_CoordSystem* aPSCS ); + + //! A function repaints OpenGL scene in export mode + /* Repaints all objects in only current view */ + void exportRepaint(); + +#ifdef WIN32 + //! A function translate background of window in to EMF file on disk + //! + /*! + *\warning WIN32 only + * + *\param dc the name of HDC associated with file chosen by user + *\param aViewerCS the GLViewer_CoordSystem of window + *\param aEMFCS the GLViewer_CoordSystem of EMF page + */ + virtual void translateBackgroundToEMF( HDC dc, GLViewer_CoordSystem* aViewerCS, GLViewer_CoordSystem* aEMFCS ); +#endif + +private: + //! Auxiliary function. Returns rect of window background in viewer coordinate system + void getBackgroundRectInViewerCS( double& left, double& top, double& right, double& bottom ); + +protected: + /* Redefined QT methods */ + //! A function is called before first display of window (create OpenGL scene) + virtual void initializeGL(); + //! A function is called in earch paint event of window + /* Calling by public method repaint() */ + virtual void paintGL(); + //! A function is called in earch resize event of window + virtual void resizeGL( int, int ); + + + virtual void paintEvent( QPaintEvent* ); + virtual void mouseMoveEvent( QMouseEvent* ); + virtual void mousePressEvent( QMouseEvent* ); + virtual void mouseReleaseEvent( QMouseEvent* ); + + /* Needs to redefine because Window must be updated highlight presentation when mouse enter window */ + virtual void enterEvent( QEvent* ); + /* Needs to redefine because Window must be updated highlight presentation when mouse leave window */ + virtual void leaveEvent( QEvent* ); + +private: + //! width of window + GLint myWidth; + //! height of window + GLint myHeight; + + //! Scale along X direction + GLfloat myXScale; + //! Scale along Y direction + GLfloat myYScale; + //! Scale along Z direction + /* equals 1 in 2D */ + GLfloat myZScale; + + //! Window offset along X direction + GLfloat myXPan; + //! Window offset along Y direction + GLfloat myYPan; + //! Window offset along Z direction + /* equals 0 in 2D */ + GLfloat myZPan; + + GLfloat myRotationStartX; + GLfloat myRotationStartY; + GLfloat myRotationStartZ; + GLfloat myRotationAngle; + GLfloat myRotationCenterX; + GLfloat myRotationCenterY; + GLfloat myRotationCenterZ; + GLfloat myRotationAnglePrev; + + GLboolean myStart; + GLViewer_ViewPort2d* myViewPort; + + //! True if background is loaded + bool isLoadBackground; + //! File name of background image + QString myBackgroundFile; + //! Texture id of loaded background image + GLuint texName; + //! Width of background image + int myIW; + //! Height of background image + int myIH; + //! Size of background image + int myBackgroundSize; + + QRect myToolTipRect; + + //! Needs for export repaint + bool isExportMode; +}; + +#endif // GLVIEWER_WIDGET_H diff --git a/src/LightApp/LightApp_AboutDlg.cxx b/src/LightApp/LightApp_AboutDlg.cxx new file mode 100644 index 000000000..689d4165c --- /dev/null +++ b/src/LightApp/LightApp_AboutDlg.cxx @@ -0,0 +1,130 @@ +// File: LightApp_AboutDlg.cxx +// Created: 03.06.2005 13:52:45 +// Author: Sergey TELKOV +// Copyright (C) CEA 2005 + +#include "LightApp_AboutDlg.h" + +#include +#include + +#include +#include +#include +#include + +/*!Constructor.*/ +LightApp_AboutDlg::LightApp_AboutDlg( const QString& defName, const QString& defVer, QWidget* parent ) +: QtxDialog( parent, "salome_about_dialog", true, false, None ) +{ + SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr(); + + QPixmap ico = resMgr->loadPixmap( "LightApp", tr( "ICO_ABOUT" ), false ); + if ( !ico.isNull() ) + setIcon( ico ); + + QPalette pal = palette(); + QColorGroup cg = pal.active(); + cg.setColor( QColorGroup::Foreground, Qt::darkBlue ); + cg.setColor( QColorGroup::Background, Qt::white ); + pal.setActive( cg ); pal.setInactive( cg ); pal.setDisabled( cg ); + setPalette(pal); + + QVBoxLayout* main = new QVBoxLayout( mainFrame() ); + QGroupBox* base = new QGroupBox( 1, Qt::Horizontal, "", mainFrame() ); + base->setFrameStyle( QFrame::NoFrame ); + base->setInsideMargin( 0 ); + main->addWidget( base ); + + QLabel* screen = new QLabel( base ); + screen->setScaledContents( true ); + screen->setAlignment( Qt::AlignCenter ); + screen->setFrameStyle( QFrame::Box | QFrame::Plain ); + + QLabel* title = new QLabel( base ); + title->setAlignment( Qt::AlignCenter ); + changeFont( title, true, false, false, 5 ); + + QLabel* version = new QLabel( base ); + version->setAlignment( Qt::AlignCenter ); + changeFont( version, false, true, false, 2 ); + + QLabel* copyright = new QLabel( base ); + copyright->setAlignment( Qt::AlignCenter ); + changeFont( copyright, false, false, false, 1 ); + + QLabel* license = new QLabel( base ); + license->setAlignment( Qt::AlignCenter ); + changeFont( license, false, false, false, 1 ); + + screen->setPixmap( resMgr->loadPixmap( "LightApp", tr( "ABOUT" ), false ) ); + checkLabel( screen ); + + QString titleText = tr( "ABOUT_TITLE" ); + if ( titleText == "ABOUT_TITLE" ) + titleText = defName; + title->setText( titleText ); + checkLabel( title ); + + QString verText = tr( "ABOUT_VERSION" ); + if ( verText.contains( "%1" ) ) + verText = verText.arg( defVer ); + version->setText( verText ); + checkLabel( version ); + + copyright->setText( tr( "ABOUT_COPYRIGHT" ) ); + checkLabel( copyright ); + + license->setText( tr( "ABOUT_LICENSE" ) ); + checkLabel( license ); + + QString capText = tr( "ABOUT_CAPTION" ); + if ( capText.contains( "%1" ) ) + capText = capText.arg( defName ); + setCaption( capText ); + + setSizeGripEnabled( false ); +} + +/*!Destructor.*/ +LightApp_AboutDlg::~LightApp_AboutDlg() +{ + //! Do nothing. +} + +/*!On mouse press event.*/ +void LightApp_AboutDlg::mousePressEvent( QMouseEvent* ) +{ + accept(); +} + +/*!Change font of widget \a wid. + *\param wid - QWidget + *\param bold - boolean value + *\param italic - boolean value + *\param underline - boolean value + *\param inc - integer increment for font point size. + */ +void LightApp_AboutDlg::changeFont( QWidget* wid, const bool bold, const bool italic, + const bool underline, const int inc ) const +{ + if ( !wid ) + return; + + QFont widFont = wid->font(); + widFont.setBold( bold ); + widFont.setItalic( italic ); + widFont.setUnderline( underline ); + widFont.setPointSize( widFont.pointSize() + inc ); +} + +/*!Check lable \a lab.*/ +void LightApp_AboutDlg::checkLabel( QLabel* lab ) const +{ + if ( !lab ) + return; + + bool vis = !lab->text().stripWhiteSpace().isEmpty() || + ( lab->pixmap() && !lab->pixmap()->isNull() ); + vis ? lab->show() : lab->hide(); +} diff --git a/src/LightApp/LightApp_AboutDlg.h b/src/LightApp/LightApp_AboutDlg.h new file mode 100644 index 000000000..c59cc938b --- /dev/null +++ b/src/LightApp/LightApp_AboutDlg.h @@ -0,0 +1,36 @@ +// File: LightApp_AboutDlg.h +// Created: 03.06.2005 13:49:25 +// Author: Sergey TELKOV +// Copyright (C) CEA 2005 + +#ifndef LIGHTAPP_ABOUTDLG_H +#define LIGHTAPP_ABOUTDLG_H + +#include "LightApp.h" + +#include + +/*! + Descr: LightApp help about dialog +*/ + +class QLabel; + +class LIGHTAPP_EXPORT LightApp_AboutDlg : public QtxDialog +{ + Q_OBJECT + +public: + LightApp_AboutDlg( const QString&, const QString&, QWidget* = 0 ); + virtual ~LightApp_AboutDlg(); + +protected: + virtual void mousePressEvent( QMouseEvent* ); + +private: + void checkLabel( QLabel* ) const; + void changeFont( QWidget*, const bool = false, const bool = false, + const bool = false, const int = 0 ) const; +}; + +#endif diff --git a/src/LightApp/LightApp_DataModel.cxx b/src/LightApp/LightApp_DataModel.cxx new file mode 100644 index 000000000..6ccba618b --- /dev/null +++ b/src/LightApp/LightApp_DataModel.cxx @@ -0,0 +1,122 @@ +// File: LightApp_DataModel.cxx +// Created: 10/25/2004 10:36:06 AM +// Author: Sergey LITONIN +// Copyright (C) CEA 2004 + +#include "LightApp_DataModel.h" +#include "LightApp_Study.h" +#include "LightApp_RootObject.h" +#include "LightApp_Module.h" +#include "LightApp_Application.h" + +#include + +#include +#include +#include +#include + +//======================================================================= +// name : LightApp_DataModel::LightApp_DataModel +/*!Purpose : Constructor*/ +//======================================================================= +LightApp_DataModel::LightApp_DataModel( CAM_Module* theModule ) +: CAM_DataModel( theModule ) +{ +} + +//======================================================================= +// name : LightApp_DataModel::~LightApp_DataModel +/*! Purpose : Destructor*/ +//======================================================================= +LightApp_DataModel::~LightApp_DataModel() +{ +} + +//================================================================ +// Function : open +/*! Purpose : Emit opened()*/ +//================================================================ +bool LightApp_DataModel::open( const QString&, CAM_Study* study, QStringList ) +{ + emit opened(); //TODO: is it really needed? to be removed maybe... + return true; +} + +//================================================================ +// Function : save +/*! Purpose : Emit saved()*/ +//================================================================ +bool LightApp_DataModel::save( QStringList& ) +{ + emit saved(); + return true; +} + +//================================================================ +// Function : saveAs +/*! Purpose : Emit saved()*/ +//================================================================ +bool LightApp_DataModel::saveAs( const QString&, CAM_Study*, QStringList& ) +{ + emit saved(); + return true; +} + +//================================================================ +// Function : close +/*! Purpose : Emit closed()*/ +//================================================================ +bool LightApp_DataModel::close() +{ + emit closed(); + return true; +} + +//================================================================ +// Function : update +/*! Purpose : Update application (empty virtual function).*/ +//================================================================ +void LightApp_DataModel::update( LightApp_DataObject*, LightApp_Study* study ) +{ +} + +//================================================================ +// Function : getModule +/*! Purpose : gets module*/ +//================================================================ + +LightApp_Module* LightApp_DataModel::getModule() const +{ + return dynamic_cast( module() ); +} + +//================================================================ +// Function : getStudy +/*! Purpose : gets study */ +//================================================================ +LightApp_Study* LightApp_DataModel::getStudy() const +{ + LightApp_RootObject* aRoot = dynamic_cast( root()->root() ); + if ( !aRoot ) + return 0; + return aRoot->study(); +} + +//================================================================ +// Function : isModified +/*! Purpose : default implementation, always returns false so as not to mask study's isModified()*/ +//================================================================ +bool LightApp_DataModel::isModified() const +{ + return false; +} + +//================================================================ +// Function : isSaved +/*! Purpose : default implementation, always returns true so as not to mask study's isSaved()*/ +//================================================================ +bool LightApp_DataModel::isSaved() const +{ + return true; +} diff --git a/src/LightApp/LightApp_DataModel.h b/src/LightApp/LightApp_DataModel.h new file mode 100644 index 000000000..7b1f92d6c --- /dev/null +++ b/src/LightApp/LightApp_DataModel.h @@ -0,0 +1,53 @@ +// File: LightApp_DataModel.h +// Created: 10/25/2004 10:32:33 AM +// Author: Sergey LITONIN +// Copyright (C) CEA 2004 + +#ifndef LIGHTAPP_DATAMODEL_H +#define LIGHTAPP_DATAMODEL_H + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#include "LightApp.h" +#include "CAM_DataModel.h" + +class LightApp_Module; +class LightApp_Study; +class LightApp_DataObject; + +/*! + Description : Base class of data model +*/ +class LIGHTAPP_EXPORT LightApp_DataModel : public CAM_DataModel +{ + Q_OBJECT + +public: + LightApp_DataModel ( CAM_Module* theModule ); + virtual ~LightApp_DataModel(); + + virtual bool open( const QString&, CAM_Study*, QStringList ); + virtual bool save( QStringList& ); + virtual bool saveAs( const QString&, CAM_Study*, QStringList& ); + virtual bool close(); + + virtual void update( LightApp_DataObject* = 0, LightApp_Study* = 0 ); + + virtual bool isModified() const; + virtual bool isSaved() const; + + LightApp_Module* getModule() const; + +signals: + void opened(); + void saved(); + void closed(); + +protected: + LightApp_Study* getStudy() const; + +}; + +#endif diff --git a/src/LightApp/LightApp_ModuleDlg.h b/src/LightApp/LightApp_ModuleDlg.h new file mode 100644 index 000000000..526f16f22 --- /dev/null +++ b/src/LightApp/LightApp_ModuleDlg.h @@ -0,0 +1,45 @@ +// SALOME SALOMEGUI : implementation of desktop and GUI kernel +// +// Copyright (C) 2005 CEA/DEN, EDF R&D +// +// +// +// File : LightApp_ModuleDlg.h +// Author : Michael ZORIN (mzn) +// Module : SALOME + +#ifndef LIGHTAPP_MODULEDLG_H +#define LIGHTAPP_MODULEDLG_H + +#include "LightApp.h" +#include +#include + +class QFrame; +class QLabel; +class QPushButton; + +class LIGHTAPP_EXPORT LightApp_ModuleDlg : public QDialog +{ + Q_OBJECT + +public: + LightApp_ModuleDlg ( QWidget* parent, const QString& component, const QPixmap icon = QPixmap() ) ; + ~LightApp_ModuleDlg ( ) { }; + +private slots: + void onButtonClicked(); + +private: + QFrame* myComponentFrame; + QLabel* myComponentLab; + QLabel* myComponentIcon; + QLabel* myInfoLabel; + QPushButton* myNewBtn; + QPushButton* myOpenBtn; + QPushButton* myLoadBtn; + QPushButton* myCancelBtn; +}; + +#endif + diff --git a/src/LightApp/LightApp_NameDlg.h b/src/LightApp/LightApp_NameDlg.h new file mode 100644 index 000000000..c0309c0f2 --- /dev/null +++ b/src/LightApp/LightApp_NameDlg.h @@ -0,0 +1,47 @@ +// SALOME SalomeApp : implementation of desktop and GUI kernel +// +// Copyright (C) 2003 CEA/DEN, EDF R&D +// +// +// +// File : LightApp_NameDlg.h +// Author : Vadim SANDLER +// Module : SALOME +// $Header$ + +#ifndef LIGHTAPP_NAMEDLG_H +#define LIGHTAPP_NAMEDLG_H + +#include "LightApp.h" +#include + +class QLineEdit; +class QPushButton; + +//================================================================================= +// class : LightApp_NameDlg +/*! purpose : Common dialog box class*/ +//================================================================================= +class LIGHTAPP_EXPORT LightApp_NameDlg : public QDialog +{ + Q_OBJECT + +public: + LightApp_NameDlg( QWidget* parent = 0 ); + ~LightApp_NameDlg(); + + void setName( const QString& name ); + QString name(); + + static QString getName( QWidget* parent = 0, const QString& oldName = QString::null ); + +protected slots: + void accept(); + +private: + QPushButton* myButtonOk; + QPushButton* myButtonCancel; + QLineEdit* myLineEdit; +}; + +#endif // LightApp_NAMEDLG_H diff --git a/src/LightApp/LightApp_OBSelector.cxx b/src/LightApp/LightApp_OBSelector.cxx new file mode 100644 index 000000000..3129b240e --- /dev/null +++ b/src/LightApp/LightApp_OBSelector.cxx @@ -0,0 +1,101 @@ +#include "LightApp_OBSelector.h" + +#include "LightApp_DataOwner.h" +#include "LightApp_DataObject.h" + +#include + +#include + +/*! + Constructor +*/ +LightApp_OBSelector::LightApp_OBSelector( OB_Browser* ob, SUIT_SelectionMgr* mgr ) +: SUIT_Selector( mgr, ob ), + myBrowser( ob ) +{ + if ( myBrowser ) { + connect( myBrowser, SIGNAL( selectionChanged() ), this, SLOT( onSelectionChanged() ) ); + } +} + +/*! + Destructor +*/ +LightApp_OBSelector::~LightApp_OBSelector() +{ +} + +/*! + Gets browser. +*/ +OB_Browser* LightApp_OBSelector::browser() const +{ + return myBrowser; +} + +/*! + Gets selection. +*/ +void LightApp_OBSelector::getSelection( SUIT_DataOwnerPtrList& theList ) const +{ + if ( !myBrowser ) + return; + + DataObjectList objlist; + myBrowser->getSelected( objlist ); + for ( DataObjectListIterator it( objlist ); it.current(); ++it ) + { + LightApp_DataObject* obj = dynamic_cast( it.current() ); + if ( obj ) + { + Handle( SALOME_InteractiveObject ) aSObj = new SALOME_InteractiveObject + ( obj->entry(), obj->componentDataType(), obj->name() ); + LightApp_DataOwner* owner = new LightApp_DataOwner( aSObj ); + theList.append( SUIT_DataOwnerPtr( owner ) ); + } + } +} + +/*!Sets selection.*/ +void LightApp_OBSelector::setSelection( const SUIT_DataOwnerPtrList& theList ) +{ + if ( !myBrowser ) + return; + + QMap themap; + fillEntries( themap ); + + DataObjectList objList; + for ( SUIT_DataOwnerPtrList::const_iterator it = theList.begin(); it != theList.end(); ++it ) + { + const LightApp_DataOwner* owner = dynamic_cast( (*it).operator->() ); + if ( owner && themap.contains( owner->entry() ) ) + objList.append( themap[owner->entry()] ); + } + + myBrowser->setSelected( objList ); +} + +/*!On selection changed.*/ +void LightApp_OBSelector::onSelectionChanged() +{ + selectionChanged(); +} + +/*!Fill entries.*/ +void LightApp_OBSelector::fillEntries( QMap& entires ) +{ + entires.clear(); + + if ( !myBrowser ) + return; + + for ( SUIT_DataObjectIterator it( myBrowser->getRootObject(), + SUIT_DataObjectIterator::DepthLeft ); it.current(); ++it ) + { + LightApp_DataObject* obj = dynamic_cast( it.current() ); + if ( obj ) + entires.insert( obj->entry(), obj ); + } +} diff --git a/src/LightApp/LightApp_OBSelector.h b/src/LightApp/LightApp_OBSelector.h new file mode 100644 index 000000000..22e4eae50 --- /dev/null +++ b/src/LightApp/LightApp_OBSelector.h @@ -0,0 +1,38 @@ +#ifndef LIGHTAPP_OBSELECTOR_H +#define LIGHTAPP_OBSELECTOR_H + +#include "LightApp.h" + +#include + +class OB_Browser; +class LightApp_DataObject; + +class LIGHTAPP_EXPORT LightApp_OBSelector : public SUIT_Selector +{ + Q_OBJECT + +public: + LightApp_OBSelector( OB_Browser*, SUIT_SelectionMgr* ); + virtual ~LightApp_OBSelector(); + + OB_Browser* browser() const; + + /*!Return "ObjectBrowser"*/ + virtual QString type() const { return "ObjectBrowser"; } + +private slots: + void onSelectionChanged(); + +protected: + virtual void getSelection( SUIT_DataOwnerPtrList& ) const; + virtual void setSelection( const SUIT_DataOwnerPtrList& ); + +private: + void fillEntries( QMap& ); + +private: + OB_Browser* myBrowser; +}; + +#endif diff --git a/src/LightApp/LightApp_Operation.cxx b/src/LightApp/LightApp_Operation.cxx new file mode 100755 index 000000000..197eb93ee --- /dev/null +++ b/src/LightApp/LightApp_Operation.cxx @@ -0,0 +1,290 @@ +// LIGHT LightApp +// +// Copyright (C) 2005 CEA/DEN, EDF R&D +// +// +// +// File : LightApp_Operation.h +// Author : Sergey LITONIN +// Module : LIGHT + +#include +#include +#include +#include +#include +#include + +#include + +#include + + +/*! + * \brief Constructor +* +* Constructor sets myModule in NULL and myIsAutoResumed in TRUE +*/ +LightApp_Operation::LightApp_Operation() +: SUIT_Operation( 0 ), + myModule( 0 ), + myIsAutoResumed( true ) +{ +} + +/*! + * \brief Destructor +* +* Destructor does nothing +*/ +LightApp_Operation::~LightApp_Operation() +{ + +} + +/*! + * \brief Gets module of operation + * \return Pointer to the module +* +* Gets pointer to the module or NULL if module was not set. It is strongly recomended to +* set valid pointer on the module before start of operation +*/ +LightApp_Module* LightApp_Operation::module() const +{ + return myModule; +} + + +/*! + * \brief Sets module of operation + * \param theModule - module to be set +* +* Sets pointer to the module. It is strongly recomended to set valid pointer on the +* module before start of operation +*/ +void LightApp_Operation::setModule( LightApp_Module* theModule ) +{ + myModule = theModule; + setApplication( myModule ? myModule->application() : 0 ); + setStudy( application() ? application()->activeStudy() : 0 ); +} + +/*! + * \brief Gets desktop of operation + * \return Pointer to the desktop +* +* Gets pointer to the desktop or NULL if application was not set. It is strongly recomended +* to set valid pointer on the application before start of operation +*/ +SUIT_Desktop* LightApp_Operation::desktop() const +{ + return application() != 0 ? application()->desktop() : 0; +} + +/*! + * \brief Enable dialog of operation +* +* Virtual method redefined from the base class. Enable dialog if it was desabled (in +* suspend method) and activate selection +*/ +void LightApp_Operation::resumeOperation() +{ + SUIT_Operation::resumeOperation(); + setDialogActive( true ); +} + +/*! + * \brief Performs actions needed for starting operation +* +* Virtual method redefined from the base class. Connect signal of selection manager to +* onSelectionDone() slot +*/ +void LightApp_Operation::startOperation() +{ + if( selectionMgr() ) + connect( selectionMgr(), SIGNAL( selectionChanged() ), SLOT( onSelectionDone() ) ); + + //If suspended operation was stopped during starting other operation, + //the dialog is inactive now, We must activate it + setDialogActive( true ); +} + +/*! + * \brief Performs actions needed for suspending operation +* +* Virtual method redefined from the base class. This implementation calls corresponding +* method of base class and cals setDialogActive( false ) +*/ +void LightApp_Operation::suspendOperation() +{ + SUIT_Operation::suspendOperation(); + setDialogActive( false ); +} + +//======================================================================= +// name : abortOperation +// Purpose : Hide dialog box (if it is exists) +//======================================================================= +/*! + * \brief Performs actions needed for aborting operation +* +* Virtual method redefined from the base class calls corresponding method of base class +* and hides dialog box (if it is exists), disconnect slots from selection manager +*/ +void LightApp_Operation::abortOperation() +{ + SUIT_Operation::abortOperation(); + setDialogActive( true ); + if ( dlg() ) + dlg()->hide(); + + if( selectionMgr() ) + disconnect( selectionMgr(), SIGNAL( selectionChanged() ), this, SLOT( onSelectionDone() ) ); +} + +/*! + * \brief Performs actions needed for committing operation +* +* Virtual method redefined from the base class calls corresponding method of base class +* and hides dialog box (if it is exists), disconnect slots from selection manager +*/ +void LightApp_Operation::commitOperation() +{ + SUIT_Operation::commitOperation(); + setDialogActive( true ); + if ( dlg() ) + dlg()->hide(); + + if( selectionMgr() ) + disconnect( selectionMgr(), SIGNAL( selectionChanged() ), this, SLOT( onSelectionDone() ) ); +} + +/*! + * \brief Gets dialog + * \return Pointer to the dialog of this operation or NULL if it does not exist +* +* This method should be redefined in derived classes if they use dialogs. If this +* function returns pointer to dialog then dialog will be correctly +* -# deactivated in suspendOperation method +* -# activated in resumeOperation method +* -# hidden in abortOperation and commitOperation methods +*/ +LightApp_Dialog* LightApp_Operation::dlg() const +{ + return 0; +} + +/*! + * \brief Activates selection +* +* Virtual method should be redefined in derived classes if they use own selection modes +* (different from default) +*/ +void LightApp_Operation::activateSelection() +{ +} + +/*! + * \brief Virtual method called when selection is changed +* +* Virtual method should be redefined in derived classes if they works with selection +* to provide reaction on the change of selection +*/ +void LightApp_Operation::selectionDone() +{ +} + +/*! + * \brief Gets active operation +* +* This method provided for convinience calls SUIT_Study::activeOperation() one +*/ +SUIT_Operation* LightApp_Operation::activeOperation() const +{ + return study() != 0 ? study()->activeOperation() : 0; +} + +/*! + * \brief Gets selection manager +* +* This method provided for convinience calls LightApp_Application::selectionMgr() one +*/ +LightApp_SelectionMgr* LightApp_Operation::selectionMgr() const +{ + SUIT_Application* app = application(); + if ( app != 0 && app->inherits( "LightApp_Application" ) ) + return ( (LightApp_Application*)app )->selectionMgr(); + else + return 0; +} + +/*! + * \brief Call selectionDone() method +* +* Call selectionDone() method if operator is an active one (see selectionDone() for more +* description ) +*/ +void LightApp_Operation::onSelectionDone() +{ + if ( isActive() ) + selectionDone(); +} + +/*! + * \brief Update object browser or/and viewer etc. + * \param flags - update flags +* +* This method provided for convinience calls LightApp_Module::update() one (see +* LightApp_Module::update() for more description) +*/ +void LightApp_Operation::update( const int flags ) +{ + if ( myModule != 0 ) + myModule->update( flags ); +} + +/*! + * \brief Activate/Deactivate dialog of operation + * \param active - State of the dialog to be set +* +* Activate/Deactivate dialog of operation. This method called from startOperation(), +* suspendOperation() ones and so on +*/ +void LightApp_Operation::setDialogActive( const bool active ) +{ + if( dlg() ) + { + if( active ) + { + activateSelection(); + dlg()->setActiveWindow(); + } + } +} + +/*! + * \brief Gets autoresume property + * \return Autoresume property. +* +* Autoresume property is used during automatic resuming operation. If operation is +* suspended and cursor is moved above dialog of the operation then operation is resumed +* automatically (if possible). It can be resumed only program call otherwise (see +* LightApp_SwitchOp for more description). This property is TRUE by default and may be +* changed with setAutoResumed() method call. +*/ +bool LightApp_Operation::isAutoResumed() const +{ + return myIsAutoResumed; +} + +/*! + * \brief Sets autoresume property + * \param on - Value to be set + * \return Autoresume property. +* +* Sets autoresume property (see isAutoResumed() for more description) +*/ +void LightApp_Operation::setAutoResumed( const bool on ) +{ + myIsAutoResumed = on; +} diff --git a/src/LightApp/LightApp_Operation.h b/src/LightApp/LightApp_Operation.h new file mode 100755 index 000000000..4b07bd7b2 --- /dev/null +++ b/src/LightApp/LightApp_Operation.h @@ -0,0 +1,91 @@ +// LIGHT LightApp +// +// Copyright (C) 2005 CEA/DEN, EDF R&D +// +// +// +// File : LightApp_Operation.h +// Author : Sergey LITONIN +// Module : LIGHT + + +#ifndef LightApp_Operation_H +#define LightApp_Operation_H + +#include "LightApp.h" +#include + +class LightApp_Module; +class LightApp_Application; +class LightApp_Operation; +class LightApp_SelectionMgr; +class LightApp_Dialog; +class SUIT_Desktop; + +/* + Class : LightApp_Operation + Description : Base class for all operations +*/ + +/*! + * \brief Base class for all operations + * + * Base class for all operations (see SUIT_Operation for more description) +*/ +class LIGHTAPP_EXPORT LightApp_Operation : public SUIT_Operation +{ + Q_OBJECT + +public: + LightApp_Operation(); + virtual ~LightApp_Operation(); + + virtual void setModule( LightApp_Module* ); + LightApp_Module* module() const; + + bool isAutoResumed() const; + + virtual LightApp_Dialog* dlg() const; + +protected: + + // Methods redefined from base class + + virtual void startOperation(); + virtual void suspendOperation(); + virtual void resumeOperation(); + virtual void abortOperation(); + virtual void commitOperation(); + + // Additional virtual methods may be redefined by derived classes + + virtual void setDialogActive( const bool ); + virtual void activateSelection(); + virtual void selectionDone(); + + + // Axiluary methods + + SUIT_Desktop* desktop() const; + SUIT_Operation* activeOperation() const; + LightApp_SelectionMgr* selectionMgr() const; + void update( const int ); + void setAutoResumed( const bool ); + +private slots: + + virtual void onSelectionDone(); + +private: + + LightApp_Module* myModule; + bool myIsAutoResumed; +}; + +#endif + + + + + + diff --git a/src/LightApp/LightApp_UpdateFlags.h b/src/LightApp/LightApp_UpdateFlags.h new file mode 100755 index 000000000..2fc7fa780 --- /dev/null +++ b/src/LightApp/LightApp_UpdateFlags.h @@ -0,0 +1,37 @@ +// LIGHT LightApp +// +// Copyright (C) 2005 CEA/DEN, EDF R&D +// +// +// +// File : LightApp_UpdateFlags.h +// Author : Sergey LITONIN +// Module : LIGHT + + +#ifndef LightApp_UpdateFlags_H +#define LightApp_UpdateFlags_H + +/* + Enum : UpdateFlags + Description : Enumeration for update flags. First byte is reserved for LightApp_Module. + Modules derived from this model must use other 3 bytes to define their + own update flags +*/ + +typedef enum +{ + UF_Forced = 0x00000001, + UF_Model = 0x00000002, + UF_Viewer = 0x00000004, + UF_ObjBrowser = 0x00000008, + UF_Controls = 0x00000010, +} UpdateFlags; + +#endif + + + + + + diff --git a/src/LightApp/LightApp_VTKSelector.cxx b/src/LightApp/LightApp_VTKSelector.cxx new file mode 100644 index 000000000..c31cc4341 --- /dev/null +++ b/src/LightApp/LightApp_VTKSelector.cxx @@ -0,0 +1,187 @@ +#include "LightApp_VTKSelector.h" +#include "LightApp_DataOwner.h" + +#include "SVTK_ViewModel.h" +#include "SVTK_Selector.h" +#include "SVTK_ViewWindow.h" +#include "SVTK_Functor.h" + +#include "SALOME_Actor.h" +#include "SALOME_ListIteratorOfListIO.hxx" + +#include "VTKViewer_Algorithm.h" + +#include + +/*! + Constructor. +*/ +LightApp_SVTKDataOwner +::LightApp_SVTKDataOwner( const Handle(SALOME_InteractiveObject)& theIO, + const TColStd_IndexedMapOfInteger& theIds, + Selection_Mode theMode, + SALOME_Actor* theActor): + LightApp_DataOwner( theIO ), + mySelectionMode(theMode), + myActor(theActor) +{ + myIds = theIds; // workaround - there is no constructor copy for the container +} + +/*! + Destuctor. +*/ +LightApp_SVTKDataOwner +::~LightApp_SVTKDataOwner() +{ +} + +/*! + Gets actor pointer. +*/ +SALOME_Actor* +LightApp_SVTKDataOwner +::GetActor() const +{ + return myActor.GetPointer(); +} + +/*! + Constructor. +*/ +LightApp_VTKSelector +::LightApp_VTKSelector( SVTK_Viewer* viewer, + SUIT_SelectionMgr* mgr ): + SUIT_Selector( mgr, viewer ), + myViewer( viewer ) +{ + if ( myViewer ) + connect( myViewer, SIGNAL( selectionChanged() ), this, SLOT( onSelectionChanged() ) ); +} + +/*! + Destructor. +*/ +LightApp_VTKSelector +::~LightApp_VTKSelector() +{ +} + +/*! + Gets viewer. +*/ +SVTK_Viewer* +LightApp_VTKSelector +::viewer() const +{ + return myViewer; +} + +/*! + Gets type of vtk viewer. +*/ +QString +LightApp_VTKSelector +::type() const +{ + return SVTK_Viewer::Type(); +} + +/*! + On selection changed. +*/ +void +LightApp_VTKSelector +::onSelectionChanged() +{ + selectionChanged(); +} + +/*! + Gets list of selected data owners.(output \a aList). +*/ +void +LightApp_VTKSelector +::getSelection( SUIT_DataOwnerPtrList& aList ) const +{ + if(myViewer){ + if(SUIT_ViewManager* aViewMgr = myViewer->getViewManager()){ + if(SVTK_ViewWindow* aView = dynamic_cast(aViewMgr->getActiveView())){ + if(SVTK_Selector* aSelector = aView->GetSelector()){ + Selection_Mode aMode = aSelector->SelectionMode(); + const SALOME_ListIO& aListIO = aSelector->StoredIObjects(); + SALOME_ListIteratorOfListIO anIter(aListIO); + for(; anIter.More(); anIter.Next()){ + Handle(SALOME_InteractiveObject) anIO = anIter.Value(); + if(anIO->hasEntry()){ + TColStd_IndexedMapOfInteger anIds; + aSelector->GetIndex(anIO,anIds); + SALOME_Actor* anActor = aSelector->GetActor(anIO); + if( !anActor ) + anActor = VTK::Find(aView->getRenderer()->GetActors(),VTK::TIsSameIObject(anIO)); + + aList.append(new LightApp_SVTKDataOwner(anIO,anIds,aMode,anActor)); + } + } + } + } + } + } +} + +/*! + Sets selection to selector from data owner list \a theList. +*/ +void +LightApp_VTKSelector +::setSelection( const SUIT_DataOwnerPtrList& theList ) +{ + if(myViewer){ + if(SUIT_ViewManager* aViewMgr = myViewer->getViewManager()){ + if(SVTK_ViewWindow* aView = dynamic_cast(aViewMgr->getActiveView())){ + if(SVTK_Selector* aSelector = aView->GetSelector()){ + SALOME_ListIO anAppendList; + const SALOME_ListIO& aStoredList = aSelector->StoredIObjects(); + SUIT_DataOwnerPtrList::const_iterator anIter = theList.begin(); + for(; anIter != theList.end(); ++anIter){ + const SUIT_DataOwner* aDataOwner = (*anIter).get(); + if(const LightApp_SVTKDataOwner* anOwner = dynamic_cast(aDataOwner)){ + aSelector->SetSelectionMode(anOwner->GetMode()); + Handle(SALOME_InteractiveObject) anIO = anOwner->IO(); + + if( anOwner->GetActor() ) + aSelector->AddIObject( anOwner->GetActor() ); + else + aSelector->AddIObject(anIO); + + anAppendList.Append(anIO); + aSelector->AddOrRemoveIndex(anIO,anOwner->GetIds(),false); + }else if(const LightApp_DataOwner* anOwner = dynamic_cast(aDataOwner)){ + Handle(SALOME_InteractiveObject) anIO = + new SALOME_InteractiveObject(anOwner->entry().latin1(),""); + aSelector->AddIObject(anIO); + anAppendList.Append(anIO); + } + } + // To remove IOs, which is not selected. + QMap< QString, Handle( SALOME_InteractiveObject )> toRemove; + SALOME_ListIteratorOfListIO anIt( aStoredList ); + for( ; anIt.More(); anIt.Next() ) + if( !anIt.Value().IsNull() ) + toRemove[ anIt.Value()->getEntry() ] = anIt.Value(); + + anIt = SALOME_ListIteratorOfListIO(anAppendList); + for( ; anIt.More(); anIt.Next() ) + toRemove.remove( anIt.Value()->getEntry() ); + + QMap< QString, Handle( SALOME_InteractiveObject )>::const_iterator RIt = toRemove.begin(), + REnd = toRemove.end(); + for( ; RIt!=REnd; RIt++ ) + aSelector->RemoveIObject( RIt.data() ); + + aView->onSelectionChanged(); + } + } + } + } +} diff --git a/src/LightApp/LightApp_VTKSelector.h b/src/LightApp/LightApp_VTKSelector.h new file mode 100644 index 000000000..25c4ac44e --- /dev/null +++ b/src/LightApp/LightApp_VTKSelector.h @@ -0,0 +1,78 @@ +#ifndef LIGHTAPP_VTKSELECTOR_H +#define LIGHTAPP_VTKSELECTOR_H + +#include + +#include + +#include "SUIT_Selector.h" + +#include "LightApp.h" +#include "LightApp_DataOwner.h" + +#include "SVTK_Selection.h" +#include "SALOME_InteractiveObject.hxx" + +class SALOME_Actor; +class SVTK_Viewer; + +/*! + Provide salome vtk data owner list. +*/ +class LIGHTAPP_EXPORT LightApp_SVTKDataOwner : public LightApp_DataOwner +{ + public: + LightApp_SVTKDataOwner( const Handle(SALOME_InteractiveObject)& theIO, + const TColStd_IndexedMapOfInteger& theIds, + Selection_Mode theMode = ActorSelection, + SALOME_Actor* theActor = NULL); + virtual ~LightApp_SVTKDataOwner(); + + /*!Gets dataowners ids list.*/ + const TColStd_IndexedMapOfInteger& GetIds() const + { + return myIds; + } + + /*!Gets selection mode.*/ + Selection_Mode GetMode() const + { + return mySelectionMode; + } + + SALOME_Actor* GetActor() const; + + protected: + TColStd_IndexedMapOfInteger myIds; + Selection_Mode mySelectionMode; + vtkSmartPointer myActor; +}; + + +/*! + Provide vtk selection of data owners. +*/ +class LIGHTAPP_EXPORT LightApp_VTKSelector : public SUIT_Selector +{ + Q_OBJECT; + +public: + LightApp_VTKSelector( SVTK_Viewer*, SUIT_SelectionMgr* ); + virtual ~LightApp_VTKSelector(); + + SVTK_Viewer* viewer() const; + + virtual QString type() const; + +private slots: + void onSelectionChanged(); + +protected: + virtual void getSelection( SUIT_DataOwnerPtrList& ) const; + virtual void setSelection( const SUIT_DataOwnerPtrList& ); + +private: + SVTK_Viewer* myViewer; +}; + +#endif diff --git a/src/LightApp/resources/LightApp.ini b/src/LightApp/resources/LightApp.ini new file mode 100755 index 000000000..814a5ec84 --- /dev/null +++ b/src/LightApp/resources/LightApp.ini @@ -0,0 +1,21 @@ +# The resources mapping file for LightApp application + +[language] +language = en + +[launch] +modules = LIGHT + +[resources] +SUIT = $(SUITRoot)/resources +STD = $(SUITRoot)/resources +LightApp = $(SUITRoot)/resources +Plot2d = $(SUITRoot)/resources +GLViewer = $(SUITRoot)/resources +OCCViewer = $(SUITRoot)/resources +VTKViewer = $(SUITRoot)/resources +LIGHT = $(LIGHT_ROOT_DIR)/share/salome/resources + +[LIGHT] +name = Light +icon = LIGHT diff --git a/src/LightApp/resources/LightApp_images.po b/src/LightApp/resources/LightApp_images.po new file mode 100644 index 000000000..c1ee44b39 --- /dev/null +++ b/src/LightApp/resources/LightApp_images.po @@ -0,0 +1,33 @@ +// File: LightApp_images.po +// Created: May, 2005 +// Author: OCC team +// Copyright (C) CEA 2005 + +msgid "" +msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"POT-Creation-Date: 2002-05-28 10:57:43 AM CEST\n" +"PO-Revision-Date: YYYY-MM-DD\n" +"Last-Translator: FULLNAME \n" +"Content-Type: text/plain; charset=iso-8859-1\n" + +msgid "ABOUT" +msgstr "icon_about.png" + +msgid "ABOUT_SPLASH" +msgstr "icon_about.png" + +msgid "APP_DEFAULT_ICO" +msgstr "icon_default.png" + +msgid "APP_MODULE_ICO" +msgstr "icon_module.png" + +msgid "APP_MODULE_BIG_ICO" +msgstr "icon_module_big.png" + +msgid "ICON_SELECT" +msgstr "icon_select.png" + +msgid "APP_BASE_LOGO" +msgstr "icon_applogo.png" diff --git a/src/Plot2d/Makefile.in b/src/Plot2d/Makefile.in new file mode 100755 index 000000000..ef3d4742b --- /dev/null +++ b/src/Plot2d/Makefile.in @@ -0,0 +1,75 @@ +# File : Makefile.in +# Author : Vladimir Klyachin (OCN) +# Module : Plot2d +# $Header$ + +top_srcdir=@top_srcdir@ +top_builddir=../.. +srcdir=@srcdir@ +VPATH=.:@srcdir@:@srcdir@/resources + + +@COMMENCE@ + +# header files +EXPORT_HEADERS= Plot2d.h \ + Plot2d_Curve.h \ + Plot2d_FitDataDlg.h \ + Plot2d_Prs.h \ + Plot2d_SetupViewDlg.h \ + Plot2d_ViewFrame.h \ + Plot2d_ViewManager.h \ + Plot2d_ViewModel.h \ + Plot2d_ViewWindow.h \ + Plot2d_SetupCurveDlg.h + +# .po files to transform in .qm +PO_FILES = Plot2d_images.po \ + Plot2d_msg_en.po + +# Libraries targets +LIB = libPlot2d.la +LIB_SRC= Plot2d_Curve.cxx \ + Plot2d_FitDataDlg.cxx \ + Plot2d_Prs.cxx \ + Plot2d_SetupViewDlg.cxx \ + Plot2d_ViewFrame.cxx \ + Plot2d_ViewManager.cxx \ + Plot2d_ViewModel.cxx \ + Plot2d_ViewWindow.cxx \ + Plot2d_SetupCurveDlg.cxx + +LIB_MOC = \ + Plot2d_FitDataDlg.h \ + Plot2d_SetupViewDlg.h \ + Plot2d_ViewFrame.h \ + Plot2d_ViewManager.h \ + Plot2d_ViewModel.h \ + Plot2d_ViewWindow.h \ + Plot2d_SetupCurveDlg.h + +RESOURCES_FILES = \ +plot2d_clone.png \ +plot2d_camera_dump.png \ +plot2d_fitall.png \ +plot2d_fitarea.png \ +plot2d_glpan.png \ +plot2d_legend.png \ +plot2d_linear.png \ +plot2d_linear_y.png \ +plot2d_lines.png \ +plot2d_log.png \ +plot2d_log_y.png \ +plot2d_pan.png \ +plot2d_points.png \ +plot2d_settings.png \ +plot2d_splines.png \ +plot2d_zoom.png + +CPPFLAGS+=$(QT_INCLUDES) $(PYTHON_INCLUDES) $(QWT_INCLUDES) + +LDFLAGS+=$(QWT_LIBS) $(QT_MT_LIBS) -lsuit + +@CONCLUDE@ + + diff --git a/src/Prs/Makefile.in b/src/Prs/Makefile.in new file mode 100755 index 000000000..73133a3e6 --- /dev/null +++ b/src/Prs/Makefile.in @@ -0,0 +1,27 @@ +# source path +top_srcdir=@top_srcdir@ +top_builddir=../.. +srcdir=@srcdir@ +VPATH=.:@srcdir@:@top_srcdir@/idl + + +@COMMENCE@ + +EXPORT_HEADERS = SALOME_Prs.h + +# Libraries targets + +LIB = libSalomePrs.la +LIB_SRC = SALOME_Prs.cxx + +LIB_CLIENT_IDL = + +# Executables targets +BIN = +BIN_SRC = + +CPPFLAGS+= +LDFLAGS+= + + +@CONCLUDE@ diff --git a/src/PyInterp/Makefile.in b/src/PyInterp/Makefile.in new file mode 100755 index 000000000..1672f5ada --- /dev/null +++ b/src/PyInterp/Makefile.in @@ -0,0 +1,51 @@ +# SALOME PyInterp : implementation of base thread-safe Python services +# +# Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +# +# +# +# File : Makefile.in +# Module : SALOME + +top_srcdir=@top_srcdir@ +top_builddir=../.. +srcdir=@srcdir@ +VPATH=.:@srcdir@ + + +@COMMENCE@ + +# header files +EXPORT_HEADERS= PyInterp.h \ + PyInterp_base.h \ + PyInterp_Dispatcher.h + +# Libraries targets +LIB = libPyInterp.la + +LIB_SRC= PyInterp_base.cxx \ + PyInterp_Dispatcher.cxx + +LIB_MOC = PyInterp_Watcher.h + +CPPFLAGS+= $(PYTHON_INCLUDES) $(QT_INCLUDES) + +LDFLAGS+= $(PYTHON_LIBS) $(QT_MT_LIBS) + +@CONCLUDE@ diff --git a/src/SOCC/Makefile.in b/src/SOCC/Makefile.in new file mode 100755 index 000000000..36b2aa697 --- /dev/null +++ b/src/SOCC/Makefile.in @@ -0,0 +1,35 @@ +# File : Makefile.in +# Author : Alexander Solovyov(OCN) +# Module : SOCC +# $Header: /dn06/SALOME_CVS/GUI_SRC/src/SOCC/Makefile.in,v 1.1 + +top_srcdir=@top_srcdir@ +top_builddir=../.. +srcdir=@srcdir@ +VPATH=.:@srcdir@ + + +@COMMENCE@ + +# header files +EXPORT_HEADERS= SOCC.h \ + SOCC_ViewModel.h \ + SOCC_Prs.h \ + SOCC_ViewWindow.h + +# Libraries targets +LIB = libSOCC.la + +LIB_SRC= SOCC_ViewModel.cxx \ + SOCC_Prs.cxx \ + SOCC_ViewWindow.cxx + +LIB_MOC = SOCC_ViewModel.h \ + SOCC_ViewWindow.h + +CPPFLAGS+=$(QT_INCLUDES) $(OCC_INCLUDES) $(BOOST_CPPFLAGS) + +LDFLAGS+=$(QT_MT_LIBS) +LIBS+= -lsuit -lSalomeObject -lSalomePrs -lOCCViewer + +@CONCLUDE@ diff --git a/src/SPlot2d/Makefile.in b/src/SPlot2d/Makefile.in new file mode 100644 index 000000000..d0a8d1604 --- /dev/null +++ b/src/SPlot2d/Makefile.in @@ -0,0 +1,51 @@ +# source path +top_srcdir=@top_srcdir@ +top_builddir=../.. +srcdir=@srcdir@ +VPATH=.:@srcdir@:@top_srcdir@/idl + + +@COMMENCE@ + +EXPORT_HEADERS = \ + SPlot2d.h \ + SPlot2d_Curve.h \ + SPlot2d_Prs.h \ + SPlot2d_ViewModel.h + +# .po files to transform in .qm +PO_FILES = SPlot2d_msg_en.po + +# Libraries targets + +LIB = libSPlot2d.la +LIB_SRC = \ + SPlot2d_Curve.cxx \ + SPlot2d_Prs.cxx \ + SPlot2d_ViewModel.cxx + +LIB_MOC = \ + SPlot2d_ViewModel.h + +#LIB_CLIENT_IDL = SALOMEDS.idl \ +# SALOME_Exception.idl \ +# SALOME_GenericObj.idl + +#LIB_CLIENT_IDL = SALOMEDS.idl \ +# SALOME_ModuleCatalog.idl \ +# SALOME_Component.idl \ +# SALOME_ContainerManager.idl \ +# SALOME_Exception.idl \ +# SALOME_GenericObj.idl + +#CPPFLAGS+=$(QT_INCLUDES) $(OCC_INCLUDES) $(OGL_INCLUDES) $(PYTHON_INCLUDES) $(QWT_INCLUDES) $(BOOST_CPPFLAGS) -I$(KERNEL_ROOT_DIR)/include/salome +CPPFLAGS+=$(QT_INCLUDES) $(OCC_INCLUDES) $(QWT_INCLUDES) $(BOOST_CPPFLAGS) -I$(KERNEL_ROOT_DIR)/include/salome +LDFLAGS+=$(QT_MT_LIBS) $(QWT_LIBS) -L$(KERNEL_ROOT_DIR)/lib/salome -lsuit -lPlot2d -lSalomePrs + + +@CONCLUDE@ + + + + + diff --git a/src/SalomeApp/Makefile.in b/src/SalomeApp/Makefile.in new file mode 100755 index 000000000..308e5126b --- /dev/null +++ b/src/SalomeApp/Makefile.in @@ -0,0 +1,78 @@ +# File : Makefile.in +# Author : Vladimir Klyachin (OCN) +# Module : SalomeApp +# $Header$ + +top_srcdir=@top_srcdir@ +top_builddir=../.. +srcdir=@srcdir@ +VPATH=.:@srcdir@:@srcdir@/resources + + +@COMMENCE@ + +# header files +EXPORT_HEADERS= SalomeApp.h \ + SalomeApp_Application.h \ + SalomeApp_DataModel.h \ + SalomeApp_DataObject.h \ + SalomeApp_Module.h \ + SalomeApp_Study.h \ + SalomeApp_ExceptionHandler.h \ + SalomeApp_EventFilter.h \ + SalomeApp_Tools.h \ + SalomeApp_ImportOperation.h \ + SalomeApp_Filter.h \ + SalomeApp_TypeFilter.h \ + SalomeApp_StudyPropertiesDlg.h \ + SalomeApp_CheckFileDlg.h + +# .po files to transform in .qm +PO_FILES = SalomeApp_images.po \ + SalomeApp_msg_en.po + +# Libraries targets +LIB = libSalomeApp.la + +LIB_SRC= SalomeApp_Module.cxx \ + SalomeApp_Application.cxx \ + SalomeApp_DataModel.cxx \ + SalomeApp_DataObject.cxx \ + SalomeApp_Study.cxx \ + SalomeApp_ExceptionHandler.cxx \ + SalomeApp_EventFilter.cxx \ + SalomeApp_PyInterp.cxx \ + SalomeApp_Tools.cxx \ + SalomeApp_ImportOperation.cxx \ + SalomeApp_Filter.cxx \ + SalomeApp_TypeFilter.cxx \ + SalomeApp_StudyPropertiesDlg.cxx \ + SalomeApp_ListView.cxx \ + SalomeApp_CheckFileDlg.cxx + +LIB_MOC = SalomeApp_Application.h \ + SalomeApp_DataModel.h \ + SalomeApp_Module.h \ + SalomeApp_Study.h \ + SalomeApp_StudyPropertiesDlg.h \ + SalomeApp_ListView.h \ + SalomeApp_CheckFileDlg.h + +LIB_CLIENT_IDL = SALOMEDS.idl \ + SALOME_Exception.idl \ + SALOME_GenericObj.idl + +RESOURCES_FILES = SalomeApp.ini \ + SalomeApp.xml + +CPPFLAGS+=$(PYTHON_INCLUDES) $(QT_INCLUDES) $(QWT_INCLUDES) $(OCC_INCLUDES) $(VTK_INCLUDES) $(BOOST_CPPFLAGS) -I${KERNEL_ROOT_DIR}/include/salome + +LDFLAGS+=$(PYTHON_LIBS) $(QT_MT_LIBS) +LIBS+= -lsuit -lstd -lCAM -lObjBrowser -lSalomePrs -L$(KERNEL_ROOT_DIR)/lib/salome -lOpUtil -lSALOMELocalTrace $(CAS_KERNEL) -lSPlot2d -lGLViewer -lOCCViewer -lVTKViewer -lSalomeObject -lSVTK -lSOCC -lPyInterp -lPythonConsole -lLogWindow -lLightApp -lSalomeContainer -lToolsGUI + +@CONCLUDE@ + + + + + diff --git a/src/SalomeApp/SalomeApp_DataModel.cxx b/src/SalomeApp/SalomeApp_DataModel.cxx new file mode 100644 index 000000000..48838709e --- /dev/null +++ b/src/SalomeApp/SalomeApp_DataModel.cxx @@ -0,0 +1,230 @@ +// File: SalomeApp_DataModel.cxx +// Created: 10/25/2004 10:36:06 AM +// Author: Sergey LITONIN +// Copyright (C) CEA 2004 + +#include "SalomeApp_DataModel.h" +#include "SalomeApp_Study.h" +#include "SalomeApp_DataObject.h" +#include "SalomeApp_Module.h" +#include "SalomeApp_Application.h" +#include "SalomeApp_Engine_i.hxx" + +#include "LightApp_RootObject.h" + +#include + +#include +#include +#include + +#include "SALOMEDS_Tool.hxx" + +#include +#include CORBA_SERVER_HEADER(SALOME_Exception) + +//======================================================================= +// name : BuildTree +/*!Purpose : static method used by SalomeApp_Study and SalomeApp_DataModel classes + * to create default SALOMEDS-based data object tree + */ +//======================================================================= +SUIT_DataObject* SalomeApp_DataModel::BuildTree( const _PTR(SObject)& obj, + SUIT_DataObject* parent, + SalomeApp_Study* study, + bool skip ) +{ + SalomeApp_DataObject* aDataObj = 0; + if ( !obj || !study ) + return aDataObj; + + _PTR(SObject) refObj; + if ( obj->GetName().size() || obj->ReferencedObject( refObj ) ) // skip nameless non references SObjects + { + _PTR(SComponent) aSComp( obj ); + + // patch for bug IPAL9313 + if ( aSComp && parent && skip ) + { + QString aSName( aSComp->GetName().c_str() ); + DataObjectList allComponents = parent->children( /*recursive=*/false ); + for ( DataObjectListIterator it( allComponents ); it.current(); ++it ) { + SUIT_DataObject* componentObj = it.current(); + if ( componentObj->name() == aSName ) { + // mkr : modifications for update of already published in + // object browser, but not loaded yet components + LightApp_Application* anApp = dynamic_cast + (SUIT_Session::session()->activeApplication() ); + // asv : corresponding DataObjects are DELETED before update (so they are re-built). + if (anApp && !anApp->module(aSName)) { // if module is not loaded, delete it's DataObject + // jfa: remove children before DataObject deletion + DataObjectList chilren = componentObj->children(/*recursive=*/true); + for (DataObjectListIterator itc (chilren); itc.current(); ++itc) + componentObj->removeChild(itc.current()); + + // delete DataObject itself and re-create it and all its sub-objects + delete componentObj; + // don't do anything here, because iterator may be corrupted (deleted object inside it) + break; // proceed to build_a_data_object code below + } + else + return componentObj; + } + } + } + + aDataObj = aSComp ? new SalomeApp_ModuleObject( aSComp, parent ) : + new SalomeApp_DataObject ( obj, parent ); + + _PTR(ChildIterator) it ( study->studyDS()->NewChildIterator( obj ) ); + for ( ; it->More(); it->Next() ) { + // don't use shared_ptr here, for Data Object will take + // ownership of this pointer + _PTR(SObject) aSO( it->Value() ); + BuildTree( aSO, aDataObj, study ); + } + } + return aDataObj; +} + +//======================================================================= +// name : SalomeApp_DataModel::SalomeApp_DataModel +/*!Purpose : Constructor*/ +//======================================================================= +SalomeApp_DataModel::SalomeApp_DataModel( CAM_Module* theModule ) +: LightApp_DataModel( theModule ) +{ +} + +//======================================================================= +// name : SalomeApp_DataModel::~SalomeApp_DataModel +/*! Purpose : Destructor*/ +//======================================================================= +SalomeApp_DataModel::~SalomeApp_DataModel() +{ +} + +//================================================================ +// Function : open +/*! Purpose : Open data model*/ +//================================================================ +bool SalomeApp_DataModel::open( const QString& name, CAM_Study* study, QStringList ) +{ + SalomeApp_Study* aDoc = dynamic_cast( study ); + if ( !aDoc ) + return false; + + QString anId = getRootEntry( aDoc ); + if ( anId.isEmpty() ) + return true; // Probably nothing to load + + _PTR(Study) aStudy ( aDoc->studyDS() ); // shared_ptr cannot be used here + _PTR(SComponent) aSComp ( aStudy->FindComponentID( std::string( anId.latin1() ) ) ); + if ( aSComp ) + buildTree( aSComp, 0, aDoc ); + + QStringList listOfFiles; + LightApp_DataModel::open(name, study, listOfFiles); + return true; +} + +//================================================================ +// Function : update +/*! Purpose : Update application.*/ +//================================================================ +void SalomeApp_DataModel::update( LightApp_DataObject*, LightApp_Study* study ) +{ + SalomeApp_Study* aSStudy = dynamic_cast(study); + LightApp_RootObject* studyRoot = 0; + _PTR(SObject) sobj; + SalomeApp_DataObject* modelRoot = dynamic_cast( root() ); + if ( !modelRoot ){ // not yet connected to a study -> try using argument + if ( !aSStudy ) + aSStudy = dynamic_cast( getModule()->getApp()->activeStudy() ); + if ( aSStudy ){ + studyRoot = dynamic_cast( aSStudy->root() ); + QString anId = getRootEntry( aSStudy ); + if ( !anId.isEmpty() ){ // if nothing is published in the study for this module -> do nothing + _PTR(Study) aStudy ( aSStudy->studyDS() ); + sobj = aStudy->FindComponentID( std::string( anId.latin1() ) ); + } + } + } + else{ + studyRoot = dynamic_cast( modelRoot->root() ); + if ( studyRoot ) { + aSStudy = dynamic_cast( studyRoot->study() ); // value should not change here theoretically, but just to make sure + if ( aSStudy ) { + _PTR(Study) aStudy ( aSStudy->studyDS() ); + // modelRoot->object() cannot be reused here: it is about to be deleted by buildTree() soon + sobj = aStudy->FindComponentID( std::string( modelRoot->entry().latin1() ) ); + } + } + } + buildTree( sobj, studyRoot, aSStudy ); +} + +//================================================================ +// Function : buildTree +/*! Purpose : private method, build tree.*/ +//================================================================ +void SalomeApp_DataModel::buildTree( const _PTR(SObject)& obj, + SUIT_DataObject* parent, + SalomeApp_Study* study ) +{ + if ( !obj ) + return; + //if ( !root() ){ // Build default SALOMEDS-based data object tree and insert it into study + SalomeApp_ModuleObject* aNewRoot = dynamic_cast( BuildTree( obj, parent, study ) ); + if ( aNewRoot ){ + aNewRoot->setDataModel( this ); + setRoot( aNewRoot ); + } + //} +} + +//================================================================ +// Function : getModule +/*! Purpose : gets module*/ +//================================================================ + +SalomeApp_Module* SalomeApp_DataModel::getModule() const +{ + return dynamic_cast( module() ); +} + +//================================================================ +// Function : getStudy +/*! Purpose : gets study */ +//================================================================ +SalomeApp_Study* SalomeApp_DataModel::getStudy() const +{ + if(!root()) return 0; + LightApp_RootObject* aRoot = dynamic_cast( root()->root() ); + if ( !aRoot ) + return 0; + SalomeApp_Study* aStudy = dynamic_cast( aRoot->study() ); + if ( !aStudy ) + return 0; + return aStudy; +} + +//================================================================ +// Function : getRootEntry +/*! Purpose : returns study entry corresponding to this data model*/ +//================================================================ +QString SalomeApp_DataModel::getRootEntry( SalomeApp_Study* study ) const +{ + QString anEntry; + if ( root() && root()->root() ) { // data model already in a study + SalomeApp_DataObject* anObj = dynamic_cast( root() ); + if ( anObj ) + anEntry = anObj->entry(); + } + else if ( study && study->studyDS() ) { // this works even if is null + _PTR(SComponent) aSComp( study->studyDS()->FindComponent( module()->name() ) ); + if ( aSComp ) + anEntry = aSComp->GetID().c_str(); + } + return anEntry; +} diff --git a/src/SalomeApp/SalomeApp_DataModel.h b/src/SalomeApp/SalomeApp_DataModel.h new file mode 100644 index 000000000..4dab54d9b --- /dev/null +++ b/src/SalomeApp/SalomeApp_DataModel.h @@ -0,0 +1,49 @@ +// File: SalomeApp_DataModel.h +// Created: 10/25/2004 10:32:33 AM +// Author: Sergey LITONIN +// Copyright (C) CEA 2004 + +#ifndef SALOMEAPP_DATAMODEL_H +#define SALOMEAPP_DATAMODEL_H + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#include "SalomeApp.h" +#include "LightApp_DataModel.h" + +#include "SALOMEDSClient.hxx" + +class SalomeApp_Module; +class SalomeApp_Study; +class SalomeApp_DataObject; + +// Class : SalomeApp_DataModel +/// Description : Base class of data model +class SALOMEAPP_EXPORT SalomeApp_DataModel : public LightApp_DataModel +{ + Q_OBJECT + +public: + static SUIT_DataObject* BuildTree(const _PTR(SObject)& obj, + SUIT_DataObject* parent, + SalomeApp_Study* study, + bool skip = false ); + + SalomeApp_DataModel ( CAM_Module* theModule ); + virtual ~SalomeApp_DataModel(); + + virtual bool open( const QString&, CAM_Study*, QStringList ); + virtual void update( LightApp_DataObject* = 0, LightApp_Study* = 0 ); + + QString getRootEntry( SalomeApp_Study* ) const; + SalomeApp_Module* getModule() const; + +protected: + SalomeApp_Study* getStudy() const; + + virtual void buildTree(const _PTR(SObject)&, SUIT_DataObject*, SalomeApp_Study* ); +}; + +#endif diff --git a/src/SalomeApp/SalomeApp_PyInterp.h b/src/SalomeApp/SalomeApp_PyInterp.h new file mode 100755 index 000000000..a15b3767f --- /dev/null +++ b/src/SalomeApp/SalomeApp_PyInterp.h @@ -0,0 +1,46 @@ +// SALOME SALOMEGUI : implementation of desktop and GUI kernel +// +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : SalomeApp_PyInterp.h +// Author : Nicolas REJNERI +// Module : SALOME +// $Header$ + +#ifndef _SalomeApp_PYINTERP_H_ +#define _SalomeApp_PYINTERP_H_ + +#include // this include must be first (see PyInterp_base.h)! + +class SalomeApp_PyInterp : public PythonConsole_PyInterp +{ +public: + SalomeApp_PyInterp(); + virtual ~SalomeApp_PyInterp(); + + virtual void init_python(); + +protected: + virtual bool initContext(); +}; + +#endif diff --git a/src/SalomeApp/resources/SalomeApp.ini b/src/SalomeApp/resources/SalomeApp.ini new file mode 100644 index 000000000..305c929d7 --- /dev/null +++ b/src/SalomeApp/resources/SalomeApp.ini @@ -0,0 +1,31 @@ +[language] +language = en + +[launch] +modules = GEOM,SMESH,VISU + +[resources] +SUIT = $(SUITRoot)/resources +STD = $(SUITRoot)/resources +Plot2d = $(SUITRoot)/resources +GLViewer = $(SUITRoot)/resources +OCCViewer = $(SUITRoot)/resources +VTKViewer = $(SUITRoot)/resources +SVTK = $(SUITRoot)/resources +LightApp = $(SUITRoot)/resources +SalomeApp = $(SUITRoot)/resources +GEOM = $(GEOM_ROOT_DIR)/share/salome/resources +SMESH = $(SMESH_ROOT_DIR)/share/salome/resources +VISU = $(VISU_ROOT_DIR)/share/salome/resources + +[GEOM] +name = Geometry +icon = ModulGeom + +[SMESH] +name = Mesh +icon = ModulMesh + +[VISU] +name = Post-Pro +icon = ModulVisu diff --git a/src/SalomeApp/resources/SalomeApp_images.po b/src/SalomeApp/resources/SalomeApp_images.po new file mode 100644 index 000000000..29ec0e6e6 --- /dev/null +++ b/src/SalomeApp/resources/SalomeApp_images.po @@ -0,0 +1,13 @@ +// File: SalomeApp_images.po +// Created: November, 2004 +// Author: OCC team +// Copyright (C) CEA 2004 + +msgid "" +msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"POT-Creation-Date: 2002-05-28 10:57:43 AM CEST\n" +"PO-Revision-Date: YYYY-MM-DD\n" +"Last-Translator: FULLNAME \n" +"Content-Type: text/plain; charset=iso-8859-1\n" + diff --git a/src/VTKViewer/VTKViewer_ConvexTool.cxx b/src/VTKViewer/VTKViewer_ConvexTool.cxx new file mode 100644 index 000000000..64e712e97 --- /dev/null +++ b/src/VTKViewer/VTKViewer_ConvexTool.cxx @@ -0,0 +1,602 @@ +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org + +#include "VTKViewer_ConvexTool.h" + +#include +#include +#include +#include + +#include +#include +#include +#include + +typedef std::set TUIDS; // unique ids +typedef std::map TPTOIDS; // id points -> unique ids + +namespace CONVEX_TOOL +{ + +static float FACE_ANGLE_TOLERANCE=1.5; + +#ifdef _DEBUG_ + static int MYDEBUG = 0; +#else + static int MYDEBUG = 0; +#endif + +/*! \fn static void GetCenter(vtkUnstructuredGrid* theGrid,TCell theptIds,float *center) + * \brief Calculation of geometry center. + * \param theGrid - vtkUnstructuredGrid cell. + * \param theptIds - point ids. + * \retval center - output array[3] with coordinates of geometry center. + */ +static void GetCenter(vtkUnstructuredGrid* theGrid,TCell theptIds,float center[3]) +{ + float p[3]; + center[0] = center[1] = center[2] = 0.0; + + int numIds = theptIds.size(); + if (numIds == 0) return; + + // get the center of the cell + for (int i = 0; i < numIds; i++) + { + theGrid->GetPoint(theptIds[i], p); + for (int j = 0; j < 3; j++) + { + center[j] += p[j]; + } + } + for (int j = 0; j < 3; j++) + { + center[j] /= numIds; + } +} + +/*! \fn static void ReverseIds(TCell &theIds) + * \brief Reverse ids. + * \param theIds - points ids. + * \retval theIds - example input:(1,2,3,4) -> output:(4,3,2,1) + */ +static void ReverseIds(TCell &theIds) +{ + int i; + vtkIdType tmp; + vtkIdType npts=theIds.size(); + + for(i=0;i<(npts/2);i++){ + tmp = theIds[i]; + theIds[i] = theIds[npts-i-1]; + theIds[npts-i-1] = tmp; + } +} + +/*! \fn void GetFriends(const TPTOIDS p2faces,const TCellArray f2points,TPTOIDS& face2face_output) + * \brief Caclulation of connected faces (faceId -> (faceId1,faceId2, ...)) + * \param p2faces - point to faces ids map. + * \param f2points - faces to points ids map. + * \retval face2face_output - faces to faces ids map. + */ +void GetFriends(const TPTOIDS p2faces,const TCellArray f2points,TPTOIDS& face2face_output) +{ + TCellArray::const_iterator f2pIter = f2points.begin(); + + for( ; f2pIter!=f2points.end() ; f2pIter++ ){ + vtkIdType faceId = f2pIter->first; + TCell face_points = f2pIter->second; + int nb_face_points = face_points.size(); + + vtkIdType id1; + vtkIdType id2; + TPTOIDS::const_iterator faces1; + TPTOIDS::const_iterator faces2; + + id1 = face_points[0]; + faces1 = p2faces.find(id1); + + TUIDS output_faces; + + for(int i=1 ; isecond.begin(), faces1->second.end(), faces2->second.begin(), faces2->second.end(), + std::inserter(output_faces,output_faces.begin())); + + id1 = id2; + faces1 = faces2; + } + id1 = face_points[0]; + faces1 = p2faces.find(id1); + std::set_intersection(faces1->second.begin(), faces1->second.end(), faces2->second.begin(), faces2->second.end(), + std::inserter(output_faces,output_faces.begin())); + + output_faces.erase(faceId); // erase the face id for which we found friends + + if(MYDEBUG){ + cout << "fId[" << faceId <<"]: "; + std::copy(output_faces.begin(), output_faces.end(), std::ostream_iterator(cout, " ")); + cout << endl; + } + + face2face_output[faceId] = output_faces; + } +} + +/*! \fn bool IsConnectedFacesOnOnePlane( vtkUnstructuredGrid* theGrid,vtkIdType theFId1, vtkIdType theFId2,TUIDS FpIds1, TUIDS FpIds2 ) + * \brief Check is connected faces on one plane. + * \param theGrid - vtkUnstructuredGrid + * \param theFId1 - id of first face + * \param theFId2 - id of second face + * \param FpIds1 - first face points ids. + * \param FpIds2 - second face points ids. + * \return TRUE if two faces on one plane, else FALSE. + */ +bool IsConnectedFacesOnOnePlane( vtkUnstructuredGrid* theGrid, + vtkIdType theFId1, vtkIdType theFId2, + TUIDS FpIds1, TUIDS FpIds2 ) +{ + bool status = false; + TUIDS common_ids; + std::set_intersection(FpIds1.begin(), FpIds1.end(), FpIds2.begin(), FpIds2.end(), + std::inserter(common_ids,common_ids.begin())); + + /* Number of common ids = 2 (A1,A2) + + + _ _ _ _ _ _ _ _ _ vectors: + | \ / | v1 {A2,A1} + \ / v2 {A1,B1} + | | A2 | v3 {A1,C1} + | + | | | + | + | | A1 | + / \ + |_ _ _ _ _/ \_ _ _ _ _| + B2 B1 C1 C2 + + */ + TUIDS::iterator common_iter = common_ids.begin(); + if(common_ids.size() == 2){ + TUIDS::iterator loc_id1_0 = FpIds1.find(*(common_iter)); + common_iter++; + TUIDS::iterator loc_id1_1 = FpIds1.find(*(common_iter)); + + TUIDS::iterator loc_id2_0 = FpIds1.begin(); + TUIDS::iterator loc_id2_1 = FpIds2.begin(); + + vtkIdType A1 = *loc_id1_0; + vtkIdType A2 = *loc_id1_1; + vtkIdType B1; + vtkIdType C1; + + for(;loc_id2_0!=FpIds1.end();loc_id2_0++) + if(*loc_id2_0 != A1 && *loc_id2_0!= A2){ + B1 = *loc_id2_0; + break; + } + for(;loc_id2_1!=FpIds2.end();loc_id2_1++) + if(*loc_id2_1 != A1 && *loc_id2_1!= A2){ + C1 = *loc_id2_1; + break; + } + if(MYDEBUG) cout <"; + float *p[4]; + float v1[3],v2[3],v3[3]; + p[0] = theGrid->GetPoint(A1); + p[1] = theGrid->GetPoint(A2); + p[2] = theGrid->GetPoint(B1); + p[3] = theGrid->GetPoint(C1); + + for(int i=0;i<3;i++){ + v1[i] = p[1][i] - p[0][i]; + v2[i] = p[2][i] - p[0][i]; + v3[i] = p[3][i] - p[0][i]; + } + + + float vec_b1[3]; + vtkMath::Cross(v2,v1,vec_b1); + float vec_b2[3]; + vtkMath::Cross(v1,v3,vec_b2); + + float b1 = vtkMath::Norm(vec_b1); + + float b2 = vtkMath::Norm(vec_b2); + float aCos = vtkMath::Dot(vec_b1,vec_b2)/(b1*b2); + + float angle=90.0; + angle = aCos>=1.0 ? 0.0 : 180*acosf(aCos)/vtkMath::Pi(); + + if( angle <= FACE_ANGLE_TOLERANCE) + status = true; + if (MYDEBUG){ + for(int k=0;k<4;k++){ + cout << " ("; + for(int j=0;j<2;j++){ + cout << p[k][j] << ","; + } + cout << p[k][2] << ") "; + } + cout << "angle="<second).begin(); + for(;aIter2!=(aIter1->second).end();aIter2++){ + if (new_faces.find(*aIter2) != new_faces.end()) continue; + GetAllFacesOnOnePlane(theFaces,*aIter2, + new_faces,new_faces_v2); // recurvise + } + } + return; +} + +/*! \fn void GetSumm(TCell v1,TCell v2,TCell &output) + * \brief Gluing two faces (gluing points ids) + * \param v1 - first face + * \param v2 - second face + * \param output - output face. + */ +void GetSumm(TCell v1,TCell v2,TCell &output) +{ + output.clear(); + + if(MYDEBUG) cout << "========================================="<(cout, " ")); + if(MYDEBUG) cout << "\tv2:"; + if(MYDEBUG) std::copy(v2.begin(), v2.end(), std::ostream_iterator(cout, " ")); + if(MYDEBUG) cout << endl; + + TUIDS v1_set; + std::copy(v1.begin(), v1.end(), std::inserter(v1_set,v1_set.begin())); + TUIDS v2_set; + std::copy(v2.begin(), v2.end(), std::inserter(v2_set,v2_set.begin())); + TUIDS tmpIntersection; + std::set_intersection(v1_set.begin(),v1_set.end(),v2_set.begin(),v2_set.end(), std::inserter(tmpIntersection,tmpIntersection.begin())); + if(MYDEBUG) std::copy(tmpIntersection.begin(),tmpIntersection.end(), std::ostream_iterator(cout, " ")); + if(MYDEBUG) cout << endl; + + if(tmpIntersection.size() < 2) + if(MYDEBUG) cout << __FILE__ << "[" << __LINE__ << "]: Warning ! Wrong ids" << endl; + + TCell::iterator v1_iter = v1.begin(); + + for(;v1_iter!=v1.end();v1_iter++){ + + vtkIdType curr_id = *v1_iter; + + output.push_back(curr_id); + + if(tmpIntersection.find(curr_id) != tmpIntersection.end()){ + TCell::iterator v1_iter_tmp; + v1_iter_tmp = v1_iter; + v1_iter++; + + if(v1_iter==v1.end()) v1_iter=v1.begin(); + + curr_id = *v1_iter; + + if(tmpIntersection.find(curr_id) != tmpIntersection.end()){ + TCell::iterator v2_iter = v2.begin(); + for(;v2_iter!=v2.end();v2_iter++){ + vtkIdType v2_id = *v2_iter; + if(tmpIntersection.find(v2_id) == tmpIntersection.end()) + output.push_back(v2_id); + } + } + + v1_iter = v1_iter_tmp; + curr_id = *v1_iter; + + } + } + + if(MYDEBUG) cout << "Result: " ; + if(MYDEBUG) std::copy(output.begin(),output.end(),std::ostream_iterator(cout, " ")); + if(MYDEBUG) cout << endl; +} + +void GetPolygonalFaces(vtkUnstructuredGrid* theGrid,int cellId,TCellArray &outputCellArray) +{ + if (theGrid->GetCellType(cellId) == VTK_CONVEX_POINT_SET){ + // get vtkCell type = VTK_CONVEX_POINT_SET + if(vtkConvexPointSet* convex = static_cast(theGrid->GetCell(cellId))){ + TCellArray f2points; + float convex_center[3]; // convex center point coorinat + int aNbFaces = convex->GetNumberOfFaces(); + int numPts = convex->GetNumberOfPoints(); + TCell convex_ids; + TPTOIDS p2faces; // key=pointId , value facesIds set + + for(int i=0;iGetPointId(i)); + + GetCenter(theGrid,convex_ids,convex_center); + + for (vtkIdType faceId=0; faceId < aNbFaces; faceId++){ + vtkCell *aFace = convex->GetFace(faceId); + int numFacePts = aFace->GetNumberOfPoints(); + TCell aIds; + + int i = 0; + for(i=0;iGetPointId(i)); + + float v_a[3],v_b[3],v_convex2face[3]; // vectors + float *id_0,*id_1,*id_n; + /*============================================= + ,+- - - - _ + _ / id_n | v_b {id_0,id_n} + v_b / _ + / | v_a {id_0,id_1} + / + / | + + id_0 + \ + _ \ | + v_a \ + \ id_1 | + "+- - - - + + ============================================*/ + id_0 = theGrid->GetPoint(aIds[0]); + id_1 = theGrid->GetPoint(aIds[1]); + id_n = theGrid->GetPoint(aIds[numFacePts-1]); + + for(i=0;i<3;i++){ + v_a[i] = id_1[i] - id_0[i]; + v_b[i] = id_n[i] - id_0[i]; + v_convex2face[i] = id_0[i] - convex_center[i]; + } + + if (vtkMath::Determinant3x3(v_a,v_b,v_convex2face) < 0){ + ReverseIds(aIds); + } + + for(i=0;i<(int)aIds.size();i++){ + TUIDS &acell = p2faces[aIds[i]]; + acell.insert(faceId); + } + + f2points[faceId] = aIds; + + } + + TPTOIDS face2face; + GetFriends(p2faces,f2points,face2face); + + TPTOIDS face2points; + + // copy TCellArray::f2points to TPTOIDS::face2points + for(TCellArray::iterator f2points_iter=f2points.begin(); + f2points_iter!=f2points.end(); + f2points_iter++){ + + TUIDS tmp; + for(TCell::iterator points_iter=(f2points_iter->second).begin(); + points_iter!=(f2points_iter->second).end(); + points_iter++) + tmp.insert(*points_iter); + + face2points[f2points_iter->first] = tmp; + } // end copy + + + TPTOIDS new_face2faces; // which connected and in one plane + + TPTOIDS::const_iterator aF2FIter = face2face.begin(); + for(;aF2FIter!=face2face.end();aF2FIter++){ + vtkIdType f_key = aF2FIter->first; + TUIDS &faces = new_face2faces[f_key]; + //faces.insert(f_key); + TUIDS f_friends = aF2FIter->second; + TUIDS::const_iterator a_friends_iter = f_friends.begin(); + for(;a_friends_iter!=f_friends.end();a_friends_iter++){ + vtkIdType friend_id = *a_friends_iter; + if( IsConnectedFacesOnOnePlane(theGrid,f_key,friend_id, + (face2points.find(f_key))->second, + (face2points.find(friend_id))->second)){ + faces.insert(friend_id); + } // end if + + } // end a_friends_iter + } // end aF2FIter + + if(MYDEBUG) + { + TPTOIDS::const_iterator new_face2face_iter = new_face2faces.begin(); + cout << "Connected faces and on plane:" << endl; + for(;new_face2face_iter!=new_face2faces.end();new_face2face_iter++){ + cout << "Group ["<first<<"] :"; + TUIDS::const_iterator new_faces_iter = (new_face2face_iter->second).begin(); + for(;new_faces_iter!=(new_face2face_iter->second).end();new_faces_iter++) + cout << " " << *new_faces_iter ; + cout << endl; + } + } + + TPTOIDS output_newid2face; + TCellArray output_newid2face_v2; + { + TUIDS already_in; + TUIDS already_in_tmp; + int k=0; + TPTOIDS::const_iterator new_face2face_iter = new_face2faces.begin(); + for(;new_face2face_iter!=new_face2faces.end();new_face2face_iter++){ + if(already_in.find(new_face2face_iter->first) != already_in.end()) + continue; + if(new_face2face_iter->second.size() > 1) + continue; + + TCell &tmp_v2 = output_newid2face_v2[k]; + tmp_v2.push_back(new_face2face_iter->first); + already_in.insert(new_face2face_iter->first); + + TUIDS::const_iterator new_faces_iter = (new_face2face_iter->second).begin(); + for(;new_faces_iter!=(new_face2face_iter->second).end();new_faces_iter++){ + if(already_in.find(*new_faces_iter) != already_in.end()) continue; + already_in.insert(*new_faces_iter); + + already_in_tmp.clear(); + already_in_tmp.insert(new_face2face_iter->first); + + TUIDS &tmp = output_newid2face[k]; + GetAllFacesOnOnePlane(new_face2faces,*new_faces_iter, + already_in_tmp,tmp_v2); + + for(TUIDS::const_iterator aIter=already_in_tmp.begin(); + aIter!=already_in_tmp.end(); + aIter++) + { + already_in.insert(*aIter); + tmp.insert(*aIter); + } + } + k++; + } + } + + if(MYDEBUG) { + cout << "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"<first<<"] :"; + TUIDS::const_iterator new_faces_iter = (new_face2face_iter->second).begin(); + for(;new_faces_iter!=(new_face2face_iter->second).end();new_faces_iter++) + cout << " " << *new_faces_iter ; + cout << endl; + } + } + cout << "++++++++++++++++++++++++++ +++++++++++++++++++++++++++++++"<first<<"] :"; + TCell::const_iterator new_faces_iter = (new_face2face_iter->second).begin(); + for(;new_faces_iter!=(new_face2face_iter->second).end();new_faces_iter++) + cout << " " << *new_faces_iter ; + cout << endl; + } + } + } + TCellArray output_new_face2ids; +// { +// TPTOIDS::const_iterator new_face2face_iter = output_newid2face.begin(); +// for(;new_face2face_iter!=output_newid2face.end();new_face2face_iter++){ + +// vtkIdType new_faceId = new_face2face_iter->first; +// TUIDS::const_iterator new_faces_iter = (new_face2face_iter->second).begin(); +// vtkIdType fId0 = *new_faces_iter; +// TCellArray::const_iterator pIds0_iter = f2points.find(fId0); +// TCell pIds0 = pIds0_iter->second; +// TCell &output = output_new_face2ids[new_faceId]; +// new_faces_iter++; +// if(new_face2face_iter->second.size() > 2 ){} +// for(;new_faces_iter!=(new_face2face_iter->second).end();new_faces_iter++){ + +// vtkIdType faceId = *new_faces_iter; +// // find how much nodes in face (f2points) +// TCellArray::const_iterator pIds_iter = f2points.find(faceId); +// TCell pIds = pIds_iter->second; + +// GetSumm(pIds0,pIds,output); +// pIds0 = output; + +// } // end new_faces_iter + +// } // new_face2face_iter +// } + + { + TCellArray::const_iterator new_face2face_iter = output_newid2face_v2.begin(); + for(;new_face2face_iter!=output_newid2face_v2.end();new_face2face_iter++){ + + vtkIdType new_faceId = new_face2face_iter->first; + TCell::const_iterator new_faces_iter = (new_face2face_iter->second).begin(); + vtkIdType fId0 = *new_faces_iter; + TCellArray::const_iterator pIds0_iter = f2points.find(fId0); + TCell pIds0 = pIds0_iter->second; + TCell &output = output_new_face2ids[new_faceId]; + new_faces_iter++; + if(new_face2face_iter->second.size() == 1 ){ + TCellArray::const_iterator pIds_iter = f2points.find(fId0); + TCell pIds = pIds_iter->second; + output = pIds; + continue; + } + for(;new_faces_iter!=(new_face2face_iter->second).end();new_faces_iter++){ + + vtkIdType faceId = *new_faces_iter; + // find how much nodes in face (f2points) + TCellArray::const_iterator pIds_iter = f2points.find(faceId); + TCell pIds = pIds_iter->second; + + GetSumm(pIds0,pIds,output); + pIds0 = output; + + } // end new_faces_iter + + } // new_face2face_iter + } + + if(MYDEBUG) { + cout << "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"< +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +//VRV: porting on Qt 3.0.5 +#if QT_VERSION >= 0x030005 +#include +#endif +//VRV: porting on Qt 3.0.5 +#include + +//#include "utilities.h" + +using namespace std; + + +/* +static int GetEdgeId(vtkPicker *thePicker, SALOME_Actor *theActor, int theObjId){ + int anEdgeId = -1; + if (vtkCell* aPickedCell = theActor->GetElemCell(theObjId)) { + float aPickPosition[3]; + thePicker->GetPickPosition(aPickPosition); + float aMinDist = 1000000.0, aDist = 0; + for (int i = 0, iEnd = aPickedCell->GetNumberOfEdges(); i < iEnd; i++){ + if(vtkLine* aLine = vtkLine::SafeDownCast(aPickedCell->GetEdge(i))){ + int subId; float pcoords[3], closestPoint[3], weights[3]; + aLine->EvaluatePosition(aPickPosition,closestPoint,subId,pcoords,aDist,weights); + if (aDist < aMinDist) { + aMinDist = aDist; + anEdgeId = i; + } + } + } + } + return anEdgeId; +} +*/ +//---------------------------------------------------------------------------- +vtkStandardNewMacro(VTKViewer_InteractorStyle); + +//---------------------------------------------------------------------------- +/*!Constructor.*/ +VTKViewer_InteractorStyle::VTKViewer_InteractorStyle() +{ + m_Trihedron = 0; + this->MotionFactor = 10.0; + this->State = VTK_INTERACTOR_STYLE_CAMERA_NONE; + this->RadianToDegree = 180.0 / vtkMath::Pi(); + this->ForcedState = VTK_INTERACTOR_STYLE_CAMERA_NONE; + loadCursors(); + + myPreSelectionActor = VTKViewer_Actor::New(); + myPreSelectionActor->GetProperty()->SetColor(0,1,1); + myPreSelectionActor->GetProperty()->SetLineWidth(5); + myPreSelectionActor->GetProperty()->SetPointSize(5); + + OnSelectionModeChanged(); +} + +//---------------------------------------------------------------------------- +/*!Destructor.*/ +VTKViewer_InteractorStyle::~VTKViewer_InteractorStyle() +{ + m_ViewWnd->RemoveActor(myPreSelectionActor); +} + +//---------------------------------------------------------------------------- +/*!Set preselection properties. + *\param theRed - red color. + *\param theGreen - green color. + *\param theBlue - blue color. + *\param theWidth - width.. + */ +void VTKViewer_InteractorStyle::setPreselectionProp(const double& theRed, const double& theGreen, + const double& theBlue, const int& theWidth) +{ + if ( myPreSelectionActor->GetProperty() == 0 ) + return; + myPreSelectionActor->GetProperty()->SetColor(theRed, theGreen, theBlue); + myPreSelectionActor->GetProperty()->SetLineWidth(theWidth); + myPreSelectionActor->GetProperty()->SetPointSize(theWidth); +} + +//---------------------------------------------------------------------------- +/*!Set render window interactor + *\param theInteractor - interactor. + */ +void VTKViewer_InteractorStyle::SetInteractor(vtkRenderWindowInteractor *theInteractor){ + m_Interactor = dynamic_cast(theInteractor); + Superclass::SetInteractor(theInteractor); +} + +//---------------------------------------------------------------------------- +/*!Set view window. + *\param theViewWnd - SALOME VTKViewer_ViewWindow + */ +void VTKViewer_InteractorStyle::setViewWnd(VTKViewer_ViewWindow* theViewWnd ){ + m_ViewWnd = theViewWnd; + m_ViewWnd->AddActor(myPreSelectionActor); + myPreSelectionActor->Delete(); +} + +//---------------------------------------------------------------------------- +/*!Set GUI window. + *\param theWindow - QWidget window. + */ +void VTKViewer_InteractorStyle::setGUIWindow(QWidget* theWindow){ + myGUIWindow = theWindow; +} + +//---------------------------------------------------------------------------- +/*!Set triedron. + *\param theTrihedron - SALOME VTKViewer_Trihedron + */ +void VTKViewer_InteractorStyle::setTriedron(VTKViewer_Trihedron* theTrihedron){ + m_Trihedron = theTrihedron; +} + +//---------------------------------------------------------------------------- +/*!Rotate camera. + *\param dx - + *\param dy - + */ +void VTKViewer_InteractorStyle::RotateXY(int dx, int dy) +{ + double rxf; + double ryf; + vtkCamera *cam; + + if (this->CurrentRenderer == NULL) + { + return; + } + + int *size = this->CurrentRenderer->GetRenderWindow()->GetSize(); + this->DeltaElevation = -20.0 / size[1]; + this->DeltaAzimuth = -20.0 / size[0]; + + rxf = (double)dx * this->DeltaAzimuth * this->MotionFactor; + ryf = (double)dy * this->DeltaElevation * this->MotionFactor; + + cam = this->CurrentRenderer->GetActiveCamera(); + cam->Azimuth(rxf); + cam->Elevation(ryf); + cam->OrthogonalizeViewUp(); + ::ResetCameraClippingRange(this->CurrentRenderer); + //this->Interactor->Render(); + myGUIWindow->update(); +} + +//---------------------------------------------------------------------------- +void VTKViewer_InteractorStyle::PanXY(int x, int y, int oldX, int oldY) +{ + TranslateView(x, y, oldX, oldY); + //this->Interactor->Render(); + myGUIWindow->update(); +} + + +//---------------------------------------------------------------------------- +/*! Move the position of the camera along the direction of projection. (dx,dy)*/ +void VTKViewer_InteractorStyle::DollyXY(int dx, int dy) +{ + if (this->CurrentRenderer == NULL) return; + + double dxf = this->MotionFactor * (double)(dx) / (double)(this->CurrentRenderer->GetCenter()[1]); + double dyf = this->MotionFactor * (double)(dy) / (double)(this->CurrentRenderer->GetCenter()[1]); + + double zoomFactor = pow((double)1.1, dxf + dyf); + + vtkCamera *aCam = this->CurrentRenderer->GetActiveCamera(); + if (aCam->GetParallelProjection()) + aCam->SetParallelScale(aCam->GetParallelScale()/zoomFactor); + else{ + aCam->Dolly(zoomFactor); + ::ResetCameraClippingRange(this->CurrentRenderer); + } + + //this->Interactor->Render(); + myGUIWindow->update(); +} + +//---------------------------------------------------------------------------- +/*!*/ +void VTKViewer_InteractorStyle::SpinXY(int x, int y, int oldX, int oldY) +{ + vtkCamera *cam; + + if (this->CurrentRenderer == NULL) + { + return; + } + + double newAngle = atan2((double)(y - this->CurrentRenderer->GetCenter()[1]), + (double)(x - this->CurrentRenderer->GetCenter()[0])); + double oldAngle = atan2((double)(oldY -this->CurrentRenderer->GetCenter()[1]), + (double)(oldX - this->CurrentRenderer->GetCenter()[0])); + + newAngle *= this->RadianToDegree; + oldAngle *= this->RadianToDegree; + + cam = this->CurrentRenderer->GetActiveCamera(); + cam->Roll(newAngle - oldAngle); + cam->OrthogonalizeViewUp(); + + //this->Interactor->Render(); + myGUIWindow->update(); +} + + +//---------------------------------------------------------------------------- +/*!On mouse move event. + *\param ctrl - CTRL (not used) + *\param shift - SHIFT (on/off - integer 0/1) + *\param x - x coordinate + *\param y - y coordinate + */ +void VTKViewer_InteractorStyle::OnMouseMove(int vtkNotUsed(ctrl), + int shift, + int x, int y) +{ + myShiftState = shift; + if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) + onOperation(QPoint(x, y)); + else if (ForcedState == VTK_INTERACTOR_STYLE_CAMERA_NONE) + onCursorMove(QPoint(x, y)); +} + + +//---------------------------------------------------------------------------- +/*!On Left button down event. + *\param ctrl - CTRL (on/off - integer 0/1) + *\param shift - SHIFT (on/off - integer 0/1) + *\param x - x coordinate + *\param y - y coordinate + */ +void VTKViewer_InteractorStyle::OnLeftButtonDown(int ctrl, int shift, + int x, int y) +{ + if (this->HasObserver(vtkCommand::LeftButtonPressEvent)) { + this->InvokeEvent(vtkCommand::LeftButtonPressEvent,NULL); + return; + } + this->FindPokedRenderer(x, y); + if (this->CurrentRenderer == NULL) { + return; + } + myShiftState = shift; + // finishing current viewer operation + if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) { + onFinishOperation(); + startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE); + } + myOtherPoint = myPoint = QPoint(x, y); + if (ForcedState != VTK_INTERACTOR_STYLE_CAMERA_NONE) { + startOperation(ForcedState); + } else { + if (ctrl) + startOperation(VTK_INTERACTOR_STYLE_CAMERA_ZOOM); + else + startOperation(VTK_INTERACTOR_STYLE_CAMERA_SELECT); + } + return; +} + + +//---------------------------------------------------------------------------- +/*!On left button up event. + *\param ctrl - CTRL (not used) + *\param shift - SHIFT (on/off - integer 0/1) + *\param x - x coordinate (not used) + *\param y - y coordinate (not used) + */ +void VTKViewer_InteractorStyle::OnLeftButtonUp(int vtkNotUsed(ctrl), + int shift, + int vtkNotUsed(x), + int vtkNotUsed(y)) +{ + myShiftState = shift; + // finishing current viewer operation + if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) { + onFinishOperation(); + startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE); + } +} + + +//---------------------------------------------------------------------------- +/*!On left button up event. + *\param ctrl - CTRL (on/off - integer 0/1) + *\param shift - SHIFT (on/off - integer 0/1) + *\param x - x coordinate + *\param y - y coordinate + */ +void VTKViewer_InteractorStyle::OnMiddleButtonDown(int ctrl, + int shift, + int x, int y) +{ + if (this->HasObserver(vtkCommand::MiddleButtonPressEvent)) + { + this->InvokeEvent(vtkCommand::MiddleButtonPressEvent,NULL); + return; + } + this->FindPokedRenderer(x, y); + if (this->CurrentRenderer == NULL) + { + return; + } + myShiftState = shift; + // finishing current viewer operation + if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) { + onFinishOperation(); + startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE); + } + myOtherPoint = myPoint = QPoint(x, y); + if (ForcedState != VTK_INTERACTOR_STYLE_CAMERA_NONE) { + startOperation(ForcedState); + } + else { + if (ctrl) + startOperation(VTK_INTERACTOR_STYLE_CAMERA_PAN); + } +} + + +//---------------------------------------------------------------------------- +/*!On middle button up event. + *\param ctrl - CTRL (not used) + *\param shift - SHIFT (on/off - integer 0/1) + *\param x - x coordinate (not used) + *\param y - y coordinate (not used) + */ +void VTKViewer_InteractorStyle::OnMiddleButtonUp(int vtkNotUsed(ctrl), + int shift, + int vtkNotUsed(x), + int vtkNotUsed(y)) +{ + myShiftState = shift; + // finishing current viewer operation + if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) { + onFinishOperation(); + startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE); + } +} + + +//---------------------------------------------------------------------------- +/*!On right button down event. + *\param ctrl - CTRL (on/off - integer 0/1) + *\param shift - SHIFT (on/off - integer 0/1) + *\param x - x coordinate + *\param y - y coordinate + */ +void VTKViewer_InteractorStyle::OnRightButtonDown(int ctrl, + int shift, + int x, int y) +{ + if (this->HasObserver(vtkCommand::RightButtonPressEvent)) + { + this->InvokeEvent(vtkCommand::RightButtonPressEvent,NULL); + return; + } + this->FindPokedRenderer(x, y); + if (this->CurrentRenderer == NULL) + { + return; + } + myShiftState = shift; + // finishing current viewer operation + if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) { + onFinishOperation(); + startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE); + } + myOtherPoint = myPoint = QPoint(x, y); + if (ForcedState != VTK_INTERACTOR_STYLE_CAMERA_NONE) { + startOperation(ForcedState); + } + else { + if (ctrl) + startOperation(VTK_INTERACTOR_STYLE_CAMERA_ROTATE); + } +} + +//---------------------------------------------------------------------------- +/*!On right button up event. + *\param ctrl - CTRL (not used) + *\param shift - SHIFT (on/off - integer 0/1) + *\param x - x coordinate (not used) + *\param y - y coordinate (not used) + */ +void VTKViewer_InteractorStyle::OnRightButtonUp(int vtkNotUsed(ctrl), + int shift, + int vtkNotUsed(x), + int vtkNotUsed(y)) +{ + myShiftState = shift; + // finishing current viewer operation + if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) { + onFinishOperation(); + startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE); + } +} + +//---------------------------------------------------------------------------- +/** @name XPM - x pixmaps. */ +//@{ +/*!Image Zoom cursor*/ +const char* imageZoomCursor[] = { +"32 32 3 1", +". c None", +"a c #000000", +"# c #ffffff", +"................................", +"................................", +".#######........................", +"..aaaaaaa.......................", +"................................", +".............#####..............", +"...........##.aaaa##............", +"..........#.aa.....a#...........", +".........#.a.........#..........", +".........#a..........#a.........", +"........#.a...........#.........", +"........#a............#a........", +"........#a............#a........", +"........#a............#a........", +"........#a............#a........", +".........#...........#.a........", +".........#a..........#a.........", +".........##.........#.a.........", +"........#####.....##.a..........", +".......###aaa#####.aa...........", +"......###aa...aaaaa.......#.....", +".....###aa................#a....", +"....###aa.................#a....", +"...###aa...............#######..", +"....#aa.................aa#aaaa.", +".....a....................#a....", +"..........................#a....", +"...........................a....", +"................................", +"................................", +"................................", +"................................"}; + +/*!Image rotate cursor*/ +const char* imageRotateCursor[] = { +"32 32 3 1", +". c None", +"a c #000000", +"# c #ffffff", +"................................", +"................................", +"................................", +"................................", +"........#.......................", +".......#.a......................", +"......#######...................", +".......#aaaaa#####..............", +"........#..##.a#aa##........##..", +".........a#.aa..#..a#.....##.aa.", +".........#.a.....#...#..##.aa...", +".........#a.......#..###.aa.....", +"........#.a.......#a..#aa.......", +"........#a.........#..#a........", +"........#a.........#a.#a........", +"........#a.........#a.#a........", +"........#a.........#a.#a........", +".........#.........#a#.a........", +"........##a........#a#a.........", +"......##.a#.......#.#.a.........", +"....##.aa..##.....##.a..........", +"..##.aa.....a#####.aa...........", +"...aa.........aaa#a.............", +"................#.a.............", +"...............#.a..............", +"..............#.a...............", +"...............a................", +"................................", +"................................", +"................................", +"................................", +"................................"}; +//@} + +//---------------------------------------------------------------------------- +/*! Loads cursors for viewer operations - zoom, pan, etc...*/ +void VTKViewer_InteractorStyle::loadCursors() +{ + myDefCursor = QCursor(ArrowCursor); + myHandCursor = QCursor(PointingHandCursor); + myPanCursor = QCursor(SizeAllCursor); + myZoomCursor = QCursor(QPixmap(imageZoomCursor)); + myRotateCursor = QCursor(QPixmap(imageRotateCursor)); + mySpinCursor = QCursor(QPixmap(imageRotateCursor)); // temporarly !!!!!! + myGlobalPanCursor = QCursor(CrossCursor); + myCursorState = false; +} + + +//---------------------------------------------------------------------------- +/*! event filter - controls mouse and keyboard events during viewer operations*/ +bool VTKViewer_InteractorStyle::eventFilter(QObject* object, QEvent* event) +{ + if (!myGUIWindow) return false; + if ( (event->type() == QEvent::MouseButtonPress || event->type() == QEvent::KeyPress) && object != myGUIWindow) + { + qApp->removeEventFilter(this); + startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE); + } + return QObject::eventFilter(object, event); +} + + +//---------------------------------------------------------------------------- +/*! starts Zoom operation (e.g. through menu command)*/ +void VTKViewer_InteractorStyle::startZoom() +{ + if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) + { + onFinishOperation(); + startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE); + } + setCursor(VTK_INTERACTOR_STYLE_CAMERA_ZOOM); + ForcedState = VTK_INTERACTOR_STYLE_CAMERA_ZOOM; + qApp->installEventFilter(this); +} + + +//---------------------------------------------------------------------------- +/*! starts Pan operation (e.g. through menu command)*/ +void VTKViewer_InteractorStyle::startPan() +{ + if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) + { + onFinishOperation(); + startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE); + } + setCursor(VTK_INTERACTOR_STYLE_CAMERA_PAN); + ForcedState = VTK_INTERACTOR_STYLE_CAMERA_PAN; + qApp->installEventFilter(this); +} + +//---------------------------------------------------------------------------- +/*! starts Rotate operation (e.g. through menu command)*/ +void VTKViewer_InteractorStyle::startRotate() +{ + if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) + { + onFinishOperation(); + startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE); + } + setCursor(VTK_INTERACTOR_STYLE_CAMERA_ROTATE); + ForcedState = VTK_INTERACTOR_STYLE_CAMERA_ROTATE; + qApp->installEventFilter(this); +} + + +//---------------------------------------------------------------------------- +/*! starts Spin operation (e.g. through menu command)*/ +void VTKViewer_InteractorStyle::startSpin() +{ + if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) + { + onFinishOperation(); + startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE); + } + setCursor(VTK_INTERACTOR_STYLE_CAMERA_SPIN); + ForcedState = VTK_INTERACTOR_STYLE_CAMERA_SPIN; + qApp->installEventFilter(this); +} + + + +//---------------------------------------------------------------------------- +/*! starts Fit Area operation (e.g. through menu command)*/ +void VTKViewer_InteractorStyle::startFitArea() +{ + if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) + { + onFinishOperation(); + startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE); + } + setCursor(VTK_INTERACTOR_STYLE_CAMERA_FIT); + ForcedState = VTK_INTERACTOR_STYLE_CAMERA_FIT; + qApp->installEventFilter(this); +} + + +//---------------------------------------------------------------------------- +/*!View fit all.*/ +void VTKViewer_InteractorStyle::ViewFitAll() { + int aTriedronWasVisible = false; + if(m_Trihedron){ + aTriedronWasVisible = m_Trihedron->GetVisibility() == VTKViewer_Trihedron::eOn; + if(aTriedronWasVisible) m_Trihedron->VisibilityOff(); + } + + if(m_Trihedron->GetVisibleActorCount(CurrentRenderer)){ + m_Trihedron->VisibilityOff(); + ::ResetCamera(CurrentRenderer); + }else{ + m_Trihedron->SetVisibility(VTKViewer_Trihedron::eOnlyLineOn); + ::ResetCamera(CurrentRenderer,true); + } + if(aTriedronWasVisible) m_Trihedron->VisibilityOn(); + else m_Trihedron->VisibilityOff(); + ::ResetCameraClippingRange(CurrentRenderer); +} + + +//---------------------------------------------------------------------------- +/*! starts Global Panning operation (e.g. through menu command)*/ +void VTKViewer_InteractorStyle::startGlobalPan() +{ + if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) + { + onFinishOperation(); + startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE); + } + setCursor(VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN); + ForcedState = VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN; + + // store current zoom scale + vtkCamera *cam = this->CurrentRenderer->GetActiveCamera(); + myScale = cam->GetParallelScale(); + + ViewFitAll(); + + if (myGUIWindow) myGUIWindow->update(); + + qApp->installEventFilter(this); +} + + +//---------------------------------------------------------------------------- +/*!\retval TRUE if needs redrawing*/ +bool VTKViewer_InteractorStyle::needsRedrawing() +{ + return State == VTK_INTERACTOR_STYLE_CAMERA_ZOOM || + State == VTK_INTERACTOR_STYLE_CAMERA_PAN || + State == VTK_INTERACTOR_STYLE_CAMERA_ROTATE || + State == VTK_INTERACTOR_STYLE_CAMERA_SPIN || + State == VTK_INTERACTOR_STYLE_CAMERA_NONE; +} + + +//---------------------------------------------------------------------------- +/*! fits viewer contents to rectangle + *\param left - left side + *\param top - top side + *\param right - right side + *\param bottom - bottom side + */ +void VTKViewer_InteractorStyle::fitRect(const int left, + const int top, + const int right, + const int bottom) +{ + if (this->CurrentRenderer == NULL) return; + + // move camera + int x = (left + right)/2; + int y = (top + bottom)/2; + int *aSize = this->CurrentRenderer->GetRenderWindow()->GetSize(); + int oldX = aSize[0]/2; + int oldY = aSize[1]/2; + TranslateView(oldX, oldY, x, y); + + // zoom camera + double dxf = (double)(aSize[0]) / (double)(abs(right - left)); + double dyf = (double)(aSize[1]) / (double)(abs(bottom - top)); + double zoomFactor = (dxf + dyf)/2 ; + + vtkCamera *aCam = this->CurrentRenderer->GetActiveCamera(); + if(aCam->GetParallelProjection()) + aCam->SetParallelScale(aCam->GetParallelScale()/zoomFactor); + else{ + aCam->Dolly(zoomFactor); + ::ResetCameraClippingRange(this->CurrentRenderer); + } + + myGUIWindow->update(); +} + + +//---------------------------------------------------------------------------- +/*! starts viewer operation (!internal usage!)*/ +void VTKViewer_InteractorStyle::startOperation(int operation) +{ + switch(operation) + { + case VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN: + case VTK_INTERACTOR_STYLE_CAMERA_ZOOM: + case VTK_INTERACTOR_STYLE_CAMERA_PAN: + case VTK_INTERACTOR_STYLE_CAMERA_ROTATE: + case VTK_INTERACTOR_STYLE_CAMERA_SPIN: + case VTK_INTERACTOR_STYLE_CAMERA_FIT: + case VTK_INTERACTOR_STYLE_CAMERA_SELECT: + if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) + startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE); + State = operation; + if (State != VTK_INTERACTOR_STYLE_CAMERA_SELECT) + setCursor(operation); + onStartOperation(); + break; + case VTK_INTERACTOR_STYLE_CAMERA_NONE: + default: + setCursor(VTK_INTERACTOR_STYLE_CAMERA_NONE); + State = ForcedState = VTK_INTERACTOR_STYLE_CAMERA_NONE; + break; + } +} + + +//---------------------------------------------------------------------------- +/*! sets proper cursor for window when viewer operation is activated*/ +void VTKViewer_InteractorStyle::setCursor(const int operation) +{ + if (!myGUIWindow) return; + switch (operation) + { + case VTK_INTERACTOR_STYLE_CAMERA_ZOOM: + myGUIWindow->setCursor(myZoomCursor); + myCursorState = true; + break; + case VTK_INTERACTOR_STYLE_CAMERA_PAN: + myGUIWindow->setCursor(myPanCursor); + myCursorState = true; + break; + case VTK_INTERACTOR_STYLE_CAMERA_ROTATE: + myGUIWindow->setCursor(myRotateCursor); + myCursorState = true; + break; + case VTK_INTERACTOR_STYLE_CAMERA_SPIN: + myGUIWindow->setCursor(mySpinCursor); + myCursorState = true; + break; + case VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN: + myGUIWindow->setCursor(myGlobalPanCursor); + myCursorState = true; + break; + case VTK_INTERACTOR_STYLE_CAMERA_FIT: + case VTK_INTERACTOR_STYLE_CAMERA_SELECT: + myGUIWindow->setCursor(myHandCursor); + myCursorState = true; + break; + case VTK_INTERACTOR_STYLE_CAMERA_NONE: + default: + myGUIWindow->setCursor(myDefCursor); + myCursorState = false; + break; + } +} + + +//---------------------------------------------------------------------------- +/*! called when viewer operation started (!put necessary initialization here!)*/ +void VTKViewer_InteractorStyle::onStartOperation() +{ + if (!myGUIWindow) return; + // VSV: LOD actor activisation + // this->Interactor->GetRenderWindow()->SetDesiredUpdateRate(this->Interactor->GetDesiredUpdateRate()); + switch (State) { + case VTK_INTERACTOR_STYLE_CAMERA_SELECT: + case VTK_INTERACTOR_STYLE_CAMERA_FIT: + { + QPainter p(myGUIWindow); + p.setPen(Qt::lightGray); + p.setRasterOp(Qt::XorROP); + p.drawRect(QRect(myPoint, myOtherPoint)); + break; + } + case VTK_INTERACTOR_STYLE_CAMERA_ZOOM: + case VTK_INTERACTOR_STYLE_CAMERA_PAN: + case VTK_INTERACTOR_STYLE_CAMERA_ROTATE: + case VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN: + case VTK_INTERACTOR_STYLE_CAMERA_SPIN: + break; + } +} + + +//---------------------------------------------------------------------------- +/*! called when viewer operation finished (!put necessary post-processing here!)*/ +void VTKViewer_InteractorStyle::onFinishOperation() +{ + if (!myGUIWindow) return; + + +// SUIT_Study* aActiveStudy = SUIT_Application::getDesktop()->getActiveStudy(); +// SALOME_Selection* aSel = SALOME_Selection::Selection( aActiveStudy->getSelection() ); + + // VSV: LOD actor activisation + // rwi->GetRenderWindow()->SetDesiredUpdateRate(rwi->GetStillUpdateRate()); + +// Selection_Mode aSelectionMode = aSel->SelectionMode(); +// bool aSelActiveCompOnly = aSel->IsSelectActiveCompOnly(); + +/* switch (State) { + case VTK_INTERACTOR_STYLE_CAMERA_SELECT: + case VTK_INTERACTOR_STYLE_CAMERA_FIT: + { + QPainter p(myGUIWindow); + p.setPen(Qt::lightGray); + p.setRasterOp(Qt::XorROP); + QRect rect(myPoint, myOtherPoint); + p.drawRect(rect); + rect = rect.normalize(); + if (State == VTK_INTERACTOR_STYLE_CAMERA_FIT) { + // making fit rect opeation + int w, h; + m_Interactor->GetSize(w, h); + int x1, y1, x2, y2; + x1 = rect.left(); + y1 = h - rect.top() - 1; + x2 = rect.right(); + y2 = h - rect.bottom() - 1; + fitRect(x1, y1, x2, y2); + } + else { + if (myPoint == myOtherPoint) { + // process point selection + int w, h, x, y; + m_Interactor->GetSize(w, h); + x = myPoint.x(); + y = h - myPoint.y() - 1; + + this->FindPokedRenderer(x, y); + m_Interactor->StartPickCallback(); + + vtkPicker* aPicker = vtkPicker::SafeDownCast(m_Interactor->GetPicker()); + aPicker->Pick(x, y, 0.0, this->CurrentRenderer); + + SALOME_Actor* SActor = SALOME_Actor::SafeDownCast(aPicker->GetActor()); + + if (vtkCellPicker* picker = vtkCellPicker::SafeDownCast(aPicker)) { + int aVtkId = picker->GetCellId(); + if ( aVtkId >= 0 && SActor && SActor->hasIO() && IsValid( SActor, aVtkId ) ) { + int anObjId = SActor->GetElemObjId(aVtkId); + if(anObjId >= 0){ + Handle(SALOME_InteractiveObject) IO = SActor->getIO(); + if(aSelectionMode != EdgeOfCellSelection) { + if(CheckDimensionId(aSelectionMode,SActor,anObjId)){ + if (IsSelected(IO,aSel)) { + // This IO is already in the selection + aSel->AddOrRemoveIndex( IO, anObjId, myShiftState, false ); + } else { + if (!myShiftState) { + this->HighlightProp( NULL ); + aSel->ClearIObjects(); + } + aSel->AddOrRemoveIndex( IO, anObjId, myShiftState, false ); + aSel->AddIObject( IO, false ); + } + } + }else{ + if (!myShiftState) { + this->HighlightProp( NULL ); + aSel->ClearIObjects(); + } + int anEdgeId = GetEdgeId(picker,SActor,anObjId); + if (anEdgeId >= 0) { + aSel->AddOrRemoveIndex( IO, anObjId, true, false); + aSel->AddOrRemoveIndex( IO, -anEdgeId-1, true, true ); + aSel->AddIObject( IO, false ); + } + } + } + } else { + this->HighlightProp( NULL ); + aSel->ClearIObjects(); + } + } else if ( vtkPointPicker* picker = vtkPointPicker::SafeDownCast(aPicker) ) { + int aVtkId = picker->GetPointId(); + if ( aVtkId >= 0 && IsValid( SActor, aVtkId, true ) ) { + if ( SActor && SActor->hasIO() ) { + int anObjId = SActor->GetNodeObjId(aVtkId); + if(anObjId >= 0){ + Handle(SALOME_InteractiveObject) IO = SActor->getIO(); + if(IsSelected(IO,aSel)) { + // This IO is already in the selection + aSel->AddOrRemoveIndex( IO, anObjId, myShiftState, false ); + } else { + if(!myShiftState) { + this->HighlightProp( NULL ); + aSel->ClearIObjects(); + } + aSel->AddOrRemoveIndex( IO, anObjId, myShiftState, false ); + aSel->AddIObject( IO, false ); + } + } + } + } else { + this->HighlightProp( NULL ); + aSel->ClearIObjects(); + } + } else { + if ( SActor && SActor->hasIO() ) { + this->PropPicked++; + Handle(SALOME_InteractiveObject) IO = SActor->getIO(); + if(IsSelected(IO,aSel)) { + // This IO is already in the selection + if(myShiftState) { + aSel->RemoveIObject(IO); + } + } + else { + if(!myShiftState) { + this->HighlightProp( NULL ); + aSel->ClearIObjects(); + } + aSel->AddIObject( IO, false ); + } + }else{ + // No selection clear all + this->PropPicked = 0; + this->HighlightProp( NULL ); + aSel->ClearIObjects(); + } + } + m_Interactor->EndPickCallback(); + } else { + //processing rectangle selection + QString aComponentDataType = SUIT_Application::getDesktop()->getComponentDataType(); + if(aSelActiveCompOnly && aComponentDataType.isEmpty()) return; + m_Interactor->StartPickCallback(); + + if (!myShiftState) { + this->PropPicked = 0; + this->HighlightProp( NULL ); + aSel->ClearIObjects(); + } + + // Compute bounds + // vtkCamera *cam = this->CurrentRenderer->GetActiveCamera(); + QRect rect(myPoint, myOtherPoint); + rect = rect.normalize(); + int w, h; + m_Interactor->GetSize(w, h); + int x1, y1, x2, y2; + x1 = rect.left(); + y1 = h - rect.top() - 1; + x2 = rect.right(); + y2 = h - rect.bottom() - 1; + + switch (aSelectionMode) { + case NodeSelection: { + if ( vtkPointPicker* aPointPicker = vtkPointPicker::SafeDownCast(m_Interactor->GetPicker()) ) { + vtkActorCollection* aListActors = this->CurrentRenderer->GetActors(); + aListActors->InitTraversal(); + while (vtkActor* aActor = aListActors->GetNextActor()) { + if (!aActor->GetVisibility()) + continue; + if(SALOME_Actor* SActor = SALOME_Actor::SafeDownCast(aActor)) { + if (SActor->hasIO()) { + Handle(SALOME_InteractiveObject) IO = SActor->getIO(); + if (IO.IsNull()) + continue; + if (aSelActiveCompOnly && aComponentDataType != IO->getComponentDataType()) + continue; + if (vtkDataSet* aDataSet = SActor->GetInput()) { + SALOME_Selection::TContainerOfId anIndices; + for(int i = 0; i < aDataSet->GetNumberOfPoints(); i++) { + float aPoint[3]; + aDataSet->GetPoint(i,aPoint); + if (IsInRect(aPoint,x1,y1,x2,y2)){ + float aDisp[3]; + ComputeWorldToDisplay(aPoint[0],aPoint[1],aPoint[2],aDisp); + if(aPointPicker->Pick(aDisp[0],aDisp[1],0.0,CurrentRenderer)){ + if(vtkActorCollection *anActorCollection = aPointPicker->GetActors()){ + if(anActorCollection->IsItemPresent(SActor)){ + float aPickedPoint[3]; + aPointPicker->GetMapperPosition(aPickedPoint); + vtkIdType aVtkId = aDataSet->FindPoint(aPickedPoint); + if ( aVtkId >= 0 && IsValid( SActor, aVtkId, true ) ){ + int anObjId = SActor->GetNodeObjId(aVtkId); + anIndices.insert(anObjId); + } + } + } + } + } + } + if (!anIndices.empty()) { + aSel->AddOrRemoveIndex(IO, anIndices, true, false); + aSel->AddIObject(IO, false); + anIndices.clear(); + }else{ + aSel->RemoveIObject(IO, false); + } + } + } + } + } + } + break; + } + case CellSelection: + case EdgeOfCellSelection: + case EdgeSelection: + case FaceSelection: + case VolumeSelection: + { + vtkSmartPointer picker = VTKViewer_CellRectPicker::New(); + picker->SetTolerance(0.001); + picker->Pick(x1, y1, 0.0, x2, y2, 0.0, this->CurrentRenderer); + + vtkActorCollection* aListActors = picker->GetActors(); + aListActors->InitTraversal(); + while(vtkActor* aActor = aListActors->GetNextActor()) { + if (SALOME_Actor* aSActor = SALOME_Actor::SafeDownCast(aActor)) { + if (aSActor->hasIO()) { + Handle(SALOME_InteractiveObject) aIO = aSActor->getIO(); + if (aSelActiveCompOnly && aComponentDataType != aIO->getComponentDataType()) + continue; + VTKViewer_CellDataSet cellList = picker->GetCellData(aActor); + if ( !cellList.empty() ) { + SALOME_Selection::TContainerOfId anIndexes; + VTKViewer_CellDataSet::iterator it; + for ( it = cellList.begin(); it != cellList.end(); ++it ) { + int aCellId = (*it).cellId; + + if ( !IsValid( aSActor, aCellId ) ) + continue; + + int anObjId = aSActor->GetElemObjId(aCellId); + if (anObjId != -1){ + if ( CheckDimensionId(aSelectionMode,aSActor,anObjId) ) { + anIndexes.insert(anObjId); + } + } + } + aSel->AddOrRemoveIndex(aIO, anIndexes, true, false); + aSel->AddIObject(aIO, false); + } + } + } + } + } + break; + case ActorSelection: // objects selection + { + vtkSmartPointer picker = VTKViewer_RectPicker::New(); + picker->SetTolerance(0.001); + picker->Pick(x1, y1, 0.0, x2, y2, 0.0, this->CurrentRenderer); + + vtkActorCollection* aListActors = picker->GetActors(); + SALOME_ListIO aListIO; + aListActors->InitTraversal(); + while(vtkActor* aActor = aListActors->GetNextActor()) { + if (SALOME_Actor* aSActor = SALOME_Actor::SafeDownCast(aActor)) { + if (aSActor->hasIO()) { + Handle(SALOME_InteractiveObject) aIO = aSActor->getIO(); + if (!IsStored(aIO,aListIO)) + aListIO.Append(aIO); + } + } + } + if (!aListIO.IsEmpty()) { + SALOME_ListIteratorOfListIO It(aListIO); + for(;It.More();It.Next()) { + Handle(SALOME_InteractiveObject) IOS = It.Value(); + this->PropPicked++; + aSel->AddIObject( IOS, false ); + } + } + } // end case 4 + } //end switch + m_Interactor->EndPickCallback(); + } + aActiveStudy->update3dViewers(); + } + } + break; + case VTK_INTERACTOR_STYLE_CAMERA_ZOOM: + case VTK_INTERACTOR_STYLE_CAMERA_PAN: + case VTK_INTERACTOR_STYLE_CAMERA_ROTATE: + case VTK_INTERACTOR_STYLE_CAMERA_SPIN: + break; + case VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN: + { + int w, h, x, y; + m_Interactor->GetSize(w, h); + x = myPoint.x(); + y = h - myPoint.y() - 1; + Place(x, y); + } + break; + } + if (myGUIWindow) myGUIWindow->update(); +*/ +} + +/*! called during viewer operation when user moves mouse (!put necessary processing here!)*/ +void VTKViewer_InteractorStyle::onOperation(QPoint mousePos) +{ + if (!myGUIWindow) return; + int w, h; + GetInteractor()->GetSize(w, h); + switch (State) { + case VTK_INTERACTOR_STYLE_CAMERA_PAN: + { + // processing panning + //this->FindPokedCamera(mousePos.x(), mousePos.y()); + this->PanXY(mousePos.x(), myPoint.y(), myPoint.x(), mousePos.y()); + myPoint = mousePos; + break; + } + case VTK_INTERACTOR_STYLE_CAMERA_ZOOM: + { + // processing zooming + //this->FindPokedCamera(mousePos.x(), mousePos.y()); + this->DollyXY(mousePos.x() - myPoint.x(), mousePos.y() - myPoint.y()); + myPoint = mousePos; + break; + } + case VTK_INTERACTOR_STYLE_CAMERA_ROTATE: + { + // processing rotation + //this->FindPokedCamera(mousePos.x(), mousePos.y()); + this->RotateXY(mousePos.x() - myPoint.x(), myPoint.y() - mousePos.y()); + myPoint = mousePos; + break; + } + case VTK_INTERACTOR_STYLE_CAMERA_SPIN: + { + // processing spinning + //this->FindPokedCamera(mousePos.x(), mousePos.y()); + this->SpinXY(mousePos.x(), mousePos.y(), myPoint.x(), myPoint.y()); + myPoint = mousePos; + break; + } + case VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN: + { + break; + } + case VTK_INTERACTOR_STYLE_CAMERA_SELECT: + { + if (!myCursorState) + setCursor(VTK_INTERACTOR_STYLE_CAMERA_SELECT); + } + case VTK_INTERACTOR_STYLE_CAMERA_FIT: + { + QPainter p(myGUIWindow); + p.setPen(Qt::lightGray); + p.setRasterOp(Qt::XorROP); + p.drawRect(QRect(myPoint, myOtherPoint)); + myOtherPoint = mousePos; + p.drawRect(QRect(myPoint, myOtherPoint)); + break; + } + } + this->LastPos[0] = mousePos.x(); + this->LastPos[1] = h - mousePos.y() - 1; +} + +/*! called when selection mode changed (!put necessary initialization here!)*/ +void VTKViewer_InteractorStyle::OnSelectionModeChanged() +{ + + myPreSelectionActor->SetVisibility(false); + myElemId = myEdgeId = myNodeId = -1; + mySelectedActor = NULL; +} + +/*! called when user moves mouse inside viewer window and there is no active viewer operation \n + * (!put necessary processing here!) + */ +void VTKViewer_InteractorStyle::onCursorMove(QPoint mousePos) { + // processing highlighting +// SUIT_Study* anActiveStudy = SUIT_Application::getDesktop()->getActiveStudy(); +// SALOME_Selection* Sel = SALOME_Selection::Selection( anActiveStudy->getSelection() ); +// Selection_Mode aSelectionMode = Sel->SelectionMode(); + +/* int w, h, x, y; + m_Interactor->GetSize(w, h); + x = mousePos.x(); y = h - mousePos.y() - 1; + + this->FindPokedRenderer(x,y); + m_Interactor->StartPickCallback(); + myPreSelectionActor->SetVisibility(false); + + vtkPicker* aPicker = vtkPicker::SafeDownCast(m_Interactor->GetPicker()); + aPicker->Pick(x, y, 0.0, this->CurrentRenderer); + + SALOME_Actor* SActor = SALOME_Actor::SafeDownCast(aPicker->GetActor()); + + if (vtkCellPicker* picker = vtkCellPicker::SafeDownCast(aPicker)) { + int aVtkId = picker->GetCellId(); + if ( aVtkId >= 0 ) { + int anObjId = SActor->GetElemObjId(aVtkId); + if ( SActor && SActor->hasIO() && IsValid( SActor, aVtkId ) ) { + bool anIsSameObjId = (mySelectedActor == SActor && myElemId == anObjId); + bool aResult = anIsSameObjId; + if(!anIsSameObjId) { + if(aSelectionMode != EdgeOfCellSelection) { + aResult = CheckDimensionId(aSelectionMode,SActor,anObjId); + if(aResult){ + mySelectedActor = SActor; + myElemId = anObjId; + m_Interactor->setCellData(anObjId,SActor,myPreSelectionActor); + } + } + } + if(aSelectionMode == EdgeOfCellSelection){ + int anEdgeId = GetEdgeId(picker,SActor,anObjId); + bool anIsSameEdgeId = (myEdgeId != anEdgeId) && anIsSameObjId; + aResult = anIsSameEdgeId; + if(!anIsSameEdgeId) { + aResult = (anEdgeId >= 0); + if (aResult) { + mySelectedActor = SActor; + myEdgeId = anEdgeId; + myElemId = anObjId; + m_Interactor->setEdgeData(anObjId,SActor,-anEdgeId-1,myPreSelectionActor); + } + } + } + if(aResult) { + myPreSelectionActor->GetProperty()->SetRepresentationToSurface(); + myPreSelectionActor->SetVisibility(true); + } + } + } + } + else if (vtkPointPicker* picker = vtkPointPicker::SafeDownCast(aPicker)) { + int aVtkId = picker->GetPointId(); + if ( aVtkId >= 0 && IsValid( SActor, aVtkId, true ) ) { + if ( SActor && SActor->hasIO() ) { + int anObjId = SActor->GetNodeObjId(aVtkId); + bool anIsSameObjId = (mySelectedActor == SActor && myNodeId == anObjId); + if(!anIsSameObjId) { + mySelectedActor = SActor; + myNodeId = anObjId; + m_Interactor->setPointData(anObjId,SActor,myPreSelectionActor); + } + myPreSelectionActor->GetProperty()->SetRepresentationToSurface(); + myPreSelectionActor->SetVisibility(true); + } + } + } + else if ( vtkPicker::SafeDownCast(aPicker) ) { + if ( SActor ) { + if ( myPreViewActor != SActor ) { + if ( myPreViewActor != NULL ) { + myPreViewActor->SetPreSelected( false ); + } + myPreViewActor = SActor; + + if ( SActor->hasIO() ) { + Handle( SALOME_InteractiveObject) IO = SActor->getIO(); + if ( !IsSelected(IO,Sel) ) { + // Find All actors with same IO + vtkActorCollection* theActors = this->CurrentRenderer->GetActors(); + theActors->InitTraversal(); + while( vtkActor *ac = theActors->GetNextActor() ) { + if ( SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( ac ) ) { + if ( anActor->hasIO() ) { + Handle(SALOME_InteractiveObject) IOS = anActor->getIO(); + if(IO->isSame(IOS)) { + anActor->SetPreSelected( true ); + } + } + } + } + } + } + } + } else { + myPreViewActor = NULL; + vtkActorCollection* theActors = this->CurrentRenderer->GetActors(); + theActors->InitTraversal(); + while( vtkActor *ac = theActors->GetNextActor() ) { + if ( SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( ac ) ) { + anActor->SetPreSelected( false ); + } + } + } + } + m_Interactor->EndPickCallback(); + //m_Interactor->Render(); + myGUIWindow->update(); + + this->LastPos[0] = x; + this->LastPos[1] = y;*/ +} + +/*! called on finsh GlobalPan operation */ +void VTKViewer_InteractorStyle::Place(const int theX, const int theY) +{ + if (this->CurrentRenderer == NULL) { + return; + } + + //translate view + int *aSize = this->CurrentRenderer->GetRenderWindow()->GetSize(); + int centerX = aSize[0]/2; + int centerY = aSize[1]/2; + + TranslateView(centerX, centerY, theX, theY); + + // restore zoom scale + vtkCamera *cam = this->CurrentRenderer->GetActiveCamera(); + cam->SetParallelScale(myScale); + ::ResetCameraClippingRange(this->CurrentRenderer); + + if (myGUIWindow) myGUIWindow->update(); + +} + + + +/*! Translates view from Point to Point*/ +void VTKViewer_InteractorStyle::TranslateView(int toX, int toY, int fromX, int fromY) +{ + vtkCamera *cam = this->CurrentRenderer->GetActiveCamera(); + double viewFocus[4], focalDepth, viewPoint[3]; + float newPickPoint[4], oldPickPoint[4], motionVector[3]; + cam->GetFocalPoint(viewFocus); + + this->ComputeWorldToDisplay(viewFocus[0], viewFocus[1], + viewFocus[2], viewFocus); + focalDepth = viewFocus[2]; + + this->ComputeDisplayToWorld(double(toX), double(toY), + focalDepth, newPickPoint); + this->ComputeDisplayToWorld(double(fromX),double(fromY), + focalDepth, oldPickPoint); + + // camera motion is reversed + motionVector[0] = oldPickPoint[0] - newPickPoint[0]; + motionVector[1] = oldPickPoint[1] - newPickPoint[1]; + motionVector[2] = oldPickPoint[2] - newPickPoint[2]; + + cam->GetFocalPoint(viewFocus); + cam->GetPosition(viewPoint); + cam->SetFocalPoint(motionVector[0] + viewFocus[0], + motionVector[1] + viewFocus[1], + motionVector[2] + viewFocus[2]); + cam->SetPosition(motionVector[0] + viewPoint[0], + motionVector[1] + viewPoint[1], + motionVector[2] + viewPoint[2]); +} + + +/*! Checks: is the given Actor within display coordinates?*/ +bool VTKViewer_InteractorStyle::IsInRect(vtkActor* theActor, + const int left, const int top, + const int right, const int bottom) +{ + float* aBounds = theActor->GetBounds(); + float aMin[3], aMax[3]; + ComputeWorldToDisplay(aBounds[0], aBounds[2], aBounds[4], aMin); + ComputeWorldToDisplay(aBounds[1], aBounds[3], aBounds[5], aMax); + if (aMin[0] > aMax[0]) { + float aBuf = aMin[0]; + aMin[0] = aMax[0]; + aMax[0] = aBuf; + } + if (aMin[1] > aMax[1]) { + float aBuf = aMin[1]; + aMin[1] = aMax[1]; + aMax[1] = aBuf; + } + + return ((aMin[0]>left) && (aMax[0]bottom) && (aMax[1]GetBounds(); + float aMin[3], aMax[3]; + ComputeWorldToDisplay(aBounds[0], aBounds[2], aBounds[4], aMin); + ComputeWorldToDisplay(aBounds[1], aBounds[3], aBounds[5], aMax); + if (aMin[0] > aMax[0]) { + float aBuf = aMin[0]; + aMin[0] = aMax[0]; + aMax[0] = aBuf; + } + if (aMin[1] > aMax[1]) { + float aBuf = aMin[1]; + aMin[1] = aMax[1]; + aMax[1] = aBuf; + } + + return ((aMin[0]>left) && (aMax[0]bottom) && (aMax[1]left) && (aPnt[0]bottom) && (aPnt[1]GetId() ] = theFilter; +} + +/*!Checks: is filter present (with id \a theId) + *\param theId - filter id. + */ +bool VTKViewer_InteractorStyle::IsFilterPresent( const int theId ) +{ + return myFilters.find( theId ) != myFilters.end(); +} + +/*!Remove filter with id \a theId. + *\param theId - filter id. + */ +void VTKViewer_InteractorStyle::RemoveFilter( const int theId ) +{ + if ( IsFilterPresent( theId ) ) + myFilters.erase( theId ); +} + +/*!Checks: is valid cell(node) with id \a theId in actor \a theActor. + *\param theActor - VTKViewer_Actor pointer. + *\param theId - cell id. + *\param theIsNode - boolean flag, if true - node, else - cell. + */ +bool VTKViewer_InteractorStyle::IsValid( VTKViewer_Actor* theActor, + const int theId, + const bool theIsNode ) +{ + std::map::const_iterator anIter; + for ( anIter = myFilters.begin(); anIter != myFilters.end(); ++anIter ) + { + const Handle(VTKViewer_Filter)& aFilter = anIter->second; + if ( theIsNode == aFilter->IsNodeFilter() && + !aFilter->IsValid( theActor, theId ) ) + return false; + } + return true; +} + +/*!Gets filter handle by filter id \a theId.*/ +Handle(VTKViewer_Filter) VTKViewer_InteractorStyle::GetFilter( const int theId ) +{ + return IsFilterPresent( theId ) ? myFilters[ theId ] : Handle(VTKViewer_Filter)(); +} + +/*!Increment pan. + *\param incrX - X coordinate increment. + *\param incrY - Y coordinate increment. + */ +void VTKViewer_InteractorStyle::IncrementalPan( const int incrX, const int incrY ) +{ + this->PanXY( incrX, incrY, 0, 0 ); +} + +/*!Increment zoom. + *\param incr - zoom increment. + */ +void VTKViewer_InteractorStyle::IncrementalZoom( const int incr ) +{ + this->DollyXY( incr, incr ); +} + +/*!Increment rotate. + *\param incrX - X coordinate increment. + *\param incrY - Y coordinate increment. + */ +void VTKViewer_InteractorStyle::IncrementalRotate( const int incrX, const int incrY ) +{ + this->RotateXY( incrX, -incrY ); +} + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/VTKViewer/VTKViewer_ShrinkFilter.cxx b/src/VTKViewer/VTKViewer_ShrinkFilter.cxx new file mode 100755 index 000000000..c65699a9a --- /dev/null +++ b/src/VTKViewer/VTKViewer_ShrinkFilter.cxx @@ -0,0 +1,172 @@ +// SALOME OBJECT : kernel of SALOME component +// +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : SALOME_GeometryFilter.cxx +// Author : Michael ZORIN +// Module : SALOME +// $Header$ + +#include "VTKViewer_ShrinkFilter.h" + +#include +#include +#include +#include +#include +#include + +vtkCxxRevisionMacro(VTKViewer_ShrinkFilter, "$Revision$"); +vtkStandardNewMacro(VTKViewer_ShrinkFilter); + +/*!Constructor. Sets store mapping to zero.*/ +VTKViewer_ShrinkFilter::VTKViewer_ShrinkFilter(): + myStoreMapping(0) +{} + +/*!Destructor.*/ +VTKViewer_ShrinkFilter::~VTKViewer_ShrinkFilter() +{} + + +/*!Execute method. Calculate output.*/ +void VTKViewer_ShrinkFilter::Execute() +{ + vtkPoints *newPts; + int i, j, numIds, abort=0; + vtkIdType cellId, numCells, numPts; + vtkIdType oldId, newId; + float center[3], *p, pt[3]; + vtkPointData *pd, *outPD;; + vtkIdList *ptIds, *newPtIds; + vtkDataSet *input= this->GetInput(); + vtkUnstructuredGrid *output = this->GetOutput(); + vtkIdType tenth; + float decimal; + + vtkDebugMacro(<<"Shrinking cells"); + + numCells=input->GetNumberOfCells(); + numPts = input->GetNumberOfPoints(); + if (numCells < 1 || numPts < 1) + { + vtkErrorMacro(<<"No data to shrink!"); + return; + } + + ptIds = vtkIdList::New(); + ptIds->Allocate(VTK_CELL_SIZE); + newPtIds = vtkIdList::New(); + newPtIds->Allocate(VTK_CELL_SIZE); + + output->Allocate(numCells); + newPts = vtkPoints::New(); + newPts->Allocate(numPts*8,numPts); + pd = input->GetPointData(); + outPD = output->GetPointData(); + outPD->CopyAllocate(pd,numPts*8,numPts); + + // Traverse all cells, obtaining node coordinates. Compute "center" of cell, + // then create new vertices shrunk towards center. + // + tenth = numCells/10 + 1; + decimal = 0.0; + if(myStoreMapping){ + myVTK2ObjIds.clear(); + myVTK2ObjIds.reserve(numCells); + } + + for (cellId=0; cellId < numCells && !abort; cellId++) + { + input->GetCellPoints(cellId, ptIds); + numIds = ptIds->GetNumberOfIds(); + + //abort/progress methods + if (cellId % tenth == 0) + { + decimal += 0.1; + this->UpdateProgress (decimal); + abort = this->GetAbortExecute(); + } + + // get the center of the cell + center[0] = center[1] = center[2] = 0.0; + for (i=0; i < numIds; i++) + { + p = input->GetPoint(ptIds->GetId(i)); + for (j=0; j < 3; j++) + { + center[j] += p[j]; + } + } + for (j=0; j<3; j++) + { + center[j] /= numIds; + } + + // Create new points and cells + newPtIds->Reset(); + for (i=0; i < numIds; i++) + { + p = input->GetPoint(ptIds->GetId(i)); + for (j=0; j < 3; j++) + { + pt[j] = center[j] + this->ShrinkFactor*(p[j] - center[j]); + } + + oldId = ptIds->GetId(i); + newId = newPts->InsertNextPoint(pt); + if(myStoreMapping) + myVTK2ObjIds.push_back(oldId); + newPtIds->InsertId(i,newId); + + outPD->CopyData(pd, oldId, newId); + } + output->InsertNextCell(input->GetCellType(cellId), newPtIds); + }//for all cells + + // Update ourselves and release memory + // + output->GetCellData()->PassData(input->GetCellData()); + + output->SetPoints(newPts); + output->Squeeze(); + + ptIds->Delete(); + newPtIds->Delete(); + newPts->Delete(); +} + +/*!Sets store mapping.*/ +void VTKViewer_ShrinkFilter::SetStoreMapping(int theStoreMapping){ + myStoreMapping = theStoreMapping; + this->Modified(); +} + + +/*!Return node object id by vtk node id. + *\retval -1 - if no object, else return id. + */ +vtkIdType VTKViewer_ShrinkFilter::GetNodeObjId(int theVtkID){ + if(myVTK2ObjIds.empty() || theVtkID > myVTK2ObjIds.size()) return -1; + return myVTK2ObjIds.at(theVtkID); +}