mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-09-10 18:56:13 +00:00
Brim and Cone Aware Preview
This commit is contained in:
@@ -20,6 +20,9 @@
|
||||
#include "libslic3r/AppConfig.hpp"
|
||||
#include "libslic3r/PresetBundle.hpp"
|
||||
#include "libslic3r/ClipperUtils.hpp"
|
||||
#include "libslic3r/GCode/WipeTower.hpp"
|
||||
#include "libslic3r/GCode/WipeTower2.hpp"
|
||||
#include "libslic3r/GCode/WipeTowerEstimate.hpp"
|
||||
#include "libslic3r/Tesselate.hpp"
|
||||
#include "libslic3r/PrintConfig.hpp"
|
||||
|
||||
@@ -919,6 +922,33 @@ int GLVolumeCollection::load_wipe_tower_preview(
|
||||
GUI::PartPlateList& ppl = GUI::wxGetApp().plater()->get_partplate_list();
|
||||
std::vector<int> plate_extruders = ppl.get_plate(plate_idx)->get_extruders(true);
|
||||
TriangleMesh wipe_tower_shell = make_cube(width, depth, height);
|
||||
// The brim is part of the printed footprint: draw it and fold it into the shell so the
|
||||
// outside-bed shader and the drag clamp react to the true first-layer extent.
|
||||
const bool show_brim = brim_width > 0.f;
|
||||
const float brim_height = 0.2f; // one first layer, visual only
|
||||
TriangleMesh brim_slab;
|
||||
if (show_brim) {
|
||||
// A Type2 cone-wall tower's base bulges past the body box — follow the real base
|
||||
// outline instead of the rectangle. Type1 ignores the cone option.
|
||||
Polygon cone_base;
|
||||
{
|
||||
// Preset enums are ConfigOptionEnumGeneric, so read them by value; the planner is
|
||||
// resolved as the estimate resolves it, off the printer preset.
|
||||
const DynamicPrintConfig &print_cfg = GUI::wxGetApp().preset_bundle->prints.get_edited_preset().config;
|
||||
const DynamicPrintConfig &printer_cfg = GUI::wxGetApp().preset_bundle->printers.get_edited_preset().config;
|
||||
const ConfigOption *wall_opt = print_cfg.option("wipe_tower_wall_type");
|
||||
if (wall_opt != nullptr && wall_opt->getInt() == int(WipeTowerWallType::wtwCone) && resolve_wipe_tower_type(printer_cfg) == WipeTowerType::Type2)
|
||||
cone_base = WipeTower2::cone_base_polygon(width, depth, height, print_cfg.opt_float("wipe_tower_cone_angle"));
|
||||
}
|
||||
if (!cone_base.empty()) {
|
||||
Polygons brim_outline = offset(cone_base, scaled(brim_width));
|
||||
brim_slab = WipeTower::its_make_rib_brim(brim_outline.empty() ? cone_base : brim_outline.front(), brim_height);
|
||||
} else {
|
||||
brim_slab = make_cube(width + 2.f * brim_width, depth + 2.f * brim_width, brim_height);
|
||||
brim_slab.translate({-brim_width, -brim_width, 0.f});
|
||||
}
|
||||
wipe_tower_shell.merge(brim_slab);
|
||||
}
|
||||
for (int extruder_id : plate_extruders) {
|
||||
if (extruder_id <= extruder_colors.size())
|
||||
colors.push_back(extruder_colors[extruder_id - 1]);
|
||||
@@ -929,14 +959,19 @@ int GLVolumeCollection::load_wipe_tower_preview(
|
||||
// Orca: make it transparent
|
||||
for(auto& color : colors)
|
||||
color.a(0.66f);
|
||||
const size_t slab_count = colors.size(); // per-filament body slabs; the brim part comes after
|
||||
if (show_brim && !colors.empty())
|
||||
colors.push_back(colors.front());
|
||||
volumes.emplace_back(new GLWipeTowerVolume(colors));
|
||||
GLWipeTowerVolume& v = *dynamic_cast<GLWipeTowerVolume*>(volumes.back());
|
||||
v.model_per_colors.resize(colors.size());
|
||||
for (int i = 0; i < colors.size(); i++) {
|
||||
TriangleMesh color_part = make_cube(width, depth / colors.size(), height);
|
||||
color_part.translate({ 0.f, depth * i / colors.size(), 0. });
|
||||
for (size_t i = 0; i < slab_count; i++) {
|
||||
TriangleMesh color_part = make_cube(width, depth / slab_count, height);
|
||||
color_part.translate({ 0.f, depth * i / slab_count, 0. });
|
||||
v.model_per_colors[i].init_from(color_part);
|
||||
}
|
||||
if (show_brim && !colors.empty())
|
||||
v.model_per_colors[slab_count].init_from(brim_slab);
|
||||
v.model.init_from(wipe_tower_shell);
|
||||
v.mesh_raycaster = std::make_unique<GUI::MeshRaycaster>(std::make_shared<const TriangleMesh>(wipe_tower_shell));
|
||||
v.set_convex_hull(wipe_tower_shell);
|
||||
|
||||
@@ -2907,7 +2907,9 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
|
||||
Vec3d wipe_tower_size(footprint.width, footprint.depth, footprint.height);
|
||||
|
||||
// set_default_wipe_tower_pos_for_plate doesn't rerun when painting changes the
|
||||
// filament count, so redo its clamp here on every reload.
|
||||
// filament count, so redo its clamp here on every reload — unconditionally: a
|
||||
// paint-triggered reload can arrive before the background process invalidates
|
||||
// psWipeTower, so gating on it would skip the clamp exactly when it is needed.
|
||||
{
|
||||
Vec3d clamped_pos, clamped_size;
|
||||
part_plate->estimate_wipe_tower_polygon(full_config, plate_id, clamped_pos, clamped_size);
|
||||
|
||||
@@ -1274,9 +1274,10 @@ void Selection::translate(const Vec3d &displacement, TransformationType transfor
|
||||
Vec3d tower_origin = m_cache.volumes_data[i].get_volume_position();
|
||||
Vec3d actual_displacement = displacement;
|
||||
bool show_read_wipe_tower = wxGetApp().plater()->get_partplate_list().get_plate(plate_idx)->fff_print()->is_step_done(psWipeTower);
|
||||
float brim_width = wxGetApp().preset_bundle->prints.get_edited_preset().config.opt_float("prime_tower_brim_width");
|
||||
|
||||
const double margin = show_read_wipe_tower ? WIPE_TOWER_MARGIN : brim_width + 0.5; // 0.5 is the line width of wipe tower
|
||||
// Both preview volumes carry the brim in their bounding box (the estimate
|
||||
// preview merges a brim slab, the sliced preview the real brim mesh), so the
|
||||
// drag clamp only pads by the wipe tower line width.
|
||||
const double margin = show_read_wipe_tower ? WIPE_TOWER_MARGIN : 0.5; // 0.5 is the line width of wipe tower
|
||||
|
||||
actual_displacement = (m_cache.volumes_data[i].get_instance_rotation_matrix() * m_cache.volumes_data[i].get_instance_scale_matrix() *
|
||||
m_cache.volumes_data[i].get_instance_mirror_matrix())
|
||||
|
||||
Reference in New Issue
Block a user