效果
关键代码
# include "View3D.h"
# include "Axis.h" # include <vtkActor.h>
# include <vtkAppendPolyData.h >
# include <vtkAreaPicker.h>
# include <vtkAxesActor.h>
# include <vtkBox.h>
# include <vtkCamera.h>
# include <vtkCaptionActor2D.h>
# include <vtkCellArray.h>
# include <vtkCleanPolyData.h >
# include <vtkContourFilter.h>
# include <vtkCubeSource.h>
# include <vtkCylinder.h>
# include <vtkCylinderSource.h>
# include <vtkDataSet.h>
# include <vtkGenericOpenGLRenderWindow.h>
# include <vtkImplicitBoolean.h>
# include <vtkInteractorStyleTrackballCamera.h>
# include <vtkLine.h>
# include <vtkMinimalStandardRandomSequence.h>
# include <vtkNamedColors.h>
# include <vtkObjectFactory.h>
# include <vtkOrientationMarkerWidget.h>
# include <vtkPlane.h>
# include <vtkPolyDataMapper.h>
# include <vtkPolyDataNormals.h>
# include <vtkPropPicker.h>
# include <vtkProperty.h>
# include <vtkRenderWindow.h>
# include <vtkRenderWindowInteractor.h>
# include <vtkRenderer.h>
# include <vtkRendererCollection.h>
# include <vtkReverseSense.h>
# include <vtkSTLReader.h>
# include <vtkSampleFunction.h>
# include <vtkSmartPointer.h>
# include <vtkSphere.h>
# include <vtkTransform.h>
# include <vtkTransformPolyDataFilter.h>
decltype ( auto ) View3D :: buildBoard ( double r, double g, double b)
{ vtkNew< vtkCubeSource> cube; cube-> SetXLength ( 1 ) ; cube-> SetYLength ( 0.05 ) ; cube-> SetZLength ( 0.2 ) ; cube-> Update ( ) ; vtkNew< vtkCylinderSource> cy; cy-> SetRadius ( 0.1 ) ; cy-> SetHeight ( 0.05 ) ; cy-> SetCenter ( 0.5 , 0 , 0 ) ; cy-> SetResolution ( 100 ) ; cy-> Update ( ) ; vtkNew< vtkCylinderSource> cy1; cy1-> SetRadius ( 0.1 ) ; cy1-> SetHeight ( 0.05 ) ; cy1-> SetResolution ( 100 ) ; cy1-> SetCenter ( - 0.5 , 0 , 0 ) ; cy1-> Update ( ) ; vtkNew< vtkCylinderSource> cy2; cy2-> SetRadius ( 0.05 ) ; cy2-> SetHeight ( 0.06 ) ; cy2-> SetResolution ( 100 ) ; cy2-> SetCenter ( 0.5 , 0 , 0 ) ; cy2-> Update ( ) ; vtkNew< vtkCylinderSource> cy3; cy3-> SetRadius ( 0.05 ) ; cy3-> SetHeight ( 0.06 ) ; cy3-> SetResolution ( 100 ) ; cy3-> SetCenter ( - 0.5 , 0 , 0 ) ; cy3-> Update ( ) ; vtkNew< vtkAssembly> assembly; vtkNew< vtkPolyDataMapper> cudeMapper; cudeMapper-> SetInputConnection ( cube-> GetOutputPort ( ) ) ; vtkNew< vtkActor> cudeActor; cudeActor-> SetMapper ( cudeMapper) ; cudeActor-> GetProperty ( ) -> SetColor ( r, g, b) ; assembly-> AddPart ( cudeActor) ; vtkNew< vtkPolyDataMapper> cyMapper; cyMapper-> SetInputConnection ( cy-> GetOutputPort ( ) ) ; vtkNew< vtkActor> cyActor; cyActor-> SetMapper ( cyMapper) ; cyActor-> GetProperty ( ) -> SetColor ( r, g, b) ; assembly-> AddPart ( cyActor) ; vtkNew< vtkPolyDataMapper> cy1Mapper; cy1Mapper-> SetInputConnection ( cy1-> GetOutputPort ( ) ) ; vtkNew< vtkActor> cy1Actor; cy1Actor-> SetMapper ( cy1Mapper) ; cy1Actor-> GetProperty ( ) -> SetColor ( r, g, b) ; assembly-> AddPart ( cy1Actor) ; vtkNew< vtkPolyDataMapper> cy2Mapper; cy2Mapper-> SetInputConnection ( cy2-> GetOutputPort ( ) ) ; vtkNew< vtkActor> cy2Actor; cy2Actor-> SetMapper ( cy2Mapper) ; cy2Actor-> GetProperty ( ) -> SetColor ( 0.8 , 0 , 0 ) ; assembly-> AddPart ( cy2Actor) ; vtkNew< vtkPolyDataMapper> cy3Mapper; cy3Mapper-> SetInputConnection ( cy3-> GetOutputPort ( ) ) ; vtkNew< vtkActor> cy3Actor; cy3Actor-> SetMapper ( cy3Mapper) ; cy3Actor-> GetProperty ( ) -> SetColor ( 0.8 , 0 , 0 ) ; assembly-> AddPart ( cy3Actor) ; return assembly;
} decltype ( auto ) View3D :: buildConnectRod ( )
{ auto actor1 = buildBoard ( 0.5 , 1 , 0.5 ) ; auto actor2 = buildBoard ( 1 , 1 , 0.5 ) ; auto actor3 = buildBoard ( 0.5 , 1 , 1 ) ; actor1-> AddPosition ( 0.5 , 0 , 0 ) ; actor2-> AddPosition ( 1.5 , 0.05 , 0 ) ; actor3-> AddPosition ( 2.5 , 0.1 , 0 ) ; vtkNew< vtkAssembly> assembly1, assembly2, assembly3; assembly1-> AddPart ( actor1) ; assembly1-> AddPart ( assembly2) ; assembly2-> AddPart ( actor2) ; assembly2-> AddPart ( assembly3) ; assembly3-> AddPart ( actor3) ; assembly2-> SetOrigin ( 1 , 0.05 , 0 ) ; assembly3-> SetOrigin ( 2 , 0 , 0 ) ; return std:: make_tuple ( vtkSmartPointer < vtkAssembly> ( assembly1) , vtkSmartPointer < vtkAssembly> ( assembly2) , vtkSmartPointer < vtkAssembly> ( assembly3) ) ;
} View3D :: View3D ( QWidget* parent) : QVTKOpenGLNativeWidget ( parent)
{ vtkNew< vtkRenderer> renderer; this -> renderWindow ( ) -> AddRenderer ( renderer) ; renderer-> AddActor ( baseAxes = getBaseAxes ( ) ) ; addGuideLine ( 3 , 0.2 ) ; connectRods = buildConnectRod ( ) ; auto && [ actor1, actor2, actor3] = connectRods; renderer-> AddActor ( actor1) ; renderer-> GetActiveCamera ( ) -> Azimuth ( 90 ) ; renderer-> GetActiveCamera ( ) -> SetRoll ( - 90 ) ; renderer-> GetActiveCamera ( ) -> Azimuth ( 45 ) ; renderer-> GetActiveCamera ( ) -> Elevation ( 15 ) ; renderer-> GetActiveCamera ( ) -> SetPosition ( 3 , 3 , 1 ) ; vtkSmartPointer< vtkOrientationMarkerWidget> widget = vtkSmartPointer < vtkOrientationMarkerWidget> :: New ( ) ; ; this -> borderWidget = widget; vtkSmartPointer< vtkAxesActor> widgetAxesActor = vtkSmartPointer < vtkAxesActor> :: New ( ) ; widgetAxesActor-> SetPosition ( 0 , 0 , 0 ) ; widgetAxesActor-> SetShaftType ( 0 ) ; widgetAxesActor-> SetCylinderRadius ( 0.02 ) ; widgetAxesActor-> SetTotalLength ( 2 , 2 , 2 ) ; widget-> SetOrientationMarker ( widgetAxesActor) ; widget-> SetInteractor ( this -> interactor ( ) ) ; widget-> SetEnabled ( 1 ) ; widget-> InteractiveOn ( ) ; connect ( this , & View3D:: rotateBased, this , & View3D:: rotateBaseSlot) ; connect ( this , & View3D:: rotateBigArmed, this , & View3D:: rotateBigArmSlot) ; connect ( this , & View3D:: rotateMiddleArmed, this , & View3D:: rotateMiddleArmSlot) ; connect ( this , & View3D:: rotateSmallArmed, this , & View3D:: rotateSmallArmSlot) ;
} void View3D :: addAxis ( const Axis& axis)
{ vtkNew< vtkTransform> transform; transform-> Translate ( axis. xyz. x ( ) , axis. xyz. y ( ) , axis. xyz. z ( ) ) ; vtkAxesActor* axes = vtkAxesActor:: New ( ) ; transform-> RotateX ( axis. xyzR. x ( ) ) ; transform-> RotateY ( axis. xyzR. y ( ) ) ; transform-> RotateZ ( axis. xyzR. z ( ) ) ; axes-> SetUserTransform ( transform) ; axes-> SetTotalLength ( axis. xyzL. x ( ) , axis. xyzL. y ( ) , axis. xyzL. z ( ) ) ; axes-> SetConeRadius ( axis. xyzL[ 0 ] * 0.1 ) ; axes-> SetCylinderRadius ( axis. xyzL[ 0 ] * 0.1 ) ; axes-> SetConeResolution ( 100 ) ; axes-> SetCylinderResolution ( 100 ) ; axes-> SetXAxisLabelText ( axis. labels[ 0 ] . toStdString ( ) . c_str ( ) ) ; axes-> SetYAxisLabelText ( axis. labels[ 1 ] . toStdString ( ) . c_str ( ) ) ; axes-> SetZAxisLabelText ( axis. labels[ 2 ] . toStdString ( ) . c_str ( ) ) ; auto xLabelProperty = axes-> GetXAxisCaptionActor2D ( ) ; xLabelProperty-> SetWidth ( axis. xyzL. x ( ) * 0.1 ) ; auto yLabelProperty = axes-> GetYAxisCaptionActor2D ( ) ; yLabelProperty-> SetWidth ( axis. xyzL. y ( ) * 0.1 ) ; auto zLabelProperty = axes-> GetZAxisCaptionActor2D ( ) ; zLabelProperty-> SetWidth ( axis. xyzL. z ( ) * 0.1 ) ; this -> renderWindow ( ) -> GetRenderers ( ) -> GetFirstRenderer ( ) -> AddActor ( axes) ; this -> renderWindow ( ) -> Render ( ) ;
} void View3D :: rotateBaseSlot ( double angle)
{ auto && [ a, b, c] = connectRods; a-> SetOrientation ( 0 , 0 , 0 ) ; a-> RotateWXYZ ( angle, 0 , 0 , 1 ) ; refresh ( ) ;
} void View3D :: rotateBigArmSlot ( double angle)
{ auto && [ a, b, c] = connectRods; a-> RotateY ( angle - a-> GetOrientation ( ) [ 1 ] ) ; refresh ( ) ;
} void View3D :: rotateMiddleArmSlot ( double angle)
{ auto && [ a, b, c] = connectRods; b-> RotateY ( angle - b-> GetOrientation ( ) [ 1 ] ) ; refresh ( ) ;
} void View3D :: rotateSmallArmSlot ( double angle)
{ auto && [ a, b, c] = connectRods; c-> RotateY ( angle - c-> GetOrientation ( ) [ 1 ] ) ; refresh ( ) ;
} void View3D :: addGuideLine ( float r, float space)
{ vtkNew< vtkCellArray> lines; vtkNew< vtkPoints> points; for ( size_t i = 0 ; i <= static_cast < unsigned long long > ( r / space) * 2 ; i++ ) { points-> InsertNextPoint ( - r, r - space * i, 0 ) ; points-> InsertNextPoint ( r, r - space * i, 0 ) ; points-> InsertNextPoint ( - r + space * i, r, 0 ) ; points-> InsertNextPoint ( - r + space * i, - r, 0 ) ; } for ( size_t i = 0 ; i <= static_cast < unsigned long long > ( r / space) * 4 + 1 ; i++ ) { vtkNew< vtkLine> line; line-> GetPointIds ( ) -> SetId ( 0 , i * 2 ) ; line-> GetPointIds ( ) -> SetId ( 1 , i * 2 + 1 ) ; lines-> InsertNextCell ( line) ; } vtkNew< vtkPolyData> linesPolyData; linesPolyData-> SetPoints ( points) ; linesPolyData-> SetLines ( lines) ; vtkNew< vtkPolyDataMapper> mapper; mapper-> SetInputData ( linesPolyData) ; vtkNew< vtkActor> actor; actor-> SetMapper ( mapper) ; actor-> GetProperty ( ) -> SetOpacity ( 0.5 ) ; this -> renderWindow ( ) -> GetRenderers ( ) -> GetFirstRenderer ( ) -> AddActor ( actor) ; this -> renderWindow ( ) -> Render ( ) ;
} vtkNew< vtkAxesActor> View3D :: getBaseAxes ( )
{ vtkNew< vtkAxesActor> axes; axes-> SetTotalLength ( 1.0 , 1.0 , 1.0 ) ; axes-> SetPosition ( 0 , 0 , 0 ) ; axes-> SetShaftType ( 0 ) ; axes-> SetConeResolution ( 100 ) ; axes-> SetCylinderResolution ( 100 ) ; axes-> SetConeRadius ( 0.1 ) ; axes-> SetCylinderRadius ( 0.01 ) ; return axes;
} void View3D :: refresh ( )
{ this -> renderWindow ( ) -> Render ( ) ;
}