流线图虽然能够表示出流体流动的轨迹,但没有箭头表示流动方向,似乎不太容易看出流动方向,可以使用生成矢量箭头的方法给流线上加一定箭头表示流动方向。生成矢量箭头的类是vtkGlyph3D。还是以之前读取的open foam后台阶算例为例,具体代码如下:
#include <vtkOpenFOAMReader.h>
#include <vtkSmartPointer.h>
#include <vtkAppendPolyData.h>
#include <vtkPolyDataMapper.h>
#include <vtkUnstructuredGrid.h>
#include <vtkProperty.h>
#include <vtkActor.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkInteractorStyleTrackballCamera.h>
#include <vtkMultiBlockDataSet.h>
#include <vtkPointData.h>
#include <vtkDataSetMapper.h>
#include <vtkScalarBarActor.h>
#include <vtkLookupTable.h>
#include <vtkTextProperty.h>
#include <vtkLineSource.h>
#include <vtkStreamTracer.h>
#include <vtkGlyph3D.h>
#include <vtkMaskPoints.h>
#include <vtkGlyphSource2D.h>
#include <vtkPolyData.h>
#include <vtkArrayCalculator.h>
#include <vtkAutoInit.h>
VTK_MODULE_INIT(vtkRenderingOpenGL2)
VTK_MODULE_INIT(vtkRenderingFreeType)
VTK_MODULE_INIT(vtkInteractionStyle)
int main()
{
vtkSmartPointer<vtkOpenFOAMReader> openFOAMReader = vtkSmartPointer<vtkOpenFOAMReader>::New();
openFOAMReader->SetFileName("D://xinjian//openfoam//pitzDaily//case.foam");//设置读取文件路径
openFOAMReader->SetCreateCellToPoint(1);
openFOAMReader->SetSkipZeroTime(1);//开启跳过0时刻
openFOAMReader->SetTimeValue(298.0);//设置需要读取的时刻
openFOAMReader->Update();
vtkUnstructuredGrid *block0 = vtkUnstructuredGrid::SafeDownCast(openFOAMReader->GetOutput()->GetBlock(0));
//设置生成流线的位置
vtkSmartPointer<vtkLineSource> line1 = vtkSmartPointer<vtkLineSource>::New();
line1->SetPoint1(-0.019,0.0254,0.0005);
line1->SetPoint2(-0.0206,0,0.0005);
line1->SetResolution(10);
line1->Update();
vtkSmartPointer<vtkStreamTracer> streamline = vtkSmartPointer<vtkStreamTracer>::New();
streamline->SetSourceConnection(line1->GetOutputPort());
streamline->SetInputData(block0);
streamline->SetIntegratorTypeToRungeKutta45();//设置流线的积分类型
streamline->SetMaximumPropagation(5000);//设置流线长度
streamline->SetIntegrationStepUnit(2);//设置流线积分步长单位
streamline->SetInitialIntegrationStep(0.2);//设置流线积分初始步长
streamline->SetMinimumIntegrationStep(0.01);//设置流线积分最小步长
streamline->SetMaximumIntegrationStep(0.5);//设置流线积分最大步长
streamline->SetMaximumNumberOfSteps(2000);//设置流线积分最大步数
streamline->SetIntegrationDirectionToBoth();//设置流线积分方向
streamline->SetTerminalSpeed(1e-12);//设置流线积分终止速度
streamline->SetMaximumError(1e-6);
streamline->Update();
//计算速度的模
vtkSmartPointer<vtkArrayCalculator> calc = vtkSmartPointer<vtkArrayCalculator>::New();
calc->SetInputConnection(streamline->GetOutputPort());
calc->AddVectorArrayName("U");
calc->SetFunction("mag(U)");
calc->SetResultArrayName("u_mag");
calc->Update();
vtkSmartPointer<vtkMaskPoints> maskPoints = vtkSmartPointer<vtkMaskPoints>::New();
maskPoints->SetInputConnection(calc->GetOutputPort());
maskPoints->SetRandomMode(1);
maskPoints->SetRandomModeType(2);
maskPoints->SetMaximumNumberOfPoints(50);
maskPoints->Update();
vtkSmartPointer<vtkGlyphSource2D> Glyph2d =
vtkSmartPointer<vtkGlyphSource2D>::New();//新建二维箭头类型指针
Glyph2d->SetScale(1);//设置二维箭头比例
Glyph2d->SetGlyphTypeToArrow();//设置箭头类型为箭头
Glyph2d->SetFilled(0);//关闭箭头填充
Glyph2d->SetOutputPointsPrecision(vtkAlgorithm::SINGLE_PRECISION);//设置箭头输出精度
Glyph2d->Update();
vtkSmartPointer<vtkGlyph3D> Glyph =
vtkSmartPointer<vtkGlyph3D>::New();//新建矢量指针
Glyph->SetSourceConnection(Glyph2d->GetOutputPort());//设置之前设置好的矢量箭头为矢量符号。
Glyph->SetInputConnection(maskPoints->GetOutputPort());//设置通过maskpoints过滤的点数据为输入数据。
Glyph->SetOrient(0);
Glyph->SetVectorMode(1);
Glyph->SetVectorModeToUseVector();
Glyph->SetScaleMode(1);//开启箭头比例缩放模式
Glyph->SetScaleModeToDataScalingOff();//关闭箭头随速度或者标量大小而变化
Glyph->SetScaleFactor(0.01);//控制箭头比例,大小
Glyph->SetColorMode(1);
Glyph->Update();
vtkPolyData *streamlinedata = vtkPolyData::SafeDownCast(calc->GetOutput());
streamlinedata->GetPointData()->SetActiveScalars("u_mag");
//计算速度范围
double scalarRange[2];
scalarRange[0] = streamlinedata->GetPointData()->GetScalars()->GetRange()[0];
scalarRange[1] = streamlinedata->GetPointData()->GetScalars()->GetRange()[1];
vtkSmartPointer<vtkScalarBarActor> scalarBar =
vtkSmartPointer<vtkScalarBarActor>::New();
vtkSmartPointer<vtkLookupTable> pColorTable =
vtkSmartPointer<vtkLookupTable>::New();
pColorTable->SetNumberOfTableValues(31);
pColorTable->SetHueRange(0.67, 0);//标量条颜色范围,从蓝到红
pColorTable->SetAlphaRange(1.0, 1.0);
pColorTable->SetValueRange(1, 1);
pColorTable->SetSaturationRange(1, 1);
pColorTable->SetRange(scalarRange);
pColorTable->Build();
scalarBar->SetTitle("U (m/s)");
scalarBar->GetTitleTextProperty()->SetColor(0, 0, 0);
scalarBar->GetTitleTextProperty()->SetFontFamilyToArial();
scalarBar->GetTitleTextProperty()->SetFontSize(20);
scalarBar->GetLabelTextProperty()->SetColor(0, 0, 0);
scalarBar->SetLabelFormat("%5.3f");
scalarBar->GetLabelTextProperty()->SetFontFamilyToArial();
scalarBar->GetLabelTextProperty()->SetFontSize(20);
scalarBar->SetNumberOfLabels(7);
scalarBar->SetUnconstrainedFontSize(1);
scalarBar->SetMaximumWidthInPixels(80);
scalarBar->SetMaximumHeightInPixels(900);
scalarBar->SetLookupTable(pColorTable);
vtkSmartPointer<vtkPolyDataMapper> streamlinemappper = vtkSmartPointer<vtkPolyDataMapper>::New();
streamlinemappper->SetInputData(streamlinedata);
streamlinemappper->SetLookupTable(pColorTable);
streamlinemappper->SetScalarRange(scalarRange);
vtkSmartPointer<vtkActor> streamlineactor = vtkSmartPointer<vtkActor>::New();
streamlineactor->SetMapper(streamlinemappper);
vtkSmartPointer<vtkPolyDataMapper> glyphmappper = vtkSmartPointer<vtkPolyDataMapper>::New();
glyphmappper->SetInputConnection(Glyph->GetOutputPort());
glyphmappper->SetLookupTable(pColorTable);
glyphmappper->SetScalarRange(scalarRange);
vtkSmartPointer<vtkActor> glyphactor = vtkSmartPointer<vtkActor>::New();
glyphactor->SetMapper(glyphmappper);
vtkSmartPointer<vtkRenderer> ren = vtkSmartPointer<vtkRenderer>::New();
ren->AddActor(streamlineactor);
ren->AddActor(glyphactor);
ren->AddActor(scalarBar);
ren->SetBackground(1,1,1);//设置背景色为白色
ren->ResetCamera();
vtkSmartPointer<vtkRenderWindow> renWin =
vtkSmartPointer<vtkRenderWindow>::New();
vtkSmartPointer<vtkRenderWindowInteractor> iren =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
iren->SetRenderWindow(renWin);
vtkSmartPointer<vtkInteractorStyleTrackballCamera> TrackballCamera =
vtkSmartPointer<vtkInteractorStyleTrackballCamera>::New();
iren->SetInteractorStyle(TrackballCamera);
renWin->AddRenderer(ren.GetPointer());
renWin->SetSize(500, 500);
renWin->Render();
iren->Initialize();
iren->Start();
最终显示流线图如下所示: