Merge remote-tracking branch 'origin' into ys_printable_property

This commit is contained in:
YuSanka 2019-08-06 10:31:17 +02:00
commit 0520da3241
16 changed files with 2709 additions and 2039 deletions

View file

@ -375,7 +375,7 @@ public:
this->values[i] = rhs_vec->values[i];
modified = true;
}
return false;
return modified;
}
private:

View file

@ -579,11 +579,11 @@ void GCode::do_export(Print *print, const char *path, GCodePreviewData *preview_
}
if (print->config().remaining_times.value) {
BOOST_LOG_TRIVIAL(debug) << "Processing remaining times for normal mode";
BOOST_LOG_TRIVIAL(debug) << "Processing remaining times for normal mode" << log_memory_info();
m_normal_time_estimator.post_process_remaining_times(path_tmp, 60.0f);
m_normal_time_estimator.reset();
if (m_silent_time_estimator_enabled) {
BOOST_LOG_TRIVIAL(debug) << "Processing remaining times for silent mode";
BOOST_LOG_TRIVIAL(debug) << "Processing remaining times for silent mode" << log_memory_info();
m_silent_time_estimator.post_process_remaining_times(path_tmp, 60.0f);
m_silent_time_estimator.reset();
}
@ -591,7 +591,7 @@ void GCode::do_export(Print *print, const char *path, GCodePreviewData *preview_
// starts analyzer calculations
if (m_enable_analyzer) {
BOOST_LOG_TRIVIAL(debug) << "Preparing G-code preview data";
BOOST_LOG_TRIVIAL(debug) << "Preparing G-code preview data" << log_memory_info();
m_analyzer.calc_gcode_preview_data(*preview_data, [print]() { print->throw_if_canceled(); });
m_analyzer.reset();
}
@ -1838,7 +1838,8 @@ void GCode::process_layer(
", time estimator memory: " <<
format_memsize_MB(m_normal_time_estimator.memory_used() + m_silent_time_estimator_enabled ? m_silent_time_estimator.memory_used() : 0) <<
", analyzer memory: " <<
format_memsize_MB(m_analyzer.memory_used());
format_memsize_MB(m_analyzer.memory_used()) <<
log_memory_info();
}
void GCode::apply_print_config(const PrintConfig &print_config)

View file

@ -21,8 +21,6 @@
namespace Slic3r {
unsigned int Model::s_auto_extruder_id = 1;
Model& Model::assign_copy(const Model &rhs)
{
this->copy_id(rhs);
@ -485,9 +483,20 @@ bool Model::looks_like_multipart_object() const
return false;
}
// Generate next extruder ID string, in the range of (1, max_extruders).
static inline std::string auto_extruder_id(unsigned int max_extruders, unsigned int &cntr)
{
char str_extruder[64];
sprintf(str_extruder, "%ud", cntr + 1);
if (++ cntr == max_extruders)
cntr = 0;
return str_extruder;
}
void Model::convert_multipart_object(unsigned int max_extruders)
{
if (this->objects.empty())
assert(this->objects.size() >= 2);
if (this->objects.size() < 2)
return;
ModelObject* object = new ModelObject(this);
@ -495,58 +504,32 @@ void Model::convert_multipart_object(unsigned int max_extruders)
object->name = this->objects.front()->name;
//FIXME copy the config etc?
reset_auto_extruder_id();
bool is_single_object = (this->objects.size() == 1);
for (const ModelObject* o : this->objects)
{
for (const ModelVolume* v : o->volumes)
{
if (is_single_object)
{
// If there is only one object, just copy the volumes
ModelVolume* new_v = object->add_volume(*v);
if (new_v != nullptr)
{
new_v->name = o->name;
new_v->config.set_deserialize("extruder", get_auto_extruder_id_as_string(max_extruders));
new_v->translate(-o->origin_translation);
}
}
else
{
// If there are more than one object, put all volumes together
// Each object may contain any number of volumes and instances
// The volumes transformations are relative to the object containing them...
int counter = 1;
for (const ModelInstance* i : o->instances)
{
ModelVolume* new_v = object->add_volume(*v);
if (new_v != nullptr)
{
new_v->name = o->name + "_" + std::to_string(counter++);
new_v->config.set_deserialize("extruder", get_auto_extruder_id_as_string(max_extruders));
new_v->translate(-o->origin_translation);
// ...so, transform everything to a common reference system (world)
new_v->set_transformation(i->get_transformation() * v->get_transformation());
}
}
unsigned int extruder_counter = 0;
for (const ModelObject* o : this->objects)
for (const ModelVolume* v : o->volumes) {
// If there are more than one object, put all volumes together
// Each object may contain any number of volumes and instances
// The volumes transformations are relative to the object containing them...
Geometry::Transformation trafo_volume = v->get_transformation();
// Revert the centering operation.
trafo_volume.set_offset(trafo_volume.get_offset() - o->origin_translation);
int counter = 1;
auto copy_volume = [o, max_extruders, &counter, &extruder_counter](ModelVolume *new_v) {
assert(new_v != nullptr);
new_v->name = o->name + "_" + std::to_string(counter++);
new_v->config.set_deserialize("extruder", auto_extruder_id(max_extruders, extruder_counter));
return new_v;
};
if (o->instances.empty()) {
copy_volume(object->add_volume(*v))->set_transformation(trafo_volume);
} else {
for (const ModelInstance* i : o->instances)
// ...so, transform everything to a common reference system (world)
copy_volume(object->add_volume(*v))->set_transformation(i->get_transformation() * trafo_volume);
}
}
}
if (is_single_object)
{
// If there is only one object, keep its instances
for (const ModelInstance* i : this->objects.front()->instances)
{
object->add_instance(*i);
}
}
else
// If there are more than one object, create a single instance
object->add_instance();
// If there are more than one object, create a single instance
object->add_instance();
this->clear_objects();
this->objects.push_back(object);
@ -571,32 +554,6 @@ void Model::adjust_min_z()
}
}
unsigned int Model::get_auto_extruder_id(unsigned int max_extruders)
{
unsigned int id = s_auto_extruder_id;
if (id > max_extruders) {
// The current counter is invalid, likely due to switching the printer profiles
// to a profile with a lower number of extruders.
reset_auto_extruder_id();
id = s_auto_extruder_id;
} else if (++ s_auto_extruder_id > max_extruders) {
reset_auto_extruder_id();
}
return id;
}
std::string Model::get_auto_extruder_id_as_string(unsigned int max_extruders)
{
char str_extruder[64];
sprintf(str_extruder, "%ud", get_auto_extruder_id(max_extruders));
return str_extruder;
}
void Model::reset_auto_extruder_id()
{
s_auto_extruder_id = 1;
}
// Propose a filename including path derived from the ModelObject's input path.
// If object's name is filled in, use the object name, otherwise use the input name.
std::string Model::propose_export_file_name_and_path() const
@ -1662,7 +1619,7 @@ size_t ModelVolume::split(unsigned int max_extruders)
size_t ivolume = std::find(this->object->volumes.begin(), this->object->volumes.end(), this) - this->object->volumes.begin();
std::string name = this->name;
Model::reset_auto_extruder_id();
unsigned int extruder_counter = 0;
Vec3d offset = this->get_offset();
for (TriangleMesh *mesh : meshptrs) {
@ -1681,7 +1638,7 @@ size_t ModelVolume::split(unsigned int max_extruders)
this->object->volumes[ivolume]->center_geometry_after_creation();
this->object->volumes[ivolume]->translate(offset);
this->object->volumes[ivolume]->name = name + "_" + std::to_string(idx + 1);
this->object->volumes[ivolume]->config.set_deserialize("extruder", Model::get_auto_extruder_id_as_string(max_extruders));
this->object->volumes[ivolume]->config.set_deserialize("extruder", auto_extruder_id(max_extruders, extruder_counter));
delete mesh;
++ idx;
}

View file

@ -725,8 +725,6 @@ private:
// all objects may share mutliple materials.
class Model final : public ObjectBase
{
static unsigned int s_auto_extruder_id;
public:
// Materials are owned by a model and referenced by objects through t_model_material_id.
// Single material may be shared by multiple models.
@ -795,14 +793,10 @@ public:
void print_info() const { for (const ModelObject *o : this->objects) o->print_info(); }
static unsigned int get_auto_extruder_id(unsigned int max_extruders);
static std::string get_auto_extruder_id_as_string(unsigned int max_extruders);
static void reset_auto_extruder_id();
// Propose an output file name & path based on the first printable object's name and source input file's path.
std::string propose_export_file_name_and_path() const;
std::string propose_export_file_name_and_path() const;
// Propose an output path, replace extension. The new_extension shall contain the initial dot.
std::string propose_export_file_name_and_path(const std::string &new_extension) const;
std::string propose_export_file_name_and_path(const std::string &new_extension) const;
private:
explicit Model(int) : ObjectBase(-1) { assert(this->id().invalid()); };

View file

@ -18,8 +18,9 @@ extern void trace(unsigned int level, const char *message);
// Format memory allocated, separate thousands by comma.
extern std::string format_memsize_MB(size_t n);
// Return string to be added to the boost::log output to inform about the current process memory allocation.
// The string is non-empty only if the loglevel >= info (3).
extern std::string log_memory_info();
// The string is non-empty if the loglevel >= info (3) or ignore_loglevel==true.
// Latter is used to get the memory info from SysInfoDialog.
extern std::string log_memory_info(bool ignore_loglevel = false);
extern void disable_multi_threading();
// Returns the size of physical memory (RAM) in bytes.
extern size_t total_physical_memory();

View file

@ -13,9 +13,13 @@
#include <unistd.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/resource.h>
#ifdef BSD
#include <sys/sysctl.h>
#endif
#ifdef __APPLE__
#include <mach/mach.h>
#endif
#endif
#include <boost/log/core.hpp>
@ -431,47 +435,82 @@ std::string format_memsize_MB(size_t n)
return out + "MB";
}
#ifdef WIN32
#ifndef PROCESS_MEMORY_COUNTERS_EX
// MingW32 doesn't have this struct in psapi.h
typedef struct _PROCESS_MEMORY_COUNTERS_EX {
DWORD cb;
DWORD PageFaultCount;
SIZE_T PeakWorkingSetSize;
SIZE_T WorkingSetSize;
SIZE_T QuotaPeakPagedPoolUsage;
SIZE_T QuotaPagedPoolUsage;
SIZE_T QuotaPeakNonPagedPoolUsage;
SIZE_T QuotaNonPagedPoolUsage;
SIZE_T PagefileUsage;
SIZE_T PeakPagefileUsage;
SIZE_T PrivateUsage;
} PROCESS_MEMORY_COUNTERS_EX, *PPROCESS_MEMORY_COUNTERS_EX;
#endif /* PROCESS_MEMORY_COUNTERS_EX */
std::string log_memory_info()
// Returns platform-specific string to be used as log output or parsed in SysInfoDialog.
// The latter parses the string with (semi)colons as separators, it should look about as
// "desc1: value1; desc2: value2" or similar (spaces should not matter).
std::string log_memory_info(bool ignore_loglevel)
{
std::string out;
if (logSeverity <= boost::log::trivial::info) {
if (ignore_loglevel || logSeverity <= boost::log::trivial::info) {
#ifdef WIN32
#ifndef PROCESS_MEMORY_COUNTERS_EX
// MingW32 doesn't have this struct in psapi.h
typedef struct _PROCESS_MEMORY_COUNTERS_EX {
DWORD cb;
DWORD PageFaultCount;
SIZE_T PeakWorkingSetSize;
SIZE_T WorkingSetSize;
SIZE_T QuotaPeakPagedPoolUsage;
SIZE_T QuotaPagedPoolUsage;
SIZE_T QuotaPeakNonPagedPoolUsage;
SIZE_T QuotaNonPagedPoolUsage;
SIZE_T PagefileUsage;
SIZE_T PeakPagefileUsage;
SIZE_T PrivateUsage;
} PROCESS_MEMORY_COUNTERS_EX, *PPROCESS_MEMORY_COUNTERS_EX;
#endif /* PROCESS_MEMORY_COUNTERS_EX */
HANDLE hProcess = ::OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, ::GetCurrentProcessId());
if (hProcess != nullptr) {
PROCESS_MEMORY_COUNTERS_EX pmc;
if (GetProcessMemoryInfo(hProcess, (PROCESS_MEMORY_COUNTERS*)&pmc, sizeof(pmc)))
out = " WorkingSet: " + format_memsize_MB(pmc.WorkingSetSize) + " PrivateBytes: " + format_memsize_MB(pmc.PrivateUsage) + " Pagefile(peak): " + format_memsize_MB(pmc.PagefileUsage) + "(" + format_memsize_MB(pmc.PeakPagefileUsage) + ")";
out = " WorkingSet: " + format_memsize_MB(pmc.WorkingSetSize) + "; PrivateBytes: " + format_memsize_MB(pmc.PrivateUsage) + "; Pagefile(peak): " + format_memsize_MB(pmc.PagefileUsage) + "(" + format_memsize_MB(pmc.PeakPagefileUsage) + ")";
else
out += " Used memory: N/A";
CloseHandle(hProcess);
}
#elif defined(__linux__) or defined(__APPLE__)
// Get current memory usage.
#ifdef __APPLE__
struct mach_task_basic_info info;
mach_msg_type_number_t infoCount = MACH_TASK_BASIC_INFO_COUNT;
out += " Resident memory: ";
if ( task_info( mach_task_self( ), MACH_TASK_BASIC_INFO, (task_info_t)&info, &infoCount ) == KERN_SUCCESS )
out += format_memsize_MB((size_t)info.resident_size);
else
out += "N/A";
#else // i.e. __linux__
size_t tSize = 0, resident = 0, share = 0;
std::ifstream buffer("/proc/self/statm");
if (buffer && (buffer >> tSize >> resident >> share)) {
size_t page_size = (size_t)sysconf(_SC_PAGE_SIZE); // in case x86-64 is configured to use 2MB pages
size_t rss = resident * page_size;
out += " Resident memory: " + format_memsize_MB(rss);
out += "; Shared memory: " + format_memsize_MB(share * page_size);
out += "; Private memory: " + format_memsize_MB(rss - share * page_size);
}
else
out += " Used memory: N/A";
#endif
// Now get peak memory usage.
out += "; Peak memory usage: ";
rusage memory_info;
if (getrusage(RUSAGE_SELF, &memory_info) == 0)
{
size_t peak_mem_usage = (size_t)memory_info.ru_maxrss;
#ifdef __linux__
peak_mem_usage *= 1024;// getrusage returns the value in kB on linux
#endif
out += format_memsize_MB(peak_mem_usage);
}
else
out += "N/A";
#endif
}
return out;
}
#else
std::string log_memory_info()
{
return std::string();
}
#endif
// Returns the size of physical memory (RAM) in bytes.
// http://nadeausoftware.com/articles/2012/09/c_c_tip_how_get_physical_memory_size_system
size_t total_physical_memory()