Python Forum
Using Python to add text lines in a gcode file
Thread Rating:
  • 2 Vote(s) - 4 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Using Python to add text lines in a gcode file
#1
I have been building a 3D printer and would like to create a post-processing plugin for my slicer as the slicer doesn't provide a feature that I require. I'm using Cura as a slicer and it accepts python scripts as plugins to modify the generated Gcode as a built-in feature. Here is a (shortened) sample of the generated gcode:
Output:
;LAYER_COUNT:191   ;LAYER:0   M106 S255   G0 F3600 X99.873 Y99.731 Z0.3   ;TYPE:WALL-INNER   G1 F1800 X100.034 Y99.574 E0.02699   G1 X100.225 Y99.441 E0.05491   G1 X100.445 Y99.339 E0.08401   ;TIME_ELAPSED:18.234693   ;LAYER:1   M107   G0 F5400 X99.456 Y98.484 Z0.45   ;TYPE:WALL-INNER   M106 255   G1 F3300 X99.604 Y98.363 E47.83319   G1 X99.774 Y98.299 E47.84409   G1 X100.033 Y98.238 E47.86005   G0 X99.568 Y98.521   ;TIME_ELAPSED:37.123855   ;LAYER:2   M107   G0 F7200 X98.896 Y97.697 Z0.6   ;TYPE:WALL-INNER   M106 255   G1 F4800 X99.103 Y97.5 E80.19273   G1 X99.378 Y97.417 E80.20996   G1 X99.486 Y97.403 E80.2165   G0 X107.174 Y111.477   ;TIME_ELAPSED:1240.100936   M107   ;End of Gcode  
After each Z#.## move, I would like to insert some more lines of Gcode underneath. This could be done by looking at "LAYER" and inserting sample code 3 lines under. This is some sample code of what I would like to add.
Output:
G0 X100 Y50   G1 F100 X100 Y10   G1 F20 X110 Y10   G1 F100 X110 Y170   G1 F100 X110 Y10   G1 F20 X100 Y10   G0 X100 Y50  
So the end result would be:
Output:
;LAYER_COUNT:191   ;LAYER:0   M106 S255   G0 F3600 X99.873 Y99.731 Z0.3   G0 X100 Y50   G1 F100 X100 Y10   G1 F20 X110 Y10   G1 F100 X110 Y170   G1 F100 X110 Y10   G1 F20 X100 Y10   G0 X100 Y50   ;TYPE:WALL-INNER   G1 F1800 X100.034 Y99.574 E0.02699   G1 X100.225 Y99.441 E0.05491   G1 X100.445 Y99.339 E0.08401   ;TIME_ELAPSED:18.234693   ;LAYER:1   M107   G0 F5400 X99.456 Y98.484 Z0.45   G0 X100 Y50   G1 F100 X100 Y10   G1 F20 X110 Y10   G1 F100 X110 Y170   G1 F100 X110 Y10   G1 F20 X100 Y10   G0 X100 Y50   ;TYPE:WALL-INNER   M106 255   G1 F3300 X99.604 Y98.363 E47.83319   G1 X99.774 Y98.299 E47.84409   G1 X100.033 Y98.238 E47.86005   G0 X99.568 Y98.521   ;TIME_ELAPSED:37.123855   ;LAYER:2   M107   G0 F7200 X98.896 Y97.697 Z0.6   G0 X100 Y50   G1 F100 X100 Y10   G1 F20 X110 Y10   G1 F100 X110 Y170   G1 F100 X110 Y10   G1 F20 X100 Y10   G0 X100 Y50   ;TYPE:WALL-INNER   M106 255   G1 F4800 X99.103 Y97.5 E80.19273   G1 X99.378 Y97.417 E80.20996   G1 X99.486 Y97.403 E80.2165   G0 X107.174 Y111.477   ;TIME_ELAPSED:1240.100936   M107   ;End of Gcode  
Any Help Would be appreciated

Thanks
Reply
#2
Something like this

from collections import deque

def process_code(in_code, insert_code):
   insert_at = deque()
   new_code = []
   next_insert = -1
   for i, line in enumerate(in_code.split('\n')):
       if insert_at and i >= next_insert:
           next_insert = insert_at.popleft()
       new_code.append(line)
       if i == next_insert:
           new_code.append(insert_code)
       if line.startswith(';LAYER:'):
           insert_at.append(i+2)
   return '\n'.join(new_code)
   
if __name__ == '__main__':

   in_code=""";LAYER_COUNT:191  
;LAYER:0  
M106 S255  
G0 F3600 X99.873 Y99.731 Z0.3  
;TYPE:WALL-INNER  
G1 F1800 X100.034 Y99.574 E0.02699  
G1 X100.225 Y99.441 E0.05491  
G1 X100.445 Y99.339 E0.08401  
;TIME_ELAPSED:18.234693  
;LAYER:1  
M107  
G0 F5400 X99.456 Y98.484 Z0.45  
;TYPE:WALL-INNER  
M106 255  
G1 F3300 X99.604 Y98.363 E47.83319  
G1 X99.774 Y98.299 E47.84409  
G1 X100.033 Y98.238 E47.86005  
G0 X99.568 Y98.521  
;TIME_ELAPSED:37.123855  
;LAYER:2  
M107  
G0 F7200 X98.896 Y97.697 Z0.6  
;TYPE:WALL-INNER  
M106 255  
G1 F4800 X99.103 Y97.5 E80.19273  
G1 X99.378 Y97.417 E80.20996  
G1 X99.486 Y97.403 E80.2165  
G0 X107.174 Y111.477  
;TIME_ELAPSED:1240.100936  
M107  

;End of Gcode  """

   insert_code = """G0 X100 Y50  
G1 F100 X100 Y10  
G1 F20 X110 Y10  
G1 F100 X110 Y170  
G1 F100 X110 Y10  
G1 F20 X100 Y10  
G0 X100 Y50"""

   print process_code(in_code, insert_code)
Reply
#3
Would there be a way to do this without having to enter the in_code into the script? 
As the plugin is inbedded into the slicer which creates the gcode. Could the python script be able to detect the text that has been created by the slicer?

I have found an example script layout for my slicer.
[size=x-large]# Copyright (c) 2015 Jaime van Kessel, Ultimaker B.V.[/size]
# The PostProcessingPlugin is released under the terms of the AGPLv3 or higher.
from ..Script import Script

class ExampleScript(Script):
    def __init__(self):
        super().__init__()

    def getSettingDataString(self):
        return """{
            "name":"Example script",
            "key": "ExampleScript",
            "metadata": {},
            "version": 2,
            "settings":
            {
                "test":
                {
                    "label": "Test",
                    "description": "None",
                    "unit": "mm",
                    "type": "float",
                    "default_value": 0.5,
                    "minimum_value": "0",
                    "minimum_value_warning": "0.1",
                    "maximum_value_warning": "1"
                },
                "derp":
                {
                    "label": "zomg",
                    "description": "afgasgfgasfgasf",
                    "unit": "mm",
                    "type": "float",
                    "default_value": 0.5,
                    "minimum_value": "0",
                    "minimum_value_warning": "0.1",
                    "maximum_value_warning": "1"
                }
            }
        }"""

    def execute(self, data):
        return data[size=x-large]
[/size]
Reply
#4
Based on the examples here

https://github.com/nallath/PostProcessingPlugin


# Copyright (c) 2017 Boyan Kolev
# The PostProcessingPlugin is released under the terms of the AGPLv3 or higher.
 
from ..Script import Script
 
class InsertTextEveryLayer(Script):
    def getSettingDataString(self):
        return """{
            "name": "Insert Text in Every Layer",
            "key": "InsertText",
            "metadata": {},
            "version": 1,
            "settings":
            {
                "insert text":
                {
                    "label": "Insert Text",
                    "description": "This text will be inserted in each layer.",
                    "type": "str",
                    "default_value": ""
                },
                "insert at":
                {
                    "label": "Insert at line",
                    "description": "Number of the line (0-based) at which to insert the text.",
                    "type": "int",
                    "default_value": "3"
                },
            }
        }"""
 
    def _process_layer(self, layer):
        insert_text = self.getSettingValueByKey("insert text")
        insert_at = self.getSettingValueByKey("insert at")
        layer = layer.split("\n")
        layer.insert(insert_at, insert_text)
        return "\n".join(layer)
 
    def execute(self, data):
        return [self._process_layer(layer) for layer in data]
data is list of layers as str. I assume layers look like this

Output:
;LAYER:0   M106 S255   G0 F3600 X99.873 Y99.731 Z0.3   G0 X100 Y50   G1 F100 X100 Y10   G1 F20 X110 Y10   G1 F100 X110 Y170   G1 F100 X110 Y10   G1 F20 X100 Y10   G0 X100 Y50   ;TYPE:WALL-INNER   G1 F1800 X100.034 Y99.574 E0.02699   G1 X100.225 Y99.441 E0.05491   G1 X100.445 Y99.339 E0.08401   ;TIME_ELAPSED:18.234693
i.e. first line is the line of layer index. If this is not the case default value for 'insert at' should be decreased by 1

Note that I'm not able to test. I reserve the right to submit pull request to the above repo.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Replace a text/word in docx file using Python Devan 4 2,856 Oct-17-2023, 06:03 PM
Last Post: Devan
  save values permanently in python (perhaps not in a text file)? flash77 8 1,121 Jul-07-2023, 05:44 PM
Last Post: flash77
  What are these python lines for? What are tey doing? Led_Zeppelin 7 1,561 Feb-13-2023, 03:08 PM
Last Post: deanhystad
Thumbs Up Need to compare the Excel file name with a directory text file. veeran1991 1 1,065 Dec-15-2022, 04:32 PM
Last Post: Larz60+
  Delete multiple lines from txt file Lky 6 2,205 Jul-10-2022, 12:09 PM
Last Post: jefsummers
  Modify values in XML file by data from text file (without parsing) Paqqno 2 1,579 Apr-13-2022, 06:02 AM
Last Post: Paqqno
  Editing text between two string from different lines Paqqno 1 1,287 Apr-06-2022, 10:34 PM
Last Post: BashBedlam
  failing to print not matched lines from second file tester_V 14 5,946 Apr-05-2022, 11:56 AM
Last Post: codinglearner
  Extracting Specific Lines from text file based on content. jokerfmj 8 2,862 Mar-28-2022, 03:38 PM
Last Post: snippsat
  Converted Pipe Delimited text file to CSV file atomxkai 4 6,842 Feb-11-2022, 12:38 AM
Last Post: atomxkai

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020