2020/12/29

[Android][Kotlin] Hello World

 코틀린을 이용하여 안드로이드 앱을 만들어 보기로했다.

그래서 새로운 언어를 배우는 첫 번째 관문인 Hello World를 도전해 봤다.


Android Studio 4.1.1 버전을 이용하며 시도해보았다.

Kotlin plugin이 기본으로 설치가되어 있어서 별도로 설정해 주어야 할게 없었다.


Android Studio 를 실생시켜 새로운 프로젝트를 만들었다.


"Empty Project"를 프로젝트를 생성하여 프로젝트 이름과 Kotlin 설정만 하였다.


기본적으로 만들어진 프로젝트를 AVD를 이용하여 실행해 보았다.


짜잔~ 앱이 실행되었다.



이제 슬슬 공부를 해봐야겠다.

2020/08/07

MFC 대화장자에 VTK 올리기

이전 글(VTK 9.0.1 컴파일하기)에서 만들어진 VTK 빌드 결과물을 가지고 MFC 대화상자에 VTK를 올려보았다.


Test를 위한 대화상자 생성

Visual Studio 2019버전으로 테스트를 위한 대화상자 기반의 프로젝트 TestVTK를 만들었다. 2019버전으로는 처음 프로젝트를 먄들어보았는데 이전 버전과 프로젝트를 만드는 방법이 다소 달라졌고 프로젝트 구성이 달라졌다. VTK를 64비트만 빌드하여 테스트 프로젝트도 64비트 구성만 하였다.


VTK Property 파일 생성 및 구성 설정

Property Manager 에서 새로운 Property Sheet를 VTK_v9.0.1.props 파일로 만들었다.


VTK 경로를 하나의 설정으로 통일하여 관리하기 위해 VTK 빌드 결과물 경로를 User Macro에 VTK_DIR 이름으로 추가한다.


VTK_DIR 매크로를 이용하여 Include 및 Library 경로에 VTK 경로를 설정한다.

VC++ Directories > Include Directories: $(VTK_DIR)\include\vtk-9.0

VC++ Directories > Library Directories: $(VTK_DIR)\lib

VTK 사용을위한 기본 헤더 파일 작성

VTK 사용에 필요한 내용을 하나의 헤더파일로 작성을하여 관리하기위해 VTK_Prep.h 파일을 만들었다. 이 파일에는 VTK 초기화 코드와 VTK 사용에 필요한 헤더파일의 include와 빌드 속성에따른 lib 파일의 링크를 추가하였다. 라이브러리 파일은 모든 lib 파일을 추가하였고 Debug또는 Release에따라 로드되도록 하였다.

#pragma once

#include <vtkAutoInit.h>
#define vtkRenderingCore_AUTOINIT 3(vtkRenderingOpenGL2, vtkInteractionStyle, vtkRenderingFreeType)
#define vtkRenderingContext2D_AUTOINIT 1(vtkRenderingContextOpenGL2)
#define vtkRenderingVolume_AUTOINIT 1(vtkRenderingVolumeOpenGL)

#include <vtkRenderWindow.h>
#include <vtkSmartPointer.h>
#include <vtkPolyData.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkRenderer.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkInteractorStyleTrackballCamera.h>

#include <vtkConeSource.h>

#include <vtkCamera.h>
#include <vtkLight.h>

#include <vtkPoints.h>
#include <vtkCellArray.h>
#include <vtkPolyData.h>

