五、OrcaSlicer 切片

一、切片

1、SlicingParameters 切片参数

cpp 复制代码
struct SlicingParameters
{
	SlicingParameters() = default;

    static SlicingParameters create_from_config(
        const PrintConfig       &print_config, 
        const PrintObjectConfig &object_config,
        coordf_t                 object_height,
        const std::vector<unsigned int> &object_extruders);

    // Has any raft layers?
    bool        has_raft() const { return raft_layers() > 0; }
    size_t      raft_layers() const { return base_raft_layers + interface_raft_layers; }

    // Is the 1st object layer height fixed, or could it be varied?
    bool        first_object_layer_height_fixed()  const { return ! has_raft() || first_object_layer_bridging; }

    // Height of the object to be printed. This value does not contain the raft height.
    coordf_t    object_print_z_height() const { return object_print_z_max - object_print_z_min; }

    bool        valid { false };

    // Number of raft layers.
    size_t      base_raft_layers { 0 };
    // Number of interface layers including the contact layer.
    size_t      interface_raft_layers { 0 };

    // Layer heights of the raft (base, interface and a contact layer).
    coordf_t    base_raft_layer_height { 0 };
    coordf_t    interface_raft_layer_height { 0 };
    coordf_t    contact_raft_layer_height { 0 };

	// The regular layer height, applied for all but the first layer, if not overridden by layer ranges
	// or by the variable layer thickness table.
    coordf_t    layer_height { 0 };
    // Minimum / maximum layer height, to be used for the automatic adaptive layer height algorithm,
    // or by an interactive layer height editor.
    coordf_t    min_layer_height { 0 };
    coordf_t    max_layer_height { 0 };
    coordf_t    max_suport_layer_height { 0 };

    // First layer height of the print, this may be used for the first layer of the raft
    // or for the first layer of the print.
    coordf_t    first_print_layer_height { 0 };

    // Thickness of the first layer. This is either the first print layer thickness if printed without a raft,
    // or a bridging flow thickness if printed over a non-soluble raft,
    // or a normal layer height if printed over a soluble raft.
    coordf_t    first_object_layer_height { 0 };

    // If the object is printed over a non-soluble raft, the first layer may be printed with a briding flow.
    bool 		first_object_layer_bridging { false };

    // Soluble interface? (PLA soluble in water, HIPS soluble in lemonen)
    // otherwise the interface must be broken off.
    bool        soluble_interface { false };
    // Gap when placing object over raft.
    coordf_t    gap_raft_object { 0 };
    // Gap when placing support over object.
    coordf_t    gap_object_support { 0 };
    // Gap when placing object over support.
    coordf_t    gap_support_object { 0 };

    // Bottom and top of the printed object.
    // If printed without a raft, object_print_z_min = 0 and object_print_z_max = object height.
    // Otherwise object_print_z_min is equal to the raft height.
    coordf_t    raft_base_top_z { 0 };
    coordf_t    raft_interface_top_z { 0 };
    coordf_t    raft_contact_top_z { 0 };
    // In case of a soluble interface, object_print_z_min == raft_contact_top_z, otherwise there is a gap between the raft and the 1st object layer.
    coordf_t 	object_print_z_min { 0 };
    coordf_t 	object_print_z_max { 0 };
};

object_print_z_max 为模型高度,在添加模型或导入模型时,会调用PrintObject::update_slicing_parameters()函数,通过SlicingParameters::create_from_config进行赋值初始化。

2、generate_object_layers()生成对象层高数据

