}
}
+ void SetPanelShift(double x, double y)
+ {
+ m_PanelShift[0] = x;
+ m_PanelShift[1] = y;
+ }
// itkSetMacro(IsoCenter, OutputPointType);
// itkGetConstReferenceMacro(IsoCenter, OutputPointType)
// itkSetMacro( SourceToScreen, double );
double m_SourceToAxis;
OutputPixelType m_EdgePaddingValue;
double m_ProjectionAngle;
+ double m_PanelShift[2];
// Output image info
OutputSizeType m_OutputSize; // Size of the output image
#include "clitkBackProjectImageFilter.h"
#include "itkContinuousIndex.h"
#include "vnl/vnl_math.h"
+#include "itkLinearInterpolateImageFunction.h"
namespace clitk
{
this->m_SourceToAxis = 1000.0;
this->m_EdgePaddingValue = itk::NumericTraits<OutputPixelType>::Zero;//density images
this->m_RigidTransformMatrix.SetIdentity();
+ this->m_PanelShift[0] = 0.;
+ this->m_PanelShift[1] = 0.;
//Parameters for output
this->m_OutputSpacing.Fill(1);
{
//Projection pointer
InputImageConstPointer inputPtr=this->GetInput();
- InputPixelType * beginPtr=const_cast<InputPixelType *>(this->GetInput()->GetBufferPointer());
- InputPixelType * pp;
//Volume pointer
OutputImagePointer outputPTr= this->GetOutput();
OutputIndexType oIndex;
ContinuousInputIndexType iIndex;
InputSizeType inputSize=inputPtr->GetLargestPossibleRegion().GetSize();
- double dx,dy,dxm,dym;
- int lx, ly;
//Get the first output coordinate
oIndex=iterator.GetIndex();//costly but only once a thread
//Compute the first input coordinate (invert Y/X)
homInputPoint= (m_ProjectionMatrix * homOutputPoint);
- iPoint[0]=-homInputPoint[0]/homInputPoint[2];
- iPoint[1]=homInputPoint[1]/homInputPoint[2];
-
+ iPoint[0]=-homInputPoint[0]/homInputPoint[2] + m_PanelShift[0];
+ iPoint[1]=homInputPoint[1]/homInputPoint[2] + m_PanelShift[1];
+
+ typedef itk::LinearInterpolateImageFunction< InputImageType, double > InterpolatorType;
+ typename InterpolatorType::Pointer interpolator = InterpolatorType::New();
+ interpolator->SetInputImage(this->GetInput());
+
//Run over all output voxels
for (unsigned int i=0; i<outputSizeForThread[2]; i++)
{
{
for (unsigned int k=0; k<outputSizeForThread[0]; k++)
{
- iPoint[0]=homInputPoint[0]/homInputPoint[2];
- iPoint[1]=homInputPoint[1]/homInputPoint[2];
+ iPoint[0]=-homInputPoint[0]/homInputPoint[2] + m_PanelShift[0];
+ iPoint[1]=homInputPoint[1]/homInputPoint[2] + m_PanelShift[1];
//Check wether inside, convert to index (use modified with correct origin)
- if( m_ModifiedInput->TransformPhysicalPointToContinuousIndex(iPoint, iIndex) )
- {
- //Own (fast bilinear) interpolation
- lx = (int)floor(iIndex[0]); dx = iIndex[0]-lx; dxm = 1.-dx;
- ly = (int)floor(iIndex[1]); dy = iIndex[1]-ly; dym = 1.-dy;
- pp = beginPtr + ly*inputSize[0]+lx;
- value =static_cast<OutputPixelType>( ( dxm * dym*(double)(*pp)
- + dx * dym*(double)(*(pp+1))
- + dxm* dy *(double)(*(pp + inputSize[0]))
- + dx * dy *(double)(*(pp + inputSize[0]+1))) );
-
- }
+ if (m_ModifiedInput->TransformPhysicalPointToContinuousIndex(iPoint, iIndex) && interpolator->IsInsideBuffer(iIndex))
+ value = interpolator->EvaluateAtContinuousIndex(iIndex);
//Outside: padding value
- else value=m_EdgePaddingValue;
-
+ else
+ value=m_EdgePaddingValue;
//Set it
iterator.Set(value);
option "spacing" - "Spacing for the output image" double multiple no default="0.8"
option "panel_position" - "Approximate position of the panel: small, medium or large" string no default="small"
-option "panel_shift" - "Precise position of the panel in mm" double no
+option "panel_shift" - "Precise position of the panel in mm" double multiple no
}
/** Set the panelshift. */
- void SetPanelShift(double shift)
+ void SetPanelShift(double x, double y)
{
- if (m_PanelShift!=shift)
+ if (m_PanelShift[0] != x)
{
- m_PanelShift=shift;
+ m_PanelShift[0] = x;
+ m_IsInitialized=false;
+ }
+ if (m_PanelShift[1] != y)
+ {
+ m_PanelShift[1] = y;
m_IsInitialized=false;
}
}
double m_SourceToScreen;
double m_SourceToAxis;
double m_ProjectionAngle;
- double m_PanelShift;
+ double m_PanelShift[2];
MatrixType m_RigidTransformMatrix;
OutputPixelType m_EdgePaddingValue;
m_IsoCenter.Fill(0.0);
m_SourceToScreen=1536.;
m_SourceToAxis=1000.;
+ m_PanelShift[0] = 0.;
+ m_PanelShift[1] = 0.;
m_ProjectionAngle=0.;
m_RigidTransformMatrix.SetIdentity();
m_EdgePaddingValue=itk::NumericTraits<OutputPixelType>::Zero;//density images
spacingOutput[1] = m_OutputSpacing[0]; // pixel spacing along Y of the 2D DRR image [mm]
spacingOutput[2] = m_OutputSpacing[1]; // pixel spacing along Y of the 2D DRR image [mm]
m_Resampler->SetOutputSpacing( spacingOutput );
- if (m_Verbose)std::cout<<"The output size is "<< m_OutputSpacing <<"..."<< std::endl;
+ if (m_Verbose)std::cout<<"The output spacing is "<< m_OutputSpacing <<"..."<< std::endl;
// The position of the DRR is specified, we presume that for an angle of 0° the flatpanel is located at the negative x-axis
// JV -1 seems to correspond better with shearwarp of Simon Rit
typename InterpolatorType::InputPointType originOutput;
originOutput[0] = m_IsoCenter[0]- (m_SourceToScreen - m_SourceToAxis);
DD(m_PanelShift);
- originOutput[1] = m_IsoCenter[1]-static_cast<double>(sizeOuput[1]-1)*spacingOutput[1]/2.0 - m_PanelShift;
- originOutput[2] = m_IsoCenter[2]-static_cast<double>(sizeOuput[2]-1)*spacingOutput[2]/2.0;
+ originOutput[1] = m_IsoCenter[1]-static_cast<double>(sizeOuput[1]-1)*spacingOutput[1]/2.0 - m_PanelShift[0];
+ originOutput[2] = m_IsoCenter[2]-static_cast<double>(sizeOuput[2]-1)*spacingOutput[2]/2.0 - m_PanelShift[1];
m_Resampler->SetOutputOrigin( originOutput );
if (m_Verbose)std::cout<<"The origin of the flat panel is at "<< originOutput <<",..."<< std::endl;
DD(m_ArgsInfo.panel_position_arg);
if (m_ArgsInfo.panel_shift_given) // one should read the specific values for each angle in Frame.dbf
- filter->SetPanelShift(m_ArgsInfo.panel_shift_arg);
+ filter->SetPanelShift(m_ArgsInfo.panel_shift_arg[0], m_ArgsInfo.panel_shift_arg[1]);
else { // approximate panel positions hard coded values for the elekta synergy
if (strcmp(m_ArgsInfo.panel_position_arg,"small") ==0)
- filter->SetPanelShift(0.);
+ filter->SetPanelShift(0., 0.);
else if (strcmp(m_ArgsInfo.panel_position_arg,"medium") ==0)
- filter->SetPanelShift(114.84);
+ filter->SetPanelShift(114.84, 0.); // VD : 120 , 0 ?
else if (strcmp(m_ArgsInfo.panel_position_arg,"large") ==0)
- filter->SetPanelShift(190.);
+ filter->SetPanelShift(190., 0.);
else assert(false); //Unsupported panel position
}
// Output image info
item->setData(0,Qt::UserRole,files[i].c_str());
QFileInfo fileinfo(imageManager->GetFileName().c_str()); //Do not show the path
item->setData(COLUMN_IMAGE_NAME,Qt::DisplayRole,fileinfo.fileName());
+ item->setData(1,Qt::UserRole,tr("image"));
item->setToolTip(COLUMN_IMAGE_NAME, imageManager->GetListOfAbsoluteFilePathInOneString("image").c_str());
qApp->processEvents();
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
-void vvMainWindow::DisplayChanged(QTreeWidgetItem *clicked_item, int column)
+void vvMainWindow::DisplayChanged(QTreeWidgetItem *clickedItem, int column)
{
- int index = GetSlicerIndexFromItem(clicked_item);
if ( column >= COLUMN_CLOSE_IMAGE || column <= 0)
return;
+
+ // Get parent information (might be the same item)
+ int slicerManagerIndex = GetSlicerIndexFromItem(clickedItem);
+ QTreeWidgetItem* clickedParentItem = DataTree->topLevelItem(slicerManagerIndex);
+ vvSlicer* clickedSlicer = mSlicerManagers[slicerManagerIndex]->GetSlicer(column-1);
+
+ // Go over the complete item tree (only 2 levels, parents and children)
for (unsigned int i = 0; i < mSlicerManagers.size(); i++) {
- //Trick to avoid redoing twice the job for a key (sr)
- mSlicerManagers[i]->GetSlicer(column-1)->GetRenderWindow()-> GetInteractor()->SetKeySym("Crap");
-
- QTreeWidgetItem* current_row=DataTree->topLevelItem(i);
- if (DataTree->topLevelItem(index) == current_row) {
- vvSlicer* clicked_slicer=mSlicerManagers[i]->GetSlicer(column-1);
- if (current_row == clicked_item) {
- //If we just activated a slicer
- if (current_row->data(column,Qt::CheckStateRole).toInt() > 0) {
- mSlicerManagers[i]->UpdateSlicer(column-1,clicked_item->data(column,Qt::CheckStateRole).toInt());
- mSlicerManagers[i]->UpdateInfoOnCursorPosition(column-1);
- DisplaySliders(i,column-1);
- std::map<std::string,int> overlay_counts;
- for (int child = 0; child < current_row->childCount(); child++) {
- std::string overlay_type =
- current_row->child(child)->data(1,Qt::UserRole).toString().toStdString();
- overlay_counts[overlay_type]++;
- current_row->child(child)->setData(column,Qt::CheckStateRole,
- current_row->data(column,Qt::CheckStateRole));
- clicked_slicer->SetActorVisibility(overlay_type,overlay_counts[overlay_type]-1,true);
- }
- } else { //We don't allow simply desactivating a slicer
- clicked_item->setData(column,Qt::CheckStateRole,2);
- DisplayChanged(clicked_item, column);
- return;
- }
+ // Trick to avoid redoing twice the job for a key (sr)
+ mSlicerManagers[i]->GetSlicer(column-1)->GetRenderWindow()->GetInteractor()->SetKeySym("Crap");
+
+ QTreeWidgetItem* currentParentItem = DataTree->topLevelItem(i);
+ if(currentParentItem != clickedParentItem) {
+ // Not the branch of the clicked item, uncheck all
+
+ // Parent
+ currentParentItem->setData(column,Qt::CheckStateRole, 0);
+ mSlicerManagers[i]->UpdateSlicer(column-1, false);
+
+ // Children
+ for (int iChild = 0; iChild < currentParentItem->childCount(); iChild++) {
+ currentParentItem->child(iChild)->setData(column,Qt::CheckStateRole, 0);
}
- //if we clicked on the vector(or overlay) and not the image
- else {
- if (clicked_item->data(column,Qt::CheckStateRole).toInt()) {
- current_row->setData(column,Qt::CheckStateRole,2);
- mSlicerManagers[i]->UpdateSlicer(column-1,2);
- mSlicerManagers[i]->UpdateInfoOnCursorPosition(column-1);
- DisplaySliders(i,column-1);
- }
- int vis = clicked_item->data(column,Qt::CheckStateRole).toInt();
- std::string overlay_type = clicked_item->data(1,Qt::UserRole).toString().toStdString();
- int overlay_index=0;
- for (int child = 0; child < current_row->childCount(); child++) {
- if (current_row->child(child)->data(1,Qt::UserRole).toString().toStdString() == overlay_type)
- overlay_index++;
- if (current_row->child(child) == clicked_item) break;
- }
- clicked_slicer->SetActorVisibility(
- clicked_item->data(1,Qt::UserRole).toString().toStdString(), overlay_index-1,vis);
+ }
+ else {
+ // Branch of the clicked one: get check status from actor visibility in slicer
+ // and toggle the clicked one
+
+ // Parent
+ bool vis = clickedSlicer->GetActorVisibility("image", 0);
+ bool draw = clickedSlicer->GetRenderer()->GetDraw();
+
+ // Update slicer (after getting visibility)
+ mSlicerManagers[slicerManagerIndex]->UpdateSlicer(column-1, true);
+ mSlicerManagers[slicerManagerIndex]->UpdateInfoOnCursorPosition(column-1);
+ DisplaySliders(slicerManagerIndex, column-1);
+ if(!draw) {
+ // We were not on this branch so far => force visibility
+ vis = true;
}
- } else if (current_row->data(column,Qt::CheckStateRole).toInt() > 0) {
- current_row->setData(column,Qt::CheckStateRole,0);
- mSlicerManagers[i]->UpdateSlicer(column-1,0);
- std::map<std::string,int> overlay_counts;
- for (int child = 0; child < current_row->childCount(); child++) {
- std::string overlay_type =
- current_row->child(child)->data(1,Qt::UserRole).toString().toStdString();
- overlay_counts[overlay_type]++;
- current_row->child(child)->setData(column,Qt::CheckStateRole,0);
- vvSlicer * current_slicer=mSlicerManagers[i]->GetSlicer(column-1);
- current_slicer->SetActorVisibility(overlay_type,overlay_counts[overlay_type]-1,false);
+ else if(clickedParentItem == clickedItem) {
+ // Toggle
+ vis = !vis;
+ }
+ clickedSlicer->SetActorVisibility("image", 0, vis);
+ clickedParentItem->setData(column, Qt::CheckStateRole, vis?2:0);
+
+ // Children
+ std::map<std::string, int> actorTypeCounts;
+ for (int iChild = 0; iChild < clickedParentItem->childCount(); iChild++) {
+ QTreeWidgetItem* currentChildItem = clickedParentItem->child(iChild);
+ std::string actorType = currentChildItem->data(1,Qt::UserRole).toString().toStdString();
+ vis = clickedSlicer->GetActorVisibility(actorType, actorTypeCounts[actorType]);
+ if(currentChildItem == clickedItem) {
+ // Toggle or force visibility if it was not on this branch so far
+ vis = !draw || !vis;
+ clickedSlicer->SetActorVisibility(actorType, actorTypeCounts[actorType], vis);
+ }
+ currentChildItem->setData(column, Qt::CheckStateRole, vis?2:0);
+ actorTypeCounts[actorType]++;
}
}
- //mSlicerManagers[i]->SetColorMap(-1);
- mSlicerManagers[i]->SetColorMap();
}
- mSlicerManagers[index]->GetSlicer(column-1)->Render();
+
+ clickedSlicer->Render();
}
//------------------------------------------------------------------------------
for (int j = 1; j <= 4; j++) {
item->setData(j,Qt::CheckStateRole,DataTree->topLevelItem(index)->data(j,Qt::CheckStateRole));
- mSlicerManagers[index]->GetSlicer(j-1)->SetActorVisibility("overlay",0,
- DataTree->topLevelItem(index)->data(j,Qt::CheckStateRole).toInt());
}
//Create the buttons for reload and close
for (int j = 1; j <= 4; j++) {
item->setData(j,Qt::CheckStateRole,DataTree->topLevelItem(index)->data(j,Qt::CheckStateRole));
- mSlicerManagers[index]->GetSlicer(j-1)->SetActorVisibility("fusion",0,
- DataTree->topLevelItem(index)->data(j,Qt::CheckStateRole).toInt());
}
//Create the buttons for reload and close
for (int j = 1; j <= 4; j++) {
item->setData(j,Qt::CheckStateRole,DataTree->topLevelItem(index)->data(j,Qt::CheckStateRole));
- mSlicerManagers[index]->GetSlicer(j-1)->SetActorVisibility("vector",0,
- DataTree->topLevelItem(index)->data(j,Qt::CheckStateRole).toInt());
}
//Create the buttons for reload and close
//create an item in the tree with good settings
QTreeWidgetItem *item = new QTreeWidgetItem();
item->setData(0,Qt::UserRole,slicer_manager->GetFileName().c_str());//files[i].c_str());
+ item->setData(1,Qt::UserRole,tr("image"));
item->setData(COLUMN_IMAGE_NAME,Qt::DisplayRole,slicer_manager->GetFileName().c_str());//filename.c_str());
qApp->processEvents();
mOverlayActor = vtkSmartPointer<vvBlendImageActor>::New();
mOverlayActor->SetInput(mOverlayMapper->GetOutput());
mOverlayActor->SetPickable(0);
- mOverlayActor->SetVisibility(false);
+ mOverlayActor->SetVisibility(true);
mOverlayActor->SetOpacity(0.5);
}
mFusionActor = vtkSmartPointer<vtkImageActor>::New();
mFusionActor->SetInput(mFusionMapper->GetOutput());
mFusionActor->SetPickable(0);
- mFusionActor->SetVisibility(false);
+ mFusionActor->SetVisibility(true);
mFusionActor->SetOpacity(0.7);
this->GetRenderer()->AddActor(mFusionActor);
}
//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+bool vvSlicer::GetActorVisibility(const std::string& actor_type, int overlay_index)
+{
+ bool vis = false;
+ if (actor_type == "image") {
+ vis = this->ImageActor->GetVisibility();
+ }
+ else if (actor_type == "vector") {
+ vis = this->mVFActor->GetVisibility();
+ }
+ else if (actor_type == "overlay") {
+ vis = this->mOverlayActor->GetVisibility();
+ }
+ else if (actor_type == "fusion") {
+ vis = this->mFusionActor->GetVisibility();
+ }
+ else if (actor_type == "contour")
+ vis = this->mSurfaceCutActors[overlay_index]->GetActor()->GetVisibility();
+
+ return vis;
+}
+//------------------------------------------------------------------------------
+
//------------------------------------------------------------------------------
void vvSlicer::SetActorVisibility(const std::string& actor_type, int overlay_index ,bool vis)
{
- if (actor_type == "vector") {
+ if (actor_type == "image") {
+ this->ImageActor->SetVisibility(vis);
+ }
+ else if (actor_type == "vector") {
this->mVFActor->SetVisibility(vis);
}
- if (actor_type == "overlay") {
+ else if (actor_type == "overlay") {
this->mOverlayActor->SetVisibility(vis);
}
- if (actor_type == "fusion") {
+ else if (actor_type == "fusion") {
this->mFusionActor->SetVisibility(vis);
}
- if (actor_type == "contour")
+ else if (actor_type == "contour")
this->mSurfaceCutActors[overlay_index]->GetActor()->SetVisibility(vis);
UpdateDisplayExtent();
}
//------------------------------------------------------------------------------
-
//------------------------------------------------------------------------------
void vvSlicer::SetVF(vvImage::Pointer vf)
{
return mFusion;
}
- /**Set an actor's visibility ("overlay, fusion, vf, contour...")
+ /**Get/Set an actor's visibility ("overlay, fusion, vf, contour...")
Overlay index is the index of the overlay by type, eg. if there are
5 contours and we want to activate the 3rd one, pass 2 **/
+ bool GetActorVisibility(const std::string& actor_type, int overlay_index);
void SetActorVisibility(const std::string& actor_type, int overlay_index,bool vis);
void RemoveActor(const std::string& actor_type, int overlay_index);
//----------------------------------------------------------------------------
-//----------------------------------------------------------------------------
-void vvSlicerManager::SetColorMap()
-{
- SetColorMap(mColorMap);
-}
-//----------------------------------------------------------------------------
-
-
//----------------------------------------------------------------------------
void vvSlicerManager::SetColorMap(int colormap)
{
fusLUT = NULL;
}
for ( unsigned int i = 0; i < mSlicers.size(); i++) {
- if (mSlicers[i]->GetOverlay() && mSlicers[i]->GetOverlayActor()->GetVisibility()) {
+ if (mSlicers[i]->GetOverlay()) {
vtkLookupTable* supLUT = vtkLookupTable::New();
supLUT->SetTableRange(range[0],range[1]);
supLUT->SetValueRange(1,1);
} else {
mSlicers[i]->GetWindowLevel()->SetLookupTable(LUT);
}
- if (mSlicers[i]->GetFusion() && mSlicers[i]->GetFusionActor()->GetVisibility()) {
+ if (mSlicers[i]->GetFusion()) {
mSlicers[i]->GetFusionActor()->SetOpacity(double(mFusionOpacity)/100);
mSlicers[i]->GetFusionMapper()->SetLookupTable(fusLUT);
mSlicers[i]->GetFusionMapper()->SetWindow(mFusionWindow);
void SetColorLevel(double s);
void SetLocalColorWindowing(const int slicer);
void SetOpacity(int i, double factor);
- void SetColorMap();
void SetColorMap(int colormap);
void SetPreset(int preset);
void SetOverlayColor(int color) {