예제 #1
0
QVector<qreal> ColorGradient::bitsF(uint length) const
{
    if (!isValid())
        return QVector<qreal>();
        
    auto bits = QVector<qreal>{};
    for (auto i = 0u; i < length; ++i)
    {
        qreal position = (qreal)i / length;
        auto color = interpolateColor(position);
        bits << color.redF() << color.greenF() << color.blueF() << color.alphaF();
    }
    
    return bits;
}
VolumeRenderWidget::VolumeRenderWidget(QWidget *parent)
	:m_renderMode(0), QWidget(parent)
{
	
	m_openGLWidget = new QVTKOpenGLWidget(this);
	vtkNew<vtkGenericOpenGLRenderWindow> renderWindow;
	m_openGLWidget->SetRenderWindow(renderWindow);
	m_renderer = vtkSmartPointer<vtkOpenGLRenderer>::New();
	m_renderer->BackingStoreOn();
	renderWindow->AddRenderer(m_renderer);
	renderWindow->Render(); // making opengl context

	vtkSmartPointer<vtkVolumeProperty> volumeProperty = vtkSmartPointer<vtkVolumeProperty>::New();
	vtkSmartPointer<vtkColorTransferFunction> colorFun = vtkSmartPointer<vtkColorTransferFunction>::New();
	vtkSmartPointer<vtkPiecewiseFunction> opacityFun = vtkSmartPointer<vtkPiecewiseFunction>::New();
	vtkSmartPointer<vtkPiecewiseFunction> gradientFun = vtkSmartPointer<vtkPiecewiseFunction>::New();
	volumeProperty->SetColor(colorFun);
	volumeProperty->SetScalarOpacity(opacityFun);
	volumeProperty->SetGradientOpacity(gradientFun);
	volumeProperty->ShadeOn();
	volumeProperty->SetInterpolationTypeToLinear();
	volumeProperty->SetAmbient(0.6);
	volumeProperty->SetDiffuse(0.9);
	volumeProperty->SetSpecular(0.5);
	volumeProperty->SetSpecularPower(10.0);
	//volumeProperty->IndependentComponentsOff();

	m_settingsWidget = new VolumeRenderSettingsWidget(volumeProperty, this);
	connect(this, &VolumeRenderWidget::imageDataChanged, m_settingsWidget, &VolumeRenderSettingsWidget::setImage);
	connect(m_settingsWidget, &VolumeRenderSettingsWidget::propertyChanged, this, &VolumeRenderWidget::updateRendering);
	connect(m_settingsWidget, &VolumeRenderSettingsWidget::renderModeChanged, this, &VolumeRenderWidget::setRenderMode);
	connect(m_settingsWidget, &VolumeRenderSettingsWidget::cropPlanesChanged, this, &VolumeRenderWidget::setCropPlanes);

	auto layout = new QVBoxLayout;
	layout->setContentsMargins(0, 0, 0, 0);
	layout->addWidget(m_openGLWidget);
	this->setLayout(layout);


	//adding orientation prop
	m_orientationProp = std::make_shared<OrientationActorContainer>();
	auto orientationPropPtr = std::static_pointer_cast<VolumeActorContainer>(m_orientationProp).get();
	m_volumeProps.push_back(orientationPropPtr);
	m_renderer->AddActor(m_orientationProp->getActor());	


	//window settings
	m_renderer->SetBackground(0, 0, 0);
	auto menuIcon = QIcon(QString("resources/icons/settings.svg"));
	auto menuButton = new QPushButton(menuIcon, QString(), m_openGLWidget);
	menuButton->setIconSize(QSize(24, 24));
	menuButton->setStyleSheet("QPushButton {background-color:transparent;}");
	auto menu = new QMenu(menuButton);
	menuButton->setMenu(menu);


	auto showAdvancedAction = menu->addAction(tr("Advanced"));
	connect(showAdvancedAction, &QAction::triggered, m_settingsWidget, &VolumeRenderSettingsWidget::toggleVisibility);


	auto showGrapicsAction = menu->addAction(tr("Show graphics"));
	showGrapicsAction->setCheckable(true);
	showGrapicsAction->setChecked(true);
	connect(showGrapicsAction, &QAction::toggled, this, &VolumeRenderWidget::setActorsVisible);

	menu->addAction(QString(tr("Set background color")), [=]() {
		auto color = QColorDialog::getColor(Qt::black, this);
		if (color.isValid())
			m_renderer->SetBackground(color.redF(), color.greenF(), color.blueF());
		updateRendering();
	});
	menu->addAction(QString(tr("Save image to file")), [=]() {
		auto filename = QFileDialog::getSaveFileName(this, tr("Save File"), "untitled.png", tr("Images (*.png)"));
		if (!filename.isEmpty())
		{
			auto renderWindow = m_openGLWidget->GetRenderWindow();
			vtkSmartPointer<vtkWindowToImageFilter> windowToImageFilter =
				vtkSmartPointer<vtkWindowToImageFilter>::New();
			windowToImageFilter->SetInput(renderWindow);
			windowToImageFilter->SetScale(3, 3); //set the resolution of the output image (3 times the current resolution of vtk render window)
			windowToImageFilter->SetInputBufferTypeToRGBA(); //also record the alpha (transparency) channel
			windowToImageFilter->ReadFrontBufferOff(); // read from the back buffer
			windowToImageFilter->Update();
			vtkSmartPointer<vtkPNGWriter> writer =
				vtkSmartPointer<vtkPNGWriter>::New();
			writer->SetFileName(filename.toLatin1().data());
			writer->SetInputConnection(windowToImageFilter->GetOutputPort());
			writer->Write();
		}
	});


}