mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-01 22:50:40 +08:00
Merge branch 'master' into fs_dir_per_glyph
This commit is contained in:
commit
2bfe762dfb
Binary file not shown.
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 45 KiB |
Binary file not shown.
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 37 KiB |
@ -1,9 +1,9 @@
|
|||||||
#ifndef ARRANGE_HPP
|
#ifndef ARRANGE_HPP
|
||||||
#define ARRANGE_HPP
|
#define ARRANGE_HPP
|
||||||
|
|
||||||
#include "ExPolygon.hpp"
|
|
||||||
|
|
||||||
#include <boost/variant.hpp>
|
#include <boost/variant.hpp>
|
||||||
|
|
||||||
|
#include <libslic3r/ExPolygon.hpp>
|
||||||
#include <libslic3r/BoundingBox.hpp>
|
#include <libslic3r/BoundingBox.hpp>
|
||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
|
@ -882,14 +882,20 @@ namespace client
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (opt == nullptr)
|
if (opt == nullptr)
|
||||||
ctx->throw_exception("Variable does not exist", IteratorRange(opt_key.begin(), opt_key.end()));
|
ctx->throw_exception("Variable does not exist", opt_key);
|
||||||
if (opt->is_scalar())
|
if (opt->is_scalar()) {
|
||||||
|
if (opt->is_nil())
|
||||||
|
ctx->throw_exception("Trying to reference an undefined (nil) optional variable", opt_key);
|
||||||
output = opt->serialize();
|
output = opt->serialize();
|
||||||
else {
|
} else {
|
||||||
const ConfigOptionVectorBase *vec = static_cast<const ConfigOptionVectorBase*>(opt);
|
const ConfigOptionVectorBase *vec = static_cast<const ConfigOptionVectorBase*>(opt);
|
||||||
if (vec->empty())
|
if (vec->empty())
|
||||||
ctx->throw_exception("Indexing an empty vector variable", opt_key);
|
ctx->throw_exception("Indexing an empty vector variable", opt_key);
|
||||||
output = vec->vserialize()[(idx >= vec->size()) ? 0 : idx];
|
if (idx >= vec->size())
|
||||||
|
idx = 0;
|
||||||
|
if (vec->is_nil(idx))
|
||||||
|
ctx->throw_exception("Trying to reference an undefined (nil) element of vector of optional values", opt_key);
|
||||||
|
output = vec->vserialize()[idx];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -917,7 +923,7 @@ namespace client
|
|||||||
ctx->throw_exception("Trying to index a scalar variable", opt_key);
|
ctx->throw_exception("Trying to index a scalar variable", opt_key);
|
||||||
const ConfigOptionVectorBase *vec = static_cast<const ConfigOptionVectorBase*>(opt);
|
const ConfigOptionVectorBase *vec = static_cast<const ConfigOptionVectorBase*>(opt);
|
||||||
if (vec->empty())
|
if (vec->empty())
|
||||||
ctx->throw_exception("Indexing an empty vector variable", IteratorRange(opt_key.begin(), opt_key.end()));
|
ctx->throw_exception("Indexing an empty vector variable", opt_key);
|
||||||
const ConfigOption *opt_index = ctx->resolve_symbol(std::string(opt_vector_index.begin(), opt_vector_index.end()));
|
const ConfigOption *opt_index = ctx->resolve_symbol(std::string(opt_vector_index.begin(), opt_vector_index.end()));
|
||||||
if (opt_index == nullptr)
|
if (opt_index == nullptr)
|
||||||
ctx->throw_exception("Variable does not exist", opt_key);
|
ctx->throw_exception("Variable does not exist", opt_key);
|
||||||
@ -926,7 +932,11 @@ namespace client
|
|||||||
int idx = opt_index->getInt();
|
int idx = opt_index->getInt();
|
||||||
if (idx < 0)
|
if (idx < 0)
|
||||||
ctx->throw_exception("Negative vector index", opt_key);
|
ctx->throw_exception("Negative vector index", opt_key);
|
||||||
output = vec->vserialize()[(idx >= (int)vec->size()) ? 0 : idx];
|
if (idx >= (int)vec->size())
|
||||||
|
idx = 0;
|
||||||
|
if (vec->is_nil(idx))
|
||||||
|
ctx->throw_exception("Trying to reference an undefined (nil) element of vector of optional values", opt_key);
|
||||||
|
output = vec->vserialize()[idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
static void resolve_variable(
|
static void resolve_variable(
|
||||||
@ -976,6 +986,9 @@ namespace client
|
|||||||
|
|
||||||
assert(opt.opt->is_scalar());
|
assert(opt.opt->is_scalar());
|
||||||
|
|
||||||
|
if (opt.opt->is_nil())
|
||||||
|
ctx->throw_exception("Trying to reference an undefined (nil) optional variable", opt.it_range);
|
||||||
|
|
||||||
switch (opt.opt->type()) {
|
switch (opt.opt->type()) {
|
||||||
case coFloat: output.set_d(opt.opt->getFloat()); break;
|
case coFloat: output.set_d(opt.opt->getFloat()); break;
|
||||||
case coInt: output.set_i(opt.opt->getInt()); break;
|
case coInt: output.set_i(opt.opt->getInt()); break;
|
||||||
@ -1041,6 +1054,8 @@ namespace client
|
|||||||
if (vec->empty())
|
if (vec->empty())
|
||||||
ctx->throw_exception("Indexing an empty vector variable", opt.it_range);
|
ctx->throw_exception("Indexing an empty vector variable", opt.it_range);
|
||||||
size_t idx = (opt.index < 0) ? 0 : (opt.index >= int(vec->size())) ? 0 : size_t(opt.index);
|
size_t idx = (opt.index < 0) ? 0 : (opt.index >= int(vec->size())) ? 0 : size_t(opt.index);
|
||||||
|
if (vec->is_nil(idx))
|
||||||
|
ctx->throw_exception("Trying to reference an undefined (nil) element of vector of optional values", opt.it_range);
|
||||||
switch (opt.opt->type()) {
|
switch (opt.opt->type()) {
|
||||||
case coFloats: output.set_d(static_cast<const ConfigOptionFloats*>(opt.opt)->values[idx]); break;
|
case coFloats: output.set_d(static_cast<const ConfigOptionFloats*>(opt.opt)->values[idx]); break;
|
||||||
case coInts: output.set_i(static_cast<const ConfigOptionInts*>(opt.opt)->values[idx]); break;
|
case coInts: output.set_i(static_cast<const ConfigOptionInts*>(opt.opt)->values[idx]); break;
|
||||||
@ -1434,6 +1449,8 @@ namespace client
|
|||||||
assert(lhs.opt->is_vector());
|
assert(lhs.opt->is_vector());
|
||||||
if (rhs.has_index() || ! rhs.opt->is_vector())
|
if (rhs.has_index() || ! rhs.opt->is_vector())
|
||||||
ctx->throw_exception("Cannot assign scalar to a vector", lhs.it_range);
|
ctx->throw_exception("Cannot assign scalar to a vector", lhs.it_range);
|
||||||
|
if (rhs.opt->is_nil())
|
||||||
|
ctx->throw_exception("Some elements of the right hand side vector variable of optional values are undefined (nil)", rhs.it_range);
|
||||||
if (lhs.opt->type() != rhs.opt->type()) {
|
if (lhs.opt->type() != rhs.opt->type()) {
|
||||||
// Vector types are not compatible.
|
// Vector types are not compatible.
|
||||||
switch (lhs.opt->type()) {
|
switch (lhs.opt->type()) {
|
||||||
@ -1470,6 +1487,8 @@ namespace client
|
|||||||
if (rhs.has_index() || ! rhs.opt->is_vector())
|
if (rhs.has_index() || ! rhs.opt->is_vector())
|
||||||
// Stop parsing, let the other rules resolve this case.
|
// Stop parsing, let the other rules resolve this case.
|
||||||
return false;
|
return false;
|
||||||
|
if (rhs.opt->is_nil())
|
||||||
|
ctx->throw_exception("Some elements of the right hand side vector variable of optional values are undefined (nil)", rhs.it_range);
|
||||||
// Clone the vector variable.
|
// Clone the vector variable.
|
||||||
std::unique_ptr<ConfigOption> opt_new;
|
std::unique_ptr<ConfigOption> opt_new;
|
||||||
if (one_of(rhs.opt->type(), { coFloats, coInts, coStrings, coBools }))
|
if (one_of(rhs.opt->type(), { coFloats, coInts, coStrings, coBools }))
|
||||||
|
@ -2970,7 +2970,7 @@ static void create_nodes_from_area(
|
|||||||
assert(radius_increase >= 0);
|
assert(radius_increase >= 0);
|
||||||
double shift = (elem.state.result_on_layer - parent.state.result_on_layer).cast<double>().norm();
|
double shift = (elem.state.result_on_layer - parent.state.result_on_layer).cast<double>().norm();
|
||||||
//FIXME this assert fails a lot. Is it correct?
|
//FIXME this assert fails a lot. Is it correct?
|
||||||
assert(shift < radius_increase + 2. * config.maximum_move_distance_slow);
|
// assert(shift < radius_increase + 2. * config.maximum_move_distance_slow);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2995,7 +2995,7 @@ static void create_nodes_from_area(
|
|||||||
assert(radius_increase >= 0);
|
assert(radius_increase >= 0);
|
||||||
double shift = (elem.state.result_on_layer - parent.state.result_on_layer).cast<double>().norm();
|
double shift = (elem.state.result_on_layer - parent.state.result_on_layer).cast<double>().norm();
|
||||||
//FIXME this assert fails a lot. Is it correct?
|
//FIXME this assert fails a lot. Is it correct?
|
||||||
assert(shift < radius_increase + 2. * config.maximum_move_distance_slow);
|
// assert(shift < radius_increase + 2. * config.maximum_move_distance_slow);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2354,13 +2354,23 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool
|
|||||||
size_t last = path_id;
|
size_t last = path_id;
|
||||||
|
|
||||||
// check adjacent paths
|
// check adjacent paths
|
||||||
while (first > 0 && path.sub_paths.front().first.position.isApprox(buffer.paths[first - 1].sub_paths.back().last.position)) {
|
while (first > 0) {
|
||||||
|
const Path& ref_path = buffer.paths[first - 1];
|
||||||
|
if (!path.sub_paths.front().first.position.isApprox(ref_path.sub_paths.back().last.position) ||
|
||||||
|
path.role != ref_path.role)
|
||||||
|
break;
|
||||||
|
|
||||||
|
path.sub_paths.front().first = ref_path.sub_paths.front().first;
|
||||||
--first;
|
--first;
|
||||||
path.sub_paths.front().first = buffer.paths[first].sub_paths.front().first;
|
|
||||||
}
|
}
|
||||||
while (last < buffer.paths.size() - 1 && path.sub_paths.back().last.position.isApprox(buffer.paths[last + 1].sub_paths.front().first.position)) {
|
while (last < buffer.paths.size() - 1) {
|
||||||
|
const Path& ref_path = buffer.paths[last + 1];
|
||||||
|
if (!path.sub_paths.back().last.position.isApprox(ref_path.sub_paths.front().first.position) ||
|
||||||
|
path.role != ref_path.role)
|
||||||
|
break;
|
||||||
|
|
||||||
|
path.sub_paths.back().last = ref_path.sub_paths.back().last;
|
||||||
++last;
|
++last;
|
||||||
path.sub_paths.back().last = buffer.paths[last].sub_paths.back().last;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const size_t min_s_id = m_layers.get_range_at(min_id).first;
|
const size_t min_s_id = m_layers.get_range_at(min_id).first;
|
||||||
|
@ -955,7 +955,7 @@ void ObjectList::list_manipulation(const wxPoint& mouse_pos, bool evt_context_me
|
|||||||
|
|
||||||
if (!item) {
|
if (!item) {
|
||||||
if (col == nullptr) {
|
if (col == nullptr) {
|
||||||
if (wxOSX && !multiple_selection())
|
if (wxOSX)
|
||||||
UnselectAll();
|
UnselectAll();
|
||||||
else if (!evt_context_menu)
|
else if (!evt_context_menu)
|
||||||
// Case, when last item was deleted and under GTK was called wxEVT_DATAVIEW_SELECTION_CHANGED,
|
// Case, when last item was deleted and under GTK was called wxEVT_DATAVIEW_SELECTION_CHANGED,
|
||||||
@ -972,11 +972,17 @@ void ObjectList::list_manipulation(const wxPoint& mouse_pos, bool evt_context_me
|
|||||||
if (wxOSX && item && col) {
|
if (wxOSX && item && col) {
|
||||||
wxDataViewItemArray sels;
|
wxDataViewItemArray sels;
|
||||||
GetSelections(sels);
|
GetSelections(sels);
|
||||||
UnselectAll();
|
bool is_selection_changed = true;
|
||||||
if (sels.Count() > 1)
|
for (const auto& sel_item : sels)
|
||||||
SetSelections(sels);
|
if (sel_item == item) {
|
||||||
else
|
// item is one oth the already selected items, so resection is no needed
|
||||||
|
is_selection_changed = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (is_selection_changed) {
|
||||||
|
UnselectAll();
|
||||||
Select(item);
|
Select(item);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (col != nullptr)
|
if (col != nullptr)
|
||||||
|
@ -67,23 +67,10 @@ bool GLGizmoMove3D::on_is_activable() const
|
|||||||
void GLGizmoMove3D::on_start_dragging()
|
void GLGizmoMove3D::on_start_dragging()
|
||||||
{
|
{
|
||||||
assert(m_hover_id != -1);
|
assert(m_hover_id != -1);
|
||||||
|
|
||||||
m_displacement = Vec3d::Zero();
|
m_displacement = Vec3d::Zero();
|
||||||
const Selection& selection = m_parent.get_selection();
|
m_starting_drag_position = m_grabbers[m_hover_id].matrix * m_grabbers[m_hover_id].center;
|
||||||
const ECoordinatesType coordinates_type = wxGetApp().obj_manipul()->get_coordinates_type();
|
|
||||||
if (coordinates_type == ECoordinatesType::World)
|
|
||||||
m_starting_drag_position = m_center + m_grabbers[m_hover_id].center;
|
|
||||||
else if (coordinates_type == ECoordinatesType::Local && selection.is_single_volume_or_modifier()) {
|
|
||||||
const GLVolume& v = *selection.get_first_volume();
|
|
||||||
m_starting_drag_position = m_center + v.get_instance_transformation().get_rotation_matrix() * v.get_volume_transformation().get_rotation_matrix() * m_grabbers[m_hover_id].center;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
const GLVolume& v = *selection.get_first_volume();
|
|
||||||
m_starting_drag_position = m_center + v.get_instance_transformation().get_rotation_matrix() * m_grabbers[m_hover_id].center;
|
|
||||||
}
|
|
||||||
m_starting_box_center = m_center;
|
m_starting_box_center = m_center;
|
||||||
m_starting_box_bottom_center = m_center;
|
m_starting_box_bottom_center = Vec3d(m_center.x(), m_center.y(), m_bounding_box.min.z());
|
||||||
m_starting_box_bottom_center.z() = m_bounding_box.min.z();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLGizmoMove3D::on_stop_dragging()
|
void GLGizmoMove3D::on_stop_dragging()
|
||||||
@ -122,7 +109,8 @@ void GLGizmoMove3D::on_render()
|
|||||||
const auto& [box, box_trafo] = selection.get_bounding_box_in_current_reference_system();
|
const auto& [box, box_trafo] = selection.get_bounding_box_in_current_reference_system();
|
||||||
m_bounding_box = box;
|
m_bounding_box = box;
|
||||||
m_center = box_trafo.translation();
|
m_center = box_trafo.translation();
|
||||||
const Transform3d base_matrix = local_transform(m_parent.get_selection());
|
const Transform3d base_matrix = box_trafo;
|
||||||
|
|
||||||
for (int i = 0; i < 3; ++i) {
|
for (int i = 0; i < 3; ++i) {
|
||||||
m_grabbers[i].matrix = base_matrix;
|
m_grabbers[i].matrix = base_matrix;
|
||||||
}
|
}
|
||||||
@ -230,10 +218,12 @@ void GLGizmoMove3D::on_render()
|
|||||||
if (shader != nullptr) {
|
if (shader != nullptr) {
|
||||||
shader->start_using();
|
shader->start_using();
|
||||||
shader->set_uniform("emission_factor", 0.1f);
|
shader->set_uniform("emission_factor", 0.1f);
|
||||||
|
glsafe(::glDisable(GL_CULL_FACE));
|
||||||
// draw grabber
|
// draw grabber
|
||||||
const Vec3d box_size = m_bounding_box.size();
|
const Vec3d box_size = m_bounding_box.size();
|
||||||
const float mean_size = (float)((box_size.x() + box_size.y() + box_size.z()) / 3.0);
|
const float mean_size = (float)((box_size.x() + box_size.y() + box_size.z()) / 3.0);
|
||||||
m_grabbers[m_hover_id].render(true, mean_size);
|
m_grabbers[m_hover_id].render(true, mean_size);
|
||||||
|
glsafe(::glEnable(GL_CULL_FACE));
|
||||||
shader->stop_using();
|
shader->stop_using();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -86,7 +86,7 @@ arrangement::ArrangePolygon get_arrange_poly(T obj, const Plater *plater)
|
|||||||
using ArrangePolygon = arrangement::ArrangePolygon;
|
using ArrangePolygon = arrangement::ArrangePolygon;
|
||||||
|
|
||||||
ArrangePolygon ap = obj.get_arrange_polygon();
|
ArrangePolygon ap = obj.get_arrange_polygon();
|
||||||
ap.bed_idx = ap.translation.x() / bed_stride(plater);
|
ap.bed_idx = get_extents(ap.transformed_poly()).min.x() / bed_stride(plater);
|
||||||
ap.setter = [obj, plater](const ArrangePolygon &p) {
|
ap.setter = [obj, plater](const ArrangePolygon &p) {
|
||||||
if (p.is_arranged()) {
|
if (p.is_arranged()) {
|
||||||
Vec2d t = p.translation.cast<double>();
|
Vec2d t = p.translation.cast<double>();
|
||||||
|
@ -6057,36 +6057,36 @@ void Plater::remove_selected()
|
|||||||
p->view3D->delete_selected();
|
p->view3D->delete_selected();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Plater::increase_instances(size_t num, int obj_idx, std::optional<Selection::ObjectIdxsToInstanceIdxsMap> selection_map)
|
void Plater::increase_instances(size_t num, int obj_idx, int inst_idx)
|
||||||
{
|
{
|
||||||
if (! can_increase_instances()) { return; }
|
if (! can_increase_instances()) { return; }
|
||||||
|
|
||||||
Plater::TakeSnapshot snapshot(this, _L("Increase Instances"));
|
Plater::TakeSnapshot snapshot(this, _L("Increase Instances"));
|
||||||
|
|
||||||
if (obj_idx < 0)
|
|
||||||
obj_idx = p->get_selected_object_idx();
|
|
||||||
|
|
||||||
if (obj_idx < 0) {
|
if (obj_idx < 0) {
|
||||||
if (const auto obj_idxs = get_selection().get_object_idxs(); !obj_idxs.empty()) {
|
obj_idx = p->get_selected_object_idx();
|
||||||
// we need a copy made here because the selection changes at every call of increase_instances()
|
if (obj_idx < 0) {
|
||||||
const Selection::ObjectIdxsToInstanceIdxsMap content = selection_map.has_value() ? *selection_map : p->get_selection().get_content();
|
// It's a case of increasing per 1 instance, when multiple objects are selected
|
||||||
for (const size_t obj_id : obj_idxs) {
|
if (const auto obj_idxs = get_selection().get_object_idxs(); !obj_idxs.empty()) {
|
||||||
increase_instances(1, int(obj_id), content);
|
// we need a copy made here because the selection changes at every call of increase_instances()
|
||||||
|
const Selection::ObjectIdxsToInstanceIdxsMap content = p->get_selection().get_content();
|
||||||
|
for (const size_t& obj_id : obj_idxs) {
|
||||||
|
if (auto obj_it = content.find(int(obj_id)); obj_it != content.end())
|
||||||
|
increase_instances(1, int(obj_id), *obj_it->second.rbegin());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
assert(obj_idx >= 0);
|
||||||
|
|
||||||
ModelObject* model_object = p->model.objects[obj_idx];
|
ModelObject* model_object = p->model.objects[obj_idx];
|
||||||
int inst_idx = -1;
|
|
||||||
if (selection_map.has_value()) {
|
|
||||||
auto obj_it = selection_map->find(obj_idx);
|
|
||||||
if (obj_it != selection_map->end() && obj_it->second.size() == 1)
|
|
||||||
inst_idx = *obj_it->second.begin();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
inst_idx = p->get_selected_instance_idx();
|
|
||||||
|
|
||||||
|
if (inst_idx < 0 && get_selected_object_idx() >= 0) {
|
||||||
|
inst_idx = get_selection().get_instance_idx();
|
||||||
|
if (0 > inst_idx || inst_idx >= int(model_object->instances.size()))
|
||||||
|
inst_idx = -1;
|
||||||
|
}
|
||||||
ModelInstance* model_instance = (inst_idx >= 0) ? model_object->instances[inst_idx] : model_object->instances.back();
|
ModelInstance* model_instance = (inst_idx >= 0) ? model_object->instances[inst_idx] : model_object->instances.back();
|
||||||
|
|
||||||
bool was_one_instance = model_object->instances.size()==1;
|
bool was_one_instance = model_object->instances.size()==1;
|
||||||
@ -6098,7 +6098,6 @@ void Plater::increase_instances(size_t num, int obj_idx, std::optional<Selection
|
|||||||
Geometry::Transformation trafo = model_instance->get_transformation();
|
Geometry::Transformation trafo = model_instance->get_transformation();
|
||||||
trafo.set_offset(offset_vec);
|
trafo.set_offset(offset_vec);
|
||||||
model_object->add_instance(trafo);
|
model_object->add_instance(trafo);
|
||||||
// p->print.get_object(obj_idx)->add_copy(Slic3r::to_2d(offset_vec));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p->get_config_bool("autocenter"))
|
if (p->get_config_bool("autocenter"))
|
||||||
@ -6182,11 +6181,16 @@ void Plater::set_number_of_copies()
|
|||||||
return;
|
return;
|
||||||
TakeSnapshot snapshot(this, wxString::Format(_L("Set numbers of copies to %d"), num));
|
TakeSnapshot snapshot(this, wxString::Format(_L("Set numbers of copies to %d"), num));
|
||||||
|
|
||||||
for (const auto obj_idx : obj_idxs) {
|
// we need a copy made here because the selection changes at every call of increase_instances()
|
||||||
|
Selection::ObjectIdxsToInstanceIdxsMap content = p->get_selection().get_content();
|
||||||
|
|
||||||
|
for (const auto& obj_idx : obj_idxs) {
|
||||||
ModelObject* model_object = p->model.objects[obj_idx];
|
ModelObject* model_object = p->model.objects[obj_idx];
|
||||||
const int diff = num - (int)model_object->instances.size();
|
const int diff = num - (int)model_object->instances.size();
|
||||||
if (diff > 0)
|
if (diff > 0) {
|
||||||
increase_instances(diff, int(obj_idx));
|
if (auto obj_it = content.find(int(obj_idx)); obj_it != content.end())
|
||||||
|
increase_instances(diff, int(obj_idx), *obj_it->second.rbegin());
|
||||||
|
}
|
||||||
else if (diff < 0)
|
else if (diff < 0)
|
||||||
decrease_instances(-diff, int(obj_idx));
|
decrease_instances(-diff, int(obj_idx));
|
||||||
}
|
}
|
||||||
|
@ -250,7 +250,7 @@ public:
|
|||||||
void reset_with_confirm();
|
void reset_with_confirm();
|
||||||
bool delete_object_from_model(size_t obj_idx);
|
bool delete_object_from_model(size_t obj_idx);
|
||||||
void remove_selected();
|
void remove_selected();
|
||||||
void increase_instances(size_t num = 1, int obj_idx = -1, std::optional<Selection::ObjectIdxsToInstanceIdxsMap> selection_map = std::nullopt);
|
void increase_instances(size_t num = 1, int obj_idx = -1, int inst_idx = -1);
|
||||||
void decrease_instances(size_t num = 1, int obj_idx = -1);
|
void decrease_instances(size_t num = 1, int obj_idx = -1);
|
||||||
void set_number_of_copies();
|
void set_number_of_copies();
|
||||||
void fill_bed_with_instances();
|
void fill_bed_with_instances();
|
||||||
|
@ -1593,6 +1593,7 @@ void Selection::render_sidebar_hints(const std::string& sidebar_field)
|
|||||||
shader->start_using();
|
shader->start_using();
|
||||||
|
|
||||||
glsafe(::glEnable(GL_DEPTH_TEST));
|
glsafe(::glEnable(GL_DEPTH_TEST));
|
||||||
|
glsafe(::glDisable(GL_CULL_FACE));
|
||||||
|
|
||||||
const Transform3d base_matrix = Geometry::translation_transform(get_bounding_box().center());
|
const Transform3d base_matrix = Geometry::translation_transform(get_bounding_box().center());
|
||||||
Transform3d orient_matrix = Transform3d::Identity();
|
Transform3d orient_matrix = Transform3d::Identity();
|
||||||
@ -1603,15 +1604,15 @@ void Selection::render_sidebar_hints(const std::string& sidebar_field)
|
|||||||
if (!boost::starts_with(sidebar_field, "layer")) {
|
if (!boost::starts_with(sidebar_field, "layer")) {
|
||||||
shader->set_uniform("emission_factor", 0.05f);
|
shader->set_uniform("emission_factor", 0.05f);
|
||||||
if (is_single_full_instance() && !wxGetApp().obj_manipul()->is_world_coordinates()) {
|
if (is_single_full_instance() && !wxGetApp().obj_manipul()->is_world_coordinates()) {
|
||||||
orient_matrix = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_rotation_matrix();
|
orient_matrix = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_rotation_matrix();
|
||||||
axes_center = (*m_volumes)[*m_list.begin()]->get_instance_offset();
|
axes_center = (*m_volumes)[*m_list.begin()]->get_instance_offset();
|
||||||
}
|
}
|
||||||
else if (is_single_volume_or_modifier()) {
|
else if (is_single_volume_or_modifier()) {
|
||||||
if (!wxGetApp().obj_manipul()->is_world_coordinates()) {
|
if (!wxGetApp().obj_manipul()->is_world_coordinates()) {
|
||||||
if (wxGetApp().obj_manipul()->is_local_coordinates()) {
|
if (wxGetApp().obj_manipul()->is_local_coordinates()) {
|
||||||
const GLVolume* v = (*m_volumes)[*m_list.begin()];
|
const GLVolume* v = (*m_volumes)[*m_list.begin()];
|
||||||
orient_matrix = v->get_instance_transformation().get_rotation_matrix() * v->get_volume_transformation().get_rotation_matrix();
|
orient_matrix = get_bounding_box_in_current_reference_system().second;
|
||||||
axes_center = (*m_volumes)[*m_list.begin()]->world_matrix().translation();
|
orient_matrix.translation() = Vec3d::Zero();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
orient_matrix = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_rotation_matrix();
|
orient_matrix = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_rotation_matrix();
|
||||||
@ -1645,6 +1646,7 @@ void Selection::render_sidebar_hints(const std::string& sidebar_field)
|
|||||||
m_axes.render(Geometry::translation_transform(axes_center) * orient_matrix, 0.25f);
|
m_axes.render(Geometry::translation_transform(axes_center) * orient_matrix, 0.25f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glsafe(::glEnable(GL_CULL_FACE));
|
||||||
shader->stop_using();
|
shader->stop_using();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user