mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-11-02 20:51:23 -07:00 
			
		
		
		
	Merge branch 'master' of https://github.com/prusa3d/PrusaSlicer
This commit is contained in:
		
						commit
						070ee5308c
					
				
					 4 changed files with 53 additions and 8 deletions
				
			
		| 
						 | 
				
			
			@ -1340,7 +1340,7 @@ void GCode::_do_export(Print& print, FILE* file, ThumbnailsGeneratorCallback thu
 | 
			
		|||
std::string GCode::placeholder_parser_process(const std::string &name, const std::string &templ, unsigned int current_extruder_id, const DynamicConfig *config_override)
 | 
			
		||||
{
 | 
			
		||||
    try {
 | 
			
		||||
        return m_placeholder_parser.process(templ, current_extruder_id, config_override);
 | 
			
		||||
        return m_placeholder_parser.process(templ, current_extruder_id, config_override, &m_placeholder_parser_context);
 | 
			
		||||
    } catch (std::runtime_error &err) {
 | 
			
		||||
        // Collect the names of failed template substitutions for error reporting.
 | 
			
		||||
        auto it = m_placeholder_parser_failed_templates.find(name);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -300,6 +300,8 @@ private:
 | 
			
		|||
    FullPrintConfig                     m_config;
 | 
			
		||||
    GCodeWriter                         m_writer;
 | 
			
		||||
    PlaceholderParser                   m_placeholder_parser;
 | 
			
		||||
    // For random number generator etc.
 | 
			
		||||
    PlaceholderParser::ContextData      m_placeholder_parser_context;
 | 
			
		||||
    // Collection of templates, on which the placeholder substitution failed.
 | 
			
		||||
    std::map<std::string, std::string>  m_placeholder_parser_failed_templates;
 | 
			
		||||
    OozePrevention                      m_ooze_prevention;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,7 +6,6 @@
 | 
			
		|||
#include <iomanip>
 | 
			
		||||
#include <sstream>
 | 
			
		||||
#include <map>
 | 
			
		||||
#include <boost/nowide/convert.hpp>
 | 
			
		||||
#ifdef _MSC_VER
 | 
			
		||||
    #include <stdlib.h>  // provides **_environ
 | 
			
		||||
#else
 | 
			
		||||
| 
						 | 
				
			
			@ -26,6 +25,7 @@
 | 
			
		|||
#endif
 | 
			
		||||
 | 
			
		||||
#include <boost/algorithm/string.hpp>
 | 
			
		||||
#include <boost/nowide/convert.hpp>
 | 
			
		||||
 | 
			
		||||
// Spirit v2.5 allows you to suppress automatic generation
 | 
			
		||||
// of predefined terminals to speed up complation. With
 | 
			
		||||
| 
						 | 
				
			
			@ -496,6 +496,12 @@ namespace client
 | 
			
		|||
        static void leq      (expr &lhs, expr &rhs) { compare_op(lhs, rhs, '>', true ); }
 | 
			
		||||
        static void geq      (expr &lhs, expr &rhs) { compare_op(lhs, rhs, '<', true ); }
 | 
			
		||||
 | 
			
		||||
        static void throw_if_not_numeric(const expr ¶m)
 | 
			
		||||
        {
 | 
			
		||||
            const char *err_msg = "Not a numeric type.";
 | 
			
		||||
            param.throw_if_not_numeric(err_msg);            
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        enum Function2ParamsType {
 | 
			
		||||
            FUNCTION_MIN,
 | 
			
		||||
            FUNCTION_MAX,
 | 
			
		||||
| 
						 | 
				
			
			@ -503,9 +509,8 @@ namespace client
 | 
			
		|||
        // Store the result into param1.
 | 
			
		||||
        static void function_2params(expr ¶m1, expr ¶m2, Function2ParamsType fun)
 | 
			
		||||
        { 
 | 
			
		||||
            const char *err_msg = "Not a numeric type.";
 | 
			
		||||
            param1.throw_if_not_numeric(err_msg);
 | 
			
		||||
            param2.throw_if_not_numeric(err_msg);
 | 
			
		||||
            throw_if_not_numeric(param1);
 | 
			
		||||
            throw_if_not_numeric(param2);
 | 
			
		||||
            if (param1.type == TYPE_DOUBLE || param2.type == TYPE_DOUBLE) {
 | 
			
		||||
                double d = 0.;
 | 
			
		||||
                switch (fun) {
 | 
			
		||||
| 
						 | 
				
			
			@ -530,6 +535,20 @@ namespace client
 | 
			
		|||
        static void min(expr ¶m1, expr ¶m2) { function_2params(param1, param2, FUNCTION_MIN); }
 | 
			
		||||
        static void max(expr ¶m1, expr ¶m2) { function_2params(param1, param2, FUNCTION_MAX); }
 | 
			
		||||
 | 
			
		||||
        // Store the result into param1.
 | 
			
		||||
        static void random(expr ¶m1, expr ¶m2, std::mt19937 &rng)
 | 
			
		||||
        { 
 | 
			
		||||
            throw_if_not_numeric(param1);
 | 
			
		||||
            throw_if_not_numeric(param2);
 | 
			
		||||
            if (param1.type == TYPE_DOUBLE || param2.type == TYPE_DOUBLE) {
 | 
			
		||||
                param1.data.d = std::uniform_real_distribution<>(param1.as_d(), param2.as_d())(rng);
 | 
			
		||||
                param1.type   = TYPE_DOUBLE;
 | 
			
		||||
            } else {
 | 
			
		||||
                param1.data.i = std::uniform_int_distribution<>(param1.as_i(), param2.as_i())(rng);
 | 
			
		||||
                param1.type   = TYPE_INT;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        static void regex_op(expr &lhs, boost::iterator_range<Iterator> &rhs, char op)
 | 
			
		||||
        {
 | 
			
		||||
            const std::string *subject  = nullptr;
 | 
			
		||||
| 
						 | 
				
			
			@ -624,6 +643,7 @@ namespace client
 | 
			
		|||
        const DynamicConfig     *config                 = nullptr;
 | 
			
		||||
        const DynamicConfig     *config_override        = nullptr;
 | 
			
		||||
        size_t                   current_extruder_id    = 0;
 | 
			
		||||
        PlaceholderParser::ContextData *context_data    = nullptr;
 | 
			
		||||
        // If false, the macro_processor will evaluate a full macro.
 | 
			
		||||
        // If true, the macro processor will evaluate just a boolean condition using the full expressive power of the macro processor.
 | 
			
		||||
        bool                     just_boolean_expression = false;
 | 
			
		||||
| 
						 | 
				
			
			@ -824,6 +844,15 @@ namespace client
 | 
			
		|||
            output = expr_index.i();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        template <typename Iterator>
 | 
			
		||||
        static void random(const MyContext *ctx, expr<Iterator> ¶m1, expr<Iterator> ¶m2)
 | 
			
		||||
        {
 | 
			
		||||
            if (ctx->context_data == nullptr)
 | 
			
		||||
                ctx->throw_exception("Random number generator not available in this context.",
 | 
			
		||||
                    boost::iterator_range<Iterator>(param1.it_range.begin(), param2.it_range.end()));
 | 
			
		||||
            expr<Iterator>::random(param1, param2, ctx->context_data->rng);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        template <typename Iterator>
 | 
			
		||||
        static void throw_exception(const std::string &msg, const boost::iterator_range<Iterator> &it_range)
 | 
			
		||||
        {
 | 
			
		||||
| 
						 | 
				
			
			@ -1176,6 +1205,8 @@ namespace client
 | 
			
		|||
                                                                    [ px::bind(&expr<Iterator>::min, _val, _2) ]
 | 
			
		||||
                |   (kw["max"] > '(' > conditional_expression(_r1) [_val = _1] > ',' > conditional_expression(_r1) > ')') 
 | 
			
		||||
                                                                    [ px::bind(&expr<Iterator>::max, _val, _2) ]
 | 
			
		||||
                |   (kw["random"] > '(' > conditional_expression(_r1) [_val = _1] > ',' > conditional_expression(_r1) > ')') 
 | 
			
		||||
                                                                    [ px::bind(&MyContext::random<Iterator>, _r1, _val, _2) ]
 | 
			
		||||
                |   (kw["int"] > '(' > unary_expression(_r1) > ')') [ px::bind(&FactorActions::to_int,  _1,     _val) ]
 | 
			
		||||
                |   (strict_double > iter_pos)                      [ px::bind(&FactorActions::double_, _1, _2, _val) ]
 | 
			
		||||
                |   (int_      > iter_pos)                          [ px::bind(&FactorActions::int_,    _1, _2, _val) ]
 | 
			
		||||
| 
						 | 
				
			
			@ -1212,6 +1243,7 @@ namespace client
 | 
			
		|||
                ("false")
 | 
			
		||||
                ("min")
 | 
			
		||||
                ("max")
 | 
			
		||||
                ("random")
 | 
			
		||||
                ("not")
 | 
			
		||||
                ("or")
 | 
			
		||||
                ("true");
 | 
			
		||||
| 
						 | 
				
			
			@ -1312,13 +1344,14 @@ static std::string process_macro(const std::string &templ, client::MyContext &co
 | 
			
		|||
    return output;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::string PlaceholderParser::process(const std::string &templ, unsigned int current_extruder_id, const DynamicConfig *config_override) const
 | 
			
		||||
std::string PlaceholderParser::process(const std::string &templ, unsigned int current_extruder_id, const DynamicConfig *config_override, ContextData *context_data) const
 | 
			
		||||
{
 | 
			
		||||
    client::MyContext context;
 | 
			
		||||
    context.external_config 	= this->external_config();
 | 
			
		||||
    context.config              = &this->config();
 | 
			
		||||
    context.config_override     = config_override;
 | 
			
		||||
    context.current_extruder_id = current_extruder_id;
 | 
			
		||||
    context.context_data        = context_data;
 | 
			
		||||
    return process_macro(templ, context);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,6 +3,7 @@
 | 
			
		|||
 | 
			
		||||
#include "libslic3r.h"
 | 
			
		||||
#include <map>
 | 
			
		||||
#include <random>
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <vector>
 | 
			
		||||
#include "PrintConfig.hpp"
 | 
			
		||||
| 
						 | 
				
			
			@ -11,7 +12,16 @@ namespace Slic3r {
 | 
			
		|||
 | 
			
		||||
class PlaceholderParser
 | 
			
		||||
{
 | 
			
		||||
public:    
 | 
			
		||||
public:
 | 
			
		||||
    // Context to be shared during multiple executions of the PlaceholderParser.
 | 
			
		||||
    // The context is kept external to the PlaceholderParser, so that the same PlaceholderParser
 | 
			
		||||
    // may be called safely from multiple threads.
 | 
			
		||||
    // In the future, the context may hold variables created and modified by the PlaceholderParser
 | 
			
		||||
    // and shared between the PlaceholderParser::process() invocations.
 | 
			
		||||
    struct ContextData {
 | 
			
		||||
        std::mt19937 rng;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    PlaceholderParser(const DynamicConfig *external_config = nullptr);
 | 
			
		||||
    
 | 
			
		||||
    // Return a list of keys, which should be changed in m_config from rhs.
 | 
			
		||||
| 
						 | 
				
			
			@ -41,7 +51,7 @@ public:
 | 
			
		|||
 | 
			
		||||
    // Fill in the template using a macro processing language.
 | 
			
		||||
    // Throws Slic3r::PlaceholderParserError on syntax or runtime error.
 | 
			
		||||
    std::string process(const std::string &templ, unsigned int current_extruder_id = 0, const DynamicConfig *config_override = nullptr) const;
 | 
			
		||||
    std::string process(const std::string &templ, unsigned int current_extruder_id, const DynamicConfig *config_override, ContextData *context = nullptr) const;
 | 
			
		||||
    
 | 
			
		||||
    // Evaluate a boolean expression using the full expressive power of the PlaceholderParser boolean expression syntax.
 | 
			
		||||
    // Throws Slic3r::PlaceholderParserError on syntax or runtime error.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue