⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vtkview.cpp

📁 关于医学图象处理程序的VTK
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// VTKView.cpp : implementation of the CVTKView class
//

#include "stdafx.h"
#include "VTK.h"

#include "VTKDoc.h"
#include "VTKView.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CVTKView

IMPLEMENT_DYNCREATE(CVTKView, CView)

BEGIN_MESSAGE_MAP(CVTKView, CView)
	//{{AFX_MSG_MAP(CVTKView)
	ON_COMMAND(ID_FILE_DICOM3D, OnFileDicom3d)
	ON_WM_SIZE()
	ON_WM_CREATE()
	ON_WM_MOUSEWHEEL()
	ON_COMMAND(ID_CH_MARCHINGCUBES, OnChMarchingcubes)
	ON_COMMAND(ID_CH_IMAGEMCUBE, OnChImagemcube)
	ON_COMMAND(ID_CH_COUTOURFILTER, OnChCoutourfilter)
	ON_COMMAND(ID_CH_KITWAREFILTER, OnChKitwarefilter)
	ON_COMMAND(ID_CH_DIVIDINGCUBES, OnChDividingcubes)
	ON_COMMAND(ID_FILE_VTK, OnFileVtk)
	ON_COMMAND(ID_CH_DICOMTOVTK, OnChDicomtovtk)
	ON_COMMAND(ID_IMAGE_CHANGE, OnImageChange)
	ON_COMMAND(ID_FILE_OPEN, OnFileOpen)
	ON_COMMAND(ID_CH_RAYCAST, OnChRaycast)
	ON_COMMAND(ID_PR_GAUSSMOOTH, OnPrGaussmooth)
	//}}AFX_MSG_MAP
	// Standard printing commands
	ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CVTKView construction/destruction

CVTKView::CVTKView()
{
	// TODO: add construction code here
	m_Flag_DicomTovtk=FALSE;
	this->skinStripper = vtkStripper::New();
	m_num=0;
	for(int loop=0;loop<24;loop++)
	{
		this->m_viewer[loop]=vtkImageViewer::New();
		this->m_RenWinInter[loop]=vtkRenderWindowInteractor::New();
	}

}

CVTKView::~CVTKView()
{
	this->skinStripper->Delete();
	for(int loop=0;loop<24;loop++)
	{
		this->m_viewer[loop]->Delete();
		this->m_RenWinInter[loop]->Delete();
	}
}

BOOL CVTKView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs

	return CView::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CVTKView drawing

void CVTKView::OnDraw(CDC* pDC)
{
	CVTKDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	// TODO: add draw code for native data here
}

/////////////////////////////////////////////////////////////////////////////
// CVTKView printing

BOOL CVTKView::OnPreparePrinting(CPrintInfo* pInfo)
{
	// default preparation
	return DoPreparePrinting(pInfo);
}

void CVTKView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add extra initialization before printing
}

void CVTKView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add cleanup after printing
}

/////////////////////////////////////////////////////////////////////////////
// CVTKView diagnostics

#ifdef _DEBUG
void CVTKView::AssertValid() const
{
	CView::AssertValid();
}

void CVTKView::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}

CVTKDoc* CVTKView::GetDocument() // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CVTKDoc)));
	return (CVTKDoc*)m_pDocument;
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CVTKView message handlers

void CVTKView::OnFileDicom3d() 
{
	// TODO: Add your command handler code here
	CVTKDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	// TODO: Add your command handler code here
    //CDICOM3DDlg m_DICOM3DDlg;
    //m_DICOM3DDlg.DoModal();
//////////////////////////////////////////////////////////////////////////
	CString	m_path;

	TCHAR szPath[_MAX_PATH];
	BROWSEINFO bi;
	bi.hwndOwner=m_hWnd;
	bi.pidlRoot=NULL;
	bi.lpszTitle=_T("选择DICOM文件夹:");
	bi.pszDisplayName=szPath;
	bi.ulFlags=BIF_RETURNONLYFSDIRS;
	bi.lpfn=NULL;
	bi.lParam=NULL;
	LPITEMIDLIST pItemIDList=SHBrowseForFolder(&bi);
	if(pItemIDList)
	{
		TCHAR szPath[_MAX_PATH];
		if(SHGetPathFromIDList(pItemIDList,szPath))
		{			
				/*		CString cs;
				cs.Format("选定的文件夹是 :%s",szPath);
				AfxMessageBox("cs");*/
			pDoc->m_vtkproc.SetFlag3D(TRUE);

			m_path=szPath;
			UpdateData(FALSE);
		}
		IMalloc* pMalloc;
		if(SHGetMalloc(&pMalloc)!=NOERROR)
		{
			TRACE(_T("无法取得外壳程序的接口\n"));
		}
		pMalloc->Free(pItemIDList);
		if(pMalloc)
		pMalloc->Release();
	}
////////////////////////////////////////////////////////////////////////////
	if(pDoc->m_vtkproc.GetFlag3D()==TRUE)
	{
		pDoc->m_vtkproc.GetDICOMReader3D()->SetDataByteOrderToLittleEndian ();
		//pDoc->m_vtkproc.GetDICOMReader3D()->SetDataExtent(0,63,0,63,1,81);

		pDoc->m_vtkproc.GetDICOMReader3D()->SetDirectoryName (m_path);
		//pDoc->m_vtkproc.GetDICOMReader3D()->SetDataSpacing(pDoc->m_vtkproc.GetDICOMReader3D()->GetPixelSpacing()); //设置切片之间的间距和像素之间的间距


		vtkImageExport *exporter = vtkImageExport::New();
		exporter->SetInput(pDoc->m_vtkproc.GetDICOMReader3D()->GetOutput());
		exporter->ImageLowerLeftOn();

		int memsize = exporter->GetDataMemorySize();
		int *dimensions = exporter->GetDataDimensions();
		m_slice=dimensions[2];

		char *data = new char[memsize];
		exporter->Export(data);

		vtkImageImport *importer = vtkImageImport::New();
		importer->SetWholeExtent(1,dimensions[0],1,dimensions[1],1,dimensions[2]);
		importer->SetDataExtentToWholeExtent();
		importer->SetImportVoidPointer(data);

		vtkImageViewer *viewer = vtkImageViewer::New();
		viewer->SetInput(pDoc->m_vtkproc.GetDICOMReader3D()->GetOutput());
		viewer->SetPosition(200,100);

		viewer->SetColorWindow(1000);
		viewer->SetColorLevel(400);
		for(int s1=0;s1<dimensions[2];s1+=1)
		{
			viewer->SetZSlice(s1);
			viewer->Render();
		
			/*time_t start_time;
			time_t current_time;
			time(&start_time);
				do
			{
				time(&current_time);
			}
			while(difftime(current_time,start_time)<0.01);*/
		}
		viewer->Delete();

		CRect rect;
		this->GetClientRect(&rect);
		int m_x,m_y;
		m_x=(rect.right-rect.left-128*6)/2;
		m_y=(rect.bottom-rect.top-128*4)/2;

		vtkImageShrink3D *color=vtkImageShrink3D::New();
		color->SetInput(pDoc->m_vtkproc.GetDICOMReader3D()->GetOutput());
		color->SetShrinkFactors(4,4,1);

		for(int s2=0;s2<24;s2+=1)
		{
			if(m_x>0&&m_y>0)
				m_viewer[s2]->SetPosition(m_x+(s2%6)*128,m_y+(s2/6)*128);
			else if(m_x>0&&m_y<=0)
				m_viewer[s2]->SetPosition(m_x+(s2%6)*128,(s2/6)*128);
			else if(m_x<=0&&m_y>0)
				m_viewer[s2]->SetPosition((s2%6)*128,m_y+(s2/6)*128);
			else
				m_viewer[s2]->SetPosition((s2%6)*128,(s2/6)*128);


			m_viewer[s2]->SetInput(color->GetOutput());
			m_viewer[s2]->SetZSlice(s2);
			m_viewer[s2]->SetupInteractor(m_RenWinInter[s2]);
			m_viewer[s2]->Render();
		}

		delete data;
		color->Delete();
		exporter->Delete();
		importer->Delete();

	}
}


void CVTKView::OnSize(UINT nType, int cx, int cy) 
{
	CView::OnSize(nType, cx, cy);
	
	// TODO: Add your message handler code here
	CRect rect;
	this->GetClientRect(&rect);
	int m_x,m_y;
	m_x=(rect.right-rect.left-128*6)/2;
	m_y=(rect.bottom-rect.top-128*4)/2;
	for(int i=0;i<24;i++)
		m_viewer[i]->SetPosition(m_x+(i)%6*128,m_y+(i)/6*128);
}

int CVTKView::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (CView::OnCreate(lpCreateStruct) == -1)
		return -1;
	
	// TODO: Add your specialized creation code here
