Skip to content

Commit

Permalink
ENH: Pull request SlicerRt#124 fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
MichaelColonel committed Jan 13, 2020
1 parent 95dd9f2 commit c778013
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 17 deletions.
97 changes: 83 additions & 14 deletions Beams/MRML/vtkMRMLRTBeamNode.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
#include <vtkTable.h>
#include <vtkCellArray.h>
#include <vtkAppendPolyData.h>
#include <vtkCubeSource.h>

//------------------------------------------------------------------------------
const char* vtkMRMLRTBeamNode::NEW_BEAM_NODE_NAME_PREFIX = "NewBeam_";
Expand Down Expand Up @@ -515,27 +516,27 @@ void vtkMRMLRTBeamNode::CreateBeamPolyData(vtkPolyData* beamModelPolyData/*=null
vtkErrorMacro("CreateBeamPolyData: Invalid beam node");
return;
}

vtkMRMLTableNode* mlcTableNode = nullptr;

vtkIdType nofLeaves = 0;
vtkIdType nofLeafPairs = 0;

// MLC boundary data
vtkMRMLDoubleArrayNode* arrayNode = this->GetMLCBoundaryDoubleArrayNode();
vtkDoubleArray* mlcBoundArray = nullptr;
if (arrayNode)
{
mlcBoundArray = arrayNode->GetArray();
nofLeaves = mlcBoundArray ? (mlcBoundArray->GetNumberOfTuples() - 1) : 0;
nofLeafPairs = mlcBoundArray ? (mlcBoundArray->GetNumberOfTuples() - 1) : 0;
}

// MLC position data
if (nofLeaves)
if (nofLeafPairs)
{
mlcTableNode = this->GetMLCPositionTableNode();
if (mlcTableNode && (mlcTableNode->GetNumberOfRows() == nofLeaves))
if (mlcTableNode && (mlcTableNode->GetNumberOfRows() == nofLeafPairs))
{
vtkDebugMacro("CreateBeamPolyData: Valid MLC nodes, number of leaves: " << nofLeaves);
vtkDebugMacro("CreateBeamPolyData: Valid MLC nodes, number of leaf pairs: " << nofLeafPairs);
}
else
{
Expand All @@ -558,13 +559,13 @@ void vtkMRMLRTBeamNode::CreateBeamPolyData(vtkPolyData* beamModelPolyData/*=null
bool typeMLCY = !strncmp( "MLCY", mlcName, strlen("MLCY"));

// copy MLC data for easier processing
for ( vtkIdType leaf = 0; leaf < nofLeaves; leaf++)
for ( vtkIdType leafPair = 0; leafPair < nofLeafPairs; leafPair++)
{
vtkTable* table = mlcTableNode->GetTable();
double boundBegin = mlcBoundArray->GetTuple1(leaf);
double boundEnd = mlcBoundArray->GetTuple1(leaf + 1);
double pos1 = table->GetValue( leaf, 0).ToDouble();
double pos2 = table->GetValue( leaf, 1).ToDouble();
double boundBegin = mlcBoundArray->GetTuple1(leafPair);
double boundEnd = mlcBoundArray->GetTuple1(leafPair + 1);
double pos1 = table->GetValue( leafPair, 0).ToDouble();
double pos2 = table->GetValue( leafPair, 1).ToDouble();

mlc.push_back({ boundBegin, boundEnd, pos1, pos2 });
}
Expand Down Expand Up @@ -737,10 +738,78 @@ void vtkMRMLRTBeamNode::CreateBeamPolyData(vtkPolyData* beamModelPolyData/*=null
}

//---------------------------------------------------------------------------
vtkPolyData* vtkMRMLRTBeamNode::CreateMultiLeafCollimatorPolyData()
vtkPolyData* vtkMRMLRTBeamNode::CreateMultiLeafCollimatorModelPolyData()
{
//TODO: Create beam limiting device poly data here
return nullptr;
vtkIdType nofLeafPairs = 0;
// MLC boundary data
vtkMRMLDoubleArrayNode* arrayNode = this->GetMLCBoundaryDoubleArrayNode();
vtkDoubleArray* mlcBoundArray = nullptr;
if (arrayNode)
{
mlcBoundArray = arrayNode->GetArray();
nofLeafPairs = mlcBoundArray ? (mlcBoundArray->GetNumberOfTuples() - 1) : 0;
}

// MLC position data
vtkMRMLTableNode* mlcTableNode = nullptr;
if (nofLeafPairs)
{
mlcTableNode = this->GetMLCPositionTableNode();
if (mlcTableNode && (mlcTableNode->GetNumberOfRows() == nofLeafPairs))
{
vtkDebugMacro("CreateMultiLeafCollimatorPolyData: Valid MLC nodes, number of leaf pairs: " << nofLeafPairs);
}
else
{
vtkErrorMacro("CreateMultiLeafCollimatorPolyData: Invalid MLC nodes, or " \
"number of MLC boundaries and positions are different");
mlcTableNode = nullptr;
}
}

// Check that we have MLC
// append a leaf pair to form MLC polydata
double isoCenterToMLCDistance = this->SAD - SourceToMultiLeafCollimatorDistance;
auto append = vtkSmartPointer<vtkAppendPolyData>::New();
if (mlcTableNode)
{
const char* mlcName = mlcTableNode->GetName();
bool typeMLCX = !strncmp( "MLCX", mlcName, strlen("MLCX"));
bool typeMLCY = !strncmp( "MLCY", mlcName, strlen("MLCY"));

// create polydata for a leaf pair
for ( vtkIdType leafPair = 0; leafPair < nofLeafPairs; leafPair++)
{
vtkTable* table = mlcTableNode->GetTable();
double boundBegin = mlcBoundArray->GetTuple1(leafPair);
double boundEnd = mlcBoundArray->GetTuple1(leafPair + 1);
double pos1 = table->GetValue( leafPair, 0).ToDouble();
double pos2 = table->GetValue( leafPair, 1).ToDouble();

auto leaf1 = vtkSmartPointer<vtkCubeSource>::New();
auto leaf2 = vtkSmartPointer<vtkCubeSource>::New();
if (typeMLCX)
{
leaf1->SetBounds( pos1 - 20., pos1, boundBegin, BoundEnd, -isoCenterToMLCDistance, isoCenterToMLCDistance);
leaf2->SetBounds( pos2, pos2 + 20., boundBegin, BoundEnd, -isoCenterToMLCDistance, isoCenterToMLCDistance);
}
else if (typeMLCY)
{
leaf1->SetBounds( boundBegin, BoundEnd, pos1 - 20., pos1, -isoCenterToMLCDistance, isoCenterToMLCDistance);
leaf2->SetBounds( boundBegin, BoundEnd, pos2, pos2 + 20., -isoCenterToMLCDistance, isoCenterToMLCDistance);
}
leaf1->Update();
leaf2->Update();
append->AddInputData(leaf1->GetOutput());
append->AddInputData(leaf2->GetOutput());
}
}
append->Update();

vtkPolyData* mlcModelPolyData = vtkPolyData::New();
mlcModelPolyData->ShallowCopy(append->GetOutput());

return mlcModelPolyData;
}

//---------------------------------------------------------------------------
Expand Down
2 changes: 1 addition & 1 deletion Beams/MRML/vtkMRMLRTBeamNode.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ class VTK_SLICER_BEAMS_MODULE_MRML_EXPORT vtkMRMLRTBeamNode : public vtkMRMLMode
virtual void CreateDefaultTransformNode();

/// Create beam limiting device (MLC and jaws) polydata for model node
virtual vtkPolyData* CreateMultiLeafCollimatorPolyData();
virtual vtkPolyData* CreateMultiLeafCollimatorModelPolyData();

/// Create transform node that places the beam poly data in the right position based on geometry.
/// Always creates a new transform node.
Expand Down
2 changes: 1 addition & 1 deletion Beams/MRML/vtkMRMLRTIonBeamNode.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ void vtkMRMLRTIonBeamNode::CreateNewBeamTransformNode()
}

//---------------------------------------------------------------------------
vtkPolyData* vtkMRMLRTIonBeamNode::CreateMultiLeafCollimatorPolyData()
vtkPolyData* vtkMRMLRTIonBeamNode::CreateMultiLeafCollimatorModelPolyData()
{
//TODO: Create beam limiting device poly data here
return nullptr;
Expand Down
2 changes: 1 addition & 1 deletion Beams/MRML/vtkMRMLRTIonBeamNode.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ class VTK_SLICER_BEAMS_MODULE_MRML_EXPORT vtkMRMLRTIonBeamNode : public vtkMRMLR
void CreateDefaultTransformNode() override;

/// Create beam limiting device (MLC and jaws) polydata for model node
vtkPolyData* CreateMultiLeafCollimatorPolyData() override;
vtkPolyData* CreateMultiLeafCollimatorModelPolyData() override;

/// Create transform node that places the beam poly data in the right position based on geometry.
/// Always creates a new transform node.
Expand Down

0 comments on commit c778013

Please sign in to comment.