diff options
4 files changed, 49 insertions, 46 deletions
diff --git a/Userland/Applications/3DFileViewer/MeshLoader.h b/Userland/Applications/3DFileViewer/MeshLoader.h index fd62d49e64..9676bf2604 100644 --- a/Userland/Applications/3DFileViewer/MeshLoader.h +++ b/Userland/Applications/3DFileViewer/MeshLoader.h @@ -7,6 +7,7 @@ #pragma once #include <AK/String.h> +#include <LibCore/File.h> #include "Common.h" #include "Mesh.h" @@ -16,5 +17,5 @@ public: MeshLoader() { } virtual ~MeshLoader() { } - virtual RefPtr<Mesh> load(const String& fname) = 0; + virtual RefPtr<Mesh> load(Core::File& file) = 0; }; diff --git a/Userland/Applications/3DFileViewer/WavefrontOBJLoader.cpp b/Userland/Applications/3DFileViewer/WavefrontOBJLoader.cpp index 891f13dc8f..3022d5218f 100644 --- a/Userland/Applications/3DFileViewer/WavefrontOBJLoader.cpp +++ b/Userland/Applications/3DFileViewer/WavefrontOBJLoader.cpp @@ -9,19 +9,15 @@ #include <LibCore/File.h> #include <stdlib.h> -RefPtr<Mesh> WavefrontOBJLoader::load(const String& fname) +RefPtr<Mesh> WavefrontOBJLoader::load(Core::File& file) { - auto obj_file_or_error = Core::File::open(fname, Core::OpenMode::ReadOnly); Vector<Vertex> vertices; Vector<Triangle> triangles; - dbgln("Wavefront: Loading {}...", fname); - - if (obj_file_or_error.is_error()) - return nullptr; + dbgln("Wavefront: Loading {}...", file.name()); // Start reading file line by line - for (auto line = obj_file_or_error.value()->line_begin(); !line.at_end(); ++line) { + for (auto line = file.line_begin(); !line.at_end(); ++line) { auto object_line = *line; // FIXME: Parse texture coordinates and vertex normals @@ -67,7 +63,7 @@ RefPtr<Mesh> WavefrontOBJLoader::load(const String& fname) } if (vertices.is_empty()) { - dbgln("Wavefront: Failed to read any data from 3D file: {}", fname); + dbgln("Wavefront: Failed to read any data from 3D file: {}", file.name()); return nullptr; } diff --git a/Userland/Applications/3DFileViewer/WavefrontOBJLoader.h b/Userland/Applications/3DFileViewer/WavefrontOBJLoader.h index 92ef601577..afebce1384 100644 --- a/Userland/Applications/3DFileViewer/WavefrontOBJLoader.h +++ b/Userland/Applications/3DFileViewer/WavefrontOBJLoader.h @@ -12,10 +12,10 @@ #include "Mesh.h" #include "MeshLoader.h" -class WavefrontOBJLoader : public MeshLoader { +class WavefrontOBJLoader final : public MeshLoader { public: WavefrontOBJLoader() { } ~WavefrontOBJLoader() override { } - RefPtr<Mesh> load(const String& fname) override; + RefPtr<Mesh> load(Core::File& file) override; }; diff --git a/Userland/Applications/3DFileViewer/main.cpp b/Userland/Applications/3DFileViewer/main.cpp index 93c8c616d8..cb12a42431 100644 --- a/Userland/Applications/3DFileViewer/main.cpp +++ b/Userland/Applications/3DFileViewer/main.cpp @@ -59,11 +59,6 @@ private: glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } glEndList(); - - // Load the teapot - m_mesh = m_mesh_loader->load("/home/anon/Documents/3D Models/teapot.obj"); - - dbgln("3DFileViewer: teapot mesh has {} triangles.", m_mesh->triangle_count()); } virtual void paint_event(GUI::PaintEvent&) override; @@ -109,15 +104,39 @@ void GLContextWidget::timer_event(Core::TimerEvent&) update(); } -bool GLContextWidget::load(const String& fname) +bool GLContextWidget::load(const String& filename) { - m_mesh = m_mesh_loader->load(fname); - if (!m_mesh.is_null()) { - dbgln("3DFileViewer: mesh has {} triangles.", m_mesh->triangle_count()); - return true; + auto file = Core::File::construct(filename); + + if (!file->filename().ends_with(".obj")) { + GUI::MessageBox::show(window(), String::formatted("Opening \"{}\" failed: invalid file type", filename), "Error", GUI::MessageBox::Type::Error); + return false; + } + + if (!file->open(Core::OpenMode::ReadOnly) && file->error() != ENOENT) { + GUI::MessageBox::show(window(), String::formatted("Opening \"{}\" failed: {}", filename, strerror(errno)), "Error", GUI::MessageBox::Type::Error); + return false; + } + + if (file->is_device()) { + GUI::MessageBox::show(window(), String::formatted("Opening \"{}\" failed: Can't open device files", filename), "Error", GUI::MessageBox::Type::Error); + return false; } - return false; + if (file->is_directory()) { + GUI::MessageBox::show(window(), String::formatted("Opening \"{}\" failed: Can't open directories", filename), "Error", GUI::MessageBox::Type::Error); + return false; + } + + auto new_mesh = m_mesh_loader->load(file); + if (new_mesh.is_null()) { + GUI::MessageBox::show(window(), String::formatted("Reading \"{}\" failed.", filename), "Error", GUI::MessageBox::Type::Error); + return false; + } + + m_mesh = new_mesh; + dbgln("3DFileViewer: mesh has {} triangles.", m_mesh->triangle_count()); + return true; } int main(int argc, char** argv) @@ -143,36 +162,20 @@ int main(int argc, char** argv) auto menubar = GUI::Menubar::construct(); auto& file_menu = menubar->add_menu("&File"); + auto load_model = [&](StringView const& filename) { + if (widget.load(filename)) { + auto canonical_path = Core::File::real_path_for(filename); + window->set_title(String::formatted("{} - 3D File Viewer", canonical_path)); + } + }; + file_menu.add_action(GUI::CommonActions::make_open_action([&](auto&) { Optional<String> open_path = GUI::FilePicker::get_open_filepath(window); if (!open_path.has_value()) return; - auto file = Core::File::construct(open_path.value()); - - if (!file->filename().ends_with(".obj")) { - GUI::MessageBox::show(window, String::formatted("Opening \"{}\" failed: invalid file type", open_path.value()), "Error", GUI::MessageBox::Type::Error); - return; - } - - if (!file->open(Core::OpenMode::ReadOnly) && file->error() != ENOENT) { - GUI::MessageBox::show(window, String::formatted("Opening \"{}\" failed: {}", open_path.value(), strerror(errno)), "Error", GUI::MessageBox::Type::Error); - return; - } - - if (file->is_device()) { - GUI::MessageBox::show(window, String::formatted("Opening \"{}\" failed: Can't open device files", open_path.value()), "Error", GUI::MessageBox::Type::Error); - return; - } - - if (file->is_directory()) { - GUI::MessageBox::show(window, String::formatted("Opening \"{}\" failed: Can't open directories", open_path.value()), "Error", GUI::MessageBox::Type::Error); - return; - } - - if (!widget.load(file->filename())) - GUI::MessageBox::show(window, String::formatted("Reading \"{}\" failed.", open_path.value()), "Error", GUI::MessageBox::Type::Error); + load_model(open_path.value()); })); file_menu.add_action(GUI::CommonActions::make_quit_action([&](auto&) { @@ -185,5 +188,8 @@ int main(int argc, char** argv) window->set_menubar(move(menubar)); window->show(); + auto filename = argc > 1 ? argv[1] : "/home/anon/Documents/3D Models/teapot.obj"; + load_model(filename); + return app->exec(); } |