/*	CRect rect;
	this->GetClientRect(&rect);
	int m_x,m_y;
	m_x=(rect.right-rect.left-128*6)/2;
	m_y=(rect.bottom-rect.top-128*4)/2;*/
	for(int i=0;i<24;i++)
	{
//		m_viewer[i]->SetPosition(m_x+(i%6)*128,m_y+(i/6)*128);
		m_viewer[i]->SetSize(128,128);
		m_viewer[i]->SetColorWindow(1000);
		m_viewer[i]->SetColorLevel(200);
		m_viewer[i]->SetParentId(m_hWnd);
	}
	return 0;
}

BOOL CVTKView::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt) 
{
	CVTKDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	// TODO: Add your message handler code here and/or call default
	CRect rect;
	this->GetClientRect(&rect);
	int m_x,m_y;
	m_x=(rect.right-rect.left-128*6)/2;
	m_y=(rect.bottom-rect.top-128*4)/2;

	vtkImageShrink3D *color=vtkImageShrink3D::New();
	color->SetInput(pDoc->m_vtkproc.GetDICOMReader3D()->GetOutput());
	color->SetShrinkFactors(4,4,1);
	
	if((m_slice-m_num)>24)
	{
		m_num+=24;
		if((m_slice-m_num)>24)
		{
			for(int s2=0;s2<24;s2+=1)
			{
				m_viewer[s2]->SetPosition(m_x+(s2%6)*128,m_y+(s2/6)*128);
				m_viewer[s2]->SetZSlice(s2+m_num);
				m_viewer[s2]->Render();
			}
		}
		else 
		{
			int m_s=m_slice-m_num;
			for(int s2=0;s2<m_s;s2++)
			{
			m_viewer[s2]->SetZSlice(s2+m_num);
			m_viewer[s2]->Render();
			}
			for(int s4=m_s;s4<24;s4++)
			{
			m_viewer[s4]->SetZSlice(m_slice);
			m_viewer[s4]->Render();
			}
		}
	}
	else
	{
		m_num=0;
		for(int s3=0;s3<24;s3+=1)
		{
			m_viewer[s3]->SetZSlice(s3);
			m_viewer[s3]->Render();
		}
	}
    color->Delete();
	return CView::OnMouseWheel(nFlags, zDelta, pt);
}

void CVTKView::OnChMarchingcubes() 
{
	CVTKDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	// TODO: Add your command handler code here		
	if(pDoc->m_vtkproc.GetFlag3D()==TRUE)
	{
		m_Flag_DicomTovtk=TRUE;
		CDICOM3DDlg m_dicom3ddlg;
		m_dicom3ddlg.DoModal();

		vtkRenderer *aRenderer = vtkRenderer::New();
		vtkRenderWindow *renWin = vtkRenderWindow::New();
		renWin->AddRenderer(aRenderer);
		vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New();
		iren->SetRenderWindow(renWin);

		pDoc->m_vtkproc.GetMarchingCubes()->SetInput(pDoc->m_vtkproc.GetDICOMReader3D()->GetOutput()); //获得所读取的CT 数据
		pDoc->m_vtkproc.GetMarchingCubes()->SetValue(0, m_dicom3ddlg.m_extract); //提取出CT 值为500 的皮肤

		vtkPolyDataNormals *skinNormals = vtkPolyDataNormals::New();
		skinNormals->SetInput(pDoc->m_vtkproc.GetMarchingCubes()->GetOutput());
		skinNormals->SetFeatureAngle(60.0);

		//vtkStripper *skinStripper = vtkStripper::New(); //建立三角带对象
		this->skinStripper->SetInput(skinNormals->GetOutput()); //将生成的三角片连接成三角带

		vtkPolyDataMapper *skinMapper = vtkPolyDataMapper::New(); //建立一个数据映射对象
		skinMapper->SetInput(skinStripper->GetOutput()); //将三角带映射为几何数据

		vtkActor *skin = vtkActor::New(); //建立一个代表皮肤的演员
		skin->SetMapper(skinMapper); //获得皮肤几何数据的属性
		//skin->GetProperty()->SetDiffuseColor(0.5, 0.5, 0); //设置皮肤颜色的属性
		skin->GetProperty()->SetColor(0.6, 0.6, 0.6);
		//skin->GetProperty()->SetSpecular(0.3); //设置反射率
		//skin->GetProperty()->SetSpecularPower(20); //设置反射光强度
		skin->RotateX(90);
	
		vtkRenderer *ren1=vtkRenderer::New();
		ren1->AddActor(skin);
		ren1->SetBackground(0,0,0);

		renWin->AddRenderer(ren1);
		iren->SetRenderWindow(renWin);
		renWin->SetSize( 500, 500 );

		iren->Initialize();
		iren->Start();

//		skinStripper->Delete();
		skinMapper->Delete();
		skin->Delete();
		ren1->Delete();
		renWin->Delete();
		iren->Delete();
		skinNormals->Delete();

	}
	else
		AfxMessageBox("先打开一DICOM序列!");
}

