Skip to content

Commit

Permalink
DOC: WIP: Issue Slicer#7179 Curved Planar Reformation
Browse files Browse the repository at this point in the history
Code formatting
  • Loading branch information
Leengit committed Jan 16, 2025
1 parent 8811ed8 commit 4eb2ecf
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 87 deletions.
135 changes: 65 additions & 70 deletions Libs/MRML/Logic/vtkMRMLSliceLogic.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -1032,8 +1032,7 @@ void vtkMRMLSliceLogic::UpdateReconstructionSlab(vtkMRMLSliceLogic* sliceLogic,
}

//----------------------------------------------------------------------------
void
vtkMRMLSliceLogic::CurvedPlanarReformationInit()
void vtkMRMLSliceLogic::CurvedPlanarReformationInit()
{
// there is no need to compute displacement for each slice, we just compute for every n-th to make computation faster
// and inverse computation more robust (less contradiction because of there is less overlapping between neighbor
Expand All @@ -1042,10 +1041,9 @@ vtkMRMLSliceLogic::CurvedPlanarReformationInit()
}

//----------------------------------------------------------------------------
bool
vtkMRMLSliceLogic::CurvedPlanarReformationGetPointsProjectedToPlane(vtkPoints * pointsArrayIn,
vtkMatrix4x4 * transformWorldToPlane,
vtkPoints * pointsArrayOut)
bool vtkMRMLSliceLogic::CurvedPlanarReformationGetPointsProjectedToPlane(vtkPoints* pointsArrayIn,
vtkMatrix4x4* transformWorldToPlane,
vtkPoints* pointsArrayOut)
{
if (pointsArrayIn == nullptr)
{
Expand Down Expand Up @@ -1074,14 +1072,14 @@ vtkMRMLSliceLogic::CurvedPlanarReformationGetPointsProjectedToPlane(vtkPoints *

const vtkIdType numPoints = pointsArrayIn->GetNumberOfPoints();
pointsArrayOut->SetNumberOfPoints(numPoints);
double pIn[4] = { 0.0, 0.0, 0.0, 1.0 };
double pMiddle[4] = { 0.0, 0.0, 0.0, 1.0 };
double pOut[4] = { 0.0, 0.0, 0.0, 1.0 };
double pIn[4] = { 0.0, 0.0, 0.0, 1.0 };
double pMiddle[4] = { 0.0, 0.0, 0.0, 1.0 };
double pOut[4] = { 0.0, 0.0, 0.0, 1.0 };

for (vtkIdType i = 0; i < numPoints; ++i)
{
// Note: uses only the first three elements of pIn
pointsArrayIn->GetPoint(i, static_cast<double *>(pIn)); // requires double[3]
pointsArrayIn->GetPoint(i, static_cast<double*>(pIn)); // requires double[3]
// Point positions in the plane coordinate system:
transformWorldToPlane->MultiplyPoint(pIn, pMiddle);
// Projected point positions in the plane coordinate system:
Expand All @@ -1094,15 +1092,14 @@ vtkMRMLSliceLogic::CurvedPlanarReformationGetPointsProjectedToPlane(vtkPoints *
}

//----------------------------------------------------------------------------
bool
vtkMRMLSliceLogic::CurvedPlanarReformationComputeStraighteningTransform(
vtkMRMLTransformNode * transformToStraightenedNode,
vtkMRMLMarkupsCurveNode * curveNode,
const double sliceSizeMm[2],
double outputSpacingMm,
bool stretching,
double rotationDeg,
vtkMRMLModelNode * reslicingPlanesModelNode)
bool vtkMRMLSliceLogic::CurvedPlanarReformationComputeStraighteningTransform(
vtkMRMLTransformNode* transformToStraightenedNode,
vtkMRMLMarkupsCurveNode* curveNode,
const double sliceSizeMm[2],
double outputSpacingMm,
bool stretching,
double rotationDeg,
vtkMRMLModelNode* reslicingPlanesModelNode)
{
if (transformToStraightenedNode == nullptr)
{
Expand Down Expand Up @@ -1132,13 +1129,13 @@ vtkMRMLSliceLogic::CurvedPlanarReformationComputeStraighteningTransform(
"Resampling curve failed");
return false;
}
vtkMRMLMarkupsCurveNode * resampledCurveNode = vtkMRMLMarkupsCurveNode::SafeDownCast(
vtkMRMLMarkupsCurveNode* resampledCurveNode = vtkMRMLMarkupsCurveNode::SafeDownCast(
this->GetMRMLScene()->AddNewNodeByClass("vtkMRMLMarkupsCurveNode", "CurvedPlanarReformat_resampled_curve_temp"));
resampledCurveNode->SetNumberOfPointsPerInterpolatingSegment(1);
resampledCurveNode->SetCurveTypeToLinear();
resampledCurveNode->SetControlPointPositionsWorld(sampledPoints);

vtkPoints * resampledCurvePointsWorld = resampledCurveNode->GetCurvePointsWorld();
vtkPoints* resampledCurvePointsWorld = resampledCurveNode->GetCurvePointsWorld();
if (resampledCurvePointsWorld == nullptr || resampledCurvePointsWorld->GetNumberOfPoints() < 3)
{
vtkErrorMacro("vtkMRMLSliceLogic::CurvedPlanarReformationComputeStraighteningTransform failed: "
Expand Down Expand Up @@ -1193,7 +1190,7 @@ vtkMRMLSliceLogic::CurvedPlanarReformationComputeStraighteningTransform(
{
// X axis = average X axis of curve, to minimize torsion (and so have a
// simple displacement field, which can be robustly inverted)
double sumCurveAxisX_RAS[3] = { 0.0, 0.0, 0.0 };
double sumCurveAxisX_RAS[3] = { 0.0, 0.0, 0.0 };
const int numberOfPoints = resampledCurveNode->GetNumberOfControlPoints();
for (int gridK = 0; gridK < numberOfPoints; ++gridK)
{
Expand Down Expand Up @@ -1248,7 +1245,7 @@ vtkMRMLSliceLogic::CurvedPlanarReformationComputeStraighteningTransform(
// Project curve points to grid YZ plane
vtkSmartPointer<vtkMatrix4x4> transformFromGridYZPlane = vtkSmartPointer<vtkMatrix4x4>::New();
transformFromGridYZPlane->Identity();
const double * origin = curveNodePlane->GetOrigin();
const double* origin = curveNodePlane->GetOrigin();
for (int i = 0; i < 3; ++i)
{
transformFromGridYZPlane->SetElement(i, 0, transformGridAxisY[i]);
Expand All @@ -1259,7 +1256,7 @@ vtkMRMLSliceLogic::CurvedPlanarReformationComputeStraighteningTransform(
vtkSmartPointer<vtkMatrix4x4> transformToGridYZPlane = vtkSmartPointer<vtkMatrix4x4>::New();
vtkMatrix4x4::Invert(transformFromGridYZPlane, transformToGridYZPlane);

vtkPoints * originalCurvePointsArray = curveNode->GetCurvePoints();
vtkPoints* originalCurvePointsArray = curveNode->GetCurvePoints();
vtkSmartPointer<vtkPoints> curvePointsProjected_RAS = vtkSmartPointer<vtkPoints>::New();
this->CurvedPlanarReformationGetPointsProjectedToPlane(
originalCurvePointsArray, transformToGridYZPlane, curvePointsProjected_RAS);
Expand Down Expand Up @@ -1292,9 +1289,9 @@ vtkMRMLSliceLogic::CurvedPlanarReformationComputeStraighteningTransform(
}

// Origin (makes the grid centered at the curve)
const double curveLength = resampledCurveNode->GetCurveLengthWorld();
const double * origin = curveNodePlane->GetOrigin();
double transformGridOrigin[3] = { origin[0], origin[1], origin[2] };
const double curveLength = resampledCurveNode->GetCurveLengthWorld();
const double* origin = curveNodePlane->GetOrigin();
double transformGridOrigin[3] = { origin[0], origin[1], origin[2] };
for (int i = 0; i < 3; ++i)
{
transformGridOrigin[i] -= transformGridAxisX[i] * sliceSizeMm[0] / 2.0;
Expand All @@ -1307,9 +1304,9 @@ vtkMRMLSliceLogic::CurvedPlanarReformationComputeStraighteningTransform(
// to the straightened volume slice.
// The grid transform contains one vector at the corner of each slice.
// The transform is in the same space and orientation as the straightened volume.
const int numberOfSlices = resampledCurveNode->GetNumberOfControlPoints();
const int gridDimensions[3] = { 2, 2, numberOfSlices };
const double gridSpacing[3] = { sliceSizeMm[0], sliceSizeMm[1], resamplingCurveSpacing };
const int numberOfSlices = resampledCurveNode->GetNumberOfControlPoints();
const int gridDimensions[3] = { 2, 2, numberOfSlices };
const double gridSpacing[3] = { sliceSizeMm[0], sliceSizeMm[1], resamplingCurveSpacing };
vtkSmartPointer<vtkMatrix4x4> gridDirectionMatrixArray = vtkSmartPointer<vtkMatrix4x4>::New();
gridDirectionMatrixArray->Identity();
for (int i = 0; i < 3; ++i)
Expand Down Expand Up @@ -1338,13 +1335,13 @@ vtkMRMLSliceLogic::CurvedPlanarReformationComputeStraighteningTransform(
curveCoordinateSystemGeneratorWorld->SetInputData(resampledCurveNode->GetCurveWorld());
curveCoordinateSystemGeneratorWorld->SetPreferredInitialNormalVector(transformGridAxisX);
curveCoordinateSystemGeneratorWorld->Update();
vtkPolyData * curvePoly = curveCoordinateSystemGeneratorWorld->GetOutput();
vtkPointData * pointData = curvePoly->GetPointData();
vtkDoubleArray * normals = vtkDoubleArray::SafeDownCast(
vtkPolyData* curvePoly = curveCoordinateSystemGeneratorWorld->GetOutput();
vtkPointData* pointData = curvePoly->GetPointData();
vtkDoubleArray* normals = vtkDoubleArray::SafeDownCast(
pointData->GetAbstractArray(curveCoordinateSystemGeneratorWorld->GetNormalsArrayName()));
vtkDoubleArray * binormals = vtkDoubleArray::SafeDownCast(
vtkDoubleArray* binormals = vtkDoubleArray::SafeDownCast(
pointData->GetAbstractArray(curveCoordinateSystemGeneratorWorld->GetBinormalsArrayName()));
// vtkDoubleArray * tangents = vtkDoubleArray::SafeDownCast(
// vtkDoubleArray* tangents = vtkDoubleArray::SafeDownCast(
// pointData->GetAbstractArray(curveCoordinateSystemGeneratorWorld->GetTangentsArrayName()));

// Compute displacements
Expand All @@ -1367,12 +1364,12 @@ vtkMRMLSliceLogic::CurvedPlanarReformationComputeStraighteningTransform(
// curvePoint_RAS = curvePointToWorldArray[0:3, 3]
//
// But now we get the values from our own coordinate system generator:
const int curvePointIndex = resampledCurveNode->GetCurvePointIndexFromControlPointIndex(gridK);
const double * curveAxisX_RASVec = normals->GetTuple3(curvePointIndex);
const double * curveAxisY_RASVec = binormals->GetTuple3(curvePointIndex);
const double * curvePoint_RAS = curvePoly->GetPoint(curvePointIndex);
const int curvePointIndex = resampledCurveNode->GetCurvePointIndexFromControlPointIndex(gridK);
const double* curveAxisX_RASVec = normals->GetTuple3(curvePointIndex);
const double* curveAxisY_RASVec = binormals->GetTuple3(curvePointIndex);
const double* curvePoint_RAS = curvePoly->GetPoint(curvePointIndex);

vtkPlaneSource * plane = vtkPlaneSource::SafeDownCast(this->SliceModelNode->GetPolyDataConnection()->GetProducer());
vtkPlaneSource* plane = vtkPlaneSource::SafeDownCast(this->SliceModelNode->GetPolyDataConnection()->GetProducer());
for (int gridJ = 0; gridJ < gridDimensions[1]; ++gridJ)
{
for (int gridI = 0; gridI < gridDimensions[0]; ++gridI)
Expand Down Expand Up @@ -1418,9 +1415,9 @@ vtkMRMLSliceLogic::CurvedPlanarReformationComputeStraighteningTransform(
}
}

vtkGridTransform * transformGrid =
vtkGridTransform* transformGrid =
vtkGridTransform::SafeDownCast(transformToStraightenedNode->GetTransformFromParent());
vtkImageData * displacementGrid = transformGrid->GetDisplacementGrid();
vtkImageData* displacementGrid = transformGrid->GetDisplacementGrid();
displacementGrid->GetPointData()->GetScalars()->Modified();
displacementGrid->Modified();

Expand All @@ -1442,15 +1439,14 @@ vtkMRMLSliceLogic::CurvedPlanarReformationComputeStraighteningTransform(
}

//----------------------------------------------------------------------------
bool
vtkMRMLSliceLogic::CurvedPlanarReformationStraightenVolume(vtkMRMLScalarVolumeNode * outputStraightenedVolume,
vtkMRMLScalarVolumeNode * volumeNode,
const double outputStraightenedVolumeSpacing[3],
vtkMRMLTransformNode * straighteningTransformNode)
bool vtkMRMLSliceLogic::CurvedPlanarReformationStraightenVolume(vtkMRMLScalarVolumeNode* outputStraightenedVolume,
vtkMRMLScalarVolumeNode* volumeNode,
const double outputStraightenedVolumeSpacing[3],
vtkMRMLTransformNode* straighteningTransformNode)
{
// Compute straightened volume (useful for example for visualization of curved vessels)

if (outputStraightenedVolume == nullptr)
if (outputStraightenedVolume == nullptr)
{
vtkErrorMacro("vtkMRMLSliceLogic::CurvedPlanarReformationStraightenVolume failed: "
"outputStraightenedVolume not supplied");
Expand All @@ -1469,7 +1465,7 @@ vtkMRMLSliceLogic::CurvedPlanarReformationStraightenVolume(vtkMRMLScalarVolumeNo
return false;
}

vtkOrientedGridTransform * gridTransform = vtkOrientedGridTransform::SafeDownCast(
vtkOrientedGridTransform* gridTransform = vtkOrientedGridTransform::SafeDownCast(
straighteningTransformNode->GetTransformFromParentAs("vtkOrientedGridTransform"));
if (!gridTransform)
{
Expand All @@ -1479,9 +1475,9 @@ vtkMRMLSliceLogic::CurvedPlanarReformationStraightenVolume(vtkMRMLScalarVolumeNo
}

// Get transformation grid geometry
vtkMatrix4x4 * gridIjkToRasDirectionMatrix = gridTransform->GetGridDirectionMatrix();
vtkImageData * gridTransformImage = gridTransform->GetDisplacementGrid();
double gridOrigin[3] = { 0.0, 0.0, 0.0 };
vtkMatrix4x4* gridIjkToRasDirectionMatrix = gridTransform->GetGridDirectionMatrix();
vtkImageData* gridTransformImage = gridTransform->GetDisplacementGrid();
double gridOrigin[3] = { 0.0, 0.0, 0.0 };
gridTransformImage->GetOrigin(gridOrigin);
double gridSpacing[3] = { 0.0, 0.0, 0.0 };
gridTransformImage->GetSpacing(gridSpacing);
Expand Down Expand Up @@ -1523,9 +1519,9 @@ vtkMRMLSliceLogic::CurvedPlanarReformationStraightenVolume(vtkMRMLScalarVolumeNo
outputStraightenedVolume->SetIJKToRASMatrix(straightenedVolumeIJKToRASMatrix);

// Resample input volume to straightened volume
vtkMRMLApplicationLogic * appLogic = this->GetMRMLApplicationLogic();
std::string resampleScalarVectorDWIVolumeString = "ResampleScalarVectorDWIVolume";
bool found = appLogic->IsVolumeResamplerRegistered(resampleScalarVectorDWIVolumeString);
vtkMRMLApplicationLogic* appLogic = this->GetMRMLApplicationLogic();
std::string resampleScalarVectorDWIVolumeString = "ResampleScalarVectorDWIVolume";
bool found = appLogic->IsVolumeResamplerRegistered(resampleScalarVectorDWIVolumeString);
if (!found)
{
vtkErrorMacro(
Expand All @@ -1534,12 +1530,12 @@ vtkMRMLSliceLogic::CurvedPlanarReformationStraightenVolume(vtkMRMLScalarVolumeNo
return false;
}

std::string resamplerName = resampleScalarVectorDWIVolumeString;
vtkMRMLVolumeNode * inputVolume = volumeNode;
vtkMRMLVolumeNode * outputVolume = outputStraightenedVolume;
vtkMRMLTransformNode * resamplingTransform = straighteningTransformNode;
vtkMRMLVolumeNode * referenceVolume = outputStraightenedVolume;
int interpolationType =
std::string resamplerName = resampleScalarVectorDWIVolumeString;
vtkMRMLVolumeNode* inputVolume = volumeNode;
vtkMRMLVolumeNode* outputVolume = outputStraightenedVolume;
vtkMRMLTransformNode* resamplingTransform = straighteningTransformNode;
vtkMRMLVolumeNode* referenceVolume = outputStraightenedVolume;
int interpolationType =
(volumeNode->IsA("vtkMRMLLabelMapVolumeNode") ? vtkMRMLAbstractVolumeResampler::InterpolationTypeNearestNeighbor
: vtkMRMLAbstractVolumeResampler::InterpolationTypeBSpline);
int windowedSincFunction = vtkMRMLAbstractVolumeResampler::WindowedSincFunctionCosine;
Expand All @@ -1561,7 +1557,7 @@ vtkMRMLSliceLogic::CurvedPlanarReformationStraightenVolume(vtkMRMLScalarVolumeNo
}

outputStraightenedVolume->CreateDefaultDisplayNodes();
vtkMRMLDisplayNode * volumeDisplayNode = volumeNode->GetDisplayNode();
vtkMRMLDisplayNode* volumeDisplayNode = volumeNode->GetDisplayNode();
if (volumeDisplayNode)
{
outputStraightenedVolume->GetDisplayNode()->CopyContent(volumeDisplayNode);
Expand All @@ -1570,10 +1566,9 @@ vtkMRMLSliceLogic::CurvedPlanarReformationStraightenVolume(vtkMRMLScalarVolumeNo
}

//----------------------------------------------------------------------------
bool
vtkMRMLSliceLogic::CurvedPlanarReformationProjectVolume(vtkMRMLScalarVolumeNode * outputProjectedVolume,
vtkMRMLScalarVolumeNode * inputStraightenedVolume,
int projectionAxisIndex)
bool vtkMRMLSliceLogic::CurvedPlanarReformationProjectVolume(vtkMRMLScalarVolumeNode* outputProjectedVolume,
vtkMRMLScalarVolumeNode* inputStraightenedVolume,
int projectionAxisIndex)
{
// Create panoramic volume by mean intensity projection along an axis of the straightened volume

Expand Down Expand Up @@ -1601,7 +1596,7 @@ vtkMRMLSliceLogic::CurvedPlanarReformationProjectVolume(vtkMRMLScalarVolumeNode
outputProjectedVolume->SetAndObserveImageData(projectedImageData);

// Get the image data from the input straightened volume
vtkImageData * straightenedImageData = inputStraightenedVolume->GetImageData();
vtkImageData* straightenedImageData = inputStraightenedVolume->GetImageData();
if (!straightenedImageData)
{
vtkErrorMacro(
Expand Down Expand Up @@ -1634,7 +1629,7 @@ vtkMRMLSliceLogic::CurvedPlanarReformationProjectVolume(vtkMRMLScalarVolumeNode
for (int z = 0; z < dims[2]; ++z)
{
double sum = 0.0;
int count = 0;
int count = 0;
for (int x = 0; x < dims[0]; ++x)
{
const int index = x + dims[0] * (y + dims[1] * z);
Expand All @@ -1653,7 +1648,7 @@ vtkMRMLSliceLogic::CurvedPlanarReformationProjectVolume(vtkMRMLScalarVolumeNode
for (int z = 0; z < dims[2]; ++z)
{
double sum = 0.0;
int count = 0;
int count = 0;
for (int y = 0; y < dims[1]; ++y)
{
const int index = x + dims[0] * (y + dims[1] * z);
Expand All @@ -1672,7 +1667,7 @@ vtkMRMLSliceLogic::CurvedPlanarReformationProjectVolume(vtkMRMLScalarVolumeNode
for (int y = 0; y < dims[1]; ++y)
{
double sum = 0.0;
int count = 0;
int count = 0;
for (int z = 0; z < dims[2]; ++z)
{
int index = x + dims[0] * (y + dims[1] * z);
Expand Down
Loading

0 comments on commit 4eb2ecf

Please sign in to comment.