Browse Source

PostProcessingPlugin Script for 2-1 Dual Extruders - ColorMix 2-1

Marlin Commands:
M163 - Set Mix Factor
M164 - Save Mix
Ability to set a mix ratio or blend at a defined layer or distance.
Based on Geeetech's Color mixing software.
John Hryb IV 6 years ago
parent
commit
3a979903aa
1 changed files with 190 additions and 0 deletions
  1. 190 0
      plugins/PostProcessingPlugin/scripts/ColorMix.py

+ 190 - 0
plugins/PostProcessingPlugin/scripts/ColorMix.py

@@ -0,0 +1,190 @@
+# ColorMix script - 2-1 extruder color mix and blending
+# This script is specific for the Geeetech A10M dual extruder but should work with other Marlin printers. 
+# It runs with the PostProcessingPlugin which is released under the terms of the AGPLv3 or higher.
+# This script is licensed under the Creative Commons - Attribution - Share Alike (CC BY-SA) terms
+
+#Authors of the 2-1 ColorMix plug-in / script:
+# Written by John Hryb - john.hryb.4@gmail.com
+
+##history / change-log:
+##V1.0.0
+
+## Uses -
+## M163 - Set Mix Factor 
+## M164 - Save Mix - saves to T3 as a unique mix
+
+import re #To perform the search and replace. 
+from ..Script import Script
+
+class ColorMix(Script):
+    def __init__(self):
+        super().__init__()
+
+    def getSettingDataString(self):
+        return """{
+            "name":"ColorMix 2-1",
+            "key":"ColorMix 2-1",
+            "metadata": {},
+            "version": 2,
+            "settings":
+            {
+                "a_unitsOfMeasurement":
+                {
+                    "label": "Units of measurement",
+                    "description": "Input value as mm or layer number.",
+                    "type": "enum",
+                    "options": {"mm":"mm","layer":"Layer"},
+                    "default_value": "layer"
+                },
+                "b_start_height":
+                {
+                    "label": "Start Height",
+                    "description": "Value to start at (mm or layer)",
+                    "type": "float",
+                    "default_value": 0,
+                    "minimum_value": "0"
+                },
+                "c_behavior":
+                {
+                    "label": "Fixed or blend",
+                    "description": "Select Fixed (set new mixture) or Blend mode (dynamic mix)",
+                    "type": "enum",
+                    "options": {"fixed_value":"Fixed","blend_value":"Blend"},
+                    "default_value": "fixed_value"
+                },
+                "d_finish_height":
+                {
+                    "label": "Finish Height",
+                    "description": "Value to stop at (mm or layer)",
+                    "type": "float",
+                    "default_value": 0,
+                    "minimum_value": "0",
+                    "minimum_value_warning": "0.1",
+                    "enabled": "c_behavior == 'blend_value'" 
+                },
+                "e_mix_start":
+                {
+                    "label": "Start mix ratio",
+                    "description": "First extruder percentage 0-100",
+                    "type": "float",
+                    "default_value": 100,
+                    "minimum_value": "0",
+                    "minimum_value_warning": "0",
+                    "maximum_value_warning": "100"
+                },
+                "f_mix_finish":
+                {
+                    "label": "End mix ratio",
+                    "description": "First extruder percentage 0-100 to finish blend",
+                    "type": "float",
+                    "default_value": 0,
+                    "minimum_value": "0",
+                    "minimum_value_warning": "0",
+                    "maximum_value_warning": "100",
+                    "enabled": "c_behavior == 'blend_value'"
+                },
+                "g_notes":
+                {
+                    "label": "Notes",
+                    "description": "A spot to put a note",
+                    "type": "str",
+                    "default_value": ""
+                }
+            }
+        }"""
+    def getValue(self, line, key, default = None): #replace default getvalue due to comment-reading feature
+        if not key in line or (";" in line and line.find(key) > line.find(";") and
+                                   not ";ChangeAtZ" in key and not ";LAYER:" in key):
+            return default
+        subPart = line[line.find(key) + len(key):] #allows for string lengths larger than 1
+        if ";ChangeAtZ" in key:
+            m = re.search("^[0-4]", subPart)
+        elif ";LAYER:" in key:
+            m = re.search("^[+-]?[0-9]*", subPart)
+        else:
+            #the minus at the beginning allows for negative values, e.g. for delta printers
+            m = re.search("^[-]?[0-9]*\.?[0-9]*", subPart)
+        if m == None:
+            return default
+        try:
+            return float(m.group(0))
+        except:
+            return default
+
+    def execute(self, data):
+        #get user variables
+        firstHeight = 0.0
+        secondHeight = 0.0
+        firstMix = 0.0
+        SecondMix = 0.0
+
+        firstHeight = self.getSettingValueByKey("b_start_height")
+        secondHeight = self.getSettingValueByKey("d_finish_height")
+        firstMix = self.getSettingValueByKey("e_mix_start")
+        SecondMix = self.getSettingValueByKey("f_mix_finish")
+
+        #locals
+        layer = 0
+
+        #get layer height
+        layerHeight = .2
+        for active_layer in data:
+            lines = active_layer.split("\n")
+            for line in lines:
+                if ";Layer height: " in line:
+                    layerHeight = self.getValue(line, ";Layer height: ", layerHeight)
+                    break
+        #get layers to use
+        startLayer = 0
+        endLayer = 0
+        if self.getSettingValueByKey("a_unitsOfMeasurement") == "mm":
+            if firstHeight == 0:
+                startLayer = 0
+            else:
+                startLayer = firstHeight / layerHeight
+            if secondHeight == 0:
+                endLayer = 0
+            else:
+                endLayer = secondHeight / layerHeight
+        else:  #layer height
+            startLayer = firstHeight
+            endLayer = secondHeight
+        #see if one-shot
+        if self.getSettingValueByKey("c_behavior") == "fixed_value":
+            endLayer = startLayer
+            firstExtruderIncrements = 0
+        else:  #blend
+            firstExtruderIncrements = (SecondMix - firstMix) / (endLayer - startLayer)
+        firstExtruderValue = 0
+        index = 0
+        #start scanning
+        for active_layer in data:
+            modified_gcode = ""
+            lineIndex = 0;
+            lines = active_layer.split("\n")
+            for line in lines:
+                #dont leave blanks 
+                if line != "":
+                    modified_gcode += line + "\n"
+                # find current layer
+                if ";LAYER:" in line:
+                    layer = self.getValue(line, ";LAYER:", layer)
+                    if (layer >= startLayer) and (layer <= endLayer):  #find layers of interest
+                        if lines[lineIndex + 4] == "T2":  #check if needing to delete old data
+                            del lines[(lineIndex + 1):(lineIndex + 5)] 
+                        firstExtruderValue = int(((layer - startLayer) * firstExtruderIncrements) + firstMix)
+                        if firstExtruderValue == 100:
+                            modified_gcode += "M163 S0 P1\n"
+                            modified_gcode += "M163 S1 P0\n"
+                        elif firstExtruderValue == 0:
+                            modified_gcode += "M163 S0 P0\n"
+                            modified_gcode += "M163 S1 P1\n"
+                        else:
+                            modified_gcode += "M163 S0 P0.{:02d}\n".format(firstExtruderValue)
+                            modified_gcode += "M163 S1 P0.{:02d}\n".format(100 - firstExtruderValue)
+                        modified_gcode += "M164 S2\n"
+                        modified_gcode += "T2\n"
+                lineIndex += 1  #for deleting index
+            data[index] = modified_gcode
+            index += 1
+        return data