mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-14 04:35:54 +08:00
Draw text convex hull
This commit is contained in:
parent
9749dcb959
commit
d3dd025833
@ -9,6 +9,7 @@
|
|||||||
#endif // ENABLE_CAMERA_STATISTICS
|
#endif // ENABLE_CAMERA_STATISTICS
|
||||||
|
|
||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
|
#include <igl/project.h> // projecting points
|
||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
namespace GUI {
|
namespace GUI {
|
||||||
@ -492,6 +493,34 @@ void Camera::look_at(const Vec3d& position, const Vec3d& target, const Vec3d& up
|
|||||||
update_zenit();
|
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()
|
void Camera::set_default_orientation()
|
||||||
{
|
{
|
||||||
m_zenit = 45.0f;
|
m_zenit = 45.0f;
|
||||||
|
@ -129,6 +129,8 @@ public:
|
|||||||
double max_zoom() const { return 250.0; }
|
double max_zoom() const { return 250.0; }
|
||||||
double min_zoom() const { return 0.7 * calc_zoom_to_bounding_box_factor(m_scene_box); }
|
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:
|
private:
|
||||||
// returns tight values for nearZ and farZ plane around the given bounding box
|
// 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
|
// the camera MUST be outside of the bounding box in eye coordinate of the given box
|
||||||
|
@ -38,26 +38,13 @@ namespace GUI {
|
|||||||
|
|
||||||
m_state = Off;
|
m_state = Off;
|
||||||
|
|
||||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
|
||||||
Matrix4d modelview = camera.get_view_matrix().matrix();
|
|
||||||
Matrix4d projection= camera.get_projection_matrix().matrix();
|
|
||||||
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, modelview, projection, viewport, projections);
|
|
||||||
|
|
||||||
// bounding box created from the rectangle corners - will take care of order of the corners
|
// bounding box created from the rectangle corners - will take care of order of the corners
|
||||||
BoundingBox rectangle(Points{ Point(m_start_corner.cast<coord_t>()), Point(m_end_corner.cast<coord_t>()) });
|
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.
|
// Iterate over all points and determine whether they're in the rectangle.
|
||||||
for (int i = 0; i<projections.rows(); ++i)
|
Points points_2d = wxGetApp().plater()->get_camera().project(points);
|
||||||
if (rectangle.contains(Point(projections(i, 0), canvas.get_canvas_size().get_height() - projections(i, 1))))
|
for (int i = 0; i<points.size(); ++i)
|
||||||
|
if (rectangle.contains(points_2d[i]))
|
||||||
out.push_back(i);
|
out.push_back(i);
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
|
@ -297,8 +297,6 @@ void GLGizmoEmboss::initialize()
|
|||||||
m_font_selected = 0;
|
m_font_selected = 0;
|
||||||
|
|
||||||
bool is_font_loaded = load_font();
|
bool is_font_loaded = load_font();
|
||||||
//FontList fl = Emboss::get_font_list();
|
|
||||||
//m_font_list.insert(m_font_list.end(), fl.begin(), fl.end());
|
|
||||||
while (!is_font_loaded && !m_font_list.empty()) {
|
while (!is_font_loaded && !m_font_list.empty()) {
|
||||||
// can't load so erase it from list
|
// can't load so erase it from list
|
||||||
m_font_list.erase(m_font_list.begin() + m_font_selected);
|
m_font_list.erase(m_font_list.begin() + m_font_selected);
|
||||||
@ -319,7 +317,7 @@ FontList GLGizmoEmboss::create_default_font_list() {
|
|||||||
void GLGizmoEmboss::set_default_configuration() {
|
void GLGizmoEmboss::set_default_configuration() {
|
||||||
m_text = _u8L("Embossed text");
|
m_text = _u8L("Embossed text");
|
||||||
m_font_prop = FontProp();
|
m_font_prop = FontProp();
|
||||||
// may be set default font?
|
load_font(); // reload actual font - because of font size
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "imgui/imgui_internal.h" // to unfocus input --> ClearActiveID
|
#include "imgui/imgui_internal.h" // to unfocus input --> ClearActiveID
|
||||||
@ -457,6 +455,48 @@ void GLGizmoEmboss::close() {
|
|||||||
m_parent.get_gizmos_manager().open_gizmo(GLGizmosManager::Emboss);
|
m_parent.get_gizmos_manager().open_gizmo(GLGizmosManager::Emboss);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void draw(const Slic3r::Polygon &polygon,
|
||||||
|
ImU32 color = ImGui::GetColorU32(ImVec4(0.3f, 0.3f, 0.7f, 0.65f)),
|
||||||
|
float thickness = 1.f)
|
||||||
|
{
|
||||||
|
// minimal one line
|
||||||
|
if (polygon.size()<2) return;
|
||||||
|
|
||||||
|
auto dl = ImGui::GetOverlayDrawList();
|
||||||
|
//auto dl = ImGui::GetWindowDrawList();
|
||||||
|
const Point* prev_point = &polygon.points.back();
|
||||||
|
for (const Point &point : polygon.points) {
|
||||||
|
ImVec2 p1(prev_point->x(), prev_point->y());
|
||||||
|
ImVec2 p2(point.x(), point.y());
|
||||||
|
dl->AddLine(p1, p2, color, thickness);
|
||||||
|
prev_point = &point;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "libslic3r/Geometry.hpp"
|
||||||
|
static void draw_hull(const GLVolume& volume)
|
||||||
|
{
|
||||||
|
const TriangleMesh &tm = *volume.convex_hull();
|
||||||
|
ImGui::Text("hull size %d", (int) tm.its.vertices.size());
|
||||||
|
|
||||||
|
//Slic3r::Polygon test_triangle({Point(100, 100), Point(200, 150), Point(120, 210)});
|
||||||
|
//draw(test_triangle);
|
||||||
|
|
||||||
|
// transform 3d hull
|
||||||
|
Geometry::Transformation trafo = volume.get_instance_transformation();
|
||||||
|
const Transform3d & trafoMat = trafo.get_matrix();
|
||||||
|
std::vector<Vec3d> vertices;
|
||||||
|
vertices.reserve(tm.its.vertices.size());
|
||||||
|
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);
|
||||||
|
Slic3r::Polygon chull = Geometry::convex_hull(vertices_2d);
|
||||||
|
draw(chull, ImGui::GetColorU32(ImVec4(0.7f, 0.1f, 0.2f, 0.75f)), 3.f);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void GLGizmoEmboss::draw_window()
|
void GLGizmoEmboss::draw_window()
|
||||||
{
|
{
|
||||||
#ifdef ALLOW_DEBUG_MODE
|
#ifdef ALLOW_DEBUG_MODE
|
||||||
@ -467,11 +507,14 @@ void GLGizmoEmboss::draw_window()
|
|||||||
m_font_list.emplace_back(WxFontUtils::get_os_font());
|
m_font_list.emplace_back(WxFontUtils::get_os_font());
|
||||||
bool loaded = load_font(font_index);
|
bool loaded = load_font(font_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Selection &selection = m_parent.get_selection();
|
||||||
|
const GLVolume * volume = selection.get_volume(
|
||||||
|
*selection.get_volume_idxs().begin());
|
||||||
|
if (volume != nullptr) draw_hull(*volume);
|
||||||
|
|
||||||
|
|
||||||
#endif // ALLOW_DEBUG_MODE
|
#endif // ALLOW_DEBUG_MODE
|
||||||
|
|
||||||
std::string descriptor = m_font_list[m_font_selected].path;
|
|
||||||
ImGui::Text("actual descriptor is %s", descriptor.c_str());
|
|
||||||
|
|
||||||
if (!m_font.has_value()) {
|
if (!m_font.has_value()) {
|
||||||
ImGui::Text(_u8L("Warning: No font is selected. Select correct one.").c_str());
|
ImGui::Text(_u8L("Warning: No font is selected. Select correct one.").c_str());
|
||||||
}
|
}
|
||||||
@ -592,10 +635,6 @@ void GLGizmoEmboss::draw_text_input()
|
|||||||
|
|
||||||
// imgui_font has to be unused
|
// imgui_font has to be unused
|
||||||
if (exist_change) check_imgui_font_range();
|
if (exist_change) check_imgui_font_range();
|
||||||
|
|
||||||
#ifdef ALLOW_DEBUG_MODE
|
|
||||||
ImGui::Image(m_imgui_font_atlas.TexID, ImVec2(m_imgui_font_atlas.TexWidth, m_imgui_font_atlas.TexHeight));
|
|
||||||
#endif // ALLOW_DEBUG_MODE
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLGizmoEmboss::draw_advanced() {
|
void GLGizmoEmboss::draw_advanced() {
|
||||||
@ -637,13 +676,14 @@ void GLGizmoEmboss::draw_advanced() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ALLOW_DEBUG_MODE
|
||||||
|
std::string descriptor = m_font_list[m_font_selected].path;
|
||||||
|
ImGui::Text("descriptor = %s", descriptor.c_str());
|
||||||
ImGui::Text("style = %s", (m_font_prop.style.has_value()?m_font_prop.style->c_str() : " --- "));
|
ImGui::Text("style = %s", (m_font_prop.style.has_value()?m_font_prop.style->c_str() : " --- "));
|
||||||
ImGui::Text("weight = %s", (m_font_prop.weight.has_value()? m_font_prop.weight->c_str() : " --- "));
|
ImGui::Text("weight = %s", (m_font_prop.weight.has_value()? m_font_prop.weight->c_str() : " --- "));
|
||||||
ImGui::Text("face name = %s", (m_font_prop.face_name.has_value()?m_font_prop.face_name->c_str() : " --- "));
|
ImGui::Text("face name = %s", (m_font_prop.face_name.has_value()?m_font_prop.face_name->c_str() : " --- "));
|
||||||
|
ImGui::Image(m_imgui_font_atlas.TexID, ImVec2(m_imgui_font_atlas.TexWidth, m_imgui_font_atlas.TexHeight));
|
||||||
// ImGui::InputFloat3("Origin", m_orientation.origin.data());
|
#endif // ALLOW_DEBUG_MODE
|
||||||
// if (ImGui::InputFloat3("Normal", m_normal.data())) m_normal.normalize();
|
|
||||||
// if (ImGui::InputFloat3("Up", m_up.data())) m_up.normalize();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GLGizmoEmboss::create_default_model_object()
|
bool GLGizmoEmboss::create_default_model_object()
|
||||||
@ -733,11 +773,7 @@ bool GLGizmoEmboss::load_font(const wxFont& font)
|
|||||||
auto font_opt = WxFontUtils::load_font(font);
|
auto font_opt = WxFontUtils::load_font(font);
|
||||||
if (!font_opt.has_value()) return false;
|
if (!font_opt.has_value()) return false;
|
||||||
m_font = font_opt;
|
m_font = font_opt;
|
||||||
|
|
||||||
FontProp old_font_prop = m_font_prop; // copy
|
|
||||||
|
|
||||||
WxFontUtils::update_property(m_font_prop, font);
|
WxFontUtils::update_property(m_font_prop, font);
|
||||||
|
|
||||||
m_font_prop.emboss = m_font_prop.size_in_mm / 2.f;
|
m_font_prop.emboss = m_font_prop.size_in_mm / 2.f;
|
||||||
load_imgui_font();
|
load_imgui_font();
|
||||||
return true;
|
return true;
|
||||||
@ -818,9 +854,8 @@ void GLGizmoEmboss::load_imgui_font() {
|
|||||||
GLuint font_texture;
|
GLuint font_texture;
|
||||||
glsafe(::glGenTextures(1, &font_texture));
|
glsafe(::glGenTextures(1, &font_texture));
|
||||||
glsafe(::glBindTexture(GL_TEXTURE_2D, font_texture));
|
glsafe(::glBindTexture(GL_TEXTURE_2D, font_texture));
|
||||||
glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
|
glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
|
||||||
GL_LINEAR)); glsafe(::glTexParameteri(GL_TEXTURE_2D,
|
glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
|
||||||
GL_TEXTURE_MAG_FILTER, GL_LINEAR));
|
|
||||||
glsafe(::glPixelStorei(GL_UNPACK_ROW_LENGTH, 0));
|
glsafe(::glPixelStorei(GL_UNPACK_ROW_LENGTH, 0));
|
||||||
glsafe(::glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0,
|
glsafe(::glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0,
|
||||||
GL_ALPHA, GL_UNSIGNED_BYTE, pixels));
|
GL_ALPHA, GL_UNSIGNED_BYTE, pixels));
|
||||||
|
@ -192,7 +192,7 @@ TEST_CASE("Reduce to one triangle by Quadric Edge Collapse", "[its]")
|
|||||||
//CHECK(is_equal(its.vertices, triangle_vertices));
|
//CHECK(is_equal(its.vertices, triangle_vertices));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("Reduce to one triangle by Quadric Edge Collapse", "[its]")
|
TEST_CASE("Reduce to one tetrahedron by Quadric Edge Collapse", "[its]")
|
||||||
{
|
{
|
||||||
// Extend previous test to tetrahedron to make it manifold
|
// Extend previous test to tetrahedron to make it manifold
|
||||||
indexed_triangle_set its;
|
indexed_triangle_set its;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user