【VTK-Rendering::Annotation】第一期 vtkCaptionActor2D

很高兴在雪易的CSDN遇见你 

VTK技术爱好者 QQ:870202403


前言

本文分享vtkCaptionActor2D源码解析,希望对各位小伙伴有所帮助!

感谢各位小伙伴的点赞+关注,小易会继续努力分享,一起进步!

你的点赞就是我的动力(^U^)ノ~YO


目录

前言

1. vtkCaptionActor2D概述

2. 重要参数

2.1 定义标注文本

2.2 设置标注附着点

2.3 设置是否启用边框 

2.4 设置是否启用标注到附着点的引导线

2.5 指定2D或3D箭头

2.6 设置文本与包围盒的距离

2.7 设置文本属性

 2.8 设置箭头是否在Edge上附着 

3. 原理解析

3.1 vtkBorderRepresentation原理解析

结论:


1. vtkCaptionActor2D概述

        vtkCaptionActor2D是一个2DActor和3DActor混合的对象,用于将文本与场景中的点(AttachmentPoint)相关联。可以使用矩形边框和将标题连接到附着点的引线来绘制标题。可选地,可以在leader的端点处对其进行符号化,以创建箭头或其他指示符。

        使用vtkCaptionActor2D时,必须指定Position和Position2两个点。Position和Position2定义标题的大小,AttachmentPoint定义标题所关联的点。还必须定义标题文本、是否希望在标题周围设置边框,以及是否希望在标题到附件点之间设置一个引线。

        文本的属性通过关联的vtkTextProperty进行设置。引线可以设置为2D或3D。(2D绘制在底层几何上,3D三维引线可能被几何遮挡。)

2. 重要参数

2.1 定义标注文本

  //@{
  /**
   * Define the text to be placed in the caption. The text can be multiple
   * lines (separated by "\n").
   * 定义标注的文本,文本可以多行(通过"\n"进行分隔)
   */
  virtual void SetCaption(const char* caption);
  virtual char* GetCaption();
  //@}

2.2 设置标注附着点

  //@{
  /**
   * Set/Get the attachment point for the caption. By default, the attachment
   * point is defined in world coordinates, but this can be changed using
   * vtkCoordinate methods.
   * 设置标注的附着点,默认为世界坐标系。可以通过vtkCoordinate的方法进行更改
   */
  vtkWorldCoordinateMacro(AttachmentPoint);
  //@}

2.3 设置是否启用边框 

  //@{
  /**
   * Enable/disable the placement of a border around the text.
   * 可用/不可用文本外的包围框
   */
  vtkSetMacro(Border, vtkTypeBool);
  vtkGetMacro(Border, vtkTypeBool);
  vtkBooleanMacro(Border, vtkTypeBool);
  //@}

2.4 设置是否启用标注到附着点的引导线

  //@{
  /**
   * Enable/disable drawing a "line" from the caption to the
   * attachment point.
   * 可用/不可用 标注到附着点的线
   */
  vtkSetMacro(Leader, vtkTypeBool);
  vtkGetMacro(Leader, vtkTypeBool);
  vtkBooleanMacro(Leader, vtkTypeBool);
  //@}

2.5 指定2D或3D箭头

  //@{
  /**
   * Indicate whether the leader is 2D (no hidden line) or 3D (z-buffered).
   * 指定箭头为2D或3D
   */
  vtkSetMacro(ThreeDimensionalLeader, vtkTypeBool);
  vtkGetMacro(ThreeDimensionalLeader, vtkTypeBool);
  vtkBooleanMacro(ThreeDimensionalLeader, vtkTypeBool);
  //@}

  //@{
  /**
   * Specify a glyph to be used as the leader "head". This could be something
   * like an arrow or sphere. If not specified, no glyph is drawn. Note that
   * the glyph is assumed to be aligned along the x-axis and is rotated about
   * the origin. SetLeaderGlyphData() directly uses the polydata without
   * setting a pipeline connection. SetLeaderGlyphConnection() sets up a
   * pipeline connection and causes an update to the input during render.
   * 设置箭头的头部输入数据
   */
  virtual void SetLeaderGlyphData(vtkPolyData*);
  virtual void SetLeaderGlyphConnection(vtkAlgorithmOutput*);
  virtual vtkPolyData* GetLeaderGlyph();
  //@}

  //@{
  /**
   * Specify the relative size of the leader head. This is expressed as a
   * fraction of the size (diagonal length) of the renderer. The leader
   * head is automatically scaled so that window resize, zooming or other
   * camera motion results in proportional changes in size to the leader
   * glyph.
   * 设置箭头符号的大小
   */
  vtkSetClampMacro(LeaderGlyphSize, double, 0.0, 0.1);
  vtkGetMacro(LeaderGlyphSize, double);
  //@}

  //@{
  /**
   * Specify the maximum size of the leader head (if any) in pixels. This
   * is used in conjunction with LeaderGlyphSize to cap the maximum size of
   * the LeaderGlyph.
   * 像素上设置箭头符号的最大像素值
   */
  vtkSetClampMacro(MaximumLeaderGlyphSize, int, 1, 1000);
  vtkGetMacro(MaximumLeaderGlyphSize, int);
  //@}

