1.[5]で平行投影に切り替え、[1]でXZビューにする。
Editモードに入り、[E][Z][S]で押し出し、拡大を二回行う
2.[Ctrl+I(アイ)]で選択範囲を反転し、[H]で一時的に不可視にする。
※Hideの切り替えは[H] 及び[Alt+H]で行う
3.proportional editingをSmoothに設定し、バラの花びらの先頭部分を盛り上げる
4.[Alt + H]で全体を表示させ、内部、中央付近のエッジを選択し、Proportional editingのSmoothを使用して膨らませる
5.花びら上部を選択し、中央から外側に押し出しを行う。その後Z方向に若干移動する
Subdivide Surfaceモディファイアを追加したうえでShadingをSmoothにする

花びらの端を内側に織り込むように修正する
全ての花弁の端を織り込むと以下のような形になる
[7]を押して、上から花びらの幅を調整する


根元を調整し、茎に接続できるまで縮小する
1.Cubeを削除する
2.[7]キーでTopからのビューに変更する

3.Grease Pencilを使用し、バラの花びらの曲線を描く
4.Convert to Geometry → Polygon Curve でカーブに変換する
変換したのち、Pencilのレイヤーを不可視にし、Curveだけが見えるようにする

5.Simplify Curvesアドオンを使用し、Distance Error=0.015を設定する


※Simplify Curvesが見つからない場合はアドオンを有効にする

6.[Object]→[Convert to]→[Mesh from Curve]でカーブをエッジオブジェクトに変更する

7.Editモード、Edge選択モードで不要な連結を削除する


時々使うと忘れるので。
#include <iostream> #include <vector> int main() { std::vector<int> v{ 0,1,2,3,4,5,6 }; v.erase(v.begin()+1, v.begin() + 4); for (size_t i = 0; i < v.size(); i++) { printf("%d\n", v[i]); } getchar(); }
0
4
5
6
vectorの内容から重複を削除するには、sort→unique→eraseの順に実行する。
この時、sortはコンテナごとに違う関数を使用しなければいけなかったりするので、vector以外にも使いたいなら多少の工夫が必要となる。
#include <iostream> #include <algorithm> #include <vector> #include <list> /////////////////////////////// // ソート関数 template<class T> inline void container_sort(std::vector<T>& v) { std::sort(v.begin(), v.end()); } template<class T> inline void container_sort(std::list<T>& v) { v.sort(); }////////////////////////////// // 重複削除関数 template<class T> void vec_unique(T& v) { container_sort(v); v.erase( std::unique( v.begin(), v.end()), v.end() ); }int main() { std::vector<int> v{ 4,8,2,5, 4,8,2,5, 9,9,9,5, 5,2,3,3 }; //重複削除 vec_unique(v); for (auto it = std::begin(v); it != std::end(v);++it) { std::cout << *it << std::endl; } int i; std::cin >>i; }
下記ブログから。詳細・注意点などは転載元を確認
C++ std::vector同士の連結方法
https://qiita.com/D-3/items/b19b7acb439ed0e3deee
#include <iostream> #include <vector> int main() { std::vector<int> v123{ 1,2,3 }; std::vector<int> v456{ 4,5,6 };
//v123にv456を結合 v123.insert(v123.end(), v456.begin(), v456.end()); for (size_t i = 0; i < v123.size(); i++) { std::cout << v123[i] << std::endl; } }
#include <iostream> #include <vector> int main() { std::vector<int> v123{ 1,2,3 }; std::vector<int> v456{ 4,5,6 };
//v123にv456を結合 std::copy(v456.begin(), v456.end(), std::back_inserter(v123)); for (size_t i = 0; i < v123.size(); i++) { std::cout << v123[i] << std::endl; } }

最後、シェーディングについて。
13:28~
シェーディングタブに切り替える
[Shift+A]→[Plane]でPlaneを追加し、[S]で拡大して地面にする
二番目に作った木の葉を選択し、Newを押し、追加されたマテリアルの名前をgreen1に設定する



Principled BSDFのRoughnessを1.0に設定、さらにBaseColorをHSVで0.336,0.475,0.662 に設定する



Shiftを押しながらクリックして複数選択する。この際、コピーしたいマテリアルのオブジェクトを最後に選択する。そして[Ctrl+L]→Materialを選択しマテリアルをコピーする
幹を選択し、先ほどと同様にNewボタンでマテリアルを新規追加し、名前をbrownにする
Roughnessを1.0,色をHSVで0.066,0.729,0.486に設定する。
上の葉と同じ方法で、三つの幹全てのマテリアルをbrownにLinkする
葉の設定は以下
同様にして最後の木も設定する
レンダリングの際、Ambient Cclusionを設定する


