Merge branch 'master' of https://github.com/prusa3d/Slic3r
This commit is contained in:
commit
debbca0f14
23 changed files with 219 additions and 109 deletions
|
@ -46,7 +46,18 @@ endif()
|
||||||
add_subdirectory(libslic3r)
|
add_subdirectory(libslic3r)
|
||||||
|
|
||||||
if (SLIC3R_GUI)
|
if (SLIC3R_GUI)
|
||||||
|
if(WIN32)
|
||||||
message(STATUS "WXWIN environment set to: $ENV{WXWIN}")
|
message(STATUS "WXWIN environment set to: $ENV{WXWIN}")
|
||||||
|
elseif(UNIX)
|
||||||
|
message(STATUS "wx-config path: ${wxWidgets_CONFIG_EXECUTABLE}")
|
||||||
|
set(wxWidgets_USE_UNICODE ON)
|
||||||
|
if(SLIC3R_STATIC)
|
||||||
|
set(wxWidgets_USE_STATIC ON)
|
||||||
|
else()
|
||||||
|
set(wxWidgets_USE_STATIC OFF)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
find_package(wxWidgets REQUIRED COMPONENTS base core adv html gl)
|
find_package(wxWidgets REQUIRED COMPONENTS base core adv html gl)
|
||||||
include(${wxWidgets_USE_FILE})
|
include(${wxWidgets_USE_FILE})
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -68,7 +68,7 @@ if(TBB_FOUND)
|
||||||
target_compile_definitions(libnest2d INTERFACE -D__TBB_NO_IMPLICIT_LINKAGE)
|
target_compile_definitions(libnest2d INTERFACE -D__TBB_NO_IMPLICIT_LINKAGE)
|
||||||
endif()
|
endif()
|
||||||
# The Intel TBB library will use the std::exception_ptr feature of C++11.
|
# The Intel TBB library will use the std::exception_ptr feature of C++11.
|
||||||
target_compile_definitions(libnest2d INTERFACE -DTBB_USE_CAPTURED_EXCEPTION=1)
|
target_compile_definitions(libnest2d INTERFACE -DTBB_USE_CAPTURED_EXCEPTION=0)
|
||||||
|
|
||||||
target_link_libraries(libnest2d INTERFACE tbb)
|
target_link_libraries(libnest2d INTERFACE tbb)
|
||||||
else()
|
else()
|
||||||
|
|
|
@ -505,8 +505,9 @@ WipeTower::ToolChangeResult WipeTowerPrusaMM::prime(
|
||||||
.speed_override(100);
|
.speed_override(100);
|
||||||
|
|
||||||
writer.set_initial_position(xy(0.f, 0.f)) // Always move to the starting position
|
writer.set_initial_position(xy(0.f, 0.f)) // Always move to the starting position
|
||||||
.travel(cleaning_box.ld, 7200)
|
.travel(cleaning_box.ld, 7200);
|
||||||
.set_extruder_trimpot(750); // Increase the extruder driver current to allow fast ramming.
|
if (m_set_extruder_trimpot)
|
||||||
|
writer.set_extruder_trimpot(750); // Increase the extruder driver current to allow fast ramming.
|
||||||
|
|
||||||
for (size_t idx_tool = 0; idx_tool < tools.size(); ++ idx_tool) {
|
for (size_t idx_tool = 0; idx_tool < tools.size(); ++ idx_tool) {
|
||||||
unsigned int tool = tools[idx_tool];
|
unsigned int tool = tools[idx_tool];
|
||||||
|
@ -533,8 +534,9 @@ WipeTower::ToolChangeResult WipeTowerPrusaMM::prime(
|
||||||
// in the output gcode - we should not remember emitting them (we will output them twice in the worst case)
|
// in the output gcode - we should not remember emitting them (we will output them twice in the worst case)
|
||||||
|
|
||||||
// Reset the extruder current to a normal value.
|
// Reset the extruder current to a normal value.
|
||||||
writer.set_extruder_trimpot(550)
|
if (m_set_extruder_trimpot)
|
||||||
.feedrate(6000)
|
writer.set_extruder_trimpot(550);
|
||||||
|
writer.feedrate(6000)
|
||||||
.flush_planner_queue()
|
.flush_planner_queue()
|
||||||
.reset_extruder()
|
.reset_extruder()
|
||||||
.append("; CP PRIMING END\n"
|
.append("; CP PRIMING END\n"
|
||||||
|
@ -607,7 +609,8 @@ WipeTower::ToolChangeResult WipeTowerPrusaMM::tool_change(unsigned int tool, boo
|
||||||
writer.set_initial_position(initial_position, m_wipe_tower_width, m_wipe_tower_depth, m_internal_rotation);
|
writer.set_initial_position(initial_position, m_wipe_tower_width, m_wipe_tower_depth, m_internal_rotation);
|
||||||
|
|
||||||
// Increase the extruder driver current to allow fast ramming.
|
// Increase the extruder driver current to allow fast ramming.
|
||||||
writer.set_extruder_trimpot(750);
|
if (m_set_extruder_trimpot)
|
||||||
|
writer.set_extruder_trimpot(550);
|
||||||
|
|
||||||
// Ram the hot material out of the melt zone, retract the filament into the cooling tubes and let it cool.
|
// Ram the hot material out of the melt zone, retract the filament into the cooling tubes and let it cool.
|
||||||
if (tool != (unsigned int)-1){ // This is not the last change.
|
if (tool != (unsigned int)-1){ // This is not the last change.
|
||||||
|
@ -635,8 +638,9 @@ WipeTower::ToolChangeResult WipeTowerPrusaMM::tool_change(unsigned int tool, boo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
writer.set_extruder_trimpot(550) // Reset the extruder current to a normal value.
|
if (m_set_extruder_trimpot)
|
||||||
.feedrate(6000)
|
writer.set_extruder_trimpot(550); // Reset the extruder current to a normal value.
|
||||||
|
writer.feedrate(6000)
|
||||||
.flush_planner_queue()
|
.flush_planner_queue()
|
||||||
.reset_extruder()
|
.reset_extruder()
|
||||||
.append("; CP TOOLCHANGE END\n"
|
.append("; CP TOOLCHANGE END\n"
|
||||||
|
@ -916,12 +920,10 @@ void WipeTowerPrusaMM::toolchange_Load(
|
||||||
.resume_preview();
|
.resume_preview();
|
||||||
|
|
||||||
// Reset the extruder current to the normal value.
|
// Reset the extruder current to the normal value.
|
||||||
|
if (m_set_extruder_trimpot)
|
||||||
writer.set_extruder_trimpot(550);
|
writer.set_extruder_trimpot(550);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Wipe the newly loaded filament until the end of the assigned wipe area.
|
// Wipe the newly loaded filament until the end of the assigned wipe area.
|
||||||
void WipeTowerPrusaMM::toolchange_Wipe(
|
void WipeTowerPrusaMM::toolchange_Wipe(
|
||||||
PrusaMultiMaterial::Writer &writer,
|
PrusaMultiMaterial::Writer &writer,
|
||||||
|
|
|
@ -44,7 +44,8 @@ public:
|
||||||
// width -- width of wipe tower in mm ( default 60 mm - leave as it is )
|
// width -- width of wipe tower in mm ( default 60 mm - leave as it is )
|
||||||
// wipe_area -- space available for one toolchange in mm
|
// wipe_area -- space available for one toolchange in mm
|
||||||
WipeTowerPrusaMM(float x, float y, float width, float rotation_angle, float cooling_tube_retraction,
|
WipeTowerPrusaMM(float x, float y, float width, float rotation_angle, float cooling_tube_retraction,
|
||||||
float cooling_tube_length, float parking_pos_retraction, float extra_loading_move, float bridging,
|
float cooling_tube_length, float parking_pos_retraction, float extra_loading_move,
|
||||||
|
float bridging, bool set_extruder_trimpot,
|
||||||
const std::vector<std::vector<float>>& wiping_matrix, unsigned int initial_tool) :
|
const std::vector<std::vector<float>>& wiping_matrix, unsigned int initial_tool) :
|
||||||
m_wipe_tower_pos(x, y),
|
m_wipe_tower_pos(x, y),
|
||||||
m_wipe_tower_width(width),
|
m_wipe_tower_width(width),
|
||||||
|
@ -57,6 +58,7 @@ public:
|
||||||
m_parking_pos_retraction(parking_pos_retraction),
|
m_parking_pos_retraction(parking_pos_retraction),
|
||||||
m_extra_loading_move(extra_loading_move),
|
m_extra_loading_move(extra_loading_move),
|
||||||
m_bridging(bridging),
|
m_bridging(bridging),
|
||||||
|
m_set_extruder_trimpot(set_extruder_trimpot),
|
||||||
m_current_tool(initial_tool),
|
m_current_tool(initial_tool),
|
||||||
wipe_volumes(wiping_matrix)
|
wipe_volumes(wiping_matrix)
|
||||||
{}
|
{}
|
||||||
|
@ -212,6 +214,7 @@ private:
|
||||||
float m_parking_pos_retraction = 0.f;
|
float m_parking_pos_retraction = 0.f;
|
||||||
float m_extra_loading_move = 0.f;
|
float m_extra_loading_move = 0.f;
|
||||||
float m_bridging = 0.f;
|
float m_bridging = 0.f;
|
||||||
|
bool m_set_extruder_trimpot = false;
|
||||||
bool m_adhesion = true;
|
bool m_adhesion = true;
|
||||||
|
|
||||||
float m_perimeter_width = 0.4 * Width_To_Nozzle_Ratio; // Width of an extrusion line, also a perimeter spacing for 100% infill.
|
float m_perimeter_width = 0.4 * Width_To_Nozzle_Ratio; // Width of an extrusion line, also a perimeter spacing for 100% infill.
|
||||||
|
|
|
@ -17,6 +17,16 @@ Layer::~Layer()
|
||||||
m_regions.clear();
|
m_regions.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test whether whether there are any slices assigned to this layer.
|
||||||
|
bool Layer::empty() const
|
||||||
|
{
|
||||||
|
for (const LayerRegion *layerm : m_regions)
|
||||||
|
if (layerm != nullptr && ! layerm->slices.empty())
|
||||||
|
// Non empty layer.
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
LayerRegion* Layer::add_region(PrintRegion* print_region)
|
LayerRegion* Layer::add_region(PrintRegion* print_region)
|
||||||
{
|
{
|
||||||
m_regions.emplace_back(new LayerRegion(this, print_region));
|
m_regions.emplace_back(new LayerRegion(this, print_region));
|
||||||
|
|
|
@ -114,7 +114,8 @@ public:
|
||||||
LayerRegion* get_region(int idx) { return m_regions[idx]; }
|
LayerRegion* get_region(int idx) { return m_regions[idx]; }
|
||||||
LayerRegion* add_region(PrintRegion* print_region);
|
LayerRegion* add_region(PrintRegion* print_region);
|
||||||
const LayerRegionPtrs& regions() const { return m_regions; }
|
const LayerRegionPtrs& regions() const { return m_regions; }
|
||||||
|
// Test whether whether there are any slices assigned to this layer.
|
||||||
|
bool empty() const;
|
||||||
void make_slices();
|
void make_slices();
|
||||||
void merge_slices();
|
void merge_slices();
|
||||||
template <class T> bool any_internal_region_slice_contains(const T &item) const {
|
template <class T> bool any_internal_region_slice_contains(const T &item) const {
|
||||||
|
|
|
@ -34,23 +34,22 @@ bool Line::intersection_infinite(const Line &other, Point* point) const
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* distance to the closest point of line */
|
// Distance to the closest point of line.
|
||||||
double Line::distance_to(const Point &point) const
|
double Line::distance_to_squared(const Point &point, const Point &a, const Point &b)
|
||||||
{
|
{
|
||||||
const Line &line = *this;
|
const Vec2d v = (b - a).cast<double>();
|
||||||
const Vec2d v = (line.b - line.a).cast<double>();
|
const Vec2d va = (point - a).cast<double>();
|
||||||
const Vec2d va = (point - line.a).cast<double>();
|
|
||||||
const double l2 = v.squaredNorm(); // avoid a sqrt
|
const double l2 = v.squaredNorm(); // avoid a sqrt
|
||||||
if (l2 == 0.0)
|
if (l2 == 0.0)
|
||||||
// line.a == line.b case
|
// a == b case
|
||||||
return va.norm();
|
return va.squaredNorm();
|
||||||
// Consider the line extending the segment, parameterized as line.a + t (line.b - line.a).
|
// Consider the line extending the segment, parameterized as a + t (b - a).
|
||||||
// We find projection of this point onto the line.
|
// We find projection of this point onto the line.
|
||||||
// It falls where t = [(this-line.a) . (line.b-line.a)] / |line.b-line.a|^2
|
// It falls where t = [(this-a) . (b-a)] / |b-a|^2
|
||||||
const double t = va.dot(v) / l2;
|
const double t = va.dot(v) / l2;
|
||||||
if (t < 0.0) return va.norm(); // beyond the 'a' end of the segment
|
if (t < 0.0) return va.squaredNorm(); // beyond the 'a' end of the segment
|
||||||
else if (t > 1.0) return (point - line.b).cast<double>().norm(); // beyond the 'b' end of the segment
|
else if (t > 1.0) return (point - b).cast<double>().squaredNorm(); // beyond the 'b' end of the segment
|
||||||
return (t * v - va).norm();
|
return (t * v - va).squaredNorm();
|
||||||
}
|
}
|
||||||
|
|
||||||
double Line::perp_distance_to(const Point &point) const
|
double Line::perp_distance_to(const Point &point) const
|
||||||
|
|
|
@ -31,7 +31,8 @@ public:
|
||||||
Point midpoint() const { return (this->a + this->b) / 2; }
|
Point midpoint() const { return (this->a + this->b) / 2; }
|
||||||
bool intersection_infinite(const Line &other, Point* point) const;
|
bool intersection_infinite(const Line &other, Point* point) const;
|
||||||
bool operator==(const Line &rhs) const { return this->a == rhs.a && this->b == rhs.b; }
|
bool operator==(const Line &rhs) const { return this->a == rhs.a && this->b == rhs.b; }
|
||||||
double distance_to(const Point &point) const;
|
double distance_to_squared(const Point &point) const { return distance_to_squared(point, this->a, this->b); }
|
||||||
|
double distance_to(const Point &point) const { return distance_to(point, this->a, this->b); }
|
||||||
double perp_distance_to(const Point &point) const;
|
double perp_distance_to(const Point &point) const;
|
||||||
bool parallel_to(double angle) const;
|
bool parallel_to(double angle) const;
|
||||||
bool parallel_to(const Line &line) const { return this->parallel_to(line.direction()); }
|
bool parallel_to(const Line &line) const { return this->parallel_to(line.direction()); }
|
||||||
|
@ -43,6 +44,9 @@ public:
|
||||||
bool intersection(const Line& line, Point* intersection) const;
|
bool intersection(const Line& line, Point* intersection) const;
|
||||||
double ccw(const Point& point) const { return point.ccw(*this); }
|
double ccw(const Point& point) const { return point.ccw(*this); }
|
||||||
|
|
||||||
|
static double distance_to_squared(const Point &point, const Point &a, const Point &b);
|
||||||
|
static double distance_to(const Point &point, const Point &a, const Point &b) { return sqrt(distance_to_squared(point, a, b)); }
|
||||||
|
|
||||||
Point a;
|
Point a;
|
||||||
Point b;
|
Point b;
|
||||||
};
|
};
|
||||||
|
|
|
@ -162,45 +162,51 @@ bool MultiPoint::first_intersection(const Line& line, Point* intersection) const
|
||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
//FIXME This is very inefficient in term of memory use.
|
std::vector<Point> MultiPoint::_douglas_peucker(const std::vector<Point>& pts, const double tolerance)
|
||||||
// The recursive algorithm shall run in place, not allocating temporary data in each recursion.
|
|
||||||
Points
|
|
||||||
MultiPoint::_douglas_peucker(const Points &points, const double tolerance)
|
|
||||||
{
|
{
|
||||||
assert(points.size() >= 2);
|
std::vector<Point> result_pts;
|
||||||
Points results;
|
if (! pts.empty()) {
|
||||||
double dmax = 0;
|
const Point *anchor = &pts.front();
|
||||||
size_t index = 0;
|
size_t anchor_idx = 0;
|
||||||
Line full(points.front(), points.back());
|
const Point *floater = &pts.back();
|
||||||
for (Points::const_iterator it = points.begin() + 1; it != points.end(); ++it) {
|
size_t floater_idx = pts.size() - 1;
|
||||||
// we use shortest distance, not perpendicular distance
|
result_pts.reserve(pts.size());
|
||||||
double d = full.distance_to(*it);
|
result_pts.emplace_back(*anchor);
|
||||||
if (d > dmax) {
|
if (anchor_idx != floater_idx) {
|
||||||
index = it - points.begin();
|
assert(pts.size() > 1);
|
||||||
dmax = d;
|
std::vector<size_t> dpStack;
|
||||||
|
dpStack.reserve(pts.size());
|
||||||
|
dpStack.emplace_back(floater_idx);
|
||||||
|
for (;;) {
|
||||||
|
double max_distSq = 0.0;
|
||||||
|
size_t furthest_idx = anchor_idx;
|
||||||
|
// find point furthest from line seg created by (anchor, floater) and note it
|
||||||
|
for (size_t i = anchor_idx + 1; i < floater_idx; ++ i) {
|
||||||
|
double dist = Line::distance_to_squared(pts[i], *anchor, *floater);
|
||||||
|
if (dist > max_distSq) {
|
||||||
|
max_distSq = dist;
|
||||||
|
furthest_idx = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (dmax >= tolerance) {
|
// remove point if less than tolerance
|
||||||
Points dp0;
|
if (max_distSq <= tolerance) {
|
||||||
dp0.reserve(index + 1);
|
result_pts.emplace_back(*floater);
|
||||||
dp0.insert(dp0.end(), points.begin(), points.begin() + index + 1);
|
anchor_idx = floater_idx;
|
||||||
// Recursive call.
|
anchor = floater;
|
||||||
Points dp1 = MultiPoint::_douglas_peucker(dp0, tolerance);
|
assert(dpStack.back() == floater_idx);
|
||||||
results.reserve(results.size() + dp1.size() - 1);
|
dpStack.pop_back();
|
||||||
results.insert(results.end(), dp1.begin(), dp1.end() - 1);
|
if (dpStack.empty())
|
||||||
|
break;
|
||||||
dp0.clear();
|
floater_idx = dpStack.back();
|
||||||
dp0.reserve(points.size() - index);
|
|
||||||
dp0.insert(dp0.end(), points.begin() + index, points.end());
|
|
||||||
// Recursive call.
|
|
||||||
dp1 = MultiPoint::_douglas_peucker(dp0, tolerance);
|
|
||||||
results.reserve(results.size() + dp1.size());
|
|
||||||
results.insert(results.end(), dp1.begin(), dp1.end());
|
|
||||||
} else {
|
} else {
|
||||||
results.push_back(points.front());
|
floater_idx = furthest_idx;
|
||||||
results.push_back(points.back());
|
dpStack.emplace_back(floater_idx);
|
||||||
}
|
}
|
||||||
return results;
|
floater = &pts[floater_idx];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result_pts;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Visivalingam simplification algorithm https://github.com/slic3r/Slic3r/pull/3825
|
// Visivalingam simplification algorithm https://github.com/slic3r/Slic3r/pull/3825
|
||||||
|
|
|
@ -213,6 +213,7 @@ bool Print::invalidate_state_by_config_options(const std::vector<t_config_option
|
||||||
|| opt_key == "filament_cooling_final_speed"
|
|| opt_key == "filament_cooling_final_speed"
|
||||||
|| opt_key == "filament_ramming_parameters"
|
|| opt_key == "filament_ramming_parameters"
|
||||||
|| opt_key == "gcode_flavor"
|
|| opt_key == "gcode_flavor"
|
||||||
|
|| opt_key == "high_current_on_filament_swap"
|
||||||
|| opt_key == "infill_first"
|
|| opt_key == "infill_first"
|
||||||
|| opt_key == "single_extruder_multi_material"
|
|| opt_key == "single_extruder_multi_material"
|
||||||
|| opt_key == "spiral_vase"
|
|| opt_key == "spiral_vase"
|
||||||
|
@ -1768,7 +1769,8 @@ void Print::_make_wipe_tower()
|
||||||
float(m_config.wipe_tower_width.value),
|
float(m_config.wipe_tower_width.value),
|
||||||
float(m_config.wipe_tower_rotation_angle.value), float(m_config.cooling_tube_retraction.value),
|
float(m_config.wipe_tower_rotation_angle.value), float(m_config.cooling_tube_retraction.value),
|
||||||
float(m_config.cooling_tube_length.value), float(m_config.parking_pos_retraction.value),
|
float(m_config.cooling_tube_length.value), float(m_config.parking_pos_retraction.value),
|
||||||
float(m_config.extra_loading_move.value), float(m_config.wipe_tower_bridging), wipe_volumes,
|
float(m_config.extra_loading_move.value), float(m_config.wipe_tower_bridging),
|
||||||
|
m_config.high_current_on_filament_swap.value, wipe_volumes,
|
||||||
m_wipe_tower_data.tool_ordering.first_extruder());
|
m_wipe_tower_data.tool_ordering.first_extruder());
|
||||||
|
|
||||||
//wipe_tower.set_retract();
|
//wipe_tower.set_retract();
|
||||||
|
|
|
@ -925,6 +925,15 @@ void PrintConfigDef::init_fff_params()
|
||||||
def->mode = comExpert;
|
def->mode = comExpert;
|
||||||
def->default_value = new ConfigOptionEnum<GCodeFlavor>(gcfRepRap);
|
def->default_value = new ConfigOptionEnum<GCodeFlavor>(gcfRepRap);
|
||||||
|
|
||||||
|
def = this->add("high_current_on_filament_swap", coBool);
|
||||||
|
def->label = L("High extruder current on filament swap");
|
||||||
|
def->tooltip = L("It may be beneficial to increase the extruder motor current during the filament exchange"
|
||||||
|
" sequence to allow for rapid ramming feed rates and to overcome resistance when loading"
|
||||||
|
" a filament with an ugly shaped tip.");
|
||||||
|
def->cli = "high-current-on-filament-swap!";
|
||||||
|
def->mode = comExpert;
|
||||||
|
def->default_value = new ConfigOptionBool(0);
|
||||||
|
|
||||||
def = this->add("infill_acceleration", coFloat);
|
def = this->add("infill_acceleration", coFloat);
|
||||||
def->label = L("Infill");
|
def->label = L("Infill");
|
||||||
def->tooltip = L("This is the acceleration your printer will use for infill. Set zero to disable "
|
def->tooltip = L("This is the acceleration your printer will use for infill. Set zero to disable "
|
||||||
|
@ -2394,8 +2403,10 @@ void PrintConfigDef::init_sla_params()
|
||||||
def->tooltip = L("Display orientation");
|
def->tooltip = L("Display orientation");
|
||||||
def->cli = "display-orientation=s";
|
def->cli = "display-orientation=s";
|
||||||
def->enum_keys_map = &ConfigOptionEnum<SLADisplayOrientation>::get_enum_values();
|
def->enum_keys_map = &ConfigOptionEnum<SLADisplayOrientation>::get_enum_values();
|
||||||
def->enum_values.push_back("Landscape");
|
def->enum_values.push_back("landscape");
|
||||||
def->enum_values.push_back("Portrait");
|
def->enum_values.push_back("portrait");
|
||||||
|
def->enum_labels.push_back(L("Landscape"));
|
||||||
|
def->enum_labels.push_back(L("Portrait"));
|
||||||
def->default_value = new ConfigOptionEnum<SLADisplayOrientation>(sladoPortrait);
|
def->default_value = new ConfigOptionEnum<SLADisplayOrientation>(sladoPortrait);
|
||||||
|
|
||||||
def = this->add("printer_correction", coFloats);
|
def = this->add("printer_correction", coFloats);
|
||||||
|
|
|
@ -155,8 +155,8 @@ template<> inline const t_config_enum_values& ConfigOptionEnum<FilamentType>::ge
|
||||||
|
|
||||||
template<> inline const t_config_enum_values& ConfigOptionEnum<SLADisplayOrientation>::get_enum_values() {
|
template<> inline const t_config_enum_values& ConfigOptionEnum<SLADisplayOrientation>::get_enum_values() {
|
||||||
static const t_config_enum_values keys_map = {
|
static const t_config_enum_values keys_map = {
|
||||||
{ "Landscape", sladoLandscape},
|
{ "landscape", sladoLandscape},
|
||||||
{ "Portrait", sladoPortrait}
|
{ "portrait", sladoPortrait}
|
||||||
};
|
};
|
||||||
|
|
||||||
return keys_map;
|
return keys_map;
|
||||||
|
@ -627,6 +627,7 @@ public:
|
||||||
ConfigOptionBool variable_layer_height;
|
ConfigOptionBool variable_layer_height;
|
||||||
ConfigOptionFloat cooling_tube_retraction;
|
ConfigOptionFloat cooling_tube_retraction;
|
||||||
ConfigOptionFloat cooling_tube_length;
|
ConfigOptionFloat cooling_tube_length;
|
||||||
|
ConfigOptionBool high_current_on_filament_swap;
|
||||||
ConfigOptionFloat parking_pos_retraction;
|
ConfigOptionFloat parking_pos_retraction;
|
||||||
ConfigOptionBool remaining_times;
|
ConfigOptionBool remaining_times;
|
||||||
ConfigOptionBool silent_mode;
|
ConfigOptionBool silent_mode;
|
||||||
|
@ -695,6 +696,7 @@ protected:
|
||||||
OPT_PTR(variable_layer_height);
|
OPT_PTR(variable_layer_height);
|
||||||
OPT_PTR(cooling_tube_retraction);
|
OPT_PTR(cooling_tube_retraction);
|
||||||
OPT_PTR(cooling_tube_length);
|
OPT_PTR(cooling_tube_length);
|
||||||
|
OPT_PTR(high_current_on_filament_swap);
|
||||||
OPT_PTR(parking_pos_retraction);
|
OPT_PTR(parking_pos_retraction);
|
||||||
OPT_PTR(remaining_times);
|
OPT_PTR(remaining_times);
|
||||||
OPT_PTR(silent_mode);
|
OPT_PTR(silent_mode);
|
||||||
|
|
|
@ -384,6 +384,14 @@ void PrintObject::generate_support_material()
|
||||||
m_print->set_status(85, "Generating support material");
|
m_print->set_status(85, "Generating support material");
|
||||||
this->_generate_support_material();
|
this->_generate_support_material();
|
||||||
m_print->throw_if_canceled();
|
m_print->throw_if_canceled();
|
||||||
|
} else {
|
||||||
|
#if 0
|
||||||
|
// Printing without supports. Empty layer means some objects or object parts are levitating,
|
||||||
|
// therefore they cannot be printed without supports.
|
||||||
|
for (const Layer *layer : m_layers)
|
||||||
|
if (layer->empty())
|
||||||
|
throw std::runtime_error("Levitating objects cannot be printed without supports.");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
this->set_done(posSupportMaterial);
|
this->set_done(posSupportMaterial);
|
||||||
}
|
}
|
||||||
|
@ -522,11 +530,13 @@ bool PrintObject::invalidate_state_by_config_options(const std::vector<t_config_
|
||||||
|| opt_key == "perimeter_speed"
|
|| opt_key == "perimeter_speed"
|
||||||
|| opt_key == "small_perimeter_speed"
|
|| opt_key == "small_perimeter_speed"
|
||||||
|| opt_key == "solid_infill_speed"
|
|| opt_key == "solid_infill_speed"
|
||||||
|| opt_key == "top_solid_infill_speed"
|
|| opt_key == "top_solid_infill_speed") {
|
||||||
|| opt_key == "wipe_into_infill" // when these these two are changed, we only need to invalidate the wipe tower,
|
invalidated |= m_print->invalidate_step(psGCodeExport);
|
||||||
|| opt_key == "wipe_into_objects" // which we already did at the very beginning - nothing more to be done
|
} else if (
|
||||||
) {
|
opt_key == "wipe_into_infill"
|
||||||
// these options only affect G-code export, so nothing to invalidate
|
|| opt_key == "wipe_into_objects") {
|
||||||
|
invalidated |= m_print->invalidate_step(psWipeTower);
|
||||||
|
invalidated |= m_print->invalidate_step(psGCodeExport);
|
||||||
} else {
|
} else {
|
||||||
// for legacy, if we can't handle this option let's invalidate all steps
|
// for legacy, if we can't handle this option let's invalidate all steps
|
||||||
this->invalidate_all_steps();
|
this->invalidate_all_steps();
|
||||||
|
@ -1463,9 +1473,7 @@ void PrintObject::_slice()
|
||||||
BOOST_LOG_TRIVIAL(debug) << "Slicing objects - removing top empty layers";
|
BOOST_LOG_TRIVIAL(debug) << "Slicing objects - removing top empty layers";
|
||||||
while (! m_layers.empty()) {
|
while (! m_layers.empty()) {
|
||||||
const Layer *layer = m_layers.back();
|
const Layer *layer = m_layers.back();
|
||||||
for (size_t region_id = 0; region_id < this->region_volumes.size(); ++ region_id)
|
if (! layer->empty())
|
||||||
if (layer->m_regions[region_id] != nullptr && ! layer->m_regions[region_id]->slices.empty())
|
|
||||||
// Non empty layer.
|
|
||||||
goto end;
|
goto end;
|
||||||
delete layer;
|
delete layer;
|
||||||
m_layers.pop_back();
|
m_layers.pop_back();
|
||||||
|
|
|
@ -420,6 +420,12 @@ void swapXY(ExPolygon& expoly) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class...Args>
|
||||||
|
void report_status(SLAPrint& p, int st, const std::string& msg, Args&&...args) {
|
||||||
|
BOOST_LOG_TRIVIAL(info) << st << "% " << msg;
|
||||||
|
p.set_status(st, msg, std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
void SLAPrint::process()
|
void SLAPrint::process()
|
||||||
{
|
{
|
||||||
using namespace sla;
|
using namespace sla;
|
||||||
|
@ -525,9 +531,11 @@ void SLAPrint::process()
|
||||||
// scaling for the sub operations
|
// scaling for the sub operations
|
||||||
double d = *stthis / (objcount * 100.0);
|
double d = *stthis / (objcount * 100.0);
|
||||||
|
|
||||||
ctl.statuscb = [this, init, d](unsigned st, const std::string& msg){
|
ctl.statuscb = [this, init, d](unsigned st, const std::string& msg)
|
||||||
set_status(int(init + st*d), msg);
|
{
|
||||||
|
report_status(*this, int(init + st*d), msg);
|
||||||
};
|
};
|
||||||
|
|
||||||
ctl.stopcondition = [this](){ return canceled(); };
|
ctl.stopcondition = [this](){ return canceled(); };
|
||||||
ctl.cancelfn = [this]() { throw_if_canceled(); };
|
ctl.cancelfn = [this]() { throw_if_canceled(); };
|
||||||
|
|
||||||
|
@ -537,9 +545,9 @@ void SLAPrint::process()
|
||||||
|
|
||||||
// Create the unified mesh
|
// Create the unified mesh
|
||||||
auto rc = SlicingStatus::RELOAD_SCENE;
|
auto rc = SlicingStatus::RELOAD_SCENE;
|
||||||
set_status(-1, L("Visualizing supports"));
|
report_status(*this, -1, L("Visualizing supports"));
|
||||||
po.m_supportdata->support_tree_ptr->merged_mesh();
|
po.m_supportdata->support_tree_ptr->merged_mesh();
|
||||||
set_status(-1, L("Visualizing supports"), rc);
|
report_status(*this, -1, L("Visualizing supports"), rc);
|
||||||
} catch(sla::SLASupportsStoppedException&) {
|
} catch(sla::SLASupportsStoppedException&) {
|
||||||
// no need to rethrow
|
// no need to rethrow
|
||||||
// throw_if_canceled();
|
// throw_if_canceled();
|
||||||
|
@ -582,7 +590,7 @@ void SLAPrint::process()
|
||||||
|
|
||||||
po.throw_if_canceled();
|
po.throw_if_canceled();
|
||||||
auto rc = SlicingStatus::RELOAD_SCENE;
|
auto rc = SlicingStatus::RELOAD_SCENE;
|
||||||
set_status(-1, L("Visualizing supports"), rc);
|
report_status(*this, -1, L("Visualizing supports"), rc);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Slicing the support geometries similarly to the model slicing procedure.
|
// Slicing the support geometries similarly to the model slicing procedure.
|
||||||
|
@ -741,8 +749,12 @@ void SLAPrint::process()
|
||||||
auto lvlcnt = unsigned(m_printer_input.size());
|
auto lvlcnt = unsigned(m_printer_input.size());
|
||||||
printer.layers(lvlcnt);
|
printer.layers(lvlcnt);
|
||||||
|
|
||||||
|
// slot is the portion of 100% that is realted to rasterization
|
||||||
unsigned slot = PRINT_STEP_LEVELS[slapsRasterize];
|
unsigned slot = PRINT_STEP_LEVELS[slapsRasterize];
|
||||||
|
// ist: initial state; pst: previous state
|
||||||
unsigned ist = max_objstatus, pst = ist;
|
unsigned ist = max_objstatus, pst = ist;
|
||||||
|
// coefficient to map the rasterization state (0-99) to the allocated
|
||||||
|
// portion (slot) of the process state
|
||||||
double sd = (100 - ist) / 100.0;
|
double sd = (100 - ist) / 100.0;
|
||||||
SpinMutex slck;
|
SpinMutex slck;
|
||||||
|
|
||||||
|
@ -779,11 +791,11 @@ void SLAPrint::process()
|
||||||
// Finish the layer for later saving it.
|
// Finish the layer for later saving it.
|
||||||
printer.finish_layer(level_id);
|
printer.finish_layer(level_id);
|
||||||
|
|
||||||
// Status indication
|
// Status indication guarded with the spinlock
|
||||||
auto st = ist + unsigned(sd*level_id*slot/m_printer_input.size());
|
auto st = ist + unsigned(sd*level_id*slot/m_printer_input.size());
|
||||||
{ std::lock_guard<SpinMutex> lck(slck);
|
{ std::lock_guard<SpinMutex> lck(slck);
|
||||||
if( st > pst) {
|
if( st > pst) {
|
||||||
set_status(int(st), PRINT_STEP_LABELS[slapsRasterize]);
|
report_status(*this, int(st), PRINT_STEP_LABELS[slapsRasterize]);
|
||||||
pst = st;
|
pst = st;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -833,9 +845,14 @@ void SLAPrint::process()
|
||||||
unsigned st = min_objstatus;
|
unsigned st = min_objstatus;
|
||||||
unsigned incr = 0;
|
unsigned incr = 0;
|
||||||
|
|
||||||
|
BOOST_LOG_TRIVIAL(info) << "Start slicing process.";
|
||||||
|
|
||||||
// TODO: this loop could run in parallel but should not exhaust all the CPU
|
// TODO: this loop could run in parallel but should not exhaust all the CPU
|
||||||
// power available
|
// power available
|
||||||
for(SLAPrintObject * po : m_objects) {
|
for(SLAPrintObject * po : m_objects) {
|
||||||
|
|
||||||
|
BOOST_LOG_TRIVIAL(info) << "Slicing object " << po->model_object()->name;
|
||||||
|
|
||||||
for(size_t s = 0; s < objectsteps.size(); ++s) {
|
for(size_t s = 0; s < objectsteps.size(); ++s) {
|
||||||
auto currentstep = objectsteps[s];
|
auto currentstep = objectsteps[s];
|
||||||
|
|
||||||
|
@ -847,8 +864,7 @@ void SLAPrint::process()
|
||||||
st += unsigned(incr * ostepd);
|
st += unsigned(incr * ostepd);
|
||||||
|
|
||||||
if(po->m_stepmask[currentstep] && po->set_started(currentstep)) {
|
if(po->m_stepmask[currentstep] && po->set_started(currentstep)) {
|
||||||
|
report_status(*this, int(st), OBJ_STEP_LABELS[currentstep]);
|
||||||
set_status(int(st), OBJ_STEP_LABELS[currentstep]);
|
|
||||||
pobj_program[currentstep](*po);
|
pobj_program[currentstep](*po);
|
||||||
po->set_done(currentstep);
|
po->set_done(currentstep);
|
||||||
}
|
}
|
||||||
|
@ -873,7 +889,7 @@ void SLAPrint::process()
|
||||||
|
|
||||||
if(m_stepmask[currentstep] && set_started(currentstep))
|
if(m_stepmask[currentstep] && set_started(currentstep))
|
||||||
{
|
{
|
||||||
set_status(int(st), PRINT_STEP_LABELS[currentstep]);
|
report_status(*this, int(st), PRINT_STEP_LABELS[currentstep]);
|
||||||
print_program[currentstep]();
|
print_program[currentstep]();
|
||||||
set_done(currentstep);
|
set_done(currentstep);
|
||||||
}
|
}
|
||||||
|
@ -882,7 +898,7 @@ void SLAPrint::process()
|
||||||
}
|
}
|
||||||
|
|
||||||
// If everything vent well
|
// If everything vent well
|
||||||
set_status(100, L("Slicing done"));
|
report_status(*this, 100, L("Slicing done"));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SLAPrint::invalidate_state_by_config_options(const std::vector<t_config_option_key> &opt_keys)
|
bool SLAPrint::invalidate_state_by_config_options(const std::vector<t_config_option_key> &opt_keys)
|
||||||
|
|
|
@ -638,6 +638,8 @@ boost::any& Choice::get_value()
|
||||||
m_value = static_cast<SeamPosition>(ret_enum);
|
m_value = static_cast<SeamPosition>(ret_enum);
|
||||||
else if (m_opt_id.compare("host_type") == 0)
|
else if (m_opt_id.compare("host_type") == 0)
|
||||||
m_value = static_cast<PrintHostType>(ret_enum);
|
m_value = static_cast<PrintHostType>(ret_enum);
|
||||||
|
else if (m_opt_id.compare("display_orientation") == 0)
|
||||||
|
m_value = static_cast<SLADisplayOrientation>(ret_enum);
|
||||||
}
|
}
|
||||||
|
|
||||||
return m_value;
|
return m_value;
|
||||||
|
|
|
@ -195,6 +195,8 @@ void change_opt_value(DynamicPrintConfig& config, const t_config_option_key& opt
|
||||||
config.set_key_value(opt_key, new ConfigOptionEnum<SeamPosition>(boost::any_cast<SeamPosition>(value)));
|
config.set_key_value(opt_key, new ConfigOptionEnum<SeamPosition>(boost::any_cast<SeamPosition>(value)));
|
||||||
else if (opt_key.compare("host_type") == 0)
|
else if (opt_key.compare("host_type") == 0)
|
||||||
config.set_key_value(opt_key, new ConfigOptionEnum<PrintHostType>(boost::any_cast<PrintHostType>(value)));
|
config.set_key_value(opt_key, new ConfigOptionEnum<PrintHostType>(boost::any_cast<PrintHostType>(value)));
|
||||||
|
else if (opt_key.compare("display_orientation") == 0)
|
||||||
|
config.set_key_value(opt_key, new ConfigOptionEnum<SLADisplayOrientation>(boost::any_cast<SLADisplayOrientation>(value)));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case coPoints:{
|
case coPoints:{
|
||||||
|
|
|
@ -1459,13 +1459,14 @@ void ObjectList::update_selections()
|
||||||
|
|
||||||
select_items(sels);
|
select_items(sels);
|
||||||
|
|
||||||
#ifdef __WXMSW__
|
|
||||||
if (GetSelection()) {
|
if (GetSelection()) {
|
||||||
const int sel_item_row = GetRowByItem(GetSelection());
|
const wxRect& sel_rc = GetItemRect(GetSelection());
|
||||||
ScrollLines(sel_item_row - m_selected_row);
|
if (!sel_rc.IsEmpty()) {
|
||||||
m_selected_row = sel_item_row;
|
const int rc_h = sel_rc.height;
|
||||||
|
const int displ = GetMainWindow()->GetClientRect().GetHeight()/(2*rc_h)+1;
|
||||||
|
ScrollLines(int(sel_rc.y / rc_h - displ));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif //__WXMSW__
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ObjectList::update_selections_on_canvas()
|
void ObjectList::update_selections_on_canvas()
|
||||||
|
@ -1656,7 +1657,9 @@ void ObjectList::change_part_type()
|
||||||
void ObjectList::last_volume_is_deleted(const int obj_idx)
|
void ObjectList::last_volume_is_deleted(const int obj_idx)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (obj_idx < 0 || (*m_objects).empty() || (*m_objects)[obj_idx]->volumes.empty())
|
if (obj_idx < 0 || m_objects->empty() ||
|
||||||
|
obj_idx <= m_objects->size() ||
|
||||||
|
(*m_objects)[obj_idx]->volumes.empty())
|
||||||
return;
|
return;
|
||||||
auto volume = (*m_objects)[obj_idx]->volumes[0];
|
auto volume = (*m_objects)[obj_idx]->volumes[0];
|
||||||
|
|
||||||
|
|
|
@ -108,8 +108,6 @@ class ObjectList : public wxDataViewCtrl
|
||||||
bool m_parts_changed = false;
|
bool m_parts_changed = false;
|
||||||
bool m_part_settings_changed = false;
|
bool m_part_settings_changed = false;
|
||||||
|
|
||||||
int m_selected_row = 0;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ObjectList(wxWindow* parent);
|
ObjectList(wxWindow* parent);
|
||||||
~ObjectList();
|
~ObjectList();
|
||||||
|
|
|
@ -213,7 +213,7 @@ void SlicedInfo::SetTextAndShow(SlisedInfoIdx idx, const wxString& text, const w
|
||||||
}
|
}
|
||||||
|
|
||||||
PresetComboBox::PresetComboBox(wxWindow *parent, Preset::Type preset_type) :
|
PresetComboBox::PresetComboBox(wxWindow *parent, Preset::Type preset_type) :
|
||||||
wxBitmapComboBox(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, nullptr, wxCB_READONLY),
|
wxBitmapComboBox(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(200,-1), 0, nullptr, wxCB_READONLY),
|
||||||
preset_type(preset_type),
|
preset_type(preset_type),
|
||||||
last_selected(wxNOT_FOUND)
|
last_selected(wxNOT_FOUND)
|
||||||
{
|
{
|
||||||
|
|
|
@ -366,7 +366,8 @@ const std::vector<std::string>& Preset::printer_options()
|
||||||
"host_type", "print_host", "printhost_apikey", "printhost_cafile",
|
"host_type", "print_host", "printhost_apikey", "printhost_cafile",
|
||||||
"single_extruder_multi_material", "start_gcode", "end_gcode", "before_layer_gcode", "layer_gcode", "toolchange_gcode",
|
"single_extruder_multi_material", "start_gcode", "end_gcode", "before_layer_gcode", "layer_gcode", "toolchange_gcode",
|
||||||
"between_objects_gcode", "printer_vendor", "printer_model", "printer_variant", "printer_notes", "cooling_tube_retraction",
|
"between_objects_gcode", "printer_vendor", "printer_model", "printer_variant", "printer_notes", "cooling_tube_retraction",
|
||||||
"cooling_tube_length", "parking_pos_retraction", "extra_loading_move", "max_print_height", "default_print_profile", "inherits",
|
"cooling_tube_length", "high_current_on_filament_swap", "parking_pos_retraction", "extra_loading_move", "max_print_height",
|
||||||
|
"default_print_profile", "inherits",
|
||||||
"remaining_times", "silent_mode", "machine_max_acceleration_extruding", "machine_max_acceleration_retracting",
|
"remaining_times", "silent_mode", "machine_max_acceleration_extruding", "machine_max_acceleration_retracting",
|
||||||
"machine_max_acceleration_x", "machine_max_acceleration_y", "machine_max_acceleration_z", "machine_max_acceleration_e",
|
"machine_max_acceleration_x", "machine_max_acceleration_y", "machine_max_acceleration_z", "machine_max_acceleration_e",
|
||||||
"machine_max_feedrate_x", "machine_max_feedrate_y", "machine_max_feedrate_z", "machine_max_feedrate_e",
|
"machine_max_feedrate_x", "machine_max_feedrate_y", "machine_max_feedrate_z", "machine_max_feedrate_e",
|
||||||
|
|
|
@ -2041,6 +2041,7 @@ void TabPrinter::build_extruder_pages()
|
||||||
optgroup->append_single_option_line("cooling_tube_length");
|
optgroup->append_single_option_line("cooling_tube_length");
|
||||||
optgroup->append_single_option_line("parking_pos_retraction");
|
optgroup->append_single_option_line("parking_pos_retraction");
|
||||||
optgroup->append_single_option_line("extra_loading_move");
|
optgroup->append_single_option_line("extra_loading_move");
|
||||||
|
optgroup->append_single_option_line("high_current_on_filament_swap");
|
||||||
m_pages.insert(m_pages.end() - n_after_single_extruder_MM, page);
|
m_pages.insert(m_pages.end() - n_after_single_extruder_MM, page);
|
||||||
m_has_single_extruder_MM_page = true;
|
m_has_single_extruder_MM_page = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1228,6 +1228,14 @@ void PrusaObjectDataViewModel::SetVolumeType(const wxDataViewItem &item, const i
|
||||||
ItemChanged(item);
|
ItemChanged(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PrusaBitmapTextRenderer::PrusaBitmapTextRenderer(wxDataViewCellMode mode /*= wxDATAVIEW_CELL_EDITABLE*/,
|
||||||
|
int align /*= wxDVR_DEFAULT_ALIGNMENT*/):
|
||||||
|
wxDataViewRenderer(wxT("PrusaDataViewBitmapText"), mode, align)
|
||||||
|
{
|
||||||
|
SetMode(mode);
|
||||||
|
SetAlignment(align);
|
||||||
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// PrusaDataViewBitmapText
|
// PrusaDataViewBitmapText
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -1251,6 +1259,13 @@ bool PrusaBitmapTextRenderer::GetValue(wxVariant& WXUNUSED(value)) const
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if wxUSE_ACCESSIBILITY
|
||||||
|
wxString PrusaBitmapTextRenderer::GetAccessibleDescription() const
|
||||||
|
{
|
||||||
|
return m_value.GetText();
|
||||||
|
}
|
||||||
|
#endif // wxUSE_ACCESSIBILITY
|
||||||
|
|
||||||
bool PrusaBitmapTextRenderer::Render(wxRect rect, wxDC *dc, int state)
|
bool PrusaBitmapTextRenderer::Render(wxRect rect, wxDC *dc, int state)
|
||||||
{
|
{
|
||||||
int xoffset = 0;
|
int xoffset = 0;
|
||||||
|
@ -1291,12 +1306,12 @@ wxWindow* PrusaBitmapTextRenderer::CreateEditorCtrl(wxWindow* parent, wxRect lab
|
||||||
|
|
||||||
PrusaDataViewBitmapText data;
|
PrusaDataViewBitmapText data;
|
||||||
data << value;
|
data << value;
|
||||||
m_bmp_from_editing_item = data.GetBitmap();
|
|
||||||
m_was_unusable_symbol = false;
|
m_was_unusable_symbol = false;
|
||||||
|
|
||||||
wxPoint position = labelRect.GetPosition();
|
wxPoint position = labelRect.GetPosition();
|
||||||
if (m_bmp_from_editing_item.IsOk()) {
|
if (data.GetBitmap().IsOk()) {
|
||||||
const int bmp_width = m_bmp_from_editing_item.GetWidth();
|
const int bmp_width = data.GetBitmap().GetWidth();
|
||||||
position.x += bmp_width;
|
position.x += bmp_width;
|
||||||
labelRect.SetWidth(labelRect.GetWidth() - bmp_width);
|
labelRect.SetWidth(labelRect.GetWidth() - bmp_width);
|
||||||
}
|
}
|
||||||
|
@ -1304,6 +1319,7 @@ wxWindow* PrusaBitmapTextRenderer::CreateEditorCtrl(wxWindow* parent, wxRect lab
|
||||||
wxTextCtrl* text_editor = new wxTextCtrl(parent, wxID_ANY, data.GetText(),
|
wxTextCtrl* text_editor = new wxTextCtrl(parent, wxID_ANY, data.GetText(),
|
||||||
position, labelRect.GetSize(), wxTE_PROCESS_ENTER);
|
position, labelRect.GetSize(), wxTE_PROCESS_ENTER);
|
||||||
text_editor->SetInsertionPointEnd();
|
text_editor->SetInsertionPointEnd();
|
||||||
|
text_editor->SelectAll();
|
||||||
|
|
||||||
return text_editor;
|
return text_editor;
|
||||||
}
|
}
|
||||||
|
@ -1323,7 +1339,17 @@ bool PrusaBitmapTextRenderer::GetValueFromEditorCtrl(wxWindow* ctrl, wxVariant&
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
value << PrusaDataViewBitmapText(text_editor->GetValue(), m_bmp_from_editing_item);
|
// The icon can't be edited so get its old value and reuse it.
|
||||||
|
wxVariant valueOld;
|
||||||
|
GetView()->GetModel()->GetValue(valueOld, m_item, 0);
|
||||||
|
|
||||||
|
PrusaDataViewBitmapText bmpText;
|
||||||
|
bmpText << valueOld;
|
||||||
|
|
||||||
|
// But replace the text with the value entered by user.
|
||||||
|
bmpText.SetText(text_editor->GetValue());
|
||||||
|
|
||||||
|
value << bmpText;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -519,15 +519,18 @@ public:
|
||||||
// PrusaBitmapTextRenderer
|
// PrusaBitmapTextRenderer
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
class PrusaBitmapTextRenderer : public wxDataViewCustomRenderer
|
class PrusaBitmapTextRenderer : public wxDataViewRenderer//CustomRenderer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PrusaBitmapTextRenderer(wxDataViewCellMode mode = wxDATAVIEW_CELL_EDITABLE,
|
PrusaBitmapTextRenderer(wxDataViewCellMode mode = wxDATAVIEW_CELL_EDITABLE,
|
||||||
int align = wxDVR_DEFAULT_ALIGNMENT):
|
int align = wxDVR_DEFAULT_ALIGNMENT);//:
|
||||||
wxDataViewCustomRenderer(wxT("PrusaDataViewBitmapText"), mode, align) {}
|
// wxDataViewRenderer/*CustomRenderer*/(wxT("PrusaDataViewBitmapText"), mode, align) {}
|
||||||
|
|
||||||
bool SetValue(const wxVariant &value);
|
bool SetValue(const wxVariant &value);
|
||||||
bool GetValue(wxVariant &value) const;
|
bool GetValue(wxVariant &value) const;
|
||||||
|
#if wxUSE_ACCESSIBILITY
|
||||||
|
virtual wxString GetAccessibleDescription() const override;
|
||||||
|
#endif // wxUSE_ACCESSIBILITY
|
||||||
|
|
||||||
virtual bool Render(wxRect cell, wxDC *dc, int state);
|
virtual bool Render(wxRect cell, wxDC *dc, int state);
|
||||||
virtual wxSize GetSize() const;
|
virtual wxSize GetSize() const;
|
||||||
|
@ -542,8 +545,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PrusaDataViewBitmapText m_value;
|
PrusaDataViewBitmapText m_value;
|
||||||
wxBitmap m_bmp_from_editing_item;
|
bool m_was_unusable_symbol {false};
|
||||||
bool m_was_unusable_symbol;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue