void LVRMainWindow::exportSelectedModel()
{
    // Get selected point cloud
    QList<QTreeWidgetItem*> items = treeWidget->selectedItems();
    if(items.size() > 0)
    {
        QTreeWidgetItem* item = items.first();
        if(item->type() == LVRPointCloudItemType)
        {
            if(item->parent() && item->parent()->type() == LVRModelItemType)
            {
                QString qFileName = QFileDialog::getSaveFileName(this, tr("Export Point Cloud As..."), "", tr("Point cloud Files(*.ply *.3d)"));

                LVRModelItem* model_item = static_cast<LVRModelItem*>(item->parent());
                LVRPointCloudItem* pc_item = static_cast<LVRPointCloudItem*>(item);
                PointBufferPtr points = pc_item->getPointBuffer();

                // Get transformation matrix
                Pose p = model_item->getPose();
                Matrix4f mat(Vertexf(p.x, p.y, p.z), Vertexf(p.r, p.t, p.p));

                // Allocate target buffer and insert transformed points
                size_t n;
                floatArr transformedPoints(new float[3 * points->getNumPoints()]);
                floatArr pointArray = points->getPointArray(n);
                for(size_t i = 0; i < points->getNumPoints(); i++)
                {
                    Vertexf v(pointArray[3 * i], pointArray[3 * i + 1], pointArray[3 * i + 2]);
                    Vertexf vt = mat * v;

                    transformedPoints[3 * i    ] = vt[0];
                    transformedPoints[3 * i + 1] = vt[1];
                    transformedPoints[3 * i + 2] = vt[2];
                }

                // Save transformed points
                PointBufferPtr trans(new PointBuffer);
                trans->setPointArray(transformedPoints, n);
                ModelPtr model(new Model(trans));
                ModelFactory::saveModel(model, qFileName.toStdString());
            }
        }
    }
}
int main( int argc, char ** argv )
{

    // Parse command line arguments
    convert::Options options(argc, argv);

    // Exit if options had to generate a usage message
    // (this means required parameters are missing)
    if ( options.printUsage() )
    {
        return 0;
    }

    ::std::cout << options << ::std::endl;

    // Read input file
    ModelPtr model = ModelFactory::readModel(options.getInputFile());

    if(model)
    {

        if(model->m_pointCloud)
        {
            // Get parameters
            bool convert           = options.convertIntensity();
            bool filterIntensity   = options.getMinIntensity() > -1e10 || options.getMaxIntensity() < 1e10;

            // Check if we have to modify some data
            if(convert || filterIntensity)
            {
                PointBufferPtr points = model->m_pointCloud;
                size_t numPoints = points->getNumPoints();
                if(points)
                {
                    size_t n;
                    if(convert && !points->getPointColorArray(n))
                    {
                        cout << timestamp << "Allocating new point color array." << endl;
                        ucharArr colors(new unsigned char[numPoints * 3]);
                        points->setPointColorArray(colors, numPoints);
                    }

                    float max_i = -1e10;
                    float min_i = +1e10;
                    float maxCutOff = options.getMaxIntensity();
                    float minCutOff = options.getMinIntensity();

                    floatArr intensities = points->getPointIntensityArray(n);
                    if(intensities)
                    {
                        // Cutoff intensity values
                        for(size_t i = 0; i < numPoints; i++)
                        {
                            //cout << intensities[i] << endl;
                            if(intensities[i] < minCutOff) intensities[i] = minCutOff;
                            if(intensities[i] > maxCutOff) intensities[i] = maxCutOff;
                            if(intensities[i] < min_i) min_i = intensities[i];
                            if(intensities[i] > max_i) max_i = intensities[i];
                        }

                        // Map intensities to 0 .. 255
                        cout << max_i << " " << min_i << endl;
                        float r_diff = max_i - min_i;
                        if(r_diff > 0)
                        {
                            float b_size = r_diff / 255.0;
                            for(int a = 0; a < numPoints; a++)
                            {
                                //cout << intensities[a] << endl;
                                float value = intensities[a];
                                value -= min_i;
                                value /= b_size;
                                intensities[a] = value;
                                //cout << intensities[a] << endl << endl;
                            }
                        }

                        // Convert
                        if(convert)
                        {
                            ucharArr colors = points->getPointColorArray(n);

                            GradientType gradType = GREY;
                            string gradientName = options.getColorMap();

                            if(gradientName == "HOT")   gradType = HOT;
                            if(gradientName == "HSV")   gradType = HSV;
                            if(gradientName == "SHSV")  gradType = SHSV;
                            if(gradientName == "JET")   gradType = JET;

                            ColorMap colorMap(255);

                            for(size_t i = 0; i < numPoints; i++)
                            {
                                float color[3];

                                colorMap.getColor(color, (size_t)intensities[i], gradType );

                                colors[3 * i    ] = (unsigned char)(color[0] * 255);
                                colors[3 * i + 1] = (unsigned char)(color[1] * 255);
                                colors[3 * i + 2] = (unsigned char)(color[2] * 255);
                                //cout << intensities[i] << endl;
                                //cout << (int) colors[3 * i    ] << " " << (int)colors[3 * i + 1] << " " << (int)colors[3 * i + 2] << endl;

                            }

                            points->setPointColorArray(colors, numPoints);
                        }
                        model->m_pointCloud = points;
                    }
                    else
                    {
                        cout << timestamp << "Model contains no point intensities to convert." << endl;
                    }

                }
            }
        }
        ModelFactory::saveModel(model, options.getOutputFile());

    }
    else
    {
        cout << timestamp << "Error reading file " << options.getInputFile() << endl;
    }
}