切换开发版本前最后提交代码

This commit is contained in:
cjw 2025-06-03 09:08:41 +08:00
parent 599cd5ed72
commit 49a9b27eab
25 changed files with 3246 additions and 54 deletions

File diff suppressed because it is too large Load Diff

1341
libslic3r/Fill/Bridge.cpp Normal file

File diff suppressed because it is too large Load Diff

256
libslic3r/Fill/Bridge.hpp Normal file
View File

@ -0,0 +1,256 @@
//
// Created by ylzha on 2025/2/25.
//
//#ifndef DBRIDGE_HPP
//#define DBRIDGE_HPP
#ifndef slic3r_Bridge_hpp_
#define slic3r_Bridge_hpp_
// 防止头文件被重复包含的预处理器指令
//#pragma once
#include "../libslic3r.h"
//#include <utility>
//#include <vector>
//#include <unordered_set>
#include <boost/geometry.hpp>
//#include <boost/multiprecision/decimal/decimal.hpp>
//#include <boost/geometry/geometries/point_xy.hpp>
//#include <boost/geometry/geometries/segment.hpp>
//#include <boost/geometry/geometries/polygon.hpp>
//#include <boost/geometry/geometries/ring.hpp>
//#include <boost/geometry/geometries/linestring.hpp>
//#include <boost/functional/hash/hash.hpp>
#include "FillBase.hpp"
namespace bg = boost::geometry;
//#include <SFML/Graphics.hpp>
namespace Slic3r{
class Surface;
//namespace bg = boost::geometry;
// 定义点类型
typedef bg::model::d2::point_xy<double> Point_t;
//定义线段
typedef bg::model::segment<Point_t> Segment;
// 定义多边形类型
typedef bg::model::polygon<Point_t> Polygon_t;
// 多边形集合
typedef bg::model::multi_polygon<Polygon_t> MultiPolygon;
// 定义环类型
typedef bg::model::ring<Point_t> Ring;
// 定义折线类型(用于表示直线)
//typedef bg::model::linestring<Point> Linestring;
// 定义多边形的外边界和内边界
struct PolygonBoundaries {
Ring outerBoundary; // 外边界
std::vector<Ring> innerBoundaries; // 内边界(可能有多个)
};
struct IdIndex {
size_t id{};
size_t index{};
// 定义小于运算符
bool operator<(const IdIndex& other) const {
return id < other.id;
}
IdIndex(const size_t id, const size_t index) : id(id), index(index) {}
bool operator==(const IdIndex& ii) const {
return id == ii.id && index == ii.index;
}
};
//环路径树结构中节点类型
struct RingNode {
IdIndex id;
Ring ring; //当前环
int orientation{}; //方向 -1 向内 1 向外
std::vector<RingNode> children; //子节点集
RingNode* parent; //父节点
bool isHide{ false }; //在最终路径中是否呈现 false 呈现 true 不呈现
// 构造函数,方便初始化
RingNode(const IdIndex id, const Ring& ring, const int orientation = 0)
: id(id), ring(ring), orientation(orientation), parent(nullptr) {
}
// 重载==运算符方便比较
bool operator==(const RingNode& other) const {
return id.id == other.id.id && id.index == other.id.index;
}
};
//桥接映射
struct BridgeMap {
Point_t from;
Point_t to;
Point_t from2;
Point_t to2;
IdIndex from_ii;
IdIndex to_ii;
BridgeMap(Point_t from, Point_t to, Point_t from2, Point_t to2,IdIndex from_ii, IdIndex to_ii) :
from(from), to(to), from2(from2), to2(to2),from_ii(from_ii), to_ii(to_ii) { }
};
//合并映射
struct MergeMap {
IdIndex ii1; //环1
IdIndex ii2; //环2
std::vector<IdIndex> nodes; //产生的环集
// 构造函数
MergeMap(const IdIndex& i1, const IdIndex& i2, const std::vector<IdIndex>& nodeList)
: ii1(i1), ii2(i2), nodes(nodeList) {
}
};
//struct PointHash_t {
// std::size_t operator()(const Point_t& p) const {
// std::size_t seed = 0;
// boost::hash_combine(seed, bg::get<0>(p));
// boost::hash_combine(seed, bg::get<1>(p));
// return seed;
// }
//};
//
//struct PointEqual_t {
// bool operator()(const Point_t& a, const Point_t& b) const {
// return bg::equals(a, b);
// }
//};
class Bridge : public Fill {
//public:
// Bridge(Polygon _polygon, const double o) : offset(o), polygon(std::move(_polygon)) {};
// ~Bridge() = default;
public:
//Slic3r::Fill* clone() const override { return new Bridge(*this); };
Fill* clone() const override { return new Bridge(*this); };
//Bridge() {};
//Bridge(Polygon_t _polygon, const double o) : offset(o), polygon(std::move(_polygon)) {};
~Bridge() override = default;
Polylines fill_surface(const Surface* surface, const FillParams& params) override;
protected:
/*void _fill_surface_single(
const FillParams& params,
unsigned int thickness_layers,
const std::pair<float, Point>& direction,
ExPolygon expolygon,
Polylines& polylines_out) override;*/
//Polylines fill_surface(const Surface* surface, const FillParams& params) override;
coord_t _min_spacing;
coord_t _line_spacing;
// distance threshold for allowing the horizontal infill lines to be connected into a continuous path
coord_t _diagonal_distance;
// only for line infill
coord_t _line_oscillation;
private:
//计算多边形的外边界和内边界
void computePolygonBoundaries(const Polygon_t& polygon);
// 判断两个环是否相交(不包括包含关系)
bool ringsIntersect(const Ring& ring1, const Ring& ring2);
//获取环偏移后的环(可能为空)
std::vector<Ring> offsetRing(const Ring& ring, double distance);
// 查找环非邻边的相交点
std::vector<Point_t> findNonAdjacentIntersections(const Ring& ring);
// 将环拆分成多个环
std::vector<Ring> split(const Ring& ring, const std::vector<Point_t>& intersections);
// 合并两个环
std::vector<Ring> merge(const RingNode& ring1, const RingNode& ring2);
//生成环集
void generateRings();
//形成节点
RingNode formatNode(size_t id, size_t index, const Ring& ring, int orientation);
void addNode(RingNode& node);
void removeNode(IdIndex id);
//查找节点
RingNode& findNode(IdIndex ii);
//形成树
void formatTree();
// 深度优先搜索遍历树
void dfs(RingNode& node, std::vector<IdIndex>& visited,size_t& edge);
//找到多边形环第 N 条边的中心点
Point_t findCenterPointOnEdge(Ring& ring, size_t N);
// 在环上按顺时针方向查找距离给定点d的另一个点
Point_t find_point_at_distance_clockwise(Ring& ring, const Point_t& start_point, double d);
size_t findLongestEdgeIndex(const Ring& ring);
//在第N条边上进行内外环桥接并插入桥接点
//o_ii 外环IdIndex i_ii 内环IdIndex ring_size内环大小 N边索引
void handleBridge(IdIndex o_ii, IdIndex i_ii, const size_t ring_size, const size_t N);
//递归遍历环
void traverseRing(
RingNode& node,
IdIndex parent,
Point_t& start,
Point_t& end,
bool isOutermostLayer //是否最外层
);
//输出所有环
void printRings();
//sf::VertexArray convertToSFML(const Polygon& poly, const sf::Color& color);
public:
//输出树结构
void printTree();
//std::vector<Point_t> outputPaths();
//画路径 SFML顶点数组集
//std::vector<sf::Vertex> outputPaths();
//std::vector<sf::VertexArray> convert2vertex();
//std::vector<sf::VertexArray> verteies;
//std::vector<sf::VertexArray> convertBridge();
private:
size_t maxRid = 1; //最大环类型ID值
double offset; //偏移距离
Polygon_t polygon; //2D多边形
double area_threshold = 4; //面积阈值
PolygonBoundaries boundaries; //外/内边界
std::map<size_t, std::vector<RingNode>> ringNodes; //存储不同环类型的节点集合 size_t 环类型id
std::vector<RingNode> nodeHandles; //当前需进行自交或互交处理的节点集合
std::map<IdIndex, std::vector<IdIndex>> splitMap; //分裂映射集
std::vector<MergeMap> mergeMap; //合并映射集
std::map<IdIndex, std::vector<IdIndex>> offsetMap; //偏移后产生的分裂映射集
std::vector<BridgeMap> bridges; //桥接映射
std::vector<Point_t> path; // 路径
bool isFront{ false };
size_t sel_edge_index{ 1 }; //选择桥接边的索引
};
}; // namespace Slic3r
//#endif //DBRIDGE_HPP
#endif // slic3r_Bridge_hpp_

View File

