.net Winform 下使用VTK 选中、拖动模型
导入Nuget包
创建.net Framwork 4.8 的Winform窗体应用程序,导入 Activiz.NET 5.8.0版本。
C#版的VTK鼠标交互事件的实现方法网上是真不好找,结合AI给出的代码示例,总算找到一个可以实现鼠标选中单元后变色的方法,代码如下
public partial class Main : Form
{
private RenderWindowControl renderWindow;
private vtkRenderWindow vtkRenderWindow;
private vtkCellPicker cellPicker;
private vtkRenderWindowInteractor renderWindowInteractor;
private vtkActor selectdActor;
public Main()
{
InitializeComponent();
InitRendWindow();
CreateCubes();
}
private void InitRendWindow()
{
renderWindow = new RenderWindowControl();
renderWindow.Load += RenderWinow_Load;
renderWindow.Dock = DockStyle.Fill;
panel1.Controls.Add(renderWindow);
}
public vtkRenderer GetVtkRenderer()
{
vtkRenderer Renderer = renderWindow.RenderWindow.GetRenderers().GetFirstRenderer();
return Renderer;
}
private void RenderWinow_Load(object sender, EventArgs e)
{
vtkRenderWindow = renderWindow.RenderWindow;
var style = vtkInteractorStyleTrackballCamera.New();
//之前我把事件加在了style上,后来发现这样不好,因为指定了style的LeftButtonPressEvt事件后,其他默认的旋转、平移也都用不了了
renderWindowInteractor.LeftButtonPressEvt += new vtkObject.vtkObjectEventHandler(Interactor_LeftButtonDownEvt);
renderWindowInteractor.SetInteractorStyle(style);
renderWindowInteractor.Start();
}
private void Interactor_LeftButtonDownEvt(vtkObject sender, vtkObjectEventArgs e)
{
if (e.EventId == (uint)vtkCommand.EventIds.LeftButtonPressEvent)
{
var interactorCamera = sender as vtkInteractorStyleTrackballCamera;
var interactor32 = sender as vtkWin32RenderWindowInteractor;
winSize = vtkRenderWindow.GetSize();
if (interactor32 != null)
{
//var interactor = interactorCamera.GetInteractor();
var positions = interactor32.GetEventPosition();
var renderer = interactor32.GetRenderWindow().GetRenderers().GetFirstRenderer();
HandlePick(positions, renderer);
vtkRenderWindow.Render();
}
}
}
private void HandlePick(int[] eventPositions, vtkRenderer renderer)
{
renderer.SetDisplayPoint(eventPositions[0], eventPositions[1], 0);
renderer.DisplayToWorld();
var wordPoints = renderer.GetWorldPoint();
var picker = vtkCellPicker.New();
picker.SetTolerance(0.0005);
picker.Pick(eventPositions[0], eventPositions[1], 0.0, renderer);
vtkAssemblyPath path = picker.GetPath();
if (path != null && path.GetNumberOfItems() > 0)
{
vtkProp3D prop = path.GetFirstNode().GetViewProp() as vtkProp3D;
if (prop != null)
{
// Handle selection - for example, change color
vtkActor actor = prop as vtkActor;
if (actor != null)
{
//初始化时
if (selectdActor == null)
{
actor.GetProperty().SetColor(1, 0, 0);
}
else
{
if (selectdActor == actor)
{
if (selectdActor.GetProperty().GetColor() != actor.GetProperty().GetColor())
{
var color = actor.GetProperty().GetColor();
var oldColor = new double[] { 0.5, 1, 0 };
if (color.SequenceEqual(oldColor))
{
actor.GetProperty().SetColor(1, 0, 0);
}
else
{
actor.GetProperty().SetColor(0.5, 1, 0);
}
}
}
else
{
selectdActor.GetProperty().SetColor(0.5, 1, 0);
actor.GetProperty().SetColor(1, 0, 0);
}
}
selectdActor = actor;
}
}
}
renderer.Render();
}
private void CreateCubes()
{
var renderer = GetVtkRenderer();
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 2; j++)
{
for (int k = 0; k < 2; k++)
{
CreateAndAddCube(i * 2, j * 2, k * 2, renderer);
}
}
}
renderer.ResetCamera();
vtkRenderWindow.Render();
}
private void CreateAndAddCube(double x, double y, double z, vtkRenderer renderer)
{
// 创建正方体几何
vtkCubeSource cubeSource = vtkCubeSource.New();
cubeSource.SetCenter(x + 1, y + 1, z + 1); // 设置中心位置(每个正方体的中心)
cubeSource.SetXLength(2.0);
cubeSource.SetYLength(2.0);
cubeSource.SetZLength(2.0);
// 创建映射器
vtkPolyDataMapper mapper = vtkPolyDataMapper.New();
mapper.SetInputConnection(cubeSource.GetOutputPort());
// 创建演员并设置颜色(可选)
vtkActor actor = vtkActor.New();
actor.SetMapper(mapper);
// actor.GetProperty().SetColor(...); // 设置颜色
actor.GetProperty().SetColor(0.5, 1, 0);
actor.GetProperty().SetOpacity(1); // 设置为不透明
//actor.GetProperty().SetRepresentationToWireframe(); // 设置为线框模式
actor.GetProperty().EdgeVisibilityOn(); // 开启边缘可见性
// 添加演员到渲染器
renderer.AddActor(actor);
}
}