Commit 180238b4 authored by Jakob Weiss's avatar Jakob Weiss
Browse files

Transfer function backup and restore

It is now possible to backup and restore 1D transfer functions in a very simple text file format.
parent 923f47db
Loading
Loading
Loading
Loading
+37 −0
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@
#include <QCheckBox>
#include <QGridLayout>
#include <QLabel>
#include <QFileDialog>
#include <QPushButton>
#include <QVBoxLayout>

@@ -55,6 +56,8 @@ namespace campvis {
        , _btnAddGeometry(0)
        , _btnRemoveGeometry(0)
        , _cbLogScale(0)
        , _btnSaveTF(nullptr)
        , _btnLoadTF(nullptr)
    {
        _selectedGeometry = 0;
        setupGUI();
@@ -257,6 +260,15 @@ namespace campvis {
        _cbLogScale->setChecked(true);
        buttonLayout->addWidget(_cbLogScale);
        connect(_cbLogScale, SIGNAL(stateChanged(int)), this, SLOT(onCbLogScaleStateChanged(int)));

        _btnSaveTF = new QPushButton(tr("Save TF"), this);
        buttonLayout->addWidget(_btnSaveTF);
        connect(_btnSaveTF, &QPushButton::clicked, this, &Geometry1DTransferFunctionEditor::onBtnSaveTFClicked);
        _btnLoadTF = new QPushButton(tr("Load TF"), this);
        buttonLayout->addWidget(_btnLoadTF);
        connect(_btnLoadTF, &QPushButton::clicked, this, &Geometry1DTransferFunctionEditor::onBtnLoadTFClicked);


        _layout->setColumnStretch(2, 1);
        _layout->setRowStretch(2, 1);
    }
@@ -337,6 +349,31 @@ namespace campvis {
        emit s_invalidated();
    }

    void Geometry1DTransferFunctionEditor::onBtnSaveTFClicked()
    {
        std::cout << "Saving transfer function...." << std::endl;
        QString of = QFileDialog::getSaveFileName(this, tr("Open Transfer Function"), ".", "*.txt");
        if (!of.isEmpty()) {
            Geometry1DTransferFunction* gtf = static_cast<Geometry1DTransferFunction*>(_transferFunction);
            std::ofstream tfFile(of.toStdString());
            gtf->serialize(tfFile);
        }
    }

    void Geometry1DTransferFunctionEditor::onBtnLoadTFClicked()
    {
        std::cout << "Loading transfer function..." << std::endl;

        QString of = QFileDialog::getOpenFileName(this, tr("Open Transfer Function"), ".", "*.txt");

        if (!of.isEmpty()) {
            std::ifstream tfFile(of.toStdString());
            //Geometry1DTransferFunction* gtf = static_cast<Geometry1DTransferFunction*>(_transferFunction);
            Geometry1DTransferFunction* gtf = Geometry1DTransferFunction::unserialize(tfFile);
            _tfProperty->replaceTF(gtf);
        }
    }

    void Geometry1DTransferFunctionEditor::onTfAboutToBeDeleted() {
        disconnectFromTf();
    }
+12 −0
Original line number Diff line number Diff line
@@ -117,6 +117,16 @@ namespace campvis {
         */
        void onCbLogScaleStateChanged(int state);

        /**
         * Slot to be called when the TF save button is clicked.
         */
        void onBtnSaveTFClicked();

        /**
         * Slot to be called when the TF load button is clicked.
         */
        void onBtnLoadTFClicked();

        /**
         * Slot reacting to the invalidated signal, issueing a new paint job
         */
@@ -162,6 +172,8 @@ namespace campvis {
        QPushButton* _btnAddGeometry;
        QPushButton* _btnRemoveGeometry;
        QCheckBox* _cbLogScale;
        QPushButton* _btnSaveTF;
        QPushButton* _btnLoadTF;
    };
}

+49 −0
Original line number Diff line number Diff line
@@ -56,4 +56,53 @@ namespace campvis {
        return 1;
    }



    void Geometry1DTransferFunction::serialize(std::ostream & stream) const
    {
        stream << "Domain: " << _intensityDomain.x << " " << _intensityDomain.y << std::endl;
        stream << "Size: " << _size.x << " " << _size.y << " " << _size.z << std::endl;
        stream << "Number of Geometries: " << _geometries.size() << std::endl;
        for (auto it = _geometries.begin(); it != _geometries.end(); ++it) {
            auto keypoints = (*it)->getKeyPoints();
            stream << keypoints.size() << " ";
            for (auto kpit = keypoints.begin(); kpit != keypoints.end(); ++kpit) {
                stream << " { " << (*kpit)._position << " " << int((*kpit)._color.r) << "," << int((*kpit)._color.g) << "," 
                    << int((*kpit)._color.b) << "," << int((*kpit)._color.a) << " } ";
            }
            stream << std::endl;
        }
    }

    Geometry1DTransferFunction * Geometry1DTransferFunction::unserialize(std::istream & stream)
    {
        cgt::vec2 domain;       stream.ignore(10, ':'); stream >> domain.x >> domain.y;
        cgt::svec3 size;         stream.ignore(10, ':'); stream >> size.x >> size.y >> size.z;
        size_t numGeometries;   stream.ignore(25, ':'); stream >> numGeometries;

        auto tf = new Geometry1DTransferFunction(size.x, domain);

        for (size_t i = 0; i < numGeometries; ++i) {
            size_t numKeypoints;
            stream >> numKeypoints;
            std::vector<TFGeometry1D::KeyPoint> keypoints;

            for (size_t j = 0; j < numKeypoints; ++j) {
                float position;
                cgt::ivec4 color;
                stream.ignore(5, '{'); stream >> position;
                stream >> color.r; stream.ignore(3, ',');
                stream >> color.g; stream.ignore(3, ',');
                stream >> color.b; stream.ignore(3, ',');
                stream >> color.a; stream.ignore(5, '}');
                keypoints.push_back(TFGeometry1D::KeyPoint(position, color));
            }

            TFGeometry1D *geom = new TFGeometry1D(keypoints);
            tf->addGeometry(geom);
        }

        return tf;
    }

}
 No newline at end of file
+10 −0
Original line number Diff line number Diff line
@@ -62,6 +62,16 @@ namespace campvis {
         */
        virtual size_t getDimensionality() const;

        /**
         * Serializes the transfer function to a stream
         */
        void serialize(std::ostream& stream) const;

        /**
         * Reads a serialized transfer function from a stream
         */
        static Geometry1DTransferFunction* unserialize(std::istream& stream);

    protected:

        static const std::string loggerCat_;