Blenderでhdrファイルを読み込んでEnvironmentに指定して背景を描画します。
pngの時はImg No Alphaをチェック
レンダリング時の注意として、pngで出力する場合、そのままだと(なぜか)背景が描画されません。jpegなどならちゃんと出力されます。
仕方がないので、Outputを指定し、Img No Alphaをチェックします。
http://vcg.isti.cnr.it/vcglib/trimesh__smooth_8cpp_source.html
VCG Libraryでスムージングするには、VertexCoordPasoDoble関数を使います。公式のサンプルにあるように
vcg::tri::Clean<MyMesh>::RemoveDuplicateVertex(mesh); vcg::tri::Clean<MyMesh>::RemoveUnreferencedVertex(mesh); vcg::tri::UpdateTopology<MyMesh>::VertexFace(mesh);
が必要です。
さらに、 VertexCoordPasoDoble 関数内で、
RequireVertexCompactness<MeshType>(m); RequireFaceCompactness<MeshType>(m); RequireEdgeCompactness<MeshType>(m); RequireTetraCompactness<MeshType>(m);
とチェックが入っているので、
vcg::tri::Allocator<MyMesh>::CompactVertexVector(mesh); vcg::tri::Allocator<MyMesh>::CompactEdgeVector(mesh);
等が必要になる場合があります
vcg::tri::Clean<MyMesh>::RemoveDuplicateVertex(mesh); vcg::tri::Clean<MyMesh>::RemoveUnreferencedVertex(mesh); vcg::tri::UpdateTopology<MyMesh>::VertexFace(mesh); vcg::tri::Allocator<MyMesh>::CompactVertexVector(mesh); vcg::tri::Allocator<MyMesh>::CompactEdgeVector(mesh); int Step = 2; int NormalSmoothStep=3; float Sigma=0.5; int FitStep=4; for (int i = 0; i < Step; ++i) { vcg::tri::UpdateNormal<MyMesh>::PerFaceNormalized(mesh); vcg::tri::Smooth<MyMesh>::VertexCoordPasoDoble( mesh, NormalSmoothStep, Sigma, FitStep ); }
VCG LibraryのBall Pivotingでメッシュ生成
VCG Library ターゲットの周辺のオブジェクトを取得
Unicodeはどんな文字でも対応してるからwstringをwcoutすれば何でも表示出来るはず
#include <iostream> #include <string> int main() { std::locale::global(std::locale("japanese"));// ① std::wstring hello = L"こんにちは"; std::wcout << hello; getchar(); return 0; }
なぜUnicodeなのにsetlocaleしなければ文字が出力出来ないか。
それは、
コマンドプロンプトがShift-JISしか表示出来ないため、
wcoutはShift-JISで文字列を出力せねばならず、
wcout自身は自分がどんな環境で動いているか関知していないので、
localeでShift-JIS環境だと教えてあげる必要がある
という理屈からだ。
自分が作ったアプリケーション内で、どのように文字列を処理しようがそれは作った者の自由だ。別にshift-jisやunicodeである必要はない。必要があれば自分定義した文字コードで書いたっていい(もの凄い労力だろうが)。
しかし、それを出力するなら、出力先の仕様に合わせる必要がある。出力先がどんな文字コードに対応しているかを教えるのがlocaleの役目となる。
#include <iostream> #include <string> #include <fstream> int main() { std::locale::global(std::locale("japanese"));// ① std::wstring hello = L"こんにちは"; std::wofstream wof(L"test.txt"); wof << hello; return 0; }
ファイル出力に関しても同様で、Lをつけてワイド文字指定しても、wofstreamが自動的にShift-JISへ変換して出力する。
とやったときと、
では、どう違うのかという話です。
例えば、このようなプログラムを書きます。
int main() { { FILE* fp = fopen("output-char-abc", "wb"); char* s = "abc"; fwrite(s, 1, 3, fp); // 3 byte 出力 fclose(fp); } { FILE* fp = fopen("output-char-あいう", "wb"); char* s = "あいう"; fwrite(s, 1, 6, fp); // 6 byte 出力 fclose(fp); } { FILE* fp = fopen("output-wchar-abc", "wb"); wchar_t* s = L"abc"; fwrite(s, 1, 6, fp); // 6 byte 出力 fclose(fp); } { FILE* fp = fopen("output-wchar-あいう", "wb"); wchar_t* s = L"あいう"; fwrite(s, 1, 6, fp); // 6 byte 出力 fclose(fp); } return 0; }
このように、sの指す文字列の中身は、
LがついているときはUTF16、
ついていないときはShiftJIS
になります。
次に、プロジェクト設定の「文字コード」を、マルチバイト文字セットとUnicode文字セットでそれぞれ保存してみます。
この場合も、当然ですが、""とL""の結果も変わりません。上記したプログラムの挙動は、「文字セット」に関わらず同じです。
つぎに、プログラムの先頭にコメントで何らかの日本語を書いてみます。
結果はこのように、どちらの設定でもUTF16になります。
文字セットの設定はソースファイルの文字コードに影響を与えません。
ちなみにソースコードの文字コードを変えるには
等の方法があるようです。
では「文字セット」は、Visual Studioの何に影響を与えるのでしょうか。
このように、「文字セット」の設定によって、マクロ
・_UNICODE
・UNICODE
または
・_MBCS
が 定義されます。
つまり、「文字セット」の指定は
_UNICODEマクロが定義されるかどうか
の指定という意味です。
(続く...)
ターゲットの頂点の周囲の面にアクセスする。
http://vcg.isti.cnr.it/vcglib/adjacency.html
void OneRingNeighborhoodVF( MyVertex * v) { vcg::face::VFIterator<MyFace> vfi(v); //initialize the iterator tohe first face for(;!vfi.End();++vfi) { MyFace* f = vfi.F(); // ...do something with face f } }
これを応用して、ある頂点の周囲のエッジを選択する。
void OneRingNeighborhoodVE(MyVertex * v) { vcg::edge::VEIterator<MyEdge> vfe(v); for (; !vfe.End(); ++vfe) { MyEdge* e = vfe.E(); // ...do something with edge e } }
VCG LibraryのBall Pivotingでメッシュ生成
VCG Library ターゲットの周辺のオブジェクトを取得
Win32APIのWM_SIZEメッセージとWM_SIZINGメッセージ。
WM_SIZINGはサイズ変更中に、WM_SIZEはサイズ変更後に送られます・・・。
とはいうものの、発行されるタイミングより遙かに大きな違いがあります。というか全く別物です。
lParam & 0xFFFF | クライアント領域の幅 |
(lParam >> 16) & 0xFFFF | クライアント領域の高さ |
RECT rect;
GetClientRect(hWnd,&rect);
RECT* prect = (RECT*)lParam;
prect->left | ウィンドウの左の座標 |
prect->top | ウィンドウの上の座標 |
prect->right | ウィンドウの右の座標 |
prect->bottom | ウィンドウの下の座標 |
RECT rect;
GetWindowRect(hWnd,&rect);
case WM_SIZE: { printf(" WM_SIZE\n" "x-size : %d\n" "y-size : %d\n", lParam & 0xFFFF, (lParam >> 16) & 0xFFFF ); RECT rect; GetClientRect(hWnd, &rect); printf(" GetClientRect\n" "x-size : %d\n" "y-size : %d\n", rect.right, rect.bottom ); } puts("-----------"); break; case WM_SIZING: { RECT* prect = (RECT*)lParam; printf( " WM_SIZING\n" "left : %d\n" "top : %d\n" "right : %d\n" "bottom: %d\n" , prect->left, prect->top, prect->right, prect->bottom ); RECT rect; GetWindowRect(hWnd, &rect); printf( " GetWindowRect\n" "left : %d\n" "top : %d\n" "right : %d\n" "bottom: %d\n" , rect.left, rect.top, rect.right, rect.bottom ); puts(""); } break;
VCG LibraryでMeshに三角形を登録する方法
//パターン1 メッシュに頂点を追加してから、その頂点を結んで三角形を作成 MyMesh::VertexIterator vit = vcg::tri::Allocator< MyMesh >::AddVertices(mesh, 3); vit[0].P() = vcg::Point3f(0, 0, 0); vit[1].P() = vcg::Point3f(1, 0, 0); vit[2].P() = vcg::Point3f(1, 1, 0); vcg::tri::Allocator< MyMesh >::AddFace(mesh, &vit[0], &vit[1], &vit[2]); //パターン2 三つの頂点の座標を指定して三角形を追加 MyMesh::FaceIterator fit = vcg::tri::Allocator< MyMesh >::AddFace( mesh, vcg::Point3f(0, 0, 0), vcg::Point3f(-1, 0, 0), vcg::Point3f(-1, -1, 0) ); //面の色をここで指定 fit->C().X() = 255; fit->C().Y() = 0; fit->C().Z() = 0;
VCG LibraryのBall Pivotingでメッシュ生成
VCG Library ターゲットの周辺のオブジェクトを取得
VCG Libraryでポリゴンファイルを保存する方法。
#include <wrap/io_trimesh/export_ply.h> #include <wrap/io_trimesh/export_obj.h> #include <wrap/io_trimesh/export_stl.h>
class MyVertex : public vcg::Vertex< MyUsedTypes, vcg::vertex::Coord3f, vcg::vertex::Color4b, vcg::vertex::Normal3f, vcg::vertex::Qualityf, vcg::vertex::BitFlags, vcg::vertex::Mark > { }; class MyFace : public vcg::Face < MyUsedTypes, vcg::face::VertexRef, vcg::face::Color4b, // FACECOLORを保存するならこれを指定しておく vcg::face::Normal3f, vcg::face::Mark, vcg::face::BitFlags > { }; class MyEdge : public vcg::Edge< MyUsedTypes, vcg::edge::VertexRef, vcg::edge::BitFlags > { }; class MyMesh : public vcg::tri::TriMesh< std::vector<MyVertex>, std::vector<MyFace>, std::vector<MyEdge> > { };
//メッシュを保存する vcg::tri::io::PlyInfo pi; pi.mask = vcg::tri::io::Mask::IOM_FACECOLOR | //色情報の出力を指定 vcg::tri::io::Mask::IOM_VERTNORMAL; vcg::tri::io::ExporterPLY<MyMesh>::Save( mesh, "result.ply", true, pi ); vcg::tri::io::ExporterOBJ<MyMesh>::Save( mesh, "result.obj", vcg::tri::io::Mask::IOM_FACECOLOR //これを入れるとmtlファイルも出力される ); vcg::tri::io::ExporterSTL<MyMesh>::Save( mesh, "result.stl", true //バイナリ形式ならtrue );
VCG LibraryのBall Pivotingでメッシュ生成
VCG Library ターゲットの周辺のオブジェクトを取得
VCGで色のついたポリゴンを表示する方法。
今回はplyファイルを使用。
※あと書くのも恥ずかしいけれど上記3ファイルはパブリックドメイン扱いとします。
面に色情報を持つデータを使用する場合、MyFaceで色情報を持つことを定義する。
class MyFace; class MyVertex; class MyEdge; struct MyUsedTypes : public vcg::UsedTypes< /*省略*/> {}; class MyVertex : public vcg::Vertex< /*省略*/> {}; class MyFace : public vcg::Face < MyUsedTypes, vcg::face::VertexRef, vcg::face::Color4b, vcg::face::Normal3f, vcg::face::Mark, vcg::face::BitFlags > { }; class MyEdge : public vcg::Edge< /*省略*/> {}; class MyMesh : public vcg::tri::TriMesh< std::vector<MyVertex>, std::vector<MyFace>, std::vector<MyEdge> > { };
vcg::tri::io::ImporterPLY<MyMesh>::Open(mesh, "napple_face_color_0.ply");
色情報は C().X() , C().Y() C().Z() にそれぞれR,G,Bが入っている。cCはconst用。
上でvcg::face::Color4bを指定したので、unsigned char型で入っている。従ってOpenGLのglColor3ubを使用する。
glBegin(GL_TRIANGLES); for (const auto& f : mesh.face) { glColor3ub(f.cC().X(), f.cC().Y(), f.cC().Z()); for (size_t i = 0; i < 3; i++) { glVertex3d(f.cV(i)->cP().X(), f.cV(i)->cP().Y(), f.cV(i)->cP().Z()); } } glEnd();
頂点に色情報がある場合、MyVertexにColor4bを指定する。
class MyVertex : public vcg::Vertex< MyUsedTypes, vcg::vertex::Coord3f, vcg::vertex::Color4b, vcg::vertex::Normal3f, vcg::vertex::Qualityf, vcg::vertex::BitFlags, vcg::vertex::Mark > { };
vcg::tri::io::ImporterPLY<MyMesh>::Open(mesh, "napple_vertex_color.ply");
色情報はvertexの中に入っています。それ以外は面の時と同じです。
glBegin(GL_TRIANGLES); for (const auto& f : mesh.face) { for (size_t i = 0; i < 3; i++) { const MyVertex* pV = f.cV(i); glColor3ub(pV->cC().X(), pV->cC().Y(), pV->cC().Z()); glVertex3d(pV->cP().X(), pV->cP().Y(), pV->cP().Z()); } } glEnd();
VCG LibraryのBall Pivotingでメッシュ生成
VCG Library ターゲットの周辺のオブジェクトを取得
VCG Libraryでは、FaceがVertexのIteratorを持っていて、FaceからVertexを参照できる。
他の参照が必要な場合、vcg::tri::UpdateTopologyでFace-Edge間のリンクなどを計算できるのだが、例外が出たり、それっぽい変数に何も入っていないなどの現象に遭遇することがある。
例1:
を実行すると、
などというメッセージと共に例外がthrowされ停止する
例2:
OpenEdgeを表示しようと、faceオブジェクトからエッジオブジェクトを取得するためFEpやcFEpを使おうと、以下のように書くと、
for (const auto& f : mesh.face) { for (size_t i = 0; i < 3; i++) { if (vcg::face::IsBorder(f, i)) { glVertex3d( f.cFEp(i)->cV(0)->P().X(), f.cFEp(i)->cV(0)->P().Y(), f.cFEp(i)->cV(0)->P().Z()); glVertex3d( f.cFEp(i)->cV(1)->P().X(), f.cFEp(i)->cV(1)->P().Y(), f.cFEp(i)->cV(1)->P().Z()); } } }
と言って落ちる。恐らくリンク情報が作成されていない。
VCGではポリゴンを扱うために
と、既存の型を継承したデータ型を使う。この時、vcg::Vertex、vcg::Face,vcg::Edgeに各データ型を関連付ける適切な型をテンプレートで与える必要がある。
vcg::tri::UpdateTopology< MyMesh >::FaceFaceを使いたい場合、MyFace定義時に、vcg::face::FFAdjを指定する。なおテンプレート引数の順序は気にしなくて良い。
class MyFace : public vcg::Face < MyUsedTypes, vcg::face::VertexRef, vcg::face::Normal3f, vcg::face::FFAdj, vcg::face::EFAdj, vcg::face::Mark, vcg::face::VFAdj, vcg::face::BitFlags > { };
使用したい関数 | 指定するテンプレート引数 |
vcg::tri::UpdateTopology< MyMesh >::FaceFace | MyFaceにvcg::face::FFAdj |
vcg::tri::UpdateTopology< MyMesh >::VertexFace |
MyVertexにvcg::vertex::VFAdj MyFaceにvcg::face::VFAdj |
vcg::tri::UpdateTopology< MyMesh >::VertexEdge |
MyVertexにvcg::vertex::VEAdj MyEdgeにvcg::edge::VEAdj |
vcg::tri::UpdateTopology< MyMesh >::EdgeEdge | MyEdgeにvcg::edge::EEAdj |
例えばcFEp()を使いたい場合、まずエッジ情報を作成するため
を実行する。しかしAllocateEdgeが中でFFpを要求するので、先んじて
を実行する。FaceFaceを実行するためにはMyFaceにvcg::face::FFAdjを指定しなければならないので追加する。
するとcFEpでabortするので、MyFaceにvcg::face::FEAdjを指定する。
ここまでで、cFEpを使うコードは、以下のようになる。
※ただし、cFEpに必要な物以外を外してある。
//データ型の定義 class MyFace; class MyVertex; class MyEdge; struct MyUsedTypes : public vcg::UsedTypes< vcg::Use<MyVertex>::AsVertexType, vcg::Use<MyFace>::AsFaceType, vcg::Use<MyEdge>::AsEdgeType> {}; class MyVertex : public vcg::Vertex< MyUsedTypes, vcg::vertex::Coord3f> { }; class MyFace : public vcg::Face < MyUsedTypes, vcg::face::VertexRef, vcg::face::FFAdj, vcg::face::FEAdj> { }; class MyEdge : public vcg::Edge< MyUsedTypes, vcg::edge::VertexRef> { }; class MyMesh : public vcg::tri::TriMesh< std::vector<MyVertex>, std::vector<MyFace>, std::vector<MyEdge> > { };
//データの読み込み vcg::tri::io::ImporterPLY<MyMesh>::Open(mesh, fname); //必要に応じて vcg::tri::Clean< MyMesh >::RemoveDuplicateVertex(mesh); vcg::tri::Clean< MyMesh >::RemoveDuplicateEdge(mesh); vcg::tri::Clean< MyMesh >::RemoveDuplicateFace(mesh); //エッジ情報作成 vcg::tri::UpdateTopology< MyMesh >::FaceFace(mesh); vcg::tri::UpdateTopology< MyMesh >::AllocateEdge(mesh);
表示
glLineWidth(2); glColor3d(0, 0, 1); glBegin(GL_LINES); for (const auto& f : mesh.face) { for (size_t i = 0; i < 3; i++) { glVertex3d( f.cFEp(i)->cV(0)->P().X(), f.cFEp(i)->cV(0)->P().Y(), f.cFEp(i)->cV(0)->P().Z()); glVertex3d( f.cFEp(i)->cV(1)->P().X(), f.cFEp(i)->cV(1)->P().Y(), f.cFEp(i)->cV(1)->P().Z()); } } glEnd();
VCG LibraryのBall Pivotingでメッシュ生成
VCG Library ターゲットの周辺のオブジェクトを取得