from __future__ import division
__copyright__ = "Copyright (C) 2013 David Braam - Released under terms of the AGPLv3 License"
-import os, traceback, math, re, zlib, base64, time, sys, platform, glob, string, stat, types
+import os
+import traceback
+import math
+import re
+import zlib
+import base64
+import time
+import sys
+import platform
+import glob
+import string
+import stat
+import types
import cPickle as pickle
import numpy
if sys.version_info[0] < 3:
else:
import configparser as ConfigParser
-from Cura.util import resources
from Cura.util import version
from Cura.util import validators
setting('retraction_minimal_extrusion',0.02, float,'expert', _('Retraction')).setRange(0).setLabel(_("Minimal extrusion before retracting (mm)"), _("The minimal amount of extrusion that needs to be done before retracting again if a retraction needs to happen before this minimal is reached the retraction is ignored.\nThis avoids retraction a lot on the same piece of filament which flattens the filament and causes grinding issues."))
setting('retraction_hop', 0.0, float, 'expert', _('Retraction')).setRange(0).setLabel(_("Z hop when retracting (mm)"), _("When a retraction is done, the head is lifted by this amount to travel over the print. A value of 0.075 works good. This feature has a lot of positive effect on delta towers."))
setting('bottom_thickness', 0.3, float, 'advanced', _('Quality')).setRange(0).setLabel(_("Initial layer thickness (mm)"), _("Layer thickness of the bottom layer. A thicker bottom layer makes sticking to the bed easier. Set to 0.0 to have the bottom layer thickness the same as the other layers."))
-setting('object_sink', 0.0, float, 'advanced', _('Quality')).setLabel(_("Cut off object bottom (mm)"), _("Sinks the object into the platform, this can be used for objects that do not have a flat bottom and thus create a too small first layer."))
+setting('object_sink', 0.0, float, 'advanced', _('Quality')).setRange(0).setLabel(_("Cut off object bottom (mm)"), _("Sinks the object into the platform, this can be used for objects that do not have a flat bottom and thus create a too small first layer."))
#setting('enable_skin', False, bool, 'advanced', _('Quality')).setLabel(_("Duplicate outlines"), _("Skin prints the outer lines of the prints twice, each time with half the thickness. This gives the illusion of a higher print quality."))
setting('overlap_dual', 0.15, float, 'advanced', _('Quality')).setLabel(_("Dual extrusion overlap (mm)"), _("Add a certain amount of overlapping extrusion on dual-extrusion prints. This bonds the different colors better together."))
setting('travel_speed', 150.0, float, 'advanced', _('Speed')).setRange(0.1).setLabel(_("Travel speed (mm/s)"), _("Speed at which travel moves are done, a high quality build Ultimaker can reach speeds of 250mm/s. But some machines might miss steps then."))
setting('solid_top', True, bool, 'expert', _('Infill')).setLabel(_("Solid infill top"), _("Create a solid top surface, if set to false the top is filled with the fill percentage. Useful for cups/vases."))
setting('solid_bottom', True, bool, 'expert', _('Infill')).setLabel(_("Solid infill bottom"), _("Create a solid bottom surface, if set to false the bottom is filled with the fill percentage. Useful for buildings."))
setting('fill_overlap', 15, int, 'expert', _('Infill')).setRange(0,100).setLabel(_("Infill overlap (%)"), _("Amount of overlap between the infill and the walls. There is a slight overlap with the walls and the infill so the walls connect firmly to the infill."))
+setting('support_type', 'Grid', ['Grid', 'Lines'], 'expert', _('Support')).setLabel(_("Structure type"), _("The type of support structure.\nGrid is very strong and can come off in 1 piece, however, sometimes it is too strong.\nLines are single walled lines that break off one at a time. Which is more work to remove, but as it is less strong it does work better on tricky prints."))
setting('support_angle', 60, float, 'expert', _('Support')).setRange(0,90).setLabel(_("Overhang angle for support (deg)"), _("The minimal angle that overhangs need to have to get support. With 0 degree being horizontal and 90 degree being vertical."))
setting('support_fill_rate', 15, int, 'expert', _('Support')).setRange(0,100).setLabel(_("Fill amount (%)"), _("Amount of infill structure in the support material, less material gives weaker support which is easier to remove. 15% seems to be a good average."))
setting('support_xy_distance', 0.7, float, 'expert', _('Support')).setRange(0,10).setLabel(_("Distance X/Y (mm)"), _("Distance of the support material from the print, in the X/Y directions.\n0.7mm gives a nice distance from the print so the support does not stick to the print."))
setting('model_colour2', '#CB3030', str, 'preference', 'hidden').setLabel(_('Model colour (2)'), _('Display color for second extruder'))
setting('model_colour3', '#DDD93C', str, 'preference', 'hidden').setLabel(_('Model colour (3)'), _('Display color for third extruder'))
setting('model_colour4', '#4550D3', str, 'preference', 'hidden').setLabel(_('Model colour (4)'), _('Display color for forth extruder'))
+setting('printing_window', 'Basic', ['Basic'], 'preference', 'hidden').setLabel('Printing window type')
setting('window_maximized', 'True', bool, 'preference', 'hidden')
setting('window_pos_x', '-1', float, 'preference', 'hidden')
#Append the profile string to the end of the GCode, so we can load it from the GCode file later.
postfix = ';CURA_PROFILE_STRING:%s\n' % (getProfileString())
return unicode(prefix + re.sub("(.)\{([^\}]*)\}", replaceTagMatch, alterationContents).rstrip() + '\n' + postfix).strip().encode('utf-8') + '\n'
-
-###### PLUGIN #####
-
-def getPluginConfig():
- try:
- return pickle.loads(str(getProfileSetting('plugin_config')))
- except:
- return []
-
-def setPluginConfig(config):
- putProfileSetting('plugin_config', pickle.dumps(config))
-
-def getPluginBasePaths():
- ret = []
- if platform.system() != "Windows":
- ret.append(os.path.expanduser('~/.cura/plugins/'))
- if platform.system() == "Darwin" and hasattr(sys, 'frozen'):
- ret.append(os.path.normpath(os.path.join(resources.resourceBasePath, "Cura/plugins")))
- else:
- ret.append(os.path.normpath(os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', 'plugins')))
- return ret
-
-def getPluginList():
- ret = []
- for basePath in getPluginBasePaths():
- for filename in glob.glob(os.path.join(basePath, '*.py')):
- filename = os.path.basename(filename)
- if filename.startswith('_'):
- continue
- with open(os.path.join(basePath, filename), "r") as f:
- item = {'filename': filename, 'name': None, 'info': None, 'type': None, 'params': []}
- for line in f:
- line = line.strip()
- if not line.startswith('#'):
- break
- line = line[1:].split(':', 1)
- if len(line) != 2:
- continue
- if line[0].upper() == 'NAME':
- item['name'] = line[1].strip()
- elif line[0].upper() == 'INFO':
- item['info'] = line[1].strip()
- elif line[0].upper() == 'TYPE':
- item['type'] = line[1].strip()
- elif line[0].upper() == 'DEPEND':
- pass
- elif line[0].upper() == 'PARAM':
- m = re.match('([a-zA-Z][a-zA-Z0-9_]*)\(([a-zA-Z_]*)(?::([^\)]*))?\) +(.*)', line[1].strip())
- if m is not None:
- item['params'].append({'name': m.group(1), 'type': m.group(2), 'default': m.group(3), 'description': m.group(4)})
- else:
- print "Unknown item in effect meta data: %s %s" % (line[0], line[1])
- if item['name'] is not None and item['type'] == 'postprocess':
- ret.append(item)
- return ret
-
-def runPostProcessingPlugins(gcodefilename):
- pluginConfigList = getPluginConfig()
- pluginList = getPluginList()
-
- for pluginConfig in pluginConfigList:
- plugin = None
- for pluginTest in pluginList:
- if pluginTest['filename'] == pluginConfig['filename']:
- plugin = pluginTest
- if plugin is None:
- continue
-
- pythonFile = None
- for basePath in getPluginBasePaths():
- testFilename = os.path.join(basePath, pluginConfig['filename'])
- if os.path.isfile(testFilename):
- pythonFile = testFilename
- if pythonFile is None:
- continue
-
- locals = {'filename': gcodefilename}
- for param in plugin['params']:
- value = param['default']
- if param['name'] in pluginConfig['params']:
- value = pluginConfig['params'][param['name']]
-
- if param['type'] == 'float':
- try:
- value = float(value)
- except:
- value = float(param['default'])
-
- locals[param['name']] = value
- try:
- execfile(pythonFile, locals)
- except:
- locationInfo = traceback.extract_tb(sys.exc_info()[2])[-1]
- return "%s: '%s' @ %s:%s:%d" % (str(sys.exc_info()[0].__name__), str(sys.exc_info()[1]), os.path.basename(locationInfo[0]), locationInfo[2], locationInfo[1])
- return None