#ifdef _DEBUG
#pragma comment(lib, "vtkChartsCore-9.0d.lib")
#pragma comment(lib, "vtkCommonColor-9.0d.lib")
#pragma comment(lib, "vtkCommonComputationalGeometry-9.0d.lib")
#pragma comment(lib, "vtkCommonCore-9.0d.lib")
#pragma comment(lib, "vtkCommonDataModel-9.0d.lib")
#pragma comment(lib, "vtkCommonExecutionModel-9.0d.lib")
#pragma comment(lib, "vtkCommonMath-9.0d.lib")
#pragma comment(lib, "vtkCommonMisc-9.0d.lib")
#pragma comment(lib, "vtkCommonSystem-9.0d.lib")
#pragma comment(lib, "vtkCommonTransforms-9.0d.lib")
#pragma comment(lib, "vtkDICOMParser-9.0d.lib")
#pragma comment(lib, "vtkDomainsChemistry-9.0d.lib")
#pragma comment(lib, "vtkdoubleconversion-9.0d.lib")
#pragma comment(lib, "vtkexodusII-9.0d.lib")
#pragma comment(lib, "vtkexpat-9.0d.lib")
#pragma comment(lib, "vtkFiltersAMR-9.0d.lib")
#pragma comment(lib, "vtkFiltersCore-9.0d.lib")
#pragma comment(lib, "vtkFiltersExtraction-9.0d.lib")
#pragma comment(lib, "vtkFiltersFlowPaths-9.0d.lib")
#pragma comment(lib, "vtkFiltersGeneral-9.0d.lib")
#pragma comment(lib, "vtkFiltersGeneric-9.0d.lib")
#pragma comment(lib, "vtkFiltersGeometry-9.0d.lib")
#pragma comment(lib, "vtkFiltersHybrid-9.0d.lib")
#pragma comment(lib, "vtkFiltersHyperTree-9.0d.lib")
#pragma comment(lib, "vtkFiltersImaging-9.0d.lib")
#pragma comment(lib, "vtkFiltersModeling-9.0d.lib")
#pragma comment(lib, "vtkFiltersParallel-9.0d.lib")
#pragma comment(lib, "vtkFiltersParallelImaging-9.0d.lib")
#pragma comment(lib, "vtkFiltersPoints-9.0d.lib")
#pragma comment(lib, "vtkFiltersProgrammable-9.0d.lib")
#pragma comment(lib, "vtkFiltersSelection-9.0d.lib")
#pragma comment(lib, "vtkFiltersSMP-9.0d.lib")
#pragma comment(lib, "vtkFiltersSources-9.0d.lib")
#pragma comment(lib, "vtkFiltersStatistics-9.0d.lib")
#pragma comment(lib, "vtkFiltersTexture-9.0d.lib")
#pragma comment(lib, "vtkFiltersTopology-9.0d.lib")
#pragma comment(lib, "vtkFiltersVerdict-9.0d.lib")
#pragma comment(lib, "vtkfreetype-9.0d.lib")
#pragma comment(lib, "vtkGeovisCore-9.0d.lib")
#pragma comment(lib, "vtkgl2ps-9.0d.lib")
#pragma comment(lib, "vtkglew-9.0d.lib")
#pragma comment(lib, "vtkhdf5-9.0d.lib")
#pragma comment(lib, "vtkhdf5_hl-9.0d.lib")
#pragma comment(lib, "vtkImagingColor-9.0d.lib")
#pragma comment(lib, "vtkImagingCore-9.0d.lib")
#pragma comment(lib, "vtkImagingFourier-9.0d.lib")
#pragma comment(lib, "vtkImagingGeneral-9.0d.lib")
#pragma comment(lib, "vtkImagingHybrid-9.0d.lib")
#pragma comment(lib, "vtkImagingMath-9.0d.lib")
#pragma comment(lib, "vtkImagingMorphological-9.0d.lib")
#pragma comment(lib, "vtkImagingSources-9.0d.lib")
#pragma comment(lib, "vtkImagingStatistics-9.0d.lib")
#pragma comment(lib, "vtkImagingStencil-9.0d.lib")
#pragma comment(lib, "vtkInfovisCore-9.0d.lib")
#pragma comment(lib, "vtkInfovisLayout-9.0d.lib")
#pragma comment(lib, "vtkInteractionImage-9.0d.lib")
#pragma comment(lib, "vtkInteractionStyle-9.0d.lib")
#pragma comment(lib, "vtkInteractionWidgets-9.0d.lib")
#pragma comment(lib, "vtkIOAMR-9.0d.lib")
#pragma comment(lib, "vtkIOAsynchronous-9.0d.lib")
#pragma comment(lib, "vtkIOCityGML-9.0d.lib")
#pragma comment(lib, "vtkIOCore-9.0d.lib")
#pragma comment(lib, "vtkIOEnSight-9.0d.lib")
#pragma comment(lib, "vtkIOExodus-9.0d.lib")
#pragma comment(lib, "vtkIOExport-9.0d.lib")
#pragma comment(lib, "vtkIOExportGL2PS-9.0d.lib")
#pragma comment(lib, "vtkIOExportPDF-9.0d.lib")
#pragma comment(lib, "vtkIOGeometry-9.0d.lib")
#pragma comment(lib, "vtkIOImage-9.0d.lib")
#pragma comment(lib, "vtkIOImport-9.0d.lib")
#pragma comment(lib, "vtkIOInfovis-9.0d.lib")
#pragma comment(lib, "vtkIOLegacy-9.0d.lib")
#pragma comment(lib, "vtkIOLSDyna-9.0d.lib")
#pragma comment(lib, "vtkIOMINC-9.0d.lib")
#pragma comment(lib, "vtkIOMotionFX-9.0d.lib")
#pragma comment(lib, "vtkIOMovie-9.0d.lib")
#pragma comment(lib, "vtkIONetCDF-9.0d.lib")
#pragma comment(lib, "vtkIOOggTheora-9.0d.lib")
#pragma comment(lib, "vtkIOParallel-9.0d.lib")
#pragma comment(lib, "vtkIOParallelXML-9.0d.lib")
#pragma comment(lib, "vtkIOPLY-9.0d.lib")
#pragma comment(lib, "vtkIOSegY-9.0d.lib")
#pragma comment(lib, "vtkIOSQL-9.0d.lib")
#pragma comment(lib, "vtkIOTecplotTable-9.0d.lib")
#pragma comment(lib, "vtkIOVeraOut-9.0d.lib")
#pragma comment(lib, "vtkIOVideo-9.0d.lib")
#pragma comment(lib, "vtkIOXML-9.0d.lib")
#pragma comment(lib, "vtkIOXMLParser-9.0d.lib")
#pragma comment(lib, "vtkjpeg-9.0d.lib")
#pragma comment(lib, "vtkjsoncpp-9.0d.lib")
#pragma comment(lib, "vtklibharu-9.0d.lib")
#pragma comment(lib, "vtklibproj-9.0d.lib")
#pragma comment(lib, "vtklibxml2-9.0d.lib")
#pragma comment(lib, "vtkloguru-9.0d.lib")
#pragma comment(lib, "vtklz4-9.0d.lib")
#pragma comment(lib, "vtklzma-9.0d.lib")
#pragma comment(lib, "vtkmetaio-9.0d.lib")
#pragma comment(lib, "vtknetcdf-9.0d.lib")
#pragma comment(lib, "vtkogg-9.0d.lib")
#pragma comment(lib, "vtkParallelCore-9.0d.lib")
#pragma comment(lib, "vtkParallelDIY-9.0d.lib")
#pragma comment(lib, "vtkpng-9.0d.lib")
#pragma comment(lib, "vtkpugixml-9.0d.lib")
#pragma comment(lib, "vtkRenderingAnnotation-9.0d.lib")
#pragma comment(lib, "vtkRenderingContext2D-9.0d.lib")
#pragma comment(lib, "vtkRenderingCore-9.0d.lib")
#pragma comment(lib, "vtkRenderingFreeType-9.0d.lib")
#pragma comment(lib, "vtkRenderingGL2PSOpenGL2-9.0d.lib")
#pragma comment(lib, "vtkRenderingImage-9.0d.lib")
#pragma comment(lib, "vtkRenderingLabel-9.0d.lib")
#pragma comment(lib, "vtkRenderingLOD-9.0d.lib")
#pragma comment(lib, "vtkRenderingOpenGL2-9.0d.lib")
#pragma comment(lib, "vtkRenderingSceneGraph-9.0d.lib")
#pragma comment(lib, "vtkRenderingUI-9.0d.lib")
#pragma comment(lib, "vtkRenderingVolume-9.0d.lib")
#pragma comment(lib, "vtkRenderingVolumeOpenGL2-9.0d.lib")
#pragma comment(lib, "vtkRenderingVtkJS-9.0d.lib")
#pragma comment(lib, "vtksqlite-9.0d.lib")
#pragma comment(lib, "vtksys-9.0d.lib")
#pragma comment(lib, "vtkTestingRendering-9.0d.lib")
#pragma comment(lib, "vtktheora-9.0d.lib")
#pragma comment(lib, "vtktiff-9.0d.lib")
#pragma comment(lib, "vtkverdict-9.0d.lib")
#pragma comment(lib, "vtkViewsContext2D-9.0d.lib")
#pragma comment(lib, "vtkViewsCore-9.0d.lib")
#pragma comment(lib, "vtkViewsInfovis-9.0d.lib")
#pragma comment(lib, "vtkWrappingTools-9.0d.lib")
#pragma comment(lib, "vtkzlib-9.0d.lib")
#else
#pragma comment(lib, "vtkChartsCore-9.0.lib")
#pragma comment(lib, "vtkCommonColor-9.0.lib")
#pragma comment(lib, "vtkCommonComputationalGeometry-9.0.lib")
#pragma comment(lib, "vtkCommonCore-9.0.lib")
#pragma comment(lib, "vtkCommonDataModel-9.0.lib")
#pragma comment(lib, "vtkCommonExecutionModel-9.0.lib")
#pragma comment(lib, "vtkCommonMath-9.0.lib")
#pragma comment(lib, "vtkCommonMisc-9.0.lib")
#pragma comment(lib, "vtkCommonSystem-9.0.lib")
#pragma comment(lib, "vtkCommonTransforms-9.0.lib")
#pragma comment(lib, "vtkDICOMParser-9.0.lib")
#pragma comment(lib, "vtkDomainsChemistry-9.0.lib")
#pragma comment(lib, "vtkdoubleconversion-9.0.lib")
#pragma comment(lib, "vtkexodusII-9.0.lib")
#pragma comment(lib, "vtkexpat-9.0.lib")
#pragma comment(lib, "vtkFiltersAMR-9.0.lib")
#pragma comment(lib, "vtkFiltersCore-9.0.lib")
#pragma comment(lib, "vtkFiltersExtraction-9.0.lib")
#pragma comment(lib, "vtkFiltersFlowPaths-9.0.lib")
#pragma comment(lib, "vtkFiltersGeneral-9.0.lib")
#pragma comment(lib, "vtkFiltersGeneric-9.0.lib")
#pragma comment(lib, "vtkFiltersGeometry-9.0.lib")
#pragma comment(lib, "vtkFiltersHybrid-9.0.lib")
#pragma comment(lib, "vtkFiltersHyperTree-9.0.lib")
#pragma comment(lib, "vtkFiltersImaging-9.0.lib")
#pragma comment(lib, "vtkFiltersModeling-9.0.lib")
#pragma comment(lib, "vtkFiltersParallel-9.0.lib")
#pragma comment(lib, "vtkFiltersParallelImaging-9.0.lib")
#pragma comment(lib, "vtkFiltersPoints-9.0.lib")
#pragma comment(lib, "vtkFiltersProgrammable-9.0.lib")
#pragma comment(lib, "vtkFiltersSelection-9.0.lib")
#pragma comment(lib, "vtkFiltersSMP-9.0.lib")
#pragma comment(lib, "vtkFiltersSources-9.0.lib")
#pragma comment(lib, "vtkFiltersStatistics-9.0.lib")
#pragma comment(lib, "vtkFiltersTexture-9.0.lib")
#pragma comment(lib, "vtkFiltersTopology-9.0.lib")
#pragma comment(lib, "vtkFiltersVerdict-9.0.lib")
#pragma comment(lib, "vtkfreetype-9.0.lib")
#pragma comment(lib, "vtkGeovisCore-9.0.lib")
#pragma comment(lib, "vtkgl2ps-9.0.lib")
#pragma comment(lib, "vtkglew-9.0.lib")
#pragma comment(lib, "vtkhdf5-9.0.lib")
#pragma comment(lib, "vtkhdf5_hl-9.0.lib")
#pragma comment(lib, "vtkImagingColor-9.0.lib")
#pragma comment(lib, "vtkImagingCore-9.0.lib")
#pragma comment(lib, "vtkImagingFourier-9.0.lib")
#pragma comment(lib, "vtkImagingGeneral-9.0.lib")
#pragma comment(lib, "vtkImagingHybrid-9.0.lib")
#pragma comment(lib, "vtkImagingMath-9.0.lib")
#pragma comment(lib, "vtkImagingMorphological-9.0.lib")
#pragma comment(lib, "vtkImagingSources-9.0.lib")
#pragma comment(lib, "vtkImagingStatistics-9.0.lib")
#pragma comment(lib, "vtkImagingStencil-9.0.lib")
#pragma comment(lib, "vtkInfovisCore-9.0.lib")
#pragma comment(lib, "vtkInfovisLayout-9.0.lib")
#pragma comment(lib, "vtkInteractionImage-9.0.lib")
#pragma comment(lib, "vtkInteractionStyle-9.0.lib")
#pragma comment(lib, "vtkInteractionWidgets-9.0.lib")
#pragma comment(lib, "vtkIOAMR-9.0.lib")
#pragma comment(lib, "vtkIOAsynchronous-9.0.lib")
#pragma comment(lib, "vtkIOCityGML-9.0.lib")
#pragma comment(lib, "vtkIOCore-9.0.lib")
#pragma comment(lib, "vtkIOEnSight-9.0.lib")
#pragma comment(lib, "vtkIOExodus-9.0.lib")
#pragma comment(lib, "vtkIOExport-9.0.lib")
#pragma comment(lib, "vtkIOExportGL2PS-9.0.lib")
#pragma comment(lib, "vtkIOExportPDF-9.0.lib")
#pragma comment(lib, "vtkIOGeometry-9.0.lib")
#pragma comment(lib, "vtkIOImage-9.0.lib")
#pragma comment(lib, "vtkIOImport-9.0.lib")
#pragma comment(lib, "vtkIOInfovis-9.0.lib")
#pragma comment(lib, "vtkIOLegacy-9.0.lib")
#pragma comment(lib, "vtkIOLSDyna-9.0.lib")
#pragma comment(lib, "vtkIOMINC-9.0.lib")
#pragma comment(lib, "vtkIOMotionFX-9.0.lib")
#pragma comment(lib, "vtkIOMovie-9.0.lib")
#pragma comment(lib, "vtkIONetCDF-9.0.lib")
#pragma comment(lib, "vtkIOOggTheora-9.0.lib")
#pragma comment(lib, "vtkIOParallel-9.0.lib")
#pragma comment(lib, "vtkIOParallelXML-9.0.lib")
#pragma comment(lib, "vtkIOPLY-9.0.lib")
#pragma comment(lib, "vtkIOSegY-9.0.lib")
#pragma comment(lib, "vtkIOSQL-9.0.lib")
#pragma comment(lib, "vtkIOTecplotTable-9.0.lib")
#pragma comment(lib, "vtkIOVeraOut-9.0.lib")
#pragma comment(lib, "vtkIOVideo-9.0.lib")
#pragma comment(lib, "vtkIOXML-9.0.lib")
#pragma comment(lib, "vtkIOXMLParser-9.0.lib")
#pragma comment(lib, "vtkjpeg-9.0.lib")
#pragma comment(lib, "vtkjsoncpp-9.0.lib")
#pragma comment(lib, "vtklibharu-9.0.lib")
#pragma comment(lib, "vtklibproj-9.0.lib")
#pragma comment(lib, "vtklibxml2-9.0.lib")
#pragma comment(lib, "vtkloguru-9.0.lib")
#pragma comment(lib, "vtklz4-9.0.lib")
#pragma comment(lib, "vtklzma-9.0.lib")
#pragma comment(lib, "vtkmetaio-9.0.lib")
#pragma comment(lib, "vtknetcdf-9.0.lib")
#pragma comment(lib, "vtkogg-9.0.lib")
#pragma comment(lib, "vtkParallelCore-9.0.lib")
#pragma comment(lib, "vtkParallelDIY-9.0.lib")
#pragma comment(lib, "vtkpng-9.0.lib")
#pragma comment(lib, "vtkpugixml-9.0.lib")
#pragma comment(lib, "vtkRenderingAnnotation-9.0.lib")
#pragma comment(lib, "vtkRenderingContext2D-9.0.lib")
#pragma comment(lib, "vtkRenderingCore-9.0.lib")
#pragma comment(lib, "vtkRenderingFreeType-9.0.lib")
#pragma comment(lib, "vtkRenderingGL2PSOpenGL2-9.0.lib")
#pragma comment(lib, "vtkRenderingImage-9.0.lib")
#pragma comment(lib, "vtkRenderingLabel-9.0.lib")
#pragma comment(lib, "vtkRenderingLOD-9.0.lib")
#pragma comment(lib, "vtkRenderingOpenGL2-9.0.lib")
#pragma comment(lib, "vtkRenderingSceneGraph-9.0.lib")
#pragma comment(lib, "vtkRenderingUI-9.0.lib")
#pragma comment(lib, "vtkRenderingVolume-9.0.lib")
#pragma comment(lib, "vtkRenderingVolumeOpenGL2-9.0.lib")
#pragma comment(lib, "vtkRenderingVtkJS-9.0.lib")
#pragma comment(lib, "vtksqlite-9.0.lib")
#pragma comment(lib, "vtksys-9.0.lib")
#pragma comment(lib, "vtkTestingRendering-9.0.lib")
#pragma comment(lib, "vtktheora-9.0.lib")
#pragma comment(lib, "vtktiff-9.0.lib")
#pragma comment(lib, "vtkverdict-9.0.lib")
#pragma comment(lib, "vtkViewsContext2D-9.0.lib")
#pragma comment(lib, "vtkViewsCore-9.0.lib")
#pragma comment(lib, "vtkViewsInfovis-9.0.lib")
#pragma comment(lib, "vtkWrappingTools-9.0.lib")
#pragma comment(lib, "vtkzlib-9.0.lib")
#endif

