Commit 973b6155 authored by Emmanuel Promayon's avatar Emmanuel Promayon

NEW picking in Arbitrary Slice is back

Automatic synchronization of coronal/sagittal and axial slices
when the arbitrary slice is picked.
+ code cleaning
parent 3612684c
......@@ -105,21 +105,12 @@ void ArbitrarySingleImageComponent::setTransform(vtkSmartPointer<vtkTransform> t
// -------------------- resetTransform --------------------
void ArbitrarySingleImageComponent::resetTransform() {
getTransform()->Identity();
getTransform()->GetMatrix()->SetElement(0, 3, 0.0);
getTransform()->GetMatrix()->SetElement(1, 3, 0.0);
getTransform()->GetMatrix()->SetElement(2, 3, dimensions[2] / 2.0 * spacing[2]);
getTransform()->Modified();
setTransformRotation(0.0, 0.0, 0.0);
setTransformTranslation(0.0, 0.0, 0.5);
}
// -------------------- setTransformRotation --------------------
void ArbitrarySingleImageComponent::setTransformRotation(double angleX, double angleY, double angleZ) {
double C_L[4] = {dimensions[0]* spacing[0] / 2.0 - spacing[0] / 2.0,
dimensions[1]* spacing[1] / 2.0 - spacing[1] / 2.0,
0.0,
1.0
};
vtkSmartPointer<vtkMatrix4x4> T_P2L = vtkSmartPointer<vtkMatrix4x4>::New();
T_P2L->DeepCopy(getTransform()->GetMatrix());
......@@ -135,8 +126,9 @@ void ArbitrarySingleImageComponent::setTransformRotation(double angleX, double a
vtkSmartPointer<vtkMatrix4x4> T_P2L_rotation_only_inverse = vtkSmartPointer<vtkMatrix4x4>::New();
vtkMatrix4x4::Invert(T_P2L_rotation_only, T_P2L_rotation_only_inverse);
// get the image center in the parent (= image) reference frame
double C_P[4];
T_P2L->MultiplyPoint(C_L, C_P);
getImageCenterInParent(C_P);
vtkSmartPointer<vtkMatrix4x4> T_P2C = vtkSmartPointer<vtkMatrix4x4>::New();
T_P2C->Identity();
......@@ -167,6 +159,7 @@ void ArbitrarySingleImageComponent::setTransformRotation(double angleX, double a
if (checkCenter(checkRotation)) {
getTransform()->GetMatrix()->DeepCopy(checkRotation);
getTransform()->Modified();
updatePickPlane();
}
}
......@@ -191,14 +184,9 @@ void ArbitrarySingleImageComponent::setTransformTranslation(double x, double y,
vtkSmartPointer<vtkMatrix4x4> T_P2L = vtkSmartPointer<vtkMatrix4x4>::New();
T_P2L->DeepCopy(getTransform()->GetMatrix());
double C_L[4] = {dimensions[0]* spacing[0] / 2.0 - spacing[0] / 2.0,
dimensions[1]* spacing[1] / 2.0 - spacing[1] / 2.0,
0.0,
1.0
};
// get the image center in the parent (= image) reference frame
double C_P[4];
T_P2L->MultiplyPoint(C_L, C_P);
getImageCenterInParent(C_P);
QVector3D centerToOrigin_P(T_P2L->GetElement(0, 3) - C_P[0],
T_P2L->GetElement(1, 3) - C_P[1],
......@@ -213,29 +201,25 @@ void ArbitrarySingleImageComponent::setTransformTranslation(double x, double y,
getTransform()->GetMatrix()->DeepCopy(T_P2L);
getTransform()->Modified();
updatePickPlane();
}
// -------------------- updateTranslationExtremity --------------------
void ArbitrarySingleImageComponent::updateTranslationExtremity() {
// compute C in image coordinates
double C_L[4] = {dimensions[0]* spacing[0] / 2.0 - spacing[0] / 2.0,
dimensions[1]* spacing[1] / 2.0 - spacing[1] / 2.0,
0.0,
1.0
};
vtkSmartPointer<vtkMatrix4x4> T_P2L = vtkSmartPointer<vtkMatrix4x4>::New();
T_P2L->DeepCopy(getTransform()->GetMatrix());
double C_P[4];
T_P2L->MultiplyPoint(C_L, C_P);
getTransform()->GetMatrix()->MultiplyPoint(C_L, C_P);
// z vector in local coordinate system
// Compute the z direction vector in local coordinate system
double V_L[4] = { C_L[0], C_L[1], C_L[3] + 1.0, 1.0};
// z vector in global coordinate system
double V_P[4];
T_P2L->MultiplyPoint(V_L, V_P);
getTransform()->GetMatrix()->MultiplyPoint(V_L, V_P);
// compute intersection of line C_P + k vec(C_P, V_P) with the image
QVector3D lineVector(V_P[0] - C_P[0], V_P[1] - C_P[1], V_P[2] - C_P[2]);
......@@ -284,37 +268,30 @@ void ArbitrarySingleImageComponent::updateTranslationExtremity() {
double ArbitrarySingleImageComponent::getTranslationInVolume() {
updateTranslationExtremity();
// compute center in P reference frame
double C_L[4] = {dimensions[0]* spacing[0] / 2.0 - spacing[0] / 2.0,
dimensions[1]* spacing[1] / 2.0 - spacing[1] / 2.0,
0.0,
1.0
};
vtkSmartPointer<vtkMatrix4x4> T_P2L = vtkSmartPointer<vtkMatrix4x4>::New();
T_P2L->DeepCopy(getTransform()->GetMatrix());
// get the image center in the parent (= image) reference frame
double C_P[4];
T_P2L->MultiplyPoint(C_L, C_P);
QVector3D C(C_P[0], C_P[1], C_P[2]);
getImageCenterInParent(C_P);
// C- = 0.0
// C+ = 1.0
// C-C = k C-C+
// k = C-C / C-C+
QVector3D C(C_P[0], C_P[1], C_P[2]);
double k = QVector3D(C - cMinus_P).length() / QVector3D(cPlus_P - cMinus_P).length();
return k;
}
// -------------------- checkCenter --------------------
bool ArbitrarySingleImageComponent::checkCenter(vtkSmartPointer<vtkMatrix4x4> transform) {
double C_L[4] = {dimensions[0]* spacing[0] / 2.0 - spacing[0] / 2.0,
dimensions[1]* spacing[1] / 2.0 - spacing[1] / 2.0,
0.0,
1.0
};
double C_transform[4];
transform->MultiplyPoint(C_L, C_transform);
double centerInFrame[4] = { dimensions[0]* spacing[0] / 2.0, dimensions[1]* spacing[1] / 2.0, 0.0, 1.0};
double centerInImage[4];
transform->MultiplyPoint(centerInFrame, centerInImage);
bool inside = pointInsideVolume(QVector3D(centerInImage[0], centerInImage[1], centerInImage[2]));
bool inside = pointInsideVolume(QVector3D(C_transform[0], C_transform[1], C_transform[2]));
// positive check only is displacement will keep the center inside the box
return inside;
......@@ -323,7 +300,7 @@ bool ArbitrarySingleImageComponent::checkCenter(vtkSmartPointer<vtkMatrix4x4> tr
// -------------------- pointInsideVolume --------------------
bool ArbitrarySingleImageComponent::pointInsideVolume(QVector3D p) {
QVector3D pRounded = roundTo4Decimals(p);
return (pRounded.x() >= 0.0
return (pRounded.x() >= 0.0
&& pRounded.x() <= dimensions[0] * spacing[0]
&& pRounded.y() >= 0.0
&& pRounded.y() <= dimensions[1] * spacing[1]
......@@ -331,7 +308,15 @@ bool ArbitrarySingleImageComponent::pointInsideVolume(QVector3D p) {
&& pRounded.z() <= dimensions[2] * spacing[2]);
}
// -------------------- getImageCenterInParent --------------------
void ArbitrarySingleImageComponent::getImageCenterInParent(double C_P[4]) {
double C_L[4] = {dimensions[0]* spacing[0] / 2.0 - spacing[0] / 2.0,
dimensions[1]* spacing[1] / 2.0 - spacing[1] / 2.0,
0.0,
1.0
};
getTransform()->GetMatrix()->MultiplyPoint(C_L, C_P);
}
......@@ -383,6 +368,17 @@ int ArbitrarySingleImageComponent::getNumberOfSlices() const {
return 0;
}
// -------------------- pixelPicked --------------------
void ArbitrarySingleImageComponent::pixelPicked(double x, double y, double z) {
// transform picked from this slice to the parent frame (i.e., the image)
double picked[4] = {x, y, z, 1.0};
double picked_P[4];
getTransform()->GetMatrix()->MultiplyPoint(picked, picked_P);
// synchronize all the other slices
((ImageComponent*)getParent())->pixelPicked(picked_P[0], picked_P[1], picked_P[2], this);
}
......
......@@ -112,6 +112,16 @@ public:
/// rewritten: always return 0. For arbitrary slice use setTransformTranslation and getTranslationInVolume instead
virtual int getNumberOfSlices() const override;
/** This method is called when the arbitrary image has been picked in the arbitrary InteractiveViewer,
* The given coordinates is position where the plane was picked.
* We need to use the
*/
virtual void pixelPicked(double, double, double) override;
///@}
/// Get the current translation relatively to the volume
/// 0.0 means that the center of the slice is at the first border of the image volume
/// 1.0 means that the center of the slice is
......@@ -129,6 +139,10 @@ private:
/// update cPlus and cMinus
void updateTranslationExtremity();
/// get the current position of the image center in the parent coordinate system
/// i.e the image frame (given as homogeneous point, hence 4D)
void getImageCenterInParent(double[4]);
/// dimension of the whole image (kept here for simplifying code)
int* dimensions;
......@@ -138,14 +152,14 @@ private:
/// point of intersection of the line passing at the center of the image
/// in the z+ direction, i.e. (0,0,1) in the local frame.
/// This is the extreme possible point to translate C in the z+ direction.
/// This position is expressed in the parent frame coordinate system
/// This position is expressed in the parent frame coordinate system (the image coordinate system)
/// (required to compute getTranslationInVolume and set new translation)
QVector3D cPlus_P;
/// point of intersection of the line passing at the center of the image
/// in the z- direction, i.e. (0,0,-1) in the local frame.
/// This is the extreme possible point to translate C in the z- direction
/// This position is expressed in the parent frame coordinate system
/// This position is expressed in the parent frame coordinate system (the image coordinate system)
/// (required to compute getTranslationInVolume and set new translation)
QVector3D cMinus_P;
......
......@@ -612,7 +612,7 @@ void ImageComponent::pixelPicked(double x, double y, double z, SingleImageCompon
currentPixelPicked[1] = y;
currentPixelPicked[2] = z;
// Get Voxel Index Corrdinates
// Get Voxel Index Coordinates
int i, j, k;
getLastPixelPicked(&i, &j, &k);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment