前一段事件看到VTK的一个例子:
该案例是vtk.js写的,觉得很有意思,个人正好也要用到,于是萌生了用C++修改VTK源码来实现该功能的想法。原本以为很简单,只需要修改一下vtkResliceCursor就可以了,加上小球,加上几个Actor,就能实现,没想到该功能整花了我差不多一个月的时间。但也学到了不少知识,下面就该功能的实现效果和方法做个大致解说:
我实现的效果:
实现方法:
1,首先在vtkResliceCursor中定义六个小球的位置。因为是X,Y,Z三个轴,每个轴上两个小球,所以总共十六个小球。代码:
void vtkResliceCursor::BuildCursorGeometryWithoutHole()
{
// 其他源码省略
.......
for (int i = 0; i < 3; i++)
{
//wulc
{
this->SpherePoints[0][i] = this->Center[i] - sphereLength * this->XAxis[i];
this->SpherePoints[1][i] = this->Center[i] + sphereLength * this->XAxis[i];
this->SpherePoints[2][i] = this->Center[i] - sphereLength * this->YAxis[i];
this->SpherePoints[3][i] = this->Center[i] + sphereLength * this->YAxis[i];
this->SpherePoints[4][i] = this->Center[i] - sphereLength * this->ZAxis[i];
this->SpherePoints[5][i] = this->Center[i] + sphereLength * this->ZAxis[i];
}
}
// 其他源码省略
.......
}
sphereLength 是一个自定义的常数,也就是中心到小球的距离。可以是 30 ,40 ,50 .。。。。
除此之外我们还要定义一个函数,通过该函数可以获取这六个小球的坐标。比如 GetPointPosition(double p[6][3]);
2,在vtkResliceCursorPicker中判断鼠标是否靠近小球中心位置,靠近小球坐标时,将鼠标光标变为手掌形状。判断方法就是鼠标的位置和小球位置的距离,其中有现成的代码:
/----------------wulc---------------------------------------------------
int vtkResliceCursorPicker::IntersectPointWithPoint(double p1[3], double p2[3], double Points[], double tol)
{
double pts[6][3] = { {0,0,0} };
for (size_t i = 0; i < 6; i++)
{
pts[i][0] = Points[3*i];
pts[i][1] = Points[3*i + 1];
pts[i][2] = Points[3 * i + 2];
}
int j = 0;
for ( ; j < 6; j++)
{
double X[4] = { pts[j][0], pts[j][1], pts[j][2], 1 };
int i;
double ray[3], rayFactor, projXYZ[3];
for (i = 0; i < 3; i++)
{
ray[i] = p2[i] - p1[i];
}
if ((rayFactor = vtkMath::Dot(ray, ray)) == 0.0)
{
return 0;
}
const double t = (ray[0] * (X[0] - p1[0]) +
ray[1] * (X[1] - p1[1]) +
ray[2] * (X[2] - p1[2])) / rayFactor;
if (t >= 0.0 && t <= 1.0)
{
for (i = 0; i < 3; i++)
{
projXYZ[i] = p1[i] + t * ray[i];
if (fabs(X[i] - projXYZ[i]) > tol)
{
break;
}
}
if (i > 2) // within tolerance
{
return 1;
}
}
}
return 0;
}
3,最后要在vtkResliceCursorActor类中添加小球,代码:
//wulc
if (this->Renderer == nullptr) return;
if (axisNormal == 1)//x-z平面
{
double* position = this->CursorAlgorithm->GetResliceCursor()->GetSpherePostion(2);
if (fabs(position[0] - 0.0) > 0.001 || fabs(position[1] - 0.0) > 0.001 || fabs(position[2] - 0.0) > 0.001)
{
this->SphereActor[2]->GetProperty()->SetColor(1, 0, 0);
this->SphereActor[3]->GetProperty()->SetColor(1, 0, 0);
this->SphereActor[2]->SetPosition(position[0], position[1], position[2]);
this->SphereActor[3]->SetPosition(position[3], position[4], position[5]);
position = this->CursorAlgorithm->GetResliceCursor()->GetSpherePostion(0);
this->SphereActor[0]->GetProperty()->SetColor(0, 0, 1);
this->SphereActor[1]->GetProperty()->SetColor(0, 0, 1);
this->SphereActor[0]->SetPosition(position[0], position[1], position[2]);
this->SphereActor[1]->SetPosition(position[3], position[4], position[5]);
}
}
else if (axisNormal == 2)//x-y平面
{
double* position = this->CursorAlgorithm->GetResliceCursor()->GetSpherePostion(0);
if (fabs(position[0] - 0.0) > 0.001 || fabs(position[1] - 0.0) > 0.001 || fabs(position[2] - 0.0) > 0.001)
{
this->SphereActor[0]->GetProperty()->SetColor(0, 1, 0);
this->SphereActor[1]->GetProperty()->SetColor(0, 1, 0);
this->SphereActor[0]->SetPosition(position[0], position[1], position[2]);
this->SphereActor[1]->SetPosition(position[3], position[4], position[5]);
position = this->CursorAlgorithm->GetResliceCursor()->GetSpherePostion(1);
this->SphereActor[2]->GetProperty()->SetColor(1, 0, 0);
this->SphereActor[3]->GetProperty()->SetColor(1, 0, 0);
this->SphereActor[2]->SetPosition(position[0], position[1], position[2]);
this->SphereActor[3]->SetPosition(position[3], position[4], position[5]);
}
}
else if (axisNormal == 0) //y-z平面
{
double* position = this->CursorAlgorithm->GetResliceCursor()->GetSpherePostion(2);
if (fabs(position[0] - 0.0) > 0.001 || fabs(position[1] - 0.0) > 0.001 || fabs(position[2] - 0.0) > 0.001)
{
this->SphereActor[0]->GetProperty()->SetColor(0, 1, 0);
this->SphereActor[1]->GetProperty()->SetColor(0, 1, 0);
this->SphereActor[0]->SetPosition(position[0], position[1], position[2]);
this->SphereActor[1]->SetPosition(position[3], position[4], position[5]);
position = this->CursorAlgorithm->GetResliceCursor()->GetSpherePostion(1);
this->SphereActor[2]->GetProperty()->SetColor(0, 0, 1);
this->SphereActor[3]->GetProperty()->SetColor(0, 0, 1);
this->SphereActor[2]->SetPosition(position[0], position[1], position[2]);
this->SphereActor[3]->SetPosition(position[3], position[4], position[5]);
}
}
这就可以了,欢迎小伙伴能够一块讨论。