自学内容网 自学内容网

使用C#开发VTK笔记(四)-创建文字及坐标轴导入点云

一.使用VTK创建文字

继续上一章节,演示一下文字及坐标轴创建,然后用vtkSTLReader 导入点云。

1.创建2D文字

在窗口中创建平面文字需要用到vtkTextActor ,它的坐标通过x,y输入,起始点0,0在窗口左下角。
大小通过SetFontSize设定,文字内容通过SetInput设置。

vtkRenderer xRenderer = GetVtkRenderer();
int FontSize = 50;
string strText = "Hello World!";
int x = 10;
int y = 20; 
vtkTextActor textActor = vtkTextActor.New();
textActor.GetTextProperty().SetFontSize(FontSize);
//设置字体大小,以点为单位
textActor.SetDisplayPosition(x, y);
//设置道具在2D显示坐标系中的位置。
textActor.GetTextProperty().SetColor(1, 0, 1);
//设置文本颜色
textActor.SetInput(strText);
//设置要显示的文本字符串。“\n”被识别为回车/换行符(行分隔符)。
//字符必须采用ISO-8859-1编码。底层映射器的便捷方法
textActor.GetTextProperty().SetBold(1);
//启用/禁用文本粗体显示。
textActor.GetTextProperty().SetItalic(1);
//启用/禁用文本斜体。
textActor.GetTextProperty().SetShadow(1);
//启用/禁用文本阴影。 
xRenderer.AddActor(textActor);
xRenderer.GetRenderWindow().Render();
MessageBox.Show("创建完成!");

显示效果如下:
在这里插入图片描述

2.创建3D跟随文字

上面的文字,始终是在二维平面显示的,用来做界面的一些文字提示是不错的,但是如果想要动态的显示比如坐标点的位置,
这种就不行了。这时我们需要创建三维文字。

  vtkRenderer xRenderer = GetVtkRenderer();
  vtkPoints vPoints = new vtkPoints();
  vtkCellArray vCellArray = new vtkCellArray();

  //插入点,1是序号,后面是xyz
  //vtkPoints可以放很多点,不管是一个还是多个,都要转换为PolyData的Vert顶点才能显示
  //vCellArray.Initialize();
  double[][] inputPoints = [[0, 0, 20], [0, 20, 0], [20, 0, 0]];
  int n = inputPoints.Length;

  vtkVectorText[] vTexts = new vtkVectorText[n] ;
  vtkFollower[] txtActors = new vtkFollower[n] ;
  vtkPolyDataMapper[] vMapperPtCoords = new vtkPolyDataMapper[n];
  for (int i = 0; i < n; i++)
  {
      long PointId = vPoints.InsertNextPoint(inputPoints[i][0], inputPoints[i][1], inputPoints[i][2]);
      //顶点序列以1步进
      vCellArray.InsertNextCell(1);
      vCellArray.InsertCellPoint(PointId);

      string strXYZ = inputPoints[i][0].ToString("0.000") + "," + inputPoints[i][1].ToString("0.000") + "," + inputPoints[i][2].ToString("0.000");
      //建立每个点的坐标文本并加入渲染器
      vTexts[i] = new vtkVectorText(); 
      vTexts[i].SetText(strXYZ);
      vMapperPtCoords[i] = new vtkPolyDataMapper();
      vMapperPtCoords[i].SetInputConnection(vTexts[i].GetOutputPort());
      txtActors[i]=new vtkFollower ();
      txtActors[i].SetMapper(vMapperPtCoords[i]);
      txtActors[i].SetPosition(inputPoints[i][0], inputPoints[i][1], inputPoints[i][2]);
      //txtActors[i].SetScale(0.2, 0.2, 0.2);
      xRenderer.AddActor(txtActors[i]);
  }

  //每个点加入渲染器
  vtkPolyData polyData = new vtkPolyData();
  polyData.SetPoints(vPoints);
  polyData.SetVerts(vCellArray);

  vtkPolyDataMapper vMapper = new vtkPolyDataMapper();
  vMapper.SetInputData(polyData);
  vtkActor vptActor = new vtkActor();

  vptActor.GetProperty().SetColor((float)255 / 255, (float)255 / 255, (float)0 / 255);
  vptActor.GetProperty().SetPointSize(10);
  vptActor.SetMapper(vMapper);
  xRenderer.AddActor(vptActor);
  xRenderer.ResetCamera();
  xRenderer.GetRenderWindow().Render();
  MessageBox.Show("创建完成!");

在原有的那三个点程序上改一下,加上跟随的3D坐标位置就可以了,效果如下所示。很不错。
在这里插入图片描述

二.增加坐标轴控件

在系统中创建坐标轴控件,坐标轴带有交互作用。

  //创建坐标轴
  vtkAxesActor axes = vtkAxesActor.New();
  vtkRenderer xRenderer = GetVtkRenderer();
  axes.SetXAxisLabelText("X");
  axes.SetYAxisLabelText("Y");
  axes.SetZAxisLabelText("Z");
        
  axes.SetTotalLength(10, 10, 10);  //设置箭头长度
  axes.SetShaftTypeToCylinder();// 设置箭头形状

  //在3维坐标系中设置各轴的长度。
  axes.SetOrigin(0, 0, 0);
  //axes.AxisLabelsOff();
  //禁用绘制轴标签。
  xRenderer.AddActor(axes);
  vtkCamera camera = xRenderer.GetActiveCamera();
  //camera.Zoom(1.5);
  xRenderer.ResetCamera();
  xRenderer.GetRenderWindow().Render();
  MessageBox.Show("创建完成!");

效果如下:
在这里插入图片描述

三.使用VTK导入点云

1.导入Stl格式点云

  OpenFileDialog dlg = new OpenFileDialog();
  dlg.RestoreDirectory = true;
  dlg.FilterIndex = 1;
  dlg.Filter = "点云文件(*.stl)|*.stl";
  if (dlg.ShowDialog() == DialogResult.OK)
  {
      string fName = dlg.FileName;
      if (!File.Exists(fName))
      {
          MessageBox.Show("文件路径不存在!", "文件错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
          return;
      }
vtkSTLReader sTLReader = new vtkSTLReader();
sTLReader.SetFileName(fName);
vtkPolyDataMapper mapper = vtkPolyDataMapper.New();
mapper.SetInputConnection(sTLReader.GetOutputPort());
vtkActor actor = vtkActor.New();
actor.SetMapper(mapper);

  vtkRenderer render =renderWindowControl.RenderWindow.GetRenderers().GetFirstRenderer();
  Color color = App_VirtualMc.App_Vtk.GetRandomPartColor();
  actor.GetProperty().SetColor(0, 1, 0);
  render.AddActor(actor); /* 开始显示 */
  render.ResetCamera();
  renderWindowControl.Refresh();

加载显示还是比较快的,不过需要注意的是sTLReader.SetFileName(fName)这个里面的文件名和路径不能存在中文,否则就会崩溃。原因是由于sTLReader派生自vtkAbstractPolyDataReader,使用的这个方法
vtkAbstractPolyDataReader_SetFileName_08(HandleRef pThis, string _arg)指向的是一个半角字符串,全角的中文会出现乱码导致崩溃。这个问题暂时无法解决。
这是官方Samples的一个Stl文件。
在这里插入图片描述
在这里插入图片描述
其它格式点云或者数据文件没有尝试,如果系统支持的,同样的方法使用reader进行读取显示就可以了。


原文地址:https://blog.csdn.net/qq_43662503/article/details/144160932

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!