Move projection into separate utils to not slow down translation of files using Camera.hpp

This commit is contained in:
Filip Sykala 2021-11-04 13:16:56 +01:00
parent d3dd025833
commit 43230b2709
7 changed files with 73 additions and 34 deletions

View File

@ -133,6 +133,8 @@ set(SLIC3R_GUI_SOURCES
GUI/3DBed.hpp
GUI/Camera.cpp
GUI/Camera.hpp
GUI/CameraUtils.cpp
GUI/CameraUtils.hpp
GUI/wxExtensions.cpp
GUI/wxExtensions.hpp
GUI/ExtruderSequenceDialog.cpp

View File

@ -9,7 +9,6 @@
#endif // ENABLE_CAMERA_STATISTICS
#include <GL/glew.h>
#include <igl/project.h> // projecting points
namespace Slic3r {
namespace GUI {
@ -493,34 +492,6 @@ void Camera::look_at(const Vec3d& position, const Vec3d& target, const Vec3d& up
update_zenit();
}
Points Camera::project(const std::vector<Vec3d> &points) const
{
Vec4i viewport(m_viewport.data());
// Convert our std::vector to Eigen dynamic matrix.
Eigen::Matrix<double, Eigen::Dynamic, 3, Eigen::DontAlign>
pts(points.size(), 3);
for (size_t i = 0; i < points.size(); ++i)
pts.block<1, 3>(i, 0) = points[i];
// Get the projections.
Eigen::Matrix<double, Eigen::Dynamic, 3, Eigen::DontAlign> projections;
igl::project(pts, m_view_matrix.matrix(), m_projection_matrix.matrix(), viewport, projections);
Points result;
result.reserve(points.size());
int window_height = viewport[3];
// Iterate over all points and determine whether they're in the rectangle.
for (int i = 0; i < projections.rows(); ++i) {
double x = projections(i, 0);
double y = projections(i, 1);
// opposit direction o Y
result.emplace_back(x, window_height - y);
}
return result;
}
void Camera::set_default_orientation()
{
m_zenit = 45.0f;

View File

@ -129,8 +129,6 @@ public:
double max_zoom() const { return 250.0; }
double min_zoom() const { return 0.7 * calc_zoom_to_bounding_box_factor(m_scene_box); }
// project point throw camera to 2d coordinate
Points project(const std::vector<Vec3d> &points) const;
private:
// returns tight values for nearZ and farZ plane around the given bounding box
// the camera MUST be outside of the bounding box in eye coordinate of the given box

View File

@ -0,0 +1,35 @@
#include "CameraUtils.hpp"
#include <igl/project.h> // projecting points
using namespace Slic3r;
using namespace GUI;
Points CameraUtils::project(const Camera & camera,
const std::vector<Vec3d> &points)
{
Vec4i viewport(camera.get_viewport().data());
// Convert our std::vector to Eigen dynamic matrix.
Eigen::Matrix<double, Eigen::Dynamic, 3, Eigen::DontAlign>
pts(points.size(), 3);
for (size_t i = 0; i < points.size(); ++i)
pts.block<1, 3>(i, 0) = points[i];
// Get the projections.
Eigen::Matrix<double, Eigen::Dynamic, 3, Eigen::DontAlign> projections;
igl::project(pts, camera.get_view_matrix().matrix(),
camera.get_projection_matrix().matrix(), viewport, projections);
Points result;
result.reserve(points.size());
int window_height = viewport[3];
// Iterate over all points and determine whether they're in the rectangle.
for (int i = 0; i < projections.rows(); ++i) {
double x = projections(i, 0);
double y = projections(i, 1);
// opposit direction o Y
result.emplace_back(x, window_height - y);
}
return result;
}

View File

@ -0,0 +1,30 @@
#ifndef slic3r_CameraUtils_hpp_
#define slic3r_CameraUtils_hpp_
#include "Camera.hpp"
#include "libslic3r/Point.hpp"
namespace Slic3r::GUI {
/// <summary>
/// Help divide camera data and camera functions
/// This utility work with camera data by static funtions
/// </summary>
class CameraUtils
{
public:
CameraUtils() = delete; // only static functions
/// <summary>
/// project point throw camera to 2d coordinate into imgui window
/// </summary>
/// <param name="its">IN/OUT triangle mesh to be simplified.</param>
/// <param name="its">IN/OUT triangle mesh to be simplified.</param>
/// <returns>projected points by camera into coordinate of camera.
/// x(from left to right), y(from top to bottom)</returns>
static Points project(const Camera& camera, const std::vector<Vec3d> &points);
};
} // Slic3r::GUI
#endif /* slic3r_CameraUtils_hpp_ */

View File

@ -1,5 +1,6 @@
#include "GLSelectionRectangle.hpp"
#include "Camera.hpp"
#include "CameraUtils.hpp"
#include "3DScene.hpp"
#include "GLCanvas3D.hpp"
#include "GUI_App.hpp"
@ -42,7 +43,8 @@ namespace GUI {
BoundingBox rectangle(Points{ Point(m_start_corner.cast<coord_t>()), Point(m_end_corner.cast<coord_t>()) });
// Iterate over all points and determine whether they're in the rectangle.
Points points_2d = wxGetApp().plater()->get_camera().project(points);
const Camera &camera = wxGetApp().plater()->get_camera();
Points points_2d = CameraUtils::project(camera, points);
for (int i = 0; i<points.size(); ++i)
if (rectangle.contains(points_2d[i]))
out.push_back(i);

View File

@ -8,6 +8,7 @@
#include "slic3r/GUI/Plater.hpp"
#include "slic3r/GUI/MsgDialog.hpp"
#include "slic3r/GUI/format.hpp"
#include "slic3r/GUI/CameraUtils.hpp"
// TODO: remove include
#include "libslic3r/SVG.hpp" // debug store
@ -490,8 +491,8 @@ static void draw_hull(const GLVolume& volume)
for (const Vec3f &vertex : tm.its.vertices)
vertices.emplace_back(trafoMat * vertex.cast<double>());
const Camera camera = wxGetApp().plater()->get_camera();
Points vertices_2d = camera.project(vertices);
const Camera& camera = wxGetApp().plater()->get_camera();
Points vertices_2d = CameraUtils::project(camera, vertices);
Slic3r::Polygon chull = Geometry::convex_hull(vertices_2d);
draw(chull, ImGui::GetColorU32(ImVec4(0.7f, 0.1f, 0.2f, 0.75f)), 3.f);
}