void CVTKView::OnChImagemcube() 
{
	CVTKDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	// TODO: Add your command handler code here
	if(pDoc->m_vtkproc.GetFlag3D()==TRUE)
	{
		m_Flag_DicomTovtk=TRUE;
		CDICOM3DDlg m_dicom3ddlg;
		m_dicom3ddlg.DoModal();

		vtkRenderer *aRenderer = vtkRenderer::New();
		vtkRenderWindow *renWin = vtkRenderWindow::New();
		renWin->AddRenderer(aRenderer);
		vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New();
		iren->SetRenderWindow(renWin);

		vtkImageMarchingCubes *iso=vtkImageMarchingCubes::New();
		iso->SetInput(pDoc->m_vtkproc.GetDICOMReader3D()->GetOutput());
		iso->SetValue(0,m_dicom3ddlg.m_extract);
		//iso->SetInputMemoryLimit(1000);

		vtkPolyDataNormals *skinNormals = vtkPolyDataNormals::New();
		skinNormals->SetInput(iso->GetOutput());
		skinNormals->SetFeatureAngle(60.0);

//		vtkStripper *skinStripper = vtkStripper::New();
		this->skinStripper->SetInput(skinNormals->GetOutput());

		vtkPolyDataMapper *skinMapper = vtkPolyDataMapper::New();
		skinMapper->SetInput(skinStripper->GetOutput());
		skinMapper->ScalarVisibilityOff();

		vtkActor *skin = vtkActor::New(); 
		skin->SetMapper(skinMapper); 
		skin->GetProperty()->SetColor(1, 0.7, 0.6);
		skin->RotateX(90);
	
		vtkRenderer *ren1=vtkRenderer::New();
		ren1->AddActor(skin);
		ren1->SetBackground(0,0,0);

		renWin->AddRenderer(ren1);
		iren->SetRenderWindow(renWin);
		renWin->SetSize( 500, 500 );

		iren->Initialize();
		iren->Start();
//iren->Render();

		skinMapper->Delete();
		skin->Delete();
		ren1->Delete();
		renWin->Delete();
		iren->Delete();
		iso->Delete();
//		skinStripper->Delete();
		skinNormals->Delete();

	}
	else
		AfxMessageBox("先打开一DICOM序列!");
}

void CVTKView::OnChCoutourfilter() 
{
	CVTKDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	// TODO: Add your command handler code here
	if(pDoc->m_vtkproc.GetFlag3D()==TRUE)
	{
		m_Flag_DicomTovtk=TRUE;
		CDICOM3DDlg m_dicom3ddlg;
		m_dicom3ddlg.DoModal();

		vtkRenderer *aRenderer = vtkRenderer::New();
		vtkRenderWindow *renWin = vtkRenderWindow::New();
		renWin->AddRenderer(aRenderer);
		vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New();
		iren->SetRenderWindow(renWin);

		pDoc->m_vtkproc.GetContourFilter()->SetInput(pDoc->m_vtkproc.GetDICOMReader3D()->GetOutput()); //获得所读取的CT 数据
		pDoc->m_vtkproc.GetContourFilter()->SetValue(0, m_dicom3ddlg.m_extract); //提取出CT 值为500 的皮肤

		vtkPolyDataNormals *skinNormals = vtkPolyDataNormals::New();
		skinNormals->SetInput(pDoc->m_vtkproc.GetContourFilter()->GetOutput());
		skinNormals->SetFeatureAngle(60.0);

		this->skinStripper->SetInput(skinNormals->GetOutput());

		vtkPolyDataMapper *skinMapper = vtkPolyDataMapper::New();
		skinMapper->SetInput(skinStripper->GetOutput());
		skinMapper->ScalarVisibilityOff();

		vtkActor *skin = vtkActor::New(); 
		skin->SetMapper(skinMapper); 
		skin->GetProperty()->SetColor(1, 0.7, 0.6);
		skin->RotateX(90);
	
		vtkRenderer *ren1=vtkRenderer::New();
		ren1->AddActor(skin);
		ren1->SetBackground(0,0,0);

		renWin->AddRenderer(ren1);
		iren->SetRenderWindow(renWin);
		renWin->SetSize( 500, 500 );

		iren->Initialize();
		iren->Start();

		skinMapper->Delete();
		skin->Delete();
		ren1->Delete();
		renWin->Delete();
		iren->Delete();

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -