diff --git a/src/libslic3r/Config.hpp b/src/libslic3r/Config.hpp index c49c492a3f..adda2654ed 100644 --- a/src/libslic3r/Config.hpp +++ b/src/libslic3r/Config.hpp @@ -1390,22 +1390,7 @@ public: } // Map from an enum name to an enum integer value. - static const t_config_enum_names& get_enum_names() - { - static t_config_enum_names names; - if (names.empty()) { - // Initialize the map. - const t_config_enum_values &enum_keys_map = ConfigOptionEnum::get_enum_values(); - int cnt = 0; - for (const auto& kvp : enum_keys_map) - cnt = std::max(cnt, kvp.second); - cnt += 1; - names.assign(cnt, ""); - for (const auto& kvp : enum_keys_map) - names[kvp.second] = kvp.first; - } - return names; - } + static const t_config_enum_names& get_enum_names(); // Map from an enum name to an enum integer value. static const t_config_enum_values& get_enum_values(); diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index f2c5f70a97..0044d91fd8 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -18,6 +19,152 @@ namespace Slic3r { #define L(s) (s) #define _(s) Slic3r::I18N::translate(s) +static t_config_enum_names enum_names_from_keys_map(const t_config_enum_values &enum_keys_map) +{ + t_config_enum_names names; + int cnt = 0; + for (const auto& kvp : enum_keys_map) + cnt = std::max(cnt, kvp.second); + cnt += 1; + names.assign(cnt, ""); + for (const auto& kvp : enum_keys_map) + names[kvp.second] = kvp.first; + return names; +} + +#define CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(NAME) \ + static t_config_enum_names s_keys_names_##NAME = enum_names_from_keys_map(s_keys_map_##NAME); \ + template<> const t_config_enum_values& ConfigOptionEnum::get_enum_values() { return s_keys_map_##NAME; } \ + template<> const t_config_enum_names& ConfigOptionEnum::get_enum_names() { return s_keys_names_##NAME; } + +static t_config_enum_values s_keys_map_PrinterTechnology { + { "FFF", ptFFF }, + { "SLA", ptSLA } +}; +CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(PrinterTechnology) + +static t_config_enum_values s_keys_map_GCodeFlavor { + { "reprap", gcfRepRapSprinter }, + { "reprapfirmware", gcfRepRapFirmware }, + { "repetier", gcfRepetier }, + { "teacup", gcfTeacup }, + { "makerware", gcfMakerWare }, + { "marlin", gcfMarlinLegacy }, + { "marlinfirmware", gcfMarlinFirmware }, + { "sailfish", gcfSailfish }, + { "smoothie", gcfSmoothie }, + { "mach3", gcfMach3 }, + { "machinekit", gcfMachinekit }, + { "no-extrusion", gcfNoExtrusion } +}; +CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(GCodeFlavor) + +static t_config_enum_values s_keys_map_MachineLimitsUsage { + { "emit_to_gcode", int(MachineLimitsUsage::EmitToGCode) }, + { "time_estimate_only", int(MachineLimitsUsage::TimeEstimateOnly) }, + { "ignore", int(MachineLimitsUsage::Ignore) } +}; +CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(MachineLimitsUsage) + +static t_config_enum_values s_keys_map_PrintHostType { + { "octoprint", htOctoPrint }, + { "duet", htDuet }, + { "flashair", htFlashAir }, + { "astrobox", htAstroBox }, + { "repetier", htRepetier } +}; +CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(PrintHostType) + +static t_config_enum_values s_keys_map_AuthorizationType { + { "key", atKeyPassword }, + { "user", atUserPassword } +}; +CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(AuthorizationType) + +static t_config_enum_values s_keys_map_FuzzySkinType { + { "none", int(FuzzySkinType::None) }, + { "external", int(FuzzySkinType::External) }, + { "all", int(FuzzySkinType::All) } +}; +CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(FuzzySkinType) + +static t_config_enum_values s_keys_map_InfillPattern { + { "rectilinear", ipRectilinear }, + { "monotonic", ipMonotonic }, + { "alignedrectilinear", ipAlignedRectilinear }, + { "grid", ipGrid }, + { "triangles", ipTriangles }, + { "stars", ipStars }, + { "cubic", ipCubic }, + { "line", ipLine }, + { "concentric", ipConcentric }, + { "honeycomb", ipHoneycomb }, + { "3dhoneycomb", ip3DHoneycomb }, + { "gyroid", ipGyroid }, + { "hilbertcurve", ipHilbertCurve }, + { "archimedeanchords", ipArchimedeanChords }, + { "octagramspiral", ipOctagramSpiral }, + { "adaptivecubic", ipAdaptiveCubic }, + { "supportcubic", ipSupportCubic } +}; +CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(InfillPattern) + +static t_config_enum_values s_keys_map_IroningType { + { "top", int(IroningType::TopSurfaces) }, + { "topmost", int(IroningType::TopmostOnly) }, + { "solid", int(IroningType::AllSolid) } +}; +CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(IroningType) + +static t_config_enum_values s_keys_map_SupportMaterialPattern { + { "rectilinear", smpRectilinear }, + { "rectilinear-grid", smpRectilinearGrid }, + { "honeycomb", smpHoneycomb } +}; +CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(SupportMaterialPattern) + +static t_config_enum_values s_keys_map_SupportMaterialStyle { + { "grid", smsGrid }, + { "snug", smsSnug } +}; +CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(SupportMaterialStyle) + +static t_config_enum_values s_keys_map_SupportMaterialInterfacePattern { + { "auto", smipAuto }, + { "rectilinear", smipRectilinear }, + { "concentric", smipConcentric } +}; +CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(SupportMaterialInterfacePattern) + +static t_config_enum_values s_keys_map_SeamPosition { + { "random", spRandom }, + { "nearest", spNearest }, + { "aligned", spAligned }, + { "rear", spRear } +}; +CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(SeamPosition) + +static const t_config_enum_values s_keys_map_SLADisplayOrientation = { + { "landscape", sladoLandscape}, + { "portrait", sladoPortrait} +}; +CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(SLADisplayOrientation) + +static const t_config_enum_values s_keys_map_SLAPillarConnectionMode = { + {"zigzag", slapcmZigZag}, + {"cross", slapcmCross}, + {"dynamic", slapcmDynamic} +}; +CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(SLAPillarConnectionMode) + +static const t_config_enum_values s_keys_map_BrimType = { + {"no_brim", btNoBrim}, + {"outer_only", btOuterOnly}, + {"inner_only", btInnerOnly}, + {"outer_and_inner", btOuterAndInner} +}; +CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(BrimType) + static void assign_printer_technology_to_unknown(t_optiondef_map &options, PrinterTechnology printer_technology) { for (std::pair &kvp : options) @@ -3790,19 +3937,21 @@ std::string validate(const FullPrintConfig &cfg) return ""; } -// Declare the static caches for each StaticPrintConfig derived class. -StaticPrintConfig::StaticCache PrintObjectConfig::s_cache_PrintObjectConfig; -StaticPrintConfig::StaticCache PrintRegionConfig::s_cache_PrintRegionConfig; -StaticPrintConfig::StaticCache MachineEnvelopeConfig::s_cache_MachineEnvelopeConfig; -StaticPrintConfig::StaticCache GCodeConfig::s_cache_GCodeConfig; -StaticPrintConfig::StaticCache PrintConfig::s_cache_PrintConfig; -StaticPrintConfig::StaticCache FullPrintConfig::s_cache_FullPrintConfig; - -StaticPrintConfig::StaticCache SLAMaterialConfig::s_cache_SLAMaterialConfig; -StaticPrintConfig::StaticCache SLAPrintConfig::s_cache_SLAPrintConfig; -StaticPrintConfig::StaticCache SLAPrintObjectConfig::s_cache_SLAPrintObjectConfig; -StaticPrintConfig::StaticCache SLAPrinterConfig::s_cache_SLAPrinterConfig; -StaticPrintConfig::StaticCache SLAFullPrintConfig::s_cache_SLAFullPrintConfig; +// Declare and initialize static caches of StaticPrintConfig derived classes. +#define PRINT_CONFIG_CACHE_ELEMENT_DEFINITION(r, data, CLASS_NAME) StaticPrintConfig::StaticCache BOOST_PP_CAT(CLASS_NAME::s_cache_, CLASS_NAME); +#define PRINT_CONFIG_CACHE_ELEMENT_INITIALIZATION(r, data, CLASS_NAME) Slic3r::CLASS_NAME::initialize_cache(); +#define PRINT_CONFIG_CACHE_INITIALIZE(CLASSES_SEQ) \ + BOOST_PP_SEQ_FOR_EACH(PRINT_CONFIG_CACHE_ELEMENT_DEFINITION, _, BOOST_PP_TUPLE_TO_SEQ(CLASSES_SEQ)) \ + static int print_config_static_initializer() { \ + /* Putting a trace here to avoid the compiler to optimize out this function. */ \ + BOOST_LOG_TRIVIAL(trace) << "Initializing StaticPrintConfigs"; \ + BOOST_PP_SEQ_FOR_EACH(PRINT_CONFIG_CACHE_ELEMENT_INITIALIZATION, _, BOOST_PP_TUPLE_TO_SEQ(CLASSES_SEQ)) \ + return 1; \ + } +PRINT_CONFIG_CACHE_INITIALIZE(( + PrintObjectConfig, PrintRegionConfig, MachineEnvelopeConfig, GCodeConfig, PrintConfig, FullPrintConfig, + SLAMaterialConfig, SLAPrintConfig, SLAPrintObjectConfig, SLAPrinterConfig, SLAFullPrintConfig)) +static int print_config_static_initialized = print_config_static_initializer(); CLIActionsConfigDef::CLIActionsConfigDef() { diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index 7209bea899..2ba6d4cbd5 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -111,178 +111,27 @@ enum BrimType { btOuterAndInner, }; -template<> inline const t_config_enum_values& ConfigOptionEnum::get_enum_values() { - static t_config_enum_values keys_map; - if (keys_map.empty()) { - keys_map["FFF"] = ptFFF; - keys_map["SLA"] = ptSLA; - } - return keys_map; -} +#define CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(NAME) \ + template<> const t_config_enum_names& ConfigOptionEnum::get_enum_names(); \ + template<> const t_config_enum_values& ConfigOptionEnum::get_enum_values(); -template<> inline const t_config_enum_values& ConfigOptionEnum::get_enum_values() { - static t_config_enum_values keys_map; - if (keys_map.empty()) { - keys_map["reprap"] = gcfRepRapSprinter; - keys_map["reprapfirmware"] = gcfRepRapFirmware; - keys_map["repetier"] = gcfRepetier; - keys_map["teacup"] = gcfTeacup; - keys_map["makerware"] = gcfMakerWare; - keys_map["marlin"] = gcfMarlinLegacy; - keys_map["marlinfirmware"] = gcfMarlinFirmware; - keys_map["sailfish"] = gcfSailfish; - keys_map["smoothie"] = gcfSmoothie; - keys_map["mach3"] = gcfMach3; - keys_map["machinekit"] = gcfMachinekit; - keys_map["no-extrusion"] = gcfNoExtrusion; - } - return keys_map; -} +CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(PrinterTechnology) +CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(GCodeFlavor) +CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(MachineLimitsUsage) +CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(PrintHostType) +CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(AuthorizationType) +CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(FuzzySkinType) +CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(InfillPattern) +CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(IroningType) +CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(SupportMaterialPattern) +CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(SupportMaterialStyle) +CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(SupportMaterialInterfacePattern) +CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(SeamPosition) +CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(SLADisplayOrientation) +CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(SLAPillarConnectionMode) +CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(BrimType) -template<> inline const t_config_enum_values& ConfigOptionEnum::get_enum_values() { - static t_config_enum_values keys_map; - if (keys_map.empty()) { - keys_map["emit_to_gcode"] = int(MachineLimitsUsage::EmitToGCode); - keys_map["time_estimate_only"] = int(MachineLimitsUsage::TimeEstimateOnly); - keys_map["ignore"] = int(MachineLimitsUsage::Ignore); - } - return keys_map; -} - -template<> inline const t_config_enum_values& ConfigOptionEnum::get_enum_values() { - static t_config_enum_values keys_map; - if (keys_map.empty()) { - keys_map["octoprint"] = htOctoPrint; - keys_map["duet"] = htDuet; - keys_map["flashair"] = htFlashAir; - keys_map["astrobox"] = htAstroBox; - keys_map["repetier"] = htRepetier; - } - return keys_map; -} - -template<> inline const t_config_enum_values& ConfigOptionEnum::get_enum_values() { - static t_config_enum_values keys_map; - if (keys_map.empty()) { - keys_map["key"] = atKeyPassword; - keys_map["user"] = atUserPassword; - } - return keys_map; -} - -template<> inline const t_config_enum_values& ConfigOptionEnum::get_enum_values() { - static t_config_enum_values keys_map; - if (keys_map.empty()) { - keys_map["none"] = int(FuzzySkinType::None); - keys_map["external"] = int(FuzzySkinType::External); - keys_map["all"] = int(FuzzySkinType::All); - } - return keys_map; -} - -template<> inline const t_config_enum_values& ConfigOptionEnum::get_enum_values() { - static t_config_enum_values keys_map; - if (keys_map.empty()) { - keys_map["rectilinear"] = ipRectilinear; - keys_map["monotonic"] = ipMonotonic; - keys_map["alignedrectilinear"] = ipAlignedRectilinear; - keys_map["grid"] = ipGrid; - keys_map["triangles"] = ipTriangles; - keys_map["stars"] = ipStars; - keys_map["cubic"] = ipCubic; - keys_map["line"] = ipLine; - keys_map["concentric"] = ipConcentric; - keys_map["honeycomb"] = ipHoneycomb; - keys_map["3dhoneycomb"] = ip3DHoneycomb; - keys_map["gyroid"] = ipGyroid; - keys_map["hilbertcurve"] = ipHilbertCurve; - keys_map["archimedeanchords"] = ipArchimedeanChords; - keys_map["octagramspiral"] = ipOctagramSpiral; - keys_map["adaptivecubic"] = ipAdaptiveCubic; - keys_map["supportcubic"] = ipSupportCubic; - } - return keys_map; -} - -template<> inline const t_config_enum_values& ConfigOptionEnum::get_enum_values() { - static t_config_enum_values keys_map; - if (keys_map.empty()) { - keys_map["top"] = int(IroningType::TopSurfaces); - keys_map["topmost"] = int(IroningType::TopmostOnly); - keys_map["solid"] = int(IroningType::AllSolid); - } - return keys_map; -} - -template<> inline const t_config_enum_values& ConfigOptionEnum::get_enum_values() { - static t_config_enum_values keys_map; - if (keys_map.empty()) { - keys_map["rectilinear"] = smpRectilinear; - keys_map["rectilinear-grid"] = smpRectilinearGrid; - keys_map["honeycomb"] = smpHoneycomb; - } - return keys_map; -} - -template<> inline const t_config_enum_values& ConfigOptionEnum::get_enum_values() { - static t_config_enum_values keys_map; - if (keys_map.empty()) { - keys_map["grid"] = smsGrid; - keys_map["snug"] = smsSnug; - } - return keys_map; -} - -template<> inline const t_config_enum_values& ConfigOptionEnum::get_enum_values() { - static t_config_enum_values keys_map; - if (keys_map.empty()) { - keys_map["auto"] = smipAuto; - keys_map["rectilinear"] = smipRectilinear; - keys_map["concentric"] = smipConcentric; - } - return keys_map; -} - -template<> inline const t_config_enum_values& ConfigOptionEnum::get_enum_values() { - static t_config_enum_values keys_map; - if (keys_map.empty()) { - keys_map["random"] = spRandom; - keys_map["nearest"] = spNearest; - keys_map["aligned"] = spAligned; - keys_map["rear"] = spRear; - } - return keys_map; -} - -template<> inline const t_config_enum_values& ConfigOptionEnum::get_enum_values() { - static const t_config_enum_values keys_map = { - { "landscape", sladoLandscape}, - { "portrait", sladoPortrait} - }; - - return keys_map; -} - -template<> inline const t_config_enum_values& ConfigOptionEnum::get_enum_values() { - static const t_config_enum_values keys_map = { - {"zigzag", slapcmZigZag}, - {"cross", slapcmCross}, - {"dynamic", slapcmDynamic} - }; - - return keys_map; -} - -template<> inline const t_config_enum_values& ConfigOptionEnum::get_enum_values() { - static const t_config_enum_values keys_map = { - {"no_brim", btNoBrim}, - {"outer_only", btOuterOnly}, - {"inner_only", btInnerOnly}, - {"outer_and_inner", btOuterAndInner} - }; - - return keys_map; -} +#undef CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS // Defines each and every confiuration option of Slic3r, including the properties of the GUI dialogs. // Does not store the actual values, but defines default values. @@ -459,10 +308,12 @@ public: \ /* Overrides ConfigBase::keys(). Collect names of all configuration values maintained by this configuration store. */ \ t_config_option_keys keys() const override { return s_cache_##CLASS_NAME.keys(); } \ const t_config_option_keys& keys_ref() const override { return s_cache_##CLASS_NAME.keys(); } \ - static const CLASS_NAME& defaults() { initialize_cache(); return s_cache_##CLASS_NAME.defaults(); } \ + static const CLASS_NAME& defaults() { assert(s_cache_##CLASS_NAME.initialized()); return s_cache_##CLASS_NAME.defaults(); } \ private: \ + friend int print_config_static_initializer(); \ static void initialize_cache() \ { \ + assert(! s_cache_##CLASS_NAME.initialized()); \ if (! s_cache_##CLASS_NAME.initialized()) { \ CLASS_NAME *inst = new CLASS_NAME(1); \ inst->initialize(s_cache_##CLASS_NAME, (const char*)inst); \ @@ -476,7 +327,7 @@ private: \ STATIC_PRINT_CONFIG_CACHE_BASE(CLASS_NAME) \ public: \ /* Public default constructor will initialize the key/option cache and the default object copy if needed. */ \ - CLASS_NAME() { initialize_cache(); *this = s_cache_##CLASS_NAME.defaults(); } \ + CLASS_NAME() { assert(s_cache_##CLASS_NAME.initialized()); *this = s_cache_##CLASS_NAME.defaults(); } \ protected: \ /* Protected constructor to be called when compounded. */ \ CLASS_NAME(int) {} @@ -534,7 +385,7 @@ protected: \ #define PRINT_CONFIG_CLASS_DERIVED_DEFINE1(CLASS_NAME, CLASSES_PARENTS_TUPLE, PARAMETER_DEFINITION, PARAMETER_REGISTRATION, PARAMETER_HASHES, PARAMETER_EQUALS) \ class CLASS_NAME : PRINT_CONFIG_CLASS_DERIVED_CLASS_LIST(CLASSES_PARENTS_TUPLE) { \ STATIC_PRINT_CONFIG_CACHE_DERIVED(CLASS_NAME) \ - CLASS_NAME() : PRINT_CONFIG_CLASS_DERIVED_INITIALIZER(CLASSES_PARENTS_TUPLE, 0) { initialize_cache(); *this = s_cache_##CLASS_NAME.defaults(); } \ + CLASS_NAME() : PRINT_CONFIG_CLASS_DERIVED_INITIALIZER(CLASSES_PARENTS_TUPLE, 0) { assert(s_cache_##CLASS_NAME.initialized()); *this = s_cache_##CLASS_NAME.defaults(); } \ public: \ PARAMETER_DEFINITION \ size_t hash() const throw() \