From: ouv Date: Thu, 31 May 2012 09:58:46 +0000 (+0000) Subject: GUITHARE 2012-2014. Task 3.5: Cylindrical trihedron. X-Git-Tag: CTH_1_8_0~27 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=8cf85002177376588c39f43c5fd3e59c35623b1d;p=modules%2Fgui.git GUITHARE 2012-2014. Task 3.5: Cylindrical trihedron. --- diff --git a/src/VTKViewer/Makefile.am b/src/VTKViewer/Makefile.am index 146f162b7..467e104ac 100755 --- a/src/VTKViewer/Makefile.am +++ b/src/VTKViewer/Makefile.am @@ -48,7 +48,8 @@ salomeinclude_HEADERS = \ VTKViewer_ViewWindow.h \ VTKViewer_Functor.h \ VTKViewer_MergeFilter.h \ - VTKViewer_PassThroughFilter.h + VTKViewer_PassThroughFilter.h \ + vtkArcSource.h dist_libVTKViewer_la_SOURCES = \ VTKViewer_CellLocationsArray.cxx \ @@ -70,7 +71,8 @@ dist_libVTKViewer_la_SOURCES = \ VTKViewer_ConvexTool.cxx \ VTKViewer_ViewWindow.cxx \ VTKViewer_MergeFilter.cxx \ - VTKViewer_PassThroughFilter.cxx + VTKViewer_PassThroughFilter.cxx \ + vtkArcSource.cxx MOC_FILES = \ VTKViewer_RenderWindow_moc.cxx \ diff --git a/src/VTKViewer/VTKViewer_Trihedron.cxx b/src/VTKViewer/VTKViewer_Trihedron.cxx index 7781f1b57..42a091b80 100755 --- a/src/VTKViewer/VTKViewer_Trihedron.cxx +++ b/src/VTKViewer/VTKViewer_Trihedron.cxx @@ -19,6 +19,8 @@ #include "VTKViewer_Trihedron.h" #include "VTKViewer_Actor.h" +#include "vtkArcSource.h" // local class + // VTK Includes #include #include @@ -120,6 +122,10 @@ VTKViewer_Axis::VTKViewer_Axis() myLineSource = vtkLineSource::New(); myLineSource->SetPoint1(0.0,0.0,0.0); + myArcSource = vtkArcSource::New(); + myArcSource->SetResolution(96); + myArcSource->SetCenter(0.0,0.0,0.0); + myMapper[0] = vtkPolyDataMapper::New(); myMapper[0]->SetInput(myLineSource->GetOutput()); @@ -160,6 +166,8 @@ VTKViewer_Axis::VTKViewer_Axis() /*! \li Initialise visibility param.*/ myVisibility = VTKViewer_Trihedron::eOn; + + myIsCircular = false; } /*! @@ -190,6 +198,7 @@ VTKViewer_Axis::~VTKViewer_Axis() myMapper[2]->Delete(); myLineSource->Delete(); + myArcSource->Delete(); } /*! Add to renderer @@ -253,13 +262,26 @@ void VTKViewer_Axis::SetSize(vtkFloatingPointType theSize) { vtkFloatingPointType aPosition[3] = {myDir[0]*theSize, myDir[1]*theSize, myDir[2]*theSize}; myLineSource->SetPoint2(aPosition); - + + vtkFloatingPointType anArcPosition1[3] = { aPosition[0] / 2., + aPosition[1] / 2., + aPosition[2] / 2. }; + + // note: a small gap is added here to draw an arc instead a singular line + vtkFloatingPointType anArcPosition2[3] = { anArcPosition1[0], + anArcPosition1[1] - 0.001, + anArcPosition1[2]}; + + myArcSource->SetPoint1(anArcPosition1); + myArcSource->SetPoint2(anArcPosition2); + myArcSource->NegativeOn(); + myArrowActor->SetPosition(0.0,0.0,0.0); - myArrowActor->AddPosition(aPosition); + myArrowActor->AddPosition(myIsCircular ? anArcPosition1 : aPosition); myArrowActor->SetOrientation(myRot); myLabelActor->SetPosition(0.0,0.0,0.0); - myLabelActor->AddPosition(aPosition); + myLabelActor->AddPosition(myIsCircular ? anArcPosition1 : aPosition); } /*! Check if actor belongs to the axis object @@ -273,6 +295,26 @@ bool VTKViewer_Axis::OwnActor(const vtkActor* theActor) theActor == myLabelActor; } +/*! Makes the axis circular. + * \param theFlag - boolean value + */ +void VTKViewer_Axis::SetIsCircular(const bool theFlag) +{ + myIsCircular = theFlag; + if( myIsCircular ) + myMapper[0]->SetInput(myArcSource->GetOutput()); + else + myMapper[0]->SetInput(myLineSource->GetOutput()); +} + +/*! Sets the label text. + * \param theText - string value + */ +void VTKViewer_Axis::SetLabelText(const char* theText) +{ + myVectorText->SetText(theText); +} + /*! \class VTKViewer_XAxis * \brief X Axis actor */ @@ -309,6 +351,8 @@ protected: public: vtkTypeMacro(VTKViewer_YAxis,VTKViewer_Axis); static VTKViewer_YAxis *New(); +public: + virtual void SetIsCircular(const bool theFlag); }; vtkStandardNewMacro(VTKViewer_YAxis); @@ -325,6 +369,24 @@ VTKViewer_YAxis::VTKViewer_YAxis() aProperty->Delete(); } +/*! Makes the axis circular. + * \param theFlag - boolean value + */ +void VTKViewer_YAxis::SetIsCircular(const bool theFlag) +{ + VTKViewer_Axis::SetIsCircular( theFlag ); + if( theFlag ) + { + myDir[0] = 1.0; myDir[1] = 0.0; myDir[2] = 0.0; + myRot[0] = 0.0; myRot[1] = 0.0; myRot[2] = 90.; + } + else + { + myDir[0] = 0.0; myDir[1] = 1.0; myDir[2] = 0.0; + myRot[0] = 0.0; myRot[1] = 0.0; myRot[2] = 90.; + } +} + /*! \class VTKViewer_ZAxis * \brief Z Axis actor */ @@ -359,6 +421,7 @@ vtkStandardNewMacro(VTKViewer_Trihedron); */ VTKViewer_Trihedron::VTKViewer_Trihedron() { + myIsCylindrical = false; myPresent = vtkActorCollection::New(); myAxis[0] = VTKViewer_XAxis::New(); myAxis[1] = VTKViewer_YAxis::New(); @@ -378,6 +441,18 @@ VTKViewer_Trihedron::~VTKViewer_Trihedron() myAxis[i]->Delete(); } +/*! Makes the trihedron cylindrical. + * \param theFlag - boolean value + */ +void VTKViewer_Trihedron::SetIsCylindrical(const bool theFlag) +{ + myIsCylindrical = theFlag; + myAxis[1]->SetIsCircular(theFlag); + + myAxis[0]->SetLabelText(theFlag ? "R" : "X"); + myAxis[1]->SetLabelText(theFlag ? "O" : "Y"); // to do: replace "O" with THETA symbol +} + /*! Set size of axes */ void VTKViewer_Trihedron::SetSize(vtkFloatingPointType theSize) diff --git a/src/VTKViewer/VTKViewer_Trihedron.h b/src/VTKViewer/VTKViewer_Trihedron.h index 0d3b34561..aaec1929b 100755 --- a/src/VTKViewer/VTKViewer_Trihedron.h +++ b/src/VTKViewer/VTKViewer_Trihedron.h @@ -33,6 +33,8 @@ class vtkLineSource; class vtkConeSource; class vtkVectorText; +class vtkArcSource; + class VTKViewer_Axis; /*! \class vtkFollower @@ -130,7 +132,17 @@ public: /*!Create new instance of VTKViewer_Trihedron.*/ static VTKViewer_Trihedron *New(); - + + /*! Makes the trihedron cylindrical. + * \param theFlag - boolean value + */ + virtual void SetIsCylindrical(const bool theFlag); + + /*! Checks that the trihedron is cylindrical. + * \retval theFlag - boolean value + */ + virtual bool IsCylindrical() const { return myIsCylindrical; } + /*!Sets size of trihedron. * \param theSize - vtkFloatingPointType value */ @@ -188,6 +200,9 @@ protected: /*! Common size for trihedron, for each axis.*/ vtkFloatingPointType mySize; + + /*! Type of the trihedron (cylindrical or rectangular).*/ + bool myIsCylindrical; }; /*!The base class for concreate Axis. @@ -247,6 +262,16 @@ public: */ virtual bool OwnActor(const vtkActor* theActor); + /*! Makes the axis circular. + * \param theFlag - boolean value + */ + virtual void SetIsCircular(const bool theFlag); + + /*! Sets the label text. + * \param theText - string value + */ + virtual void SetLabelText(const char* theText); + protected: /*! Visibility flag. */ @@ -259,6 +284,11 @@ protected: * Orientation vector */ vtkFloatingPointType myDir[3], myRot[3]; + + /*! \var myIsCircular + * Type of the axis (circular or linear) + */ + bool myIsCircular; /*! VTKViewer_LineActor actor pointer */ @@ -282,6 +312,10 @@ protected: */ vtkLineSource *myLineSource; + /*! vtkArcSource pointer (Arc) + */ + vtkArcSource *myArcSource; + /*! vtkConeSource pointer (Arrow) */ vtkConeSource *myConeSource; diff --git a/src/VTKViewer/vtkArcSource.cxx b/src/VTKViewer/vtkArcSource.cxx new file mode 100644 index 000000000..98fa909f8 --- /dev/null +++ b/src/VTKViewer/vtkArcSource.cxx @@ -0,0 +1,176 @@ +/*========================================================================= + + Program: Visualization Toolkit + Module: vtkArcSource.cxx + + Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen + All rights reserved. + See Copyright.txt or http://www.kitware.com/Copyright.htm for details. + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notice for more information. + +=========================================================================*/ +#include "vtkArcSource.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +vtkStandardNewMacro(vtkArcSource); + +// -------------------------------------------------------------------------- +vtkArcSource::vtkArcSource(int res) +{ + this->Point1[0] = 0.0; + this->Point1[1] = 0.5; + this->Point1[2] = 0.0; + + this->Point2[0] = 0.5; + this->Point2[1] = 0.0; + this->Point2[2] = 0.0; + + this->Center[0] = 0.0; + this->Center[1] = 0.0; + this->Center[2] = 0.0; + + this->Resolution = (res < 1 ? 1 : res); + this->Negative = false; + + this->SetNumberOfInputPorts(0); +} + +// -------------------------------------------------------------------------- +int vtkArcSource::RequestInformation( + vtkInformation *vtkNotUsed(request), + vtkInformationVector **vtkNotUsed(inputVector), + vtkInformationVector *outputVector) +{ + // get the info object + vtkInformation *outInfo = outputVector->GetInformationObject(0); + outInfo->Set(vtkStreamingDemandDrivenPipeline::MAXIMUM_NUMBER_OF_PIECES(), + -1); + return 1; +} + +// -------------------------------------------------------------------------- +int vtkArcSource::RequestData( + vtkInformation *vtkNotUsed(request), + vtkInformationVector **vtkNotUsed(inputVector), + vtkInformationVector *outputVector) +{ + int numLines = this->Resolution; + int numPts = this->Resolution+1; + double tc[3] = {0.0, 0.0, 0.0}; + + // get the info object + vtkInformation *outInfo = outputVector->GetInformationObject(0); + + if (outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER()) > 0) + { + return 1; + } + + // get the ouptut + vtkPolyData *output = vtkPolyData::SafeDownCast( + outInfo->Get(vtkDataObject::DATA_OBJECT())); + + // Compute the cross product of the two vectors. + double v1[3] = { this->Point1[0] - this->Center[0], + this->Point1[1] - this->Center[1], + this->Point1[2] - this->Center[2] }; + double v2[3] = { this->Point2[0] - this->Center[0], + this->Point2[1] - this->Center[1], + this->Point2[2] - this->Center[2] }; + + double normal[3], perpendicular[3]; + vtkMath::Cross( v1, v2, normal ); + vtkMath::Cross( normal, v1, perpendicular ); + vtkMath::Normalize( perpendicular ); + double dotprod = + vtkMath::Dot( v1, v2 ) / (vtkMath::Norm(v1) * vtkMath::Norm(v2)); + double angle = acos( dotprod ); + if (this->Negative) + { + angle -= 2 * vtkMath::Pi(); + } + double radius = vtkMath::Normalize( v1 ); + double angleInc = angle / this->Resolution; + + vtkPoints *newPoints = vtkPoints::New(); + newPoints->Allocate(numPts); + vtkFloatArray *newTCoords = vtkFloatArray::New(); + newTCoords->SetNumberOfComponents(2); + newTCoords->Allocate(2*numPts); + newTCoords->SetName("Texture Coordinates"); + vtkCellArray *newLines = vtkCellArray::New(); + newLines->Allocate(newLines->EstimateSize(numLines,2)); + + double theta = 0.0; + for (int i = 0; i < this->Resolution; i++, theta += angleInc) + { + const double cosine = cos(theta); + const double sine = sin(theta); + double p[3] = + { this->Center[0] + cosine*radius*v1[0] + sine*radius*perpendicular[0], + this->Center[1] + cosine*radius*v1[1] + sine*radius*perpendicular[1], + this->Center[2] + cosine*radius*v1[2] + sine*radius*perpendicular[2] }; + + tc[0] = static_cast(i)/this->Resolution; + newPoints->InsertPoint(i,p); + newTCoords->InsertTuple(i,tc); + } + + tc[0] = 1.0; + newPoints->InsertPoint( this->Resolution, this->Point2 ); + newTCoords->InsertTuple(this->Resolution,tc); + + newLines->InsertNextCell(numPts); + for (int k=0; k < numPts; k++) + { + newLines->InsertCellPoint (k); + } + + output->SetPoints(newPoints); + newPoints->Delete(); + + output->GetPointData()->SetTCoords(newTCoords); + newTCoords->Delete(); + + output->SetLines(newLines); + newLines->Delete(); + + return 1; +} + +// -------------------------------------------------------------------------- +void vtkArcSource::PrintSelf(ostream& os, vtkIndent indent) +{ + this->Superclass::PrintSelf(os,indent); + + os << indent << "Resolution: " << this->Resolution << "\n"; + + os << indent << "Point 1: (" << this->Point1[0] << ", " + << this->Point1[1] << ", " + << this->Point1[2] << ")\n"; + + os << indent << "Point 2: (" << this->Point2[0] << ", " + << this->Point2[1] << ", " + << this->Point2[2] << ")\n"; + + os << indent << "Center: (" << this->Center[0] << ", " + << this->Center[1] << ", " + << this->Center[2] << ")\n"; + + os << indent << "Negative: " << this->Negative << "\n"; +} + diff --git a/src/VTKViewer/vtkArcSource.h b/src/VTKViewer/vtkArcSource.h new file mode 100644 index 000000000..5baceca0b --- /dev/null +++ b/src/VTKViewer/vtkArcSource.h @@ -0,0 +1,85 @@ +/*========================================================================= + + Program: Visualization Toolkit + Module: vtkArcSource.h + + Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen + All rights reserved. + See Copyright.txt or http://www.kitware.com/Copyright.htm for details. + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notice for more information. + +=========================================================================*/ +// .NAME vtkArcSource - create an arc between two end points +// .SECTION Description +// vtkArcSource is a source object that creates an arc defined by two +// endpoints and a center. The number of segments composing the polyline is +// controlled by setting the object resolution. + +#ifndef __vtkArcSource_h +#define __vtkArcSource_h + +#include "VTKViewer.h" + +#include + +class VTKVIEWER_EXPORT vtkArcSource : public vtkPolyDataAlgorithm +{ +public: + static vtkArcSource *New(); + vtkTypeMacro(vtkArcSource,vtkPolyDataAlgorithm); + void PrintSelf(ostream& os, vtkIndent indent); + + // Description: + // Set position of first end point. + vtkSetVector3Macro(Point1,double); + vtkGetVectorMacro(Point1,double,3); + + // Description: + // Set position of other end point. + vtkSetVector3Macro(Point2,double); + vtkGetVectorMacro(Point2,double,3); + + // Description: + // Set position of the center of the circle that define the arc. + // Note: you can use the function vtkMath::Solve3PointCircle to + // find the center from 3 points located on a circle. + vtkSetVector3Macro(Center,double); + vtkGetVectorMacro(Center,double,3); + + // Description: + // Divide line into resolution number of pieces. + // Note: if Resolution is set to 1 (default), the arc is a + // straight line. + vtkSetClampMacro(Resolution,int,1,VTK_LARGE_INTEGER); + vtkGetMacro(Resolution,int); + + // Description: + // Use the angle that is a negative coterminal of the vectors angle: + // the longest angle. + // Note: false by default. + vtkSetMacro(Negative, bool); + vtkGetMacro(Negative, bool); + vtkBooleanMacro(Negative, bool); + +protected: + vtkArcSource(int res=1); + ~vtkArcSource() {}; + + int RequestData(vtkInformation *, vtkInformationVector **, vtkInformationVector *); + int RequestInformation(vtkInformation *, vtkInformationVector **, vtkInformationVector *); + double Point1[3]; + double Point2[3]; + double Center[3]; + int Resolution; + bool Negative; + +private: + vtkArcSource(const vtkArcSource&); // Not implemented. + void operator=(const vtkArcSource&); // Not implemented. +}; + +#endif +