ぬの部屋(仮)
nu-no-he-ya
  •      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
           
  • VTKでEDLシェーダを使用してみる

    vtkEDLShadingを使うと簡単にEDLシェーダを使用できる。

    コード

    #pragma warning(disable:4996)
    
    
    //VTK_MODULE_INITに必要
    #include <vtkAutoInit.h>
    
    //必須
    VTK_MODULE_INIT(vtkRenderingOpenGL2);
    VTK_MODULE_INIT(vtkInteractionStyle);
    
    ////////////////////////////////////////////////////////////
    #include <vtkOpenGLRenderer.h>
    #include <vtkOpenGLRenderWindow.h>
    ////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////
    #include <vtkRenderStepsPass.h>
    #include <vtkEDLShading.h>
    ////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////
    #include <vtkSmartPointer.h>
    #include <vtkActor.h>
    #include <vtkRenderer.h>
    #include <vtkRenderWindow.h>
    #include <vtkRenderWindowInteractor.h>
    ////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////
    #include <vtkConeSource.h>
    #include <vtkCubeSource.h>
    #include <vtkPlaneSource.h>
    #include <vtkProperty.h>
    #include <vtkSphere.h>
    #include <vtkSphereSource.h>
    #include <vtkPolyDataMapper.h>
    ////////////////////////////////////////////////////////////
    //#include <vtkCamera.h>
    
    #pragma comment(lib, "ws2_32.lib")
    #pragma comment(lib, "Psapi.lib")
    #pragma comment(lib, "Dbghelp.lib")
    #pragma comment(lib,"opengl32.lib")
    
    
    ////////////////////////////////////////////////////////////
    void SetTestData(vtkSmartPointer<vtkOpenGLRenderer> renderer);
    ////////////////////////////////////////////////////////////
    
    int main()
    {
        auto renderer = vtkSmartPointer<vtkOpenGLRenderer>::New();
        auto window = vtkSmartPointer<vtkRenderWindow>::New();
        window->AddRenderer(renderer);
    
        SetTestData(renderer); // 表示データの設定
    
        renderer->ResetCamera();
    
    
        // EDL シェーダの設定
        auto basicPasses = vtkSmartPointer<vtkRenderStepsPass>::New();
        auto edl = vtkSmartPointer<vtkEDLShading>::New();
        edl->SetDelegatePass(basicPasses);
    
        // renderer に EDL を適用
        renderer->SetPass(edl);
    
        // マルチサンプリングオフ。EDL とは相性が悪い。深度バッファの計算が正しく行われないため。
        window->SetMultiSamples(0);
     
    
        // ウィンドウサイズ
        window->SetSize(800, 600);
    
        auto interactor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
        window->SetInteractor(interactor);
        interactor->Initialize();
        window->Render();
        interactor->Start();
    
        return 0;
    }
    
    void SetTestData(vtkSmartPointer<vtkOpenGLRenderer> renderer)
    {
        {
            auto planeSource = vtkSmartPointer<vtkPlaneSource>::New();
            planeSource->SetOrigin(-5.0, 0.0, -5.0);
            planeSource->SetPoint1(5.0, 0.0, -5.0);
            planeSource->SetPoint2(-5.0, 0.0, 5.0);
            planeSource->SetResolution(50, 50);
            planeSource->Update();
            planeSource->SetCenter(0.0, -5.0, 0.0);
    
            auto planeMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
            planeMapper->SetInputConnection(planeSource->GetOutputPort());
    
            auto planeActor = vtkSmartPointer<vtkActor>::New();
            planeActor->SetMapper(planeMapper);
            planeActor->GetProperty()->SetColor(0.8, 0.8, 0.8);    // 薄いグレー
            planeActor->GetProperty()->SetSpecular(0.1);
            planeActor->GetProperty()->SetDiffuse(0.9);
    
            renderer->AddActor(planeActor);
        }
    
        for (int i = 0; i < 10; i++)
        {
            // x,y,zを乱数で生成
            double x, y, z;
            x = (-0.5 + rand() / double(RAND_MAX)) * 10;
            y = (-0.5 + rand() / double(RAND_MAX)) * 10;
            z = (-0.5 + rand() / double(RAND_MAX)) * 10;
    
            auto sphereSource = vtkSmartPointer<vtkSphereSource>::New();
            sphereSource->SetCenter(-2.0, 1.0, 0.0);  // 床から1.0上に
            sphereSource->SetRadius(1.0);
            sphereSource->SetThetaResolution(30);
            sphereSource->SetPhiResolution(30);
            sphereSource->Update();
            sphereSource->SetCenter(x, y, z);
    
            auto sphereMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
            sphereMapper->SetInputConnection(sphereSource->GetOutputPort());
    
            auto sphereActor = vtkSmartPointer<vtkActor>::New();
            sphereActor->SetMapper(sphereMapper);
            sphereActor->GetProperty()->SetColor(1.0, 0.2, 0.2); // 赤っぽい色
    
            renderer->AddActor(sphereActor);
        }
    
        for (int i = 0; i < 10; i++)
        {
            // x,y,zを乱数で生成
            double x, y, z;
            x = (-0.5 + rand() / double(RAND_MAX)) * 10;
            y = (-0.5 + rand() / double(RAND_MAX)) * 10;
            z = (-0.5 + rand() / double(RAND_MAX)) * 10;
    
    
    
    
            auto coneSource = vtkSmartPointer<vtkConeSource>::New();
            coneSource->SetCenter(2.0, 0.0, 0.0);
            coneSource->SetRadius(1.0);
            coneSource->SetHeight(2.5);
            coneSource->SetDirection(0.0, 1.0, 0.0); // Y軸方向に伸ばす
            coneSource->SetResolution(30);
            coneSource->Update();
            coneSource->SetCenter(x, y, z);
    
            auto coneMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
            coneMapper->SetInputConnection(coneSource->GetOutputPort());
    
            auto coneActor = vtkSmartPointer<vtkActor>::New();
            coneActor->SetMapper(coneMapper);
            coneActor->GetProperty()->SetColor(0.2, 0.4, 1.0); // 青系
    
            renderer->AddActor(coneActor);
        }
    
        for (int i = 0; i < 10; i++)
        {
            // x,y,zを乱数で生成
            double x, y, z;
            x = (-0.5 + rand() / double(RAND_MAX)) * 10;
            y = (-0.5 + rand() / double(RAND_MAX)) * 10;
            z = (-0.5 + rand() / double(RAND_MAX)) * 10;
    
            auto cubeSource = vtkSmartPointer<vtkCubeSource>::New();
            cubeSource->SetCenter(0.0, 1.0, 2.0);
            cubeSource->SetXLength(1.5);
            cubeSource->SetYLength(1.5);
            cubeSource->SetZLength(1.5);
            cubeSource->Update();
            cubeSource->SetCenter(x, y, z);
    
            auto cubeMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
            cubeMapper->SetInputConnection(cubeSource->GetOutputPort());
    
            auto cubeActor = vtkSmartPointer<vtkActor>::New();
            cubeActor->SetMapper(cubeMapper);
            cubeActor->GetProperty()->SetColor(0.2, 1.0, 0.2); // 緑系
    
            renderer->AddActor(cubeActor);
        }
    
    }
    

    VTKで頂点距離を可視化

    メッシュ1の頂点からメッシュ2の頂点を探索し、最も近い頂点への距離をスカラー値としてVTKに登録して、カラーテーブルを指定して着色する。

    #include <iostream>
    
    //VTK_MODULE_INITに必要
    #include <vtkAutoInit.h>
    
    
    #include <vtkSmartPointer.h>
    #include <vtkRenderer.h>
    #include <vtkRenderWindow.h>
    #include <vtkRenderWindowInteractor.h>
    
    //円筒とその表示に必要
    #include <vtkPointData.h>
    #include <vtkCellData.h>
    #include <vtkPolyData.h>
    #include <vtkActor.h>
    #include <vtkPolyDataMapper.h>
    
    #include <vtkLookupTable.h>
    #include <vtkFloatArray.h>
    
    
    #pragma comment(lib,"opengl32.lib")
    #pragma comment(lib,"psapi.lib")
    #pragma comment(lib,"dbghelp.lib")
    #pragma comment(lib,"ws2_32.lib")
    
    #include <vtkCellArray.h>
    #include <vtkTriangle.h>
    
    #include <open3d/Open3D.h>
    #include <open3d/geometry/PointCloud.h>
    #include <open3d/geometry/TriangleMesh.h>
    
    // kdtree
    #include <open3d/geometry/KDTreeFlann.h>
    
    #pragma comment(lib,"Open3D.lib")
    
    //必須
    VTK_MODULE_INIT(vtkRenderingOpenGL2);
    VTK_MODULE_INIT(vtkInteractionStyle);
    
    
    // baseの各頂点に対して、targetの最も近い頂点までの距離を計算する
    std::vector<double> calcNearestPoint(std::shared_ptr<open3d::geometry::TriangleMesh> base, std::shared_ptr<open3d::geometry::TriangleMesh> target) {
    
      std::vector<double> ret;
      // mymeshの頂点のkd-treeを作成
      open3d::geometry::KDTreeFlann kdtree;
      kdtree.SetGeometry(*target);
      
      // 頂点Pに最も近い頂点を探す
      std::vector<double> distances;
      std::vector<int> indices;
      for (auto& p : base->vertices_) {
        int count = kdtree.SearchKNN(p,1,indices,distances);
        double distance = sqrt(distances[0]);
        ret.push_back(distance);
      }
    
      return ret;
    }
    
          
    // テストデータを作成
    void CreateMeshData_o3d_1(std::shared_ptr<open3d::geometry::TriangleMesh> mymesh, int xcount, int ycount, float width, float height,float offsetz, float depth, float density) {
      
      // 頂点の登録
      for (int i = 0; i < xcount; ++i) {
        for (int j = 0; j < ycount; ++j) {
          double x = -0.5 + 1.0 * i / (xcount - 1);
          double y = -0.5 + 1.0 * j / (ycount - 1);
          double z = sin(x * density) * depth + sin(y * density) * depth + offsetz;
    
          mymesh->vertices_.push_back(Eigen::Vector3d(x * width, y * height, z));
    
        }
      }
      // メッシュ(三角形)の作成
      for (int i = 0; i < xcount - 1; ++i) {
        for (int j = 0; j < ycount - 1; ++j) {
          // 四角形を2つの三角形に分割
          const int p1 = i * ycount + j;       // 左下
          const int p2 = (i + 1) * ycount + j; // 右下
          const int p3 = i * ycount + (j + 1); // 左上
          const int p4 = (i + 1) * ycount + (j + 1); // 右上
    
          // 三角形1 (p1, p2, p3)
          mymesh->triangles_.push_back(Eigen::Vector3i(p1, p2, p3));
          // 三角形2 (p2, p4, p3)
          mymesh->triangles_.push_back(Eigen::Vector3i(p2, p4, p3));
    
        }
      }
    
    }
    

    struct MeshData {
      std::shared_ptr<open3d::geometry::TriangleMesh> curve;
      std::shared_ptr<open3d::geometry::TriangleMesh> flat;
    };
    
    MeshData createData(int xcount,int ycount) {
      std::shared_ptr<open3d::geometry::TriangleMesh> mymesh1 = std::make_shared<open3d::geometry::TriangleMesh>();
      std::shared_ptr<open3d::geometry::TriangleMesh> mymesh2 = std::make_shared<open3d::geometry::TriangleMesh>();
    
      CreateMeshData_o3d_1(mymesh1, xcount, ycount, 2, 2, 0.0, 0.1, 10);
      CreateMeshData_o3d_1(mymesh2, xcount, ycount, 2, 2,-0.3, 0.05, 17);
    
      return MeshData{ mymesh1,mymesh2 };
    
    }
    

          
    vtkSmartPointer<vtkPolyData>
    CreateVTKMeshData(std::shared_ptr<open3d::geometry::TriangleMesh> tri,int xcount,int ycount) { vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New(); vtkSmartPointer<vtkCellArray> triangles = vtkSmartPointer<vtkCellArray>::New(); vtkSmartPointer<vtkCellArray> vertices = vtkSmartPointer<vtkCellArray>::New(); for(auto& p : tri->vertices_) { vtkIdType pid = points->InsertNextPoint(p.x(), p.y(), p.z()); vertices->InsertNextCell(1, &pid); } // メッシュ(三角形)の作成 for (int i = 0; i < xcount - 1; ++i) { for (int j = 0; j < ycount - 1; ++j) { // 四角形を2つの三角形に分割 vtkIdType p1 = i * ycount + j; // 左下 vtkIdType p2 = (i + 1) * ycount + j; // 右下 vtkIdType p3 = i * ycount + (j + 1); // 左上 vtkIdType p4 = (i + 1) * ycount + (j + 1); // 右上 // 三角形1 (p1, p2, p3) vtkSmartPointer<vtkTriangle> triangle1 = vtkSmartPointer<vtkTriangle>::New(); triangle1->GetPointIds()->SetId(0, p1); triangle1->GetPointIds()->SetId(1, p2); triangle1->GetPointIds()->SetId(2, p3); triangles->InsertNextCell(triangle1); // 三角形2 (p2, p4, p3) vtkSmartPointer<vtkTriangle> triangle2 = vtkSmartPointer<vtkTriangle>::New(); triangle2->GetPointIds()->SetId(0, p2); triangle2->GetPointIds()->SetId(1, p4); triangle2->GetPointIds()->SetId(2, p3); triangles->InsertNextCell(triangle2); } } // vtkPolyData の作成 vtkSmartPointer<vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New(); polyData->SetPoints(points); polyData->SetPolys(triangles); // 三角形セルを設定 return polyData; }

    vtkSmartPointer<vtkActor>
    createActor(vtkSmartPointer<vtkPolyData> polyData, vtkSmartPointer<vtkLookupTable> table,double min_,double max_ ) { vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New(); mapper->SetInputData(polyData); if( table != nullptr) { mapper->SetLookupTable(table); mapper->SetScalarRange(min_, max_); mapper->SetInterpolateScalarsBeforeMapping(true); } vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New(); actor->SetMapper(mapper); return actor; }
    //! @brief サーモグラフィー風のカラールックアップテーブルを生成する
    //! @param [in] scalar_min スカラー値の最小値
    //! @param [in] scalar_max スカラー値の最大値
    //! @param [in] division スカラー値の範囲を何分割するか
    //! @return カラールックアップテーブル
    vtkSmartPointer<vtkLookupTable> ThermographyColorTable(const double scalar_min, const double scalar_max, const int division) {
    
      vtkSmartPointer<vtkLookupTable> lut = vtkSmartPointer<vtkLookupTable>::New();
      lut->SetNumberOfTableValues(division); // テーブルの要素数を設定
      lut->SetTableRange(scalar_min, scalar_max); // スカラー値の範囲を設定
      lut->Build();
    
      // テーブルの i 番目の要素に対応する色を設定
      for (int i = 0; i < division; i++)
      {
        double t = static_cast<double>(i) / float(division - 1);
        double r, g, b;
        if (t < 0.33)
        {
          // 青から緑への補間
          double factor = t / 0.33;
          r = 0.0;
          g = factor;
          b = 1.0 - factor;
        }
        else if (t < 0.66)
        {
          // 緑から黄への補間
          double factor = (t - 0.33) / 0.33;
          r = factor;
          g = 1.0;
          b = 0.0;
        }
        else
        {
          // 黄から赤への補間
          double factor = (t - 0.66) / 0.34;
          r = 1.0;
          g = 1.0 - factor;
          b = 0.0;
        }
    
        // テーブルの i 番目の要素に色を設定
        lut->SetTableValue(
          i  // テーブルの要素番号
          , r, g, b, 1.0
        );
      }
      return lut;
    }
    
    int main(int /*argc*/, char** /*argv*/)
    {
      auto meshes = createData(100, 100);
      std::vector<double>  scalar = calcNearestPoint(meshes.curve, meshes.flat);
    
      vtkSmartPointer<vtkPolyData> curve = CreateVTKMeshData(meshes.curve, 100, 100);
      vtkSmartPointer<vtkPolyData> flat = CreateVTKMeshData(meshes.flat, 100, 100);
    
      // scalarをvtkFloatArrayに変換
      vtkSmartPointer<vtkFloatArray> scalars = vtkSmartPointer<vtkFloatArray>::New();
      scalars->SetName("MyScalarValues");
      double _min = *std::min_element(scalar.begin(), scalar.end());
      double _max = *std::max_element(scalar.begin(), scalar.end());
      for (auto& s : scalar) {
        scalars->InsertNextValue(s);
      }
      curve->GetPointData()->AddArray(scalars);
      curve->GetPointData()->SetActiveScalars("MyScalarValues");
    
      vtkSmartPointer<vtkLookupTable> colortable = ThermographyColorTable(_min, _max, 100);
      vtkSmartPointer<vtkActor> actor1 = createActor(curve, colortable,_min,_max);
      vtkSmartPointer<vtkActor> actor2 = createActor(flat,nullptr,0,0);
    
      //////////////////////////////////////
      auto renderer = vtkSmartPointer<vtkRenderer>::New();
      renderer->AddActor(actor1);
      renderer->AddActor(actor2);
      renderer->ResetCamera();
    
      //////////////////////////////////////
      auto interactor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
    
      //////////////////////////////////////
      auto renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
      renderWindow->AddRenderer(renderer);
      renderWindow->SetInteractor(interactor);
      renderWindow->Render();
    
      interactor->Start(); //イベントループへ入る
    
      return 0;
    }
    
    

    VTKでテスト用の簡単な曲面を描画

    #include <iostream>
    
    //VTK_MODULE_INITに必要
    #include <vtkAutoInit.h>
    
    
    #include <vtkSmartPointer.h>
    #include <vtkRenderer.h>
    #include <vtkRenderWindow.h>
    #include <vtkRenderWindowInteractor.h>
    
    #include <vtkPointData.h>
    #include <vtkCellData.h>
    #include <vtkPolyData.h>
    #include <vtkActor.h>
    #include <vtkPolyDataMapper.h>
    
    #pragma comment(lib,"opengl32.lib")
    #pragma comment(lib,"psapi.lib")
    #pragma comment(lib,"dbghelp.lib")
    #pragma comment(lib,"ws2_32.lib")
    
    #include <vtkCellArray.h>
    #include <vtkTriangle.h>
    
    
    //必須
    VTK_MODULE_INIT(vtkRenderingOpenGL2);
    VTK_MODULE_INIT(vtkInteractionStyle);
    
    
    
    vtkSmartPointer<vtkPolyData> CreateMeshData(bool cloudonly,int xcount, int ycount,float width,float height,float depth,float density) {
      vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
      vtkSmartPointer<vtkCellArray> triangles = vtkSmartPointer<vtkCellArray>::New();
      vtkSmartPointer<vtkCellArray> vertices = vtkSmartPointer<vtkCellArray>::New();
    
      // 頂点の登録
      for (int i = 0; i < xcount; ++i) {
        for (int j = 0; j < ycount; ++j) {
          double x = -0.5 + 1.0 * i / (xcount - 1);
          double y = -0.5 + 1.0 * j / (ycount - 1);
          double z = sin(x * density)*depth + sin(y * density) * depth;
          vtkIdType pid = points->InsertNextPoint(x*width, y*height, z);
    
          if (cloudonly == true)
          {
            vertices->InsertNextCell(1, &pid);
          }
    
        }
      }
      
      if (cloudonly == true)
      {
        vtkSmartPointer<vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New();
        polyData->SetPoints(points);
        polyData->SetVerts(vertices);
        return polyData;
      }
    
      // メッシュ(三角形)の作成
      for (int i = 0; i < xcount - 1; ++i) {
        for (int j = 0; j < ycount - 1; ++j) {
          // 四角形を2つの三角形に分割
          vtkIdType p1 = i * ycount + j;       // 左下
          vtkIdType p2 = (i + 1) * ycount + j; // 右下
          vtkIdType p3 = i * ycount + (j + 1); // 左上
          vtkIdType p4 = (i + 1) * ycount + (j + 1); // 右上
    
          // 三角形1 (p1, p2, p3)
          vtkSmartPointer<vtkTriangle> triangle1 = vtkSmartPointer<vtkTriangle>::New();
          triangle1->GetPointIds()->SetId(0, p1);
          triangle1->GetPointIds()->SetId(1, p2);
          triangle1->GetPointIds()->SetId(2, p3);
          triangles->InsertNextCell(triangle1);
    
          // 三角形2 (p2, p4, p3)
          vtkSmartPointer<vtkTriangle> triangle2 = vtkSmartPointer<vtkTriangle>::New();
          triangle2->GetPointIds()->SetId(0, p2);
          triangle2->GetPointIds()->SetId(1, p4);
          triangle2->GetPointIds()->SetId(2, p3);
          triangles->InsertNextCell(triangle2);
        }
      }
    
      // vtkPolyData の作成
      vtkSmartPointer<vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New();
      polyData->SetPoints(points);
      polyData->SetPolys(triangles);  // 三角形セルを設定
    
      return polyData;
    }
    
    
    int main(int /*argc*/, char** /*argv*/)
    {
      vtkSmartPointer<vtkPolyData> polyData = CreateMeshData(false,500, 500,2,2,0.1,10);
    
      vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
      vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
      mapper->SetInputData(polyData);
      actor->SetMapper(mapper);
    
      //////////////////////////////////////
      auto renderer = vtkSmartPointer<vtkRenderer>::New();
      renderer->AddActor(actor);
      renderer->ResetCamera();
    
      //////////////////////////////////////
      auto interactor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
    
      //////////////////////////////////////
      auto renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
      renderWindow->AddRenderer(renderer);
      renderWindow->SetInteractor(interactor);
      renderWindow->Render();
    
      interactor->Start(); //イベントループへ入る
    
      return 0;
    }