8:55~
[Shift+A]→[Cylinder]でシリンダを追加。
前回同様Verticesを6にする。
① [1]を押してXZビューに変更、[S][Z]でZ方向に拡大する。
② [S][Shift+Z]でXY方向に縮小し、細くする
③ [G][Z]で円筒の底面をX平面に置く。
[Ctrl+R]でループカットし、円筒を二分割する。
[3]で面選択モードにし、上面を選択、[S]で円筒の上部だけを細くする
[2]でエッジ選択モードにし、[Alt+左クリック]で連続したエッジを選択する。
[S]で縮小、[R]で回転、[G]で移動を行い、幹の曲げを作る
[3]で面選択モードに移行し、[S]で底面を拡大する
カメラ方向を変え、枝の曲げが見えない方向を無いように、[Alt+左クリック]→[G]で下のLoopCut部分にも曲げを加える
[Shift+右クリック]で幹の根本付近に3Dカーソルを移動し、[Shift+A]→[Plane]で面を追加する
Editモードに入り、[Ctrl+R]でループカットで三分割する
各エッジを[S]で拡大し、葉っぱの形を整える
Editモードに入り、中央の四角形を少し持ち上げる
Objectモードで[S][X]で引き延ばす
[G]で根元を幹の側面に移動する

回転・複製を行うため、originを葉の左側のエッジの中点に置く。
①Editモードに入り、[2]でエッジモードにし、幹の方のエッジを選択する。
②[Shift+S]→[Cursor to Selected]を選択
③Objectモードに切り替え、右クリック→[Set Origin]→[Origin to 3D curosor]を選択

葉のエッジを回転し、形状を有機的にする

[7]でTopビューにし、[Alt+D]でオブジェクトをコピー、[R]で回転する。

コピー時にAlt+Dを使用しているので、全てのオブジェクトはリンクしている。
一番幹側のエッジを選択し、[S]で縮小し、一括で編集する.

根元から頭頂まで葉をコピーする

二種類目の木
3:50~

[Shift+A]→[Mesh]→[Cylinder]で円筒を作成。
頂点数を6にしポリゴンが目立つようにする

Objectモードに戻り、幹を[Shift+D]で複製、上に配置する

[S] + [Shift+Z]でXY方向に拡大する

上の手順と同様にして、葉の部分の上部を細くする

葉の下部分を広げ、さらにくぼませる

[Shift+D]で葉をコピーし、上に重ねる。回転・拡大縮小を行いバリエーションを増やす。

葉の一つを選択し、Editモードへ入る。
[Ctrl+R]でループカットを行い、下部のエッジを選択して移動する

Editモードで[K]を押しナイフにする。
奥行きのある三角形のような形に切り込みを入れる

できた三つの平面を[X]→[Faces]で削除する


[2]を押しエッジ選択モードに切り替え、エッジを一本選択して[F]を押し、面を張る



作業中、他のオブジェクトが邪魔な時は[Num /]で選択中のオブジェクトだけを表示できる
[S] + [Shift+Z]でXY方向に縮小し、幹を細くする


[Ctrl + R]でループカットし、[G]で移動して幹を曲げる


ローポリの自然物のチュートリアル。Blender 2.8のUIになれるにはちょうどいい素材。
1:05~
TabキーでEditモードに入り、[1] キー (NumPadではないほう)を押しVertex Selectにする。そして[A]キーでキューブの頂点を全て選択し、[Alt+M]→At Centerで一つの頂点にマージする
Editモードのまま、頂点を選択し、[E]で押し出して木の形を作る。
頂点がうまく選択できない、[C]の範囲選択が解除できないときは、左上のSelectのモードがただのSelectになっているかを確認する。
Editモードで[Alt+Z]を押すと、X-rayモードになり頂点とエッジが見やすくなる
[Ctrl+A]でスケールを変更する
エッジの両端を選択し、[右クリック→Subdivide]で分割できる
形が整ったら、ObjectModeに戻りApplyする。

木の先端を[Shift+右クリック]で3Dカーソルをクリック位置に配置する

[Shift+A]→[Mesh]→Ico SphereでICO Sphereを追加
ICO Sphere はSubdivisionsを1にしてよりポリゴンぽくする



[Shift+D]で複製、[R]で回転、[S]で縮小などを行い、葉を増やして配置する
[B]の矩形選択で木全体を選択し、[G][X]でX方向にずらしておく。
[Shift+S]→Cursor to World Originを選択し、3Dカーソルを(0,0,0)に初期化する

次回:二本目
これもさすがに簡単すぎるので一回でやります。



#include <iostream> #include <Windows.h> #include <gl/GL.h> #include <gl/GLU.h> #include <gl/freeglut.h> // freeglut: // http://freeglut.sourceforge.net/ //ウィンドウの幅と高さ int width, height;//! @brief X軸回転行列を作成する //! @param [out] m 結果を格納する要素数16の配列 //! @param [in] rad 回転角(ラジアン) //! @return なし void GetXRotate(double* m, double rad) { m[ 0] = 1; m[ 1] = 0; m[ 2] = 0; m[ 3] = 0; m[ 4] = 0; m[ 5] = cos(rad); m[ 6] = sin(rad); m[ 7] = 0; m[ 8] = 0; m[ 9] = -sin(rad); m[10] = cos(rad); m[11] = 0; m[12] = 0; m[13] = 0; m[14] = 0; m[15] = 1; }//! @brief Y軸回転行列を作成する //! @param [out] m 結果を格納する要素数16の配列 //! @param [in] rad 回転角(ラジアン) //! @return なし void GetYRotate(double* m, double rad) { m[0] = cos(rad); m[1] = 0; m[2] = -sin(rad); m[3] = 0; m[4] = 0; m[5] = 1; m[6] = 0; m[7] = 0; m[8] = sin(rad); m[9] = 0; m[10] = cos(rad); m[11] = 0; m[12] = 0; m[13] = 0; m[14] = 0; m[15] = 1; }//! @brief Z軸回転行列を作成する //! @param [out] m 結果を格納する要素数16の配列 //! @param [in] rad 回転角(ラジアン) //! @return なし void GetZRotate(double* m, double rad) { m[0] = cos(rad); m[1] = sin(rad); m[2] = 0; m[3] = 0; m[4] = -sin(rad); m[5] = cos(rad); m[6] = 0; m[7] = 0; m[8] = 0; m[9] = 0; m[10] = 1; m[11] = 0; m[12] = 0; m[13] = 0; m[14] = 0; m[15] = 1; }//! @brief 角度degreeをラジアンに変換する //! @param [in] degree 度で表した角度 //! @return ラジアンの角度 inline double toRadian(const double degree) { return degree * 3.1415926535897932384626 / 180; } double rotate_angle = 0; //描画関数 void disp(void) { glViewport(0, 0, width, height); glClearColor(0.2, 0.2, 0.2, 1); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //glEnable(GL_CULL_FACE); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); double v; //テスト1 OpenGLZ軸回転する { v = 0.7; glPushMatrix(); glRotated(rotate_angle, 0, 0, 1); glBegin(GL_QUADS); glColor3d(0, 0, 1); glVertex2d(-v, -v); glColor3d(1, 0, 1); glVertex2d(v, -v); glColor3d(1, 1, 1); glVertex2d(v, v); glColor3d(0, 1, 1); glVertex2d(-v, v); glEnd(); glPopMatrix(); } //テスト2 自作関数でZ軸回転行列を作ってOpenGLのMatrixに掛ける { v = 0.5; glPushMatrix(); double m[16]; GetZRotate(m, toRadian(rotate_angle)); glMultMatrixd(m); glBegin(GL_QUADS); glColor3d(1, 1, 0); glVertex2d(-v, -v); glColor3d(1, 1, 1); glVertex2d(v, -v); glColor3d(0, 1, 0); glVertex2d(v, v); glColor3d(1, 0, 0); glVertex2d(-v, v); glEnd(); glPopMatrix(); } glFlush(); } //ウィンドウサイズの変化時に呼び出される void reshape(int w, int h) { width = w; height = h; disp(); } void timer(int value) { rotate_angle += 5; disp(); glutTimerFunc(100, timer, 0); } //エントリポイント int main(int argc, char** argv) { glutInit(&argc, argv); glutInitWindowPosition(100, 50); glutInitWindowSize(500, 500); glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA); glutCreateWindow("sample"); glutDisplayFunc(disp); glutReshapeFunc(reshape); glutTimerFunc(10, timer, 0);//タイマー glutMainLoop(); return 0; }
外側の矩形はOpenGLのglRotate(r,0,0,1);で描いている。
内側の矩形は自覚関数でZ回転行列を作成してglMultMatrixdしている。