2.6 设置文本与包围盒的距离

  //@{
  /**
   * Set/Get the padding between the caption and the border. The value
   * is specified in pixels.
   * 设置/获取标注文本和包围框之间的距离
   */
  vtkSetClampMacro(Padding, int, 0, 50);
  vtkGetMacro(Padding, int);
  //@}

  //@{
  /**
   * Get the text actor used by the caption. This is useful if you want to control
   * justification and other characteristics of the text actor.
   * 获取文本Actor对象
   */
  vtkGetObjectMacro(TextActor, vtkTextActor);
  //@}

2.7 设置文本属性

  //@{
  /**
   * Set/Get the text property.
   * 设置文本的属性
   */
  virtual void SetCaptionTextProperty(vtkTextProperty* p);
  vtkGetObjectMacro(CaptionTextProperty, vtkTextProperty);
  //@}

 2.8 设置箭头是否在Edge上附着 

  //@{
  /**
   * Enable/disable whether to attach the arrow only to the edge,
   * NOT the vertices of the caption border.
   * 箭头在包围框上的附着点;若为On时,表示附着点考虑包围框四个边的中点;否则不考虑
   */
  vtkSetMacro(AttachEdgeOnly, vtkTypeBool);
  vtkGetMacro(AttachEdgeOnly, vtkTypeBool);
  vtkBooleanMacro(AttachEdgeOnly, vtkTypeBool);
  //@}

3. 原理解析

3.1 vtkBorderRepresentation原理解析

        定义一个矩形,左下角点为(0.,0.,0.),右上角点为(1.,1.,0.)。

        定义由这四个点组成的矩形边界的PolyData数据

  // Create the geometry in canonical coordinates
  this->BWPoints = vtkPoints::New();
  this->BWPoints->SetDataTypeToDouble();
  this->BWPoints->SetNumberOfPoints(4);
  this->BWPoints->SetPoint(0, 0.0, 0.0, 0.0); // may be updated by the subclass
  this->BWPoints->SetPoint(1, 1.0, 0.0, 0.0);
  this->BWPoints->SetPoint(2, 1.0, 1.0, 0.0);
  this->BWPoints->SetPoint(3, 0.0, 1.0, 0.0);

  vtkCellArray* outline = vtkCellArray::New();
  outline->InsertNextCell(5);
  outline->InsertCellPoint(0);
  outline->InsertCellPoint(1);
  outline->InsertCellPoint(2);
  outline->InsertCellPoint(3);
  outline->InsertCellPoint(0);

  this->BWPolyData = vtkPolyData::New();
  this->BWPolyData->SetPoints(this->BWPoints);
  this->BWPolyData->SetLines(outline);
  outline->Delete();

        给PolyData数据添加Transform变换,并将其映射为actor2D 数据。

  this->BWTransform = vtkTransform::New();
  this->BWTransformFilter = vtkTransformPolyDataFilter::New();
  this->BWTransformFilter->SetTransform(this->BWTransform);
  this->BWTransformFilter->SetInputData(this->BWPolyData);

  this->BWMapper = vtkPolyDataMapper2D::New();
  this->BWMapper->SetInputConnection(this->BWTransformFilter->GetOutputPort());
  this->BWActor = vtkActor2D::New();
  this->BWActor->SetMapper(this->BWMapper);

  this->BorderProperty = vtkProperty2D::New();
  this->BWActor->SetProperty(this->BorderProperty);

        通过两个vtkCoordinate对象约束矩形的左下角点和右上角点。

  this->PositionCoordinate = vtkCoordinate::New();
  this->PositionCoordinate->SetCoordinateSystemToNormalizedViewport();
  this->PositionCoordinate->SetValue(0.05, 0.05);
  this->Position2Coordinate = vtkCoordinate::New();
  this->Position2Coordinate->SetCoordinateSystemToNormalizedViewport();
  this->Position2Coordinate->SetValue(0.1, 0.1); // may be updated by the subclass
  this->Position2Coordinate->SetReferenceCoordinate(this->PositionCoordinate);

        在每次Render的时候,获取当前的Display坐标对原始PolyData数据进行Transform,即可看到一个一直处于视平面的矩形框。

    // Set things up
    int* pos1 = this->PositionCoordinate->GetComputedViewportValue(this->Renderer);
    int* pos2 = this->Position2Coordinate->GetComputedViewportValue(this->Renderer);

    // If the widget's aspect ratio is to be preserved (ProportionalResizeOn),
    // then (pos1,pos2) are a bounding rectangle.
    if (this->ProportionalResize)
    {
    }

    // Now transform the canonical widget into display coordinates
    double size[2];
    this->GetSize(size);
    double tx = pos1[0];
    double ty = pos1[1];
    double sx = (pos2[0] - pos1[0]) / size[0];
    double sy = (pos2[1] - pos1[1]) / size[1];

    this->BWTransform->Identity();
    this->BWTransform->Translate(tx, ty, 0.0);
    this->BWTransform->Scale(sx, sy, 1);

    this->BuildTime.Modified();

保持位置不变的原因:每次旋转或移动渲染窗口时,都重新获取两个vtkCoordinate对象的ViewPort坐标系下的坐标,并对其进行重新绘制。 

3.2 vtkCaptionActor2D

结论:

感谢各位小伙伴的点赞+关注,小易会继续努力分享,一起进步!

你的赞赏是我的最最最最大的动力(^U^)ノ~YO