<commit_before>#include <librealsense/rs2.hpp>
#include "example.hpp"
#include "model-views.h"
#include "../common/realsense-ui/realsense-ui-advanced-mode.h"

#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "../third-party/stb_image_write.h"

#include <cstdarg>
#include <thread>
#include <iostream>
#include <algorithm>
#include <iomanip>
#include <map>
#include <sstream>
#include <array>
#include <mutex>
#include <set>
#include <regex>

#include <imgui_internal.h>

#define NOC_FILE_DIALOG_IMPLEMENTATION
#include <noc_file_dialog.h>

#define ARCBALL_CAMERA_IMPLEMENTATION
#include "arcball_camera.h"

#pragma comment(lib, "opengl32.lib")

using namespace rs2;
using namespace rs400;

void export_to_ply(notifications_model& ns, points points, video_frame texture)
{
    const char *ret;
    ret = noc_file_dialog_open(NOC_FILE_DIALOG_SAVE, "PLY\0*.ply\0", NULL, NULL);
    if (!ret) return; // user cancelled dialog. Don't save image.
    const std::string fname(ret);

    std::thread([&ns, points, texture, fname]() {
        std::string texfname(fname);
        texfname += ".png";

        const auto vertices = points.get_vertices();
        const auto texcoords = points.get_texture_coordinates();
        std::vector<vertex> new_vertices;
        std::vector<texture_coordinate> new_texcoords;
        new_vertices.reserve(points.size());
        new_texcoords.reserve(points.size());

        for (int i=0; i < points.size(); ++i)
            if (std::abs(vertices[i].x) >= 1e-6 || std::abs(vertices[i].y) >= 1e-6 || std::abs(vertices[i].z) >= 1e-6)
            {
                new_vertices.push_back(vertices[i]);
                if (texture) new_texcoords.push_back(texcoords[i]);
            }

        std::ofstream out(fname);
        out << "ply\n";
        out << "format binary_little_endian 1.0\n";
        out << "comment pointcloud saved from Realsense Viewer\n";
        if (texture) out << "comment TextureFile " << texfname.substr(texfname.find_last_of("\\")+1) << "\n";
        out << "element vertex " << new_vertices.size() << "\n";
        out << "property float" << sizeof(float) * 8 << " x\n";
        out << "property float" << sizeof(float) * 8 << " y\n";
        out << "property float" << sizeof(float) * 8 << " z\n";
        if (texture)
        {
            out << "property float" << sizeof(float) * 8 << " u\n";
            out << "property float" << sizeof(float) * 8 << " v\n";
        }
        out << "end_header\n";
        out.close();

        out.open(fname, std::ios_base::app|std::ios_base::binary);
        for (int i=0; i < new_vertices.size(); ++i)
        {
            // we assume little endian architecture on your device
            out.write(reinterpret_cast<const char*>(&(new_vertices[i].x)), sizeof(float));
            out.write(reinterpret_cast<const char*>(&(new_vertices[i].y)), sizeof(float));
            out.write(reinterpret_cast<const char*>(&(new_vertices[i].z)), sizeof(float));
            if (texture)
            {
                out.write(reinterpret_cast<const char*>(&(new_texcoords[i].u)), sizeof(float));
                out.write(reinterpret_cast<const char*>(&(new_texcoords[i].v)), sizeof(float));
            }
        }

        /* save texture to texfname */
        if (texture) stbi_write_png(texfname.data(), texture.get_width(), texture.get_height(), texture.get_bytes_per_pixel(), texture.get_data(), texture.get_width() * texture.get_bytes_per_pixel());

        ns.add_notification({ to_string() << "Finished saving 3D view " << (texture? "to ":"without texture to ") << fname,<commit_msg>Make PLY export cross platform<commit_after>#include <librealsense/rs2.hpp>
#include "example.hpp"
#include "model-views.h"
#include "../common/realsense-ui/realsense-ui-advanced-mode.h"

#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "../third-party/stb_image_write.h"

#include <cstdarg>
#include <thread>
#include <iostream>
#include <algorithm>
#include <iomanip>
#include <map>
#include <sstream>
#include <array>
#include <mutex>
#include <set>
#include <regex>

#include <imgui_internal.h>

#define NOC_FILE_DIALOG_IMPLEMENTATION
#include <noc_file_dialog.h>

#define ARCBALL_CAMERA_IMPLEMENTATION
#include "arcball_camera.h"

#pragma comment(lib, "opengl32.lib")

using namespace rs2;
using namespace rs400;

void export_to_ply(notifications_model& ns, points points, video_frame texture)
{
    const char *ret;
    ret = noc_file_dialog_open(NOC_FILE_DIALOG_SAVE, "PLY\0*.ply\0", NULL, NULL);
    if (!ret) return; // user cancelled dialog. Don't save image.
    const std::string fname(ret);

    std::thread([&ns, points, texture, fname]() {
        std::string texfname(fname);
        texfname += ".png";

        const auto vertices = points.get_vertices();
        const auto texcoords = points.get_texture_coordinates();
        std::vector<vertex> new_vertices;
        std::vector<texture_coordinate> new_texcoords;
        new_vertices.reserve(points.size());
        new_texcoords.reserve(points.size());

        for (int i=0; i < points.size(); ++i)
            if (std::abs(vertices[i].x) >= 1e-6 || std::abs(vertices[i].y) >= 1e-6 || std::abs(vertices[i].z) >= 1e-6)
            {
                new_vertices.push_back(vertices[i]);
                if (texture) new_texcoords.push_back(texcoords[i]);
            }

        std::ofstream out(fname);
        out << "ply\n";
        out << "format binary_little_endian 1.0\n";
        out << "comment pointcloud saved from Realsense Viewer\n";
        if (texture) out << "comment TextureFile " << texfname.substr(texfname.find_last_of("\\/")+1) << "\n";
        out << "element vertex " << new_vertices.size() << "\n";
        out << "property float" << sizeof(float) * 8 << " x\n";
        out << "property float" << sizeof(float) * 8 << " y\n";
        out << "property float" << sizeof(float) * 8 << " z\n";
        if (texture)
        {
            out << "property float" << sizeof(float) * 8 << " u\n";
            out << "property float" << sizeof(float) * 8 << " v\n";
        }
        out << "end_header\n";
        out.close();

        out.open(fname, std::ios_base::app|std::ios_base::binary);
        for (int i=0; i < new_vertices.size(); ++i)
        {
            // we assume little endian architecture on your device
            out.write(reinterpret_cast<const char*>(&(new_vertices[i].x)), sizeof(float));
            out.write(reinterpret_cast<const char*>(&(new_vertices[i].y)), sizeof(float));
            out.write(reinterpret_cast<const char*>(&(new_vertices[i].z)), sizeof(float));
            if (texture)
            {
                out.write(reinterpret_cast<const char*>(&(new_texcoords[i].u)), sizeof(float));
                out.write(reinterpret_cast<const char*>(&(new_texcoords[i].v)), sizeof(float));
            }
        }

        /* save texture to texfname */
        if (texture) stbi_write_png(texfname.data(), texture.get_width(), texture.get_height(), texture.get_bytes_per_pixel(), texture.get_data(), texture.get_width() * texture.get_bytes_per_pixel());

        ns.add_notification({ to_string() << "Finished saving 3D view " << (texture? "to ":"without texture to ") << fname,
{'fraction_non_alphanumeric': 0.16277453433416736, 'fraction_numerical': 0.007228245760355852, 'mean_word_length': 3.078798185941043, 'pattern_counts': {'":': 2, '<': 161, '<?xml version=': 0, '>': 51, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3215366', 'n_tokens_mistral': 2443, 'n_tokens_neox': 2394, 'n_words': 481}