mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-09-27 02:41:17 +00:00
Merge remote-tracking branch 'upstream/main' into dev/h2d
# Conflicts: # resources/profiles/BBL.json # src/slic3r/GUI/AmsMappingPopup.cpp # src/slic3r/GUI/MediaFilePanel.cpp # src/slic3r/GUI/Plater.cpp # src/slic3r/GUI/StatusPanel.cpp
This commit is contained in:
+233
-190
@@ -21,6 +21,197 @@
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
// Calculate infill rotation angle (in radians) for a given layer from a rotation template.
|
||||
// Grammar subset handled (rotation only):
|
||||
// [±]α[*Z or !][joint][-][N|B|T][length][* or !]
|
||||
// [±]α* sets an initial angle only (no layer processed)
|
||||
// Where:
|
||||
// - α: angle in degrees. Without a sign it's absolute; with +/− it's relative. α% means a percentage of 360°.
|
||||
// - Runtime: *Z repeats the instruction Z times; bare * is a no-op used for initialization; ! runs once globally and then stops.
|
||||
// - Solid signs (D,S,O,M,R) are not processed here; if present they are treated as invalid/non-rotation characters.
|
||||
// - Joint signs (shape of the turn across a range):
|
||||
// / linear;
|
||||
// N,n vertical sinus (n = lazy/half amplitude);
|
||||
// Z,z horizontal sinus (z = lazy/half amplitude);
|
||||
// $ arcsin; L quarter circle H→V; l quarter circle V→H;
|
||||
// U,u squared; Q,q cubic; ~ random; ^ pseudorandom; | middle step; # vertical step at end.
|
||||
// - Counting / range length:
|
||||
// After the joint (or after α) a count determines duration of the turn:
|
||||
// N = layer count, B = bottom_shell_layers, T = top_shell_layers.
|
||||
// Prefix '-' flips the joint (swap initial/final orientation).
|
||||
// - Length modifiers convert the count to a Z range instead of a pure layer count:
|
||||
// mm, cm, m, ' (feet), " (inches), # (standard height of N layers), % (percent of model height).
|
||||
//
|
||||
// Behavior:
|
||||
// - The template string is tokenized by commas/whitespace and evaluated cyclically with one or more "ranges" per token.
|
||||
// - Absolute α resets the accumulated angle at the start of its range; relative α accumulates.
|
||||
// - *Z and ! control repetition and one-time execution of tokens across layers.
|
||||
// - If the template contains no metalanguage symbols, it is treated as a simple comma-separated list of angles repeated by modulo.
|
||||
// - Returns angle in radians for the requested layer_id. 0° aligns with +X; fillers may internally rotate as needed.
|
||||
double calculate_infill_rotation_angle(const PrintObject* object,
|
||||
size_t layer_id,
|
||||
const double& fixed_infill_angle,
|
||||
const std::string& template_string)
|
||||
{
|
||||
if (template_string.empty()) {
|
||||
return Geometry::deg2rad(fixed_infill_angle);
|
||||
}
|
||||
double angle = 0.0;
|
||||
ConfigOptionFloats rotate_angles;
|
||||
const std::string search_string = "/NnZz$LlUuQq~^|#";
|
||||
if (regex_search(template_string, std::regex("[+\\-%*@\'\"cm" + search_string + "]"))) { // template metalanguage of rotating infill
|
||||
std::regex del("[\\s,]+");
|
||||
std::sregex_token_iterator it(template_string.begin(), template_string.end(), del, -1);
|
||||
std::vector<std::string> tk;
|
||||
std::sregex_token_iterator end;
|
||||
while (it != end) {
|
||||
tk.push_back(*it++);
|
||||
}
|
||||
int t = 0;
|
||||
int repeats = 0;
|
||||
double angle_add = 0;
|
||||
double angle_steps = 1;
|
||||
double angle_start = 0;
|
||||
double limit_fill_z = object->get_layer(0)->bottom_z();
|
||||
double start_fill_z = limit_fill_z;
|
||||
bool _noop = false;
|
||||
auto fill_form = std::string::npos;
|
||||
bool _absolute = false;
|
||||
bool _negative = false;
|
||||
std::vector<bool> stop(tk.size(), false);
|
||||
|
||||
for (int i = 0; i <= layer_id; i++) {
|
||||
double fill_z = object->get_layer(i)->bottom_z();
|
||||
|
||||
if (limit_fill_z < object->get_layer(i)->slice_z) {
|
||||
if (repeats) { // if repeats >0 then restore parameters for new iteration
|
||||
limit_fill_z += limit_fill_z - start_fill_z;
|
||||
start_fill_z = fill_z;
|
||||
repeats--;
|
||||
} else {
|
||||
start_fill_z = fill_z;
|
||||
limit_fill_z = object->get_layer(i)->print_z;
|
||||
// Solid handling removed: this function only computes rotation.
|
||||
fill_form = std::string::npos;
|
||||
do {
|
||||
if (!stop[t]) {
|
||||
_noop = false;
|
||||
_absolute = false;
|
||||
_negative = false;
|
||||
angle_start += angle_add;
|
||||
angle_add = 0;
|
||||
angle_steps = 1;
|
||||
repeats = 1;
|
||||
if (tk[t].find('!') != std::string::npos) // this is an one-time instruction
|
||||
stop[t] = true;
|
||||
|
||||
char* cs = &tk[t][0];
|
||||
|
||||
if ((cs[0] >= '0' && cs[0] <= '9') && !(cs[0] == '+' || cs[0] == '-')) // absolute/relative
|
||||
_absolute = true;
|
||||
|
||||
angle_add = strtod(cs, &cs); // read angle parameter
|
||||
|
||||
if (cs[0] == '%') { // percentage of angles
|
||||
angle_add *= 3.6;
|
||||
cs = &cs[1];
|
||||
}
|
||||
|
||||
int tit = tk[t].find('*');
|
||||
if (tit != std::string::npos) // overall angle_cycles
|
||||
repeats = strtol(&tk[t][tit + 1], &cs, 0);
|
||||
|
||||
if (repeats) { // run if overall cycles greater than 0
|
||||
// Solid signs (D,S,O,M,R) are not handled here; if present they behave as invalid characters.
|
||||
|
||||
if (cs[0] == 'B') {
|
||||
angle_steps = object->print()->default_region_config().bottom_shell_layers.value;
|
||||
} else if (cs[0] == 'T') {
|
||||
angle_steps = object->print()->default_region_config().top_shell_layers.value;
|
||||
} else {
|
||||
fill_form = search_string.find(cs[0]);
|
||||
if (fill_form != std::string::npos)
|
||||
cs = &cs[1];
|
||||
|
||||
_negative = (cs[0] == '-'); // negative parameter
|
||||
angle_steps = abs(strtod(cs, &cs));
|
||||
|
||||
if (angle_steps && cs[0] != '\0' && cs[0] != '!') {
|
||||
if (cs[0] == '%') // value in the percents of fill_z
|
||||
limit_fill_z = angle_steps * object->height() * 1e-8;
|
||||
else if (cs[0] == '#') // value in the feet
|
||||
limit_fill_z = angle_steps * object->config().layer_height;
|
||||
else if (cs[0] == '\'') // value in the feet
|
||||
limit_fill_z = angle_steps * 12 * 25.4;
|
||||
else if (cs[0] == '\"') // value in the inches
|
||||
limit_fill_z = angle_steps * 25.4;
|
||||
else if (cs[0] == 'c') // value in centimeters
|
||||
limit_fill_z = angle_steps * 10.;
|
||||
else if (cs[0] == 'm') {
|
||||
if (cs[1] == 'm') { // value in the millimeters
|
||||
limit_fill_z = angle_steps * 1.;
|
||||
} else{
|
||||
limit_fill_z = angle_steps * 1000.;
|
||||
}
|
||||
}
|
||||
limit_fill_z += fill_z;
|
||||
angle_steps = 0; // limit_fill_z has already count
|
||||
}
|
||||
}
|
||||
if (angle_steps) { // if limit_fill_z does not setting by lenght method. Get count the layer id above model height
|
||||
if (fill_form == std::string::npos && !_absolute)
|
||||
angle_add *= (int) angle_steps;
|
||||
int idx = i + std::max(angle_steps - 1, 0.);
|
||||
int sdx = std::max(0, idx - (int) object->layers().size());
|
||||
idx = std::min(idx, (int) object->layers().size() - 1);
|
||||
limit_fill_z = object->get_layer(idx)->print_z + sdx * object->config().layer_height;
|
||||
}
|
||||
repeats = std::max(--repeats, 0);
|
||||
} else
|
||||
_noop = true; // set the dumb cycle
|
||||
if (_absolute) { // is absolute
|
||||
angle_start = angle_add;
|
||||
angle_add = 0;
|
||||
}
|
||||
}
|
||||
if (++t >= tk.size())
|
||||
t = 0;
|
||||
} while (std::all_of(stop.begin(), stop.end(), [](bool v) { return v; }) ?
|
||||
false :
|
||||
(t ? _noop : false) || stop[t]); // if this is a dumb instruction which never reaprated twice
|
||||
}
|
||||
}
|
||||
double top_z = object->get_layer(i)->print_z;
|
||||
double negvalue = (_negative ? limit_fill_z - top_z : top_z - start_fill_z) / (limit_fill_z - start_fill_z);
|
||||
|
||||
switch (fill_form) {
|
||||
case 0: break; // /-joint, linear
|
||||
case 1: negvalue -= sin(negvalue * PI * 2.) / (PI * 2.); break; // N-joint, sinus, vertical start
|
||||
case 2: negvalue -= sin(negvalue * PI * 2.) / (PI * 4.); break; // n-joint, sinus, vertical start, lazy
|
||||
case 3: negvalue += sin(negvalue * PI * 2.) / (PI * 2.); break; // Z-joint, sinus, horizontal start
|
||||
case 4: negvalue += sin(negvalue * PI * 2.) / (PI * 4.); break; // z-joint, sinus, horizontal start, lazy
|
||||
case 5: negvalue = asin(negvalue * 2. - 1.) / PI + 0.5; break; // $-joint, arcsin
|
||||
case 6: negvalue = sin(negvalue * PI / 2.); break; // L-joint, quarter of circle, horizontal start
|
||||
case 7: negvalue = 1. - cos(negvalue * PI / 2.); break; // l-joint, quarter of circle, vertical start
|
||||
case 8: negvalue = 1. - pow(1. - negvalue, 2); break; // U-joint, squared, x2
|
||||
case 9: negvalue = pow(1 - negvalue, 2); break; // u-joint, squared, x2 inverse
|
||||
case 10: negvalue = 1. - pow(1. - negvalue, 3); break; // Q-joint, cubic, x3
|
||||
case 11: negvalue = pow(1. - negvalue, 3); break; // q-joint, cubic, x3 inverse
|
||||
case 12: negvalue = (double) rand() / RAND_MAX; break; // ~-joint, random, fill the whole angle
|
||||
case 13: negvalue += (double) rand() / RAND_MAX - 0.5; break; // ^-joint, pseudorandom, disperse at middle line
|
||||
case 14: negvalue = 0.5; break; // |-joint, like #-joint but placed at middle angle
|
||||
case 15: negvalue = _negative ? 0. : 1.; break; // #-joint, vertical at the end angle
|
||||
}
|
||||
angle = Geometry::deg2rad(angle_start + angle_add * negvalue);
|
||||
}
|
||||
} else {
|
||||
rotate_angles.deserialize(template_string);
|
||||
auto rotate_angle_idx = layer_id % rotate_angles.size();
|
||||
angle = Geometry::deg2rad(rotate_angles.values[rotate_angle_idx]);
|
||||
}
|
||||
return angle;
|
||||
}
|
||||
|
||||
struct SurfaceFillParams
|
||||
{
|
||||
// Zero based extruder ID.
|
||||
@@ -35,6 +226,8 @@ struct SurfaceFillParams
|
||||
coordf_t overlap = 0.;
|
||||
// Angle as provided by the region config, in radians.
|
||||
float angle = 0.f;
|
||||
// Orca: is_using_template_angle
|
||||
bool is_using_template_angle = false;
|
||||
// Is bridging used for this fill? Bridging parameters may be used even if this->flow.bridge() is not set.
|
||||
bool bridge;
|
||||
// Non-negative for a bridge.
|
||||
@@ -90,6 +283,7 @@ struct SurfaceFillParams
|
||||
RETURN_COMPARE_NON_EQUAL(spacing);
|
||||
RETURN_COMPARE_NON_EQUAL(overlap);
|
||||
RETURN_COMPARE_NON_EQUAL(angle);
|
||||
RETURN_COMPARE_NON_EQUAL(is_using_template_angle);
|
||||
RETURN_COMPARE_NON_EQUAL(density);
|
||||
RETURN_COMPARE_NON_EQUAL(multiline);
|
||||
// RETURN_COMPARE_NON_EQUAL_TYPED(unsigned, dont_adjust);
|
||||
@@ -118,6 +312,7 @@ struct SurfaceFillParams
|
||||
this->spacing == rhs.spacing &&
|
||||
this->overlap == rhs.overlap &&
|
||||
this->angle == rhs.angle &&
|
||||
this->is_using_template_angle == rhs.is_using_template_angle &&
|
||||
this->bridge == rhs.bridge &&
|
||||
this->bridge_angle == rhs.bridge_angle &&
|
||||
this->density == rhs.density &&
|
||||
@@ -627,7 +822,6 @@ std::vector<SurfaceFill> group_fills(const Layer &layer, LockRegionParam &lock_p
|
||||
flow_params.insert({flow, {exp}});
|
||||
else
|
||||
it->second.push_back(exp);
|
||||
it++;
|
||||
};
|
||||
|
||||
auto append_density_param = [](std::map<float, ExPolygons> &density_params, float density, const ExPolygon &exp) {
|
||||
@@ -636,7 +830,6 @@ std::vector<SurfaceFill> group_fills(const Layer &layer, LockRegionParam &lock_p
|
||||
density_params.insert({density, {exp}});
|
||||
else
|
||||
it->second.push_back(exp);
|
||||
it++;
|
||||
};
|
||||
|
||||
for (size_t region_id = 0; region_id < layer.regions().size(); ++ region_id) {
|
||||
@@ -652,11 +845,9 @@ std::vector<SurfaceFill> group_fills(const Layer &layer, LockRegionParam &lock_p
|
||||
params.extruder = layerm.region().extruder(extrusion_role);
|
||||
params.pattern = region_config.sparse_infill_pattern.value;
|
||||
params.density = float(region_config.sparse_infill_density);
|
||||
params.multiline = int(region_config.fill_multiline);
|
||||
params.lateral_lattice_angle_1 = region_config.lateral_lattice_angle_1;
|
||||
params.lateral_lattice_angle_2 = region_config.lateral_lattice_angle_2;
|
||||
params.infill_overhang_angle = region_config.infill_overhang_angle;
|
||||
params.angle = 0.;
|
||||
if (params.pattern == ipLockedZag) {
|
||||
params.infill_lock_depth = scale_(region_config.infill_lock_depth);
|
||||
params.skin_infill_depth = scale_(region_config.skin_infill_depth);
|
||||
@@ -704,17 +895,24 @@ std::vector<SurfaceFill> group_fills(const Layer &layer, LockRegionParam &lock_p
|
||||
params.extrusion_role = erSolidInfill;
|
||||
}
|
||||
}
|
||||
// Orca: apply fill multiline only for sparse infill
|
||||
params.multiline = params.extrusion_role == erInternalInfill ? int(region_config.fill_multiline) : 1;
|
||||
|
||||
if (params.extrusion_role == erInternalInfill) {
|
||||
params.angle = calculate_infill_rotation_angle(layer.object(), layer.id(), region_config.infill_direction.value,
|
||||
region_config.sparse_infill_rotate_template.value);
|
||||
params.is_using_template_angle = !region_config.sparse_infill_rotate_template.value.empty();
|
||||
} else {
|
||||
params.angle = calculate_infill_rotation_angle(layer.object(), layer.id(), region_config.solid_infill_direction.value,
|
||||
region_config.solid_infill_rotate_template.value);
|
||||
params.is_using_template_angle = !region_config.solid_infill_rotate_template.value.empty();
|
||||
}
|
||||
params.bridge_angle = float(surface.bridge_angle);
|
||||
|
||||
if (region_config.align_infill_direction_to_model) {
|
||||
auto m = layer.object()->trafo().matrix();
|
||||
params.angle += atan2((float) m(1, 0), (float) m(0, 0));
|
||||
}
|
||||
if (params.extrusion_role == erInternalInfill) {
|
||||
params.angle += float(Geometry::deg2rad(region_config.infill_direction.value));
|
||||
} else {
|
||||
params.angle += float(Geometry::deg2rad(region_config.solid_infill_direction.value));
|
||||
}
|
||||
|
||||
// Calculate the actual flow we'll be using for this infill.
|
||||
params.bridge = is_bridge || Fill::use_bridge_flow(params.pattern);
|
||||
@@ -892,8 +1090,12 @@ std::vector<SurfaceFill> group_fills(const Layer &layer, LockRegionParam &lock_p
|
||||
params.pattern = ipRectilinear;
|
||||
params.density = 100.f;
|
||||
params.extrusion_role = erSolidInfill;
|
||||
params.angle = float(Geometry::deg2rad(layerm.region().config().solid_infill_direction.value));
|
||||
// calculate the actual flow we'll be using for this infill
|
||||
const PrintRegionConfig ®ion_config = layerm.region().config();
|
||||
params.angle = calculate_infill_rotation_angle(layer.object(), layer.id(), region_config.solid_infill_direction.value,
|
||||
region_config.solid_infill_rotate_template.value);
|
||||
params.is_using_template_angle = !region_config.solid_infill_rotate_template.value.empty();
|
||||
|
||||
// calculate the actual flow we'll be using for this infill
|
||||
params.flow = layerm.flow(frSolidInfill);
|
||||
params.spacing = params.flow.spacing();
|
||||
surface_fills.emplace_back(params);
|
||||
@@ -996,6 +1198,7 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive:
|
||||
f->layer_id = this->id();
|
||||
f->z = this->print_z;
|
||||
f->angle = surface_fill.params.angle;
|
||||
f->is_using_template_angle = surface_fill.params.is_using_template_angle;
|
||||
f->adapt_fill_octree = (surface_fill.params.pattern == ipSupportCubic) ? support_fill_octree : adaptive_fill_octree;
|
||||
f->print_config = &this->object()->print()->config();
|
||||
f->print_object_config = &this->object()->config();
|
||||
@@ -1054,184 +1257,7 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive:
|
||||
params.config = ®ion_config;
|
||||
params.pattern = surface_fill.params.pattern;
|
||||
|
||||
ConfigOptionFloats rotate_angles;
|
||||
const std::string search_string = "/NnZz$LlUuQq~^|#";
|
||||
std::string v(params.extrusion_role == erInternalInfill ? region_config.sparse_infill_rotate_template.value :
|
||||
region_config.solid_infill_rotate_template.value);
|
||||
if (regex_search(v, std::regex("[+\\-%*@\'\"cmSODMR" + search_string + "]"))) { // template metalanguage of rotating infill
|
||||
std::regex del("[\\s,]+");
|
||||
std::sregex_token_iterator it(v.begin(), v.end(), del, -1);
|
||||
std::vector<std::string> tk;
|
||||
std::sregex_token_iterator end;
|
||||
while (it != end) {
|
||||
tk.push_back(*it++);
|
||||
}
|
||||
int t = 0;
|
||||
int repeats = 0;
|
||||
double angle = 0;
|
||||
double angle_add = 0;
|
||||
double angle_steps = 1;
|
||||
double angle_start = 0;
|
||||
double limit_fill_z = this->object()->get_layer(0)->bottom_z();
|
||||
double start_fill_z = limit_fill_z;
|
||||
bool _noop = false;
|
||||
auto solid = std::string::npos; // -1 - sparse, 0 - native (D), 1 - internal solid (S), 2 - concentric (O), 3 - monotonic (M), 4 - rectilinear (R)
|
||||
auto fill_form = std::string::npos;
|
||||
bool _absolute = false;
|
||||
bool _negative = false;
|
||||
std::vector<bool> stop(tk.size(), false);
|
||||
|
||||
for (int i = 0; i <= this->id(); i++) {
|
||||
double fill_z = this->object()->get_layer(i)->bottom_z();
|
||||
|
||||
if (limit_fill_z < this->object()->get_layer(i)->slice_z) {
|
||||
if (repeats) { // if repeats >0 then restore parameters for new iteration
|
||||
limit_fill_z += limit_fill_z - start_fill_z;
|
||||
start_fill_z = fill_z;
|
||||
repeats--;
|
||||
} else {
|
||||
start_fill_z = fill_z;
|
||||
limit_fill_z = this->object()->get_layer(i)->print_z;
|
||||
solid = std::string::npos;
|
||||
fill_form = std::string::npos;
|
||||
do {
|
||||
if (!stop[t]) {
|
||||
_noop = false;
|
||||
_absolute = false;
|
||||
_negative = false;
|
||||
angle_start += angle_add;
|
||||
angle_add = 0;
|
||||
angle_steps = 1;
|
||||
repeats = 1;
|
||||
if (tk[t].find('!') != std::string::npos) // this is an one-time instruction
|
||||
stop[t] = true;
|
||||
|
||||
char* cs = &tk[t][0];
|
||||
|
||||
if ((cs[0] >= '0' && cs[0] <= '9') && !(cs[0] == '+' || cs[0] == '-')) // absolute/relative
|
||||
_absolute = true;
|
||||
|
||||
angle_add = strtod(cs, &cs); // read angle parameter
|
||||
|
||||
if (cs[0] == '%') { // percentage of angles
|
||||
angle_add *= 3.6;
|
||||
cs = &cs[1];
|
||||
}
|
||||
|
||||
int tit = tk[t].find('*');
|
||||
if (tit != std::string::npos) // overall angle_cycles
|
||||
repeats = strtol(&tk[t][tit + 1], &cs, 0);
|
||||
|
||||
if (repeats) { // run if overall cycles greater than 0
|
||||
solid = std::string("DSOMR").find(cs[0]); // solid infill
|
||||
if (solid != std::string::npos)
|
||||
cs = &cs[1];
|
||||
|
||||
if (cs[0] == 'B') {
|
||||
angle_steps = this->object()->print()->default_region_config().bottom_shell_layers.value;
|
||||
} else if (cs[0] == 'T') {
|
||||
angle_steps = this->object()->print()->default_region_config().top_shell_layers.value;
|
||||
} else {
|
||||
fill_form = search_string.find(cs[0]);
|
||||
if (fill_form != std::string::npos)
|
||||
cs = &cs[1];
|
||||
|
||||
_negative = (cs[0] == '-'); // negative parameter
|
||||
angle_steps = abs(strtod(cs, &cs));
|
||||
|
||||
if (angle_steps && cs[0] != '\0' && cs[0] != '!') {
|
||||
if (cs[0] == '%') // value in the percents of fill_z
|
||||
limit_fill_z = angle_steps * this->object()->height() * 1e-8;
|
||||
else if (cs[0] == '#') // value in the feet
|
||||
limit_fill_z = angle_steps * this->object()->config().layer_height;
|
||||
else if (cs[0] == '\'') // value in the feet
|
||||
limit_fill_z = angle_steps * 12 * 25.4;
|
||||
else if (cs[0] == '\"') // value in the inches
|
||||
limit_fill_z = angle_steps * 25.4;
|
||||
else if (cs[0] == 'c') // value in centimeters
|
||||
limit_fill_z = angle_steps * 10.;
|
||||
else if (cs[0] == 'm')
|
||||
if (cs[1] == 'm') { // value in the millimeters
|
||||
limit_fill_z = angle_steps * 1.;
|
||||
} else // value in the meters
|
||||
limit_fill_z = angle_steps * 1000.;
|
||||
limit_fill_z += fill_z;
|
||||
angle_steps = 0; // limit_fill_z has already count
|
||||
}
|
||||
}
|
||||
if (angle_steps) { // if limit_fill_z does not setting by lenght method. Get count the layer id above model height
|
||||
if (fill_form == std::string::npos && !_absolute)
|
||||
angle_add *= (int) angle_steps;
|
||||
int idx = i + std::max(angle_steps - 1, 0.);
|
||||
int sdx = std::max(0, idx - (int) this->object()->layers().size());
|
||||
idx = std::min(idx, (int) this->object()->layers().size() - 1);
|
||||
limit_fill_z = this->object()->get_layer(idx)->print_z + sdx * this->object()->config().layer_height;
|
||||
}
|
||||
repeats = std::max(--repeats, 0);
|
||||
} else
|
||||
_noop = true; // set the dumb cycle
|
||||
if (_absolute) { // is absolute
|
||||
angle_start = angle_add;
|
||||
angle_add = 0;
|
||||
}
|
||||
}
|
||||
if (++t >= tk.size())
|
||||
t = 0;
|
||||
} while (std::all_of(stop.begin(), stop.end(), [](bool v) { return v; }) ? false :
|
||||
(t ? _noop : false) || stop[t]); // if this is a dumb instruction which never reaprated twice
|
||||
}
|
||||
}
|
||||
double top_z = this->object()->get_layer(i)->print_z;
|
||||
double negvalue = (_negative ? limit_fill_z - top_z : top_z - start_fill_z) / (limit_fill_z - start_fill_z);
|
||||
|
||||
switch (fill_form) {
|
||||
case 0: break; // /-joint, linear
|
||||
case 1: negvalue -= sin(negvalue * PI * 2.) / (PI * 2.); break; // N-joint, sinus, vertical start
|
||||
case 2: negvalue -= sin(negvalue * PI * 2.) / (PI * 4.); break; // n-joint, sinus, vertical start, lazy
|
||||
case 3: negvalue += sin(negvalue * PI * 2.) / (PI * 2.); break; // Z-joint, sinus, horizontal start
|
||||
case 4: negvalue += sin(negvalue * PI * 2.) / (PI * 4.); break; // z-joint, sinus, horizontal start, lazy
|
||||
case 5: negvalue = asin(negvalue * 2. - 1.) / PI + 0.5; break; // $-joint, arcsin
|
||||
case 6: negvalue = sin(negvalue * PI / 2.); break; // L-joint, quarter of circle, horizontal start
|
||||
case 7: negvalue = 1. - cos(negvalue * PI / 2.); break; // l-joint, quarter of circle, vertical start
|
||||
case 8: negvalue = 1. - pow(1. - negvalue, 2); break; // U-joint, squared, x2
|
||||
case 9: negvalue = pow(1 - negvalue, 2); break; // u-joint, squared, x2 inverse
|
||||
case 10: negvalue = 1. - pow(1. - negvalue, 3); break; // Q-joint, cubic, x3
|
||||
case 11: negvalue = pow(1. - negvalue, 3); break; // q-joint, cubic, x3 inverse
|
||||
case 12: negvalue = (double) rand() / RAND_MAX; break; // ~-joint, random, fill the whole angle
|
||||
case 13: negvalue += (double) rand() / RAND_MAX - 0.5; break; // ^-joint, pseudorandom, disperse at middle line
|
||||
case 14: negvalue = 0.5; break; // |-joint, like #-joint but placed at middle angle
|
||||
case 15: negvalue = _negative ? 0. : 1.; break; // #-joint, vertical at the end angle
|
||||
}
|
||||
angle = angle_start + angle_add * negvalue;
|
||||
}
|
||||
if (solid != std::string::npos) {
|
||||
switch (solid) {
|
||||
case 1: params.pattern = region_config.internal_solid_infill_pattern.value; break; // selected solid pattern
|
||||
case 2: params.pattern = ipConcentric; break; // concentric pattern
|
||||
case 3: params.pattern = ipMonotonic; break; // monotonic pattern
|
||||
case 4: params.pattern = ipRectilinear; // rectilinear pattern
|
||||
} // or else use native pattern
|
||||
params.extrusion_role = erSolidInfill;
|
||||
params.density = 1.;
|
||||
surface_fill.params.pattern = params.pattern;
|
||||
|
||||
f = std::unique_ptr<Fill>(Fill::new_from_type(params.pattern)); // reinitialize surface
|
||||
f->set_bounding_box(bbox);
|
||||
f->layer_id = this->id();
|
||||
f->z = this->print_z;
|
||||
f->angle = surface_fill.params.angle;
|
||||
f->print_config = &this->object()->print()->config();
|
||||
f->print_object_config = &this->object()->config();
|
||||
params.use_arachne = surface_fill.params.pattern == ipConcentric || surface_fill.params.pattern == ipConcentricInternal;
|
||||
}
|
||||
f->rotate_angle = Geometry::deg2rad(angle);
|
||||
} else {
|
||||
rotate_angles.deserialize(v);
|
||||
auto rotate_angle_idx = f->layer_id % rotate_angles.size();
|
||||
f->rotate_angle = Geometry::deg2rad(rotate_angles.values[rotate_angle_idx]);
|
||||
}
|
||||
|
||||
if( surface_fill.params.pattern == ipLockedZag ) {
|
||||
if( surface_fill.params.pattern == ipLockedZag ) {
|
||||
params.locked_zag = true;
|
||||
params.infill_lock_depth = surface_fill.params.infill_lock_depth;
|
||||
params.skin_infill_depth = surface_fill.params.skin_infill_depth;
|
||||
@@ -1293,7 +1319,23 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive:
|
||||
assert(dynamic_cast<ExtrusionEntityCollection*>(layerm->fills.entities[i]) != nullptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate sparse-infill polylines for anchoring/analysis purposes.
|
||||
*
|
||||
* This produces the geometric polylines of internal sparse infill for the current
|
||||
* layer (using the same infill pattern, angle, rotation template, and spacing that
|
||||
* normal slicing would use), but it does not create extrusion entities.
|
||||
*
|
||||
* The returned polylines are consumed by internal-bridge detection on the next
|
||||
* layer to derive anchor lines and compute the bridge direction over sparse infill.
|
||||
*
|
||||
* Notes:
|
||||
* - Only `stInternal` surfaces are considered.
|
||||
* - Rotation templates (e.g. `sparse_infill_rotate_template`) are applied so the
|
||||
* anchors reflect the actual infill orientation.
|
||||
* - For lightning/adaptive patterns, the respective generators are wired so their
|
||||
* polylines match the final infill layout.
|
||||
*/
|
||||
Polylines Layer::generate_sparse_infill_polylines_for_anchoring(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive::Octree* support_fill_octree, FillLightning::Generator* lightning_generator) const
|
||||
{
|
||||
LockRegionParam skin_inner_param;
|
||||
@@ -1346,6 +1388,7 @@ Polylines Layer::generate_sparse_infill_polylines_for_anchoring(FillAdaptive::Oc
|
||||
f->layer_id = this->id() - this->object()->get_layer(0)->id(); // We need to subtract raft layers.
|
||||
f->z = this->print_z;
|
||||
f->angle = surface_fill.params.angle;
|
||||
f->is_using_template_angle = surface_fill.params.is_using_template_angle;
|
||||
f->adapt_fill_octree = (surface_fill.params.pattern == ipSupportCubic) ? support_fill_octree : adaptive_fill_octree;
|
||||
f->print_config = &this->object()->print()->config();
|
||||
f->print_object_config = &this->object()->config();
|
||||
|
||||
@@ -15,8 +15,9 @@ public:
|
||||
Fill* clone() const override { return new Fill3DHoneycomb(*this); };
|
||||
~Fill3DHoneycomb() override {}
|
||||
|
||||
// require bridge flow since most of this pattern hangs in air
|
||||
bool use_bridge_flow() const override { return true; }
|
||||
// note: updated 3D Honeycomb doesn't need bridge flow because the
|
||||
// pattern is placed on top of previous layers
|
||||
bool use_bridge_flow() const override { return false; }
|
||||
bool is_self_crossing() override { return false; }
|
||||
|
||||
protected:
|
||||
|
||||
@@ -306,7 +306,9 @@ std::pair<float, Point> Fill::_infill_direction(const Surface *surface) const
|
||||
out_angle = float(surface->bridge_angle);
|
||||
} else if (this->layer_id != size_t(-1)) {
|
||||
// alternate fill direction
|
||||
out_angle += this->_layer_angle(this->layer_id / surface->thickness_layers);
|
||||
//Orca: if template angle is not empty, don't apply layer angle
|
||||
if(!is_using_template_angle)
|
||||
out_angle += this->_layer_angle(this->layer_id / surface->thickness_layers);
|
||||
} else {
|
||||
// printf("Layer_ID undefined!\n");
|
||||
}
|
||||
|
||||
@@ -119,8 +119,8 @@ public:
|
||||
coordf_t overlap;
|
||||
// in radians, ccw, 0 = East
|
||||
float angle;
|
||||
// Orca: enable angle shifting for layer change
|
||||
float rotate_angle{ M_PI/180.0 };
|
||||
// Orca: is_using_template_angle
|
||||
bool is_using_template_angle{false};
|
||||
// In scaled coordinates. Maximum lenght of a perimeter segment connecting two infill lines.
|
||||
// Used by the FillRectilinear2, FillGrid2, FillTriangles, FillStars and FillCubic.
|
||||
// If left to zero, the links will not be limited.
|
||||
@@ -182,7 +182,6 @@ protected:
|
||||
overlap(0.),
|
||||
// Initial angle is undefined.
|
||||
angle(FLT_MAX),
|
||||
rotate_angle(M_PI/180.0),
|
||||
link_max_length(0),
|
||||
loop_clipping(0),
|
||||
// The initial bounding box is empty, therefore undefined.
|
||||
@@ -204,7 +203,7 @@ protected:
|
||||
ExPolygon expolygon,
|
||||
ThickPolylines& thick_polylines_out) {}
|
||||
|
||||
virtual float _layer_angle(size_t idx) const { return rotate_angle; }
|
||||
virtual float _layer_angle(size_t idx) const { return is_using_template_angle ? 0.f : (idx & 1) ? float(M_PI/2.) : 0.f; }
|
||||
|
||||
virtual std::pair<float, Point> _infill_direction(const Surface *surface) const;
|
||||
|
||||
|
||||
@@ -3044,7 +3044,7 @@ Polylines FillRectilinear::fill_surface(const Surface *surface, const FillParams
|
||||
{
|
||||
Polylines polylines_out;
|
||||
// Orca Todo: fow now don't use fill_surface_by_multilines for zipzag infill
|
||||
if (params.full_infill() || params.pattern == ipCrossZag || params.pattern == ipZigZag || params.pattern == ipLockedZag) {
|
||||
if (params.full_infill() || params.multiline == 1 || params.pattern == ipCrossZag || params.pattern == ipZigZag || params.pattern == ipLockedZag) {
|
||||
if (!fill_surface_by_lines(surface, params, 0.f, 0.f, polylines_out))
|
||||
BOOST_LOG_TRIVIAL(error) << "FillRectilinear::fill_surface() fill_surface_by_lines() failed to fill a region.";
|
||||
} else {
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
#include <unordered_set>
|
||||
#include <utility>
|
||||
#include <tbb/parallel_for.h>
|
||||
#include <mutex>
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
@@ -157,8 +156,8 @@ vector<double> getGridValues(int i, int j, vector<vector<double>>& data)
|
||||
values.push_back(data[i][j]);
|
||||
return values;
|
||||
}
|
||||
bool needContour(double value, double contourValue) { return value >= contourValue; }
|
||||
Point interpolate(std::vector<std::vector<MarchingSquares::Point>>& posxy,
|
||||
static bool needContour(double value, double contourValue) { return value >= contourValue; }
|
||||
static Point interpolate(std::vector<std::vector<MarchingSquares::Point>>& posxy,
|
||||
std::vector<int> p1ij,
|
||||
std::vector<int> p2ij,
|
||||
double v1,
|
||||
@@ -186,7 +185,7 @@ Point interpolate(std::vector<std::vector<MarchingSquares::Point>>& posxy,
|
||||
return p;
|
||||
}
|
||||
|
||||
void process_block(int i,
|
||||
static void process_block(int i,
|
||||
int j,
|
||||
vector<vector<double>>& data,
|
||||
double contourValue,
|
||||
@@ -288,43 +287,7 @@ void process_block(int i,
|
||||
}
|
||||
}
|
||||
|
||||
// --- Chaikin Smooth ---
|
||||
|
||||
static Polyline chaikin_smooth(Polyline poly, int iterations , double weight )
|
||||
{
|
||||
if (poly.points.size() < 3) return poly;
|
||||
|
||||
const double w1 = 1.0 - weight;
|
||||
decltype(poly.points) buffer;
|
||||
buffer.reserve(poly.points.size() * 2);
|
||||
|
||||
for (int it = 0; it < iterations; ++it) {
|
||||
buffer.clear();
|
||||
buffer.push_back(poly.points.front());
|
||||
|
||||
for (size_t i = 0; i < poly.points.size() - 1; ++i) {
|
||||
const auto &p0 = poly.points[i];
|
||||
const auto &p1 = poly.points[i + 1];
|
||||
|
||||
buffer.emplace_back(
|
||||
p0.x() * w1 + p1.x() * weight,
|
||||
p0.y() * w1 + p1.y() * weight
|
||||
);
|
||||
buffer.emplace_back(
|
||||
p0.x() * weight + p1.x() * w1,
|
||||
p0.y() * weight + p1.y() * w1
|
||||
);
|
||||
}
|
||||
|
||||
buffer.push_back(poly.points.back());
|
||||
poly.points.swap(buffer);
|
||||
}
|
||||
|
||||
return poly;
|
||||
}
|
||||
|
||||
|
||||
void drawContour(double contourValue,
|
||||
static void drawContour(double contourValue,
|
||||
int gridSize_w,
|
||||
int gridSize_h,
|
||||
vector<vector<double>>& data,
|
||||
@@ -382,62 +345,18 @@ void drawContour(double contourValue,
|
||||
for (myPoint& pt : p) {
|
||||
repltmp.points.push_back(Slic3r::Point(pt.x, pt.y));
|
||||
}
|
||||
// symplify tolerance based on density
|
||||
const float min_tolerance = 0.005f;
|
||||
const float max_tolerance = 0.2f;
|
||||
float simplify_tolerance = (0.005f / params.density);
|
||||
simplify_tolerance = std::clamp(simplify_tolerance, min_tolerance, max_tolerance);
|
||||
repltmp.simplify(scale_(simplify_tolerance));
|
||||
repltmp = chaikin_smooth(repltmp, 2, 0.25);
|
||||
repls.push_back(repltmp);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace MarchingSquares
|
||||
|
||||
static float sin_table[360];
|
||||
static float cos_table[360];
|
||||
static std::once_flag trig_tables_once_flag;
|
||||
|
||||
#define PIratio 57.29577951308232 // 180/PI
|
||||
|
||||
static void initialize_lookup_tables()
|
||||
{
|
||||
for (int i = 0; i < 360; ++i) {
|
||||
float angle = i * (M_PI / 180.0);
|
||||
sin_table[i] = std::sin(angle);
|
||||
cos_table[i] = std::cos(angle);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
inline static void ensure_trig_tables_initialized()
|
||||
{
|
||||
std::call_once(trig_tables_once_flag, initialize_lookup_tables);
|
||||
}
|
||||
|
||||
inline static float get_sin(float angle)
|
||||
{
|
||||
angle = angle * PIratio;
|
||||
int index = static_cast<int>(std::fmod(angle, 360) + 360) % 360;
|
||||
return sin_table[index];
|
||||
}
|
||||
|
||||
inline static float get_cos(float angle)
|
||||
{
|
||||
angle = angle * PIratio;
|
||||
int index = static_cast<int>(std::fmod(angle, 360) + 360) % 360;
|
||||
return cos_table[index];
|
||||
}
|
||||
|
||||
void FillTpmsFK::_fill_surface_single(const FillParams& params,
|
||||
unsigned int thickness_layers,
|
||||
const std::pair<float, Point>& direction,
|
||||
ExPolygon expolygon,
|
||||
Polylines& polylines_out)
|
||||
{
|
||||
ensure_trig_tables_initialized();
|
||||
|
||||
auto infill_angle = float(this->angle + (CorrectionAngle * 2 * M_PI) / 360.);
|
||||
if(std::abs(infill_angle) >= EPSILON)
|
||||
expolygon.rotate(-infill_angle);
|
||||
@@ -452,40 +371,29 @@ void FillTpmsFK::_fill_surface_single(const FillParams& params,
|
||||
float xlen = boxsize.x();
|
||||
float ylen = boxsize.y();
|
||||
|
||||
const float delta = 0.5f; // mesh step (adjust for quality/performance)
|
||||
|
||||
const float delta = 0.4f; // mesh step (adjust for quality/performance)
|
||||
float myperiod = 2 * PI / vari_T;
|
||||
float c_z = myperiod * this->z; // z height
|
||||
|
||||
// scalar field Fischer-Koch
|
||||
auto scalar_field = [&](float x, float y) {
|
||||
float a_x = myperiod * x;
|
||||
float b_y = myperiod * y;
|
||||
|
||||
auto scalar_field = [&](float x, float y) -> float {
|
||||
const float a_x = myperiod * x;
|
||||
const float b_y = myperiod * y;
|
||||
|
||||
// Fischer - Koch S equation:
|
||||
// cos(2x)sin(y)cos(z) + cos(2y)sin(z)cos(x) + cos(2z)sin(x)cos(y) = 0
|
||||
const float cos2ax = get_cos(2*a_x);
|
||||
const float cos2by = get_cos(2*b_y);
|
||||
const float cos2cz = get_cos(2*c_z);
|
||||
const float sinby = get_sin(b_y);
|
||||
const float cosax = get_cos(a_x);
|
||||
const float sinax = get_sin(a_x);
|
||||
const float cosby = get_cos(b_y);
|
||||
const float sincz = get_sin(c_z);
|
||||
const float coscz = get_cos(c_z);
|
||||
|
||||
return cos2ax * sinby * coscz
|
||||
+ cos2by * sincz * cosax
|
||||
+ cos2cz * sinax * cosby;
|
||||
return cosf(2 * a_x) * sinf(b_y) * cosf(c_z)
|
||||
+ cosf(2 * b_y) * sinf(c_z) * cosf(a_x)
|
||||
+ cosf(2 * c_z) * sinf(a_x) * cosf(b_y);
|
||||
};
|
||||
|
||||
// Mesh generation
|
||||
std::vector<std::vector<MarchingSquares::Point>> posxy;
|
||||
int i = 0, j = 0;
|
||||
for (float y = -(ylen) / 2.0f - 2; y < (ylen) / 2.0f + 2; y = y + delta, i++) {
|
||||
for (float y = -(ylen) / 2.0f - 0.5f; y < (ylen) / 2.0f + 0.5f; y = y + delta, i++) {
|
||||
j = 0;
|
||||
std::vector<MarchingSquares::Point> colposxy;
|
||||
for (float x = -(xlen) / 2.0f - 2; x < (xlen) / 2.0f + 2; x = x + delta, j++) {
|
||||
for (float x = -(xlen) / 2.0f - 0.5f; x < (xlen) / 2.0f + 0.5f; x = x + delta, j++) {
|
||||
MarchingSquares::Point pt;
|
||||
pt.x = cenpos.x() + x;
|
||||
pt.y = cenpos.y() + y;
|
||||
@@ -510,33 +418,36 @@ void FillTpmsFK::_fill_surface_single(const FillParams& params,
|
||||
|
||||
|
||||
Polylines polylines;
|
||||
const double contour_value = 0.075; // offset from zero to avoid numerical issues
|
||||
const double contour_value = 0; // offset from theoretical surface
|
||||
MarchingSquares::drawContour(contour_value, width , height , data, posxy, polylines, params);
|
||||
|
||||
if (!polylines.empty()) {
|
||||
// Apply multiline offset if needed
|
||||
multiline_fill(polylines, params, spacing);
|
||||
// Apply multiline offset if needed
|
||||
multiline_fill(polylines, params, spacing);
|
||||
|
||||
polylines = intersection_pl(polylines, expolygon);
|
||||
|
||||
polylines = intersection_pl(polylines, expolygon);
|
||||
|
||||
// Remove very small bits, but be careful to not remove infill lines connecting thin walls!
|
||||
if (! polylines.empty()) {
|
||||
// Remove very small bits, but be careful to not remove infill lines connecting thin walls!
|
||||
// The infill perimeter lines should be separated by around a single infill line width.
|
||||
const double minlength = scale_(0.8 * this->spacing);
|
||||
polylines.erase(
|
||||
std::remove_if(polylines.begin(), polylines.end(), [minlength](const Polyline &pl) { return pl.length() < minlength; }),
|
||||
polylines.end());
|
||||
}
|
||||
|
||||
if (! polylines.empty()) {
|
||||
// connect lines
|
||||
size_t polylines_out_first_idx = polylines_out.size();
|
||||
chain_or_connect_infill(std::move(polylines), expolygon, polylines_out, this->spacing, params);
|
||||
|
||||
//chain_or_connect_infill(std::move(polylines), expolygon, polylines_out, this->spacing, params);
|
||||
//chain_infill not situable for this pattern due to internal "islands", this also affect performance a lot.
|
||||
connect_infill(std::move(polylines), expolygon, polylines_out, this->spacing, params);
|
||||
|
||||
// new paths must be rotated back
|
||||
if (std::abs(infill_angle) >= EPSILON) {
|
||||
for (auto it = polylines_out.begin() + polylines_out_first_idx; it != polylines_out.end(); ++ it)
|
||||
it->rotate(infill_angle);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1129,7 +1129,7 @@ void PerimeterGenerator::process_classic()
|
||||
coord_t ext_perimeter_spacing = this->ext_perimeter_flow.scaled_spacing();
|
||||
coord_t ext_perimeter_spacing2;
|
||||
// Orca: ignore precise_outer_wall if wall_sequence is not InnerOuter
|
||||
if(config->precise_outer_wall)
|
||||
if(config->precise_outer_wall && config->wall_sequence == WallSequence::InnerOuter)
|
||||
ext_perimeter_spacing2 = scaled<coord_t>(0.5f * (this->ext_perimeter_flow.width() + this->perimeter_flow.width()));
|
||||
else
|
||||
ext_perimeter_spacing2 = scaled<coord_t>(0.5f * (this->ext_perimeter_flow.spacing() + this->perimeter_flow.spacing()));
|
||||
@@ -2124,7 +2124,7 @@ void PerimeterGenerator::process_arachne()
|
||||
if (is_topmost_layer && loop_number > 0 && config->only_one_wall_top)
|
||||
loop_number = 0;
|
||||
|
||||
auto apply_precise_outer_wall = config->precise_outer_wall;
|
||||
auto apply_precise_outer_wall = config->precise_outer_wall && config->wall_sequence == WallSequence::InnerOuter;
|
||||
// Orca: properly adjust offset for the outer wall if precise_outer_wall is enabled.
|
||||
ExPolygons last = offset_ex(surface.expolygon.simplify_p(surface_simplify_resolution),
|
||||
apply_precise_outer_wall? -float(ext_perimeter_width - ext_perimeter_spacing )
|
||||
|
||||
@@ -788,7 +788,7 @@ static std::vector<std::string> s_Preset_print_options {
|
||||
"extra_perimeters_on_overhangs", "ensure_vertical_shell_thickness", "reduce_crossing_wall", "detect_thin_wall", "detect_overhang_wall", "overhang_reverse", "overhang_reverse_threshold","overhang_reverse_internal_only", "wall_direction",
|
||||
"seam_position", "staggered_inner_seams", "wall_sequence", "is_infill_first", "sparse_infill_density","fill_multiline", "sparse_infill_pattern", "lateral_lattice_angle_1", "lateral_lattice_angle_2", "infill_overhang_angle", "top_surface_pattern", "bottom_surface_pattern",
|
||||
"infill_direction", "solid_infill_direction", "counterbore_hole_bridging","infill_shift_step", "sparse_infill_rotate_template", "solid_infill_rotate_template", "symmetric_infill_y_axis","skeleton_infill_density", "infill_lock_depth", "skin_infill_depth", "skin_infill_density",
|
||||
"align_infill_direction_to_model",
|
||||
"align_infill_direction_to_model", "extra_solid_infills",
|
||||
"minimum_sparse_infill_area", "reduce_infill_retraction","internal_solid_infill_pattern","gap_fill_target",
|
||||
"ironing_type", "ironing_pattern", "ironing_flow", "ironing_speed", "ironing_spacing", "ironing_angle", "ironing_inset",
|
||||
"support_ironing", "support_ironing_pattern", "support_ironing_flow", "support_ironing_spacing",
|
||||
|
||||
@@ -1627,6 +1627,12 @@ StringObjectException Print::validate(StringObjectException *warning, Polygons*
|
||||
// }
|
||||
// }
|
||||
|
||||
// check wall sequence and precise outer wall
|
||||
if (m_default_region_config.precise_outer_wall && m_default_region_config.wall_sequence != WallSequence::InnerOuter) {
|
||||
warning->string = L("The precise wall option will be ignored for outer-inner or inner-outer-inner wall sequences.");
|
||||
warning->opt_key = "precise_outer_wall";
|
||||
}
|
||||
|
||||
} catch (std::exception& e) {
|
||||
BOOST_LOG_TRIVIAL(warning) << "Orca: validate motion ability failed: " << e.what() << std::endl;
|
||||
}
|
||||
|
||||
@@ -679,7 +679,7 @@ void PrintConfigDef::init_common_params()
|
||||
|
||||
def = this->add("preferred_orientation", coFloat);
|
||||
def->label = L("Preferred orientation");
|
||||
def->tooltip = L("Automatically orient stls on the Z-axis upon initial import.");
|
||||
def->tooltip = L("Automatically orient stls on the Z axis upon initial import.");
|
||||
def->sidetext = "°"; // degrees, don't need translation
|
||||
def->max = 360;
|
||||
def->min = -360;
|
||||
@@ -1203,9 +1203,10 @@ void PrintConfigDef::init_fff_params()
|
||||
def = this->add("precise_outer_wall",coBool);
|
||||
def->label = L("Precise wall");
|
||||
def->category = L("Quality");
|
||||
def->tooltip = L("Improve shell precision by adjusting outer wall spacing. This also improves layer consistency.");
|
||||
def->set_default_value(new ConfigOptionBool{false});
|
||||
|
||||
def->tooltip = L("Improve shell precision by adjusting outer wall spacing. This also improves layer consistency. NOTE: This option "
|
||||
"will be ignored for outer-inner or inner-outer-inner wall sequences.");
|
||||
def->set_default_value(new ConfigOptionBool{true});
|
||||
|
||||
def = this->add("only_one_wall_top", coBool);
|
||||
def->label = L("Only one wall on top surfaces");
|
||||
def->category = L("Quality");
|
||||
@@ -1454,9 +1455,9 @@ void PrintConfigDef::init_fff_params()
|
||||
def = this->add("brim_ears_detection_length", coFloat);
|
||||
def->label = L("Brim ear detection radius");
|
||||
def->category = L("Support");
|
||||
def->tooltip = L("The geometry will be decimated before detecting sharp angles. This parameter indicates the "
|
||||
"minimum length of the deviation for the decimation. "
|
||||
"\n0 to deactivate.");
|
||||
def->tooltip = L("The geometry will be decimated before detecting sharp angles. "
|
||||
"This parameter indicates the minimum length of the deviation for the decimation.\n"
|
||||
"0 to deactivate.");
|
||||
def->sidetext = "mm"; // milimeters, don't need translation
|
||||
def->min = 0;
|
||||
def->mode = comAdvanced;
|
||||
@@ -2114,8 +2115,8 @@ void PrintConfigDef::init_fff_params()
|
||||
|
||||
def = this->add("default_filament_colour", coStrings);
|
||||
def->label = L("Default color");
|
||||
def->tooltip = L("Default filament color"
|
||||
"\nRight click to reset value to system default.");
|
||||
def->tooltip = L("Default filament color.\n"
|
||||
"Right click to reset value to system default.");
|
||||
def->gui_type = ConfigOptionDef::GUIType::color;
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionStrings{""});
|
||||
@@ -2567,6 +2568,13 @@ void PrintConfigDef::init_fff_params()
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionBool(false));
|
||||
|
||||
def = this->add("extra_solid_infills", coString);
|
||||
def->label = L("Insert solid layers");
|
||||
def->category = L("Strength");
|
||||
def->tooltip = L("Insert solid infill at specific layers. Use N to insert every Nth layer, N#K to insert K consecutive solid layers every N layers (K is optional, e.g. '5#' equals '5#1'), or a comma-separated list (e.g. 1,7,9) to insert at explicit layers. Layers are 1-based.");
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionString());
|
||||
|
||||
|
||||
// Infill multiline
|
||||
def = this->add("fill_multiline", coInt);
|
||||
@@ -2816,7 +2824,7 @@ void PrintConfigDef::init_fff_params()
|
||||
|
||||
def = this->add("default_junction_deviation", coFloat);
|
||||
def->label = L("Junction Deviation");
|
||||
def->tooltip = L("Marlin Firmware Junction Deviation (replaces the traditional XY Jerk setting)");
|
||||
def->tooltip = L("Marlin Firmware Junction Deviation (replaces the traditional XY Jerk setting).");
|
||||
def->sidetext = "mm"; // milimeters, don't need translation
|
||||
def->min = 0;
|
||||
def->mode = comAdvanced;
|
||||
@@ -3044,7 +3052,7 @@ void PrintConfigDef::init_fff_params()
|
||||
"This is the fast and straight algorithm without unnecessary nozzle shake that gives a smooth pattern. "
|
||||
"But it is more useful for forming loose walls in the entire they array.\n"
|
||||
"Combined: Joint mode [Displacement] + [Extrusion]. The appearance of the walls is similar to [Displacement] Mode, but it leaves no pores between the perimeters.\n\n"
|
||||
"Attention! The [Extrusion] and [Combined] modes works only the fuzzy_skin_thickness parameter not more than the thickness of printed loop."
|
||||
"Attention! The [Extrusion] and [Combined] modes works only the fuzzy_skin_thickness parameter not more than the thickness of printed loop. "
|
||||
"At the same time, the width of the extrusion for a particular layer should also not be below a certain level. "
|
||||
"It is usually equal 15-25%% of a layer height. Therefore, the maximum fuzzy skin thickness with a perimeter width of 0.4 mm and a layer height of 0.2 mm will be 0.4-(0.2*0.25)=±0.35mm! "
|
||||
"If you enter a higher parameter than this, the error Flow::spacing() will displayed, and the model will not be sliced. You can choose this number until this error is repeated." );
|
||||
@@ -3366,35 +3374,37 @@ void PrintConfigDef::init_fff_params()
|
||||
|
||||
//Orca
|
||||
def = this->add("sparse_infill_rotate_template", coString);
|
||||
def->label = L("Sparse infill rotatation template");
|
||||
def->label = L("Sparse infill rotation template");
|
||||
def->category = L("Strength");
|
||||
def->tooltip = L("This parameter adds a rotation of sparse infill direction to each layer according to the specified template. "
|
||||
"The template is a comma-separated list of angles in degrees, e.g. '0,90'. "
|
||||
"The first angle is applied to the first layer, the second angle to the second layer, and so on. "
|
||||
"If there are more layers than angles, the angles will be repeated. Note that not all sparse infill patterns support rotation.");
|
||||
def->tooltip = L("Rotate the sparse infill direction per layer using a template of angles. "
|
||||
"Enter comma-separated degrees (e.g., '0,30,60,90'). "
|
||||
"Angles are applied in order by layer and repeat when the list ends. "
|
||||
"Advanced syntax is supported: '+5' rotates +5° every layer; '+5#5' rotates +5° every 5 layers. See the Wiki for details. "
|
||||
"When a template is set, the standard infill direction setting is ignored. "
|
||||
"Note: some infill patterns (e.g., Gyroid) control rotation themselves; use with care.");
|
||||
def->sidetext = L("°");
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionString("0,90"));
|
||||
def->set_default_value(new ConfigOptionString(""));
|
||||
|
||||
//Orca
|
||||
def = this->add("solid_infill_rotate_template", coString);
|
||||
def->label = L("Solid infill rotatation template");
|
||||
def->label = L("Solid infill rotation template");
|
||||
def->category = L("Strength");
|
||||
def->tooltip = L("This parameter adds a rotation of solid infill direction to each layer according to the specified template. "
|
||||
"The template is a comma-separated list of angles in degrees, e.g. '0,90'. "
|
||||
"The first angle is applied to the first layer, the second angle to the second layer, and so on. "
|
||||
"If there are more layers than angles, the angles will be repeated. Note that not all solid infill patterns support rotation.");
|
||||
def->sidetext = L("°");
|
||||
def->sidetext = "°"; // degrees, don't need translation
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionString("0,90"));
|
||||
|
||||
def->set_default_value(new ConfigOptionString(""));
|
||||
|
||||
def = this->add("skeleton_infill_density", coPercent);
|
||||
def->label = L("Skeleton infill density");
|
||||
def->category = L("Strength");
|
||||
def->tooltip = L("The remaining part of the model contour after removing a certain depth from the surface is called the skeleton. This parameter is used to adjust the density of this section."
|
||||
"When two regions have the same sparse infill settings but different skeleton densities, their skeleton areas will develop overlapping sections."
|
||||
"default is as same as infill density.");
|
||||
def->tooltip = L("The remaining part of the model contour after removing a certain depth from the surface is called the skeleton. "
|
||||
"This parameter is used to adjust the density of this section. "
|
||||
"When two regions have the same sparse infill settings but different skeleton densities, their skeleton areas will develop overlapping sections. "
|
||||
"Default is as same as infill density.");
|
||||
def->sidetext = "%";
|
||||
def->min = 0;
|
||||
def->max = 100;
|
||||
@@ -3404,9 +3414,10 @@ void PrintConfigDef::init_fff_params()
|
||||
def = this->add("skin_infill_density", coPercent);
|
||||
def->label = L("Skin infill density");
|
||||
def->category = L("Strength");
|
||||
def->tooltip = L("The portion of the model's outer surface within a certain depth range is called the skin. This parameter is used to adjust the density of this section."
|
||||
"When two regions have the same sparse infill settings but different skin densities, This area will not be split into two separate regions."
|
||||
"default is as same as infill density.");
|
||||
def->tooltip = L("The portion of the model's outer surface within a certain depth range is called the skin. "
|
||||
"This parameter is used to adjust the density of this section. "
|
||||
"When two regions have the same sparse infill settings but different skin densities, this area will not be split into two separate regions. "
|
||||
"Default is as same as infill density.");
|
||||
def->sidetext = "%";
|
||||
def->min = 0;
|
||||
def->max = 100;
|
||||
@@ -3454,9 +3465,9 @@ void PrintConfigDef::init_fff_params()
|
||||
def->set_default_value(new ConfigOptionFloatOrPercent(100, true));
|
||||
|
||||
def = this->add("symmetric_infill_y_axis", coBool);
|
||||
def->label = L("Symmetric infill y axis");
|
||||
def->label = L("Symmetric infill Y axis");
|
||||
def->category = L("Strength");
|
||||
def->tooltip = L("If the model has two parts that are symmetric about the y-axis,"
|
||||
def->tooltip = L("If the model has two parts that are symmetric about the Y axis,"
|
||||
" and you want these parts to have symmetric textures, please click this option on one of the parts.");
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionBool(false));
|
||||
@@ -3693,7 +3704,7 @@ void PrintConfigDef::init_fff_params()
|
||||
def = this->add("ironing_speed", coFloat);
|
||||
def->label = L("Ironing speed");
|
||||
def->category = L("Quality");
|
||||
def->tooltip = L("Print speed of ironing lines");
|
||||
def->tooltip = L("Print speed of ironing lines.");
|
||||
def->sidetext = "mm/s"; // milimeters per second, don't need translation
|
||||
def->min = 1;
|
||||
def->mode = comAdvanced;
|
||||
@@ -3858,7 +3869,7 @@ void PrintConfigDef::init_fff_params()
|
||||
def = this->add("machine_max_junction_deviation", coFloats);
|
||||
def->full_label = L("Maximum Junction Deviation");
|
||||
def->category = L("Machine limits");
|
||||
def->tooltip = L("Maximum junction deviation (M205 J, only apply if JD > 0 for Marlin Firmware)");
|
||||
def->tooltip = L("Maximum junction deviation (M205 J, only apply if JD > 0 for Marlin Firmware)");
|
||||
def->sidetext = "mm"; // milimeters, don't need translation
|
||||
def->min = 0;
|
||||
def->mode = comAdvanced;
|
||||
@@ -4044,7 +4055,7 @@ void PrintConfigDef::init_fff_params()
|
||||
|
||||
def = this->add("nozzle_diameter", coFloats);
|
||||
def->label = L("Nozzle diameter");
|
||||
def->tooltip = L("Diameter of nozzle");
|
||||
def->tooltip = L("The diameter of nozzle.");
|
||||
def->sidetext = "mm"; // milimeters, don't need translation
|
||||
def->mode = comAdvanced;
|
||||
def->max = 100;
|
||||
@@ -4218,7 +4229,7 @@ void PrintConfigDef::init_fff_params()
|
||||
def->gui_type = ConfigOptionDef::GUIType::i_enum_open;
|
||||
def->label = L("Walls");
|
||||
def->category = L("Extruders");
|
||||
def->tooltip = L("Filament to print walls");
|
||||
def->tooltip = L("Filament to print walls.");
|
||||
def->min = 1;
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionInt(1));
|
||||
@@ -4277,7 +4288,7 @@ void PrintConfigDef::init_fff_params()
|
||||
|
||||
def = this->add("printer_model", coString);
|
||||
def->label = L("Printer type");
|
||||
def->tooltip = L("Type of the printer");
|
||||
def->tooltip = L("Type of the printer.");
|
||||
def->set_default_value(new ConfigOptionString());
|
||||
def->cli = ConfigOptionDef::nocli;
|
||||
|
||||
@@ -4812,10 +4823,10 @@ void PrintConfigDef::init_fff_params()
|
||||
def->min = 0;
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionFloatOrPercent(80,true));
|
||||
|
||||
|
||||
def = this->add("skirt_distance", coFloat);
|
||||
def->label = L("Skirt distance");
|
||||
def->tooltip = L("Distance from skirt to brim or object");
|
||||
def->tooltip = L("The distance from the skirt to the brim or the object.");
|
||||
def->sidetext = "mm"; // milimeters, don't need translation
|
||||
def->min = 0;
|
||||
def->max = 60;
|
||||
@@ -4924,7 +4935,7 @@ void PrintConfigDef::init_fff_params()
|
||||
def->gui_type = ConfigOptionDef::GUIType::i_enum_open;
|
||||
def->label = L("Solid infill");
|
||||
def->category = L("Extruders");
|
||||
def->tooltip = L("Filament to print solid infill");
|
||||
def->tooltip = L("Filament to print solid infill.");
|
||||
def->min = 1;
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionInt(1));
|
||||
@@ -5089,7 +5100,7 @@ void PrintConfigDef::init_fff_params()
|
||||
|
||||
def = this->add("enable_filament_ramming", coBool);
|
||||
def->label = L("Enable filament ramming");
|
||||
def->tooltip = L("Enable filament ramming.");
|
||||
def->tooltip = L("Enable filament ramming");
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionBool(true));
|
||||
|
||||
@@ -5940,7 +5951,7 @@ void PrintConfigDef::init_fff_params()
|
||||
|
||||
def = this->add("wipe_tower_rotation_angle", coFloat);
|
||||
def->label = L("Wipe tower rotation angle");
|
||||
def->tooltip = L("Wipe tower rotation angle with respect to x-axis.");
|
||||
def->tooltip = L("Wipe tower rotation angle with respect to X axis.");
|
||||
def->sidetext = "°"; // degrees, don't need translation
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionFloat(0.));
|
||||
@@ -5994,7 +6005,7 @@ void PrintConfigDef::init_fff_params()
|
||||
|
||||
def = this->add("wipe_tower_extra_rib_length", coFloat);
|
||||
def->label = L("Extra rib length");
|
||||
def->tooltip = L("Positive values can increase the size of the rib wall, while negative values can reduce the size."
|
||||
def->tooltip = L("Positive values can increase the size of the rib wall, while negative values can reduce the size. "
|
||||
"However, the size of the rib wall can not be smaller than that determined by the cleaning volume.");
|
||||
def->sidetext = "mm"; // milimeters, don't need translation
|
||||
def->max = 300;
|
||||
@@ -6003,7 +6014,7 @@ void PrintConfigDef::init_fff_params()
|
||||
|
||||
def = this->add("wipe_tower_rib_width", coFloat);
|
||||
def->label = L("Rib width");
|
||||
def->tooltip = L("Rib width");
|
||||
def->tooltip = L("Rib width.");
|
||||
def->sidetext = "mm"; // milimeters, don't need translation
|
||||
def->mode = comAdvanced;
|
||||
def->min = 0;
|
||||
@@ -9345,7 +9356,7 @@ CLIMiscConfigDef::CLIMiscConfigDef()
|
||||
def->set_default_value(new ConfigOptionString());
|
||||
|
||||
def = this->add("load_filament_ids", coInts);
|
||||
def->label = L("Load filament ids");
|
||||
def->label = L("Load filament IDs");
|
||||
def->tooltip = L("Load filament IDs for each object.");
|
||||
def->cli_params = "\"1,2,3,1\"";
|
||||
def->set_default_value(new ConfigOptionInts());
|
||||
@@ -9373,25 +9384,25 @@ CLIMiscConfigDef::CLIMiscConfigDef()
|
||||
|
||||
def = this->add("makerlab_name", coString);
|
||||
def->label = L("MakerLab name");
|
||||
def->tooltip = L("MakerLab name to generate this 3mf");
|
||||
def->tooltip = L("MakerLab name to generate this 3mf.");
|
||||
def->cli_params = "name";
|
||||
def->set_default_value(new ConfigOptionString());
|
||||
|
||||
def = this->add("makerlab_version", coString);
|
||||
def->label = L("MakerLab version");
|
||||
def->tooltip = L("MakerLab version to generate this 3mf");
|
||||
def->tooltip = L("MakerLab version to generate this 3mf.");
|
||||
def->cli_params = "version";
|
||||
def->set_default_value(new ConfigOptionString());
|
||||
|
||||
def = this->add("metadata_name", coStrings);
|
||||
def->label = L("metadata name list");
|
||||
def->tooltip = L("metadata name list added into 3mf");
|
||||
def->tooltip = L("metadata name list added into 3mf.");
|
||||
def->cli_params = "\"name1;name2;...\"";
|
||||
def->set_default_value(new ConfigOptionStrings());
|
||||
|
||||
def = this->add("metadata_value", coStrings);
|
||||
def->label = L("metadata value list");
|
||||
def->tooltip = L("metadata value list added into 3mf");
|
||||
def->tooltip = L("metadata value list added into 3mf.");
|
||||
def->cli_params = "\"value1;value2;...\"";
|
||||
def->set_default_value(new ConfigOptionStrings());
|
||||
|
||||
@@ -9741,11 +9752,11 @@ CustomGcodeSpecificConfigDef::CustomGcodeSpecificConfigDef()
|
||||
def->tooltip = L("Index of the current layer. One-based (i.e. first layer is number 1).");
|
||||
|
||||
def = this->add("layer_z", coFloat);
|
||||
def->label = L("Layer z");
|
||||
def->label = L("Layer Z");
|
||||
def->tooltip = L("Height of the current layer above the print bed, measured to the top of the layer.");
|
||||
|
||||
def = this->add("max_layer_z", coFloat);
|
||||
def->label = L("Maximal layer z");
|
||||
def->label = L("Maximal layer Z");
|
||||
def->tooltip = L("Height of the last layer above the print bed.");
|
||||
|
||||
def = this->add("filament_extruder_id", coInt);
|
||||
@@ -9755,32 +9766,32 @@ CustomGcodeSpecificConfigDef::CustomGcodeSpecificConfigDef()
|
||||
// change_filament_gcode
|
||||
new_def("previous_extruder", coInt, "Previous extruder", "Index of the extruder that is being unloaded. The index is zero based (first extruder has index 0).");
|
||||
new_def("next_extruder", coInt, "Next extruder", "Index of the extruder that is being loaded. The index is zero based (first extruder has index 0).");
|
||||
new_def("relative_e_axis", coBool, "Relative e-axis", "Indicates if relative positioning is being used");
|
||||
new_def("toolchange_count", coInt, "Toolchange count", "The number of toolchanges throught the print");
|
||||
new_def("relative_e_axis", coBool, "Relative e-axis", "Indicates if relative positioning is being used.");
|
||||
new_def("toolchange_count", coInt, "Toolchange count", "The number of toolchanges throught the print.");
|
||||
new_def("fan_speed", coNone, "", ""); //Option is no longer used and is zeroed by placeholder parser for compatability
|
||||
new_def("old_retract_length", coFloat, "Old retract length", "The retraction length of the previous filament");
|
||||
new_def("new_retract_length", coFloat, "New retract length", "The retraction lenght of the new filament");
|
||||
new_def("old_retract_length_toolchange", coFloat, "Old retract length toolchange", "The toolchange retraction length of the previous filament");
|
||||
new_def("new_retract_length_toolchange", coFloat, "New retract length toolchange", "The toolchange retraction length of the new filament");
|
||||
new_def("old_filament_temp", coInt, "Old filament temp", "The old filament temp");
|
||||
new_def("new_filament_temp", coInt, "New filament temp", "The new filament temp");
|
||||
new_def("x_after_toolchange", coFloat, "X after toolchange", "The x pos after toolchange");
|
||||
new_def("y_after_toolchange", coFloat, "Y after toolchange", "The y pos after toolchange");
|
||||
new_def("z_after_toolchange", coFloat, "Z after toolchange", "The z pos after toolchange");
|
||||
new_def("first_flush_volume", coFloat, "First flush volume", "The first flush volume");
|
||||
new_def("second_flush_volume", coFloat, "Second flush volume", "The second flush volume");
|
||||
new_def("old_filament_e_feedrate", coInt, "Old filament e feedrate", "The old filament extruder feedrate");
|
||||
new_def("new_filament_e_feedrate", coInt, "New filament e feedrate", "The new filament extruder feedrate");
|
||||
new_def("travel_point_1_x", coFloat, "Travel point 1 x", "The travel point 1 x");
|
||||
new_def("travel_point_1_y", coFloat, "Travel point 1 y", "The travel point 1 y");
|
||||
new_def("travel_point_2_x", coFloat, "Travel point 2 x", "The travel point 2 x");
|
||||
new_def("travel_point_2_y", coFloat, "Travel point 2 y", "The travel point 2 y");
|
||||
new_def("travel_point_3_x", coFloat, "Travel point 3 x", "The travel point 3 x");
|
||||
new_def("travel_point_3_y", coFloat, "Travel point 3 y", "The travel point 3 y");
|
||||
new_def("flush_length_1", coFloat, "Flush Length 1", "The first flush length");
|
||||
new_def("flush_length_2", coFloat, "Flush Length 2", "The second flush length");
|
||||
new_def("flush_length_3", coFloat, "Flush Length 3", "The third flush length");
|
||||
new_def("flush_length_4", coFloat, "Flush Length 4", "The fourth flush length");
|
||||
new_def("old_retract_length", coFloat, "Old retract length", "The retraction length of the previous filament.");
|
||||
new_def("new_retract_length", coFloat, "New retract length", "The retraction lenght of the new filament.");
|
||||
new_def("old_retract_length_toolchange", coFloat, "Old retract length toolchange", "The toolchange retraction length of the previous filament.");
|
||||
new_def("new_retract_length_toolchange", coFloat, "New retract length toolchange", "The toolchange retraction length of the new filament.");
|
||||
new_def("old_filament_temp", coInt, "Old filament temp", "The old filament temp.");
|
||||
new_def("new_filament_temp", coInt, "New filament temp", "The new filament temp.");
|
||||
new_def("x_after_toolchange", coFloat, "X after toolchange", "The X pos after toolchange.");
|
||||
new_def("y_after_toolchange", coFloat, "Y after toolchange", "The Y pos after toolchange.");
|
||||
new_def("z_after_toolchange", coFloat, "Z after toolchange", "The Z pos after toolchange.");
|
||||
new_def("first_flush_volume", coFloat, "First flush volume", "The first flush volume.");
|
||||
new_def("second_flush_volume", coFloat, "Second flush volume", "The second flush volume.");
|
||||
new_def("old_filament_e_feedrate", coInt, "Old filament e feedrate", "The old filament extruder feedrate.");
|
||||
new_def("new_filament_e_feedrate", coInt, "New filament e feedrate", "The new filament extruder feedrate.");
|
||||
new_def("travel_point_1_x", coFloat, "Travel point 1 X", "The travel point 1 X.");
|
||||
new_def("travel_point_1_y", coFloat, "Travel point 1 Y", "The travel point 1 Y.");
|
||||
new_def("travel_point_2_x", coFloat, "Travel point 2 X", "The travel point 2 X.");
|
||||
new_def("travel_point_2_y", coFloat, "Travel point 2 Y", "The travel point 2 Y.");
|
||||
new_def("travel_point_3_x", coFloat, "Travel point 3 X", "The travel point 3 X.");
|
||||
new_def("travel_point_3_y", coFloat, "Travel point 3 Y", "The travel point 3 Y.");
|
||||
new_def("flush_length_1", coFloat, "Flush Length 1", "The first flush length.");
|
||||
new_def("flush_length_2", coFloat, "Flush Length 2", "The second flush length.");
|
||||
new_def("flush_length_3", coFloat, "Flush Length 3", "The third flush length.");
|
||||
new_def("flush_length_4", coFloat, "Flush Length 4", "The fourth flush length.");
|
||||
|
||||
// change_extrusion_role_gcode
|
||||
std::string extrusion_role_types = "Possible Values:\n[\"Perimeter\", \"ExternalPerimeter\", "
|
||||
|
||||
@@ -1044,6 +1044,7 @@ PRINT_CONFIG_CLASS_DEFINE(
|
||||
((ConfigOptionFloat, lateral_lattice_angle_2))
|
||||
((ConfigOptionFloat, infill_overhang_angle))
|
||||
((ConfigOptionBool, align_infill_direction_to_model))
|
||||
((ConfigOptionString, extra_solid_infills))
|
||||
((ConfigOptionEnum<FuzzySkinType>, fuzzy_skin))
|
||||
((ConfigOptionFloat, fuzzy_skin_thickness))
|
||||
((ConfigOptionFloat, fuzzy_skin_point_distance))
|
||||
|
||||
@@ -1203,6 +1203,7 @@ bool PrintObject::invalidate_state_by_config_options(
|
||||
|| opt_key == "infill_direction"
|
||||
|| opt_key == "solid_infill_direction"
|
||||
|| opt_key == "align_infill_direction_to_model"
|
||||
|| opt_key == "extra_solid_infills"
|
||||
|| opt_key == "ensure_vertical_shell_thickness"
|
||||
|| opt_key == "bridge_angle"
|
||||
|| opt_key == "internal_bridge_angle" // ORCA: Internal bridge angle override
|
||||
@@ -1268,7 +1269,6 @@ bool PrintObject::invalidate_state_by_config_options(
|
||||
|| opt_key == "overhang_reverse_internal_only"
|
||||
|| opt_key == "overhang_reverse_threshold"
|
||||
|| opt_key == "wall_direction"
|
||||
//BBS
|
||||
|| opt_key == "enable_overhang_speed"
|
||||
|| opt_key == "detect_thin_wall"
|
||||
|| opt_key == "precise_outer_wall") {
|
||||
@@ -3613,16 +3613,14 @@ void PrintObject::discover_horizontal_shells()
|
||||
Layer *layer = m_layers[i];
|
||||
LayerRegion *layerm = layer->regions()[region_id];
|
||||
const PrintRegionConfig ®ion_config = layerm->region().config();
|
||||
#if 0
|
||||
if (region_config.solid_infill_every_layers.value > 0 && region_config.sparse_infill_density.value > 0 &&
|
||||
(i % region_config.solid_infill_every_layers) == 0) {
|
||||
// Insert a solid internal layer. Mark stInternal surfaces as stInternalSolid or stInternalBridge.
|
||||
SurfaceType type = (region_config.sparse_infill_density == 100 || region_config.solid_infill_every_layers == 1) ? stInternalSolid : stInternalBridge;
|
||||
for (Surface &surface : layerm->fill_surfaces.surfaces)
|
||||
|
||||
if (!region_config.extra_solid_infills.value.empty() &&
|
||||
check_layer_id_pattern(region_config.extra_solid_infills.value, i)) {
|
||||
// Insert a solid internal layer. Mark stInternal surfaces as stInternalSolid.
|
||||
for (Surface& surface : layerm->fill_surfaces.surfaces)
|
||||
if (surface.surface_type == stInternal)
|
||||
surface.surface_type = type;
|
||||
surface.surface_type = stInternalSolid;
|
||||
}
|
||||
#endif
|
||||
|
||||
// If ensure_vertical_shell_thickness, then the rest has already been performed by discover_vertical_shells().
|
||||
if (region_config.ensure_vertical_shell_thickness.value == evstAll)
|
||||
|
||||
@@ -695,6 +695,8 @@ void copy_directory_recursively(const boost::filesystem::path &source, const boo
|
||||
void save_string_file(const boost::filesystem::path& p, const std::string& str);
|
||||
void load_string_file(const boost::filesystem::path& p, std::string& str);
|
||||
|
||||
bool check_layer_id_pattern(const std::string& pattern, int layer_id);
|
||||
|
||||
} // namespace Slic3r
|
||||
|
||||
#if WIN32
|
||||
|
||||
@@ -1578,4 +1578,91 @@ void load_string_file(const boost::filesystem::path& p, std::string& str)
|
||||
file.read(&str[0], sz);
|
||||
}
|
||||
|
||||
// pattern string supprt these pattern: "
|
||||
// 1. 5#1, insert 1 solid layer every 5 layers. this can be simplified to 5
|
||||
// 2."1,7,9", explicitly insert solid layer at layer 1, 7, 9
|
||||
bool check_layer_id_pattern(const std::string& pattern, int layer_id){
|
||||
if (pattern.empty() || layer_id < 0)
|
||||
return false;
|
||||
|
||||
// layer_id is 0-based, so we need to add 1 to make it 1-based
|
||||
layer_id++;
|
||||
|
||||
// Remove whitespace and surrounding quotes.
|
||||
std::string p; p.reserve(pattern.size());
|
||||
for (char c : pattern) {
|
||||
if (c == ' ' || c == '\t' || c == '\n' || c == '\r')
|
||||
continue;
|
||||
p.push_back(c);
|
||||
}
|
||||
if (!p.empty() && (p.front() == '"' || p.front() == '\''))
|
||||
p.erase(p.begin());
|
||||
if (!p.empty() && (p.back() == '"' || p.back() == '\''))
|
||||
p.pop_back();
|
||||
if (p.empty())
|
||||
return false;
|
||||
|
||||
// Explicit list form: "1,7,9" or with counts per entry: "5,9#2,18"
|
||||
if (p.find(',') != std::string::npos) {
|
||||
size_t start = 0;
|
||||
while (start < p.size()) {
|
||||
size_t end = p.find(',', start);
|
||||
std::string token = p.substr(start, (end == std::string::npos) ? std::string::npos : end - start);
|
||||
if (!token.empty()) {
|
||||
try {
|
||||
size_t hash_pos_token = token.find('#');
|
||||
if (hash_pos_token == std::string::npos) {
|
||||
int value = std::stoi(token);
|
||||
if (value == layer_id)
|
||||
return true;
|
||||
} else {
|
||||
int base_layer = std::stoi(token.substr(0, hash_pos_token));
|
||||
std::string count_str = token.substr(hash_pos_token + 1);
|
||||
int local_count = 1;
|
||||
if (!count_str.empty())
|
||||
local_count = std::stoi(count_str);
|
||||
if (base_layer > 0 && local_count > 0) {
|
||||
if (layer_id >= base_layer && layer_id < base_layer + local_count)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} catch (...) {
|
||||
// Ignore invalid tokens
|
||||
}
|
||||
}
|
||||
if (end == std::string::npos)
|
||||
break;
|
||||
start = end + 1;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Interval form: "N#K" or simplified "N" (equals to N#1)
|
||||
int interval = 0;
|
||||
int count = 1;
|
||||
size_t hash_pos = p.find('#');
|
||||
try {
|
||||
if (hash_pos == std::string::npos) {
|
||||
interval = std::stoi(p);
|
||||
} else {
|
||||
interval = std::stoi(p.substr(0, hash_pos));
|
||||
std::string count_str = p.substr(hash_pos + 1);
|
||||
if (!count_str.empty())
|
||||
count = std::stoi(count_str);
|
||||
}
|
||||
} catch (...) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (interval <= 0 || count <= 0)
|
||||
return false;
|
||||
|
||||
// Layers are 1-based. Match layers interval, interval+1, ..., interval+count-1, then repeat every interval.
|
||||
if (layer_id < interval)
|
||||
return false;
|
||||
int mod = layer_id % interval; // For multiples, mod == 0
|
||||
return mod >= 0 && mod < count;
|
||||
}
|
||||
|
||||
|
||||
}; // namespace Slic3r
|
||||
|
||||
@@ -230,20 +230,17 @@ void Bed3D::Axes::render()
|
||||
shader->start_using();
|
||||
//shader->set_uniform("emission_factor", 0.0f);
|
||||
|
||||
// ORCA show axes on current plate
|
||||
Vec3d plate_origin = wxGetApp().plater()->get_partplate_list().get_selected_plate()->get_origin();
|
||||
|
||||
// x axis
|
||||
m_arrow.set_color(AXIS_X_COLOR);
|
||||
render_axis(shader, Geometry::assemble_transform(plate_origin, { 0.0, 0.5 * M_PI, 0.0 }));
|
||||
render_axis(shader, Geometry::assemble_transform(m_origin, { 0.0, 0.5 * M_PI, 0.0 }));
|
||||
|
||||
// y axis
|
||||
m_arrow.set_color(AXIS_Y_COLOR);
|
||||
render_axis(shader, Geometry::assemble_transform(plate_origin, { -0.5 * M_PI, 0.0, 0.0 }));
|
||||
render_axis(shader, Geometry::assemble_transform(m_origin, { -0.5 * M_PI, 0.0, 0.0 }));
|
||||
|
||||
// z axis
|
||||
m_arrow.set_color(AXIS_Z_COLOR);
|
||||
render_axis(shader, Geometry::assemble_transform(plate_origin));
|
||||
render_axis(shader, Geometry::assemble_transform(m_origin));
|
||||
|
||||
shader->stop_using();
|
||||
|
||||
|
||||
@@ -131,7 +131,7 @@ void ConfigManipulation::check_filament_max_volumetric_speed(DynamicPrintConfig
|
||||
float max_volumetric_speed = config->has("filament_max_volumetric_speed") ? config->opt_float("filament_max_volumetric_speed", (float) 0.5) : 0.5;
|
||||
// BBS: limite the min max_volumetric_speed
|
||||
if (max_volumetric_speed < 0.5) {
|
||||
const wxString msg_text = _(L("Too small max volumetric speed.\nReset to 0.5"));
|
||||
const wxString msg_text = _(L("Too small max volumetric speed.\nReset to 0.5."));
|
||||
MessageDialog dialog(nullptr, msg_text, "", wxICON_WARNING | wxOK);
|
||||
DynamicPrintConfig new_conf = *config;
|
||||
is_msg_dlg_already_exist = true;
|
||||
@@ -188,7 +188,7 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con
|
||||
auto gpreset = GUI::wxGetApp().preset_bundle->printers.get_edited_preset();
|
||||
if (layer_height < EPSILON)
|
||||
{
|
||||
const wxString msg_text = _(L("Too small layer height.\nReset to 0.2"));
|
||||
const wxString msg_text = _(L("Too small layer height.\nReset to 0.2."));
|
||||
MessageDialog dialog(m_msg_dlg_parent, msg_text, "", wxICON_WARNING | wxOK);
|
||||
DynamicPrintConfig new_conf = *config;
|
||||
is_msg_dlg_already_exist = true;
|
||||
@@ -202,7 +202,7 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con
|
||||
auto max_lh = gpreset.config.opt_float("max_layer_height",0);
|
||||
if (max_lh > 0.2 && layer_height > max_lh+ EPSILON)
|
||||
{
|
||||
const wxString msg_text = wxString::Format(L"Too large layer height.\nReset to %0.3f", max_lh);
|
||||
const wxString msg_text = wxString::Format(L"Too large layer height.\nReset to %0.3f.", max_lh);
|
||||
MessageDialog dialog(nullptr, msg_text, "", wxICON_WARNING | wxOK);
|
||||
DynamicPrintConfig new_conf = *config;
|
||||
is_msg_dlg_already_exist = true;
|
||||
@@ -215,7 +215,7 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con
|
||||
//BBS: ironing_spacing shouldn't be too small or equal to zero
|
||||
if (config->opt_float("ironing_spacing") < 0.05)
|
||||
{
|
||||
const wxString msg_text = _(L("Too small ironing spacing.\nReset to 0.1"));
|
||||
const wxString msg_text = _(L("Too small ironing spacing.\nReset to 0.1."));
|
||||
MessageDialog dialog(nullptr, msg_text, "", wxICON_WARNING | wxOK);
|
||||
DynamicPrintConfig new_conf = *config;
|
||||
is_msg_dlg_already_exist = true;
|
||||
@@ -226,7 +226,7 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con
|
||||
}
|
||||
if (config->opt_float("support_ironing_spacing") < 0.05)
|
||||
{
|
||||
const wxString msg_text = _(L("Too small ironing spacing.\nReset to 0.1"));
|
||||
const wxString msg_text = _(L("Too small ironing spacing.\nReset to 0.1."));
|
||||
MessageDialog dialog(nullptr, msg_text, "", wxICON_WARNING | wxOK);
|
||||
DynamicPrintConfig new_conf = *config;
|
||||
is_msg_dlg_already_exist = true;
|
||||
@@ -477,7 +477,7 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con
|
||||
// layer_height shouldn't be equal to zero
|
||||
float skin_depth = config->opt_float("skin_infill_depth");
|
||||
if (config->opt_float("infill_lock_depth") > skin_depth) {
|
||||
const wxString msg_text = _(L("lock depth should smaller than skin depth.\nReset to 50% of skin depth"));
|
||||
const wxString msg_text = _(L("Lock depth should smaller than skin depth.\nReset to 50% of skin depth."));
|
||||
MessageDialog dialog(m_msg_dlg_parent, msg_text, "", wxICON_WARNING | wxOK);
|
||||
DynamicPrintConfig new_conf = *config;
|
||||
is_msg_dlg_already_exist = true;
|
||||
@@ -883,20 +883,9 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, co
|
||||
for (auto el : { "lateral_lattice_angle_1", "lateral_lattice_angle_2"})
|
||||
toggle_line(el, lattice_options);
|
||||
|
||||
//Orca: hide rotate template for solid infill if not support
|
||||
const auto _sparse_infill_pattern = config->option<ConfigOptionEnum<InfillPattern>>("sparse_infill_pattern")->value;
|
||||
bool show_sparse_infill_rotate_template = _sparse_infill_pattern == ipRectilinear || _sparse_infill_pattern == ipLine ||
|
||||
_sparse_infill_pattern == ipZigZag || _sparse_infill_pattern == ipCrossZag ||
|
||||
_sparse_infill_pattern == ipLockedZag;
|
||||
|
||||
toggle_line("sparse_infill_rotate_template", show_sparse_infill_rotate_template);
|
||||
|
||||
//Orca: hide rotate template for solid infill if not support
|
||||
const auto _solid_infill_pattern = config->option<ConfigOptionEnum<InfillPattern>>("internal_solid_infill_pattern")->value;
|
||||
bool show_solid_infill_rotate_template = _solid_infill_pattern == ipRectilinear || _solid_infill_pattern == ipMonotonic ||
|
||||
_solid_infill_pattern == ipMonotonicLine || _solid_infill_pattern == ipAlignedRectilinear;
|
||||
|
||||
toggle_line("solid_infill_rotate_template", show_solid_infill_rotate_template);
|
||||
//Orca: disable infill_direction/solid_infill_direction if sparse_infill_rotate_template/solid_infill_rotate_template is not empty value
|
||||
toggle_field("infill_direction", config->opt_string("sparse_infill_rotate_template") == "");
|
||||
toggle_field("solid_infill_direction", config->opt_string("solid_infill_rotate_template") == "");
|
||||
|
||||
|
||||
toggle_line("infill_overhang_angle", config->opt_enum<InfillPattern>("sparse_infill_pattern") == InfillPattern::ipLateralHoneycomb);
|
||||
|
||||
@@ -3547,7 +3547,7 @@ std::string ExportConfigsDialog::initial_file_name(const wxString &path, const s
|
||||
}
|
||||
catch(...) {
|
||||
MessageDialog dlg(this,
|
||||
wxString::Format(_L("The file: %s \nmay have been opened by another program. \nPlease close it and try again."),
|
||||
wxString::Format(_L("The file: %s\nmay have been opened by another program.\nPlease close it and try again."),
|
||||
encode_path(printer_export_path.string().c_str())),
|
||||
wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Info"), wxYES | wxYES_DEFAULT | wxCENTRE);
|
||||
dlg.ShowModal();
|
||||
|
||||
@@ -437,15 +437,9 @@ void Field::get_value_by_opt_type(wxString& str, const bool check_value/* = true
|
||||
string v;
|
||||
std::smatch match;
|
||||
string ps = (m_opt.opt_key == "sparse_infill_rotate_template") ?
|
||||
u8"[SODMR]?[BT][!]?|[SODMR]?[#][\\d]+[!]?|[+\\-]?[\\d.]+[%]?[*]?[\\d]*[SODMR]?[/NnZz$LlUuQq~^|#]?[+\\-]?[\\d.]*[%#\'\"cm]?[m]?[BT]?[!*]?" :
|
||||
u8"[BT][!]?|[#][\\d]+[!]?|[+\\-]?[\\d.]+[%]?[*]?[\\d]*[/NnZz$LlUuQq~^|#]?[+\\-]?[\\d.]*[%#\'\"cm]?[m]?[BT]?[!*]?" :
|
||||
u8"[#][\\d]+[!]?|[+\\-]?[\\d.]+[%]?[*]?[\\d]*[/NnZz$LlUuQq~^|#]?[+\\-]?[\\d.]*[%#\'\"cm]?[m]?[!*]?";
|
||||
|
||||
//if (m_opt.opt_key == "sparse_infill_rotate_template") {
|
||||
//string ps = u8"[#][\\d]+[!]?|[+\\-]?[\\d.]+[%]?[*]?[\\d]*[SODMR]?[/NnZz$LlUuQq~^|#]?[+\\-]?[\\d.]*[%#\'\"cm]?[m]?[";
|
||||
//if (m_opt.opt_key == "sparse_infill_rotate_template") {
|
||||
// ps = u8"[BT][!]?|" + ps ;
|
||||
//}
|
||||
//ps += u8"BT]?[!*]?";
|
||||
while (std::regex_search(ustr, match, std::regex(ps))) {
|
||||
for (auto x : match) v += x.str() + ", ";
|
||||
ustr = match.suffix().str();
|
||||
@@ -458,13 +452,27 @@ void Field::get_value_by_opt_type(wxString& str, const bool check_value/* = true
|
||||
show_error(m_parent, format_wxstr(_L("This parameter expects a valid template.")));
|
||||
wxString old_value(boost::any_cast<std::string>(m_value));
|
||||
this->set_value(old_value, true); // Revert to previous value
|
||||
throw;
|
||||
}
|
||||
} else {
|
||||
// Valid string, so update m_value with the new string from the control.
|
||||
m_value = into_u8(str);
|
||||
}
|
||||
break;
|
||||
} else if (m_opt.opt_key == "extra_solid_infills") {
|
||||
string ustr(str.utf8_string());
|
||||
// New rule: accept either interval form (N or N#K) or explicit list (e.g. 1,7,9), with optional quotes.
|
||||
const std::regex rx_interval(u8R"(^\s*['"]?\s*\d+\s*(?:#\s*\d*)?\s*['"]?\s*$)");
|
||||
// List entries may be plain numbers or number with optional #K count, e.g., 5, 9#2, 18
|
||||
const std::regex rx_list(u8R"(^\s*['"]?\s*\d+(?:\s*#\s*\d*)?(?:\s*,\s*\d+(?:\s*#\s*\d*)?)*\s*['"]?\s*$)");
|
||||
bool is_valid = ustr.empty() || std::regex_match(ustr, rx_interval) || std::regex_match(ustr, rx_list);
|
||||
if (!is_valid) {
|
||||
show_error(m_parent, format_wxstr(_L("Invalid pattern. Use N, N#K, or a comma-separated list with optional #K per entry. Examples: 5, 5#2, 1,7,9, 5,9#2,18.")));
|
||||
wxString old_value(boost::any_cast<std::string>(m_value));
|
||||
this->set_value(old_value, true); // Revert to previous value
|
||||
}
|
||||
// Valid string or empty, so update m_value with the new string from the control.
|
||||
m_value = into_u8(str);
|
||||
break;
|
||||
}
|
||||
|
||||
m_value = into_u8(str);
|
||||
|
||||
@@ -4676,6 +4676,7 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv
|
||||
const ColorRGBA& color,
|
||||
const std::vector<std::pair<std::string, float>>& columns_offsets,
|
||||
bool checkbox = true,
|
||||
float checkbox_pos = 0.f, // ORCA use calculated value for eye icon. Aligned to "Display" header or end of combo box
|
||||
bool visible = true,
|
||||
std::function<void()> callback = nullptr)
|
||||
{
|
||||
@@ -4728,14 +4729,14 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv
|
||||
if (b_menu_item)
|
||||
callback();
|
||||
if (checkbox) {
|
||||
//ImGui::SameLine(ImGui::GetWindowWidth() - ImGui::CalcTextSize(_u8L("Display").c_str()).x / 2 - ImGui::GetFrameHeight() / 2 - 2 * window_padding);
|
||||
//ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0, 0.0));
|
||||
//ImGui::PushStyleColor(ImGuiCol_CheckMark, ImVec4(0.00f, 0.59f, 0.53f, 1.00f));
|
||||
//ImGui::Checkbox(("##" + columns_offsets[0].first).c_str(), &visible);
|
||||
//ImGui::PopStyleVar(1);
|
||||
// ORCA replace checkboxes with eye icon
|
||||
ImGui::SameLine(ImGui::GetWindowWidth() - (16.f + 6.f) * m_scale - window_padding * 2 - (ImGui::GetScrollMaxY() > 0.0f ? ImGui::GetStyle().ScrollbarSize : 0));
|
||||
// Use calculated position from argument. this method has predictable result compared to alingning button using window width
|
||||
// fixes slowly resizing window and endlessly expanding window when there is a miscalculation on position
|
||||
ImGui::SameLine(checkbox_pos);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0, 0.0)); // ensure no padding active
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0, 0.0)); // ensure no item spacing active
|
||||
ImGui::Text(into_u8(visible ? ImGui::VisibleIcon : ImGui::HiddenIcon).c_str(), ImVec2(16 * m_scale, 16 * m_scale));
|
||||
ImGui::PopStyleVar(2);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4785,7 +4786,7 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv
|
||||
for (size_t i = 0; i < title_offsets.size(); i++) {
|
||||
if (title_offsets[i].first == _u8L("Display")) { // ORCA Hide Display header
|
||||
ImGui::SameLine(title_offsets[i].second);
|
||||
ImGui::Dummy({16.f * m_scale, 1}); // 16(icon)
|
||||
ImGui::Dummy({16.f * m_scale, 1}); // 16(icon_size)
|
||||
continue;
|
||||
}
|
||||
ImGui::SameLine(title_offsets[i].second);
|
||||
@@ -4809,16 +4810,11 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv
|
||||
const ImGuiStyle& style = ImGui::GetStyle();
|
||||
std::vector<float> offsets;
|
||||
// ORCA increase spacing for more readable format. Using direct number requires much less code change in here. GetTextLineHeight for additional spacing for icon_size
|
||||
offsets.push_back(max_width(title_columns[0].second, title_columns[0].first, extra_size) + 12.f * m_scale + ImGui::GetTextLineHeight());
|
||||
for (size_t i = 1; i < title_columns.size() - 1; i++)
|
||||
offsets.push_back(offsets.back() + max_width(title_columns[i].second, title_columns[i].first) + 12.f * m_scale); // ORCA increase spacing for more readable format. Using direct number requires much less code change in here
|
||||
if (title_columns.back().first == _u8L("Display")) {
|
||||
//const auto preferred_offset = ImGui::GetWindowWidth() - ImGui::CalcTextSize(_u8L("Display").c_str()).x - ImGui::GetFrameHeight() / 2 - 2 * window_padding - ImGui::GetStyle().ScrollbarSize;
|
||||
const auto preferred_offset = ImGui::GetWindowWidth() - (16.f - 6.f) * m_scale - ImGui::GetFrameHeight() / 2 - 2 * window_padding - (ImGui::GetScrollMaxY() > 0.0f ? ImGui::GetStyle().ScrollbarSize : 0);
|
||||
if (preferred_offset > offsets.back()) {
|
||||
offsets.back() = preferred_offset;
|
||||
}
|
||||
}
|
||||
offsets.push_back(max_width(title_columns[0].second, title_columns[0].first, extra_size) + 12.f * m_scale + ImGui::GetTextLineHeight());
|
||||
for (size_t i = 1; i < title_columns.size() - 1; i++) // ORCA dont add extra spacing after icon / "Display" header
|
||||
offsets.push_back(offsets.back() + max_width(title_columns[i].second, title_columns[i].first) + ((title_columns[i].first == _u8L("Display") ? 0 : 12.f) * m_scale));
|
||||
if (title_columns.back().first == _u8L("Display") && title_columns.size() > 2)
|
||||
offsets[title_columns.size() - 2] -= 3.f; // ORCA reduce spacing after previous header
|
||||
|
||||
float average_col_width = ImGui::GetWindowWidth() / static_cast<float>(title_columns.size());
|
||||
std::vector<float> ret;
|
||||
@@ -4985,6 +4981,8 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv
|
||||
}
|
||||
pop_combo_style();
|
||||
ImGui::SameLine(0, window_padding); // ORCA Without (0,window_padding) it adds unnecessary item spacing after combo box
|
||||
// ORCA predictable_icon_pos helpful when window size determined by combo box.
|
||||
float predictable_icon_pos = ImGui::GetCursorPosX() - icon_size - window_padding - ImGui::GetStyle().ItemSpacing.x - 1.f * m_scale; // 1 for border
|
||||
ImGui::Dummy({ window_padding, window_padding });
|
||||
ImGui::Dummy({ window_padding, window_padding }); // ORCA Matches top-bottom window paddings
|
||||
float window_width = ImGui::GetWindowWidth(); // ORCA Store window width
|
||||
@@ -5192,6 +5190,7 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv
|
||||
if ((displayed_columns & ~ColumnData::Model) > 0) {
|
||||
title_columns.push_back({ _u8L("Total"), total_filaments });
|
||||
}
|
||||
title_columns.push_back({ _u8L("Display"), {""}}); // ORCA Add spacing for eye icon. used as color_print_offsets[_u8L("Display")]
|
||||
auto offsets_ = calculate_offsets(title_columns, icon_size);
|
||||
std::vector<std::pair<std::string, float>> title_offsets;
|
||||
for (int i = 0; i < offsets_.size(); i++) {
|
||||
@@ -5207,7 +5206,7 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv
|
||||
|
||||
auto append_option_item = [this, append_item](EMoveType type, std::vector<float> offsets) {
|
||||
auto append_option_item_with_type = [this, offsets, append_item](EMoveType type, const ColorRGBA& color, const std::string& label, bool visible) {
|
||||
append_item(EItemType::Rect, color, {{ label , offsets[0] }}, true, visible, [this, type, visible]() {
|
||||
append_item(EItemType::Rect, color, {{ label , offsets[0] }}, true, offsets.back()/*ORCA checkbox_pos*/, visible, [this, type, visible]() {
|
||||
m_buffers[buffer_id(type)].visible = !m_buffers[buffer_id(type)].visible;
|
||||
// update buffers' render paths
|
||||
refresh_render_paths(false, false);
|
||||
@@ -5249,7 +5248,7 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv
|
||||
columns_offsets.push_back({used_filaments_length[i], offsets[3]});
|
||||
columns_offsets.push_back({used_filaments_weight[i], offsets[4]});
|
||||
append_item(EItemType::Rect, Extrusion_Role_Colors[static_cast<unsigned int>(role)], columns_offsets,
|
||||
true, visible, [this, role, visible]() {
|
||||
true, offsets.back(), visible, [this, role, visible]() {
|
||||
m_extrusions.role_visibility_flags = visible ? m_extrusions.role_visibility_flags & ~(1 << role) : m_extrusions.role_visibility_flags | (1 << role);
|
||||
// update buffers' render paths
|
||||
refresh_render_paths(false, false);
|
||||
@@ -5268,7 +5267,7 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv
|
||||
columns_offsets.push_back({ _u8L("Travel"), offsets[0] });
|
||||
columns_offsets.push_back({ travel_time, offsets[1] });
|
||||
columns_offsets.push_back({ travel_percent, offsets[2] });
|
||||
append_item(EItemType::Rect, Travel_Colors[0], columns_offsets, true, visible, [this, item, visible]() {
|
||||
append_item(EItemType::Rect, Travel_Colors[0], columns_offsets, true, offsets.back()/*ORCA checkbox_pos*/, visible, [this, item, visible]() {
|
||||
m_buffers[buffer_id(item)].visible = !m_buffers[buffer_id(item)].visible;
|
||||
// update buffers' render paths
|
||||
refresh_render_paths(false, false);
|
||||
@@ -5290,7 +5289,7 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv
|
||||
append_headers({ {_u8L("Options"), offsets[0] }, { _u8L("Display"), offsets[1]} });
|
||||
const bool travel_visible = m_buffers[buffer_id(EMoveType::Travel)].visible;
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, 3.0f));
|
||||
append_item(EItemType::None, Travel_Colors[0], { {_u8L("travel"), offsets[0] }}, true, travel_visible, [this, travel_visible]() {
|
||||
append_item(EItemType::None, Travel_Colors[0], { {_u8L("travel"), offsets[0] }}, true, predictable_icon_pos/*ORCA checkbox_pos*/, travel_visible, [this, travel_visible]() {
|
||||
m_buffers[buffer_id(EMoveType::Travel)].visible = !m_buffers[buffer_id(EMoveType::Travel)].visible;
|
||||
// update buffers' render paths, and update m_tools.m_tool_colors and m_extrusions.ranges
|
||||
refresh(*m_gcode_result, wxGetApp().plater()->get_extruder_colors_from_plater_config(m_gcode_result));
|
||||
@@ -5398,7 +5397,8 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv
|
||||
columns_offsets.push_back({ buf, color_print_offsets[_u8L("Total")] });
|
||||
}
|
||||
|
||||
append_item(EItemType::Rect, m_tools.m_tool_colors[extruder_idx], columns_offsets, false, filament_visible, [this, extruder_idx]() {
|
||||
float checkbox_pos = std::max(predictable_icon_pos, color_print_offsets[_u8L("Display")]); // ORCA prefer predictable_icon_pos when header not reacing end
|
||||
append_item(EItemType::Rect, m_tools.m_tool_colors[extruder_idx], columns_offsets, true, checkbox_pos/*ORCA*/, filament_visible, [this, extruder_idx]() {
|
||||
m_tools.m_tool_visibles[extruder_idx] = !m_tools.m_tool_visibles[extruder_idx];
|
||||
// update buffers' render paths
|
||||
refresh_render_paths(false, false);
|
||||
@@ -5993,6 +5993,7 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv
|
||||
ImGui::Dummy({ window_padding, window_padding });
|
||||
ImGui::SameLine();
|
||||
offsets = calculate_offsets({ { _u8L("Options"), { ""}}, { _u8L("Display"), {""}} }, icon_size);
|
||||
offsets[1] = std::max(predictable_icon_pos, color_print_offsets[_u8L("Display")]); // ORCA prefer predictable_icon_pos when header not reacing end
|
||||
append_headers({ {_u8L("Options"), offsets[0] }, { _u8L("Display"), offsets[1]} });
|
||||
for (auto item : options_items)
|
||||
append_option_item(item, offsets);
|
||||
|
||||
@@ -328,10 +328,10 @@ void GLCanvas3D::LayersEditing::render_variable_layer_height_dialog(const GLCanv
|
||||
|
||||
float get_cur_y = ImGui::GetContentRegionMax().y + ImGui::GetFrameHeight() + canvas.m_main_toolbar.get_height();
|
||||
std::map<wxString, wxString> captions_texts = {
|
||||
{_L("Left mouse button:") ,_L("Add detail")},
|
||||
{_L("Right mouse button:"), _L("Remove detail")},
|
||||
{_L("Shift + Left mouse button:"),_L("Reset to base")},
|
||||
{_L("Shift + Right mouse button:"), _L("Smoothing")},
|
||||
{_L("Left mouse button") + ":" , _L("Add detail")},
|
||||
{_L("Right mouse button") + ":", _L("Remove detail")},
|
||||
{_L("Shift+") + _L("Left mouse button") + ":", _L("Reset to base")},
|
||||
{_L("Shift+") + _L("Right mouse button") + ":", _L("Smoothing")},
|
||||
{_L("Mouse wheel:"), _L("Increase/decrease edit area")}
|
||||
};
|
||||
show_tooltip_information(canvas, captions_texts, x, get_cur_y);
|
||||
@@ -1196,8 +1196,9 @@ GLCanvas3D::GLCanvas3D(wxGLCanvas* canvas, Bed3D &bed)
|
||||
|
||||
m_assembly_view_desc["object_selection_caption"] = _L("Left mouse button");
|
||||
m_assembly_view_desc["object_selection"] = _L("object selection");
|
||||
m_assembly_view_desc["part_selection_caption"] = "Alt +" + _L("Left mouse button");
|
||||
m_assembly_view_desc["part_selection"] = _L("part selectiont");
|
||||
// FIXME: maybe should be using GUI::shortkey_alt_prefix() or equivalent?
|
||||
m_assembly_view_desc["part_selection_caption"] = _L("Alt+") + _L("Left mouse button");
|
||||
m_assembly_view_desc["part_selection"] = _L("part selection");
|
||||
m_assembly_view_desc["number_key_caption"] = "1~16 " + _L("number keys");
|
||||
m_assembly_view_desc["number_key"] = _L("number keys can quickly change the color of objects");
|
||||
}
|
||||
@@ -6679,7 +6680,7 @@ bool GLCanvas3D::_init_main_toolbar()
|
||||
|
||||
item.name = "orient";
|
||||
item.icon_filename = m_is_dark ? "toolbar_orient_dark.svg" : "toolbar_orient.svg";
|
||||
item.tooltip = _utf8(L("Auto orient all/selected objects")) + " [Q]\n" + _utf8(L("Auto orient all objects on current plate")) + " [Shift+Q]";
|
||||
item.tooltip = _utf8(L("Auto orient all/selected objects")) + " [Q]\n" + _utf8(L("Auto orient all objects on current plate")) + " [" + _utf8(L("Shift+")) + "Q]";
|
||||
item.sprite_id++;
|
||||
item.left.render_callback = nullptr;
|
||||
item.enabling_callback = []()->bool { return wxGetApp().plater()->can_arrange(); };
|
||||
@@ -6701,7 +6702,7 @@ bool GLCanvas3D::_init_main_toolbar()
|
||||
|
||||
item.name = "arrange";
|
||||
item.icon_filename = m_is_dark ? "toolbar_arrange_dark.svg" : "toolbar_arrange.svg";
|
||||
item.tooltip = _utf8(L("Arrange all objects")) + " [A]\n" + _utf8(L("Arrange objects on selected plates")) + " [Shift+A]";
|
||||
item.tooltip = _utf8(L("Arrange all objects")) + " [A]\n" + _utf8(L("Arrange objects on selected plates")) + " [" + _utf8(L("Shift+")) + "A]";
|
||||
item.sprite_id++;
|
||||
item.left.action_callback = []() {};
|
||||
item.enabling_callback = []()->bool { return wxGetApp().plater()->can_arrange(); };
|
||||
|
||||
@@ -82,7 +82,7 @@ const std::string& shortkey_ctrl_prefix()
|
||||
{
|
||||
static const std::string str =
|
||||
#ifdef __APPLE__
|
||||
"⌘+"
|
||||
u8"\u2318+" // "⌘+" (Mac Command+)
|
||||
#else
|
||||
_u8L("Ctrl+")
|
||||
#endif
|
||||
@@ -94,9 +94,9 @@ const std::string& shortkey_alt_prefix()
|
||||
{
|
||||
static const std::string str =
|
||||
#ifdef __APPLE__
|
||||
"⌥+"
|
||||
u8"\u2325+" // "⌥+" (Mac Option+)
|
||||
#else
|
||||
"Alt+"
|
||||
_u8L("Alt+")
|
||||
#endif
|
||||
;
|
||||
return str;
|
||||
|
||||
@@ -108,6 +108,7 @@ std::map<std::string, std::vector<SimpleSettingData>> SettingsFactory::PART_CAT
|
||||
{"bottom_shell_layers", L("Bottom Solid Layers"),1}, {"bottom_shell_thickness", L("Bottom Minimum Shell Thickness"),1},{"bottom_surface_density", L("Bottom Surface Density"),1},
|
||||
{"sparse_infill_density", "",1},{"sparse_infill_pattern", "",1},{"lateral_lattice_angle_1", "",1},{"lateral_lattice_angle_2", "",1},{"infill_overhang_angle", "",1},{"infill_anchor", "",1},{"infill_anchor_max", "",1},{"top_surface_pattern", "",1},{"bottom_surface_pattern", "",1}, {"internal_solid_infill_pattern", "",1},
|
||||
{"align_infill_direction_to_model", "", 1},
|
||||
{"extra_solid_infills", "", 1},
|
||||
{"infill_combination", "",1}, {"infill_combination_max_layer_height", "",1}, {"infill_wall_overlap", "",1},{"top_bottom_infill_wall_overlap", "",1}, {"solid_infill_direction", "",1}, {"infill_direction", "",1}, {"bridge_angle", "",1}, {"internal_bridge_angle", "",1}, {"minimum_sparse_infill_area", "",1}
|
||||
}},
|
||||
{ L("Speed"), {{"outer_wall_speed", "",1},{"inner_wall_speed", "",2},{"sparse_infill_speed", "",3},{"top_surface_speed", "",4}, {"internal_solid_infill_speed", "",5},
|
||||
@@ -488,7 +489,7 @@ void MenuFactory::append_menu_item_delete(wxMenu* menu)
|
||||
[](wxCommandEvent&) { plater()->remove_selected(); }, "menu_delete", nullptr,
|
||||
[]() { return plater()->can_delete(); }, m_parent);
|
||||
#else
|
||||
append_menu_item(menu, wxID_ANY, _L("Delete") + "\tBackSpace", _L("Delete the selected object"),
|
||||
append_menu_item(menu, wxID_ANY, _L("Delete") + "\t" + _L("Backspace"), _L("Delete the selected object"),
|
||||
[](wxCommandEvent&) { plater()->remove_selected(); }, "", nullptr,
|
||||
[]() { return plater()->can_delete(); }, m_parent);
|
||||
#endif
|
||||
@@ -1838,6 +1839,7 @@ void MenuFactory::append_menu_item_clone(wxMenu* menu)
|
||||
#ifdef __APPLE__
|
||||
static const wxString ctrl = ("Ctrl+");
|
||||
#else
|
||||
// FIXME: maybe should be using GUI::shortkey_ctrl_prefix() or equivalent?
|
||||
static const wxString ctrl = _L("Ctrl+");
|
||||
#endif
|
||||
append_menu_item(menu, wxID_ANY, _L("Clone") + "\t" + ctrl + "K", "",
|
||||
|
||||
@@ -357,7 +357,7 @@ bool GLGizmoAdvancedCut::on_init()
|
||||
// initiate info shortcuts
|
||||
const wxString ctrl = GUI::shortkey_ctrl_prefix();
|
||||
const wxString alt = GUI::shortkey_alt_prefix();
|
||||
const wxString shift = "Shift+";
|
||||
const wxString shift = _L("Shift+");
|
||||
|
||||
m_shortcuts.push_back(std::make_pair(_L("Left click"), _L("Add connector")));
|
||||
m_shortcuts.push_back(std::make_pair(_L("Right click"), _L("Remove connector")));
|
||||
|
||||
@@ -40,11 +40,15 @@ GLGizmoBrimEars::GLGizmoBrimEars(GLCanvas3D &parent, const std::string &icon_fil
|
||||
|
||||
bool GLGizmoBrimEars::on_init()
|
||||
{
|
||||
|
||||
m_new_point_head_diameter = get_brim_default_radius();
|
||||
|
||||
m_shortcut_key = WXK_CONTROL_E;
|
||||
|
||||
// FIXME: maybe should be using GUI::shortkey_ctrl_prefix() or equivalent?
|
||||
const wxString ctrl = _L("Ctrl+");
|
||||
// FIXME: maybe should be using GUI::shortkey_alt_prefix() or equivalent?
|
||||
const wxString alt = _L("Alt+");
|
||||
|
||||
m_desc["head_diameter"] = _L("Head diameter");
|
||||
m_desc["max_angle"] = _L("Max angle");
|
||||
m_desc["detection_radius"] = _L("Detection radius");
|
||||
@@ -57,9 +61,9 @@ bool GLGizmoBrimEars::on_init()
|
||||
m_desc["left_click"] = _L("Add a brim ear");
|
||||
m_desc["right_click_caption"] = _L("Right click");
|
||||
m_desc["right_click"] = _L("Delete a brim ear");
|
||||
m_desc["ctrl_mouse_wheel_caption"] = _L("Ctrl+Mouse wheel");
|
||||
m_desc["ctrl_mouse_wheel_caption"] = ctrl + _L("Mouse wheel");
|
||||
m_desc["ctrl_mouse_wheel"] = _L("Adjust head diameter");
|
||||
m_desc["alt_mouse_wheel_caption"] = _L("Alt + Mouse wheel");
|
||||
m_desc["alt_mouse_wheel_caption"] = alt + _L("Mouse wheel");
|
||||
m_desc["alt_mouse_wheel"] = _L("Adjust section view");
|
||||
|
||||
return true;
|
||||
|
||||
@@ -1183,7 +1183,7 @@ bool GLGizmoCut3D::on_init()
|
||||
// initiate info shortcuts
|
||||
const wxString ctrl = GUI::shortkey_ctrl_prefix();
|
||||
const wxString alt = GUI::shortkey_alt_prefix();
|
||||
const wxString shift = "Shift+";
|
||||
const wxString shift = _L("Shift+");
|
||||
|
||||
m_shortcuts_cut.push_back(std::make_pair(shift + _L("Drag"), _L("Draw cut line")));
|
||||
|
||||
|
||||
@@ -79,25 +79,31 @@ bool GLGizmoFdmSupports::on_init()
|
||||
// BBS
|
||||
m_shortcut_key = WXK_CONTROL_L;
|
||||
|
||||
m_desc["clipping_of_view_caption"] = _L("Alt + Mouse wheel");
|
||||
// FIXME: maybe should be using GUI::shortkey_ctrl_prefix() or equivalent?
|
||||
const wxString ctrl = _L("Ctrl+");
|
||||
// FIXME: maybe should be using GUI::shortkey_alt_prefix() or equivalent?
|
||||
const wxString alt = _L("Alt+");
|
||||
const wxString shift = _L("Shift+");
|
||||
|
||||
m_desc["clipping_of_view_caption"] = alt + _L("Mouse wheel");
|
||||
m_desc["clipping_of_view"] = _L("Section view");
|
||||
m_desc["reset_direction"] = _L("Reset direction");
|
||||
m_desc["cursor_size_caption"] = _L("Ctrl + Mouse wheel");
|
||||
m_desc["cursor_size_caption"] = ctrl + _L("Mouse wheel");
|
||||
m_desc["cursor_size"] = _L("Pen size");
|
||||
m_desc["enforce_caption"] = _L("Left mouse button");
|
||||
m_desc["enforce"] = _L("Enforce supports");
|
||||
m_desc["block_caption"] = _L("Right mouse button");
|
||||
m_desc["block"] = _L("Block supports");
|
||||
m_desc["remove_caption"] = _L("Shift + Left mouse button");
|
||||
m_desc["remove_caption"] = shift + _L("Left mouse button");
|
||||
m_desc["remove"] = _L("Erase");
|
||||
m_desc["remove_all"] = _L("Erase all painting");
|
||||
m_desc["highlight_by_angle"] = _L("Highlight overhang areas");
|
||||
m_desc["gap_fill"] = _L("Gap fill");
|
||||
m_desc["perform"] = _L("Perform");
|
||||
m_desc["gap_area_caption"] = _L("Ctrl + Mouse wheel");
|
||||
m_desc["gap_area_caption"] = ctrl + _L("Mouse wheel");
|
||||
m_desc["gap_area"] = _L("Gap area");
|
||||
m_desc["tool_type"] = _L("Tool type");
|
||||
m_desc["smart_fill_angle_caption"] = _L("Ctrl + Mouse wheel");
|
||||
m_desc["smart_fill_angle_caption"] = ctrl + _L("Mouse wheel");
|
||||
m_desc["smart_fill_angle"] = _L("Smart fill angle");
|
||||
m_desc["on_overhangs_only"] = _L("On overhangs only");
|
||||
|
||||
|
||||
@@ -31,15 +31,21 @@ bool GLGizmoFuzzySkin::on_init()
|
||||
{
|
||||
m_shortcut_key = WXK_CONTROL_H;
|
||||
|
||||
m_desc["clipping_of_view_caption"] = _L("Alt + Mouse wheel");
|
||||
// FIXME: maybe should be using GUI::shortkey_ctrl_prefix() or equivalent?
|
||||
const wxString ctrl = _L("Ctrl+");
|
||||
// FIXME: maybe should be using GUI::shortkey_alt_prefix() or equivalent?
|
||||
const wxString alt = _L("Alt+");
|
||||
const wxString shift = _L("Shift+");
|
||||
|
||||
m_desc["clipping_of_view_caption"] = alt + _L("Mouse wheel");
|
||||
m_desc["clipping_of_view"] = _L("Section view");
|
||||
m_desc["reset_direction"] = _L("Reset direction");
|
||||
m_desc["cursor_size_caption"] = _L("Ctrl + Mouse wheel");
|
||||
m_desc["cursor_size_caption"] = ctrl + _L("Mouse wheel");
|
||||
m_desc["cursor_size"] = _L("Brush size");
|
||||
m_desc["cursor_type"] = _L("Brush shape") ;
|
||||
m_desc["add_fuzzy_skin_caption"] = _L("Left mouse button");
|
||||
m_desc["add_fuzzy_skin"] = _L("Add fuzzy skin");
|
||||
m_desc["remove_fuzzy_skin_caption"] = _L("Shift + Left mouse button");
|
||||
m_desc["remove_fuzzy_skin_caption"] = shift + _L("Left mouse button");
|
||||
m_desc["remove_fuzzy_skin"] = _L("Remove fuzzy skin");
|
||||
m_desc["remove_all"] = _L("Erase all painting");
|
||||
m_desc["circle"] = _L("Circle");
|
||||
@@ -48,7 +54,7 @@ bool GLGizmoFuzzySkin::on_init()
|
||||
m_desc["tool_type"] = _L("Tool type");
|
||||
m_desc["tool_brush"] = _L("Brush");
|
||||
m_desc["tool_smart_fill"] = _L("Smart fill");
|
||||
m_desc["smart_fill_angle_caption"] = _L("Ctrl + Mouse wheel");
|
||||
m_desc["smart_fill_angle_caption"] = ctrl + _L("Mouse wheel");
|
||||
m_desc["smart_fill_angle"] = _L("Smart fill angle");
|
||||
|
||||
return true;
|
||||
|
||||
@@ -444,8 +444,10 @@ bool GLGizmoMeasure::on_init()
|
||||
{
|
||||
m_shortcut_key = WXK_CONTROL_U;
|
||||
|
||||
const wxString shift = _L("Shift+");
|
||||
|
||||
m_desc["feature_selection"] = _L("Select feature");
|
||||
m_desc["point_selection_caption"] = _L("Shift + Left mouse button");
|
||||
m_desc["point_selection_caption"] = shift + _L("Left mouse button");
|
||||
m_desc["point_selection"] = _L("Select point");
|
||||
m_desc["reset_caption"] = _L("Delete");
|
||||
m_desc["reset"] = _L("Restart selection");
|
||||
|
||||
@@ -88,21 +88,27 @@ bool GLGizmoMmuSegmentation::on_init()
|
||||
// BBS
|
||||
m_shortcut_key = WXK_CONTROL_N;
|
||||
|
||||
m_desc["clipping_of_view_caption"] = _L("Alt + Mouse wheel");
|
||||
// FIXME: maybe should be using GUI::shortkey_ctrl_prefix() or equivalent?
|
||||
const wxString ctrl = _L("Ctrl+");
|
||||
// FIXME: maybe should be using GUI::shortkey_alt_prefix() or equivalent?
|
||||
const wxString alt = _L("Alt+");
|
||||
const wxString shift = _L("Shift+");
|
||||
|
||||
m_desc["clipping_of_view_caption"] = alt + _L("Mouse wheel");
|
||||
m_desc["clipping_of_view"] = _L("Section view");
|
||||
m_desc["reset_direction"] = _L("Reset direction");
|
||||
m_desc["cursor_size_caption"] = _L("Ctrl + Mouse wheel");
|
||||
m_desc["cursor_size_caption"] = ctrl + _L("Mouse wheel");
|
||||
m_desc["cursor_size"] = _L("Pen size");
|
||||
m_desc["cursor_type"] = _L("Pen shape");
|
||||
|
||||
m_desc["paint_caption"] = _L("Left mouse button");
|
||||
m_desc["paint"] = _L("Paint");
|
||||
m_desc["erase_caption"] = _L("Shift + Left mouse button");
|
||||
m_desc["erase_caption"] = shift + _L("Left mouse button");
|
||||
m_desc["erase"] = _L("Erase");
|
||||
m_desc["shortcut_key_caption"] = _L("Key 1~9");
|
||||
m_desc["shortcut_key"] = _L("Choose filament");
|
||||
m_desc["edge_detection"] = _L("Edge detection");
|
||||
m_desc["gap_area_caption"] = _L("Ctrl + Mouse wheel");
|
||||
m_desc["gap_area_caption"] = ctrl + _L("Mouse wheel");
|
||||
m_desc["gap_area"] = _L("Gap area");
|
||||
m_desc["perform"] = _L("Perform");
|
||||
|
||||
@@ -117,14 +123,14 @@ bool GLGizmoMmuSegmentation::on_init()
|
||||
m_desc["tool_smart_fill"] = _L("Smart fill");
|
||||
m_desc["tool_bucket_fill"] = _L("Bucket fill");
|
||||
|
||||
m_desc["smart_fill_angle_caption"] = _L("Ctrl + Mouse wheel");
|
||||
m_desc["smart_fill_angle_caption"] = ctrl + _L("Mouse wheel");
|
||||
m_desc["smart_fill_angle"] = _L("Smart fill angle");
|
||||
|
||||
m_desc["height_range_caption"] = _L("Ctrl + Mouse wheel");
|
||||
m_desc["height_range_caption"] = ctrl + _L("Mouse wheel");
|
||||
m_desc["height_range"] = _L("Height range");
|
||||
|
||||
//add toggle wire frame hint
|
||||
m_desc["toggle_wireframe_caption"] = _L("Alt + Shift + Enter");
|
||||
m_desc["toggle_wireframe_caption"] = alt + shift + _L("Enter");
|
||||
m_desc["toggle_wireframe"] = _L("Toggle Wireframe");
|
||||
|
||||
// Filament remapping descriptions
|
||||
|
||||
@@ -29,17 +29,23 @@ bool GLGizmoSeam::on_init()
|
||||
{
|
||||
m_shortcut_key = WXK_CONTROL_P;
|
||||
|
||||
m_desc["clipping_of_view_caption"] = _L("Alt + Mouse wheel");
|
||||
// FIXME: maybe should be using GUI::shortkey_ctrl_prefix() or equivalent?
|
||||
const wxString ctrl = _L("Ctrl+");
|
||||
// FIXME: maybe should be using GUI::shortkey_alt_prefix() or equivalent?
|
||||
const wxString alt = _L("Alt+");
|
||||
const wxString shift = _L("Shift+");
|
||||
|
||||
m_desc["clipping_of_view_caption"] = alt + _L("Mouse wheel");
|
||||
m_desc["clipping_of_view"] = _L("Section view");
|
||||
m_desc["reset_direction"] = _L("Reset direction");
|
||||
m_desc["cursor_size_caption"] = _L("Ctrl + Mouse wheel");
|
||||
m_desc["cursor_size_caption"] = ctrl + _L("Mouse wheel");
|
||||
m_desc["cursor_size"] = _L("Brush size");
|
||||
m_desc["cursor_type"] = _L("Brush shape");
|
||||
m_desc["enforce_caption"] = _L("Left mouse button");
|
||||
m_desc["enforce"] = _L("Enforce seam");
|
||||
m_desc["block_caption"] = _L("Right mouse button");
|
||||
m_desc["block"] = _L("Block seam");
|
||||
m_desc["remove_caption"] = _L("Shift + Left mouse button");
|
||||
m_desc["remove_caption"] = shift + _L("Left mouse button");
|
||||
m_desc["remove"] = _L("Erase");
|
||||
m_desc["remove_all"] = _L("Erase all painting");
|
||||
m_desc["circle"] = _L("Circle");
|
||||
|
||||
@@ -1175,9 +1175,10 @@ SlaGizmoHelpDialog::SlaGizmoHelpDialog()
|
||||
: wxDialog(nullptr, wxID_ANY, _L("SLA gizmo keyboard shortcuts"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER)
|
||||
{
|
||||
SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
|
||||
|
||||
const wxString ctrl = GUI::shortkey_ctrl_prefix();
|
||||
const wxString alt = GUI::shortkey_alt_prefix();
|
||||
|
||||
const wxString shift = _L("Shift+");
|
||||
|
||||
// fonts
|
||||
const wxFont& font = wxGetApp().small_font();
|
||||
@@ -1206,14 +1207,14 @@ SlaGizmoHelpDialog::SlaGizmoHelpDialog()
|
||||
shortcuts.push_back(std::make_pair(_L("Drag"), _L("Move point")));
|
||||
shortcuts.push_back(std::make_pair(ctrl+_L("Left click"), _L("Add point to selection")));
|
||||
shortcuts.push_back(std::make_pair(alt+_L("Left click"), _L("Remove point from selection")));
|
||||
shortcuts.push_back(std::make_pair(wxString("Shift+")+_L("Drag"), _L("Select by rectangle")));
|
||||
shortcuts.push_back(std::make_pair(shift+_L("Drag"), _L("Select by rectangle")));
|
||||
shortcuts.push_back(std::make_pair(alt+_(L("Drag")), _L("Deselect by rectangle")));
|
||||
shortcuts.push_back(std::make_pair(ctrl+"A", _L("Select all points")));
|
||||
shortcuts.push_back(std::make_pair("Delete", _L("Remove selected points")));
|
||||
shortcuts.push_back(std::make_pair(_L"Del", _L("Remove selected points")));
|
||||
shortcuts.push_back(std::make_pair(ctrl+_L("Mouse wheel"), _L("Move clipping plane")));
|
||||
shortcuts.push_back(std::make_pair("R", _L("Reset clipping plane")));
|
||||
shortcuts.push_back(std::make_pair("Enter", _L("Apply changes")));
|
||||
shortcuts.push_back(std::make_pair("Esc", _L("Discard changes")));
|
||||
shortcuts.push_back(std::make_pair(_L("Enter"), _L("Apply changes")));
|
||||
shortcuts.push_back(std::make_pair(_L("Esc"), _L("Discard changes")));
|
||||
shortcuts.push_back(std::make_pair("M", _L("Switch to editing mode")));
|
||||
shortcuts.push_back(std::make_pair("A", _L("Auto-generate points")));
|
||||
|
||||
|
||||
@@ -278,7 +278,7 @@ bool GLGizmoText::on_init()
|
||||
m_desc["surface"] = _L("Surface");
|
||||
m_desc["horizontal_text"] = _L("Horizontal text");
|
||||
|
||||
m_desc["rotate_text_caption"] = _L("Shift + Mouse move up or down");
|
||||
m_desc["rotate_text_caption"] = _L("Shift+") + _L("Mouse move up or down");
|
||||
m_desc["rotate_text"] = _L("Rotate text");
|
||||
|
||||
return true;
|
||||
|
||||
@@ -55,9 +55,10 @@ GizmoObjectManipulation::GizmoObjectManipulation(GLCanvas3D& glcanvas)
|
||||
m_imperial_units = wxGetApp().app_config->get("use_inches") == "1";
|
||||
m_new_unit_string = m_imperial_units ? L("in") : L("mm");
|
||||
|
||||
const wxString shift = "Shift+";
|
||||
const wxString shift = _L("Shift+");
|
||||
const wxString alt = GUI::shortkey_alt_prefix();
|
||||
const wxString ctrl = GUI::shortkey_ctrl_prefix();
|
||||
|
||||
m_desc_move["part_selection_caption"] = alt + _L("Left mouse button");
|
||||
m_desc_move["part_selection"] = _L("Part selection");
|
||||
m_desc_move["snap_step_caption"] = shift + _L("Left mouse button");
|
||||
|
||||
@@ -163,8 +163,9 @@ void KBShortcutsDialog::on_dpi_changed(const wxRect& suggested_rect)
|
||||
|
||||
void KBShortcutsDialog::fill_shortcuts()
|
||||
{
|
||||
const std::string& ctrl = GUI::shortkey_ctrl_prefix();
|
||||
const std::string& alt = GUI::shortkey_alt_prefix();
|
||||
const std::string ctrl = GUI::shortkey_ctrl_prefix();
|
||||
const std::string alt = GUI::shortkey_alt_prefix();
|
||||
const std::string shift = L("Shift+");
|
||||
|
||||
if (wxGetApp().is_editor()) {
|
||||
Shortcuts global_shortcuts = {
|
||||
@@ -172,7 +173,7 @@ void KBShortcutsDialog::fill_shortcuts()
|
||||
{ ctrl + "N", L("New Project") },
|
||||
{ ctrl + "O", L("Open Project") },
|
||||
{ ctrl + "S", L("Save Project") },
|
||||
{ ctrl + "Shift+S", L("Save Project as")},
|
||||
{ ctrl + shift + "S", L("Save Project as")},
|
||||
// File>Import
|
||||
{ ctrl + "I", L("Import geometry data from STL/STEP/3MF/OBJ/AMF files") },
|
||||
// File>Export
|
||||
@@ -180,12 +181,7 @@ void KBShortcutsDialog::fill_shortcuts()
|
||||
// Slice plate
|
||||
{ ctrl + "R", L("Slice plate")},
|
||||
// Send to Print
|
||||
#ifdef __APPLE__
|
||||
{ L("⌘+Shift+G"), L("Print plate")},
|
||||
#else
|
||||
{ L("Ctrl+Shift+G"), L("Print plate")},
|
||||
#endif // __APPLE
|
||||
|
||||
{ ctrl + shift + "G", L("Print plate")},
|
||||
// Edit
|
||||
{ ctrl + "X", L("Cut") },
|
||||
{ ctrl + "C", L("Copy to clipboard") },
|
||||
@@ -194,13 +190,13 @@ void KBShortcutsDialog::fill_shortcuts()
|
||||
{ ctrl + "P", L("Preferences") },
|
||||
//3D control
|
||||
#ifdef __APPLE__
|
||||
{ ctrl + "Shift+M", L("Show/Hide 3Dconnexion devices settings dialog") },
|
||||
{ ctrl + shift + "M", L("Show/Hide 3Dconnexion devices settings dialog") },
|
||||
#else
|
||||
{ ctrl + "M", L("Show/Hide 3Dconnexion devices settings dialog") },
|
||||
#endif // __APPLE
|
||||
|
||||
// Switch table page
|
||||
{ ctrl + "Tab", L("Switch table page")},
|
||||
{ ctrl + L("Tab"), L("Switch table page")},
|
||||
//DEL
|
||||
#ifdef __APPLE__
|
||||
{"fn+⌫", L("Delete selected")},
|
||||
@@ -217,28 +213,21 @@ void KBShortcutsDialog::fill_shortcuts()
|
||||
{ L("Right mouse button"), L("Pan View") },
|
||||
{ L("Mouse wheel"), L("Zoom View") },
|
||||
{ "A", L("Arrange all objects") },
|
||||
{ L("Shift+A"), L("Arrange objects on selected plates") },
|
||||
{ shift + "A", L("Arrange objects on selected plates") },
|
||||
|
||||
{ "Q", L("Auto orients selected objects or all objects. If there are selected objects, it just orients the selected ones. Otherwise, it will orient all objects in the current project.") },
|
||||
{L("Shift+Q"), L("Auto orients all objects on the active plate.")},
|
||||
{ shift + "Q", L("Auto orients all objects on the active plate.") },
|
||||
|
||||
{L("Shift+Tab"), L("Collapse/Expand the sidebar")},
|
||||
#ifdef __APPLE__
|
||||
{L("⌘+Any arrow"), L("Movement in camera space")},
|
||||
{L("⌥+Left mouse button"), L("Select a part")},
|
||||
{L("⌘+Left mouse button"), L("Select multiple objects")},
|
||||
#else
|
||||
{L("Ctrl+Any arrow"), L("Movement in camera space")},
|
||||
{L("Alt+Left mouse button"), L("Select a part")},
|
||||
{L("Ctrl+Left mouse button"), L("Select multiple objects")},
|
||||
|
||||
#endif
|
||||
{L("Shift+Left mouse button"), L("Select objects by rectangle")},
|
||||
{shift + L("Tab"), L("Collapse/Expand the sidebar")},
|
||||
{ctrl + L("Any arrow"), L("Movement in camera space")},
|
||||
{alt + L("Left mouse button"), L("Select a part")},
|
||||
{ctrl + L("Left mouse button"), L("Select multiple objects")},
|
||||
{shift + L("Left mouse button"), L("Select objects by rectangle")},
|
||||
{L("Arrow Up"), L("Move selection 10 mm in positive Y direction")},
|
||||
{L("Arrow Down"), L("Move selection 10 mm in negative Y direction")},
|
||||
{L("Arrow Left"), L("Move selection 10 mm in negative X direction")},
|
||||
{L("Arrow Right"), L("Move selection 10 mm in positive X direction")},
|
||||
{L("Shift+Any arrow"), L("Movement step set to 1 mm")},
|
||||
{shift + L("Any arrow"), L("Movement step set to 1 mm")},
|
||||
{L("Esc"), L("Deselect all")},
|
||||
{"1-9", L("keyboard 1-9: set filament for object/part")},
|
||||
{ctrl + "0", L("Camera view - Default")},
|
||||
@@ -268,21 +257,16 @@ void KBShortcutsDialog::fill_shortcuts()
|
||||
{ "E", L("Gizmo brim ears") },
|
||||
{ "I", L("Zoom in") },
|
||||
{ "O", L("Zoom out") },
|
||||
{ "Tab", L("Switch between Prepare/Preview") },
|
||||
{ L("Tab"), L("Switch between Prepare/Preview") },
|
||||
|
||||
};
|
||||
m_full_shortcuts.push_back({ { _L("Plater"), "" }, plater_shortcuts });
|
||||
|
||||
Shortcuts gizmos_shortcuts = {
|
||||
{L("Esc"), L("Deselect all")},
|
||||
{L("Shift+"), L("Move: press to snap by 1mm")},
|
||||
#ifdef __APPLE__
|
||||
{L("⌘+Mouse wheel"), L("Support/Color Painting: adjust pen radius")},
|
||||
{L("⌥+Mouse wheel"), L("Support/Color Painting: adjust section position")},
|
||||
#else
|
||||
{L("Ctrl+Mouse wheel"), L("Support/Color Painting: adjust pen radius")},
|
||||
{L("Alt+Mouse wheel"), L("Support/Color Painting: adjust section position")},
|
||||
#endif
|
||||
{shift, L("Move: press to snap by 1mm")},
|
||||
{ctrl + L("Mouse wheel"), L("Support/Color Painting: adjust pen radius")},
|
||||
{alt + L("Mouse wheel"), L("Support/Color Painting: adjust section position")},
|
||||
};
|
||||
m_full_shortcuts.push_back({{_L("Gizmo"), ""}, gizmos_shortcuts});
|
||||
|
||||
@@ -310,16 +294,11 @@ void KBShortcutsDialog::fill_shortcuts()
|
||||
{ L("Arrow Right"), L("Horizontal slider - Move active thumb Right")},
|
||||
{ "L", L("On/Off one layer mode of the vertical slider")},
|
||||
{ "C", L("On/Off G-code window")},
|
||||
{ "Tab", L("Switch between Prepare/Preview") },
|
||||
{L("Shift+Any arrow"), L("Move slider 5x faster")},
|
||||
{L("Shift+Mouse wheel"), L("Move slider 5x faster")},
|
||||
#ifdef __APPLE__
|
||||
{L("⌘+Any arrow"), L("Move slider 5x faster")},
|
||||
{L("⌘+Mouse wheel"), L("Move slider 5x faster")},
|
||||
#else
|
||||
{L("Ctrl+Any arrow"), L("Move slider 5x faster")},
|
||||
{L("Ctrl+Mouse wheel"), L("Move slider 5x faster")},
|
||||
#endif
|
||||
{ L("Tab"), L("Switch between Prepare/Preview")},
|
||||
{shift + L("Any arrow"), L("Move slider 5x faster")},
|
||||
{shift + L("Mouse wheel"), L("Move slider 5x faster")},
|
||||
{ctrl + L("Any arrow"), L("Move slider 5x faster")},
|
||||
{ctrl + L("Mouse wheel"), L("Move slider 5x faster")},
|
||||
{ L("Home"), L("Horizontal slider - Move to start position")},
|
||||
{ L("End"), L("Horizontal slider - Move to last position")},
|
||||
};
|
||||
|
||||
@@ -169,11 +169,14 @@ wxDEFINE_EVENT(EVT_SYNC_CLOUD_PRESET, SimpleEvent);
|
||||
|
||||
#ifdef __APPLE__
|
||||
static const wxString ctrl = ("Ctrl+");
|
||||
static const std::string ctrl_t = "⌘";
|
||||
// FIXME: maybe should be using GUI::shortkey_ctrl_prefix() or equivalent?
|
||||
static const std::string ctrl_t = u8"\u2318+"; // "⌘" (Mac Command)
|
||||
#else
|
||||
static const wxString ctrl = _L("Ctrl+");
|
||||
// FIXME: maybe should be using GUI::shortkey_ctrl_prefix() or equivalent?
|
||||
static const wxString ctrl_t = ctrl;
|
||||
#endif
|
||||
static const wxString shift = _L("Shift+");
|
||||
|
||||
MainFrame::MainFrame() :
|
||||
DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, BORDERLESS_FRAME_STYLE, "mainframe")
|
||||
@@ -2402,13 +2405,12 @@ void MainFrame::init_menubar_as_editor()
|
||||
[this](){return m_plater != nullptr && can_save(); }, this);
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef __APPLE__
|
||||
append_menu_item(fileMenu, wxID_ANY, _L("Save Project as") + dots + "\t" + ctrl + _L("Shift+") + "S", _L("Save current project as"),
|
||||
append_menu_item(fileMenu, wxID_ANY, _L("Save Project as") + dots + "\t" + ctrl + shift + "S", _L("Save current project as"),
|
||||
[this](wxCommandEvent&) { if (m_plater) m_plater->save_project(true); }, "menu_save", nullptr,
|
||||
[this](){return m_plater != nullptr && can_save_as(); }, this);
|
||||
#else
|
||||
append_menu_item(fileMenu, wxID_ANY, _L("Save Project as") + dots + "\t" + ctrl + _L("Shift+") + "S", _L("Save current project as"),
|
||||
append_menu_item(fileMenu, wxID_ANY, _L("Save Project as") + dots + "\t" + ctrl + shift + "S", _L("Save current project as"),
|
||||
[this](wxCommandEvent&) { if (m_plater) m_plater->save_project(true); }, "", nullptr,
|
||||
[this](){return m_plater != nullptr && can_save_as(); }, this);
|
||||
#endif
|
||||
@@ -2432,7 +2434,7 @@ void MainFrame::init_menubar_as_editor()
|
||||
append_menu_item(import_menu, wxID_ANY, _L("Import Zip Archive") + dots, _L("Load models contained within a zip archive"),
|
||||
[this](wxCommandEvent&) { if (m_plater) m_plater->import_zip_archive(); }, "menu_import", nullptr,
|
||||
[this]() { return can_add_models(); });
|
||||
append_menu_item(import_menu, wxID_ANY, _L("Import Configs") + dots /*+ "\tCtrl+I"*/, _L("Load configs"),
|
||||
append_menu_item(import_menu, wxID_ANY, _L("Import Configs") + dots /*+ "\t" + ctrl + "I"*/, _L("Load configs"),
|
||||
[this](wxCommandEvent&) { load_config_file(); }, "menu_import", nullptr,
|
||||
[this](){return true; }, this);
|
||||
|
||||
@@ -2447,7 +2449,7 @@ void MainFrame::init_menubar_as_editor()
|
||||
append_menu_item(export_menu, wxID_ANY, _L("Export all objects as STLs") + dots, _L("Export all objects as STLs"),
|
||||
[this](wxCommandEvent&) { if (m_plater) m_plater->export_stl(false, false, true); }, "menu_export_stl", nullptr,
|
||||
[this](){return can_export_model(); }, this);
|
||||
append_menu_item(export_menu, wxID_ANY, _L("Export Generic 3MF") + dots/* + "\tCtrl+G"*/, _L("Export 3mf file without using some 3mf-extensions"),
|
||||
append_menu_item(export_menu, wxID_ANY, _L("Export Generic 3MF") + dots/* + "\t" + ctrl + "G"*/, _L("Export 3mf file without using some 3mf-extensions"),
|
||||
[this](wxCommandEvent&) { if (m_plater) m_plater->export_core_3mf(); }, "menu_export_sliced_file", nullptr,
|
||||
[this](){return can_export_model(); }, this);
|
||||
// BBS export .gcode.3mf
|
||||
@@ -2455,15 +2457,15 @@ void MainFrame::init_menubar_as_editor()
|
||||
[this](wxCommandEvent&) { if (m_plater) wxPostEvent(m_plater, SimpleEvent(EVT_GLTOOLBAR_EXPORT_SLICED_FILE)); }, "menu_export_sliced_file", nullptr,
|
||||
[this](){return can_export_gcode(); }, this);
|
||||
|
||||
append_menu_item(export_menu, wxID_ANY, _L("Export all plate sliced file") + dots/* + "\tCtrl+G"*/, _L("Export all plate sliced file"),
|
||||
append_menu_item(export_menu, wxID_ANY, _L("Export all plate sliced file") + dots/* + "\t" + ctrl + "G"*/, _L("Export all plate sliced file"),
|
||||
[this](wxCommandEvent&) { if (m_plater) wxPostEvent(m_plater, SimpleEvent(EVT_GLTOOLBAR_EXPORT_ALL_SLICED_FILE)); }, "menu_export_sliced_file", nullptr,
|
||||
[this]() {return can_export_all_gcode(); }, this);
|
||||
|
||||
append_menu_item(export_menu, wxID_ANY, _L("Export G-code") + dots/* + "\tCtrl+G"*/, _L("Export current plate as G-code"),
|
||||
append_menu_item(export_menu, wxID_ANY, _L("Export G-code") + dots/* + "\t" + ctrl + "G"*/, _L("Export current plate as G-code"),
|
||||
[this](wxCommandEvent&) { if (m_plater) m_plater->export_gcode(false); }, "menu_export_gcode", nullptr,
|
||||
[this]() {return can_export_gcode(); }, this);
|
||||
append_menu_item(
|
||||
export_menu, wxID_ANY, _L("Export Preset Bundle") + dots /* + "\tCtrl+E"*/, _L("Export current configuration to files"),
|
||||
export_menu, wxID_ANY, _L("Export Preset Bundle") + dots /* + "\t" + ctrl + "E"*/, _L("Export current configuration to files"),
|
||||
[this](wxCommandEvent &) { export_config(); },
|
||||
"menu_export_config", nullptr,
|
||||
[]() { return true; }, this);
|
||||
@@ -2486,12 +2488,6 @@ void MainFrame::init_menubar_as_editor()
|
||||
if (m_plater != nullptr)
|
||||
{
|
||||
editMenu = new wxMenu();
|
||||
#ifdef __APPLE__
|
||||
// Backspace sign
|
||||
wxString hotkey_delete = "\u232b";
|
||||
#else
|
||||
wxString hotkey_delete = "Del";
|
||||
#endif
|
||||
|
||||
auto handle_key_event = [](wxKeyEvent& evt) {
|
||||
if (wxGetApp().imgui()->update_key_data(evt)) {
|
||||
@@ -2532,7 +2528,7 @@ void MainFrame::init_menubar_as_editor()
|
||||
"menu_remove", nullptr, [this](){return can_delete_all(); }, this);
|
||||
editMenu->AppendSeparator();
|
||||
// BBS Clone Selected
|
||||
append_menu_item(editMenu, wxID_ANY, _L("Clone selected") /*+ "\tCtrl+M"*/,
|
||||
append_menu_item(editMenu, wxID_ANY, _L("Clone selected") /*+ "\t" + ctrl + "M"*/,
|
||||
_L("Clone copies of selections"),[this](wxCommandEvent&) {
|
||||
m_plater->clone_selection();
|
||||
},
|
||||
@@ -2608,7 +2604,7 @@ void MainFrame::init_menubar_as_editor()
|
||||
"", nullptr, [this](){return m_plater->can_paste_from_clipboard(); }, this);
|
||||
#if 0
|
||||
// BBS Delete selected
|
||||
append_menu_item(editMenu, wxID_ANY, _L("Delete selected") + "\tBackSpace",
|
||||
append_menu_item(editMenu, wxID_ANY, _L("Delete selected") + "\t" + _L("Backspace"),
|
||||
_L("Deletes the current selection"),[this](wxCommandEvent&) {
|
||||
m_plater->remove_selected();
|
||||
},
|
||||
@@ -2663,7 +2659,7 @@ void MainFrame::init_menubar_as_editor()
|
||||
m_plater->select_all(); },
|
||||
"", nullptr, [this](){return can_select(); }, this);
|
||||
// BBS Deslect All
|
||||
append_menu_item(editMenu, wxID_ANY, _L("Deselect all") + sep + "Esc",
|
||||
append_menu_item(editMenu, wxID_ANY, _L("Deselect all") + sep + _L("Esc"),
|
||||
_L("Deselects all objects"), [this, handle_key_event](wxCommandEvent&) {
|
||||
wxKeyEvent e;
|
||||
e.SetEventType(wxEVT_KEY_DOWN);
|
||||
@@ -2782,7 +2778,7 @@ void MainFrame::init_menubar_as_editor()
|
||||
[this]() { return wxGetApp().show_outline(); }, this);
|
||||
|
||||
/*viewMenu->AppendSeparator();
|
||||
append_menu_check_item(viewMenu, wxID_ANY, _L("Show &Wireframe") + "\tCtrl+Shift+Enter", _L("Show wireframes in 3D scene."),
|
||||
append_menu_check_item(viewMenu, wxID_ANY, _L("Show &Wireframe") + "\t" + ctrl + shift + _L("Enter"), _L("Show wireframes in 3D scene."),
|
||||
[this](wxCommandEvent&) { m_plater->toggle_show_wireframe(); m_plater->get_current_canvas3D()->post_event(SimpleEvent(wxEVT_PAINT)); }, this,
|
||||
[this]() { return m_plater->is_wireframe_enabled(); }, [this]() { return m_plater->is_show_wireframe(); }, this);*/
|
||||
|
||||
@@ -2805,7 +2801,7 @@ void MainFrame::init_menubar_as_editor()
|
||||
#ifdef __APPLE__
|
||||
wxWindowID bambu_studio_id_base = wxWindow::NewControlId(int(2));
|
||||
wxMenu* parent_menu = m_menubar->OSXGetAppleMenu();
|
||||
//auto preference_item = new wxMenuItem(parent_menu, OrcaSlicerMenuPreferences + bambu_studio_id_base, _L("Preferences") + "\tCtrl+,", "");
|
||||
//auto preference_item = new wxMenuItem(parent_menu, OrcaSlicerMenuPreferences + bambu_studio_id_base, _L("Preferences") + "\t" + ctrl + ",", "");
|
||||
#else
|
||||
wxMenu* parent_menu = m_topbar->GetTopMenu();
|
||||
auto preference_item = new wxMenuItem(parent_menu, ConfigMenuPreferences + config_id_base, _L("Preferences") + "\t" + ctrl + "P", "");
|
||||
@@ -3248,11 +3244,11 @@ void MainFrame::init_menubar_as_gcodeviewer()
|
||||
#if 0
|
||||
wxMenu* fileMenu = new wxMenu;
|
||||
{
|
||||
append_menu_item(fileMenu, wxID_ANY, _L("&Open G-code") + dots + "\tCtrl+O", _L("Open a G-code file"),
|
||||
append_menu_item(fileMenu, wxID_ANY, _L("&Open G-code") + dots + "\t" + ctrl + "O", _L("Open a G-code file"),
|
||||
[this](wxCommandEvent&) { if (m_plater != nullptr) m_plater->load_gcode(); }, "open", nullptr,
|
||||
[this]() {return m_plater != nullptr; }, this);
|
||||
#ifdef __APPLE__
|
||||
append_menu_item(fileMenu, wxID_ANY, _L("Re&load from Disk") + dots + "\tCtrl+Shift+R",
|
||||
append_menu_item(fileMenu, wxID_ANY, _L("Re&load from Disk") + dots + "\t" + ctrl + shift + "R",
|
||||
_L("Reload the plater from disk"), [this](wxCommandEvent&) { m_plater->reload_gcode_from_disk(); },
|
||||
"", nullptr, [this]() { return !m_plater->get_last_loaded_gcode().empty(); }, this);
|
||||
#else
|
||||
|
||||
@@ -298,7 +298,7 @@ void MediaFilePanel::SetMachineObject(MachineObject* obj)
|
||||
switch (status) {
|
||||
case PrinterFileSystem::Initializing: icon = m_bmp_loading; msg = _L("Initializing..."); break;
|
||||
case PrinterFileSystem::Connecting: icon = m_bmp_loading; msg = _L("Connecting..."); break;
|
||||
case PrinterFileSystem::Failed: icon = m_bmp_failed; if (extra != 1) msg = _L("Please check the network and try again, You can restart or update the printer if the issue persists."); break;
|
||||
case PrinterFileSystem::Failed: icon = m_bmp_failed; if (extra != 1) msg = _L("Please check the network and try again. You can restart or update the printer if the issue persists."); break;
|
||||
case PrinterFileSystem::ListSyncing: {
|
||||
icon = m_bmp_loading;
|
||||
msg = _L("Loading file list...");
|
||||
|
||||
@@ -63,11 +63,13 @@ namespace GUI {
|
||||
m_control_refresh->Bind(wxEVT_LEAVE_WINDOW, [this](auto& e) {SetCursor(wxCursor(wxCURSOR_ARROW)); });
|
||||
|
||||
#ifdef __APPLE__
|
||||
m_control_back->SetToolTip(_L("Click to return (Command + Left Arrow)"));
|
||||
m_control_forward->SetToolTip(_L("Click to continue (Command + Right Arrow)"));
|
||||
// FIXME: maybe should be using GUI::shortkey_ctrl_prefix() or equivalent?
|
||||
m_control_back->SetToolTip(_L("Click to return") + "(" + u8"\u2318+" /* u8"⌘+" */ + _L("Left Arrow") + ")");
|
||||
m_control_forward->SetToolTip(_L("Click to continue") + "(" + u8"\u2318+" /* u8"⌘+" */ + _L("Right Arrow") + ")");
|
||||
#else
|
||||
m_control_back->SetToolTip(_L("Click to return (Alt + Left Arrow)"));
|
||||
m_control_forward->SetToolTip(_L("Click to continue (Alt + Right Arrow)"));
|
||||
// FIXME: maybe should be using GUI::shortkey_alt_prefix() or equivalent?
|
||||
m_control_back->SetToolTip(_L("Click to return") + "(" + _L("Alt+") + _L("Left Arrow") + ")");
|
||||
m_control_forward->SetToolTip(_L("Click to continue") + "(" + _L("Alt+") + _L("Right Arrow") + ")");
|
||||
#endif
|
||||
|
||||
m_control_refresh->SetToolTip(_L("Refresh"));
|
||||
|
||||
@@ -300,7 +300,7 @@ ParamsPanel::ParamsPanel( wxWindow* parent, wxWindowID id, const wxPoint& pos, c
|
||||
|
||||
// BBS: new layout
|
||||
//m_search_btn = new ScalableButton(m_top_panel, wxID_ANY, "search", wxEmptyString, wxDefaultSize, wxDefaultPosition, wxBU_EXACTFIT | wxNO_BORDER, true);
|
||||
//m_search_btn->SetToolTip(format_wxstr(_L("Search in settings [%1%]"), "Ctrl+F"));
|
||||
//m_search_btn->SetToolTip(format_wxstr(_L("Search in settings [%1%]"), _L("Ctrl+") + "F");
|
||||
//m_search_btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent &) { wxGetApp().plater()->search(false); });
|
||||
|
||||
m_compare_btn = new ScalableButton(m_top_panel, wxID_ANY, "compare", wxEmptyString, wxDefaultSize, wxDefaultPosition, wxBU_EXACTFIT | wxNO_BORDER, true);
|
||||
|
||||
@@ -4611,7 +4611,7 @@ void Plater::priv::collapse_sidebar(bool collapse)
|
||||
std::string new_tooltip = collapse
|
||||
? _u8L("Expand sidebar")
|
||||
: _u8L("Collapse sidebar");
|
||||
new_tooltip += " [Shift+Tab]";
|
||||
new_tooltip += " [" + _u8L("Shift+") + _u8L("Tab") + "]";
|
||||
int id = collapse_toolbar.get_item_id("collapse_sidebar");
|
||||
collapse_toolbar.set_tooltip(id, new_tooltip);
|
||||
|
||||
@@ -4980,8 +4980,32 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
|
||||
// // Is there any modifier or advanced config data?
|
||||
// for (ModelVolume *model_volume : model_object->volumes) model_volume->config.reset();
|
||||
// }
|
||||
// }
|
||||
else if (load_config && (file_version > app_version)) {
|
||||
// }
|
||||
// Orca: check if the project is created with OrcaSlicer 2.3.1-alpha and use the sparse infill rotation template for non-safe infill patterns
|
||||
else if ((file_version < app_version) && file_version == Semver("2.3.1-alpha")) {
|
||||
if (!config_loaded.opt_string("sparse_infill_rotate_template").empty()) {
|
||||
const auto _sparse_infill_pattern =
|
||||
config_loaded.option<ConfigOptionEnum<InfillPattern>>("sparse_infill_pattern")->value;
|
||||
bool is_safe_to_rotate = _sparse_infill_pattern == ipRectilinear || _sparse_infill_pattern == ipLine ||
|
||||
_sparse_infill_pattern == ipZigZag || _sparse_infill_pattern == ipCrossZag ||
|
||||
_sparse_infill_pattern == ipLockedZag;
|
||||
if (!is_safe_to_rotate) {
|
||||
wxString msg_text = _(
|
||||
L("This project was created with an OrcaSlicer 2.3.1-alpha and uses "
|
||||
"infill rotation template settings that may not work properly with your current infill pattern. "
|
||||
"This could result in weak support or print quality issues."));
|
||||
msg_text += "\n\n" +
|
||||
_(L("Would you like OrcaSlicer to automatically fix this by clearing the rotation template settings?"));
|
||||
MessageDialog dialog(wxGetApp().plater(), msg_text, "", wxICON_WARNING | wxYES | wxNO);
|
||||
dialog.SetButtonLabel(wxID_YES, _L("Yes"));
|
||||
dialog.SetButtonLabel(wxID_NO, _L("No"));
|
||||
if (dialog.ShowModal() == wxID_YES) {
|
||||
config_loaded.opt_string("sparse_infill_rotate_template") = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else if (load_config && (file_version > app_version)) {
|
||||
if (config_substitutions.unrecogized_keys.size() > 0) {
|
||||
wxString text = wxString::Format(_L("The 3mf's version %s is newer than %s's version %s, found following unrecognized keys:"),
|
||||
file_version.to_string(), std::string(SLIC3R_APP_FULL_NAME), app_version.to_string());
|
||||
|
||||
@@ -1640,7 +1640,7 @@ wxPanel *StatusBasePanel::create_bed_control(wxWindow *parent)
|
||||
StateColor z_1_ctrl_bg(std::pair<wxColour, int>(BUTTON_PRESS_COL, StateColor::Pressed), std::pair<wxColour, int>(BUTTON_NORMAL2_COL, StateColor::Normal));
|
||||
StateColor z_1_ctrl_bd(std::pair<wxColour, int>(BUTTON_HOVER_COL, StateColor::Hovered), std::pair<wxColour, int>(BUTTON_NORMAL2_COL, StateColor::Normal));
|
||||
|
||||
m_bpButton_z_10 = new Button(panel, wxString("10"), "monitor_bed_up", 0, FromDIP(15));
|
||||
m_bpButton_z_10 = new Button(panel, wxString("10"), "monitor_bed_up", 0, 15); // Orca Dont scale icon size
|
||||
m_bpButton_z_10->SetFont(::Label::Body_12);
|
||||
m_bpButton_z_10->SetBorderWidth(0);
|
||||
m_bpButton_z_10->SetBackgroundColor(z_10_ctrl_bg);
|
||||
@@ -1649,7 +1649,7 @@ wxPanel *StatusBasePanel::create_bed_control(wxWindow *parent)
|
||||
m_bpButton_z_10->SetMinSize(Z_BUTTON_SIZE);
|
||||
m_bpButton_z_10->SetMaxSize(Z_BUTTON_SIZE);
|
||||
m_bpButton_z_10->SetCornerRadius(0);
|
||||
m_bpButton_z_1 = new Button(panel, wxString(" 1"), "monitor_bed_up", 0, FromDIP(15));
|
||||
m_bpButton_z_1 = new Button(panel, wxString(" 1"), "monitor_bed_up", 0, 15); // Orca Dont scale icon size
|
||||
m_bpButton_z_1->SetFont(::Label::Body_12);
|
||||
m_bpButton_z_1->SetBorderWidth(0);
|
||||
m_bpButton_z_1->SetBackgroundColor(z_1_ctrl_bg);
|
||||
@@ -1665,7 +1665,7 @@ wxPanel *StatusBasePanel::create_bed_control(wxWindow *parent)
|
||||
if (wxGetApp().app_config->get("language") == "de_DE") m_staticText_z_tip->SetFont(::Label::Body_11);
|
||||
m_staticText_z_tip->Wrap(-1);
|
||||
m_staticText_z_tip->SetForegroundColour(TEXT_LIGHT_FONT_COL);
|
||||
m_bpButton_z_down_1 = new Button(panel, wxString(" 1"), "monitor_bed_down", 0, FromDIP(15));
|
||||
m_bpButton_z_down_1 = new Button(panel, wxString(" 1"), "monitor_bed_down", 0, 15); // Orca Dont scale icon size
|
||||
m_bpButton_z_down_1->SetFont(::Label::Body_12);
|
||||
m_bpButton_z_down_1->SetBorderWidth(0);
|
||||
m_bpButton_z_down_1->SetBackgroundColor(z_1_ctrl_bg);
|
||||
@@ -1674,7 +1674,7 @@ wxPanel *StatusBasePanel::create_bed_control(wxWindow *parent)
|
||||
m_bpButton_z_down_1->SetSize(Z_BUTTON_SIZE);
|
||||
m_bpButton_z_down_1->SetTextColor(StateColor(std::make_pair(DISCONNECT_TEXT_COL, (int) StateColor::Disabled), std::make_pair(NORMAL_TEXT_COL, (int) StateColor::Normal)));
|
||||
|
||||
m_bpButton_z_down_10 = new Button(panel, wxString("10"), "monitor_bed_down", 0, FromDIP(15));
|
||||
m_bpButton_z_down_10 = new Button(panel, wxString("10"), "monitor_bed_down", 0, 15); // Orca Dont scale icon size
|
||||
m_bpButton_z_down_10->SetFont(::Label::Body_12);
|
||||
m_bpButton_z_down_10->SetBorderWidth(0);
|
||||
m_bpButton_z_down_10->SetBackgroundColor(z_10_ctrl_bg);
|
||||
@@ -1713,7 +1713,7 @@ wxBoxSizer *StatusBasePanel::create_extruder_control(wxWindow *parent)
|
||||
m_nozzle_btn_panel = new SwitchBoard(panel, _L("Left"), _L("Right"), wxSize(FromDIP(126), FromDIP(26)));
|
||||
m_nozzle_btn_panel->SetAutoDisableWhenSwitch();
|
||||
|
||||
m_bpButton_e_10 = new Button(panel, "", "monitor_extruder_up", 0, FromDIP(22));
|
||||
m_bpButton_e_10 = new Button(panel, "", "monitor_extruder_up", 0, 22); // Orca Dont scale icon size
|
||||
m_bpButton_e_10->SetBorderWidth(2);
|
||||
m_bpButton_e_10->SetBackgroundColor(e_ctrl_bg);
|
||||
m_bpButton_e_10->SetBorderColor(e_ctrl_bd);
|
||||
@@ -1729,7 +1729,7 @@ wxBoxSizer *StatusBasePanel::create_extruder_control(wxWindow *parent)
|
||||
}
|
||||
m_extruder_book->SetSelection(0);
|
||||
|
||||
m_bpButton_e_down_10 = new Button(panel, "", "monitor_extruder_down", 0, FromDIP(22));
|
||||
m_bpButton_e_down_10 = new Button(panel, "", "monitor_extruder_down", 0, 22); // Orca Dont scale icon size
|
||||
m_bpButton_e_down_10->SetBorderWidth(2);
|
||||
m_bpButton_e_down_10->SetBackgroundColor(e_ctrl_bg);
|
||||
m_bpButton_e_down_10->SetBorderColor(e_ctrl_bd);
|
||||
|
||||
+38
-8
@@ -254,7 +254,7 @@ void Tab::create_preset_tab()
|
||||
"or click this button.")));
|
||||
|
||||
add_scaled_button(panel, &m_search_btn, "search");
|
||||
m_search_btn->SetToolTip(format_wxstr(_L("Search in settings [%1%]"), "Ctrl+F"));*/
|
||||
m_search_btn->SetToolTip(format_wxstr(_L("Search in settings [%1%]"), _L("Ctrl+") + "F"));*/
|
||||
|
||||
// Bitmaps to be shown on the "Revert to system" aka "Lock to system" button next to each input field.
|
||||
add_scaled_bitmap(this, m_bmp_value_lock , "unlock_normal");
|
||||
@@ -1658,6 +1658,35 @@ void Tab::on_value_change(const std::string& opt_key, const boost::any& value)
|
||||
}
|
||||
}
|
||||
|
||||
if (opt_key == "sparse_infill_rotate_template") {
|
||||
// Orca: show warning dialog if rotate template for solid infill if not support
|
||||
const auto _sparse_infill_pattern = m_config->option<ConfigOptionEnum<InfillPattern>>("sparse_infill_pattern")->value;
|
||||
bool is_safe_to_rotate = _sparse_infill_pattern == ipRectilinear || _sparse_infill_pattern == ipLine ||
|
||||
_sparse_infill_pattern == ipZigZag || _sparse_infill_pattern == ipCrossZag ||
|
||||
_sparse_infill_pattern == ipLockedZag;
|
||||
|
||||
auto new_value = boost::any_cast<std::string>(value);
|
||||
is_safe_to_rotate = is_safe_to_rotate || new_value.empty();
|
||||
|
||||
if (!is_safe_to_rotate) {
|
||||
wxString msg_text = _(
|
||||
L("Infill patterns are typically designed to handle rotation automatically to ensure proper printing and achieve their "
|
||||
"intended effects (e.g., Gyroid, Cubic). Rotating the current sparse infill pattern may lead to insufficient support. "
|
||||
"Please proceed with caution and thoroughly check for any potential printing issues."
|
||||
"Are you sure you want to enable this option?"));
|
||||
msg_text += "\n\n" + _(L("Are you sure you want to enable this option?"));
|
||||
MessageDialog dialog(wxGetApp().plater(), msg_text, "", wxICON_WARNING | wxYES | wxNO);
|
||||
dialog.SetButtonLabel(wxID_YES, _L("Enable"));
|
||||
dialog.SetButtonLabel(wxID_NO, _L("Cancel"));
|
||||
if (dialog.ShowModal() == wxID_NO) {
|
||||
DynamicPrintConfig new_conf = *m_config;
|
||||
new_conf.set_key_value("sparse_infill_rotate_template", new ConfigOptionString(""));
|
||||
m_config_manipulation.apply(m_config, &new_conf);
|
||||
wxGetApp().plater()->update();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(opt_key=="layer_height"){
|
||||
auto min_layer_height_from_nozzle=wxGetApp().preset_bundle->full_config().option<ConfigOptionFloats>("min_layer_height")->values;
|
||||
auto max_layer_height_from_nozzle=wxGetApp().preset_bundle->full_config().option<ConfigOptionFloats>("max_layer_height")->values;
|
||||
@@ -2278,7 +2307,7 @@ void TabPrint::build()
|
||||
optgroup->append_single_option_line("fill_multiline", "strength_settings_infill#fill-multiline");
|
||||
optgroup->append_single_option_line("sparse_infill_pattern", "strength_settings_infill#sparse-infill-pattern");
|
||||
optgroup->append_single_option_line("infill_direction", "strength_settings_infill#direction");
|
||||
optgroup->append_single_option_line("sparse_infill_rotate_template", "strength_settings_infill#rotation");
|
||||
optgroup->append_single_option_line("sparse_infill_rotate_template", "strength_settings_infill_rotation_template_metalanguage");
|
||||
optgroup->append_single_option_line("skin_infill_density", "strength_settings_patterns#locked-zag");
|
||||
optgroup->append_single_option_line("skeleton_infill_density", "strength_settings_patterns#locked-zag");
|
||||
optgroup->append_single_option_line("infill_lock_depth", "strength_settings_patterns#locked-zag");
|
||||
@@ -2294,13 +2323,14 @@ void TabPrint::build()
|
||||
optgroup->append_single_option_line("infill_anchor", "strength_settings_infill#anchor");
|
||||
optgroup->append_single_option_line("internal_solid_infill_pattern", "strength_settings_infill#internal-solid-infill");
|
||||
optgroup->append_single_option_line("solid_infill_direction", "strength_settings_infill#direction");
|
||||
optgroup->append_single_option_line("solid_infill_rotate_template", "strength_settings_infill#rotation");
|
||||
optgroup->append_single_option_line("solid_infill_rotate_template", "strength_settings_infill_rotation_template_metalanguage");
|
||||
optgroup->append_single_option_line("gap_fill_target", "strength_settings_infill#apply-gap-fill");
|
||||
optgroup->append_single_option_line("filter_out_gap_fill", "strength_settings_infill#filter-out-tiny-gaps");
|
||||
optgroup->append_single_option_line("infill_wall_overlap", "strength_settings_infill#infill-wall-overlap");
|
||||
|
||||
optgroup = page->new_optgroup(L("Advanced"), L"param_advanced");
|
||||
optgroup->append_single_option_line("align_infill_direction_to_model", "strength_settings_advanced#align-infill-direction-to-model");
|
||||
optgroup->append_single_option_line("extra_solid_infills", "strength_settings_infill#extra-solid-infill");
|
||||
optgroup->append_single_option_line("bridge_angle", "strength_settings_advanced#bridge-infill-direction");
|
||||
optgroup->append_single_option_line("internal_bridge_angle", "strength_settings_advanced#bridge-infill-direction"); // ORCA: Internal bridge angle override
|
||||
optgroup->append_single_option_line("minimum_sparse_infill_area", "strength_settings_advanced#minimum-sparse-infill-threshold");
|
||||
@@ -3568,13 +3598,13 @@ void TabFilament::build()
|
||||
optgroup->append_single_option_line("pellet_flow_coefficient", "pellet-flow-coefficient");
|
||||
optgroup->append_single_option_line("filament_flow_ratio", "", 0);
|
||||
|
||||
optgroup->append_single_option_line("enable_pressure_advance");
|
||||
optgroup->append_single_option_line("pressure_advance");
|
||||
optgroup->append_single_option_line("enable_pressure_advance", "pressure-advance-calib");
|
||||
optgroup->append_single_option_line("pressure_advance", "pressure-advance-calib");
|
||||
|
||||
// Orca: adaptive pressure advance and calibration model
|
||||
optgroup->append_single_option_line("adaptive_pressure_advance");
|
||||
optgroup->append_single_option_line("adaptive_pressure_advance_overhangs");
|
||||
optgroup->append_single_option_line("adaptive_pressure_advance_bridges");
|
||||
optgroup->append_single_option_line("adaptive_pressure_advance", "adaptive-pressure-advance-calib");
|
||||
optgroup->append_single_option_line("adaptive_pressure_advance_overhangs", "adaptive-pressure-advance-calib");
|
||||
optgroup->append_single_option_line("adaptive_pressure_advance_bridges", "adaptive-pressure-advance-calib");
|
||||
|
||||
Option option = optgroup->get_option("adaptive_pressure_advance_model");
|
||||
option.opt.full_width = true;
|
||||
|
||||
@@ -18,8 +18,8 @@ static const std::unordered_map<wxString, wxString> ACCESSORY_DISPLAY_STR = {
|
||||
{"N3F", "AMS 2 PRO"},
|
||||
{"N3S", "AMS HT"},
|
||||
{"O2L_PC", L("Air Pump")},
|
||||
{"O2L_10B", L("Laser 10w")},
|
||||
{"O2L_40B", L("Laser 40w")},
|
||||
{"O2L_10B", L("Laser 10 W")},
|
||||
{"O2L_40B", L("Laser 40 W")},
|
||||
{"O2L_PCM", L("Cutting Module")},
|
||||
{"O2L_ACM", "Active Cutting Module"},
|
||||
{"O2L_UCM", "Ultrasonic Cutting Module"},
|
||||
|
||||
Reference in New Issue
Block a user