@ -428,7 +428,7 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive:
std::vector<SurfaceFill> surface_fills = group_fills(*this);
const Slic3r::BoundingBox bbox = this->object()->bounding_box();
const auto resolution = this->object()->print()->config().resolution.value;
//bbox.area();
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
{
static int iRun = 0;
@ -437,6 +437,7 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive:
#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
for (SurfaceFill &surface_fill : surface_fills) {
//surface_fill.expolygons.contour().
// Create the filler object.
//创建填充对象。
std::unique_ptr<Fill> f = std::unique_ptr<Fill>(Fill::new_from_type(surface_fill.params.pattern));
@ -505,6 +506,12 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive:
//填充物会修改间距以表示调整。为每个expolygon重置它。
f->spacing = surface_fill.params.spacing;
surface_fill.surface.expolygon = std::move(expoly);
//expoly.contour.bounding_box().polygon().points;
//for (auto p : surface_fill.surface.expolygon.contour.bounding_box().polygon().points) {
//wss << L"Point(" << p.x() << L", " << p.y() << L"),\n";
//strstrm << "Point(" << p.x() << ", " << p.y() << "),\n";
//strstrm << p.x() << "," << p.y() << "\n";
//}
// BBS: make fill
//此处往里执行
f->fill_surface_extrusion(&surface_fill.surface,

View File

@ -24,6 +24,7 @@
// BBS: new infill pattern header
#include "FillConcentricInternal.hpp"
#include "FillCrossHatch.hpp"
#include "Bridge.hpp"
// #define INFILL_DEBUG_OUTPUT
@ -57,7 +58,7 @@ Fill* Fill::new_from_type(const InfillPattern type)
// BBS: for bottom and top surface only
case ipMonotonicLine: return new FillMonotonicLineWGapFill();
//xiamian+
case ipFiberSpiral: return new FillLine();
case ipFiberSpiral: return new Bridge();
default: throw Slic3r::InvalidArgument("unknown type");
}
}
@ -133,15 +134,45 @@ void Fill::fill_surface_extrusion(const Surface* surface, const FillParams& para
catch (InfillFailedException&) {}
if (!polylines.empty() || !thick_polylines.empty()) {
if (!pointMap.empty()) {
Point tempPoint = pointMap.at(1);
Polyline firstPolyline = polylines.front();
firstPolyline.append_before(tempPoint);
//Point firstPoint = firstPolyline.first_point();
}
Polyline lastPolyline = polylines.back();
Point lastPoint = lastPolyline.last_point();
pointMap.insert(std::make_pair(1, lastPoint));
//int key = 1;
//tbb::concurrent_hash_map<int, Point>::const_accessor accessor;
//if (!polylines.empty()) {
// for (auto& one : polylines) {
// //if (!pointMap.empty()) {
// tbb::concurrent_hash_map<int, Point>::const_accessor accessor1;
// if (pointMap.find(accessor1, key)) {
// //Point tempOne = pointMap.at(1);
// Point tempOne = accessor1 -> second;
// Point firstOne = one.first_point();
// double a1 = (firstOne - tempOne).norm();
// double a2 = (tempOne - firstOne).norm();
// if (a1 > 0 || a2 > 0) {
// one.append_before(tempOne);
// }
// }
// Point lastOne = one.last_point();
// pointMap.emplace(key, lastOne);
// }
//}
//if (!thick_polylines.empty()) {
// for (auto& two : thick_polylines) {
// //if (!pointMap.empty()) {
// tbb::concurrent_hash_map<int, Point>::const_accessor accessor2;
// if (pointMap.find(accessor2,key)){
// //if (it != pointMap.end()) {
// //Point tempTwo = pointMap.at(1);
// Point tempTwo = accessor2 -> second;
// Point firstTwo = two.first_point();
// double b1 = (firstTwo - tempTwo).norm();
// double b2 = (tempTwo - firstTwo).norm();
// if (b1 > 100 || b2 > 100) {
// two.append_before(tempTwo);
// }
// }
// Point lastTwo = two.last_point();
// pointMap.emplace(key, lastTwo);
// }
//}
// calculate actual flow from spacing (which might have been adjusted by the infill
// pattern generator)
//根据间距计算实际流量(可能已由填充生成器调整)
@ -188,6 +219,8 @@ void Fill::fill_surface_extrusion(const Surface* surface, const FillParams& para
// This function possibly increases the spacing, never decreases,
// and for a narrow width the increase in spacing may become severe,
// therefore the adjustment is limited to 20% increase.
//计算一个新的间距,用可能的整数行填充宽度,第一行和最后一行以间隔结束为中心。
//此功能可能会增加间距但不会减少对于窄宽度间距的增加可能会变得严重因此调整仅限于20%的增加。
coord_t Fill::_adjust_solid_spacing(const coord_t width, const coord_t distance)
{
assert(width >= 0);
@ -200,6 +233,7 @@ coord_t Fill::_adjust_solid_spacing(const coord_t width, const coord_t distance)
const coordf_t factor = coordf_t(distance_new) / coordf_t(distance);
assert(factor > 1. - 1e-5);
// How much could the extrusion width be increased? By 20%.
//挤压宽度可以增加多少20%。
const coordf_t factor_max = 1.2;
if (factor > factor_max)
distance_new = coord_t(floor((coordf_t(distance) * factor_max + 0.5)));

View File

@ -6,7 +6,7 @@
#include <float.h>
#include <stdint.h>
#include <stdexcept>
#include <tbb/concurrent_hash_map.h>
#include <type_traits>
#include "../libslic3r.h"
@ -20,6 +20,7 @@
#include "../ExtrusionEntity.hpp"
#include "../ExtrusionEntityCollection.hpp"
namespace Slic3r {
class Surface;
@ -106,7 +107,8 @@ public:
// BBS: all no overlap expolygons in same layer
ExPolygons no_overlap_expolygons;
std::map<int, Point> pointMap;
//std::map<int, Point> pointMap;
tbb::concurrent_hash_map<int, Point> pointMap;
public:
virtual ~Fill() {}

View File

@ -17,6 +17,7 @@ void FillConcentric::_fill_surface_single(
Polylines &polylines_out)
{
// no rotation is supported for this infill pattern
//此填充图案不支持旋转
BoundingBox bounding_box = expolygon.contour.bounding_box();
coord_t min_spacing = scale_(this->spacing);
@ -36,9 +37,11 @@ void FillConcentric::_fill_surface_single(
// generate paths from the outermost to the innermost, to avoid
// adhesion problems of the first central tiny loops
//生成从最外层到最内层的路径,以避免第一个中心微环的粘附问题
loops = union_pt_chained_outside_in(loops);
// split paths using a nearest neighbor search
//使用最近邻搜索分割路径
size_t iPathFirst = polylines_out.size();
Point last_pos(0, 0);
for (const Polygon &loop : loops) {
@ -48,6 +51,7 @@ void FillConcentric::_fill_surface_single(
// clip the paths to prevent the extruder from getting exactly on the first point of the loop
// Keep valid paths only.
//剪切路径以防止挤出机精确地到达回路的第一点。仅保留有效路径。
size_t j = iPathFirst;
for (size_t i = iPathFirst; i < polylines_out.size(); ++ i) {
polylines_out[i].clip_end(this->loop_clipping);
@ -74,6 +78,7 @@ void FillConcentric::_fill_surface_single(const FillParams& params,
assert(this->print_config != nullptr && this->print_object_config != nullptr);
// no rotation is supported for this infill pattern
//此填充图案不支持旋转
Point bbox_size = expolygon.contour.bounding_box().size();
coord_t min_spacing = scaled<coord_t>(this->spacing);
@ -102,6 +107,7 @@ void FillConcentric::_fill_surface_single(const FillParams& params,
}
// Split paths using a nearest neighbor search.
//使用最近邻搜索分割路径。
size_t firts_poly_idx = thick_polylines_out.size();
Point last_pos(0, 0);
for (const Arachne::ExtrusionLine* extrusion : all_extrusions) {
@ -123,6 +129,7 @@ void FillConcentric::_fill_surface_single(const FillParams& params,
// clip the paths to prevent the extruder from getting exactly on the first point of the loop
// Keep valid paths only.
//夹紧路径,防止挤出机精确地到达环路的第一点 仅保留有效路径。
size_t j = firts_poly_idx;
for (size_t i = firts_poly_idx; i < thick_polylines_out.size(); ++i) {
thick_polylines_out[i].clip_end(this->loop_clipping);

View File

@ -15,6 +15,7 @@ void FillLine::_fill_surface_single(
Polylines &polylines_out)
{
// rotate polygons so that we can work with vertical lines here
//旋转多边形,这样我们就可以在这里处理垂直线
expolygon.rotate(- direction.first);
this->_min_spacing = scale_(this->spacing);
@ -25,12 +26,15 @@ void FillLine::_fill_surface_single(
BoundingBox bounding_box = expolygon.contour.bounding_box();
// define flow spacing according to requested density
//根据要求的密度定义流间距
if (params.density > 0.9999f && !params.dont_adjust) {
this->_line_spacing = this->_adjust_solid_spacing(bounding_box.size()(0), this->_line_spacing);
this->spacing = unscale<double>(this->_line_spacing);
} else {
// extend bounding box so that our pattern will be aligned with other layers
// Transform the reference point to the rotated coordinate system.
//扩展边界框,使我们的图案与其他层对齐
//将参考点变换到旋转坐标系。
bounding_box.merge(align_to_grid(
bounding_box.min,
Point(this->_line_spacing, this->_line_spacing),
@ -38,6 +42,7 @@ void FillLine::_fill_surface_single(
}
// generate the basic pattern
//生成基本模式
coord_t x_max = bounding_box.max(0) + SCALED_EPSILON;
Lines lines;
for (coord_t x = bounding_box.min(0); x <= x_max; x += this->_line_spacing)
@ -49,6 +54,9 @@ void FillLine::_fill_surface_single(
// however we use a larger offset to support expolygons with slightly skewed sides and
// not perfectly straight
//FIXME Vojtech: Update the intersecton function to work directly with lines.
//将路径剪切到稍大的expolygon上这样即使expolygon有垂直边也能保持第一条和最后一条路径防止边缘线被剪切的最小偏移量为SCALED_EPSILON
//然而我们使用更大的偏移量来支持边略微倾斜且不完全笔直的expolygon
//FIXME Vojtech更新交集函数以直接处理线条。
Polylines polylines_src;
polylines_src.reserve(lines.size());
for (Lines::const_iterator it = lines.begin(); it != lines.end(); ++ it) {
@ -61,8 +69,10 @@ void FillLine::_fill_surface_single(
Polylines polylines = intersection_pl(polylines_src, offset(expolygon, scale_(0.02)));
// FIXME Vojtech: This is only performed for horizontal lines, not for the vertical lines!
//FIXME Vojtech这只适用于水平线不适用于垂直线
const float INFILL_OVERLAP_OVER_SPACING = 0.3f;
// How much to extend an infill path from expolygon outside?
//将填充路径从expolygon向外延伸多少
coord_t extra = coord_t(floor(this->_min_spacing * INFILL_OVERLAP_OVER_SPACING + 0.5f));
for (Polylines::iterator it_polyline = polylines.begin(); it_polyline != polylines.end(); ++ it_polyline) {
Point *first_point = &it_polyline->points.front();
@ -76,13 +86,14 @@ void FillLine::_fill_surface_single(
size_t n_polylines_out_old = polylines_out.size();
// connect lines
if (! params.dont_connect() && ! polylines.empty()) { // prevent calling leftmost_point() on empty collections
if (! params.dont_connect() && ! polylines.empty()) { // prevent calling leftmost_point() on empty collections//防止对空集合调用left most_point
// offset the expolygon by max(min_spacing/2, extra)
ExPolygon expolygon_off;
{
ExPolygons expolygons_off = offset_ex(expolygon, this->_min_spacing/2);
if (! expolygons_off.empty()) {
// When expanding a polygon, the number of islands could only shrink. Therefore the offset_ex shall generate exactly one expanded island for one input island.
//展开多边形时岛的数量只能缩小。因此offset_ex应为一个输入岛生成一个扩展岛。
assert(expolygons_off.size() == 1);
std::swap(expolygon_off, expolygons_off.front());
}
@ -98,6 +109,8 @@ void FillLine::_fill_surface_single(
const Vector distance = last_point - first_point;
// TODO: we should also check that both points are on a fill_boundary to avoid
// connecting paths on the boundaries of internal regions
//TODO我们还应该检查这两个点是否都在fill_boundary上以避免
//内部区域边界上的连接路径
if (this->_can_connect(std::abs(distance(0)), std::abs(distance(1))) &&
expolygon_off.contains(Line(last_point, first_point))) {
// Append the polyline.
@ -106,14 +119,17 @@ void FillLine::_fill_surface_single(
}
}
// The lines cannot be connected.
//线路无法连接。
polylines_out.emplace_back(std::move(polyline));
first = false;
}
}
// paths must be rotated back
//路径必须向后旋转
for (Polylines::iterator it = polylines_out.begin() + n_polylines_out_old; it != polylines_out.end(); ++ it) {
// No need to translate, the absolute position is irrelevant.
//无需翻译,绝对位置无关紧要。
// it->translate(- direction.second(0), - direction.second(1));
it->rotate(direction.first);
}

View File

@ -1770,9 +1770,12 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
// Get optimal tool ordering to minimize tool switches of a multi-exruder print.
// For a print by objects, find the 1st printing object.
//获得最佳的刀具订购,以最大限度地减少多喷嘴打印的刀具切换。
//对于按对象打印,请找到第一个打印对象。
ToolOrdering tool_ordering;
unsigned int initial_extruder_id = (unsigned int)-1;
//BBS: first non-support filament extruder
//BBS第一台无支撑长丝挤出机
unsigned int initial_non_support_extruder_id;
unsigned int final_extruder_id = (unsigned int)-1;
bool has_wipe_tower = false;
@ -1780,14 +1783,17 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
std::vector<const PrintInstance*>::const_iterator print_object_instance_sequential_active;
if (print.config().print_sequence == PrintSequence::ByObject) {
// Order object instances for sequential print.
//订购对象实例以进行顺序打印。
print_object_instances_ordering = sort_object_instances_by_model_order(print);
// print_object_instances_ordering = sort_object_instances_by_max_z(print);
// Find the 1st printing object, find its tool ordering and the initial extruder ID.
//找到第一个打印对象找到其工具订购和初始挤出机ID。
print_object_instance_sequential_active = print_object_instances_ordering.begin();
for (; print_object_instance_sequential_active != print_object_instances_ordering.end(); ++ print_object_instance_sequential_active) {
tool_ordering = ToolOrdering(*(*print_object_instance_sequential_active)->print_object, initial_extruder_id);
if ((initial_extruder_id = tool_ordering.first_extruder()) != static_cast<unsigned int>(-1)) {
//BBS: try to find the non-support filament extruder if is multi color and initial_extruder is support filament
//BBS如果是多色的初始挤出机是支撑长丝试着找到非支撑长丝挤出机
initial_non_support_extruder_id = initial_extruder_id;
if (tool_ordering.all_extruders().size() > 1 && print.config().filament_is_support.get_at(initial_extruder_id)) {
bool has_non_support_filament = false;
@ -1798,6 +1804,7 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
}
}
//BBS: find the non-support filament extruder of object
//BBS查找非支撑长丝挤出机的对象
if (has_non_support_filament) {
bool find_initial_non_support_filament = false;
for (LayerTools layer_tools : tool_ordering.layer_tools()) {
@ -1822,22 +1829,29 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
}
if (initial_extruder_id == static_cast<unsigned int>(-1))
// No object to print was found, cancel the G-code export.
//未找到要打印的对象请取消G代码导出。
throw Slic3r::SlicingError(_(L("No object can be printed. Maybe too small")));
// We don't allow switching of extruders per layer by Model::custom_gcode_per_print_z in sequential mode.
// Use the extruder IDs collected from Regions.
//我们不允许在顺序模式下按Model:custom_gcode_per_print_z切换每层挤出机。
//使用从区域收集的挤出机ID。
this->set_extruders(print.extruders());
has_wipe_tower = print.has_wipe_tower() && tool_ordering.has_wipe_tower();
} else {
// Find tool ordering for all the objects at once, and the initial extruder ID.
// If the tool ordering has been pre-calculated by Print class for wipe tower already, reuse it.
//一次查找所有对象的工具顺序和初始挤出机ID。
//如果擦拭塔的Print类已经预先计算了工具订购量请重新使用。
tool_ordering = print.tool_ordering();
tool_ordering.assign_custom_gcodes(print);
if (tool_ordering.all_extruders().empty())
// No object to print was found, cancel the G-code export.
//未找到要打印的对象请取消G代码导出。
throw Slic3r::SlicingError(_(L("No object can be printed. Maybe too small")));
has_wipe_tower = print.has_wipe_tower() && tool_ordering.has_wipe_tower();
// BBS: priming logic is removed, so 1st layer tool_ordering also respect the object tool sequence
//BBS删除了启动逻辑因此第一层工具排序也尊重对象工具序列
#if 0
initial_extruder_id = (has_wipe_tower && !print.config().single_extruder_multi_material_priming) ?
// The priming towers will be skipped.
@ -1848,6 +1862,7 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
initial_extruder_id = tool_ordering.first_extruder();
#endif
//BBS: try to find the non-support filament extruder if is multi color and initial_extruder is support filament
//BBS如果是多色的初始挤出机是支撑长丝试着找到非支撑长丝挤出机
if (initial_extruder_id != static_cast<unsigned int>(-1)) {
initial_non_support_extruder_id = initial_extruder_id;
if (tool_ordering.all_extruders().size() > 1 && print.config().filament_is_support.get_at(initial_extruder_id)) {
@ -1859,6 +1874,7 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
}
}
//BBS: find the non-support filament extruder of object
//BBS查找非支撑长丝挤出机的对象
if (has_non_support_filament){
bool find_initial_non_support_filament = false;
for (LayerTools layer_tools : tool_ordering.layer_tools()) {
@ -1881,8 +1897,11 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
// In non-sequential print, the printing extruders may have been modified by the extruder switches stored in Model::custom_gcode_per_print_z.
// Therefore initialize the printing extruders from there.
//在非顺序打印中打印挤出机可能已被存储在Model:custom_gcode_per_print_z中的挤出机开关修改。
//因此,从那里初始化打印挤出机。
this->set_extruders(tool_ordering.all_extruders());
// Order object instances using a nearest neighbor search.
//使用最近邻搜索对对象实例进行排序。
print_object_instances_ordering = chain_print_object_instances(print);
}
if (initial_extruder_id == (unsigned int)-1) {
@ -1896,6 +1915,7 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
m_cooling_buffer->set_current_extruder(initial_extruder_id);
// Emit machine envelope limits for the Marlin firmware.
//发射Marlin固件的机器包络限制。
this->print_machine_envelope(file, print);
// Disable fan.
@ -1906,6 +1926,7 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
}
// Let the start-up script prime the 1st printing tool.
//让启动脚本启动第一个打印工具。
m_placeholder_parser.set("initial_tool", initial_extruder_id);
m_placeholder_parser.set("initial_extruder", initial_extruder_id);
//BBS
@ -1913,16 +1934,20 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
m_placeholder_parser.set("initial_no_support_extruder", initial_non_support_extruder_id);
m_placeholder_parser.set("current_extruder", initial_extruder_id);
//set the key for compatibilty
//设置兼容性密钥
m_placeholder_parser.set("retraction_distance_when_cut", m_config.retraction_distances_when_cut.get_at(initial_extruder_id));
m_placeholder_parser.set("long_retraction_when_cut", m_config.long_retractions_when_cut.get_at(initial_extruder_id));
m_placeholder_parser.set("retraction_distances_when_cut", new ConfigOptionFloats(m_config.retraction_distances_when_cut));
m_placeholder_parser.set("long_retractions_when_cut",new ConfigOptionBools(m_config.long_retractions_when_cut));
//Set variable for total layer count so it can be used in custom gcode.
//设置总层数变量以便在自定义gcode中使用。
m_placeholder_parser.set("total_layer_count", m_layer_count);
// Useful for sequential prints.
//适用于连续打印。
m_placeholder_parser.set("current_object_idx", 0);
// For the start / end G-code to do the priming and final filament pull in case there is no wipe tower provided.
//在没有提供擦拭塔的情况下,开始/结束G代码可以进行底漆和最终灯丝拉拔。
m_placeholder_parser.set("has_wipe_tower", has_wipe_tower);
//m_placeholder_parser.set("has_single_extruder_multi_material_priming", has_wipe_tower && print.config().single_extruder_multi_material_priming);
m_placeholder_parser.set("total_toolchanges", std::max(0, print.wipe_tower_data().number_of_toolchanges)); // Check for negative toolchanges (single extruder mode) and set to 0 (no tool change).
@ -1939,6 +1964,11 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
// It does NOT encompass user extrusions generated by custom G-code,
// therefore it does NOT encompass the initial purge line.
// It does NOT encompass MMU/MMU2 starting (wipe) areas.
//第一层挤压件的凸面外壳,用于床层平整和放置初始吹扫管线。
//它包括物体拉伸、支撑拉伸、裙子、帽沿、擦拭塔。
//它不包括由自定义G代码生成的用户拉伸
//因此,它不包括初始净化管线。
//它不包括MMU/MMU2启动擦除区域。
auto pts = std::make_unique<ConfigOptionPoints>();
pts->values.reserve(print.first_layer_convex_hull().size());
for (const Point &pt : print.first_layer_convex_hull().points)
@ -1957,6 +1987,8 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
{ // BBS:deal with head wrap detect
// use first layer convex_hull union with each object's bbox to check whether in head detect zone
//BBS处理头部包裹检测
//使用第一层凸包联合每个对象的bbox来检查是否在头部检测区域
Polygons object_projections;
for (auto& obj : print.objects()) {
for (auto& instance : obj->instances()) {
@ -1983,7 +2015,8 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
}
// get center without wipe tower
BoundingBoxf bbox_wo_wt;// bounding box without wipe tower
//无需擦拭塔即可获得中心
BoundingBoxf bbox_wo_wt;// bounding box without wipe tower//无擦拭塔的边界框
for (auto& objPtr : print.objects()) {
BBoxData data;
bbox_wo_wt.merge(unscaled(objPtr->get_first_layer_bbox(data.area, data.layer_height, data.name)));
@ -2024,6 +2057,7 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
during_print_exhaust_fan_speed_num.emplace_back((int)(item / 100.0 * 255));
m_placeholder_parser.set("during_print_exhaust_fan_speed_num",new ConfigOptionInts(during_print_exhaust_fan_speed_num));
//BBS: calculate the volumetric speed of outer wall. Ignore pre-object setting and multi-filament, and just use the default setting
//BBS计算外壁的体积速度。忽略预对象设置和多灯丝只使用默认设置
{
float filament_max_volumetric_speed = m_config.option<ConfigOptionFloats>("filament_max_volumetric_speed")->get_at(initial_non_support_extruder_id);
float outer_wall_line_width = print.default_region_config().outer_wall_line_width.value;
@ -2046,22 +2080,28 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
std::string machine_start_gcode = this->placeholder_parser_process("machine_start_gcode", print.config().machine_start_gcode.value, initial_extruder_id);
if (print.config().gcode_flavor != gcfKlipper) {
// Set bed temperature if the start G-code does not contain any bed temp control G-codes.
//如果启动G代码不包含任何床温控制G代码则设置床温。
this->_print_first_layer_bed_temperature(file, print, machine_start_gcode, initial_extruder_id, true);
// Set extruder(s) temperature before and after start G-code.
//在启动G-代码之前和之后设置挤出机温度。
this->_print_first_layer_extruder_temperatures(file, print, machine_start_gcode, initial_extruder_id, false);
}
// BBS: chamber temp control for 3rd printers
//BBS:第三台打印机的腔室温度控制
if (!is_BBL_Printer() && print.config().support_chamber_temp_control.value && max_chamber_temp > 0 ){
file.write(m_writer.set_chamber_temperature(max_chamber_temp,true));
}
// adds tag for processor
//为处理器添加标签
file.write_format(";%s%s\n", GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Role).c_str(), ExtrusionEntity::role_to_string(erCustom).c_str());
// Write the custom start G-code
//编写自定义启动G代码
file.writeln(machine_start_gcode);
//BBS: gcode writer doesn't know where the real position of extruder is after inserting custom gcode
//BBS:插入自定义gcode后gcode编写者不知道挤出机的实际位置在哪里
m_writer.set_current_position_clear(false);
m_start_gcode_filament = GCodeProcessor::get_gcode_last_filament(machine_start_gcode);
@ -2084,17 +2124,21 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
print.throw_if_canceled();
// Set other general things.
//设置其他一般事项。
file.write(this->preamble());
// Calculate wiping points if needed
//如果需要,计算擦拭点
DoExport::init_ooze_prevention(print, m_ooze_prevention);
print.throw_if_canceled();
// Collect custom seam data from all objects.
//从所有对象收集自定义接缝数据。
std::function<void(void)> throw_if_canceled_func = [&print]() { print.throw_if_canceled(); };
m_seam_placer.init(print, throw_if_canceled_func);
// BBS: get path for change filament
//BBS获取更换灯丝的路径
if (m_writer.multiple_extruders) {
std::vector<Vec2d> points = get_path_of_change_filament(print);
if (points.size() == 3) {
@ -2105,6 +2149,7 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
}
// BBS: priming logic is removed, always set first extruer here.
//BBS启动逻辑已删除始终在此处设置第一台挤出机。
//if (! (has_wipe_tower && print.config().single_extruder_multi_material_priming))
{
// Set initial extruder only after custom start G-code.
@ -2112,6 +2157,7 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
file.write(this->set_extruder(initial_extruder_id, 0.));
}
// BBS: set that indicates objs with brim
//BBS:用边缘表示对象的集合
for (auto iter = print.m_brimMap.begin(); iter != print.m_brimMap.end(); ++iter) {
if (!iter->second.empty())
this->m_objsWithBrim.insert(iter->first);
@ -2148,10 +2194,12 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
}
else {
// BBS: open spaghetti detector
//BBS开放式意大利面条检测器
// if (print.config().spaghetti_detector.value)
if (print.is_BBL_Printer()) file.write("M981 S1 P20000 ;open spaghetti detector\n");
// Do all objects for each layer.
//为每个图层执行所有对象。
if (print.config().print_sequence == PrintSequence::ByObject && !has_wipe_tower) {
size_t finished_objects = 0;
const PrintObject *prev_object = (*print_object_instance_sequential_active)->print_object;
@ -2171,13 +2219,17 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
this->set_origin(unscale((*print_object_instance_sequential_active)->shift));
// BBS: prime extruder if extruder change happens before this object instance
//BBS:如果挤出机在此对象实例之前发生更改,则启动挤出机
bool prime_extruder = false;
if (finished_objects > 0) {
// Move to the origin position for the copy we're going to print.
// This happens before Z goes down to layer 0 again, so that no collision happens hopefully.
m_enable_cooling_markers = false; // we're not filtering these moves through CoolingBuffer
//移动到我们要打印的副本的原点位置。
//这发生在Z再次下降到层0之前所以希望不会发生碰撞。
m_enable_cooling_markers = false; // we're not filtering these moves through CoolingBuffer//我们不会通过CoolingBuffer过滤这些动作
m_avoid_crossing_perimeters.use_external_mp_once();
// BBS. change tool before moving to origin point.
//BBS。在移动到原点之前更换工具。
if (m_writer.need_toolchange(initial_extruder_id)) {
const PrintObjectConfig &object_config = object.config();
coordf_t initial_layer_print_height = print.config().initial_layer_print_height.value;
@ -2190,19 +2242,23 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
file.write(this->travel_to(Point(0, 0), erNone, "move to origin position for next object"));
m_enable_cooling_markers = true;
// Disable motion planner when traveling to first object point.
//在移动到第一个对象点时禁用运动规划器。
m_avoid_crossing_perimeters.disable_once();
// Ff we are printing the bottom layer of an object, and we have already finished
// another one, set first layer temperatures. This happens before the Z move
// is triggered, so machine has more time to reach such temperatures.
//如果我们正在打印一个对象的底层并且已经完成了另一个请设置第一层温度。这发生在Z移动被触发之前因此机器有更多的时间达到这样的温度。
m_placeholder_parser.set("current_object_idx", int(finished_objects));
std::string printing_by_object_gcode = this->placeholder_parser_process("printing_by_object_gcode", print.config().printing_by_object_gcode.value,
initial_extruder_id);
// Set first layer bed and extruder temperatures, don't wait for it to reach the temperature.
//设置第一层床和挤出机的温度,不要等到它达到温度。
this->_print_first_layer_bed_temperature(file, print, printing_by_object_gcode, initial_extruder_id, false);
this->_print_first_layer_extruder_temperatures(file, print, printing_by_object_gcode, initial_extruder_id, false);
file.writeln(printing_by_object_gcode);
}
// Reset the cooling buffer internal state (the current position, feed rate, accelerations).
//重置冷却缓冲器内部状态(当前位置、进给速度、加速度)。
m_cooling_buffer->reset(this->writer().get_position());
m_cooling_buffer->set_current_extruder(initial_extruder_id);
// Process all layers of a single object instance (sequential mode) with a parallel pipeline:

View File

@ -435,7 +435,7 @@ std::string GCodeWriter::travel_to_xyz(const Vec3d &point, const std::string &co
}
else if (m_to_lift_type == LiftType::NormalLift) {
slop_move = _travel_to_z(target.z(), "normal lift Z");
slop_move = _travel_to_z_test(target.z(), "normal lift Z");
//slop_move = _travel_to_z_test(target.z(), "normal lift Z");
}
}
@ -444,11 +444,11 @@ std::string GCodeWriter::travel_to_xyz(const Vec3d &point, const std::string &co
GCodeG1Formatter w0;
if (this->is_current_position_clear()) {
w0.emit_xyz(target);
//auto dE = m_extruder->E();
/* //auto dE = m_extruder->E();
auto dE = 1;
if (dE > 0) {
w0.emit_e(dE);
}
}*/
w0.emit_f(this->config.travel_speed.value * 60.0);
w0.emit_comment(GCodeWriter::full_gcode_comment, comment);
xy_z_move = w0.string();
@ -474,8 +474,8 @@ std::string GCodeWriter::travel_to_xyz(const Vec3d &point, const std::string &co
m_lifted = 0.;
//BBS
this->set_current_position_clear(true);
//return this->travel_to_xy(to_2d(point));
return this->travel_to_xy_test(to_2d(point));
return this->travel_to_xy(to_2d(point));
//return this->travel_to_xy_test(to_2d(point));
}
else {
/* In all the other cases, we perform an actual XYZ move and cancel

View File

@ -805,7 +805,7 @@ static std::vector<std::string> s_Preset_print_options {
"minimum_sparse_infill_area", "reduce_infill_retraction", "ironing_pattern", "ironing_type",
"ironing_flow", "ironing_speed", "ironing_spacing","ironing_direction",
"max_travel_detour_distance",
"fuzzy_skin", "fuzzy_skin_thickness", "fuzzy_skin_point_distance","fibre_feed_rate",
"fuzzy_skin", "fuzzy_skin_thickness", "fuzzy_skin_point_distance",//"fibre_feed_rate",
#ifdef HAS_PRESSURE_EQUALIZER
"max_volumetric_extrusion_rate_slope_positive", "max_volumetric_extrusion_rate_slope_negative",
#endif /* HAS_PRESSURE_EQUALIZER */
@ -996,16 +996,16 @@ static std::vector<std::string> s_Preset_sla_printer_options {
"min_initial_exposure_time", "max_initial_exposure_time",
"inherits"
};
static std::vector<std::string> s_Preset_config_options{
"initial_layer_print_height","initial_layer_line_width","outer_wall_line_width","inner_wall_line_width","top_surface_line_width","sparse_infill_line_width","support_line_width","seam_gap","seam_slope_conditional","scarf_angle_threshold","seam_slope_start_height",
"seam_slope_entire_loop","seam_slope_min_length","seam_slope_steps","seam_slope_inner_walls","wipe_speed","resolution","enable_arc_fitting","ironing_pattern","ironing_speed","ironing_flow","ironing_spacing","ironing_direction","wall_generator","wall_transition_angle",
"wall_transition_filter_deviation","wall_transition_length","wall_distribution_count","min_bead_width","min_feature_size","wall_sequence","top_one_wall_type","top_area_threshold","only_one_wall_first_layer","detect_overhang_wall","max_travel_detour_distance","support_base_pattern_spacing",
"support_interface_top_layers","support_interface_bottom_layers","support_bottom_interface_spacing","top_surface_pattern","bottom_surface_pattern","internal_solid_infill_pattern","sparse_infill_pattern","filter_out_gap_fill","bridge_angle","minimum_sparse_infill_area","infill_combination",
"default_print_speed","initial_layer_speed","initial_layer_infill_speed","outer_wall_speed","inner_wall_speed","sparse_infill_speed","internal_solid_infill_speed","top_surface_speed","bridge_speed","gap_infill_speed","support_speed","support_interface_speed","travel_speed",
"default_acceleration","accel_to_decel_enable","accel_to_decel_factor","support_type","support_style","support_threshold_angle","support_on_build_plate_only","support_critical_regions_only","support_remove_small_overhang","raft_layers","raft_contact_distance","raft_first_layer_density",
"support_filament","support_interface_filament","support_interface_not_for_body","raft_first_layer_expansion","tree_support_wall_count","support_base_pattern","support_interface_pattern","support_object_xy_distance","bridge_no_support","max_bridge_length","independent_support_layer_height",
"tree_support_branch_distance","tree_support_branch_diameter","tree_support_branch_angle","slicing_mode","fibre_feed_rate","print_sequence","spiral_mode","spiral_mode_smooth","spiral_mode_max_xy_smoothing","timelapse_type","fuzzy_skin","fuzzy_skin_point_distance","fuzzy_skin_thickness"
};
//static std::vector<std::string> s_Preset_config_options{
// "initial_layer_print_height","initial_layer_line_width","outer_wall_line_width","inner_wall_line_width","top_surface_line_width","sparse_infill_line_width","support_line_width","seam_gap","seam_slope_conditional","scarf_angle_threshold","seam_slope_start_height",
// "seam_slope_entire_loop","seam_slope_min_length","seam_slope_steps","seam_slope_inner_walls","wipe_speed","resolution","enable_arc_fitting","ironing_pattern","ironing_speed","ironing_flow","ironing_spacing","ironing_direction","wall_generator","wall_transition_angle",
// "wall_transition_filter_deviation","wall_transition_length","wall_distribution_count","min_bead_width","min_feature_size","wall_sequence","top_one_wall_type","top_area_threshold","only_one_wall_first_layer","detect_overhang_wall","max_travel_detour_distance","support_base_pattern_spacing",
// "support_interface_top_layers","support_interface_bottom_layers","support_bottom_interface_spacing","top_surface_pattern","bottom_surface_pattern","internal_solid_infill_pattern","sparse_infill_pattern","filter_out_gap_fill","bridge_angle","minimum_sparse_infill_area","infill_combination",
// "default_print_speed","initial_layer_speed","initial_layer_infill_speed","outer_wall_speed","inner_wall_speed","sparse_infill_speed","internal_solid_infill_speed","top_surface_speed","bridge_speed","gap_infill_speed","support_speed","support_interface_speed","travel_speed",
// "default_acceleration","accel_to_decel_enable","accel_to_decel_factor","support_type","support_style","support_threshold_angle","support_on_build_plate_only","support_critical_regions_only","support_remove_small_overhang","raft_layers","raft_contact_distance","raft_first_layer_density",
// "support_filament","support_interface_filament","support_interface_not_for_body","raft_first_layer_expansion","tree_support_wall_count","support_base_pattern","support_interface_pattern","support_object_xy_distance","bridge_no_support","max_bridge_length","independent_support_layer_height",
// "tree_support_branch_distance","tree_support_branch_diameter","tree_support_branch_angle","slicing_mode","fibre_feed_rate","print_sequence","spiral_mode","spiral_mode_smooth","spiral_mode_max_xy_smoothing","timelapse_type","fuzzy_skin","fuzzy_skin_point_distance","fuzzy_skin_thickness"
//};
const std::vector<std::string>& Preset::print_options() { return s_Preset_print_options; }
const std::vector<std::string>& Preset::filament_options() { return s_Preset_filament_options; }
@ -1016,7 +1016,7 @@ const std::vector<std::string>& Preset::nozzle_options() { return print_
const std::vector<std::string>& Preset::sla_print_options() { return s_Preset_sla_print_options; }
const std::vector<std::string>& Preset::sla_material_options() { return s_Preset_sla_material_options; }
const std::vector<std::string>& Preset::sla_printer_options() { return s_Preset_sla_printer_options; }
const std::vector<std::string>& Preset::config_options() { return s_Preset_config_options; }
const std::vector<std::string>& Preset::config_options() { return s_Preset_print_options; }
const std::vector<std::string>& Preset::printer_options()
{

View File

@ -2036,6 +2036,7 @@ DynamicPrintConfig PresetBundle::full_fff_config() const
// Add the default filament preset to have the "filament_preset_id" defined.
out.apply(this->filaments.default_preset().config);
out.apply(this->printers.get_edited_preset().config);
out.apply(this->configs.get_edited_preset().config);
out.apply(this->project_config);
// BBS

View File

@ -1553,6 +1553,7 @@ std::map<ObjectID, unsigned int> getObjectExtruderMap(const Print& print) {
}
// Slicing process, running at a background thread.
//切片过程,在后台线程上运行。
void Print::process(std::unordered_map<std::string, long long>* slice_time, bool use_cache)
{
long long start_time = 0, end_time = 0;
@ -1567,6 +1568,7 @@ void Print::process(std::unordered_map<std::string, long long>* slice_time, bool
name_tbb_thread_pool_threads_set_locale();
//compute the PrintObject with the same geometries
//使用相同的几何图形计算PrintObject
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": this=%1%, enter, use_cache=%2%, object size=%3%")%this%use_cache%m_objects.size();
if (m_objects.empty())
return;
@ -1575,6 +1577,7 @@ void Print::process(std::unordered_map<std::string, long long>* slice_time, bool
obj->clear_shared_object();
//add the print_object share check logic
//添加打印对象共享检查逻辑
auto is_print_object_the_same = [this](const PrintObject* object1, const PrintObject* object2) -> bool{
if (object1->trafo().matrix() != object2->trafo().matrix())
return false;
@ -1658,6 +1661,8 @@ void Print::process(std::unordered_map<std::string, long long>* slice_time, bool
BOOST_LOG_TRIVIAL(warning) << boost::format("Also can not find the shared object, identify_id %1%, maybe shared object is skipped")%obj->model_object()->instances[0]->loaded_id;
//throw Slic3r::SlicingError("Can not find the cached data.");
//don't report errot, set use_cache to false, and reslice these objects
//throw Slic3rSlicingError“找不到缓存的数据。”
//不报告错误将use_cache设置为false并重新切片这些对象
need_slicing_objects.insert(obj);
re_slicing_objects.insert(obj);
//use_cache = false;
@ -1799,6 +1804,7 @@ void Print::process(std::unordered_map<std::string, long long>* slice_time, bool
this->_make_wipe_tower();
} else if (this->config().print_sequence != PrintSequence::ByObject) {
// Initialize the tool ordering, so it could be used by the G-code preview slider for planning tool changes and filament switches.
//初始化刀具订购以便G代码预览滑块可以使用它来计划刀具更换和灯丝切换。
m_tool_ordering = ToolOrdering(*this, -1, false);
if (m_tool_ordering.empty() || m_tool_ordering.last_extruder() == unsigned(-1))
throw Slic3r::SlicingError("The print is empty. The model is not printable with current print settings.");
@ -1820,10 +1826,12 @@ void Print::process(std::unordered_map<std::string, long long>* slice_time, bool
if (this->has_skirt() && draft_shield) {
// In case that draft shield is active, generate skirt first so brim
// can be trimmed to make room for it.
//如果防风罩处于活动状态,请先制作裙子,这样帽沿就可以修剪,为它腾出空间。
_make_skirt();
}
//BBS: get the objects' indices when GCodes are generated
//BBS生成GCode时获取对象的索引
ToolOrdering tool_ordering;
unsigned int initial_extruder_id = (unsigned int)-1;
unsigned int final_extruder_id = (unsigned int)-1;
@ -1834,6 +1842,7 @@ void Print::process(std::unordered_map<std::string, long long>* slice_time, bool
std::vector<unsigned int> printExtruders;
if (this->config().print_sequence == PrintSequence::ByObject) {
// Order object instances for sequential print.
//订购对象实例以进行顺序打印。
print_object_instances_ordering = sort_object_instances_by_model_order(*this);
// print_object_instances_ordering = sort_object_instances_by_max_z(print);
print_object_instance_sequential_active = print_object_instances_ordering.begin();
@ -1873,9 +1882,10 @@ void Print::process(std::unordered_map<std::string, long long>* slice_time, bool
objPrintVec.push_back(std::make_pair(print_object_ID, objectExtruderMap.at(print_object_ID)));
}
// BBS: m_brimMap and m_supportBrimMap are used instead of m_brim to generate brim of objs and supports seperately
//BBS:使用m_brimMap和m_supportBrimMap代替m_period来生成对象边缘并分别支持
m_brimMap.clear();
m_supportBrimMap.clear();
m_first_layer_convex_hull.points.clear(); // BBS: plate offset is contained in this convexhull
m_first_layer_convex_hull.points.clear(); // BBS: plate offset is contained in this convexhull//BBS:板材偏移量包含在这个凸块中
if (this->has_brim()) {
Polygons islands_area;
make_brim(*this, this->make_try_cancel(), islands_area, m_brimMap,
@ -1890,6 +1900,8 @@ void Print::process(std::unordered_map<std::string, long long>* slice_time, bool
if (has_skirt() && ! draft_shield) {
// In case that draft shield is NOT active, generate skirt now.
// It will be placed around the brim, so brim has to be ready.
//如果导流罩未激活,请立即生成裙板。
//它将被放置在帽沿周围,所以帽沿必须准备好。
assert(m_skirt.empty());
_make_skirt();
}
@ -1927,6 +1939,7 @@ void Print::process(std::unordered_map<std::string, long long>* slice_time, bool
}
}
// TODO adaptive layer height won't work with conflict checker because m_fake_wipe_tower's path is generated using fixed layer height
//TODO自适应层高度不适用于冲突检查器因为m_fake_wipe_tower的路径是使用固定层高度生成的
if(!m_no_check && !has_adaptive_layer_height)
{
using Clock = std::chrono::high_resolution_clock;
@ -1954,14 +1967,20 @@ void Print::process(std::unordered_map<std::string, long long>* slice_time, bool
// The export_gcode may die for various reasons (fails to process filename_format,
// write error into the G-code, cannot execute post-processing scripts).
// It is up to the caller to show an error message.
//G代码导出进程在后台线程中运行。
//export_gode可能会因各种原因而死亡无法处理filename_format、在G-代码中写入错误、无法执行后处理脚本)。
//由呼叫者显示错误消息。
std::string Print::export_gcode(const std::string& path_template, GCodeProcessorResult* result, ThumbnailsGeneratorCallback thumbnail_cb)
{
// output everything to a G-code file
// The following call may die if the filename_format template substitution fails.
//将所有内容输出到G代码文件
//如果filename_format模板替换失败则以下调用可能会终止。
std::string path = this->output_filepath(path_template);
std::string message;
if (!path.empty() && result == nullptr) {
// Only show the path if preview_data is not set -> running from command line.
//仅在未设置preview_data时显示路径->从命令行运行。
message = L("Exporting G-code");
message += " to ";
message += path;
@ -1970,8 +1989,10 @@ std::string Print::export_gcode(const std::string& path_template, GCodeProcessor
this->set_status(80, message);
// The following line may die for multiple reasons.
//以下行可能因多种原因而终止。
GCode gcode;
//BBS: compute plate offset for gcode-generator
//BBS:计算gcode生成器的板偏移
const Vec3d origin = this->get_plate_origin();
gcode.set_gcode_offset(origin(0), origin(1));
gcode.do_export(this, path.c_str(), result, thumbnail_cb);

View File

@ -1167,7 +1167,7 @@ void PrintConfigDef::init_fff_params()
def->enum_values.push_back("archimedeanchords");
def->enum_values.push_back("octagramspiral");
//xiamian+
//def->enum_values.push_back("fiberspiral");
def->enum_values.push_back("fiberspiral");
def->enum_labels.push_back(L("Concentric"));
def->enum_labels.push_back(L("Rectilinear"));
@ -1179,7 +1179,7 @@ void PrintConfigDef::init_fff_params()
def->enum_labels.push_back(L("Archimedean Chords"));
def->enum_labels.push_back(L("Octagram Spiral"));
//xiamian+
//def->enum_labels.push_back(L("Fiber Spiral"));
def->enum_labels.push_back(L("Fiber Spiral"));
def->set_default_value(new ConfigOptionEnum<InfillPattern>(ipRectilinear));
def = this->add("bottom_surface_pattern", coEnum);
@ -1625,7 +1625,7 @@ void PrintConfigDef::init_fff_params()
def->enum_values.push_back("lightning");
def->enum_values.push_back("crosshatch");
//xiamian+
//def->enum_values.push_back("fiberspiral");
def->enum_values.push_back("fiberspiral");
def->enum_labels.push_back(L("Concentric"));
def->enum_labels.push_back(L("Rectilinear"));
def->enum_labels.push_back(L("Grid"));
@ -1646,7 +1646,7 @@ void PrintConfigDef::init_fff_params()
def->enum_labels.push_back(L("Lightning"));
def->enum_labels.push_back(L("Cross Hatch"));
//xiamian+
//def->enum_labels.push_back(L("Fiber Spiral"));
def->enum_labels.push_back(L("Fiber Spiral"));
def->set_default_value(new ConfigOptionEnum<InfillPattern>(ipGrid));
def = this->add("top_surface_acceleration", coFloat);
@ -1867,7 +1867,7 @@ void PrintConfigDef::init_fff_params()
def->mode = comSimple;
def->set_default_value(new ConfigOptionFloat(0.3));
def = this->add("fibre_feed_rate", coFloats);
/*def = this->add("fibre_feed_rate", coFloats);
def->label = L("Fibre feed rate");
def->category = L("Others");
//def->tooltip = L("The width within which to jitter. It's adversed to be below outer wall line width");
@ -1876,6 +1876,7 @@ void PrintConfigDef::init_fff_params()
def->max = 2;
def->mode = comSimple;
def->set_default_value(new ConfigOptionFloats{ 1. });
*/
def = this->add("fuzzy_skin_point_distance", coFloat);
def->label = L("Fuzzy skin point distance");

View File

@ -895,7 +895,7 @@ PRINT_CONFIG_CLASS_DEFINE(
((ConfigOptionString, machine_end_gcode))
((ConfigOptionStrings, filament_end_gcode))
((ConfigOptionFloats, filament_flow_ratio))
((ConfigOptionFloats, fibre_feed_rate))
//((ConfigOptionFloats, fibre_feed_rate))
((ConfigOptionBools, enable_pressure_advance))
((ConfigOptionFloats, pressure_advance))
((ConfigOptionFloats, filament_diameter))

View File

@ -132,9 +132,13 @@ std::vector<std::reference_wrapper<const PrintRegion>> PrintObject::all_regions(
// 1) Merges typed region slices into stInternal type.
// 2) Increases an "extra perimeters" counter at region slices where needed.
// 3) Generates perimeters, gap fills and fill regions (fill regions of type stInternal).
//1将类型化的区域切片合并为stInternal类型。
//2在需要的区域切片处增加“额外周长”计数器。
//3生成周界、间隙填充和填充区域stInternal类型的填充区域
void PrintObject::make_perimeters()
{
// prerequisites
//先决条件
this->slice();
if (! this->set_started(posPerimeters))
@ -144,6 +148,7 @@ void PrintObject::make_perimeters()
BOOST_LOG_TRIVIAL(info) << "Generating walls..." << log_memory_info();
// Revert the typed slices into untyped slices.
//将类型化切片还原为非类型化切片。
if (m_typed_slices) {
for (Layer *layer : m_layers) {
layer->restore_untyped_slices();
@ -159,6 +164,8 @@ void PrintObject::make_perimeters()
// but we don't generate any extra perimeter if fill density is zero, as they would be floating
// inside the object - infill_only_where_needed should be the method of choice for printing
// hollow objects
//将每一层与下面的一层进行比较,并标记需要额外内周的切片,如圆顶对象的顶部-
//该算法确保至少有一个周长是重叠的,但如果填充密度为零,我们不会生成任何额外的周长,因为它们将漂浮在对象内部-仅填充,其中需要填充应该是打印空心对象的首选方法
for (size_t region_id = 0; region_id < this->num_printing_regions(); ++ region_id) {
const PrintRegion &region = this->printing_region(region_id);
//BBS: remove extra_perimeters, always false
@ -175,6 +182,7 @@ void PrintObject::make_perimeters()
const LayerRegion &upper_layerm = *m_layers[layer_idx+1]->get_region(region_id);
const Polygons upper_layerm_polygons = to_polygons(upper_layerm.slices.surfaces);
// Filter upper layer polygons in intersection_ppl by their bounding boxes?
//通过边界框过滤intersection_ppl中的上层多边形
// my $upper_layerm_poly_bboxes= [ map $_->bounding_box, @{$upper_layerm_polygons} ];
const double total_loop_length = total_length(upper_layerm_polygons);
const coord_t perimeter_spacing = layerm.flow(frPerimeter).scaled_spacing();
@ -185,9 +193,11 @@ void PrintObject::make_perimeters()
for (Surface &slice : layerm.slices.surfaces) {
for (;;) {
// compute the total thickness of perimeters
//计算周界的总厚度
const coord_t perimeters_thickness = ext_perimeter_width/2 + ext_perimeter_spacing/2
+ (region.config().wall_loops-1 + slice.extra_perimeters) * perimeter_spacing;
// define a critical area where we don't want the upper slice to fall into
//定义一个关键区域,我们不希望上部切片落入其中
// (it should either lay over our perimeters or outside this area)
const coord_t critical_area_depth = coord_t(perimeter_spacing * 1.5);
const Polygons critical_area = diff(
@ -195,8 +205,10 @@ void PrintObject::make_perimeters()
offset(slice.expolygon, float(- perimeters_thickness - critical_area_depth))
);
// check whether a portion of the upper slices falls inside the critical area
//检查上部切片的一部分是否落在临界区域内
const Polylines intersection = intersection_pl(to_polylines(upper_layerm_polygons), critical_area);
// only add an additional loop if at least 30% of the slice loop would benefit from it
//仅当切片循环的至少30%将从中受益时,才添加额外的循环
if (total_length(intersection) <= total_loop_length*0.3)
break;
/*
@ -262,10 +274,13 @@ void PrintObject::prepare_infill()
// Then the classifcation of $layerm->slices is transfered onto
// the $layerm->fill_surfaces by clipping $layerm->fill_surfaces
// by the cummulative area of the previous $layerm->fill_surfaces.
//这将为$layer->切片分配一个类型(顶部/底部/内部)。
//然后,通过用前一个$layer->fill_surfaces的累积面积裁剪$layer-->fill_surface将$layer->切片的分类转移到$layer-->fill_surposes上。
this->detect_surfaces_type();
m_print->throw_if_canceled();
// Also tiny stInternal surfaces are turned to stInternalSolid.
//此外微小的stInternal表面也会变成stInternalSolid。
BOOST_LOG_TRIVIAL(info) << "Preparing fill surfaces..." << log_memory_info();
for (auto *layer : m_layers)
for (auto *region : layer->m_regions) {
@ -274,6 +289,7 @@ void PrintObject::prepare_infill()
}
// Add solid fills to ensure the shell vertical thickness.
//添加实心填充物以确保壳体的垂直厚度。
this->discover_vertical_shells();
m_print->throw_if_canceled();
@ -286,6 +302,13 @@ void PrintObject::prepare_infill()
// 3) Clip the internal surfaces by the grown top/bottom surfaces.
// 4) Merge surfaces with the same style. This will mostly get rid of the overlaps.
//FIXME This does not likely merge surfaces, which are supported by a material with different colors, but same properties.
//这将检测桥接和反向桥接,并重新排列顶部/底部/内部表面
//它产生了扩大的重叠桥接区域。
//1stBottomBridge/stBottom填充物增长了3mm并被总填充面积所限。检测到桥梁。这些区域可能会重叠。
//2stTop生长3mm并被生长的底部区域夹住。这些区域可能会重叠。
//3用生长的顶面/底面夹住内表面。
//4合并具有相同样式的曲面。这将主要消除重叠。
//FIXME这不太可能合并由具有不同颜色但属性相同的材质支持的曲面。
this->process_external_surfaces();
m_print->throw_if_canceled();
@ -307,6 +330,10 @@ void PrintObject::prepare_infill()
// and to add a configurable number of solid layers above the BOTTOM / BOTTOMBRIDGE surfaces
// to close these surfaces reliably.
//FIXME Vojtech: Is this a good place to add supporting infills below sloping perimeters?
//检测哪些填充表面靠近外层。
//它们将分为内部和内部固体表面。
//目的是添加可配置数量的实体层来支撑顶部表面,并在底部/底部桥表面上方添加可配置的实体层数量,以可靠地闭合这些表面。
//FIXME Vojtech这是在倾斜周界下方添加支撑填充物的好地方吗
this->discover_horizontal_shells();
m_print->throw_if_canceled();
@ -327,6 +354,11 @@ void PrintObject::prepare_infill()
//FIXME The surfaces are supported by a sparse infill, but the sparse infill is only as large as the area to support.
// Likely the sparse infill will not be anchored correctly, so it will not work as intended.
// Also one wishes the perimeters to be supported by a full infill.
//仅当config->fill_Only_where_needed时才激活。此步骤修剪稀疏填充使其充当内部支撑。它保持所有其他填充类型的完整性。
//这里的内表面和周界必须由稀疏填充物支撑。
//FIXME曲面由稀疏填充物支持但稀疏填充物的大小仅与要支持的区域一样大。
//稀疏填充可能无法正确锚定,因此无法按预期工作。
//此外,人们还希望周边由完整的填充物支撑。
this->clip_fill_surfaces();
m_print->throw_if_canceled();
@ -342,10 +374,12 @@ void PrintObject::prepare_infill()
// the following step needs to be done before combination because it may need
// to remove only half of the combined infill
//在组合之前需要完成以下步骤,因为它可能只需要删除组合填充的一半
this->bridge_over_infill();
m_print->throw_if_canceled();
// combine fill surfaces to honor the "infill every N layers" option
//组合填充曲面以实现“每N层填充”选项
this->combine_infill();
m_print->throw_if_canceled();

View File

@ -116,6 +116,10 @@ static inline bool model_volume_needs_slicing(const ModelVolume &mv)
// Apply closing radius.
// Apply positive XY compensation to ModelVolumeType::MODEL_PART and ModelVolumeType::PARAMETER_MODIFIER, not to ModelVolumeType::NEGATIVE_VOLUME.
// Apply contour simplification.
//切片可打印卷、负卷和修改器卷按ModelVolume:id排序。
//应用闭合半径。
//将正XY补偿应用于ModelVolumeType:MODEL_PART和ModelVolumeTypePARAMETERMODIFIER而不是应用于ModelVolumeType:NEGATIVE_VOLUME。
//应用轮廓简化。
static std::vector<VolumeSlices> slice_volumes_inner(
const PrintConfig &print_config,
const PrintObjectConfig &print_object_config,
@ -140,6 +144,8 @@ static std::vector<VolumeSlices> slice_volumes_inner(
params_base.trafo = object_trafo;
//BBS: 0.0025mm is safe enough to simplify the data to speed slicing up for high-resolution model.
//Also has on influence on arc fitting which has default resolution 0.0125mm.
//BBS:0.0025mm足够安全,可以简化数据,加快高分辨率模型的切片速度。
//对默认分辨率为0.0125mm的圆弧拟合也没有影响。
params_base.resolution = print_config.resolution <= 0.001 ? 0.0f : 0.0025;
switch (print_object_config.slicing_mode.value) {
case SlicingMode::Regular: params_base.mode = MeshSlicingParams::SlicingMode::Regular; break;
@ -154,6 +160,8 @@ static std::vector<VolumeSlices> slice_volumes_inner(
const bool is_mm_painted = num_extruders > 1 && std::any_of(model_volumes.cbegin(), model_volumes.cend(), [](const ModelVolume *mv) { return mv->is_mm_painted(); });
// BBS: don't do size compensation when slice volume.
// Will handle contour and hole size compensation seperately later.
//BBS切片时不要做尺寸补偿。
//稍后将分别处理轮廓和孔尺寸补偿。
//const auto extra_offset = is_mm_painted ? 0.f : std::max(0.f, float(print_object_config.xy_contour_compensation.value));
const auto extra_offset = 0.f;
@ -170,6 +178,8 @@ static std::vector<VolumeSlices> slice_volumes_inner(
params.mode = MeshSlicingParams::SlicingMode::PositiveLargestContour;
// Slice the bottom layers with SlicingMode::Regular.
// This needs to be in sync with LayerRegion::make_perimeters() spiral_mode!
//使用SlicingModeRegular对底层进行切片。
//这需要与LayerRegion:make_perimetersspiral_mode同步
const PrintRegionConfig &region_config = it->region->config();
params.slicing_mode_normal_below_layer = size_t(region_config.bottom_shell_layers.value);
for (; params.slicing_mode_normal_below_layer < zs.size() && zs[params.slicing_mode_normal_below_layer] < region_config.bottom_shell_thickness - EPSILON;
@ -244,6 +254,8 @@ static std::vector<std::vector<ExPolygons>> slices_to_regions(
std::vector<VolumeSlices> &&volume_slices,
// If clipping is disabled, then ExPolygons produced by different volumes will never be merged, thus they will be allowed to overlap.
// It is up to the model designer to handle these overlaps.
//如果禁用剪裁则由不同体积生成的ExPolygon将永远不会合并因此它们将被允许重叠。
//由模型设计者来处理这些重叠。
const bool clip_multipart_objects,
const std::function<void()> &throw_on_cancel_callback)
{
@ -252,6 +264,7 @@ static std::vector<std::vector<ExPolygons>> slices_to_regions(
std::vector<std::vector<ExPolygons>> slices_by_region(print_object_regions.all_regions.size(), std::vector<ExPolygons>(zs.size(), ExPolygons()));
// First shuffle slices into regions if there is no overlap with another region possible, collect zs of the complex cases.
//首先若并没有可能和另一个区域重叠则将切片洗牌到各个区域收集复杂案例的zs。
std::vector<std::pair<size_t, float>> zs_complex;
{
size_t z_idx = 0;
@ -280,6 +293,7 @@ static std::vector<std::vector<ExPolygons>> slices_to_regions(
idx_first_printable_region = idx_region;
else if (idx_first_printable_region != -1) {
// Test for overlap with some other region.
//测试是否与其他区域重叠。
for (int idx_region2 = idx_first_printable_region; idx_region2 < idx_region; ++ idx_region2) {
const PrintObjectRegions::VolumeRegion &region2 = layer_range.volume_regions[idx_region2];
if (region2.bbox->min().z() <= z && region2.bbox->max().z() >= z && overlap_in_xy(*region.bbox, *region2.bbox)) {
@ -303,6 +317,7 @@ static std::vector<std::vector<ExPolygons>> slices_to_regions(
}
// Second perform region clipping and assignment in parallel.
//其次,并行执行区域裁剪和分配。
if (! zs_complex.empty()) {
std::vector<std::vector<VolumeSlices*>> layer_ranges_regions_to_slices(print_object_regions.layer_ranges.size(), std::vector<VolumeSlices*>());
for (const PrintObjectRegions::LayerRangeRegions &layer_range : print_object_regions.layer_ranges) {
@ -318,9 +333,11 @@ static std::vector<std::vector<ExPolygons>> slices_to_regions(
float z = zs_complex[range.begin()].second;
auto it_layer_range = layer_range_first(print_object_regions.layer_ranges, z);
// Per volume_regions slices at this Z height.
//按体积_区域在此Z高度处切片。
struct RegionSlice {
ExPolygons expolygons;
// Identifier of this region in PrintObjectRegions::all_regions
//PrintObjectRegions中此区域的标识符all_regions
int region_id;
ObjectID volume_id;
bool operator<(const RegionSlice &rhs) const {
@ -328,6 +345,8 @@ static std::vector<std::vector<ExPolygons>> slices_to_regions(
bool rhs_empty = rhs.region_id < 0 || rhs.expolygons.empty();
// Sort the empty items to the end of the list.
// Sort by region_id & volume_id lexicographically.
//将空项目排序到列表末尾。
//按region_id和volume_id按字母顺序排序。
return ! this_empty && (rhs_empty || (this->region_id < rhs.region_id || (this->region_id == rhs.region_id && volume_id < volume_id)));
}
};
@ -368,6 +387,7 @@ static std::vector<std::vector<ExPolygons>> slices_to_regions(
{
std::vector<VolumeSlices*> &layer_range_regions_to_slices = layer_ranges_regions_to_slices[it_layer_range - print_object_regions.layer_ranges.begin()];
// Per volume_regions slices at thiz Z height.
//按体积_区域在Z高度处切片。
temp_slices.clear();
temp_slices.reserve(layer_range.volume_regions.size());
for (VolumeSlices* &slices : layer_range_regions_to_slices) {
@ -392,12 +412,15 @@ static std::vector<std::vector<ExPolygons>> slices_to_regions(
}
if (next_region_same_modifier)
// To be used in the following iteration.
//将在以下迭代中使用。
temp_slices[idx_region + 1].expolygons = std::move(source);
} else if ((region.model_volume->is_model_part() && clip_multipart_objects) || region.model_volume->is_negative_volume()) {
// Clip every non-zero region preceding it.
//剪切它前面的每个非零区域。
for (int idx_region2 = 0; idx_region2 < idx_region; ++ idx_region2)
if (! temp_slices[idx_region2].expolygons.empty()) {
// Skip trim_overlap for now, because it slow down the performace so much for some special cases
//暂时跳过trim_overlap因为在某些特殊情况下它会大大降低性能
#if 1
if (const PrintObjectRegions::VolumeRegion& region2 = layer_range.volume_regions[idx_region2];
!region2.model_volume->is_negative_volume() && overlap_in_xy(*region.bbox, *region2.bbox))
@ -415,12 +438,15 @@ static std::vector<std::vector<ExPolygons>> slices_to_regions(
}
}
// Sort by region_id, push empty slices to the end.
//按region_id排序将空切片推到末尾。
std::sort(temp_slices.begin(), temp_slices.end());
// Remove the empty slices.
temp_slices.erase(std::find_if(temp_slices.begin(), temp_slices.end(), [](const auto &slice) { return slice.region_id == -1 || slice.expolygons.empty(); }), temp_slices.end());
// Merge slices and store them to the output.
//合并切片并将其存储到输出中。
for (int i = 0; i < int(temp_slices.size());) {
// Find a range of temp_slices with the same region_id.
//查找具有相同region_id的temp_slices范围。
int j = i;
bool merged = false;
ExPolygons &expolygons = temp_slices[i].expolygons;
@ -436,6 +462,7 @@ static std::vector<std::vector<ExPolygons>> slices_to_regions(
// Don't unite the regions if ! clip_multipart_objects. In that case it is user's responsibility
// to handle region overlaps. Indeed, one may intentionally let the regions overlap to produce crossing perimeters
// for example.
//如果发生这种情况不要团结各地区clip_multipart_objects。在这种情况下用户有责任处理区域重叠。事实上例如人们可能会故意让这些区域重叠以产生交叉边界。
if (merged && clip_multipart_objects)
expolygons = closing_ex(expolygons, float(scale_(EPSILON)));
slices_by_region[temp_slices[i].region_id][z_idx] = std::move(expolygons);
@ -565,6 +592,7 @@ bool groupingVolumes(std::vector<VolumeSlices> objSliceByVolume, std::vector<gro
}
//BBS: filter the members of "objSliceByVolume" such that only "model_part" are included
//BBS过滤“objSliceByVolume”的成员使其仅包含“model_part”
std::vector<VolumeSlices> findPartVolumes(const std::vector<VolumeSlices>& objSliceByVolume, ModelVolumePtrs model_volumes) {
std::vector<VolumeSlices> outPut;
for (const auto& vs : objSliceByVolume) {
@ -781,11 +809,20 @@ void groupingVolumesForBrim(PrintObject* object, LayerPtrs& layers, int firstLay
// 5) Applies size compensation (offsets the slices in XY plane)
// 6) Replaces bad slices by the slices reconstructed from the upper/lower layer
// Resulting expolygons of layer regions are marked as Internal.
//由make_perimeters调用
//1决定层的Z位置
//2初始化层及其区域
//3分割对象网格
//4对修改器网格进行切片并根据修改器网格的切片对对象网格的切片进行重新分类
//5应用尺寸补偿偏移XY平面中的切片
//6用从上层/下层重建的切片替换坏切片
//层区域的扩展结果标记为内部。
void PrintObject::slice()
{
if (! this->set_started(posSlice))
return;
//BBS: add flag to reload scene for shell rendering
//BBS添加标志以重新加载场景进行shell渲染
m_print->set_status(5, L("Slicing mesh"), PrintBase::SlicingStatus::RELOAD_SCENE);
std::vector<coordf_t> layer_height_profile;
this->update_layer_height_profile(*this->model_object(), m_slicing_params, layer_height_profile);
@ -800,10 +837,14 @@ void PrintObject::slice()
#if 1
// Fix the model.
//FIXME is this the right place to do? It is done repeateadly at the UI and now here at the backend.
//修复模型。
//FIXME是合适的地方吗它在UI上重复完成现在在后端完成。
std::string warning = fix_slicing_errors(this, m_layers, [this](){ m_print->throw_if_canceled(); }, firstLayerReplacedBy);
m_print->throw_if_canceled();
//BBS: send warning message to slicing callback
// This warning is inaccurate, because the empty layers may have been replaced, or the model has supports.
//BBS向切片回调发送警告消息
//此警告不准确,因为空层可能已被替换,或者模型有支撑。
//if (!warning.empty()) {
// BOOST_LOG_TRIVIAL(info) << warning;
// this->active_step_add_warning(PrintStateBase::WarningLevel::CRITICAL, warning, PrintStateBase::SlicingReplaceInitEmptyLayers);
@ -811,9 +852,11 @@ void PrintObject::slice()
#endif
// BBS: the actual first layer slices stored in layers are re-sorted by volume group and will be used to generate brim
//BBS存储在层中的实际第一层切片按卷组重新排序并将用于生成边缘
groupingVolumesForBrim(this, m_layers, firstLayerReplacedBy);
// Update bounding boxes, back up raw slices of complex models.
//更新边界框,备份复杂模型的原始切片。
tbb::parallel_for(
tbb::blocked_range<size_t>(0, m_layers.size()),
[this](const tbb::blocked_range<size_t>& range) {
@ -971,6 +1014,15 @@ static inline void apply_mm_segmentation(PrintObject &print_object, ThrowOnCance
// Resulting expolygons of layer regions are marked as Internal.
//
// this should be idempotent
//1决定层的Z位置
//2初始化层及其区域
//3分割对象网格
//4对修改器网格进行切片并根据修改器网格的切片对对象网格的切片进行重新分类
//5应用尺寸补偿偏移XY平面中的切片
//6用从上层/下层重建的切片替换坏切片
//层区域的扩展结果标记为内部。
//
//这应该是幂等的
void PrintObject::slice_volumes()
{
BOOST_LOG_TRIVIAL(info) << "Slicing volumes..." << log_memory_info();
@ -978,8 +1030,10 @@ void PrintObject::slice_volumes()
const auto throw_on_cancel_callback = std::function<void()>([print](){ print->throw_if_canceled(); });
// Clear old LayerRegions, allocate for new PrintRegions.
//清除旧的LayerRegions为新的PrintRegions分配。
for (Layer* layer : m_layers) {
//BBS: should delete all LayerRegionPtr to avoid memory leak
//BBS应删除所有LayerRegionPtr以避免内存泄漏
while (!layer->m_regions.empty()) {
if (layer->m_regions.back())
delete layer->m_regions.back();
@ -999,6 +1053,7 @@ void PrintObject::slice_volumes()
}
//BBS: "model_part" volumes are grouded according to their connections
//BBS:“model_part”卷根据其连接进行分组
//const auto scaled_resolution = scaled<double>(print->config().resolution.value);
//firstLayerObjSliceByVolume = findPartVolumes(objSliceByVolume, this->model_object()->volumes);
//groupingVolumes(objSliceByVolumeParts, firstLayerObjSliceByGroups, scaled_resolution);
@ -1030,12 +1085,14 @@ void PrintObject::slice_volumes()
m_print->throw_if_canceled();
// Is any ModelVolume MMU painted?
//是否有任何ModelVolume MMU涂漆
if (const auto& volumes = this->model_object()->volumes;
m_print->config().filament_diameter.size() > 1 && // BBS
std::find_if(volumes.begin(), volumes.end(), [](const ModelVolume* v) { return !v->mmu_segmentation_facets.empty(); }) != volumes.end()) {
// If XY Size compensation is also enabled, notify the user that XY Size compensation
// would not be used because the object is multi-material painted.
//如果还启用了XY尺寸补偿请通知用户由于对象是多材质绘制的因此不会使用XY尺寸补偿。
if (m_config.xy_hole_compensation.value != 0.f || m_config.xy_contour_compensation.value != 0.f) {
this->active_step_add_warning(
PrintStateBase::WarningLevel::CRITICAL,
@ -1052,16 +1109,20 @@ void PrintObject::slice_volumes()
BOOST_LOG_TRIVIAL(debug) << "Slicing volumes - make_slices in parallel - begin";
{
// Compensation value, scaled. Only applying the negative scaling here, as the positive scaling has already been applied during slicing.
//补偿值,按比例计算。此处仅应用负缩放,因为在切片过程中已经应用了正缩放。
const size_t num_extruders = print->config().filament_diameter.size();
const auto xy_hole_scaled = (num_extruders > 1 && this->is_mm_painted()) ? scaled<float>(0.f) : scaled<float>(m_config.xy_hole_compensation.value);
const auto xy_contour_scaled = (num_extruders > 1 && this->is_mm_painted()) ? scaled<float>(0.f) : scaled<float>(m_config.xy_contour_compensation.value);
const float elephant_foot_compensation_scaled = (m_config.raft_layers == 0) ?
// Only enable Elephant foot compensation if printing directly on the print bed.
//仅在直接在打印床上打印时启用象脚补偿。
float(scale_(m_config.elefant_foot_compensation.value)) :
0.f;
// Uncompensated slices for the first layer in case the Elephant foot compensation is applied.
//在应用象脚补偿的情况下,第一层的无补偿切片。
ExPolygons lslices_1st_layer;
//BBS: this part has been changed a lot to support seperated contour and hole size compensation
//BBS这部分已经做了很多更改以支持单独的轮廓和孔尺寸补偿
tbb::parallel_for(
tbb::blocked_range<size_t>(0, m_layers.size()),
[this, xy_hole_scaled, xy_contour_scaled, elephant_foot_compensation_scaled, &lslices_1st_layer](const tbb::blocked_range<size_t>& range) {
@ -1069,13 +1130,17 @@ void PrintObject::slice_volumes()
m_print->throw_if_canceled();
Layer *layer = m_layers[layer_id];
// Apply size compensation and perform clipping of multi-part objects.
//应用尺寸补偿并对多部分对象进行剪裁。
float elfoot = (layer_id == 0) ? elephant_foot_compensation_scaled : 0.f;
if (layer->m_regions.size() == 1) {
// Optimized version for a single region layer.
// Single region, growing or shrinking.
//针对单个区域层的优化版本。
//单一地区,增长或萎缩。
LayerRegion *layerm = layer->m_regions.front();
if (elfoot > 0) {
// Apply the elephant foot compensation and store the 1st layer slices without the Elephant foot compensation applied.
//应用象脚补偿,并存储未应用象脚赔偿的第一层切片。
lslices_1st_layer = to_expolygons(std::move(layerm->slices.surfaces));
if (xy_contour_scaled > 0 || xy_hole_scaled > 0) {
lslices_1st_layer = _shrink_contour_holes(std::max(0.f, xy_contour_scaled),
@ -1094,6 +1159,7 @@ void PrintObject::slice_volumes()
stInternal);
} else {
// Apply the XY contour and hole size compensation.
//应用XY轮廓和孔尺寸补偿。
if (xy_contour_scaled != 0.0f || xy_hole_scaled != 0.0f) {
ExPolygons expolygons = to_expolygons(std::move(layerm->slices.surfaces));
if (xy_contour_scaled > 0 || xy_hole_scaled > 0) {
@ -1116,12 +1182,15 @@ void PrintObject::slice_volumes()
if (max_growth > 0) {
//BBS: merge polygons because region can cut "holes".
//Then, cut them to give them again later to their region
//BBS合并多边形因为该区域可以切割“孔”。
//然后,把它们剪下来,稍后再送给它们所在的地区
merged_poly_for_holes_growing = layer->merged(float(SCALED_EPSILON));
merged_poly_for_holes_growing = _shrink_contour_holes(std::max(0.f, xy_contour_scaled),
std::max(0.f, xy_hole_scaled),
union_ex(merged_poly_for_holes_growing));
// BBS: clipping regions, priority is given to the first regions.
//BBS剪切区域优先剪切第一个区域。
Polygons processed;
for (size_t region_id = 0; region_id < layer->regions().size(); ++region_id) {
ExPolygons slices = to_expolygons(std::move(layer->m_regions[region_id]->slices.surfaces));
@ -1130,16 +1199,19 @@ void PrintObject::slice_volumes()
}
//BBS: Trim by the slices of already processed regions.
//BBS按已加工区域的切片进行修剪。
if (region_id > 0)
slices = diff_ex(to_polygons(std::move(slices)), processed);
if (region_id + 1 < layer->regions().size())
// Collect the already processed regions to trim the to be processed regions.
//收集已处理的区域以修剪待处理的区域。
polygons_append(processed, slices);
layer->m_regions[region_id]->slices.set(std::move(slices), stInternal);
}
}
if (min_growth < 0.f || elfoot > 0.f) {
// Apply the negative XY compensation. (the ones that is <0)
//应用负XY补偿。小于0的那些
ExPolygons trimming;
static const float eps = float(scale_(m_config.slice_closing_radius.value) * 1.5);
if (elfoot > 0.f) {
@ -1154,8 +1226,10 @@ void PrintObject::slice_volumes()
std::min(0.f, xy_hole_scaled),
trimming);
//BBS: trim surfaces
//BBS修整表面
for (size_t region_id = 0; region_id < layer->regions().size(); ++region_id) {
// BBS: split trimming result by region
//BBS按地区划分修剪结果
ExPolygons contour_exp = to_expolygons(std::move(layer->regions()[region_id]->slices.surfaces));
layer->regions()[region_id]->slices.set(intersection_ex(contour_exp, to_polygons(trimming)), stInternal);
@ -1163,15 +1237,20 @@ void PrintObject::slice_volumes()
}
}
// Merge all regions' slices to get islands, chain them by a shortest path.
//合并所有区域的切片以获得岛屿,用最短路径将它们链接起来。
layer->make_slices();
}
});
if (elephant_foot_compensation_scaled > 0.f && ! m_layers.empty()) {
// The Elephant foot has been compensated, therefore the 1st layer's lslices are shrank with the Elephant foot compensation value.
// Store the uncompensated value there.
//大象脚已经得到补偿,因此第一层的切片缩小了大象脚补偿值。
//将未补偿的价值存储在那里。
assert(m_layers.front()->id() == 0);
//BBS: sort the lslices_1st_layer according to shortest path before saving
//Otherwise the travel of first layer would be mess.
//BBS保存前按最短路径对lslices_1st_layer进行排序
//否则,第一层的旅行会一团糟。
Points ordering_points;
ordering_points.reserve(lslices_1st_layer.size());
for (const ExPolygon& ex : lslices_1st_layer)

View File

@ -723,6 +723,7 @@ bool adjust_layer_series_to_align_object_height(const SlicingParameters &slicing
}
// Produce object layers as pairs of low / high layer boundaries, stored into a linear vector.
//将对象层作为低/高层边界对生成,并存储到线性向量中。
std::vector<coordf_t> generate_object_layers(
const SlicingParameters &slicing_params,
const std::vector<coordf_t> &layer_height_profile,
@ -743,6 +744,7 @@ std::vector<coordf_t> generate_object_layers(
size_t idx_layer_height_profile = 0;
// loop until we have at least one layer and the max slice_z reaches the object height
//循环直到我们至少有一个层并且最大slice_z达到对象高度
coordf_t slice_z = print_z + 0.5 * slicing_params.min_layer_height;
while (slice_z < slicing_params.object_print_z_height()) {
height = slicing_params.min_layer_height;

View File

@ -1878,20 +1878,26 @@ std::vector<Polygons> slice_mesh(
// Instead of edge identifiers, one shall use a sorted pair of edge vertex indices.
// However facets_edges assigns a single edge ID to two triangles only, thus when factoring facets_edges out, one will have
// to make sure that no code relies on it.
//FIXME facets_edges可能不需要计算成本相当高。
//应使用排序后的一对边顶点索引来代替边标识符。
//然而facets_edges只为两个三角形分配一个边ID因此在分解facets_edge时必须确保没有代码依赖于它。
std::vector<Vec3i> face_edge_ids = its_face_edge_ids(mesh);
if (zs.size() <= 1) {
// It likely is not worthwile to copy the vertices. Apply the transformation in place.
//复制顶点可能不值得。将转换应用到位。
if (is_identity(params.trafo)) {
lines = slice_make_lines(
mesh.vertices, [](const Vec3f &p) { return Vec3f(scaled<float>(p.x()), scaled<float>(p.y()), p.z()); },
mesh.indices, face_edge_ids, zs, throw_on_cancel);
} else {
// Transform the vertices, scale up in XY, not in Z.
//变换顶点在XY方向上放大而不是在Z方向上。
Transform3f tf = make_trafo_for_slicing(params.trafo);
lines = slice_make_lines(mesh.vertices, [tf](const Vec3f &p) { return tf * p; }, mesh.indices, face_edge_ids, zs, throw_on_cancel);
}
} else {
// Copy and scale vertices in XY, don't scale in Z. Possibly apply the transformation.
//在XY中复制和缩放顶点不要在Z中缩放。可能会应用变换。
lines = slice_make_lines(
transform_mesh_vertices_for_slicing(mesh, params.trafo),
[](const Vec3f &p) { return p; }, mesh.indices, face_edge_ids, zs, throw_on_cancel);

View File

@ -98,6 +98,7 @@ ExtrusionMultiPath thick_polyline_to_multi_path(const ThickPolyline& thick_polyl
}
//BBS: new function to filter width to avoid too fragmented segments
//BBS新功能过滤宽度避免片段过于碎片化
static ExtrusionPaths thick_polyline_to_extrusion_paths_2(const ThickPolyline& thick_polyline, ExtrusionRole role, const Flow& flow, const float tolerance)
{
ExtrusionPaths paths;
@ -216,6 +217,7 @@ void variable_width(const ThickPolylines& polylines, ExtrusionRole role, const F
// This value determines granularity of adaptive width, as G-code does not allow
// variable extrusion within a single move; this value shall only affect the amount
// of segments, and any pruning shall be performed before we apply this tolerance.
//该值决定了自适应宽度的粒度因为G代码不允许在一次移动中进行可变拉伸该值仅影响分段数量在应用此公差之前应进行任何修剪。
const float tolerance = float(scale_(0.05));
for (const ThickPolyline& p : polylines) {
ExtrusionPaths paths = thick_polyline_to_extrusion_paths_2(p, role, flow, tolerance);

View File

@ -192,18 +192,22 @@ std::string BackgroundSlicingProcess::output_filepath_for_project(const boost::f
// This function may one day be merged into the Print, but historically the print was separated
// from the G-code generator.
//此功能可能有一天会合并到打印中但历史上打印与G代码生成器是分开的。
void BackgroundSlicingProcess::process_fff()
{
assert(m_print == m_fff_print);
PresetBundle &preset_bundle = *wxGetApp().preset_bundle;
m_fff_print->set_BBL_Printer(preset_bundle.printers.get_edited_preset().is_bbl_vendor_preset(&preset_bundle));
//BBS: add the logic to process from an existed gcode file
//BBS从已有的gcode文件中添加逻辑以进行处理
if (m_print->finished()) {
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(" %1%: skip slicing, to process previous gcode file")%__LINE__;
m_fff_print->set_status(80, _utf8(L("Processing G-Code from Previous file...")));
wxCommandEvent evt(m_event_slicing_completed_id);
// Post the Slicing Finished message for the G-code viewer to update.
// Passing the timestamp
//发布“切片完成”消息以便G代码查看器进行更新。
//传递时间戳
evt.SetInt((int)(m_fff_print->step_state_with_timestamp(PrintStep::psSlicingFinished).timestamp));
wxQueueEvent(GUI::wxGetApp().mainframe->m_plater, evt.Clone());
@ -219,6 +223,8 @@ void BackgroundSlicingProcess::process_fff()
else {
//BBS: reset the gcode before reload_print in slicing_completed event processing
//FIX the gcode rename failed issue
//BBS:在slicing_colleged事件处理中reload_print之前重置gcode
//修复gcode重命名失败的问题
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(" %1%: will start slicing, reset gcode_result %2% firstly")%__LINE__%m_gcode_result;
m_gcode_result->reset();
@ -229,10 +235,13 @@ void BackgroundSlicingProcess::process_fff()
wxCommandEvent evt(m_event_slicing_completed_id);
// Post the Slicing Finished message for the G-code viewer to update.
// Passing the timestamp
//发布“切片完成”消息以便G代码查看器进行更新。
//传递时间戳
evt.SetInt((int)(m_fff_print->step_state_with_timestamp(PrintStep::psSlicingFinished).timestamp));
wxQueueEvent(GUI::wxGetApp().mainframe->m_plater, evt.Clone());
//BBS: add plate index into render params
//BBS在渲染参数中添加板块索引
m_temp_output_path = this->get_current_plate()->get_tmp_gcode_path();
m_fff_print->export_gcode(m_temp_output_path, m_gcode_result, [this](const ThumbnailsParams& params) { return this->render_thumbnails(params); });
finalize_gcode();

View File

@ -9447,6 +9447,8 @@ void Plater::_calib_pa_pattern(const Calib_Params &params)
wxGetApp().get_tab(Preset::TYPE_PRINT)->update_dirty();
wxGetApp().get_tab(Preset::TYPE_PRINT)->reload_config();
wxGetApp().get_tab(Preset::TYPE_CONFIG)->update_dirty();
wxGetApp().get_tab(Preset::TYPE_CONFIG)->reload_config();
const DynamicPrintConfig full_config = wxGetApp().preset_bundle->full_config();
PresetBundle * preset_bundle = wxGetApp().preset_bundle;
@ -9502,6 +9504,8 @@ void Plater::_calib_pa_tower(const Calib_Params &params)
wxGetApp().get_tab(Preset::TYPE_PRINT)->reload_config();
wxGetApp().get_tab(Preset::TYPE_FILAMENT)->reload_config();
wxGetApp().get_tab(Preset::TYPE_PRINTER)->reload_config();
wxGetApp().get_tab(Preset::TYPE_CONFIG)->update_dirty();
wxGetApp().get_tab(Preset::TYPE_CONFIG)->reload_config();
auto new_height = std::ceil((params.end - params.start) / params.step) + 1;
auto obj_bb = model().objects[0]->bounding_box();
@ -9616,6 +9620,8 @@ void Plater::calib_flowrate(int pass)
wxGetApp().get_tab(Preset::TYPE_PRINT)->reload_config();
wxGetApp().get_tab(Preset::TYPE_FILAMENT)->reload_config();
wxGetApp().get_tab(Preset::TYPE_PRINTER)->reload_config();
wxGetApp().get_tab(Preset::TYPE_CONFIG)->update_dirty();
wxGetApp().get_tab(Preset::TYPE_CONFIG)->reload_config();
try {
json js;
@ -9669,6 +9675,8 @@ void Plater::calib_temp(const Calib_Params &params)
wxGetApp().get_tab(Preset::TYPE_FILAMENT)->update_dirty();
wxGetApp().get_tab(Preset::TYPE_PRINT)->reload_config();
wxGetApp().get_tab(Preset::TYPE_FILAMENT)->reload_config();
wxGetApp().get_tab(Preset::TYPE_CONFIG)->update_dirty();
wxGetApp().get_tab(Preset::TYPE_CONFIG)->reload_config();
// cut upper
auto obj_bb = model().objects[0]->bounding_box();
@ -9759,6 +9767,8 @@ void Plater::calib_max_vol_speed(const Calib_Params &params)
wxGetApp().get_tab(Preset::TYPE_PRINT)->reload_config();
wxGetApp().get_tab(Preset::TYPE_FILAMENT)->reload_config();
wxGetApp().get_tab(Preset::TYPE_PRINTER)->reload_config();
wxGetApp().get_tab(Preset::TYPE_CONFIG)->update_dirty();
wxGetApp().get_tab(Preset::TYPE_CONFIG)->reload_config();
// cut upper
auto obj_bb = obj->bounding_box();
@ -9866,6 +9876,8 @@ void Plater::calib_VFA(const Calib_Params &params)
wxGetApp().get_tab(Preset::TYPE_FILAMENT)->update_dirty();
wxGetApp().get_tab(Preset::TYPE_PRINT)->update_ui_from_settings();
wxGetApp().get_tab(Preset::TYPE_FILAMENT)->update_ui_from_settings();
wxGetApp().get_tab(Preset::TYPE_CONFIG)->update_dirty();
wxGetApp().get_tab(Preset::TYPE_CONFIG)->update_ui_from_settings();
// cut upper
auto obj_bb = model().objects[0]->bounding_box();

View File

@ -1971,12 +1971,12 @@ void TabPrint::build()
//optgroup = page->new_optgroup(L("Wall generator"), L"param_wall");
//optgroup->append_single_option_line("wall_generator", "wall-generator");
optgroup->append_single_option_line("wall_transition_angle");
optgroup->append_single_option_line("wall_transition_filter_deviation");
optgroup->append_single_option_line("wall_transition_length");
optgroup->append_single_option_line("wall_distribution_count");
optgroup->append_single_option_line("min_bead_width");
optgroup->append_single_option_line("min_feature_size");
//optgroup->append_single_option_line("wall_transition_angle");
//optgroup->append_single_option_line("wall_transition_filter_deviation");
//optgroup->append_single_option_line("wall_transition_length");
//optgroup->append_single_option_line("wall_distribution_count");
//optgroup->append_single_option_line("min_bead_width");
//->append_single_option_line("min_feature_size");
//optgroup = page->new_optgroup(L("Advanced"), L"param_advanced");
//optgroup->append_single_option_line("wall_sequence");
@ -4378,7 +4378,10 @@ void TabPrinter::update_sla()
void TabConfig::build() {
m_presets = &m_preset_bundle->configs;
if (m_presets == nullptr)
m_presets = &m_preset_bundle->configs;
load_initial_data();
auto page = add_options_page(L("Quality"), "spool");
auto optgroup = page->new_optgroup("", L"param_layer_height");
@ -4428,7 +4431,6 @@ void TabConfig::build() {
optgroup->append_single_option_line("support_base_pattern_spacing", "support#base-pattern");
optgroup->append_single_option_line("support_interface_top_layers", "support#base-pattern");
optgroup->append_single_option_line("support_interface_bottom_layers", "support#base-pattern");
//you cuo wu -- zan ding
//optgroup->append_single_option_line("support_interface_spacing", "support#base-pattern");
@ -4508,7 +4510,7 @@ void TabConfig::build() {
page = add_options_page(L("Others"), "advanced");
optgroup = page->new_optgroup("", L"param_adhension");
optgroup->append_single_option_line("slicing_mode");
optgroup->append_single_option_line("fibre_feed_rate");
//optgroup->append_single_option_line("fibre_feed_rate");
optgroup->append_single_option_line("print_sequence", "sequent-print");
optgroup->append_single_option_line("spiral_mode", "spiral-vase");
optgroup->append_single_option_line("spiral_mode_smooth", "spiral-vase#smooth");
@ -4526,6 +4528,7 @@ void TabConfig::reload_config()
{
//this->compatible_widget_reload(m_compatible_printers);
//this->compatible_widget_reload(m_compatible_prints);
this->compatible_widget_reload(m_compatible_printers);
Tab::reload_config();
}
//void TabConfig::update_description_lines()
@ -4545,10 +4548,12 @@ void TabConfig::toggle_options() {
if (!m_active_page)
return;
bool is_BBL_printer = false;
if (m_preset_bundle) {
is_BBL_printer = m_preset_bundle->configs.get_edited_preset().is_bbl_vendor_preset(m_preset_bundle);
bool is_BBL_printer = m_preset_bundle->configs.get_edited_preset().is_bbl_vendor_preset(m_preset_bundle);
m_config_manipulation.set_is_BBL_Printer(is_BBL_printer);
}
m_config_manipulation.toggle_print_fff_options(m_config, m_type < Preset::TYPE_COUNT);
bool enable_support = m_preset_bundle->prints.get_edited_preset().config.opt_bool("enable_support");
for (auto el : { "support_style", "support_base_pattern",
@ -4779,14 +4784,22 @@ void TabConfig::toggle_options() {
}
}
void TabConfig::update() {
if (m_preset_bundle->printers.get_selected_preset().printer_technology() == ptSLA)
return; // ys_FIXME
m_update_cnt++;
toggle_options();
m_config_manipulation.update_print_fff_config(m_config, m_type < Preset::TYPE_COUNT, m_type == Preset::TYPE_PLATE);
m_parent->Layout();
m_update_cnt--;
if (m_update_cnt == 0) {
toggle_options();
if (m_type != Preset::TYPE_MODEL && !wxGetApp().plater()->inside_snapshot_capture())
wxGetApp().obj_list()->update_and_show_object_settings_item();
if (m_update_cnt == 0)
wxGetApp().mainframe->on_config_changed(m_config);
}
}
void TabConfig::clear_pages() {
Tab::clear_pages();

View File

@ -508,6 +508,7 @@ bool CalibUtils::calib_flowrate(int pass, const CalibInfo &calib_info, wxString
DynamicConfig print_config = calib_info.print_prest->config;
DynamicConfig filament_config = calib_info.filament_prest->config;
DynamicConfig printer_config = calib_info.printer_prest->config;
DynamicConfig config_config = calib_info.config_prest->config;
/// --- scale ---
// model is created for a 0.4 nozzle, scale z with nozzle size.
@ -577,6 +578,7 @@ bool CalibUtils::calib_flowrate(int pass, const CalibInfo &calib_info, wxString
full_config.apply(print_config);
full_config.apply(filament_config);
full_config.apply(printer_config);
full_config.apply(config_config);
Calib_Params params;
params.mode = CalibMode::Calib_Flow_Rate;
@ -618,12 +620,14 @@ void CalibUtils::calib_pa_pattern(const CalibInfo &calib_info, Model& model)
DynamicPrintConfig& print_config = calib_info.print_prest->config;
DynamicPrintConfig& filament_config = calib_info.filament_prest->config;
DynamicPrintConfig& printer_config = calib_info.printer_prest->config;
DynamicPrintConfig& config_config = calib_info.config_prest->config;
DynamicPrintConfig full_config;
full_config.apply(FullPrintConfig::defaults());
full_config.apply(print_config);
full_config.apply(filament_config);
full_config.apply(printer_config);
full_config.apply(config_config);
float nozzle_diameter = printer_config.option<ConfigOptionFloats>("nozzle_diameter")->get_at(0);
@ -652,6 +656,7 @@ void CalibUtils::calib_pa_pattern(const CalibInfo &calib_info, Model& model)
full_config.apply(print_config);
full_config.apply(filament_config);
full_config.apply(printer_config);
full_config.apply(config_config);
Vec3d plate_origin(0, 0, 0);
CalibPressureAdvancePattern pa_pattern(calib_info.params, full_config, true, model, plate_origin);
@ -688,6 +693,7 @@ bool CalibUtils::calib_generic_PA(const CalibInfo &calib_info, wxString &error_m
DynamicPrintConfig print_config = calib_info.print_prest->config;
DynamicPrintConfig filament_config = calib_info.filament_prest->config;
DynamicPrintConfig printer_config = calib_info.printer_prest->config;
DynamicPrintConfig config_config = calib_info.config_prest->config;
filament_config.set_key_value("curr_bed_type", new ConfigOptionEnum<BedType>(calib_info.bed_type));
@ -696,6 +702,8 @@ bool CalibUtils::calib_generic_PA(const CalibInfo &calib_info, wxString &error_m
full_config.apply(print_config);
full_config.apply(filament_config);
full_config.apply(printer_config);
full_config.apply(config_config);
if (!process_and_store_3mf(&model, full_config, params, error_message))
return false;
@ -780,6 +788,7 @@ void CalibUtils::calib_temptue(const CalibInfo &calib_info, wxString &error_mess
DynamicPrintConfig print_config = calib_info.print_prest->config;
DynamicPrintConfig filament_config = calib_info.filament_prest->config;
DynamicPrintConfig printer_config = calib_info.printer_prest->config;
DynamicPrintConfig config_config = calib_info.config_prest->config;
auto start_temp = lround(params.start);
filament_config.set_key_value("nozzle_temperature_initial_layer", new ConfigOptionInts(1, (int) start_temp));
@ -797,6 +806,7 @@ void CalibUtils::calib_temptue(const CalibInfo &calib_info, wxString &error_mess
full_config.apply(print_config);
full_config.apply(filament_config);
full_config.apply(printer_config);
full_config.apply(config_config);
process_and_store_3mf(&model, full_config, params, error_message);
if (!error_message.empty())
@ -818,6 +828,7 @@ void CalibUtils::calib_max_vol_speed(const CalibInfo &calib_info, wxString &erro
DynamicPrintConfig print_config = calib_info.print_prest->config;
DynamicPrintConfig filament_config = calib_info.filament_prest->config;
DynamicPrintConfig printer_config = calib_info.printer_prest->config;
DynamicPrintConfig config_config = calib_info.config_prest->config;
auto obj = model.objects[0];
auto bed_shape = printer_config.option<ConfigOptionPoints>("printable_area")->values;
@ -877,6 +888,7 @@ void CalibUtils::calib_max_vol_speed(const CalibInfo &calib_info, wxString &erro
full_config.apply(print_config);
full_config.apply(filament_config);
full_config.apply(printer_config);
full_config.apply(config_config);
process_and_store_3mf(&model, full_config, new_params, error_message);
if (!error_message.empty())
@ -898,6 +910,7 @@ void CalibUtils::calib_VFA(const CalibInfo &calib_info, wxString &error_message)
DynamicPrintConfig print_config = calib_info.print_prest->config;
DynamicPrintConfig filament_config = calib_info.filament_prest->config;
DynamicPrintConfig printer_config = calib_info.printer_prest->config;
DynamicPrintConfig config_config = calib_info.config_prest->config;
filament_config.set_key_value("slow_down_layer_time", new ConfigOptionInts{0});
filament_config.set_key_value("filament_max_volumetric_speed", new ConfigOptionFloats{200});
@ -935,6 +948,7 @@ void CalibUtils::calib_VFA(const CalibInfo &calib_info, wxString &error_message)
full_config.apply(print_config);
full_config.apply(filament_config);
full_config.apply(printer_config);
full_config.apply(config_config);
process_and_store_3mf(&model, full_config, params, error_message);
if (!error_message.empty())
@ -956,6 +970,7 @@ void CalibUtils::calib_retraction(const CalibInfo &calib_info, wxString &error_m
DynamicPrintConfig print_config = calib_info.print_prest->config;
DynamicPrintConfig filament_config = calib_info.filament_prest->config;
DynamicPrintConfig printer_config = calib_info.printer_prest->config;
DynamicPrintConfig config_config = calib_info.config_prest->config;
auto obj = model.objects[0];
@ -986,6 +1001,7 @@ void CalibUtils::calib_retraction(const CalibInfo &calib_info, wxString &error_m
full_config.apply(print_config);
full_config.apply(filament_config);
full_config.apply(printer_config);
full_config.apply(config_config);
process_and_store_3mf(&model, full_config, params, error_message);
if (!error_message.empty())

View File

@ -19,6 +19,7 @@ public:
Preset* printer_prest;
Preset* filament_prest;
Preset* print_prest;
Preset* config_prest;
BedType bed_type;
std::string dev_id;
std::string select_ams;