이렇게 작성한 Property Sheet 파일은 경로가 수정될 경우 VTK_DIR 매크로만 수정을하면 되며 사용하는 Object가 추가될 경우 VTK_Prep.h 파일만 수정하면 되며 다른 프로젝트에 적용시 이 두 파일을 적용을 하면 된다.


프로젝트 코드 작성

리소스 뷰의 대화상자 리소스에 Picture Control을 올리고 이름을 IDC_STATIC_VTK_FRAME으로 설정하고 속성중 Type를 Owner Draw로 설정한다. 그리고 아래과 같이 코드를 추가하였

// Header 파일
public:
	vtkSmartPointer< vtkRenderWindow >		m_pVTKRenderWnd;
	void initVTKWindow(void* hWnd);
	void resizeVTKWindow();

// Source 파일
void CTestVTKDlg::initVTKWindow(void* hWnd)
{
	if (m_pVTKRenderWnd == nullptr)
	{
		// Interactor 생성
		vtkSmartPointer<vtkRenderWindowInteractor> pInteractor =
			vtkSmartPointer<vtkRenderWindowInteractor>::New();

		// Trackball Camera 인터랙션 스타일 적용
		pInteractor->SetInteractorStyle(
			vtkSmartPointer<vtkInteractorStyleTrackballCamera>::New());

		// Renderer 생성
		vtkSmartPointer<vtkRenderer> pRenderer =
			vtkSmartPointer<vtkRenderer>::New();
		pRenderer->SetBackground(0.0, 0.0, 0.0);

		// RenderWindow 생성 후 Dialog 핸들, Interactor, Renderer 설정
		m_pVTKRenderWnd = vtkSmartPointer<vtkRenderWindow>::New();
		m_pVTKRenderWnd->SetParentId(hWnd);
		m_pVTKRenderWnd->SetInteractor(pInteractor);
		m_pVTKRenderWnd->AddRenderer(pRenderer);
		m_pVTKRenderWnd->Render();
	}
}

