切换开发版本前最后提交代码
This commit is contained in:
parent
599cd5ed72
commit
49a9b27eab
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -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_
|
|
@ -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,
|
||||
|
|
|
@ -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)));
|
||||
|
|
|
@ -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() {}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 Slic3r::SlicingError(“找不到缓存的数据。”);
|
||||
//不报告错误,将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);
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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 ®ion = 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.
|
||||
//这将检测桥接和反向桥接,并重新排列顶部/底部/内部表面
|
||||
//它产生了扩大的重叠桥接区域。
|
||||
//1)stBottomBridge/stBottom填充物增长了3mm,并被总填充面积所限。检测到桥梁。这些区域可能会重叠。
|
||||
//2)stTop生长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();
|
||||
|
||||
|
|
|
@ -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和ModelVolumeType::PARAMETERMODIFIER,而不是应用于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!
|
||||
//使用SlicingMode::Regular对底层进行切片。
|
||||
//这需要与LayerRegion::make_perimeters()spiral_mode同步!
|
||||
const PrintRegionConfig ®ion_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 ®ion2 = 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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -9447,6 +9447,8 @@ void Plater::_calib_pa_pattern(const Calib_Params ¶ms)
|
|||
|
||||
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 ¶ms)
|
|||
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 ¶ms)
|
|||
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 ¶ms)
|
|||
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 ¶ms)
|
|||
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();
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue