VTK中通过鼠标点一下开始画线,线随鼠标移动,再次按下即画出?
vtk吧
全部回复
仅看楼主
level 5
fcf_2015 楼主
尝试使用vtkCommand::MouseMoveEvent来画线,但是问题每次移动都会多出一根线,与想要的结果不符,不知大家有没有什么好的建议?
2016年08月14日 09点08分 1
level 8
可以这样呀:鼠标按下是一个响应,并获取坐标值,设为起点,鼠标在移动(mousemove)的过程中,不断的获取坐标值,然后用直线连接起点和鼠标所在位置,不断的刷新,这样这条直线就会根据你的鼠标位置不断的更新。当鼠标抬起的时候是一个响应并返回坐标值,这样就能确定那条直线了,可以一次性完成,你这样鼠标还要点击两次。。。
2016年08月15日 00点08分 2
这种方式我试过了,无法达到我想要的结果。
2016年08月18日 15点08分
level 12
贴代码,帮你看[哈哈]
2016年08月15日 02点08分 3
代码已贴,吧主帮忙看看
2016年08月18日 15点08分
@fcf_2015 嗯嗯,在看了,幸苦了[太开心]
2016年08月19日 00点08分
level 5
fcf_2015 楼主
我使用的是观察者/命令模式,我想得到的理想效果是:鼠标在A点时按下鼠标右键,这时按住右键不放移动鼠标,界面上实时会显示A点与鼠标当前点之间的连线;当松开右键时,界面上只显示A点与右键松开时坐标点之间的连线。但是目前我的程序显示的结果如图所示,当按住鼠标右键移动鼠标时,界面上会把鼠标移动过的点与A点的连线全都显示出来,一直没有找到解决方案。
class PickCommand : public vtkCommand
{
public:
static PickCommand *New()
{
return new PickCommand;
}
void Delete()
{
delete this;
}
virtual void Execute(vtkObject *caller, unsigned long l, void *callData)
{
if (picker->GetCellId() < 0 )
{
textActor->VisibilityOff();
double selpt[3];
picker->GetSelectionPoint(selpt);
double x = selpt[0];
double y = selpt[1];
picker->GetPickPosition( pickPos );
xp = pickPos[0];
yp = pickPos[1];
zp = pickPos[2];
cout<<" X:"<<xp<<" Y:"<<yp<<" Z:"<<zp<<endl;
// volume->VisibilityOff();
char text[120];
sprintf( text, "(%5.5f, %5.5f, %5.5f)", xp, yp, zp );
textMapper->SetInput( text );
textActor->SetPosition(x, y);
textActor->VisibilityOn();
}
else
{
}
renWin->Render();
}
};
void PickerInteractionCallback( vtkObject* vtkNotUsed(object),
unsigned long event,
void* clientdata,
void* vtkNotUsed(calldata) )
{
vtkInteractorStyleTrackballCamera * style =
(vtkInteractorStyleTrackballCamera*)clientdata;
int *pick = iren->GetEventPosition();
vtkPolyData *polydata = vtkPolyData::New();
vtkPolyDataMapper *lineMapper = vtkPolyDataMapper::New();
vtkActor *lineActor1 = vtkActor::New();
vtkPoints *points1 = vtkPoints::New();
vtkLine *line0 = vtkLine::New();
vtkCellArray *lines1 = vtkCellArray::New();
switch( event )
{
case vtkCommand::RightButtonPressEvent:
MouseMotion=1;
// double pickPos[3];
picker->Pick((double)pick[0], (double)pick[1], 0.0, ren);//拾取操作
picker->GetPickPosition( pickPos );
xp1 = pickPos[0];
yp1 = pickPos[1];
zp1 = pickPos[2];
break;
case vtkCommand::RightButtonReleaseEvent:
MouseMotion=0;
/* xp2=xp1;
yp2=yp1;
zp2=zp1;*/
break;
case vtkCommand::MouseMoveEvent:
if(MouseMotion)
{
picker->Pick((double)pick[0], (double)pick[1], 0.0, ren);//拾取操作
picker->GetPickPosition( pickPos );
xp2 = pickPos[0];
yp2 = pickPos[1];
zp2 = pickPos[2];
vtkPoints *points1 = vtkPoints::New();
points1->InsertNextPoint ( xp1, yp1, zp1 ); //返回第一个点的ID:0
points1->InsertNextPoint ( xp2, yp2, zp2 ); //返回第二个点的ID:1
//每两个坐标点之间分别创建一条线
//SetId()的第一个参数是线段的端点ID,第二个参数是连接的点的ID
vtkLine *line0 = vtkLine::New();
line0->GetPointIds()->SetId ( 0,1);
// line0->GetPointIds()->SetId ( 1,1 );
//创建Cell数组,用于存储以上创建的线段
vtkCellArray *lines1 = vtkCellArray::New();
lines1->InsertNextCell ( line0 );
//将点和线加入到数据集中,前者指定数据集的几何,后者指定其拓扑
polydata->SetPoints ( points1 );
polydata->SetLines ( lines1 );
points1->Delete();
lines1->Delete();
vtkPolyDataMapper *lineMapper = vtkPolyDataMapper::New();
lineMapper->SetInput(polydata); //测试划线
vtkProperty *property=vtkProperty::New();
property->SetColor(0,0,0);
property->SetOpacity(1); //透明度
vtkActor *lineActor1 = vtkActor::New();
lineActor1->SetMapper(lineMapper);
lineActor1->SetProperty(property);
ren->AddActor(lineActor1);
style->OnRightButtonUp();
style->OnMouseMove();
}
break;
}
}
2016年08月18日 15点08分 4
level 12
vtkDistanceWidget中的代码可以参考下。
你鼠标每动一下,就创建一个新的actor放进来,当然会一直画了。
就是这货:vtkActor *lineActor1 = vtkActor::New();
把这个actor放外面,做成唯一的,一直刷新它应该就好了。
每次鼠标在A点按下的时候,才new
2016年08月19日 00点08分 5
正如吧主所说,将这句移到外面就得到了我希望的效果,非常感谢[大拇指]
2016年08月19日 07点08分
@fcf_2015 [哈哈]客气,我也是猜的
2016年08月19日 08点08分
@rabbitbride 吧主您好,我抄的这段程序,但是发现他对于RightButtonRelease命令并不响应,是怎么回事?
2016年10月06日 07点10分
@oimqtie51546 是不是版本问题?肯定是信号没穿过去
2016年10月08日 00点10分
level 5
fcf_2015 楼主
还有一个问题再请教一下,我想实现当松开右键时,所画的线同时消失,为了实现此功能,我在RightButtonReleaseEvent:这里增加了一句ren->removeActor(lineActor1 ),但是在运行时发现,只有按一下鼠标左键或者是右键,所画的线才会消失,不明白是为什么?
2016年08月19日 07点08分 6
没刷新~remove完记得render
2016年08月19日 08点08分
@rabbitbride 刷新后OK[大拇指]
2016年09月05日 06点09分
2016年09月05日 06点09分
level 3
请问下怎么能把一条线画在打开的DICOM图像上,不知道为什么总是划不上去。也不知道哪里出了问题。
2016年11月19日 02点11分 7
vtkImageTracerWidget
2020年07月13日 15点07分
level 6
我只是偶尔上来看一看,看看现在的问题和我几年前遇到的有什么区别
2020年07月16日 02点07分 9
你好 想请教一个 您这边 在切面 上 画线 同步 实时三维显示部分的实现,目前我这边想实现 在切面上规划一个钉子,用鼠标在切面上拖动这根钉子,此时钉子会实时的三维拖动
2023年03月15日 05点03分
1