www.pudn.com > SurfaceRecon.rar > MITKTestDoc.cpp
// MITKTestDoc.cpp : implementation of the CMITKTestDoc class // #include "stdafx.h" #include "MITKTest.h" #include "MITKTestDoc.h" #include "SpacingSetDlg.h" #include "RawSetDlg.h" #include "ThresholdDlg.h" #include "mitkVolume.h" #include "mitkMesh.h" #include "mitkIM0Reader.h" #include "mitkJPEGReader.h" #include "mitkDICOMReader.h" #include "mitkTIFFReader.h" #include "mitkBMPReader.h" #include "mitkRawReader.h" #include "mitkCacheVolumeReader.h" #include "mitkMarchingCubes.h" #include "mitkPLYBinaryWriter.h" #include#ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CMITKTestDoc IMPLEMENT_DYNCREATE(CMITKTestDoc, CDocument) BEGIN_MESSAGE_MAP(CMITKTestDoc, CDocument) //{{AFX_MSG_MAP(CMITKTestDoc) ON_COMMAND(ID_FILE_OPEN_BMP, OnFileOpenBmp) ON_COMMAND(ID_FILE_OPEN_DICOM, OnFileOpenDicom) ON_COMMAND(ID_FILE_OPEN_IM0, OnFileOpenIm0) ON_COMMAND(ID_FILE_OPEN_JPEG, OnFileOpenJpeg) ON_COMMAND(ID_FILE_OPEN_RAW, OnFileOpenRaw) ON_COMMAND(ID_FILE_OPEN_TIFF, OnFileOpenTiff) ON_COMMAND(ID_MC, OnMc) ON_COMMAND(ID_FILE_OPEN, OnFileOpen) ON_COMMAND(ID_FILE_SAVE, OnFileSave) ON_COMMAND(ID_FILE_OPEN_VOLCACHE, OnFileOpenVolcache) ON_COMMAND(ID_FILE_OPEN_VOLCACHE_BIN, OnFileOpenVolcacheBin) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CMITKTestDoc construction/destruction CMITKTestDoc::CMITKTestDoc() { // TODO: add one-time construction code here // 初始化指针变量 m_Volume = NULL; m_Mesh = NULL; } CMITKTestDoc::~CMITKTestDoc() { this->clearVolume(); //清理Volume数据 this->clearMesh(); //清理Mesh数据 } BOOL CMITKTestDoc::OnNewDocument() { if (!CDocument::OnNewDocument()) return FALSE; // TODO: add reinitialization code here // (SDI documents will reuse this document) return TRUE; } ///////////////////////////////////////////////////////////////////////////// // CMITKTestDoc serialization void CMITKTestDoc::Serialize(CArchive& ar) { if (ar.IsStoring()) { // TODO: add storing code here } else { // TODO: add loading code here } } ///////////////////////////////////////////////////////////////////////////// // CMITKTestDoc diagnostics #ifdef _DEBUG void CMITKTestDoc::AssertValid() const { CDocument::AssertValid(); } void CMITKTestDoc::Dump(CDumpContext& dc) const { CDocument::Dump(dc); } #endif //_DEBUG ///////////////////////////////////////////////////////////////////////////// // CMITKTestDoc commands void CMITKTestDoc::clearVolume() { if (m_Volume) { // 解除引用 m_Volume->RemoveReference(); // 这时候的m_Volume是无意义的指针,应将其置为NULL m_Volume = NULL; } } void CMITKTestDoc::clearMesh() { if (m_Mesh) { // 解除引用 m_Mesh->RemoveReference(); // 这时候的m_Mesh是无意义的指针,应将其置为NULL m_Mesh = NULL; } } void CMITKTestDoc::OnFileOpenBmp() { // TODO: Add your command handler code here // 生成打开文件对话框(可以选择多个文件) CFileDialog dlg(TRUE, ".bmp", NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | OFN_ALLOWMULTISELECT, "BMP文件(*.bmp)|*.bmp||", NULL); if (dlg.DoModal() == IDOK) { // 弹出设置像素间距的对话框 CSpacingSetDlg setDlg; if (setDlg.DoModal() == IDCANCEL) return; // 生成一个mitkBMPReader mitkBMPReader *reader = new mitkBMPReader; // 根据对话框中的数据设置像素间距 reader->SetSpacingX(setDlg.m_SpacingX); reader->SetSpacingY(setDlg.m_SpacingY); reader->SetSpacingZ(setDlg.m_SpacingZ); // 得到所有选中文件的文件名,加入到reader中。 // 各个切片在Volume中是有排列次序的,对于BMP文件来说,次序信息只能从文件名得到, // 但为简便起见,这儿省去了对文件名进行排序的过程 POSITION pos = dlg.GetStartPosition(); while (pos) reader->AddFileName(dlg.GetNextPathName(pos)); // 运行reader if (reader->Run()) { // 若无错误发生,则清除旧的数据,加载新的数据 this->clearVolume(); m_Volume = reader->GetOutput(); m_Volume->AddReference(); //重要! // 更新View中的显示 this->UpdateAllViews(NULL); } // 删除reader reader->Delete(); } } void CMITKTestDoc::OnFileOpenDicom() { // TODO: Add your command handler code here // 生成打开文件对话框(可以选择多个文件) CFileDialog dlg(TRUE, NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | OFN_ALLOWMULTISELECT, "DICOM文件(*.*)|*.*||", NULL); if (dlg.DoModal() == IDOK) { // 生成一个mitkDICOMReader mitkDICOMReader *reader = new mitkDICOMReader; // 得到所有选中文件的文件名,加入到reader中。 // DICOM文件本身包含了切片的位置信息,mitkDICOMReader会根据相关信息 // 对切片进行重排,所以这里只需要把文件名直接加入进去就可以了。 POSITION pos = dlg.GetStartPosition(); while (pos) reader->AddFileName(dlg.GetNextPathName(pos)); // 运行reader if (reader->Run()) { // 若无错误发生,则清除旧的数据,加载新的数据 this->clearVolume(); m_Volume = reader->GetOutput(); m_Volume->AddReference(); //重要! // 更新View中的显示 this->UpdateAllViews(NULL); } // 删除reader reader->Delete(); } } void CMITKTestDoc::OnFileOpenIm0() { // TODO: Add your command handler code here // 生成打开文件对话框 CFileDialog dlg(TRUE, ".im0", NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, "IM0文件(*.im0)|*.im0||", NULL); if (dlg.DoModal() == IDOK) { // 生成一个mitkIM0Reader mitkIM0Reader *reader = new mitkIM0Reader; // 一个IM0文件就包含一个Volume,只需加一个文件名 reader->AddFileName(dlg.GetPathName()); // out-of-core test #ifdef TEST_OOC reader->SetOoCSupport(DISK_CACHE_PATH, 8); #endif // 运行reader if (reader->Run()) { // 若无错误发生,则清除旧的数据,加载新的数据 this->clearVolume(); m_Volume = reader->GetOutput(); m_Volume->AddReference(); //重要! // 更新View中的显示 this->UpdateAllViews(NULL); } // 删除reader reader->Delete(); } } void CMITKTestDoc::OnFileOpenJpeg() { // TODO: Add your command handler code here // 生成打开文件对话框(可以选择多个文件) CFileDialog dlg(TRUE, ".jpg", NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | OFN_ALLOWMULTISELECT, "JPEG文件(*.jpeg;*.jpg)|*.jpeg;*.jpg||", NULL); if (dlg.DoModal() == IDOK) { // 弹出设置像素间距的对话框 CSpacingSetDlg setDlg; if (setDlg.DoModal() == IDCANCEL) return; // 生成一个mitkJPEGReader mitkJPEGReader *reader = new mitkJPEGReader; // 根据对话框中的数据设置像素间距 reader->SetSpacingX(setDlg.m_SpacingX); reader->SetSpacingY(setDlg.m_SpacingY); reader->SetSpacingZ(setDlg.m_SpacingZ); // 得到所有选中文件的文件名,加入到reader中。 // 各个切片在Volume中是有排列次序的,对于JPEG文件来说,次序信息只能从文件名得到, // 但为简便起见,这儿省去了对文件名进行排序的过程 POSITION pos = dlg.GetStartPosition(); while (pos) reader->AddFileName(dlg.GetNextPathName(pos)); // 运行reader if (reader->Run()) { // 若无错误发生,则清除旧的数据,加载新的数据 this->clearVolume(); m_Volume = reader->GetOutput(); m_Volume->AddReference(); //重要! // 更新View中的显示 this->UpdateAllViews(NULL); } // 删除reader reader->Delete(); } } void CMITKTestDoc::OnFileOpenRaw() { // TODO: Add your command handler code here // 生成打开文件对话框 CFileDialog dlg(TRUE, ".raw", NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, "Raw文件(*.raw;*.*)|*.raw;*.*||", NULL); if (dlg.DoModal() == IDOK) { // 弹出参数设置对话框 CRawSetDlg setDlg; if (setDlg.DoModal() == IDCANCEL) return; // 生成一个mitkRawReader mitkRawReader *reader = new mitkRawReader; // 根据对话框中的数据设置读取图像的参数 // 图像的尺寸以及切片数 reader->SetWidth(setDlg.m_Width); reader->SetHeight(setDlg.m_Height); reader->SetImageNum(setDlg.m_ImageNum); // 三个方向的像素间距 reader->SetSpacingX(setDlg.m_SpacingX); reader->SetSpacingY(setDlg.m_SpacingY); reader->SetSpacingZ(setDlg.m_SpacingZ); // 通道数 reader->SetChannelNum(setDlg.m_ChannelNum); // 数据类型 // 其值为MITK_CHAR、MITK_SHORT ... 中的一个, // 这些数据类型的定义参见mitkGlobal.h reader->SetDataType(setDlg.m_DataType); // 是否是大端序 reader->SetEndian((bool)(setDlg.m_IsBigEndian!=0)); // 各通道是否分开存储(按颜色平面存储) reader->SetPlanarCfg((bool)(setDlg.m_IsColorByPlane!=0)); reader->AddFileName(dlg.GetPathName()); if (reader->Run()) { // 若无错误发生,则清除旧的数据,加载新的数据 this->clearVolume(); m_Volume = reader->GetOutput(); m_Volume->AddReference(); //重要! // 更新View中的显示 this->UpdateAllViews(NULL); } // 删除reader reader->Delete(); } } void CMITKTestDoc::OnFileOpenTiff() { // TODO: Add your command handler code here // 生成打开文件对话框(可以选择多个文件) CFileDialog dlg(TRUE, ".tif", NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | OFN_ALLOWMULTISELECT, "TIFF文件(*.tif;*.tiff)|*.tif;*.tiff||", NULL); if (dlg.DoModal() == IDOK) { // 弹出设置像素间距的对话框 CSpacingSetDlg setDlg; if (setDlg.DoModal() == IDCANCEL) return; // 生成一个mitkTIFFReader mitkTIFFReader *reader = new mitkTIFFReader; // 根据对话框中的数据设置像素间距 reader->SetSpacingX(setDlg.m_SpacingX); reader->SetSpacingY(setDlg.m_SpacingY); reader->SetSpacingZ(setDlg.m_SpacingZ); // 得到所有选中文件的文件名,加入到reader中。 // 各个切片在Volume中是有排列次序的,对于TIFF文件来说,次序信息只能从文件名得到, // 但为简便起见,这儿省去了对文件名进行排序的过程 POSITION pos = dlg.GetStartPosition(); while (pos) reader->AddFileName(dlg.GetNextPathName(pos)); if (reader->Run()) { // 若无错误发生,则清除旧的数据,加载新的数据 this->clearVolume(); m_Volume = reader->GetOutput(); m_Volume->AddReference(); //重要! // 更新View中的显示 this->UpdateAllViews(NULL); } // 删除reader reader->Delete(); } } void CMITKTestDoc::OnMc() { // TODO: Add your command handler code here // 产生阈值设置对话框 CThresholdDlg dlg; // 显示阈值设置对话框 if (dlg.DoModal() == IDOK) { // 生成一个mitkMarchingCubes对象 mitkMarchingCubes *mc = new mitkMarchingCubes; // 将从对话框中得到的阈值设置给Marching Cubes算法 mc->SetThreshold(dlg.m_LowValue, dlg.m_HighValue); // 设置输入数据 mc->SetInput(m_Volume); // out-of-core test #ifdef TEST_OOC mc->SetOoCSupport(DISK_CACHE_PATH, 8); #endif // 测试算法运行时间 LARGE_INTEGER li; ::QueryPerformanceFrequency(&li); double frequency = (double)(li.QuadPart); ::QueryPerformanceCounter(&li); double counts = (double)(li.QuadPart); // 运行该算法,如果算法非正常结束则退出 if (!mc->Run()) return; ::QueryPerformanceCounter(&li); counts = (double)(li.QuadPart) - counts; double runtime = counts / frequency; // 清除旧的Mesh数据 this->clearMesh(); // 从mitkMarchingCubes算法得到输出结果 m_Mesh = mc->GetOutput(); m_Mesh->AddReference(); //重要 // 删除mitkMarchingCubes对象 mc->Delete(); CString msg; msg.Format("Vertices: %d\nTriangles: %d\nTime used: %fs", m_Mesh->GetVertexNumber(), m_Mesh->GetFaceNumber(), runtime); ::AfxMessageBox(msg); // 更新View UpdateAllViews(NULL); } } void CMITKTestDoc::OnFileOpen() { // TODO: Add your command handler code here CMenu menu; CMenu *pPopUp; menu.LoadMenu(IDR_MAINFRAME); pPopUp = menu.GetSubMenu(0); pPopUp = pPopUp->GetSubMenu(1); CWnd *mainFrame = AfxGetMainWnd(); CRect rect; mainFrame->GetWindowRect(rect); pPopUp->TrackPopupMenu(TPM_LEFTALIGN | TPM_LEFTBUTTON,rect.left+55,rect.top+65,mainFrame); } void CMITKTestDoc::OnFileSave() { // TODO: Add your command handler code here if (m_Mesh == NULL) return; CFileDialog dlg(FALSE, ".ply", NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, "PLY文件(*.ply)|*.ply||", NULL); if (dlg.DoModal() == IDOK) { mitkPLYBinaryWriter *writer = new mitkPLYBinaryWriter; writer->AddFileName(dlg.GetPathName()); writer->SetInput(m_Mesh); writer->Run(); writer->Delete(); } } void CMITKTestDoc::OnFileOpenVolcache() { // TODO: Add your command handler code here CFileDialog dlg(TRUE, ".volcfg", NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, "Volume设置文件(*.volcfg)|*.volcfg||", NULL); if (dlg.DoModal() == IDOK) { mitkCacheVolumeReader *reader = new mitkCacheVolumeReader; reader->AddFileName(dlg.GetPathName()); reader->SetConfigFileToBinary(false); if (reader->Run()) { // 若无错误发生,则清除旧的数据,加载新的数据 this->clearVolume(); m_Volume = reader->GetOutput(); m_Volume->AddReference(); //重要! // 更新View中的显示 this->UpdateAllViews(NULL); } // 删除reader reader->Delete(); } } void CMITKTestDoc::OnFileOpenVolcacheBin() { // TODO: Add your command handler code here CFileDialog dlg(TRUE, ".volbincfg", NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, "Volume设置文件(*.volbincfg)|*.volbincfg||", NULL); if (dlg.DoModal() == IDOK) { mitkCacheVolumeReader *reader = new mitkCacheVolumeReader; reader->AddFileName(dlg.GetPathName()); reader->SetConfigFileToBinary(true); if (reader->Run()) { // 若无错误发生,则清除旧的数据,加载新的数据 this->clearVolume(); m_Volume = reader->GetOutput(); m_Volume->AddReference(); //重要! // 更新View中的显示 this->UpdateAllViews(NULL); } // 删除reader reader->Delete(); } }