Skip to content

Commit

Permalink
Cura: Fix selection of which start/end gcode to choose
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
foosel committed Jan 13, 2017
1 parent 95e4ad8 commit 20cd139
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 20 deletions.
34 changes: 25 additions & 9 deletions src/octoprint/plugins/cura/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -246,11 +246,11 @@ def do_slice(self, model_path, printer_profile, machinecode_path=None, profile_p
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:
Expand All @@ -266,8 +266,24 @@ def do_slice(self, model_path, printer_profile, machinecode_path=None, profile_p

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']
Expand Down Expand Up @@ -443,9 +459,9 @@ def _save_profile(self, path, profile, allow_overwrite=True):
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:
Expand Down
21 changes: 10 additions & 11 deletions src/octoprint/plugins/cura/profile.py
Original file line number Diff line number Diff line change
Expand Up @@ -674,9 +674,7 @@ def get_microns(self, key, default=None):
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:
Expand Down Expand Up @@ -736,7 +734,7 @@ def replaceTagMatch(self, m):

return pre + str(f)

def get_gcode(self, key):
def get_gcode(self, key, extruder_count=1):
prefix = ""
postfix = ""

Expand All @@ -746,11 +744,11 @@ def get_gcode(self, key):
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'

Expand Down Expand Up @@ -861,13 +859,14 @@ def get_pos_y(self):

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"),
Expand Down Expand Up @@ -916,10 +915,10 @@ def convert_to_engine(self):
"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,
Expand Down

0 comments on commit 20cd139

Please sign in to comment.