mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-22 06:04:01 -06:00
Fixed conflicts after merge with master
This commit is contained in:
commit
6bddacee44
90 changed files with 4276 additions and 4185 deletions
|
@ -12,6 +12,9 @@
|
|||
#include "Plater.hpp"
|
||||
|
||||
#include "libslic3r/Model.hpp"
|
||||
#if DISABLE_ALLOW_NEGATIVE_Z_FOR_SLA
|
||||
#include "libslic3r/PresetBundle.hpp"
|
||||
#endif // DISABLE_ALLOW_NEGATIVE_Z_FOR_SLA
|
||||
|
||||
#include <GL/glew.h>
|
||||
|
||||
|
@ -62,13 +65,11 @@ bool Selection::Clipboard::is_sla_compliant() const
|
|||
if (m_mode == Selection::Volume)
|
||||
return false;
|
||||
|
||||
for (const ModelObject* o : m_model->objects)
|
||||
{
|
||||
for (const ModelObject* o : m_model->objects) {
|
||||
if (o->is_multiparts())
|
||||
return false;
|
||||
|
||||
for (const ModelVolume* v : o->volumes)
|
||||
{
|
||||
for (const ModelVolume* v : o->volumes) {
|
||||
if (v->is_modifier())
|
||||
return false;
|
||||
}
|
||||
|
@ -82,7 +83,8 @@ Selection::Clipboard::Clipboard()
|
|||
m_model.reset(new Model);
|
||||
}
|
||||
|
||||
void Selection::Clipboard::reset() {
|
||||
void Selection::Clipboard::reset()
|
||||
{
|
||||
m_model->clear_objects();
|
||||
}
|
||||
|
||||
|
@ -153,7 +155,7 @@ void Selection::set_model(Model* model)
|
|||
|
||||
void Selection::add(unsigned int volume_idx, bool as_single_selection, bool check_for_already_contained)
|
||||
{
|
||||
if (!m_valid || ((unsigned int)m_volumes->size() <= volume_idx))
|
||||
if (!m_valid || (unsigned int)m_volumes->size() <= volume_idx)
|
||||
return;
|
||||
|
||||
const GLVolume* volume = (*m_volumes)[volume_idx];
|
||||
|
@ -171,9 +173,8 @@ void Selection::add(unsigned int volume_idx, bool as_single_selection, bool chec
|
|||
needs_reset |= as_single_selection && !is_any_modifier() && volume->is_modifier;
|
||||
needs_reset |= is_any_modifier() && !volume->is_modifier;
|
||||
|
||||
if (!already_contained || needs_reset)
|
||||
{
|
||||
wxGetApp().plater()->take_snapshot(_(L("Selection-Add")));
|
||||
if (!already_contained || needs_reset) {
|
||||
wxGetApp().plater()->take_snapshot(_L("Selection-Add"));
|
||||
|
||||
if (needs_reset)
|
||||
clear();
|
||||
|
@ -189,7 +190,7 @@ void Selection::add(unsigned int volume_idx, bool as_single_selection, bool chec
|
|||
{
|
||||
case Volume:
|
||||
{
|
||||
if ((volume->volume_idx() >= 0) && (is_empty() || (volume->instance_idx() == get_instance_idx())))
|
||||
if (volume->volume_idx() >= 0 && (is_empty() || volume->instance_idx() == get_instance_idx()))
|
||||
do_add_volume(volume_idx);
|
||||
|
||||
break;
|
||||
|
@ -208,13 +209,13 @@ void Selection::add(unsigned int volume_idx, bool as_single_selection, bool chec
|
|||
|
||||
void Selection::remove(unsigned int volume_idx)
|
||||
{
|
||||
if (!m_valid || ((unsigned int)m_volumes->size() <= volume_idx))
|
||||
if (!m_valid || (unsigned int)m_volumes->size() <= volume_idx)
|
||||
return;
|
||||
|
||||
if (!contains_volume(volume_idx))
|
||||
return;
|
||||
|
||||
wxGetApp().plater()->take_snapshot(_(L("Selection-Remove")));
|
||||
wxGetApp().plater()->take_snapshot(_L("Selection-Remove"));
|
||||
|
||||
GLVolume* volume = (*m_volumes)[volume_idx];
|
||||
|
||||
|
@ -246,7 +247,7 @@ void Selection::add_object(unsigned int object_idx, bool as_single_selection)
|
|||
(as_single_selection && matches(volume_idxs)))
|
||||
return;
|
||||
|
||||
wxGetApp().plater()->take_snapshot(_(L("Selection-Add Object")));
|
||||
wxGetApp().plater()->take_snapshot(_L("Selection-Add Object"));
|
||||
|
||||
// resets the current list if needed
|
||||
if (as_single_selection)
|
||||
|
@ -265,7 +266,7 @@ void Selection::remove_object(unsigned int object_idx)
|
|||
if (!m_valid)
|
||||
return;
|
||||
|
||||
wxGetApp().plater()->take_snapshot(_(L("Selection-Remove Object")));
|
||||
wxGetApp().plater()->take_snapshot(_L("Selection-Remove Object"));
|
||||
|
||||
do_remove_object(object_idx);
|
||||
|
||||
|
@ -278,12 +279,12 @@ void Selection::add_instance(unsigned int object_idx, unsigned int instance_idx,
|
|||
if (!m_valid)
|
||||
return;
|
||||
|
||||
std::vector<unsigned int> volume_idxs = get_volume_idxs_from_instance(object_idx, instance_idx);
|
||||
const std::vector<unsigned int> volume_idxs = get_volume_idxs_from_instance(object_idx, instance_idx);
|
||||
if ((!as_single_selection && contains_all_volumes(volume_idxs)) ||
|
||||
(as_single_selection && matches(volume_idxs)))
|
||||
return;
|
||||
|
||||
wxGetApp().plater()->take_snapshot(_(L("Selection-Add Instance")));
|
||||
wxGetApp().plater()->take_snapshot(_L("Selection-Add Instance"));
|
||||
|
||||
// resets the current list if needed
|
||||
if (as_single_selection)
|
||||
|
@ -302,7 +303,7 @@ void Selection::remove_instance(unsigned int object_idx, unsigned int instance_i
|
|||
if (!m_valid)
|
||||
return;
|
||||
|
||||
wxGetApp().plater()->take_snapshot(_(L("Selection-Remove Instance")));
|
||||
wxGetApp().plater()->take_snapshot(_L("Selection-Remove Instance"));
|
||||
|
||||
do_remove_instance(object_idx, instance_idx);
|
||||
|
||||
|
@ -337,10 +338,9 @@ void Selection::remove_volume(unsigned int object_idx, unsigned int volume_idx)
|
|||
if (!m_valid)
|
||||
return;
|
||||
|
||||
for (unsigned int i = 0; i < (unsigned int)m_volumes->size(); ++i)
|
||||
{
|
||||
for (unsigned int i = 0; i < (unsigned int)m_volumes->size(); ++i) {
|
||||
GLVolume* v = (*m_volumes)[i];
|
||||
if ((v->object_idx() == (int)object_idx) && (v->volume_idx() == (int)volume_idx))
|
||||
if (v->object_idx() == (int)object_idx && v->volume_idx() == (int)volume_idx)
|
||||
do_remove_volume(i);
|
||||
}
|
||||
|
||||
|
@ -362,8 +362,7 @@ void Selection::add_volumes(EMode mode, const std::vector<unsigned int>& volume_
|
|||
clear();
|
||||
|
||||
m_mode = mode;
|
||||
for (unsigned int i : volume_idxs)
|
||||
{
|
||||
for (unsigned int i : volume_idxs) {
|
||||
if (i < (unsigned int)m_volumes->size())
|
||||
do_add_volume(i);
|
||||
}
|
||||
|
@ -378,8 +377,7 @@ void Selection::remove_volumes(EMode mode, const std::vector<unsigned int>& volu
|
|||
return;
|
||||
|
||||
m_mode = mode;
|
||||
for (unsigned int i : volume_idxs)
|
||||
{
|
||||
for (unsigned int i : volume_idxs) {
|
||||
if (i < (unsigned int)m_volumes->size())
|
||||
do_remove_volume(i);
|
||||
}
|
||||
|
@ -394,8 +392,7 @@ void Selection::add_all()
|
|||
return;
|
||||
|
||||
unsigned int count = 0;
|
||||
for (unsigned int i = 0; i < (unsigned int)m_volumes->size(); ++i)
|
||||
{
|
||||
for (unsigned int i = 0; i < (unsigned int)m_volumes->size(); ++i) {
|
||||
if (!(*m_volumes)[i]->is_wipe_tower)
|
||||
++count;
|
||||
}
|
||||
|
@ -408,8 +405,7 @@ void Selection::add_all()
|
|||
m_mode = Instance;
|
||||
clear();
|
||||
|
||||
for (unsigned int i = 0; i < (unsigned int)m_volumes->size(); ++i)
|
||||
{
|
||||
for (unsigned int i = 0; i < (unsigned int)m_volumes->size(); ++i) {
|
||||
if (!(*m_volumes)[i]->is_wipe_tower)
|
||||
do_add_volume(i);
|
||||
}
|
||||
|
@ -459,8 +455,7 @@ void Selection::clear()
|
|||
if (m_list.empty())
|
||||
return;
|
||||
|
||||
for (unsigned int i : m_list)
|
||||
{
|
||||
for (unsigned int i : m_list) {
|
||||
(*m_volumes)[i]->selected = false;
|
||||
}
|
||||
|
||||
|
@ -526,16 +521,15 @@ bool Selection::is_single_full_instance() const
|
|||
return false;
|
||||
|
||||
int object_idx = m_valid ? get_object_idx() : -1;
|
||||
if ((object_idx < 0) || ((int)m_model->objects.size() <= object_idx))
|
||||
if (object_idx < 0 || (int)m_model->objects.size() <= object_idx)
|
||||
return false;
|
||||
|
||||
int instance_idx = (*m_volumes)[*m_list.begin()]->instance_idx();
|
||||
|
||||
std::set<int> volumes_idxs;
|
||||
for (unsigned int i : m_list)
|
||||
{
|
||||
for (unsigned int i : m_list) {
|
||||
const GLVolume* v = (*m_volumes)[i];
|
||||
if ((object_idx != v->object_idx()) || (instance_idx != v->instance_idx()))
|
||||
if (object_idx != v->object_idx() || instance_idx != v->instance_idx())
|
||||
return false;
|
||||
|
||||
int volume_idx = v->volume_idx();
|
||||
|
@ -548,8 +542,8 @@ bool Selection::is_single_full_instance() const
|
|||
|
||||
bool Selection::is_from_single_object() const
|
||||
{
|
||||
int idx = get_object_idx();
|
||||
return (0 <= idx) && (idx < 1000);
|
||||
const int idx = get_object_idx();
|
||||
return 0 <= idx && idx < 1000;
|
||||
}
|
||||
|
||||
bool Selection::is_sla_compliant() const
|
||||
|
@ -557,8 +551,7 @@ bool Selection::is_sla_compliant() const
|
|||
if (m_mode == Volume)
|
||||
return false;
|
||||
|
||||
for (unsigned int i : m_list)
|
||||
{
|
||||
for (unsigned int i : m_list) {
|
||||
if ((*m_volumes)[i]->is_modifier)
|
||||
return false;
|
||||
}
|
||||
|
@ -568,8 +561,7 @@ bool Selection::is_sla_compliant() const
|
|||
|
||||
bool Selection::contains_all_volumes(const std::vector<unsigned int>& volume_idxs) const
|
||||
{
|
||||
for (unsigned int i : volume_idxs)
|
||||
{
|
||||
for (unsigned int i : volume_idxs) {
|
||||
if (m_list.find(i) == m_list.end())
|
||||
return false;
|
||||
}
|
||||
|
@ -579,8 +571,7 @@ bool Selection::contains_all_volumes(const std::vector<unsigned int>& volume_idx
|
|||
|
||||
bool Selection::contains_any_volume(const std::vector<unsigned int>& volume_idxs) const
|
||||
{
|
||||
for (unsigned int i : volume_idxs)
|
||||
{
|
||||
for (unsigned int i : volume_idxs) {
|
||||
if (m_list.find(i) != m_list.end())
|
||||
return true;
|
||||
}
|
||||
|
@ -592,8 +583,7 @@ bool Selection::matches(const std::vector<unsigned int>& volume_idxs) const
|
|||
{
|
||||
unsigned int count = 0;
|
||||
|
||||
for (unsigned int i : volume_idxs)
|
||||
{
|
||||
for (unsigned int i : volume_idxs) {
|
||||
if (m_list.find(i) != m_list.end())
|
||||
++count;
|
||||
else
|
||||
|
@ -618,8 +608,7 @@ int Selection::get_object_idx() const
|
|||
|
||||
int Selection::get_instance_idx() const
|
||||
{
|
||||
if (m_cache.content.size() == 1)
|
||||
{
|
||||
if (m_cache.content.size() == 1) {
|
||||
const InstanceIdxsList& idxs = m_cache.content.begin()->second;
|
||||
if (idxs.size() == 1)
|
||||
return *idxs.begin();
|
||||
|
@ -676,25 +665,20 @@ void Selection::translate(const Vec3d& displacement, bool local)
|
|||
|
||||
EMode translation_type = m_mode;
|
||||
|
||||
for (unsigned int i : m_list)
|
||||
{
|
||||
if ((m_mode == Volume) || (*m_volumes)[i]->is_wipe_tower)
|
||||
{
|
||||
for (unsigned int i : m_list) {
|
||||
if (m_mode == Volume || (*m_volumes)[i]->is_wipe_tower) {
|
||||
if (local)
|
||||
(*m_volumes)[i]->set_volume_offset(m_cache.volumes_data[i].get_volume_position() + displacement);
|
||||
else
|
||||
{
|
||||
Vec3d local_displacement = (m_cache.volumes_data[i].get_instance_rotation_matrix() * m_cache.volumes_data[i].get_instance_scale_matrix() * m_cache.volumes_data[i].get_instance_mirror_matrix()).inverse() * displacement;
|
||||
else {
|
||||
const Vec3d local_displacement = (m_cache.volumes_data[i].get_instance_rotation_matrix() * m_cache.volumes_data[i].get_instance_scale_matrix() * m_cache.volumes_data[i].get_instance_mirror_matrix()).inverse() * displacement;
|
||||
(*m_volumes)[i]->set_volume_offset(m_cache.volumes_data[i].get_volume_position() + local_displacement);
|
||||
}
|
||||
}
|
||||
else if (m_mode == Instance)
|
||||
{
|
||||
else if (m_mode == Instance) {
|
||||
if (is_from_fully_selected_instance(i))
|
||||
(*m_volumes)[i]->set_instance_offset(m_cache.volumes_data[i].get_instance_position() + displacement);
|
||||
else
|
||||
{
|
||||
Vec3d local_displacement = (m_cache.volumes_data[i].get_instance_rotation_matrix() * m_cache.volumes_data[i].get_instance_scale_matrix() * m_cache.volumes_data[i].get_instance_mirror_matrix()).inverse() * displacement;
|
||||
else {
|
||||
const Vec3d local_displacement = (m_cache.volumes_data[i].get_instance_rotation_matrix() * m_cache.volumes_data[i].get_instance_scale_matrix() * m_cache.volumes_data[i].get_instance_mirror_matrix()).inverse() * displacement;
|
||||
(*m_volumes)[i]->set_volume_offset(m_cache.volumes_data[i].get_volume_position() + local_displacement);
|
||||
translation_type = Volume;
|
||||
}
|
||||
|
@ -722,18 +706,14 @@ void Selection::rotate(const Vec3d& rotation, TransformationType transformation_
|
|||
|
||||
if (!is_wipe_tower()) {
|
||||
int rot_axis_max = 0;
|
||||
if (rotation.isApprox(Vec3d::Zero()))
|
||||
{
|
||||
for (unsigned int i : m_list)
|
||||
{
|
||||
if (rotation.isApprox(Vec3d::Zero())) {
|
||||
for (unsigned int i : m_list) {
|
||||
GLVolume &volume = *(*m_volumes)[i];
|
||||
if (m_mode == Instance)
|
||||
{
|
||||
if (m_mode == Instance) {
|
||||
volume.set_instance_rotation(m_cache.volumes_data[i].get_instance_rotation());
|
||||
volume.set_instance_offset(m_cache.volumes_data[i].get_instance_position());
|
||||
}
|
||||
else if (m_mode == Volume)
|
||||
{
|
||||
else if (m_mode == Volume) {
|
||||
volume.set_volume_rotation(m_cache.volumes_data[i].get_volume_rotation());
|
||||
volume.set_volume_offset(m_cache.volumes_data[i].get_volume_position());
|
||||
}
|
||||
|
@ -750,14 +730,14 @@ void Selection::rotate(const Vec3d& rotation, TransformationType transformation_
|
|||
// For generic rotation, we want to rotate the first volume in selection, and then to synchronize the other volumes with it.
|
||||
std::vector<int> object_instance_first(m_model->objects.size(), -1);
|
||||
auto rotate_instance = [this, &rotation, &object_instance_first, rot_axis_max, transformation_type](GLVolume &volume, int i) {
|
||||
int first_volume_idx = object_instance_first[volume.object_idx()];
|
||||
const int first_volume_idx = object_instance_first[volume.object_idx()];
|
||||
if (rot_axis_max != 2 && first_volume_idx != -1) {
|
||||
// Generic rotation, but no rotation around the Z axis.
|
||||
// Always do a local rotation (do not consider the selection to be a rigid body).
|
||||
assert(is_approx(rotation.z(), 0.0));
|
||||
const GLVolume &first_volume = *(*m_volumes)[first_volume_idx];
|
||||
const Vec3d &rotation = first_volume.get_instance_rotation();
|
||||
double z_diff = Geometry::rotation_diff_z(m_cache.volumes_data[first_volume_idx].get_instance_rotation(), m_cache.volumes_data[i].get_instance_rotation());
|
||||
const double z_diff = Geometry::rotation_diff_z(m_cache.volumes_data[first_volume_idx].get_instance_rotation(), m_cache.volumes_data[i].get_instance_rotation());
|
||||
volume.set_instance_rotation(Vec3d(rotation(0), rotation(1), rotation(2) + z_diff));
|
||||
}
|
||||
else {
|
||||
|
@ -767,7 +747,7 @@ void Selection::rotate(const Vec3d& rotation, TransformationType transformation_
|
|||
transformation_type.absolute() ? rotation : rotation + m_cache.volumes_data[i].get_instance_rotation();
|
||||
if (rot_axis_max == 2 && transformation_type.joint()) {
|
||||
// Only allow rotation of multiple instances as a single rigid body when rotating around the Z axis.
|
||||
double z_diff = Geometry::rotation_diff_z(m_cache.volumes_data[i].get_instance_rotation(), new_rotation);
|
||||
const double z_diff = Geometry::rotation_diff_z(m_cache.volumes_data[i].get_instance_rotation(), new_rotation);
|
||||
volume.set_instance_offset(m_cache.dragging_center + Eigen::AngleAxisd(z_diff, Vec3d::UnitZ()) * (m_cache.volumes_data[i].get_instance_position() - m_cache.dragging_center));
|
||||
}
|
||||
volume.set_instance_rotation(new_rotation);
|
||||
|
@ -775,19 +755,16 @@ void Selection::rotate(const Vec3d& rotation, TransformationType transformation_
|
|||
}
|
||||
};
|
||||
|
||||
for (unsigned int i : m_list)
|
||||
{
|
||||
for (unsigned int i : m_list) {
|
||||
GLVolume &volume = *(*m_volumes)[i];
|
||||
if (is_single_full_instance())
|
||||
rotate_instance(volume, i);
|
||||
else if (is_single_volume() || is_single_modifier())
|
||||
{
|
||||
else if (is_single_volume() || is_single_modifier()) {
|
||||
if (transformation_type.independent())
|
||||
volume.set_volume_rotation(volume.get_volume_rotation() + rotation);
|
||||
else
|
||||
{
|
||||
Transform3d m = Geometry::assemble_transform(Vec3d::Zero(), rotation);
|
||||
Vec3d new_rotation = Geometry::extract_euler_angles(m * m_cache.volumes_data[i].get_volume_rotation_matrix());
|
||||
else {
|
||||
const Transform3d m = Geometry::assemble_transform(Vec3d::Zero(), rotation);
|
||||
const Vec3d new_rotation = Geometry::extract_euler_angles(m * m_cache.volumes_data[i].get_volume_rotation_matrix());
|
||||
volume.set_volume_rotation(new_rotation);
|
||||
}
|
||||
}
|
||||
|
@ -795,15 +772,13 @@ void Selection::rotate(const Vec3d& rotation, TransformationType transformation_
|
|||
{
|
||||
if (m_mode == Instance)
|
||||
rotate_instance(volume, i);
|
||||
else if (m_mode == Volume)
|
||||
{
|
||||
else if (m_mode == Volume) {
|
||||
// extracts rotations from the composed transformation
|
||||
Transform3d m = Geometry::assemble_transform(Vec3d::Zero(), rotation);
|
||||
Vec3d new_rotation = Geometry::extract_euler_angles(m * m_cache.volumes_data[i].get_volume_rotation_matrix());
|
||||
if (transformation_type.joint())
|
||||
{
|
||||
Vec3d local_pivot = m_cache.volumes_data[i].get_instance_full_matrix().inverse() * m_cache.dragging_center;
|
||||
Vec3d offset = m * (m_cache.volumes_data[i].get_volume_position() - local_pivot);
|
||||
if (transformation_type.joint()) {
|
||||
const Vec3d local_pivot = m_cache.volumes_data[i].get_instance_full_matrix().inverse() * m_cache.dragging_center;
|
||||
const Vec3d offset = m * (m_cache.volumes_data[i].get_volume_position() - local_pivot);
|
||||
volume.set_volume_offset(local_pivot + offset);
|
||||
}
|
||||
volume.set_volume_rotation(new_rotation);
|
||||
|
@ -824,8 +799,8 @@ void Selection::rotate(const Vec3d& rotation, TransformationType transformation_
|
|||
|
||||
// make sure the wipe tower rotates around its center, not origin
|
||||
// we can assume that only Z rotation changes
|
||||
Vec3d center_local = volume.transformed_bounding_box().center() - volume.get_volume_offset();
|
||||
Vec3d center_local_new = Eigen::AngleAxisd(rotation(2)-volume.get_volume_rotation()(2), Vec3d(0, 0, 1)) * center_local;
|
||||
const Vec3d center_local = volume.transformed_bounding_box().center() - volume.get_volume_offset();
|
||||
const Vec3d center_local_new = Eigen::AngleAxisd(rotation(2)-volume.get_volume_rotation()(2), Vec3d(0.0, 0.0, 1.0)) * center_local;
|
||||
volume.set_volume_rotation(rotation);
|
||||
volume.set_volume_offset(volume.get_volume_offset() + center_local - center_local_new);
|
||||
}
|
||||
|
@ -843,8 +818,7 @@ void Selection::flattening_rotate(const Vec3d& normal)
|
|||
if (!m_valid)
|
||||
return;
|
||||
|
||||
for (unsigned int i : m_list)
|
||||
{
|
||||
for (unsigned int i : m_list) {
|
||||
// Normal transformed from the object coordinate space to the world coordinate space.
|
||||
const auto &voldata = m_cache.volumes_data[i];
|
||||
Vec3d tnormal = (Geometry::assemble_transform(
|
||||
|
@ -870,12 +844,10 @@ void Selection::scale(const Vec3d& scale, TransformationType transformation_type
|
|||
if (!m_valid)
|
||||
return;
|
||||
|
||||
for (unsigned int i : m_list)
|
||||
{
|
||||
for (unsigned int i : m_list) {
|
||||
GLVolume &volume = *(*m_volumes)[i];
|
||||
if (is_single_full_instance()) {
|
||||
if (transformation_type.relative())
|
||||
{
|
||||
if (transformation_type.relative()) {
|
||||
Transform3d m = Geometry::assemble_transform(Vec3d::Zero(), Vec3d::Zero(), scale);
|
||||
Eigen::Matrix<double, 3, 3, Eigen::DontAlign> new_matrix = (m * m_cache.volumes_data[i].get_instance_scale_matrix()).matrix().block(0, 0, 3, 3);
|
||||
// extracts scaling factors from the composed transformation
|
||||
|
@ -885,8 +857,7 @@ void Selection::scale(const Vec3d& scale, TransformationType transformation_type
|
|||
|
||||
volume.set_instance_scaling_factor(new_scale);
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
if (transformation_type.world() && (std::abs(scale.x() - scale.y()) > EPSILON || std::abs(scale.x() - scale.z()) > EPSILON)) {
|
||||
// Non-uniform scaling. Transform the scaling factors into the local coordinate system.
|
||||
// This is only possible, if the instance rotation is mulitples of ninety degrees.
|
||||
|
@ -899,11 +870,9 @@ void Selection::scale(const Vec3d& scale, TransformationType transformation_type
|
|||
}
|
||||
else if (is_single_volume() || is_single_modifier())
|
||||
volume.set_volume_scaling_factor(scale);
|
||||
else
|
||||
{
|
||||
else {
|
||||
Transform3d m = Geometry::assemble_transform(Vec3d::Zero(), Vec3d::Zero(), scale);
|
||||
if (m_mode == Instance)
|
||||
{
|
||||
if (m_mode == Instance) {
|
||||
Eigen::Matrix<double, 3, 3, Eigen::DontAlign> new_matrix = (m * m_cache.volumes_data[i].get_instance_scale_matrix()).matrix().block(0, 0, 3, 3);
|
||||
// extracts scaling factors from the composed transformation
|
||||
Vec3d new_scale(new_matrix.col(0).norm(), new_matrix.col(1).norm(), new_matrix.col(2).norm());
|
||||
|
@ -912,13 +881,11 @@ void Selection::scale(const Vec3d& scale, TransformationType transformation_type
|
|||
|
||||
volume.set_instance_scaling_factor(new_scale);
|
||||
}
|
||||
else if (m_mode == Volume)
|
||||
{
|
||||
else if (m_mode == Volume) {
|
||||
Eigen::Matrix<double, 3, 3, Eigen::DontAlign> new_matrix = (m * m_cache.volumes_data[i].get_volume_scale_matrix()).matrix().block(0, 0, 3, 3);
|
||||
// extracts scaling factors from the composed transformation
|
||||
Vec3d new_scale(new_matrix.col(0).norm(), new_matrix.col(1).norm(), new_matrix.col(2).norm());
|
||||
if (transformation_type.joint())
|
||||
{
|
||||
if (transformation_type.joint()) {
|
||||
Vec3d offset = m * (m_cache.volumes_data[i].get_volume_position() + m_cache.volumes_data[i].get_instance_position() - m_cache.dragging_center);
|
||||
volume.set_volume_offset(m_cache.dragging_center - m_cache.volumes_data[i].get_instance_position() + offset);
|
||||
}
|
||||
|
@ -933,35 +900,36 @@ void Selection::scale(const Vec3d& scale, TransformationType transformation_type
|
|||
else if (m_mode == Volume)
|
||||
synchronize_unselected_volumes();
|
||||
#endif // !DISABLE_INSTANCES_SYNCH
|
||||
|
||||
ensure_on_bed();
|
||||
|
||||
#if DISABLE_ALLOW_NEGATIVE_Z_FOR_SLA
|
||||
if (wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology() == ptSLA)
|
||||
ensure_on_bed();
|
||||
#endif // DISABLE_ALLOW_NEGATIVE_Z_FOR_SLA
|
||||
|
||||
this->set_bounding_boxes_dirty();
|
||||
}
|
||||
|
||||
void Selection::scale_to_fit_print_volume(const DynamicPrintConfig& config)
|
||||
{
|
||||
if (is_empty() || (m_mode == Volume))
|
||||
if (is_empty() || m_mode == Volume)
|
||||
return;
|
||||
|
||||
// adds 1/100th of a mm on all sides to avoid false out of print volume detections due to floating-point roundings
|
||||
Vec3d box_size = get_bounding_box().size() + 0.01 * Vec3d::Ones();
|
||||
|
||||
const ConfigOptionPoints* opt = dynamic_cast<const ConfigOptionPoints*>(config.option("bed_shape"));
|
||||
if (opt != nullptr)
|
||||
{
|
||||
if (opt != nullptr) {
|
||||
BoundingBox bed_box_2D = get_extents(Polygon::new_scale(opt->values));
|
||||
BoundingBoxf3 print_volume(Vec3d(unscale<double>(bed_box_2D.min(0)), unscale<double>(bed_box_2D.min(1)), 0.0), Vec3d(unscale<double>(bed_box_2D.max(0)), unscale<double>(bed_box_2D.max(1)), config.opt_float("max_print_height")));
|
||||
BoundingBoxf3 print_volume({ unscale<double>(bed_box_2D.min(0)), unscale<double>(bed_box_2D.min(1)), 0.0 }, { unscale<double>(bed_box_2D.max(0)), unscale<double>(bed_box_2D.max(1)), config.opt_float("max_print_height") });
|
||||
Vec3d print_volume_size = print_volume.size();
|
||||
double sx = (box_size(0) != 0.0) ? print_volume_size(0) / box_size(0) : 0.0;
|
||||
double sy = (box_size(1) != 0.0) ? print_volume_size(1) / box_size(1) : 0.0;
|
||||
double sz = (box_size(2) != 0.0) ? print_volume_size(2) / box_size(2) : 0.0;
|
||||
if ((sx != 0.0) && (sy != 0.0) && (sz != 0.0))
|
||||
if (sx != 0.0 && sy != 0.0 && sz != 0.0)
|
||||
{
|
||||
double s = std::min(sx, std::min(sy, sz));
|
||||
if (s != 1.0)
|
||||
{
|
||||
wxGetApp().plater()->take_snapshot(_(L("Scale To Fit")));
|
||||
if (s != 1.0) {
|
||||
wxGetApp().plater()->take_snapshot(_L("Scale To Fit"));
|
||||
|
||||
TransformationType type;
|
||||
type.set_world();
|
||||
|
@ -991,8 +959,7 @@ void Selection::mirror(Axis axis)
|
|||
|
||||
bool single_full_instance = is_single_full_instance();
|
||||
|
||||
for (unsigned int i : m_list)
|
||||
{
|
||||
for (unsigned int i : m_list) {
|
||||
if (single_full_instance)
|
||||
(*m_volumes)[i]->set_instance_mirror(axis, -(*m_volumes)[i]->get_instance_mirror(axis));
|
||||
else if (m_mode == Volume)
|
||||
|
@ -1014,8 +981,7 @@ void Selection::translate(unsigned int object_idx, const Vec3d& displacement)
|
|||
if (!m_valid)
|
||||
return;
|
||||
|
||||
for (unsigned int i : m_list)
|
||||
{
|
||||
for (unsigned int i : m_list) {
|
||||
GLVolume* v = (*m_volumes)[i];
|
||||
if (v->object_idx() == (int)object_idx)
|
||||
v->set_instance_offset(v->get_instance_offset() + displacement);
|
||||
|
@ -1024,8 +990,7 @@ void Selection::translate(unsigned int object_idx, const Vec3d& displacement)
|
|||
std::set<unsigned int> done; // prevent processing volumes twice
|
||||
done.insert(m_list.begin(), m_list.end());
|
||||
|
||||
for (unsigned int i : m_list)
|
||||
{
|
||||
for (unsigned int i : m_list) {
|
||||
if (done.size() == m_volumes->size())
|
||||
break;
|
||||
|
||||
|
@ -1034,8 +999,7 @@ void Selection::translate(unsigned int object_idx, const Vec3d& displacement)
|
|||
continue;
|
||||
|
||||
// Process unselected volumes of the object.
|
||||
for (unsigned int j = 0; j < (unsigned int)m_volumes->size(); ++j)
|
||||
{
|
||||
for (unsigned int j = 0; j < (unsigned int)m_volumes->size(); ++j) {
|
||||
if (done.size() == m_volumes->size())
|
||||
break;
|
||||
|
||||
|
@ -1059,18 +1023,16 @@ void Selection::translate(unsigned int object_idx, unsigned int instance_idx, co
|
|||
if (!m_valid)
|
||||
return;
|
||||
|
||||
for (unsigned int i : m_list)
|
||||
{
|
||||
for (unsigned int i : m_list) {
|
||||
GLVolume* v = (*m_volumes)[i];
|
||||
if ((v->object_idx() == (int)object_idx) && (v->instance_idx() == (int)instance_idx))
|
||||
if (v->object_idx() == (int)object_idx && v->instance_idx() == (int)instance_idx)
|
||||
v->set_instance_offset(v->get_instance_offset() + displacement);
|
||||
}
|
||||
|
||||
std::set<unsigned int> done; // prevent processing volumes twice
|
||||
done.insert(m_list.begin(), m_list.end());
|
||||
|
||||
for (unsigned int i : m_list)
|
||||
{
|
||||
for (unsigned int i : m_list) {
|
||||
if (done.size() == m_volumes->size())
|
||||
break;
|
||||
|
||||
|
@ -1079,8 +1041,7 @@ void Selection::translate(unsigned int object_idx, unsigned int instance_idx, co
|
|||
continue;
|
||||
|
||||
// Process unselected volumes of the object.
|
||||
for (unsigned int j = 0; j < (unsigned int)m_volumes->size(); ++j)
|
||||
{
|
||||
for (unsigned int j = 0; j < (unsigned int)m_volumes->size(); ++j) {
|
||||
if (done.size() == m_volumes->size())
|
||||
break;
|
||||
|
||||
|
@ -1088,7 +1049,7 @@ void Selection::translate(unsigned int object_idx, unsigned int instance_idx, co
|
|||
continue;
|
||||
|
||||
GLVolume* v = (*m_volumes)[j];
|
||||
if ((v->object_idx() != object_idx) || (v->instance_idx() != (int)instance_idx))
|
||||
if (v->object_idx() != object_idx || v->instance_idx() != (int)instance_idx)
|
||||
continue;
|
||||
|
||||
v->set_instance_offset(v->get_instance_offset() + displacement);
|
||||
|
@ -1803,18 +1764,16 @@ void Selection::render_synchronized_volumes() const
|
|||
|
||||
float color[3] = { 1.0f, 1.0f, 0.0f };
|
||||
|
||||
for (unsigned int i : m_list)
|
||||
{
|
||||
for (unsigned int i : m_list) {
|
||||
const GLVolume* volume = (*m_volumes)[i];
|
||||
int object_idx = volume->object_idx();
|
||||
int volume_idx = volume->volume_idx();
|
||||
for (unsigned int j = 0; j < (unsigned int)m_volumes->size(); ++j)
|
||||
{
|
||||
for (unsigned int j = 0; j < (unsigned int)m_volumes->size(); ++j) {
|
||||
if (i == j)
|
||||
continue;
|
||||
|
||||
const GLVolume* v = (*m_volumes)[j];
|
||||
if ((v->object_idx() != object_idx) || (v->volume_idx() != volume_idx))
|
||||
if (v->object_idx() != object_idx || v->volume_idx() != volume_idx)
|
||||
continue;
|
||||
|
||||
render_bounding_box(v->transformed_convex_hull_bounding_box(), color);
|
||||
|
@ -2087,9 +2046,9 @@ void Selection::render_sidebar_layers_hints(const std::string& sidebar_field) co
|
|||
#ifndef NDEBUG
|
||||
static bool is_rotation_xy_synchronized(const Vec3d &rot_xyz_from, const Vec3d &rot_xyz_to)
|
||||
{
|
||||
Eigen::AngleAxisd angle_axis(Geometry::rotation_xyz_diff(rot_xyz_from, rot_xyz_to));
|
||||
Vec3d axis = angle_axis.axis();
|
||||
double angle = angle_axis.angle();
|
||||
const Eigen::AngleAxisd angle_axis(Geometry::rotation_xyz_diff(rot_xyz_from, rot_xyz_to));
|
||||
const Vec3d axis = angle_axis.axis();
|
||||
const double angle = angle_axis.angle();
|
||||
if (std::abs(angle) < 1e-8)
|
||||
return true;
|
||||
assert(std::abs(axis.x()) < 1e-8);
|
||||
|
@ -2126,24 +2085,22 @@ void Selection::synchronize_unselected_instances(SyncRotationType sync_rotation_
|
|||
std::set<unsigned int> done; // prevent processing volumes twice
|
||||
done.insert(m_list.begin(), m_list.end());
|
||||
|
||||
for (unsigned int i : m_list)
|
||||
{
|
||||
for (unsigned int i : m_list) {
|
||||
if (done.size() == m_volumes->size())
|
||||
break;
|
||||
|
||||
const GLVolume* volume = (*m_volumes)[i];
|
||||
int object_idx = volume->object_idx();
|
||||
const int object_idx = volume->object_idx();
|
||||
if (object_idx >= 1000)
|
||||
continue;
|
||||
|
||||
int instance_idx = volume->instance_idx();
|
||||
const int instance_idx = volume->instance_idx();
|
||||
const Vec3d& rotation = volume->get_instance_rotation();
|
||||
const Vec3d& scaling_factor = volume->get_instance_scaling_factor();
|
||||
const Vec3d& mirror = volume->get_instance_mirror();
|
||||
|
||||
// Process unselected instances.
|
||||
for (unsigned int j = 0; j < (unsigned int)m_volumes->size(); ++j)
|
||||
{
|
||||
for (unsigned int j = 0; j < (unsigned int)m_volumes->size(); ++j) {
|
||||
if (done.size() == m_volumes->size())
|
||||
break;
|
||||
|
||||
|
@ -2151,24 +2108,36 @@ void Selection::synchronize_unselected_instances(SyncRotationType sync_rotation_
|
|||
continue;
|
||||
|
||||
GLVolume* v = (*m_volumes)[j];
|
||||
if ((v->object_idx() != object_idx) || (v->instance_idx() == instance_idx))
|
||||
if (v->object_idx() != object_idx || v->instance_idx() == instance_idx)
|
||||
continue;
|
||||
|
||||
assert(is_rotation_xy_synchronized(m_cache.volumes_data[i].get_instance_rotation(), m_cache.volumes_data[j].get_instance_rotation()));
|
||||
switch (sync_rotation_type) {
|
||||
case SYNC_ROTATION_NONE:
|
||||
case SYNC_ROTATION_NONE: {
|
||||
#if ENABLE_ALLOW_NEGATIVE_Z
|
||||
// z only rotation -> synch instance z
|
||||
// The X,Y rotations should be synchronized from start to end of the rotation.
|
||||
assert(is_rotation_xy_synchronized(rotation, v->get_instance_rotation()));
|
||||
#if DISABLE_ALLOW_NEGATIVE_Z_FOR_SLA
|
||||
if (wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology() != ptSLA)
|
||||
#endif // DISABLE_ALLOW_NEGATIVE_Z_FOR_SLA
|
||||
v->set_instance_offset(Z, volume->get_instance_offset().z());
|
||||
break;
|
||||
#else
|
||||
// z only rotation -> keep instance z
|
||||
// The X,Y rotations should be synchronized from start to end of the rotation.
|
||||
assert(is_rotation_xy_synchronized(rotation, v->get_instance_rotation()));
|
||||
break;
|
||||
#endif // ENABLE_ALLOW_NEGATIVE_Z
|
||||
}
|
||||
case SYNC_ROTATION_FULL:
|
||||
// rotation comes from place on face -> force given z
|
||||
v->set_instance_rotation(Vec3d(rotation(0), rotation(1), rotation(2)));
|
||||
v->set_instance_rotation({ rotation.x(), rotation.y(), rotation.z() });
|
||||
break;
|
||||
case SYNC_ROTATION_GENERAL:
|
||||
// generic rotation -> update instance z with the delta of the rotation.
|
||||
double z_diff = Geometry::rotation_diff_z(m_cache.volumes_data[i].get_instance_rotation(), m_cache.volumes_data[j].get_instance_rotation());
|
||||
v->set_instance_rotation(Vec3d(rotation(0), rotation(1), rotation(2) + z_diff));
|
||||
const double z_diff = Geometry::rotation_diff_z(m_cache.volumes_data[i].get_instance_rotation(), m_cache.volumes_data[j].get_instance_rotation());
|
||||
v->set_instance_rotation({ rotation.x(), rotation.y(), rotation.z() + z_diff });
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -2186,27 +2155,25 @@ void Selection::synchronize_unselected_instances(SyncRotationType sync_rotation_
|
|||
|
||||
void Selection::synchronize_unselected_volumes()
|
||||
{
|
||||
for (unsigned int i : m_list)
|
||||
{
|
||||
for (unsigned int i : m_list) {
|
||||
const GLVolume* volume = (*m_volumes)[i];
|
||||
int object_idx = volume->object_idx();
|
||||
const int object_idx = volume->object_idx();
|
||||
if (object_idx >= 1000)
|
||||
continue;
|
||||
|
||||
int volume_idx = volume->volume_idx();
|
||||
const int volume_idx = volume->volume_idx();
|
||||
const Vec3d& offset = volume->get_volume_offset();
|
||||
const Vec3d& rotation = volume->get_volume_rotation();
|
||||
const Vec3d& scaling_factor = volume->get_volume_scaling_factor();
|
||||
const Vec3d& mirror = volume->get_volume_mirror();
|
||||
|
||||
// Process unselected volumes.
|
||||
for (unsigned int j = 0; j < (unsigned int)m_volumes->size(); ++j)
|
||||
{
|
||||
for (unsigned int j = 0; j < (unsigned int)m_volumes->size(); ++j) {
|
||||
if (j == i)
|
||||
continue;
|
||||
|
||||
GLVolume* v = (*m_volumes)[j];
|
||||
if ((v->object_idx() != object_idx) || (v->volume_idx() != volume_idx))
|
||||
if (v->object_idx() != object_idx || v->volume_idx() != volume_idx)
|
||||
continue;
|
||||
|
||||
v->set_volume_offset(offset);
|
||||
|
@ -2222,10 +2189,8 @@ void Selection::ensure_on_bed()
|
|||
typedef std::map<std::pair<int, int>, double> InstancesToZMap;
|
||||
InstancesToZMap instances_min_z;
|
||||
|
||||
for (GLVolume* volume : *m_volumes)
|
||||
{
|
||||
if (!volume->is_wipe_tower && !volume->is_modifier)
|
||||
{
|
||||
for (GLVolume* volume : *m_volumes) {
|
||||
if (!volume->is_wipe_tower && !volume->is_modifier) {
|
||||
double min_z = volume->transformed_convex_hull_bounding_box().min(2);
|
||||
std::pair<int, int> instance = std::make_pair(volume->object_idx(), volume->instance_idx());
|
||||
InstancesToZMap::iterator it = instances_min_z.find(instance);
|
||||
|
@ -2236,8 +2201,7 @@ void Selection::ensure_on_bed()
|
|||
}
|
||||
}
|
||||
|
||||
for (GLVolume* volume : *m_volumes)
|
||||
{
|
||||
for (GLVolume* volume : *m_volumes) {
|
||||
std::pair<int, int> instance = std::make_pair(volume->object_idx(), volume->instance_idx());
|
||||
InstancesToZMap::iterator it = instances_min_z.find(instance);
|
||||
if (it != instances_min_z.end())
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue