Inhalt
See also this ultimaker forum thread: http://ultimaker.com/en/community/35622-curaengine-command-line-use-cura-profiles-instead-of-s-options (dead link, seems to be moved to: https://community.ultimaker.com/topic/16462-curaengine-command-line-use-cura-profiles-instead-of-s-options).
This is a python helper script to use CURA (-GUI) created printer- and materialprofiles when working with CuraEngine from the commandline. You can download it here: http://github.com/ErwinRieger/ddprint/tree/master/scripts.
I'm using it on a Debian Jessie Linux system together with CURA 2.3 to call openscad and CuraEngine from a Makefile.
Calling CuraEngine: so many parameters
CuraEngine is the slicer part of the Ultimaker CURA software package (http://ultimaker.com/en/products/cura-software) and it is executed everytime the CURA GUI wants to slice the 3D model.
To specify the various slicing parameters, CURA uses a huge amount of -s options (up to hundreds) when calling CuraEngine, you can see them in the CURA logfile (stored in $HOME/.local/share/cura/cura.log). It looks like this:
-s acceleration_print="3000" -s travel="0" -s top_bottom_thickness="0.6" -s acceleration_layer_0="3000" -s acceleration_wall="3000" -s machine_settings="0" -s blackmagic="0" -s bottom_thickness="0.6" -s infill_overlap="10" -s infill="0" -s raft_jerk="20" -s acceleration_support="3000" -s wireframe_flow="100" -s machine_head_polygon="[[-1, 1], [-1, -1], [1, -1], [1, 1]]" -s speed="0" -s top_thickness="0.6" -s raft_fan_speed="0" -s speed_support="100" -s experimental="0" -s meshfix="0" -s support_z_distance="0.1" -s wall_line_width="0.8" -s cool_fan_speed="100.0" -s skin_overlap="5" -s line_width="0.8" -s raft_acceleration="3000" -s wall_thickness="1.2" -s support_extruder_nr="0" -s support_interface_height="1" -s jerk_print="20" -s wireframe_nozzle_clearance="1" -s wireframe_roof_drag_along="0.8" -s wireframe_roof_fall_down="2" -s wireframe_straight_before_down="20" -s wireframe_strategy="compensate" -s wireframe_drag_along="0.6" -s wireframe_top_jump="0.6" -s wireframe_flat_delay="0.1" \
-s support_infill_rate="15" -s jerk_support="20" -s wireframe_top_delay="0" -s wireframe_flow_flat="100" -s wireframe_flow_connection="100" -s wireframe_printspeed_flat="5" -s brim_width="8.0" -s wireframe_printspeed_up="5" -s wireframe_printspeed_bottom="5" -s wireframe_height="3" -s magic_fuzzy_skin_thickness="0.3" -s magic_fuzzy_skin_enabled="False" -s support_conical_angle="30" -s support_conical_enabled="False" -s cool_fan_full_at_height="0.9" -s skin_outline_count="0" -s coasting_min_volume="0.8" -s coasting_volume="0.064" -s coasting_enable="False" -s draft_shield_height_limitation="full" -s draft_shield_enabled="False" -s magic_mesh_surface_mode="normal" -s material="0" -s infill_mesh="False" -s print_sequence="all_at_once" -s meshfix_union_all_remove_holes="False" -s meshfix_union_all="True" -s ooze_shield_enabled="False" -s prime_tower_flow="100" -s wireframe_roof_outer_delay="0.2" -s prime_tower_position_y="200" -s prime_tower_enable="False" -s raft_base_fan_speed="0" -s cooling="0" \
-s raft_interface_fan_speed="0" -s raft_surface_fan_speed="0" -s raft_base_jerk="20" -s raft_interface_acceleration="3000" -s magic_fuzzy_skin_point_dist="0.8" -s retraction_count_max="90" -s bottom_layers="3" -s cool_fan_enabled="True" -s retraction_min_travel="1.6" -s retraction_amount="6.5" -s retraction_enable="True" -s material_diameter="2.85" -s machine_max_acceleration_z="100" -s support_join_distance="2.0" -s material_extrusion_cool_down_speed="0.5" -s resolution="0" -s coasting_speed="90" -s infill_pattern="grid" -s acceleration_topbottom="3000" -s material_flow_dependent_temperature="False" -s raft_base_speed="37.5" -s travel_compensate_overlapping_walls_enabled="True" -s infill_before_walls="True" -s switch_extruder_retraction_speed="20" -s machine_head_with_fans_polygon="[[-42, 12], [-42, -32], [62, 12], [62, -32]]" -s support_interface_enable="False" -s infill_sparse_thickness="0.25" -s material_standby_temperature="150" -s support_type="everywhere" -s wireframe_bottom_delay="0" \
-s gantry_height="48" -s layer_0_z_overlap="0.15" -s retraction_hop_enabled="False" -s meshfix_keep_open_polygons="False" -s gradual_infill_step_height="5.0" -s wireframe_roof_inset="3" -s support_line_distance="5.333333333333333" -s speed_wall="100" -s speed_wall_0="100" -s jerk_prime_tower="20" -s speed_print="100" -s skin_no_small_gaps_heuristic="True" -s material_flow="100" -s skirt_brim_speed="30" -s xy_offset="0" -s jerk_infill="20" -s travel_compensate_overlapping_walls_x_enabled="True" -s skin_overlap_mm="0.04" -s speed_equalize_flow_enabled="False" -s raft_interface_speed="37.5" -s wall_0_inset="0" -s speed_wall_x="100" -s top_bottom_pattern="lines" -s cool_fan_speed_max="100.0" -s retraction_prime_speed="25" -s acceleration_wall_0="3000" -s retraction_speed="25" -s speed_infill="100" -s wall_line_count="1" -s cool_min_layer_time="5" -s prime_tower_line_width="0.8" -s infill_line_distance="10.666666666666666" -s jerk_support_infill="20" -s switch_extruder_retraction_speeds="20" \
-s prime_tower_size="0" -s switch_extruder_retraction_amount="16" -s retraction_extrusion_window="0" -s wireframe_enabled="False" -s cool_fan_speed_min="100.0" -s support_interface_extruder_nr="0" -s machine_min_cool_heat_time_window="50.0" -s machine_nozzle_tip_outer_diameter="1" -s magic_spiralize="False" -s infill_wipe_dist="0.2" -s extruder_prime_pos_z="0" -s raft_base_line_width="1.6" -s machine_nozzle_head_distance="3" -s machine_acceleration="3000" -s machine_center_is_zero="False" -s skin_alternate_rotation="False" -s acceleration_enabled="False" -s wall_line_width_0="0.8" -s retraction_combing="all" -s machine_nozzle_cool_down_speed="2" -s raft_interface_line_width="1.6" -s meshfix_extensive_stitching="False" -s infill_line_width="0.8" -s multiple_mesh_overlap="0.15" -s raft_surface_jerk="20" -s acceleration_travel="5000" -s wireframe_up_half_speed="0.3" -s speed_topbottom="50.0" -s machine_nozzle_expansion_angle="45" -s machine_gcode_flavor="UltiGCode" -s travel_avoid_distance="0.625" \
-s machine_max_acceleration_x="9000" -s support_line_width="0.8" -s support_top_distance="0.1" -s support_xy_distance_overhang="0.4" -s wireframe_printspeed="5" -s raft_interface_jerk="20" -s skin_line_width="0.8" -s support_interface_density="100" -s prime_tower_wipe_enabled="True" -s support_use_towers="True" -s raft_surface_acceleration="3000" -s z_seam_type="back" -s machine_name="Ultimaker 2" -s jerk_wall="20" -s conical_overhang_angle="50" -s speed_support_infill="100" -s skirt_brim_minimal_length="250" -s material_bed_temperature="60" -s retraction_extra_prime_amount="0" -s material_bed_temp_wait="True" -s gradual_infill_steps="0" -s support_tower_roof_angle="65" -s material_print_temp_wait="True" -s speed_equalize_flow_max="150" -s skirt_gap="3" -s raft_airgap="0.3" -s top_layers="3" -s machine_width="223" -s jerk_travel_layer_0="30.0" -s cool_min_layer_time_fan_speed_max="10" -s material_flow_temp_graph="[[3.5,200],[7.0,240]]" -s retraction_hop_after_extruder_switch="True" -s shell="0" \
-s ooze_shield_dist="2" -s machine_heat_zone_length="16" -s speed_prime_tower="100" -s adhesion_type="skirt" -s machine_nozzle_size="0.8" -s magic_fuzzy_skin_point_density="1.25" -s draft_shield_height="10" -s material_print_temperature="210" -s jerk_topbottom="20" -s alternate_extra_perimeter="False" -s machine_show_variants="False" -s raft_speed="50.0" -s machine_max_acceleration_y="9000" -s extruder_prime_pos_abs="False" -s machine_max_feedrate_x="300" -s machine_max_feedrate_y="300" -s raft_base_acceleration="3000" -s switch_extruder_prime_speed="20" -s acceleration_infill="3000" -s layer_height="0.25" -s speed_print_layer_0="30" -s machine_extruder_count="1" -s acceleration_travel_layer_0="5000.0" -s machine_max_feedrate_z="40" -s machine_max_acceleration_e="10000" -s support_bottom_height="1" -s machine_heated_bed="True" -s machine_max_jerk_xy="20.0" -s acceleration_skirt_brim="3000" -s machine_max_jerk_z="0.4" -s machine_depth="223" -s material_bed_temp_prepend="True" \
-s travel_compensate_overlapping_walls_0_enabled="True" -s machine_max_feedrate_e="45" -s skirt_brim_line_width="0.8" -s support_interface_line_width="0.8" -s brim_line_count="10" -s machine_minimum_feedrate="0.0" -s jerk_layer_0="20" -s support_conical_min_width="5.0" -s layer_height_0="0.3" -s acceleration_print_layer_0="3000" -s speed_support_interface="66.66666666666667" -s cool_fan_full_layer="4" -s speed_travel="250" -s speed_travel_layer_0="75.0" -s support_xy_overrides_z="z_overrides_xy" -s raft_interface_thickness="0.375" -s max_feedrate_z_override="0" -s cool_min_speed="10" -s speed_slowdown_layers="2.0" -s dual="0" -s acceleration_wall_x="3000" -s acceleration_prime_tower="3000" -s support_tower_diameter="3.0" -s acceleration_support_infill="3000" -s jerk_enabled="False" -s platform_adhesion="0" -s machine_max_jerk_e="5.0" -s jerk_wall_0="20" -s jerk_wall_x="20" -s wireframe_printspeed_down="5" -s jerk_support_interface="20" -s speed_layer_0="30" -s jerk_travel="30" \
-s brim_outside_only="True" -s material_print_temp_prepend="True" -s jerk_print_layer_0="20" -s raft_base_thickness="0.36" -s jerk_skirt_brim="20" -s travel_avoid_other_parts="True" -s adhesion_extruder_nr="0" -s wireframe_fall_down="0.5" -s retraction_hop_only_when_collides="False" -s machine_disallowed_areas="[[[-115, 112.5], [-82, 112.5], [-84, 102.5], [-115, 102.5]], [[115, 112.5], [115, 102.5], [110, 102.5], [108, 112.5]], [[-115, -112.5], [-115, -104.5], [-84, -104.5], [-82, -112.5]], [[115, -112.5], [108, -112.5], [110, -104.5], [115, -104.5]]]" -s machine_use_extruder_offset_to_offset_coords="True" -s retraction_hop="1" -s cool_lift_head="False" -s support_pattern="zigzag" -s support_interface_skip_height="0.3" -s support_enable="False" -s support_infill_extruder_nr="0" -s support="0" -s support_bottom_stair_step_height="0.3" -s support_angle="50" -s machine_height="205" -s support_connect_zigzags="True" -s support_xy_distance="0.7" -s support_bottom_distance="0.1" \
-s support_offset="0.2" -s conical_overhang_enabled="False" -s draft_shield_dist="10" -s support_interface_line_distance="0.8" -s infill_sparse_density="15" -s support_roof_height="1" -s support_interface_pattern="concentric" -s infill_mesh_order="0" -s support_minimal_diameter="3.0" -s ooze_shield_angle="60" -s acceleration_support_interface="3000" -s machine_nozzle_heat_up_speed="2" -s retraction_retract_speed="25" -s extruder_prime_pos_x="0" -s extruder_prime_pos_y="0" -s prime_tower_position_x="200" -s raft_margin="15" -s raft_surface_layers="2" -s raft_surface_thickness="0.25" -s wall_line_width_x="0.8" -s raft_surface_line_width="0.8" -s skirt_line_count="1" -s support_extruder_nr_layer_0="0" -s raft_surface_line_spacing="0.8" -s infill_overlap_mm="0.08" -s outer_inset_first="False" -s raft_interface_line_spacing="1.8" -s raft_base_line_spacing="3.2" -s raft_surface_speed="50.0" -g -e0 -s extruder_prime_pos_y="0" -s extruder_prime_pos_z="0" -s machine_extruder_end_pos_y="0" \
-s machine_nozzle_offset_y="0" -s extruder_nr="0" -s machine_nozzle_offset_x="0" -s machine_extruder_end_pos_x="0" -s machine_extruder_start_pos_abs="false" -s machine_extruder_start_pos_x="0" -s extruder_prime_pos_x="0" -s machine_extruder_start_pos_y="0" -s machine_extruder_end_pos_abs="false" -e0 -l "0"
So, to call CuraEngine you could write a shell commandline or better a shell script (or a Makefile) and use the options from cura.log. But this is a very tedious and expensive way of doing it. Every time you change your CURA slicing parameters (stored in CURA Profiles) you have to repeat this step and have to change your script.
I wanted a more elegant and more "single source" way of doing it, and the better way is to use the same profiles that CURA creates/uses.
To do this i have written a little python program cura-engine-wrapper.py (and a small helper script cura-engine-wrapper.sh to call it). It collects the slicing options from various places, constructs the CuraEngine commandline and executes the CuraEngine process.
CURA stores its slicing parameters in several profiles:
- The printer default profile (fdmprinter.def.json): this profile specifies the default values for the slicing parameters. It is located in a subdirectory of the CURA installation ($curaDir/share/cura/resources/definitions/fdmprinter.def.json).
- The machine profile: Parameters for your specific printer, there are predefined machine profiles (for the Ultimaker UM2 for example) or you can define your own machine profile in CURA. In CURA this profile is specified with the Printer selection box. They are stored in the CURA installation folder ($curaDir/share/cura/resources) and in your home directory ($HOME/.local/share/cura) if you have created your own printer profile(s).
- The quality/material profile, corresponding to the Material selection box in the CURA GUI. Like the printer profiles they are stored in the CURA installation folder or in the local cura settings folder in your home directory.
How to use it
Cura-engine-wrapper.py is called like this:
<set environment here>
./cura-engine-wrapper.py <cura-install-folder> <printer-profile-name> <material-profile-name> <stl-inputfile> <gcode-outputfile> [<additionalSettings>]
- cura-install-folder is where CURA is installed (/opt/cura for example).
- printer-profile-name is the name of the printer profile to use like it's called in CURA Gui ("Ultimaker 2 0.80" for example).
- material-profile-name is the name of the quality/material profile to use like it's called in CURA Gui ("advance_08" for example).
- stl-inputfile is the path of the (STL-) file to slice.
- gcode-outputfile is the path where CuraEngine stores its output (gcode-) file.
- With the optional parameter additionalSettings one can overwrite some slicing parameters from the commandline ("{'infill_sparse_density':25,'gradual_infill_steps':4}" for example). Note: this is a single string argument that is evaluated using the python eval statement and should resolve to a dictionary of slicer options (option name is the key and option value ist the value).
Usage example:
$ ls -l cura-engine-wrapper.* test*
-rwxr-xr-x 1 erwin users 10437 Jul 25 09:37 cura-engine-wrapper.py
-rwxr-xr-x 1 erwin users 505 Jul 25 09:18 cura-engine-wrapper.sh
-rw-r--r-- 1 erwin users 1755 Jul 25 09:11 test.stl
$ curaDir=/opt/cura
$ export PYTHONPATH="${curaDir}/lib/python3/dist-packages"
$ export LD_LIBRARY_PATH="${curaDir}/lib"
$ ./cura-engine-wrapper.py "/opt/cura" "Ultimaker 2 0.80" "advance_08" "test.stl" "test.gcode" "{'infill_sparse_density':25,'gradual_infill_steps':4}"
Cura_SteamEngine version DEV
Copyright (C) 2014 David Braam
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
[WARNING] Setting an unregistered setting center_object to true
[WARNING] Unregistered setting mesh_rotation_matrix
[WARNING] Unregistered setting mesh_position_z
[WARNING] Unregistered setting mesh_position_y
[WARNING] Unregistered setting mesh_position_x
[WARNING] -s center_object="true" -s bottom_thickness="0.9" -s wall_thickness="1.6" -s raft_jerk="20" -s machine_head_polygon="[[-1, 1], [-1, -1], [1, -1], [1, 1]]" -s raft_acceleration="3000" -s acceleration_print="3000" -s top_bottom_thickness="0.9" -s blackmagic="0" -s acceleration_wall="3000" -s support_z_distance="0.1" -s meshfix="0" -s line_width="0.8" -s travel="0" -s infill_overlap="=10 if infill_sparse_density < 95 and infill_pattern != 'concentric' else 0" -s machine_settings="0" -s experimental="0" -s speed_support="60" -s infill="0" -s acceleration_support="3000" -s wireframe_flow="100" -s wall_line_width="0.8" -s speed="0" -s skin_overlap="5" -s acceleration_layer_0="3000" -s support_extruder_nr="0" -s cool_fan_speed="100.0" -s raft_fan_speed="0" -s top_thickness="0.9" -s jerk_print="20" -s support_interface_height="1" -s wireframe_nozzle_clearance="1" -s wireframe_roof_drag_along="0.8" -s wireframe_roof_fall_down="2" -s wireframe_straight_before_down="20" -s wireframe_strategy="compensate" ...
Log: i .../UM/PluginRegistry.py (loadPlugin [63]): Loaded plugin XmlMaterialProfile
Log: i .../UM/PluginRegistry.py (loadPlugin [63]): Loaded plugin CuraProfileReader
Log: d .../UM/Settings/ContainerStack.py (deserialize [235]): While deserializing, we got the following container string: Ultimaker 2 0.40_current_settings,ultimaker2_advance_04,normal,empty_material,Ultimaker 2 0.40_variant,ultimaker2,
Log: d .../UM/Settings/ContainerStack.py (deserialize [235]): While deserializing, we got the following container string: Ultimaker 2 #2_current_settings,fdmprinter_advance_025,normal,empty_material,Ultimaker 2 #2_variant,ultimaker2,
Log: d .../UM/Settings/ContainerStack.py (deserialize [235]): While deserializing, we got the following container string: Ultimaker 2+_current_settings,empty_quality_changes,pla_0.4_normal,generic_pla_ultimaker2_plus_0.4_mm,ultimaker2_plus_0.4,ultimaker2_plus,
Log: d .../UM/Settings/ContainerStack.py (deserialize [235]): While deserializing, we got the following container string: Ultimaker 2_current_settings,ultimaker2_advance_08,normal,empty_material,Ultimaker 2_variant,ultimaker2,
Log: d .../UM/Settings/ContainerStack.py (deserialize [235]): While deserializing, we got the following container string: Ultimaker 2 #3_current_settings,empty_quality_changes,normal,empty_material,empty_variant,ultimaker2,
$ ls -rtl test*
-rw-r--r-- 1 erwin users 1755 Jul 25 09:11 test.stl
-rw-r--r-- 1 erwin users 44212 Jul 25 09:44 test.gcode
More possibilities of cura-engine-wrapper.py
There are more ways to use cura-engine-wrapper.py, mainly for debugging reasons.
List available containers/profiles
List all available CURA containers/profile names and its type.
cura-engine-wrapper.py <curapath> -l
Example:
$ ./cura-engine-wrapper.py /opt/cura -l
# containers: 742
container: empty None
container: empty variant
container: empty material
container: empty quality_changes
container: Extruder extruder
container: Printrbot Simple machine
container: Ultimaker 3 machine
container: Ultimaker machine
container: Ultimaker Original+ machine
container: RigidBot machine
container: FDM Printer Base Description machine
.
.
.
container: High Quality quality
container: Draft Print quality
container: High Quality quality
container: High Quality quality
container: Normal Quality quality
container: Fast Print quality
container: Fast Print quality
container: High Quality quality
.
.
.
container: Ultimaker 2 #3_current_settings user
container: Ultimaker 2 0.40_current_settings user
container: Ultimaker 2 0.25 machine
container: Ultimaker 2+ machine
container: Ultimaker 2 0.80 machine
container: Ultimaker 2 0.40 machine
container: Ultimaker 2 test machine
List machine container contents
Dumps the contents of a machine container/profile, useful to determine the available options for <additionalSettings>.
cura-engine-wrapper.py <curapath> -pm <machine name>
Example:
$ ./cura-engine-wrapper.py /opt/cura -pm "Ultimaker 2 0.80"
Machine container:
brim_line_count = 10
material_bed_temp_wait = True
acceleration_support = 3000
skirt_brim_speed = 30
acceleration_print_layer_0 = 3000
support_interface_pattern = concentric
wireframe_bottom_delay = 0
support_join_distance = 2.0
machine_heated_bed = True
cool_fan_speed_min = 100.0
.
.
.
material = 0
wireframe_up_half_speed = 0.3
speed_wall = 60
material_guid =
speed_slowdown_layers = 2
support_xy_distance_overhang = 0.4
List profile contents
Dumps the contents of a quality container/profile, useful to determine the available options for <additionalSettings>.
cura-engine-wrapper.py <curapath> -pp <profile name>
Example:
$ ./cura-engine-wrapper.py /opt/cura -pp "Low Quality"
Profile container:
cool_min_layer_time = 3
wall_thickness = 1
speed_wall_x = 80
speed_wall_0 = 40
speed_topbottom = 30
layer_height = 0.15
infill_sparse_density = 10
speed_infill = 100
Helper script cura-engine-wrapper.sh
This script sets the neccesarry environment variables and calls cura-engine-wrapper.py, usage:
$ ./cura-engine-settings.sh <cura-dir> <machine-profile> <mat-profile> <input-stl> <output-gcode> [<additionalSettings>]
Example usage:
$ ./cura-engine-wrapper.sh /opt/cura "Ultimaker 2 0.80" "advance_08" test.stl test.gcode "{'infill_sparse_density':25,'gradual_infill_steps':4}"
Using cura-engine-wrapper.py from within a Makefile
TODO: show Makefile usage