VTK的视点研究之三维空间漫游(转载)
分类:计算机
2009-08-17 16:19
阅读(?)评论(0)
#include
#include "vtkConeSource.h"
#include "vtkPolyDataMapper.h"
#include "vtkRenderWindow.h"
#include "vtkCamera.h"
#include "vtkActor.h"
#include "vtkRenderer.h"
#include "vtkDICOMImageReader.h"
#include "vtkSphereSource.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkImageCast.h"
#include "vtkCallbackCommand.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkImageDataGeometryFilter.h"
#include "vtkWarpScalar.h"
#include "vtkWindowLevelLookupTable.h"
#include "vtkImageMapToWindowLevelColors.h"
#include "vtkInteractorStyleTrackballCamera.h"
#include "vtkInteractorStyle.h"
#include "vtkInteractorEventRecorder.h"
#include "vtkTextActor.h"
#include "vtkSphereSource.h"
#include
#include
#include "vtkTextProperty.h"
#include "vtkOrientationMarkerWidget.h"
#include "vtkAxesActor.h"
#include "vtkCaptionActor2D.h"
#include
#include
#include
#include "vtkSphereSource.h"
#include "vtkPlane.h"
#include "vtkClipPolyData.h"
#include "vtkTextureMapToCylinder.h"
#include "vtkPolyDataNormals.h"
#include "vtkTextureMapToCylinder.h"
#include "vtkTransformTextureCoords.h"
#include "vtkDataSetMapper.h"
vtkRenderWindowInteractor *iren;
vtkCamera *aCamera;
vtkRenderer *ren1;
vtkRenderWindow *renWin;
vtkTextActor *txt;
vtkActor *feidie;
vtkInteractorEventRecorder *recorder;
int pos;
float dis;
char BoxWidgetEventLog[] =
"LeftButtonPressEvent 153 253 0 0 0 0 i\n"
"MouseMoveEvent 153 252 0 0 0 0 i\n"
"LeftButtonReleaseEvent 153 252 0 0 0 0 i\n"
;
void keypress(vtkObject *caller, unsigned long eid, void *clientdata, void *calldata);
int main()
{
ren1= vtkRenderer::New();
renWin = vtkRenderWindow::New();
renWin->AddRenderer( ren1 );
iren = vtkRenderWindowInteractor::New();
iren->SetRenderWindow(renWin);
vtkInteractorStyleTrackballCamera *style=vtkInteractorStyleTrackballCamera::New();
pos=3;
dis=0.7;
vtkDICOMImageReader *dr = vtkDICOMImageReader::New();
dr->SetDataByteOrderToLittleEndian();
dr->SetFileName("E://CT/100098.dcm");
dr->SetDataOrigin(0.0,0.0,0.0);
vtkLookupTable *hueLut=vtkLookupTable::New();
hueLut->SetTableRange (0, 2000);
hueLut->SetHueRange (0, 1);
hueLut->SetSaturationRange (1, 1);
hueLut->SetValueRange (1, 1);
hueLut->SetAlpha(1);
hueLut->Build(); //effective built
vtkImageMapToWindowLevelColors* pImageMapToColors = vtkImageMapToWindowLevelColors ::New();
pImageMapToColors->SetOutputFormatToRGBA();
pImageMapToColors->SetInput((vtkDataObject *)dr->GetOutput());
pImageMapToColors->SetLookupTable(hueLut);
vtkImageDataGeometryFilter *geo=vtkImageDataGeometryFilter::New();
geo->SetInput((vtkDataObject *)pImageMapToColors->GetOutput());
vtkWarpScalar *scalar=vtkWarpScalar::New();
scalar->SetInput(geo->GetOutput());
scalar->SetScaleFactor(0.06);
scalar->UseNormalOff ( );
scalar->SetUseNormal (60);
vtkPolyDataMapper *skinMapper1 = vtkPolyDataMapper::New();
skinMapper1->SetInputConnection(scalar->GetOutputPort());
// skinMapper1->SetScalarRange(-1000,2000);
// skinMapper1->ImmediateModeRenderingOff();
vtkActor *skin1 = vtkActor::New();
skin1->SetMapper(skinMapper1);
txt = vtkTextActor::New();
txt->SetDisplayPosition(0, 0);
txt->SetInput("Information Shown!");
txt->GetTextProperty()->SetFontSize(18);
txt->GetTextProperty()->SetFontFamilyToArial();
txt->GetTextProperty()->BoldOff();
txt->GetTextProperty()->ItalicOn();
txt->GetTextProperty()->ShadowOn();
txt->GetTextProperty()->SetColor(0, 0, 1);
vtkSphereSource *sphere = vtkSphereSource::New();
sphere->SetThetaResolution(10);
sphere->SetPhiResolution(10);
sphere->SetRadius(0.3);
vtkTransform *aTransform = vtkTransform::New();
aTransform->Scale(1,1,0.2);
vtkTransformFilter *transFilter = vtkTransformFilter::New();
transFilter->SetInput(sphere->GetOutput());
transFilter->SetTransform(aTransform);
vtkPolyDataMapper *mapper = vtkPolyDataMapper::New();
mapper->SetInputConnection(transFilter->GetOutputPort());
feidie = vtkActor::New();
feidie->SetMapper(mapper);
/
vtkCallbackCommand * cmd1 = vtkCallbackCommand::New();
cmd1->SetCallback(keypress);
style-> AddObserver (vtkCommand::KeyPressEvent,cmd1);
/
//方向
vtkAxesActor* axes2 = vtkAxesActor::New();
axes2->SetShaftTypeToCylinder();
axes2->SetXAxisLabelText( "X" );
axes2->SetYAxisLabelText( "Y" );
axes2->SetZAxisLabelText( "Z" );
axes2->SetTotalLength( 1.5, 1.5, 1.5 );
axes2->SetCylinderRadius( 0.500 * axes2->GetCylinderRadius() );
axes2->SetConeRadius ( 1.025 * axes2->GetConeRadius() );
axes2->SetSphereRadius ( 1.500 * axes2->GetSphereRadius() );
vtkTextProperty* tprop2 = axes2->GetXAxisCaptionActor2D()->GetCaptionTextProperty();
tprop2->ItalicOn();
tprop2->ShadowOn();
tprop2->SetFontFamilyToTimes();
axes2->GetYAxisCaptionActor2D()->GetCaptionTextProperty()->ShallowCopy( tprop2 );
axes2->GetZAxisCaptionActor2D()->GetCaptionTextProperty()->ShallowCopy( tprop2 );
vtkOrientationMarkerWidget *widget = vtkOrientationMarkerWidget::New();
widget->SetOutlineColor( 0.9300, 0.5700, 0.1300 );
widget->SetOrientationMarker( axes2 );
widget->SetInteractor( iren );
widget->SetViewport( 0.85, 0.0, 1, 0.2 );
widget->SetEnabled( 1 );
widget->InteractiveOff();
widget->InteractiveOn();
/天空纹理
vtkJPEGReader *pnm1=vtkJPEGReader::New();
pnm1-> SetFileName("高山云海_04.jpg");
vtkTexture *atext=vtkTexture::New();
atext-> SetInputConnection(pnm1->GetOutputPort());
atext-> InterpolateOn();
vtkSphereSource *sphere1 = vtkSphereSource::New();
sphere1->SetThetaResolution(100);
sphere1->SetPhiResolution(100);
sphere1->SetRadius(100);
vtkPlane *plane1=vtkPlane::New();
plane1->SetNormal(0,0,1);//设置切平面的法向量
plane1->SetOrigin(1,0,0);
vtkClipPolyData *clipper=vtkClipPolyData::New();
clipper->SetInputConnection(sphere1-> GetOutputPort());
clipper->SetClipFunction(plane1);
clipper->InsideOutOff();
vtkPolyDataNormals *normals=vtkPolyDataNormals::New();
normals-> SetInputConnection (clipper->GetOutputPort());
normals-> FlipNormalsOn();
vtkTextureMapToCylinder *tmapper=vtkTextureMapToCylinder::New();
tmapper->SetInput(normals->GetOutput());
tmapper->PreventSeamOn();
vtkTransformTextureCoords *xform=vtkTransformTextureCoords::New();
xform-> SetInputConnection(tmapper-> GetOutputPort());
xform-> SetScale( 1, 1, 1);
vtkDataSetMapper *franMapper=vtkDataSetMapper::New();
franMapper-> SetInputConnection(xform-> GetOutputPort());
vtkActor *franActor =vtkActor::New();
franActor -> SetMapper (franMapper);
franActor -> SetTexture (atext);
franActor -> SetPosition(100,100,0);
ren1->AddActor(skin1);
ren1->AddActor(txt);
ren1->AddActor(feidie);
ren1->AddActor(franActor);
ren1->SetBackground( 0.0, 0.6, 1.0 );
aCamera = vtkCamera::New();
ren1->SetActiveCamera(aCamera);
ren1->ResetCamera();
aCamera->SetPosition(100,100,5);
aCamera->SetFocalPoint(110,100,5);
aCamera->SetViewUp(0,0,1);
feidie->SetPosition(103,100,5);
// record events
recorder = vtkInteractorEventRecorder::New();
recorder->SetInteractor(iren);
recorder->ReadFromInputStringOn();
recorder->SetInputString(BoxWidgetEventLog);
//调整视窗大小
renWin->SetSize( 800, 600 );
iren-> SetInteractorStyle(style);
iren->Initialize();
renWin->Render();
recorder->Play();
recorder->Off();
iren->Start();
// dr->Delete();
ren1->Delete();
renWin->Delete();
iren->Delete();
return 0;
}
void keypress(vtkObject *caller, unsigned long eid, void *clientdata, void *calldata)
{
char key=iren->GetKeyCode();
double normal[3];
double focal[3];
double position[3];
double view[3];
switch (key)
{
case '8':
aCamera->GetViewPlaneNormal (normal);
aCamera->GetFocalPoint(focal);
aCamera->GetPosition(position);
position[0]=position[0]-pos*normal[0];
position[1]=position[1]-pos*normal[1];
//position[2]=position[2]-pos*normal[2];
focal[0]=focal[0]-pos*normal[0];
focal[1]=focal[1]-pos*normal[1];
//focal[2]=focal[2]-pos*normal[2];
aCamera->SetPosition(position);
aCamera->SetFocalPoint(focal);
break;
case '5':
aCamera->GetViewPlaneNormal (normal);
aCamera->GetFocalPoint(focal);
aCamera->GetPosition(position);
position[0]=position[0]+pos*normal[0];
position[1]=position[1]+pos*normal[1];
//position[2]=position[2]+pos*normal[2];
focal[0]=focal[0]+pos*normal[0];
focal[1]=focal[1]+pos*normal[1];
//focal[2]=focal[2]+pos*normal[2];
aCamera->SetPosition(position);
aCamera->SetFocalPoint(focal);
break;
case '6':
aCamera->Yaw (-pos);
break;
case '4':
aCamera->Yaw (pos);
break;
case 'n':
aCamera->Pitch(-pos);
break;
case 'm':
aCamera->Pitch(pos);
break;
case '+':
pos=pos+1;
printf("%d\n",pos);
break;
case '-':
pos=pos-1;
printf("%d\n",pos);
break;
case '.':
aCamera->GetViewPlaneNormal (normal);
aCamera->GetFocalPoint(focal);
focal[0]=focal[0]+normal[0];
focal[1]=focal[1]+normal[1];
focal[2]=focal[2]+normal[2];
aCamera->SetFocalPoint(focal);
break;
case ',':
aCamera->GetViewPlaneNormal (normal);
aCamera->GetFocalPoint(focal);
focal[0]=focal[0]-normal[0];
focal[1]=focal[1]-normal[1];
focal[2]=focal[2]-normal[2];
aCamera->SetFocalPoint(focal);
break;
case 'v':
aCamera->SetViewUp(0,0,1);
break;
case 'c':
case '0':
aCamera->SetPosition(100,100,5);
aCamera->SetFocalPoint(110,100,5);
aCamera->SetViewUp(0,0,1);
recorder->Play();
recorder->Off();
break;
case 'b':
if (feidie->GetVisibility())
feidie->VisibilityOff();
else
feidie->VisibilityOn();
break;
case '*'://上
aCamera->GetFocalPoint(focal);
aCamera->GetPosition(position);
position[2]=position[2]-pos/3.0;
focal[2]=focal[2]-pos/3.0;
aCamera->SetPosition(position);
aCamera->SetFocalPoint(focal);
break;
case '/'://下
aCamera->GetFocalPoint(focal);
aCamera->GetPosition(position);
position[2]=position[2]+pos/3.0;
focal[2]=focal[2]+pos/3.0;
aCamera->SetPosition(position);
aCamera->SetFocalPoint(focal);
break;
}
aCamera->GetViewPlaneNormal (normal);
aCamera->GetFocalPoint(focal);
aCamera->GetPosition(position);
aCamera->GetViewUp(view);
double length;
length=sqrt((focal[0]-position[0])*(focal[0]-position[0])+
(focal[1]-position[1])*(focal[1]-position[1])+
(focal[2]-position[2])*(focal[2]-position[2]));
char text[300];
sprintf(text," Distance of focus: %f\n normal: %f,%f,%f\n position: %f,%f,%f\n focal: %f,%f,%f\n viewup: %f,%f,%f\n",
length,
normal[0],normal[1],normal[2],
position[0],position[1],position[2],
focal[0],focal[1],focal[2],
view[0],view[1],view[2]);
txt->SetInput(text);
if (feidie->GetVisibility())
{
double dp[3];
dp[0]=position[0]*dis+focal[0]*(1-dis);
dp[1]=position[1]*dis+focal[1]*(1-dis);
dp[2]=position[2]*dis+focal[2]*(1-dis);
feidie->SetPosition(dp);
}
renWin->Render();
}