void CTestVTKDlg::resizeVTKWindow()
{
	CRect rc;
	GetDlgItem(IDC_STATIC_VTK_FRAME)->GetClientRect(&rc);
	m_pVTKRenderWnd->SetSize(rc.Width(), rc.Height());
}

BOOL CTestVTKDlg::OnInitDialog()
{
	|

	if (GetDlgItem(IDC_STATIC_VTK_FRAME))
	{
		initVTKWindow(GetDlgItem(IDC_STATIC_VTK_FRAME)->GetSafeHwnd());
		resizeVTKWindow();
	}

	return TRUE;  // return TRUE  unless you set the focus to a control
}


프로젝트 실행

이렇게 작성된 프로젝트를 실행하면 dll파일이 없다는 에러 메시지가 출력되는데 프로젝트의 속성에 Debugging 페이지의 Environment 항목에 VTK 빌드 결과물의 bin 폴더를 지정해준다.

Debugging > Environment: PATH=$(VTK_DIR)\bin


설정 후 프로그젝트를 실행하면 대화상자의 Picture Control에 검은색 배경이 보이면 정상적으로 실행이 된 것이다.


Cone 그려보기

대화 상자에 버튼을 올리고 버튼의 이벤트 핸들러에 아래와 같이 코드를 추가한다.

void CTestVTKDlg::OnBnClickedButtonCone()
{
	// Create a cone source
	vtkSmartPointer<vtkConeSource> pConeSource =
		vtkSmartPointer<vtkConeSource>::New();

	// Create a mapper and actor
	vtkSmartPointer<vtkPolyDataMapper> pMapper =
		vtkSmartPointer<vtkPolyDataMapper>::New();
	pMapper->SetInputConnection(pConeSource->GetOutputPort());

	vtkSmartPointer<vtkActor> pActor =
		vtkSmartPointer<vtkActor>::New();
	pActor->SetMapper(pMapper);

	// Visualize
	vtkSmartPointer<vtkRenderer> pRenderer =
		vtkSmartPointer<vtkRenderer>::New();
	pRenderer->AddActor(pActor);
	pRenderer->SetBackground(0.1, 0.2, 0.3);
	pRenderer->ResetCamera();

	// Rendering
	m_pVTKRenderWnd->AddRenderer(pRenderer);
	m_pVTKRenderWnd->Render();
}

추가후 실행하면 아래와같이 각뿔 형태의 콘이 출력된다.



참고한 서적이나 인터넷의 자료에는 프로젝트의 메모리 누수를 방지하기위해서 VTK Dll들을 Delay Load를 설정해야 한다고 하였으나 본인이 테스트한 VTK 9.0.1 과 Visual Studio 2019버전에서의 테스트에서는 Delay Load를 설정하지 않아도 메모리 누수가 발생하지 않았다.