cpp 复制代码
std::vector<coordf_t> generate_object_layers(
	const SlicingParameters 	&slicing_params,
	const std::vector<coordf_t> &layer_height_profile,
    bool is_precise_z_height)
{
    assert(! layer_height_profile.empty());

    coordf_t print_z = 0;
    coordf_t height  = 0;

    std::vector<coordf_t> out;

    if (slicing_params.first_object_layer_height_fixed()) {
        out.push_back(0);
        print_z = slicing_params.first_object_layer_height;
        out.push_back(print_z);
    }

    size_t idx_layer_height_profile = 0;
    // loop until we have at least one layer and the max slice_z reaches the object height
    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;
        if (idx_layer_height_profile < layer_height_profile.size()) {
            size_t next = idx_layer_height_profile + 2;
            for (;;) {
                if (next >= layer_height_profile.size() || slice_z < layer_height_profile[next])
                    break;
                idx_layer_height_profile = next;
                next += 2;
            }
            coordf_t z1 = layer_height_profile[idx_layer_height_profile];
            coordf_t h1 = layer_height_profile[idx_layer_height_profile + 1];
            height = h1;
            if (next < layer_height_profile.size()) {
                coordf_t z2 = layer_height_profile[next];
                coordf_t h2 = layer_height_profile[next + 1];
                height = lerp(h1, h2, (slice_z - z1) / (z2 - z1));
                assert(height >= slicing_params.min_layer_height - EPSILON && height <= slicing_params.max_layer_height + EPSILON);
            }
        }
        slice_z = print_z + 0.5 * height;
        if (slice_z >= slicing_params.object_print_z_height())
            break;
        assert(height > slicing_params.min_layer_height - EPSILON);
        assert(height < slicing_params.max_layer_height + EPSILON);
        out.push_back(print_z);
        print_z += height;
        slice_z = print_z + 0.5 * slicing_params.min_layer_height;
        out.push_back(print_z);
    }

    if (is_precise_z_height)
        adjust_layer_series_to_align_object_height(slicing_params, out);
    return out;
}

此函数会对模型进行层高的分割。将每一层的边界数值通过std::vector<coordf_t> out进行返回。以层高为0.2毫米来说,保存的值为[0,0.2,0.2,0.4,0.4,0.6...]进行返回。

3、new_layers()创建Layer类对象

cpp 复制代码
LayerPtrs new_layers(
    PrintObject                 *print_object,
    // Object layers (pairs of bottom/top Z coordinate), without the raft.
    const std::vector<coordf_t> &object_layers)
{
    LayerPtrs out;
    out.reserve(object_layers.size());
    auto     id   = int(print_object->slicing_parameters().raft_layers());
    coordf_t zmin = print_object->slicing_parameters().object_print_z_min;
    Layer   *prev = nullptr;
    for (size_t i_layer = 0; i_layer < object_layers.size(); i_layer += 2) {
        coordf_t lo = object_layers[i_layer];
        coordf_t hi = object_layers[i_layer + 1];
        coordf_t slice_z = 0.5 * (lo + hi);
        Layer *layer = new Layer(id ++, print_object, hi - lo, hi + zmin, slice_z);
        out.emplace_back(layer);
        if (prev != nullptr) {
            prev->upper_layer = layer;
            layer->lower_layer = prev;
        }
        prev = layer;
    }
    return out;
}

4、Layer 切片层类

cpp 复制代码
class Layer
{
public:
    // Sequential index of this layer in PrintObject::m_layers, offsetted by the number of raft layers.
    size_t              id() const          { return m_id; }
    void                set_id(size_t id)   { m_id = id; }
    PrintObject*        object()            { return m_object; }
    const PrintObject*  object() const      { return m_object; }

    Layer              *upper_layer;
    Layer              *lower_layer;
    bool                slicing_errors;
    coordf_t            slice_z;       // Z used for slicing in unscaled coordinates
    coordf_t            print_z;       // Z used for printing in unscaled coordinates
    coordf_t            height;        // layer height in unscaled coordinates
    coordf_t            bottom_z() const { return this->print_z - this->height; }

    // BBS
    mutable ExPolygons          sharp_tails;
    mutable ExPolygons          cantilevers;
    mutable std::vector<float>  sharp_tails_height;

