FIX: auto arrange estimates wrong wipe tower
Jira: STUDIO-4678 Change-Id: Iff2273b464db939a2b5e19f8791bd2a4d67ce8c1 (cherry picked from commit fe4b1f79faeade42300622367fb23d7bd1079785)
This commit is contained in:
parent
00373df52c
commit
8d74732348
|
@ -73,6 +73,7 @@ static constexpr double INSET_OVERLAP_TOLERANCE = 0.4;
|
||||||
//FIXME This is quite a lot.
|
//FIXME This is quite a lot.
|
||||||
static constexpr double EXTERNAL_INFILL_MARGIN = 3;
|
static constexpr double EXTERNAL_INFILL_MARGIN = 3;
|
||||||
static constexpr double BRIDGE_INFILL_MARGIN = 1;
|
static constexpr double BRIDGE_INFILL_MARGIN = 1;
|
||||||
|
static constexpr double WIPE_TOWER_MARGIN = 15.;
|
||||||
//FIXME Better to use an inline function with an explicit return type.
|
//FIXME Better to use an inline function with an explicit return type.
|
||||||
//inline coord_t scale_(coordf_t v) { return coord_t(floor(v / SCALING_FACTOR + 0.5f)); }
|
//inline coord_t scale_(coordf_t v) { return coord_t(floor(v / SCALING_FACTOR + 0.5f)); }
|
||||||
#define scale_(val) ((val) / SCALING_FACTOR)
|
#define scale_(val) ((val) / SCALING_FACTOR)
|
||||||
|
|
|
@ -1737,45 +1737,6 @@ bool GLCanvas3D::make_current_for_postinit() {
|
||||||
return _set_current();
|
return _set_current();
|
||||||
}
|
}
|
||||||
|
|
||||||
Points GLCanvas3D::estimate_wipe_tower_points(int plate_index, bool global) const
|
|
||||||
{
|
|
||||||
PartPlateList & ppl = wxGetApp().plater()->get_partplate_list();
|
|
||||||
DynamicPrintConfig &proj_cfg = wxGetApp().preset_bundle->project_config;
|
|
||||||
auto & print = wxGetApp().plater()->get_partplate_list().get_current_fff_print();
|
|
||||||
int plate_count = ppl.get_plate_count();
|
|
||||||
float x = dynamic_cast<const ConfigOptionFloats *>(proj_cfg.option("wipe_tower_x"))->get_at(plate_index);
|
|
||||||
float y = dynamic_cast<const ConfigOptionFloats *>(proj_cfg.option("wipe_tower_y"))->get_at(plate_index);
|
|
||||||
if (plate_index >= plate_count) { plate_index = 0; }
|
|
||||||
float w = dynamic_cast<const ConfigOptionFloat *>(m_config->option("prime_tower_width"))->value;
|
|
||||||
float v = dynamic_cast<const ConfigOptionFloat *>(m_config->option("prime_volume"))->value;
|
|
||||||
const DynamicPrintConfig &print_cfg = wxGetApp().preset_bundle->prints.get_edited_preset().config;
|
|
||||||
Vec3d wipe_tower_size = ppl.get_plate(plate_index)->estimate_wipe_tower_size(print_cfg, w, v);
|
|
||||||
|
|
||||||
if (wipe_tower_size(1) == 0) {
|
|
||||||
// when depth is unavailable (no items on this plate), we have to estimate the depth using the extruder number of all plates
|
|
||||||
std::set<int> extruder_ids;
|
|
||||||
if (global) {
|
|
||||||
auto objs = wxGetApp().obj_list()->objects();
|
|
||||||
for (ModelObject *obj : *objs) {
|
|
||||||
for (ModelVolume *volume : obj->volumes) {
|
|
||||||
std::vector<int> es = volume->get_extruders();
|
|
||||||
extruder_ids.insert(es.begin(), es.end());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
PartPlate* pl = ppl.get_plate(plate_index);
|
|
||||||
std::vector<int> es = pl->get_extruders();
|
|
||||||
extruder_ids.insert(es.begin(), es.end());
|
|
||||||
}
|
|
||||||
int extruder_size = extruder_ids.size();
|
|
||||||
wipe_tower_size(1) = extruder_size * print.wipe_tower_data(extruder_size).depth + 2 * print.wipe_tower_data().brim_width;
|
|
||||||
}
|
|
||||||
Vec3d plate_origin = ppl.get_plate(plate_index)->get_origin();
|
|
||||||
Point wt_min_corner{scale_(x), scale_(y)};
|
|
||||||
Point wt_max_corner(scale_(x + wipe_tower_size(0)), scale_(y + wipe_tower_size(1)));
|
|
||||||
return {wt_min_corner, {wt_max_corner.x(), wt_min_corner.y()}, wt_max_corner, {wt_min_corner.x(), wt_max_corner.y()}};
|
|
||||||
}
|
|
||||||
|
|
||||||
void GLCanvas3D::render(bool only_init)
|
void GLCanvas3D::render(bool only_init)
|
||||||
{
|
{
|
||||||
if (m_in_render) {
|
if (m_in_render) {
|
||||||
|
@ -2639,7 +2600,7 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
|
||||||
const DynamicPrintConfig &print_cfg = wxGetApp().preset_bundle->prints.get_edited_preset().config;
|
const DynamicPrintConfig &print_cfg = wxGetApp().preset_bundle->prints.get_edited_preset().config;
|
||||||
Vec3d wipe_tower_size = ppl.get_plate(plate_id)->estimate_wipe_tower_size(print_cfg, w, v);
|
Vec3d wipe_tower_size = ppl.get_plate(plate_id)->estimate_wipe_tower_size(print_cfg, w, v);
|
||||||
|
|
||||||
const float margin = 15.f;
|
const float margin = WIPE_TOWER_MARGIN;
|
||||||
BoundingBoxf3 plate_bbox = wxGetApp().plater()->get_partplate_list().get_plate(plate_id)->get_bounding_box();
|
BoundingBoxf3 plate_bbox = wxGetApp().plater()->get_partplate_list().get_plate(plate_id)->get_bounding_box();
|
||||||
coordf_t plate_bbox_x_max_local_coord = plate_bbox.max(0) - plate_origin(0);
|
coordf_t plate_bbox_x_max_local_coord = plate_bbox.max(0) - plate_origin(0);
|
||||||
coordf_t plate_bbox_y_max_local_coord = plate_bbox.max(1) - plate_origin(1);
|
coordf_t plate_bbox_y_max_local_coord = plate_bbox.max(1) - plate_origin(1);
|
||||||
|
@ -4913,10 +4874,10 @@ GLCanvas3D::WipeTowerInfo GLCanvas3D::get_wipe_tower_info(int plate_idx) const
|
||||||
wti.m_bb.offset((brim_width));
|
wti.m_bb.offset((brim_width));
|
||||||
|
|
||||||
// BBS: the wipe tower pos might be outside bed
|
// BBS: the wipe tower pos might be outside bed
|
||||||
PartPlate* plate = wxGetApp().plater()->get_partplate_list().get_curr_plate();
|
PartPlate* plate = wxGetApp().plater()->get_partplate_list().get_plate(plate_idx);
|
||||||
BoundingBoxf3 build_volume = plate->get_build_volume();
|
Vec2d plate_size = plate->get_size();
|
||||||
wti.m_pos.x() = std::clamp(wti.m_pos.x(), 0.0, build_volume.max.x() - wti.m_bb.size().x());
|
wti.m_pos.x() = std::clamp(wti.m_pos.x(), 0.0, plate_size(0) - wti.m_bb.size().x());
|
||||||
wti.m_pos.y() = std::clamp(wti.m_pos.y(), 0.0, build_volume.max.y() - wti.m_bb.size().y());
|
wti.m_pos.y() = std::clamp(wti.m_pos.y(), 0.0, plate_size(1) - wti.m_bb.size().y());
|
||||||
|
|
||||||
// BBS: add partplate logic
|
// BBS: add partplate logic
|
||||||
wti.m_plate_idx = plate_idx;
|
wti.m_plate_idx = plate_idx;
|
||||||
|
|
|
@ -1083,9 +1083,6 @@ public:
|
||||||
|
|
||||||
bool make_current_for_postinit();
|
bool make_current_for_postinit();
|
||||||
|
|
||||||
//BBS
|
|
||||||
Points estimate_wipe_tower_points(int plate_index, bool global = true) const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool _is_shown_on_screen() const;
|
bool _is_shown_on_screen() const;
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,7 @@ public:
|
||||||
ret.is_wipe_tower = true;
|
ret.is_wipe_tower = true;
|
||||||
++ret.priority;
|
++ret.priority;
|
||||||
|
|
||||||
BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << " arrange: wipe tower info:" << m_bb << ", m_pos: " << m_pos.transpose();
|
BOOST_LOG_TRIVIAL(debug) << " arrange: wipe tower info:" << m_bb << ", m_pos: " << m_pos.transpose();
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -240,6 +240,21 @@ void ArrangeJob::prepare_all() {
|
||||||
plate_list.preprocess_exclude_areas(m_unselected, MAX_NUM_PLATES);
|
plate_list.preprocess_exclude_areas(m_unselected, MAX_NUM_PLATES);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
arrangement::ArrangePolygon estimate_wipe_tower_info(int plate_index, std::set<int>& extruder_ids)
|
||||||
|
{
|
||||||
|
PartPlateList& ppl = wxGetApp().plater()->get_partplate_list();
|
||||||
|
const auto& full_config = wxGetApp().preset_bundle->full_config();
|
||||||
|
int plate_count = ppl.get_plate_count();
|
||||||
|
int plate_index_valid = std::min(plate_index, plate_count - 1);
|
||||||
|
|
||||||
|
// we have to estimate the depth using the extruder number of all plates
|
||||||
|
int extruder_size = extruder_ids.size();
|
||||||
|
|
||||||
|
auto arrange_poly = ppl.get_plate(plate_index_valid)->estimate_wipe_tower_polygon(full_config, plate_index, extruder_size);
|
||||||
|
arrange_poly.bed_idx = plate_index;
|
||||||
|
return arrange_poly;
|
||||||
|
}
|
||||||
|
|
||||||
// 准备料塔。逻辑如下:
|
// 准备料塔。逻辑如下:
|
||||||
// 1. 以下几种情况不需要料塔:
|
// 1. 以下几种情况不需要料塔:
|
||||||
// 1)料塔被禁用,
|
// 1)料塔被禁用,
|
||||||
|
@ -299,6 +314,14 @@ void ArrangeJob::prepare_wipe_tower()
|
||||||
wipe_tower_ap.is_virt_object = true;
|
wipe_tower_ap.is_virt_object = true;
|
||||||
wipe_tower_ap.is_wipe_tower = true;
|
wipe_tower_ap.is_wipe_tower = true;
|
||||||
const GLCanvas3D* canvas3D = static_cast<const GLCanvas3D*>(m_plater->canvas3D());
|
const GLCanvas3D* canvas3D = static_cast<const GLCanvas3D*>(m_plater->canvas3D());
|
||||||
|
|
||||||
|
std::set<int> extruder_ids;
|
||||||
|
PartPlateList& ppl = wxGetApp().plater()->get_partplate_list();
|
||||||
|
int plate_count = ppl.get_plate_count();
|
||||||
|
if (!only_on_partplate) {
|
||||||
|
extruder_ids = ppl.get_extruders(true);
|
||||||
|
}
|
||||||
|
|
||||||
for (int bedid = 0; bedid < MAX_NUM_PLATES; bedid++) {
|
for (int bedid = 0; bedid < MAX_NUM_PLATES; bedid++) {
|
||||||
if (auto wti = get_wipe_tower(*m_plater, bedid)) {
|
if (auto wti = get_wipe_tower(*m_plater, bedid)) {
|
||||||
// wipe tower is already there
|
// wipe tower is already there
|
||||||
|
@ -307,8 +330,14 @@ void ArrangeJob::prepare_wipe_tower()
|
||||||
m_unselected.emplace_back(wipe_tower_ap);
|
m_unselected.emplace_back(wipe_tower_ap);
|
||||||
}
|
}
|
||||||
else if (need_wipe_tower) {
|
else if (need_wipe_tower) {
|
||||||
wipe_tower_ap.translation = { 0, 0 };
|
if (only_on_partplate) {
|
||||||
wipe_tower_ap.poly.contour.points = canvas3D->estimate_wipe_tower_points(bedid, !only_on_partplate);
|
int plate_index_valid = std::min(bedid, plate_count - 1);
|
||||||
|
PartPlate* pl = ppl.get_plate(plate_index_valid);
|
||||||
|
auto plate_extruders = pl->get_extruders(true);
|
||||||
|
extruder_ids.clear();
|
||||||
|
extruder_ids.insert(plate_extruders.begin(), plate_extruders.end());
|
||||||
|
}
|
||||||
|
wipe_tower_ap = estimate_wipe_tower_info(bedid, extruder_ids);
|
||||||
wipe_tower_ap.bed_idx = bedid;
|
wipe_tower_ap.bed_idx = bedid;
|
||||||
m_unselected.emplace_back(wipe_tower_ap);
|
m_unselected.emplace_back(wipe_tower_ap);
|
||||||
}
|
}
|
||||||
|
@ -365,7 +394,7 @@ void ArrangeJob::prepare_partplate() {
|
||||||
//skip this object due to be not in current plate, treated as locked
|
//skip this object due to be not in current plate, treated as locked
|
||||||
ap.itemid = m_locked.size();
|
ap.itemid = m_locked.size();
|
||||||
m_locked.emplace_back(std::move(ap));
|
m_locked.emplace_back(std::move(ap));
|
||||||
BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(": skip locked instance, obj_id %1%, name %2%") % oidx % mo->name;
|
//BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(": skip locked instance, obj_id %1%, name %2%") % oidx % mo->name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -523,7 +552,8 @@ void ArrangeJob::process()
|
||||||
}
|
}
|
||||||
BOOST_LOG_TRIVIAL(debug) << "items unselected before arrange: ";
|
BOOST_LOG_TRIVIAL(debug) << "items unselected before arrange: ";
|
||||||
for (auto item : m_unselected)
|
for (auto item : m_unselected)
|
||||||
BOOST_LOG_TRIVIAL(debug) << item.name << ", bed: " << item.bed_idx << ", trans: " << item.translation.transpose();
|
BOOST_LOG_TRIVIAL(debug) << item.name << ", bed: " << item.bed_idx << ", trans: " << item.translation.transpose()
|
||||||
|
<<", bbox:"<<get_extents(item.poly).min.transpose()<<","<<get_extents(item.poly).max.transpose();
|
||||||
}
|
}
|
||||||
|
|
||||||
arrangement::arrange(m_selected, m_unselected, bedpts, params);
|
arrangement::arrange(m_selected, m_unselected, bedpts, params);
|
||||||
|
|
|
@ -1701,6 +1701,46 @@ Vec3d PartPlate::estimate_wipe_tower_size(const DynamicPrintConfig & config, con
|
||||||
return wipe_tower_size;
|
return wipe_tower_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
arrangement::ArrangePolygon PartPlate::estimate_wipe_tower_polygon(const DynamicPrintConfig& config, int plate_index, int plate_extruder_size) const
|
||||||
|
{
|
||||||
|
float x = dynamic_cast<const ConfigOptionFloats*>(config.option("wipe_tower_x"))->get_at(plate_index);
|
||||||
|
float y = dynamic_cast<const ConfigOptionFloats*>(config.option("wipe_tower_y"))->get_at(plate_index);
|
||||||
|
float w = dynamic_cast<const ConfigOptionFloat*>(config.option("prime_tower_width"))->value;
|
||||||
|
//float a = dynamic_cast<const ConfigOptionFloat*>(config.option("wipe_tower_rotation_angle"))->value;
|
||||||
|
float v = dynamic_cast<const ConfigOptionFloat*>(config.option("prime_volume"))->value;
|
||||||
|
Vec3d wipe_tower_size = estimate_wipe_tower_size(config, w, v, plate_extruder_size);
|
||||||
|
int plate_width=m_width, plate_depth=m_depth;
|
||||||
|
float depth = wipe_tower_size(1);
|
||||||
|
float margin = WIPE_TOWER_MARGIN, wp_brim_width = 0.f;
|
||||||
|
const ConfigOption* wipe_tower_brim_width_opt = config.option("prime_tower_brim_width");
|
||||||
|
if (wipe_tower_brim_width_opt) {
|
||||||
|
wp_brim_width = wipe_tower_brim_width_opt->getFloat();
|
||||||
|
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format("arrange wipe_tower: wp_brim_width %1%") % wp_brim_width;
|
||||||
|
}
|
||||||
|
|
||||||
|
x = std::clamp(x, margin, (float)plate_width - w - margin - wp_brim_width);
|
||||||
|
y = std::clamp(y, margin, (float)plate_depth - depth - margin - wp_brim_width);
|
||||||
|
|
||||||
|
arrangement::ArrangePolygon wipe_tower_ap;
|
||||||
|
Polygon ap({
|
||||||
|
{scaled(x - wp_brim_width), scaled(y - wp_brim_width)},
|
||||||
|
{scaled(x + w + wp_brim_width), scaled(y - wp_brim_width)},
|
||||||
|
{scaled(x + w + wp_brim_width), scaled(y + depth + wp_brim_width)},
|
||||||
|
{scaled(x - wp_brim_width), scaled(y + depth + wp_brim_width)}
|
||||||
|
});
|
||||||
|
wipe_tower_ap.bed_idx = plate_index;
|
||||||
|
wipe_tower_ap.setter = NULL; // do not move wipe tower
|
||||||
|
|
||||||
|
wipe_tower_ap.poly.contour = std::move(ap);
|
||||||
|
wipe_tower_ap.translation = { scaled(0.f), scaled(0.f) };
|
||||||
|
//wipe_tower_ap.rotation = a;
|
||||||
|
wipe_tower_ap.name = "WipeTower";
|
||||||
|
wipe_tower_ap.is_virt_object = true;
|
||||||
|
wipe_tower_ap.is_wipe_tower = true;
|
||||||
|
|
||||||
|
return wipe_tower_ap;
|
||||||
|
}
|
||||||
|
|
||||||
bool PartPlate::operator<(PartPlate& plate) const
|
bool PartPlate::operator<(PartPlate& plate) const
|
||||||
{
|
{
|
||||||
int index = plate.get_index();
|
int index = plate.get_index();
|
||||||
|
@ -3702,6 +3742,20 @@ std::vector<const GCodeProcessorResult*> PartPlateList::get_nonempty_plates_slic
|
||||||
return nonempty_plates_slice_result;
|
return nonempty_plates_slice_result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::set<int> PartPlateList::get_extruders(bool conside_custom_gcode) const
|
||||||
|
{
|
||||||
|
int plate_count = get_plate_count();
|
||||||
|
std::set<int> extruder_ids;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < plate_count; i++) {
|
||||||
|
auto plate_extruders = m_plate_list[i]->get_extruders(conside_custom_gcode);
|
||||||
|
extruder_ids.insert(plate_extruders.begin(), plate_extruders.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
return extruder_ids;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//select plate
|
//select plate
|
||||||
int PartPlateList::select_plate(int index)
|
int PartPlateList::select_plate(int index)
|
||||||
{
|
{
|
||||||
|
@ -3795,7 +3849,7 @@ double PartPlateList::plate_stride_y()
|
||||||
}
|
}
|
||||||
|
|
||||||
//get the plate counts, not including the invalid plate
|
//get the plate counts, not including the invalid plate
|
||||||
int PartPlateList::get_plate_count()
|
int PartPlateList::get_plate_count() const
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
|
@ -4353,7 +4407,7 @@ bool PartPlateList::preprocess_arrange_polygon_other_locked(int obj_index, int i
|
||||||
arrange_polygon.col = i % m_plate_cols;
|
arrange_polygon.col = i % m_plate_cols;
|
||||||
arrange_polygon.translation(X) -= scaled<double>(plate_stride_x() * arrange_polygon.col);
|
arrange_polygon.translation(X) -= scaled<double>(plate_stride_x() * arrange_polygon.col);
|
||||||
arrange_polygon.translation(Y) += scaled<double>(plate_stride_y() * arrange_polygon.row);
|
arrange_polygon.translation(Y) += scaled<double>(plate_stride_y() * arrange_polygon.row);
|
||||||
BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(": obj_id %1% instance_id %2% in plate %3%, locked %4%, row %5%, col %6%\n") % obj_index % instance_index % i % locked % arrange_polygon.row % arrange_polygon.col;
|
//BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(": obj_id %1% instance_id %2% in plate %3%, locked %4%, row %5%, col %6%\n") % obj_index % instance_index % i % locked % arrange_polygon.row % arrange_polygon.col;
|
||||||
return locked;
|
return locked;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -288,11 +288,13 @@ public:
|
||||||
void set_pos_and_size(Vec3d& origin, int width, int depth, int height, bool with_instance_move);
|
void set_pos_and_size(Vec3d& origin, int width, int depth, int height, bool with_instance_move);
|
||||||
|
|
||||||
// BBS
|
// BBS
|
||||||
|
Vec2d get_size() const { return Vec2d(m_width, m_depth); }
|
||||||
ModelObjectPtrs get_objects() { return m_model->objects; }
|
ModelObjectPtrs get_objects() { return m_model->objects; }
|
||||||
ModelInstance* get_instance(int obj_id, int instance_id);
|
ModelInstance* get_instance(int obj_id, int instance_id);
|
||||||
|
|
||||||
Vec3d get_origin() { return m_origin; }
|
Vec3d get_origin() { return m_origin; }
|
||||||
Vec3d estimate_wipe_tower_size(const DynamicPrintConfig & config, const double w, const double wipe_volume, int plate_extruder_size = 0) const;
|
Vec3d estimate_wipe_tower_size(const DynamicPrintConfig & config, const double w, const double wipe_volume, int plate_extruder_size = 0) const;
|
||||||
|
arrangement::ArrangePolygon estimate_wipe_tower_polygon(const DynamicPrintConfig & config, int plate_index, int plate_extruder_size = 0) const;
|
||||||
std::vector<int> get_extruders(bool conside_custom_gcode = false) const;
|
std::vector<int> get_extruders(bool conside_custom_gcode = false) const;
|
||||||
std::vector<int> get_extruders_under_cli(bool conside_custom_gcode, DynamicPrintConfig& full_config) const;
|
std::vector<int> get_extruders_under_cli(bool conside_custom_gcode, DynamicPrintConfig& full_config) const;
|
||||||
std::vector<int> get_extruders_without_support(bool conside_custom_gcode = false) const;
|
std::vector<int> get_extruders_without_support(bool conside_custom_gcode = false) const;
|
||||||
|
@ -687,11 +689,13 @@ public:
|
||||||
Vec2d get_current_shape_position() { return compute_shape_position(m_current_plate, m_plate_cols); }
|
Vec2d get_current_shape_position() { return compute_shape_position(m_current_plate, m_plate_cols); }
|
||||||
Pointfs get_exclude_area() { return m_exclude_areas; }
|
Pointfs get_exclude_area() { return m_exclude_areas; }
|
||||||
|
|
||||||
|
std::set<int> get_extruders(bool conside_custom_gcode = false) const;
|
||||||
|
|
||||||
//select plate
|
//select plate
|
||||||
int select_plate(int index);
|
int select_plate(int index);
|
||||||
|
|
||||||
//get the plate counts, not including the invalid plate
|
//get the plate counts, not including the invalid plate
|
||||||
int get_plate_count();
|
int get_plate_count() const;
|
||||||
|
|
||||||
//update the plate cols due to plate count change
|
//update the plate cols due to plate count change
|
||||||
void update_plate_cols();
|
void update_plate_cols();
|
||||||
|
|
|
@ -899,7 +899,7 @@ void Selection::translate(const Vec3d& displacement, bool local)
|
||||||
Vec3d tower_size = v.bounding_box().size();
|
Vec3d tower_size = v.bounding_box().size();
|
||||||
Vec3d tower_origin = m_cache.volumes_data[i].get_volume_position();
|
Vec3d tower_origin = m_cache.volumes_data[i].get_volume_position();
|
||||||
Vec3d actual_displacement = displacement;
|
Vec3d actual_displacement = displacement;
|
||||||
const double margin = 15.f;
|
const double margin = WIPE_TOWER_MARGIN;
|
||||||
|
|
||||||
if (!local)
|
if (!local)
|
||||||
actual_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;
|
actual_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;
|
||||||
|
|
Loading…
Reference in New Issue