Jump to content

EasyGoing1

Member
  • Posts

    8
  • Joined

  • Last visited

Personal Information

  • 3D printer
    Other
  • Country
    US
  • Industry
    Other

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

EasyGoing1's Achievements

2

Reputation

  1. Here is the final script which allows any text to be typed in then it will get inserted before the last layer. from ..Script import Script import re class RunAtEnd(Script): def getSettingDataString(self): return """ { "name": "Run At End", "key": "RunAtEnd", "metadata": {}, "version": 2, "settings": { "insert": { "label": "Run before last layer", "description": "The code will be inserted before the last layer.", "type": "str", "default_value": "Code" } } } """ def execute(self, data): insert_string = self.getSettingValueByKey("insert") lastLayer = 0 for layer_number, layer in enumerate(data): lastLayer = layer_number - 1 lines = data[lastLayer - 1].split("\n") lines.insert(1, insert_string) data[lastLayer - 1] = "\n".join(lines) return data
  2. Thats the same line of thinking I was in too ... like theres a last layer, then there is the finishing gcode which I think must get treated as a layer as well .
  3. @gr5 I got it! Thanks to you, I went under the assumption that the first iteration of data contains an array of gcode layers ... and I came up with this really simple code (commented for explanation): def execute(self, data): # define our variable that will store the number of the last layer lastLayer = 0 for layer_number, layer in enumerate(data): # as this keeps looping, layer_number increases, # so we just set lastLayer to that number since # the last time the loop happens, we will then be # assigning lastLayer the highest number # (minus one because array indexes start at 0) lastLayer = layer_number - 1 # Now all we have to do is reference the lastLayer # (minus one again because it didn't work without that) # and then split the layer into an array called lines then # insert the custom macro command at the beginning of that # array. lines = data[lastLayer - 1].split("\n") lines.insert(1, '@FinalCountdown\n') # Replace the layer with the new array that has # the inserted command. data[lastLayer - 1] = "\n".join(lines) # Hand the new data object back to Cura for finalizing... # All done! return data
  4. OK, then this makes sense ... and is also useful. So perhaps then the data object when first iterated, brings out the gcode for each layer which can then be iterated by separating out each line at \n using split. Split is used in standard Java all the time as well ... it merely takes a string, then splits it into an array using whatever you pass into it as the split parameter (new line in this case). Im gonna experiment with it going on the assumption that you just pointed out ... I was most likely over-thinking things. ☺ In theory, I could iterate data once, then count the iterations and in that count, know how many layers there are in the gcode then use that number to insert my macro command.
  5. By the way ... where I seem to be struggling with the Python code, is where it has to engage the data object. The way that the search and replace python script iterates that object has me really confused. Which i'm sure has more to do with my lack of Python knowledge, but then when you add to that, the fact that Python has no requirement to declare datatypes, I look at the code and I don't even know what to Google to figure out what it is that the search and replace script is doing with that data object. Specifically, this is from the stock search and replace script that comes installed by default with Cura: for layer_number, layer in enumerate(data): data[layer_number] = re.sub(search_regex, replace_string, layer) #Replace all. return data I've never seen a for next loop initialize with two different objects before in reference to a third ... I get layer_number, which might be the line number of the gcode in the data object ... but then that word layer ... not sure what that is at all and I tied working with it assuming that layer was just each line of the gcode as the iteration happens, but that doesn't seem to be true because i could not - no matter what I tried (and I must have made 20 or 30 different attempts at doing this with various changes in the script) find the last line matching the regex then replace it with my macro command. I looked at another script that comes with Cura, and its called DisplayProgressOnLCD ... and it does a similar iteration through the data object but it gets even more bizarre for layer in data: layer_index = data.index(layer) lines = layer.split("\n") for line in lines: Now when I look at that code, that makes me think that layer is just the complete gcode which can be further iterated by breaking out the lines within that layer through the split call... but then this begs the question ... are there multiple different sets of gcode in the data object that it then becomes necessary to keep track of the index number for each "layer" ... I don't know ... it's very confusing and without having any kind of reference to explain what data even is ... all of my attempts to make this work, were just stabs in the dark.
  6. Hi Mari, Thank you for your reply. What I am wanting to do, is have my gcode execute an Octoprint macro just before starting the last layer of any print that I slice. And I want the insertion of that macro command to be automatic so that I dont have to do a manual search and replace every time I slice a print. The idea seemed fairly simple to me ... using regex, do a findAll on a simple string pattern ;LAYER:\d+ ... the last one found would be the start of the final layer, then simply replace that string with the macro call and it's all good. But it doesn't seem to be working out. I did learn through trying to make this work, that Prusa slicer can call any program that you desire for post processing and it will pass it the absolute file path of the gcode file that it generates as an argument to the program, where you can then further process the gcode, save it then the slicer drops it in to the folder that you chose when you export the gcode. Using a Java program that I threw together, I was able to successfully do what I want in post processing with Prusa, but I'm otherwise not familiar with Prusa slicer so im not sure how that is going to work out. Also, if this is the place to make suggestions for Cura, I think it would be great to have a post processing option that allows us to insert gcode at specific layers ... in similar fashion to how we can pause a print at any layer - which Ive used many times to print objects into parts etc. Being able to insert gcode at a given layer might be a function that others would find useful as well ... though that's just a presumption on my part of course ☺
  7. I'm trying to create a post processing script that finds the last layer comment and replaces it with some text. I copied the Search And Replace python script and modified it, but my problem is, that I don't code in Python, so I'm really not knowledgeable enough to understand why this isn't working (I work primarily in Java). Here is the script that I ended up creating, and it does show up in the Post Processing script list so I have it copied to the correct folder. The issue is that the search and replace isn't actually happening so Im hoping someone can look at this and tell me why it isn't working: import re from ..Script import Script class PlayAtEnd(Script): """Adds custom command to the last layer. """ def getSettingDataString(self): return """{ "name": "Play At End", "key": "PlayAtEnd", "metadata": {}, "version": 2, "settings": { "searchCode": { "label": "Last Layer comment Will Be Found", "description": "Replace last layer comment.", "type": "str", "default_value": "" }, "replaceCode": { "label": "And replaced with", "description": "Replace Text", "type": "str", "default_value": "@FinalCountdown" } } }""" def execute(self, data): foundHits = re.findall(";LAYER:\\d+", data) lastIndex = len(foundHits) - 1 search_string = ";LAYER:" + str(lastIndex) final_countdown = '@FinalCountdown\n' replace_string = ''.join([final_countdown, search_string]) for layer_number, layer in enumerate(data): data[layer_number] = re.sub(search_string, replace_string, layer) # Replace all. return data
  8. I have this part that I made in Tinker Cad and when I slice it in Cura, it adds this weird ring to the print and I don't know why. I've tried re-creating the STL file .. I've even gone backwards in the part creation and tried combining the pieces differently ... it still adds the ring to the slice ... Does anyone know why it's doing this or how to make it NOT do this? Thank you, Mike
×
×
  • Create New...