2 years ago

#70246

test-img

Meyer Buaharon

get segmentation fault when moving mouse inside open3d cpp gui

I'm trying to make a gui in open3d, and did something that renders quite good in python. I decided to move from python to cpp but i have problem with the threads there...

This is my code:

#include <atomic>
#include <random>
#include <sstream>
#include <thread>

#include "open3d/Open3D.h"

using namespace open3d;
using namespace open3d::visualization;

using std::chrono::duration;
using std::chrono::duration_cast;
using std::chrono::high_resolution_clock;
using std::chrono::milliseconds;

class ReconstructionWindow : public gui::Window {
    using Super = gui::Window;

public:
    ReconstructionWindow(const std::string& device)
        : gui::Window("Open3D - Reconstruction", 1280, 800),
          device_str_(device) {
        widget3d_ = std::make_shared<gui::SceneWidget>();

        AddChild(widget3d_);


        widget3d_->SetScene(
                std::make_shared<rendering::Open3DScene>(GetRenderer()));
        is_done_ = false;
        update_thread_ = std::thread([this]() { this->UpdateMain(); });
    }

    ~ReconstructionWindow() { update_thread_.join(); }

protected:
    std::atomic<bool> is_started_;
    std::string device_str_;

    // General logic
    std::atomic<bool> is_running_;
    std::atomic<bool> is_done_;

    // Panels and controls
    std::shared_ptr<gui::SceneWidget> widget3d_;

    std::thread update_thread_;

protected:
    void UpdateMain() {
        gui::Application::GetInstance().PostToMainThread(this, [this]() {
            geometry::AxisAlignedBoundingBox bbox(Eigen::Vector3d(-5, -5, -5),
                                                  Eigen::Vector3d(5, 5, 5));
            Eigen::Vector3f center = {0.0, 0.0, 0.0};
            Eigen::Vector3f eye = {125.0, 125.0, 125.0};
            Eigen::Vector3f up = {0.0, 0.0, 1.0};
            this->widget3d_->SetupCamera(60, bbox, center);
            this->widget3d_->LookAt(center, eye, up);
        });

        size_t idx = 1;

        int number_of_points = 10000;
        static struct geometry::PointCloud pcds[100];
        std::cout << "creating plys\n";

        std::random_device rd;   // obtain a random number from hardware
        std::mt19937 gen(rd());  // seed the generator
        std::uniform_int_distribution<> distr(0, 100);  // define the range
        std::cout << "here" << std::endl;

        for (int i = 0; i < 100; i++) {
            for (size_t j = 0; j < number_of_points; j++) {
                pcds[i].points_.push_back(
                        {distr(gen), distr(gen) + i * 5, distr(gen)});

                pcds[i].colors_.push_back({0, 1, 0});
            }
        }
        std::cout << "Done!\n";
        auto t1 = high_resolution_clock::now();

        while (!is_done_) {
            std::this_thread::sleep_for(std::chrono::milliseconds(1000 / 25));
            auto mat = rendering::MaterialRecord();

            gui::Application::GetInstance().PostToMainThread(this, [this, idx,
                                                                    mat]() {
                std::thread t([this, mat, idx]() {
                    std::shared_ptr<geometry::PointCloud> pointcloud_ptr_A(
                            new geometry::PointCloud);
                    
                    
                    if (idx != 49)
                        this->widget3d_->GetScene()->AddGeometry(
                                "PointCloud" + std::to_string(idx), &pcds[idx],
                                mat);

                    if (idx > 1) {
                        this->widget3d_->GetScene()->RemoveGeometry(
                                "PointCloud" + std::to_string(idx - 1));
                    }
                });
                t.detach();
            });

            idx++;
            if (idx == 50) {
                idx = 1;
                auto t2 = high_resolution_clock::now();
                duration<double, std::milli> ms_double = t2 - t1;
                std::cout << ms_double.count() << "ms\n";
                t1 = high_resolution_clock::now();
            }
        }
    }
};

int main(int argc, char* argv[]) {
    using namespace open3d;

    std::string device_code =
            utility::GetProgramOptionAsString(argc, argv, "--device", "CUDA:0");
    if (device_code != "CPU:0" && device_code != "CUDA:0") {
        utility::LogWarning(
                "Unrecognized device {}. Expecting CPU:0 or CUDA:0.",
                device_code);
        return -1;
    }
    utility::LogInfo("Using device {}.", device_code);
    auto& app = gui::Application::GetInstance();
    app.Initialize(argc, const_cast<const char**>(argv));
    app.AddWindow(std::make_shared<ReconstructionWindow>(device_code));
    app.Run();
}

I believe that the main problem is happening inside the while loop. If you know what I did wrong, I would love to get some pointers.

c++

open3d

0 Answers

Your Answer

Accepted video resources