Merge branch 'scene_manipulators' of https://github.com/prusa3d/Slic3r
This commit is contained in:
commit
bbe5586c15
@ -127,6 +127,8 @@ sub new {
|
||||
$range->[1] *= $variation;
|
||||
}
|
||||
$_->set_scaling_factor($scale) for @{ $model_object->instances };
|
||||
|
||||
$self->{list}->SetItem($obj_idx, 2, ($model_object->instances->[0]->scaling_factor * 100) . "%");
|
||||
$object->transform_thumbnail($self->{model}, $obj_idx);
|
||||
|
||||
#update print and start background processing
|
||||
@ -2100,7 +2102,8 @@ sub object_list_changed {
|
||||
|
||||
my $export_in_progress = $self->{export_gcode_output_file} || $self->{send_gcode_file};
|
||||
my $model_fits = $self->{canvas3D} ? Slic3r::GUI::_3DScene::check_volumes_outside_state($self->{canvas3D}, $self->{config}) : 1;
|
||||
my $method = ($have_objects && ! $export_in_progress && $model_fits) ? 'Enable' : 'Disable';
|
||||
# $model_fits == 1 -> ModelInstance::PVS_Partly_Outside
|
||||
my $method = ($have_objects && ! $export_in_progress && ($model_fits != 1)) ? 'Enable' : 'Disable';
|
||||
$self->{"btn_$_"}->$method
|
||||
for grep $self->{"btn_$_"}, qw(reslice export_gcode print send_gcode);
|
||||
}
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 100 KiB After Width: | Height: | Size: 33 KiB |
Binary file not shown.
Before Width: | Height: | Size: 83 KiB After Width: | Height: | Size: 186 KiB |
@ -1989,7 +1989,7 @@ namespace Slic3r {
|
||||
|
||||
// stores object's name
|
||||
if (!obj->name.empty())
|
||||
stream << " <" << METADATA_TAG << " " << TYPE_ATTR << "=\"" << OBJECT_TYPE << "\" " << KEY_ATTR << "=\"name\" " << VALUE_ATTR << "=\"" << obj->name << "\"/>\n";
|
||||
stream << " <" << METADATA_TAG << " " << TYPE_ATTR << "=\"" << OBJECT_TYPE << "\" " << KEY_ATTR << "=\"name\" " << VALUE_ATTR << "=\"" << xml_escape(obj->name) << "\"/>\n";
|
||||
|
||||
// stores object's config data
|
||||
for (const std::string& key : obj->config.keys())
|
||||
@ -2012,7 +2012,7 @@ namespace Slic3r {
|
||||
|
||||
// stores volume's name
|
||||
if (!volume->name.empty())
|
||||
stream << " <" << METADATA_TAG << " " << TYPE_ATTR << "=\"" << VOLUME_TYPE << "\" " << KEY_ATTR << "=\"" << NAME_KEY << "\" " << VALUE_ATTR << "=\"" << volume->name << "\"/>\n";
|
||||
stream << " <" << METADATA_TAG << " " << TYPE_ATTR << "=\"" << VOLUME_TYPE << "\" " << KEY_ATTR << "=\"" << NAME_KEY << "\" " << VALUE_ATTR << "=\"" << xml_escape(volume->name) << "\"/>\n";
|
||||
|
||||
// stores volume's modifier field
|
||||
if (volume->modifier)
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "../libslic3r.h"
|
||||
#include "../Model.hpp"
|
||||
#include "../GCode.hpp"
|
||||
#include "../Utils.hpp"
|
||||
#include "../slic3r/GUI/PresetBundle.hpp"
|
||||
#include "AMF.hpp"
|
||||
|
||||
@ -686,33 +687,6 @@ bool load_amf(const char *path, PresetBundle* bundle, Model *model)
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string xml_escape(std::string text)
|
||||
{
|
||||
std::string::size_type pos = 0;
|
||||
for (;;)
|
||||
{
|
||||
pos = text.find_first_of("\"\'&<>", pos);
|
||||
if (pos == std::string::npos)
|
||||
break;
|
||||
|
||||
std::string replacement;
|
||||
switch (text[pos])
|
||||
{
|
||||
case '\"': replacement = """; break;
|
||||
case '\'': replacement = "'"; break;
|
||||
case '&': replacement = "&"; break;
|
||||
case '<': replacement = "<"; break;
|
||||
case '>': replacement = ">"; break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
text.replace(pos, 1, replacement);
|
||||
pos += replacement.size();
|
||||
}
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
bool store_amf(const char *path, Model *model, Print* print, bool export_print_config)
|
||||
{
|
||||
if ((path == nullptr) || (model == nullptr) || (print == nullptr))
|
||||
@ -761,7 +735,7 @@ bool store_amf(const char *path, Model *model, Print* print, bool export_print_c
|
||||
for (const std::string &key : object->config.keys())
|
||||
stream << " <metadata type=\"slic3r." << key << "\">" << object->config.serialize(key) << "</metadata>\n";
|
||||
if (!object->name.empty())
|
||||
stream << " <metadata type=\"name\">" << object->name << "</metadata>\n";
|
||||
stream << " <metadata type=\"name\">" << xml_escape(object->name) << "</metadata>\n";
|
||||
std::vector<double> layer_height_profile = object->layer_height_profile_valid ? object->layer_height_profile : std::vector<double>();
|
||||
if (layer_height_profile.size() >= 4 && (layer_height_profile.size() % 2) == 0) {
|
||||
// Store the layer height profile as a single semicolon separated list.
|
||||
@ -805,7 +779,7 @@ bool store_amf(const char *path, Model *model, Print* print, bool export_print_c
|
||||
for (const std::string &key : volume->config.keys())
|
||||
stream << " <metadata type=\"slic3r." << key << "\">" << volume->config.serialize(key) << "</metadata>\n";
|
||||
if (!volume->name.empty())
|
||||
stream << " <metadata type=\"name\">" << volume->name << "</metadata>\n";
|
||||
stream << " <metadata type=\"name\">" << xml_escape(volume->name) << "</metadata>\n";
|
||||
if (volume->modifier)
|
||||
stream << " <metadata type=\"slic3r.modifier\">1</metadata>\n";
|
||||
for (int i = 0; i < volume->mesh.stl.stats.number_of_facets; ++i) {
|
||||
|
@ -309,10 +309,12 @@ std::vector<std::pair<coordf_t, std::vector<GCode::LayerToPrint>>> GCode::collec
|
||||
size_t object_idx;
|
||||
size_t layer_idx;
|
||||
};
|
||||
std::vector<std::vector<LayerToPrint>> per_object(print.objects.size(), std::vector<LayerToPrint>());
|
||||
|
||||
PrintObjectPtrs printable_objects = print.get_printable_objects();
|
||||
std::vector<std::vector<LayerToPrint>> per_object(printable_objects.size(), std::vector<LayerToPrint>());
|
||||
std::vector<OrderingItem> ordering;
|
||||
for (size_t i = 0; i < print.objects.size(); ++ i) {
|
||||
per_object[i] = collect_layers_to_print(*print.objects[i]);
|
||||
for (size_t i = 0; i < printable_objects.size(); ++i) {
|
||||
per_object[i] = collect_layers_to_print(*printable_objects[i]);
|
||||
OrderingItem ordering_item;
|
||||
ordering_item.object_idx = i;
|
||||
ordering.reserve(ordering.size() + per_object[i].size());
|
||||
@ -337,8 +339,8 @@ std::vector<std::pair<coordf_t, std::vector<GCode::LayerToPrint>>> GCode::collec
|
||||
std::pair<coordf_t, std::vector<LayerToPrint>> merged;
|
||||
// Assign an average print_z to the set of layers with nearly equal print_z.
|
||||
merged.first = 0.5 * (ordering[i].print_z + ordering[j-1].print_z);
|
||||
merged.second.assign(print.objects.size(), LayerToPrint());
|
||||
for (; i < j; ++ i) {
|
||||
merged.second.assign(printable_objects.size(), LayerToPrint());
|
||||
for (; i < j; ++i) {
|
||||
const OrderingItem &oi = ordering[i];
|
||||
assert(merged.second[oi.object_idx].layer() == nullptr);
|
||||
merged.second[oi.object_idx] = std::move(per_object[oi.object_idx][oi.layer_idx]);
|
||||
@ -472,9 +474,10 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data)
|
||||
// How many times will be change_layer() called?
|
||||
// change_layer() in turn increments the progress bar status.
|
||||
m_layer_count = 0;
|
||||
PrintObjectPtrs printable_objects = print.get_printable_objects();
|
||||
if (print.config.complete_objects.value) {
|
||||
// Add each of the object's layers separately.
|
||||
for (auto object : print.objects) {
|
||||
for (auto object : printable_objects) {
|
||||
std::vector<coordf_t> zs;
|
||||
zs.reserve(object->layers.size() + object->support_layers.size());
|
||||
for (auto layer : object->layers)
|
||||
@ -487,7 +490,7 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data)
|
||||
} else {
|
||||
// Print all objects with the same print_z together.
|
||||
std::vector<coordf_t> zs;
|
||||
for (auto object : print.objects) {
|
||||
for (auto object : printable_objects) {
|
||||
zs.reserve(zs.size() + object->layers.size() + object->support_layers.size());
|
||||
for (auto layer : object->layers)
|
||||
zs.push_back(layer->print_z);
|
||||
@ -506,8 +509,8 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data)
|
||||
{
|
||||
// get the minimum cross-section used in the print
|
||||
std::vector<double> mm3_per_mm;
|
||||
for (auto object : print.objects) {
|
||||
for (size_t region_id = 0; region_id < print.regions.size(); ++ region_id) {
|
||||
for (auto object : printable_objects) {
|
||||
for (size_t region_id = 0; region_id < print.regions.size(); ++region_id) {
|
||||
auto region = print.regions[region_id];
|
||||
for (auto layer : object->layers) {
|
||||
auto layerm = layer->regions[region_id];
|
||||
@ -567,7 +570,7 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data)
|
||||
_write(file, "\n");
|
||||
}
|
||||
// Write some terse information on the slicing parameters.
|
||||
const PrintObject *first_object = print.objects.front();
|
||||
const PrintObject *first_object = printable_objects.front();
|
||||
const double layer_height = first_object->config.layer_height.value;
|
||||
const double first_layer_height = first_object->config.first_layer_height.get_abs_value(layer_height);
|
||||
for (size_t region_id = 0; region_id < print.regions.size(); ++ region_id) {
|
||||
@ -596,13 +599,14 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data)
|
||||
size_t initial_print_object_id = 0;
|
||||
bool has_wipe_tower = false;
|
||||
if (print.config.complete_objects.value) {
|
||||
// Find the 1st printing object, find its tool ordering and the initial extruder ID.
|
||||
for (; initial_print_object_id < print.objects.size(); ++initial_print_object_id) {
|
||||
tool_ordering = ToolOrdering(*print.objects[initial_print_object_id], initial_extruder_id);
|
||||
if ((initial_extruder_id = tool_ordering.first_extruder()) != (unsigned int)-1)
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// Find the 1st printing object, find its tool ordering and the initial extruder ID.
|
||||
for (; initial_print_object_id < printable_objects.size(); ++initial_print_object_id) {
|
||||
tool_ordering = ToolOrdering(*printable_objects[initial_print_object_id], initial_extruder_id);
|
||||
if ((initial_extruder_id = tool_ordering.first_extruder()) != (unsigned int)-1)
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Find tool ordering for all the objects at once, and the initial extruder ID.
|
||||
// If the tool ordering has been pre-calculated by Print class for wipe tower already, reuse it.
|
||||
tool_ordering = print.m_tool_ordering.empty() ?
|
||||
@ -676,7 +680,7 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data)
|
||||
// Collect outer contours of all objects over all layers.
|
||||
// Discard objects only containing thin walls (offset would fail on an empty polygon).
|
||||
Polygons islands;
|
||||
for (const PrintObject *object : print.objects)
|
||||
for (const PrintObject *object : printable_objects)
|
||||
for (const Layer *layer : object->layers)
|
||||
for (const ExPolygon &expoly : layer->slices.expolygons)
|
||||
for (const Point © : object->_shifted_copies) {
|
||||
@ -724,7 +728,7 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data)
|
||||
if (print.config.complete_objects.value) {
|
||||
// Print objects from the smallest to the tallest to avoid collisions
|
||||
// when moving onto next object starting point.
|
||||
std::vector<PrintObject*> objects(print.objects);
|
||||
std::vector<PrintObject*> objects(printable_objects);
|
||||
std::sort(objects.begin(), objects.end(), [](const PrintObject* po1, const PrintObject* po2) { return po1->size.z < po2->size.z; });
|
||||
size_t finished_objects = 0;
|
||||
for (size_t object_id = initial_print_object_id; object_id < objects.size(); ++ object_id) {
|
||||
@ -788,7 +792,7 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data)
|
||||
PrintObjectPtrs printable_objects = print.get_printable_objects();
|
||||
for (PrintObject *object : printable_objects)
|
||||
object_reference_points.push_back(object->_shifted_copies.front());
|
||||
Slic3r::Geometry::chained_path(object_reference_points, object_indices);
|
||||
Slic3r::Geometry::chained_path(object_reference_points, object_indices);
|
||||
// Sort layers by Z.
|
||||
// All extrusion moves with the same top layer height are extruded uninterrupted.
|
||||
std::vector<std::pair<coordf_t, std::vector<LayerToPrint>>> layers_to_print = collect_layers_to_print(print);
|
||||
|
@ -451,10 +451,9 @@ float WipingExtrusions::mark_wiping_extrusions(const Print& print, unsigned int
|
||||
return volume_to_wipe; // Soluble filament cannot be wiped in a random infill, neither the filament after it
|
||||
|
||||
// we will sort objects so that dedicated for wiping are at the beginning:
|
||||
PrintObjectPtrs object_list = print.objects;
|
||||
PrintObjectPtrs object_list = print.get_printable_objects();
|
||||
std::sort(object_list.begin(), object_list.end(), [](const PrintObject* a, const PrintObject* b) { return a->config.wipe_into_objects; });
|
||||
|
||||
|
||||
// We will now iterate through
|
||||
// - first the dedicated objects to mark perimeters or infills (depending on infill_first)
|
||||
// - second through the dedicated ones again to mark infills or perimeters (depending on infill_first)
|
||||
@ -548,7 +547,8 @@ void WipingExtrusions::ensure_perimeters_infills_order(const Print& print)
|
||||
unsigned int first_nonsoluble_extruder = first_nonsoluble_extruder_on_layer(print.config);
|
||||
unsigned int last_nonsoluble_extruder = last_nonsoluble_extruder_on_layer(print.config);
|
||||
|
||||
for (const PrintObject* object : print.objects) {
|
||||
PrintObjectPtrs printable_objects = print.get_printable_objects();
|
||||
for (const PrintObject* object : printable_objects) {
|
||||
// Finds this layer:
|
||||
auto this_layer_it = std::find_if(object->layers.begin(), object->layers.end(), [<](const Layer* lay) { return std::abs(lt.print_z - lay->print_z)<EPSILON; });
|
||||
if (this_layer_it == object->layers.end())
|
||||
|
@ -84,6 +84,8 @@ inline T next_highest_power_of_2(T v)
|
||||
return ++ v;
|
||||
}
|
||||
|
||||
extern std::string xml_escape(std::string text);
|
||||
|
||||
class PerlCallback {
|
||||
public:
|
||||
PerlCallback(void *sv) : m_callback(nullptr) { this->register_callback(sv); }
|
||||
|
@ -387,4 +387,31 @@ unsigned get_current_pid()
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string xml_escape(std::string text)
|
||||
{
|
||||
std::string::size_type pos = 0;
|
||||
for (;;)
|
||||
{
|
||||
pos = text.find_first_of("\"\'&<>", pos);
|
||||
if (pos == std::string::npos)
|
||||
break;
|
||||
|
||||
std::string replacement;
|
||||
switch (text[pos])
|
||||
{
|
||||
case '\"': replacement = """; break;
|
||||
case '\'': replacement = "'"; break;
|
||||
case '&': replacement = "&"; break;
|
||||
case '<': replacement = "<"; break;
|
||||
case '>': replacement = ">"; break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
text.replace(pos, 1, replacement);
|
||||
pos += replacement.size();
|
||||
}
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
}; // namespace Slic3r
|
||||
|
@ -1651,7 +1651,7 @@ void _3DScene::update_volumes_selection(wxGLCanvas* canvas, const std::vector<in
|
||||
s_canvas_mgr.update_volumes_selection(canvas, selections);
|
||||
}
|
||||
|
||||
bool _3DScene::check_volumes_outside_state(wxGLCanvas* canvas, const DynamicPrintConfig* config)
|
||||
int _3DScene::check_volumes_outside_state(wxGLCanvas* canvas, const DynamicPrintConfig* config)
|
||||
{
|
||||
return s_canvas_mgr.check_volumes_outside_state(canvas, config);
|
||||
}
|
||||
|
@ -460,7 +460,7 @@ public:
|
||||
static void deselect_volumes(wxGLCanvas* canvas);
|
||||
static void select_volume(wxGLCanvas* canvas, unsigned int id);
|
||||
static void update_volumes_selection(wxGLCanvas* canvas, const std::vector<int>& selections);
|
||||
static bool check_volumes_outside_state(wxGLCanvas* canvas, const DynamicPrintConfig* config);
|
||||
static int check_volumes_outside_state(wxGLCanvas* canvas, const DynamicPrintConfig* config);
|
||||
static bool move_volume_up(wxGLCanvas* canvas, unsigned int id);
|
||||
static bool move_volume_down(wxGLCanvas* canvas, unsigned int id);
|
||||
|
||||
|
@ -1878,9 +1878,11 @@ void GLCanvas3D::update_volumes_selection(const std::vector<int>& selections)
|
||||
}
|
||||
}
|
||||
|
||||
bool GLCanvas3D::check_volumes_outside_state(const DynamicPrintConfig* config) const
|
||||
int GLCanvas3D::check_volumes_outside_state(const DynamicPrintConfig* config) const
|
||||
{
|
||||
return m_volumes.check_outside_state(config, nullptr);
|
||||
ModelInstance::EPrintVolumeState state;
|
||||
m_volumes.check_outside_state(config, &state);
|
||||
return (int)state;
|
||||
}
|
||||
|
||||
bool GLCanvas3D::move_volume_up(unsigned int id)
|
||||
|
@ -495,7 +495,7 @@ public:
|
||||
void deselect_volumes();
|
||||
void select_volume(unsigned int id);
|
||||
void update_volumes_selection(const std::vector<int>& selections);
|
||||
bool check_volumes_outside_state(const DynamicPrintConfig* config) const;
|
||||
int check_volumes_outside_state(const DynamicPrintConfig* config) const;
|
||||
bool move_volume_up(unsigned int id);
|
||||
bool move_volume_down(unsigned int id);
|
||||
|
||||
|
@ -237,7 +237,7 @@ void GLCanvas3DManager::update_volumes_selection(wxGLCanvas* canvas, const std::
|
||||
it->second->update_volumes_selection(selections);
|
||||
}
|
||||
|
||||
bool GLCanvas3DManager::check_volumes_outside_state(wxGLCanvas* canvas, const DynamicPrintConfig* config) const
|
||||
int GLCanvas3DManager::check_volumes_outside_state(wxGLCanvas* canvas, const DynamicPrintConfig* config) const
|
||||
{
|
||||
CanvasesMap::const_iterator it = _get_canvas(canvas);
|
||||
return (it != m_canvases.end()) ? it->second->check_volumes_outside_state(config) : false;
|
||||
|
@ -75,7 +75,7 @@ public:
|
||||
void deselect_volumes(wxGLCanvas* canvas);
|
||||
void select_volume(wxGLCanvas* canvas, unsigned int id);
|
||||
void update_volumes_selection(wxGLCanvas* canvas, const std::vector<int>& selections);
|
||||
bool check_volumes_outside_state(wxGLCanvas* canvas, const DynamicPrintConfig* config) const;
|
||||
int check_volumes_outside_state(wxGLCanvas* canvas, const DynamicPrintConfig* config) const;
|
||||
bool move_volume_up(wxGLCanvas* canvas, unsigned int id);
|
||||
bool move_volume_down(wxGLCanvas* canvas, unsigned int id);
|
||||
|
||||
|
@ -79,7 +79,8 @@ bool GLTexture::load_from_file(const std::string& filename, bool generate_mipmap
|
||||
if (generate_mipmaps)
|
||||
{
|
||||
// we manually generate mipmaps because glGenerateMipmap() function is not reliable on all graphics cards
|
||||
_generate_mipmaps(image);
|
||||
unsigned int levels_count = _generate_mipmaps(image);
|
||||
::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1 + levels_count);
|
||||
::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||
}
|
||||
else
|
||||
@ -149,14 +150,14 @@ void GLTexture::render_texture(unsigned int tex_id, float left, float right, flo
|
||||
::glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
void GLTexture::_generate_mipmaps(wxImage& image)
|
||||
unsigned int GLTexture::_generate_mipmaps(wxImage& image)
|
||||
{
|
||||
int w = image.GetWidth();
|
||||
int h = image.GetHeight();
|
||||
GLint level = 0;
|
||||
std::vector<unsigned char> data(w * h * 4, 0);
|
||||
|
||||
while ((w > 1) && (h > 1))
|
||||
while ((w > 1) || (h > 1))
|
||||
{
|
||||
++level;
|
||||
|
||||
@ -183,6 +184,8 @@ void GLTexture::_generate_mipmaps(wxImage& image)
|
||||
|
||||
::glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, (GLsizei)w, (GLsizei)h, 0, GL_RGBA, GL_UNSIGNED_BYTE, (const void*)data.data());
|
||||
}
|
||||
|
||||
return (unsigned int)level;
|
||||
}
|
||||
|
||||
} // namespace GUI
|
||||
|
@ -32,7 +32,7 @@ namespace GUI {
|
||||
static void render_texture(unsigned int tex_id, float left, float right, float bottom, float top);
|
||||
|
||||
protected:
|
||||
void _generate_mipmaps(wxImage& image);
|
||||
unsigned int _generate_mipmaps(wxImage& image);
|
||||
};
|
||||
|
||||
} // namespace GUI
|
||||
|
@ -230,7 +230,7 @@ update_volumes_selection(canvas, selections)
|
||||
CODE:
|
||||
_3DScene::update_volumes_selection((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), selections);
|
||||
|
||||
bool
|
||||
int
|
||||
check_volumes_outside_state(canvas, config)
|
||||
SV *canvas;
|
||||
DynamicPrintConfig *config;
|
||||
|
Loading…
Reference in New Issue
Block a user