참고 자료

VTK 프로그래밍 - 일진사

https://luckygg.tistory.com/130




VTK 9.0.1 컴파일하기

오랜만에 버전업이 된 VTK를 빌드해 보았다.

버전이 올라감에따라 높은 버전의 컴파일러(Visual Studio 2015 이상)를 요구하였지만 컴파일 설정은 이전보다 단순화 되었다.

빌드는 Visual Studio 2015 버전과 Visual Studio 2019 버전을 사용하였다.


다운로드 받은 VTK v9.0.1 소스를 작업 폴더에 압축해제 한 후, CMake v3.18.1 버전을 이용하여 구성을 하였다.


컴파일러는 Visual Studio 2019 버전으로 64비트를 선택하였다.


설정은 설치 경로와 Python 버전을 3으로 설정한 것 밖에 없다.

CMAKE_INSTALL_PREFIX: D:/DevWork/VTK/VTK-9.0.1/VS2019_x64/install

VTK_PYTHON_VERSION: 3

빌드는 ALL_BUILD 프로젝트와 INSTALL 프로젝트에 대하여 Debug와 Release 만 빌드를 수행하였다.

빌드는 시간은 많이 소요되었지만 에러없이 결과물을 얻을 수 있었다.

결과물로는 CMAKE_INSTALL_PREFIX 경로에 여러 폴더가 만들어지고 dll 과 lib 그리고 헤더파일이 만들어진다.

