CentOS 7에 특정 버전의 Docker-CE 설치하기

$ yum remove docker docker-client docker-client-latest docker-common docker-latest                   docker-latest-logrotate docker-logrotate docker-engine
$ rm -rf /var/lib/docker/

$ sudo yum install -y yum-utils

$ yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
$ yum list docker-ce --showduplicates | sort -r
...
docker-ce.x86_64            3:19.03.4-3.el7                     docker-ce-stable
docker-ce.x86_64            3:19.03.3-3.el7                     docker-ce-stable
docker-ce.x86_64            3:19.03.2-3.el7                     docker-ce-stable
docker-ce.x86_64            3:19.03.1-3.el7                     docker-ce-stable
docker-ce.x86_64            3:19.03.11-3.el7                    docker-ce-stable
docker-ce.x86_64            3:19.03.10-3.el7                    docker-ce-stable
docker-ce.x86_64            3:19.03.0-3.el7                     docker-ce-stable
docker-ce.x86_64            3:18.09.9-3.el7                     docker-ce-stable
docker-ce.x86_64            3:18.09.8-3.el7                     docker-ce-stable
docker-ce.x86_64            3:18.09.7-3.el7                     docker-ce-stable
docker-ce.x86_64            3:18.09.6-3.el7                     docker-ce-stable
...

$ yum install docker-ce-18.09.9 docker-ce-cli-18.09.9

$ docker --version
Docker version 18.09.9, build 039a7df9ba

$ systemctl enable docker
Created symlink from /etc/systemd/system/multi-user.target.wants/docker.service to /usr/lib/systemd/system/docker.service.

$ systemctl start docker
$ systemctl status docker

Ubuntu 12.04 에 Python 3.7 설치하기

사실 python 에서 protobuf3 를 사용할려면..
최신의 protobuf3 버전이 현재 python 3.7용만 설치가 되는듯하다..
기본 Ubuntu 12.04는 python이.. 3.8..

암튼.. python 3.7을 설치하려면 아래와 같이 하면됨.

$ sudo add-apt-repository ppa:deadsnakes/ppa
$ sudo apt install python3.7
$ curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
$ python3.7 get-pip.py

$ vim ~/.bashrc
alias pip='/home/ihmin/.local/bin/pip3.7'
alias python='/usr/bin/python3.7'

$ python --version
Python 3.7.7

$ pip --version
pip 20.1.1 from /home/ihmin/.local/lib/python3.7/site-packages/pip (python 3.7)

pip로 설치된 package는 아래에 설치됨.

/home/ihmin/.local/lib/python3.7/site-packages

CentOS 6.x 에 Python 3 버전 설치하기

