Jump to content

Kin

Dormant
  • Posts

    36
  • Joined

  • Last visited

Personal Information

  • Country
    US

Recent Profile Visitors

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

Kin's Achievements

3

Reputation

  1. from ..Script import Script import re class share_Wipe(Script): version = "3.2" def __init__(self): super().__init__() def getSettingDataString(self): return """{ "name":"share Wipe """ + self.version + """", "key":"share_Wipe", "metadata": {}, "version": 2, "settings": { "machine_type": { "label": "Machine Type", "description": "Select which machine type you are using. CRITICAL!", "type": "enum", "options": { "printer0":"printer0 Type", "printer1":"printer1 Type", "printer2":"printer2 W/Varipower Bed", "printer3":"printer3 W/Original Bed", "printer4":"printer4 NOT IMPLEMENTED" }, "default_value": "printer2" }, "wipe_layer": { "label": "Wipe Frequency", "description": "Wipe every N layers", "unit": "Layers", "type": "int", "default_value": 1 }, "wipe_volume": { "label": "Wipe Volume", "description": "Wipe every N layers and volume - not implemented", "unit": "mm", "type": "float", "default_value": 0 }, "Xcenter": { "label": "Brush X Center", "description": "center X point of brush movement", "unit": "mm", "type": "float", "default_value": 99, "value": "20 if machine_type == 'printer0' else (100 if machine_type == 'printer2' else (100 if machine_type == 'printer3' else (20 if machine_type == 'printer1' else 0)))" }, "Ycenter": { "label": "Brush Y Center", "description": "center Y point of the brush movement", "unit": "mm", "type": "float", "default_value": 99, "value": "80 if machine_type == 'printer0' else (272 if machine_type == 'printer2' else (272 if machine_type == 'printer3' else (80 if machine_type == 'printer1' else 0)))" }, "Yapproach": { "label": "Y Approach Offset", "description": "how far away from brush Ycenter to start moving Z if below Zbrush", "unit": "mm", "type": "float", "default_value": 99, "value": "0 if machine_type == 'printer0' else (40 if machine_type == 'printer2' else (40 if machine_type == 'printer3' else (0 if machine_type == 'printer1' else 0)))" }, "Xmove": { "label": "X move", "description": "How far from Xcenter that the brush script moves", "unit": "mm", "type": "float", "default_value": 99, "value": "5 if machine_type == 'printer0' else (30 if machine_type == 'printer2' else (30 if machine_type == 'printer3' else (5 if machine_type == 'printer1' else 0)))" }, "Ymove": { "label": "Y move", "description": "How far from Ycenter that the brush script moves", "unit": "mm", "type": "float", "default_value": 99, "value": "40 if machine_type == 'printer0' else (5 if machine_type == 'printer2' else (5 if machine_type == 'printer3' else (40 if machine_type == 'printer1' else 0)))" }, "travelSpeed": { "label": "Travel Speed", "description": "Travel speed to use during the brush script", "unit": "mm/min", "type": "float", "default_value": 99, "value": "2900 if machine_type == 'printer0' else (4800 if machine_type == 'printer2' else (4800 if machine_type == 'printer3' else (5200 if machine_type == 'printer1' else 2500)))" }, "Z_brushHeight": { "label": "brush movement Z height", "description": "If brush movement has a Z height component, otherwise ignore", "unit": "mm", "type": "float", "default_value": 9999, "value": "5 if machine_type == 'printer2' else (27 if machine_type == 'printer3' else 90)", "enabled": "True if machine_type == 'printer2' else (True if machine_type == 'printer3' else False)" } } }""" #getMyValue is like the script default getValue, but can find <1 values. def getMyValue(self, line, key, default = None): if not key in line or (';' in line and line.find(key)> line.find(';')): return default sub_part = line[line.find(key)+len(key):] m = re.search('^[-+]?[0-9]*\.?[0-9]*',sub_part) if m is None: return default try: return float(m.group(0)) except: return default def getMyCommentVal(self, line, key, default = None): #less safe version that doesn't ignore comments. if not key in line: return default sub_part = line[line.find(key)+len(key):] m = re.search('^[-+]?[0-9]*\.?[0-9]*',sub_part) if m is None: return default try: return float(m.group(0)) except: return default def buildGCode(self,Xcenter_local,Ycenter_local,Yapproach_local,Z_truth_local,X_resume,Y_resume,Z_resume,Z_brushHeight_local,Xwidth_local,Ywidth_local,travelSpeed_local,resumeSpeed_local,brush_type_local): #Z_brusHeight default 27 for printer3 wipeGcode = "; TEST WIPE:" + str(wipe_count) + " \n" #TODO remove this wipeGcode += "G1 F" + str(travelSpeed_local) + "\n" if Z_truth_local == 1: #Z_truth = 1 is also for Taz-type brushes. How one "approaches" the brush is very specific for taz-type brushes (to avoid collisions) if (Z_resume<(Z_brushHeight_local+5)): wipeGcode+="G1 Y" + str((Ycenter_local-Yapproach_local)) + ";move close to wiper but not too close when below brushheight \n" wipeGcode+="G1 Z" + str(Z_brushHeight_local+5) +"; Move to above the wipe \n" wipeGcode+="G1 Y" + str(Ycenter_local) + " X" + str(Xcenter_local) +";get back to the brush center \n" else: wipeGcode += "G1 Y" + str(Ycenter_local) + ";Move close to wiper without changing Z height \n" wipeGcode += "G1 Z" + str(Z_brushHeight_local+5) + "; Move to above the wiper \n" wipeGcode += "G1 X" + str(Xcenter_local) + " Y" + str(Ycenter_local) + "\n" wipeGcode += "G1 Z" + str(Z_brushHeight_local) + ";move down to the Z_brush height \n" else: wipeGcode += "G1 X" + str(Xcenter_local) + " Y" + str(Ycenter_local) + ";Move to center of brush w/o changing Z \n" wipeGcode += "G1 X" + str(Xcenter_local+Xwidth_local) + " Y" + str(Ycenter_local+Ywidth_local) + "; move to positive max of brush \n" wipeGcode += "G1 X" + str(Xcenter_local-Xwidth_local) + " Y" + str(Ycenter_local-Ywidth_local) + "; move to negative max of brush \n" if Z_truth_local == 1: wipeGcode+= "G1 Z" + str(Z_brushHeight_local+5) + "; move away from brush before return movement \n" wipeGcode+= "G1 Y" + str(Ycenter_local-30) + "\n" wipeGcode+= "G1 Z" + str(Z_resume) + "\n" wipeGcode+= "G1 X" +str(X_resume) + " Y" + str(Y_resume) + "\n" if resumeSpeed_local != 3030303030: #don't add a speed value if you don't have an old speed value wipeGcode+="G1 F" + str(resumeSpeed_local) + "; resumeSpeed based on last XY speed of previous layer \n" else: wipeGcode+="G1 F" + str(1807) + "; resume speed based on default exception \n" return wipeGcode def execute(self, data): #initialize values for different brushes Xcenter = self.getSettingValueByKey("Xcenter") Ycenter = self.getSettingValueByKey("Ycenter") Xwidth = self.getSettingValueByKey("Xmove") #note Xmove is the JSON move for width. Width is the name in code but poor choice due to the fact it really represents 1/2 of the width of the movement and isn't very clear. Ywidth = self.getSettingValueByKey("Ymove") travelSpeed = self.getSettingValueByKey("travelSpeed") Z_brushHeight = self.getSettingValueByKey("Z_brushHeight") Yapproach = self.getSettingValueByKey("Yapproach") brush_type = 0 Z_truth = 0 #default assumption that there's no Z movement [safest] wipeEveryN = self.getSettingValueByKey("wipe_layer") wipeEveryLayerCounter = 0 if self.getSettingValueByKey("machine_type") == "printer0": Z_truth = 0 if self.getSettingValueByKey("machine_type") == "printer2": Z_truth = 1 if self.getSettingValueByKey("machine_type") == "printer3": Z_truth = 1 if self.getSettingValueByKey("machine_type") == "printer4": Z_truth = 0 layers_started = False last_layer = False last_speed = 3030303030 #wipe script is added at the start of indicated layers. So throughout the previous layer, I should look for Fcommands, and keep the most recent one. resume_speed = 3030303030 extruded_count = 0 # TODO - volumetric wipe functionality extruding_type = None # absolute vs relative, lets say absolute = 0, relative = 1 TODO global wipe_count wipe_count = 0 total_layers = -555555555555#wary as last_layer counting system relies on wipe_count and I don't want cura to break the script by devising "negative layers" or something like that #skip layers = self.getSettingValueByKey("every_layer") #future functionality for layer in data: #data is already split by layers as given by cura (see tweakZ for same format) lines = layer.splitlines() #'Ive used both layer.split("\n") and this, but find same behavior. I believe all gcode from cura should split on \n, but a stackexchange answer said it can be platform dependant as a general convention so I chose to use splitlines to circumvent that. first_Z = None first_X = None first_Y = None wipe_gcode = None #reset the wipe gcode per layer for line in lines: if ";LAYER_COUNT:" in line: total_layers = self.getMyCommentVal(line,';LAYER_COUNT:') total_layers = int(round(total_layers,0)) if ";LAYER:1" in line: #should run once when passing LAYER:N layers_started = True #wipe_gcode = "Total Layer No. = " + str(total_layers) + "\n" #TODO REMOVE THIS DEBUG if not layers_started: #should run once after passed LAYER:N continue if (";LAYER:"+str(total_layers-1)) in line: last_layer = True #Next, searching for the first Z, first X, first Y, and last F. if self.getMyValue(line,'G') == 1 or self.getMyValue(line,'G') == 0: if first_Z == None: #only act if we haven't found Z yet in this layer first_Z = self.getMyValue(line,'Z') #should return None if doesn't find anything in this line if first_X == None: #TODO consider case of X1 command then a Y1 command later (I.e, first X command isn't in same line as first Y command) first_X = self.getMyValue(line,'X') #should return None if doesn't find anything if first_Y == None: first_Y = self.getMyValue(line,'Y') #should return None if doesn't find anything if self.getMyValue(line,'F') != None: if (self.getMyValue(line,'X') != None) or (self.getMyValue(line,'Y')!=None): #only count F commands that include some XY motion to ignore slow extruder or Z speeds. TODO: Consider that this 'safety' should not be required, because even if you set the speed to that slower speed, if it truly was the last F command in a layer, the next layer should fix itself (or else it would fail without the wipe code) last_speed = self.getMyValue(line,'F') if not layers_started: #should run once after passed LAYER:N continue wipeEveryLayerCounter+=1 #this counter should reset each time you build and store a wipe code wipe_count += 1 #this is a more general count of what potential wipe layer you're on, but mostly defunct code (cleanup?) if wipeEveryLayerCounter<wipeEveryN: #e.g, wipe every 2 layers. counter =1, N=2. Second layer should wipe and reset counter to 0. if last_speed != None: #See this same line later, after buildGcode. Even if you skip buildGcode you still want to track your previous layer speed, for the next buildGcode to have a speed ready. resume_speed = last_speed if last_layer == True: #There are two last layer checks, they could probably be consolidated to (1) in front of both of them, that checks for N-1 of the current check [checking within this loop was chosen as an extension of the original test before wiping every N layers was implemented [original test was after the last gcode one adds rather than before building]] return data continue #skips the wipe gcode generation and inclusion (below) else: wipeEveryLayerCounter=0 #resets the wipe skipping counter. Assume default wipeEveryN = 1, should turn 0 here, then turn to 1 again by the +=1 val. wipe_gcode = self.buildGCode(Xcenter,Ycenter,Yapproach,Z_truth,first_X,first_Y,first_Z,Z_brushHeight,Xwidth,Ywidth,travelSpeed,resume_speed,brush_type)#travelSpeed,resumeSpeed,brush_type) if last_speed != None: resume_speed = last_speed #add the wipe code adding -format pulled from BQ Pause@height code index = data.index(layer) #find our current layer layer = wipe_gcode + layer #add wipe code then (is there order of operations to string addition? Presumably) data[index] = layer if last_layer == True: return data return data I don't know if this will be useful for you, I have not used it in over six months. But last I used it I believe it was working :-)
  2. That sounds like a cold plug, one of the situations where I might actually recommend the high temp warmup hold. The difference is I'd go to the material print temp, wait 3 minutes, then physically hold back the heatsink cooling fan for the hot end for 1-2 minutes before pulling. This causes filament to soften above the heatbreak [because the heatsink isn't cooled anymore and warms up], and can loosen a cold plug. It's a risky move but would probably be next step. Alternatively if you've managed to get support through other channels and methods, there's no guarantee my suspicion is correct so you might prefer other courses of action.
  3. Hi gilbert, I agree cura doesn't really place objects very well (coming from slic3r background.) I don't know exactly the functionality you saw before, i can't remember if cura would just intelligently place objects after a row fills up into a new row. It seems if it did this after each duplication to check if it needed to change rows, it might be confused when you're making 9 duplicates in a row (that is the implementation of "multiply objects" could be barebones.) But two suggestions for your immediate problem: (1) Try multiplying 5 units, then 5 units again. My point here is ask for the amount that one row can fit, then ask for more and see if it behaves more like you expect. (2) Try multiplying 5 units, select all units, and "merge stls" or "group stls as one object" whatever it is called [i don't recall and cura boots slowly for me]. Now duplicate that object of 5 and see if it behaves how you want. Hope some of those suggestions work for you. Bare in mind also that if you disable "ensure objects are kept apart" in the cura settings, you'll totally change this behavior (they'll all get lumped on top of each other)
  4. So OK I would like to distill this to two questions: (1) In JSONs, can I access the material temperature settings? It seems like I cannot, I can only access a global default print_material_settings (1B) If I can access material temperature settings in the machine instance, can I also access it in the extruder specific json? (1C) If I add a temperature command to my extruder start gcode, does cura see that and turn off its M109 print temperature command? I understand it might not be enabled for the extruders but I can't figure out how to confirm, it seems my tests so far suggest it is not functional in extruder JSONs. I can make a post processing plugin (due to all the help on this forum:)! thanks daidhai8 and others), but I would love to edit in jsons. (2) What is the meaning of "extruder_start_pos" and "extruder_end_pos" The value exists for X, Y, and Z, but in output files I only see the extruder ever moving to the prime position, not the extruder_start_pos. I expect the extruder_start_pos would represent something like "go here before the extruder_start_gcode" but it does not seem to represent that. My goal is to make a "perfect" dual extruder setup for my custom reprap, so I'm trying to tune a bunch of extruder switching things. I want to do it to whatever extent I can in the existing functionality, but I will supplement anything I can't do with a post processing plugin (which would be more satisfying if I could set them to always apply, like "if using dual extrusion, turn on this post processing plugin" but I also think that is not an option.) I hope my questions aren't too much, but I'm hopeful there's someone with knowledge about this who can swoop in because it's been a lot of trial an error messing with this so far .
  5. You should not need to get it hot over 15 minutes and you are likely to just degrade any plastic further. The typical procedure (please correct me anyone if I'm wrong) is more like what Labern said, to heat it up so you can fuse the filament with filament in the hot end, then pull when it's somewhere between cold and hot, such that you can pull out viscous material attached to the filament you just fused into the melt chamber. This is repeated a few times. Sometimes I find it useful to insert a 0.35mm steel cable into the nozzle end to break things up, feeling it 1mm in at a time, but I haven't done that for 2 years since I don't really clog much these days. There are some conditions in which you might heat for 15 minutes, but not typical ones [maybe that's why someone suggested teh 15 minute procedure, I'm not 100% clear on it and haven't fully checked where it is someone wrote that]
  6. For the record I am absolutely aware there is no way to "merge" the two programs. I hope i didn't distress anyone by throwing around words like that with more specific meaning than I intended . [Distressed insofar as someone feels distressed when they hear someone talking about things so far off-base] I absolutely only meant it in the sense of a dream world concept in which all the things I like about slic3r existed in cura, and cura handled the random nifty super-tweakable settings of slic3r. I also meant it in the sense that I conceptually admire slic3r (it was my first quality slicing experience and got my first amazing prints with it), but I see cura/ultimaker as a wonderful platform overall that I prefer to use (it feels less disjointed than slic3r.) So I just am recognizing that there are some awesome developers contributing to both slic3r and cura, and my eyes bug out at the thought of what could be done if one of the projects had *all* of the developers, haha.
  7. I am glad to have encouraged some movement on this post, but I admit I'm out of my comfort zone for debugging this. It does look like you found a genuine issue with 2.4 install on linux, but I don't know exactly what you've found. For the record i run in windows and expect the scripts in program files>cura>plugins>postprocessingplugins>scripts, which is totally different. Hopefully someone with more knowledge (looks like already one other person has responded) will have a better sense of whether or not this should be pushed to a github issue. Although what you've found so far suggests that there's a global issue with the post processing effects, but I still suggest also trying another script like the tweak@Z, if only because you can probably find a temporary work around if you can get some other script to work
  8. edited this post because I think I'm shooting too far from hip, I will try to look into pause@height but also suggest trying a couple other gcodes/files, and also a different height (not 5.0 try 5.02 or something randomly different.) just trying to troubleshoot.
  9. Hi Martin, I checked over the pause@height and I couldn't find any major issues why it would fail for your parameters and gcode. It should be starting to look at your lines after LAYER:0, and the it should find the first Z that is above the z target, so it finds Z5.07 around layer 49, and it should then insert the pause script (m83 + anything you modify the plugin with, but I think you indicate you haven't odified it.) Have you tried any of the other default scripts? Maybe the tweak@Z or something? One suggestion: can you try pausing it at a height other than 5.0mm? maybe it's an odd bug that doesn't register 5.0 since it's the default, and even though it's showing 5.0.. try maybe 5.02 if you want it to pause around 5mm (your first >5mm layer is 5.07mm)
  10. Hey sorry about it I see you're having a lot of trouble. I run a shared UM3 a little and a prusa along with my repraps. Sometimes every printer goes through the worst shit. I didn't really read the whole thread and notice you agreed brim might make sense in some cases. Hope the rest of your problems resolve. FYI in future I think heating the t-glase above 200C should be plenty to remove it from a clog. I would probably heat the end up and manually pull back, but it sounds like you've tried a few similar things like that and your issue might be more complicated than I can diagnose from the description. Good luck I acually don't print as often on the UM3 as on my own printers (since it's not really mine) but it is in my mind a beautiful machine. I can't see where it would have worse problems than other printers in terms of the clog/jam you got. My issues with clogs in all my printers have nearly eliminated vs. 3 yrs ago except for certain filaments that seem to have quality issues and if I print .25mm nozzle (just too small.)
  11. I've heard but not seen that stratasys software can do something like this (their high end suite.) I don't see a lot of value over "infill thickness" (e.g, .1mm perimeters with .3mm infill.) But it is something neat enough that it would be cool if cura matched. Sometimes I wish slic3r and cura were one software package, they both have a ton of strengths and end up doing a lot of redundant work. besides the general reasons for why they are not one project, I also have no conception of why they probably physically can't be merged [presumably they have different architectures and code bases.]
  12. I suggest uploading your gcode as well, your copy of pause at height, and also let know (and confirm) what you put the pause layer height at. I suspect it's just that you are attempting to pause above a layer that the gcode gets to, as a typo or something.
  13. You seem bizarrely indignant that cura defaults to brim. Meanwhile I'll present why I think this is correct: If the part warps off the bed, the user blames the printer. Even if only 1/20 prints *need* a brim, I think keeping it simple for basic users is what cura default settings should do, so then the brim should stay on.
  14. The behavior I'm trying to do is fairly basic: Standard cura warmup for dual extrusion heats both heaters up simultaneously with a M104 command. I want to heat up one heater, then the next, ideally adding to my machine_start_gcode json something like this: M109 T1 S{material_print_temperature_1} M109 T0 S{material_print_temperature_0} My first adventure was learning by trial and error that I can't modify the machine_start_gcode in the "extruder" json because it doesn't parse for things like S{material_print_temperature}. I am not entirely sure what settings it does parse for and which it doesn't in the extruder json. However, in the printer json it does parse for at least "material_print_temperature" but it only puts in the globally defined setting (which has to be wrong for most materials since it's just a basic default.) There was one old thread I found when researching this problem, but I think it wasn't really conclusive as to whether I can access the material print temperature setting for a specific material with this machine_start_gcode override. So, is what I'm trying to do even possible? just checking in I'm not really sure. I would love to get a better background on the cura json structures, but I'm somewhat amatuer and not sure if I'm missing some place where it's documented more (most of what I've learned has been on forum posts and painful break-observe iteration.) Thanks!
  15. Update: So this totally went wayside during the holiday madness . I am glad to have finally sat down on it. Dahai8 you uncovered the secret. I've include below the example code you gave extended to a more complicated number of parameters. I still have had a bear with opening cura to test edits to the script, but mostly it's just me not being a cautious practiced programmer and missing punctuation. I probably rely too much on (for example) the compiler in arduino to point out such issues. I don't get so lucky with the gcode modifier script because I never see how it fails in cura (just that it doesnt load, which no longer is an issue.) Thanks again for all the help! Very happy to have done this as neatly as extensively as I hoped would be possible. Only due to the json hacking help of others. from ..Script import Scriptimport reclass Robust_Wipe(Script): version = "2.1" def __init__(self): super().__init__() def getSettingDataString(self): return """{ "name":"Robust Wipe """ + self.version + """", "key":"Robust_Wipe", "metadata": {}, "version": 2, "settings": { "machine_type": { "label": "Machine Type", "description": "Select which machine type you are using. CRITICAL!", "type": "enum", "options": { "A":"A Type", "B":"B Type", "C":"C Type", "D":"D Type", "E":"E Type" }, "default_value": "A" }, "wipe_layer": { "label": "Wipe Frequency", "description": "Wipe every N layers", "unit": "Layers", "type": "int", "default_value": 1 }, "wipe_volume": { "label": "Wipe Volume", "description": "Wipe every N layers and volume - not implemented", "unit": "mm", "type": "float", "default_value": 0 }, "input_paramA": { "label": "Input A", "description": "First Input Parameter", "unit": "mm", "type": "float", "default_value": 99, "value": "1 if machine_type == 'A' else (2 if machine_type == 'B' else (3 if machine_type == 'C' else (4 if machine_type == 'D' else (5 if machine_type=='E' else 9))))" }, "input_paramB": { "label": "Input B", "description": "Second Input Parameter", "unit": "mm", "type": "float", "default_value": 99, "value": "1 if machine_type == 'A' else (2 if machine_type == 'B' else (3 if machine_type == 'C' else (4 if machine_type == 'D' else (5 if machine_type=='E' else 9))))" }, "input_paramC": { "label": "Input C", "description": "Third Input Parameter", "unit": "mm", "type": "float", "default_value": 99, "value": "1 if machine_type == 'A' else (2 if machine_type == 'B' else (3 if machine_type == 'C' else (4 if machine_type == 'D' else (5 if machine_type=='E' else 9))))" }, "input_paramD": { "label": "Input D", "description": "Fourth Input Parameter", "unit": "mm", "type": "float", "default_value": 99, "value": "1 if machine_type == 'A' else (2 if machine_type == 'B' else (3 if machine_type == 'C' else (4 if machine_type == 'D' else (5 if machine_type=='E' else 9))))" }, "input_paramE": { "label": "Input E", "description": "Fifth Input Parameter", "unit": "mm", "type": "float", "default_value": 99, "value": "1 if machine_type == 'A' else (2 if machine_type == 'B' else (3 if machine_type == 'C' else (4 if machine_type == 'D' else (5 if machine_type=='E' else 9))))" }, "input_paramF": { "label": "Input F", "description": "Sixth Input Parameter", "unit": "mm", "type": "float", "default_value": 99, "value": "1 if machine_type == 'A' else (2 if machine_type == 'B' else (3 if machine_type == 'C' else (4 if machine_type == 'D' else (5 if machine_type=='E' else 9))))" }, "input_paramG": { "label": "Input G", "description": "Seventh Input Parameter", "unit": "mm", "type": "float", "default_value": 99, "value": "1 if machine_type == 'A' else (2 if machine_type == 'B' else (3 if machine_type == 'C' else (4 if machine_type == 'D' else (5 if machine_type=='E' else 9))))" }, "input_paramH": { "label": "Input H", "description": "First Input Parameter", "unit": "mm", "type": "float", "default_value": 99, "value": "1 if machine_type == 'A' else (2 if machine_type == 'B' else (3 if machine_type == 'C' else (4 if machine_type == 'D' else (5 if machine_type=='E' else 9))))" } } }""" def execute(self, data): if 1==1: pass #I want the most basic version of the script for figuring out JSON return data
×
×
  • Create New...