Group Outputの前に Realize Instancesを入れることで、モディファイアの設定からapplyができるようになる。

結果が全て一つのオブジェクトになっているので、個別のオブジェクトにするには By Loose Parts で分離する。
Mesh → Separate → By Loose Parts

ただし、 By Loose Partsは頂点が繋がっていなければ纏まってくれないので、連続していないパーツが一つのオブジェクトになっている場合はどこかでつなげておかないといけない

諸事情によりPythonで株価を取得するコードを書いた。
株価を取得するAPIは有料から無料までいろいろあるが今回はただ呼び出せば使える yfinance をつかう。
################################### # 株価取得 ################################### import yfinance as yf df = yf.download("AAPL", start="2020-01-01", interval="1d") ################################### # 終値をグラフ表示 ################################### import matplotlib.pyplot as plt df["Close"].plot(title="AAPL Closing Price") plt.show()

import yfinance as yf import matplotlib.pyplot as plt # データ取得 df = yf.download("AAPL", start="2020-01-01", interval="1d") # EMA(指数移動平均)を計算 df["EMA20"] = df["Close"].ewm(span=20, adjust=False).mean() # 20日EMA df["EMA50"] = df["Close"].ewm(span=50, adjust=False).mean() # 50日EMA # 終値とEMAを同じグラフに描画 plt.figure(figsize=(10, 5)) plt.plot(df.index, df["Close"], label="Close", color="black", linewidth=1) plt.plot(df.index, df["EMA20"], label="EMA 20", color="blue", linewidth=1) plt.plot(df.index, df["EMA50"], label="EMA 50", color="red", linewidth=1) plt.title("AAPL Closing Price with EMA(20) & EMA(50)") plt.xlabel("Date") plt.ylabel("Price (USD)") plt.legend() plt.grid(True) plt.tight_layout() plt.show()

日本株は銘柄の後に.Tをつけるといいらしい。
import yfinance as yf import matplotlib.pyplot as plt tickers = ["7203.T", "6758.T", "7974.T"] # 一括取得 df = yf.download(tickers, start="2020-01-01", interval="1d")["Close"] # DataFrame の確認 print(df.head()) print("==========================") # 銘柄 for symbol in df.columns: print(df[symbol]) print("==========================") # グラフ描画 plt.figure(figsize=(10, 5)) for symbol in df.columns: plt.plot( df.index, # 横軸 日付 df[symbol], # 縦軸 価格 label=symbol # 凡例のラベル ) print("==========================") plt.title("Stock Prices (Close)") plt.xlabel("Date") plt.ylabel("Price (JPY)") plt.legend() plt.grid(True) plt.tight_layout() plt.show()

