Merge branch 'master' of https://github.com/prusa3d/Slic3r into svg_icons
This commit is contained in:
commit
9ff8cd01b3
9 changed files with 262 additions and 69 deletions
|
@ -1,11 +1,12 @@
|
|||
#version 110
|
||||
|
||||
attribute vec4 v_position;
|
||||
attribute vec2 v_tex_coords;
|
||||
|
||||
varying vec2 tex_coords;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = ftransform();
|
||||
gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * v_position;
|
||||
tex_coords = v_tex_coords;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -242,6 +242,7 @@ public:
|
|||
|
||||
void set_scaling_factor(const Vec3d& scaling_factor);
|
||||
void set_scaling_factor(Axis axis, double scaling_factor);
|
||||
bool is_scaling_uniform() const { return std::abs(m_scaling_factor.x() - m_scaling_factor.y()) < 1e-8 && std::abs(m_scaling_factor.x() - m_scaling_factor.z()) < 1e-8; }
|
||||
|
||||
const Vec3d& get_mirror() const { return m_mirror; }
|
||||
double get_mirror(Axis axis) const { return m_mirror(axis); }
|
||||
|
|
|
@ -516,9 +516,9 @@ void Bed3D::render_prusa(const std::string &key, bool bottom) const
|
|||
|
||||
if (max_anisotropy > 0.0f)
|
||||
{
|
||||
::glBindTexture(GL_TEXTURE_2D, m_texture.get_id());
|
||||
::glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, max_anisotropy);
|
||||
::glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glsafe(::glBindTexture(GL_TEXTURE_2D, m_texture.get_id()));
|
||||
glsafe(::glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, max_anisotropy));
|
||||
glsafe(::glBindTexture(GL_TEXTURE_2D, 0));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -542,9 +542,9 @@ void Bed3D::render_prusa(const std::string &key, bool bottom) const
|
|||
|
||||
if (!m_model.get_filename().empty())
|
||||
{
|
||||
::glEnable(GL_LIGHTING);
|
||||
glsafe(::glEnable(GL_LIGHTING));
|
||||
m_model.render();
|
||||
::glDisable(GL_LIGHTING);
|
||||
glsafe(::glDisable(GL_LIGHTING));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -553,39 +553,32 @@ void Bed3D::render_prusa(const std::string &key, bool bottom) const
|
|||
{
|
||||
if (m_vbo_id == 0)
|
||||
{
|
||||
::glGenBuffers(1, &m_vbo_id);
|
||||
::glBindBuffer(GL_ARRAY_BUFFER, m_vbo_id);
|
||||
::glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)m_triangles.get_vertices_data_size(), (const GLvoid*)m_triangles.get_vertices_data(), GL_STATIC_DRAW);
|
||||
::glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, m_triangles.get_vertex_data_size(), (GLvoid*)m_triangles.get_position_offset());
|
||||
::glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, m_triangles.get_vertex_data_size(), (GLvoid*)m_triangles.get_tex_coords_offset());
|
||||
::glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glsafe(::glGenBuffers(1, &m_vbo_id));
|
||||
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, m_vbo_id));
|
||||
glsafe(::glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)m_triangles.get_vertices_data_size(), (const GLvoid*)m_triangles.get_vertices_data(), GL_STATIC_DRAW));
|
||||
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
|
||||
}
|
||||
|
||||
::glEnable(GL_DEPTH_TEST);
|
||||
::glDepthMask(GL_FALSE);
|
||||
glsafe(::glEnable(GL_DEPTH_TEST));
|
||||
glsafe(::glDepthMask(GL_FALSE));
|
||||
|
||||
::glEnable(GL_BLEND);
|
||||
::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
::glEnable(GL_TEXTURE_2D);
|
||||
::glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
|
||||
glsafe(::glEnable(GL_BLEND));
|
||||
glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
|
||||
|
||||
if (bottom)
|
||||
::glFrontFace(GL_CW);
|
||||
glsafe(::glFrontFace(GL_CW));
|
||||
|
||||
render_prusa_shader(triangles_vcount, bottom);
|
||||
render_prusa_shader(bottom);
|
||||
|
||||
if (bottom)
|
||||
::glFrontFace(GL_CCW);
|
||||
glsafe(::glFrontFace(GL_CCW));
|
||||
|
||||
::glDisable(GL_TEXTURE_2D);
|
||||
|
||||
::glDisable(GL_BLEND);
|
||||
::glDepthMask(GL_TRUE);
|
||||
glsafe(::glDisable(GL_BLEND));
|
||||
glsafe(::glDepthMask(GL_TRUE));
|
||||
}
|
||||
}
|
||||
|
||||
void Bed3D::render_prusa_shader(unsigned int vertices_count, bool transparent) const
|
||||
void Bed3D::render_prusa_shader(bool transparent) const
|
||||
{
|
||||
if (m_shader.get_shader_program_id() == 0)
|
||||
m_shader.init("printbed.vs", "printbed.fs");
|
||||
|
@ -595,15 +588,35 @@ void Bed3D::render_prusa_shader(unsigned int vertices_count, bool transparent) c
|
|||
m_shader.start_using();
|
||||
m_shader.set_uniform("transparent_background", transparent);
|
||||
|
||||
::glBindTexture(GL_TEXTURE_2D, (GLuint)m_texture.get_id());
|
||||
::glBindBuffer(GL_ARRAY_BUFFER, m_vbo_id);
|
||||
::glEnableVertexAttribArray(0);
|
||||
::glEnableVertexAttribArray(1);
|
||||
::glDrawArrays(GL_TRIANGLES, 0, (GLsizei)vertices_count);
|
||||
::glDisableVertexAttribArray(1);
|
||||
::glDisableVertexAttribArray(0);
|
||||
::glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
::glBindTexture(GL_TEXTURE_2D, 0);
|
||||
unsigned int stride = m_triangles.get_vertex_data_size();
|
||||
|
||||
GLint position_id = m_shader.get_attrib_location("v_position");
|
||||
GLint tex_coords_id = m_shader.get_attrib_location("v_tex_coords");
|
||||
|
||||
glsafe(::glBindTexture(GL_TEXTURE_2D, (GLuint)m_texture.get_id()));
|
||||
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, m_vbo_id));
|
||||
|
||||
if (position_id != -1)
|
||||
{
|
||||
glsafe(::glEnableVertexAttribArray(position_id));
|
||||
glsafe(::glVertexAttribPointer(position_id, 3, GL_FLOAT, GL_FALSE, stride, (GLvoid*)m_triangles.get_position_offset()));
|
||||
}
|
||||
if (tex_coords_id != -1)
|
||||
{
|
||||
glsafe(::glEnableVertexAttribArray(tex_coords_id));
|
||||
glsafe(::glVertexAttribPointer(tex_coords_id, 2, GL_FLOAT, GL_FALSE, stride, (GLvoid*)m_triangles.get_tex_coords_offset()));
|
||||
}
|
||||
|
||||
glsafe(::glDrawArrays(GL_TRIANGLES, 0, (GLsizei)m_triangles.get_vertices_count()));
|
||||
|
||||
if (tex_coords_id != -1)
|
||||
glsafe(::glDisableVertexAttribArray(tex_coords_id));
|
||||
|
||||
if (position_id != -1)
|
||||
glsafe(::glDisableVertexAttribArray(position_id));
|
||||
|
||||
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
|
||||
glsafe(::glBindTexture(GL_TEXTURE_2D, 0));
|
||||
|
||||
m_shader.stop_using();
|
||||
}
|
||||
|
@ -754,7 +767,7 @@ void Bed3D::render_custom() const
|
|||
glsafe(::glColor4f(0.35f, 0.35f, 0.35f, 0.4f));
|
||||
glsafe(::glNormal3d(0.0f, 0.0f, 1.0f));
|
||||
#if ENABLE_TEXTURES_FROM_SVG
|
||||
::glVertexPointer(3, GL_FLOAT, m_triangles.get_vertex_data_size(), (GLvoid*)m_triangles.get_vertices_data());
|
||||
glsafe(::glVertexPointer(3, GL_FLOAT, m_triangles.get_vertex_data_size(), (GLvoid*)m_triangles.get_vertices_data()));
|
||||
#else
|
||||
glsafe(::glVertexPointer(3, GL_FLOAT, 0, (GLvoid*)m_triangles.get_vertices()));
|
||||
#endif // ENABLE_TEXTURES_FROM_SVG
|
||||
|
@ -768,7 +781,7 @@ void Bed3D::render_custom() const
|
|||
glsafe(::glLineWidth(3.0f * m_scale_factor));
|
||||
glsafe(::glColor4f(0.2f, 0.2f, 0.2f, 0.4f));
|
||||
#if ENABLE_TEXTURES_FROM_SVG
|
||||
::glVertexPointer(3, GL_FLOAT, m_triangles.get_vertex_data_size(), (GLvoid*)m_gridlines.get_vertices_data());
|
||||
glsafe(::glVertexPointer(3, GL_FLOAT, m_triangles.get_vertex_data_size(), (GLvoid*)m_gridlines.get_vertices_data()));
|
||||
#else
|
||||
glsafe(::glVertexPointer(3, GL_FLOAT, 0, (GLvoid*)m_gridlines.get_vertices()));
|
||||
#endif // ENABLE_TEXTURES_FROM_SVG
|
||||
|
@ -786,7 +799,7 @@ void Bed3D::reset()
|
|||
{
|
||||
if (m_vbo_id > 0)
|
||||
{
|
||||
::glDeleteBuffers(1, &m_vbo_id);
|
||||
glsafe(::glDeleteBuffers(1, &m_vbo_id));
|
||||
m_vbo_id = 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -131,7 +131,7 @@ private:
|
|||
EType detect_type(const Pointfs& shape) const;
|
||||
#if ENABLE_TEXTURES_FROM_SVG
|
||||
void render_prusa(const std::string& key, bool bottom) const;
|
||||
void render_prusa_shader(unsigned int vertices_count, bool transparent) const;
|
||||
void render_prusa_shader(bool transparent) const;
|
||||
#else
|
||||
void render_prusa(const std::string &key, float theta, bool useVBOs) const;
|
||||
#endif // ENABLE_TEXTURES_FROM_SVG
|
||||
|
|
|
@ -225,6 +225,17 @@ bool GLShader::set_uniform(const char* name, const float* matrix) const
|
|||
return false;
|
||||
}
|
||||
|
||||
bool GLShader::set_uniform(const char* name, int value) const
|
||||
{
|
||||
int id = get_uniform_location(name);
|
||||
if (id >= 0)
|
||||
{
|
||||
::glUniform1i(id, value);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
# Set shader vector
|
||||
sub SetVector
|
||||
|
@ -306,6 +317,16 @@ void Shader::stop_using() const
|
|||
m_shader->disable();
|
||||
}
|
||||
|
||||
int Shader::get_attrib_location(const std::string& name) const
|
||||
{
|
||||
return (m_shader != nullptr) ? m_shader->get_attrib_location(name.c_str()) : -1;
|
||||
}
|
||||
|
||||
int Shader::get_uniform_location(const std::string& name) const
|
||||
{
|
||||
return (m_shader != nullptr) ? m_shader->get_uniform_location(name.c_str()) : -1;
|
||||
}
|
||||
|
||||
void Shader::set_uniform(const std::string& name, float value) const
|
||||
{
|
||||
if (m_shader != nullptr)
|
||||
|
@ -321,7 +342,7 @@ void Shader::set_uniform(const std::string& name, const float* matrix) const
|
|||
void Shader::set_uniform(const std::string& name, bool value) const
|
||||
{
|
||||
if (m_shader != nullptr)
|
||||
m_shader->set_uniform(name.c_str(), value);
|
||||
m_shader->set_uniform(name.c_str(), value ? 1 : 0);
|
||||
}
|
||||
|
||||
unsigned int Shader::get_shader_program_id() const
|
||||
|
|
|
@ -26,6 +26,7 @@ public:
|
|||
|
||||
bool set_uniform(const char *name, float value) const;
|
||||
bool set_uniform(const char* name, const float* matrix) const;
|
||||
bool set_uniform(const char* name, int value) const;
|
||||
|
||||
void enable() const;
|
||||
void disable() const;
|
||||
|
@ -52,6 +53,9 @@ public:
|
|||
bool start_using() const;
|
||||
void stop_using() const;
|
||||
|
||||
int get_attrib_location(const std::string& name) const;
|
||||
int get_uniform_location(const std::string& name) const;
|
||||
|
||||
void set_uniform(const std::string& name, float value) const;
|
||||
void set_uniform(const std::string& name, const float* matrix) const;
|
||||
void set_uniform(const std::string& name, bool value) const;
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
|
||||
#include "libslic3r/Utils.hpp"
|
||||
|
||||
#include "libslic3r/Utils.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
|
||||
|
|
|
@ -1173,10 +1173,161 @@ void ObjectList::load_part( ModelObject* model_object,
|
|||
|
||||
}
|
||||
|
||||
// Find volume transformation, so that the chained (instance_trafo * volume_trafo) will be as close to identity
|
||||
// as possible in least squares norm in regard to the 8 corners of bbox.
|
||||
// Bounding box is expected to be centered around zero in all axes.
|
||||
Geometry::Transformation volume_to_bed_transformation(const Geometry::Transformation &instance_transformation, const BoundingBoxf3 &bbox)
|
||||
{
|
||||
Geometry::Transformation out;
|
||||
|
||||
if (instance_transformation.is_scaling_uniform()) {
|
||||
// No need to run the non-linear least squares fitting for uniform scaling.
|
||||
// Just set the inverse.
|
||||
out.set_from_transform(instance_transformation.get_matrix(true).inverse());
|
||||
}
|
||||
else
|
||||
{
|
||||
Eigen::Matrix3d instance_rotation_trafo =
|
||||
(Eigen::AngleAxisd(instance_transformation.get_rotation().z(), Vec3d::UnitZ()) *
|
||||
Eigen::AngleAxisd(instance_transformation.get_rotation().y(), Vec3d::UnitY()) *
|
||||
Eigen::AngleAxisd(instance_transformation.get_rotation().x(), Vec3d::UnitX())).toRotationMatrix();
|
||||
Eigen::Matrix3d instance_rotation_trafo_inv =
|
||||
(Eigen::AngleAxisd(- instance_transformation.get_rotation().x(), Vec3d::UnitX()) *
|
||||
Eigen::AngleAxisd(- instance_transformation.get_rotation().y(), Vec3d::UnitY()) *
|
||||
Eigen::AngleAxisd(- instance_transformation.get_rotation().z(), Vec3d::UnitZ())).toRotationMatrix();
|
||||
Vec3d euler_angles_inv = Geometry::extract_euler_angles(instance_rotation_trafo_inv);
|
||||
|
||||
Eigen::Matrix3d instance_trafo = instance_rotation_trafo *
|
||||
Eigen::Scaling(instance_transformation.get_scaling_factor().cwiseProduct(instance_transformation.get_mirror()));
|
||||
|
||||
// 8 corners of the bounding box.
|
||||
auto pts = Eigen::MatrixXd(8, 3);
|
||||
pts(0, 0) = bbox.min.x(); pts(0, 1) = bbox.min.y(); pts(0, 2) = bbox.min.z();
|
||||
pts(1, 0) = bbox.min.x(); pts(1, 1) = bbox.min.y(); pts(1, 2) = bbox.max.z();
|
||||
pts(2, 0) = bbox.min.x(); pts(2, 1) = bbox.max.y(); pts(2, 2) = bbox.min.z();
|
||||
pts(3, 0) = bbox.min.x(); pts(3, 1) = bbox.max.y(); pts(3, 2) = bbox.max.z();
|
||||
pts(4, 0) = bbox.max.x(); pts(4, 1) = bbox.min.y(); pts(4, 2) = bbox.min.z();
|
||||
pts(5, 0) = bbox.max.x(); pts(5, 1) = bbox.min.y(); pts(5, 2) = bbox.max.z();
|
||||
pts(6, 0) = bbox.max.x(); pts(6, 1) = bbox.max.y(); pts(6, 2) = bbox.min.z();
|
||||
pts(7, 0) = bbox.max.x(); pts(7, 1) = bbox.max.y(); pts(7, 2) = bbox.max.z();
|
||||
|
||||
// Current parameters: 3x scale, 3x rotation
|
||||
auto beta = Eigen::MatrixXd(3 + 3, 1);
|
||||
beta << 1., 1., 1., euler_angles_inv(0), euler_angles_inv(1), euler_angles_inv(2);
|
||||
|
||||
{
|
||||
// Trafo from world to the coordinate system of the modifier mesh, with the inverse rotation applied to the modifier.
|
||||
Eigen::Matrix3d A_scaling = instance_trafo * instance_rotation_trafo_inv;
|
||||
// Corners of the bounding box transformed into the modifier mesh coordinate space, with inverse rotation applied to the modifier.
|
||||
auto qs = pts * A_scaling.inverse().transpose();
|
||||
// Fill in scaling based on least squares fitting of the bounding box corners.
|
||||
for (int i = 0; i < 3; ++i)
|
||||
beta(i) = pts.col(i).dot(qs.col(i)) / pts.col(i).dot(pts.col(i));
|
||||
}
|
||||
|
||||
// Jacobian
|
||||
// rows: 8 corners of a cube times 3 dimensions,
|
||||
// cols: 3x scale, 3x rotation
|
||||
auto J = Eigen::MatrixXd(8 * 3, 3 + 3);
|
||||
|
||||
// Until convergence:
|
||||
Eigen::Matrix3d s, dsx, dsy, dsz;
|
||||
Eigen::Matrix3d rx, drx, ry, dry, rz, drz;
|
||||
s.setIdentity();
|
||||
rx.setIdentity(); ry.setIdentity(); rz.setIdentity();
|
||||
dsx.setZero(); dsy.setZero(); dsz.setZero();
|
||||
drx.setZero(); dry.setZero(); drz.setZero();
|
||||
dsx(0, 0) = 1.; dsy(1, 1) = 1.; dsz(2, 2) = 1.;
|
||||
|
||||
// Solve the non-linear Least Squares problem by Levenberg–Marquardt algorithm (modified Gauss–Newton iteration)
|
||||
const double eps = 1.e-7;
|
||||
auto beta_best = beta;
|
||||
double beta_best_error = 1e10;
|
||||
for (size_t iter = 0; iter < 200; ++ iter) {
|
||||
// Current rotation & scaling transformation.
|
||||
auto trafo = instance_trafo *
|
||||
Eigen::AngleAxisd(beta(5), Vec3d::UnitZ()) *
|
||||
Eigen::AngleAxisd(beta(4), Vec3d::UnitY()) *
|
||||
Eigen::AngleAxisd(beta(3), Vec3d::UnitX()) *
|
||||
Eigen::Scaling(Vec3d(beta(0), beta(1), beta(2)));
|
||||
// Current error after rotation & scaling.
|
||||
auto dy = (pts - pts * trafo.transpose()).eval();
|
||||
double err = 0;
|
||||
for (int i = 0; i < 8; ++i)
|
||||
err += dy.row(i).norm();
|
||||
if (err < beta_best_error) {
|
||||
beta_best = beta;
|
||||
beta_best_error = err;
|
||||
}
|
||||
// Fill in the Jacobian at current beta.
|
||||
double cos_rx = cos(beta(3));
|
||||
double sin_rx = sin(beta(3));
|
||||
double cos_ry = cos(beta(4));
|
||||
double sin_ry = sin(beta(4));
|
||||
double cos_rz = cos(beta(5));
|
||||
double sin_rz = sin(beta(5));
|
||||
rx << 1., 0., 0., 0., cos_rx, -sin_rx, 0., sin_rx, cos_rx;
|
||||
drx << 0., 0., 0., 0., -sin_rx, -cos_rx, 0., cos_rx, -sin_rx;
|
||||
ry << cos_ry, 0., sin_ry, 0., 1., 0., -sin_ry, 0., cos_ry;
|
||||
dry << -sin_ry, 0., cos_ry, 0., 0., 0., -cos_ry, 0., -sin_ry;
|
||||
rz << cos_rz, -sin_rz, 0., sin_rz, cos_rz, 0., 0., 0., 1.;
|
||||
drz << -sin_rz, -cos_rz, 0., cos_rz, -sin_rz, 0., 0., 0., 0.;
|
||||
s(0, 0) = beta(0);
|
||||
s(1, 1) = beta(1);
|
||||
s(2, 2) = beta(2);
|
||||
auto rot = (instance_trafo * rz * ry * rx).eval();
|
||||
auto jrx = pts * (instance_trafo * rz * ry * drx * s).transpose();
|
||||
auto jry = pts * (instance_trafo * rz * dry * rx * s).transpose();
|
||||
auto jrz = pts * (instance_trafo * drz * ry * rx * s).transpose();
|
||||
for (int r = 0; r < 8; ++ r) {
|
||||
for (int i = 0; i < 3; ++ i) {
|
||||
J(r * 3 + i, 0) = rot(i, 0) * pts(r, 0);
|
||||
J(r * 3 + i, 1) = rot(i, 1) * pts(r, 1);
|
||||
J(r * 3 + i, 2) = rot(i, 2) * pts(r, 2);
|
||||
J(r * 3 + i, 3) = jrx(r, i);
|
||||
J(r * 3 + i, 4) = jry(r, i);
|
||||
J(r * 3 + i, 5) = jrz(r, i);
|
||||
}
|
||||
}
|
||||
// Solving the normal equations for delta beta.
|
||||
auto rhs = (J.transpose() * Eigen::Map<Eigen::VectorXd>(dy.data(), dy.size())).eval();
|
||||
double lambda = 1.; // 0.01;
|
||||
auto A = (J.transpose() * J + Eigen::Matrix<double, 6, 6>::Identity() * lambda).eval();
|
||||
auto L = A.ldlt();
|
||||
auto delta_beta = L.solve(rhs).eval();
|
||||
// Check for convergence.
|
||||
auto delta_beta_max = delta_beta.cwiseAbs().maxCoeff();
|
||||
if (delta_beta_max < eps)
|
||||
break;
|
||||
beta = beta + delta_beta;
|
||||
}
|
||||
|
||||
out.set_rotation(Vec3d(beta_best(3), beta_best(4), beta_best(5)));
|
||||
out.set_scaling_factor(Vec3d(std::abs(beta_best(0)), std::abs(beta_best(1)), std::abs(beta_best(2))));
|
||||
out.set_mirror(Vec3d(beta_best(0) > 0 ? 1. : -1, beta_best(1) > 0 ? 1. : -1, beta_best(2) > 0 ? 1. : -1));
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
void ObjectList::load_generic_subobject(const std::string& type_name, const ModelVolumeType type)
|
||||
{
|
||||
const auto obj_idx = get_selected_obj_idx();
|
||||
if (obj_idx < 0) return;
|
||||
if (obj_idx < 0)
|
||||
return;
|
||||
|
||||
const GLCanvas3D::Selection& selection = wxGetApp().plater()->canvas3D()->get_selection();
|
||||
assert(obj_idx == selection.get_object_idx());
|
||||
// Selected instance index in ModelObject. Only valid if there is only one instance selected in the selection.
|
||||
int instance_idx = selection.get_instance_idx();
|
||||
assert(instance_idx != -1);
|
||||
if (instance_idx == -1)
|
||||
return;
|
||||
|
||||
// Selected object
|
||||
ModelObject &model_object = *(*m_objects)[obj_idx];
|
||||
// Bounding box of the selected instance in world coordinate system including the translation, without modifiers.
|
||||
BoundingBoxf3 instance_bb = model_object.instance_bounding_box(instance_idx);
|
||||
|
||||
const wxString name = _(L("Generic")) + "-" + _(type_name);
|
||||
TriangleMesh mesh;
|
||||
|
@ -1185,48 +1336,48 @@ void ObjectList::load_generic_subobject(const std::string& type_name, const Mode
|
|||
const auto& sz = BoundingBoxf(bed_shape).size();
|
||||
const auto side = 0.1 * std::max(sz(0), sz(1));
|
||||
|
||||
if (type_name == "Box") {
|
||||
if (type_name == "Box")
|
||||
// Sitting on the print bed, left front front corner at (0, 0).
|
||||
mesh = make_cube(side, side, side);
|
||||
// box sets the base coordinate at 0, 0, move to center of plate
|
||||
mesh.translate(-side * 0.5, -side * 0.5, 0);
|
||||
}
|
||||
else if (type_name == "Cylinder")
|
||||
mesh = make_cylinder(0.5*side, side);
|
||||
// Centered around 0, sitting on the print bed.
|
||||
// The cylinder has the same volume as the box above.
|
||||
mesh = make_cylinder(0.564 * side, side);
|
||||
else if (type_name == "Sphere")
|
||||
mesh = make_sphere(0.5*side, PI/18);
|
||||
else if (type_name == "Slab") {
|
||||
const auto& size = (*m_objects)[obj_idx]->bounding_box().size();
|
||||
mesh = make_cube(size(0)*1.5, size(1)*1.5, size(2)*0.5);
|
||||
// box sets the base coordinate at 0, 0, move to center of plate and move it up to initial_z
|
||||
mesh.translate(-size(0)*1.5 / 2.0, -size(1)*1.5 / 2.0, 0);
|
||||
}
|
||||
// Centered around 0, half the sphere below the print bed, half above.
|
||||
// The sphere has the same volume as the box above.
|
||||
mesh = make_sphere(0.62 * side, PI / 18);
|
||||
else if (type_name == "Slab")
|
||||
// Sitting on the print bed, left front front corner at (0, 0).
|
||||
mesh = make_cube(instance_bb.size().x()*1.5, instance_bb.size().y()*1.5, instance_bb.size().z()*0.5);
|
||||
mesh.repair();
|
||||
|
||||
auto new_volume = (*m_objects)[obj_idx]->add_volume(mesh);
|
||||
// Mesh will be centered when loading.
|
||||
ModelVolume *new_volume = model_object.add_volume(std::move(mesh));
|
||||
new_volume->set_type(type);
|
||||
|
||||
#if !ENABLE_GENERIC_SUBPARTS_PLACEMENT
|
||||
new_volume->set_offset(Vec3d(0.0, 0.0, (*m_objects)[obj_idx]->origin_translation(2) - mesh.stl.stats.min(2)));
|
||||
new_volume->set_offset(Vec3d(0.0, 0.0, model_object.origin_translation(2) - mesh.stl.stats.min(2)));
|
||||
#endif // !ENABLE_GENERIC_SUBPARTS_PLACEMENT
|
||||
#if !ENABLE_VOLUMES_CENTERING_FIXES
|
||||
new_volume->center_geometry();
|
||||
#endif // !ENABLE_VOLUMES_CENTERING_FIXES
|
||||
|
||||
#if ENABLE_GENERIC_SUBPARTS_PLACEMENT
|
||||
const GLCanvas3D::Selection& selection = wxGetApp().plater()->canvas3D()->get_selection();
|
||||
int instance_idx = selection.get_instance_idx();
|
||||
if (instance_idx != -1)
|
||||
{
|
||||
// First (any) GLVolume of the selected instance. They all share the same instance matrix.
|
||||
const GLVolume* v = selection.get_volume(*selection.get_volume_idxs().begin());
|
||||
const Transform3d& inst_m = v->get_instance_transformation().get_matrix(true);
|
||||
TriangleMesh vol_mesh(mesh);
|
||||
vol_mesh.transform(inst_m);
|
||||
Vec3d vol_shift = -vol_mesh.bounding_box().center();
|
||||
vol_mesh.translate((float)vol_shift(0), (float)vol_shift(1), (float)vol_shift(2));
|
||||
Vec3d world_mesh_bb_size = vol_mesh.bounding_box().size();
|
||||
BoundingBoxf3 inst_bb = (*m_objects)[obj_idx]->instance_bounding_box(instance_idx);
|
||||
Vec3d world_target = Vec3d(inst_bb.max(0), inst_bb.min(1), inst_bb.min(2)) + 0.5 * world_mesh_bb_size;
|
||||
new_volume->set_offset(inst_m.inverse() * (world_target - v->get_instance_offset()));
|
||||
// Transform the new modifier to be aligned with the print bed.
|
||||
const BoundingBoxf3 mesh_bb = new_volume->mesh.bounding_box();
|
||||
new_volume->set_transformation(volume_to_bed_transformation(v->get_instance_transformation(), mesh_bb));
|
||||
// Set the modifier position.
|
||||
auto offset = (type_name == "Slab") ?
|
||||
// Slab: Lift to print bed
|
||||
Vec3d(0., 0., 0.5 * mesh_bb.size().z() + instance_bb.min.z() - v->get_instance_offset().z()) :
|
||||
// Translate the new modifier to be pickable: move to the left front corner of the instance's bounding box, lift to print bed.
|
||||
Vec3d(instance_bb.max(0), instance_bb.min(1), instance_bb.min(2)) + 0.5 * mesh_bb.size() - v->get_instance_offset();
|
||||
new_volume->set_offset(v->get_instance_transformation().get_matrix(true).inverse() * offset);
|
||||
}
|
||||
#endif // ENABLE_GENERIC_SUBPARTS_PLACEMENT
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
# (the version numbers are generated by the build script from the git current label)
|
||||
|
||||
set(SLIC3R_FORK_NAME "Slic3r Prusa Edition")
|
||||
set(SLIC3R_VERSION "1.42.0-alpha5")
|
||||
set(SLIC3R_VERSION "1.42.0-alpha6")
|
||||
set(SLIC3R_BUILD "${SLIC3R_VERSION}+UNKNOWN")
|
||||
set(SLIC3R_BUILD_ID "${SLIC3R_BUILD_ID}")
|
||||
set(SLIC3R_RC_VERSION "1,42,0,0")
|
||||
|
|
Loading…
Add table
Reference in a new issue