vtk的AddObserver困惑

不知道为什么对于vtkBoxWidget 实例 boxWidget,通过AddObserver添加LeftButtonPressEvent类型事件,不能响应。但改为InteractionEvent类型的就可以。我试了下,似乎vtkRenderWindowInteractor 会响应LeftButtonPressEvent类型事件。

于是为了能给物体添加点的拾取功能,先通过为 vtkRenderWindowInteractor *  iren 添加消息响应类

class vtkLeftButtonPress :
  public vtkCommand
{
public:
 static vtkLeftButtonPress* New(){return new vtkLeftButtonPress;}
 void Delete(){delete this;};
 void SetParameters(vtkRenderer* r){m_ren = r;}
 virtual void Execute(vtkObject * caller, unsigned long l, void *callData)
 {  
 // if(!m_picker) return;
  vtkRenderWindowInteractor* iren = reinterpret_cast<vtkRenderWindowInteractor*>(caller);
  vtkAbstractPicker * picker = iren->GetPicker();

  int *pickPos = iren->GetEventPosition();
  picker->Pick((double)pickPos[0], (double)pickPos[1], 0.0, m_ren);
 }
protected:
 vtkRenderer* m_ren;
};

  然后 lbp->SetParameters(ren);把vtkRenderer传递进来,再添加事件处理
  iren->AddObserver(vtkCommand::LeftButtonPressEvent, lbp); iren得到鼠标左击事件,并对vktPointPick进行PicK.

这样pointPicker就能收到EndPickEvent命令,并进行相应的处理,

我们为vtkPointPicker *pointPicker添加消息响应类

class vtkPrintPointID :
 public vtkCommand
{
public:
 static vtkPrintPointID* New(){return new vtkPrintPointID;}
 void Delete(){delete this;};
 virtual void Execute(vtkObject *caller, unsigned long l, void *callData)
 {
  vtkPointPicker*  ptPicker = reinterpret_cast<vtkPointPicker*>(caller);
  std::cout<<ptPicker->GetPointId()<<endl;
 }
};

最终就能显示点击顶点的索引号

 

主要源码:

// Arrays.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"

