#ifndef FILAMENT_GROUP_HPP #define FILAMENT_GROUP_HPP #include #include #include #include #include #include #include #include "GCode/ToolOrderUtils.hpp" const static int DEFAULT_CLUSTER_SIZE = 16; const static int ABSOLUTE_FLUSH_GAP_TOLERANCE = 2000; namespace Slic3r { std::vectorcollect_sorted_used_filaments(const std::vector>& layer_filaments); enum FGStrategy { BestCost, BestFit }; struct Color { unsigned char r = 0; unsigned char g = 0; unsigned char b = 0; unsigned char a = 255; Color(unsigned char r_ = 0, unsigned char g_ = 0, unsigned char b_ = 0, unsigned a_ = 255) :r(r_), g(g_), b(b_), a(a_) {} Color(const std::string& hexstr); }; std::vector select_best_group_for_ams(const std::vector>& map_lists, const std::vector& used_filaments, const std::vector& used_filament_colors, const std::vector>& ams_filament_colros); namespace FilamentGroupUtils { struct FlushTimeMachine { private: std::chrono::high_resolution_clock::time_point start; public: void time_machine_start() { start = std::chrono::high_resolution_clock::now(); } int time_machine_end() { auto end = std::chrono::high_resolution_clock::now(); auto duration = std::chrono::duration_cast(end - start); return duration.count(); } }; struct MemoryedGroup { int cost{ 0 }; int prefer_level{ 0 }; std::vectorgroup; bool operator>(const MemoryedGroup& other) const { return prefer_level < other.prefer_level || (prefer_level == other.prefer_level && cost > other.cost); } }; using MemoryedGroupHeap = std::priority_queue, std::greater>; void update_memoryed_groups(const MemoryedGroup& item,const double gap_threshold, MemoryedGroupHeap& groups); } struct FilamentGroupContext { std::vector flush_matrix; std::vector>physical_unprintables; std::vector>geometric_unprintables; std::vectormax_group_size; int total_filament_num; }; class FlushDistanceEvaluator { public: FlushDistanceEvaluator(const FlushMatrix& flush_matrix,const std::vector&used_filaments,const std::vector>& layer_filaments, double p = 0.65); ~FlushDistanceEvaluator() = default; double get_distance(int idx_a, int idx_b) const; private: std::vector>m_distance_matrix; }; class FilamentGroup { using MemoryedGroupHeap = FilamentGroupUtils::MemoryedGroupHeap; using MemoryedGroup = FilamentGroupUtils::MemoryedGroup; public: FilamentGroup(const FilamentGroupContext& context); std::vector calc_filament_group(const std::vector>& layer_filaments, const FGStrategy& g_strategy = FGStrategy::BestFit, int* cost = nullptr); public: std::vector calc_filament_group_by_enum(const std::vector>& layer_filaments, const std::vector& used_filaments, const FGStrategy& g_strategy, int* cost = nullptr); std::vector calc_filament_group_by_pam2(const std::vector>& layer_filaments, const std::vector& used_filaments, const FGStrategy& g_strategy, int* cost = nullptr, int timeout_ms = 300); void set_memory_threshold(double threshold) { memory_threshold = threshold; } std::vector> get_memoryed_groups()const { return m_memoryed_groups; } private: FilamentGroupContext m_context; double memory_threshold{ 0 }; std::vector> m_memoryed_groups; public: std::optional&)>> get_custom_seq; }; class KMediods2 { using MemoryedGroupHeap = FilamentGroupUtils::MemoryedGroupHeap; using MemoryedGroup = FilamentGroupUtils::MemoryedGroup; enum INIT_TYPE { Random = 0, Farthest }; public: KMediods2(const int elem_count, const std::shared_ptr& evaluator) : m_evaluator{ evaluator }, m_elem_count{ elem_count } { m_max_cluster_size = std::vector(m_k, DEFAULT_CLUSTER_SIZE); } // set max group size void set_max_cluster_size(const std::vector& group_size) { m_max_cluster_size = group_size; } // key stores elem idx, value stores the cluster id that elem cnanot be placed void set_unplaceable_limits(const std::map& placeable_limits) { m_unplaceable_limits = placeable_limits; } void do_clustering(const FGStrategy& g_strategy,int timeout_ms = 100); void set_memory_threshold(double threshold) { memory_threshold; } MemoryedGroupHeap get_memoryed_groups()const { return memoryed_groups; } std::vectorget_cluster_labels()const { return m_cluster_labels; } private: std::vectorcluster_small_data(const std::map& unplaceable_limits, const std::vector& group_size); std::vectorassign_cluster_label(const std::vector& center, const std::map& unplaceable_limits, const std::vector& group_size, const FGStrategy& strategy); int calc_cost(const std::vector& labels, const std::vector& medoids); private: std::shared_ptr m_evaluator; std::mapm_unplaceable_limits; std::vectorm_max_cluster_size; int m_elem_count; const int m_k = 2; double memory_threshold{ 0 }; FilamentGroupUtils::MemoryedGroupHeap memoryed_groups; std::vectorm_cluster_labels; }; } #endif // !FILAMENT_GROUP_HPP