ここでは, 体積要素ではなく, 体積要素の境界にある面積要素のデータを構築する手法を説明します.詳細はXCodeでVTK楽園を参照
基本は先ほどと同じです.
フォルダー指定等
// 時間ステップ{{{
unsigned int ntMax=100;
boost::filesystem::path bodyFolder("myBody");
boost::filesystem::path wallFolder("myWall"); // stemNameを下にするなら, 同フォルダーでいいかもしれないが,まあいいぢゃん
std::string bodyStemName="body"; // ファイル名は folderName/stemName時間ステップ(N桁の数字)extName
std::string wallStemName="wall"; // ファイル名は folderName/stemName時間ステップ(N桁の数字)extName
std::string extName=".vtm";
int fileN=4;
//}}}
// フォルダーを作成{{{
try
{
// 既存は削除
if (boost::filesystem::exists(bodyFolder)) boost::filesystem::remove_all(bodyFolder);
if (boost::filesystem::exists(wallFolder)) boost::filesystem::remove_all(wallFolder);
boost::filesystem::create_directory(bodyFolder);
boost::filesystem::create_directory(wallFolder);
}
catch (std::exception& e)
{
std::cerr << bodyFolder << "フォルダあるいは" << wallFolder << "がエラー:" << e.what() << std::endl;
return 1;
}//}}}
領域定義の部分
// 時間ステップだけ作業する
for(unsigned int nt=1;nt<=ntMax;nt++)
{
vtkSmartPointer<vtkMultiBlockDataSet> body=vtkSmartPointer<vtkMultiBlockDataSet>::New();
vtkSmartPointer<vtkMultiBlockDataSet> wall=vtkSmartPointer<vtkMultiBlockDataSet>::New();
// 領域達を定義 {{{
for(int idom=0;idom<2;idom++)
{
double imageSpacing[3]={0.05,0.05,0.05};
int imageExtent[6]={0,0,0,0,0,0};
double imageOrigin[3]={0.,0.,0.};
+---- 60 行:本体を定義-------------------------------------------------------------------------------------------------------------------------------------------
+---- 78 行:境界達を定義-----------------------------------------------------------------------------------------------------------------------------------------
std::cout << "作製:" << idom << std::endl;
}//}}}
本体を定義
for(int idom=0;idom<2;idom++)
{
double imageSpacing[3]={0.05,0.05,0.05};
int imageExtent[6]={0,0,0,0,0,0};
double imageOrigin[3]={0.,0.,0.};
// 本体を定義{{{
{
// 本体の形状を定義{{{
typedef vtkSmartPointer<vtkImageData> ImageDataPtr;
ImageDataPtr image=ImageDataPtr::New();
image->SetSpacing(imageSpacing);
switch (idom)
{
case 0: // 領域0 0,0.05,0.10
imageExtent[1]=20; imageExtent[3]=10; imageExtent[5]=10;
imageOrigin[0]=0; imageOrigin[1]=0; imageOrigin[2]=0;
break;
;;
case 1: // 領域1
imageExtent[1]=10; imageExtent[3]=40; imageExtent[5]=40;
imageOrigin[0]=1; imageOrigin[1]=-0.5; imageOrigin[2]=-0.5;
break;
;;
}
image->SetExtent(imageExtent);
image->SetOrigin(imageOrigin);
body->SetBlock(idom,image);
//}}}
+----- 35 行:本体の物理量を定義 ---------------------------------------------------------------------------------------------------------------------------------
}
+---- 63 行:境界達を定義 -----------------------------------------------------------------------------------------------------------------------------------------
std::cout << "作製:" << idom << std::endl;
}//}}}
境界たちを定義
// 境界達を定義{{{
for(int iwall=0;iwall<6;iwall++)
{
typedef vtkSmartPointer<vtkImageData> ImageDataPtr;
ImageDataPtr image=ImageDataPtr::New();
image->SetSpacing(imageSpacing);
int wimageExtent[6]; for(int iii=0;iii<6;iii++) wimageExtent[iii]=imageExtent[iii];
double wimageOrigin[3]; for(int iii=0;iii<3;iii++) wimageOrigin[iii]=imageOrigin[iii];
std::string name;
switch (iwall)
{
case 0: // 左側面:X幅がない
wimageExtent[1]=wimageExtent[0]=0; name="left";break;;
case 1: // 右側面:X幅がない & 原点がずれる
wimageExtent[0]=wimageExtent[1];name="right"; break;;
case 2: // 下側面:Y幅がない
wimageExtent[3]=wimageExtent[2];name="floor"; break;;
case 3: // 上側面:Y幅がない
wimageExtent[2]=wimageExtent[3];name="ceiling"; break;;
case 4: // 奥側面:Z幅がない
wimageExtent[5]=wimageExtent[4];name="away"; break;;
case 5: // 前側面:Z幅がない
wimageExtent[4]=wimageExtent[5];name="home"; break;;
}
image->SetExtent(wimageExtent);
image->SetOrigin(wimageOrigin);
int iBL=6*idom+iwall;
wall->SetBlock(iBL,image);
wall->GetMetaData(iBL)->Set(vtkImageData::NAME(),name.c_str()); // イメージに名前を付ける
+----- 35 行:境界面の物理量を定義 -------------------------------------------------------------------------------------------------------------------------------
}
動作
上記のプログラムでは, myBody.vtm が本体の体積要素のデータを, myWall.vtmに境界の面積要素のデータが入る. 境界の面積要素データは, 各領域・各境界の壁面が別々のデータとして入る.場合によっては,選択を行うときに困難かもしれないが,これはMultiDataSetのツリー構成を各自工夫すればよい.