.vtkhdf形式は複数のオブジェクトを一つのファイルにまとめて保存できる。
ただしバイナリ形式なのと、保存形式が複数あるのでややこしい。今回はvtkMultiBlockDataSet形式で保存する。
vtkhdfで保存・読み込みを行う。データはvtkMultiBlockDataSetで保存する
#pragma once #include "createpoly.hpp" #include <vtkDataArraySelection.h> ///////////////////////////////////////// ///////////////////////////////////////// // 保存コード ///////////////////////////////////////// /////////////////////////////////////////
void save_as_Multiblock() { vtkSmartPointer<vtkPolyData> polypoints = createPoints(); vtkSmartPointer<vtkPolyData> polycone = createCone(); vtkSmartPointer<vtkPolyData> polyline = createPolyLine(); auto mb = vtkSmartPointer<vtkMultiBlockDataSet>::New(); mb->SetNumberOfBlocks(3); mb->SetBlock(0, polypoints); mb->SetBlock(1, polycone); mb->SetBlock(2, polyline); auto w = vtkSmartPointer<vtkHDFWriter>::New(); w->SetInputData(mb); w->SetFileName("scene.vtkhdf"); w->Write(); }
/////////////////////////////////////////
/////////////////////////////////////////
// 読み込みコード
/////////////////////////////////////////
/////////////////////////////////////////
std::vector< vtkSmartPointer<vtkPolyData> > load_as_Multiblock() { std::vector< vtkSmartPointer<vtkPolyData> > polyvec; auto reader = vtkSmartPointer<vtkHDFReader>::New(); reader->SetFileName("scene.vtkhdf"); reader->GetPointDataArraySelection()->EnableAllArrays(); reader->GetCellDataArraySelection()->EnableAllArrays(); reader->Update(); //vtkDataObject* out = reader->GetOutput(); vtkDataObject* out = reader->GetOutputDataObject(0); auto mb = vtkMultiBlockDataSet::SafeDownCast(out); std::cout << "MultiBlock with " << mb->GetNumberOfBlocks() << " blocks\n"; // 各ブロックを処理 for (unsigned int i = 0; i < mb->GetNumberOfBlocks(); i++) { vtkPolyData* poly = vtkPolyData::SafeDownCast(mb->GetBlock(i)); if (poly) { // RGB配列があればアクティブにする例 if (poly->GetPointData()->HasArray("RGB")) { poly->GetPointData()->SetActiveScalars("RGB"); } } polyvec.push_back(poly); } return polyvec; }
データを作成する。
#pragma once #include <vtkSmartPointer.h> #include <vtkDoubleArray.h> #include <vtkPointData.h> #include <vtkConeSource.h> #include <vtkCellArray.h> #include <vtkPoints.h> #include <vtkPolyData.h> #include <vtkPolyDataMapper.h> #include <vtkProperty.h> #include <vtkUnsignedCharArray.h> #include <array> #include <vtkCellData.h>
vtkSmartPointer<vtkPolyData> createPoints() { // 頂点配列 vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New(); // 色情報の配列 vtkSmartPointer<vtkUnsignedCharArray> colors = vtkSmartPointer<vtkUnsignedCharArray>::New(); colors->SetNumberOfComponents(3); colors->SetName("RGB"); // 頂点インデクスの配列 vtkSmartPointer<vtkCellArray> cells = vtkSmartPointer<vtkCellArray>::New(); for (size_t i = 0; i < 100000; i++) { double x = (double)rand() / (double)RAND_MAX; double y = (double)rand() / (double)RAND_MAX; double z = (double)rand() / (double)RAND_MAX; points->InsertNextPoint(x, y, z); // 座標追加 unsigned char r = static_cast<unsigned char>(x * 255.0); unsigned char g = static_cast<unsigned char>(y * 255.0); unsigned char b = static_cast<unsigned char>(z * 255.0); colors->InsertNextTypedTuple(std::array<unsigned char, 3>{r, g, b}.data()); cells->InsertNextCell(1); // 要素数 cells->InsertCellPoint(i); // 頂点インデックスを追加 } // --- vtkPolyData作成 --- auto polydata = vtkSmartPointer<vtkPolyData>::New(); polydata->SetPoints(points); polydata->SetVerts(cells); polydata->GetPointData()->SetScalars(colors); polydata->GetPointData()->SetActiveScalars("RGB"); return polydata; }
vtkSmartPointer<vtkPolyData> createCone() { vtkSmartPointer<vtkConeSource> coneSource; coneSource = vtkSmartPointer<vtkConeSource>::New(); coneSource->SetHeight(1.0); coneSource->SetRadius(0.2); coneSource->SetResolution(10); coneSource->Update(); vtkSmartPointer<vtkPolyData> conePolyData = coneSource->GetOutput(); return conePolyData; }
vtkSmartPointer<vtkPolyData> createPolyLine() { // VTKのデータ構造で W の形状を作成 // 頂点配列 vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New(); // 色情報の配列 vtkSmartPointer<vtkUnsignedCharArray> colors = vtkSmartPointer<vtkUnsignedCharArray>::New(); colors->SetNumberOfComponents(3); colors->SetName("RGB"); // 頂点インデクスの配列 vtkSmartPointer<vtkCellArray> cells = vtkSmartPointer<vtkCellArray>::New(); // 頂点追加 points->InsertNextPoint(0.0, 0.0, 0.0); // 0 colors->InsertNextTypedTuple(std::array<unsigned char, 3>{255,0,0}.data()); points->InsertNextPoint(0.5, 1.0, 0.0); // 1 colors->InsertNextTypedTuple(std::array<unsigned char, 3>{0,255, 0}.data()); points->InsertNextPoint(1.0, 0.0, 0.0); // 2 colors->InsertNextTuple3(0.0, 0.0, 1.0); colors->InsertNextTypedTuple(std::array<unsigned char, 3>{0, 0, 255}.data()); points->InsertNextPoint(1.5, 1.0, 0.0); // 3 colors->InsertNextTypedTuple(std::array<unsigned char, 3>{255, 255, 0}.data()); points->InsertNextPoint(2.0, 0.0, 0.0); // 4 colors->InsertNextTypedTuple(std::array<unsigned char, 3>{255, 0, 255}.data()); // 頂点インデクス追加 cells->InsertNextCell(5); // 要素数 cells->InsertCellPoint(0); cells->InsertCellPoint(1); cells->InsertCellPoint(2); cells->InsertCellPoint(3); cells->InsertCellPoint(4); // --- vtkPolyData作成 --- auto polydata = vtkSmartPointer<vtkPolyData>::New(); polydata->SetPoints(points); polydata->SetLines(cells); polydata->GetPointData()->SetScalars(colors); return polydata; }
#pragma once #include <vtkCellArray.h> #include <vtkPoints.h> #include <vtkPolyData.h> #include <vtkPolyDataMapper.h> #include <vtkActor.h> #include <vtkDoubleArray.h> #include <vtkSmartPointer.h> #include <vtkPointData.h> #include <vtkProperty.h> #include <vtkLine.h> #include "vtkFromO3dCommon.hpp" #include <open3d/Open3D.h> namespace vtko3d {
vtkSmartPointer<vtkPolyData> toLineSetPolyData(const open3d::geometry::LineSet& linesegments, USEVALUE usedata) { // 頂点の作成 vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New(); // 色情報の配列 vtkSmartPointer<vtkDoubleArray> colors = vtkSmartPointer<vtkDoubleArray>::New(); colors->SetNumberOfComponents(3); colors->SetName("Colors"); for (size_t i = 0; i < linesegments.points_.size(); i++) { double x = linesegments.points_[i].x(); double y = linesegments.points_[i].y(); double z = linesegments.points_[i].z(); points->InsertNextPoint(x, y, z); if (usedata & POINT_RGB) { double r = linesegments.colors_[i].x(); double g = linesegments.colors_[i].y(); double b = linesegments.colors_[i].z(); colors->InsertNextTuple3(r, g, b); // 色情報追加 } } // 線分(Cell)を定義 vtkSmartPointer<vtkCellArray> lines = vtkSmartPointer<vtkCellArray>::New(); for (size_t i = 0; i < linesegments.lines_.size(); i++) { size_t v1 = linesegments.lines_[i].x(); size_t v2 = linesegments.lines_[i].y(); // 線分を作成 auto line = vtkSmartPointer<vtkLine>::New(); line->GetPointIds()->SetId(0, v1); // 始点 line->GetPointIds()->SetId(1, v2); // 終点 lines->InsertNextCell(line); } // PolyDataへ格納 vtkSmartPointer<vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New(); polyData->SetPoints(points); polyData->SetLines(lines); polyData->GetPointData()->SetScalars(colors); return polyData; }
vtkSmartPointer<vtkActor> toLineSegmentsActor(vtkSmartPointer<vtkPolyDataMapper> mapper, std::optional< std::array<double, 3> > single_color = std::nullopt, int line_width = 1) { vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New(); actor->SetMapper(mapper); if (single_color.has_value()) { actor->GetProperty()->SetColor(single_color.value()[0], single_color.value()[1], single_color.value()[2]); } else { actor->GetProperty()->SetColor(1.0, 1.0, 1.0); // デフォルトは白色 } if (line_width > 0) { actor->GetProperty()->SetLineWidth(line_width); // 線の太さ } return actor; }
std::shared_ptr<open3d::geometry::LineSet> createSampleLineSegments() { auto linesets = std::make_shared<open3d::geometry::LineSet>(); for (size_t i = 0; i < 1000; i++) { for (size_t j = 0; j < 100; j++) { double x1 = (double)rand() / (double)RAND_MAX; double y1 = (double)rand() / (double)RAND_MAX; double z1 = 0.0;// (double)rand() / (double)RAND_MAX; double x2 = x1; double y2 = y1; double z2 = 1.0;// (double)rand() / (double)RAND_MAX; linesets->points_.emplace_back(x1, y1, z1); linesets->points_.emplace_back(x2, y2, z2); linesets->colors_.emplace_back(x1, y1, z1); // 赤色のライン linesets->colors_.emplace_back(x2, y2, z2); // 青色のライン linesets->lines_.emplace_back(i * 2, i * 2 + 1); // ラインセグメントのインデックス } } return linesets; }
}
auto linesegments = vtko3d::createSampleLineSegments(); auto polyData = vtko3d::toLineSetPolyData(*linesegments, vtko3d::POINT_RGB); auto mapper = vtko3d::toMapper(polyData); auto actor = vtko3d::toLineSegmentsActor(mapper, std::nullopt, 2);

#include <open3d/Open3D.h> #include <Eigen/Dense> #include <vector> #include <cmath> #include <memory> #pragma comment(lib, "opengl32.lib") #pragma comment(lib, "glew32s.lib") using namespace open3d;
std::shared_ptr<geometry::LineSet> MakePolyline() { const double x0 = -2.0 * 3.14159; const double x1 = 2.0 * 3.14159; const double amplitude = 1.0; // 振幅 const double frequency = 1.0; // 周波数 const double phase = 1.0; // 位相 const int samples = 400; ///////////////////////////////////////////////////////// auto lineset = std::make_shared<geometry::LineSet>(); // 頂点作成 const double step = (x1 - x0) / (samples - 1); for (int i = 0; i < samples; ++i) { double x = x0 + step * i; double y = amplitude * std::sin(frequency * x + phase); lineset->points_.emplace_back(Eigen::Vector3d(x, y, 0.0)); } ///////////////////////////////////////////////////////// // 頂点インデックスの組み合わせで線分を作成 for (size_t i = 0; i < samples-1; ++i){ lineset->lines_.emplace_back( (int)i, (int)(i + 1) ); // 線分に対する色を設定 lineset->colors_.emplace_back(Eigen::Vector3d(1.0, i/float(samples), 0.0)); } return lineset; }
int main() { auto sine_ls = MakePolyline(); visualization::Visualizer vis; vis.CreateVisualizerWindow("LineSet", 800, 600); vis.AddGeometry(sine_ls); auto& opt = vis.GetRenderOption(); opt.line_width_ = 2.0; opt.background_color_ = { 0, 0, 0 }; vis.Run(); vis.DestroyVisualizerWindow(); return 0; }

#pragma once #include <vtkCellArray.h> #include <vtkPoints.h> #include <vtkPolyData.h> #include <vtkPolyDataMapper.h> #include <vtkActor.h> #include <vtkDoubleArray.h> #include <vtkSmartPointer.h> #include <vtkPointData.h> #include <vtkProperty.h> #include <open3d/Open3D.h> #include <open3d/geometry/PointCloud.h> #include <Eigen/Core> #include "vtkFromO3dCommon.hpp" namespace vtko3d {
vtkSmartPointer<vtkPolyData> toCloudPolyData(const open3d::geometry::PointCloud& cloud, USEVALUE usedata=POINT_RGB) { // 頂点配列 vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New(); // 色情報の配列 vtkSmartPointer<vtkDoubleArray> colors = vtkSmartPointer<vtkDoubleArray>::New(); colors->SetNumberOfComponents(3); colors->SetName("Colors"); auto normals = vtkSmartPointer<vtkDoubleArray>::New(); normals->SetNumberOfComponents(3); // x, y, z normals->SetName("Normals"); // 頂点インデクスの配列 vtkSmartPointer<vtkCellArray> cells = vtkSmartPointer<vtkCellArray>::New(); for (size_t i = 0; i < cloud.points_.size(); i++) { double x = cloud.points_[i].x(); double y = cloud.points_[i].y(); double z = cloud.points_[i].z(); points->InsertNextPoint(x, y, z); // 座標追加 if (usedata & POINT_RGB) { double r = cloud.colors_[i].x(); double g = cloud.colors_[i].y(); double b = cloud.colors_[i].z(); colors->InsertNextTuple3(r, g, b); // 色情報追加 } if (usedata & POINT_NORMAL) { double nx = cloud.normals_[i].x(); double ny = cloud.normals_[i].y(); double nz = cloud.normals_[i].z(); normals->InsertNextTuple3(nx, ny, nz); // 法線ベクトル追加 } cells->InsertNextCell(1); // 要素数 cells->InsertCellPoint(i); // 頂点インデックスを追加 } // --- vtkPolyData作成 --- auto polydata = vtkSmartPointer<vtkPolyData>::New(); polydata->SetPoints(points); polydata->SetVerts(cells); if (usedata & POINT_RGB) { polydata->GetPointData()->SetScalars(colors); } if (usedata & POINT_NORMAL) { polydata->GetPointData()->SetNormals(normals); } return polydata; }
vtkSmartPointer<vtkActor> toCloudActor(vtkSmartPointer<vtkPolyDataMapper> mapper, int point_size = 1,std::optional< std::array<double, 3> > single_color = std::nullopt) { auto actor = vtkSmartPointer<vtkActor>::New(); if (single_color.has_value()) { mapper->SetScalarVisibility(false); // 頂点ごとの色情報を無視 } actor->SetMapper(mapper); if (mapper->GetScalarVisibility() == false) { if (single_color.has_value()) { actor->GetProperty()->SetColor(single_color.value()[0], single_color.value()[1], single_color.value()[2]); // 単色(R, G, B)を指定 } } actor->GetProperty()->SetPointSize(point_size); // 頂点サイズを5に設定(ピクセル単位) actor->GetProperty()->SetLighting(false); return actor; }
std::shared_ptr<open3d::geometry::PointCloud> createSampleCloud() { auto pointcloud = std::make_shared<open3d::geometry::PointCloud>(); for (size_t i = 0; i < 100000; i++) { double x = (double)rand() / (double)RAND_MAX; double y = (double)rand() / (double)RAND_MAX; double z = (double)rand() / (double)RAND_MAX; pointcloud->points_.emplace_back(x, y, z); // 座標追加 pointcloud->colors_.emplace_back(x, y, z); // 色情報追加 pointcloud->normals_.emplace_back(x, y, z); // 法線ベクトル追加 } return pointcloud; }
}
auto cloud = vtko3d::createSampleCloud(); auto polyData = vtko3d::toCloudPolyData(*cloud, vtko3d::POINT_RGB); auto mapper = vtko3d::toMapper(polyData); auto actor = vtko3d::toCloudActor(mapper,3);
open3dのメッシュを可視化するためのコードを纏めておく。
#pragma once #include <vtkTriangle.h> #include <vtkProperty.h> #include <vtkActor.h> #include <open3d/Open3D.h> #include <open3d/geometry/PointCloud.h> #include <Eigen/Core> #include "vtkFromO3dCommon.hpp" namespace vtko3d {
vtkSmartPointer<vtkPolyData> toMeshPolyData(const open3d::geometry::TriangleMesh& mesh, USEVALUE usedata, bool withpoints = false) { vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New(); vtkSmartPointer<vtkCellArray> triangles = vtkSmartPointer<vtkCellArray>::New(); vtkSmartPointer<vtkCellArray> vertices = vtkSmartPointer<vtkCellArray>::New(); // 色情報の配列 vtkSmartPointer<vtkDoubleArray> colors = vtkSmartPointer<vtkDoubleArray>::New(); colors->SetNumberOfComponents(3); colors->SetName("Colors"); vtkSmartPointer<vtkDoubleArray> normals = vtkSmartPointer<vtkDoubleArray>::New(); normals->SetNumberOfComponents(3); normals->SetName("Normals"); for (size_t i = 0; i < mesh.vertices_.size(); ++i) { double x = mesh.vertices_[i].x(); double y = mesh.vertices_[i].y(); double z = mesh.vertices_[i].z(); vtkIdType pid = points->InsertNextPoint(x, y, z); if (withpoints) { vertices->InsertNextCell(1, &pid); } if (usedata & POINT_RGB) { double r = mesh.vertex_colors_[i].x(); double g = mesh.vertex_colors_[i].y(); double b = mesh.vertex_colors_[i].z(); colors->InsertNextTuple3(r, g, b); // 色情報追加 } if (usedata & POINT_NORMAL) { double nx = mesh.vertex_normals_[i].x(); double ny = mesh.vertex_normals_[i].y(); double nz = mesh.vertex_normals_[i].z(); normals->InsertNextTuple3(nx, ny, nz); } } ////////////////////////////////////////////////////////////////////// for (size_t i = 0; i < mesh.triangles_.size(); ++i) { size_t p1 = mesh.triangles_[i](0); size_t p2 = mesh.triangles_[i](1); size_t p3 = mesh.triangles_[i](2); // 三角形1 (p1, p2, p3) vtkSmartPointer<vtkTriangle> tri = vtkSmartPointer<vtkTriangle>::New(); tri->GetPointIds()->SetId(0, p1); tri->GetPointIds()->SetId(1, p2); tri->GetPointIds()->SetId(2, p3); triangles->InsertNextCell(tri); } // vtkPolyData の作成 vtkSmartPointer<vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New(); polyData->SetPoints(points); if (withpoints) { polyData->SetVerts(vertices); } polyData->SetPolys(triangles); // 三角形セルを設定 if(usedata & POINT_RGB) { polyData->GetPointData()->SetScalars(colors); } if (usedata & POINT_NORMAL) { polyData->GetPointData()->SetNormals(normals); } return polyData; }
struct wireframe_option { bool show_faces = false; float line_width = 1.2f; std::array<double, 3> line_color = { 1.0, 1.0, 1.0 }; };
vtkSmartPointer<vtkActor> toMeshActor( vtkSmartPointer<vtkPolyDataMapper> mapper, bool usephong=false, std::optional<wireframe_option> wireopt = std::nullopt, std::optional< std::array<double, 3> > single_color = std::nullopt, int point_size = 5 ) { vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New(); actor->SetMapper(mapper); if (single_color.has_value()) { actor->GetProperty()->SetColor(single_color.value()[0], single_color.value()[1], single_color.value()[2]); } else { actor->GetProperty()->SetColor(1.0, 1.0, 1.0); // デフォルトは白色 } vtkPolyData* poly = mapper->GetInput(); if (poly->GetVerts()->GetNumberOfCells() > 0) { actor->GetProperty()->SetPointSize(point_size); // 点のサイズを設定 } if (usephong) { actor->GetProperty()->SetInterpolationToPhong(); // またはSetInterpolationToGouraud() } if (wireopt.has_value()) { if (wireopt->show_faces) { actor->GetProperty()->SetRepresentationToSurface(); actor->GetProperty()->EdgeVisibilityOn(); actor->GetProperty()->SetEdgeColor( wireopt->line_color.data() ); // エッジ色 actor->GetProperty()->SetLineWidth(wireopt->line_width); } else { actor->GetProperty()->SetRepresentationToWireframe(); actor->GetProperty()->SetLineWidth(wireopt->line_width); actor->GetProperty()->SetLighting(false); actor->GetProperty()->BackfaceCullingOff(); actor->GetProperty()->FrontfaceCullingOff(); } } return actor; }
// テスト用のメッシュを作成 std::shared_ptr<open3d::geometry::TriangleMesh> createSampleMesh() { std::shared_ptr<open3d::geometry::TriangleMesh> mesh = std::make_shared<open3d::geometry::TriangleMesh>(); int xcount = 20; int ycount = 20; float width = 1.0f; float height = 1.0f; float depth = 0.1f; float density = 10.0f; // 頂点の登録 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; mesh->vertices_.emplace_back(x, y, z); mesh->vertex_colors_.emplace_back(x + 0.5, y + 0.5, z + 0.5); } } // メッシュ(三角形)の作成 for (int i = 0; i < xcount - 1; ++i) { for (int j = 0; j < ycount - 1; ++j) { // 四角形を2つの三角形に分割 int p1 = i * ycount + j; // 左下 int p2 = (i + 1) * ycount + j; // 右下 int p3 = i * ycount + (j + 1); // 左上 int p4 = (i + 1) * ycount + (j + 1); // 右上 mesh->triangles_.emplace_back(Eigen::Vector3i(p1, p2, p3)); mesh->triangles_.emplace_back(Eigen::Vector3i(p2, p4, p3)); } } return mesh; } }
#pragma once #include <vtkSmartPointer.h> #include <vtkPolyData.h> #include <vtkPolyDataMapper.h> namespace vtko3d { enum USEVALUE { POINT_XYZ = 0b0001, POINT_RGB = 0b0010, POINT_NORMAL = 0b0100, POINT_RGBNORMAL = POINT_RGB | POINT_NORMAL, }; vtkSmartPointer<vtkPolyDataMapper> toMapper(vtkSmartPointer<vtkPolyData> polydata) { auto mapper = vtkSmartPointer<vtkPolyDataMapper>::New(); mapper->SetInputData(polydata); return mapper; } }
auto mesh = vtko3d::createSampleMesh(); mesh->ComputeVertexNormals(); // 法線ベクトルを計算 auto polyData = vtko3d::toMeshPolyData(*mesh, vtko3d::POINT_RGBNORMAL,false); auto mapper = vtko3d::toMapper(polyData); auto actor = vtko3d::toMeshActor(mapper, true, vtko3d::wireframe_option{ false }); auto renderer = vtkSmartPointer<vtkRenderer>::New(); renderer->AddActor(actor);
動作を中断して状況を見たいが、ブレークポイントなどでプログラムそのものを中断すると出力コードも動かなくて困る。デバッグしたい処理をスレッドで動かし、セマフォを使うことで任意の場所で中断・再開できるらしい。
#include <iostream> #include <semaphore> #include <atomic> #include <thread>
class MyBreakPoint { std::binary_semaphore gate{ 0 }; // 許可は最大1に飽和 std::atomic<bool> run_free{ false }; // trueで連続実行 public: // 停止点: run_free=false のときだけ待つ void BreakPoint() { if (run_free.load(std::memory_order_acquire)) return; gate.acquire(); } // 次のBreakPointまで進める void ContinueToNextBreak() { gate.release(); } // 以後ブレーク無視 void RunFree() { run_free.store(true, std::memory_order_release); gate.release(); // 既に待っていれば抜ける } // 以後BreakPointで停止 void PauseAtBreak() { run_free.store(false, std::memory_order_release); // 残っている許可を掃き出し、次回は必ず止まる while (gate.try_acquire()) { /* drain */ } } };
void worker(MyBreakPoint& pauser) { for (int i = 0; i < 100; ++i) { // 処理本体 std::cout << i << std::endl; if (i % 5 == 0) { std::cout << "i % 5 == 0" << std::endl; pauser.BreakPoint(); // ブレークポイント } // 動作を見るための速度調節 std::this_thread::sleep_for(std::chrono::milliseconds(100)); } std::cout << "done" << std::endl; }
int main() { MyBreakPoint poser; std::thread th(worker, std::ref(poser)); // ユーザー入力でデバッグ操作 for (char c; std::cin >> c; ) { if (c == 'c') poser.ContinueToNextBreak();// 次にBreakPointが呼ばれるまで実行 else if (c == 'r') poser.RunFree();// 以後BreakPointを無視 else if (c == 'p') poser.PauseAtBreak();// 以後BreakPointが呼ばれたら止まる } th.join(); }
MFCを使う機会が増えそうになってきた。CStringで正規表現する方法を調べたがATL,MFCには(今はもう)無いらしく、C++標準のstd::regexを使うのが一番いいらしい。
// AfxMessageBox #include <afxwin.h> // CString #include <atlstr.h> #include <string> #include <regex> #ifdef _UNICODE using tregex = std::wregex; using tmatch = std::wcmatch; #else using tregex = std::regex; using tmatch = std::cmatch; #endif int main() { CString text = _T("Hello, 123 こんにちは"); #ifdef _UNICODE CString cset= _T(" (UNICODE)"); #else CString cset= _T(" (MULTIBYTE)"); #endif tregex re(_T("こん.*")); tmatch match; if (std::regex_search( LPCTSTR(text), match, re)) { int length = (int)(match[0].second - match[0].first); CString result(match[0].first, length); AfxMessageBox(result + cset); } }
自分で導入したvcpkg installをコマンドプロンプトから実行して以下のエラーに遭遇
error: Could not locate a manifest (vcpkg.json) above the current working directory.
This vcpkg distribution does not have a classic mode instance.
これは自分で導入したvcpkgを実行したつもりで、実はVisual Studioが管理しているvcpkgが実行された場合に起こるらしい。具体的には
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvars64.bat
などでVisual Studioの環境を設定した場合、且つ、環境変数などで自前のvcpkgのパスを通していた場合に起こる可能性がある。
つまり、vcvars64.batが環境を整備しているときに、Visual Studio以外で導入したvcpkgの存在が確認できた時、これを有効にしてしまうとVisual Studioのvcpkgを使っているつもりなのに異なるvcpkgを操作してしまったということが起こり得てしまいまずいので、強制的にVS用のvcpkgに上書きされる。
この上書きはdoskeyというコマンドで行われるらしい。以下の確認用コマンドで、もし
の結果が
などであれば、vcpkgのパスが上書きされているので、以下を実行してこの設定を消す。