/*=========================================================================

  Program:   Visualization Toolkit
  Module:    $RCSfile: Arrays.cxx,v $

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
// This example demonstrate the use of VTK data arrays as attribute
// data as well as field data. It creates geometry (vtkPolyData) as
// well as attribute data explicitly.

// first include the required header files for the vtk classes we are using
#include "vtkActor.h"
#include "vtkCellArray.h"
#include "vtkDoubleArray.h"
#include "vtkFloatArray.h"
#include "vtkIntArray.h"
#include "vtkPointData.h"
#include "vtkPoints.h"
#include "vtkPolyData.h"
#include "vtkPolyDataMapper.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkRenderer.h"
#include "vtkPointPicker.h"
#include <iostream>
#include "vtkCommand.h"

class vtkLeftButtonPress :
  public vtkCommand
{
public:
 static vtkLeftButtonPress* New(){return new vtkLeftButtonPress;}
 void Delete(){delete this;};
 void SetParameters(vtkRenderer* r){m_ren = r;}
 virtual void Execute(vtkObject * caller, unsigned long l, void *callData)
 {  
 // if(!m_picker) return;
  vtkRenderWindowInteractor* iren = reinterpret_cast<vtkRenderWindowInteractor*>(caller);
  vtkAbstractPicker * picker = iren->GetPicker();

  int *pickPos = iren->GetEventPosition();
  picker->Pick((double)pickPos[0], (double)pickPos[1], 0.0, m_ren);
 }
protected:
 vtkRenderer* m_ren;
};


class vtkPrintPointID :
 public vtkCommand
{
public:
 static vtkPrintPointID* New(){return new vtkPrintPointID;}
 void Delete(){delete this;};
 virtual void Execute(vtkObject *caller, unsigned long l, void *callData)
 {
  vtkPointPicker*  ptPicker = reinterpret_cast<vtkPointPicker*>(caller);
//  ptPicker->Pick((double)pickPos[0], (double)pickPos[1], 0.0, g_ren1);//触发了EndPickEvent:在CHoleRepairDlg::OnLandmark()中的g_picker->AddObserver( vtkCommand::EndPickEvent, landmarkObserver );
  std::cout<<ptPicker->GetPointId()<<endl;
 }
};

 

int main()
{
  int i;

  // Create a float array which represents the points.
  vtkFloatArray* pcoords = vtkFloatArray::New();

  // Note that by default, an array has 1 component.
  // We have to change it to 3 for points
  pcoords->SetNumberOfComponents(3);
  // We ask pcoords to allocate room for at least 4 tuples
  // and set the number of tuples to 4.
  pcoords->SetNumberOfTuples(4);
  // Assign each tuple. There are 5 specialized versions of SetTuple:
  // SetTuple1 SetTuple2 SetTuple3 SetTuple4 SetTuple9
  // These take 1, 2, 3, 4 and 9 components respectively.
  float pts[4][3] = { {0.0, 0.0, 0.0}, {1.0, 0.0, 0.0},
                      {0.0, 1.0, 0.0}, {1.0, 1.0, 0.0} };
  for (i=0; i<4; i++)
    {
    pcoords->SetTuple(i, pts[i]);
    }

  // Create vtkPoints and assign pcoords as the internal data array.
  vtkPoints* points = vtkPoints::New();
  points->SetData(pcoords);

  // Create the cells. In this case, a triangle strip with 2 triangles
  // (which can be represented by 4 points)
  vtkCellArray* strips = vtkCellArray::New();
  strips->InsertNextCell(4);
  strips->InsertCellPoint(0);
  strips->InsertCellPoint(1);
  strips->InsertCellPoint(2);
  strips->InsertCellPoint(3);

  // Create an integer array with 4 tuples. Note that when using
  // InsertNextValue (or InsertNextTuple1 which is equivalent in
  // this situation), the array will expand automatically
  vtkIntArray* temperature = vtkIntArray::New();
  temperature->SetName("Temperature");
  temperature->InsertNextValue(10);
  temperature->InsertNextValue(200);
  temperature->InsertNextValue(10);
  temperature->InsertNextValue(10);

  // Create a double array.
  vtkDoubleArray * vorticity = vtkDoubleArray::New();
  vorticity->SetName("Vorticity");
  vorticity->InsertNextValue(2.7);
  vorticity->InsertNextValue(4.1);
  vorticity->InsertNextValue(5.3);
  vorticity->InsertNextValue(3.4);

  // Create the dataset. In this case, we create a vtkPolyData
  vtkPolyData* polydata = vtkPolyData::New();
  // Assign points and cells
  polydata->SetPoints(points);
  polydata->SetStrips(strips);
  // Assign scalars
  polydata->GetPointData()->SetScalars(temperature);
  // Add the vorticity array. In this example, this field
  // is not used.
  polydata->GetPointData()->AddArray(vorticity);

  // Create the mapper and set the appropriate scalar range
  // (default is (0,1)
  vtkPolyDataMapper* mapper = vtkPolyDataMapper::New();
  mapper->SetInput(polydata);
  mapper->SetScalarRange(0, 250);

  // Create an actor.
  vtkActor* actor = vtkActor::New();
  actor->SetMapper(mapper);

  // Create the rendering objects.
  vtkRenderer* ren = vtkRenderer::New();
  ren->AddActor(actor);

  vtkRenderWindow* renWin = vtkRenderWindow::New();
  renWin->AddRenderer(ren);

  vtkRenderWindowInteractor* iren = vtkRenderWindowInteractor::New();
  iren->SetRenderWindow(renWin);

  vtkPointPicker * pointPicker = vtkPointPicker::New();
 
  vtkLeftButtonPress * lbp = vtkLeftButtonPress::New();
  lbp->SetParameters(ren);
  iren->AddObserver(vtkCommand::LeftButtonPressEvent, lbp);

  vtkPrintPointID *ppID = vtkPrintPointID::New();
  pointPicker->AddObserver(vtkCommand::EndPickEvent, ppID);
 
  iren->SetPicker(pointPicker); //设置picker
 
  iren->Initialize();
  iren->Start();
 
  ppID->Delete();
  pcoords->Delete();
  points->Delete();
  strips->Delete();
  temperature->Delete();
  vorticity->Delete();
  polydata->Delete();
  mapper->Delete();
  actor->Delete();
  ren->Delete();
  renWin->Delete();
  pointPicker->Delete();
  iren->Delete();
  return 0;
}

 

 

 

转载于:https://www.cnblogs.com/tandge/archive/2009/07/13/1522600.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值