ぬの部屋(仮)
nu-no-he-ya
  •      12
    3456789
    10111213141516
    17181920212223
    24252627282930
           
      12345
    6789101112
    13141516171819
    20212223242526
    2728293031  
           
    1234567
    891011121314
    15161718192021
    22232425262728
    2930     
           
        123
    45678910
    11121314151617
    18192021222324
    25262728293031
           
     123456
    78910111213
    14151617181920
    21222324252627
    28293031   
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    30      
       1234
    567891011
    12131415161718
    19202122232425
    262728293031 
           
     123456
    78910111213
    14151617181920
    21222324252627
    282930    
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
    31      
         12
    3456789
    10111213141516
    17181920212223
    2425262728  
           
      12345
    6789101112
    13141516171819
    20212223242526
    2728293031  
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    3031     
        123
    45678910
    11121314151617
    18192021222324
    252627282930 
           
     123456
    78910111213
    14151617181920
    21222324252627
    28293031   
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    30      
       1234
    567891011
    12131415161718
    19202122232425
    262728293031 
           
    1234567
    891011121314
    15161718192021
    22232425262728
    293031    
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
           
      12345
    6789101112
    13141516171819
    20212223242526
    2728293031  
           
    1234567
    891011121314
    15161718192021
    22232425262728
    2930     
           
        123
    45678910
    11121314151617
    18192021222324
    25262728293031
           
       1234
    567891011
    12131415161718
    19202122232425
    26272829   
           
    1234567
    891011121314
    15161718192021
    22232425262728
    293031    
           
        123
    45678910
    11121314151617
    18192021222324
    25262728293031
           
      12345
    6789101112
    13141516171819
    20212223242526
    27282930   
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    3031     
        123
    45678910
    11121314151617
    18192021222324
    252627282930 
           
     123456
    78910111213
    14151617181920
    21222324252627
    28293031   
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
    31      
       1234
    567891011
    12131415161718
    19202122232425
    2627282930  
           
    1234567
    891011121314
    15161718192021
    22232425262728
    293031    
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
           
      12345
    6789101112
    13141516171819
    20212223242526
    2728293031  
           
      12345
    6789101112
    13141516171819
    20212223242526
    2728     
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    3031     
       1234
    567891011
    12131415161718
    19202122232425
    262728293031 
           
     123456
    78910111213
    14151617181920
    21222324252627
    282930    
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
    31      
       1234
    567891011
    12131415161718
    19202122232425
    2627282930  
           
    1234567
    891011121314
    15161718192021
    22232425262728
    293031    
           
        123
    45678910
    11121314151617
    18192021222324
    25262728293031
           
      12345
    6789101112
    13141516171819
    20212223242526
    27282930   
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    3031     
        123
    45678910
    11121314151617
    18192021222324
    252627282930 
           
     123456
    78910111213
    14151617181920
    21222324252627
    28293031   
           
     123456
    78910111213
    14151617181920
    21222324252627
    28      
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
    31      
      12345
    6789101112
    13141516171819
    20212223242526
    2728293031  
           
    1234567
    891011121314
    15161718192021
    22232425262728
    2930     
           
        123
    45678910
    11121314151617
    18192021222324
    25262728293031
           
      12345
    6789101112
    13141516171819
    20212223242526
    27282930   
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    3031     
       1234
    567891011
    12131415161718
    19202122232425
    262728293031 
           
     123456
    78910111213
    14151617181920
    21222324252627
    282930    
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
    31      
       1234
    567891011
    12131415161718
    19202122232425
    2627282930  
           
    1234567
    891011121314
    15161718192021
    22232425262728
    293031    
           
    1234567
    891011121314
    15161718192021
    22232425262728
           
           
        123
    45678910
    11121314151617
    18192021222324
    25262728293031
           
     123456
    78910111213
    14151617181920
    21222324252627
    28293031   
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    30      
       1234
    567891011
    12131415161718
    19202122232425
    262728293031 
           
     123456
    78910111213
    14151617181920
    21222324252627
    282930    
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
    31      
      12345
    6789101112
    13141516171819
    20212223242526
    2728293031  
           
    1234567
    891011121314
    15161718192021
    22232425262728
    2930     
           
        123
    45678910
    11121314151617
    18192021222324
    25262728293031
           
      12345
    6789101112
    13141516171819
    20212223242526
    27282930   
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    3031     
         12
    3456789
    10111213141516
    17181920212223
    242526272829 
           
      12345
    6789101112
    13141516171819
    20212223242526
    2728293031  
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    3031     
        123
    45678910
    11121314151617
    18192021222324
    252627282930 
           
     123456
    78910111213
    14151617181920
    21222324252627
    28293031   
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    30      
       1234
    567891011
    12131415161718
    19202122232425
    262728293031 
           
    1234567
    891011121314
    15161718192021
    22232425262728
    293031    
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
           
      12345
    6789101112
    13141516171819
    20212223242526
    2728293031  
           
    1234567
    891011121314
    15161718192021
    22232425262728
    2930     
           
        123
    45678910
    11121314151617
    18192021222324
    25262728293031
           
        123
    45678910
    11121314151617
    18192021222324
    25262728   
           
     123456
    78910111213
    14151617181920
    21222324252627
    28293031   
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
    31      
       1234
    567891011
    12131415161718
    19202122232425
    2627282930  
           
    1234567
    15161718192021
    293031    
           
         12
    3456789
    10111213141516
           
      12345
    6789101112
    13141516171819
    20212223242526
    2728293031  
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    3031     
        123
    45678910
    11121314151617
    18192021222324
    252627282930 
           
     123456
    78910111213
    14151617181920
    21222324252627
    28293031   
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    30      
       1234
    567891011
    12131415161718
    19202122232425
    262728293031 
           
    1234567
    891011121314
    15161718192021
    22232425262728
    293031    
           
        123
    45678910
    11121314151617
    18192021222324
    25262728293031
           
      12345
    6789101112
    13141516171819
    20212223242526
    27282930   
           
        123
    45678910
    11121314151617
    18192021222324
    252627282930 
           
     123456
    78910111213
    14151617181920
    21222324252627
    28293031   
           
       1234
    567891011
    12131415161718
    19202122232425
    2627282930  
           
    1234567
    891011121314
    15161718192021
    22232425262728
    293031    
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
           
      12345
    6789101112
    13141516171819
    20212223242526
    2728293031  
           
      12345
    6789101112
    13141516171819
    20212223242526
    2728     
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    3031     
     123456
    78910111213
    14151617181920
    21222324252627
    282930    
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
    31      
    1234567
    891011121314
    15161718192021
    22232425262728
    293031    
           
        123
    45678910
    11121314151617
    18192021222324
    252627282930 
           
     123456
    78910111213
    14151617181920
    21222324252627
    28293031   
           
     123456
    78910111213
    14151617181920
    21222324252627
    28293031   
           
       1234
    567891011
    12131415161718
    19202122232425
    262728293031 
           
     123456
    78910111213
    14151617181920
    21222324252627
    282930    
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
    31      
      12345
    6789101112
    13141516171819
    20212223242526
    2728293031  
           
    1234567
    891011121314
    15161718192021
    22232425262728
    2930     
           
        123
    45678910
    11121314151617
    18192021222324
    25262728293031
           
      12345
    6789101112
    13141516171819
    20212223242526
    27282930   
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    3031     
          1
    2345678
    9101112131415
    16171819202122
    232425262728 
           
       1234
    567891011
    12131415161718
    19202122232425
    262728293031 
           
    1234567
    891011121314
    15161718192021
    22232425262728
    293031    
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
           
      12345
    6789101112
    13141516171819
    20212223242526
    2728293031  
           
    1234567
    891011121314
    15161718192021
    22232425262728
    2930     
           
        123
    45678910
    11121314151617
    18192021222324
    25262728293031
           
  • 古いVisual Studioのダウンロード元

    古いVisual Studioのダウンロードが必要だったので調べた。

    左側のツリーを展開して青いボタンを押すとダウンロードできる。


    https://docs.microsoft.com/ja-jp/visualstudio/productinfo/

     

    glfwを試す(3)複数ウィンドウ

    glfwでは複数のウィンドウを作れる。以下はそのサンプルコード。

    ただし別に別スレッドで動いているというものでもない。メッセージループは一つ。

    イベント処理時は、コールバック関数がウィンドウへのポインタを第一引数に渡すので、それを比較して呼び出し元を区別できるが、違う関数を呼び出しても問題ない(はずだ)し普通はそうすべきだと思う。

    ソースコード

    #include <cstdio>
    
    #include <Windows.h>
    #include <gl/GL.h>
    #include <GLFW/glfw3.h>
    
    #pragma comment(lib,"opengl32.lib")
    #pragma comment(lib,"glfw3.lib")
    
    // ウィンドウを格納する変数
    GLFWwindow* window1;
    GLFWwindow* window2;
    
    
    //キー入力を処理するコールバック関数 void key_callback(GLFWwindow* pwin, int key, int scancode, int action, int mods) { if ( action != GLFW_PRESS) return; //ウィンドウの判別をポインタで行う if (window1 == pwin) { printf("window 1 "); } if (window2 == pwin) { printf("window 2 "); } //キーイベント if ( key == GLFW_KEY_UP) { printf("key up\n"); } else if ( key == GLFW_KEY_DOWN ) { printf("key down\n"); } else if ( key == GLFW_KEY_LEFT ) { printf("key left\n"); } else if ( key == GLFW_KEY_RIGHT ) { printf("key right\n"); } else { printf("\n"); } } // マウスクリックを処理するコールバック関数 void mouse_button_callback(GLFWwindow* pwin, int button, int action, int mods) { if (action != GLFW_PRESS) { return; } //ウィンドウの判別をポインタで行う if (window1 == pwin) { printf("window 1 "); } if (window2 == pwin) { printf("window 2 "); } //マウスイベント if (button == GLFW_MOUSE_BUTTON_LEFT) { printf("L - down\n"); } else if (button == GLFW_MOUSE_BUTTON_RIGHT) { printf("R - down\n"); } else if (button == GLFW_MOUSE_BUTTON_MIDDLE) { printf("M - down\n"); } else { printf("\n"); } }
    void render1(int width,int height);//window 1 用描画関数 void render2(int width, int height);//window 2 用描画関数
    int main() { if (glfwInit() == GL_FALSE) { return 1; } window1 = glfwCreateWindow(400,400,"window 1",NULL,NULL); window2 = glfwCreateWindow(400,400,"window 2",NULL,NULL); if (window1 == nullptr) { glfwTerminate(); return 1; } if (window2 == nullptr) { glfwTerminate(); return 1; } //////////////////////////////////////////// // コールバック関数の設定 glfwSetKeyCallback(window1, key_callback); glfwSetKeyCallback(window2, key_callback); glfwSetMouseButtonCallback(window1, mouse_button_callback); glfwSetMouseButtonCallback(window2, mouse_button_callback); // //////////////////////////////////////////// while (glfwWindowShouldClose(window1) == GL_FALSE) { int width, height; //////////////////////////////////////////////////////// glfwGetFramebufferSize(window1, &width, &height); glfwMakeContextCurrent(window1); render1(width,height); glfwSwapBuffers(window1); //////////////////////////////////////////////////////// glfwGetFramebufferSize(window2, &width, &height); glfwMakeContextCurrent(window2); render2(width, height); glfwSwapBuffers(window2); //////////////////////////////////////////////////////// // イベント取得 glfwWaitEvents(); } glfwTerminate(); }
    void render1(int width, int height) { glViewport(0, 0, width, height); glOrtho(-1, 1, -1, 1, -1, 1); glClearColor(0, 0, 0, 1); glClear(GL_COLOR_BUFFER_BIT); glBegin(GL_QUADS); glColor3d(1, 0, 0); glVertex2d(-0.7, -0.7); glColor3d(0, 1, 0); glVertex2d(-0.7, 0.7); glColor3d(0, 0, 1); glVertex2d(0.7, 0.7); glColor3d(1, 1, 1); glVertex2d(0.7, -0.7); glEnd(); } void render2(int width, int height) { glViewport(0, 0, width, height); glOrtho(-1, 1, -1, 1, -1, 1); glClearColor(0, 0, 0, 1); glClear(GL_COLOR_BUFFER_BIT); glBegin(GL_QUADS); glColor3d(0, 1, 1); glVertex2d(-0.7, -0.7); glColor3d(1, 0, 1); glVertex2d(-0.7, 0.7); glColor3d(1, 1, 0); glVertex2d(0.7, 0.7); glColor3d(0, 0, 0); glVertex2d(0.7, -0.7); glEnd(); }
     

    glfwを試す(1)

    glfwを試す(2)イベント

    glfwを試す(3)複数ウィンドウ

    glfwを試す(2)イベント

    ドキュメントトップ

    イベントの扱いについて。

    キーの定数一覧:

    ソースコード

    #include <cstdio>
    
    #include <Windows.h>
    #include <gl/GL.h>
    #include <GLFW/glfw3.h>
    
    #pragma comment(lib,"opengl32.lib")
    #pragma comment(lib,"glfw3.lib")
    
    // 参考文献 ////////////////////////////////////////
    // https://www.glfw.org/docs/latest/input_guide.html
     
    //キー入力を処理するコールバック関数 void key_callback(GLFWwindow* pwin, int key, int scancode, int action, int mods) { // https://www.glfw.org/docs/latest/group__keys.html#ga99aacc875b6b27a072552631e13775c7 // action ... GLFW_PRESS , GLFW_REPEAT , GLFW_RELEASE //特殊キー if (key == GLFW_KEY_UP && action == GLFW_PRESS) { printf("key up\n"); } if (key == GLFW_KEY_DOWN && action == GLFW_PRESS) { printf("key down\n"); } if (key == GLFW_KEY_LEFT && action == GLFW_PRESS) { printf("key left\n"); } if (key == GLFW_KEY_RIGHT && action == GLFW_PRESS) { printf("key right\n"); } if (key >= GLFW_KEY_A && key <= GLFW_KEY_Z) { if (action == GLFW_PRESS) { const char* key_name = glfwGetKeyName(key, 0); printf("key - %s\n", key_name); } } }
    // マウスクリックを処理するコールバック関数 void mouse_button_callback(GLFWwindow* pwin, int button, int action, int mods) { if (button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_PRESS) { printf("L - down\n"); } if (button == GLFW_MOUSE_BUTTON_RIGHT && action == GLFW_PRESS) { printf("R - down\n"); } if (button == GLFW_MOUSE_BUTTON_MIDDLE && action == GLFW_PRESS) { printf("M - down\n"); } }
    // マウスホイールを処理するコールバック関数 void mouse_wheel_callback(GLFWwindow* window, double xoffset, double yoffset) { if (yoffset < 0) { printf("wheel down \n"); } if (yoffset > 0) { printf("wheel up \n"); } }
    int main() { if (glfwInit() == GL_FALSE) { return 1; } GLFWwindow* window = glfwCreateWindow( 400, 400, "window title", NULL, NULL ); if (window == nullptr) { glfwTerminate(); return 1; } //////////////////////////////////////////// // コールバック関数の設定 glfwSetKeyCallback(window, key_callback); glfwSetMouseButtonCallback(window, mouse_button_callback); glfwSetScrollCallback(window, mouse_wheel_callback); // //////////////////////////////////////////// glfwMakeContextCurrent(window); while (glfwWindowShouldClose(window) == GL_FALSE) { int width, height; glfwGetFramebufferSize(window, &width, &height); ///////////////////// // 描画 glViewport(0, 0, width, height); glOrtho(-1, 1, -1, 1, -1, 1); glClearColor(0.2, 0.2, 0.2, 1); glClear(GL_COLOR_BUFFER_BIT); // ///////////////////// glfwSwapBuffers(window); // イベント取得 glfwWaitEvents(); } glfwTerminate(); }

    glfwを試す(1)

    glfwを試す(2)イベント

    glfwを試す(3)複数ウィンドウ

    glfwを試す(1)

    最近ではglutよりglfwという風潮がある。

    そこでglfwでウィンドウを表示して簡単な描画までを行う。

    1.ダウンロード

    https://www.glfw.org/download.html


    2.ソースコード

    #include <cstdlib>
    #include <iostream>
    
    #include <Windows.h>
    #include <gl/GL.h> #include <GLFW/glfw3.h> #pragma comment(lib,"opengl32.lib") #pragma comment(lib,"glfw3.lib") int main() { //////////////////////////////////////////////////////////////////////////////// // GLFW の初期化 if (glfwInit() == GL_FALSE) { // 初期化に失敗したら終了 return 1; } //////////////////////////////////////////////////////////////////////////////// // ウィンドウを作成 GLFWwindow* window = glfwCreateWindow( 400, //width 400, //height "window title",//title NULL, //monitor NULL //share ); //////////////////////////////////////////////////////////////////////////////// // ウィンドウを作成できなければ終了 if (window == nullptr) { glfwTerminate(); return 1; } glfwMakeContextCurrent(window); while (glfwWindowShouldClose(window) == GL_FALSE) { int width, height; glfwGetFramebufferSize(window, &width, &height);
     
    ///////////////////// // 描画 glViewport(0, 0, width, height); glOrtho(-1, 1, -1, 1, -1, 1); glClearColor(0, 0, 0, 1); glClear(GL_COLOR_BUFFER_BIT); glBegin(GL_QUADS); glColor3d(1, 0, 0); glVertex2d(-0.7, -0.7); glColor3d(0, 1, 0); glVertex2d(-0.7, 0.7); glColor3d(0, 0, 1); glVertex2d( 0.7, 0.7); glColor3d(1, 1, 1); glVertex2d(0.7, -0.7); glEnd(); // /////////////////////
    glfwSwapBuffers(window); // イベント取得 glfwWaitEvents(); } glfwTerminate(); }

    glfwを試す(1)

    glfwを試す(2)イベント

    glfwを試す(3)複数ウィンドウ

    Blenderのply Exportの重複頂点

    当然だが、File → Export → Stanford(.ply)でply出力できる。

    しかしその時、出力されたPLYファイルを見ると、頂点が重複している。

    重複頂点を削除するオプションがどうも見つからなかったので、別の方法を考える。最も確実な方法は、おそらくMeshLab等の有名どころを使って重複頂点削除コマンドを実行すること。

    MeshLabで重複削除

    MeshLab → [Filters] → [Cleaning and Repairing] → [Remove Duplicate Vertices]

    Blender Pythonで出力プログラムを書く

    あるいは、plyは比較的わかりやすいフォーマットなので出力プログラムを自力で書いてもいいかもしれない。

    import bpy
    
    msh = bpy.context.active_object
    
    fname = 'C:/test/' + msh.name + '.ply'
    
    with open(fname, 'w') as myf:
    
        print( "ply" ,file=myf )
        print( "format ascii 1.0" ,file=myf )
        print( "element vertex",len(msh.data.vertices) ,file=myf )
        print( "property float x" ,file=myf )
        print( "property float y" ,file=myf )
        print( "property float z" ,file=myf )
        print( "property float nx" ,file=myf )
        print( "property float ny" ,file=myf )
        print( "property float nz" ,file=myf )
        print( "element face",len(msh.data.polygons) ,file=myf )
        print( "property list uchar int vertex_index" ,file=myf )
        print( "end_header" ,file=myf )
        for vt in msh.data.vertices:
            print(vt.co[0],vt.co[1],vt.co[2], " " ,end="",file=myf ) #頂点座標出力
            print(vt.normal[0],vt.normal[1],vt.normal[2],file=myf ) #頂点法線出力
    
        for f in msh.data.polygons:
            print( len(f.vertices) ," ", end="",file=myf ) #各面の頂点数出力
            for v in f.vertices:
                print( v ," ", end="" ,file=myf ) #各面を構成する頂点の頂点番号を出力
            print( "" ,file=myf )
    

    処理結果

    MeshLabで頂点数の確認をする。Verticesが減っているのがわかる

    そのまま出力
    Pythonスクリプトで出力

    注意

    以下のように、結果がやや異なる。頂点数の違いは重複と見なす距離の差だと思う(想像)。四角形以上のNgonの扱いも異なっている面法線の再計算の有無あたりかとも思うが不明。

    Pythonスクリプトで出力
    MeshLabでClean

    Blender 2.8でアドオンを作ってみる

    まず以下のスクリプトをおもむろに実行する

    import bpy
    
    ##############################################
    
    # ボタンを定義
    class ConeButton(bpy.types.Operator):
      bl_idname = "szl.button"
      bl_label = "Add a CONE"
      
      def execute(self, context):
        bpy.ops.mesh.primitive_cone_add()
        return{'FINISHED'}
    
    
    ##############################################
    
    # パネルの項目を定義
    class ConeUI(bpy.types.Panel):
      bl_label = "panel title"
      bl_space_type = "VIEW_3D"
      bl_region_type = "UI"
      bl_category = "AddConePanel"
      
      def draw(self, context):
        self.layout.operator("szl.button")
    
    ##############################################
        
    classes = (
      ConeUI,
      ConeButton
    )
    
    ##############################################
    
    # アドオン有効化時に呼び出される
    def register():
      for c in classes:
        bpy.utils.register_class(c)
    
    # アドオン無効化時に呼び出される
    def unregister():
      for c in classes:
        bpy.utils.unregister_class(c)
    
    
    if __name__ == "__main__": register()
     

    すると、パネルに新しい項目が追加され、ボタンを押すとConeが生成される。

    これは上記スクリプトの最後の register() 関数が実行されたため。

    しかしBlenderを再起動すれば消えてしまう。そこでまず以下のように変更を加える。ファイル名は add-cone-addon.py とでもしておく。

    下記、bl_infoの部分があるとアドオンとして認識される。

    また、registerはBlenderがアドオンを読み込んだときに自動で呼び出されるので、一番下の呼び出し部分を削除する。

    import bpy
    
    ##############################################
    
    bl_info = { "name" : "sample: add-on-name", "author" : "yodori soratori", "version" : (1, 0), "blender" : (2, 81, 0), "location" : "location", "description": "sample", "warning" : "warning message", # 空だと!アイコンが出ない "support" : "TESTING", # または OFFICIAL または COMMUNITY "wiki_url" : "", "tracker_url": "", "category" : "Object" #アドオンのカテゴリ }
    ############################################## # ボタンを定義 class ConeButton(bpy.types.Operator): bl_idname = "szl.button" bl_label = "Add a CONE" def execute(self, context): bpy.ops.mesh.primitive_cone_add() return{'FINISHED'} ############################################## # class ConeUI(bpy.types.Panel): bl_label = "panel title" bl_space_type = "VIEW_3D" bl_region_type = "UI" bl_category = "AddConePanel" def draw(self, context): self.layout.operator("szl.button") ############################################## classes = ( ConeUI, ConeButton ) ############################################## # アドオン有効化時に呼び出される def register(): for c in classes: bpy.utils.register_class(c) # アドオン無効化時に呼び出される def unregister(): for c in classes: bpy.utils.unregister_class(c)
    #if __name__ == "__main__": # register()

    そして、Preference → Add-ons でアドオンとしてインストールする

    参考

    https://dskjal.com/blender/ui-script.html

    Blenderで二本のエッジの交点に点を追加する(Python) 2.79,2.8両対応

    エッジを二本選択し、その交点を求めたい。


    How can I add vertices to intersection of two edges?

    https://blender.stackexchange.com/questions/2976/how-can-i-add-vertices-to-intersection-of-two-edges

    のPythonスクリプトを実行すると、二辺の交差点に頂点を一つ追加できる。(Blender 2.79 , 2.8 両対応)

    しかし頂点が一つ置かれるだけだと不便なので、各エッジをsubdivideする形で追加するように変更した。

    コードは以下:

    import bmesh
    import bpy
    from mathutils import geometry
    
    # get cross point of 2 edges
    def calc_cross_coordinate(edge2):
    
    
        if len(edge2) == 2:
            [[v1, v2], [v3, v4]] = [[v.co for v in e.verts] for e in edge2]
    
            iv = geometry.intersect_line_line(v1, v2, v3, v4)
            iv = (iv[0] + iv[1]) / 2
            return iv
        
    # subdivide 2 edges and move the points to cross point
    def subdivide_selects(edge2, moveto):
        obj = bpy.context.object
        me = obj.data
        bm = bmesh.from_edit_mesh(me)
    
        ret = bmesh.ops.subdivide_edges(bm,
            edges=edge2,
            use_grid_fill=True,
            cuts=1)
        bmesh.update_edit_mesh(me)
    
        for i in ret['geom_split']:
            if type(i) == bmesh.types.BMVert:
                i.co=moveto
    
    def cross_subdivide():
        obj = bpy.context.object
        me = obj.data
        bm = bmesh.from_edit_mesh(me)
    
        edge2 = [e for e in bm.edges if e.select]
        if len(edge2) == 2:
            pos = calc_cross_coordinate(edge2)
            subdivide_selects(edge2,pos)
        
    cross_subdivide()
        
    

    実行例

    解説

    cross_subdivide

    今回の処理を行う関数。

    エッジが二本選択されているとき、二本のエッジをsubdivideし、新規頂点を交点に作成する。

    calc_cross_coordinate

    二本のエッジを引数にとり、geometry.intersect_line_lineで交差している座標を求める。

    三次元の線分の場合、現実には誤差の関係で絶対に交差しないので、交点は二つ求まる。その中間点を交点(iv)としている。

    subdivide_selects

    bmesh.ops.subdivide_edgesでオブジェクトをsubdivideしている。

    戻り値の['geom_split']に作成されたデータが入っているので、データ型がBMVertのものだけを取り出し、座標を交点で上書きする

    OpenGLで文字列描画(Asciiのみ)

    glutBitmapCharacterは珍しい関数では無いけれどなぜかどのサンプルもzを殺している。個人的には以下のようにx,y,zの指定をちゃんとやった方が圧倒的に使いやすい。

    //! @brief 文字列を表示
    //! @param [in] x 三次元の座標(X)
    //! @param [in] y 三次元の座標(Y)
    //! @param [in] z 三次元の座標(Z)
    //! @param [in] str 文字列(英語のみ)
    void render_string(float x, float y, float z, const char* str) {
      glRasterPos3f(x, y, z);
    
      const char* c = str;
      while (*c) {
        glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, *c++);
      }
    }
    

    単に現在の状態を表示するだけならコンソールでいいし、見栄えが重要ならそもそもglutなんて使わないし、何より、文字を左上に出すならちゃんとglLoadIdentityしてから世界座標系で指定する必要がある。手間を省けてない。

    //! @brief 文字列を表示
    //! @param [in] x 三次元の座標(X)
    //! @param [in] y 三次元の座標(Y)
    //! @param [in] z 三次元の座標(Z)
    //! @param [in] str 文字列(英語のみ)
    void render_string(float x, float y, float z, const char* str) {
      glRasterPos3f(x, y, z);
    
      const char* c = str;
      while (*c) {
        glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, *c++);
      }
    }
    
    
    int width, height;
    //回転オブジェクト定義
    nu::mrotate camr;
    
    //表示
    void disp(void) {
      glClear(GL_COLOR_BUFFER_BIT);
      glViewport(0, 0, width, height);
    
      glPushMatrix();
    
      //原点を視線方向に0.5ずらす
      glTranslated(0, 0, -0.5);
    
      //回転行列を適用
      double mat[16];
      glMultMatrixd(camr.getmatrix(mat));
    
      //一辺0.7のキューブを描画
      cube(0.7);
    
    
      glColor3d(1, 1, 1);
    
      double ws = -0.7 / 2;
      double we = 0.7 / 2;
      render_string(ws, ws, ws, "min");
      render_string(we, we, we, "max");
    
      glPopMatrix();
    
      glLoadIdentity();
      render_string(-1, 0.9, 0, "sample");
    
      glFlush();
    }
    

    (今更)FirefoxのトップサイトのGoogleとAmazonを開けるようにする(@付き)

    ずっと不便き極まりなかったことが今更だがわかったのでここに残しておきたい。というか、世の人は多分今の方が使いやすいか、簡単に戻し型がわかってしまうのだろう。だから私の使う検索ワードではヒットしないのである。

    問題

    ある日の更新を境に、Firefoxホームに表示されたgoogleやamazonをクリックすると検索になってしまい、サイトに飛ばなくなった。

    記憶が確かなら元々はよくアクセスするサイトが自動で出てきていたのに、虫眼鏡マークのボタンに上書きされてしまった格好だったと思う。

    虫眼鏡のマークがついているやつをクリックすると
    サイトに飛ばずに検索ワード入力になる

    @がついていると検索ワード入力になるのかとか思って色々試したが戻らなかった。

    解決方法

    @amazonと@googleは検索エンジン扱いになっている。つまりリンクでは無い。だからトップサイトとして登録し、それとは全く別に、(必要であれば)検索エンジンとしてのアイコンを無効にする。

    トップサイトとして登録

    トップサイト右側の...から「トップサイト追加」
    amazonのURIを入力し「追加」

    検索エンジンを非表示にする

    トップサイト右側の...から「検索エンジンを追加」
    チェックを外す
    検索エンジンとしてのamazonが消える

    Bitnami MODx Stackを動かしてみる(3) ページを作る

    bitnamiのバナーについて

    ロゴを消す方法

    sudo /opt/bitnami/apps/modx/bnconfig --disable_banner 1

    としたのち、以下でapacheを再起動

    sudo /opt/bitnami/ctlscript.sh restart apache

    もう一度表示する方法

    以下でいいはずなのだが、

    sudo /opt/bitnami/apps/modx/bnconfig --disable_banner 0

    なぜか動いてくれないので、以下を実行する

    sudo rm -rf /opt/bitnami/apps/bitnami/banner/disable-banner

    ページを作成

    「ドキュメント」の左上の「新しいドキュメント」をクリック

    「コンテンツ」に本文を書いて「保存」をクリック。「プレビュー」で表示を確認できる。

    HTMLタグを直に打てる

    トップページの変更

    サイトのトップページの設定がデフォルトではHomeになっているので、システム設定で site_start の項目を検索し、トップページにしたい記事のIDを設定する