Merge branch 'master' of https://github.com/prusa3d/PrusaSlicer
This commit is contained in:
commit
06a8bfa588
@ -77,7 +77,7 @@ inline void offset(PolygonImpl& sh, TCoord<PointImpl> distance, const PolygonTag
|
|||||||
#define DISABLE_BOOST_OFFSET
|
#define DISABLE_BOOST_OFFSET
|
||||||
|
|
||||||
using ClipperLib::ClipperOffset;
|
using ClipperLib::ClipperOffset;
|
||||||
using ClipperLib::jtMiter;
|
using ClipperLib::jtSquare;
|
||||||
using ClipperLib::etClosedPolygon;
|
using ClipperLib::etClosedPolygon;
|
||||||
using ClipperLib::Paths;
|
using ClipperLib::Paths;
|
||||||
|
|
||||||
@ -85,8 +85,8 @@ inline void offset(PolygonImpl& sh, TCoord<PointImpl> distance, const PolygonTag
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
ClipperOffset offs;
|
ClipperOffset offs;
|
||||||
offs.AddPath(sh.Contour, jtMiter, etClosedPolygon);
|
offs.AddPath(sh.Contour, jtSquare, etClosedPolygon);
|
||||||
offs.AddPaths(sh.Holes, jtMiter, etClosedPolygon);
|
offs.AddPaths(sh.Holes, jtSquare, etClosedPolygon);
|
||||||
offs.Execute(result, static_cast<double>(distance));
|
offs.Execute(result, static_cast<double>(distance));
|
||||||
} catch (ClipperLib::clipperException &) {
|
} catch (ClipperLib::clipperException &) {
|
||||||
throw GeometryException(GeomErr::OFFSET);
|
throw GeometryException(GeomErr::OFFSET);
|
||||||
|
@ -528,15 +528,12 @@ public:
|
|||||||
|
|
||||||
static inline double overfit(const Box& bb, const Box& bin)
|
static inline double overfit(const Box& bb, const Box& bin)
|
||||||
{
|
{
|
||||||
auto Bw = bin.width();
|
auto wdiff = TCompute<RawShape>(bb.width()) - bin.width();
|
||||||
auto Bh = bin.height();
|
auto hdiff = TCompute<RawShape>(bb.height()) - bin.height();
|
||||||
auto mBw = -Bw;
|
double diff = .0;
|
||||||
auto mBh = -Bh;
|
if(wdiff > 0) diff += double(wdiff);
|
||||||
auto wdiff = double(bb.width()) + mBw;
|
if(hdiff > 0) diff += double(hdiff);
|
||||||
auto hdiff = double(bb.height()) + mBh;
|
|
||||||
double diff = 0;
|
|
||||||
if(wdiff > 0) diff += wdiff;
|
|
||||||
if(hdiff > 0) diff += hdiff;
|
|
||||||
return diff;
|
return diff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -396,7 +396,10 @@ template<> std::function<double(const Item&)> AutoArranger<Box>::get_objfn()
|
|||||||
double score = std::get<0>(result);
|
double score = std::get<0>(result);
|
||||||
auto& fullbb = std::get<1>(result);
|
auto& fullbb = std::get<1>(result);
|
||||||
|
|
||||||
double miss = Placer::overfit(fullbb, m_bin);
|
auto bin = m_bin;
|
||||||
|
sl::offset(bin, -EPSILON * (m_bin.width() + m_bin.height()));
|
||||||
|
|
||||||
|
double miss = Placer::overfit(fullbb, bin);
|
||||||
miss = miss > 0? miss : 0;
|
miss = miss > 0? miss : 0;
|
||||||
score += miss*miss;
|
score += miss*miss;
|
||||||
|
|
||||||
|
@ -695,33 +695,41 @@ void ObjectList::selection_changed()
|
|||||||
part_selection_changed();
|
part_selection_changed();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ObjectList::fill_layer_config_ranges_cache()
|
void ObjectList::copy_layers_to_clipboard()
|
||||||
{
|
{
|
||||||
wxDataViewItemArray sel_layers;
|
wxDataViewItemArray sel_layers;
|
||||||
GetSelections(sel_layers);
|
GetSelections(sel_layers);
|
||||||
|
|
||||||
const int obj_idx = m_objects_model->GetObjectIdByItem(sel_layers[0]);
|
const int obj_idx = m_objects_model->GetObjectIdByItem(sel_layers.front());
|
||||||
if (obj_idx < 0 || (int)m_objects->size() <= obj_idx)
|
if (obj_idx < 0 || (int)m_objects->size() <= obj_idx)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const t_layer_config_ranges& ranges = object(obj_idx)->layer_config_ranges;
|
const t_layer_config_ranges& ranges = object(obj_idx)->layer_config_ranges;
|
||||||
m_layer_config_ranges_cache.clear();
|
t_layer_config_ranges& cache_ranges = m_clipboard.get_ranges_cache();
|
||||||
|
|
||||||
|
if (sel_layers.Count() == 1 && m_objects_model->GetItemType(sel_layers.front()) & itLayerRoot)
|
||||||
|
{
|
||||||
|
cache_ranges.clear();
|
||||||
|
cache_ranges = ranges;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (const auto layer_item : sel_layers)
|
for (const auto layer_item : sel_layers)
|
||||||
if (m_objects_model->GetItemType(layer_item) & itLayer) {
|
if (m_objects_model->GetItemType(layer_item) & itLayer) {
|
||||||
auto range = m_objects_model->GetLayerRangeByItem(layer_item);
|
auto range = m_objects_model->GetLayerRangeByItem(layer_item);
|
||||||
auto it = ranges.find(range);
|
auto it = ranges.find(range);
|
||||||
if (it != ranges.end())
|
if (it != ranges.end())
|
||||||
m_layer_config_ranges_cache[it->first] = it->second;
|
cache_ranges[it->first] = it->second;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ObjectList::paste_layers_into_list()
|
void ObjectList::paste_layers_into_list()
|
||||||
{
|
{
|
||||||
const int obj_idx = m_objects_model->GetObjectIdByItem(GetSelection());
|
const int obj_idx = m_objects_model->GetObjectIdByItem(GetSelection());
|
||||||
|
t_layer_config_ranges& cache_ranges = m_clipboard.get_ranges_cache();
|
||||||
|
|
||||||
if (obj_idx < 0 || (int)m_objects->size() <= obj_idx ||
|
if (obj_idx < 0 || (int)m_objects->size() <= obj_idx ||
|
||||||
m_layer_config_ranges_cache.empty() || printer_technology() == ptSLA)
|
cache_ranges.empty() || printer_technology() == ptSLA)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const wxDataViewItem object_item = m_objects_model->GetItemById(obj_idx);
|
const wxDataViewItem object_item = m_objects_model->GetItemById(obj_idx);
|
||||||
@ -732,7 +740,7 @@ void ObjectList::paste_layers_into_list()
|
|||||||
t_layer_config_ranges& ranges = object(obj_idx)->layer_config_ranges;
|
t_layer_config_ranges& ranges = object(obj_idx)->layer_config_ranges;
|
||||||
|
|
||||||
// and create Layer item(s) according to the layer_config_ranges
|
// and create Layer item(s) according to the layer_config_ranges
|
||||||
for (const auto range : m_layer_config_ranges_cache)
|
for (const auto range : cache_ranges)
|
||||||
ranges.emplace(range);
|
ranges.emplace(range);
|
||||||
|
|
||||||
layers_item = add_layer_root_item(object_item);
|
layers_item = add_layer_root_item(object_item);
|
||||||
@ -745,6 +753,48 @@ void ObjectList::paste_layers_into_list()
|
|||||||
#endif //no __WXOSX__
|
#endif //no __WXOSX__
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ObjectList::copy_settings_to_clipboard()
|
||||||
|
{
|
||||||
|
wxDataViewItem item = GetSelection();
|
||||||
|
assert(item.IsOk());
|
||||||
|
if (m_objects_model->GetItemType(item) & itSettings)
|
||||||
|
item = m_objects_model->GetParent(item);
|
||||||
|
|
||||||
|
DynamicPrintConfig& config_cache = m_clipboard.get_config_cache();
|
||||||
|
config_cache = get_item_config(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ObjectList::paste_settings_into_list()
|
||||||
|
{
|
||||||
|
wxDataViewItem item = GetSelection();
|
||||||
|
assert(item.IsOk());
|
||||||
|
if (m_objects_model->GetItemType(item) & itSettings)
|
||||||
|
item = m_objects_model->GetParent(item);
|
||||||
|
|
||||||
|
ItemType item_type = m_objects_model->GetItemType(item);
|
||||||
|
if(!(item_type & (itObject | itVolume |itLayer)))
|
||||||
|
return;
|
||||||
|
|
||||||
|
DynamicPrintConfig& config_cache = m_clipboard.get_config_cache();
|
||||||
|
assert(!config_cache.empty());
|
||||||
|
|
||||||
|
auto keys = config_cache.keys();
|
||||||
|
auto part_options = get_options(true);
|
||||||
|
|
||||||
|
for (const std::string& opt_key: keys) {
|
||||||
|
if (item_type & (itVolume | itLayer) &&
|
||||||
|
std::find(part_options.begin(), part_options.end(), opt_key) == part_options.end())
|
||||||
|
continue; // we can't to add object specific options for the part's(itVolume | itLayer) config
|
||||||
|
|
||||||
|
const ConfigOption* option = config_cache.option(opt_key);
|
||||||
|
if (option)
|
||||||
|
m_config->set_key_value(opt_key, option->clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add settings item for object/sub-object and show them
|
||||||
|
show_settings(add_settings_item(item, m_config));
|
||||||
|
}
|
||||||
|
|
||||||
void ObjectList::paste_volumes_into_list(int obj_idx, const ModelVolumePtrs& volumes)
|
void ObjectList::paste_volumes_into_list(int obj_idx, const ModelVolumePtrs& volumes)
|
||||||
{
|
{
|
||||||
if ((obj_idx < 0) || ((int)m_objects->size() <= obj_idx))
|
if ((obj_idx < 0) || ((int)m_objects->size() <= obj_idx))
|
||||||
@ -984,22 +1034,48 @@ void ObjectList::extruder_editing()
|
|||||||
|
|
||||||
void ObjectList::copy()
|
void ObjectList::copy()
|
||||||
{
|
{
|
||||||
// if (m_selection_mode & smLayer)
|
|
||||||
// fill_layer_config_ranges_cache();
|
|
||||||
// else {
|
|
||||||
// m_layer_config_ranges_cache.clear();
|
|
||||||
wxPostEvent((wxEvtHandler*)wxGetApp().plater()->canvas3D()->get_wxglcanvas(), SimpleEvent(EVT_GLTOOLBAR_COPY));
|
wxPostEvent((wxEvtHandler*)wxGetApp().plater()->canvas3D()->get_wxglcanvas(), SimpleEvent(EVT_GLTOOLBAR_COPY));
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ObjectList::paste()
|
void ObjectList::paste()
|
||||||
{
|
{
|
||||||
// if (!m_layer_config_ranges_cache.empty())
|
|
||||||
// paste_layers_into_list();
|
|
||||||
// else
|
|
||||||
wxPostEvent((wxEvtHandler*)wxGetApp().plater()->canvas3D()->get_wxglcanvas(), SimpleEvent(EVT_GLTOOLBAR_PASTE));
|
wxPostEvent((wxEvtHandler*)wxGetApp().plater()->canvas3D()->get_wxglcanvas(), SimpleEvent(EVT_GLTOOLBAR_PASTE));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ObjectList::copy_to_clipboard()
|
||||||
|
{
|
||||||
|
wxDataViewItemArray sels;
|
||||||
|
GetSelections(sels);
|
||||||
|
ItemType type = m_objects_model->GetItemType(sels.front());
|
||||||
|
if (!(type & (itSettings | itLayer | itLayerRoot))) {
|
||||||
|
m_clipboard.reset();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type & itSettings)
|
||||||
|
copy_settings_to_clipboard();
|
||||||
|
if (type & (itLayer | itLayerRoot))
|
||||||
|
copy_layers_to_clipboard();
|
||||||
|
|
||||||
|
m_clipboard.set_type(type);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ObjectList::paste_from_clipboard()
|
||||||
|
{
|
||||||
|
if (!(m_clipboard.get_type() & (itSettings | itLayer | itLayerRoot))) {
|
||||||
|
m_clipboard.reset();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_clipboard.get_type() & itSettings)
|
||||||
|
paste_settings_into_list();
|
||||||
|
if (m_clipboard.get_type() & (itLayer | itLayerRoot))
|
||||||
|
paste_layers_into_list();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void ObjectList::undo()
|
void ObjectList::undo()
|
||||||
{
|
{
|
||||||
wxGetApp().plater()->undo();
|
wxGetApp().plater()->undo();
|
||||||
|
@ -81,10 +81,32 @@ public:
|
|||||||
smLayerRoot = 16, // used for undo/redo
|
smLayerRoot = 16, // used for undo/redo
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Clipboard
|
||||||
|
{
|
||||||
|
void reset() {
|
||||||
|
m_type = itUndef;
|
||||||
|
m_layer_config_ranges_cache .clear();
|
||||||
|
m_config_cache.clear();
|
||||||
|
}
|
||||||
|
bool empty() const { return m_type == itUndef; }
|
||||||
|
ItemType get_type() const { return m_type; }
|
||||||
|
void set_type(ItemType type) { m_type = type; }
|
||||||
|
|
||||||
|
t_layer_config_ranges& get_ranges_cache() { return m_layer_config_ranges_cache; }
|
||||||
|
DynamicPrintConfig& get_config_cache() { return m_config_cache; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
ItemType m_type {itUndef};
|
||||||
|
t_layer_config_ranges m_layer_config_ranges_cache;
|
||||||
|
DynamicPrintConfig m_config_cache;
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SELECTION_MODE m_selection_mode {smUndef};
|
SELECTION_MODE m_selection_mode {smUndef};
|
||||||
int m_selected_layers_range_idx;
|
int m_selected_layers_range_idx;
|
||||||
|
|
||||||
|
Clipboard m_clipboard;
|
||||||
|
|
||||||
struct dragged_item_data
|
struct dragged_item_data
|
||||||
{
|
{
|
||||||
void init(const int obj_idx, const int subobj_idx, const ItemType type) {
|
void init(const int obj_idx, const int subobj_idx, const ItemType type) {
|
||||||
@ -148,8 +170,6 @@ private:
|
|||||||
|
|
||||||
std::vector<wxBitmap*> m_bmp_vector;
|
std::vector<wxBitmap*> m_bmp_vector;
|
||||||
|
|
||||||
t_layer_config_ranges m_layer_config_ranges_cache;
|
|
||||||
|
|
||||||
int m_selected_object_id = -1;
|
int m_selected_object_id = -1;
|
||||||
bool m_prevent_list_events = false; // We use this flag to avoid circular event handling Select()
|
bool m_prevent_list_events = false; // We use this flag to avoid circular event handling Select()
|
||||||
// happens to fire a wxEVT_LIST_ITEM_SELECTED on OSX, whose event handler
|
// happens to fire a wxEVT_LIST_ITEM_SELECTED on OSX, whose event handler
|
||||||
@ -230,6 +250,8 @@ public:
|
|||||||
|
|
||||||
void copy();
|
void copy();
|
||||||
void paste();
|
void paste();
|
||||||
|
bool copy_to_clipboard();
|
||||||
|
bool paste_from_clipboard();
|
||||||
void undo();
|
void undo();
|
||||||
void redo();
|
void redo();
|
||||||
|
|
||||||
@ -385,8 +407,11 @@ public:
|
|||||||
void fix_through_netfabb();
|
void fix_through_netfabb();
|
||||||
void update_item_error_icon(const int obj_idx, int vol_idx) const ;
|
void update_item_error_icon(const int obj_idx, int vol_idx) const ;
|
||||||
|
|
||||||
void fill_layer_config_ranges_cache();
|
void copy_layers_to_clipboard();
|
||||||
void paste_layers_into_list();
|
void paste_layers_into_list();
|
||||||
|
void copy_settings_to_clipboard();
|
||||||
|
void paste_settings_into_list();
|
||||||
|
bool clipboard_is_empty() const { return m_clipboard.empty(); }
|
||||||
void paste_volumes_into_list(int obj_idx, const ModelVolumePtrs& volumes);
|
void paste_volumes_into_list(int obj_idx, const ModelVolumePtrs& volumes);
|
||||||
void paste_objects_into_list(const std::vector<size_t>& object_idxs);
|
void paste_objects_into_list(const std::vector<size_t>& object_idxs);
|
||||||
|
|
||||||
|
@ -5456,7 +5456,10 @@ void Plater::show_action_buttons(const bool ready_to_slice) const { p->show_acti
|
|||||||
|
|
||||||
void Plater::copy_selection_to_clipboard()
|
void Plater::copy_selection_to_clipboard()
|
||||||
{
|
{
|
||||||
if (can_copy_to_clipboard())
|
// At first try to copy selected values to the ObjectList's clipboard
|
||||||
|
// to check if Settings or Layers are selected in the list
|
||||||
|
// and then copy to 3DCanvas's clipboard if not
|
||||||
|
if (can_copy_to_clipboard() && !p->sidebar->obj_list()->copy_to_clipboard())
|
||||||
p->view3D->get_canvas3d()->get_selection().copy_to_clipboard();
|
p->view3D->get_canvas3d()->get_selection().copy_to_clipboard();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5466,6 +5469,11 @@ void Plater::paste_from_clipboard()
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
Plater::TakeSnapshot snapshot(this, _L("Paste From Clipboard"));
|
Plater::TakeSnapshot snapshot(this, _L("Paste From Clipboard"));
|
||||||
|
|
||||||
|
// At first try to paste values from the ObjectList's clipboard
|
||||||
|
// to check if Settings or Layers were copied
|
||||||
|
// and then paste from the 3DCanvas's clipboard if not
|
||||||
|
if (!p->sidebar->obj_list()->paste_from_clipboard())
|
||||||
p->view3D->get_canvas3d()->get_selection().paste_from_clipboard();
|
p->view3D->get_canvas3d()->get_selection().paste_from_clipboard();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5591,7 +5599,7 @@ bool Plater::can_paste_from_clipboard() const
|
|||||||
const Selection& selection = p->view3D->get_canvas3d()->get_selection();
|
const Selection& selection = p->view3D->get_canvas3d()->get_selection();
|
||||||
const Selection::Clipboard& clipboard = selection.get_clipboard();
|
const Selection::Clipboard& clipboard = selection.get_clipboard();
|
||||||
|
|
||||||
if (clipboard.is_empty())
|
if (clipboard.is_empty() && p->sidebar->obj_list()->clipboard_is_empty())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if ((wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology() == ptSLA) && !clipboard.is_sla_compliant())
|
if ((wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology() == ptSLA) && !clipboard.is_sla_compliant())
|
||||||
|
Loading…
Reference in New Issue
Block a user