2020/07/22

ZXing-cpp 라이브러리를 이용한 QRCode 인식

ZXing-cpp(https://github.com/glassechidna/zxing-cpp) 라이브러리를 이용한 QRCode 인식을 해 보았다.

그간 ZXing-cpp 라이브러리를 보다 쉽게 사용하기 위해 OpenCV 라이브러리를 포함하여 만들려 했으나 굳이 그럴 필요 없이 기본 사양으로 만들어 OpenCV Raw 데이터를 이용하여 바코드 검사를 수행하도록 해 보았다. 다행스럽게도 동작이 잘 되었다. 디버그 모드에서 인식속도와 인식률은 떨어지지만 동작은 잘 되었다.


try
{
	zxing::ArrayRef<char> greyData((char*)pBuff, nWidth * nHeight);
	zxing::Ref< zxing::LuminanceSource > source(new zxing::GreyscaleLuminanceSource(greyData, nWidth, nHeight, 0, 0, nWidth, nHeight));

	zxing::Ref< zxing::Binarizer> binarizer(new zxing::GlobalHistogramBinarizer(source));
	zxing::Ref< zxing::BinaryBitmap> bitmap(new zxing::BinaryBitmap(binarizer));

	zxing::Ref< zxing::Reader > reader;
	reader.reset(new zxing::MultiFormatReader);
	zxing::Ref< zxing::Result> result(reader->decode(bitmap, zxing::DecodeHints(zxing::DecodeHints::DEFAULT_HINT)));

	zxing::Ref< zxing::String > ResultString = result->getText();
	if ( ResultString->getText().length() > 0 )
	{
		++nDetectedBarcodeCount;
		strncpy_s( szResult, nBufSize, ResultString->getText().c_str(), _TRUNCATE );

		strcat_s(szExtraResult, nBufSize, zxing::BarcodeFormat::barcodeFormatNames[result->getBarcodeFormat().value]);
		
		// Get result point count
		char szPoint[20];
		zxing::ArrayRef< zxing::Ref<zxing::ResultPoint> > resultPoints = result->getResultPoints();
		if ( resultPoints->size() > 0 ) strcat_s(szExtraResult, nBufSize, "|");
		for (int p = 0; p < resultPoints->size(); p++)
		{
			sprintf_s(szPoint, 20, "%.1fx%.1f", resultPoints[p]->getX(), resultPoints[p]->getY());

			if (p > 0) strcat_s(szExtraResult, nBufSize, ","); // Add Seprator
			strcat_s(szExtraResult, nBufSize, szPoint);
		}
	}
}
catch (const zxing::ReaderException& e)
{
	char szLog[2048] = { 0 };
	sprintf_s(szLog, _TRUNCATE, "zxing::ReaderException: %s", e.what());
	CZXingBarcode::writeLog(szLog);

	nErrorCode = -101;
}
catch (const zxing::IllegalArgumentException& e)
{
	char szLog[2048] = { 0 };
	sprintf_s(szLog, _TRUNCATE, "zxing::IllegalArgumentException: %s", e.what());
	CZXingBarcode::writeLog(szLog);

	nErrorCode = -102;
}
catch (const zxing::Exception& e)
{
	char szLog[2048] = { 0 };
	sprintf_s(szLog, _TRUNCATE, "zxing::Exception: %s", e.what());
	CZXingBarcode::writeLog(szLog);

	nErrorCode = -103;
}
catch (const std::exception& e)
{
	char szLog[2048] = { 0 };
	sprintf_s(szLog, _TRUNCATE, "std::exception: %s", e.what());
	CZXingBarcode::writeLog(szLog);

	nErrorCode = -104;
}

2020/06/26

C++ 람다(Lambda) 함수 재귀호출

람다 함수를 재귀호출을 하려면 함수를 auto로 생성하면 안되고 std::function으로 생성해야 한다.
	std::function< int (int)> fibonacci = [&fibonacci](int nValue) -> int
	{
		if ( nValue <= 0 ) return 0;
		if ( nValue == 1 ) return 1;

		return fibonacci(nValue - 1) + fibonacci(nValue - 2);
	};

	int nResult = fibonacci(10);
	TRACE("Fibonacci: %d\n", nResult);

2020/06/18

[MFC] 관리자 권한을 필요로 하는 프로그램 만들기

관리자 권한이 필요한 프로그램을 만들어야 할 일이 있어 만드는 방법을 찾아보았다.

방법은 간단하였다. Visual Studio의 프로젝트 속성에서 Linker의 Manifest File 설정 항목중 UAC Execution Level 을 "requireAdministrator" 로 설정해 주면된다.

이렇게 만들어진 프로그램은 프로그램 아이콘에 방패모양이 오버레이된다.

Visual Studio 에서 프로젝트를 실행하려 할 경우 관리자 권한이 필요하여 아래 이미지처럼 관리자 계정으로 다시 시작을 요하는 메시지 박스가 나온다.

재시작 메뉴를 선택하면 현재 기동중인 Visual Studio가 종료되고 새로운 Visual Studio가 실행되며 관리자 권한은 요청하는 메시지 박스가 나타난다.

확인 후 실행된 Visual Studio은 아래처럼 관리자 권한으로 실행되었다.

이제 프로젝트를 실행할 수 있다.

2020/05/29

[MFC] TreeCtrl 전체 노드 확장하기

	// 전체 Tree 확장
	std::function< void (HTREEITEM) > ldExpand = [&](HTREEITEM hItem)
	{
		if ( m_treeLibrary.ItemHasChildren(hItem) )
		{
			m_treeLibrary.Expand( hItem, TVE_EXPAND );
			HTREEITEM hChild = m_treeLibrary.GetChildItem(hItem);
			if ( hItem != nullptr ) ldExpand(hChild);
		}

		hItem = m_treeLibrary.GetNextSiblingItem(hItem);
		if ( hItem != nullptr ) ldExpand(hItem);
	};

	HTREEITEM hRootItem = m_treeLibrary.GetRootItem();
	ldExpand(hRootItem);