#include <iostream> //VTK_MODULE_INITに必要 #include <vtkAutoInit.h> #include <vtkSmartPointer.h> #include <vtkRenderer.h> #include <vtkRenderWindow.h> #include <vtkRenderWindowInteractor.h> // コールバック関数を使用するのに必要 #include <vtkCallbackCommand.h> //必須 VTK_MODULE_INIT(vtkRenderingOpenGL2); VTK_MODULE_INIT(vtkInteractionStyle);
// コールバック関数に渡すデータ struct MyData { std::string text; int counter; };
// タイマーのコールバック関数 void MyTimerCallbackFunction(vtkObject* caller, long unsigned int eventId, void* clientData, void* callData) { MyData* data = static_cast<MyData*>(clientData); // タイマーイベントが発生したことを確認する std::cout << data->text << " " << data->counter << std::endl; data->counter++; // 画面更新 auto interactor = static_cast<vtkRenderWindowInteractor*>(caller); interactor->Render(); }
int main(int /*argc*/, char** /*argv*/) { ////////////////////////////////////// auto renderer = vtkSmartPointer<vtkRenderer>::New(); renderer->ResetCamera(); ////////////////////////////////////// auto interactor = vtkSmartPointer<vtkRenderWindowInteractor>::New(); auto renderWindow = vtkSmartPointer<vtkRenderWindow>::New(); renderWindow->AddRenderer(renderer); renderWindow->SetInteractor(interactor); renderWindow->Render(); //////////////////////////////////////
// タイマーに渡す構造体の作成 MyData callbackData{ "Counter:",0 }; // タイマー作成 auto timerCallback = vtkSmartPointer<vtkCallbackCommand>::New(); timerCallback->SetCallback(MyTimerCallbackFunction); // コールバック関数を設定 timerCallback->SetClientData(&callbackData); // コールバック関数に渡すデータを設定 interactor->AddObserver(vtkCommand::TimerEvent, timerCallback); // タイマーイベントにコールバック関数を設定 interactor->Initialize(); interactor->CreateRepeatingTimer(100); // 100msごとにタイマーイベントを発生させる
////////////////////////////////////// interactor->Start(); //イベントループへ入る return 0; }
以前、UnicodeStringを使用したが、これは内部に文字列をコピーしてしまうので、文字列の管理をicuにやらせないのであれば効率が悪い。ubrk_openでブレークイテレータを取得すると、元の文字列に対して操作できる。
#include <iostream> #include <unicode/ubrk.h> #include <unicode/ustring.h> #include <vector> #include <fstream> // 要リンク #pragma comment(lib, "icuuc.lib") struct Grapheme { int32_t start; int32_t end; };
std::vector<Grapheme> createGraphemeList(const char16_t* text,const size_t length) { UErrorCode status = U_ZERO_ERROR; std::vector<Grapheme> graphemes; // イテレータ作成 UBreakIterator* bi = ubrk_open(UBRK_CHARACTER, "ja_JP", nullptr, 0, &status); if (U_FAILURE(status)) { return std::vector<Grapheme>(); // エラーが発生 } // テキストを設定 ubrk_setText(bi, (const UChar*)text, length, &status); // ubrk_setText(bi, (const UChar*)text, -1, &status);// null終端の場合は -1 を指定できる if (U_FAILURE(status)) { ubrk_close(bi); return std::vector<Grapheme>(); // エラーが発生 } // 最初の書記素の位置を取得 int32_t start = ubrk_first(bi); int32_t end; // 書記素リストを作成 while ((end = ubrk_next(bi)) != UBRK_DONE) { graphemes.push_back(Grapheme{ start, end }); start = end; } // 終了処理 ubrk_close(bi); return graphemes; }
int main() { // 日本語ロケール setlocale(LC_ALL, "japanese"); std::u16string u16str = u"あいうえお"; std::vector<Grapheme> glist = createGraphemeList(u16str.data(),u16str.length()); for(size_t i = 0; i < glist.size(); i++) { size_t length = glist[i].end - glist[i].start; std::wstring u16w( (wchar_t*)u16str.data()+ glist[i].start, length); std::wcout << u16w;// 一文字ずつ表示 std::wcout << "( " << glist[i].start << L" " << glist[i].end << " )" << std::endl; } }
結合文字はWindowsのコンソールで扱うとうまく表示できないので、代わりにテキストファイルとして出力して動作確認する。
int main() { // 日本語ロケール setlocale(LC_ALL, "japanese"); std::u16string u16str = u"あい👨👩👧👦うえお"; // 👨👩👧👦 絵文字(結合文字) std::vector<Grapheme> glist = createGraphemeList(u16str.data(), u16str.length()); // バイナリ出力 std::ofstream out("grapheme.txt", std::ios_base::binary); for (size_t i = 0; i < glist.size(); i++) { size_t length = glist[i].end - glist[i].start; out.write((const char*)(u16str.data() + glist[i].start), length * 2);// 一文字出力 out.write("\n", 2); } }
確認には、Wordを開き、テキストファイルを開く際の文字コードをUnicodeに指定するのが良い。
VC++のC++言語標準をISO C++ 20に設定したところ、以下のエラーが出た。
Open3DConfig.h を確認してみると、バージョン 0.9.0.0だった。
#define OPEN3D_VERSION "0.9.0.0"
調べた限りまともな対処法がないので、Open3Dを最新版にする。
公式 https://www.open3d.org/ の下のほうへ行き、0.18.0を選択する。
展開してC++20で使用。
そのままだとC4996が出るので、#pragma warning(disalbe:4996) を入れる。
あるいは
_SILENCE_CXX20_IS_POD_DEPRECATION_WARNING
_SILENCE_STDEXT_ARR_ITERS_DEPRECATION_WARNING
を定義する。
#pragma warning(disable:4996) #if defined(_DEBUG) #pragma comment(lib,"C:\\libraries\\Open3D-0.18.0\\debug\\lib\\Open3D.lib") #else #pragma comment(lib,"C:\\libraries\\Open3D-0.18.0\\release\\lib\\Open3D.lib") #endif #include <Open3D/Open3D.h> #include <iostream> int main() { std::string filename = "bunny.ply"; auto mesh = open3d::io::CreateMeshFromFile(filename); auto pcd = open3d::io::CreatePointCloudFromFile(filename); }
以下のように、StatisticalOutlierRemovalを使ってみると、Eigenのコード内で、aligned_freeで例外が発生する。
#include <pcl/io/pcd_io.h> #include <pcl/point_types.h> #include <pcl/features/normal_3d.h> #include <pcl/filters/statistical_outlier_removal.h> pcl::PointCloud<pcl::PointXYZ>::Ptr create_cloud() { // 点群データの生成 pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>()); cloud->width = 1000; cloud->height = 1; cloud->is_dense = false; cloud->points.resize(cloud->width * cloud->height); for (size_t i = 0; i < cloud->points.size(); ++i) { cloud->points[i].x = 1024 * rand() / (RAND_MAX + 1.0f); cloud->points[i].y = 1024 * rand() / (RAND_MAX + 1.0f); cloud->points[i].z = 1024 * rand() / (RAND_MAX + 1.0f); } return cloud; }
int main(int argc, char** argv) { auto cloud = create_cloud(); pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered(new pcl::PointCloud<pcl::PointXYZ>); pcl::StatisticalOutlierRemoval<pcl::PointXYZ> sor; sor.setInputCloud(cloud); sor.setMeanK(50); sor.setStddevMulThresh(1.0); sor.filter(*cloud_filtered); return 0; }
C:/Program Files/PCL 1.14.1/3rdParty/Eigen3/include/eigen3/Eigen/src/Core/util/memory.h
ファイル内、以下の部分で例外が発生。
/** \internal Frees memory allocated with aligned_malloc. */ EIGEN_DEVICE_FUNC inline void aligned_free(void *ptr) { #if (EIGEN_DEFAULT_ALIGN_BYTES==0) || EIGEN_MALLOC_ALREADY_ALIGNED EIGEN_USING_STD(free) free(ptr); #else handmade_aligned_free(ptr); #endif }
C/C++ → コード生成 → 拡張命令セットを有効にする → Advanced Vector Extensions (X86/X64) (/arch:AVX)
に設定
VTKのvtkSmartPointerは参照カウンタ付きだが、vtkWeakPointerもある(初めて知った)。
まず以下は、vtkSmartPointerを使った場合で、ポインタをコピーするたびに参照カウンタが増え、ポインタにnullptrを代入して無効化することで参照カウンタが減ることを確認する。
vtkSmartPointer<vtkActor> actor1 = vtkSmartPointer<vtkActor>::New(); std::cout << "actor1 reference count: " << actor1->GetReferenceCount() << std::endl; vtkSmartPointer<vtkActor> actor2 = actor1; std::cout << "actor2 reference count: " << actor2->GetReferenceCount() << std::endl; actor1 = nullptr;// actor1を無効化 std::cout << "Delete" << std::endl; // ここは通らない if(actor1) std::cout << "actor1 reference count: " << actor1->GetReferenceCount() << std::endl; if(actor2) std::cout << "actor2 reference count: " << actor2->GetReferenceCount() << std::endl;
vtkWeakPointer<vtkActor> weak_actor; // WeakPointerを定義
{ vtkSmartPointer<vtkActor> actor1 = vtkSmartPointer<vtkActor>::New(); std::cout << "actor1 reference count: " << actor1->GetReferenceCount() << std::endl; weak_actor = actor1;// actor1 を弱参照 参照カウンタは増えない std::cout << "weak_actor reference count: " << weak_actor->GetReferenceCount() << std::endl; vtkSmartPointer<vtkActor> actor2 = actor1; std::cout << "actor2 reference count: " << actor2->GetReferenceCount() << std::endl; actor1 = nullptr; std::cout << "Delete" << std::endl; // ここは通らない if (actor1) std::cout << "actor1 reference count: " << actor1->GetReferenceCount() << std::endl; if (actor2) std::cout << "actor2 reference count: " << actor2->GetReferenceCount() << std::endl; }
if (weak_actor) { // ここは通らない std::cout << "actor1 reference count: " << weak_actor->GetReferenceCount() << std::endl; } else { // こちらを通る std::cout << "actor is deleted" << std::endl; }
gumbo-parseがどのようにデータを保持しているのかをチェックするためのコード。
タグはenumで区別するため、タグ名は保持していない。<から始まっていることを利用してstd::regexでタグ名を取得している。
#include <iostream> #include <fstream> #include <sstream> #include <regex> #include <gumbo.h>
std::string getTagName(std::string str) { // HTMLのタグ名を取得する関数 // タグは< > で囲まれているが、attribute等があるかもしれないので // < スペース 文字列 という構造になっている部分の文字列部分だけを取り出す std::regex tagPattern("<\\s*([^ >]+)\\s*"); std::smatch matches; std::regex_search(str, matches, tagPattern); return matches[1].str(); }
void myTraceCore(const GumboNode* node, const char* src) { switch (node->type) { case GUMBO_NODE_ELEMENT: { // 要素開始位置 const char* tag_start = node->v.element.original_tag.data; // 要素終了位置 const char* tag_end = node->v.element.original_end_tag.data; std::string tagname; // タグ名を抽出 tagname = getTagName(tag_start); std::cout << "tag: '" << tagname << "'" << std::endl; // 子要素一覧へアクセス const GumboVector* children = &node->v.element.children; // 子要素がある場合 if (children->length > 0) { for (unsigned int i = 0; i < children->length; ++i) { const GumboNode* node = static_cast<GumboNode*>(children->data[i]); myTraceCore(node, src); } } // タグ名を抽出 tagname = getTagName(tag_end); std::cout << "tag: '" << tagname << "'" << std::endl; break; } case GUMBO_NODE_TEXT: // テキストノードの場合 std::cout << "text: '" << node->v.text.text << "'" << std::endl; break; case GUMBO_NODE_WHITESPACE: // 空白ノードの場合 std::cout << "whitespace: '" << node->v.text.text << "'" << std::endl; break; default: std::cout << "others: '" << node->v.text.text << "'" << std::endl; break; } }
void myTrace(std::string html) { // Gumboでパース GumboOutput* output = gumbo_parse(html.c_str()); // 自作関数の本体呼び出し myTraceCore(output->root,html.c_str()); // GumboOutputの解放 gumbo_destroy_output(&kGumboDefaultOptions, output); } int main() { std::string html = R"( <!DOCTYPE html> <html> <head> <title>The Title</title> </head> <body> <h1>Test</h1> </body> </html> )"; myTrace(html); }
tag: 'html' tag: 'head' whitespace: ' ' tag: 'title' text: 'The Title' tag: '/title' whitespace: ' ' tag: '/head' whitespace: ' ' tag: 'body' whitespace: ' ' tag: 'h1' text: 'Test' tag: '/h1' whitespace: ' ' tag: '/body' tag: '/html'
node->typeがGUMBO_NODE_ELEMENTの時は、属性を取得できる。
#include <iostream> #include <fstream> #include <sstream> #include <regex> #include <gumbo.h>
// 要素の属性を取得する関数 void myAttributes(const GumboNode* node) { if (node->type != GUMBO_NODE_ELEMENT) { return; } // 要素の属性を取得 const GumboVector* attributes = &node->v.element.attributes; // 属性リストへアクセス for (unsigned int i = 0; i < attributes->length; ++i) { GumboAttribute* attr = (GumboAttribute*)attributes->data[i]; std::cout << " "; std::cout << " " << attr->name << " : " << attr->value << std::endl; } }
void myTraceCore(const GumboNode* node, const char* src) { switch (node->type) { case GUMBO_NODE_ELEMENT: {
/* ... */ myAttributes(node); // 要素の取得
/* ... */ break; } /* ... */ } }
int main() { std::string html = R"( <!DOCTYPE html> <html> <head> <title id = "bodyid" style="color:red;">The Title</title> </head> <body> <h1>Test</h1> </body> </html> )"; myTrace(html); }
id : bodyid
style : color:red;
HTMLを扱う方法を探している。gumbo-parserはgoogleが公開したApache-2.0 licenseのパーサー。
ソースコードをGitHubからダウンロード・展開する。
https://github.com/google/gumbo-parser
CMake不要。.cファイルをコピーしてプロジェクトに加える。
注意点として、windowsにはstrings.hが存在しない。
追加のインクルードディレクトリ:
visualc/includeにはstrings.hが入っている。
・gumbo-parser-master/src
・gumbo-parser-master/visualc/include
プロジェクトへ追加
src/*.c ファイルをプロジェクトへ追加する。
attribute.c
char_ref.c
error.c
parser.c
string_buffer.c
string_piece.c
tag.c
tokenizer.c
utf8.c
util.c
vector.c
・gumbo_parse関数でパースを行う。
・GumboVectorはGumboNodeの配列となっている。
・node->v.element.children->data から子ノードにアクセスできる
#include <iostream> #include <fstream> #include <sstream> #include <gumbo.h>
std::unique_ptr<std::string> getTitleCore(const GumboNode* node) { // ノードがHTML要素の場合だけ処理 if (node->type == GUMBO_NODE_ELEMENT) { // titleタグの場合 if (node->v.element.tag == GUMBO_TAG_TITLE) {
// 子要素一覧へアクセス const GumboVector* children = &node->v.element.children; // 子要素がある場合 if (children->length > 0) { // 子要素の先頭を取得 const GumboNode* child = static_cast<GumboNode*>(children->data[0]); if (child->type == GUMBO_NODE_TEXT) { return std::make_unique<std::string>(child->v.text.text); } }
}
// titleタグ以外の場合、このタグの子要素を全て調査。それを再帰的に行う else {
const GumboVector* children = &node->v.element.children; for (unsigned int i = 0; i < children->length; ++i) { std::unique_ptr<std::string> result = getTitleCore(static_cast<GumboNode*>(children->data[i])); if (result != nullptr) { return result; } }
}
} return nullptr; }
std::unique_ptr<std::string> getTitle(std::string html) { // Gumboでパース GumboOutput* output = gumbo_parse(html.c_str()); // タイトルを取得する自作関数の本体呼び出し std::unique_ptr<std::string> result = getTitleCore(output->root); // GumboOutputの解放 gumbo_destroy_output(&kGumboDefaultOptions, output); return result; }
int main() { std::string html = R"( <html> <head> <title>The Title</title> </head> <body> <h1>Test</h1> </body> </html> )"; std::unique_ptr<std::string> mytitle = getTitle(html); if (mytitle != nullptr) { std::cout << *mytitle << std::endl; } else { std::cout << "** No title **" << std::endl; } }
wxStyledTextCtrlはscintillaというオープンソースのエディタを元に実装されたコントロールで、様々な言語をハイライトできる。
例えば以下のようにStyleSetForegroundを使用すると設定した項目をハイライトできる
//wxStyledTextCtrl #include <wx/stc/stc.h> /* ... */ // ウィンドウ作成 class MyFrame : public wxFrame { public: void PostCreate() {
auto editor = new wxStyledTextCtrl(this, wxID_ANY); editor->SetLexer(wxSTC_LEX_HTML); // HTMLのシンタックスハイライトを設定 editor->StyleSetForeground(wxSTC_H_TAG, wxColour(0, 0, 255)); // タグの色を青に設定 editor->StyleSetForeground(wxSTC_H_ATTRIBUTE, wxColour(255, 255, 0)); editor->StyleSetForeground(wxSTC_H_VALUE, wxColour(0, 0, 0)); editor->StyleSetForeground(wxSTC_H_COMMENT, wxColour(0, 255, 0));
this->Layout(); // レイアウトの更新 } MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size) : wxFrame(NULL, wxID_ANY, title, pos, size) { CallAfter(&MyFrame::PostCreate); } private: }; /* ... */
void PostCreate() { // #include <wx/stc/stc.h> が必要 auto editor = new wxStyledTextCtrl(this, wxID_ANY); // テキストの設定 editor->SetText("<html>\n<head>\n<title>Sample</title>\n</head>\n<body>\n<!-- 本文 -->\n<h1>Hello World</h1>\n</body>\n</html>"); // テキストの設定 editor->SetLexer(wxSTC_LEX_HTML); // HTMLのシンタックスハイライトを設定 editor->StyleSetForeground(wxSTC_H_TAG, wxColour(0, 0, 255)); // タグの色を赤に設定 editor->StyleSetForeground(wxSTC_H_ATTRIBUTE, wxColour(255, 0, 255)); editor->StyleSetForeground(wxSTC_H_VALUE, wxColour(0, 0, 0)); editor->StyleSetForeground(wxSTC_H_COMMENT, wxColour(0, 255, 0)); // コメントの色を緑に設定 editor->StyleSetBackground(wxSTC_H_COMMENT, wxColour(0, 0, 0)); // コメントの背景色を黒に設定 this->Layout(); // レイアウトの更新 }
void PostCreate() { auto editor = new wxStyledTextCtrl(this, wxID_ANY); editor->SetLexer(wxSTC_LEX_HTML); // HTMLのシンタックスハイライトを設定 //// 左側にマージンを追加し、その列に表示するものを設定 //// マージンインデクスは左側に追加する列番号と考えればよい //// マージンに表示するものを行番号に設定 editor->SetMarginType(0, wxSTC_MARGIN_NUMBER);
//// 左側にマージン(スペース)を作成 editor->SetMarginWidth(0/*マージンインデクス*/, 40/*マージンのピクセル幅*/); // テキストの設定 editor->SetText(R"( <html> <body> <div> <!-- 本文 --> <h1>Hello World</h1> </div> </body> </html>)"); /* ... */
this->Layout(); // レイアウトの更新 }
void PostCreate() { auto editor = new wxStyledTextCtrl(this, wxID_ANY); editor->SetLexer(wxSTC_LEX_HTML); // HTMLのシンタックスハイライトを設定 // インデントガイド editor->SetIndentationGuides(wxSTC_IV_LOOKBOTH); //editor->SetTabWidth(4); editor->SetIndent(4); editor->StyleSetForeground(wxSTC_STYLE_INDENTGUIDE, wxColour(50, 50, 50)); // インデントガイドの色を設定 // テキストの設定 editor->SetText(R"( <html> <body> <div> <!-- 本文 --> <h1>Hello World</h1> </div> </body> </html>)"); // テキストの設定 /* ... */
this->Layout(); // レイアウトの更新 }
void PostCreate() { editor = new wxStyledTextCtrl(this, wxID_ANY); //editor->SetLexer(wxSTC_LEX_HTML); // HTMLのシンタックスハイライトを設定 editor->SetLexer(wxSTC_LEX_CPP); // マージン1をコード折り畳み用のシンボルマージンとして設定 folder_margin_id = 1; editor->SetMarginType(folder_margin_id, wxSTC_MARGIN_SYMBOL); editor->SetMarginMask(folder_margin_id, wxSTC_MASK_FOLDERS); //editor->SetMarginWidth(1, 16); // マージンの幅を設定 editor->SetMarginSensitive(folder_margin_id, true); // マージンをクリック可能にする // 折り畳みのマーカーの設定 // editor->MarkerDefine(設定する対象 , どのマークを使うか , 背景色, 前景色) // トップレベルの+/-マーカーを設定 editor->MarkerDefine(wxSTC_MARKNUM_FOLDER, wxSTC_MARK_BOXPLUS, wxColour(255, 255, 255), wxColour(0, 0, 0)); editor->MarkerDefine(wxSTC_MARKNUM_FOLDEROPEN, wxSTC_MARK_BOXMINUS, wxColour(255, 255, 255), wxColour(0, 0, 0)); // 垂直線を引く editor->MarkerDefine(wxSTC_MARKNUM_FOLDERSUB, wxSTC_MARK_VLINE,wxColour(0,0,0), wxColour(0, 0, 0)); // 折り畳みの中間の+/-マーカーを設定 editor->MarkerDefine(wxSTC_MARKNUM_FOLDEREND, wxSTC_MARK_BOXPLUSCONNECTED, wxColour(255, 0, 0), wxColour(0, 0, 0)); editor->MarkerDefine(wxSTC_MARKNUM_FOLDEROPENMID, wxSTC_MARK_BOXMINUSCONNECTED, wxColour(0,255, 0), wxColour(255, 255, 255)); // 折り畳みの中間の終了マーク editor->MarkerDefine(wxSTC_MARKNUM_FOLDERMIDTAIL, wxSTC_MARK_TCORNER, wxColour(0, 0, 0), wxColour(255, 0, 255)); // トップレベルの終了マーク editor->MarkerDefine(wxSTC_MARKNUM_FOLDERTAIL, wxSTC_MARK_LCORNER, wxColour(0, 0, 0), wxColour(0, 255, 255)); // 折り畳みの有効化 editor->SetProperty("fold", "1"); editor->SetFoldFlags(0 /*wxSTC_FOLDFLAG_LINEBEFORE_CONTRACTED | wxSTC_FOLDFLAG_LINEAFTER_EXPANDED*/); // テキストの設定 editor->SetText(R"(
#include <iostream> int main() { int i = 0; for(i = 0; i < 10; i++) { if( i % 2 == 0) { std::cout << "even "; } else { std::cout << "odd "; } std::cout << i << std::endl; } return 0; }
)"); editor->Bind(wxEVT_STC_MARGINCLICK, &MyFrame::OnMarginClick, this); this->Layout(); // レイアウトの更新 }
void OnMarginClick(wxStyledTextEvent& event) { // マージンに表示されたマークをクリックしたときのイベント処理 if (event.GetMargin() == folder_margin_id) { int lineClick = editor->LineFromPosition(event.GetPosition()); int levelClick = editor->GetFoldLevel(lineClick); if ((levelClick & wxSTC_FOLDLEVELHEADERFLAG) > 0) { editor->ToggleFold(lineClick); } } }
公式に詳しく書いてある。
{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942} ... C++であることを表すGUID。定数。
TestApplicationCPP ... プロジェクト名。ただし変えても影響ない(なぜ)。
TestApplicationCPP\TestApplicationCPP.vcxproj ... プロジェクトファイルへのパス
{BCFFEF98-34EF-437F-BE38-8A084328984F} ... プロジェクトを一意に表す識別子。GUID。プロジェクトを作るたびに変わる。
{722044A8-0732-4C11-87C7-85A5DDFF9F78} ... ソリューションを一意に表す識別子。GUID。ソリューションを作るたびに変わる。
Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.5.33530.505 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestApplicationCPP", "TestApplicationCPP\TestApplicationCPP.vcxproj", "{BCFFEF98-34EF-437F-BE38-8A084328984F}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 Debug|x86 = Debug|x86 Release|x64 = Release|x64 Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {BCFFEF98-34EF-437F-BE38-8A084328984F}.Debug|x64.ActiveCfg = Debug|x64 {BCFFEF98-34EF-437F-BE38-8A084328984F}.Debug|x64.Build.0 = Debug|x64 {BCFFEF98-34EF-437F-BE38-8A084328984F}.Debug|x86.ActiveCfg = Debug|Win32 {BCFFEF98-34EF-437F-BE38-8A084328984F}.Debug|x86.Build.0 = Debug|Win32 {BCFFEF98-34EF-437F-BE38-8A084328984F}.Release|x64.ActiveCfg = Release|x64 {BCFFEF98-34EF-437F-BE38-8A084328984F}.Release|x64.Build.0 = Release|x64 {BCFFEF98-34EF-437F-BE38-8A084328984F}.Release|x86.ActiveCfg = Release|Win32 {BCFFEF98-34EF-437F-BE38-8A084328984F}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {722044A8-0732-4C11-87C7-85A5DDFF9F78} EndGlobalSection EndGlobal
TestApplicationCPPの部分は変更してもどこにも反映されず影響もないが、直後のvcxprojへのパスが間違った場合のみ、エラー表記中にこの文字列が表示される。
せっかくなので.vcxprojファイルの中も見てみる。こちらはxmlファイル。
例としてLuaのinclude設定、ライブラリ設定をしたプロジェクトを作成した。
<?xml version="1.0" encoding="utf-8"?> <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32"> <Configuration>Debug</Configuration> <Platform>Win32</Platform> </ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32"> <Configuration>Release</Configuration> <Platform>Win32</Platform> </ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64"> <Configuration>Debug</Configuration> <Platform>x64</Platform> </ProjectConfiguration>
<ProjectConfiguration Include="Release|x64"> <Configuration>Release</Configuration> <Platform>x64</Platform> </ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals"> <VCProjectVersion>16.0</VCProjectVersion> <Keyword>Win32Proj</Keyword> <ProjectGuid>{bcffef98-34ef-437f-be38-8a084328984f}</ProjectGuid> <RootNamespace>TestApplicationCPP</RootNamespace> <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion> <ProjectName>TestApplicationCPP</ProjectName> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <ConfigurationType>Application</ConfigurationType> <UseDebugLibraries>true</UseDebugLibraries> <PlatformToolset>v143</PlatformToolset> <CharacterSet>Unicode</CharacterSet> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <ConfigurationType>Application</ConfigurationType> <UseDebugLibraries>false</UseDebugLibraries> <PlatformToolset>v143</PlatformToolset> <WholeProgramOptimization>true</WholeProgramOptimization> <CharacterSet>Unicode</CharacterSet> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <ConfigurationType>Application</ConfigurationType> <UseDebugLibraries>true</UseDebugLibraries> <PlatformToolset>v143</PlatformToolset> <CharacterSet>Unicode</CharacterSet> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <ConfigurationType>Application</ConfigurationType> <UseDebugLibraries>false</UseDebugLibraries> <PlatformToolset>v143</PlatformToolset> <WholeProgramOptimization>true</WholeProgramOptimization> <CharacterSet>Unicode</CharacterSet> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> </ImportGroup> <ImportGroup Label="Shared"> </ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> </ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> </ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> </ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> </ImportGroup>
<PropertyGroup Label="UserMacros" />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile> <WarningLevel>Level3</WarningLevel> <SDLCheck>true</SDLCheck> <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> <ConformanceMode>true</ConformanceMode> </ClCompile>
<Link> <SubSystem>Console</SubSystem> <GenerateDebugInformation>true</GenerateDebugInformation> </Link> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile> <WarningLevel>Level3</WarningLevel> <FunctionLevelLinking>true</FunctionLevelLinking> <IntrinsicFunctions>true</IntrinsicFunctions> <SDLCheck>true</SDLCheck> <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> <ConformanceMode>true</ConformanceMode> </ClCompile>
<Link> <SubSystem>Console</SubSystem> <EnableCOMDATFolding>true</EnableCOMDATFolding> <OptimizeReferences>true</OptimizeReferences> <GenerateDebugInformation>true</GenerateDebugInformation> </Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile> <WarningLevel>Level3</WarningLevel> <SDLCheck>true</SDLCheck> <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> <ConformanceMode>true</ConformanceMode> <AdditionalIncludeDirectories>C:\libraries\lua\include</AdditionalIncludeDirectories> </ClCompile>
<Link> <SubSystem>Console</SubSystem> <GenerateDebugInformation>true</GenerateDebugInformation> <AdditionalDependencies>lua54.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalLibraryDirectories>C:\libraries\lua</AdditionalLibraryDirectories> </Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile> <WarningLevel>Level3</WarningLevel> <FunctionLevelLinking>true</FunctionLevelLinking> <IntrinsicFunctions>true</IntrinsicFunctions> <SDLCheck>true</SDLCheck> <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> <ConformanceMode>true</ConformanceMode> <AdditionalIncludeDirectories>C:\libraries\lua\include</AdditionalIncludeDirectories> </ClCompile>
<Link> <SubSystem>Console</SubSystem> <EnableCOMDATFolding>true</EnableCOMDATFolding> <OptimizeReferences>true</OptimizeReferences> <GenerateDebugInformation>true</GenerateDebugInformation> <AdditionalLibraryDirectories>C:\libraries\lua</AdditionalLibraryDirectories> <AdditionalDependencies>lua54.lib;%(AdditionalDependencies)</AdditionalDependencies> </Link>
</ItemDefinitionGroup>
<ItemGroup> <ClCompile Include="TestApplicationCPP.cpp" /> </ItemGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <ImportGroup Label="ExtensionTargets"> </ImportGroup>
</Project>
Voxel Pluginを使ってみる。なお著者はUnreal Engineのプラグインを使うのが初めてである。
以下からダウンロード・インストール。なんかクリックしていくといつの間にか入っている。
https://www.unrealengine.com/marketplace/ja/product/voxel-plugin-free
どれでもいいが今回は地形をVoxelWorldで作成するので、「ファーストパーソン」を選択し、床を削除する。
次にプラグインを有効にする。[編集][プラグイン]でプラグイン画面を開き、検索にvoxelと打つと補完で出てくるのでチェックする。
有効化のためには再起動が必要。
[Voxel] → [VoxelWorld]を選択するとボクセルの地形が追加される。
少し上のほうに出てくるかもしれないので位置は自分のスポーン位置より低いところに移動する
Static Cylinderを追加して、自分のスポーン位置の目の前、少し上のあたりに配置。
まずブループリントクラスに変換する。
VoxelWorldの設定からOn Component Hitイベントを追加する。
Cylinderが落下して発生するOn Component Hitでは、ぶつかったものがCylinderで、ぶつけられたほうがVoxelWorldになる。
On Component Hit が発生したら、ぶつけられたほうをVoxelWorld型に変更し、ボクセルを消す処理をを呼び出す。
後で重力の設定をして落下とOn Component Hitの処理を有効化する。