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(); } }); }