├── NMRI
├── res
│ ├── NMRI.ico
│ ├── NMRI.rc2
│ ├── NMRIDoc.ico
│ ├── Toolbar.bmp
│ ├── Toolbar256.bmp
│ ├── properties.bmp
│ ├── properties_hc.bmp
│ ├── properties_wnd.ico
│ └── properties_wnd_hc.ico
├── UserImages.bmp
├── stdafx.cpp
├── NMRI.vcxproj.user
├── targetver.h
├── FFT.cpp
├── NMRI.h
├── NMRIDoc.h
├── NMRIView.h
├── NMRIFile.cpp
├── MainFrm.h
├── MemoryBitmap.h
├── stdafx.h
├── resource.h
├── PropertiesWnd.h
├── NMRIFile.h
├── VTKView.h
├── NMRIDoc.cpp
├── NMRI.vcxproj.filters
├── MemoryBitmap.cpp
├── NMRIView.cpp
├── NMRI.cpp
├── ReadMe.txt
├── PropertiesWnd.cpp
├── FFT.h
├── MainFrm.cpp
├── NMRI.rc
├── VTKView.cpp
└── NMRI.vcxproj
├── .gitignore
├── NMRI.sln
├── README.md
└── LICENSE
/NMRI/res/NMRI.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aromanro/NMRI/HEAD/NMRI/res/NMRI.ico
--------------------------------------------------------------------------------
/NMRI/res/NMRI.rc2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aromanro/NMRI/HEAD/NMRI/res/NMRI.rc2
--------------------------------------------------------------------------------
/NMRI/UserImages.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aromanro/NMRI/HEAD/NMRI/UserImages.bmp
--------------------------------------------------------------------------------
/NMRI/res/NMRIDoc.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aromanro/NMRI/HEAD/NMRI/res/NMRIDoc.ico
--------------------------------------------------------------------------------
/NMRI/res/Toolbar.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aromanro/NMRI/HEAD/NMRI/res/Toolbar.bmp
--------------------------------------------------------------------------------
/NMRI/res/Toolbar256.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aromanro/NMRI/HEAD/NMRI/res/Toolbar256.bmp
--------------------------------------------------------------------------------
/NMRI/res/properties.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aromanro/NMRI/HEAD/NMRI/res/properties.bmp
--------------------------------------------------------------------------------
/NMRI/res/properties_hc.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aromanro/NMRI/HEAD/NMRI/res/properties_hc.bmp
--------------------------------------------------------------------------------
/NMRI/res/properties_wnd.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aromanro/NMRI/HEAD/NMRI/res/properties_wnd.ico
--------------------------------------------------------------------------------
/NMRI/res/properties_wnd_hc.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aromanro/NMRI/HEAD/NMRI/res/properties_wnd_hc.ico
--------------------------------------------------------------------------------
/NMRI/stdafx.cpp:
--------------------------------------------------------------------------------
1 |
2 | // stdafx.cpp : source file that includes just the standard includes
3 | // NMRI.pch will be the pre-compiled header
4 | // stdafx.obj will contain the pre-compiled type information
5 |
6 | #include "stdafx.h"
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | .vs/NMRI/v15/.suo
3 | *.db
4 | *.ipch
5 | .vs/NMRI/v16/.suo
6 | *.dat
7 | *.obj
8 | *.APS
9 | *.log
10 | *.pch
11 | *.res
12 | *.tlog
13 | *.txt
14 | *.pdb
15 | *.lastcodeanalysissucceeded
16 | *.iobj
17 | *.ipdb
18 | *.exe
19 |
--------------------------------------------------------------------------------
/NMRI/NMRI.vcxproj.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | NMRI.rc
5 |
6 |
--------------------------------------------------------------------------------
/NMRI/targetver.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | // Including SDKDDKVer.h defines the highest available Windows platform.
4 |
5 | // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and
6 | // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.
7 |
8 | #include
9 |
--------------------------------------------------------------------------------
/NMRI/FFT.cpp:
--------------------------------------------------------------------------------
1 | #include "stdafx.h"
2 |
3 | #include "FFT.h"
4 |
5 | namespace Fourier {
6 | const int FFT::init = fftw_init_threads();
7 |
8 | std::mutex FFTWPlan::planMutex;
9 |
10 | FFT::FFT(int numThreads)
11 | {
12 | if (numThreads != 0) SetNumThreads(numThreads);
13 | }
14 |
15 | void FFT::SetNumThreads(int numThreads)
16 | {
17 | Clear();
18 |
19 | std::lock_guard lock(FFTWPlan::planMutex);
20 |
21 | fftw_plan_with_nthreads(numThreads);
22 | }
23 |
24 | }
--------------------------------------------------------------------------------
/NMRI/NMRI.h:
--------------------------------------------------------------------------------
1 |
2 | // NMRI.h : main header file for the NMRI application
3 | //
4 | #pragma once
5 |
6 | #ifndef __AFXWIN_H__
7 | #error "include 'stdafx.h' before including this file for PCH"
8 | #endif
9 |
10 | #include "resource.h" // main symbols
11 |
12 |
13 | // CNMRIApp:
14 | // See NMRI.cpp for the implementation of this class
15 | //
16 |
17 | class CNMRIApp : public CWinAppEx
18 | {
19 | public:
20 | CNMRIApp();
21 |
22 | // Implementation
23 | UINT m_nAppLook;
24 | BOOL m_bHiColorIcons;
25 |
26 | private:
27 | // Overrides
28 | BOOL InitInstance() override;
29 | void PreLoadState() override;
30 | void LoadCustomState() override;
31 | void SaveCustomState() override;
32 |
33 | afx_msg void OnAppAbout();
34 | DECLARE_MESSAGE_MAP()
35 | };
36 |
37 | extern CNMRIApp theApp;
38 |
--------------------------------------------------------------------------------
/NMRI/NMRIDoc.h:
--------------------------------------------------------------------------------
1 |
2 | // NMRIDoc.h : interface of the CNMRIDoc class
3 | //
4 |
5 |
6 | #pragma once
7 |
8 |
9 | #include "NMRIFile.h"
10 |
11 | class CNMRIDoc : public CDocument
12 | {
13 | protected: // create from serialization only
14 | CNMRIDoc() = default;
15 | DECLARE_DYNCREATE(CNMRIDoc)
16 |
17 | // Attributes
18 | public:
19 | NMRIFile theFile;
20 |
21 | bool animate = true;
22 |
23 | bool colorFunction = true;
24 | bool opacityFunction = true;
25 | bool gradientFunction = true;
26 | int opacityVal = 50;
27 | int gradientVal = 50;
28 |
29 | // Operations
30 | bool Load(const CString& name);
31 | void UpdateViews();
32 | void Update3DOptions();
33 |
34 | private:
35 | // Overrides
36 | BOOL OnNewDocument() override;
37 | void Serialize(CArchive& ar) override;
38 | #ifdef SHARED_HANDLERS
39 | void InitializeSearchContent() override;
40 | void OnDrawThumbnail(CDC& dc, LPRECT lprcBounds) override;
41 | #endif // SHARED_HANDLERS
42 |
43 | // Implementation
44 | #ifdef _DEBUG
45 | void AssertValid() const override;
46 | void Dump(CDumpContext& dc) const override;
47 | #endif
48 |
49 | // Generated message map functions
50 | DECLARE_MESSAGE_MAP()
51 |
52 | #ifdef SHARED_HANDLERS
53 | // Helper function that sets search content for a Search Handler
54 | void SetSearchContent(const CString& value);
55 | #endif // SHARED_HANDLERS
56 | };
57 |
--------------------------------------------------------------------------------
/NMRI.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 15
4 | VisualStudioVersion = 15.0.26730.12
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "NMRI", "NMRI\NMRI.vcxproj", "{0419845C-98D5-4E5F-8880-19315E366367}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|x64 = Debug|x64
11 | Debug|x86 = Debug|x86
12 | Release|x64 = Release|x64
13 | Release|x86 = Release|x86
14 | EndGlobalSection
15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
16 | {0419845C-98D5-4E5F-8880-19315E366367}.Debug|x64.ActiveCfg = Debug|x64
17 | {0419845C-98D5-4E5F-8880-19315E366367}.Debug|x64.Build.0 = Debug|x64
18 | {0419845C-98D5-4E5F-8880-19315E366367}.Debug|x86.ActiveCfg = Debug|Win32
19 | {0419845C-98D5-4E5F-8880-19315E366367}.Debug|x86.Build.0 = Debug|Win32
20 | {0419845C-98D5-4E5F-8880-19315E366367}.Release|x64.ActiveCfg = Release|x64
21 | {0419845C-98D5-4E5F-8880-19315E366367}.Release|x64.Build.0 = Release|x64
22 | {0419845C-98D5-4E5F-8880-19315E366367}.Release|x86.ActiveCfg = Release|Win32
23 | {0419845C-98D5-4E5F-8880-19315E366367}.Release|x86.Build.0 = Release|Win32
24 | EndGlobalSection
25 | GlobalSection(SolutionProperties) = preSolution
26 | HideSolutionNode = FALSE
27 | EndGlobalSection
28 | GlobalSection(ExtensibilityGlobals) = postSolution
29 | SolutionGuid = {223E4B78-3A33-4BE1-B565-953761FC21E2}
30 | EndGlobalSection
31 | EndGlobal
32 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # NMRI
2 | 2D Fourier Transform of Nuclear Magnetic Resonance Imaging raw data, 3D visualization with VTK
3 |
4 | [](https://app.codacy.com/gh/aromanro/NMRI?utm_source=github.com&utm_medium=referral&utm_content=aromanro/NMRI&utm_campaign=Badge_Grade_Settings)
5 | [](https://www.codefactor.io/repository/github/aromanro/nmri)
6 |
7 | Description on https://compphys.go.ro/nuclear-magnetic-resonance-and-fourier-transform/
8 |
9 | Basically this is a quickly implemented project to test some wrapper classes for FFTW library: http://www.fftw.org/ Obviously, the project needs the FFTW library.
10 | A later addition was the 3D visualization, using VTK: https://vtk.org/
11 |
12 | It's a 2D Fourier Transform of Nuclear Magnetic Resonance Imaging raw data. It displays both the raw data and the image, allows cutting out low and high frequency information.
13 | It also has a 3D view implemented with VTK.
14 |
15 | It needs the Head2D.dat raw data file one can find here: http://download.nvidia.com/developer/GPU_Gems_2/CD/Index.html in the source tree from Chap. 48, Medical Image Reconstruction with the FFT.
16 | By the way, here is the chapter, in case somebody wants to look over it: https://developer.nvidia.com/gpugems/GPUGems2/gpugems2_chapter48.html
17 |
18 | ### PROGRAM IN ACTION
19 |
20 | [](https://youtu.be/toGlT4gNKds)
21 |
--------------------------------------------------------------------------------
/NMRI/NMRIView.h:
--------------------------------------------------------------------------------
1 |
2 | // NMRIView.h : interface of the CNMRIView class
3 | //
4 |
5 | #pragma once
6 |
7 |
8 | #include "MemoryBitmap.h"
9 |
10 | class CNMRIView : public CView
11 | {
12 | protected: // create from serialization only
13 | CNMRIView() = default;
14 | DECLARE_DYNCREATE(CNMRIView)
15 |
16 | // Attributes
17 | public:
18 | CNMRIDoc* GetDocument() const;
19 |
20 | // Operations
21 | // Overrides
22 | private:
23 | void OnDraw(CDC* pDC) override; // overridden to draw this view
24 | BOOL PreCreateWindow(CREATESTRUCT& cs) override;
25 | BOOL OnPreparePrinting(CPrintInfo* pInfo) override;
26 | void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo) override;
27 | void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo) override;
28 |
29 | // Implementation
30 | #ifdef _DEBUG
31 | void AssertValid() const override;
32 | void Dump(CDumpContext& dc) const override;
33 | #endif
34 |
35 | MemoryBitmap img1;
36 | MemoryBitmap img2;
37 |
38 | int theFrame = 0;
39 | UINT_PTR timer = 0;
40 |
41 | // Generated message map functions
42 | afx_msg void OnFilePrintPreview();
43 | afx_msg void OnRButtonUp(UINT nFlags, CPoint point);
44 | afx_msg void OnContextMenu(CWnd* pWnd, CPoint point);
45 | afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
46 | afx_msg void OnDestroy();
47 | afx_msg BOOL OnEraseBkgnd(CDC* pDC);
48 | afx_msg void OnTimer(UINT_PTR nIDEvent);
49 |
50 | DECLARE_MESSAGE_MAP()
51 | };
52 |
53 | #ifndef _DEBUG // debug version in NMRIView.cpp
54 | inline CNMRIDoc* CNMRIView::GetDocument() const
55 | { return reinterpret_cast(m_pDocument); }
56 | #endif
57 |
58 |
--------------------------------------------------------------------------------
/NMRI/NMRIFile.cpp:
--------------------------------------------------------------------------------
1 | #include "stdafx.h"
2 | #include "NMRIFile.h"
3 |
4 |
5 | NMRIFile::NMRIFile()
6 | : filterHighFreqs(false), filterLowFreqs(false), NrFrames(0), Width(0), Height(0), themax(0), realData(nullptr), imgData(nullptr), theFrame(nullptr), srcFrame(nullptr), fft(4)
7 | {
8 | }
9 |
10 |
11 | NMRIFile::~NMRIFile()
12 | {
13 | delete[] srcFrame;
14 | delete[] theFrame;
15 | delete[] realData;
16 | delete[] imgData;
17 | }
18 |
19 |
20 | bool NMRIFile::Load(const CString& name)
21 | {
22 | FILE *f = nullptr;
23 | if (_wfopen_s(&f, (LPCWSTR)name, L"rb")) return false;
24 |
25 | fread(&NrFrames,sizeof(int),1,f);
26 | fread(&Width,sizeof(int),1,f);
27 | fread(&Height,sizeof(int),1,f);
28 |
29 | const int Size = Width * Height * NrFrames;
30 |
31 | delete[] realData;
32 | delete[] imgData;
33 | delete[] theFrame;
34 | delete[] srcFrame;
35 |
36 | fft.Clear();
37 |
38 | themax = 0;
39 |
40 | if (Size)
41 | {
42 | realData = new float[Size];
43 | imgData = new float[Size];
44 |
45 | fread(realData, sizeof(float)*Size, 1, f);
46 | fread(imgData, sizeof(float)*Size, 1, f);
47 |
48 | theFrame = new std::complex[Width*Height];
49 | srcFrame = new std::complex[Width*Height];
50 | }
51 | else
52 | {
53 | realData = nullptr;
54 | imgData = nullptr;
55 | theFrame = nullptr;
56 | srcFrame = nullptr;
57 | }
58 |
59 | fclose(f);
60 |
61 | for (int frame = 0; frame < NrFrames; ++frame)
62 | for (int x = 0; x < Width; ++x)
63 | for (int y = 0; y < Height; ++y)
64 | {
65 | const std::complex val = GetValue(frame, x, y);
66 |
67 | if (themax < std::norm(val)) themax = std::norm(val);
68 | }
69 |
70 | return true;
71 | }
72 |
--------------------------------------------------------------------------------
/NMRI/MainFrm.h:
--------------------------------------------------------------------------------
1 |
2 | // MainFrm.h : interface of the CMainFrame class
3 | //
4 |
5 | #pragma once
6 | #include "PropertiesWnd.h"
7 |
8 | class CMainFrame : public CFrameWndEx
9 | {
10 | protected: // create from serialization only
11 | CMainFrame();
12 | DECLARE_DYNCREATE(CMainFrame)
13 |
14 | // Attributes
15 | // Operations
16 | void Init();
17 |
18 | private:
19 | // Overrides
20 | BOOL PreCreateWindow(CREATESTRUCT& cs) override;
21 | BOOL LoadFrame(UINT nIDResource, DWORD dwDefaultStyle = WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE, CWnd* pParentWnd = nullptr, CCreateContext* pContext = nullptr) override;
22 |
23 | // Implementation
24 | #ifdef _DEBUG
25 | void AssertValid() const override;
26 | void Dump(CDumpContext& dc) const override;
27 | #endif
28 |
29 | // control bar embedded members
30 | CMFCMenuBar m_wndMenuBar;
31 | CMFCToolBar m_wndToolBar;
32 | CMFCStatusBar m_wndStatusBar;
33 | CMFCToolBarImages m_UserImages;
34 |
35 | CSplitterWnd m_wndSplitter;
36 |
37 | CPropertiesWnd m_wndProperties;
38 |
39 | // Generated message map functions
40 | afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
41 | afx_msg void OnViewCustomize();
42 | afx_msg LRESULT OnToolbarCreateNew(WPARAM wp, LPARAM lp);
43 | afx_msg void OnApplicationLook(UINT id);
44 | afx_msg void OnUpdateApplicationLook(CCmdUI* pCmdUI);
45 | BOOL OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext) override;
46 |
47 | DECLARE_MESSAGE_MAP()
48 |
49 | BOOL CreateDockingWindows();
50 | void SetDockingWindowIcons(BOOL bHiColorIcons);
51 |
52 | afx_msg void OnFileOpen();
53 | afx_msg void OnShowWindow(BOOL bShow, UINT nStatus);
54 | afx_msg void OnViewAnimation();
55 | afx_msg void OnUpdateViewAnimation(CCmdUI* pCmdUI);
56 | };
57 |
58 |
59 |
--------------------------------------------------------------------------------
/NMRI/MemoryBitmap.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | class MemoryBitmap
6 | {
7 | public:
8 | MemoryBitmap() = default;
9 | MemoryBitmap(const MemoryBitmap& other); // copy constructor
10 | MemoryBitmap(MemoryBitmap&& other) noexcept; // move constructor
11 | MemoryBitmap& operator=(const MemoryBitmap& other); //copy assignment operator
12 | MemoryBitmap& operator=(MemoryBitmap&& other) noexcept; // move assignment operator
13 |
14 | ~MemoryBitmap() noexcept;
15 |
16 | void SetSize(int width, int height);
17 |
18 | void SetMatrix(const double* results, int Width, int Height);
19 | void SetMatrix(const std::complex* results, int Width, int Height);
20 |
21 | void Draw(CDC* pDC) const;
22 | void Draw(CDC* pDC, CRect& rect, int origWidth = 0, int origHeight = 0) const;
23 |
24 | private:
25 | int m_width = 0;
26 | int m_height = 0;
27 |
28 | unsigned char* data = nullptr;
29 |
30 | inline int GetStrideLength() const {
31 | return 4 * ((m_width * 3 + 3) / 4);
32 | }
33 |
34 | inline COLORREF ConvertToColor(double value, int colorType, double minVal, double maxVal) const
35 | {
36 | COLORREF color = 0;
37 |
38 | if (value < minVal) value = minVal;
39 | else if (value > maxVal) value = maxVal;
40 |
41 | if (const double interval = maxVal - minVal; 0 == colorType) // two colors
42 | {
43 | const int B = static_cast((value - minVal) / interval * 255.);
44 | const int R = 255 - B;
45 |
46 | color = RGB(R, 0, B);
47 | }
48 | else if (int v = static_cast((value - minVal) / interval * 255. * 2.); v > 0xff)
49 | {
50 | v -= 0xff;
51 |
52 | const int B = v;
53 | const int G = 255 - v;
54 |
55 | color = RGB(0, G, B);
56 | }
57 | else
58 | {
59 | const int G = v;
60 | const int R = 255 - v;
61 |
62 | color = RGB(R, G, 0);
63 | }
64 |
65 | return color;
66 | }
67 | };
68 |
69 |
--------------------------------------------------------------------------------
/NMRI/stdafx.h:
--------------------------------------------------------------------------------
1 |
2 | // stdafx.h : include file for standard system include files,
3 | // or project specific include files that are used frequently,
4 | // but are changed infrequently
5 |
6 | #pragma once
7 |
8 | #ifndef VC_EXTRALEAN
9 | #define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers
10 | #endif
11 |
12 | #include "targetver.h"
13 |
14 | #define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors will be explicit
15 |
16 | // turns off MFC's hiding of some common and often safely ignored warning messages
17 | #define _AFX_ALL_WARNINGS
18 |
19 | #include // MFC core and standard components
20 | #include // MFC extensions
21 |
22 |
23 |
24 |
25 |
26 | #ifndef _AFX_NO_OLE_SUPPORT
27 | #include // MFC support for Internet Explorer 4 Common Controls
28 | #endif
29 | #ifndef _AFX_NO_AFXCMN_SUPPORT
30 | #include // MFC support for Windows Common Controls
31 | #endif // _AFX_NO_AFXCMN_SUPPORT
32 |
33 | #include // MFC support for ribbons and control bars
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 | #ifdef _UNICODE
44 | #if defined _M_IX86
45 | #pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"")
46 | #elif defined _M_X64
47 | #pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"")
48 | #else
49 | #pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
50 | #endif
51 | #endif
52 |
53 |
54 |
--------------------------------------------------------------------------------
/NMRI/resource.h:
--------------------------------------------------------------------------------
1 | //{{NO_DEPENDENCIES}}
2 | // Microsoft Visual C++ generated include file.
3 | // Used by NMRI.rc
4 | //
5 | #define IDD_ABOUTBOX 100
6 | #define ID_STATUSBAR_PANE1 120
7 | #define ID_STATUSBAR_PANE2 121
8 | #define IDS_STATUS_PANE1 122
9 | #define IDS_STATUS_PANE2 123
10 | #define IDS_TOOLBAR_STANDARD 124
11 | #define IDS_TOOLBAR_CUSTOMIZE 125
12 | #define ID_VIEW_CUSTOMIZE 126
13 | #define IDR_MAINFRAME 128
14 | #define IDR_MAINFRAME_256 129
15 | #define IDR_NMRITYPE 130
16 | #define ID_VIEW_PROPERTIESWND 150
17 | #define IDS_PROPERTIES_WND 158
18 | #define IDI_PROPERTIES_WND 167
19 | #define IDI_PROPERTIES_WND_HC 168
20 | #define IDR_THEME_MENU 200
21 | #define ID_SET_STYLE 201
22 | #define ID_VIEW_APPLOOK_WIN_2000 205
23 | #define ID_VIEW_APPLOOK_OFF_XP 206
24 | #define ID_VIEW_APPLOOK_WIN_XP 207
25 | #define ID_VIEW_APPLOOK_OFF_2003 208
26 | #define ID_VIEW_APPLOOK_VS_2005 209
27 | #define ID_VIEW_APPLOOK_VS_2008 210
28 | #define ID_VIEW_APPLOOK_OFF_2007_BLUE 215
29 | #define ID_VIEW_APPLOOK_OFF_2007_BLACK 216
30 | #define ID_VIEW_APPLOOK_OFF_2007_SILVER 217
31 | #define ID_VIEW_APPLOOK_OFF_2007_AQUA 218
32 | #define ID_VIEW_APPLOOK_WINDOWS_7 219
33 | #define IDS_EDIT_MENU 306
34 | #define IDC_MFCLINK1 1000
35 | #define IDC_MFCLINK2 1001
36 | #define ID_FILE_OEN 32771
37 | #define ID_VIEW_ 32772
38 | #define ID_VIEW_ANIMATION 32773
39 | #define ID_BUTTON32775 32775
40 |
41 | // Next default values for new objects
42 | //
43 | #ifdef APSTUDIO_INVOKED
44 | #ifndef APSTUDIO_READONLY_SYMBOLS
45 | #define _APS_NEXT_RESOURCE_VALUE 311
46 | #define _APS_NEXT_COMMAND_VALUE 32776
47 | #define _APS_NEXT_CONTROL_VALUE 1001
48 | #define _APS_NEXT_SYMED_VALUE 310
49 | #endif
50 | #endif
51 |
--------------------------------------------------------------------------------
/NMRI/PropertiesWnd.h:
--------------------------------------------------------------------------------
1 |
2 | #pragma once
3 |
4 | class CNMRIDoc;
5 |
6 |
7 | // for CSliderProp and CPropSliderCtrl see: https://github.com/jhlee8804/MFC-Feature-Pack/tree/master/NewControls
8 | // modified to allow setting a range
9 |
10 | class CSliderProp : public CMFCPropertyGridProperty
11 | {
12 | public:
13 | CSliderProp(const CString& strName, long nValue, long minVal = 0, long maxVal = 100, LPCTSTR lpszDescr = nullptr, DWORD dwData = 0);
14 |
15 | BOOL OnUpdateValue() override;
16 |
17 | private:
18 | CWnd* CreateInPlaceEdit(CRect rectEdit, BOOL& bDefaultFormat) override;
19 | BOOL OnSetCursor() const override { return FALSE; /* Use default */ }
20 |
21 | long m_minVal;
22 | long m_maxVal;
23 | };
24 |
25 | /////////////////////////////////////////////////////////////////////////////
26 | // CPropSliderCtrl window
27 |
28 | class CPropSliderCtrl : public CSliderCtrl
29 | {
30 | // Construction
31 | public:
32 | CPropSliderCtrl(CSliderProp* pProp, COLORREF clrBack);
33 |
34 | // Attributes
35 | private:
36 | CBrush m_brBackground;
37 | COLORREF m_clrBack;
38 | CSliderProp* m_pProp;
39 |
40 | // Implementation
41 |
42 | //{{AFX_MSG(CPropSliderCtrl)
43 | afx_msg HBRUSH CtlColor(CDC* pDC, UINT nCtlColor);
44 | //}}AFX_MSG
45 | afx_msg void HScroll(UINT nSBCode, UINT nPos);
46 |
47 | DECLARE_MESSAGE_MAP()
48 | };
49 |
50 |
51 | class CPropertiesWnd : public CDockablePane
52 | {
53 | // Construction
54 | public:
55 | void AdjustLayout() override;
56 |
57 | // Attributes
58 | void SetVSDotNetLook(BOOL bSet)
59 | {
60 | m_wndPropList.SetVSDotNetLook(bSet);
61 | m_wndPropList.SetGroupNameFullWidth(bSet);
62 | }
63 |
64 | CNMRIDoc* theDoc = nullptr;
65 |
66 | private:
67 | CMFCPropertyGridCtrl m_wndPropList;
68 |
69 | // Implementation
70 | void InitPropList();
71 |
72 | afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
73 | afx_msg void OnSize(UINT nType, int cx, int cy);
74 | afx_msg void OnSetFocus(CWnd* pOldWnd);
75 | afx_msg void OnSettingChange(UINT uFlags, LPCTSTR lpszSection);
76 | afx_msg LRESULT OnPropertyChanged(__in WPARAM wparam, __in LPARAM lparam);
77 |
78 | DECLARE_MESSAGE_MAP()
79 | };
80 |
81 |
--------------------------------------------------------------------------------
/NMRI/NMRIFile.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | #include "FFT.h"
6 |
7 | class NMRIFile
8 | {
9 | public:
10 | NMRIFile();
11 | ~NMRIFile();
12 |
13 | bool filterHighFreqs;
14 | bool filterLowFreqs;
15 |
16 | int NrFrames;
17 | int Width;
18 | int Height;
19 |
20 | int LowPassPercentage = 50;
21 | int HighPassPercentage = 50;
22 |
23 | bool Load(const CString& name);
24 |
25 | void FFT(int frame)
26 | {
27 | if (!Width || !Height) return;
28 |
29 | // this is done due of the order of the frames in the file!
30 | if (frame % 2) frame = frame / 2;
31 | else frame = NrFrames / 2 + frame / 2;
32 |
33 | Filter(frame);
34 | fft.fwd(srcFrame, theFrame, Width, Height);
35 |
36 | Normalize();
37 | }
38 |
39 | inline double GetRealValue(int posx, int posy) const
40 | {
41 | return std::abs(theFrame[Height*posx + posy]);
42 | }
43 |
44 | const std::complex* GetRealFrame() const { return theFrame; }
45 | const std::complex* GetFrame() const { return srcFrame; }
46 |
47 | private:
48 | inline std::complex GetValue(int frame, int posx, int posy) const
49 | {
50 | if (frame >= NrFrames) return std::complex(0, 0);
51 |
52 | const int pos = Width * Height * frame;
53 |
54 | const float re = realData[pos + Height * posx + posy];
55 | const float im = imgData[pos + Height * posx + posy];
56 |
57 | return std::complex(re, im);
58 | }
59 |
60 | inline void Normalize()
61 | {
62 | const double thenorm = sqrt(Width * Height);
63 |
64 | for (int x = 0; x < Width; ++x)
65 | for (int y = 0; y < Height; ++y)
66 | theFrame[y * Width + x] /= thenorm;
67 | }
68 |
69 | inline void Filter(int frame)
70 | {
71 | const double xCenter = Width / 2.;
72 | const double yCenter = Height / 2.;
73 |
74 | const double xLowPass = Width / 32. * LowPassPercentage / 100.;
75 | const double yLowPass = Height / 32. * LowPassPercentage / 100.;
76 |
77 | const double xLowLowLimit = xCenter - xLowPass;
78 | const double xHighLowLimit = xCenter + xLowPass;
79 | const double yLowLowLimit = yCenter - yLowPass;
80 | const double yHighLowLimit = yCenter + yLowPass;
81 |
82 | const double xHighPass = Width / 4. * (2. - HighPassPercentage / 100.);
83 | const double yHighPass = Height / 4. * (2. - HighPassPercentage / 100.);
84 |
85 |
86 | const double xLowHighLimit = xCenter - xHighPass;
87 | const double xHighHighLimit = xCenter + xHighPass;
88 | const double yLowHighLimit = yCenter - yHighPass;
89 | const double yHighHighLimit = yCenter + yHighPass;
90 |
91 | for (int x = 0; x < Width; ++x)
92 | for (int y = 0; y < Height; ++y)
93 | {
94 | if (filterLowFreqs && x > xLowLowLimit && x < xHighLowLimit && y > yLowLowLimit && y < yHighLowLimit)
95 | {
96 | srcFrame[y * Width + x] = 0;
97 | continue;
98 | }
99 |
100 | if (filterHighFreqs && (x < xLowHighLimit || x > xHighHighLimit || y < yLowHighLimit || y > yHighHighLimit))
101 | {
102 | srcFrame[y * Width + x] = 0;
103 | continue;
104 | }
105 |
106 | const std::complex val = GetValue(frame, x, y);
107 | srcFrame[y * Width + x] = (themax > 1E-14 ? val / themax : val);
108 | }
109 | }
110 |
111 | double themax;
112 |
113 | float* realData;
114 | float* imgData;
115 |
116 | std::complex* theFrame;
117 | std::complex* srcFrame;
118 |
119 | Fourier::FFT fft;
120 | };
121 |
122 |
--------------------------------------------------------------------------------
/NMRI/VTKView.h:
--------------------------------------------------------------------------------
1 |
2 | // VTKView.h : interface of the CVTKView class
3 | //
4 |
5 | #pragma once
6 |
7 |
8 | #ifdef _DEBUG
9 | #define new ::new
10 | #endif
11 |
12 | #include
13 | //#include
14 | #include
15 | #include
16 | #include
17 | #include
18 | #include
19 | #include
20 |
21 | #include
22 |
23 | #include
24 | #include
25 |
26 | #include
27 | #include
28 | #include
29 |
30 | #include
31 | #include
32 |
33 | #include
34 |
35 | #include
36 | #include
37 | #include
38 |
39 | #include
40 | #include
41 |
42 | #include
43 | #include
44 | #include
45 |
46 | #include
47 |
48 |
49 | #ifdef _DEBUG
50 | #undef new
51 | #endif
52 |
53 |
54 | class CVTKView;
55 |
56 | // class stolen from VTK examples and modified
57 |
58 | class ErrorObserver : public vtkCommand
59 | {
60 | public:
61 | static ErrorObserver *New();
62 |
63 | bool GetError() const
64 | {
65 | return Error;
66 | }
67 |
68 | bool GetWarning() const
69 | {
70 | return Warning;
71 | }
72 |
73 | void Clear()
74 | {
75 | Error = false;
76 | Warning = false;
77 | ErrorMessage = "";
78 | WarningMessage = "";
79 | }
80 |
81 | void Execute(vtkObject *vtkNotUsed(caller), unsigned long event, void *calldata) override;
82 |
83 | std::string GetErrorMessage() const
84 | {
85 | return ErrorMessage;
86 | }
87 |
88 | std::string GetWarningMessage() const
89 | {
90 | return WarningMessage;
91 | }
92 |
93 | void SetView(CVTKView* view)
94 | {
95 | theView = view;
96 | }
97 |
98 | private:
99 | CVTKView* theView = nullptr;
100 | bool Error = false;
101 | bool Warning = false;
102 | std::string ErrorMessage;
103 | std::string WarningMessage;
104 | };
105 |
106 |
107 | class CVTKView : public CView
108 | {
109 | protected: // create from serialization only
110 | CVTKView();
111 | DECLARE_DYNCREATE(CVTKView)
112 |
113 | static bool IsHandledMessage(UINT message);
114 |
115 | public:
116 | ~CVTKView() override;
117 | CNMRIDoc* GetDocument() const;
118 |
119 | // Operations
120 | void RecoverFromWarning();
121 | void GrabResultsFromDoc();
122 | void UpdateTransferFunctions();
123 |
124 | private:
125 | // Overrides
126 | void OnDraw(CDC* pDC) override; // overridden to draw this view
127 | BOOL OnPreparePrinting(CPrintInfo* pInfo) override;
128 | void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo) override;
129 | void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo) override;
130 |
131 | // Implementation
132 | void Pipeline();
133 |
134 | #ifdef _DEBUG
135 | void AssertValid() const override;
136 | void Dump(CDumpContext& dc) const override;
137 | #endif
138 |
139 | ErrorObserver* errorObserver = nullptr;
140 | vtkImageData* dataImage = nullptr;
141 |
142 | vtkWin32OpenGLRenderWindow *renWin;
143 | vtkRenderer *ren = nullptr;
144 | vtkWin32RenderWindowInteractor *iren = nullptr;
145 |
146 | vtkGPUVolumeRayCastMapper* volumeMapper = nullptr;
147 | vtkVolume* volume = nullptr;
148 |
149 | vtkSmartPointer textActor;
150 |
151 | unsigned int Width = 0;
152 | unsigned int Height = 0;
153 | unsigned int NrFrames = 0;
154 |
155 | // Generated message map functions
156 | afx_msg void OnFilePrintPreview();
157 | afx_msg void OnSize(UINT nType, int cx, int cy);
158 | afx_msg BOOL OnEraseBkgnd(CDC* pDC);
159 | void OnInitialUpdate() override;
160 | LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam) override;
161 | afx_msg void OnDestroy();
162 | //afx_msg void OnTimer(UINT_PTR nIDEvent);
163 |
164 | DECLARE_MESSAGE_MAP()
165 | };
166 |
167 | #ifndef _DEBUG // debug version in DFTView.cpp
168 | inline CNMRIDoc* CVTKView::GetDocument() const
169 | { return reinterpret_cast(m_pDocument); }
170 | #endif
171 |
172 |
--------------------------------------------------------------------------------
/NMRI/NMRIDoc.cpp:
--------------------------------------------------------------------------------
1 |
2 | // NMRIDoc.cpp : implementation of the CNMRIDoc class
3 | //
4 |
5 | #include "stdafx.h"
6 | // SHARED_HANDLERS can be defined in an ATL project implementing preview, thumbnail
7 | // and search filter handlers and allows sharing of document code with that project.
8 | #ifndef SHARED_HANDLERS
9 | #include "NMRI.h"
10 | #endif
11 |
12 | #include "NMRIDoc.h"
13 |
14 | #include "NMRIFile.h"
15 | #include "MainFrm.h"
16 |
17 | #include "VTKView.h"
18 |
19 | #include
20 |
21 | #ifdef _DEBUG
22 | #define new DEBUG_NEW
23 | #endif
24 |
25 | // CNMRIDoc
26 |
27 | IMPLEMENT_DYNCREATE(CNMRIDoc, CDocument)
28 |
29 | BEGIN_MESSAGE_MAP(CNMRIDoc, CDocument)
30 | END_MESSAGE_MAP()
31 |
32 |
33 | // CNMRIDoc construction/destruction
34 |
35 | BOOL CNMRIDoc::OnNewDocument()
36 | {
37 | if (!CDocument::OnNewDocument())
38 | return FALSE;
39 |
40 | // TODO: add reinitialization code here
41 | // (SDI documents will reuse this document)
42 |
43 | if (Load(L"Head2D.dat"))
44 | SetTitle(L"Head2D");
45 | else
46 | SetTitle(L"No file loaded");
47 |
48 | return TRUE;
49 | }
50 |
51 |
52 |
53 |
54 | // CNMRIDoc serialization
55 |
56 | void CNMRIDoc::Serialize(CArchive& ar)
57 | {
58 | if (ar.IsStoring())
59 | {
60 | // TODO: add storing code here
61 | }
62 | else
63 | {
64 | // TODO: add loading code here
65 | }
66 | }
67 |
68 | #ifdef SHARED_HANDLERS
69 |
70 | // Support for thumbnails
71 | void CNMRIDoc::OnDrawThumbnail(CDC& dc, LPRECT lprcBounds)
72 | {
73 | // Modify this code to draw the document's data
74 | dc.FillSolidRect(lprcBounds, RGB(255, 255, 255));
75 |
76 | CString strText = _T("TODO: implement thumbnail drawing here");
77 | LOGFONT lf;
78 |
79 | CFont* pDefaultGUIFont = CFont::FromHandle((HFONT) GetStockObject(DEFAULT_GUI_FONT));
80 | pDefaultGUIFont->GetLogFont(&lf);
81 | lf.lfHeight = 36;
82 |
83 | CFont fontDraw;
84 | fontDraw.CreateFontIndirect(&lf);
85 |
86 | CFont* pOldFont = dc.SelectObject(&fontDraw);
87 | dc.DrawText(strText, lprcBounds, DT_CENTER | DT_WORDBREAK);
88 | dc.SelectObject(pOldFont);
89 | }
90 |
91 | // Support for Search Handlers
92 | void CNMRIDoc::InitializeSearchContent()
93 | {
94 | CString strSearchContent;
95 | // Set search contents from document's data.
96 | // The content parts should be separated by ";"
97 |
98 | // For example: strSearchContent = _T("point;rectangle;circle;ole object;");
99 | SetSearchContent(strSearchContent);
100 | }
101 |
102 | void CNMRIDoc::SetSearchContent(const CString& value)
103 | {
104 | if (value.IsEmpty())
105 | {
106 | RemoveChunk(PKEY_Search_Contents.fmtid, PKEY_Search_Contents.pid);
107 | }
108 | else
109 | {
110 | CMFCFilterChunkValueImpl *pChunk = nullptr;
111 | ATLTRY(pChunk = new CMFCFilterChunkValueImpl);
112 | if (pChunk != nullptr)
113 | {
114 | pChunk->SetTextValue(PKEY_Search_Contents, value, CHUNK_TEXT);
115 | SetChunkValue(pChunk);
116 | }
117 | }
118 | }
119 |
120 | #endif // SHARED_HANDLERS
121 |
122 | // CNMRIDoc diagnostics
123 |
124 | #ifdef _DEBUG
125 | void CNMRIDoc::AssertValid() const
126 | {
127 | CDocument::AssertValid();
128 | }
129 |
130 | void CNMRIDoc::Dump(CDumpContext& dc) const
131 | {
132 | CDocument::Dump(dc);
133 | }
134 | #endif //_DEBUG
135 |
136 |
137 | // CNMRIDoc commands
138 |
139 |
140 | bool CNMRIDoc::Load(const CString& name)
141 | {
142 | if (theFile.Load(name))
143 | {
144 | theFile.FFT(0);
145 |
146 | return true;
147 | }
148 |
149 | return false;
150 | }
151 |
152 |
153 | void CNMRIDoc::UpdateViews()
154 | {
155 | POSITION pos = GetFirstViewPosition();
156 | while (pos != nullptr) {
157 | CView* pView = GetNextView(pos);
158 |
159 | // the other one refreshes itself by timer
160 | if (pView->IsKindOf(RUNTIME_CLASS(CVTKView)))
161 | {
162 | ((CVTKView*)pView)->GrabResultsFromDoc();
163 | ((CVTKView*)pView)->Invalidate();
164 | }
165 | }
166 | }
167 |
168 |
169 | void CNMRIDoc::Update3DOptions()
170 | {
171 | POSITION pos = GetFirstViewPosition();
172 | while (pos != nullptr) {
173 | CView* pView = GetNextView(pos);
174 |
175 | // the other one refreshes itself by timer
176 | if (pView->IsKindOf(RUNTIME_CLASS(CVTKView)))
177 | {
178 | ((CVTKView*)pView)->UpdateTransferFunctions();
179 | ((CVTKView*)pView)->Invalidate();
180 | }
181 | }
182 | }
--------------------------------------------------------------------------------
/NMRI/NMRI.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;hm;inl;inc;xsd
11 |
12 |
13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | Header Files
23 |
24 |
25 | Header Files
26 |
27 |
28 | Header Files
29 |
30 |
31 | Header Files
32 |
33 |
34 | Header Files
35 |
36 |
37 | Header Files
38 |
39 |
40 | Header Files
41 |
42 |
43 | Header Files
44 |
45 |
46 | Header Files
47 |
48 |
49 | Header Files
50 |
51 |
52 | Header Files
53 |
54 |
55 | Header Files
56 |
57 |
58 |
59 |
60 | Source Files
61 |
62 |
63 | Source Files
64 |
65 |
66 | Source Files
67 |
68 |
69 | Source Files
70 |
71 |
72 | Source Files
73 |
74 |
75 | Source Files
76 |
77 |
78 | Source Files
79 |
80 |
81 | Source Files
82 |
83 |
84 | Source Files
85 |
86 |
87 | Source Files
88 |
89 |
90 |
91 |
92 | Resource Files
93 |
94 |
95 |
96 |
97 | Resource Files
98 |
99 |
100 | Resource Files
101 |
102 |
103 | Resource Files
104 |
105 |
106 | Resource Files
107 |
108 |
109 | Resource Files
110 |
111 |
112 | Resource Files
113 |
114 |
115 | Resource Files
116 |
117 |
118 | Resource Files
119 |
120 |
121 | Resource Files
122 |
123 |
124 |
125 |
126 | Resource Files
127 |
128 |
129 |
--------------------------------------------------------------------------------
/NMRI/MemoryBitmap.cpp:
--------------------------------------------------------------------------------
1 | #include "stdafx.h"
2 | #include "MemoryBitmap.h"
3 |
4 |
5 | #include
6 | #include
7 |
8 | MemoryBitmap::MemoryBitmap(const MemoryBitmap& other) // copy constructor
9 | {
10 | if (other.data)
11 | {
12 | m_width = other.m_width;
13 | m_height = other.m_height;
14 | int size = GetStrideLength() * m_height;
15 | data = new unsigned char[size];
16 | memcpy(data, other.data, size);
17 | }
18 | else {
19 | data = nullptr;
20 | m_width = m_height = 0;
21 | }
22 | }
23 |
24 | MemoryBitmap::MemoryBitmap(MemoryBitmap&& other) noexcept // move constructor
25 | : data(other.data), m_width(other.m_width), m_height(other.m_height)
26 | {
27 | other.data = nullptr;
28 | other.m_height = other.m_width = 0;
29 | }
30 |
31 | MemoryBitmap& MemoryBitmap::operator=(const MemoryBitmap& other) //copy assignment operator
32 | {
33 | MemoryBitmap temp(other);
34 |
35 | *this = std::move(temp);
36 |
37 | return *this;
38 | }
39 |
40 | MemoryBitmap& MemoryBitmap::operator=(MemoryBitmap&& other) noexcept // move assignment operator
41 | {
42 | delete[] data;
43 |
44 | m_width = other.m_width;
45 | m_height = other.m_height;
46 |
47 | data = other.data;
48 |
49 | other.m_height = other.m_width = 0;
50 | other.data = nullptr;
51 |
52 | return *this;
53 | }
54 |
55 | MemoryBitmap::~MemoryBitmap() noexcept
56 | {
57 | delete[] data;
58 | }
59 |
60 |
61 | void MemoryBitmap::SetSize(int width, int height)
62 | {
63 | assert(width != 0 && height != 0);
64 |
65 | if (m_width != width || m_height != height)
66 | {
67 | delete[] data;
68 |
69 | m_width = width;
70 | m_height = height;
71 |
72 | data = new unsigned char[static_cast(GetStrideLength()) * height];
73 | }
74 | }
75 |
76 |
77 |
78 | void MemoryBitmap::SetMatrix(const double* results, int Width, int Height)
79 | {
80 | if (Width == 0 || Height == 0 || !results) return;
81 |
82 | SetSize(Width, Height);
83 |
84 | int stride = GetStrideLength();
85 |
86 |
87 |
88 | for (int i = 0; i < Height; ++i)
89 | {
90 | const int line = (Height - i - 1) * stride;
91 |
92 | for (int j = 0; j < Width; ++j)
93 | {
94 | int pos = line + 3 * j;
95 |
96 | const double val = results[Width*i + j];
97 |
98 | data[pos] = static_cast(val * 255.);
99 | data[pos + 1] = data[pos];
100 | data[pos + 2] = data[pos];
101 | }
102 | }
103 | }
104 |
105 | void MemoryBitmap::SetMatrix(const std::complex* results, int Width, int Height)
106 | {
107 | if (Width == 0 || Height == 0 || !results) return;
108 |
109 | SetSize(Width, Height);
110 |
111 | const int stride = GetStrideLength();
112 |
113 | for (int i = 0; i < Height; ++i)
114 | {
115 | const int line = (Height - i - 1) * stride;
116 |
117 | for (int j = 0; j < Width; ++j)
118 | {
119 | const int pos = line + 3 * j;
120 |
121 | const double val = std::abs(results[Width*i + j]);
122 |
123 | data[pos] = static_cast(val * 255.);
124 | data[pos + 1] = data[pos];
125 | data[pos + 2] = data[pos];
126 | }
127 | }
128 | }
129 |
130 | void MemoryBitmap::Draw(CDC* pDC) const
131 | {
132 | BITMAPINFO bmi;
133 | ZeroMemory(&bmi, sizeof(BITMAPINFOHEADER));
134 |
135 | bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
136 | bmi.bmiHeader.biWidth = m_width;
137 | bmi.bmiHeader.biHeight = m_height;
138 | bmi.bmiHeader.biPlanes = 1;
139 | bmi.bmiHeader.biBitCount = 24;
140 | bmi.bmiHeader.biCompression = BI_RGB;
141 |
142 | CBitmap bitmap;
143 |
144 | bitmap.CreateCompatibleBitmap(pDC, m_width, m_height);
145 | ::SetDIBits(pDC->GetSafeHdc(), bitmap, 0, m_height, data, &bmi, DIB_RGB_COLORS);
146 | CDC dcMemory;
147 | dcMemory.CreateCompatibleDC(pDC);
148 | CBitmap * pOldBitmap = dcMemory.SelectObject(&bitmap);
149 | pDC->BitBlt(0, 0, m_width, m_height, &dcMemory, 0, 0, SRCCOPY);
150 | dcMemory.SelectObject(pOldBitmap);
151 | }
152 |
153 | void MemoryBitmap::Draw(CDC* pDC, CRect& rect, int origWidth, int origHeight) const
154 | {
155 | BITMAPINFO bmi;
156 | ZeroMemory(&bmi, sizeof(BITMAPINFOHEADER));
157 |
158 | bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
159 | bmi.bmiHeader.biWidth = m_width;
160 | bmi.bmiHeader.biHeight = m_height;
161 | bmi.bmiHeader.biPlanes = 1;
162 | bmi.bmiHeader.biBitCount = 24;
163 | bmi.bmiHeader.biCompression = BI_RGB;
164 |
165 | CBitmap bitmap;
166 |
167 | bitmap.CreateCompatibleBitmap(pDC, m_width, m_height);
168 | ::SetDIBits(pDC->GetSafeHdc(), bitmap, 0, m_height, data, &bmi, DIB_RGB_COLORS);
169 | CDC dcMemory;
170 | dcMemory.CreateCompatibleDC(pDC);
171 | CBitmap * pOldBitmap = dcMemory.SelectObject(&bitmap);
172 | pDC->StretchBlt(rect.left, rect.top, rect.Width(), rect.Height(), &dcMemory, origWidth ? (m_width - origWidth)/2 : 0, origHeight ? (m_height - origHeight)/2 : 0, origWidth ? origWidth : m_width, origHeight ? origHeight : m_height, SRCCOPY);
173 | dcMemory.SelectObject(pOldBitmap);
174 | }
175 |
176 |
177 |
178 |
179 |
--------------------------------------------------------------------------------
/NMRI/NMRIView.cpp:
--------------------------------------------------------------------------------
1 |
2 | // NMRIView.cpp : implementation of the CNMRIView class
3 | //
4 |
5 | #include "stdafx.h"
6 | // SHARED_HANDLERS can be defined in an ATL project implementing preview, thumbnail
7 | // and search filter handlers and allows sharing of document code with that project.
8 | #ifndef SHARED_HANDLERS
9 | #include "NMRI.h"
10 | #endif
11 |
12 | #include "NMRIDoc.h"
13 | #include "NMRIView.h"
14 |
15 | #ifdef _DEBUG
16 | #define new DEBUG_NEW
17 | #endif
18 |
19 |
20 | // CNMRIView
21 |
22 | IMPLEMENT_DYNCREATE(CNMRIView, CView)
23 |
24 | BEGIN_MESSAGE_MAP(CNMRIView, CView)
25 | // Standard printing commands
26 | ON_COMMAND(ID_FILE_PRINT, &CView::OnFilePrint)
27 | ON_COMMAND(ID_FILE_PRINT_DIRECT, &CView::OnFilePrint)
28 | ON_COMMAND(ID_FILE_PRINT_PREVIEW, &CNMRIView::OnFilePrintPreview)
29 | ON_WM_CONTEXTMENU()
30 | ON_WM_RBUTTONUP()
31 | ON_WM_CREATE()
32 | ON_WM_DESTROY()
33 | ON_WM_ERASEBKGND()
34 | ON_WM_TIMER()
35 | END_MESSAGE_MAP()
36 |
37 | // CNMRIView construction/destruction
38 |
39 | BOOL CNMRIView::PreCreateWindow(CREATESTRUCT& cs)
40 | {
41 | // TODO: Modify the Window class or styles here by modifying
42 | // the CREATESTRUCT cs
43 |
44 | return CView::PreCreateWindow(cs);
45 | }
46 |
47 | // CNMRIView drawing
48 |
49 | void CNMRIView::OnDraw(CDC* pDC)
50 | {
51 | const CNMRIDoc* pDoc = GetDocument();
52 | ASSERT_VALID(pDoc);
53 | if (!pDoc)
54 | return;
55 |
56 | // TODO: add draw code for native data here
57 |
58 | int width = pDoc->theFile.Width;
59 | int height = pDoc->theFile.Height;
60 |
61 | img1.SetMatrix(pDoc->theFile.GetFrame(), width, height);
62 | img2.SetMatrix(pDoc->theFile.GetRealFrame(), width, height);
63 |
64 | CRect rect;
65 | GetClientRect(rect);
66 |
67 | width *= 2;
68 | height *= 2;
69 |
70 |
71 | CRect rct;
72 | rct.top = rect.top + rect.Height() / 2 - height / 2;
73 | rct.left = rect.left + rect.Width() / 2 - width - 5;
74 | rct.right = rct.left + width;
75 | rct.bottom = rct.top + height;
76 |
77 | img1.Draw(pDC, rct);
78 |
79 | rct.left = rect.left + rect.Width() / 2 + 5;
80 | rct.right = rct.left + width;
81 |
82 | img2.Draw(pDC, rct);
83 |
84 |
85 | CBrush whiteBrush(RGB(255,255,255));
86 | CRect paintRect;
87 |
88 | paintRect.top = rect.top;
89 | paintRect.bottom = rct.top;
90 | paintRect.left = rect.left;
91 | paintRect.right = rect.right;
92 | pDC->FillRect(paintRect, &whiteBrush);
93 |
94 | paintRect.top = rct.bottom;
95 | paintRect.bottom = rect.bottom;
96 | pDC->FillRect(paintRect, &whiteBrush);
97 |
98 | paintRect.right = rect.left + rect.Width() / 2 - width - 5;
99 | paintRect.top = rct.top;
100 | paintRect.bottom = rct.bottom;
101 | pDC->FillRect(paintRect, &whiteBrush);
102 |
103 | paintRect.left = rct.right;
104 | paintRect.right = rect.right;
105 | pDC->FillRect(paintRect, &whiteBrush);
106 |
107 | paintRect.left = rct.left-10;
108 | paintRect.right = rct.left;
109 | pDC->FillRect(paintRect, &whiteBrush);
110 | }
111 |
112 |
113 | // CNMRIView printing
114 |
115 |
116 | void CNMRIView::OnFilePrintPreview()
117 | {
118 | #ifndef SHARED_HANDLERS
119 | AFXPrintPreview(this);
120 | #endif
121 | }
122 |
123 | BOOL CNMRIView::OnPreparePrinting(CPrintInfo* pInfo)
124 | {
125 | // default preparation
126 | return DoPreparePrinting(pInfo);
127 | }
128 |
129 | void CNMRIView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
130 | {
131 | // TODO: add extra initialization before printing
132 | }
133 |
134 | void CNMRIView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
135 | {
136 | // TODO: add cleanup after printing
137 | }
138 |
139 | void CNMRIView::OnRButtonUp(UINT /* nFlags */, CPoint point)
140 | {
141 | ClientToScreen(&point);
142 | OnContextMenu(this, point);
143 | }
144 |
145 | void CNMRIView::OnContextMenu(CWnd* /* pWnd */, CPoint /*point*/)
146 | {
147 | #ifndef SHARED_HANDLERS
148 | #endif
149 | }
150 |
151 |
152 | // CNMRIView diagnostics
153 |
154 | #ifdef _DEBUG
155 | void CNMRIView::AssertValid() const
156 | {
157 | CView::AssertValid();
158 | }
159 |
160 | void CNMRIView::Dump(CDumpContext& dc) const
161 | {
162 | CView::Dump(dc);
163 | }
164 |
165 | CNMRIDoc* CNMRIView::GetDocument() const // non-debug version is inline
166 | {
167 | ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CNMRIDoc)));
168 | return dynamic_cast(m_pDocument);
169 | }
170 | #endif //_DEBUG
171 |
172 |
173 | // CNMRIView message handlers
174 |
175 |
176 | int CNMRIView::OnCreate(LPCREATESTRUCT lpCreateStruct)
177 | {
178 | if (CView::OnCreate(lpCreateStruct) == -1)
179 | return -1;
180 |
181 | timer = SetTimer(1, 500, nullptr);
182 |
183 | return 0;
184 | }
185 |
186 |
187 | void CNMRIView::OnDestroy()
188 | {
189 | KillTimer(timer);
190 |
191 | CView::OnDestroy();
192 | }
193 |
194 |
195 | BOOL CNMRIView::OnEraseBkgnd(CDC* pDC)
196 | {
197 | if (pDC->IsPrinting())
198 | return CView::OnEraseBkgnd(pDC);
199 |
200 | return TRUE;
201 | }
202 |
203 |
204 | void CNMRIView::OnTimer(UINT_PTR nIDEvent)
205 | {
206 | CView::OnTimer(nIDEvent);
207 |
208 | CNMRIDoc* pDoc = GetDocument();
209 | ASSERT_VALID(pDoc);
210 | if (!pDoc)
211 | return;
212 |
213 | // the reason why the timer is not stopped is that the image should be updated if the filter is changed
214 | if (pDoc->animate)
215 | {
216 | if (++theFrame >= pDoc->theFile.NrFrames) theFrame = 0;
217 | }
218 |
219 | pDoc->theFile.FFT(theFrame);
220 | Invalidate();
221 | }
222 |
--------------------------------------------------------------------------------
/NMRI/NMRI.cpp:
--------------------------------------------------------------------------------
1 |
2 | // NMRI.cpp : Defines the class behaviors for the application.
3 | //
4 |
5 | #include "stdafx.h"
6 | #include "afxwinappex.h"
7 | #include "afxdialogex.h"
8 | #include "NMRI.h"
9 | #include "MainFrm.h"
10 |
11 | #include "NMRIDoc.h"
12 | #include "NMRIView.h"
13 |
14 | #ifdef _DEBUG
15 | #define new DEBUG_NEW
16 | #endif
17 |
18 |
19 | // CNMRIApp
20 |
21 | BEGIN_MESSAGE_MAP(CNMRIApp, CWinAppEx)
22 | ON_COMMAND(ID_APP_ABOUT, &CNMRIApp::OnAppAbout)
23 | // Standard file based document commands
24 | ON_COMMAND(ID_FILE_NEW, &CWinAppEx::OnFileNew)
25 | ON_COMMAND(ID_FILE_OPEN, &CWinAppEx::OnFileOpen)
26 | // Standard print setup command
27 | ON_COMMAND(ID_FILE_PRINT_SETUP, &CWinAppEx::OnFilePrintSetup)
28 | END_MESSAGE_MAP()
29 |
30 |
31 | // CNMRIApp construction
32 |
33 | CNMRIApp::CNMRIApp()
34 | : m_nAppLook(0), m_bHiColorIcons(TRUE)
35 | {
36 | // support Restart Manager
37 | m_dwRestartManagerSupportFlags = AFX_RESTART_MANAGER_SUPPORT_ALL_ASPECTS;
38 | #ifdef _MANAGED
39 | // If the application is built using Common Language Runtime support (/clr):
40 | // 1) This additional setting is needed for Restart Manager support to work properly.
41 | // 2) In your project, you must add a reference to System.Windows.Forms in order to build.
42 | System::Windows::Forms::Application::SetUnhandledExceptionMode(System::Windows::Forms::UnhandledExceptionMode::ThrowException);
43 | #endif
44 |
45 | // TODO: replace application ID string below with unique ID string; recommended
46 | // format for string is CompanyName.ProductName.SubProduct.VersionInformation
47 | SetAppID(_T("NMRI.AppID.NoVersion"));
48 |
49 | // TODO: add construction code here,
50 | // Place all significant initialization in InitInstance
51 | }
52 |
53 | // The one and only CNMRIApp object
54 |
55 | CNMRIApp theApp;
56 |
57 |
58 | // CNMRIApp initialization
59 |
60 | BOOL CNMRIApp::InitInstance()
61 | {
62 | // InitCommonControlsEx() is required on Windows XP if an application
63 | // manifest specifies use of ComCtl32.dll version 6 or later to enable
64 | // visual styles. Otherwise, any window creation will fail.
65 | INITCOMMONCONTROLSEX InitCtrls;
66 | InitCtrls.dwSize = sizeof(InitCtrls);
67 | // Set this to include all the common control classes you want to use
68 | // in your application.
69 | InitCtrls.dwICC = ICC_WIN95_CLASSES;
70 | InitCommonControlsEx(&InitCtrls);
71 |
72 | CWinAppEx::InitInstance();
73 |
74 |
75 | EnableTaskbarInteraction(FALSE);
76 |
77 | // AfxInitRichEdit2() is required to use RichEdit control
78 | // AfxInitRichEdit2();
79 |
80 | // Standard initialization
81 | // If you are not using these features and wish to reduce the size
82 | // of your final executable, you should remove from the following
83 | // the specific initialization routines you do not need
84 | // Change the registry key under which our settings are stored
85 | // TODO: You should modify this string to be something appropriate
86 | // such as the name of your company or organization
87 | SetRegistryKey(_T("NMRI"));
88 | LoadStdProfileSettings(0); // Load standard INI file options (including MRU)
89 |
90 |
91 | InitContextMenuManager();
92 |
93 | InitKeyboardManager();
94 |
95 | InitTooltipManager();
96 | CMFCToolTipInfo ttParams;
97 | ttParams.m_bVislManagerTheme = TRUE;
98 | theApp.GetTooltipManager()->SetTooltipParams(AFX_TOOLTIP_TYPE_ALL,
99 | RUNTIME_CLASS(CMFCToolTipCtrl), &ttParams);
100 |
101 | // Register the application's document templates. Document templates
102 | // serve as the connection between documents, frame windows and views
103 | CSingleDocTemplate* pDocTemplate = new CSingleDocTemplate(
104 | IDR_MAINFRAME,
105 | RUNTIME_CLASS(CNMRIDoc),
106 | RUNTIME_CLASS(CMainFrame), // main SDI frame window
107 | RUNTIME_CLASS(CNMRIView));
108 | if (!pDocTemplate)
109 | return FALSE;
110 | AddDocTemplate(pDocTemplate);
111 |
112 | // Parse command line for standard shell commands, DDE, file open
113 | CCommandLineInfo cmdInfo;
114 | ParseCommandLine(cmdInfo);
115 |
116 | // Dispatch commands specified on the command line. Will return FALSE if
117 | // app was launched with /RegServer, /Register, /Unregserver or /Unregister.
118 | if (!ProcessShellCommand(cmdInfo))
119 | return FALSE;
120 |
121 | // The one and only window has been initialized, so show and update it
122 | m_pMainWnd->ShowWindow(SW_SHOW);
123 | m_pMainWnd->UpdateWindow();
124 |
125 | dynamic_cast(m_pMainWnd)->Init();
126 |
127 | return TRUE;
128 | }
129 |
130 | // CNMRIApp message handlers
131 |
132 |
133 | // CAboutDlg dialog used for App About
134 |
135 | class CAboutDlg : public CDialogEx
136 | {
137 | public:
138 | CAboutDlg();
139 |
140 | // Dialog Data
141 | #ifdef AFX_DESIGN_TIME
142 | enum { IDD = IDD_ABOUTBOX };
143 | #endif
144 |
145 | protected:
146 | virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
147 |
148 | // Implementation
149 | protected:
150 | DECLARE_MESSAGE_MAP()
151 | };
152 |
153 | CAboutDlg::CAboutDlg() : CDialogEx(IDD_ABOUTBOX)
154 | {
155 | }
156 |
157 | void CAboutDlg::DoDataExchange(CDataExchange* pDX)
158 | {
159 | CDialogEx::DoDataExchange(pDX);
160 | }
161 |
162 | BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
163 | END_MESSAGE_MAP()
164 |
165 | // App command to run the dialog
166 | void CNMRIApp::OnAppAbout()
167 | {
168 | CAboutDlg aboutDlg;
169 | aboutDlg.DoModal();
170 | }
171 |
172 | // CNMRIApp customization load/save methods
173 |
174 | void CNMRIApp::PreLoadState()
175 | {
176 | }
177 |
178 | void CNMRIApp::LoadCustomState()
179 | {
180 | }
181 |
182 | void CNMRIApp::SaveCustomState()
183 | {
184 | }
185 |
186 | // CNMRIApp message handlers
187 |
188 |
189 |
190 |
--------------------------------------------------------------------------------
/NMRI/ReadMe.txt:
--------------------------------------------------------------------------------
1 | ================================================================================
2 | MICROSOFT FOUNDATION CLASS LIBRARY : NMRI Project Overview
3 | ===============================================================================
4 |
5 | The application wizard has created this NMRI application for
6 | you. This application not only demonstrates the basics of using the Microsoft
7 | Foundation Classes but is also a starting point for writing your application.
8 |
9 | This file contains a summary of what you will find in each of the files that
10 | make up your NMRI application.
11 |
12 | NMRI.vcxproj
13 | This is the main project file for VC++ projects generated using an application wizard.
14 | It contains information about the version of Visual C++ that generated the file, and
15 | information about the platforms, configurations, and project features selected with the
16 | application wizard.
17 |
18 | NMRI.vcxproj.filters
19 | This is the filters file for VC++ projects generated using an Application Wizard.
20 | It contains information about the assciation between the files in your project
21 | and the filters. This association is used in the IDE to show grouping of files with
22 | similar extensions under a specific node (for e.g. ".cpp" files are associated with the
23 | "Source Files" filter).
24 |
25 | NMRI.h
26 | This is the main header file for the application. It includes other
27 | project specific headers (including Resource.h) and declares the
28 | CNMRIApp application class.
29 |
30 | NMRI.cpp
31 | This is the main application source file that contains the application
32 | class CNMRIApp.
33 |
34 | NMRI.rc
35 | This is a listing of all of the Microsoft Windows resources that the
36 | program uses. It includes the icons, bitmaps, and cursors that are stored
37 | in the RES subdirectory. This file can be directly edited in Microsoft
38 | Visual C++. Your project resources are in 1033.
39 |
40 | res\NMRI.ico
41 | This is an icon file, which is used as the application's icon. This
42 | icon is included by the main resource file NMRI.rc.
43 |
44 | res\NMRI.rc2
45 | This file contains resources that are not edited by Microsoft
46 | Visual C++. You should place all resources not editable by
47 | the resource editor in this file.
48 |
49 | /////////////////////////////////////////////////////////////////////////////
50 |
51 | For the main frame window:
52 | The project includes a standard MFC interface.
53 |
54 | MainFrm.h, MainFrm.cpp
55 | These files contain the frame class CMainFrame, which is derived from
56 | CFrameWnd and controls all SDI frame features.
57 |
58 | res\Toolbar.bmp
59 | This bitmap file is used to create tiled images for the toolbar.
60 | The initial toolbar and status bar are constructed in the CMainFrame
61 | class. Edit this toolbar bitmap using the resource editor, and
62 | update the IDR_MAINFRAME TOOLBAR array in NMRI.rc to add
63 | toolbar buttons.
64 | /////////////////////////////////////////////////////////////////////////////
65 |
66 | The application wizard creates one document type and one view:
67 |
68 | NMRIDoc.h, NMRIDoc.cpp - the document
69 | These files contain your CNMRIDoc class. Edit these files to
70 | add your special document data and to implement file saving and loading
71 | (via CNMRIDoc::Serialize).
72 |
73 | NMRIView.h, NMRIView.cpp - the view of the document
74 | These files contain your CNMRIView class.
75 | CNMRIView objects are used to view CNMRIDoc objects.
76 |
77 |
78 |
79 |
80 | /////////////////////////////////////////////////////////////////////////////
81 |
82 | Help Support:
83 |
84 | hlp\NMRI.hhp
85 | This file is a help project file. It contains the data needed to
86 | compile the help files into a .chm file.
87 |
88 | hlp\NMRI.hhc
89 | This file lists the contents of the help project.
90 |
91 | hlp\NMRI.hhk
92 | This file contains an index of the help topics.
93 |
94 | hlp\afxcore.htm
95 | This file contains the standard help topics for standard MFC
96 | commands and screen objects. Add your own help topics to this file.
97 |
98 | hlp\afxprint.htm
99 | This file contains the help topics for the printing commands.
100 |
101 | makehtmlhelp.bat
102 | This file is used by the build system to compile the help files.
103 |
104 | hlp\Images\*.gif
105 | These are bitmap files required by the standard help file topics for
106 | Microsoft Foundation Class Library standard commands.
107 |
108 |
109 | /////////////////////////////////////////////////////////////////////////////
110 |
111 | Other Features:
112 |
113 | Printing and Print Preview support
114 | The application wizard has generated code to handle the print, print setup, and print preview
115 | commands by calling member functions in the CView class from the MFC library.
116 |
117 | /////////////////////////////////////////////////////////////////////////////
118 |
119 | Other standard files:
120 |
121 | StdAfx.h, StdAfx.cpp
122 | These files are used to build a precompiled header (PCH) file
123 | named NMRI.pch and a precompiled types file named StdAfx.obj.
124 |
125 | Resource.h
126 | This is the standard header file, which defines new resource IDs.
127 | Microsoft Visual C++ reads and updates this file.
128 |
129 | NMRI.manifest
130 | Application manifest files are used by Windows XP to describe an applications
131 | dependency on specific versions of Side-by-Side assemblies. The loader uses this
132 | information to load the appropriate assembly from the assembly cache or private
133 | from the application. The Application manifest maybe included for redistribution
134 | as an external .manifest file that is installed in the same folder as the application
135 | executable or it may be included in the executable in the form of a resource.
136 | /////////////////////////////////////////////////////////////////////////////
137 |
138 | Other notes:
139 |
140 | The application wizard uses "TODO:" to indicate parts of the source code you
141 | should add to or customize.
142 |
143 | If your application uses MFC in a shared DLL, you will need
144 | to redistribute the MFC DLLs. If your application is in a language
145 | other than the operating system's locale, you will also have to
146 | redistribute the corresponding localized resources MFC100XXX.DLL.
147 | For more information on both of these topics, please see the section on
148 | redistributing Visual C++ applications in MSDN documentation.
149 |
150 | /////////////////////////////////////////////////////////////////////////////
151 |
--------------------------------------------------------------------------------
/NMRI/PropertiesWnd.cpp:
--------------------------------------------------------------------------------
1 |
2 | #include "stdafx.h"
3 |
4 | #include "PropertiesWnd.h"
5 | #include "Resource.h"
6 | #include "MainFrm.h"
7 | #include "NMRI.h"
8 |
9 | #include "NMRIDoc.h"
10 |
11 | #ifdef _DEBUG
12 | #undef THIS_FILE
13 | static char THIS_FILE[]=__FILE__;
14 | #define new DEBUG_NEW
15 | #endif
16 |
17 | // for CSliderProp and CPropSliderCtrl see: https://github.com/jhlee8804/MFC-Feature-Pack/tree/master/NewControls
18 | // the code is adjusted to allow setting the range
19 |
20 | /////////////////////////////////////////////////////////////////////////////
21 | // CPropSliderCtrl
22 |
23 | CPropSliderCtrl::CPropSliderCtrl(CSliderProp* pProp, COLORREF clrBack) {
24 | m_clrBack = clrBack;
25 | m_brBackground.CreateSolidBrush(m_clrBack);
26 | m_pProp = pProp;
27 | }
28 |
29 | BEGIN_MESSAGE_MAP(CPropSliderCtrl, CSliderCtrl)
30 | //{{AFX_MSG_MAP(CPropSliderCtrl)
31 | ON_WM_CTLCOLOR_REFLECT()
32 | ON_WM_HSCROLL_REFLECT()
33 | //}}AFX_MSG_MAP
34 | END_MESSAGE_MAP()
35 |
36 | /////////////////////////////////////////////////////////////////////////////
37 | // CPropSliderCtrl message handlers
38 |
39 | HBRUSH CPropSliderCtrl::CtlColor(CDC* pDC, UINT /*nCtlColor*/) {
40 | pDC->SetBkColor(m_clrBack);
41 | return m_brBackground;
42 | }
43 |
44 | void CPropSliderCtrl::HScroll(UINT /*nSBCode*/, UINT /*nPos*/) {
45 | ASSERT_VALID(m_pProp);
46 |
47 | m_pProp->OnUpdateValue();
48 | m_pProp->Redraw();
49 | }
50 |
51 | ////////////////////////////////////////////////////////////////////////////////
52 | // CSliderProp class
53 |
54 | CSliderProp::CSliderProp(const CString& strName, long nValue, long minVal, long maxVal, LPCTSTR lpszDescr, DWORD dwData) :
55 | CMFCPropertyGridProperty(strName, nValue, lpszDescr, dwData), m_minVal(minVal), m_maxVal(maxVal)
56 | {
57 | }
58 |
59 | CWnd* CSliderProp::CreateInPlaceEdit(CRect rectEdit, BOOL& bDefaultFormat) {
60 | CPropSliderCtrl* pWndSlider = new CPropSliderCtrl(this, m_pWndList->GetBkColor());
61 |
62 | rectEdit.left += rectEdit.Height() + 5;
63 |
64 | pWndSlider->Create(WS_VISIBLE | WS_CHILD, rectEdit, m_pWndList, AFX_PROPLIST_ID_INPLACE);
65 | pWndSlider->SetRange(m_minVal, m_maxVal);
66 | pWndSlider->SetPos(m_varValue.lVal);
67 |
68 | bDefaultFormat = TRUE;
69 | return pWndSlider;
70 | }
71 |
72 | BOOL CSliderProp::OnUpdateValue() {
73 | ASSERT_VALID(this);
74 | ASSERT_VALID(m_pWndInPlace);
75 | ASSERT_VALID(m_pWndList);
76 | ASSERT(::IsWindow(m_pWndInPlace->GetSafeHwnd()));
77 |
78 | long lCurrValue = m_varValue.lVal;
79 |
80 | CSliderCtrl* pSlider = (CSliderCtrl*)m_pWndInPlace;
81 |
82 | m_varValue = (long)pSlider->GetPos();
83 |
84 | if (lCurrValue != m_varValue.lVal) {
85 | m_pWndList->OnPropertyChanged(this);
86 | }
87 |
88 | return TRUE;
89 | }
90 |
91 |
92 |
93 | /////////////////////////////////////////////////////////////////////////////
94 | // CResourceViewBar
95 |
96 |
97 | BEGIN_MESSAGE_MAP(CPropertiesWnd, CDockablePane)
98 | ON_WM_CREATE()
99 | ON_WM_SIZE()
100 | ON_WM_SETFOCUS()
101 | ON_WM_SETTINGCHANGE()
102 | ON_REGISTERED_MESSAGE(AFX_WM_PROPERTY_CHANGED, OnPropertyChanged)
103 | END_MESSAGE_MAP()
104 |
105 | /////////////////////////////////////////////////////////////////////////////
106 | // CResourceViewBar message handlers
107 |
108 | void CPropertiesWnd::AdjustLayout()
109 | {
110 | if (GetSafeHwnd () == nullptr || (AfxGetMainWnd() != nullptr && AfxGetMainWnd()->IsIconic()))
111 | {
112 | return;
113 | }
114 |
115 | CRect rectClient;
116 | GetClientRect(rectClient);
117 |
118 | m_wndPropList.SetWindowPos(nullptr, rectClient.left, rectClient.top, rectClient.Width(), rectClient.Height(), SWP_NOACTIVATE | SWP_NOZORDER);
119 | }
120 |
121 | int CPropertiesWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)
122 | {
123 | if (CDockablePane::OnCreate(lpCreateStruct) == -1)
124 | return -1;
125 |
126 | CRect rectDummy;
127 | rectDummy.SetRectEmpty();
128 |
129 |
130 | if (!m_wndPropList.Create(WS_VISIBLE | WS_CHILD, rectDummy, this, 2))
131 | {
132 | TRACE0("Failed to create Properties Grid \n");
133 | return -1; // fail to create
134 | }
135 |
136 | InitPropList();
137 |
138 |
139 | AdjustLayout();
140 | return 0;
141 | }
142 |
143 | void CPropertiesWnd::OnSize(UINT nType, int cx, int cy)
144 | {
145 | CDockablePane::OnSize(nType, cx, cy);
146 | AdjustLayout();
147 | }
148 |
149 |
150 | void CPropertiesWnd::InitPropList()
151 | {
152 | m_wndPropList.EnableHeaderCtrl(FALSE);
153 | m_wndPropList.EnableDescriptionArea();
154 | m_wndPropList.SetVSDotNetLook();
155 | m_wndPropList.MarkModifiedProperties();
156 |
157 | CMFCPropertyGridProperty* pGroup1 = new CMFCPropertyGridProperty(_T("Filter"));
158 |
159 | CMFCPropertyGridProperty *prop = new CMFCPropertyGridProperty(_T("Low Frequencies"), (_variant_t)false, _T("Removes the low frequency information"));
160 |
161 | prop->SetData(0);
162 | pGroup1->AddSubItem(prop);
163 |
164 | prop = new CMFCPropertyGridProperty(_T("High Frequencies"), (_variant_t)false, _T("Removes the high frequency information"));
165 | prop->SetData(1);
166 | pGroup1->AddSubItem(prop);
167 |
168 | prop = new CSliderProp(_T("Low filter threshold"), 50, 0, 100, _T("Low filter cutoff value"));
169 | prop->SetData(2);
170 | pGroup1->AddSubItem(prop);
171 |
172 | prop = new CSliderProp(_T("High filter threshold"), 50, 0, 100, _T("High filter cutoff value"));
173 | prop->SetData(3);
174 | pGroup1->AddSubItem(prop);
175 |
176 |
177 | m_wndPropList.AddProperty(pGroup1);
178 |
179 | CMFCPropertyGridProperty* pGroup2 = new CMFCPropertyGridProperty(_T("3D View"));
180 |
181 | prop = new CMFCPropertyGridProperty(_T("Color transfer function"), (_variant_t)true, _T("Color the 3D image with blue for low values, red for high"));
182 | prop->SetData(4);
183 | pGroup2->AddSubItem(prop);
184 |
185 | prop = new CMFCPropertyGridProperty(_T("Scalar opacity transfer function"), (_variant_t)true, _T("Make the small values more transparent than the big ones"));
186 | prop->SetData(5);
187 | pGroup2->AddSubItem(prop);
188 |
189 | prop = new CMFCPropertyGridProperty(_T("Gradient opacity transfer function"), (_variant_t)true, _T("Make the low gradient values more transparent"));
190 | prop->SetData(6);
191 | pGroup2->AddSubItem(prop);
192 |
193 | prop = new CSliderProp(_T("Opacity depth"), 50, 0, 100, _T("Opacity depth where the value is 1"));
194 | prop->SetData(7);
195 | pGroup2->AddSubItem(prop);
196 |
197 | prop = new CSliderProp(_T("Gradient point"), 50, 0, 100, _T("Gradient point where the value is 1"));
198 | prop->SetData(8);
199 | pGroup2->AddSubItem(prop);
200 |
201 | m_wndPropList.AddProperty(pGroup2);
202 | }
203 |
204 | void CPropertiesWnd::OnSetFocus(CWnd* pOldWnd)
205 | {
206 | CDockablePane::OnSetFocus(pOldWnd);
207 | m_wndPropList.SetFocus();
208 | }
209 |
210 | void CPropertiesWnd::OnSettingChange(UINT uFlags, LPCTSTR lpszSection)
211 | {
212 | CDockablePane::OnSettingChange(uFlags, lpszSection);
213 | }
214 |
215 | LRESULT CPropertiesWnd::OnPropertyChanged(__in WPARAM /*wparam*/, __in LPARAM lparam)
216 | {
217 | if (!theDoc) return 0;
218 |
219 | const CMFCPropertyGridProperty *prop = (CMFCPropertyGridProperty *)lparam;
220 |
221 |
222 | if (prop)
223 | {
224 | COleVariant v = prop->GetValue();
225 |
226 | const auto opt = prop->GetData();
227 | switch (opt)
228 | {
229 | case 0:
230 | v.ChangeType(VT_BOOL);
231 | theDoc->theFile.filterLowFreqs = v.boolVal;
232 | break;
233 | case 1:
234 | v.ChangeType(VT_BOOL);
235 | theDoc->theFile.filterHighFreqs = v.boolVal;
236 | break;
237 | case 2:
238 | v.ChangeType(VT_INT);
239 | theDoc->theFile.LowPassPercentage = v.intVal;
240 | break;
241 | case 3:
242 | v.ChangeType(VT_INT);
243 | theDoc->theFile.HighPassPercentage = v.intVal;
244 | break;
245 | case 4:
246 | v.ChangeType(VT_BOOL);
247 | theDoc->colorFunction = v.boolVal;
248 | break;
249 | case 5:
250 | v.ChangeType(VT_BOOL);
251 | theDoc->opacityFunction = v.boolVal;
252 | break;
253 | case 6:
254 | v.ChangeType(VT_BOOL);
255 | theDoc->gradientFunction = v.boolVal;
256 | break;
257 | case 7:
258 | v.ChangeType(VT_INT);
259 | theDoc->opacityVal = v.intVal;
260 | break;
261 | case 8:
262 | v.ChangeType(VT_INT);
263 | theDoc->gradientVal = v.intVal;
264 | break;
265 | }
266 |
267 | if (opt <= 3)
268 | theDoc->UpdateViews();
269 | else
270 | theDoc->Update3DOptions();
271 | }
272 |
273 | return 0;
274 | }
275 |
276 |
277 |
--------------------------------------------------------------------------------
/NMRI/FFT.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 |
4 | #include
5 | #include