mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-08-03 12:04:05 -06:00
Merge BS 1.7.7.89
# Conflicts: # bbl/i18n/ko/BambuStudio_ko.po # localization/i18n/OrcaSlicer.pot # localization/i18n/de/OrcaSlicer_de.po # localization/i18n/en/OrcaSlicer_en.po # localization/i18n/es/OrcaSlicer_es.po # localization/i18n/fr/OrcaSlicer_fr.po # localization/i18n/hu/OrcaSlicer_hu.po # localization/i18n/it/OrcaSlicer_it.po # localization/i18n/ja/OrcaSlicer_ja.po # localization/i18n/nl/OrcaSlicer_nl.po # localization/i18n/sv/OrcaSlicer_sv.po # localization/i18n/zh_cn/OrcaSlicer_zh_CN.po # resources/i18n/de/BambuStudio.mo # resources/i18n/en/BambuStudio.mo # resources/i18n/es/BambuStudio.mo # resources/i18n/fr/BambuStudio.mo # resources/i18n/hu/BambuStudio.mo # resources/i18n/it/BambuStudio.mo # resources/i18n/ja/BambuStudio.mo # resources/i18n/ko/BambuStudio.mo # resources/i18n/nl/BambuStudio.mo # resources/i18n/sv/BambuStudio.mo # resources/i18n/zh_cn/BambuStudio.mo # resources/profiles/Anycubic/machine/Anycubic Kobra Max 0.4 nozzle.json # src/OrcaSlicer.cpp # src/libnest2d/include/libnest2d/selections/firstfit.hpp # src/libslic3r/GCode/GCodeProcessor.cpp # src/libslic3r/Print.cpp # src/libslic3r/Print.hpp # src/libslic3r/PrintConfig.cpp # src/slic3r/GUI/CalibrationWizardPresetPage.cpp # src/slic3r/GUI/GLCanvas3D.cpp # src/slic3r/GUI/PartPlate.cpp # src/slic3r/GUI/PartPlate.hpp # src/slic3r/GUI/ReleaseNote.cpp # src/slic3r/GUI/Tab.cpp # version.inc
This commit is contained in:
commit
a7729ca83f
213 changed files with 2090 additions and 649 deletions
|
@ -1,5 +1,5 @@
|
|||
#include "Arrange.hpp"
|
||||
|
||||
#include "Print.hpp"
|
||||
#include "BoundingBox.hpp"
|
||||
|
||||
#include <libnest2d/backends/libslic3r/geometries.hpp>
|
||||
|
@ -80,19 +80,18 @@ using ItemGroup = std::vector<std::reference_wrapper<Item>>;
|
|||
const double BIG_ITEM_TRESHOLD = 0.02;
|
||||
#define VITRIFY_TEMP_DIFF_THRSH 15 // bed temp can be higher than vitrify temp, but not higher than this thresh
|
||||
|
||||
void update_arrange_params(ArrangeParams& params, const DynamicPrintConfig& print_cfg, const ArrangePolygons& selected)
|
||||
void update_arrange_params(ArrangeParams& params, const DynamicPrintConfig* print_cfg, const ArrangePolygons& selected)
|
||||
{
|
||||
double skirt_distance = get_real_skirt_dist(print_cfg);
|
||||
double skirt_distance = get_real_skirt_dist(*print_cfg);
|
||||
// Note: skirt_distance is now defined between outermost brim and skirt, not the object and skirt.
|
||||
// So we can't do max but do adding instead.
|
||||
params.brim_skirt_distance = skirt_distance;
|
||||
params.bed_shrink_x = params.brim_skirt_distance;
|
||||
params.bed_shrink_y = params.brim_skirt_distance;
|
||||
params.bed_shrink_x += params.brim_skirt_distance;
|
||||
params.bed_shrink_y += params.brim_skirt_distance;
|
||||
// for sequential print, we need to inflate the bed because cleareance_radius is so large
|
||||
if (params.is_seq_print) {
|
||||
float shift_dist = params.cleareance_radius / 2 - 5;
|
||||
params.bed_shrink_x -= shift_dist;
|
||||
params.bed_shrink_y -= shift_dist;
|
||||
params.bed_shrink_x -= params.cleareance_radius / 2;
|
||||
params.bed_shrink_y -= params.cleareance_radius / 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -126,11 +125,13 @@ void update_selected_items_inflation(ArrangePolygons& selected, const DynamicPri
|
|||
|
||||
void update_unselected_items_inflation(ArrangePolygons& unselected, const DynamicPrintConfig* print_cfg, const ArrangeParams& params)
|
||||
{
|
||||
float exclusion_gap = 1.f;
|
||||
if (params.is_seq_print) {
|
||||
float shift_dist = params.cleareance_radius / 2 - 5;
|
||||
// bed_shrink_x is typically (-params.cleareance_radius / 2+5) for seq_print
|
||||
exclusion_gap = std::max(exclusion_gap, params.cleareance_radius / 2 + params.bed_shrink_x + 1.f); // +1mm gap so the exclusion region is not too close
|
||||
// dont forget to move the excluded region
|
||||
for (auto& region : unselected) {
|
||||
if (region.is_virt_object) region.poly.translate(-scaled(shift_dist), -scaled(shift_dist));
|
||||
if (region.is_virt_object) region.poly.translate(scaled(params.bed_shrink_x), scaled(params.bed_shrink_y));
|
||||
}
|
||||
}
|
||||
// For occulusion regions, inflation should be larger to prevent genrating brim on them.
|
||||
|
@ -138,10 +139,9 @@ void update_unselected_items_inflation(ArrangePolygons& unselected, const Dynami
|
|||
// 屏蔽区域只需要膨胀brim宽度,防止brim长过去;挤出标定区域不需要膨胀,brim可以长过去。
|
||||
// 以前我们认为还需要膨胀clearance_radius/2,这其实是不需要的,因为这些区域并不会真的摆放物体,
|
||||
// 其他物体的膨胀轮廓是可以跟它们重叠的。
|
||||
double scaled_exclusion_gap = scale_(1);
|
||||
std::for_each(unselected.begin(), unselected.end(),
|
||||
[&](auto& ap) { ap.inflation = !ap.is_virt_object ? (params.min_obj_distance == 0 ? scaled(ap.brim_width) : params.min_obj_distance / 2)
|
||||
: (ap.is_extrusion_cali_object ? 0 : scaled_exclusion_gap); });
|
||||
: (ap.is_extrusion_cali_object ? 0 : scale_(exclusion_gap)); });
|
||||
}
|
||||
|
||||
void update_selected_items_axis_align(ArrangePolygons& selected, const DynamicPrintConfig* print_cfg, const ArrangeParams& params)
|
||||
|
@ -260,7 +260,7 @@ Points get_shrink_bedpts(const DynamicPrintConfig* print_cfg, const ArrangeParam
|
|||
// Slic3r.
|
||||
template<class PConf>
|
||||
void fill_config(PConf& pcfg, const ArrangeParams ¶ms) {
|
||||
|
||||
|
||||
if (params.is_seq_print) {
|
||||
// Start placing the items from the center of the print bed
|
||||
pcfg.starting_point = PConf::Alignment::BOTTOM_LEFT;
|
||||
|
@ -269,7 +269,7 @@ void fill_config(PConf& pcfg, const ArrangeParams ¶ms) {
|
|||
// Start placing the items from the center of the print bed
|
||||
pcfg.starting_point = PConf::Alignment::TOP_RIGHT;
|
||||
}
|
||||
|
||||
|
||||
if (params.do_final_align) {
|
||||
// Align the arranged pile into the center of the bin
|
||||
pcfg.alignment = PConf::Alignment::CENTER;
|
||||
|
@ -286,7 +286,7 @@ void fill_config(PConf& pcfg, const ArrangeParams ¶ms) {
|
|||
// The accuracy of optimization.
|
||||
// Goes from 0.0 to 1.0 and scales performance as well
|
||||
pcfg.accuracy = params.accuracy;
|
||||
|
||||
|
||||
// Allow parallel execution.
|
||||
pcfg.parallel = params.parallel;
|
||||
|
||||
|
@ -312,7 +312,7 @@ static double fixed_overfit(const std::tuple<double, Box>& result, const Box &bi
|
|||
Box fullbb = sl::boundingBox(pilebb, binbb);
|
||||
auto diff = double(fullbb.area()) - binbb.area();
|
||||
if(diff > 0) score += diff;
|
||||
|
||||
|
||||
return score;
|
||||
}
|
||||
|
||||
|
@ -379,7 +379,7 @@ protected:
|
|||
std::vector<Box> m_excluded_and_extruCali_regions; // excluded and extrusion calib regions
|
||||
size_t m_item_count = 0; // Number of all items to be packed
|
||||
ArrangeParams params;
|
||||
|
||||
|
||||
template<class T> ArithmeticOnly<T, double> norm(T val)
|
||||
{
|
||||
return double(val) / m_norm;
|
||||
|
@ -417,18 +417,18 @@ protected:
|
|||
const double bin_area = m_bin_area;
|
||||
const SpatIndex& spatindex = m_rtree;
|
||||
const SpatIndex& smalls_spatindex = m_smallsrtree;
|
||||
|
||||
|
||||
// We will treat big items (compared to the print bed) differently
|
||||
auto isBig = [bin_area](double a) {
|
||||
return a/bin_area > BIG_ITEM_TRESHOLD ;
|
||||
};
|
||||
|
||||
|
||||
// Candidate item bounding box
|
||||
auto ibb = item.boundingBox();
|
||||
|
||||
|
||||
// Calculate the full bounding box of the pile with the candidate item
|
||||
auto fullbb = sl::boundingBox(m_pilebb, ibb);
|
||||
|
||||
|
||||
// The bounding box of the big items (they will accumulate in the center
|
||||
// of the pile
|
||||
Box bigbb;
|
||||
|
@ -437,31 +437,31 @@ protected:
|
|||
auto boostbb = spatindex.bounds();
|
||||
boost::geometry::convert(boostbb, bigbb);
|
||||
}
|
||||
|
||||
|
||||
// Will hold the resulting score
|
||||
double score = 0;
|
||||
|
||||
|
||||
// Density is the pack density: how big is the arranged pile
|
||||
double density = 0;
|
||||
|
||||
|
||||
// Distinction of cases for the arrangement scene
|
||||
enum e_cases {
|
||||
// This branch is for big items in a mixed (big and small) scene
|
||||
// OR for all items in a small-only scene.
|
||||
BIG_ITEM,
|
||||
|
||||
|
||||
// This branch is for the last big item in a mixed scene
|
||||
LAST_BIG_ITEM,
|
||||
|
||||
|
||||
// For small items in a mixed scene.
|
||||
SMALL_ITEM
|
||||
} compute_case;
|
||||
|
||||
|
||||
bool bigitems = isBig(item.area()) || spatindex.empty();
|
||||
if(!params.is_seq_print && bigitems && !m_remaining.empty()) compute_case = BIG_ITEM; // do not use so complicated logic for sequential printing
|
||||
else if (bigitems && m_remaining.empty()) compute_case = LAST_BIG_ITEM;
|
||||
else compute_case = SMALL_ITEM;
|
||||
|
||||
|
||||
switch (compute_case) {
|
||||
case BIG_ITEM: {
|
||||
const Point& minc = ibb.minCorner(); // bottom left corner
|
||||
|
@ -566,7 +566,7 @@ protected:
|
|||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -603,9 +603,11 @@ protected:
|
|||
for (int i = 0; i < m_items.size(); i++) {
|
||||
Item& p = m_items[i];
|
||||
if (p.is_virt_object) continue;
|
||||
score += lambda3 * (item.bed_temp - p.vitrify_temp > VITRIFY_TEMP_DIFF_THRSH);
|
||||
//score += lambda3 * (item.bed_temp - p.vitrify_temp > VITRIFY_TEMP_DIFF_THRSH);
|
||||
if (!Print::is_filaments_compatible({item.filament_temp_type,p.filament_temp_type}))
|
||||
score += lambda3;
|
||||
}
|
||||
score += lambda3 * (item.bed_temp - item.vitrify_temp > VITRIFY_TEMP_DIFF_THRSH);
|
||||
//score += lambda3 * (item.bed_temp - item.vitrify_temp > VITRIFY_TEMP_DIFF_THRSH);
|
||||
score += lambda4 * hasRowHeightConflict + lambda4 * hasLidHeightConflict;
|
||||
}
|
||||
else {
|
||||
|
@ -625,7 +627,9 @@ protected:
|
|||
// 高度接近的件尽量摆到一起
|
||||
score += (1- std::abs(item.height - p.height) / params.printable_height)
|
||||
* norm(pl::distance(ibb.center(), p.boundingBox().center()));
|
||||
score += LARGE_COST_TO_REJECT * (item.bed_temp - p.bed_temp != 0);
|
||||
//score += LARGE_COST_TO_REJECT * (item.bed_temp - p.bed_temp != 0);
|
||||
if (!Print::is_filaments_compatible({ item.filament_temp_type,p.filament_temp_type }))
|
||||
score += LARGE_COST_TO_REJECT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -656,9 +660,9 @@ protected:
|
|||
|
||||
return std::make_tuple(score, fullbb);
|
||||
}
|
||||
|
||||
|
||||
std::function<double(const Item&, const ItemGroup&)> get_objfn();
|
||||
|
||||
|
||||
public:
|
||||
AutoArranger(const TBin & bin,
|
||||
const ArrangeParams ¶ms,
|
||||
|
@ -708,7 +712,7 @@ public:
|
|||
|
||||
m_rtree.clear();
|
||||
m_smallsrtree.clear();
|
||||
|
||||
|
||||
// We will treat big items (compared to the print bed) differently
|
||||
auto isBig = [this](double a) {
|
||||
return a / m_bin_area > BIG_ITEM_TRESHOLD ;
|
||||
|
@ -721,7 +725,7 @@ public:
|
|||
m_smallsrtree.insert({itm.boundingBox(), idx});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
m_pconf.object_function = get_objfn();
|
||||
|
||||
// preload fixed items (and excluded regions) on plate
|
||||
|
@ -746,7 +750,7 @@ public:
|
|||
};
|
||||
|
||||
auto on_packed = params.on_packed;
|
||||
|
||||
|
||||
if (progressind || on_packed)
|
||||
m_pck.progressIndicator(
|
||||
[this, progressind, on_packed](unsigned num_finished) {
|
||||
|
@ -760,7 +764,8 @@ public:
|
|||
if (on_packed)
|
||||
on_packed(ap);
|
||||
BOOST_LOG_TRIVIAL(debug) << "arrange " + last_packed.name + " succeed!"
|
||||
<< ", plate id=" << ap.bed_idx << ", pos=" << last_packed.translation();
|
||||
<< ", plate id=" << ap.bed_idx << ", pos=" << last_packed.translation()
|
||||
<< ", temp_type=" << last_packed.filament_temp_type;
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -783,21 +788,21 @@ public:
|
|||
(i1.extrude_ids != i2.extrude_ids ? (i1.extrude_ids.front() < i2.extrude_ids.front()) : (i1.area() > i2.area()));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
m_pck.configure(m_pconf);
|
||||
}
|
||||
|
||||
|
||||
template<class It> inline void operator()(It from, It to) {
|
||||
m_rtree.clear();
|
||||
m_item_count += size_t(to - from);
|
||||
m_pck.execute(from, to);
|
||||
m_item_count = 0;
|
||||
}
|
||||
|
||||
|
||||
PConfig& config() { return m_pconf; }
|
||||
const PConfig& config() const { return m_pconf; }
|
||||
|
||||
inline void preload(std::vector<Item>& fixeditems) {
|
||||
|
||||
inline void preload(std::vector<Item>& fixeditems) {
|
||||
for(unsigned idx = 0; idx < fixeditems.size(); ++idx) {
|
||||
Item& itm = fixeditems[idx];
|
||||
itm.markAsFixedInBin(itm.binId());
|
||||
|
@ -813,7 +818,7 @@ template<> std::function<double(const Item&, const ItemGroup&)> AutoArranger<Box
|
|||
|
||||
return [this, origin_pack](const Item &itm, const ItemGroup&) {
|
||||
auto result = objfunc(itm, origin_pack);
|
||||
|
||||
|
||||
double score = std::get<0>(result);
|
||||
auto& fullbb = std::get<1>(result);
|
||||
|
||||
|
@ -840,15 +845,15 @@ template<> std::function<double(const Item&, const ItemGroup&)> AutoArranger<Cir
|
|||
auto bb = sl::boundingBox(m_bin);
|
||||
auto origin_pack = m_pconf.starting_point == PConfig::Alignment::CENTER ? bb.center() : bb.minCorner();
|
||||
return [this, origin_pack](const Item &item, const ItemGroup&) {
|
||||
|
||||
|
||||
auto result = objfunc(item, origin_pack);
|
||||
|
||||
|
||||
double score = std::get<0>(result);
|
||||
|
||||
|
||||
auto isBig = [this](const Item& itm) {
|
||||
return itm.area() / m_bin_area > BIG_ITEM_TRESHOLD ;
|
||||
};
|
||||
|
||||
|
||||
if(isBig(item)) {
|
||||
auto mp = m_merged_pile;
|
||||
mp.push_back(item.transformedShape());
|
||||
|
@ -857,7 +862,7 @@ template<> std::function<double(const Item&, const ItemGroup&)> AutoArranger<Cir
|
|||
if(miss < 0) miss = 0;
|
||||
score += miss*miss;
|
||||
}
|
||||
|
||||
|
||||
return score;
|
||||
};
|
||||
}
|
||||
|
@ -873,7 +878,7 @@ std::function<double(const Item &, const ItemGroup&)> AutoArranger<ExPolygon>::g
|
|||
auto result = objfunc(itm, origin_pack);
|
||||
|
||||
double score = std::get<0>(result);
|
||||
|
||||
|
||||
auto mp = m_merged_pile;
|
||||
mp.emplace_back(itm.transformedShape());
|
||||
auto chull = sl::convexHull(mp);
|
||||
|
@ -930,14 +935,14 @@ void _arrange(
|
|||
// Integer ceiling the min distance from the bed perimeters
|
||||
coord_t md = params.min_obj_distance;
|
||||
md = md / 2;
|
||||
|
||||
|
||||
auto corrected_bin = bin;
|
||||
//sl::offset(corrected_bin, md);
|
||||
ArrangeParams mod_params = params;
|
||||
mod_params.min_obj_distance = 0; // items are already inflated
|
||||
|
||||
AutoArranger<BinT> arranger{corrected_bin, mod_params, progressfn, stopfn};
|
||||
|
||||
|
||||
remove_large_items(excludes, corrected_bin);
|
||||
|
||||
// If there is something on the plate
|
||||
|
@ -947,7 +952,7 @@ void _arrange(
|
|||
inp.reserve(shapes.size() + excludes.size());
|
||||
for (auto &itm : shapes ) inp.emplace_back(itm);
|
||||
for (auto &itm : excludes) inp.emplace_back(itm);
|
||||
|
||||
|
||||
// Use the minimum bounding box rotation as a starting point.
|
||||
// TODO: This only works for convex hull. If we ever switch to concave
|
||||
// polygon nesting, a convex hull needs to be calculated.
|
||||
|
@ -987,16 +992,16 @@ inline double distance_to(const Point& p1, const Point& p2)
|
|||
static CircleBed to_circle(const Point ¢er, const Points& points) {
|
||||
std::vector<double> vertex_distances;
|
||||
double avg_dist = 0;
|
||||
|
||||
|
||||
for (auto pt : points)
|
||||
{
|
||||
double distance = distance_to(center, pt);
|
||||
vertex_distances.push_back(distance);
|
||||
avg_dist += distance;
|
||||
}
|
||||
|
||||
|
||||
avg_dist /= vertex_distances.size();
|
||||
|
||||
|
||||
CircleBed ret(center, avg_dist);
|
||||
for(auto el : vertex_distances)
|
||||
{
|
||||
|
@ -1005,7 +1010,7 @@ static CircleBed to_circle(const Point ¢er, const Points& points) {
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1039,6 +1044,7 @@ static void process_arrangeable(const ArrangePolygon &arrpoly,
|
|||
item.print_temp = arrpoly.print_temp;
|
||||
item.vitrify_temp = arrpoly.vitrify_temp;
|
||||
item.inflation(arrpoly.inflation);
|
||||
item.filament_temp_type = arrpoly.filament_temp_type;
|
||||
}
|
||||
|
||||
template<class Fn> auto call_with_bed(const Points &bed, Fn &&fn)
|
||||
|
@ -1079,20 +1085,20 @@ void arrange(ArrangePolygons & arrangables,
|
|||
const ArrangeParams & params)
|
||||
{
|
||||
namespace clppr = Slic3r::ClipperLib;
|
||||
|
||||
|
||||
std::vector<Item> items, fixeditems;
|
||||
items.reserve(arrangables.size());
|
||||
|
||||
|
||||
for (ArrangePolygon &arrangeable : arrangables)
|
||||
process_arrangeable(arrangeable, items);
|
||||
|
||||
|
||||
for (const ArrangePolygon &fixed: excludes)
|
||||
process_arrangeable(fixed, fixeditems);
|
||||
|
||||
|
||||
for (Item &itm : fixeditems) itm.inflate(scaled(-2. * EPSILON));
|
||||
|
||||
|
||||
_arrange(items, fixeditems, to_nestbin(bed), params, params.progressind, params.stopcondition);
|
||||
|
||||
|
||||
for(size_t i = 0; i < items.size(); ++i) {
|
||||
Point tr = items[i].translation();
|
||||
arrangables[i].translation = {coord_t(tr.x()), coord_t(tr.y())};
|
||||
|
|
|
@ -3,6 +3,9 @@
|
|||
|
||||
#include "ExPolygon.hpp"
|
||||
#include "PrintConfig.hpp"
|
||||
|
||||
#define BED_SHRINK_SEQ_PRINT 5
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
class BoundingBox;
|
||||
|
@ -37,12 +40,12 @@ static const constexpr int UNARRANGED = -1;
|
|||
/// be modified during arrangement. Instead, the translation and rotation fields
|
||||
/// will mark the needed transformation for the polygon to be in the arranged
|
||||
/// position. These can also be set to an initial offset and rotation.
|
||||
///
|
||||
///
|
||||
/// The bed_idx field will indicate the logical bed into which the
|
||||
/// polygon belongs: UNARRANGED means no place for the polygon
|
||||
/// (also the initial state before arrange), 0..N means the index of the bed.
|
||||
/// Zero is the physical bed, larger than zero means a virtual bed.
|
||||
struct ArrangePolygon {
|
||||
struct ArrangePolygon {
|
||||
ExPolygon poly; /// The 2D silhouette to be arranged
|
||||
Vec2crd translation{0, 0}; /// The translation of the poly
|
||||
double rotation{0.0}; /// The rotation of the poly in radians
|
||||
|
@ -59,6 +62,7 @@ struct ArrangePolygon {
|
|||
int row{0};
|
||||
int col{0};
|
||||
std::vector<int> extrude_ids{}; /// extruder_id for least extruder switch
|
||||
int filament_temp_type{ -1 };
|
||||
int bed_temp{0}; ///bed temperature for different material judge
|
||||
int print_temp{0}; ///print temperature for different material judge
|
||||
int first_bed_temp{ 0 }; ///first layer bed temperature for different material judge
|
||||
|
@ -66,20 +70,20 @@ struct ArrangePolygon {
|
|||
int vitrify_temp{ 0 }; // max bed temperature for material compatibility, which is usually the filament vitrification temp
|
||||
int itemid{ 0 }; // item id in the vector, used for accessing all possible params like extrude_id
|
||||
int is_applied{ 0 }; // transform has been applied
|
||||
double height{ 0 }; // item height
|
||||
double height{ 0 }; // item height
|
||||
double brim_width{ 0 }; // brim width
|
||||
std::string name;
|
||||
|
||||
|
||||
// If empty, any rotation is allowed (currently unsupported)
|
||||
// If only a zero is there, no rotation is allowed
|
||||
std::vector<double> allowed_rotations = {0.};
|
||||
|
||||
|
||||
/// Optional setter function which can store arbitrary data in its closure
|
||||
std::function<void(const ArrangePolygon&)> setter = nullptr;
|
||||
|
||||
|
||||
/// Helper function to call the setter with the arrange data arguments
|
||||
void apply() {
|
||||
if (setter && !is_applied) {
|
||||
if (setter && !is_applied) {
|
||||
setter(*this);
|
||||
is_applied = 1;
|
||||
}
|
||||
|
@ -101,15 +105,15 @@ struct ArrangePolygon {
|
|||
using ArrangePolygons = std::vector<ArrangePolygon>;
|
||||
|
||||
struct ArrangeParams {
|
||||
|
||||
/// The minimum distance which is allowed for any
|
||||
|
||||
/// The minimum distance which is allowed for any
|
||||
/// pair of items on the print bed in any direction.
|
||||
coord_t min_obj_distance = 0;
|
||||
|
||||
|
||||
/// The accuracy of optimization.
|
||||
/// Goes from 0.0 to 1.0 and scales performance as well
|
||||
float accuracy = 1.f;
|
||||
|
||||
|
||||
/// Allow parallel execution.
|
||||
bool parallel = true;
|
||||
|
||||
|
@ -122,8 +126,8 @@ struct ArrangeParams {
|
|||
bool avoid_extrusion_cali_region = true;
|
||||
bool is_seq_print = false;
|
||||
bool align_to_y_axis = false;
|
||||
float bed_shrink_x = 0;
|
||||
float bed_shrink_y = 0;
|
||||
float bed_shrink_x = 1;
|
||||
float bed_shrink_y = 1;
|
||||
float brim_skirt_distance = 0;
|
||||
float clearance_height_to_rod = 0;
|
||||
float clearance_height_to_lid = 0;
|
||||
|
@ -133,18 +137,18 @@ struct ArrangeParams {
|
|||
|
||||
ArrangePolygons excluded_regions; // regions cant't be used
|
||||
ArrangePolygons nonprefered_regions; // regions can be used but not prefered
|
||||
|
||||
/// Progress indicator callback called when an object gets packed.
|
||||
|
||||
/// Progress indicator callback called when an object gets packed.
|
||||
/// The unsigned argument is the number of items remaining to pack.
|
||||
std::function<void(unsigned, std::string)> progressind = [](unsigned st, std::string str = "") {
|
||||
std::cout << "st=" << st << ", " << str << std::endl;
|
||||
};
|
||||
|
||||
std::function<void(const ArrangePolygon &)> on_packed;
|
||||
|
||||
|
||||
/// A predicate returning true if abort is needed.
|
||||
std::function<bool(void)> stopcondition;
|
||||
|
||||
|
||||
ArrangeParams() = default;
|
||||
explicit ArrangeParams(coord_t md) : min_obj_distance(md) {}
|
||||
// to json format
|
||||
|
@ -170,7 +174,7 @@ struct ArrangeParams {
|
|||
|
||||
};
|
||||
|
||||
void update_arrange_params(ArrangeParams& params, const DynamicPrintConfig& print_cfg, const ArrangePolygons& selected);
|
||||
void update_arrange_params(ArrangeParams& params, const DynamicPrintConfig* print_cfg, const ArrangePolygons& selected);
|
||||
|
||||
void update_selected_items_inflation(ArrangePolygons& selected, const DynamicPrintConfig* print_cfg, ArrangeParams& params);
|
||||
|
||||
|
@ -183,11 +187,11 @@ Points get_shrink_bedpts(const DynamicPrintConfig* print_cfg, const ArrangeParam
|
|||
/**
|
||||
* \brief Arranges the input polygons.
|
||||
*
|
||||
* WARNING: Currently, only convex polygons are supported by the libnest2d
|
||||
* WARNING: Currently, only convex polygons are supported by the libnest2d
|
||||
* library which is used to do the arrangement. This might change in the future
|
||||
* this is why the interface contains a general polygon capable to have holes.
|
||||
*
|
||||
* \param items Input vector of ArrangePolygons. The transformation, rotation
|
||||
* \param items Input vector of ArrangePolygons. The transformation, rotation
|
||||
* and bin_idx fields will be changed after the call finished and can be used
|
||||
* to apply the result on the input polygon.
|
||||
*/
|
||||
|
|
|
@ -783,6 +783,9 @@ int ConfigBase::load_from_json(const std::string &file, ConfigSubstitutionContex
|
|||
std::list<std::string> different_settings_append;
|
||||
std::string new_support_style;
|
||||
bool is_project_settings = false;
|
||||
|
||||
CNumericLocalesSetter locales_setter;
|
||||
|
||||
try {
|
||||
boost::nowide::ifstream ifs(file);
|
||||
ifs >> j;
|
||||
|
|
|
@ -5894,8 +5894,11 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result)
|
|||
/* step width and step height */
|
||||
int sw = thumbnail_data.width / PLATE_THUMBNAIL_SMALL_WIDTH;
|
||||
int sh = thumbnail_data.height / PLATE_THUMBNAIL_SMALL_HEIGHT;
|
||||
for (int i = 0; i < thumbnail_data.height; i += sh) {
|
||||
for (int j = 0; j < thumbnail_data.width; j += sw) {
|
||||
int clampped_width = sw * PLATE_THUMBNAIL_SMALL_WIDTH;
|
||||
int clampped_height = sh * PLATE_THUMBNAIL_SMALL_HEIGHT;
|
||||
|
||||
for (int i = 0; i < clampped_height; i += sh) {
|
||||
for (int j = 0; j < clampped_width; j += sw) {
|
||||
int r = 0, g = 0, b = 0, a = 0;
|
||||
for (int m = 0; m < sh; m++) {
|
||||
for (int n = 0; n < sw; n++) {
|
||||
|
|
|
@ -83,12 +83,6 @@ const std::vector<std::string> GCodeProcessor::Reserved_Tags_compatible = {
|
|||
const std::string GCodeProcessor::Flush_Start_Tag = " FLUSH_START";
|
||||
const std::string GCodeProcessor::Flush_End_Tag = " FLUSH_END";
|
||||
|
||||
const std::map<NozzleType,int> GCodeProcessor::Nozzle_Type_To_HRC={
|
||||
{NozzleType::ntStainlessSteel,20},
|
||||
{NozzleType::ntHardenedSteel,55},
|
||||
{NozzleType::ntBrass,2},
|
||||
{NozzleType::ntUndefine,0}
|
||||
};
|
||||
|
||||
const float GCodeProcessor::Wipe_Width = 0.05f;
|
||||
const float GCodeProcessor::Wipe_Height = 0.05f;
|
||||
|
@ -4350,7 +4344,7 @@ void GCodeProcessor::update_slice_warnings()
|
|||
if (m_highest_bed_temp != 0) {
|
||||
for (size_t i = 0; i < used_extruders.size(); i++) {
|
||||
int temperature = get_filament_vitrification_temperature(used_extruders[i]);
|
||||
if (temperature != 0 && m_highest_bed_temp > temperature)
|
||||
if (temperature != 0 && m_highest_bed_temp >= temperature)
|
||||
warning.params.push_back(std::to_string(used_extruders[i]));
|
||||
}
|
||||
}
|
||||
|
@ -4367,7 +4361,7 @@ void GCodeProcessor::update_slice_warnings()
|
|||
|
||||
int nozzle_hrc = m_result.nozzle_hrc;
|
||||
if(nozzle_hrc <= 0)
|
||||
nozzle_hrc = Nozzle_Type_To_HRC.find(m_result.nozzle_type)->second;
|
||||
nozzle_hrc = Print::get_hrc_by_nozzle_type(m_result.nozzle_type);
|
||||
if (nozzle_hrc!=0) {
|
||||
for (size_t i = 0; i < used_extruders.size(); i++) {
|
||||
int HRC=0;
|
||||
|
|
|
@ -244,7 +244,6 @@ namespace Slic3r {
|
|||
static const std::vector<std::string> Reserved_Tags_compatible;
|
||||
static const std::string Flush_Start_Tag;
|
||||
static const std::string Flush_End_Tag;
|
||||
static const std::map<NozzleType, int>Nozzle_Type_To_HRC;
|
||||
public:
|
||||
enum class ETags : unsigned char
|
||||
{
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include <libslic3r/Model.hpp>
|
||||
#include <libslic3r/Geometry/ConvexHull.hpp>
|
||||
#include <libslic3r/Print.hpp>
|
||||
#include "MTUtils.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
|
@ -10,7 +11,7 @@ arrangement::ArrangePolygons get_arrange_polys(const Model &model, ModelInstance
|
|||
{
|
||||
size_t count = 0;
|
||||
for (auto obj : model.objects) count += obj->instances.size();
|
||||
|
||||
|
||||
ArrangePolygons input;
|
||||
input.reserve(count);
|
||||
instances.clear(); instances.reserve(count);
|
||||
|
@ -21,21 +22,21 @@ arrangement::ArrangePolygons get_arrange_polys(const Model &model, ModelInstance
|
|||
input.emplace_back(ap);
|
||||
instances.emplace_back(minst);
|
||||
}
|
||||
|
||||
|
||||
return input;
|
||||
}
|
||||
|
||||
bool apply_arrange_polys(ArrangePolygons &input, ModelInstancePtrs &instances, VirtualBedFn vfn)
|
||||
{
|
||||
bool ret = true;
|
||||
|
||||
|
||||
for(size_t i = 0; i < input.size(); ++i) {
|
||||
if (input[i].bed_idx != 0) { ret = false; if (vfn) vfn(input[i]); }
|
||||
if (input[i].bed_idx >= 0)
|
||||
instances[i]->apply_arrange_result(input[i].translation.cast<double>(),
|
||||
input[i].rotation);
|
||||
}
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -52,7 +53,7 @@ Slic3r::arrangement::ArrangePolygon get_arrange_poly(const Model &model)
|
|||
const Points &pts = obj_ap.poly.contour.points;
|
||||
std::copy(pts.begin(), pts.end(), std::back_inserter(apts));
|
||||
}
|
||||
|
||||
|
||||
apts = std::move(Geometry::convex_hull(apts).points);
|
||||
return ap;
|
||||
}
|
||||
|
@ -118,7 +119,7 @@ arrangement::ArrangePolygon get_arrange_poly(ModelInstance* inst, const Slic3r::
|
|||
ArrangePolygon get_instance_arrange_poly(ModelInstance* instance, const Slic3r::DynamicPrintConfig& config)
|
||||
{
|
||||
ArrangePolygon ap = get_arrange_poly(PtrWrapper{ instance }, config);
|
||||
|
||||
|
||||
//BBS: add temperature information
|
||||
if (config.has("curr_bed_type")) {
|
||||
ap.bed_temp = 0;
|
||||
|
@ -138,11 +139,23 @@ ArrangePolygon get_instance_arrange_poly(ModelInstance* instance, const Slic3r::
|
|||
ap.print_temp = config.opt_int("nozzle_temperature", ap.extrude_ids.front() - 1);
|
||||
if (config.has("nozzle_temperature_initial_layer")) //get the nozzle_temperature_initial_layer
|
||||
ap.first_print_temp = config.opt_int("nozzle_temperature_initial_layer", ap.extrude_ids.front() - 1);
|
||||
|
||||
|
||||
if (config.has("temperature_vitrification")) {
|
||||
ap.vitrify_temp = config.opt_int("temperature_vitrification", ap.extrude_ids.front() - 1);
|
||||
}
|
||||
|
||||
// get filament temp types
|
||||
auto* filament_types_opt = dynamic_cast<const ConfigOptionStrings*>(config.option("filament_type"));
|
||||
if (filament_types_opt) {
|
||||
std::set<int> filament_temp_types;
|
||||
for (auto i : ap.extrude_ids) {
|
||||
std::string type_str = filament_types_opt->get_at(i-1);
|
||||
int temp_type = Print::get_filament_temp_type(type_str);
|
||||
filament_temp_types.insert(temp_type);
|
||||
}
|
||||
ap.filament_temp_type = Print::get_compatible_filament_type(filament_temp_types);
|
||||
}
|
||||
|
||||
// get brim width
|
||||
auto obj = instance->get_object();
|
||||
|
||||
|
@ -162,7 +175,7 @@ ArrangePolygon get_instance_arrange_poly(ModelInstance* instance, const Slic3r::
|
|||
ap.brim_width = 24.0; // 2*MAX_BRANCH_RADIUS_FIRST_LAYER
|
||||
ap.has_tree_support = true;
|
||||
}
|
||||
|
||||
|
||||
ap.height = obj->bounding_box().size().z();
|
||||
ap.name = obj->name;
|
||||
return ap;
|
||||
|
|
|
@ -2828,7 +2828,6 @@ void PresetBundle::load_config_file_config(const std::string &name_or_path, bool
|
|||
std::pair<PresetsConfigSubstitutions, size_t> PresetBundle::load_vendor_configs_from_json(
|
||||
const std::string &path, const std::string &vendor_name, LoadConfigBundleAttributes flags, ForwardCompatibilitySubstitutionRule compatibility_rule)
|
||||
{
|
||||
CNumericLocalesSetter locales_setter;
|
||||
// Enable substitutions for user config bundle, throw an exception when loading a system profile.
|
||||
ConfigSubstitutionContext substitution_context { compatibility_rule };
|
||||
PresetsConfigSubstitutions substitutions;
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include "ShortestPath.hpp"
|
||||
#include "SupportMaterial.hpp"
|
||||
#include "Thread.hpp"
|
||||
#include "Time.hpp"
|
||||
#include "GCode.hpp"
|
||||
#include "GCode/WipeTower.hpp"
|
||||
#include "GCode/WipeTower2.hpp"
|
||||
|
@ -589,7 +590,7 @@ StringObjectException Print::sequential_print_clearance_valid(const Print &print
|
|||
auto tmp = offset(convex_hull_no_offset,
|
||||
// Shrink the extruder_clearance_radius a tiny bit, so that if the object arrangement algorithm placed the objects
|
||||
// exactly by satisfying the extruder_clearance_radius, this test will not trigger collision.
|
||||
float(scale_(0.5 * print.config().extruder_clearance_radius.value - EPSILON)),
|
||||
float(scale_(0.5 * print.config().extruder_clearance_radius.value - 0.1)),
|
||||
jtRound, scale_(0.1));
|
||||
if (!tmp.empty()) { // tmp may be empty due to clipper's bug, see STUDIO-2452
|
||||
convex_hull = tmp.front();
|
||||
|
@ -954,30 +955,15 @@ static StringObjectException layered_print_cleareance_valid(const Print &print,
|
|||
|
||||
bool Print::check_multi_filaments_compatibility(const std::vector<std::string>& filament_types)
|
||||
{
|
||||
static std::map<std::string, bool> filament_is_high_temp{
|
||||
{"PLA", false},
|
||||
{"PLA-CF", false},
|
||||
//{"PETG", true},
|
||||
{"ABS", true},
|
||||
{"TPU", false},
|
||||
{"PA", true},
|
||||
{"PA-CF", true},
|
||||
{"PET-CF", true},
|
||||
{"PC", true},
|
||||
{"ASA", true},
|
||||
{"HIPS", true}
|
||||
};
|
||||
|
||||
bool has_high_temperature_filament = false;
|
||||
bool has_low_temperature_filament = false;
|
||||
|
||||
for (const auto& type : filament_types)
|
||||
if (filament_is_high_temp.find(type) != filament_is_high_temp.end()) {
|
||||
if (filament_is_high_temp[type])
|
||||
has_high_temperature_filament = true;
|
||||
else
|
||||
has_low_temperature_filament = true;
|
||||
}
|
||||
for (const auto& type : filament_types) {
|
||||
if (get_filament_temp_type(type) ==FilamentTempType::HighTemp)
|
||||
has_high_temperature_filament = true;
|
||||
else if (get_filament_temp_type(type) == FilamentTempType::LowTemp)
|
||||
has_low_temperature_filament = true;
|
||||
}
|
||||
|
||||
if (has_high_temperature_filament && has_low_temperature_filament)
|
||||
return false;
|
||||
|
@ -985,6 +971,44 @@ bool Print::check_multi_filaments_compatibility(const std::vector<std::string>&
|
|||
return true;
|
||||
}
|
||||
|
||||
bool Print::is_filaments_compatible(const std::vector<int>& filament_types)
|
||||
{
|
||||
bool has_high_temperature_filament = false;
|
||||
bool has_low_temperature_filament = false;
|
||||
|
||||
for (const auto& type : filament_types) {
|
||||
if (type == FilamentTempType::HighTemp)
|
||||
has_high_temperature_filament = true;
|
||||
else if (type == FilamentTempType::LowTemp)
|
||||
has_low_temperature_filament = true;
|
||||
}
|
||||
|
||||
if (has_high_temperature_filament && has_low_temperature_filament)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
int Print::get_compatible_filament_type(const std::set<int>& filament_types)
|
||||
{
|
||||
bool has_high_temperature_filament = false;
|
||||
bool has_low_temperature_filament = false;
|
||||
|
||||
for (const auto& type : filament_types) {
|
||||
if (type == FilamentTempType::HighTemp)
|
||||
has_high_temperature_filament = true;
|
||||
else if (type == FilamentTempType::LowTemp)
|
||||
has_low_temperature_filament = true;
|
||||
}
|
||||
|
||||
if (has_high_temperature_filament && has_low_temperature_filament)
|
||||
return HighLowCompatible;
|
||||
else if (has_high_temperature_filament)
|
||||
return HighTemp;
|
||||
else if (has_low_temperature_filament)
|
||||
return LowTemp;
|
||||
return HighLowCompatible;
|
||||
}
|
||||
|
||||
//BBS: this function is used to check whether multi filament can be printed
|
||||
StringObjectException Print::check_multi_filament_valid(const Print& print)
|
||||
{
|
||||
|
@ -1613,8 +1637,12 @@ std::map<ObjectID, unsigned int> getObjectExtruderMap(const Print& print) {
|
|||
}
|
||||
|
||||
// Slicing process, running at a background thread.
|
||||
void Print::process(bool use_cache)
|
||||
void Print::process(long long *time_cost_with_cache, bool use_cache)
|
||||
{
|
||||
long long start_time = 0, end_time = 0;
|
||||
if (time_cost_with_cache)
|
||||
*time_cost_with_cache = 0;
|
||||
|
||||
name_tbb_thread_pool_threads_set_locale();
|
||||
|
||||
//compute the PrintObject with the same geometries
|
||||
|
@ -1775,6 +1803,16 @@ void Print::process(bool use_cache)
|
|||
}
|
||||
}
|
||||
);
|
||||
|
||||
for (PrintObject* obj : m_objects) {
|
||||
if (need_slicing_objects.count(obj) != 0) {
|
||||
obj->detect_overhangs_for_lift();
|
||||
}
|
||||
else {
|
||||
if (obj->set_started(posDetectOverhangsForLift))
|
||||
obj->set_done(posDetectOverhangsForLift);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (PrintObject *obj : m_objects) {
|
||||
|
@ -1791,6 +1829,8 @@ void Print::process(bool use_cache)
|
|||
obj->set_done(posIroning);
|
||||
if (obj->set_started(posSupportMaterial))
|
||||
obj->set_done(posSupportMaterial);
|
||||
if (obj->set_started(posDetectOverhangsForLift))
|
||||
obj->set_done(posDetectOverhangsForLift);
|
||||
}
|
||||
else {
|
||||
obj->make_perimeters();
|
||||
|
@ -1804,8 +1844,10 @@ void Print::process(bool use_cache)
|
|||
|
||||
for (PrintObject *obj : m_objects)
|
||||
{
|
||||
if (need_slicing_objects.count(obj) == 0)
|
||||
if (need_slicing_objects.count(obj) == 0) {
|
||||
obj->copy_layers_from_shared_object();
|
||||
obj->copy_layers_overhang_from_shared_object();
|
||||
}
|
||||
}
|
||||
|
||||
if (this->set_started(psWipeTower)) {
|
||||
|
@ -1824,6 +1866,9 @@ void Print::process(bool use_cache)
|
|||
if (this->set_started(psSkirtBrim)) {
|
||||
this->set_status(70, L("Generating skirt & brim"));
|
||||
|
||||
if (time_cost_with_cache)
|
||||
start_time = (long long)Slic3r::Utils::get_current_time_utc();
|
||||
|
||||
m_skirt.clear();
|
||||
m_skirt_convex_hull.clear();
|
||||
m_first_layer_convex_hull.points.clear();
|
||||
|
@ -1908,6 +1953,11 @@ void Print::process(bool use_cache)
|
|||
|
||||
this->finalize_first_layer_convex_hull();
|
||||
this->set_done(psSkirtBrim);
|
||||
|
||||
if (time_cost_with_cache) {
|
||||
end_time = (long long)Slic3r::Utils::get_current_time_utc();
|
||||
*time_cost_with_cache = *time_cost_with_cache + end_time - start_time;
|
||||
}
|
||||
}
|
||||
//BBS
|
||||
for (PrintObject *obj : m_objects) {
|
||||
|
@ -1925,18 +1975,6 @@ void Print::process(bool use_cache)
|
|||
}
|
||||
}
|
||||
|
||||
// BBS
|
||||
for (PrintObject* obj : m_objects) {
|
||||
if (need_slicing_objects.count(obj) != 0) {
|
||||
obj->detect_overhangs_for_lift();
|
||||
}
|
||||
else {
|
||||
obj->copy_layers_overhang_from_shared_object();
|
||||
if (obj->set_started(posDetectOverhangsForLift))
|
||||
obj->set_done(posDetectOverhangsForLift);
|
||||
}
|
||||
}
|
||||
|
||||
// BBS
|
||||
if(!m_no_check)
|
||||
{
|
||||
|
@ -2229,6 +2267,77 @@ Vec2d Print::translate_to_print_space(const Vec2d &point) const {
|
|||
Vec2d Print::translate_to_print_space(const Point &point) const {
|
||||
return Vec2d(unscaled(point.x()) - m_origin(0), unscaled(point.y()) - m_origin(1));
|
||||
}
|
||||
|
||||
FilamentTempType Print::get_filament_temp_type(const std::string& filament_type)
|
||||
{
|
||||
const static std::string HighTempFilamentStr = "high_temp_filament";
|
||||
const static std::string LowTempFilamentStr = "low_temp_filament";
|
||||
const static std::string HighLowCompatibleFilamentStr = "high_low_compatible_filament";
|
||||
static std::unordered_map<std::string, std::unordered_set<std::string>>filament_temp_type_map;
|
||||
|
||||
if (filament_temp_type_map.empty()) {
|
||||
fs::path file_path = fs::path(resources_dir()) / "info" / "filament_info.json";
|
||||
std::ifstream in(file_path.string());
|
||||
json j;
|
||||
try{
|
||||
j = json::parse(in);
|
||||
in.close();
|
||||
auto&&high_temp_filament_arr =j[HighTempFilamentStr].get < std::vector<std::string>>();
|
||||
filament_temp_type_map[HighTempFilamentStr] = std::unordered_set<std::string>(high_temp_filament_arr.begin(), high_temp_filament_arr.end());
|
||||
auto&& low_temp_filament_arr = j[LowTempFilamentStr].get < std::vector<std::string>>();
|
||||
filament_temp_type_map[LowTempFilamentStr] = std::unordered_set<std::string>(low_temp_filament_arr.begin(), low_temp_filament_arr.end());
|
||||
auto&& high_low_compatible_filament_arr = j[HighLowCompatibleFilamentStr].get < std::vector<std::string>>();
|
||||
filament_temp_type_map[HighLowCompatibleFilamentStr] = std::unordered_set<std::string>(high_low_compatible_filament_arr.begin(), high_low_compatible_filament_arr.end());
|
||||
}
|
||||
catch (const json::parse_error& err){
|
||||
in.close();
|
||||
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ": parse " << file_path.string() << " got a nlohmann::detail::parse_error, reason = " << err.what();
|
||||
filament_temp_type_map[HighTempFilamentStr] = {"ABS","ASA","PC","PA","PA-CF","PA6-CF","PET-CF","PPS","PPS-CF","PPA-GF","PPA-CF"};
|
||||
filament_temp_type_map[LowTempFilamentStr] = {"PLA","TPU","PLA-CF","PLA-AERO","PVA"};
|
||||
filament_temp_type_map[HighLowCompatibleFilamentStr] = { "HIPS","PETG" };
|
||||
}
|
||||
}
|
||||
|
||||
if (filament_temp_type_map[HighLowCompatibleFilamentStr].find(filament_type) != filament_temp_type_map[HighLowCompatibleFilamentStr].end())
|
||||
return HighLowCompatible;
|
||||
if (filament_temp_type_map[HighTempFilamentStr].find(filament_type) != filament_temp_type_map[HighTempFilamentStr].end())
|
||||
return HighTemp;
|
||||
if (filament_temp_type_map[LowTempFilamentStr].find(filament_type) != filament_temp_type_map[LowTempFilamentStr].end())
|
||||
return LowTemp;
|
||||
return Undefine;
|
||||
}
|
||||
|
||||
int Print::get_hrc_by_nozzle_type(const NozzleType&type)
|
||||
{
|
||||
static std::map<std::string, int>nozzle_type_to_hrc;
|
||||
if (nozzle_type_to_hrc.empty()) {
|
||||
fs::path file_path = fs::path(resources_dir()) / "info" / "nozzle_info.json";
|
||||
std::ifstream in(file_path.string());
|
||||
json j;
|
||||
try {
|
||||
j = json::parse(in);
|
||||
in.close();
|
||||
for (const auto& elem : j["nozzle_hrc"].items())
|
||||
nozzle_type_to_hrc[elem.key()] = elem.value();
|
||||
}
|
||||
catch (const json::parse_error& err) {
|
||||
in.close();
|
||||
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ": parse " << file_path.string() << " got a nlohmann::detail::parse_error, reason = " << err.what();
|
||||
nozzle_type_to_hrc = {
|
||||
{"hardened_steel",55},
|
||||
{"stainless_steel",20},
|
||||
{"brass",2},
|
||||
{"undefine",0}
|
||||
};
|
||||
}
|
||||
}
|
||||
auto iter = nozzle_type_to_hrc.find(NozzleTypeEumnToStr[type]);
|
||||
if (iter != nozzle_type_to_hrc.end())
|
||||
return iter->second;
|
||||
//0 represents undefine
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Print::finalize_first_layer_convex_hull()
|
||||
{
|
||||
append(m_first_layer_convex_hull.points, m_skirt_convex_hull);
|
||||
|
@ -2656,6 +2765,8 @@ std::string PrintStatistics::finalize_output_path(const std::string &path_in) co
|
|||
#define JSON_LAYER_ID "layer_id"
|
||||
#define JSON_LAYER_SLICED_POLYGONS "sliced_polygons"
|
||||
#define JSON_LAYER_SLLICED_BBOXES "sliced_bboxes"
|
||||
#define JSON_LAYER_OVERHANG_POLYGONS "overhang_polygons"
|
||||
#define JSON_LAYER_OVERHANG_BBOX "overhang_bbox"
|
||||
|
||||
#define JSON_SUPPORT_LAYER_ISLANDS "support_islands"
|
||||
#define JSON_SUPPORT_LAYER_FILLS "support_fills"
|
||||
|
@ -3292,6 +3403,19 @@ void extract_layer(const json& layer_json, Layer& layer) {
|
|||
layer.lslices_bboxes.push_back(std::move(bbox));
|
||||
}
|
||||
|
||||
//overhang_polygons
|
||||
int overhang_polygons_count = layer_json[JSON_LAYER_OVERHANG_POLYGONS].size();
|
||||
for (int polygon_index = 0; polygon_index < overhang_polygons_count; polygon_index++)
|
||||
{
|
||||
ExPolygon polygon;
|
||||
|
||||
polygon = layer_json[JSON_LAYER_OVERHANG_POLYGONS][polygon_index];
|
||||
layer.loverhangs.push_back(std::move(polygon));
|
||||
}
|
||||
|
||||
//overhang_box
|
||||
layer.loverhangs_bbox = layer_json[JSON_LAYER_OVERHANG_BBOX];
|
||||
|
||||
//layer_regions
|
||||
int layer_region_count = layer.region_count();
|
||||
for (int layer_region_index = 0; layer_region_index < layer_region_count; layer_region_index++)
|
||||
|
@ -3367,7 +3491,7 @@ int Print::export_cached_data(const std::string& directory, bool with_space)
|
|||
boost::filesystem::path directory_path(directory);
|
||||
|
||||
auto convert_layer_to_json = [](json& layer_json, const Layer* layer) {
|
||||
json slice_polygons_json = json::array(), slice_bboxs_json = json::array(), layer_regions_json = json::array();
|
||||
json slice_polygons_json = json::array(), slice_bboxs_json = json::array(), overhang_polygons_json = json::array(), layer_regions_json = json::array();
|
||||
layer_json[JSON_LAYER_PRINT_Z] = layer->print_z;
|
||||
layer_json[JSON_LAYER_HEIGHT] = layer->height;
|
||||
layer_json[JSON_LAYER_SLICE_Z] = layer->slice_z;
|
||||
|
@ -3390,6 +3514,16 @@ int Print::export_cached_data(const std::string& directory, bool with_space)
|
|||
}
|
||||
layer_json[JSON_LAYER_SLLICED_BBOXES] = std::move(slice_bboxs_json);
|
||||
|
||||
//overhang_polygons
|
||||
for (const ExPolygon& overhang_polygon : layer->loverhangs) {
|
||||
json overhang_polygon_json = overhang_polygon;
|
||||
overhang_polygons_json.push_back(std::move(overhang_polygon_json));
|
||||
}
|
||||
layer_json[JSON_LAYER_OVERHANG_POLYGONS] = std::move(overhang_polygons_json);
|
||||
|
||||
//overhang_box
|
||||
layer_json[JSON_LAYER_OVERHANG_BBOX] = layer->loverhangs_bbox;
|
||||
|
||||
for (const LayerRegion *layer_region : layer->regions()) {
|
||||
json region_json = *layer_region;
|
||||
|
||||
|
|
|
@ -92,8 +92,8 @@ enum PrintObjectStep {
|
|||
posSlice, posPerimeters,posEstimateCurledExtrusions, posPrepareInfill,
|
||||
posInfill, posIroning, posSupportMaterial, posSimplifyPath, posSimplifySupportPath,
|
||||
// BBS
|
||||
posSimplifyInfill,
|
||||
posDetectOverhangsForLift,
|
||||
posSimplifyWall, posSimplifyInfill,
|
||||
posCount,
|
||||
};
|
||||
|
||||
|
@ -779,6 +779,12 @@ class ConstPrintRegionPtrsAdaptor : public ConstVectorOfPtrsAdaptor<PrintRegion>
|
|||
};
|
||||
*/
|
||||
|
||||
enum FilamentTempType {
|
||||
HighTemp=0,
|
||||
LowTemp,
|
||||
HighLowCompatible,
|
||||
Undefine
|
||||
};
|
||||
// The complete print tray with possibly multiple objects.
|
||||
class Print : public PrintBaseWithState<PrintStep, psCount>
|
||||
{
|
||||
|
@ -805,7 +811,7 @@ public:
|
|||
|
||||
ApplyStatus apply(const Model &model, DynamicPrintConfig config) override;
|
||||
|
||||
void process(bool use_cache = false) override;
|
||||
void process(long long *time_cost_with_cache = nullptr, bool use_cache = false) override;
|
||||
// Exports G-code into a file name based on the path_template, returns the file path of the generated G-code file.
|
||||
// If preview_data is not null, the preview_data is filled in for the G-code visualization (not used by the command line Slic3r).
|
||||
std::string export_gcode(const std::string& path_template, GCodeProcessorResult* result, ThumbnailsGeneratorCallback thumbnail_cb = nullptr);
|
||||
|
@ -929,8 +935,18 @@ public:
|
|||
Vec2d translate_to_print_space(const Vec2d &point) const;
|
||||
// scaled point
|
||||
Vec2d translate_to_print_space(const Point &point) const;
|
||||
|
||||
static FilamentTempType get_filament_temp_type(const std::string& filament_type);
|
||||
static int get_hrc_by_nozzle_type(const NozzleType& type);
|
||||
static bool check_multi_filaments_compatibility(const std::vector<std::string>& filament_types);
|
||||
// similar to check_multi_filaments_compatibility, but the input is int, and may be negative (means unset)
|
||||
static bool is_filaments_compatible(const std::vector<int>& types);
|
||||
// get the compatible filament type of a multi-material object
|
||||
// Rule:
|
||||
// 1. LowTemp+HighLowCompatible=LowTemp
|
||||
// 2. HighTemp++HighLowCompatible=HighTemp
|
||||
// 3. LowTemp+HighTemp+...=HighLowCompatible
|
||||
// Unset types are just ignored.
|
||||
static int get_compatible_filament_type(const std::set<int>& types);
|
||||
|
||||
protected:
|
||||
// Invalidates the step, and its depending steps in Print.
|
||||
|
|
|
@ -422,7 +422,7 @@ public:
|
|||
// After calling the apply() function, call set_task() to limit the task to be processed by process().
|
||||
virtual void set_task(const TaskParams ¶ms) {}
|
||||
// Perform the calculation. This is the only method that is to be called at a worker thread.
|
||||
virtual void process(bool use_cache = false) = 0;
|
||||
virtual void process(long long *time_cost_with_cache = nullptr, bool use_cache = false) = 0;
|
||||
virtual int export_cached_data(const std::string& dir_path, bool with_space=false) { return 0;}
|
||||
virtual int load_cached_data(const std::string& directory) { return 0;}
|
||||
// Clean up after process() finished, either with success, error or if canceled.
|
||||
|
|
|
@ -1660,8 +1660,8 @@ def = this->add("filament_loading_speed", coFloats);
|
|||
|
||||
// BBS
|
||||
def = this->add("temperature_vitrification", coInts);
|
||||
def->label = L("Temperature of vitrificaiton");
|
||||
def->tooltip = L("Material becomes soft at this temperature. Thus the heatbed cannot be hotter than this tempature");
|
||||
def->label = L("Softening temperature");
|
||||
def->tooltip = L("The material softens at this temperature, so when the bed temperature is equal to or greater than it, it's highly recommended to open the front door and/or remove the upper glass to avoid cloggings.");
|
||||
def->mode = comSimple;
|
||||
def->set_default_value(new ConfigOptionInts{ 100 });
|
||||
|
||||
|
|
|
@ -225,6 +225,13 @@ enum NozzleType {
|
|||
ntCount
|
||||
};
|
||||
|
||||
static std::unordered_map<NozzleType, std::string>NozzleTypeEumnToStr = {
|
||||
{NozzleType::ntUndefine, "undefine"},
|
||||
{NozzleType::ntHardenedSteel, "hardened_steel"},
|
||||
{NozzleType::ntStainlessSteel, "stainless_steel"},
|
||||
{NozzleType::ntBrass, "brass"}
|
||||
};
|
||||
|
||||
// BBS
|
||||
enum PrinterStructure {
|
||||
psUndefine=0,
|
||||
|
|
|
@ -607,7 +607,7 @@ void PrintObject::detect_overhangs_for_lift()
|
|||
size_t num_layers = this->layer_count();
|
||||
size_t num_raft_layers = m_slicing_params.raft_layers();
|
||||
|
||||
m_print->set_status(78, L("Detect overhangs for auto-lift"));
|
||||
m_print->set_status(71, L("Detect overhangs for auto-lift"));
|
||||
|
||||
this->clear_overhangs_for_lift();
|
||||
|
||||
|
|
|
@ -105,6 +105,7 @@ public:
|
|||
int job_id;
|
||||
int design_id;
|
||||
int profile_id;
|
||||
int instance_id;
|
||||
std::string task_id;
|
||||
std::string model_id;
|
||||
std::string model_name;
|
||||
|
|
|
@ -686,7 +686,7 @@ bool SLAPrint::invalidate_step(SLAPrintStep step)
|
|||
return invalidated;
|
||||
}
|
||||
|
||||
void SLAPrint::process(bool use_cache)
|
||||
void SLAPrint::process(long long *time_cost_with_cache, bool use_cache)
|
||||
{
|
||||
if (m_objects.empty())
|
||||
return;
|
||||
|
|
|
@ -451,7 +451,7 @@ public:
|
|||
std::vector<ObjectID> print_object_ids() const override;
|
||||
ApplyStatus apply(const Model &model, DynamicPrintConfig config) override;
|
||||
void set_task(const TaskParams ¶ms) override;
|
||||
void process(bool use_cache = false) override;
|
||||
void process(long long *time_cost_with_cache = nullptr, bool use_cache = false) override;
|
||||
void finalize() override;
|
||||
// Returns true if an object step is done on all objects and there's at least one object.
|
||||
bool is_step_done(SLAPrintObjectStep step) const;
|
||||
|
|
|
@ -3357,7 +3357,7 @@ std::vector<LayerHeightData> TreeSupport::plan_layer_heights(std::vector<std::ve
|
|||
break;
|
||||
}
|
||||
}
|
||||
BOOST_LOG_TRIVIAL(info) << "plan_layer_heights print_z, height, layer_nr->next_layer_nr: " << layer_heights[i].print_z << " " << layer_heights[i].height << " "
|
||||
BOOST_LOG_TRIVIAL(trace) << "plan_layer_heights print_z, height, layer_nr->next_layer_nr: " << layer_heights[i].print_z << " " << layer_heights[i].height << " "
|
||||
<< i << "->" << layer_heights[i].next_layer_nr << std::endl;
|
||||
}
|
||||
|
||||
|
|
|
@ -65,7 +65,7 @@
|
|||
#define CLI_FILAMENTS_DIFFERENT_TEMP -62
|
||||
#define CLI_OBJECT_COLLISION_IN_SEQ_PRINT -63
|
||||
#define CLI_OBJECT_COLLISION_IN_LAYER_PRINT -64
|
||||
#define CLI_SPIRAL_MODE_CANNOT_DUPLICATE -65
|
||||
#define CLI_SPIRAL_MODE_INVALID_PARAMS -65
|
||||
|
||||
#define CLI_SLICING_ERROR -100
|
||||
#define CLI_GCODE_PATH_CONFLICTS -101
|
||||
|
|
|
@ -123,11 +123,11 @@ static ExtrusionPaths thick_polyline_to_extrusion_paths_2(const ThickPolyline& t
|
|||
if (start_index != i){
|
||||
path = ExtrusionPath(role);
|
||||
double length = lines[start_index].length();
|
||||
double sum = lines[start_index].length() * lines[start_index].a_width;
|
||||
double sum = lines[start_index].length() * 0.5 * (lines[start_index].a_width + lines[start_index].b_width);
|
||||
path.polyline.append(lines[start_index].a);
|
||||
for (int idx = start_index + 1; idx < i; idx++) {
|
||||
length += lines[idx].length();
|
||||
sum += lines[idx].length() * lines[idx].a_width;
|
||||
sum += lines[idx].length() * 0.5 * (lines[idx].a_width + lines[idx].b_width);
|
||||
path.polyline.append(lines[idx].a);
|
||||
}
|
||||
path.polyline.append(lines[i].a);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue