mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-05-14 00:52:04 +00:00
Merge branch 'main' into disable_arc_fitting
This commit is contained in:
@@ -493,7 +493,8 @@ if (APPLE)
|
||||
endif ()
|
||||
|
||||
if(MSVC)
|
||||
# 添加编译选项,忽略警告 C4305 (格式转换截断)
|
||||
# Ignore truncating casts in initializers & constructors
|
||||
# https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-1-c4305
|
||||
add_compile_options(/wd4305)
|
||||
endif()
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
"inherits": "fdm_filament_q_common",
|
||||
"from": "system",
|
||||
"setting_id": "GFSA04",
|
||||
"filament_id": "GFB99",
|
||||
"filament_id": "QD_1_0_23",
|
||||
"instantiation": "false",
|
||||
"box_temperature_range_high": [
|
||||
"65"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"type": "filament",
|
||||
"filament_id": "GFB99",
|
||||
"filament_id": "QD_2_0_23",
|
||||
"setting_id": "GFSA04",
|
||||
"name": "Generic PC@Q2C-Series",
|
||||
"from": "system",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"type": "filament",
|
||||
"filament_id": "GFB99",
|
||||
"filament_id": "QD_3_0_23",
|
||||
"setting_id": "GFSA04",
|
||||
"name": "Generic PC@X-Max 4-Series",
|
||||
"from": "system",
|
||||
|
||||
@@ -23,10 +23,11 @@ template<> struct hash<Slic3r::GridPoint3>
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
void InterlockingGenerator::generate_interlocking_structure(PrintObject* print_object)
|
||||
void InterlockingGenerator::generate_interlocking_structure(PrintObject* print_object, const std::function<void()>& throw_on_cancel)
|
||||
{
|
||||
const auto& config = print_object->config();
|
||||
if (!config.interlocking_beam) {
|
||||
// Check if interlocking is enabled, and avoid errors like division by zero due to invalid configuration.
|
||||
if (!config.interlocking_beam || config.interlocking_beam_layer_count < 1 || config.interlocking_depth < 1 || config.interlocking_beam_width < EPSILON ) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -55,8 +56,10 @@ void InterlockingGenerator::generate_interlocking_structure(PrintObject* print_o
|
||||
continue;
|
||||
}
|
||||
|
||||
throw_on_cancel();
|
||||
|
||||
InterlockingGenerator gen(*print_object, region_a_index, region_b_index, beam_width, boundary_avoidance, rotation, cell_size, beam_layer_count,
|
||||
interface_dilation, air_dilation, air_filtering);
|
||||
interface_dilation, air_dilation, air_filtering, throw_on_cancel);
|
||||
gen.generateInterlockingStructure();
|
||||
}
|
||||
}
|
||||
@@ -108,12 +111,14 @@ void InterlockingGenerator::handleThinAreas(const std::unordered_set<GridPoint3>
|
||||
}
|
||||
}
|
||||
for (auto& near_interlock : near_interlock_per_layer) {
|
||||
throw_on_cancel();
|
||||
near_interlock = offset(union_(closing(near_interlock, rounding_errors)), detect);
|
||||
polygons_rotate(near_interlock, rotation);
|
||||
}
|
||||
|
||||
// Only alter layers when they are present in both meshes, zip should take care if that.
|
||||
for (size_t layer_nr = 0; layer_nr < print_object.layer_count(); layer_nr++){
|
||||
throw_on_cancel();
|
||||
auto layer = print_object.get_layer(layer_nr);
|
||||
ExPolygons polys_a = to_expolygons(layer->get_region(region_a_index)->slices.surfaces);
|
||||
ExPolygons polys_b = to_expolygons(layer->get_region(region_b_index)->slices.surfaces);
|
||||
@@ -199,7 +204,8 @@ void InterlockingGenerator::addBoundaryCells(const std::vector<ExPolygons>& lay
|
||||
const DilationKernel& kernel,
|
||||
std::unordered_set<GridPoint3>& cells) const
|
||||
{
|
||||
auto voxel_emplacer = [&cells](GridPoint3 p) {
|
||||
auto voxel_emplacer = [this, &cells](GridPoint3 p) {
|
||||
this->throw_on_cancel();
|
||||
if (p.z() < 0) {
|
||||
return true;
|
||||
}
|
||||
@@ -313,6 +319,7 @@ void InterlockingGenerator::applyMicrostructureToOutlines(const std::unordered_s
|
||||
for (size_t region_idx = 0; region_idx < 2; region_idx++) {
|
||||
const size_t region = (region_idx == 0) ? region_a_index : region_b_index;
|
||||
for (size_t layer_nr = 0; layer_nr < max_layer_count; layer_nr++) {
|
||||
throw_on_cancel();
|
||||
ExPolygons layer_outlines = layer_regions[layer_nr];
|
||||
expolygons_rotate(layer_outlines, unapply_rotation);
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ public:
|
||||
/*!
|
||||
* Generate an interlocking structure between each two adjacent meshes.
|
||||
*/
|
||||
static void generate_interlocking_structure(PrintObject* print_object);
|
||||
static void generate_interlocking_structure(PrintObject* print_object, const std::function<void()>& throw_on_cancel);
|
||||
|
||||
private:
|
||||
/*!
|
||||
@@ -75,7 +75,8 @@ private:
|
||||
const coord_t beam_layer_count,
|
||||
const DilationKernel& interface_dilation,
|
||||
const DilationKernel& air_dilation,
|
||||
const bool air_filtering)
|
||||
const bool air_filtering,
|
||||
const std::function<void()>& throw_on_cancel)
|
||||
: print_object(print_object)
|
||||
, region_a_index(region_a_index)
|
||||
, region_b_index(region_b_index)
|
||||
@@ -88,6 +89,7 @@ private:
|
||||
, interface_dilation(interface_dilation)
|
||||
, air_dilation(air_dilation)
|
||||
, air_filtering(air_filtering)
|
||||
, throw_on_cancel(throw_on_cancel)
|
||||
{}
|
||||
|
||||
/*! Given two polygons, return the parts that border on air, and grow 'perpendicular' up to 'detect' distance.
|
||||
@@ -165,6 +167,8 @@ private:
|
||||
// Whether to fully remove all of the interlocking cells which would be visible on the outside. If no air filtering then those cells
|
||||
// will be cut off midway in a beam.
|
||||
const bool air_filtering;
|
||||
|
||||
const std::function<void()>& throw_on_cancel;
|
||||
};
|
||||
|
||||
} // namespace Slic3r
|
||||
|
||||
@@ -1212,7 +1212,7 @@ void PrintObject::slice_volumes()
|
||||
apply_fuzzy_skin_segmentation(*this, [print]() { print->throw_if_canceled(); });
|
||||
}
|
||||
|
||||
InterlockingGenerator::generate_interlocking_structure(this);
|
||||
InterlockingGenerator::generate_interlocking_structure(this, [print]() { print->throw_if_canceled(); });
|
||||
m_print->throw_if_canceled();
|
||||
|
||||
BOOST_LOG_TRIVIAL(debug) << "Slicing volumes - make_slices in parallel - begin";
|
||||
|
||||
@@ -2835,6 +2835,12 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
|
||||
DynamicPrintConfig& proj_cfg = wxGetApp().preset_bundle->project_config;
|
||||
float x = dynamic_cast<const ConfigOptionFloats*>(proj_cfg.option("wipe_tower_x"))->get_at(plate_id);
|
||||
float y = dynamic_cast<const ConfigOptionFloats*>(proj_cfg.option("wipe_tower_y"))->get_at(plate_id);
|
||||
// Helper: persist corrected wipe tower position to config so the next slice uses valid coords.
|
||||
auto persist_wipe_tower_pos = [&](float nx, float ny) {
|
||||
ConfigOptionFloat cx(nx), cy(ny);
|
||||
proj_cfg.option<ConfigOptionFloats>("wipe_tower_x")->set_at(&cx, plate_id, 0);
|
||||
proj_cfg.option<ConfigOptionFloats>("wipe_tower_y")->set_at(&cy, plate_id, 0);
|
||||
};
|
||||
float w = dynamic_cast<const ConfigOptionFloat*>(m_config->option("prime_tower_width"))->value;
|
||||
float a = dynamic_cast<const ConfigOptionFloat*>(proj_cfg.option("wipe_tower_rotation_angle"))->value;
|
||||
|
||||
@@ -2884,6 +2890,8 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
|
||||
_set_warning_notification(EWarning::PreviewPrimeTowerOutside, true);
|
||||
x = new_x;
|
||||
y = new_y;
|
||||
// Persist the correction to config so the next slice uses the valid position
|
||||
persist_wipe_tower_pos(new_x, new_y);
|
||||
}
|
||||
|
||||
|
||||
@@ -2906,7 +2914,13 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
|
||||
BoundingBoxf3 plate_bbox = wxGetApp().plater()->get_partplate_list().get_plate(plate_id)->get_build_volume(true);
|
||||
BoundingBox plate_bbox2d = BoundingBox(scaled(Vec2f(plate_bbox.min[0], plate_bbox.min[1])), scaled(Vec2f(plate_bbox.max[0], plate_bbox.max[1])));
|
||||
Vec2f offset = WipeTower::move_box_inside_box(tower_bottom_bbox, plate_bbox2d, scaled(margin));
|
||||
int volume_idx_wipe_tower_new = m_volumes.load_real_wipe_tower_preview(1000 + plate_id, x + plate_origin(0), y + plate_origin(1),
|
||||
// move_box_inside_box returns mm (already unscaled); apply directly.
|
||||
// If the actual brim polygon is outside bounds, persist the correction to config.
|
||||
float display_x = x + offset[0];
|
||||
float display_y = y + offset[1];
|
||||
if (offset.norm() > float(EPSILON))
|
||||
persist_wipe_tower_pos(display_x, display_y);
|
||||
int volume_idx_wipe_tower_new = m_volumes.load_real_wipe_tower_preview(1000 + plate_id, display_x + plate_origin(0), display_y + plate_origin(1),
|
||||
current_print->wipe_tower_data().wipe_tower_mesh_data->real_wipe_tower_mesh,
|
||||
current_print->wipe_tower_data().wipe_tower_mesh_data->real_brim_mesh,
|
||||
true,a,/*!print->is_step_done(psWipeTower)*/ true, m_initialized);
|
||||
|
||||
@@ -4074,6 +4074,13 @@ void PartPlateList::set_default_wipe_tower_pos_for_plate(int plate_idx)
|
||||
wt_x_opt = ConfigOptionFloat(I3_WIPE_TOWER_DEFAULT_X_POS);
|
||||
wt_y_opt = ConfigOptionFloat(I3_WIPE_TOWER_DEFAULT_Y_POS);
|
||||
}
|
||||
// Clamp default position to fit within the actual plate dimensions so the wipe tower
|
||||
// doesn't start outside the bed for printers smaller than the hardcoded defaults.
|
||||
const double wt_default_margin = 2.;
|
||||
const double wt_estimated_width = 60.; // conservative estimate matching prime_tower_width default
|
||||
const double wt_estimated_depth = 20.; // conservative depth estimate
|
||||
wt_x_opt.value = std::max(wt_default_margin, std::min(wt_x_opt.value, m_plate_width - wt_estimated_width - wt_default_margin));
|
||||
wt_y_opt.value = std::max(wt_default_margin, std::min(wt_y_opt.value, m_plate_depth - wt_estimated_depth - wt_default_margin));
|
||||
dynamic_cast<ConfigOptionFloats *>(proj_cfg.option("wipe_tower_x"))->set_at(&wt_x_opt, plate_idx, 0);
|
||||
dynamic_cast<ConfigOptionFloats *>(proj_cfg.option("wipe_tower_y"))->set_at(&wt_y_opt, plate_idx, 0);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user