mirror of
https://gitlab.ethz.ch/gfattori/glocalize.git
synced 2026-05-04 06:04:33 +02:00
496 lines
15 KiB
C++
496 lines
15 KiB
C++
|
|
#include "gRen.h"
|
|
#include <vtkOpenGLGPUVolumeRayCastMapper.h>
|
|
|
|
|
|
gRen::gRen(QVTKOpenGLNativeWidget *m_qvtk){
|
|
CTinfos.clear();
|
|
qvtk= m_qvtk;
|
|
nmarker=0;
|
|
|
|
markerSources = 0;
|
|
markerMappers = 0;
|
|
markerActors = 0;
|
|
|
|
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
void gRen::init()
|
|
{
|
|
|
|
qDebug() << "rw=" << qvtk->renderWindow()
|
|
<< "iren=" << qvtk->interactor();
|
|
|
|
if(!qvtk || !qvtk->renderWindow()) {
|
|
qDebug() << "QVTK widget not ready yet";
|
|
return;
|
|
}
|
|
|
|
// Interactor must exist before using it
|
|
if(!qvtk->renderWindow()->GetInteractor()) {
|
|
qvtk->renderWindow()->Render(); // forces initialization in many setups
|
|
}
|
|
|
|
qDebug()<<"buildRenderPipe";
|
|
buildRenderPipe();
|
|
qDebug()<<"createRenderers";
|
|
createRenderers();
|
|
qDebug()<<"Render";
|
|
qvtk->renderWindow()->Render();
|
|
}
|
|
|
|
void gRen::onAutoSkullMaskEnd(vtkImageData* fixedVol){
|
|
cout << "Auto masking complete"<<endl;
|
|
//CTvolume=vtkSmartPointer<vtkImageData>::New();
|
|
//CTvolume->Initialize();
|
|
CTvolume->DeepCopy(fixedVol);
|
|
CTvolume->Modified();
|
|
|
|
extractVOI->Update();
|
|
ren1->Render();
|
|
qvtk->renderWindow()->Render();
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
void gRen::loadVolume(vtkImageData* volCT){
|
|
|
|
CTvolume=vtkSmartPointer<vtkImageData>::New();
|
|
CTvolume->Initialize();
|
|
CTvolume->DeepCopy(volCT);
|
|
CTvolume->Modified();
|
|
CTvolume->GetExtent(CTinfos.extent);
|
|
CTvolume->GetSpacing(CTinfos.spacing);
|
|
CTvolume->GetOrigin(CTinfos.origin);
|
|
cout<< "ORIGIN REN: "<<CTinfos.origin[0]<<" "<<CTinfos.origin[1]<<" "<<CTinfos.origin[2]<<" " <<endl;
|
|
|
|
#if VTK_MAJOR_VERSION <= 5
|
|
volumeMapper->SetInput(CTvolume/*extractVOI->GetOutput()*/);
|
|
#else
|
|
volumeMapper->SetInputData(CTvolume);
|
|
#endif
|
|
ren1->AddViewProp(volume);
|
|
|
|
if(volume->GetVisibility() == 0)
|
|
volume->SetVisibility(false);
|
|
else
|
|
volume->SetVisibility(true);
|
|
|
|
extractVOI->SetInputData(CTvolume);
|
|
extractVOI->SetVOI(CTvolume->GetExtent());
|
|
extractVOI->Update();
|
|
|
|
boxCallback_NEW->setNominalGeometry(volCT->GetExtent(),volCT->GetBounds(),volCT->GetSpacing());
|
|
boxWidget_NEW->SetRotationEnabled(false);
|
|
boxWidget_NEW->SetScalingEnabled(true);
|
|
boxWidget_NEW->SetTranslationEnabled(true);
|
|
boxWidget_NEW->SetPriority(1);
|
|
boxWidget_NEW->SetInputData((vtkDataSet *) CTvolume);
|
|
boxWidget_NEW->PlaceWidget();
|
|
boxWidget_NEW->InsideOutOn();
|
|
boxWidget_NEW->GetOutlineProperty()->SetRepresentationToWireframe();
|
|
boxWidget_NEW->GetOutlineProperty()->SetAmbient(1.0);
|
|
boxWidget_NEW->GetOutlineProperty()->SetAmbientColor(1,1,1);
|
|
boxWidget_NEW->GetOutlineProperty()->SetLineWidth(3);
|
|
boxWidget_NEW->GetSelectedOutlineProperty()->SetRepresentationToWireframe();
|
|
boxWidget_NEW->GetSelectedOutlineProperty()->SetAmbient(1.0);
|
|
boxWidget_NEW->GetSelectedOutlineProperty()->SetAmbientColor(1,0,0);
|
|
boxWidget_NEW->GetSelectedOutlineProperty()->SetLineWidth(3);
|
|
|
|
outline-> SetInputConnection(extractVOI->GetOutputPort());
|
|
|
|
planeWidgetX->SetInputConnection(extractVOI->GetOutputPort());
|
|
planeWidgetY->SetInputConnection(extractVOI->GetOutputPort());
|
|
planeWidgetZ->SetInputConnection(extractVOI->GetOutputPort());
|
|
|
|
if(outlineActor->GetVisibility() == 0){
|
|
}
|
|
else{
|
|
planeWidgetX->On();
|
|
planeWidgetY->On();
|
|
planeWidgetZ->On();
|
|
}
|
|
|
|
orthoPlanes->SetPlane(0, planeWidgetX);
|
|
orthoPlanes->SetPlane(1, planeWidgetY);
|
|
orthoPlanes->SetPlane(2, planeWidgetZ);
|
|
orthoPlanes->ResetPlanes();
|
|
|
|
vtkCamera * cam = ren1->GetActiveCamera();
|
|
cam->SetPosition(0, 0, -1);
|
|
cam->SetFocalPoint(0, 0, 0);
|
|
cam->SetViewUp(0, -1, 0);
|
|
|
|
ren1->ResetCamera();
|
|
ren1->Render();
|
|
qvtk->renderWindow()->Render();
|
|
|
|
emit PatientLoaded();
|
|
return;
|
|
|
|
}
|
|
|
|
void gRen::createRenderers(){
|
|
|
|
ren1 = vtkRenderer::New();
|
|
ren1->SetBackground(0.13, 0.25, 0.32);
|
|
qvtk->renderWindow()->AddRenderer(ren1);
|
|
|
|
ren1->AddActor(assi);
|
|
ren1->AddActor( outlineActor);
|
|
|
|
boxWidget_NEW = vtkBoxWidget::New();
|
|
boxWidget_NEW->SetInteractor(qvtk->interactor());
|
|
boxWidget_NEW->SetPlaceFactor(1.0);
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - -
|
|
|
|
boxCallback_NEW->rcm=volumeMapper;
|
|
boxWidget_NEW->AddObserver(vtkCommand::InteractionEvent, boxCallback_NEW);
|
|
|
|
return;
|
|
}
|
|
|
|
void gRen::buildRenderPipe(){
|
|
|
|
qDebug()<<"buildRenderPipe: outline";
|
|
|
|
outline = vtkSmartPointer<vtkOutlineFilter>::New();
|
|
|
|
qDebug()<<"buildRenderPipe: outlineMapper";
|
|
|
|
vtkPolyDataMapper* outlineMapper = vtkPolyDataMapper::New();
|
|
outlineMapper->SetInputConnection(outline->GetOutputPort());
|
|
|
|
outlineActor = vtkSmartPointer <vtkActor> ::New();
|
|
outlineActor->SetMapper( outlineMapper);
|
|
|
|
qDebug()<<"buildRenderPipe: picker";
|
|
|
|
vtkCellPicker* picker = vtkCellPicker::New();
|
|
picker->SetTolerance(0.005);
|
|
|
|
vtkProperty* ipwProp = vtkProperty::New();
|
|
//// //assign default props to the ipw's texture plane actor
|
|
|
|
qDebug()<<"buildRenderPipe: planeX";
|
|
|
|
planeWidgetX = vtkImagePlaneWidget::New();
|
|
planeWidgetX->SetInteractor( qvtk->interactor());
|
|
planeWidgetX->SetKeyPressActivationValue('x');
|
|
planeWidgetX->SetPicker(picker);
|
|
planeWidgetX->RestrictPlaneToVolumeOn();
|
|
planeWidgetX->GetPlaneProperty()->SetColor(1,0,0);
|
|
planeWidgetX->SetTexturePlaneProperty(ipwProp);
|
|
planeWidgetX->TextureInterpolateOff();
|
|
planeWidgetX->SetResliceInterpolateToNearestNeighbour();
|
|
planeWidgetX->SetPlaneOrientationToXAxes();
|
|
planeWidgetX->DisplayTextOn();
|
|
planeWidgetX->InteractionOff();
|
|
planeWidgetX->InteractionOn();
|
|
|
|
qDebug()<<"buildRenderPipe: planeY";
|
|
|
|
planeWidgetY = vtkImagePlaneWidget::New();
|
|
planeWidgetY->SetInteractor( qvtk->interactor());
|
|
planeWidgetY->SetKeyPressActivationValue('y');
|
|
planeWidgetY->SetPicker(picker);
|
|
planeWidgetY->GetPlaneProperty()->SetColor(1,1,0);
|
|
planeWidgetY->SetTexturePlaneProperty(ipwProp);
|
|
planeWidgetY->TextureInterpolateOn();
|
|
planeWidgetY->SetResliceInterpolateToLinear();
|
|
planeWidgetY->SetPlaneOrientationToYAxes();
|
|
planeWidgetY->SetLookupTable( planeWidgetX->GetLookupTable());
|
|
planeWidgetY->DisplayTextOn();
|
|
planeWidgetY->UpdatePlacement();
|
|
|
|
qDebug()<<"buildRenderPipe: planeZ";
|
|
|
|
planeWidgetZ = vtkImagePlaneWidget::New();
|
|
planeWidgetZ->SetInteractor( qvtk->interactor());
|
|
planeWidgetZ->SetKeyPressActivationValue('z');
|
|
planeWidgetZ->SetPicker(picker);
|
|
planeWidgetZ->GetPlaneProperty()->SetColor(0,0,1);
|
|
planeWidgetZ->SetTexturePlaneProperty(ipwProp);
|
|
planeWidgetZ->TextureInterpolateOn();
|
|
planeWidgetZ->SetResliceInterpolateToCubic();
|
|
planeWidgetZ->SetPlaneOrientationToZAxes();
|
|
planeWidgetZ->SetLookupTable( planeWidgetX->GetLookupTable());
|
|
planeWidgetZ->DisplayTextOn();
|
|
|
|
qDebug()<<"buildRenderPipe: assi";
|
|
|
|
|
|
assi= vtkAxesActor::New();
|
|
assi->SetOrigin(0,0,0);
|
|
assi->AxisLabelsOff();
|
|
assi->SetTotalLength(15,15,15);
|
|
|
|
qDebug()<<"buildRenderPipe: volMapper";
|
|
|
|
// Create mapper (as vtkVolumeMapper smart pointer)
|
|
auto gpuMapper = vtkSmartPointer<vtkOpenGLGPUVolumeRayCastMapper>::New();
|
|
gpuMapper->SetBlendModeToComposite();
|
|
if (!gpuMapper)
|
|
{
|
|
qDebug() << "ERROR: GPU volume mapper creation returned null";
|
|
return;
|
|
}
|
|
// store into the member (base type)
|
|
this->volumeMapper = gpuMapper;
|
|
|
|
qDebug()<<"buildRenderPipe: volProps";
|
|
|
|
volumeProperty = vtkSmartPointer<vtkVolumeProperty>::New();
|
|
volumeProperty->ShadeOff();
|
|
volumeProperty->SetInterpolationType(VTK_LINEAR_INTERPOLATION);
|
|
|
|
qDebug()<<"buildRenderPipe: opacity";
|
|
|
|
compositeOpacity = vtkSmartPointer<vtkPiecewiseFunction>::New();
|
|
compositeOpacity->AddPoint(-3024, 0, 0.5, 0.0 );
|
|
compositeOpacity->AddPoint(-16, 0, .49, .61 );
|
|
compositeOpacity->AddPoint(-10, .1, .49, .4 );
|
|
compositeOpacity->AddPoint(500, .4, .49, .4 );
|
|
compositeOpacity->AddPoint(641, .72, .5, 0.0 );
|
|
compositeOpacity->AddPoint(1700, .8, .5, 0.0 );
|
|
compositeOpacity->AddPoint(2500, .8, .5, 0.0 );
|
|
compositeOpacity->AddPoint(3071, .71, 0.5, 0.0);
|
|
volumeProperty->SetScalarOpacity(compositeOpacity); // composite first.
|
|
|
|
qDebug()<<"buildRenderPipe: color";
|
|
|
|
color = vtkSmartPointer<vtkColorTransferFunction>::New();
|
|
color->AddRGBPoint( -3024, 0, 0, 0, 0.5, 0.0 );
|
|
color->AddRGBPoint( -16, 0.73, 0.25, 0.30, 0.49, .61 );
|
|
color->AddRGBPoint( -10, .3, .3, .3, .5, 0.0 );
|
|
color->AddRGBPoint( 500, .7, .7, .7, .5, 0.0 );
|
|
color->AddRGBPoint( 641, .90, .82, .56, .5, 0.0 );
|
|
color->AddRGBPoint( 1700, 1, 0,0, .5, 1 );
|
|
color->AddRGBPoint( 2500, 1, 0,0, .5,.1 );
|
|
color->AddRGBPoint( 3071, 1, 1, 1, .5, 0.0 );
|
|
volumeProperty->SetColor(color);
|
|
|
|
volumeProperty->ShadeOn();
|
|
volumeProperty->SetAmbient(0.1);
|
|
volumeProperty->SetDiffuse(0.9);
|
|
volumeProperty->SetSpecular(0.2);
|
|
volumeProperty->SetSpecularPower(10.0);
|
|
volumeProperty->SetScalarOpacityUnitDistance(0.8919);
|
|
|
|
|
|
qDebug()<<"buildRenderPipe: volume";
|
|
|
|
volume = vtkSmartPointer<vtkVolume>::New();
|
|
volume->SetMapper(volumeMapper);
|
|
volume->SetProperty(volumeProperty);
|
|
volume->SetVisibility(false);
|
|
|
|
// outlineActor->SetVisibility(true);
|
|
// planeWidgetX->EnabledOn();
|
|
// planeWidgetY->EnabledOn();
|
|
// planeWidgetZ->EnabledOn();
|
|
// planeWidgetX->On();
|
|
// planeWidgetY->On();
|
|
// planeWidgetZ->On();
|
|
|
|
qDebug()<<"buildRenderPipe: extractVOI";
|
|
|
|
extractVOI = vtkSmartPointer<vtkExtractVOI>::New();
|
|
|
|
qDebug()<<"buildRenderPipe: callback";
|
|
|
|
boxCallback_NEW = vtkSmartPointer<vtkMyCallback>::New();
|
|
boxCallback_NEW->setExtractVoiFilter(extractVOI);
|
|
|
|
qDebug()<<"buildRenderPipe: orthoplanes";
|
|
|
|
orthoPlanes = vtkImageOrthoPlanes::New();
|
|
|
|
return;
|
|
}
|
|
|
|
void gRen::onSingleMarkerChange(int idx, bool state){
|
|
|
|
cout<< "onSingleMarkerChange : "<<idx<<" "<<(state == true? "true":"false")<<endl;
|
|
|
|
if(state){
|
|
markerActors[idx]->GetProperty()->SetColor(0,1,0);
|
|
} else {
|
|
markerActors[idx]->GetProperty()->SetColor(1,1,1);
|
|
}
|
|
qvtk->renderWindow()->Render();
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
void gRen::renderMarkers(QList<surf> marker_list){
|
|
|
|
cout << "renderMarkers" << endl;
|
|
|
|
if(markerSources != 0) {
|
|
for(int ii=0;ii<nmarker;ii++){
|
|
ren1->RemoveActor(markerActors[ii]);
|
|
markerActors[ii]->RemoveAllObservers();
|
|
markerMappers[ii]->RemoveAllObservers();
|
|
markerSources[ii]->RemoveAllObservers();
|
|
markerSources[ii]->Delete();
|
|
markerActors[ii]->Delete();
|
|
markerMappers[ii]->Delete();
|
|
}
|
|
delete [] markerActors;
|
|
delete [] markerMappers;
|
|
delete [] markerSources;
|
|
ren1->RemoveActor(pointLabels);
|
|
}
|
|
|
|
nmarker = marker_list.size();
|
|
markerSources = new vtkSphereSource* [nmarker];
|
|
markerMappers = new vtkPolyDataMapper* [nmarker];
|
|
markerActors = new vtkActor* [nmarker];
|
|
|
|
modelPoints = vtkSmartPointer<vtkPoints>::New();
|
|
modelPoints->Reset();
|
|
modelPoints->SetNumberOfPoints(nmarker);
|
|
|
|
|
|
stringData = vtkSmartPointer<vtkStringArray>::New();
|
|
stringData->Reset();
|
|
stringData->SetName("Labels");
|
|
|
|
for(int i=0;i<nmarker;i++){
|
|
stringData->InsertNextValue(QString::number(i).toLatin1().constData());
|
|
modelPoints->InsertPoint(i,marker_list.at(i).centroid.x*1000,marker_list.at(i).centroid.y*1000,marker_list.at(i).centroid.z*1000);
|
|
|
|
markerSources[i] = vtkSphereSource::New();
|
|
markerSources[i]->SetCenter(marker_list.at(i).centroid.x*1000,marker_list.at(i).centroid.y*1000,marker_list.at(i).centroid.z*1000);
|
|
markerSources[i]->SetRadius(10);
|
|
// markerSources[i]->SetRadius(2);
|
|
|
|
markerMappers[i]= vtkPolyDataMapper::New();
|
|
markerMappers[i]->SetInputConnection (markerSources[i]->GetOutputPort());
|
|
|
|
markerActors[i]= vtkActor::New();
|
|
markerActors[i]->SetMapper(markerMappers[i]);
|
|
markerActors[i]->GetProperty()->SetRepresentationToWireframe();
|
|
markerActors[i]->GetProperty()->SetColor(0,1,0);
|
|
ren1->AddActor(markerActors[i]);
|
|
}
|
|
|
|
cout << "modelPoints" << endl;
|
|
modelPoints->Modified();
|
|
|
|
cells = vtkSmartPointer<vtkCellArray>::New();
|
|
cells->Reset();
|
|
cells->InsertNextCell(nmarker);
|
|
for(int i = 0; i < nmarker; i++)
|
|
cells->InsertCellPoint(i);
|
|
|
|
polyData = vtkSmartPointer<vtkPolyData>::New();
|
|
polyData->Reset();
|
|
polyData->SetPoints(modelPoints);
|
|
polyData->SetVerts(cells);
|
|
polyData->GetPointData()->AddArray(stringData);
|
|
|
|
polyData->GetFieldData()->AddArray(stringData);
|
|
ldm = vtkSmartPointer<vtkLabeledDataMapper>::New();
|
|
ldm->SetInputData(polyData);
|
|
ldm->SetLabelModeToLabelFieldData();
|
|
ldm->SetFieldDataName("Labels");
|
|
ldm->GetLabelTextProperty()->SetShadow(false);
|
|
ldm->GetLabelTextProperty()->SetFontSize(22);
|
|
cout << "plab" << endl;
|
|
pointLabels = vtkSmartPointer<vtkActor2D>::New();
|
|
pointLabels->SetMapper( ldm );
|
|
ren1->AddActor(pointLabels);
|
|
qvtk->renderWindow()->Render();
|
|
|
|
return;
|
|
}
|
|
|
|
void gRen::onReferenceChange(double dx, double dy, double dz){
|
|
|
|
if(markerSources == 0)
|
|
return;
|
|
|
|
for(int i=0;i<nmarker;i++){
|
|
markerSources[i]->SetCenter(
|
|
markerSources[i]->GetCenter()[0]-dx,
|
|
markerSources[i]->GetCenter()[1]-dy,
|
|
markerSources[i]->GetCenter()[2]-dz);
|
|
markerSources[i]->Update();
|
|
|
|
modelPoints->SetPoint(i,
|
|
modelPoints->GetPoint(i)[0]-dx,
|
|
modelPoints->GetPoint(i)[1]-dy,
|
|
modelPoints->GetPoint(i)[2]-dz);
|
|
}
|
|
|
|
modelPoints->Modified();
|
|
qvtk->renderWindow()->Render();
|
|
return;
|
|
}
|
|
|
|
void gRen::onRequestRenderChange(int idx){
|
|
switch (idx){
|
|
case 0:
|
|
volume->SetVisibility(true);
|
|
outlineActor->SetVisibility(false);
|
|
planeWidgetX->EnabledOff();
|
|
planeWidgetY->EnabledOff();
|
|
planeWidgetZ->EnabledOff();
|
|
//volumeMapper->SetRequestedRenderMode(2);
|
|
qvtk->renderWindow()->Render();
|
|
|
|
// Software mode, for coverage. It also makes sure we will get the same
|
|
// regression image on all platforms.
|
|
//volumeMapper->SetRequestedRenderModeToRayCast();
|
|
qvtk->renderWindow()->Render();
|
|
|
|
ren1->Render();
|
|
break;
|
|
|
|
case 1:
|
|
volume->SetVisibility(false);
|
|
outlineActor->SetVisibility(true);
|
|
planeWidgetX->EnabledOn();
|
|
planeWidgetY->EnabledOn();
|
|
planeWidgetZ->EnabledOn();
|
|
ren1->Render();
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
return;
|
|
}
|
|
|
|
|
|
void gRen::onRequestManualMask(int idx){
|
|
|
|
switch (idx){
|
|
case 0:
|
|
boxWidget_NEW->On();
|
|
qvtk->renderWindow()->Render();
|
|
break;
|
|
|
|
case 1:
|
|
boxWidget_NEW->Off();
|
|
qvtk->renderWindow()->Render();
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
|