-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
PLY options #4906
PLY options #4906
Changes from 13 commits
86bde93
aaf50eb
8a893e5
9d2df5b
4a2a6b0
0652311
b432726
37b93dd
a164a90
d9336a9
018d11c
0adaea3
b808ff3
5bf84dc
1db327c
e858531
f94f832
eea6ebc
9a1f849
dbaa4fd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -24,6 +24,23 @@ | |
|
||
namespace rs2 | ||
{ | ||
frameset_allocator::frameset_allocator(viewer_model* viewer) : owner(viewer), | ||
filter([this](frame f, frame_source& s) | ||
{ | ||
std::vector<rs2::frame> frame_vec; | ||
auto tex = owner->get_last_texture()->get_last_frame(true); | ||
if (tex) | ||
{ | ||
frame_vec.push_back(tex); | ||
frame_vec.push_back(f); | ||
auto frame = s.allocate_composite_frame(frame_vec); | ||
if (frame) | ||
s.frame_ready(std::move(frame)); | ||
} | ||
else | ||
s.frame_ready(std::move(f)); | ||
}) {} | ||
|
||
void viewer_model::render_pose(rs2::rect stream_rect, float buttons_heights) | ||
{ | ||
int num_of_pose_buttons = 2; // trajectory, info | ||
|
@@ -83,7 +100,7 @@ namespace rs2 | |
//ImGui::End(); | ||
} | ||
|
||
void viewer_model::show_3dviewer_header(ImFont* font, rs2::rect stream_rect, bool& paused, std::string& error_message) | ||
void viewer_model::show_3dviewer_header(ImFont* large_font, ImFont* font, rs2::rect stream_rect, bool& paused, std::string& error_message) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. PLs add a comment what is the 2nd font for |
||
{ | ||
int combo_boxes = 0; | ||
const float combo_box_width = 200; | ||
|
@@ -264,6 +281,193 @@ namespace rs2 | |
} | ||
} | ||
|
||
ImGui::PopStyleColor(3); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is strange that the section starts with pop and not push - seem to indicate and issue elsewhere. Please encapsulate this fragment into a function call for maintainability. |
||
|
||
float w = stream_rect.w * 0.33f; | ||
float h = stream_rect.h * 0.34f; | ||
float x0 = stream_rect.x * 2; | ||
float y0 = stream_rect.y * 6; | ||
ImGui::SetNextWindowPos({ x0, y0 }); | ||
ImGui::SetNextWindowSize({ w, h }); | ||
|
||
auto flags = ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | | ||
ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoSavedSettings; | ||
|
||
ImGui_ScopePushFont(font); | ||
ImGui::PushStyleColor(ImGuiCol_PopupBg, sensor_bg); | ||
ImGui::PushStyleColor(ImGuiCol_TextSelectedBg, white); | ||
ImGui::PushStyleColor(ImGuiCol_Text, light_grey); | ||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(15, 15)); | ||
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 1); | ||
|
||
static config_file temp_cfg; | ||
static export_type tab = export_type::ply; | ||
if (ImGui::BeginPopupModal("Export", nullptr, flags)) | ||
{ | ||
ImGui::SetCursorScreenPos({ (float)(x0), (float)(y0 + 30) }); | ||
ImGui::PushStyleColor(ImGuiCol_Button, sensor_bg); | ||
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, sensor_bg); | ||
ImGui::PushFont(large_font); | ||
for (auto& exporter : exporters) | ||
{ | ||
ImGui::PushStyleColor(ImGuiCol_Text, tab != exporter.first ? light_grey : light_blue); | ||
ImGui::PushStyleColor(ImGuiCol_TextSelectedBg, tab != exporter.first ? light_grey : light_blue); | ||
ImGui::SameLine(); | ||
if (ImGui::Button(exporter.second.name.c_str(), { w / exporters.size() - 50, 30 })) | ||
{ | ||
config_file::instance().set(configurations::viewer::settings_tab, tab); | ||
temp_cfg.set(configurations::viewer::settings_tab, tab); | ||
tab = exporter.first; | ||
} | ||
ImGui::PopStyleColor(2); | ||
} | ||
|
||
ImGui::PopFont(); | ||
if (tab == export_type::ply) | ||
{ | ||
bool mesh = temp_cfg.get(configurations::ply::mesh); | ||
bool use_normals = temp_cfg.get(configurations::ply::use_normals); | ||
if (!mesh) use_normals = false; | ||
int encoding = temp_cfg.get(configurations::ply::encoding); | ||
|
||
ImGui::PushStyleColor(ImGuiCol_Text, grey); | ||
ImGui::Text("Polygon File Format defines a flexible systematic scheme for storing 3D data"); | ||
ImGui::PopStyleColor(); | ||
ImGui::NewLine(); | ||
ImGui::SetCursorScreenPos({ (float)(x0 + 15), (float)(y0 + 90) }); | ||
ImGui::Separator(); | ||
if (ImGui::Checkbox("Meshing", &mesh)) | ||
{ | ||
temp_cfg.set(configurations::ply::mesh, mesh); | ||
} | ||
ImGui::PushStyleColor(ImGuiCol_Text, grey); | ||
ImGui::Text(" Use faces for meshing by connecting each group of 3 adjacent points"); | ||
ImGui::PopStyleColor(); | ||
ImGui::Separator(); | ||
|
||
if (!mesh) | ||
{ | ||
ImGui::PushStyleVar(ImGuiStyleVar_Alpha, ImGui::GetStyle().Alpha * 0.5f); | ||
ImGui::PushStyleColor(ImGuiCol_FrameBgHovered, black); | ||
ImGui::PushStyleColor(ImGuiCol_FrameBgActive, black); | ||
} | ||
if (ImGui::Checkbox("Normals", &use_normals)) | ||
{ | ||
if (!mesh) | ||
use_normals = false; | ||
else | ||
temp_cfg.set(configurations::ply::use_normals, use_normals); | ||
} | ||
if (!mesh) | ||
{ | ||
if (ImGui::IsItemHovered()) | ||
{ | ||
ImGui::SetTooltip("Enable meshing to allow vertex normals calculation"); | ||
} | ||
ImGui::PopStyleColor(2); | ||
ImGui::PopStyleVar(); | ||
} | ||
|
||
ImGui::PushStyleColor(ImGuiCol_Text, grey); | ||
ImGui::Text(" Calculate vertex normals and add them to the PLY"); | ||
ImGui::PopStyleColor(); | ||
ImGui::Separator(); | ||
|
||
ImGui::Text("Encoding:"); | ||
ImGui::PushStyleColor(ImGuiCol_Text, grey); | ||
ImGui::Text("Save PLY as binary, or as a larger textual human-readable file"); | ||
ImGui::PopStyleColor(); | ||
if (ImGui::RadioButton("Textual", encoding == 0)) | ||
{ | ||
encoding = 0; | ||
temp_cfg.set(configurations::ply::encoding, encoding); | ||
} | ||
if (ImGui::RadioButton("Binary", encoding == 1)) | ||
{ | ||
encoding = 1; | ||
temp_cfg.set(configurations::ply::encoding, encoding); | ||
} | ||
|
||
auto curr_exporter = exporters.find(tab); | ||
assert(curr_exporter != exporters.end()); // every tab should have a corresponding exporter | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The assert will be discarded in release. A run-time error should probably be generated here |
||
rs2::save_to_ply ply; | ||
curr_exporter->second.options[rs2::save_to_ply::OPTION_PLY_MESH] = mesh; | ||
curr_exporter->second.options[rs2::save_to_ply::OPTION_PLY_NORMALS] = use_normals; | ||
curr_exporter->second.options[rs2::save_to_ply::OPTION_PLY_BINARY] = encoding; | ||
} | ||
|
||
ImGui::PopStyleColor(2); // button color | ||
|
||
auto apply = [&]() { | ||
config_file::instance() = temp_cfg; | ||
update_configuration(); | ||
}; | ||
|
||
ImGui::SetCursorScreenPos({ (float)(x0 + w / 2 - 190), (float)(y0 + h - 30) }); | ||
if (ImGui::Button("OK", ImVec2(120, 0))) | ||
{ | ||
ImGui::CloseCurrentPopup(); | ||
apply(); | ||
} | ||
if (ImGui::IsItemHovered()) | ||
{ | ||
ImGui::SetTooltip("%s", "Save settings and close"); | ||
} | ||
ImGui::SameLine(); | ||
|
||
if (ImGui::Button("Export", ImVec2(120, 0))) | ||
{ | ||
auto curr_exporter = exporters.find(tab); | ||
assert(curr_exporter != exporters.end()); // every tab should have a corresponding exporter | ||
if (auto ret = file_dialog_open(save_file, curr_exporter->second.filters.c_str(), NULL, NULL)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as in line 392 |
||
{ | ||
auto model = ppf.get_points(); | ||
frame tex; | ||
if (selected_tex_source_uid >= 0 && streams.find(selected_tex_source_uid) != streams.end()) | ||
{ | ||
tex = streams[selected_tex_source_uid].texture->get_last_frame(true); | ||
if (tex) ppf.update_texture(tex); | ||
} | ||
|
||
std::string fname(ret); | ||
if (!ends_with(to_lower(fname), curr_exporter->second.extension)) fname += curr_exporter->second.extension; | ||
|
||
std::unique_ptr<rs2::filter> exporter; | ||
if (tab == 0) | ||
exporter = std::unique_ptr<rs2::filter>(new rs2::save_to_ply(fname)); | ||
auto data = alloc.process(last_points); | ||
|
||
for (auto& option : curr_exporter->second.options) | ||
{ | ||
exporter->set_option(option.first, option.second); | ||
} | ||
|
||
export_frame(fname, std::move(exporter), not_model, data); | ||
exporter.reset(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why do you need to reset it explicitly just before scoping out ? |
||
} | ||
} | ||
if (ImGui::IsItemHovered()) | ||
{ | ||
ImGui::SetTooltip("%s", "Save settings and export file"); | ||
} | ||
ImGui::SameLine(); | ||
if (ImGui::Button("Cancel", ImVec2(120, 0))) | ||
{ | ||
ImGui::CloseCurrentPopup(); | ||
} | ||
if (ImGui::IsItemHovered()) | ||
{ | ||
ImGui::SetTooltip("%s", "Close window without saving any changes to the settings"); | ||
} | ||
|
||
ImGui::EndPopup(); | ||
} | ||
ImGui::PopStyleVar(2); | ||
|
||
ImGui::PushStyleColor(ImGuiCol_Button, header_window_bg); | ||
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, header_window_bg); | ||
ImGui::PushStyleColor(ImGuiCol_ButtonActive, header_window_bg); | ||
|
||
ImGui::SetCursorPos({ stream_rect.w - 32 * num_of_buttons - 5, 0 }); | ||
|
||
if (paused) | ||
|
@@ -303,24 +507,10 @@ namespace rs2 | |
} | ||
|
||
ImGui::SameLine(); | ||
|
||
if (ImGui::Button(textual_icons::floppy, { 24, buttons_heights })) | ||
{ | ||
if (auto ret = file_dialog_open(save_file, "Polygon File Format (PLY)\0*.ply\0", NULL, NULL)) | ||
{ | ||
auto model = ppf.get_points(); | ||
|
||
frame tex; | ||
if (selected_tex_source_uid >= 0 && streams.find(selected_tex_source_uid) != streams.end()) | ||
{ | ||
tex = streams[selected_tex_source_uid].texture->get_last_frame(true); | ||
if (tex) ppf.update_texture(tex); | ||
} | ||
|
||
std::string fname(ret); | ||
if (!ends_with(to_lower(fname), ".ply")) fname += ".ply"; | ||
export_to_ply(fname.c_str(), not_model, last_points, last_texture->get_last_frame()); | ||
} | ||
temp_cfg = config_file::instance(); | ||
ImGui::OpenPopup("Export"); | ||
} | ||
if (ImGui::IsItemHovered()) | ||
ImGui::SetTooltip("Export 3D model to PLY format"); | ||
|
@@ -399,16 +589,11 @@ namespace rs2 | |
} | ||
|
||
auto total_top_bar_height = top_bar_height * (1 + pose_render); // may include single bar or additional bar for pose | ||
|
||
ImGui::PopStyleColor(5); | ||
|
||
ImGui::PushStyleColor(ImGuiCol_Text, light_grey); | ||
ImGui::PushStyleColor(ImGuiCol_TextSelectedBg, white); | ||
|
||
ImGui::PushStyleColor(ImGuiCol_Button, header_window_bg); | ||
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, header_window_bg); | ||
ImGui::PushStyleColor(ImGuiCol_ButtonActive, header_window_bg); | ||
|
||
auto old_pos = ImGui::GetCursorScreenPos(); | ||
ImVec2 pos { stream_rect.x + stream_rect.w - 215, stream_rect.y + total_top_bar_height + 5 }; | ||
ImGui::SetCursorScreenPos(pos); | ||
|
@@ -567,16 +752,19 @@ namespace rs2 | |
viewer_model::viewer_model() | ||
: ppf(*this), | ||
synchronization_enable(true), | ||
zo_sensors(0) | ||
zo_sensors(0), | ||
alloc(this) | ||
{ | ||
syncer = std::make_shared<syncer_model>(); | ||
reset_camera(); | ||
rs2_error* e = nullptr; | ||
not_model.add_log(to_string() << "librealsense version: " << api_version_to_string(rs2_get_api_version(&e)) << "\n"); | ||
|
||
update_configuration(); | ||
|
||
check_permissions(); | ||
export_model exp_model("PLY", ".ply", "Polygon File Format(PLY)\0 * .ply"); | ||
exporters.insert(std::pair<export_type, export_model>(export_type::ply, exp_model)); | ||
} | ||
|
||
void viewer_model::gc_streams() | ||
|
@@ -1871,8 +2059,8 @@ namespace rs2 | |
temp_cfg.set(configurations::viewer::settings_tab, tab); | ||
} | ||
ImGui::PopStyleColor(2); | ||
|
||
ImGui::SameLine(); | ||
|
||
ImGui::PushStyleColor(ImGuiCol_Text, tab != 3 ? light_grey : light_blue); | ||
ImGui::PushStyleColor(ImGuiCol_TextSelectedBg, tab != 3 ? light_grey : light_blue); | ||
if (ImGui::Button("Updates", { 120, 30 })) | ||
|
@@ -2493,6 +2681,11 @@ namespace rs2 | |
return false; | ||
} | ||
|
||
std::shared_ptr<texture_buffer> viewer_model::get_last_texture() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This seem to be a public member - what is the getter for ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. last_texture is private |
||
{ | ||
return last_texture; | ||
} | ||
|
||
std::vector<frame> rs2::viewer_model::get_frames(frame frame) | ||
{ | ||
std::vector<rs2::frame> res; | ||
|
@@ -2578,7 +2771,7 @@ namespace rs2 | |
if (paused) | ||
show_paused_icon(window.get_large_font(), static_cast<int>(panel_width + 15), static_cast<int>(panel_y + 15 + 32), 0); | ||
|
||
show_3dviewer_header(window.get_font(), viewer_rect, paused, error_message); | ||
show_3dviewer_header(window.get_large_font(), window.get_font(), viewer_rect, paused, error_message); | ||
|
||
update_3d_camera(window, viewer_rect); | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pls check whether the capture is safe if device is disconnected while processing the export