Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/prusa3d/PrusaSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/libslic3r/GCode/PreviewData.cpp')
-rw-r--r--src/libslic3r/GCode/PreviewData.cpp456
1 files changed, 456 insertions, 0 deletions
diff --git a/src/libslic3r/GCode/PreviewData.cpp b/src/libslic3r/GCode/PreviewData.cpp
new file mode 100644
index 000000000..9cf9716e0
--- /dev/null
+++ b/src/libslic3r/GCode/PreviewData.cpp
@@ -0,0 +1,456 @@
+#include "Analyzer.hpp"
+#include "PreviewData.hpp"
+#include <float.h>
+#include <wx/intl.h>
+#include <I18N.hpp>
+
+#include <boost/format.hpp>
+
+//! macro used to mark string used at localization,
+#define L(s) (s)
+
+namespace Slic3r {
+
+const GCodePreviewData::Color GCodePreviewData::Color::Dummy(0.0f, 0.0f, 0.0f, 0.0f);
+
+GCodePreviewData::Color::Color()
+{
+ rgba[0] = 1.0f;
+ rgba[1] = 1.0f;
+ rgba[2] = 1.0f;
+ rgba[3] = 1.0f;
+}
+
+GCodePreviewData::Color::Color(float r, float g, float b, float a)
+{
+ rgba[0] = r;
+ rgba[1] = g;
+ rgba[2] = b;
+ rgba[3] = a;
+}
+
+std::vector<unsigned char> GCodePreviewData::Color::as_bytes() const
+{
+ std::vector<unsigned char> ret;
+ for (unsigned int i = 0; i < 4; ++i)
+ {
+ ret.push_back((unsigned char)(255.0f * rgba[i]));
+ }
+ return ret;
+}
+
+GCodePreviewData::Extrusion::Layer::Layer(float z, const ExtrusionPaths& paths)
+ : z(z)
+ , paths(paths)
+{
+}
+
+GCodePreviewData::Travel::Polyline::Polyline(EType type, EDirection direction, float feedrate, unsigned int extruder_id, const Polyline3& polyline)
+ : type(type)
+ , direction(direction)
+ , feedrate(feedrate)
+ , extruder_id(extruder_id)
+ , polyline(polyline)
+{
+}
+
+const GCodePreviewData::Color GCodePreviewData::Range::Default_Colors[Colors_Count] =
+{
+ Color(0.043f, 0.173f, 0.478f, 1.0f),
+ Color(0.075f, 0.349f, 0.522f, 1.0f),
+ Color(0.110f, 0.533f, 0.569f, 1.0f),
+ Color(0.016f, 0.839f, 0.059f, 1.0f),
+ Color(0.667f, 0.949f, 0.000f, 1.0f),
+ Color(0.988f, 0.975f, 0.012f, 1.0f),
+ Color(0.961f, 0.808f, 0.039f, 1.0f),
+ Color(0.890f, 0.533f, 0.125f, 1.0f),
+ Color(0.820f, 0.408f, 0.188f, 1.0f),
+ Color(0.761f, 0.322f, 0.235f, 1.0f)
+};
+
+GCodePreviewData::Range::Range()
+{
+ reset();
+}
+
+void GCodePreviewData::Range::reset()
+{
+ min = FLT_MAX;
+ max = -FLT_MAX;
+}
+
+bool GCodePreviewData::Range::empty() const
+{
+ return min == max;
+}
+
+void GCodePreviewData::Range::update_from(float value)
+{
+ min = std::min(min, value);
+ max = std::max(max, value);
+}
+
+void GCodePreviewData::Range::update_from(const Range& other)
+{
+ min = std::min(min, other.min);
+ max = std::max(max, other.max);
+}
+
+void GCodePreviewData::Range::set_from(const Range& other)
+{
+ min = other.min;
+ max = other.max;
+}
+
+float GCodePreviewData::Range::step_size() const
+{
+ return (max - min) / (float)(Colors_Count - 1);
+}
+
+GCodePreviewData::Color GCodePreviewData::Range::get_color_at(float value) const
+{
+ if (empty())
+ return Color::Dummy;
+
+ float global_t = (value - min) / step_size();
+
+ unsigned int low = (unsigned int)global_t;
+ unsigned int high = clamp((unsigned int)0, Colors_Count - 1, low + 1);
+
+ Color color_low = colors[low];
+ Color color_high = colors[high];
+
+ float local_t = global_t - (float)low;
+
+ // interpolate in RGB space
+ Color ret;
+ for (unsigned int i = 0; i < 4; ++i)
+ {
+ ret.rgba[i] = lerp(color_low.rgba[i], color_high.rgba[i], local_t);
+ }
+ return ret;
+}
+
+GCodePreviewData::LegendItem::LegendItem(const std::string& text, const GCodePreviewData::Color& color)
+ : text(text)
+ , color(color)
+{
+}
+
+const GCodePreviewData::Color GCodePreviewData::Extrusion::Default_Extrusion_Role_Colors[Num_Extrusion_Roles] =
+{
+ Color(0.0f, 0.0f, 0.0f, 1.0f), // erNone
+ Color(1.0f, 0.0f, 0.0f, 1.0f), // erPerimeter
+ Color(0.0f, 1.0f, 0.0f, 1.0f), // erExternalPerimeter
+ Color(0.0f, 0.0f, 1.0f, 1.0f), // erOverhangPerimeter
+ Color(1.0f, 1.0f, 0.0f, 1.0f), // erInternalInfill
+ Color(1.0f, 0.0f, 1.0f, 1.0f), // erSolidInfill
+ Color(0.0f, 1.0f, 1.0f, 1.0f), // erTopSolidInfill
+ Color(0.5f, 0.5f, 0.5f, 1.0f), // erBridgeInfill
+ Color(1.0f, 1.0f, 1.0f, 1.0f), // erGapFill
+ Color(0.5f, 0.0f, 0.0f, 1.0f), // erSkirt
+ Color(0.0f, 0.5f, 0.0f, 1.0f), // erSupportMaterial
+ Color(0.0f, 0.0f, 0.5f, 1.0f), // erSupportMaterialInterface
+ Color(0.7f, 0.89f, 0.67f, 1.0f), // erWipeTower
+ Color(1.0f, 1.0f, 0.0f, 1.0f), // erCustom
+ Color(0.0f, 0.0f, 0.0f, 1.0f) // erMixed
+};
+
+// todo: merge with Slic3r::ExtrusionRole2String() from GCode.cpp
+const std::string GCodePreviewData::Extrusion::Default_Extrusion_Role_Names[Num_Extrusion_Roles]
+{
+ L("None"),
+ L("Perimeter"),
+ L("External perimeter"),
+ L("Overhang perimeter"),
+ L("Internal infill"),
+ L("Solid infill"),
+ L("Top solid infill"),
+ L("Bridge infill"),
+ L("Gap fill"),
+ L("Skirt"),
+ L("Support material"),
+ L("Support material interface"),
+ L("Wipe tower"),
+ L("Custom"),
+ L("Mixed")
+};
+
+const GCodePreviewData::Extrusion::EViewType GCodePreviewData::Extrusion::Default_View_Type = GCodePreviewData::Extrusion::FeatureType;
+
+void GCodePreviewData::Extrusion::set_default()
+{
+ view_type = Default_View_Type;
+
+ ::memcpy((void*)role_colors, (const void*)Default_Extrusion_Role_Colors, Num_Extrusion_Roles * sizeof(Color));
+
+ for (unsigned int i = 0; i < Num_Extrusion_Roles; ++i)
+ {
+ role_names[i] = Default_Extrusion_Role_Names[i];
+ }
+
+ role_flags = 0;
+ for (unsigned int i = 0; i < Num_Extrusion_Roles; ++i)
+ {
+ role_flags |= 1 << i;
+ }
+}
+
+bool GCodePreviewData::Extrusion::is_role_flag_set(ExtrusionRole role) const
+{
+ return is_role_flag_set(role_flags, role);
+}
+
+bool GCodePreviewData::Extrusion::is_role_flag_set(unsigned int flags, ExtrusionRole role)
+{
+ return GCodeAnalyzer::is_valid_extrusion_role(role) && (flags & (1 << (role - erPerimeter))) != 0;
+}
+
+const float GCodePreviewData::Travel::Default_Width = 0.075f;
+const float GCodePreviewData::Travel::Default_Height = 0.075f;
+const GCodePreviewData::Color GCodePreviewData::Travel::Default_Type_Colors[Num_Types] =
+{
+ Color(0.0f, 0.0f, 0.75f, 1.0f), // Move
+ Color(0.0f, 0.75f, 0.0f, 1.0f), // Extrude
+ Color(0.75f, 0.0f, 0.0f, 1.0f), // Retract
+};
+
+void GCodePreviewData::Travel::set_default()
+{
+ width = Default_Width;
+ height = Default_Height;
+ ::memcpy((void*)type_colors, (const void*)Default_Type_Colors, Num_Types * sizeof(Color));
+
+ is_visible = false;
+}
+
+const GCodePreviewData::Color GCodePreviewData::Retraction::Default_Color = GCodePreviewData::Color(1.0f, 1.0f, 1.0f, 1.0f);
+
+GCodePreviewData::Retraction::Position::Position(const Vec3crd& position, float width, float height)
+ : position(position)
+ , width(width)
+ , height(height)
+{
+}
+
+void GCodePreviewData::Retraction::set_default()
+{
+ color = Default_Color;
+ is_visible = false;
+}
+
+void GCodePreviewData::Shell::set_default()
+{
+ is_visible = false;
+}
+
+GCodePreviewData::GCodePreviewData()
+{
+ set_default();
+}
+
+void GCodePreviewData::set_default()
+{
+ ::memcpy((void*)ranges.height.colors, (const void*)Range::Default_Colors, Range::Colors_Count * sizeof(Color));
+ ::memcpy((void*)ranges.width.colors, (const void*)Range::Default_Colors, Range::Colors_Count * sizeof(Color));
+ ::memcpy((void*)ranges.feedrate.colors, (const void*)Range::Default_Colors, Range::Colors_Count * sizeof(Color));
+ ::memcpy((void*)ranges.volumetric_rate.colors, (const void*)Range::Default_Colors, Range::Colors_Count * sizeof(Color));
+
+ extrusion.set_default();
+ travel.set_default();
+ retraction.set_default();
+ unretraction.set_default();
+ shell.set_default();
+}
+
+void GCodePreviewData::reset()
+{
+ ranges.width.reset();
+ ranges.height.reset();
+ ranges.feedrate.reset();
+ ranges.volumetric_rate.reset();
+ extrusion.layers.clear();
+ travel.polylines.clear();
+ retraction.positions.clear();
+ unretraction.positions.clear();
+}
+
+bool GCodePreviewData::empty() const
+{
+ return extrusion.layers.empty() && travel.polylines.empty() && retraction.positions.empty() && unretraction.positions.empty();
+}
+
+GCodePreviewData::Color GCodePreviewData::get_extrusion_role_color(ExtrusionRole role) const
+{
+ return extrusion.role_colors[role];
+}
+
+GCodePreviewData::Color GCodePreviewData::get_height_color(float height) const
+{
+ return ranges.height.get_color_at(height);
+}
+
+GCodePreviewData::Color GCodePreviewData::get_width_color(float width) const
+{
+ return ranges.width.get_color_at(width);
+}
+
+GCodePreviewData::Color GCodePreviewData::get_feedrate_color(float feedrate) const
+{
+ return ranges.feedrate.get_color_at(feedrate);
+}
+
+GCodePreviewData::Color GCodePreviewData::get_volumetric_rate_color(float rate) const
+{
+ return ranges.volumetric_rate.get_color_at(rate);
+}
+
+void GCodePreviewData::set_extrusion_role_color(const std::string& role_name, float red, float green, float blue, float alpha)
+{
+ for (unsigned int i = 0; i < Extrusion::Num_Extrusion_Roles; ++i)
+ {
+ if (role_name == extrusion.role_names[i])
+ {
+ extrusion.role_colors[i] = Color(red, green, blue, alpha);
+ break;
+ }
+ }
+}
+
+void GCodePreviewData::set_extrusion_paths_colors(const std::vector<std::string>& colors)
+{
+ unsigned int size = (unsigned int)colors.size();
+
+ if (size % 2 != 0)
+ return;
+
+ for (unsigned int i = 0; i < size; i += 2)
+ {
+ const std::string& color_str = colors[i + 1];
+
+ if (color_str.size() == 6)
+ {
+ bool valid = true;
+ for (int c = 0; c < 6; ++c)
+ {
+ if (::isxdigit(color_str[c]) == 0)
+ {
+ valid = false;
+ break;
+ }
+ }
+
+ if (valid)
+ {
+ unsigned int color;
+ std::stringstream ss;
+ ss << std::hex << color_str;
+ ss >> color;
+
+ float den = 1.0f / 255.0f;
+
+ float r = (float)((color & 0xFF0000) >> 16) * den;
+ float g = (float)((color & 0x00FF00) >> 8) * den;
+ float b = (float)(color & 0x0000FF) * den;
+
+ this->set_extrusion_role_color(colors[i], r, g, b, 1.0f);
+ }
+ }
+ }
+}
+
+std::string GCodePreviewData::get_legend_title() const
+{
+ switch (extrusion.view_type)
+ {
+ case Extrusion::FeatureType:
+ return L("Feature type");
+ case Extrusion::Height:
+ return L("Height (mm)");
+ case Extrusion::Width:
+ return L("Width (mm)");
+ case Extrusion::Feedrate:
+ return L("Speed (mm/s)");
+ case Extrusion::VolumetricRate:
+ return L("Volumetric flow rate (mm3/s)");
+ case Extrusion::Tool:
+ return L("Tool");
+ }
+
+ return "";
+}
+
+GCodePreviewData::LegendItemsList GCodePreviewData::get_legend_items(const std::vector<float>& tool_colors) const
+{
+ struct Helper
+ {
+ static void FillListFromRange(LegendItemsList& list, const Range& range, unsigned int decimals, float scale_factor)
+ {
+ list.reserve(Range::Colors_Count);
+
+ float step = range.step_size();
+ for (int i = Range::Colors_Count - 1; i >= 0; --i)
+ {
+ char buf[1024];
+ sprintf(buf, "%.*f", decimals, scale_factor * (range.min + (float)i * step));
+ list.emplace_back(buf, range.colors[i]);
+ }
+ }
+ };
+
+ LegendItemsList items;
+
+ switch (extrusion.view_type)
+ {
+ case Extrusion::FeatureType:
+ {
+ ExtrusionRole first_valid = erPerimeter;
+ ExtrusionRole last_valid = erCustom;
+
+ items.reserve(last_valid - first_valid + 1);
+ for (unsigned int i = (unsigned int)first_valid; i <= (unsigned int)last_valid; ++i)
+ {
+ items.emplace_back(Slic3r::I18N::translate(extrusion.role_names[i]), extrusion.role_colors[i]);
+ }
+
+ break;
+ }
+ case Extrusion::Height:
+ {
+ Helper::FillListFromRange(items, ranges.height, 3, 1.0f);
+ break;
+ }
+ case Extrusion::Width:
+ {
+ Helper::FillListFromRange(items, ranges.width, 3, 1.0f);
+ break;
+ }
+ case Extrusion::Feedrate:
+ {
+ Helper::FillListFromRange(items, ranges.feedrate, 1, 1.0f);
+ break;
+ }
+ case Extrusion::VolumetricRate:
+ {
+ Helper::FillListFromRange(items, ranges.volumetric_rate, 3, 1.0f);
+ break;
+ }
+ case Extrusion::Tool:
+ {
+ unsigned int tools_colors_count = tool_colors.size() / 4;
+ items.reserve(tools_colors_count);
+ for (unsigned int i = 0; i < tools_colors_count; ++i)
+ {
+ GCodePreviewData::Color color;
+ ::memcpy((void*)color.rgba, (const void*)(tool_colors.data() + i * 4), 4 * sizeof(float));
+ items.emplace_back((boost::format(Slic3r::I18N::translate(L("Extruder %d"))) % (i + 1)).str(), color);
+ }
+
+ break;
+ }
+ }
+
+ return items;
+}
+
+} // namespace Slic3r