vtkBoxWidget

  vtkBoxWidget是一个正交六面体3D控件;这个3D小部件定义了一个感兴趣的区域,该区域由一个内表面角度为90度(正交面)的任意定向六面体表示。该对象创建了7个可在其上进行鼠标移动和操作的控制柄。前六个面对应六个面,第七个面在六面体的中心。此外,还显示了一个边界框轮廓,可以选择其“面”进行对象旋转或缩放。该对象的一个很好的特性是,vtkBoxWidget与任何3D小部件一样,将使用当前的interactior样式。也就是说,如果vtkBoxWidget不处理事件,那么所有其他注册的观察者(包括interactior样式)都有机会处理该事件。否则,vtkBoxWidget将终止对其处理的事件的处理。
  要使用此对象,只需使用vtkRenderWindowInteractior方法的参数调用SetInteractior()。如果还希望调用“PlaceWidget()”来初始定位小部件。在按下“i”键(表示“interactior”)之前,interactior将正常工作,此时vtkBoxWidget将出现(有关更改此行为的信息,请参阅超类文档。)通过抓住六个面控制柄(使用鼠标左键),可以移动面。通过抓住中心手柄(用鼠标左键),可以平移整个六面体(平移也可以通过使用小部件内部的“鼠标左键”组合来实现。)缩放是通过使用鼠标右键“向上”渲染窗口(使小部件变大)或“向下”渲染窗口(使小部件变小)来实现的。要旋转vtkBoxWidget,请选择一个面(但不是面控制柄)并移动鼠标左键(注意:在操作过程中必须按住鼠标按钮。)小部件外部发生的事件(即,没有拾取小部件的任何部分)会传播到任何其他已注册的obsever(例如交互样式)。再次按“i”键关闭小部件。
  vtkBoxWidget非常灵活。它可以用于选择、剪切、剪裁或执行依赖于隐式函数的任何其他操作(使用GetPlanes()方法);或者可以使用线性变换来变换对象(使用GetTransform()方法)。小部件的典型用法是使用StartInteractionEvent、InteractionEvent和EndInteractionEvent事件。在鼠标移动时调用InteractionEvent;另外两个事件分别称为“按下按钮”和“按下按钮”(左键或右键)。
  vtkBoxWidget类的一些附加特性包括控制小部件的呈现属性的能力。可以设置小部件部分的选定和未选定表示的属性。例如,可以在控制柄、面和轮廓的正常和选定状态下设置其特性。
  box小部件可以通过指定转换矩阵来定向。此转换应用于PlaceWidget()方法定义的初始边界框。不要假定变换应用于以原点为中心的单位框;这是错误的!

接口

PlaceWidget

void PlaceWidget(double bounds[6]) override;
void PlaceWidget() override { this->Superclass::PlaceWidget(); }
void PlaceWidget(double xmin, double xmax, double ymin, double ymax, double zmin, double zmax) override
{
   this->Superclass::PlaceWidget(xmin, xmax, ymin, ymax, zmin, zmax);
}

获取Box的polyData和planes

void GetPlanes(vtkPlanes* planes);
void GetPolyData(vtkPolyData* pd);

  GetPolyData方法用于获取定义box小部件的polydata(包括点)。
  polydata由6个四边形面和15个点组成。前八个点定义了八个角点顶点;接下来的六个定义了-x、+x、-y、+y、-z、+z面点;最后一点(15个点中的第15个点)定义了六面体的中心。当调用InteractionEvent或EndInteractionEvent事件时,这些点值保证是最新的。用户提供vtkPolyData并向其中添加点和单元格。
  GetPlanes方法可以获取描述由box小部件定义的隐式函数的平面。
  用户必须提供类vtkPlanes的实例。需要注意的是:vtkPlanes是vtkImplicitFunction的一个子类,这意味着各种过滤器都可以使用它来执行数据的剪裁、剪切和选择(可以反转平面法线的方向以启用InsideOut标志)

控制裁剪的方向InsideOut

  InsideOut用来控制裁剪的方向,向内或这向外;
  禁用此选项后,法线将指向框外。启用时,法线指向六面体。默认情况下,“InsideOut”处于禁用状态

vtkSetMacro(InsideOut, vtkTypeBool);
vtkGetMacro(InsideOut, vtkTypeBool);
vtkBooleanMacro(InsideOut, vtkTypeBool);

Box的vtkTransform

virtual void GetTransform(vtkTransform* t);  
virtual void SetTransform(vtkTransform* t);

  SetTransform设置获取表示长方体变换的线性变换矩阵信息。
  注意:转换与最初调用PlaceWidget的位置有关。此方法修改提供的变换。变换可用于控制vtkProp3D的位置,以及其他变换操作(例如vtkTransformorMPolyData)。

控制句柄的显示

通过操纵actor可见性来打开或关闭控制柄(表面上的小球体)。

void HandlesOn();
void HandlesOff();