    // Collection of expolygons generated by slicing the possibly multiple meshes of the source geometry
    // (with possibly differing extruder ID and slicing parameters) and merged.
    // For the first layer, if the Elephant foot compensation is applied, this lslice is uncompensated, therefore
    // it includes the Elephant foot effect, thus it corresponds to the shape of the printed 1st layer.
    // These lslices aka islands are chained by the shortest traverse distance and this traversal
    // order will be applied by the G-code generator to the extrusions fitting into these lslices.
    // These lslices are also used to detect overhangs and overlaps between successive layers, therefore it is important
    // that the 1st lslice is not compensated by the Elephant foot compensation algorithm.
    ExPolygons 				 lslices;
    ExPolygons 				 lslices_extrudable;  // BBS: the extrudable part of lslices used for tree support
    std::vector<BoundingBox> lslices_bboxes;

    // BBS
    ExPolygons              loverhangs;
    std::vector<std::pair<ExPolygon, int>> loverhangs_with_type;
    BoundingBox             loverhangs_bbox;
    std::vector<LoopNode>   loop_nodes;
    size_t                  region_count() const { return m_regions.size(); }
    const LayerRegion*      get_region(int idx) const { return m_regions[idx]; }
    LayerRegion*            get_region(int idx) { return m_regions[idx]; }
    LayerRegion*            add_region(const PrintRegion *print_region);
    const LayerRegionPtrs&  regions() const { return m_regions; }
    // Test whether whether there are any slices assigned to this layer.
    bool                    empty() const;
    void                    apply_auto_circle_compensation();
    void                    make_slices();
    // Backup and restore raw sliced regions if needed.
    //FIXME Review whether not to simplify the code by keeping the raw_slices all the time.
    void                    backup_untyped_slices();
    void                    restore_untyped_slices();
    // To improve robustness of detect_surfaces_type() when reslicing (working with typed slices), see GH issue #7442.
    void                    restore_untyped_slices_no_extra_perimeters();
    // Slices merged into islands, to be used by the elephant foot compensation to trim the individual surfaces with the shrunk merged slices.
    ExPolygons              merged(float offset) const;
    template <class T> bool any_internal_region_slice_contains(const T &item) const {
        for (const LayerRegion *layerm : m_regions) if (layerm->slices.any_internal_contains(item)) return true;
        return false;
    }
    template <class T> bool any_bottom_region_slice_contains(const T &item) const {
        for (const LayerRegion *layerm : m_regions) if (layerm->slices.any_bottom_contains(item)) return true;
        return false;
    }
    void                    make_perimeters();
    //BBS
    void                    calculate_perimeter_continuity(std::vector<LoopNode> &prev_nodes);
    void                    recrod_cooling_node_for_each_extrusion();
    // Phony version of make_fills() without parameters for Perl integration only.
    void                    make_fills() { this->make_fills(nullptr, nullptr); }
    void                    make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive::Octree* support_fill_octree, FillLightning::Generator* lightning_generator = nullptr);
    Polylines               generate_sparse_infill_polylines_for_anchoring(FillAdaptive::Octree *adaptive_fill_octree,
        FillAdaptive::Octree *support_fill_octree,
        FillLightning::Generator* lightning_generator) const;

    void 					make_ironing();

    void                    export_region_slices_to_svg(const char *path) const;
    void                    export_region_fill_surfaces_to_svg(const char *path) const;
    // Export to "out/LayerRegion-name-%d.svg" with an increasing index with every export.
    void                    export_region_slices_to_svg_debug(const char *name) const;
    void                    export_region_fill_surfaces_to_svg_debug(const char *name) const;

    // Is there any valid extrusion assigned to this LayerRegion?
    virtual bool            has_extrusions() const { for (auto layerm : m_regions) if (layerm->has_extrusions()) return true; return false; }

    //BBS
    void simplify_wall_extrusion_path() { for (auto layerm : m_regions) layerm->simplify_wall_extrusion_entity();}
    void simplify_infill_extrusion_path() { for (auto layerm : m_regions) layerm->simplify_infill_extrusion_entity(); }
    //BBS: this function calculate the maximum void grid area of sparse infill of this layer. Just estimated value
    coordf_t get_sparse_infill_max_void_area();

    // FN_HIGHER_EQUAL: the provided object pointer has a Z value >= of an internal threshold.
    // Find the first item with Z value >= of an internal threshold of fn_higher_equal.
    // If no vec item with Z value >= of an internal threshold of fn_higher_equal is found, return vec.size()
    // If the initial idx is size_t(-1), then use binary search.
    // Otherwise search linearly upwards.
    template<typename IteratorType, typename IndexType, typename FN_HIGHER_EQUAL>
    static IndexType idx_higher_or_equal(IteratorType begin, IteratorType end, IndexType idx, FN_HIGHER_EQUAL fn_higher_equal)
    {
        auto size = int(end - begin);
        if (size == 0) {
            idx = 0;
            }
        else if (idx == IndexType(-1)) {
            // First of the batch of layers per thread pool invocation. Use binary search.
            int idx_low = 0;
            int idx_high = std::max(0, size - 1);
            while (idx_low + 1 < idx_high) {
                int idx_mid = (idx_low + idx_high) / 2;
                if (fn_higher_equal(begin[idx_mid]))
                    idx_high = idx_mid;
                else
                    idx_low = idx_mid;
                }
            idx = fn_higher_equal(begin[idx_low]) ? idx_low :
                (fn_higher_equal(begin[idx_high]) ? idx_high : size);
            }
        else {
            // For the other layers of this batch of layers, search incrementally, which is cheaper than the binary search.
            while (int(idx) < size && !fn_higher_equal(begin[idx]))
                ++idx;
            }
        return idx;
    }

    size_t get_extruder_id(unsigned int filament_id) const;

protected:
    friend class PrintObject;
    friend std::vector<Layer*> new_layers(PrintObject*, const std::vector<coordf_t>&);
    friend std::string fix_slicing_errors(PrintObject* object, LayerPtrs&, const std::function<void()>&, int &);

    Layer(size_t id, PrintObject *object, coordf_t height, coordf_t print_z, coordf_t slice_z) :
        upper_layer(nullptr), lower_layer(nullptr), slicing_errors(false),
        slice_z(slice_z), print_z(print_z), height(height),
        m_id(id), m_object(object) {}
    virtual ~Layer();

//BBS: method to simplify support path
    void    simplify_support_entity_collection(ExtrusionEntityCollection* entity_collection);
    void    simplify_support_path(ExtrusionPath* path);
    void    simplify_support_multi_path(ExtrusionMultiPath* multipath);
    void    simplify_support_loop(ExtrusionLoop* loop);

private:
    // Sequential index of layer, 0-based, offsetted by number of raft layers.
    size_t              m_id;
    PrintObject        *m_object;
    LayerRegionPtrs     m_regions;
};

成员变量:

m_id:从0开始计数,进行累加。

height:层高

print_z:开始打印的z坐标

slice_z:切片的z坐标,层最高最低边界位置的中间值

通过new_layers得到的指针数组,保存在PrintObject::m_layers中

相关推荐
无限进步_36 分钟前
C语言双向循环链表实现详解:哨兵位与循环结构
c语言·开发语言·数据结构·c++·后端·算法·链表
罗湖老棍子1 小时前
宠物小精灵之收服(信息学奥赛一本通- P1292)
算法·动态规划·01背包
LDG_AGI1 小时前
【推荐系统】深度学习训练框架(十四):特征映射——Murmur哈希:高效“无状态”转换
人工智能·深度学习·算法·机器学习·哈希算法·推荐算法
Jing_Rainbow1 小时前
【LeetCode Hot 100 刷题日记(22/100)】160. 相交链表——链表、双指针、哈希表📌
算法·面试·程序员
兩尛1 小时前
HJ98 喜欢切数组的红(dp
算法
adam_life1 小时前
【P4551 最长异或路径】
算法·bfs·01字典树
CoovallyAIHub1 小时前
2025年值得关注的5款数据标注工具
深度学习·算法·计算机视觉
FuckPatience1 小时前
C# 补码
开发语言·算法·c#
稚辉君.MCA_P8_Java1 小时前
Gemini永久会员 VB返回最长有效子串长度
数据结构·后端·算法