Cura: Fix selection of which start/end gcode to choose

So far the plugin selected the gcode script corresponding to the number of
extruders configured in the printer profile. After a close look into the
implementation in Cura itself, prompted by #1708, it turns out that this is
in fact wrong.

Cura selects the gcode script to use based on the maximum of the number of
extruders needed for printing the models in the scene and the minimum number
of extruders needed for generating support (if support extruder is "both" or "first"
or there is only one extruder, that's 1, if it's "second" and there is more than one
extruder, it's 2).

This commit changes the plugin's implementation to mirror this implementation.
The difference to Cura is that we have the number of extruders needed for the
models in the scene hard coded to 1 since we only support STL right now which
can never contain more than one object. If we ever decide to support merging of
multiple STLs into one single multi-extruder print or other model files like AMF
or OBJ from OctoPrint's slicer support, we need to change this.
This commit is contained in:
Gina Häußge 2017-01-13 12:54:01 +01:00
parent 95e4ad82b4
commit 20cd13904d
2 changed files with 35 additions and 20 deletions

View file

@ -246,11 +246,11 @@ class CuraPlugin(octoprint.plugin.SlicerPlugin,
machinecode_path = path + ".gco"
if position and isinstance(position, dict) and "x" in position and "y" in position:
posX = position["x"]
posY = position["y"]
pos_x = position["x"]
pos_y = position["y"]
else:
posX = None
posY = None
pos_x = None
pos_y = None
if on_progress:
if not on_progress_args:
@ -266,8 +266,24 @@ class CuraPlugin(octoprint.plugin.SlicerPlugin,
working_dir = os.path.dirname(executable)
slicing_profile = Profile(self._load_profile(profile_path), printer_profile, posX, posY)
engine_settings = self._convert_to_engine(profile_path, printer_profile, posX, posY)
slicing_profile = Profile(self._load_profile(profile_path), printer_profile, pos_x, pos_y)
# NOTE: We can assume an extruder count of 1 here since the only way we currently
# support dual extrusion in this implementation is by using the second extruder for support (which
# the engine conversion will automatically detect and adapt accordingly).
#
# We currently do only support STL files as sliceables, which by default can only contain one mesh,
# so no risk of having to slice multi-objects at the moment, which would necessitate a full analysis
# of the objects to slice to determine amount of needed extruders to use here. If we ever decide to
# also support dual extrusion slicing (including composition from multiple STLs or support for OBJ or
# AMF files and the like), this code needs to be adapted!
#
# The extruder count is needed to decide which start/end gcode will be used from the Cura profile.
# Stock Cura implementation counts the number of objects in the scene for this (and also takes a look
# at the support usage, like the engine conversion here does). We only ever have one object.
engine_settings = self._convert_to_engine(profile_path, printer_profile,
pos_x=pos_x, pos_y=pos_y,
used_extruders=1)
# Start building the argument list for the CuraEngine command execution
args = [executable, '-v', '-p']
@ -443,9 +459,9 @@ class CuraPlugin(octoprint.plugin.SlicerPlugin,
with octoprint.util.atomic_write(path, "wb", max_permissions=0o666) as f:
yaml.safe_dump(profile, f, default_flow_style=False, indent=" ", allow_unicode=True)
def _convert_to_engine(self, profile_path, printer_profile, posX, posY):
profile = Profile(self._load_profile(profile_path), printer_profile, posX, posY)
return profile.convert_to_engine()
def _convert_to_engine(self, profile_path, printer_profile, pos_x=None, pos_y=None, used_extruders=1):
profile = Profile(self._load_profile(profile_path), printer_profile, pos_x, pos_y)
return profile.convert_to_engine(used_extruders=used_extruders)
def _sanitize_name(name):
if name is None:

View file

@ -674,9 +674,7 @@ class Profile(object):
return default
return int(value * 1000)
def get_gcode_template(self, key):
extruder_count = self.get_int("extruder_amount")
def get_gcode_template(self, key, extruder_count=1):
if key in self._profile:
gcode = self._profile[key]
else:
@ -736,7 +734,7 @@ class Profile(object):
return pre + str(f)
def get_gcode(self, key):
def get_gcode(self, key, extruder_count=1):
prefix = ""
postfix = ""
@ -746,11 +744,11 @@ class Profile(object):
return ""
if key == "start_gcode":
contents = self.get_gcode_template("start_gcode")
contents = self.get_gcode_template("start_gcode", extruder_count=extruder_count)
prefix += self.get_start_gcode_prefix(contents)
else:
contents = self.get_gcode_template(key)
contents = self.get_gcode_template(key, extruder_count=extruder_count)
return unicode(prefix + re.sub("(.)\{([^\}]*)\}", self.replaceTagMatch, contents).rstrip() + '\n' + postfix).strip().encode('utf-8') + '\n'
@ -861,13 +859,14 @@ class Profile(object):
return int(self.get_float("machine_depth") / 2.0) if not self.get_boolean("machine_center_is_zero") else 0.0
def convert_to_engine(self):
def convert_to_engine(self, used_extruders=1):
edge_width, line_count = self.calculate_edge_width_and_line_count()
solid_layer_count = self.calculate_solid_layer_count()
extruder_count = self.get_int("extruder_amount")
minimal_extruder_count = self.calculate_minimal_extruder_count()
actual_extruder_count = max(minimal_extruder_count, used_extruders)
settings = {
"layerThickness": self.get_microns("layer_height"),
@ -916,10 +915,10 @@ class Profile(object):
"posy": self.get_pos_y() * 1000, # in microns
# gcodes
"startCode": self.get_gcode("start_gcode"),
"endCode": self.get_gcode("end_gcode"),
"preSwitchExtruderCode": self.get_gcode("preSwitchExtruder_gcode"),
"postSwitchExtruderCode": self.get_gcode("postSwitchExtruder_gcode"),
"startCode": self.get_gcode("start_gcode", extruder_count=actual_extruder_count),
"endCode": self.get_gcode("end_gcode", extruder_count=actual_extruder_count),
"preSwitchExtruderCode": self.get_gcode("preSwitchExtruder_gcode", extruder_count=actual_extruder_count),
"postSwitchExtruderCode": self.get_gcode("postSwitchExtruder_gcode", extruder_count=actual_extruder_count),
# fixing
"fixHorrible": 0,