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 ...@@ -105,21 +105,12 @@ void ArbitrarySingleImageComponent::setTransform(vtkSmartPointer<vtkTransform> t
// -------------------- resetTransform -------------------- // -------------------- resetTransform --------------------
void ArbitrarySingleImageComponent::resetTransform() { void ArbitrarySingleImageComponent::resetTransform() {
getTransform()->Identity(); setTransformRotation(0.0, 0.0, 0.0);
getTransform()->GetMatrix()->SetElement(0, 3, 0.0); setTransformTranslation(0.0, 0.0, 0.5);
getTransform()->GetMatrix()->SetElement(1, 3, 0.0);
getTransform()->GetMatrix()->SetElement(2, 3, dimensions[2] / 2.0 * spacing[2]);
getTransform()->Modified();
} }
// -------------------- setTransformRotation -------------------- // -------------------- setTransformRotation --------------------
void ArbitrarySingleImageComponent::setTransformRotation(double angleX, double angleY, double angleZ) { 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(); vtkSmartPointer<vtkMatrix4x4> T_P2L = vtkSmartPointer<vtkMatrix4x4>::New();
T_P2L->DeepCopy(getTransform()->GetMatrix()); T_P2L->DeepCopy(getTransform()->GetMatrix());
...@@ -135,8 +126,9 @@ void ArbitrarySingleImageComponent::setTransformRotation(double angleX, double a ...@@ -135,8 +126,9 @@ void ArbitrarySingleImageComponent::setTransformRotation(double angleX, double a
vtkSmartPointer<vtkMatrix4x4> T_P2L_rotation_only_inverse = vtkSmartPointer<vtkMatrix4x4>::New(); vtkSmartPointer<vtkMatrix4x4> T_P2L_rotation_only_inverse = vtkSmartPointer<vtkMatrix4x4>::New();
vtkMatrix4x4::Invert(T_P2L_rotation_only, T_P2L_rotation_only_inverse); 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]; double C_P[4];
T_P2L->MultiplyPoint(C_L, C_P); getImageCenterInParent(C_P);
vtkSmartPointer<vtkMatrix4x4> T_P2C = vtkSmartPointer<vtkMatrix4x4>::New(); vtkSmartPointer<vtkMatrix4x4> T_P2C = vtkSmartPointer<vtkMatrix4x4>::New();
T_P2C->Identity(); T_P2C->Identity();
...@@ -167,6 +159,7 @@ void ArbitrarySingleImageComponent::setTransformRotation(double angleX, double a ...@@ -167,6 +159,7 @@ void ArbitrarySingleImageComponent::setTransformRotation(double angleX, double a
if (checkCenter(checkRotation)) { if (checkCenter(checkRotation)) {
getTransform()->GetMatrix()->DeepCopy(checkRotation); getTransform()->GetMatrix()->DeepCopy(checkRotation);
getTransform()->Modified(); getTransform()->Modified();
updatePickPlane();
} }
} }
...@@ -191,14 +184,9 @@ void ArbitrarySingleImageComponent::setTransformTranslation(double x, double y, ...@@ -191,14 +184,9 @@ void ArbitrarySingleImageComponent::setTransformTranslation(double x, double y,
vtkSmartPointer<vtkMatrix4x4> T_P2L = vtkSmartPointer<vtkMatrix4x4>::New(); vtkSmartPointer<vtkMatrix4x4> T_P2L = vtkSmartPointer<vtkMatrix4x4>::New();
T_P2L->DeepCopy(getTransform()->GetMatrix()); T_P2L->DeepCopy(getTransform()->GetMatrix());
double C_L[4] = {dimensions[0]* spacing[0] / 2.0 - spacing[0] / 2.0, // get the image center in the parent (= image) reference frame
dimensions[1]* spacing[1] / 2.0 - spacing[1] / 2.0,
0.0,
1.0
};
double C_P[4]; 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], QVector3D centerToOrigin_P(T_P2L->GetElement(0, 3) - C_P[0],
T_P2L->GetElement(1, 3) - C_P[1], T_P2L->GetElement(1, 3) - C_P[1],
...@@ -213,29 +201,25 @@ void ArbitrarySingleImageComponent::setTransformTranslation(double x, double y, ...@@ -213,29 +201,25 @@ void ArbitrarySingleImageComponent::setTransformTranslation(double x, double y,
getTransform()->GetMatrix()->DeepCopy(T_P2L); getTransform()->GetMatrix()->DeepCopy(T_P2L);
getTransform()->Modified(); getTransform()->Modified();
updatePickPlane();
} }
// -------------------- updateTranslationExtremity -------------------- // -------------------- updateTranslationExtremity --------------------
void ArbitrarySingleImageComponent::updateTranslationExtremity() { void ArbitrarySingleImageComponent::updateTranslationExtremity() {
// compute C in image coordinates
double C_L[4] = {dimensions[0]* spacing[0] / 2.0 - spacing[0] / 2.0, double C_L[4] = {dimensions[0]* spacing[0] / 2.0 - spacing[0] / 2.0,
dimensions[1]* spacing[1] / 2.0 - spacing[1] / 2.0, dimensions[1]* spacing[1] / 2.0 - spacing[1] / 2.0,
0.0, 0.0,
1.0 1.0
}; };
vtkSmartPointer<vtkMatrix4x4> T_P2L = vtkSmartPointer<vtkMatrix4x4>::New();
T_P2L->DeepCopy(getTransform()->GetMatrix());
double C_P[4]; 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}; 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]; 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 // 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]); 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() { ...@@ -284,37 +268,30 @@ void ArbitrarySingleImageComponent::updateTranslationExtremity() {
double ArbitrarySingleImageComponent::getTranslationInVolume() { double ArbitrarySingleImageComponent::getTranslationInVolume() {
updateTranslationExtremity(); updateTranslationExtremity();
// compute center in P reference frame // get the image center in the parent (= image) 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());
double C_P[4]; double C_P[4];
T_P2L->MultiplyPoint(C_L, C_P); getImageCenterInParent(C_P);
QVector3D C(C_P[0], C_P[1], C_P[2]);
// C- = 0.0 // C- = 0.0
// C+ = 1.0 // C+ = 1.0
// C-C = k C-C+ // C-C = k C-C+
// k = C-C / 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(); double k = QVector3D(C - cMinus_P).length() / QVector3D(cPlus_P - cMinus_P).length();
return k; return k;
} }
// -------------------- checkCenter -------------------- // -------------------- checkCenter --------------------
bool ArbitrarySingleImageComponent::checkCenter(vtkSmartPointer<vtkMatrix4x4> transform) { 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}; bool inside = pointInsideVolume(QVector3D(C_transform[0], C_transform[1], C_transform[2]));
double centerInImage[4];
transform->MultiplyPoint(centerInFrame, centerInImage);
bool inside = pointInsideVolume(QVector3D(centerInImage[0], centerInImage[1], centerInImage[2]));
// positive check only is displacement will keep the center inside the box // positive check only is displacement will keep the center inside the box
return inside; return inside;
...@@ -323,7 +300,7 @@ bool ArbitrarySingleImageComponent::checkCenter(vtkSmartPointer<vtkMatrix4x4> tr ...@@ -323,7 +300,7 @@ bool ArbitrarySingleImageComponent::checkCenter(vtkSmartPointer<vtkMatrix4x4> tr
// -------------------- pointInsideVolume -------------------- // -------------------- pointInsideVolume --------------------
bool ArbitrarySingleImageComponent::pointInsideVolume(QVector3D p) { bool ArbitrarySingleImageComponent::pointInsideVolume(QVector3D p) {
QVector3D pRounded = roundTo4Decimals(p); QVector3D pRounded = roundTo4Decimals(p);
return (pRounded.x() >= 0.0 return (pRounded.x() >= 0.0
&& pRounded.x() <= dimensions[0] * spacing[0] && pRounded.x() <= dimensions[0] * spacing[0]
&& pRounded.y() >= 0.0 && pRounded.y() >= 0.0
&& pRounded.y() <= dimensions[1] * spacing[1] && pRounded.y() <= dimensions[1] * spacing[1]
...@@ -331,7 +308,15 @@ bool ArbitrarySingleImageComponent::pointInsideVolume(QVector3D p) { ...@@ -331,7 +308,15 @@ bool ArbitrarySingleImageComponent::pointInsideVolume(QVector3D p) {
&& pRounded.z() <= dimensions[2] * spacing[2]); && 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 { ...@@ -383,6 +368,17 @@ int ArbitrarySingleImageComponent::getNumberOfSlices() const {
return 0; 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: ...@@ -112,6 +112,16 @@ public:
/// rewritten: always return 0. For arbitrary slice use setTransformTranslation and getTranslationInVolume instead /// rewritten: always return 0. For arbitrary slice use setTransformTranslation and getTranslationInVolume instead
virtual int getNumberOfSlices() const override; 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 /// 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 /// 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 /// 1.0 means that the center of the slice is
...@@ -129,6 +139,10 @@ private: ...@@ -129,6 +139,10 @@ private:
/// update cPlus and cMinus /// update cPlus and cMinus
void updateTranslationExtremity(); 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) /// dimension of the whole image (kept here for simplifying code)
int* dimensions; int* dimensions;
...@@ -138,14 +152,14 @@ private: ...@@ -138,14 +152,14 @@ private:
/// point of intersection of the line passing at the center of the image /// 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. /// 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 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) /// (required to compute getTranslationInVolume and set new translation)
QVector3D cPlus_P; QVector3D cPlus_P;
/// point of intersection of the line passing at the center of the image /// 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. /// 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 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) /// (required to compute getTranslationInVolume and set new translation)
QVector3D cMinus_P; QVector3D cMinus_P;
......
...@@ -612,7 +612,7 @@ void ImageComponent::pixelPicked(double x, double y, double z, SingleImageCompon ...@@ -612,7 +612,7 @@ void ImageComponent::pixelPicked(double x, double y, double z, SingleImageCompon
currentPixelPicked[1] = y; currentPixelPicked[1] = y;
currentPixelPicked[2] = z; currentPixelPicked[2] = z;
// Get Voxel Index Corrdinates // Get Voxel Index Coordinates
int i, j, k; int i, j, k;
getLastPixelPicked(&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