From 976c1283a936caccb7aa7bc0201d559d7da5e158 Mon Sep 17 00:00:00 2001 From: ouv Date: Thu, 27 Sep 2018 11:18:14 +0300 Subject: [PATCH] 0004389: External 20933 Plots 3D - display whole numbers on axis --- adm_local/win32/Plot3d.vcproj | 14 +- adm_local/win32/SVTK.vcproj | 30 ++- src/Plot3d/Makefile.am | 2 + src/Plot3d/Plot3d_ViewWindow.cxx | 100 +++++++ src/Plot3d/Plot3d_ViewWindow.h | 7 + src/SVTK/Makefile.am | 2 + src/SVTK/SVTK_AxisActor2D.cxx | 423 ++++++++++++++++++++++++++++++ src/SVTK/SVTK_AxisActor2D.h | 65 +++++ src/SVTK/SVTK_CubeAxesActor2D.cxx | 54 +++- src/SVTK/SVTK_CubeAxesActor2D.h | 13 + src/SVTK/SVTK_CubeAxesDlg.cxx | 93 +++---- src/SVTK/SVTK_CubeAxesDlg.h | 58 ++++ src/SVTK/SVTK_ViewWindow.cxx | 8 + src/SVTK/SVTK_ViewWindow.h | 2 + src/SVTK/resources/SVTK_msg_en.ts | 4 + 15 files changed, 818 insertions(+), 57 deletions(-) create mode 100644 src/SVTK/SVTK_AxisActor2D.cxx create mode 100644 src/SVTK/SVTK_AxisActor2D.h diff --git a/adm_local/win32/Plot3d.vcproj b/adm_local/win32/Plot3d.vcproj index 49e40cf75..e6f14bb5a 100644 --- a/adm_local/win32/Plot3d.vcproj +++ b/adm_local/win32/Plot3d.vcproj @@ -1,7 +1,7 @@ + + + + + + + + @@ -2677,6 +2701,10 @@ RelativePath="..\..\src\Svtk\SVTK_Actor.cxx" > + + diff --git a/src/Plot3d/Makefile.am b/src/Plot3d/Makefile.am index fe4043f7a..d1b144a4c 100644 --- a/src/Plot3d/Makefile.am +++ b/src/Plot3d/Makefile.am @@ -72,6 +72,7 @@ nodist_salomeres_DATA = \ libPlot3d_la_CPPFLAGS = \ $(QT_INCLUDES) \ + $(QWT_INCLUDES) \ $(CAS_CPPFLAGS) \ $(VTK_INCLUDES) \ -I$(srcdir)/../Qtx \ @@ -83,6 +84,7 @@ libPlot3d_la_CPPFLAGS = \ libPlot3d_la_LDFLAGS = \ $(QT_MT_LIBS) \ + $(QWT_LIBS) \ $(CAS_KERNEL) $(CAS_VIEWER) -lTKCDF \ $(VTK_LIBS) $(OGL_LIBS) diff --git a/src/Plot3d/Plot3d_ViewWindow.cxx b/src/Plot3d/Plot3d_ViewWindow.cxx index 422acd2ae..7db17df35 100644 --- a/src/Plot3d/Plot3d_ViewWindow.cxx +++ b/src/Plot3d/Plot3d_ViewWindow.cxx @@ -45,6 +45,8 @@ #include #include +#include + #include #include #include @@ -130,6 +132,8 @@ Plot3d_ViewWindow::Plot3d_ViewWindow( SUIT_Desktop* theDesktop ): // Cell picker (required to display mapped coordinates in the status bar) myCellPicker = vtkCellPicker::New(); myCellPicker->Delete(); + + myScaleEngine = new QwtLinearScaleEngine(); } /*! @@ -146,6 +150,12 @@ Plot3d_ViewWindow::~Plot3d_ViewWindow() delete myColorDic; myColorDic = 0; } + + if( myScaleEngine ) + { + delete myScaleEngine; + myScaleEngine = 0; + } } /*! @@ -157,6 +167,9 @@ void Plot3d_ViewWindow::Initialize( SVTK_ViewModelBase* theModel ) SVTK_ViewWindow::Initialize( theModel ); + // 0004389: External 20933 Plots 3D - display whole numbers on axis + myCubeAxesDlg->SetAdjustRangeEnabled( true ); + // Initialize global scalar bar if( vtkRenderWindow* aRenderWindow = getRenderWindow() ) { @@ -508,6 +521,7 @@ void Plot3d_ViewWindow::onSurfacesSettings() UpdateScalarBar( false ); UpdateFitData( false ); + UpdateCubeAxes( false ); NormalizeSurfaces( false ); onFitAll(); } @@ -631,6 +645,7 @@ void Plot3d_ViewWindow::onFitData() } UpdateFitData( false ); + UpdateCubeAxes( false ); NormalizeSurfaces( false ); onFitAll(); } @@ -908,6 +923,91 @@ void Plot3d_ViewWindow::UpdateFitData( const bool theIsRepaint ) Repaint(); } +/*! + Adjust the specified range to get a scale with "round" values +*/ +void Plot3d_ViewWindow::AdjustRange( double& theMin, double& theMax, int& theNumberOfLabels ) +{ + static int MaxNumSteps = 10; + + double aStepSize = 1.0; + myScaleEngine->autoScale( MaxNumSteps, theMin, theMax, aStepSize ); + + if( fabs( aStepSize ) > 0 ) + { + double aNumber = fabs( theMax - theMin ) / aStepSize; + theNumberOfLabels = int( fabs( theMax - theMin ) / aStepSize + 0.5 ) + 1; + } +} + +/*! + Update CubeAxes actor +*/ +void Plot3d_ViewWindow::UpdateCubeAxes( const bool theIsRepaint ) +{ + SVTK_CubeAxesActor2D* aCubeAxes = GetRenderer()->GetCubeAxes(); + if( !aCubeAxes ) + return; + + vtkAxisActor2D* aXAxis = aCubeAxes->GetXAxisActor2D(); + vtkAxisActor2D* aYAxis = aCubeAxes->GetYAxisActor2D(); + vtkAxisActor2D* aZAxis = aCubeAxes->GetZAxisActor2D(); + if( !aXAxis || !aYAxis || !aZAxis ) + return; + + // Unfortunately, it is necessary to call Repaint() here, because the bounds of + // CubeAxes actor are recomputed in SVTK_CubeAxesActor2D::RenderOpaqueGeometry(). + Repaint(); + + double* aBounds = aCubeAxes->GetBounds(); + + double aScale[3]; + GetScale( aScale ); + aBounds[0] /= aScale[0]; + aBounds[1] /= aScale[0]; + aBounds[2] /= aScale[1]; + aBounds[3] /= aScale[1]; + aBounds[4] /= aScale[2]; + aBounds[5] /= aScale[2]; + + if( myIsFitDataEnabled ) + { + aBounds[0] = std::max( aBounds[0], myFitDataBounds[0] ); + aBounds[1] = std::min( aBounds[1], myFitDataBounds[1] ); + aBounds[2] = std::max( aBounds[2], myFitDataBounds[2] ); + aBounds[3] = std::min( aBounds[3], myFitDataBounds[3] ); + aBounds[4] = std::max( aBounds[4], myFitDataBounds[4] ); + aBounds[5] = std::min( aBounds[5], myFitDataBounds[5] ); + } + + int aXNumberOfLabels = aXAxis->GetNumberOfLabels(); + double aXMin = std::min( aBounds[0], aBounds[1] ); + double aXMax = std::max( aBounds[0], aBounds[1] ); + if( aCubeAxes->GetAdjustXRange() ) + AdjustRange( aXMin, aXMax, aXNumberOfLabels ); + aXAxis->SetRange( aXMin, aXMax ); + aXAxis->SetNumberOfLabels( aXNumberOfLabels ); + + int aYNumberOfLabels = aYAxis->GetNumberOfLabels(); + double aYMin = std::min( aBounds[2], aBounds[3] ); + double aYMax = std::max( aBounds[2], aBounds[3] ); + if( aCubeAxes->GetAdjustYRange() ) + AdjustRange( aYMin, aYMax, aYNumberOfLabels ); + aYAxis->SetRange( aYMin, aYMax ); + aYAxis->SetNumberOfLabels( aYNumberOfLabels ); + + int aZNumberOfLabels = aZAxis->GetNumberOfLabels(); + double aZMin = std::min( aBounds[4], aBounds[5] ); + double aZMax = std::max( aBounds[4], aBounds[5] ); + if( aCubeAxes->GetAdjustZRange() ) + AdjustRange( aZMin, aZMax, aZNumberOfLabels ); + aZAxis->SetRange( aZMin, aZMax ); + aZAxis->SetNumberOfLabels( aZNumberOfLabels ); + + if( theIsRepaint ) + Repaint(); +} + /*! Arrange the view scale to normalize the displayed surfaces */ diff --git a/src/Plot3d/Plot3d_ViewWindow.h b/src/Plot3d/Plot3d_ViewWindow.h index c9e08c481..01779e5bb 100644 --- a/src/Plot3d/Plot3d_ViewWindow.h +++ b/src/Plot3d/Plot3d_ViewWindow.h @@ -23,6 +23,8 @@ #include +class QwtScaleEngine; + class vtkCellPicker; class vtkLookupTable; class vtkScalarBarActor; @@ -64,6 +66,9 @@ public: const double theBounds[6] ); void UpdateFitData( const bool theIsRepaint = true ); + void AdjustRange( double& theMin, double& theMax, int& theNumberOfLabels ); + virtual void UpdateCubeAxes( const bool theIsRepaint = true ); + void NormalizeSurfaces( const bool theIsRepaint = true ); public slots: @@ -117,6 +122,8 @@ protected: double myFitDataBounds[6]; vtkSmartPointer myCellPicker; + + QwtScaleEngine* myScaleEngine; }; #endif diff --git a/src/SVTK/Makefile.am b/src/SVTK/Makefile.am index 8c86a8d52..93c1ff9e6 100755 --- a/src/SVTK/Makefile.am +++ b/src/SVTK/Makefile.am @@ -34,6 +34,7 @@ salomeinclude_HEADERS= \ SVTK_DeviceActor.h \ SVTK_DialogBase.h \ SVTK_FontWidget.h \ + SVTK_AxisActor2D.h \ SVTK_CubeAxesActor2D.h \ SVTK_Functor.h \ SVTK_View.h \ @@ -68,6 +69,7 @@ dist_libSVTK_la_SOURCES= \ SALOME_Actor.cxx \ SVTK_RectPicker.cxx \ SVTK_DeviceActor.cxx \ + SVTK_AxisActor2D.cxx \ SVTK_CubeAxesActor2D.cxx \ SVTK_NonIsometricDlg.cxx \ SVTK_UpdateRateDlg.cxx \ diff --git a/src/SVTK/SVTK_AxisActor2D.cxx b/src/SVTK/SVTK_AxisActor2D.cxx new file mode 100644 index 000000000..4f2e4a794 --- /dev/null +++ b/src/SVTK/SVTK_AxisActor2D.cxx @@ -0,0 +1,423 @@ +// 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.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// +// +// File : SVTK_AxisActor2D.cxx +// Module : SALOME +// $Header$ + +#include "SVTK_AxisActor2D.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +vtkCxxRevisionMacro(SVTK_AxisActor2D, "$Revision$"); +vtkStandardNewMacro(SVTK_AxisActor2D); + +// Instantiate this object. +SVTK_AxisActor2D::SVTK_AxisActor2D() +{ +} + +SVTK_AxisActor2D::~SVTK_AxisActor2D() +{ +} + +// OUV: Only two lines have been added to this virtual method (see the comment +// "0004389: External 20933 Plots 3D - display whole numbers on axis" below). +void SVTK_AxisActor2D::BuildAxis(vtkViewport *viewport) +{ + int i, *x, viewportSizeHasChanged, positionsHaveChanged; + vtkIdType ptIds[2]; + double p1[3], p2[3], offset; + double interval, deltaX, deltaY; + double xTick[3]; + double theta, val; + int *size, stringSize[2]; + char string[512]; + + if (this->TitleVisibility && !this->TitleTextProperty) + { + vtkErrorMacro(<<"Need title text property to render axis actor"); + return; + } + + if (this->LabelVisibility && !this->LabelTextProperty) + { + vtkErrorMacro(<<"Need label text property to render axis actor"); + return; + } + + // Check to see whether we have to rebuild everything + // Viewport change may not require rebuild + positionsHaveChanged = 0; + int *lastPosition = + this->PositionCoordinate->GetComputedViewportValue(viewport); + int *lastPosition2 = + this->Position2Coordinate->GetComputedViewportValue(viewport); + if (lastPosition[0] != this->LastPosition[0] || + lastPosition[1] != this->LastPosition[1] || + lastPosition2[0] != this->LastPosition2[0] || + lastPosition2[1] != this->LastPosition2[1] ) + { + positionsHaveChanged = 1; + } + + // See whether fonts have to be rebuilt (font size depends on viewport size) + viewportSizeHasChanged = 0; + size = viewport->GetSize(); + if (this->LastSize[0] != size[0] || this->LastSize[1] != size[1]) + { + viewportSizeHasChanged = 1; + this->LastSize[0] = size[0]; + this->LastSize[1] = size[1]; + } + + if ( ! viewport->GetVTKWindow() || + (!positionsHaveChanged && !viewportSizeHasChanged && + viewport->GetMTime() < this->BuildTime && + viewport->GetVTKWindow()->GetMTime() < this->BuildTime && + this->GetMTime() < this->BuildTime && + (!this->LabelVisibility || + this->LabelTextProperty->GetMTime() < this->BuildTime) && + (!this->TitleVisibility || + this->TitleTextProperty->GetMTime() < this->BuildTime)) ) + { + return; + } + + vtkDebugMacro(<<"Rebuilding axis"); + + // Initialize and get important info + this->Axis->Initialize(); + this->AxisActor->SetProperty(this->GetProperty()); + this->TitleActor->SetProperty(this->GetProperty()); + + // Compute the location of tick marks and labels + + this->UpdateAdjustedRange(); + + interval = (this->AdjustedRange[1] - this->AdjustedRange[0]) / (this->AdjustedNumberOfLabels - 1); + + this->NumberOfLabelsBuilt = this->AdjustedNumberOfLabels; + + // Generate the axis and tick marks. + // We'll do our computation in viewport coordinates. First determine the + // location of the endpoints. + x = this->PositionCoordinate->GetComputedViewportValue(viewport); + p1[0] = x[0]; + p1[1] = x[1]; + p1[2] = 0.0; + this->LastPosition[0] = x[0]; + this->LastPosition[1] = x[1]; + + x = this->Position2Coordinate->GetComputedViewportValue(viewport); + p2[0] = x[0]; + p2[1] = x[1]; + p2[2] = 0.0; + this->LastPosition2[0] = x[0]; + this->LastPosition2[1] = x[1]; + + double *xp1, *xp2, len=0.0; + if ( this->SizeFontRelativeToAxis ) + { + xp1 = this->PositionCoordinate->GetComputedDoubleDisplayValue(viewport); + xp2 = this->Position2Coordinate->GetComputedDoubleViewportValue(viewport); + len = sqrt((xp2[0]-xp1[0])*(xp2[0]-xp1[0]) + (xp2[1]-xp1[1])*(xp2[1]-xp1[1])); + } + + vtkPoints *pts = vtkPoints::New(); + vtkCellArray *lines = vtkCellArray::New(); + this->Axis->SetPoints(pts); + this->Axis->SetLines(lines); + pts->Delete(); + lines->Delete(); + + // Generate point along axis (as well as tick points) + deltaX = p2[0] - p1[0]; + deltaY = p2[1] - p1[1]; + + if (deltaX == 0. && deltaY == 0.) + { + theta = 0.; + } + else + { + theta = atan2(deltaY, deltaX); + } + + // First axis point, where first tick is located + ptIds[0] = pts->InsertNextPoint(p1); + xTick[0] = p1[0] + this->TickLength*sin(theta); + xTick[1] = p1[1] - this->TickLength*cos(theta); + xTick[2] = 0.0; + pts->InsertNextPoint(xTick); + + // Set up creation of ticks + double p21[3], length; + p21[0] = p2[0] - p1[0]; + p21[1] = p2[1] - p1[1]; + p21[2] = p2[2] - p1[2]; + length = vtkMath::Normalize(p21); + + int numTicks; + double distance; + if ( this->RulerMode ) + { + double wp1[3], wp2[3], wp21[3], wLength, wDistance; + this->PositionCoordinate->GetValue(wp1); + this->Position2Coordinate->GetValue(wp2); + wp21[0] = wp2[0] - wp1[0]; + wp21[1] = wp2[1] - wp1[1]; + wp21[2] = wp2[2] - wp1[2]; + wLength = vtkMath::Norm(wp21); + wDistance = this->RulerDistance / (this->NumberOfMinorTicks+1); + numTicks = (wDistance <= 0.0 ? 0 : static_cast(wLength / wDistance)+1); + wDistance *= numTicks; + distance = (length / (numTicks-1)) * (wDistance/wLength); + } + else + { + numTicks = (this->AdjustedNumberOfLabels-1) * + (this->NumberOfMinorTicks+1) + 1; + distance = length / (numTicks-1); + } + + for (i = 1; i < numTicks - 1; i++) + { + int tickLength = 0; + if ( i % (this->NumberOfMinorTicks+1) == 0 ) + { + tickLength = this->TickLength; + } + else + { + tickLength = this->MinorTickLength; + } + xTick[0] = p1[0] + i * p21[0] * distance; + xTick[1] = p1[1] + i * p21[1] * distance; + pts->InsertNextPoint(xTick); + xTick[0] = xTick[0] + tickLength * sin(theta); + xTick[1] = xTick[1] - tickLength * cos(theta); + pts->InsertNextPoint(xTick); + } + + // Last axis point + ptIds[1] = pts->InsertNextPoint(p2); + xTick[0] = p2[0] + this->TickLength*sin(theta); + xTick[1] = p2[1] - this->TickLength*cos(theta); + pts->InsertNextPoint(xTick); + + // Add the axis if requested + if (this->AxisVisibility) + { + lines->InsertNextCell(2, ptIds); + } + + // Create lines representing the tick marks + if (this->TickVisibility) + { + for (i = 0; i < numTicks; i++) + { + ptIds[0] = 2*i; + ptIds[1] = 2*i + 1; + lines->InsertNextCell(2, ptIds); + } + } + + // Build the labels + if (this->LabelVisibility) + { + // Update the labels text. Do it only if the range has been adjusted, + // i.e. if we think that new labels must be created. + // WARNING: if LabelFormat has changed, they should be recreated too + // but at this point the check on LabelFormat is "included" in + // UpdateAdjustedRange(), which is the function that update + // AdjustedRangeBuildTime or not. + unsigned long labeltime = this->AdjustedRangeBuildTime; + if (this->AdjustedRangeBuildTime > this->BuildTime) + { + for (i = 0; i < this->AdjustedNumberOfLabels; i++) + { + val = this->AdjustedRange[0] + i * interval; + + // OUV: This workaround has appeared during implementation of the issue + // "0004389: External 20933 Plots 3D - display whole numbers on axis". + // It is intended to avoid labels like "4.4408...e-016" (DBL_EPSILON * 2). + // Such label is appeared, for example, at the bottom edge of the inverted Y axis, + // when the Plot3d surface is displayed in 2D mode. + // Scenario: "Check C2 GUITHARE", BYPAS, ALFA, draw surface, activate 2D mode. + if( fabs( val ) < DBL_EPSILON * 10 ) + val = 0; + + sprintf(string, this->LabelFormat, val); + this->LabelMappers[i]->SetInput(string); + + // Check if the label text has changed + + if (this->LabelMappers[i]->GetMTime() > labeltime) + { + labeltime = this->LabelMappers[i]->GetMTime(); + } + } + } + + // Copy prop and text prop eventually + for (i = 0; i < this->AdjustedNumberOfLabels; i++) + { + this->LabelActors[i]->SetProperty(this->GetProperty()); + if (this->LabelTextProperty->GetMTime() > this->BuildTime || + this->AdjustedRangeBuildTime > this->BuildTime) + { + // Shallow copy here so that the size of the label prop is not + // affected by the automatic adjustment of its text mapper's + // size (i.e. its mapper's text property is identical except + // for the font size which will be modified later). This + // allows text actors to share the same text property, and in + // that case specifically allows the title and label text prop + // to be the same. + this->LabelMappers[i]->GetTextProperty()->ShallowCopy( + this->LabelTextProperty); + } + } + + // Resize the mappers if needed (i.e. viewport has changed, than + // font size should be changed, or label text property has changed, + // or some of the labels have changed (got bigger for example) + if (positionsHaveChanged || viewportSizeHasChanged || + this->LabelTextProperty->GetMTime() > this->BuildTime || + labeltime > this->BuildTime) + { + if ( ! this->SizeFontRelativeToAxis ) + { + vtkTextMapper::SetMultipleRelativeFontSize(viewport, + this->LabelMappers, + this->AdjustedNumberOfLabels, + size, + this->LastMaxLabelSize, + 0.015*this->FontFactor*this->LabelFactor); + } + else + { + int minFontSize=1000, fontSize, minLabel=0; + for (i = 0; i < this->AdjustedNumberOfLabels; i++) + { + fontSize = this->LabelMappers[i]-> + SetConstrainedFontSize(viewport, + static_cast((1.0/this->AdjustedNumberOfLabels)*len), + static_cast(0.2*len) ); + if ( fontSize < minFontSize ) + { + minFontSize = fontSize; + minLabel = i; + } + } + for (i=0; iAdjustedNumberOfLabels; i++) + { + this->LabelMappers[i]->GetTextProperty()->SetFontSize(minFontSize); + } + this->LabelMappers[minLabel]->GetSize(viewport,this->LastMaxLabelSize); + } + } + + // Position the mappers + for (i = 0; i < this->AdjustedNumberOfLabels; i++) + { + pts->GetPoint((this->NumberOfMinorTicks+1) * 2 * i + 1, xTick); + this->LabelMappers[i]->GetSize(viewport, stringSize); + this->SetOffsetPosition(xTick, + theta, + this->LastMaxLabelSize[0], + this->LastMaxLabelSize[1], + this->TickOffset, + this->LabelActors[i]); + } + } // If labels visible + + // Now build the title + if (this->Title != NULL && this->Title[0] != 0 && this->TitleVisibility) + { + this->TitleMapper->SetInput(this->Title); + + if (this->TitleTextProperty->GetMTime() > this->BuildTime) + { + // Shallow copy here so that the size of the title prop is not + // affected by the automatic adjustment of its text mapper's + // size (i.e. its mapper's text property is identical except for + // the font size which will be modified later). This allows text + // actors to share the same text property, and in that case + // specifically allows the title and label text prop to be the same. + this->TitleMapper->GetTextProperty()->ShallowCopy( + this->TitleTextProperty); + } + + if (positionsHaveChanged || viewportSizeHasChanged || + this->TitleTextProperty->GetMTime() > this->BuildTime) + { + if ( ! this->SizeFontRelativeToAxis ) + { + vtkTextMapper::SetRelativeFontSize(this->TitleMapper, viewport, size, stringSize, 0.015*this->FontFactor); + } + else + { + this->TitleMapper->SetConstrainedFontSize(viewport, + static_cast(0.33*len), + static_cast(0.2*len) ); + this->TitleMapper->GetSize(viewport, stringSize); + } + } + else + { + this->TitleMapper->GetSize(viewport, stringSize); + } + + xTick[0] = p1[0] + (p2[0] - p1[0]) * this->TitlePosition; + xTick[1] = p1[1] + (p2[1] - p1[1]) * this->TitlePosition; + xTick[0] = xTick[0] + (this->TickLength + this->TickOffset) * sin(theta); + xTick[1] = xTick[1] - (this->TickLength + this->TickOffset) * cos(theta); + + offset = 0.0; + if (this->LabelVisibility) + { + offset = this->ComputeStringOffset(this->LastMaxLabelSize[0], + this->LastMaxLabelSize[1], + theta); + } + + this->SetOffsetPosition(xTick, + theta, + stringSize[0], + stringSize[1], + static_cast(offset), + this->TitleActor); + } // If title visible + + this->BuildTime.Modified(); +} diff --git a/src/SVTK/SVTK_AxisActor2D.h b/src/SVTK/SVTK_AxisActor2D.h new file mode 100644 index 000000000..8864c532a --- /dev/null +++ b/src/SVTK/SVTK_AxisActor2D.h @@ -0,0 +1,65 @@ +// 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.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// +// +// File : SVTK_AxisActor2D.cxx +// Module : SALOME +// $Header$ + +#ifndef __SVTK_AxisActor2D_h +#define __SVTK_AxisActor2D_h + +#include + +#include "SVTK.h" + +#ifdef WIN32 +#pragma warning ( disable:4251 ) +#endif + +#ifndef WIN32 +class VTK_HYBRID_EXPORT SVTK_AxisActor2D : public vtkAxisActor2D +#else +class SVTK_EXPORT SVTK_AxisActor2D : public vtkAxisActor2D +#endif +{ +public: + vtkTypeRevisionMacro(SVTK_AxisActor2D,vtkAxisActor2D); + + static SVTK_AxisActor2D *New(); + + virtual void BuildAxis(vtkViewport *viewport); + +protected: + SVTK_AxisActor2D(); + ~SVTK_AxisActor2D(); + +private: + SVTK_AxisActor2D(const SVTK_AxisActor2D&); // Not implemented. + void operator=(const SVTK_AxisActor2D&); // Not implemented. +}; + +#ifdef WIN32 +//#pragma warning ( default:4251 ) +#endif + +#endif diff --git a/src/SVTK/SVTK_CubeAxesActor2D.cxx b/src/SVTK/SVTK_CubeAxesActor2D.cxx index 31b442484..430bc8b03 100644 --- a/src/SVTK/SVTK_CubeAxesActor2D.cxx +++ b/src/SVTK/SVTK_CubeAxesActor2D.cxx @@ -27,6 +27,7 @@ // $Header$ #include "SVTK_CubeAxesActor2D.h" +#include "SVTK_AxisActor2D.h" #include "VTKViewer_Transform.h" #include @@ -51,6 +52,21 @@ vtkStandardNewMacro(SVTK_CubeAxesActor2D); // Instantiate this object. SVTK_CubeAxesActor2D::SVTK_CubeAxesActor2D() { + this->XAxis = SVTK_AxisActor2D::New(); + this->XAxis->GetPositionCoordinate()->SetCoordinateSystemToDisplay(); + this->XAxis->GetPosition2Coordinate()->SetCoordinateSystemToDisplay(); + this->XAxis->AdjustLabelsOff(); + + this->YAxis = SVTK_AxisActor2D::New(); + this->YAxis->GetPositionCoordinate()->SetCoordinateSystemToDisplay(); + this->YAxis->GetPosition2Coordinate()->SetCoordinateSystemToDisplay(); + this->YAxis->AdjustLabelsOff(); + + this->ZAxis = SVTK_AxisActor2D::New(); + this->ZAxis->GetPositionCoordinate()->SetCoordinateSystemToDisplay(); + this->ZAxis->GetPosition2Coordinate()->SetCoordinateSystemToDisplay(); + this->ZAxis->AdjustLabelsOff(); + this->wireActorXY = vtkActor::New(); this->wireActorYZ = vtkActor::New(); this->wireActorXZ = vtkActor::New(); @@ -128,6 +144,10 @@ SVTK_CubeAxesActor2D::SVTK_CubeAxesActor2D() aTLProp->Delete(); this->IsInvertedGrid = false; + + this->AdjustXRange = false; + this->AdjustYRange = false; + this->AdjustZRange = false; } SVTK_CubeAxesActor2D::~SVTK_CubeAxesActor2D() @@ -273,9 +293,39 @@ int SVTK_CubeAxesActor2D::RenderOpaqueGeometry(vtkViewport *viewport) this->RenderSomething = 1; + double aTScale[3] = { 1, 1, 1 }; + if(m_Transform.GetPointer() != NULL) + m_Transform->GetMatrixScale( aTScale ); + // determine the bounds to use this->GetBounds(bounds); + // 0004389: External 20933 Plots 3D - display whole numbers on axis) + if( this->AdjustXRange ) + { + double* aXRange = this->XAxis->GetRange(); + double aXMin = std::min( aXRange[0], aXRange[1] ); + double aXMax = std::max( aXRange[0], aXRange[1] ); + bounds[0] = aXMin * aTScale[0]; + bounds[1] = aXMax * aTScale[0]; + } + if( this->AdjustYRange ) + { + double* aYRange = this->YAxis->GetRange(); + double aYMin = std::min( aYRange[0], aYRange[1] ); + double aYMax = std::max( aYRange[0], aYRange[1] ); + bounds[2] = aYMin * aTScale[1]; + bounds[3] = aYMax * aTScale[1]; + } + if( this->AdjustZRange ) + { + double* aZRange = this->ZAxis->GetRange(); + double aZMin = std::min( aZRange[0], aZRange[1] ); + double aZMax = std::max( aZRange[0], aZRange[1] ); + bounds[4] = aZMin * aTScale[2]; + bounds[5] = aZMax * aTScale[2]; + } + // Build the axes (almost always needed so we don't check mtime) // Transform all points into display coordinates this->TransformBounds(viewport, bounds, pts); @@ -427,10 +477,6 @@ int SVTK_CubeAxesActor2D::RenderOpaqueGeometry(vtkViewport *viewport) xRange,yRange,zRange, xAxes,yAxes,zAxes); - double aTScale[3]; - if(m_Transform.GetPointer() != NULL) - m_Transform->GetMatrixScale(aTScale); - this->XAxis->GetPositionCoordinate()->SetValue(xCoords[0], xCoords[1]); this->XAxis->GetPosition2Coordinate()->SetValue(xCoords[2], xCoords[3]); if(m_Transform.GetPointer() != NULL) this->XAxis->SetRange(xRange[0]/aTScale[0], xRange[1]/aTScale[0]); diff --git a/src/SVTK/SVTK_CubeAxesActor2D.h b/src/SVTK/SVTK_CubeAxesActor2D.h index 71ca0669a..6fe0e4301 100644 --- a/src/SVTK/SVTK_CubeAxesActor2D.h +++ b/src/SVTK/SVTK_CubeAxesActor2D.h @@ -86,6 +86,15 @@ public: vtkSetMacro(IsInvertedGrid, bool); vtkGetMacro(IsInvertedGrid, bool); + vtkSetMacro(AdjustXRange, bool); + vtkGetMacro(AdjustXRange, bool); + + vtkSetMacro(AdjustYRange, bool); + vtkGetMacro(AdjustYRange, bool); + + vtkSetMacro(AdjustZRange, bool); + vtkGetMacro(AdjustZRange, bool); + protected: SVTK_CubeAxesActor2D(); ~SVTK_CubeAxesActor2D(); @@ -111,6 +120,10 @@ private: bool IsInvertedGrid; + bool AdjustXRange; + bool AdjustYRange; + bool AdjustZRange; + private: SVTK_CubeAxesActor2D(const SVTK_CubeAxesActor2D&); // Not implemented. void operator=(const SVTK_CubeAxesActor2D&); // Not implemented. diff --git a/src/SVTK/SVTK_CubeAxesDlg.cxx b/src/SVTK/SVTK_CubeAxesDlg.cxx index 967ecec3d..113dcf7f3 100644 --- a/src/SVTK/SVTK_CubeAxesDlg.cxx +++ b/src/SVTK/SVTK_CubeAxesDlg.cxx @@ -49,44 +49,6 @@ #define DEFAULT_FONT_SIZE 16 -/*! - \class SVTK_CubeAxesDlg::AxisWidget - \brief Axis tab widget of the "Graduated axis" dialog box - \internal -*/ - -class SVTK_CubeAxesDlg::AxisWidget : public QFrame -{ -public: - AxisWidget( QWidget* ); - ~AxisWidget(); - - void UseName( const bool ); - void SetName( const QString& ); - void SetNameFont( const QColor&, const int, const int, const bool, const bool, const bool ); - bool ReadData( vtkAxisActor2D* ); - bool Apply( vtkAxisActor2D* ); - -private: - // name - QGroupBox* myNameGrp; - QLineEdit* myAxisName; - SVTK_FontWidget* myNameFont; - - // labels - QGroupBox* myLabelsGrp; - QtxIntSpinBox* myLabelNumber; - QtxIntSpinBox* myLabelOffset; - QLineEdit* myLabelFormat; - SVTK_FontWidget* myLabelsFont; - - // tick marks - QGroupBox* myTicksGrp; - QtxIntSpinBox* myTickLength; - - friend class SVTK_CubeAxesDlg; -}; - /*! Constructor */ @@ -136,8 +98,11 @@ SVTK_CubeAxesDlg::AxisWidget::AxisWidget (QWidget* theParent) aHBox->setSpacing(5); aLabel = new QLabel(SVTK_CubeAxesDlg::tr("NUMBER")); aHBox->addWidget(aLabel); - myLabelNumber = new QtxIntSpinBox(0,25,1,myLabelsGrp); - aHBox->addWidget(myLabelNumber); + myLabelNumber = new QtxIntSpinBox(2,25,1,myLabelsGrp); + aHBox->addWidget(myLabelNumber, 1); + myAdjustRange = new QCheckBox(SVTK_CubeAxesDlg::tr("ADJUST_AUTOMATICALLY")); + myAdjustRange->setChecked(false); + aHBox->addWidget(myAdjustRange); aLabels.append(aLabel); aVBox->addLayout(aHBox); @@ -208,6 +173,8 @@ SVTK_CubeAxesDlg::AxisWidget::AxisWidget (QWidget* theParent) myLabelsGrp->setChecked( true ); myTicksGrp->setChecked( true ); + myAdjustRange->setVisible( false ); + // Adjust label widths QList< QLabel* >::iterator anIter; int aMaxWidth = 0; @@ -215,6 +182,9 @@ SVTK_CubeAxesDlg::AxisWidget::AxisWidget (QWidget* theParent) aMaxWidth = qMax(aMaxWidth, (*anIter)->sizeHint().width()); for (anIter = aLabels.begin(); anIter != aLabels.end(); anIter++) (*anIter)->setFixedWidth(aMaxWidth); + + // Connections + connect( myAdjustRange, SIGNAL( toggled( bool ) ), this, SLOT( onAdjustRange( bool ) ) ); } /*! @@ -244,6 +214,26 @@ void SVTK_CubeAxesDlg::AxisWidget::SetNameFont(const QColor& theColor, myNameFont->SetData(theColor, theFont, theSize, theIsBold, theIsItalic, theIsShadow); } +void SVTK_CubeAxesDlg::AxisWidget::SetAdjustRangeEnabled( const bool theIsEnabled ) +{ + myAdjustRange->setVisible( theIsEnabled ); +} + +void SVTK_CubeAxesDlg::AxisWidget::SetAdjustRange( const bool theState ) +{ + myAdjustRange->setChecked( theState ); +} + +bool SVTK_CubeAxesDlg::AxisWidget::GetAdjustRange() const +{ + return myAdjustRange->isChecked(); +} + +void SVTK_CubeAxesDlg::AxisWidget::onAdjustRange( bool theState ) +{ + myLabelNumber->setEnabled( !theState ); +} + bool SVTK_CubeAxesDlg::AxisWidget::ReadData(vtkAxisActor2D* theActor) { if (theActor == 0) @@ -520,6 +510,10 @@ void SVTK_CubeAxesDlg::Update() myAxes[ 1 ]->ReadData(myActor->GetYAxisActor2D()); myAxes[ 2 ]->ReadData(myActor->GetZAxisActor2D()); + myAxes[ 0 ]->SetAdjustRange( myActor->GetAdjustXRange() ); + myAxes[ 1 ]->SetAdjustRange( myActor->GetAdjustYRange() ); + myAxes[ 2 ]->SetAdjustRange( myActor->GetAdjustZRange() ); + myIsVisible->setChecked(myActor->GetVisibility() ? true : false); } @@ -547,6 +541,15 @@ void SVTK_CubeAxesDlg::SetDimensionZEnabled( const bool theIsEnabled ) myTabWg->setTabEnabled( 2, theIsEnabled ); } +/*! + Show hide the checkboxes "Adjust automatically" in each tab +*/ +void SVTK_CubeAxesDlg::SetAdjustRangeEnabled( const bool theIsEnabled ) +{ + for( int i = 0; i <= 2; i++ ) + myAxes[ i ]->SetAdjustRangeEnabled( theIsEnabled ); +} + /*! Verify validity of entry data */ @@ -572,17 +575,17 @@ bool SVTK_CubeAxesDlg::onApply() isOk = isOk && myAxes[ 1 ]->Apply(myActor->GetYAxisActor2D()); isOk = isOk && myAxes[ 2 ]->Apply(myActor->GetZAxisActor2D()); + myActor->SetAdjustXRange( myAxes[0]->GetAdjustRange() ); + myActor->SetAdjustYRange( myAxes[1]->GetAdjustRange() ); + myActor->SetAdjustZRange( myAxes[2]->GetAdjustRange() ); - //myActor->SetXLabel(myAxes[ 0 ]->myAxisName->text()); - //myActor->SetYLabel(myAxes[ 1 ]->myAxisName->text()); - //myActor->SetZLabel(myAxes[ 2 ]->myAxisName->text()); - - //myActor->SetNumberOfLabels(myActor->GetXAxisActor2D()->GetNumberOfLabels()); if (myIsVisible->isChecked()) myActor->VisibilityOn(); else myActor->VisibilityOff(); + myMainWindow->UpdateCubeAxes( false ); + if (isOk) myMainWindow->Repaint(); } diff --git a/src/SVTK/SVTK_CubeAxesDlg.h b/src/SVTK/SVTK_CubeAxesDlg.h index abac6738f..d3f3a002b 100644 --- a/src/SVTK/SVTK_CubeAxesDlg.h +++ b/src/SVTK/SVTK_CubeAxesDlg.h @@ -29,12 +29,19 @@ #include "SVTK_DialogBase.h" +#include + class QWidget; class QPushButton; class QTabWidget; class QCheckBox; +class QGroupBox; +class QLineEdit; + +class vtkAxisActor2D; class QtxAction; +class QtxIntSpinBox; class SVTK_CubeAxesActor2D; class SVTK_FontWidget; @@ -63,6 +70,8 @@ public: void SetDimensionYEnabled( const bool theIsEnabled ); void SetDimensionZEnabled( const bool theIsEnabled ); + void SetAdjustRangeEnabled( const bool theIsEnabled ); + private slots: void onOk(); bool onApply(); @@ -86,4 +95,53 @@ private: AxisWidget* myAxes[ 3 ]; }; +/*! + \class SVTK_CubeAxesDlg::AxisWidget + \brief Axis tab widget of the "Graduated axis" dialog box + \internal +*/ + +class SVTK_CubeAxesDlg::AxisWidget : public QFrame +{ + Q_OBJECT + +public: + AxisWidget( QWidget* ); + ~AxisWidget(); + + void UseName( const bool ); + void SetName( const QString& ); + void SetNameFont( const QColor&, const int, const int, const bool, const bool, const bool ); + + void SetAdjustRangeEnabled( const bool theIsEnabled ); + void SetAdjustRange( const bool theState ); + bool GetAdjustRange() const; + + bool ReadData( vtkAxisActor2D* ); + bool Apply( vtkAxisActor2D* ); + +private slots: + void onAdjustRange( bool theState ); + +private: + // name + QGroupBox* myNameGrp; + QLineEdit* myAxisName; + SVTK_FontWidget* myNameFont; + + // labels + QGroupBox* myLabelsGrp; + QtxIntSpinBox* myLabelNumber; + QCheckBox* myAdjustRange; + QtxIntSpinBox* myLabelOffset; + QLineEdit* myLabelFormat; + SVTK_FontWidget* myLabelsFont; + + // tick marks + QGroupBox* myTicksGrp; + QtxIntSpinBox* myTickLength; + + friend class SVTK_CubeAxesDlg; +}; + #endif diff --git a/src/SVTK/SVTK_ViewWindow.cxx b/src/SVTK/SVTK_ViewWindow.cxx index 740f78bed..769f05420 100755 --- a/src/SVTK/SVTK_ViewWindow.cxx +++ b/src/SVTK/SVTK_ViewWindow.cxx @@ -2041,3 +2041,11 @@ void SVTK_ViewWindow::hideEvent( QHideEvent * theEvent ) { emit Hide( theEvent ); } + +/*! + Update CubeAxes actor +*/ +void SVTK_ViewWindow::UpdateCubeAxes( const bool theIsRepaint ) +{ + // the base implementation does nothing +} diff --git a/src/SVTK/SVTK_ViewWindow.h b/src/SVTK/SVTK_ViewWindow.h index c2612fc0f..30d5a5cfa 100755 --- a/src/SVTK/SVTK_ViewWindow.h +++ b/src/SVTK/SVTK_ViewWindow.h @@ -260,6 +260,8 @@ class SVTK_EXPORT SVTK_ViewWindow : public SUIT_ViewWindow virtual void RefreshDumpImage(); + virtual void UpdateCubeAxes( const bool theIsRepaint = true ); + //! To invoke a VTK event on #SVTK_RenderWindowInteractor instance void InvokeEvent(unsigned long theEvent, void* theCallData); diff --git a/src/SVTK/resources/SVTK_msg_en.ts b/src/SVTK/resources/SVTK_msg_en.ts index 26972f242..a175f2212 100644 --- a/src/SVTK/resources/SVTK_msg_en.ts +++ b/src/SVTK/resources/SVTK_msg_en.ts @@ -216,6 +216,10 @@ LABELS Labels + + ADJUST_AUTOMATICALLY + Adjust automatically + LENGTH Length -- 2.39.2