$ yum install -y https://repo.ius.io/ius-release-el6.rpm
$ yum install -y python36u python36u-libs python36u-devel python36u-pip
$ python3.6 -V
Python 3.6.8
$ rm -f /usr/bin/python3
$ ln -s /usr/bin/python3.6 /usr/bin/python3
$ python3
Python 3.6.8 (default, Aug 10 2019, 06:52:10) 
[GCC 4.4.7 20120313 (Red Hat 4.4.7-23)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> 

opencv4nodejs 설치

우선 opencv4nodejs 를 설치하려면..
당연히 visual studio 타 기타 개발 툴들이 정상적으로 설치되어 있어야한다..
근데 착하게도.. node.js 용 네이티브 모듈을 설치하는데 필요한 개발툴을 자동으로 깔아주는 모듈이 있음..

https://github.com/felixrieseberg/windows-build-tools

우선 cmd를 관리자권한으로 실행하고..
아래를 실행하면 python이나 vs 같은 개발툴이 자동으로 설치가 된다..

C:\> npm install --global windows-build-tools

다음 아래를 실행하면 node.js용 opencv가 설치됨.

C:\> npm i opencv4nodejs 

CentOS 6 gcc 버전 업데이트

$ yum install centos-release-scl-rh centos-release-scl
$ yum check-update
$ yum install devtoolset-7-gcc-c++
$ source /opt/rh/devtoolset-7/enable
$ gcc --version
gcc (GCC) 7.3.1 20180303 (Red Hat 7.3.1-5)
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

아래도 가능..

yum install devtoolset-7-gcc-c++ (GCC 7.3.1)
yum install devtoolset-8-gcc-c++ (GCC 8.3.1)
yum install devtoolset-9-gcc-c++ (GCC 9.1.1)

아래와 같이 devtoolset-7-gcc-c++ 을 enable..

$ vim /etc/profile.d/enabledevtoolset-7.sh
#!/bin/bash
source /opt/rh/devtoolset-7/enable

LMDB

메모리에 통째로 올려 놓고 쓰는 작지만 아주 빠른 DB..
Key, Value 로 이루어진 심플한 DB..
쓰레드에 안전한 DB..
Fetch 시에 추가적인 시간이 들지 않는 빠른 DB.. (이미 메모리에 올려져있는 상태..)

http://www.lmdb.tech/
http://www.lmdb.tech/doc/index.html
https://github.com/LMDB/lmdb

자작 어플리케이션의 세션 저장용으로 쓰면 아주 좋을듯하다..
msys2의 pacman 패키지로도 설치 가능..

Crypto++ 을 이용한 암호화/복호화 예제

출처: https://lyb1495.tistory.com/25

가끔 텍스트 파일을 감추고 싶을때.. 이용하면 좋음.

#include <iostream>
#include <iomanip>

#include "cryptopp/cryptlib.h"
#include "cryptopp/modes.h"
#include "cryptopp/aes.h"
#include "cryptopp/filters.h"
#include "cryptopp/base64.h"

void hex2byte(const char *in, uint len, byte *out)
{
	for (uint i = 0; i < len; i+=2) {
		char c0 = in[i+0];
		char c1 = in[i+1];
		byte c = (
			((c0 & 0x40 ? (c0 & 0x20 ? c0-0x57 : c0-0x37) : c0-0x30)<<4) |
			((c1 & 0x40 ? (c1 & 0x20 ? c1-0x57 : c1-0x37) : c1-0x30))
			);
		out[i/2] = c;
	}
}

int main(int argc, char* argv[]) {
	// 키 할당
	byte key[CryptoPP::AES::DEFAULT_KEYLENGTH];
	memset(key, 0x00, CryptoPP::AES::DEFAULT_KEYLENGTH );
	char* rawKey="f4150d4a1ac5708c29e437749045a39a";
	hex2byte(rawKey, strlen(rawKey), key);

	// 초기벡터 할당
	byte iv[CryptoPP::AES::BLOCKSIZE];
	memset(iv, 0x00, CryptoPP::AES::BLOCKSIZE );
	char* rawIv="86afc43868fea6abd40fbf6d5ed50905";
	hex2byte(rawIv, strlen(rawIv), iv);

	// 평문 할당
	std::string plaintext = "http://sopt.org/";
	std::string ciphertext;
	std::string base64encodedciphertext;
	std::string decryptedtext;
	std::string base64decryptedciphertext;

	// 평문 출력
	std::cout << "Plain Text (" << plaintext.size() <<
		" bytes)" << std::endl;
	std::cout << plaintext;
	std::cout << std::endl << std::endl;

	unsigned int plainTextLength = plaintext.length();

	// AES 암호화 수행
	CryptoPP::AES::Encryption 
		aesEncryption(key, CryptoPP::AES::DEFAULT_KEYLENGTH);
	CryptoPP::CBC_Mode_ExternalCipher::Encryption 
		cbcEncryption(aesEncryption, iv);

	CryptoPP::StreamTransformationFilter 
		stfEncryptor(cbcEncryption, new CryptoPP::StringSink( ciphertext));
	stfEncryptor.Put(reinterpret_cast<const unsigned="" char*="">
		(plaintext.c_str()), plainTextLength + 1);
	stfEncryptor.MessageEnd();

	// Base64 인코딩
	CryptoPP::StringSource(ciphertext, true,
		new CryptoPP::Base64Encoder(
		new CryptoPP::StringSink(base64encodedciphertext)
		) // Base64Encoder
		); // StringSource

	// Base64 인코딩 문자열 출력
	std::cout << "Cipher Text (" << base64encodedciphertext.size() 
		<< " bytes)" << std::endl;
	std::cout << "cipher : " << base64encodedciphertext << std::endl;
	std::cout << std::endl << std::endl;

	// Base64 디코딩
	CryptoPP::StringSource(base64encodedciphertext, true,
		new CryptoPP::Base64Decoder(
		new CryptoPP::StringSink( base64decryptedciphertext)
		) // Base64Encoder
		); // StringSource

	// AES 복호화
	CryptoPP::AES::Decryption aesDecryption(key, 
		CryptoPP::AES::DEFAULT_KEYLENGTH);
	CryptoPP::CBC_Mode_ExternalCipher::Decryption 
		cbcDecryption(aesDecryption, iv );

	CryptoPP::StreamTransformationFilter 
		stfDecryptor(cbcDecryption, new CryptoPP::StringSink(decryptedtext));
	stfDecryptor.Put( reinterpret_cast<const unsigned="" char*="">
		(base64decryptedciphertext.c_str()), base64decryptedciphertext.size());
	stfDecryptor.MessageEnd();

	// 복호화 문자열 출력
	std::cout << "Decrypted Text: " << std::endl;
	std::cout << decryptedtext;
	std::cout << std::endl << std::endl;
	return 0;
}

pacman 패키지 삭제하기

우선.. 버전을 빼고 설치된 패키지 목록을 보기..

% pacman -Q|cut -f 1 -d " "
apr
apr-devel
apr-util
apr-util-devel
asciidoc
aspell
aspell-devel
autoconf
autoconf2.13
autogen
automake-wrapper
automake1.1
...

다음.. 의존성 걸린 패키지들까지 몽땅 삭제하기..

% pacman -Rcn mingw-w64-i686-SDL2 mingw-w64-i686-allegro mingw-w64-i686-boost mingw-w64-i686-cgal mingw-w64-i686-clblast mingw-w64-i686-doxygen mingw-w64-i686-eigen3 mingw-w64-i686-ffmpeg mingw-w64-i686-fftw mingw-w64-i686-fontconfig mingw-w64-i686-freealut mingw-w64-i686-freeimage mingw-w64-i686-ftgl mingw-w64-i686-glew mingw-w64-i686-glfw mingw-w64-i686-glm mingw-w64-i686-imagemagick mingw-w64-i686-intel-tbb mingw-w64-i686-liblas mingw-w64-i686-libmariadbclient mingw-w64-i686-libssh2 mingw-w64-i686-libzip mingw-w64-i686-magnum mingw-w64-i686-magnum-integration mingw-w64-i686-magnum-plugins mingw-w64-i686-oce mingw-w64-i686-pdcurses mingw-w64-i686-physfs mingw-w64-i686-pkg-config mingw-w64-i686-python2 mingw-w64-i686-qt-creator mingw-w64-i686-qt5 mingw-w64-i686-wxWidgets mingw-w64-i686-zeromq
checking dependencies...
:: mingw-w64-i686-harfbuzz optionally requires mingw-w64-i686-cairo: hb-view program
:: mingw-w64-i686-libde265 optionally requires mingw-w64-i686-ffmpeg: sherlock265
:: mingw-w64-i686-libde265 optionally requires mingw-w64-i686-qt5: sherlock265
warning: dependency cycle detected:
warning: mingw-w64-i686-ffms2 will be removed after its mingw-w64-i686-ffmpeg dependency

Packages (47) mingw-w64-i686-cairo-1.16.0-1  mingw-w64-i686-curl-7.69.1-2
              mingw-w64-i686-ffms2-2.23.1-1  mingw-w64-i686-flif-0.3-1
              mingw-w64-i686-gdal-3.0.4-2  mingw-w64-i686-libass-0.14.0-1
              mingw-w64-i686-libcaca-0.99.beta19-5
              mingw-w64-i686-libkml-1.3.0-8  mingw-w64-i686-netcdf-4.7.3-1
              mingw-w64-i686-poppler-0.86.1-1  mingw-w64-i686-qbs-1.15.0-1
              mingw-w64-i686-ttf-dejavu-2.37-2
              mingw-w64-i686-x264-git-r2991.1771b556-1
              mingw-w64-i686-SDL2-2.0.12-1  mingw-w64-i686-allegro-5.2.6.0-1
              mingw-w64-i686-boost-1.72.0-1  mingw-w64-i686-cgal-5.0-1
              mingw-w64-i686-clblast-1.5.1-1  mingw-w64-i686-doxygen-1.8.17-1
              mingw-w64-i686-eigen3-3.3.7-1  mingw-w64-i686-ffmpeg-4.2.2-2
              mingw-w64-i686-fftw-3.3.8-1  mingw-w64-i686-fontconfig-2.13.1-1
              mingw-w64-i686-freealut-1.1.0-1
              mingw-w64-i686-freeimage-3.18.0-3  mingw-w64-i686-ftgl-2.4.0-1
              mingw-w64-i686-glew-2.1.0-1  mingw-w64-i686-glfw-3.3.2-1
              mingw-w64-i686-glm-0.9.9.7-1
              mingw-w64-i686-imagemagick-7.0.9.17-1
              mingw-w64-i686-intel-tbb-1~2020.2-1
              mingw-w64-i686-liblas-1.8.1-1
              mingw-w64-i686-libmariadbclient-2.3.7-1
              mingw-w64-i686-libssh2-1.9.0-1  mingw-w64-i686-libzip-1.6.1-1
              mingw-w64-i686-magnum-2019.10-1
              mingw-w64-i686-magnum-integration-2019.01-2
              mingw-w64-i686-magnum-plugins-2019.10-1
              mingw-w64-i686-oce-0.18.3-3  mingw-w64-i686-pdcurses-4.1.0-3
              mingw-w64-i686-physfs-3.0.2-1  mingw-w64-i686-pkg-config-0.29.2-1
              mingw-w64-i686-python2-2.7.17-1
              mingw-w64-i686-qt-creator-4.11.1-1  mingw-w64-i686-qt5-5.14.1-3
              mingw-w64-i686-wxWidgets-3.0.4-3  mingw-w64-i686-zeromq-4.3.2-1

Total Removed Size:  2425.99 MiB

:: Do you want to remove these packages? [Y/n]
...

PMP 라이브러리 Half Edge 테스트

폴리곤 메시 처리 라이브러리중 PMP 라이브러리가 있음..

https://www.pmp-library.org/

OpenMesh 와 비교하여 비교적 심플한 사용법과..상당히 구조적으로 잘 짜여져 있음..
근데 사실.. half edge 의 특성상 half edge 한개가 2개 이상의 face를 공유할수 없는 문제로..
실제 mesh 편집 프로그램에서는 사용하기가 어렵다..

예를 들어 Solid 메시는 한개의 half edge를 두고 2개 이상을 공유해야 하는 문제가 허다하고..
shell 메세중.. 2개이상을 지원해야 하는 경우도 종종있다..

암튼.. 난 이런 사실을 모른체.. 이걸 써야겠다하고.. 맘먹고 테스트해본 코드임..
그냥 이런 라이브러리가 있구나.. 하는 정도만.. 기억할것임.
지금은 직접 만들어 쓰고 있다..

#include <SurfaceMesh.h>

int main(void)
{
	pmp::SurfaceMesh mesh;

	pmp::Vertex v0,v1,v2,v3;

    // add 4 vertices
    v0 = mesh.add_vertex(pmp::Point(0,0,0));
    v1 = mesh.add_vertex(pmp::Point(1,0,0));
    v2 = mesh.add_vertex(pmp::Point(0,1,0));
    v3 = mesh.add_vertex(pmp::Point(0,0,1));

	// temp 노드 셋팅
	pmp::VertexProperty<bool> vtmp;
    vtmp = mesh.add_vertex_property<bool>("v:temp", false);
	vtmp[v0] = true;
	vtmp[v2] = true;
	
	// solver id 셋팅
	pmp::VertexProperty<unsigned int> vsolver;
    vsolver = mesh.add_vertex_property<unsigned int>("v:solver");
	vsolver[v0] = 100;
	vsolver[v1] = 101;
	vsolver[v2] = 102;
	vsolver[v3] = 103;
    //mesh.remove_vertex_property(vsolver);

    auto points = mesh.get_vertex_property<bool>("v:temp");

    for (auto v : mesh.vertices())
    {
        if ( points[v] ) {
			printf("%d : temp node, solver id: %d\n", v.idx(), vsolver[v]);
		} else {
			printf("%d : node, solver id: %d\n", v.idx(), vsolver[v]);
		}
    }

    // add 4 triangular faces
	pmp::Face f0 = mesh.add_triangle(v0,v1,v3);
    mesh.add_triangle(v1,v2,v3);
    mesh.add_triangle(v2,v0,v3);
    mesh.add_triangle(v0,v2,v1);
	
	// face에 대한 solver id 셋팅
	pmp::FaceProperty<unsigned int> fsolver;
    fsolver = mesh.add_face_property<unsigned int>("f:solver");
	fsolver[f0] = 10000;
	
	// face에 대한 part id 셋팅
	pmp::FaceProperty<unsigned int> fpart;
    fpart = mesh.add_face_property<unsigned int>("f:part");
	fpart[f0] = 1001;

	// part 1001 번에 대한 opengl 출력용 tri indices
	std::map<unsigned int, std::vector<unsigned int>> indices;
	std::map<pmp::Face, unsigned int> offset;
	offset[f0].push_back(indices[1001].size());
	indices[1001].push_back(v0.idx());
	indices[1001].push_back(v1.idx());
	indices[1001].push_back(v3.idx());
	offset[f1].push_back(indices[1001].size());
	indices[1001].push_back(v1.idx());
	indices[1001].push_back(v2.idx());
	indices[1001].push_back(v3.idx());

    std::cout << "vertices: " << mesh.n_vertices() << std::endl;
    std::cout << "edges: "    << mesh.n_edges()    << std::endl;
    std::cout << "faces: "    << mesh.n_faces()    << std::endl;
}