From 917236f386a90e9da61fb7fe442c2346c8d80098 Mon Sep 17 00:00:00 2001 From: xitix Date: Sun, 16 Aug 2020 14:11:00 +0300 Subject: [PATCH 1/3] Add files via upload modified to work with Blender 2.83.4 --- ioImportGcode.py | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/ioImportGcode.py b/ioImportGcode.py index f555e01..69ee012 100644 --- a/ioImportGcode.py +++ b/ioImportGcode.py @@ -28,8 +28,9 @@ bl_info = { 'name': 'Import Slic3r GCode', 'author': 'Lee Butler', - 'version': (0,1,0), - 'blender': (2, 7, 0), + 'version': (0,1,1), + 'blender': (2, 83, 4), + 'api': 32738, 'location': 'File > Import-Export > Gcode', 'description': 'Import and visualize gcode files generated by Slic3r (.gcode)', "wiki_url": "https://github.com/iraytrace/BlenderGcodeImport/wiki", @@ -143,8 +144,9 @@ def parse(self, fileName): #print (dir(profilePoly)) profileObject = bpy.data.objects.new(profileName, profileData) - scn = bpy.context.scene - scn.objects.link(profileObject) + scn = bpy.context.view_layer + scn.update() + bpy.context.collection.objects.link(profileObject) scn.objects.active = profileObject @@ -173,7 +175,7 @@ def parse(self, fileName): polyline.points[1].co = newPt oldPt = newPt layerObject = bpy.data.objects.new(layerName, curveData) - scn.objects.link(layerObject) + bpy.context.collection.objects.link(layerObject) scn.objects.active = layerObject @@ -338,12 +340,22 @@ def menu_func(self, context): self.layout.operator(IMPORT_OT_gcode.bl_idname, text="Slic3r GCode (.gcode)", icon='PLUGIN') def register(): - bpy.utils.register_module(__name__) - bpy.types.INFO_MT_file_import.append(menu_func) + classes = ( + IMPORT_OT_gcode, + ) + from bpy.utils import register_class + for cls in classes: + register_class(cls) + bpy.types.TOPBAR_MT_file_import.append(menu_func) def unregister(): - bpy.utils.unregister_module(__name__) - bpy.types.INFO_MT_file_import.remove(menu_func) + classes = ( + IMPORT_OT_gcode, + ) + from bpy.utils import register_class + for cls in classes: + register_class(cls) + bpy.types.TOPBAR_MT_file_import.remove(menu_func) if __name__ == "__main__": register() From 73b52bda0b23d1f64b4ffc9f075470fa4ec1b6a1 Mon Sep 17 00:00:00 2001 From: xitix Date: Sun, 16 Aug 2020 14:13:34 +0300 Subject: [PATCH 2/3] Update README.md --- README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index dd40254..90e04d3 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,9 @@ BlenderGcodeImport ================== -Python script to load gcode files produced by Slic3r into Blender +Python script to load gcode files produced by Slic3r*(Cura & IdeaMaker) into Blender -This work was based on the plugin (now defunct?) by Simon Kirkby. I wrote this because the previous one -did not work with more recent (2.7.0) versions of Blender. +This work was based on the plugin (now defunct?) by Simon Kirkby. It was modified to work with more recent (2.83.4) versions of Blender. To use this download the plugin and start Blender From 134a17ba474ae7795ebd2df4055b7bc9c10fa40c Mon Sep 17 00:00:00 2001 From: xitix Date: Thu, 20 Aug 2020 00:30:01 +0300 Subject: [PATCH 3/3] Eliminated few bugs on G-code parsing & unregister with Blender 2.83.4 on PrusaSlicer there was a gcode parser issue with z-hop --- ioImportGcode.py | 103 +++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 86 insertions(+), 17 deletions(-) diff --git a/ioImportGcode.py b/ioImportGcode.py index 69ee012..63053a2 100644 --- a/ioImportGcode.py +++ b/ioImportGcode.py @@ -60,14 +60,16 @@ def __init__(self): # set of polylines self.polys = [] - # each layer is a set of polylines at a constant Z - self.layers = [] + # each layer is a set of polylines at a constant Z or float (z-hop) + self.layers = {} # set of Z elevation changes. Most common is layer height self.thickness = { } self.ySquash = 0.5 - self.xOoze = 1.65 + self.xOoze = 1.15 + + self.Prusa=False ##### DRAW ##### @@ -99,6 +101,8 @@ def parse(self, fileName): f = open(fileName) for line in f.readlines(): # remove comments and leading/trailing whitespace + if 'PrusaSlicer' in line: + self.Prusa=True line = line.split(';', 1)[0].strip() # skip the blank lines @@ -110,7 +114,7 @@ def parse(self, fileName): self.dispatch(tokens) f.close() - self.newLayer(-1.0) + self.newLayer(-1.0, -1.0) #print ('---------- build ------------') #print (' %d slices' % len(self.layers) ) @@ -151,14 +155,13 @@ def parse(self, fileName): for layerNum,layer in enumerate(self.layers): - layerName = self.obName + '_slice_%d' % layerNum curveData = bpy.data.curves.new(layerName, type='CURVE') curveData.dimensions = '3D' curveData.bevel_object = profileObject #print (layerName + ':') - for poly in layer: + for poly in self.layers[layer]: pointNum = 0 for point in poly: if pointNum == 0: @@ -202,15 +205,20 @@ def newPoly(self): self.polys.append( self.points[:] ) self.points = [] - ##### newLayer ##### - def newLayer(self, delta): + ##### newLayer ##### // zetta + def newLayer(self, delta, zetta): # stash existing points into curve self.newPoly() # stash existing set of polys into layer if len(self.polys) > 0: #print( 'new layer with %d polys' % len(self.polys) ) - self.layers.append( self.polys[:] ) + if zetta in self.layers: + t = self.layers[zetta] + t.extend( self.polys[:] ) + self.layers[zetta] = t + else: + self.layers[zetta] = self.polys[:] self.polys = [] @@ -220,16 +228,30 @@ def newLayer(self, delta): else: self.thickness[delta] = 1 - ##### moveTo ##### + ##### moveTo ##### modificat E newlayer def moveTo(self, newPos): if newPos['Z'] != self.pos['Z']: delta = newPos['Z'] - self.pos['Z'] - self.newLayer(delta) + zetta = self.pos['Z'] + self.newLayer(delta, zetta) - if newPos['E'] <= self.pos['E'] or newPos['E'] <= 0.0: - self.newPoly() + # modificat or newPos['E'] <= self.pos['E'] + if self.Prusa: + if newPos['E'] is None or newPos['E'] <= 0.0: + self.newPoly() + else: + if newPos['E'] is None or newPos['E'] <= 0.0 or newPos['E'] <= self.pos['E']: + self.newPoly() - if newPos['E'] > 0 and newPos['E'] >= self.pos['E']: + # modificat or and newPos['E'] >= self.pos['E'] + if newPos['E'] is not None and newPos['E'] > 0 : + # adaugat conditii x, y, z + if newPos['Z'] is None : + newPos['Z']=self.pos['Z'] + if newPos['X'] is None : + newPos['X']=self.pos['X'] + if newPos['Y'] is None : + newPos['Y']=self.pos['Y'] self.points.append([newPos['X'], newPos['Y'], newPos['Z']]) @@ -275,6 +297,10 @@ def G1(self, tokens): '''move to''' self.G0(tokens) + def G4(self, tokens): + '''wait''' + pass + def G21(self,tokens): '''set units mm''' pass @@ -292,6 +318,10 @@ def G28(self, tokens): # no matter what we won't be extruding npos['E'] = 0.0 self.moveTo(npos) + + def G80(self, tokens): + '''Mesh-based Z probe''' + pass def G90(self, tokens): '''set absolute positioning''' @@ -308,11 +338,19 @@ def G92(self, tokens): self.newPoly() self.pos = newPos + + def M73(self, tokens): + '''Set Print Progress''' + pass def M82(self, tokens): '''set extruder absolute mode''' pass + def M83(self, tokens): + '''E Relative''' + pass + def M84(self, tokens): '''stop idle hold''' pass @@ -332,7 +370,38 @@ def M107(self,tokens): def M109(self,tokens): '''set extruder temperature and wait''' pass - + def M115(self,tokens): + '''Firmware Info''' + pass + def M140(self,tokens): + '''Set Bed Temperature''' + pass + def M190(self,tokens): + '''Wait for Bed Temperature''' + pass + def M201(self,tokens): + '''Set Print Max Acceleration''' + pass + def M203(self,tokens): + '''Set Max Feedrate''' + pass + def M204(self,tokens): + '''Set Starting Acceleration''' + pass + def M205(self,tokens): + '''Set Advanced Settings''' + pass + def M221(self,tokens): + '''Set Flow Percentage''' + pass + def M900(self,tokens): + '''Linear Advance Factor''' + pass + def M907(self,tokens): + '''Set Motor Current''' + pass + def M862(self,tokens): + '''PRUSA FW''' @@ -352,9 +421,9 @@ def unregister(): classes = ( IMPORT_OT_gcode, ) - from bpy.utils import register_class + from bpy.utils import unregister_class for cls in classes: - register_class(cls) + unregister_class(cls) bpy.types.TOPBAR_MT_file_import.remove(menu_func) if __name__ == "__main__":