外轮廓和光标

  用OutlineFaceWires控制轮廓的显示。此标志启用面导线。默认情况下,面线处于禁用状态。
  用OutlineCursorWires控制光标的显示。此标志启用在句柄之间运行的光标行。默认情况下,光标导线处于启用状态。

void SetOutlineFaceWires(int);
vtkGetMacro(OutlineFaceWires, int);
void OutlineFaceWiresOn() { this->SetOutlineFaceWires(1); }
void OutlineFaceWiresOff() { this->SetOutlineFaceWires(0); }
void SetOutlineCursorWires(int);
vtkGetMacro(OutlineCursorWires, int);
void OutlineCursorWiresOn() { this->SetOutlineCursorWires(1); }
void OutlineCursorWiresOff() { this->SetOutlineCursorWires(0); }

句柄属性

  HandleProperty是句柄属性(小球就是句柄),可以设置选定和正常时控制柄的属性。
  SelectedHandleProperty是当前被选中的句柄属性。
  FaceProperty是面属性(长方体的面),可以设置选定面和法线时面的特性。
  SelectedFaceProperty是当前被选中的面属性。
  OutlineProperty是轮廓属性(外边框的轮廓),可以设置被选中的和正常时轮廓的属性。
  SelectedOutlineProperty是当前被选中的轮廓属性。

vtkGetObjectMacro(HandleProperty, vtkProperty);
vtkGetObjectMacro(SelectedHandleProperty, vtkProperty);
vtkGetObjectMacro(FaceProperty, vtkProperty);
vtkGetObjectMacro(SelectedFaceProperty, vtkProperty);
vtkGetObjectMacro(OutlineProperty, vtkProperty);
vtkGetObjectMacro(SelectedOutlineProperty, vtkProperty);

控制变量

  TranslationEnabled/ScalingEnabled/RotationEnabled用来控制小部件的行为,可以启用和禁用平移、旋转和缩放的行为。

vtkSetMacro(TranslationEnabled, vtkTypeBool);
vtkGetMacro(TranslationEnabled, vtkTypeBool);
vtkBooleanMacro(TranslationEnabled, vtkTypeBool);
vtkSetMacro(ScalingEnabled, vtkTypeBool);
vtkGetMacro(ScalingEnabled, vtkTypeBool);
vtkBooleanMacro(ScalingEnabled, vtkTypeBool);
vtkSetMacro(RotationEnabled, vtkTypeBool);
vtkGetMacro(RotationEnabled, vtkTypeBool);
vtkBooleanMacro(RotationEnabled, vtkTypeBool);

代码

#include <vtkActor.h>
#include <vtkBoxWidget.h>
#include <vtkCommand.h>
#include <vtkConeSource.h>
#include <vtkInteractorStyleTrackballCamera.h>
#include <vtkNamedColors.h>
#include <vtkNew.h>
#include <vtkPolyDataMapper.h>
#include <vtkProperty.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkTransform.h>

#include "vtkAutoInit.h" 
VTK_MODULE_INIT(vtkRenderingOpenGL2);
VTK_MODULE_INIT(vtkRenderingVolumeOpenGL2);
VTK_MODULE_INIT(vtkRenderingFreeType);
VTK_MODULE_INIT(vtkInteractionStyle);

using namespace std;

namespace {
	class vtkMyCallback : public vtkCommand	{
	public:
		static vtkMyCallback* New()	{
			return new vtkMyCallback;
		}
		virtual void Execute(vtkObject* caller, unsigned long, void*){
			// Here we use the vtkBoxWidget to transform the underlying coneActor
			// (by manipulating its transformation matrix).
			vtkNew<vtkTransform> t;
			vtkBoxWidget* widget = reinterpret_cast<vtkBoxWidget*>(caller);
			widget->GetTransform(t);
			widget->GetProp3D()->SetUserTransform(t);
		}
	};
} // namespace

int main() {
	vtkNew<vtkNamedColors> colors;
	vtkNew<vtkConeSource> cone;

	vtkNew<vtkPolyDataMapper> coneMapper;
	coneMapper->SetInputConnection(cone->GetOutputPort());

	vtkNew<vtkActor> coneActor;
	coneActor->SetMapper(coneMapper);
	coneActor->GetProperty()->SetColor(colors->GetColor3d("BurlyWood").GetData());

	vtkNew<vtkRenderer> renderer;
	renderer->AddActor(coneActor);
	renderer->SetBackground(colors->GetColor3d("Blue").GetData());

	vtkNew<vtkRenderWindow> window;
	window->AddRenderer(renderer);
	window->SetSize(300, 300);
	window->SetWindowName("BoxWidget");

	vtkNew<vtkRenderWindowInteractor> interactor;
	interactor->SetRenderWindow(window);

	vtkNew<vtkInteractorStyleTrackballCamera> style;
	interactor->SetInteractorStyle(style);

	vtkNew<vtkBoxWidget> boxWidget;
	boxWidget->SetInteractor(interactor);
	boxWidget->SetProp3D(coneActor);
	boxWidget->SetPlaceFactor(1.25); // Make the box 1.25x larger than the actor
	boxWidget->PlaceWidget();

	vtkNew<vtkMyCallback> callback;
	boxWidget->AddObserver(vtkCommand::InteractionEvent, callback);
	boxWidget->On();

	window->Render();
	interactor->Start();
	return 0;
}

在这里插入图片描述

vtkBoxWidget2

  vtkBoxWidget2类继承自vtkAbstractWidget类,vtkAbstractWidget是VTK里实现“交互/表达实体”设计的所有Widget的基类;
  VTK中Widget的设计是从VTK 5.0版本开始引入的,最初的Widget是从vtk3DWidget派生出来的,从VTK5.1版本开始,VTK中的Widget重新进行设计,主要的设计理念是将Widget的消息处理与几何表达实体分离,但还是保留了vtk3DWidget及其子类。
  本例使用vtkBoxWidget2来操纵参与者。小部件只包含交互逻辑;实际框由附带的vtkBoxRepresentation绘制。与旧的vtkBoxWidget相反,这个小部件不提供将其分配给一个或多个参与者的功能,因此必须手动实现。通过将边界框传递给PlaceWidget方法来确定框的尺寸和位置,SetPlaceFactor方法提供与该边界框相关的缩放因子。应用于box的转换可以通过自定义回调类来操作任意数量的对象,该回调类通过AddObserver方法传递给box小部件。
  旧的实现vtkBoxWidget提供了接收vtkProp3D进行初始定位和调整大小的功能,但是转换同步仍然需要手动完成。有关如何使用它的简单示例,请参见BoxWidget。

代码

#include <vtkActor.h>
#include <vtkBoxRepresentation.h>
#include <vtkBoxWidget2.h>
#include <vtkCommand.h>
#include <vtkConeSource.h>
#include <vtkInteractorStyleTrackballCamera.h>
#include <vtkNamedColors.h>
#include <vtkNew.h>
#include <vtkPolyDataMapper.h>
#include <vtkProperty.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkTransform.h>

#include "vtkAutoInit.h" 
VTK_MODULE_INIT(vtkRenderingOpenGL2);
VTK_MODULE_INIT(vtkRenderingVolumeOpenGL2);
VTK_MODULE_INIT(vtkRenderingFreeType);
VTK_MODULE_INIT(vtkInteractionStyle);

using namespace std;

namespace {
	class vtkBoxCallback : public vtkCommand{
	public:
		static vtkBoxCallback* New(){
			return new vtkBoxCallback;
		}

		vtkSmartPointer<vtkActor> m_actor;
		void SetActor(vtkSmartPointer<vtkActor> actor){
			m_actor = actor;
		}

		virtual void Execute(vtkObject* caller, unsigned long, void*){
			vtkSmartPointer<vtkBoxWidget2> boxWidget = dynamic_cast<vtkBoxWidget2*>(caller);
			vtkNew<vtkTransform> t;
			dynamic_cast<vtkBoxRepresentation*>(boxWidget->GetRepresentation())->GetTransform(t);
			this->m_actor->SetUserTransform(t);
		}
		vtkBoxCallback(){}
	};
} // namespace

int main(){
	vtkNew<vtkNamedColors> colors;

	vtkNew<vtkConeSource> coneSource;
	coneSource->SetHeight(1.5);

	vtkNew<vtkPolyDataMapper> mapper;
	mapper->SetInputConnection(coneSource->GetOutputPort());

	vtkNew<vtkActor> actor;
	actor->SetMapper(mapper);
	actor->GetProperty()->SetColor(colors->GetColor3d("BurlyWood").GetData());

	vtkNew<vtkRenderer> renderer;
	renderer->AddActor(actor);
	renderer->SetBackground(colors->GetColor3d("Blue").GetData());
	renderer->ResetCamera(); // Reposition camera so the whole scene is visible

	vtkNew<vtkRenderWindow> renderWindow;
	renderWindow->AddRenderer(renderer);
	renderWindow->SetWindowName("BoxWidget2");

	vtkNew<vtkRenderWindowInteractor> renderWindowInteractor;
	renderWindowInteractor->SetRenderWindow(renderWindow);

	// Use the "trackball camera" interactor style, rather than the default
	// "joystick camera"
	vtkNew<vtkInteractorStyleTrackballCamera> style;
	renderWindowInteractor->SetInteractorStyle(style);

	vtkNew<vtkBoxWidget2> boxWidget;
	boxWidget->SetInteractor(renderWindowInteractor);
	boxWidget->GetRepresentation()->SetPlaceFactor(1); // Default is 0.5
	boxWidget->GetRepresentation()->PlaceWidget(actor->GetBounds());

	// Set up a callback for the interactor to call so we can manipulate the actor
	vtkNew<vtkBoxCallback> boxCallback;
	boxCallback->SetActor(actor);
	boxWidget->AddObserver(vtkCommand::InteractionEvent, boxCallback);

	boxWidget->On();

	renderWindow->Render();
	renderWindowInteractor->Start();
	return 0;
}

在这里插入图片描述

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