diff --git a/build_linux.sh b/build_linux.sh
index 59a0f824b8..816f1809fe 100755
--- a/build_linux.sh
+++ b/build_linux.sh
@@ -8,7 +8,7 @@ SCRIPT_PATH=$(dirname "$(readlink -f "${0}")")
pushd "${SCRIPT_PATH}" > /dev/null
function usage() {
- echo "Usage: ./${SCRIPT_NAME} [-1][-b][-c][-d][-D][-e][-F][-g][-h][-i][-j N][-J N][-p][-r][-s][-t][-u][-l][-L]"
+ echo "Usage: ./${SCRIPT_NAME} [-1][-b][-c][-d][-D][-e][-F][-g][-h][-i][-j N][-J N][-p][-r][-s][-t][-u][-l][-L] [-- CMAKE_ARGS...]"
echo " -1: limit builds to one core (where possible)"
echo " -j N: limit builds to N cores (where possible)"
echo " -J N: build up to N dependencies at a time, each still using -j jobs (default: 1)"
@@ -29,11 +29,15 @@ function usage() {
echo " -u: install system dependencies (asks for sudo password; build prerequisite)"
echo " -l: use Clang instead of GCC (default: GCC)"
echo " -L: use ld.lld as linker (if available)"
+ echo " -- CMAKE_ARGS...: pass everything after '--' to the cmake configure step of the deps (-d) and OrcaSlicer (-s/-t) builds,"
+ echo " e.g. -DCMAKE_CXX_FLAGS=\"-O2 -march=native\", -DCMAKE_CXX_COMPILER=g++-14, -DCMAKE_EXE_LINKER_FLAGS=-fuse-ld=mold."
+ echo " They come last on the cmake command line, so they override what -l and -L set."
echo "For a first use, you want to './${SCRIPT_NAME} -u'"
echo " and then './${SCRIPT_NAME} -dsi'"
echo "For a GitHub Actions-like Linux build locally, use './${SCRIPT_NAME} -g -istrlL'"
echo "Use './${SCRIPT_NAME} -gF -istrlL' to rebuild the cached runner image first."
echo "Set ORCA_CONTAINER_CLI, ORCA_DOCKER_IMAGE, ORCA_DOCKER_BASE_IMAGE, or ORCA_DOCKER_CMAKE_VERSION to override the container runtime, cached image tag, base image, or CMake version."
+ echo "DEPS_EXTRA_BUILD_ARGS and ORCA_EXTRA_BUILD_ARGS add whitespace-separated cmake configure arguments to the deps and OrcaSlicer builds; prefer '--' for arguments that contain spaces."
}
SLIC3R_PRECOMPILED_HEADERS="ON"
@@ -131,6 +135,20 @@ while getopts ":1j:J:bcCdDeFghiprstulL" opt ; do
esac
done
+# getopts stops at '--'; whatever follows is handed to cmake unchanged.
+if [[ ${OPTIND} -le $# ]] ; then
+ separator_index=$((OPTIND-1))
+ if [[ "${!separator_index}" != "--" ]] ; then
+ echo "Unexpected argument '${!OPTIND}': cmake arguments must follow '--', aborting."
+ exit 1
+ fi
+fi
+shift $((OPTIND-1))
+EXTRA_CMAKE_ARGS=("$@")
+if [[ ${#EXTRA_CMAKE_ARGS[@]} -gt 0 ]] ; then
+ FORWARDED_ARGS+=("--" "${EXTRA_CMAKE_ARGS[@]}")
+fi
+
if [ ${OPTIND} -eq 1 ] ; then
usage
exit 1
@@ -547,7 +565,7 @@ if [[ -n "${BUILD_DEPS}" ]] ; then
BUILD_ARGS+=(-DCMAKE_BUILD_TYPE="${BUILD_CONFIG}")
fi
- print_and_run cmake -S deps -B deps/$BUILD_DIR "${CMAKE_C_CXX_COMPILER_CLANG[@]}" "${CMAKE_LLD_LINKER_ARGS[@]}" "${CMAKE_CCACHE_ARGS[@]}" -G Ninja "${COLORED_OUTPUT}" "${BUILD_ARGS[@]}"
+ print_and_run cmake -S deps -B deps/$BUILD_DIR "${CMAKE_C_CXX_COMPILER_CLANG[@]}" "${CMAKE_LLD_LINKER_ARGS[@]}" "${CMAKE_CCACHE_ARGS[@]}" -G Ninja "${COLORED_OUTPUT}" "${BUILD_ARGS[@]}" "${EXTRA_CMAKE_ARGS[@]}"
# The top-level build runs one dependency at a time by default, which keeps the console
# output readable and lets that dependency's own build use all of CMAKE_BUILD_PARALLEL_LEVEL.
# -J raises the top level instead, and -j still applies in full to every dependency, so the
@@ -593,7 +611,8 @@ if [[ -n "${BUILD_ORCA}" ]] || [[ -n "${BUILD_TESTS}" ]] ; then
-DSLIC3R_PCH=${SLIC3R_PRECOMPILED_HEADERS} \
-DORCA_TOOLS=ON \
"${COLORED_OUTPUT}" \
-"${BUILD_ARGS[@]}"
+"${BUILD_ARGS[@]}" \
+"${EXTRA_CMAKE_ARGS[@]}"
echo "done"
if [[ -n "${BUILD_ORCA}" ]]; then
echo "Building OrcaSlicer ..."
diff --git a/resources/profiles/Goofoo.json b/resources/profiles/Goofoo.json
new file mode 100644
index 0000000000..441e3919ab
--- /dev/null
+++ b/resources/profiles/Goofoo.json
@@ -0,0 +1,89 @@
+{
+ "name": "Goofoo",
+ "version": "02.04.00.01",
+ "force_update": "0",
+ "description": "Goofoo configurations",
+ "machine_model_list": [
+ {
+ "name": "Goofoo GP1",
+ "sub_path": "machine/Goofoo GP1.json"
+ },
+ {
+ "name": "Goofoo TurboM",
+ "sub_path": "machine/Goofoo TurboM.json"
+ },
+ {
+ "name": "Goofoo Velo+",
+ "sub_path": "machine/Goofoo Velo+.json"
+ },
+ {
+ "name": "Goofoo Velo+ Tool",
+ "sub_path": "machine/Goofoo Velo+ Tool.json"
+ }
+ ],
+ "process_list": [
+ {
+ "name": "fdm_process_common",
+ "sub_path": "process/fdm_process_common.json"
+ },
+ {
+ "name": "fdm_process_klipper_common",
+ "sub_path": "process/fdm_process_klipper_common.json"
+ },
+ {
+ "name": "0.20mm Standard @Goofoo GP1",
+ "sub_path": "process/0.20mm Standard @Goofoo GP1.json"
+ },
+ {
+ "name": "0.20mm Standard @Goofoo TurboM",
+ "sub_path": "process/0.20mm Standard @Goofoo TurboM.json"
+ },
+ {
+ "name": "0.20mm Standard @Goofoo Velo+",
+ "sub_path": "process/0.20mm Standard @Goofoo Velo+.json"
+ },
+ {
+ "name": "0.30mm Standard @Goofoo Velo+",
+ "sub_path": "process/0.30mm Standard @Goofoo Velo+.json"
+ },
+ {
+ "name": "0.10mm Standard @Goofoo Velo+",
+ "sub_path": "process/0.10mm Standard @Goofoo Velo+.json"
+ }
+ ],
+ "filament_list": [],
+ "machine_list": [
+ {
+ "name": "fdm_machine_common",
+ "sub_path": "machine/fdm_machine_common.json"
+ },
+ {
+ "name": "fdm_klipper_common",
+ "sub_path": "machine/fdm_klipper_common.json"
+ },
+ {
+ "name": "Goofoo GP1 0.4 nozzle",
+ "sub_path": "machine/Goofoo GP1 0.4 nozzle.json"
+ },
+ {
+ "name": "Goofoo TurboM 0.4 nozzle",
+ "sub_path": "machine/Goofoo TurboM 0.4 nozzle.json"
+ },
+ {
+ "name": "Goofoo Velo+ 0.2 nozzle",
+ "sub_path": "machine/Goofoo Velo+ 0.2 nozzle.json"
+ },
+ {
+ "name": "Goofoo Velo+ 0.4 nozzle",
+ "sub_path": "machine/Goofoo Velo+ 0.4 nozzle.json"
+ },
+ {
+ "name": "Goofoo Velo+ 0.6 nozzle",
+ "sub_path": "machine/Goofoo Velo+ 0.6 nozzle.json"
+ },
+ {
+ "name": "Goofoo Velo+ Tool 0.4",
+ "sub_path": "machine/Goofoo Velo+ Tool 0.4.json"
+ }
+ ]
+}
diff --git a/resources/profiles/Goofoo/Goofoo GP1_cover.png b/resources/profiles/Goofoo/Goofoo GP1_cover.png
new file mode 100644
index 0000000000..1a56866dc0
Binary files /dev/null and b/resources/profiles/Goofoo/Goofoo GP1_cover.png differ
diff --git a/resources/profiles/Goofoo/Goofoo TurboM_cover.png b/resources/profiles/Goofoo/Goofoo TurboM_cover.png
new file mode 100644
index 0000000000..1064bb3b3c
Binary files /dev/null and b/resources/profiles/Goofoo/Goofoo TurboM_cover.png differ
diff --git a/resources/profiles/Goofoo/Goofoo Velo+_cover.png b/resources/profiles/Goofoo/Goofoo Velo+_cover.png
new file mode 100644
index 0000000000..d1e80038c5
Binary files /dev/null and b/resources/profiles/Goofoo/Goofoo Velo+_cover.png differ
diff --git a/resources/profiles/Goofoo/Goofoo-GP1-texture.svg b/resources/profiles/Goofoo/Goofoo-GP1-texture.svg
new file mode 100644
index 0000000000..77c24deac5
--- /dev/null
+++ b/resources/profiles/Goofoo/Goofoo-GP1-texture.svg
@@ -0,0 +1,7 @@
+
\ No newline at end of file
diff --git a/resources/profiles/Goofoo/Goofoo-GP1.stl b/resources/profiles/Goofoo/Goofoo-GP1.stl
new file mode 100644
index 0000000000..09ba1bc44a
Binary files /dev/null and b/resources/profiles/Goofoo/Goofoo-GP1.stl differ
diff --git a/resources/profiles/Goofoo/Goofoo-TurboM-texture.svg b/resources/profiles/Goofoo/Goofoo-TurboM-texture.svg
new file mode 100644
index 0000000000..94343a4d55
--- /dev/null
+++ b/resources/profiles/Goofoo/Goofoo-TurboM-texture.svg
@@ -0,0 +1,7 @@
+
\ No newline at end of file
diff --git a/resources/profiles/Goofoo/Goofoo-TurboM.stl b/resources/profiles/Goofoo/Goofoo-TurboM.stl
new file mode 100644
index 0000000000..79fa370b24
Binary files /dev/null and b/resources/profiles/Goofoo/Goofoo-TurboM.stl differ
diff --git a/resources/profiles/Goofoo/Goofoo-Velo+-texture.svg b/resources/profiles/Goofoo/Goofoo-Velo+-texture.svg
new file mode 100644
index 0000000000..a1fc804f20
--- /dev/null
+++ b/resources/profiles/Goofoo/Goofoo-Velo+-texture.svg
@@ -0,0 +1,6 @@
+
\ No newline at end of file
diff --git a/resources/profiles/Goofoo/Goofoo-Velo+.stl b/resources/profiles/Goofoo/Goofoo-Velo+.stl
new file mode 100644
index 0000000000..db004034e6
Binary files /dev/null and b/resources/profiles/Goofoo/Goofoo-Velo+.stl differ
diff --git a/resources/profiles/Goofoo/machine/Goofoo GP1 0.4 nozzle.json b/resources/profiles/Goofoo/machine/Goofoo GP1 0.4 nozzle.json
new file mode 100644
index 0000000000..d3713b2255
--- /dev/null
+++ b/resources/profiles/Goofoo/machine/Goofoo GP1 0.4 nozzle.json
@@ -0,0 +1,98 @@
+{
+ "type": "machine",
+ "name": "Goofoo GP1 0.4 nozzle",
+ "inherits": "fdm_klipper_common",
+ "from": "system",
+ "setting_id": "x4GJ08PooNDQ8WJj",
+ "instantiation": "true",
+ "nozzle_diameter": [
+ "0.4"
+ ],
+ "default_filament_profile": [
+ "Goofoo ABS @System"
+ ],
+ "printer_model": "Goofoo GP1",
+ "default_print_profile": "0.20mm Standard @Goofoo GP1",
+ "printer_variant": "0.4",
+ "before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\n;[layer_z]\n;G92 E0",
+ "change_filament_gcode": "G5",
+ "layer_change_gcode": ";AFTER_LAYER_CHANGE\n;[layer_z]\n;layer\n;{if layer_num == 2}\n;M106 P1 S255\n;{endif}\nSET_PRINT_STATS_INFO CURRENT_LAYER=[layer_num]\n",
+ "machine_end_gcode": "; End G-code\nEND_PRINT",
+ "machine_pause_gcode": "G5",
+ "machine_start_gcode": "M117 Printing...\nM107 ; Turn off the fan\nG21 ; set units to millimeters\nG90 ; use absolute coordinates\nM83 ; use relative distances for extrusion\nM104 S140\nM190 S[first_layer_bed_temperature] ; wait for bed temp\n;G32 ;Load bed mesh\nG28 ;home\nG29 bed leveling\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nG0 Z2.0 F600;\nG0 X50 Y10 F8000;\nG92 E0.0 ; reset extruder distance position\nG0 Z0.4 F600;\nG1 X100.0 E10 F3000.0 ; intro line\nG92 E0.0 ; reset extruder distance position\nG1 X200.0 E15 F3000.0 ; intro line\nG92 E0.0 ; reset extruder distance position\nG0 Z0.8 F600;\nG1 X100.0 E15 F3000.0 ; intro line\nG1 Z0.4 F600 ;Wipe\nG0 Y12 F6000 ;Wipe\nG1 X100 F6000 ;Wipe\nG0 Y8 F12000 ;Wipe\nG1 X200 F6000 ;Wipe\nG1 X190 Y12 F6000 ;Wipe\nG1 X180 Y8 F6000 ;Wipe\nG1 X170 Y12 F6000 ;Wipe\nG1 X160 Y8 F6000 ;Wipe\nG1 X150 Y12 F6000 ;Wipe\n;G0 Z2.0 F600;\nG92 E0.0 ; reset extruder distance position\n;START_PRINT",
+ "purge_in_prime_tower": "0",
+ "time_lapse_gcode": ";TIMELAPSE_TAKE_FRAME",
+ "printable_height": "250",
+ "printable_area": [
+ "0x0",
+ "250x0",
+ "250x250",
+ "0x250"
+ ],
+ "deretraction_speed": [
+ "0"
+ ],
+ "extruder_clearance_height_to_lid": "140",
+ "extruder_clearance_height_to_rod": "36",
+ "extruder_clearance_radius": "65",
+ "machine_max_acceleration_e": [
+ "20000",
+ "5000"
+ ],
+ "machine_max_acceleration_retracting": [
+ "15000",
+ "5000"
+ ],
+ "machine_max_acceleration_z": [
+ "100",
+ "200"
+ ],
+ "machine_max_jerk_e": [
+ "1",
+ "2.5"
+ ],
+ "machine_max_jerk_x": [
+ "5",
+ "9"
+ ],
+ "machine_max_jerk_y": [
+ "5",
+ "9"
+ ],
+ "machine_max_speed_e": [
+ "25",
+ "25"
+ ],
+ "machine_max_speed_x": [
+ "500",
+ "200"
+ ],
+ "machine_max_speed_y": [
+ "500",
+ "200"
+ ],
+ "machine_max_speed_z": [
+ "12",
+ "12"
+ ],
+ "retract_before_wipe": [
+ "100%"
+ ],
+ "retract_length_toolchange": [
+ "10"
+ ],
+ "retraction_length": [
+ "0.5"
+ ],
+ "retraction_minimum_travel": [
+ "2"
+ ],
+ "retraction_speed": [
+ "50"
+ ],
+ "thumbnails": "300x300/PNG",
+ "z_hop": [
+ "0"
+ ],
+ "upward_compatible_machine": []
+}
\ No newline at end of file
diff --git a/resources/profiles/Goofoo/machine/Goofoo GP1.json b/resources/profiles/Goofoo/machine/Goofoo GP1.json
new file mode 100644
index 0000000000..53f55c7c84
--- /dev/null
+++ b/resources/profiles/Goofoo/machine/Goofoo GP1.json
@@ -0,0 +1,11 @@
+{
+ "type": "machine_model",
+ "name": "Goofoo GP1",
+ "nozzle_diameter": "0.4",
+ "bed_model": "Goofoo-GP1.stl",
+ "bed_texture": "Goofoo-GP1-texture.svg",
+ "family": "Goofoo",
+ "machine_tech": "FFF",
+ "model_id": "V003",
+ "default_materials": "Goofoo ABS @System"
+}
\ No newline at end of file
diff --git a/resources/profiles/Goofoo/machine/Goofoo TurboM 0.4 nozzle.json b/resources/profiles/Goofoo/machine/Goofoo TurboM 0.4 nozzle.json
new file mode 100644
index 0000000000..183d049d39
--- /dev/null
+++ b/resources/profiles/Goofoo/machine/Goofoo TurboM 0.4 nozzle.json
@@ -0,0 +1,54 @@
+{
+ "type": "machine",
+ "name": "Goofoo TurboM 0.4 nozzle",
+ "inherits": "fdm_klipper_common",
+ "from": "system",
+ "setting_id": "Wmdn5zTy1HH93Q5d",
+ "instantiation": "true",
+ "nozzle_diameter": [
+ "0.4"
+ ],
+ "nozzle_type": "brass",
+ "printer_model": "Goofoo TurboM",
+ "printer_variant": "0.4",
+ "default_filament_profile": [
+ "Goofoo ABS @System"
+ ],
+ "default_print_profile": "0.20mm Standard @Goofoo TurboM",
+ "printable_area": [
+ "0x0",
+ "230x0",
+ "230x200",
+ "0x200"
+ ],
+ "extruder_clearance_height_to_lid": "350",
+ "extruder_clearance_height_to_rod": "60",
+ "extruder_clearance_radius": "50",
+ "machine_end_gcode": "M104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nG92 E0.0 ; reset extruder distance position;\nG1 E-1 F2100 ; retract\nG28 X Y; home X Y axis\n;M84 ; disable motors\nM107 ; turn off fan\n;SET_VELOCITY_LIMIT ACCEL_TO_DECEL=4000",
+ "machine_max_jerk_z": [
+ "3",
+ "0.4"
+ ],
+ "machine_start_gcode": "M107 ; Turn off the fan\nG21 ; set units to millimeters\nG90 ; use absolute coordinates\nM83 ; use relative distances for extrusion\n\n\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\n\nG28 ;home\n\nG1 X2 Y10 F3000;\n\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\n\nG1 Z0.28 F240\n\nG92 E0\n\nG1 Y140 E10 F1500 ; prime the nozzle\n\nG1 X2.3 F5000\nG92 E0\n\nG1 Y10 E10 F1200 ; prime the nozzle\n;G0 Z2.0 F600;\nG92 E0.0 ; reset extruder distance position;\nM82\n;SET_PRESSURE_ADVANCE ADVANCE=0.05\n;SET_VELOCITY_LIMIT ACCEL_TO_DECEL=10000\n",
+ "printable_height": "200",
+ "z_hop": [
+ "0"
+ ],
+ "machine_max_speed_e": [
+ "25",
+ "25"
+ ],
+ "machine_max_speed_x": [
+ "500",
+ "200"
+ ],
+ "machine_max_speed_y": [
+ "500",
+ "200"
+ ],
+ "machine_max_speed_z": [
+ "12",
+ "12"
+ ],
+ "upward_compatible_machine": []
+}
\ No newline at end of file
diff --git a/resources/profiles/Goofoo/machine/Goofoo TurboM.json b/resources/profiles/Goofoo/machine/Goofoo TurboM.json
new file mode 100644
index 0000000000..1be44f99d9
--- /dev/null
+++ b/resources/profiles/Goofoo/machine/Goofoo TurboM.json
@@ -0,0 +1,11 @@
+{
+ "type": "machine_model",
+ "name": "Goofoo TurboM",
+ "nozzle_diameter": "0.4",
+ "bed_model": "Goofoo-TurboM.stl",
+ "bed_texture": "Goofoo-TurboM-texture.svg",
+ "family": "Goofoo",
+ "machine_tech": "FFF",
+ "model_id": "V002",
+ "default_materials": "Goofoo ABS @System"
+}
\ No newline at end of file
diff --git a/resources/profiles/Goofoo/machine/Goofoo Velo+ 0.2 nozzle.json b/resources/profiles/Goofoo/machine/Goofoo Velo+ 0.2 nozzle.json
new file mode 100644
index 0000000000..43d8afdc46
--- /dev/null
+++ b/resources/profiles/Goofoo/machine/Goofoo Velo+ 0.2 nozzle.json
@@ -0,0 +1,106 @@
+{
+ "type": "machine",
+ "name": "Goofoo Velo+ 0.2 nozzle",
+ "inherits": "fdm_klipper_common",
+ "from": "system",
+ "setting_id": "wSr6VNECZHekeNRi",
+ "instantiation": "true",
+ "nozzle_diameter": [
+ "0.2"
+ ],
+ "nozzle_type": "hardened_steel",
+ "printer_model": "Goofoo Velo+",
+ "printer_variant": "0.2",
+ "default_filament_profile": [
+ "Goofoo ABS @System"
+ ],
+ "default_print_profile": "0.10mm Standard @Goofoo Velo+",
+ "printable_area": [
+ "0x0",
+ "600x0",
+ "600x500",
+ "0x500"
+ ],
+ "machine_end_gcode": "{if max_layer_z < printable_height}G1 Z{z_offset+min(max_layer_z+2, printable_height)} F600 ; Move print head up{endif}\nG1 X5 Y{print_bed_max[1]*0.8} F{travel_speed*60} ; present print\n{if max_layer_z < printable_height-10}G1 Z{z_offset+min(max_layer_z+70, printable_height-10)} F600 ; Move print head further up{endif}\n{if max_layer_z < max_print_height*0.6}G1 Z{printable_height*0.6} F600 ; Move print head further up{endif}\nM140 S0 ; turn off heatbed\nM104 S0 ; turn off temperature\nM107 ; turn off fan\nM84 X Y E ; disable motors",
+ "printable_height": "600",
+ "before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0",
+ "change_filament_gcode": "PAUSE",
+ "deretraction_speed": [
+ "0"
+ ],
+ "extruder_clearance_height_to_lid": "350",
+ "extruder_clearance_height_to_rod": "60",
+ "extruder_clearance_radius": "50",
+ "machine_max_acceleration_e": [
+ "20000",
+ "5000"
+ ],
+ "machine_max_acceleration_retracting": [
+ "15000",
+ "5000"
+ ],
+ "machine_max_acceleration_z": [
+ "100",
+ "200"
+ ],
+ "machine_max_jerk_e": [
+ "1",
+ "2.5"
+ ],
+ "machine_max_jerk_x": [
+ "5",
+ "9"
+ ],
+ "machine_max_jerk_y": [
+ "5",
+ "9"
+ ],
+ "machine_max_speed_e": [
+ "50",
+ "25"
+ ],
+ "machine_max_speed_x": [
+ "730",
+ "200"
+ ],
+ "machine_max_speed_y": [
+ "730",
+ "200"
+ ],
+ "machine_max_speed_z": [
+ "15",
+ "12"
+ ],
+ "machine_start_gcode": "G90 ; 绝对坐标模式\nM83 ; 挤出机相对模式\nM140 S[first_layer_bed_temperature] ; 设置热床温度\nM104 S140 ; 临时喷嘴温度=切片首层设定(防止归零渗料)\nG4 S10 ; 预热等待10秒\nG28 ; 归零所有轴\nG1 Z50 F240 ; Z轴抬升\nG1 X2 Y10 F3000 ; 移动至起始位置\nM104 S[nozzle_temperature_initial_layer] ; 正式设置喷嘴温度(与切片设置一致)\nM190 S[bed_temperature_initial_layer_single] ; 等待热床温度稳定\nM109 S[nozzle_temperature_initial_layer] ; 等待喷嘴温度稳定\nG1 Z0.28 F240 ; 喷嘴下降至打印高度\nG92 E0 ; 挤出机归零\nG1 Y140 E10 F1500 ; 画第一条 priming 线\nG1 X2.3 F5000 ; X轴微调\nG92 E0 ; 挤出机归零\nG1 Y10 E10 F1200 ; 画第二条 priming 线\nG92 E0 ; 最终挤出机归零",
+
+ "retract_before_wipe": [
+ "100%"
+ ],
+ "retract_length_toolchange": [
+ "10"
+ ],
+ "retraction_length": [
+ "0.5"
+ ],
+ "retraction_minimum_travel": [
+ "2"
+ ],
+ "retraction_speed": [
+ "50"
+ ],
+ "thumbnails": "300x300/PNG",
+ "z_hop": [
+ "0"
+ ],
+ "machine_max_acceleration_travel": [
+ "10000",
+ "10000"
+ ],
+ "max_layer_height": [
+ "0.16"
+ ],
+ "min_layer_height": [
+ "0.04"
+ ],
+ "upward_compatible_machine": []
+}
\ No newline at end of file
diff --git a/resources/profiles/Goofoo/machine/Goofoo Velo+ 0.4 nozzle.json b/resources/profiles/Goofoo/machine/Goofoo Velo+ 0.4 nozzle.json
new file mode 100644
index 0000000000..b334146d6a
--- /dev/null
+++ b/resources/profiles/Goofoo/machine/Goofoo Velo+ 0.4 nozzle.json
@@ -0,0 +1,100 @@
+{
+ "type": "machine",
+ "name": "Goofoo Velo+ 0.4 nozzle",
+ "inherits": "fdm_klipper_common",
+ "from": "system",
+ "setting_id": "XzHz1vNOYg3Ofe8X",
+ "instantiation": "true",
+ "nozzle_diameter": [
+ "0.4"
+ ],
+ "nozzle_type": "hardened_steel",
+ "printer_model": "Goofoo Velo+",
+ "printer_variant": "0.4",
+ "default_filament_profile": [
+ "Goofoo ABS @System"
+ ],
+ "default_print_profile": "0.20mm Standard @Goofoo Velo+",
+ "printable_area": [
+ "0x0",
+ "600x0",
+ "600x500",
+ "0x500"
+ ],
+ "machine_end_gcode": "{if max_layer_z < printable_height}G1 Z{z_offset+min(max_layer_z+2, printable_height)} F600 ; Move print head up{endif}\nG1 X5 Y{print_bed_max[1]*0.8} F{travel_speed*60} ; present print\n{if max_layer_z < printable_height-10}G1 Z{z_offset+min(max_layer_z+70, printable_height-10)} F600 ; Move print head further up{endif}\n{if max_layer_z < max_print_height*0.6}G1 Z{printable_height*0.6} F600 ; Move print head further up{endif}\nM140 S0 ; turn off heatbed\nM104 S0 ; turn off temperature\nM107 ; turn off fan\nM84 X Y E ; disable motors",
+ "printable_height": "600",
+ "before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0",
+ "change_filament_gcode": "PAUSE",
+ "deretraction_speed": [
+ "0"
+ ],
+ "extruder_clearance_height_to_lid": "350",
+ "extruder_clearance_height_to_rod": "60",
+ "extruder_clearance_radius": "50",
+ "machine_max_acceleration_e": [
+ "20000",
+ "5000"
+ ],
+ "machine_max_acceleration_retracting": [
+ "15000",
+ "5000"
+ ],
+ "machine_max_acceleration_z": [
+ "100",
+ "200"
+ ],
+ "machine_max_jerk_e": [
+ "1",
+ "2.5"
+ ],
+ "machine_max_jerk_x": [
+ "5",
+ "9"
+ ],
+ "machine_max_jerk_y": [
+ "5",
+ "9"
+ ],
+ "machine_max_speed_e": [
+ "50",
+ "25"
+ ],
+ "machine_max_speed_x": [
+ "730",
+ "200"
+ ],
+ "machine_max_speed_y": [
+ "730",
+ "200"
+ ],
+ "machine_max_speed_z": [
+ "15",
+ "12"
+ ],
+ "machine_start_gcode": "G90 ; 绝对坐标模式\nM83 ; 挤出机相对模式\nM140 S[first_layer_bed_temperature] ; 设置热床温度\nM104 S140 ; 临时喷嘴温度=切片首层设定(防止归零渗料)\nG4 S10 ; 预热等待10秒\nG28 ; 归零所有轴\nG1 Z50 F240 ; Z轴抬升\nG1 X2 Y10 F3000 ; 移动至起始位置\nM104 S[nozzle_temperature_initial_layer] ; 正式设置喷嘴温度(与切片设置一致)\nM190 S[bed_temperature_initial_layer_single] ; 等待热床温度稳定\nM109 S[nozzle_temperature_initial_layer] ; 等待喷嘴温度稳定\nG1 Z0.28 F240 ; 喷嘴下降至打印高度\nG92 E0 ; 挤出机归零\nG1 Y140 E10 F1500 ; 画第一条 priming 线\nG1 X2.3 F5000 ; X轴微调\nG92 E0 ; 挤出机归零\nG1 Y10 E10 F1200 ; 画第二条 priming 线\nG92 E0 ; 最终挤出机归零",
+
+ "retract_before_wipe": [
+ "100%"
+ ],
+ "retract_length_toolchange": [
+ "10"
+ ],
+ "retraction_length": [
+ "0.5"
+ ],
+ "retraction_minimum_travel": [
+ "2"
+ ],
+ "retraction_speed": [
+ "50"
+ ],
+ "thumbnails": "300x300/PNG",
+ "z_hop": [
+ "0"
+ ],
+ "machine_max_acceleration_travel": [
+ "10000",
+ "10000"
+ ],
+ "upward_compatible_machine": []
+}
\ No newline at end of file
diff --git a/resources/profiles/Goofoo/machine/Goofoo Velo+ 0.6 nozzle.json b/resources/profiles/Goofoo/machine/Goofoo Velo+ 0.6 nozzle.json
new file mode 100644
index 0000000000..56a0824da8
--- /dev/null
+++ b/resources/profiles/Goofoo/machine/Goofoo Velo+ 0.6 nozzle.json
@@ -0,0 +1,106 @@
+{
+ "type": "machine",
+ "name": "Goofoo Velo+ 0.6 nozzle",
+ "inherits": "fdm_klipper_common",
+ "from": "system",
+ "setting_id": "Pauu7JRq7u2OD6kv",
+ "instantiation": "true",
+ "nozzle_diameter": [
+ "0.6"
+ ],
+ "nozzle_type": "hardened_steel",
+ "printer_model": "Goofoo Velo+",
+ "printer_variant": "0.6",
+ "default_filament_profile": [
+ "Goofoo ABS @System"
+ ],
+ "default_print_profile": "0.30mm Standard @Goofoo Velo+",
+ "printable_area": [
+ "0x0",
+ "600x0",
+ "600x500",
+ "0x500"
+ ],
+ "machine_end_gcode": "{if max_layer_z < printable_height}G1 Z{z_offset+min(max_layer_z+2, printable_height)} F600 ; Move print head up{endif}\nG1 X5 Y{print_bed_max[1]*0.8} F{travel_speed*60} ; present print\n{if max_layer_z < printable_height-10}G1 Z{z_offset+min(max_layer_z+70, printable_height-10)} F600 ; Move print head further up{endif}\n{if max_layer_z < max_print_height*0.6}G1 Z{printable_height*0.6} F600 ; Move print head further up{endif}\nM140 S0 ; turn off heatbed\nM104 S0 ; turn off temperature\nM107 ; turn off fan\nM84 X Y E ; disable motors",
+ "printable_height": "600",
+ "before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0",
+ "change_filament_gcode": "PAUSE",
+ "deretraction_speed": [
+ "0"
+ ],
+ "extruder_clearance_height_to_lid": "350",
+ "extruder_clearance_height_to_rod": "60",
+ "extruder_clearance_radius": "50",
+ "machine_max_acceleration_e": [
+ "20000",
+ "5000"
+ ],
+ "machine_max_acceleration_retracting": [
+ "15000",
+ "5000"
+ ],
+ "machine_max_acceleration_z": [
+ "100",
+ "200"
+ ],
+ "machine_max_jerk_e": [
+ "1",
+ "2.5"
+ ],
+ "machine_max_jerk_x": [
+ "5",
+ "9"
+ ],
+ "machine_max_jerk_y": [
+ "5",
+ "9"
+ ],
+ "machine_max_speed_e": [
+ "50",
+ "25"
+ ],
+ "machine_max_speed_x": [
+ "730",
+ "200"
+ ],
+ "machine_max_speed_y": [
+ "730",
+ "200"
+ ],
+ "machine_max_speed_z": [
+ "15",
+ "12"
+ ],
+ "machine_start_gcode": "G90 ; 绝对坐标模式\nM83 ; 挤出机相对模式\nM140 S[first_layer_bed_temperature] ; 设置热床温度\nM104 S140 ; 临时喷嘴温度=切片首层设定(防止归零渗料)\nG4 S10 ; 预热等待10秒\nG28 ; 归零所有轴\nG1 Z50 F240 ; Z轴抬升\nG1 X2 Y10 F3000 ; 移动至起始位置\nM104 S[nozzle_temperature_initial_layer] ; 正式设置喷嘴温度(与切片设置一致)\nM190 S[bed_temperature_initial_layer_single] ; 等待热床温度稳定\nM109 S[nozzle_temperature_initial_layer] ; 等待喷嘴温度稳定\nG1 Z0.28 F240 ; 喷嘴下降至打印高度\nG92 E0 ; 挤出机归零\nG1 Y140 E10 F1500 ; 画第一条 priming 线\nG1 X2.3 F5000 ; X轴微调\nG92 E0 ; 挤出机归零\nG1 Y10 E10 F1200 ; 画第二条 priming 线\nG92 E0 ; 最终挤出机归零",
+
+ "retract_before_wipe": [
+ "100%"
+ ],
+ "retract_length_toolchange": [
+ "10"
+ ],
+ "retraction_length": [
+ "0.5"
+ ],
+ "retraction_minimum_travel": [
+ "2"
+ ],
+ "retraction_speed": [
+ "50"
+ ],
+ "thumbnails": "300x300/PNG",
+ "z_hop": [
+ "0"
+ ],
+ "machine_max_acceleration_travel": [
+ "10000",
+ "10000"
+ ],
+ "max_layer_height": [
+ "0.4"
+ ],
+ "min_layer_height": [
+ "0.12"
+ ],
+ "upward_compatible_machine": []
+}
\ No newline at end of file
diff --git a/resources/profiles/Goofoo/machine/Goofoo Velo+ Tool 0.4.json b/resources/profiles/Goofoo/machine/Goofoo Velo+ Tool 0.4.json
new file mode 100644
index 0000000000..37872c1e11
--- /dev/null
+++ b/resources/profiles/Goofoo/machine/Goofoo Velo+ Tool 0.4.json
@@ -0,0 +1,152 @@
+{
+ "type": "machine",
+ "name": "Goofoo Velo+ Tool 0.4",
+ "inherits": "Goofoo Velo+ 0.4 nozzle",
+ "from": "system",
+ "setting_id": "ww39WeaF5nYks1em",
+ "instantiation": "true",
+ "nozzle_diameter": [
+ "0.4",
+ "0.4"
+ ],
+ "printer_model": "Goofoo Velo+ Tool",
+ "change_filament_gcode": "T[next_extruder]\n;M104 S[nozzle_temperature_initial_layer] T[next_extruder]; 正式设置喷嘴温度(与切片设置一致)\n;M109 S[nozzle_temperature_initial_layer] T[next_extruder] ; 等待喷嘴温度稳定\n",
+ "default_nozzle_volume_type": [
+ "Standard",
+ "Standard"
+ ],
+ "deretraction_speed": [
+ "0",
+ "0"
+ ],
+ "extruder_colour": [
+ "#FCE94F",
+ "#FCE94F"
+ ],
+ "extruder_offset": [
+ "0x0",
+ "0x0"
+ ],
+ "extruder_printable_height": [
+ "0",
+ "0"
+ ],
+ "extruder_type": [
+ "Direct Drive",
+ "Direct Drive"
+ ],
+ "extruder_variant_list": [
+ "Direct Drive Standard",
+ "Direct Drive Standard"
+ ],
+ "long_retractions_when_cut": [
+ "0",
+ "0"
+ ],
+ "machine_end_gcode": "{if max_layer_z < printable_height}G1 Z{z_offset+min(max_layer_z+2, printable_height)} F600 ; Move print head up{endif}\nT0\nG1 X5 Y{print_bed_max[1]*0.8} F{travel_speed*60} ; present print\n{if max_layer_z < printable_height-10}G1 Z{z_offset+min(max_layer_z+70, printable_height-10)} F600 ; Move print head further up{endif}\n{if max_layer_z < max_print_height*0.6}G1 Z{printable_height*0.6} F600 ; Move print head further up{endif}\nM140 S0 ; turn off heatbed\nM104 S0 ; turn off temperature\nM107 ; turn off fan\nM84 X Y E ; disable motors",
+ "machine_start_gcode": "G90 ; 绝对坐标模式\nM83 ; 挤出机相对模式\nM140 S[first_layer_bed_temperature] ; 设置热床温度\nM104 S140 T0 ; 临时喷嘴温度=切片首层设定(防止归零渗料)\nM104 S140 T1\nG4 S10 ; 预热等待10秒\nG28 ; 归零所有轴\nG1 Z50 F240 ; Z轴抬升\nG1 X2 Y10 F3000 ; 移动至起始位置\nM104 S[nozzle_temperature_initial_layer] T0 ; 正式设置喷嘴温度(与切片设置一致)\nM104 S[nozzle_temperature_initial_layer] T1 ; 正式设置喷嘴温度(与切片设置一致)\nM190 S[bed_temperature_initial_layer_single] T0; 等待热床温度稳定\nM109 S[nozzle_temperature_initial_layer] T0 ; 等待喷嘴温度稳定\nG1 Z0.28 F240 ; 喷嘴下降至打印高度\nG92 E0 ; 挤出机归零\nG1 Y140 E10 F1500 ; 画第一条 priming 线\nG1 X2.3 F5000 ; X轴微调\nG92 E0 ; 挤出机归零\nG1 Y10 E10 F1200 ; 画第二条 priming 线\nG92 E0 ; 最终挤出机归零\nG1 Z20 F240 ; Z轴抬升\nG1 X280 Y10 F3000 ; 移动至起始位置\nT1\nM104 S[nozzle_temperature_initial_layer] T1 ; 正式设置喷嘴温度(与切片设置一致)\nM190 S[bed_temperature_initial_layer_single] T1; 等待热床温度稳定\nM109 S[nozzle_temperature_initial_layer] T1; 等待喷嘴温度稳定\nG4 S10 ; 预热等待10秒\nG1 Z0.28 F240 ; 喷嘴下降至打印高度\nG92 E0 ; 挤出机归零\nG1 Y140 E10 F1500 ; 画第一条 priming 线\nG1 X282.3 F5000 ; X轴微调\nG92 E0 ; 挤出机归零\nG1 Y10 E10 F1200 ; 画第二条 priming 线\nG92 E0 ; 最终挤出机归零",
+ "max_layer_height": [
+ "0.32",
+ "0.32"
+ ],
+ "min_layer_height": [
+ "0.08",
+ "0.08"
+ ],
+ "nozzle_flush_dataset": [
+ "nil",
+ "0"
+ ],
+ "nozzle_type": [
+ "nil",
+ "hardened_steel"
+ ],
+ "nozzle_volume": [
+ "nil",
+ "0"
+ ],
+ "printable_area": [
+ "0x0",
+ "300x0",
+ "300x300",
+ "0x300"
+ ],
+ "printer_extruder_id": [
+ "1",
+ "2"
+ ],
+ "printer_extruder_variant": [
+ "Direct Drive Standard",
+ "Direct Drive Standard"
+ ],
+ "purge_in_prime_tower": "0",
+ "retract_before_wipe": [
+ "100%",
+ "100%"
+ ],
+ "retract_length_toolchange": [
+ "10",
+ "10"
+ ],
+ "retract_lift_above": [
+ "0",
+ "0"
+ ],
+ "retract_lift_below": [
+ "0",
+ "0"
+ ],
+ "retract_lift_enforce": [
+ "All Surfaces",
+ "All Surfaces"
+ ],
+ "retract_restart_extra": [
+ "0",
+ "0"
+ ],
+ "retract_restart_extra_toolchange": [
+ "0",
+ "0"
+ ],
+ "retract_when_changing_layer": [
+ "1",
+ "1"
+ ],
+ "retraction_distances_when_cut": [
+ "18",
+ "18"
+ ],
+ "retraction_length": [
+ "0.5",
+ "0.5"
+ ],
+ "retraction_minimum_travel": [
+ "2",
+ "2"
+ ],
+ "retraction_speed": [
+ "50",
+ "50"
+ ],
+ "single_extruder_multi_material": "0",
+ "travel_slope": [
+ "3",
+ "3"
+ ],
+ "wipe": [
+ "1",
+ "1"
+ ],
+ "wipe_distance": [
+ "1",
+ "1"
+ ],
+ "z_hop": [
+ "0",
+ "0"
+ ],
+ "z_hop_types": [
+ "Slope Lift",
+ "Slope Lift"
+ ]
+}
\ No newline at end of file
diff --git a/resources/profiles/Goofoo/machine/Goofoo Velo+ Tool.json b/resources/profiles/Goofoo/machine/Goofoo Velo+ Tool.json
new file mode 100644
index 0000000000..004352b3b3
--- /dev/null
+++ b/resources/profiles/Goofoo/machine/Goofoo Velo+ Tool.json
@@ -0,0 +1,11 @@
+{
+ "type": "machine_model",
+ "name": "Goofoo Velo+ Tool",
+ "nozzle_diameter": "0.4",
+ "bed_model": "Goofoo-Velo+.stl",
+ "bed_texture": "Goofoo-Velo+-texture.svg",
+ "family": "Goofoo",
+ "machine_tech": "FFF",
+ "model_id": "V006",
+ "default_materials": "Goofoo ABS @System"
+}
\ No newline at end of file
diff --git a/resources/profiles/Goofoo/machine/Goofoo Velo+.json b/resources/profiles/Goofoo/machine/Goofoo Velo+.json
new file mode 100644
index 0000000000..3f60e1738f
--- /dev/null
+++ b/resources/profiles/Goofoo/machine/Goofoo Velo+.json
@@ -0,0 +1,11 @@
+{
+ "type": "machine_model",
+ "name": "Goofoo Velo+",
+ "nozzle_diameter": "0.2;0.4;0.6",
+ "bed_model": "Goofoo-Velo+.stl",
+ "bed_texture": "Goofoo-Velo+-texture.svg",
+ "family": "Goofoo",
+ "machine_tech": "FFF",
+ "model_id": "V001",
+ "default_materials": "Goofoo ABS @System"
+}
\ No newline at end of file
diff --git a/resources/profiles/Goofoo/machine/fdm_klipper_common.json b/resources/profiles/Goofoo/machine/fdm_klipper_common.json
new file mode 100644
index 0000000000..ece1ca5052
--- /dev/null
+++ b/resources/profiles/Goofoo/machine/fdm_klipper_common.json
@@ -0,0 +1,13 @@
+{
+ "type": "machine",
+ "name": "fdm_klipper_common",
+ "inherits": "fdm_machine_common",
+ "from": "system",
+ "instantiation": "false",
+ "gcode_flavor": "klipper",
+ "before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\nG92 E0.0\n;[layer_z]\n\n",
+ "machine_start_gcode": "G90 ; use absolute coordinates\nM83 ; use relative distances for extrusion\nM140 S{first_layer_bed_temperature[0]} ; set bed temp\nM104 S140 ; set temporary nozzle temp to prevent oozing\nG4 S10 ; wait 10s for preheating\nG28 ; home all axes\nG1 Z50 F240 ; raise Z axis\nG1 X2 Y10 F3000 ; move to start position\nM104 S{first_layer_temperature[0]} ; set final nozzle temp\nM190 S{first_layer_bed_temperature[0]} ; wait for bed temp\nM109 S{first_layer_temperature[0]} ; wait for nozzle temp\nG1 Z0.28 F240 ; lower nozzle to print height\nG92 E0 ; reset extrusion distance\nG1 Y140 E10 F1500 ; prime the nozzle\nG1 X2.3 F5000 ; slight X adjustment\nG92 E0 ; reset extrusion distance\nG1 Y10 E10 F1200 ; prime again\nG92 E0 ; final extrusion reset",
+ "machine_end_gcode": "{if max_layer_z < printable_height}G1 Z{z_offset+min(max_layer_z+2, printable_height)} F600 ; Move print head up{endif}\nG1 X5 Y{print_bed_max[1]*0.8} F{travel_speed*60} ; present print\n{if max_layer_z < printable_height-10}G1 Z{z_offset+min(max_layer_z+70, printable_height-10)} F600 ; Move print head further up{endif}\n{if max_layer_z < max_print_height*0.6}G1 Z{printable_height*0.6} F600 ; Move print head further up{endif}\nM140 S0 ; turn off heatbed\nM104 S0 ; turn off temperature\nM107 ; turn off fan\nM84 X Y E ; disable motors",
+ "change_filament_gcode": "PAUSE",
+ "machine_pause_gcode": "PAUSE"
+}
\ No newline at end of file
diff --git a/resources/profiles/Goofoo/machine/fdm_machine_common.json b/resources/profiles/Goofoo/machine/fdm_machine_common.json
new file mode 100644
index 0000000000..bf8f2249cf
--- /dev/null
+++ b/resources/profiles/Goofoo/machine/fdm_machine_common.json
@@ -0,0 +1,118 @@
+{
+ "type": "machine",
+ "name": "fdm_machine_common",
+ "from": "system",
+ "instantiation": "false",
+ "printer_technology": "FFF",
+ "deretraction_speed": [
+ "40"
+ ],
+ "extruder_colour": [
+ "#FCE94F"
+ ],
+ "extruder_offset": [
+ "0x0"
+ ],
+ "gcode_flavor": "marlin",
+ "machine_max_acceleration_e": [
+ "5000"
+ ],
+ "machine_max_acceleration_extruding": [
+ "10000"
+ ],
+ "machine_max_acceleration_retracting": [
+ "1000"
+ ],
+ "machine_max_acceleration_x": [
+ "10000"
+ ],
+ "machine_max_acceleration_y": [
+ "10000"
+ ],
+ "machine_max_acceleration_z": [
+ "500"
+ ],
+ "machine_max_speed_e": [
+ "60"
+ ],
+ "machine_max_speed_x": [
+ "500"
+ ],
+ "machine_max_speed_y": [
+ "500"
+ ],
+ "machine_max_speed_z": [
+ "10"
+ ],
+ "machine_max_jerk_e": [
+ "5"
+ ],
+ "machine_max_jerk_x": [
+ "8"
+ ],
+ "machine_max_jerk_y": [
+ "8"
+ ],
+ "machine_max_jerk_z": [
+ "0.4"
+ ],
+ "machine_min_extruding_rate": [
+ "0"
+ ],
+ "machine_min_travel_rate": [
+ "0"
+ ],
+ "max_layer_height": [
+ "0.32"
+ ],
+ "min_layer_height": [
+ "0.08"
+ ],
+ "printable_height": "250",
+ "extruder_clearance_radius": "65",
+ "extruder_clearance_height_to_rod": "36",
+ "extruder_clearance_height_to_lid": "140",
+ "nozzle_diameter": [
+ "0.4"
+ ],
+ "printer_settings_id": "",
+ "printer_variant": "0.4",
+ "retraction_minimum_travel": [
+ "2"
+ ],
+ "retract_before_wipe": [
+ "70%"
+ ],
+ "retract_when_changing_layer": [
+ "1"
+ ],
+ "retraction_length": [
+ "1"
+ ],
+ "retract_length_toolchange": [
+ "1"
+ ],
+ "z_hop": [
+ "0"
+ ],
+ "retract_restart_extra": [
+ "0"
+ ],
+ "retract_restart_extra_toolchange": [
+ "0"
+ ],
+ "retraction_speed": [
+ "60"
+ ],
+ "single_extruder_multi_material": "1",
+ "change_filament_gcode": "",
+ "wipe": [
+ "1"
+ ],
+ "default_print_profile": "",
+ "machine_start_gcode": "G0 Z20 F9000\nG92 E0; G1 E-10 F1200\nG28\nM970 Q1 A10 B10 C130 K0\nM970 Q1 A10 B131 C250 K1\nM974 Q1 S1 P0\nM970 Q0 A10 B10 C130 H20 K0\nM970 Q0 A10 B131 C250 K1\nM974 Q0 S1 P0\nM220 S100 ;Reset Feedrate\nM221 S100 ;Reset Flowrate\nG29 ;Home\nG90;\nG92 E0 ;Reset Extruder \nG1 Z2.0 F3000 ;Move Z Axis up \nG1 X10.1 Y20 Z0.28 F5000.0 ;Move to start position\nM109 S205;\nG1 X10.1 Y200.0 Z0.28 F1500.0 E15 ;Draw the first line\nG1 X10.4 Y200.0 Z0.28 F5000.0 ;Move to side a little\nG1 X10.4 Y20 Z0.28 F1500.0 E30 ;Draw the second line\nG92 E0 ;Reset Extruder \nG1 X110 Y110 Z2.0 F3000 ;Move Z Axis up",
+ "machine_end_gcode": "M400 ; wait for buffer to clear\nG92 E0 ; zero the extruder\nG1 E-4.0 F3600; retract \nG91\nG1 Z3;\nM104 S0 ; turn off hotend\nM140 S0 ; turn off bed\nM106 S0 ; turn off fan\nG90 \nG0 X110 Y200 F3600 \nprint_end",
+ "layer_change_gcode": ";AFTER_LAYER_CHANGE\n;[layer_z]",
+ "before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0\n",
+ "machine_pause_gcode": "M601"
+}
diff --git a/resources/profiles/Goofoo/process/0.10mm Standard @Goofoo Velo+.json b/resources/profiles/Goofoo/process/0.10mm Standard @Goofoo Velo+.json
new file mode 100644
index 0000000000..edd118bd26
--- /dev/null
+++ b/resources/profiles/Goofoo/process/0.10mm Standard @Goofoo Velo+.json
@@ -0,0 +1,26 @@
+{
+ "type": "process",
+ "name": "0.10mm Standard @Goofoo Velo+",
+ "inherits": "0.20mm Standard @Goofoo Velo+",
+ "from": "system",
+ "setting_id": "dJV4bTrLbOPzW2YB",
+ "instantiation": "true",
+ "compatible_printers": [
+ "Goofoo Velo+ 0.2 nozzle"
+ ],
+ "layer_height": "0.1",
+ "initial_layer_print_height": "0.1",
+ "bottom_shell_layers": "6",
+ "top_shell_layers": "12",
+ "wall_loops": "4",
+ "line_width": "0.22",
+ "initial_layer_line_width": "0.25",
+ "inner_wall_line_width": "0.22",
+ "outer_wall_line_width": "0.22",
+ "sparse_infill_line_width": "0.22",
+ "internal_solid_infill_line_width": "0.22",
+ "top_surface_line_width": "0.22",
+ "support_line_width": "0.22",
+ "support_top_z_distance": "0.1",
+ "support_bottom_z_distance": "0.1"
+}
diff --git a/resources/profiles/Goofoo/process/0.20mm Standard @Goofoo GP1.json b/resources/profiles/Goofoo/process/0.20mm Standard @Goofoo GP1.json
new file mode 100644
index 0000000000..5ee5aae3c6
--- /dev/null
+++ b/resources/profiles/Goofoo/process/0.20mm Standard @Goofoo GP1.json
@@ -0,0 +1,35 @@
+{
+ "type": "process",
+ "name": "0.20mm Standard @Goofoo GP1",
+ "inherits": "fdm_process_klipper_common",
+ "from": "system",
+ "setting_id": "zrscQBUxp6L7BlQ9",
+ "instantiation": "true",
+ "compatible_printers": [
+ "Goofoo GP1 0.4 nozzle"
+ ],
+ "layer_height": "0.2",
+ "accel_to_decel_enable": "0",
+ "bridge_acceleration": "100%",
+ "bridge_speed": "100",
+ "brim_type": "no_brim",
+ "gap_infill_speed": "250",
+ "initial_layer_acceleration": "1000",
+ "initial_layer_infill_speed": "100",
+ "initial_layer_speed": "70",
+ "inner_wall_speed": "250",
+ "internal_bridge_speed": "200%",
+ "internal_solid_infill_speed": "250",
+ "outer_wall_acceleration": "5000",
+ "outer_wall_speed": "100",
+ "overhang_4_4_speed": "0",
+ "reduce_crossing_wall": "1",
+ "skirt_distance": "6",
+ "skirt_height": "1",
+ "skirt_loops": "1",
+ "sparse_infill_pattern": "grid",
+ "sparse_infill_speed": "250",
+ "top_surface_acceleration": "5000",
+ "top_surface_speed": "200",
+ "travel_acceleration": "5000"
+}
\ No newline at end of file
diff --git a/resources/profiles/Goofoo/process/0.20mm Standard @Goofoo TurboM.json b/resources/profiles/Goofoo/process/0.20mm Standard @Goofoo TurboM.json
new file mode 100644
index 0000000000..74812f5de4
--- /dev/null
+++ b/resources/profiles/Goofoo/process/0.20mm Standard @Goofoo TurboM.json
@@ -0,0 +1,67 @@
+{
+ "type": "process",
+ "name": "0.20mm Standard @Goofoo TurboM",
+ "inherits": "fdm_process_klipper_common",
+ "from": "system",
+ "setting_id": "LVXxUtAcYGCY6irA",
+ "instantiation": "true",
+ "compatible_printers": [
+ "Goofoo TurboM 0.4 nozzle"
+ ],
+ "layer_height": "0.2",
+ "bridge_acceleration": "2000",
+ "bridge_speed": "60",
+ "brim_type": "no_brim",
+ "default_acceleration": "10000",
+ "enable_support": "1",
+ "exclude_object": "0",
+ "gap_infill_speed": "200",
+ "infill_anchor": "600%",
+ "infill_combination": "1",
+ "infill_wall_overlap": "15%",
+ "initial_layer_acceleration": "1000",
+ "initial_layer_line_width": "0.45",
+ "initial_layer_speed": "60",
+ "inner_wall_acceleration": "3000",
+ "inner_wall_line_width": "0.42",
+ "inner_wall_speed": "150",
+ "internal_solid_infill_acceleration": "3000",
+ "internal_solid_infill_line_width": "0.42",
+ "internal_solid_infill_speed": "150",
+ "line_width": "0.42",
+ "min_skirt_length": "0",
+ "minimum_sparse_infill_area": "70",
+ "only_one_wall_top": "1",
+ "outer_wall_acceleration": "2500",
+ "outer_wall_line_width": "0.42",
+ "outer_wall_speed": "100",
+ "reduce_crossing_wall": "1",
+ "skirt_distance": "6",
+ "skirt_height": "1",
+ "skirt_loops": "4",
+ "small_perimeter_speed": "200",
+ "sparse_infill_acceleration": "3000",
+ "sparse_infill_line_width": "0.42",
+ "sparse_infill_pattern": "grid",
+ "sparse_infill_speed": "150",
+ "support_base_pattern": "rectilinear",
+ "support_interface_bottom_layers": "-1",
+ "support_interface_pattern": "rectilinear",
+ "support_interface_spacing": "0",
+ "support_interface_speed": "100",
+ "support_interface_top_layers": "3",
+ "support_line_width": "0.35",
+ "support_object_xy_distance": "0.21",
+ "support_speed": "100",
+ "thick_bridges": "1",
+ "top_shell_layers": "6",
+ "top_shell_thickness": "0",
+ "top_surface_acceleration": "2500",
+ "top_surface_line_width": "0.42",
+ "top_surface_speed": "150",
+ "travel_acceleration": "10000",
+ "travel_speed": "200",
+ "wall_generator": "classic",
+ "wall_loops": "2",
+ "wall_sequence": "outer wall/inner wall"
+}
\ No newline at end of file
diff --git a/resources/profiles/Goofoo/process/0.20mm Standard @Goofoo Velo+.json b/resources/profiles/Goofoo/process/0.20mm Standard @Goofoo Velo+.json
new file mode 100644
index 0000000000..68bb4470c6
--- /dev/null
+++ b/resources/profiles/Goofoo/process/0.20mm Standard @Goofoo Velo+.json
@@ -0,0 +1,70 @@
+{
+ "type": "process",
+ "name": "0.20mm Standard @Goofoo Velo+",
+ "inherits": "fdm_process_klipper_common",
+ "from": "system",
+ "setting_id": "iWjynhCcvbF8MWev",
+ "instantiation": "true",
+ "compatible_printers": [
+ "Goofoo Velo+ 0.4 nozzle",
+ "Goofoo Velo+ Tool 0.4"
+ ],
+ "layer_height": "0.2",
+ "initial_layer_print_height": "0.2",
+ "bottom_shell_layers": "3",
+ "top_shell_layers": "6",
+ "bridge_acceleration": "2000",
+ "bridge_speed": "60",
+ "brim_type": "no_brim",
+ "default_acceleration": "10000",
+ "enable_support": "1",
+ "exclude_object": "0",
+ "gap_infill_speed": "200",
+ "infill_anchor": "600%",
+ "infill_combination": "1",
+ "infill_wall_overlap": "15%",
+ "initial_layer_acceleration": "1000",
+ "initial_layer_line_width": "0.45",
+ "initial_layer_speed": "60",
+ "inner_wall_acceleration": "3000",
+ "inner_wall_line_width": "0.42",
+ "inner_wall_speed": "150",
+ "internal_solid_infill_acceleration": "3000",
+ "internal_solid_infill_line_width": "0.42",
+ "internal_solid_infill_speed": "150",
+ "line_width": "0.42",
+ "min_skirt_length": "0",
+ "minimum_sparse_infill_area": "70",
+ "only_one_wall_top": "1",
+ "outer_wall_acceleration": "2500",
+ "outer_wall_line_width": "0.42",
+ "outer_wall_speed": "100",
+ "reduce_crossing_wall": "1",
+ "skirt_distance": "6",
+ "skirt_height": "1",
+ "skirt_loops": "4",
+ "small_perimeter_speed": "200",
+ "sparse_infill_acceleration": "3000",
+ "sparse_infill_line_width": "0.42",
+ "sparse_infill_pattern": "grid",
+ "sparse_infill_speed": "150",
+ "support_base_pattern": "rectilinear",
+ "support_interface_bottom_layers": "-1",
+ "support_interface_pattern": "rectilinear",
+ "support_interface_spacing": "0",
+ "support_interface_speed": "100",
+ "support_interface_top_layers": "3",
+ "support_line_width": "0.35",
+ "support_object_xy_distance": "0.21",
+ "support_speed": "100",
+ "thick_bridges": "1",
+ "top_shell_thickness": "0",
+ "top_surface_acceleration": "2500",
+ "top_surface_line_width": "0.42",
+ "top_surface_speed": "150",
+ "travel_acceleration": "10000",
+ "travel_speed": "300",
+ "wall_generator": "classic",
+ "wall_loops": "2",
+ "wall_sequence": "outer wall/inner wall"
+}
diff --git a/resources/profiles/Goofoo/process/0.30mm Standard @Goofoo Velo+.json b/resources/profiles/Goofoo/process/0.30mm Standard @Goofoo Velo+.json
new file mode 100644
index 0000000000..d25f90484b
--- /dev/null
+++ b/resources/profiles/Goofoo/process/0.30mm Standard @Goofoo Velo+.json
@@ -0,0 +1,13 @@
+{
+ "type": "process",
+ "name": "0.30mm Standard @Goofoo Velo+",
+ "inherits": "fdm_process_klipper_common",
+ "from": "system",
+ "setting_id": "mi8ogYOYpqb2x60z",
+ "instantiation": "true",
+ "compatible_printers": [
+ "Goofoo Velo+ 0.6 nozzle"
+ ],
+ "initial_layer_print_height": "0.3",
+ "layer_height": "0.3"
+}
diff --git a/resources/profiles/Goofoo/process/fdm_process_common.json b/resources/profiles/Goofoo/process/fdm_process_common.json
new file mode 100644
index 0000000000..b95f1c3487
--- /dev/null
+++ b/resources/profiles/Goofoo/process/fdm_process_common.json
@@ -0,0 +1,91 @@
+{
+ "type": "process",
+ "name": "fdm_process_common",
+ "from": "system",
+ "instantiation": "false",
+ "seam_position": "aligned",
+ "resolution": "0.012",
+ "elefant_foot_compensation": "0.2",
+ "precise_outer_wall": "1",
+ "ironing_type": "no ironing",
+ "ironing_speed": "30",
+ "ironing_flow": "10%",
+ "ironing_spacing": "0.15",
+ "reduce_crossing_wall": "1",
+ "max_travel_detour_distance": "0",
+ "detect_overhang_wall": "1",
+ "wall_loops": "3",
+ "top_surface_pattern": "monotonicline",
+ "top_shell_layers": "5",
+ "top_shell_thickness": "0.7",
+ "bottom_surface_pattern": "monotonic",
+ "bottom_shell_layers": "4",
+ "bottom_shell_thickness": "0.5",
+ "sparse_infill_density": "15%",
+ "sparse_infill_pattern": "crosshatch",
+ "infill_wall_overlap": "23%",
+ "infill_direction": "45",
+ "minimum_sparse_infill_area": "15",
+ "infill_combination": "0",
+ "ensure_vertical_shell_thickness": "1",
+ "initial_layer_speed": "50",
+ "initial_layer_infill_speed": "50",
+ "initial_layer_travel_speed": "100%",
+ "outer_wall_speed": "125",
+ "inner_wall_speed": "250",
+ "sparse_infill_speed": "250",
+ "internal_solid_infill_speed": "200",
+ "top_surface_speed": "150",
+ "gap_infill_speed": "150",
+ "support_speed": "125",
+ "support_interface_speed": "80",
+ "enable_overhang_speed": "1",
+ "overhang_1_4_speed": "0",
+ "overhang_2_4_speed": "50",
+ "overhang_3_4_speed": "25",
+ "overhang_4_4_speed": "15",
+ "bridge_speed": "50",
+ "travel_speed": "300",
+ "default_acceleration": "2500",
+ "outer_wall_acceleration": "500",
+ "inner_wall_acceleration": "500",
+ "bridge_acceleration": "500",
+ "travel_acceleration": "2500",
+ "default_jerk": "15",
+ "outer_wall_jerk": "10",
+ "inner_wall_jerk": "15",
+ "infill_jerk": "15",
+ "top_surface_jerk": "12",
+ "initial_layer_jerk": "12",
+ "travel_jerk": "20",
+ "enable_support": "0",
+ "support_type": "normal(auto)",
+ "support_threshold_angle": "30",
+ "support_on_build_plate_only": "0",
+ "raft_layers": "0",
+ "support_filament": "0",
+ "support_interface_filament": "0",
+ "support_top_z_distance": "0.2",
+ "support_base_pattern": "default",
+ "support_base_pattern_spacing": "2.5",
+ "support_interface_top_layers": "2",
+ "support_interface_bottom_layers": "2",
+ "support_interface_spacing": "0.5",
+ "support_object_xy_distance": "0.5",
+ "bridge_no_support": "0",
+ "independent_support_layer_height": "1",
+ "tree_support_branch_angle": "30",
+ "tree_support_wall_count": "0",
+ "skirt_loops": "2",
+ "skirt_distance": "3",
+ "skirt_height": "1",
+ "brim_width": "5",
+ "brim_object_gap": "0.1",
+ "enable_prime_tower": "0",
+ "prime_tower_width": "60",
+ "wipe_tower_no_sparse_layers": "0",
+ "print_sequence": "by layer",
+ "spiral_mode": "0",
+ "reduce_infill_retraction": "1",
+ "filename_format": "{input_filename_base}_{layer_height}mm_{filament_type[0]}_{printer_model}.gcode"
+}
diff --git a/resources/profiles/Goofoo/process/fdm_process_klipper_common.json b/resources/profiles/Goofoo/process/fdm_process_klipper_common.json
new file mode 100644
index 0000000000..2977d9392a
--- /dev/null
+++ b/resources/profiles/Goofoo/process/fdm_process_klipper_common.json
@@ -0,0 +1,23 @@
+{
+ "type": "process",
+ "name": "fdm_process_klipper_common",
+ "inherits": "fdm_process_common",
+ "from": "system",
+ "instantiation": "false",
+ "default_acceleration": "5000",
+ "top_surface_acceleration": "3000",
+ "travel_acceleration": "7000",
+ "inner_wall_acceleration": "5000",
+ "outer_wall_acceleration": "3000",
+ "initial_layer_acceleration": "500",
+ "initial_layer_speed": "50",
+ "initial_layer_infill_speed": "105",
+ "outer_wall_speed": "120",
+ "inner_wall_speed": "200",
+ "internal_solid_infill_speed": "200",
+ "top_surface_speed": "100",
+ "gap_infill_speed": "100",
+ "sparse_infill_speed": "200",
+ "travel_speed": "350",
+ "exclude_object": "1"
+}
diff --git a/resources/profiles/OrcaFilamentLibrary.json b/resources/profiles/OrcaFilamentLibrary.json
index 084a12993f..93694b0824 100644
--- a/resources/profiles/OrcaFilamentLibrary.json
+++ b/resources/profiles/OrcaFilamentLibrary.json
@@ -1,6 +1,6 @@
{
"name": "OrcaFilamentLibrary",
- "version": "02.04.00.15",
+ "version": "02.04.00.16",
"force_update": "0",
"description": "Orca Filament Library",
"filament_list": [
@@ -1396,6 +1396,10 @@
"name": "addnorth ABS rABS",
"sub_path": "filament/addnorth/BBL/addnorth ABS rABS.json"
},
+ {
+ "name": "Goofoo ABS @base",
+ "sub_path": "filament/Goofoo/Goofoo ABS @base.json"
+ },
{
"name": "NIT ABS @System",
"sub_path": "filament/NIT/NIT ABS @System.json"
@@ -1480,6 +1484,10 @@
"name": "Elegoo ASA-CF @base",
"sub_path": "filament/Elegoo/Elegoo ASA-CF @base.json"
},
+ {
+ "name": "Goofoo ASA @base",
+ "sub_path": "filament/Goofoo/Goofoo ASA @base.json"
+ },
{
"name": "Overture ASA @BBL X1",
"sub_path": "filament/Overture/BBL/Overture ASA @BBL X1.json"
@@ -1636,10 +1644,22 @@
"name": "addnorth PVDF Adamant S1",
"sub_path": "filament/addnorth/BBL/addnorth PVDF Adamant S1.json"
},
+ {
+ "name": "Goofoo PA @base",
+ "sub_path": "filament/Goofoo/Goofoo PA @base.json"
+ },
{
"name": "addnorth PA-CF Adura X",
"sub_path": "filament/addnorth/BBL/addnorth PA-CF Adura X.json"
},
+ {
+ "name": "Goofoo PA-CF @base",
+ "sub_path": "filament/Goofoo/Goofoo PA-CF @base.json"
+ },
+ {
+ "name": "Goofoo PA-GF10 @base",
+ "sub_path": "filament/Goofoo/Goofoo PA-GF10 @base.json"
+ },
{
"name": "INSLOGIC PA6-66 @BBL P2S",
"sub_path": "filament/INSLOGIC/BBL/INSLOGIC PA6-66 @BBL P2S.json"
@@ -1712,6 +1732,10 @@
"name": "COEX PCTG PRIME @System",
"sub_path": "filament/COEX/COEX PCTG PRIME @System.json"
},
+ {
+ "name": "Goofoo PE @base",
+ "sub_path": "filament/Goofoo/Goofoo PE @base.json"
+ },
{
"name": "Generic PE-CF @System",
"sub_path": "filament/Generic PE-CF @System.json"
@@ -2176,6 +2200,10 @@
"name": "addnorth PETG rPETG Matte",
"sub_path": "filament/addnorth/BBL/addnorth PETG rPETG Matte.json"
},
+ {
+ "name": "Goofoo PETG @base",
+ "sub_path": "filament/Goofoo/Goofoo PETG @base.json"
+ },
{
"name": "Generic PETG HF @System",
"sub_path": "filament/Generic PETG HF @System.json"
@@ -2236,6 +2264,10 @@
"name": "eSUN PETG @System",
"sub_path": "filament/eSUN/eSUN PETG @System.json"
},
+ {
+ "name": "Goofoo PHA @base",
+ "sub_path": "filament/Goofoo/Goofoo PHA @base.json"
+ },
{
"name": "AliZ PLA @P1-X1",
"sub_path": "filament/AliZ/BBL/AliZ PLA @P1-X1.json"
@@ -3120,6 +3152,10 @@
"name": "addnorth PLA rPLA RE-ADD",
"sub_path": "filament/addnorth/BBL/addnorth PLA rPLA RE-ADD.json"
},
+ {
+ "name": "Goofoo PLA @base",
+ "sub_path": "filament/Goofoo/Goofoo PLA @base.json"
+ },
{
"name": "addnorth PLA X-PLA High Speed",
"sub_path": "filament/addnorth/BBL/addnorth PLA X-PLA High Speed.json"
@@ -3136,6 +3172,10 @@
"name": "addnorth PLA-CF Carbon Fiber",
"sub_path": "filament/addnorth/BBL/addnorth PLA-CF Carbon Fiber.json"
},
+ {
+ "name": "Goofoo PLA-CF @base",
+ "sub_path": "filament/Goofoo/Goofoo PLA-CF @base.json"
+ },
{
"name": "INSLOGIC PLA Pro @BBL P2S",
"sub_path": "filament/INSLOGIC/BBL/INSLOGIC PLA Pro @BBL P2S.json"
@@ -3820,6 +3860,10 @@
"name": "FILL3D PPCF @System",
"sub_path": "filament/FILL3D/FILL3D PPCF @System.json"
},
+ {
+ "name": "Goofoo PP @base",
+ "sub_path": "filament/Goofoo/Goofoo PP @base.json"
+ },
{
"name": "Generic PP-CF @System",
"sub_path": "filament/Generic PP-CF @System.json"
@@ -3840,6 +3884,10 @@
"name": "Bambu PVA @System",
"sub_path": "filament/Bambu/Bambu PVA @System.json"
},
+ {
+ "name": "Goofoo PVA @base",
+ "sub_path": "filament/Goofoo/Goofoo PVA @base.json"
+ },
{
"name": "FDplast SBS @System",
"sub_path": "filament/FDplast/FDplast SBS @System.json"
@@ -4112,6 +4160,14 @@
"name": "addnorth TPU Pro Matte 95A",
"sub_path": "filament/addnorth/BBL/addnorth TPU Pro Matte 95A.json"
},
+ {
+ "name": "Goofoo 90A TPU @base",
+ "sub_path": "filament/Goofoo/Goofoo 90A TPU @base.json"
+ },
+ {
+ "name": "Goofoo 95A TPU @base",
+ "sub_path": "filament/Goofoo/Goofoo 95A TPU @base.json"
+ },
{
"name": "Overture TPU @BBL A1",
"sub_path": "filament/Overture/BBL/Overture TPU @BBL A1.json"
@@ -4156,10 +4212,30 @@
"name": "Overture TPU @System",
"sub_path": "filament/Overture/Overture TPU @System.json"
},
+ {
+ "name": "Goofoo ABS @System",
+ "sub_path": "filament/Goofoo/Goofoo ABS @System.json"
+ },
{
"name": "Elegoo ASA-CF @System",
"sub_path": "filament/Elegoo/Elegoo ASA-CF @System.json"
},
+ {
+ "name": "Goofoo ASA @System",
+ "sub_path": "filament/Goofoo/Goofoo ASA @System.json"
+ },
+ {
+ "name": "Goofoo PA @System",
+ "sub_path": "filament/Goofoo/Goofoo PA @System.json"
+ },
+ {
+ "name": "Goofoo PA-CF @System",
+ "sub_path": "filament/Goofoo/Goofoo PA-CF @System.json"
+ },
+ {
+ "name": "Goofoo PA-GF10 @System",
+ "sub_path": "filament/Goofoo/Goofoo PA-GF10 @System.json"
+ },
{
"name": "Elegoo PC-FR @System",
"sub_path": "filament/Elegoo/Elegoo PC-FR @System.json"
@@ -4176,6 +4252,14 @@
"name": "COEX PCTG PRIME @BBL A1M 0.8 nozzle",
"sub_path": "filament/COEX/BBL/COEX PCTG PRIME @BBL A1M 0.8 nozzle.json"
},
+ {
+ "name": "Goofoo PE @System",
+ "sub_path": "filament/Goofoo/Goofoo PE @System.json"
+ },
+ {
+ "name": "Goofoo PE-CF @base",
+ "sub_path": "filament/Goofoo/Goofoo PE-CF @base.json"
+ },
{
"name": "AliZ PETG-CF @P1-X1",
"sub_path": "filament/AliZ/BBL/AliZ PETG-CF @P1-X1.json"
@@ -4236,10 +4320,26 @@
"name": "Fiberon PETG-ESD @BBL X1",
"sub_path": "filament/Polymaker/BBL/Fiberon PETG-ESD @BBL X1.json"
},
+ {
+ "name": "Goofoo PETG @System",
+ "sub_path": "filament/Goofoo/Goofoo PETG @System.json"
+ },
+ {
+ "name": "Goofoo PETG HF @base",
+ "sub_path": "filament/Goofoo/Goofoo PETG HF @base.json"
+ },
{
"name": "addnorth PETG-CF Rigid X",
"sub_path": "filament/addnorth/BBL/addnorth PETG-CF Rigid X.json"
},
+ {
+ "name": "Goofoo PETG-CF @base",
+ "sub_path": "filament/Goofoo/Goofoo PETG-CF @base.json"
+ },
+ {
+ "name": "Goofoo PHA @System",
+ "sub_path": "filament/Goofoo/Goofoo PHA @System.json"
+ },
{
"name": "COEX PLA @BBL A1M 0.2 nozzle",
"sub_path": "filament/COEX/BBL/COEX PLA @BBL A1M 0.2 nozzle.json"
@@ -4304,6 +4404,14 @@
"name": "Elegoo Rapid PLA+ @System",
"sub_path": "filament/Elegoo/Elegoo Rapid PLA+ @System.json"
},
+ {
+ "name": "Goofoo PLA @System",
+ "sub_path": "filament/Goofoo/Goofoo PLA @System.json"
+ },
+ {
+ "name": "Goofoo PLA-CF @System",
+ "sub_path": "filament/Goofoo/Goofoo PLA-CF @System.json"
+ },
{
"name": "Numakers PLA+ @BBL A1",
"sub_path": "filament/Numakers/BBL/Numakers PLA+ @BBL A1.json"
@@ -5188,9 +5296,61 @@
"name": "COEX PLA+Silk @System",
"sub_path": "filament/COEX/COEX PLA+Silk @System.json"
},
+ {
+ "name": "Goofoo PLA Silk @base",
+ "sub_path": "filament/Goofoo/Goofoo PLA Silk @base.json"
+ },
+ {
+ "name": "Goofoo PP @System",
+ "sub_path": "filament/Goofoo/Goofoo PP @System.json"
+ },
+ {
+ "name": "Goofoo PP-CF @base",
+ "sub_path": "filament/Goofoo/Goofoo PP-CF @base.json"
+ },
+ {
+ "name": "Goofoo PP-GF @base",
+ "sub_path": "filament/Goofoo/Goofoo PP-GF @base.json"
+ },
+ {
+ "name": "Goofoo PVA @System",
+ "sub_path": "filament/Goofoo/Goofoo PVA @System.json"
+ },
{
"name": "Elegoo Rapid TPU 95A @System",
"sub_path": "filament/Elegoo/Elegoo Rapid TPU 95A @System.json"
+ },
+ {
+ "name": "Goofoo 90A TPU @System",
+ "sub_path": "filament/Goofoo/Goofoo 90A TPU @System.json"
+ },
+ {
+ "name": "Goofoo 95A TPU @System",
+ "sub_path": "filament/Goofoo/Goofoo 95A TPU @System.json"
+ },
+ {
+ "name": "Goofoo PE-CF @System",
+ "sub_path": "filament/Goofoo/Goofoo PE-CF @System.json"
+ },
+ {
+ "name": "Goofoo PETG HF @System",
+ "sub_path": "filament/Goofoo/Goofoo PETG HF @System.json"
+ },
+ {
+ "name": "Goofoo PETG-CF @System",
+ "sub_path": "filament/Goofoo/Goofoo PETG-CF @System.json"
+ },
+ {
+ "name": "Goofoo PLA Silk @System",
+ "sub_path": "filament/Goofoo/Goofoo PLA Silk @System.json"
+ },
+ {
+ "name": "Goofoo PP-CF @System",
+ "sub_path": "filament/Goofoo/Goofoo PP-CF @System.json"
+ },
+ {
+ "name": "Goofoo PP-GF @System",
+ "sub_path": "filament/Goofoo/Goofoo PP-GF @System.json"
}
],
"process_list": [],
diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo 90A TPU @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo 90A TPU @System.json
new file mode 100644
index 0000000000..9c4d016d49
--- /dev/null
+++ b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo 90A TPU @System.json
@@ -0,0 +1,9 @@
+{
+ "type": "filament",
+ "name": "Goofoo 90A TPU @System",
+ "inherits": "Goofoo 90A TPU @base",
+ "from": "system",
+ "setting_id": "tjq76AQe9SCzZVo6",
+ "instantiation": "true",
+ "compatible_printers": []
+}
diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo 90A TPU @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo 90A TPU @base.json
new file mode 100644
index 0000000000..d54531f8c7
--- /dev/null
+++ b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo 90A TPU @base.json
@@ -0,0 +1,41 @@
+{
+ "type": "filament",
+ "name": "Goofoo 90A TPU @base",
+ "inherits": "Generic TPU @System",
+ "from": "system",
+ "filament_id": "OFlVOXX3",
+ "instantiation": "false",
+ "fan_cooling_layer_time": [
+ "60"
+ ],
+ "fan_min_speed": [
+ "35"
+ ],
+ "filament_max_volumetric_speed": [
+ "2"
+ ],
+ "hot_plate_temp": [
+ "40"
+ ],
+ "hot_plate_temp_initial_layer": [
+ "40"
+ ],
+ "nozzle_temperature": [
+ "220"
+ ],
+ "nozzle_temperature_initial_layer": [
+ "220"
+ ],
+ "reduce_fan_stop_start_freq": [
+ "0"
+ ],
+ "slow_down_layer_time": [
+ "5"
+ ],
+ "filament_vendor": [
+ "Goofoo"
+ ],
+ "filament_type": [
+ "TPU"
+ ]
+}
diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo 95A TPU @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo 95A TPU @System.json
new file mode 100644
index 0000000000..034e46e5dc
--- /dev/null
+++ b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo 95A TPU @System.json
@@ -0,0 +1,9 @@
+{
+ "type": "filament",
+ "name": "Goofoo 95A TPU @System",
+ "inherits": "Goofoo 95A TPU @base",
+ "from": "system",
+ "setting_id": "2YTvrE1gu1yHHTNM",
+ "instantiation": "true",
+ "compatible_printers": []
+}
diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo 95A TPU @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo 95A TPU @base.json
new file mode 100644
index 0000000000..2847a0d028
--- /dev/null
+++ b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo 95A TPU @base.json
@@ -0,0 +1,38 @@
+{
+ "type": "filament",
+ "name": "Goofoo 95A TPU @base",
+ "inherits": "Generic TPU @System",
+ "from": "system",
+ "filament_id": "OFk50t30",
+ "instantiation": "false",
+ "fan_cooling_layer_time": [
+ "60"
+ ],
+ "fan_min_speed": [
+ "35"
+ ],
+ "hot_plate_temp": [
+ "40"
+ ],
+ "hot_plate_temp_initial_layer": [
+ "40"
+ ],
+ "nozzle_temperature": [
+ "220"
+ ],
+ "nozzle_temperature_initial_layer": [
+ "220"
+ ],
+ "reduce_fan_stop_start_freq": [
+ "0"
+ ],
+ "slow_down_layer_time": [
+ "5"
+ ],
+ "filament_vendor": [
+ "Goofoo"
+ ],
+ "filament_type": [
+ "TPU"
+ ]
+}
diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo ABS @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo ABS @System.json
new file mode 100644
index 0000000000..628ca6e5bd
--- /dev/null
+++ b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo ABS @System.json
@@ -0,0 +1,9 @@
+{
+ "type": "filament",
+ "name": "Goofoo ABS @System",
+ "inherits": "Goofoo ABS @base",
+ "from": "system",
+ "setting_id": "UeINgPGH4eaSJinC",
+ "instantiation": "true",
+ "compatible_printers": []
+}
diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo ABS @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo ABS @base.json
new file mode 100644
index 0000000000..be841b5806
--- /dev/null
+++ b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo ABS @base.json
@@ -0,0 +1,23 @@
+{
+ "type": "filament",
+ "name": "Goofoo ABS @base",
+ "inherits": "Generic ABS @System",
+ "from": "system",
+ "filament_id": "OFd3PmW4",
+ "instantiation": "false",
+ "close_fan_the_first_x_layers": [
+ "1"
+ ],
+ "hot_plate_temp": [
+ "110"
+ ],
+ "hot_plate_temp_initial_layer": [
+ "110"
+ ],
+ "filament_vendor": [
+ "Goofoo"
+ ],
+ "filament_type": [
+ "ABS"
+ ]
+}
diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo ASA @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo ASA @System.json
new file mode 100644
index 0000000000..5b5c7355de
--- /dev/null
+++ b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo ASA @System.json
@@ -0,0 +1,9 @@
+{
+ "type": "filament",
+ "name": "Goofoo ASA @System",
+ "inherits": "Goofoo ASA @base",
+ "from": "system",
+ "setting_id": "9ohqNl44uygTPfS9",
+ "instantiation": "true",
+ "compatible_printers": []
+}
diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo ASA @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo ASA @base.json
new file mode 100644
index 0000000000..3faf0926e2
--- /dev/null
+++ b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo ASA @base.json
@@ -0,0 +1,20 @@
+{
+ "type": "filament",
+ "name": "Goofoo ASA @base",
+ "inherits": "Generic ASA @System",
+ "from": "system",
+ "filament_id": "OFyncHIG",
+ "instantiation": "false",
+ "filament_flow_ratio": [
+ "0.93"
+ ],
+ "hot_plate_temp_initial_layer": [
+ "100"
+ ],
+ "filament_vendor": [
+ "Goofoo"
+ ],
+ "filament_type": [
+ "ASA"
+ ]
+}
diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PA @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PA @System.json
new file mode 100644
index 0000000000..1229eb0e3b
--- /dev/null
+++ b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PA @System.json
@@ -0,0 +1,9 @@
+{
+ "type": "filament",
+ "name": "Goofoo PA @System",
+ "inherits": "Goofoo PA @base",
+ "from": "system",
+ "setting_id": "1ximJVgZZfGmGyzD",
+ "instantiation": "true",
+ "compatible_printers": []
+}
diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PA @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PA @base.json
new file mode 100644
index 0000000000..2a490fa4e0
--- /dev/null
+++ b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PA @base.json
@@ -0,0 +1,20 @@
+{
+ "type": "filament",
+ "name": "Goofoo PA @base",
+ "inherits": "Generic PA @System",
+ "from": "system",
+ "filament_id": "OFc2x7Ly",
+ "instantiation": "false",
+ "filament_max_volumetric_speed": [
+ "12"
+ ],
+ "reduce_fan_stop_start_freq": [
+ "1"
+ ],
+ "filament_vendor": [
+ "Goofoo"
+ ],
+ "filament_type": [
+ "PA"
+ ]
+}
diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PA-CF @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PA-CF @System.json
new file mode 100644
index 0000000000..61f3d494b2
--- /dev/null
+++ b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PA-CF @System.json
@@ -0,0 +1,9 @@
+{
+ "type": "filament",
+ "name": "Goofoo PA-CF @System",
+ "inherits": "Goofoo PA-CF @base",
+ "from": "system",
+ "setting_id": "US4zznMNti8tLUHG",
+ "instantiation": "true",
+ "compatible_printers": []
+}
diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PA-CF @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PA-CF @base.json
new file mode 100644
index 0000000000..ad309aa6bf
--- /dev/null
+++ b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PA-CF @base.json
@@ -0,0 +1,17 @@
+{
+ "type": "filament",
+ "name": "Goofoo PA-CF @base",
+ "inherits": "Generic PA-CF @System",
+ "from": "system",
+ "filament_id": "OF7skcRj",
+ "instantiation": "false",
+ "filament_max_volumetric_speed": [
+ "12"
+ ],
+ "filament_vendor": [
+ "Goofoo"
+ ],
+ "filament_type": [
+ "PA-CF"
+ ]
+}
diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PA-GF10 @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PA-GF10 @System.json
new file mode 100644
index 0000000000..34235b2c92
--- /dev/null
+++ b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PA-GF10 @System.json
@@ -0,0 +1,9 @@
+{
+ "type": "filament",
+ "name": "Goofoo PA-GF10 @System",
+ "inherits": "Goofoo PA-GF10 @base",
+ "from": "system",
+ "setting_id": "Lea3hf2lQG0M9eTC",
+ "instantiation": "true",
+ "compatible_printers": []
+}
diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PA-GF10 @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PA-GF10 @base.json
new file mode 100644
index 0000000000..c0233b81e4
--- /dev/null
+++ b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PA-GF10 @base.json
@@ -0,0 +1,23 @@
+{
+ "type": "filament",
+ "name": "Goofoo PA-GF10 @base",
+ "inherits": "Generic PA-CF @System",
+ "from": "system",
+ "filament_id": "OFtjqw2h",
+ "instantiation": "false",
+ "nozzle_temperature": [
+ "230"
+ ],
+ "nozzle_temperature_initial_layer": [
+ "230"
+ ],
+ "reduce_fan_stop_start_freq": [
+ "1"
+ ],
+ "filament_vendor": [
+ "Goofoo"
+ ],
+ "filament_type": [
+ "PA-GF"
+ ]
+}
diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PE @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PE @System.json
new file mode 100644
index 0000000000..9ba71b4874
--- /dev/null
+++ b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PE @System.json
@@ -0,0 +1,9 @@
+{
+ "type": "filament",
+ "name": "Goofoo PE @System",
+ "inherits": "Goofoo PE @base",
+ "from": "system",
+ "setting_id": "muNxvgr0vdavMaOJ",
+ "instantiation": "true",
+ "compatible_printers": []
+}
diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PE @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PE @base.json
new file mode 100644
index 0000000000..a6ad2ee8a1
--- /dev/null
+++ b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PE @base.json
@@ -0,0 +1,14 @@
+{
+ "type": "filament",
+ "name": "Goofoo PE @base",
+ "inherits": "Generic PE @System",
+ "from": "system",
+ "filament_id": "OFAln723",
+ "instantiation": "false",
+ "filament_vendor": [
+ "Goofoo"
+ ],
+ "filament_type": [
+ "PE"
+ ]
+}
diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PE-CF @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PE-CF @System.json
new file mode 100644
index 0000000000..fe4f954ade
--- /dev/null
+++ b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PE-CF @System.json
@@ -0,0 +1,9 @@
+{
+ "type": "filament",
+ "name": "Goofoo PE-CF @System",
+ "inherits": "Goofoo PE-CF @base",
+ "from": "system",
+ "setting_id": "58fMbg6AClvalw5o",
+ "instantiation": "true",
+ "compatible_printers": []
+}
diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PE-CF @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PE-CF @base.json
new file mode 100644
index 0000000000..5f5719676b
--- /dev/null
+++ b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PE-CF @base.json
@@ -0,0 +1,14 @@
+{
+ "type": "filament",
+ "name": "Goofoo PE-CF @base",
+ "inherits": "Generic PE-CF @System",
+ "from": "system",
+ "filament_id": "OF4Ll1Sk",
+ "instantiation": "false",
+ "filament_vendor": [
+ "Goofoo"
+ ],
+ "filament_type": [
+ "PE-CF"
+ ]
+}
diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PETG @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PETG @System.json
new file mode 100644
index 0000000000..96a96f60f1
--- /dev/null
+++ b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PETG @System.json
@@ -0,0 +1,9 @@
+{
+ "type": "filament",
+ "name": "Goofoo PETG @System",
+ "inherits": "Goofoo PETG @base",
+ "from": "system",
+ "setting_id": "a9OKgJeoJgzfZiAB",
+ "instantiation": "true",
+ "compatible_printers": []
+}
diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PETG @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PETG @base.json
new file mode 100644
index 0000000000..5d380c9207
--- /dev/null
+++ b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PETG @base.json
@@ -0,0 +1,26 @@
+{
+ "type": "filament",
+ "name": "Goofoo PETG @base",
+ "inherits": "Generic PETG @System",
+ "from": "system",
+ "filament_id": "OFHdIbiu",
+ "instantiation": "false",
+ "hot_plate_temp": [
+ "80"
+ ],
+ "hot_plate_temp_initial_layer": [
+ "80"
+ ],
+ "nozzle_temperature": [
+ "240"
+ ],
+ "nozzle_temperature_initial_layer": [
+ "240"
+ ],
+ "filament_vendor": [
+ "Goofoo"
+ ],
+ "filament_type": [
+ "PETG"
+ ]
+}
diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PETG HF @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PETG HF @System.json
new file mode 100644
index 0000000000..9e7bef8497
--- /dev/null
+++ b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PETG HF @System.json
@@ -0,0 +1,9 @@
+{
+ "type": "filament",
+ "name": "Goofoo PETG HF @System",
+ "inherits": "Goofoo PETG HF @base",
+ "from": "system",
+ "setting_id": "eMjhTRf5qPeeqSgk",
+ "instantiation": "true",
+ "compatible_printers": []
+}
diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PETG HF @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PETG HF @base.json
new file mode 100644
index 0000000000..dd5ec7628c
--- /dev/null
+++ b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PETG HF @base.json
@@ -0,0 +1,14 @@
+{
+ "type": "filament",
+ "name": "Goofoo PETG HF @base",
+ "inherits": "Generic PETG HF @System",
+ "from": "system",
+ "filament_id": "OF5bjxyx",
+ "instantiation": "false",
+ "filament_vendor": [
+ "Goofoo"
+ ],
+ "filament_type": [
+ "PETG HF"
+ ]
+}
diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PETG-CF @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PETG-CF @System.json
new file mode 100644
index 0000000000..6a2a6713f5
--- /dev/null
+++ b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PETG-CF @System.json
@@ -0,0 +1,9 @@
+{
+ "type": "filament",
+ "name": "Goofoo PETG-CF @System",
+ "inherits": "Goofoo PETG-CF @base",
+ "from": "system",
+ "setting_id": "ULNFo6zjgjc5MEIa",
+ "instantiation": "true",
+ "compatible_printers": []
+}
diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PETG-CF @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PETG-CF @base.json
new file mode 100644
index 0000000000..2c937a5b7e
--- /dev/null
+++ b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PETG-CF @base.json
@@ -0,0 +1,14 @@
+{
+ "type": "filament",
+ "name": "Goofoo PETG-CF @base",
+ "inherits": "Generic PETG-CF @System",
+ "from": "system",
+ "filament_id": "OFo6Ff38",
+ "instantiation": "false",
+ "filament_vendor": [
+ "Goofoo"
+ ],
+ "filament_type": [
+ "PETG-CF"
+ ]
+}
diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PHA @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PHA @System.json
new file mode 100644
index 0000000000..dee540cbca
--- /dev/null
+++ b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PHA @System.json
@@ -0,0 +1,9 @@
+{
+ "type": "filament",
+ "name": "Goofoo PHA @System",
+ "inherits": "Goofoo PHA @base",
+ "from": "system",
+ "setting_id": "cfdeMyqld72Lqh38",
+ "instantiation": "true",
+ "compatible_printers": []
+}
diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PHA @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PHA @base.json
new file mode 100644
index 0000000000..bf93e717ee
--- /dev/null
+++ b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PHA @base.json
@@ -0,0 +1,14 @@
+{
+ "type": "filament",
+ "name": "Goofoo PHA @base",
+ "inherits": "Generic PHA @System",
+ "from": "system",
+ "filament_id": "OFicmNhN",
+ "instantiation": "false",
+ "filament_vendor": [
+ "Goofoo"
+ ],
+ "filament_type": [
+ "PHA"
+ ]
+}
diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PLA @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PLA @System.json
new file mode 100644
index 0000000000..bb5cec6fb5
--- /dev/null
+++ b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PLA @System.json
@@ -0,0 +1,9 @@
+{
+ "type": "filament",
+ "name": "Goofoo PLA @System",
+ "inherits": "Goofoo PLA @base",
+ "from": "system",
+ "setting_id": "UFWRE1b3706Cu1Iq",
+ "instantiation": "true",
+ "compatible_printers": []
+}
diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PLA @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PLA @base.json
new file mode 100644
index 0000000000..953226b7bb
--- /dev/null
+++ b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PLA @base.json
@@ -0,0 +1,26 @@
+{
+ "type": "filament",
+ "name": "Goofoo PLA @base",
+ "inherits": "Generic PLA @System",
+ "from": "system",
+ "filament_id": "OFoq0Cmt",
+ "instantiation": "false",
+ "hot_plate_temp": [
+ "40"
+ ],
+ "hot_plate_temp_initial_layer": [
+ "40"
+ ],
+ "nozzle_temperature": [
+ "230"
+ ],
+ "nozzle_temperature_initial_layer": [
+ "230"
+ ],
+ "filament_vendor": [
+ "Goofoo"
+ ],
+ "filament_type": [
+ "PLA"
+ ]
+}
diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PLA Silk @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PLA Silk @System.json
new file mode 100644
index 0000000000..faff94a9dc
--- /dev/null
+++ b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PLA Silk @System.json
@@ -0,0 +1,9 @@
+{
+ "type": "filament",
+ "name": "Goofoo PLA Silk @System",
+ "inherits": "Goofoo PLA Silk @base",
+ "from": "system",
+ "setting_id": "2pW2NEoY4hFCkNun",
+ "instantiation": "true",
+ "compatible_printers": []
+}
diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PLA Silk @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PLA Silk @base.json
new file mode 100644
index 0000000000..0142549b3c
--- /dev/null
+++ b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PLA Silk @base.json
@@ -0,0 +1,14 @@
+{
+ "type": "filament",
+ "name": "Goofoo PLA Silk @base",
+ "inherits": "Generic PLA Silk @System",
+ "from": "system",
+ "filament_id": "OFpta2gc",
+ "instantiation": "false",
+ "filament_vendor": [
+ "Goofoo"
+ ],
+ "filament_type": [
+ "PLA Silk"
+ ]
+}
diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PLA-CF @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PLA-CF @System.json
new file mode 100644
index 0000000000..b5dd4d30b2
--- /dev/null
+++ b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PLA-CF @System.json
@@ -0,0 +1,9 @@
+{
+ "type": "filament",
+ "name": "Goofoo PLA-CF @System",
+ "inherits": "Goofoo PLA-CF @base",
+ "from": "system",
+ "setting_id": "R0UMDUPY9ryat8gQ",
+ "instantiation": "true",
+ "compatible_printers": []
+}
diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PLA-CF @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PLA-CF @base.json
new file mode 100644
index 0000000000..e7c18576db
--- /dev/null
+++ b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PLA-CF @base.json
@@ -0,0 +1,29 @@
+{
+ "type": "filament",
+ "name": "Goofoo PLA-CF @base",
+ "inherits": "Generic PLA-CF @System",
+ "from": "system",
+ "filament_id": "OFMNABGJ",
+ "instantiation": "false",
+ "filament_flow_ratio": [
+ "0.98"
+ ],
+ "hot_plate_temp": [
+ "40"
+ ],
+ "hot_plate_temp_initial_layer": [
+ "40"
+ ],
+ "nozzle_temperature": [
+ "240"
+ ],
+ "nozzle_temperature_initial_layer": [
+ "240"
+ ],
+ "filament_vendor": [
+ "Goofoo"
+ ],
+ "filament_type": [
+ "PLA-CF"
+ ]
+}
diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PP @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PP @System.json
new file mode 100644
index 0000000000..239d479185
--- /dev/null
+++ b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PP @System.json
@@ -0,0 +1,9 @@
+{
+ "type": "filament",
+ "name": "Goofoo PP @System",
+ "inherits": "Goofoo PP @base",
+ "from": "system",
+ "setting_id": "TaB8JUtjJWgRcNrv",
+ "instantiation": "true",
+ "compatible_printers": []
+}
diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PP @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PP @base.json
new file mode 100644
index 0000000000..e664d23e6c
--- /dev/null
+++ b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PP @base.json
@@ -0,0 +1,14 @@
+{
+ "type": "filament",
+ "name": "Goofoo PP @base",
+ "inherits": "Generic PP @System",
+ "from": "system",
+ "filament_id": "OFlqlUSx",
+ "instantiation": "false",
+ "filament_vendor": [
+ "Goofoo"
+ ],
+ "filament_type": [
+ "PP"
+ ]
+}
diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PP-CF @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PP-CF @System.json
new file mode 100644
index 0000000000..ee7d75d9dc
--- /dev/null
+++ b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PP-CF @System.json
@@ -0,0 +1,9 @@
+{
+ "type": "filament",
+ "name": "Goofoo PP-CF @System",
+ "inherits": "Goofoo PP-CF @base",
+ "from": "system",
+ "setting_id": "uHocbocT6flJhlBz",
+ "instantiation": "true",
+ "compatible_printers": []
+}
diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PP-CF @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PP-CF @base.json
new file mode 100644
index 0000000000..2a5650d6eb
--- /dev/null
+++ b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PP-CF @base.json
@@ -0,0 +1,14 @@
+{
+ "type": "filament",
+ "name": "Goofoo PP-CF @base",
+ "inherits": "Generic PP-CF @System",
+ "from": "system",
+ "filament_id": "OFUUiuIV",
+ "instantiation": "false",
+ "filament_vendor": [
+ "Goofoo"
+ ],
+ "filament_type": [
+ "PP-CF"
+ ]
+}
diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PP-GF @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PP-GF @System.json
new file mode 100644
index 0000000000..a532c66dd9
--- /dev/null
+++ b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PP-GF @System.json
@@ -0,0 +1,9 @@
+{
+ "type": "filament",
+ "name": "Goofoo PP-GF @System",
+ "inherits": "Goofoo PP-GF @base",
+ "from": "system",
+ "setting_id": "mns8gICV0aNwJ02L",
+ "instantiation": "true",
+ "compatible_printers": []
+}
diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PP-GF @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PP-GF @base.json
new file mode 100644
index 0000000000..c6e692c13f
--- /dev/null
+++ b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PP-GF @base.json
@@ -0,0 +1,14 @@
+{
+ "type": "filament",
+ "name": "Goofoo PP-GF @base",
+ "inherits": "Generic PP-GF @System",
+ "from": "system",
+ "filament_id": "OFaOhzl8",
+ "instantiation": "false",
+ "filament_vendor": [
+ "Goofoo"
+ ],
+ "filament_type": [
+ "PP-GF"
+ ]
+}
diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PVA @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PVA @System.json
new file mode 100644
index 0000000000..a81dba232c
--- /dev/null
+++ b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PVA @System.json
@@ -0,0 +1,9 @@
+{
+ "type": "filament",
+ "name": "Goofoo PVA @System",
+ "inherits": "Goofoo PVA @base",
+ "from": "system",
+ "setting_id": "tUXbv31nYkXJ87OT",
+ "instantiation": "true",
+ "compatible_printers": []
+}
diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PVA @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PVA @base.json
new file mode 100644
index 0000000000..a83b99e0d3
--- /dev/null
+++ b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PVA @base.json
@@ -0,0 +1,14 @@
+{
+ "type": "filament",
+ "name": "Goofoo PVA @base",
+ "inherits": "Generic PVA @System",
+ "from": "system",
+ "filament_id": "OF86rkt6",
+ "instantiation": "false",
+ "filament_vendor": [
+ "Goofoo"
+ ],
+ "filament_type": [
+ "PVA"
+ ]
+}
diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt
index 52651e9b06..45a6344073 100644
--- a/src/slic3r/CMakeLists.txt
+++ b/src/slic3r/CMakeLists.txt
@@ -174,6 +174,8 @@ set(SLIC3R_GUI_SOURCES
GUI/Gizmos/GLGizmoAssembly.hpp
GUI/Gizmos/GLGizmoBase.cpp
GUI/Gizmos/GLGizmoBase.hpp
+ GUI/Gizmos/GLGizmoAlignment.cpp
+ GUI/Gizmos/GLGizmoAlignment.hpp
GUI/Gizmos/GLGizmoBrimEars.cpp
GUI/Gizmos/GLGizmoBrimEars.hpp
GUI/Gizmos/GLGizmoCut.cpp
diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp
index de838f5a2b..3ac4fc2f78 100644
--- a/src/slic3r/GUI/GLCanvas3D.cpp
+++ b/src/slic3r/GUI/GLCanvas3D.cpp
@@ -5520,7 +5520,7 @@ void GLCanvas3D::set_tooltip(const std::string& tooltip)
m_tooltip.set_text(tooltip);
}
-void GLCanvas3D::do_move(const std::string& snapshot_type)
+void GLCanvas3D::do_move(const std::string& snapshot_type, bool force_volume_move)
{
if (m_model == nullptr)
return;
@@ -5552,10 +5552,18 @@ void GLCanvas3D::do_move(const std::string& snapshot_type)
// Move instances/volumes
ModelObject* model_object = m_model->objects[object_idx];
- if (model_object == nullptr)
+ if (model_object == nullptr)
continue;
- if (selection_mode == Selection::Instance) {
+ if (force_volume_move || selection_mode == Selection::Volume) {
+ auto cur_mv = model_object->volumes[volume_idx];
+ if (cur_mv->get_transformation() != v->get_volume_transformation()) {
+ cur_mv->set_transformation(v->get_volume_transformation());
+ // BBS: backup
+ Slic3r::save_object_mesh(*model_object);
+ }
+ }
+ else if (selection_mode == Selection::Instance) {
if (m_canvas_type == GLCanvas3D::ECanvasType::CanvasAssembleView) {
if ((model_object->instances[instance_idx]->get_assemble_offset() - v->get_instance_offset()).norm() > 1e-2) {
model_object->instances[instance_idx]->set_assemble_transformation(v->get_instance_transformation());
@@ -5564,14 +5572,6 @@ void GLCanvas3D::do_move(const std::string& snapshot_type)
model_object->instances[instance_idx]->set_transformation(v->get_instance_transformation());
}
}
- else if (selection_mode == Selection::Volume) {
- auto cur_mv = model_object->volumes[volume_idx];
- if (cur_mv->get_transformation() != v->get_volume_transformation()) {
- cur_mv->set_transformation(v->get_volume_transformation());
- // BBS: backup
- Slic3r::save_object_mesh(*model_object);
- }
- }
object_moved = true;
model_object->invalidate_bounding_box();
diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp
index 2cb6bcea4f..df265bb080 100644
--- a/src/slic3r/GUI/GLCanvas3D.hpp
+++ b/src/slic3r/GUI/GLCanvas3D.hpp
@@ -1305,7 +1305,7 @@ public:
void set_tooltip(const std::string& tooltip);
// the following methods add a snapshot to the undo/redo stack, unless the given string is empty
- void do_move(const std::string& snapshot_type);
+ void do_move(const std::string& snapshot_type, bool force_volume_move = false);
void do_rotate(const std::string& snapshot_type);
void do_scale(const std::string& snapshot_type);
void do_center();
diff --git a/src/slic3r/GUI/GUI_Factories.cpp b/src/slic3r/GUI/GUI_Factories.cpp
index f4508f47ac..ca487ec3a5 100644
--- a/src/slic3r/GUI/GUI_Factories.cpp
+++ b/src/slic3r/GUI/GUI_Factories.cpp
@@ -16,6 +16,7 @@
#include "Selection.hpp"
//BBS: add partplate related logic
#include "PartPlate.hpp"
+#include "Gizmos/GLGizmoAlignment.hpp"
#include "Gizmos/GLGizmoEmboss.hpp"
#include "Gizmos/GLGizmoSVG.hpp"
@@ -1672,6 +1673,8 @@ void MenuFactory::create_extra_object_menu()
append_menu_item_merge_parts_to_single_part(&m_object_menu);
// Object Center
append_menu_item_center(&m_object_menu);
+ // Object Align/Distribute
+ append_menu_item_align_distribute(&m_object_menu);
// Object Drop
append_menu_item_drop(&m_object_menu);
// Object Split
@@ -1779,6 +1782,7 @@ void MenuFactory::create_text_part_menu()
append_menu_item_fix_through_cgal(menu);
append_menu_item_simplify(menu);
append_menu_item_center(menu);
+ append_menu_item_align_distribute(menu);
append_menu_items_mirror(menu);
menu->AppendSeparator();
append_menu_item_per_object_process(menu);
@@ -1811,6 +1815,7 @@ void MenuFactory::create_bbl_part_menu()
append_menu_item_simplify(menu);
append_menu_item_smooth_mesh(menu);
append_menu_item_center(menu);
+ append_menu_item_align_distribute(menu);
append_menu_item_drop(menu);
append_menu_items_mirror(menu);
wxMenu* split_menu = new wxMenu();
@@ -2136,6 +2141,7 @@ wxMenu* MenuFactory::multi_selection_menu()
index++;
}
append_menu_item_center(menu);
+ append_menu_item_align_distribute(menu);
append_menu_item_drop(menu);
append_menu_item_fix_through_cgal(menu);
//append_menu_item_simplify(menu);
@@ -2144,13 +2150,13 @@ wxMenu* MenuFactory::multi_selection_menu()
append_menu_item_set_printable(menu);
menu->AppendSeparator();
-
+
append_menu_item_set_auto_drop(menu);
menu->AppendSeparator();
-
+
append_menu_item_per_object_process(menu);
menu->AppendSeparator();
-
+
append_menu_items_convert_unit(menu);
append_menu_item_replace_all_with_stl(menu);
//BBS
@@ -2161,6 +2167,7 @@ wxMenu* MenuFactory::multi_selection_menu()
}
else {
append_menu_item_center(menu);
+ append_menu_item_align_distribute(menu);
append_menu_item_drop(menu);
append_menu_item_fix_through_cgal(menu);
//append_menu_item_simplify(menu);
@@ -2325,6 +2332,247 @@ void MenuFactory::append_menu_item_center(wxMenu* menu)
}, m_parent);
}
+void MenuFactory::append_menu_item_align_distribute(wxMenu *menu)
+{
+ wxMenu* align_distribute_menu = new wxMenu();
+ if (!align_distribute_menu)
+ return;
+
+ append_menu_item(
+ align_distribute_menu, wxID_ANY, _L("Distribute left-right") + " (X)", "",
+ [](wxCommandEvent &) {
+ auto canvas3d = plater()->get_view3D_canvas3D();
+ canvas3d->get_gizmos_manager().check_object_located_outside_plate(true);
+ plater()->distribute_selection_x();
+ },
+ "", nullptr,
+ []() {
+ if (plater()->canvas3D()->get_canvas_type() != GLCanvas3D::ECanvasType::CanvasView3D)
+ return false;
+ auto canvas3d = plater()->get_view3D_canvas3D();
+ GLGizmoAlignment alignment_helper(*canvas3d);
+ return alignment_helper.can_distribute(GLGizmoAlignment::AlignType::DISTRIBUTE_X);
+ },
+ m_parent);
+
+ append_menu_item(
+ align_distribute_menu, wxID_ANY, _L("Distribute front-back") + " (Y)", "",
+ [](wxCommandEvent &) {
+ auto canvas3d = plater()->get_view3D_canvas3D();
+ canvas3d->get_gizmos_manager().check_object_located_outside_plate(true);
+ plater()->distribute_selection_y();
+ },
+ "", nullptr,
+ []() {
+ if (plater()->canvas3D()->get_canvas_type() != GLCanvas3D::ECanvasType::CanvasView3D)
+ return false;
+ auto canvas3d = plater()->get_view3D_canvas3D();
+ GLGizmoAlignment alignment_helper(*canvas3d);
+ return alignment_helper.can_distribute(GLGizmoAlignment::AlignType::DISTRIBUTE_Y);
+ },
+ m_parent);
+
+ append_menu_item(
+ align_distribute_menu, wxID_ANY, _L("Distribute top-bottom") + " (Z)", "",
+ [](wxCommandEvent &) {
+ auto canvas3d = plater()->get_view3D_canvas3D();
+ canvas3d->get_gizmos_manager().check_object_located_outside_plate(true);
+ plater()->distribute_selection_z();
+ },
+ "", nullptr,
+ []() {
+ if (plater()->canvas3D()->get_canvas_type() != GLCanvas3D::ECanvasType::CanvasView3D)
+ return false;
+ auto canvas3d = plater()->get_view3D_canvas3D();
+ GLGizmoAlignment alignment_helper(*canvas3d);
+ return alignment_helper.can_distribute(GLGizmoAlignment::AlignType::DISTRIBUTE_Z);
+ },
+ m_parent);
+
+ align_distribute_menu->AppendSeparator();
+
+ append_menu_item(
+ align_distribute_menu, wxID_ANY, _L("Align left") + " (-X)", "",
+ [](wxCommandEvent &) {
+ auto canvas3d = plater()->get_view3D_canvas3D();
+ canvas3d->get_gizmos_manager().check_object_located_outside_plate(true);
+ plater()->align_selection_x_min();
+ },
+ "", nullptr,
+ []() {
+ if (plater()->canvas3D()->get_canvas_type() != GLCanvas3D::ECanvasType::CanvasView3D)
+ return false;
+ auto canvas3d = plater()->get_view3D_canvas3D();
+ GLGizmoAlignment alignment_helper(*canvas3d);
+ return alignment_helper.can_align(GLGizmoAlignment::AlignType::X_MIN);
+ },
+ m_parent);
+
+ append_menu_item(
+ align_distribute_menu, wxID_ANY, _L("Align left-right center") + " (X)", "",
+ [](wxCommandEvent &) {
+ auto canvas3d = plater()->get_view3D_canvas3D();
+ canvas3d->get_gizmos_manager().check_object_located_outside_plate(true);
+ plater()->align_selection_x_center();
+ },
+ "", nullptr,
+ []() {
+ if (plater()->canvas3D()->get_canvas_type() != GLCanvas3D::ECanvasType::CanvasView3D)
+ return false;
+ auto canvas3d = plater()->get_view3D_canvas3D();
+ GLGizmoAlignment alignment_helper(*canvas3d);
+ return alignment_helper.can_align(GLGizmoAlignment::AlignType::CENTER_X);
+ },
+ m_parent);
+
+ append_menu_item(
+ align_distribute_menu, wxID_ANY, _L("Align right") + " (+X)", "",
+ [](wxCommandEvent &) {
+ auto canvas3d = plater()->get_view3D_canvas3D();
+ canvas3d->get_gizmos_manager().check_object_located_outside_plate(true);
+ plater()->align_selection_x_max();
+ },
+ "", nullptr,
+ []() {
+ if (plater()->canvas3D()->get_canvas_type() != GLCanvas3D::ECanvasType::CanvasView3D)
+ return false;
+ auto canvas3d = plater()->get_view3D_canvas3D();
+ GLGizmoAlignment alignment_helper(*canvas3d);
+ return alignment_helper.can_align(GLGizmoAlignment::AlignType::X_MAX);
+ },
+ m_parent);
+
+ align_distribute_menu->AppendSeparator();
+
+ append_menu_item(
+ align_distribute_menu, wxID_ANY, _L("Align front") + " (-Y)", "",
+ [](wxCommandEvent &) {
+ auto canvas3d = plater()->get_view3D_canvas3D();
+ canvas3d->get_gizmos_manager().check_object_located_outside_plate(true);
+ plater()->align_selection_y_min();
+ },
+ "", nullptr,
+ []() {
+ if (plater()->canvas3D()->get_canvas_type() != GLCanvas3D::ECanvasType::CanvasView3D)
+ return false;
+ auto canvas3d = plater()->get_view3D_canvas3D();
+ GLGizmoAlignment alignment_helper(*canvas3d);
+ return alignment_helper.can_align(GLGizmoAlignment::AlignType::Y_MIN);
+ },
+ m_parent);
+
+ append_menu_item(
+ align_distribute_menu, wxID_ANY, _L("Align front-back center") + " (Y)", "",
+ [](wxCommandEvent &) {
+ auto canvas3d = plater()->get_view3D_canvas3D();
+ canvas3d->get_gizmos_manager().check_object_located_outside_plate(true);
+ plater()->align_selection_y_center();
+ },
+ "", nullptr,
+ []() {
+ if (plater()->canvas3D()->get_canvas_type() != GLCanvas3D::ECanvasType::CanvasView3D)
+ return false;
+ auto canvas3d = plater()->get_view3D_canvas3D();
+ GLGizmoAlignment alignment_helper(*canvas3d);
+ return alignment_helper.can_align(GLGizmoAlignment::AlignType::CENTER_Y);
+ },
+ m_parent);
+
+ append_menu_item(
+ align_distribute_menu, wxID_ANY, _L("Align back") + " (+Y)", "",
+ [](wxCommandEvent &) {
+ auto canvas3d = plater()->get_view3D_canvas3D();
+ canvas3d->get_gizmos_manager().check_object_located_outside_plate(true);
+ plater()->align_selection_y_max();
+ },
+ "", nullptr,
+ []() {
+ if (plater()->canvas3D()->get_canvas_type() != GLCanvas3D::ECanvasType::CanvasView3D)
+ return false;
+ auto canvas3d = plater()->get_view3D_canvas3D();
+ GLGizmoAlignment alignment_helper(*canvas3d);
+ return alignment_helper.can_align(GLGizmoAlignment::AlignType::Y_MAX);
+ },
+ m_parent);
+
+ align_distribute_menu->AppendSeparator();
+
+ append_menu_item(
+ align_distribute_menu, wxID_ANY, _L("Align bottom") + " (-Z)", "",
+ [](wxCommandEvent &) {
+ auto canvas3d = plater()->get_view3D_canvas3D();
+ canvas3d->get_gizmos_manager().check_object_located_outside_plate(true);
+ plater()->align_selection_z_min();
+ },
+ "", nullptr,
+ []() {
+ if (plater()->canvas3D()->get_canvas_type() != GLCanvas3D::ECanvasType::CanvasView3D)
+ return false;
+ auto canvas3d = plater()->get_view3D_canvas3D();
+ GLGizmoAlignment alignment_helper(*canvas3d);
+ return alignment_helper.can_align(GLGizmoAlignment::AlignType::Z_MIN);
+ },
+ m_parent);
+
+ append_menu_item(
+ align_distribute_menu, wxID_ANY, _L("Align top-bottom center") + " (Z)", "",
+ [](wxCommandEvent &) {
+ auto canvas3d = plater()->get_view3D_canvas3D();
+ canvas3d->get_gizmos_manager().check_object_located_outside_plate(true);
+ plater()->align_selection_z_center();
+ },
+ "", nullptr,
+ []() {
+ if (plater()->canvas3D()->get_canvas_type() != GLCanvas3D::ECanvasType::CanvasView3D)
+ return false;
+ auto canvas3d = plater()->get_view3D_canvas3D();
+ GLGizmoAlignment alignment_helper(*canvas3d);
+ return alignment_helper.can_align(GLGizmoAlignment::AlignType::CENTER_Z);
+ },
+ m_parent);
+
+ append_menu_item(
+ align_distribute_menu, wxID_ANY, _L("Align top") + " (+Z)", "",
+ [](wxCommandEvent &) {
+ auto canvas3d = plater()->get_view3D_canvas3D();
+ canvas3d->get_gizmos_manager().check_object_located_outside_plate(true);
+ plater()->align_selection_z_max();
+ },
+ "", nullptr,
+ []() {
+ if (plater()->canvas3D()->get_canvas_type() != GLCanvas3D::ECanvasType::CanvasView3D)
+ return false;
+ auto canvas3d = plater()->get_view3D_canvas3D();
+ GLGizmoAlignment alignment_helper(*canvas3d);
+ return alignment_helper.can_align(GLGizmoAlignment::AlignType::Z_MAX);
+ },
+ m_parent);
+
+ append_submenu(menu, align_distribute_menu, wxID_ANY, _L("Align/Distribute"), _L("Align and distribute objects"), "",
+ []() {
+ if (plater()->canvas3D()->get_canvas_type() != GLCanvas3D::ECanvasType::CanvasView3D)
+ return false;
+ auto canvas3d = plater()->get_view3D_canvas3D();
+ GLGizmoAlignment alignment_helper(*canvas3d);
+
+ bool has_any_align = alignment_helper.can_align(GLGizmoAlignment::AlignType::CENTER_X) ||
+ alignment_helper.can_align(GLGizmoAlignment::AlignType::CENTER_Y) ||
+ alignment_helper.can_align(GLGizmoAlignment::AlignType::CENTER_Z) ||
+ alignment_helper.can_align(GLGizmoAlignment::AlignType::X_MAX) ||
+ alignment_helper.can_align(GLGizmoAlignment::AlignType::X_MIN) ||
+ alignment_helper.can_align(GLGizmoAlignment::AlignType::Y_MAX) ||
+ alignment_helper.can_align(GLGizmoAlignment::AlignType::Y_MIN) ||
+ alignment_helper.can_align(GLGizmoAlignment::AlignType::Z_MAX) ||
+ alignment_helper.can_align(GLGizmoAlignment::AlignType::Z_MIN);
+
+ bool has_any_distribute = alignment_helper.can_distribute(GLGizmoAlignment::AlignType::DISTRIBUTE_X) ||
+ alignment_helper.can_distribute(GLGizmoAlignment::AlignType::DISTRIBUTE_Y) ||
+ alignment_helper.can_distribute(GLGizmoAlignment::AlignType::DISTRIBUTE_Z);
+
+ return has_any_align || has_any_distribute;
+ }, m_parent);
+}
+
void MenuFactory::append_menu_item_drop(wxMenu* menu)
{
append_menu_item(menu, wxID_ANY, _L("Drop") , "",
diff --git a/src/slic3r/GUI/GUI_Factories.hpp b/src/slic3r/GUI/GUI_Factories.hpp
index 4202cce5bc..65526c5c04 100644
--- a/src/slic3r/GUI/GUI_Factories.hpp
+++ b/src/slic3r/GUI/GUI_Factories.hpp
@@ -175,6 +175,7 @@ private:
void append_menu_item_merge_to_single_object(wxMenu* menu);
void append_menu_item_merge_parts_to_single_part(wxMenu *menu);
void append_menu_items_mirror(wxMenu *menu);
+ void append_menu_item_align_distribute(wxMenu *menu);
void append_menu_item_precise_seam_submenu(wxMenu* menu);
void append_menu_item_invalidate_cut_info(wxMenu *menu);
void append_menu_item_edit_text(wxMenu *menu);
diff --git a/src/slic3r/GUI/Gizmos/GLGizmoAlignment.cpp b/src/slic3r/GUI/Gizmos/GLGizmoAlignment.cpp
new file mode 100644
index 0000000000..7e97d64940
--- /dev/null
+++ b/src/slic3r/GUI/Gizmos/GLGizmoAlignment.cpp
@@ -0,0 +1,694 @@
+#include "GLGizmoAlignment.hpp"
+#include "slic3r/GUI/GLCanvas3D.hpp"
+#include "slic3r/GUI/GUI_App.hpp"
+#include "slic3r/GUI/Plater.hpp"
+#include "libslic3r/Model.hpp"
+
+namespace Slic3r {
+namespace GUI {
+
+GLGizmoAlignment::GLGizmoAlignment(GLCanvas3D& canvas) : m_canvas(canvas)
+{
+}
+
+bool GLGizmoAlignment::align_objects(AlignType type, bool align_parent)
+{
+ if (!validate_selection_for_align()) {
+ return false;
+ }
+
+ switch (type) {
+ case AlignType::CENTER_X: return align_to_center(type, align_parent);
+ case AlignType::CENTER_Y: return align_to_center(type, align_parent);
+ case AlignType::CENTER_Z: return align_to_center(type, align_parent);
+ case AlignType::Y_MAX: return align_to_y_max(align_parent);
+ case AlignType::Y_MIN: return align_to_y_min(align_parent);
+ case AlignType::X_MAX: return align_to_x_max(align_parent);
+ case AlignType::X_MIN: return align_to_x_min(align_parent);
+ case AlignType::Z_MAX: return align_to_z_max(align_parent);
+ case AlignType::Z_MIN: return align_to_z_min(align_parent);
+ default:
+ return false;
+ }
+}
+
+bool GLGizmoAlignment::distribute_objects(AlignType type)
+{
+ if (!can_distribute(type)) {
+ return false;
+ }
+
+ switch (type) {
+ case AlignType::DISTRIBUTE_X:
+ return distribute_x();
+ case AlignType::DISTRIBUTE_Y:
+ return distribute_y();
+ case AlignType::DISTRIBUTE_Z:
+ return distribute_z();
+ default:
+ return false;
+ }
+}
+
+bool GLGizmoAlignment::align_to_y_max(bool align_parent)
+{
+ return align_objects_generic(
+ [](const ObjectInfo& obj) { return obj.bbox.max.y(); },
+ [](Vec3d& displacement, double target, double current_max) {
+ displacement.y() = target - current_max;
+ }, "Align Y Max", align_parent
+ );
+}
+
+bool GLGizmoAlignment::align_to_y_min(bool align_parent)
+{
+ return align_objects_generic(
+ [](const ObjectInfo& obj) { return obj.bbox.min.y(); },
+ [](Vec3d& displacement, double target, double current_min) {
+ displacement.y() = target - current_min;
+ }, "Align Y Min", align_parent
+ );
+}
+
+bool GLGizmoAlignment::align_to_x_max(bool align_parent)
+{
+ return align_objects_generic(
+ [](const ObjectInfo& obj) { return obj.bbox.max.x(); },
+ [](Vec3d& displacement, double target, double current_max) {
+ displacement.x() = target - current_max;
+ }, "Align X Max", align_parent
+ );
+}
+
+bool GLGizmoAlignment::align_to_x_min(bool align_parent)
+{
+ return align_objects_generic(
+ [](const ObjectInfo& obj) { return obj.bbox.min.x(); },
+ [](Vec3d& displacement, double target, double current_min) {
+ displacement.x() = target - current_min;
+ }, "Align X Min", align_parent
+ );
+}
+
+bool GLGizmoAlignment::align_to_center(AlignType type,bool align_parent)
+{
+ const Selection& selection = get_selection();
+ std::string type_str = type == AlignType::CENTER_X ? "X" : (type == AlignType::CENTER_Y ? "Y" : "Z");
+ std::string operation_name = type == AlignType::CENTER_X ? "X Center" : (type == AlignType::CENTER_Y ? "Y Center" : "Z Center");
+ double selection_center = 0.f;
+ if (align_parent) {
+ selection_center = get_current_coord(operation_name, m_parent_box);
+
+ // Handle multiple volume selection
+ if (is_part_align_parent()) {
+ if (!take_snapshot("Align to parent center " + type_str)) {
+ return false;
+ }
+
+ get_selection().setup_cache();
+
+ auto selection_bbox = selection.get_bounding_box();
+ double current_coord = get_current_coord(operation_name, selection_bbox);
+ Vec3d displacement = generate_displacement(operation_name, selection_center - current_coord);
+ // Move each selected volume to align to the center of their collective bounding box
+ for (unsigned int idx : selection.get_volume_idxs()) {
+ const GLVolume *volume = selection.get_volume(idx);
+ if (volume) {
+ get_selection().translate(volume->object_idx(), volume->instance_idx(), volume->volume_idx(), displacement);
+ }
+ }
+ finish_operation("Align to parent center " + type_str);
+ return true;
+ }
+ BoundingBoxf3 big_bb;
+ auto objects = get_selected_objects_info(big_bb);
+ if (objects.empty()) return false;
+ // Handle multiple objects or parts selection
+
+ BoundingBoxf3 selection_bbox = selection.get_bounding_box();
+ if (!take_snapshot("Align to parent center " + type_str)) {
+ return false;
+ }
+
+ get_selection().setup_cache();
+ double current_coord = get_current_coord(operation_name, big_bb);
+ Vec3d displacement = generate_displacement(operation_name, selection_center - current_coord);
+ // Multiple objects: use selection bounding box for alignment
+ for (const auto &obj : objects) {
+ apply_transformation(obj.object_idx, obj.instance_idx, displacement);
+ }
+
+ finish_operation("Align to parent center " + type_str);
+ return true;
+ }
+ // Handle single object selection// Handle multiple volume selection
+ if (selection.is_single_full_object() ||
+ selection.is_multiple_volume() || selection.is_multiple_modifier() || selection.is_single_volume() || selection.is_single_modifier()) {
+ if (!take_snapshot("Align Parts Center " + type_str)){
+ return false;
+ }
+
+ get_selection().setup_cache();
+
+ BoundingBoxf3 selection_bbox = selection.get_bounding_box();
+ selection_center = get_current_coord(operation_name, selection_bbox);
+
+ // Move each selected volume to align to the center of their collective bounding box
+ for (unsigned int idx : selection.get_volume_idxs()) {
+ const GLVolume* volume = selection.get_volume(idx);
+ if (volume) {
+ auto temp_box = volume->transformed_convex_hull_bounding_box();
+ double current = get_current_coord(operation_name, temp_box);
+ double offset = selection_center - current;
+ Vec3d displacement = generate_displacement(operation_name, offset);
+ get_selection().translate(volume->object_idx(), volume->instance_idx(), volume->volume_idx(), displacement);
+ }
+ }
+
+ finish_operation("Align Parts Center" + type_str, true);
+ return true;
+ }
+ BoundingBoxf3 big_bb;
+ auto objects = get_selected_objects_info(big_bb);
+ if (objects.empty()) return false;
+ // Handle multiple objects or parts selection
+ if (selection.is_multiple_full_object()) {
+ BoundingBoxf3 selection_bbox = selection.get_bounding_box();
+ double selection_center = get_current_coord(operation_name, selection_bbox);
+
+ if (!take_snapshot("Align Objects Center" + type_str)) {
+ return false;
+ }
+
+ get_selection().setup_cache();
+ // Multiple objects: use selection bounding box for alignment
+ for (const auto& obj : objects) {
+ BoundingBoxf3 temp_bbox = obj.bbox;
+ double current_coord = get_current_coord(operation_name, temp_bbox);
+ Vec3d displacement = generate_displacement(operation_name, selection_center - current_coord);
+ apply_transformation(obj.object_idx, obj.instance_idx, displacement);
+ }
+ finish_operation("Align Objects Center" + type_str);
+ return true;
+ }
+ return false;
+}
+
+bool GLGizmoAlignment::align_to_z_max(bool align_parent)
+{
+ return align_objects_generic(
+ [](const ObjectInfo& obj) { return obj.bbox.max.z(); },
+ [](Vec3d& displacement, double target, double current_max) {
+ displacement.z() = target - current_max;
+ }, "Align Z Max", align_parent
+ );
+}
+
+bool GLGizmoAlignment::align_to_z_min(bool align_parent)
+{
+ return align_objects_generic(
+ [](const ObjectInfo& obj) { return obj.bbox.min.z(); },
+ [](Vec3d& displacement, double target, double current_min) {
+ displacement.z() = target - current_min;
+ }, "Align Z Min", align_parent
+ );
+}
+
+bool GLGizmoAlignment::distribute_y()
+{
+ return distribute_objects_generic(
+ [](const ObjectInfo& obj) { return obj.center.y(); },
+ 1,
+ "Distribute Y"
+ );
+}
+
+bool GLGizmoAlignment::distribute_x()
+{
+ return distribute_objects_generic(
+ [](const ObjectInfo& obj) { return obj.center.x(); },
+ 0,
+ "Distribute X"
+ );
+}
+
+bool GLGizmoAlignment::distribute_z()
+{
+ return distribute_objects_generic(
+ [](const ObjectInfo& obj) { return obj.center.z(); },
+ 2,
+ "Distribute Z"
+ );
+}
+
+template
+bool GLGizmoAlignment::align_objects_generic(GetCoordFunc get_coord, SetCoordFunc set_coord, const std::string &operation_name ,bool align_parent)
+{
+ const Selection& selection = get_selection();
+ if (align_parent) {
+ // Find reference coordinate
+ double reference_coord = get_current_coord(operation_name, m_parent_box);
+ // Handle parts selection differently
+ if (is_part_align_parent()) {
+ if (!take_snapshot("align to parent node " + operation_name)) {
+ return false;
+ }
+
+ get_selection().setup_cache();
+
+ // Get all selected volumes
+ std::vector volumes;
+ for (unsigned int idx : selection.get_volume_idxs()) {
+ const GLVolume *volume = selection.get_volume(idx);
+ if (volume) { volumes.push_back(volume); }
+ }
+
+ if (volumes.empty())
+ return false;
+ BoundingBoxf3 selection_bbox = selection.get_bounding_box();
+ double current_coord = get_current_coord(operation_name, selection_bbox);
+ Vec3d displacement = generate_displacement(operation_name, reference_coord - current_coord);
+ for (const GLVolume *volume : volumes) {
+ if (displacement.norm() > 1e-6) {
+ get_selection().translate(volume->object_idx(), volume->instance_idx(), volume->volume_idx(), displacement);
+ }
+ }
+
+ finish_operation("align to parent node " + operation_name);
+ return true;
+ }
+
+ // Handle objects selection (original logic)
+ BoundingBoxf3 big_bb;
+ auto objects = get_selected_objects_info(big_bb);
+ if (objects.empty()) return false;
+
+ if (!take_snapshot("align to parent node " + operation_name)) { return false; }
+
+ get_selection().setup_cache();
+
+ double current_coord = get_current_coord(operation_name, big_bb);
+ Vec3d displacement = generate_displacement(operation_name, reference_coord - current_coord);
+
+ for (const auto &obj : objects) {
+ if (displacement.norm() > 1e-6) {
+ apply_transformation(obj.object_idx, obj.instance_idx, displacement);
+ }
+ }
+
+ finish_operation("align to parent node " + operation_name);
+ return true;
+ }
+ // Handle parts selection differently
+ if (selection.is_single_full_object() || selection.is_multiple_volume() || selection.is_multiple_modifier()) {
+ if (!take_snapshot(operation_name)) {
+ return false;
+ }
+
+ get_selection().setup_cache();
+
+ // Get all selected volumes
+ std::vector volumes;
+ for (unsigned int idx : selection.get_volume_idxs()) {
+ const GLVolume* volume = selection.get_volume(idx);
+ if (volume) {
+ volumes.push_back(volume);
+ }
+ }
+
+ if (volumes.empty()) return false;
+
+ // Find reference coordinate
+ double reference_coord = 0.0;
+ bool first = true;
+
+ for (const GLVolume* volume : volumes) {
+ BoundingBoxf3 bbox = volume->transformed_convex_hull_bounding_box();
+ double coord = 0.0;
+
+ if (operation_name.find("X Max") != std::string::npos) {
+ coord = bbox.max.x();
+ } else if (operation_name.find("X Min") != std::string::npos) {
+ coord = bbox.min.x();
+ } else if (operation_name.find("Y Max") != std::string::npos) {
+ coord = bbox.max.y();
+ } else if (operation_name.find("Y Min") != std::string::npos) {
+ coord = bbox.min.y();
+ } else if (operation_name.find("Z Max") != std::string::npos) {
+ coord = bbox.max.z();
+ } else if (operation_name.find("Z Min") != std::string::npos) {
+ coord = bbox.min.z();
+ }
+
+ if (first) {
+ reference_coord = coord;
+ first = false;
+ } else {
+ if (operation_name.find("Max") != std::string::npos) {
+ reference_coord = std::max(reference_coord, coord);
+ } else if (operation_name.find("Min") != std::string::npos) {
+ reference_coord = std::min(reference_coord, coord);
+ }
+ }
+ }
+
+ for (const GLVolume* volume : volumes) {
+ BoundingBoxf3 bbox = volume->transformed_convex_hull_bounding_box();
+ double current_coord = 0.0;
+
+ if (operation_name.find("X Max") != std::string::npos) {
+ current_coord = bbox.max.x();
+ } else if (operation_name.find("X Min") != std::string::npos) {
+ current_coord = bbox.min.x();
+ } else if (operation_name.find("Y Max") != std::string::npos) {
+ current_coord = bbox.max.y();
+ } else if (operation_name.find("Y Min") != std::string::npos) {
+ current_coord = bbox.min.y();
+ } else if (operation_name.find("Z Max") != std::string::npos) {
+ current_coord = bbox.max.z();
+ } else if (operation_name.find("Z Min") != std::string::npos) {
+ current_coord = bbox.min.z();
+ }
+
+ Vec3d displacement = Vec3d::Zero();
+
+ if (operation_name.find("X") != std::string::npos) {
+ displacement.x() = reference_coord - current_coord;
+ } else if (operation_name.find("Y") != std::string::npos) {
+ displacement.y() = reference_coord - current_coord;
+ } else if (operation_name.find("Z") != std::string::npos) {
+ displacement.z() = reference_coord - current_coord;
+ }
+
+ if (displacement.norm() > 1e-6) {
+ get_selection().translate(volume->object_idx(), volume->instance_idx(), volume->volume_idx(), displacement);
+ }
+ }
+
+ finish_operation(operation_name,true);
+ return true;
+ }
+
+ // Handle objects selection (original logic)
+ BoundingBoxf3 big_bb;
+ auto objects = get_selected_objects_info(big_bb);
+ if (objects.empty()) return false;
+
+ if (!take_snapshot(operation_name)) {
+ return false;
+ }
+
+ get_selection().setup_cache();
+
+ double reference_coord = get_coord(objects[0]);
+ for (const auto& obj : objects) {
+ double coord = get_coord(obj);
+ if (operation_name.find("Max") != std::string::npos) {
+ reference_coord = std::max(reference_coord, coord);
+ } else if (operation_name.find("Min") != std::string::npos) {
+ reference_coord = std::min(reference_coord, coord);
+ }
+ }
+
+ for (const auto& obj : objects) {
+ double current_coord = get_coord(obj);
+ Vec3d displacement = Vec3d::Zero();
+ set_coord(displacement, reference_coord, current_coord);
+
+ if (displacement.norm() > 1e-6) {
+ apply_transformation(obj.object_idx, obj.instance_idx, displacement);
+ }
+ }
+
+ finish_operation(operation_name);
+ return true;
+}
+
+template
+bool GLGizmoAlignment::distribute_objects_generic(GetCoordFunc get_coord, int axis, const std::string& operation_name)
+{
+ const Selection& selection = get_selection();
+
+ if (selection.is_single_full_object() || selection.is_multiple_volume() || selection.is_multiple_modifier()) {
+ std::vector volumes;
+ for (unsigned int idx : selection.get_volume_idxs()) {
+ const GLVolume* v = selection.get_volume(idx);
+ if (v) volumes.push_back(v);
+ }
+
+ if (volumes.size() < 3) return false;
+ if (!take_snapshot(operation_name)) {
+ return false;
+ }
+ get_selection().setup_cache();
+
+ struct VolEntry { const GLVolume* v; double coord; };
+ std::vector entries;
+ entries.reserve(volumes.size());
+ for (const GLVolume* v : volumes) {
+ BoundingBoxf3 bbox = v->transformed_convex_hull_bounding_box();
+ Vec3d c = bbox.center();
+ double coord = (axis == 0 ? c.x() : axis == 1 ? c.y() : c.z());
+ entries.push_back({v, coord});
+ }
+
+ std::sort(entries.begin(), entries.end(), [](const VolEntry& a, const VolEntry& b){ return a.coord < b.coord; });
+
+ BoundingBoxf3 selection_bbox = selection.get_bounding_box();
+ BoundingBoxf3 left_bbox = entries.front().v->transformed_convex_hull_bounding_box();
+ BoundingBoxf3 right_bbox = entries.back().v->transformed_convex_hull_bounding_box();
+ auto axis_extent = [&](const BoundingBoxf3 &bb) { return (axis == 0 ? (bb.max.x() - bb.min.x()) : axis == 1 ? (bb.max.y() - bb.min.y()) : (bb.max.z() - bb.min.z())); };
+ double left_width = axis_extent(left_bbox);
+ double right_width = axis_extent(right_bbox);
+ double bbox_min = (axis == 0 ? selection_bbox.min.x() : axis == 1 ? selection_bbox.min.y() : selection_bbox.min.z());
+ double bbox_max = (axis == 0 ? selection_bbox.max.x() : axis == 1 ? selection_bbox.max.y() : selection_bbox.max.z());
+ double min_center = bbox_min + left_width * 0.5;
+ double max_center = bbox_max - right_width * 0.5;
+ double total_distance = max_center - min_center;
+ double interval = (entries.size() > 1) ? total_distance / (entries.size() - 1) : 0;
+ for (size_t i = 1; i < entries.size() - 1; ++i) {
+ double target_coord = min_center + i * interval;
+ double current_coord = entries[i].coord;
+ double offset = target_coord - current_coord;
+
+ if (std::abs(offset) > 1e-6) {
+ Vec3d displacement = Vec3d::Zero();
+ displacement[axis] = offset;
+ const GLVolume *v = entries[i].v;
+ get_selection().translate(v->object_idx(), v->instance_idx(), v->volume_idx(), displacement);
+ }
+ }
+
+ finish_operation(operation_name,true);
+ return true;
+ }
+ BoundingBoxf3 big_bb;
+ auto objects = get_selected_objects_info(big_bb);
+ if (objects.size() < 3) return false;
+
+ if (!take_snapshot(operation_name)) {
+ return false;
+ }
+
+ get_selection().setup_cache();
+
+ std::sort(objects.begin(), objects.end(),
+ [&get_coord](const ObjectInfo& a, const ObjectInfo& b) {
+ return get_coord(a) < get_coord(b);
+ });
+
+ double min_coord = get_coord(objects.front());
+ double max_coord = get_coord(objects.back());
+ double total_distance = max_coord - min_coord;
+ double interval = (objects.size() > 1) ? total_distance / (objects.size() - 1) : 0;
+ for (size_t i = 1; i < objects.size() - 1; ++i) {
+ double target_coord = min_coord + i * interval;
+ double current_coord = get_coord(objects[i]);
+ double offset = target_coord - current_coord;
+
+ if (std::abs(offset) > 1e-6) {
+ Vec3d displacement = Vec3d::Zero();
+ displacement[axis] = offset;
+ apply_transformation(objects[i].object_idx, objects[i].instance_idx, displacement);
+ }
+ }
+
+ finish_operation(operation_name);
+ return true;
+}
+
+bool GLGizmoAlignment::can_align(AlignType type) const
+{
+ const Selection& selection = get_selection();
+
+ bool is_single_object = selection.is_single_full_object();
+ bool is_multiple_objects = selection.is_multiple_full_object();
+ bool is_single_part = selection.is_single_volume() || selection.is_single_modifier();
+ bool is_multiple_parts = selection.is_multiple_volume() || selection.is_multiple_modifier();
+
+
+ return validate_selection_for_align();
+}
+
+bool GLGizmoAlignment::can_distribute(AlignType type) const
+{
+ const Selection& selection = get_selection();
+ if (selection.is_single_full_object()) {
+ size_t count = selection.get_volume_idxs().size();
+ if (count >= 3)
+ return true;
+ }
+ if (selection.is_single_volume() ||
+ selection.is_single_modifier()) {
+ return false;
+ }
+
+ if (selection.is_multiple_volume() || selection.is_multiple_modifier()) {
+ size_t count = selection.get_volume_idxs().size();
+ if (count < 3) return false;
+ return (type == AlignType::DISTRIBUTE_X ||
+ type == AlignType::DISTRIBUTE_Y ||
+ type == AlignType::DISTRIBUTE_Z);
+ }
+
+ if (selection.is_multiple_full_object()) {
+ BoundingBoxf3 big_bb;
+ auto objects = get_selected_objects_info(big_bb);
+ if (objects.size() < 3) return false;
+ return (type == AlignType::DISTRIBUTE_X || type == AlignType::DISTRIBUTE_Y || type == AlignType::DISTRIBUTE_Z);
+ }
+
+ return validate_selection_for_distribute();
+}
+
+double GLGizmoAlignment::get_current_coord(std::string operation_name, BoundingBoxf3 &bbox)
+{
+ double current_coord = 0.0;
+ if (operation_name.find("X Max") != std::string::npos) {
+ current_coord = bbox.max.x();
+ } else if (operation_name.find("X Min") != std::string::npos) {
+ current_coord = bbox.min.x();
+ } else if (operation_name.find("Y Max") != std::string::npos) {
+ current_coord = bbox.max.y();
+ } else if (operation_name.find("Y Min") != std::string::npos) {
+ current_coord = bbox.min.y();
+ } else if (operation_name.find("Z Max") != std::string::npos) {
+ current_coord = bbox.max.z();
+ } else if (operation_name.find("Z Min") != std::string::npos) {
+ current_coord = bbox.min.z();
+ } else if (operation_name.find("X Center") != std::string::npos) {
+ current_coord = bbox.center().x();
+ } else if (operation_name.find("Y Center") != std::string::npos) {
+ current_coord = bbox.center().y();
+ } else if (operation_name.find("Z Center") != std::string::npos) {
+ current_coord = bbox.center().z();
+ }
+ return current_coord;
+}
+
+Vec3d GLGizmoAlignment::generate_displacement(std::string operation_name, double offset) {
+ Vec3d displacement = Vec3d::Zero();
+ if (operation_name.find("X") != std::string::npos) {
+ displacement.x() = offset;
+ } else if (operation_name.find("Y") != std::string::npos) {
+ displacement.y() = offset;
+ } else if (operation_name.find("Z") != std::string::npos) {
+ displacement.z() = offset;
+ }
+ return displacement;
+}
+
+bool GLGizmoAlignment::is_part_align_parent()
+{
+ Selection &selection = get_selection();
+ if (selection.is_multiple_volume() || selection.is_multiple_modifier() || selection.is_single_volume() || selection.is_single_modifier()) {
+ return true;
+ }
+ return false;
+}
+
+std::vector GLGizmoAlignment::get_selected_objects_info(BoundingBoxf3 &big_bb) const
+{
+ std::vector objects;
+ Selection& selection = get_selection();
+
+ if (selection.is_empty()) return objects;
+
+ const auto& content = selection.get_content();
+ for (const auto& obj_it : content) {
+ for (const auto& inst_idx : obj_it.second) {
+ int obj_idx = obj_it.first;
+
+ if (obj_idx >= 0 && obj_idx < selection.get_model()->objects.size()) {
+ ModelObject* object = selection.get_model()->objects[obj_idx];
+ if (inst_idx >= 0 && inst_idx < object->instances.size()) {
+ BoundingBoxf3 bbox = object->instance_bounding_box(inst_idx);
+ big_bb.merge(bbox);
+ objects.emplace_back(obj_idx, inst_idx, bbox);
+ }
+ }
+ }
+ }
+
+ return objects;
+}
+
+void GLGizmoAlignment::set_parent_box(const BoundingBoxf3 &bb) {
+ m_parent_box = bb;
+}
+
+Selection& GLGizmoAlignment::get_selection() const
+{
+ return m_canvas.get_selection();
+}
+
+bool GLGizmoAlignment::take_snapshot(const std::string& name)
+{
+ wxGetApp().plater()->take_snapshot(name);
+ return true;
+}
+
+void GLGizmoAlignment::apply_transformation(int obj_idx, int inst_idx, const Vec3d& displacement)
+{
+ get_selection().translate(obj_idx, inst_idx, displacement);
+}
+
+void GLGizmoAlignment::finish_operation(const std::string &operation_name, bool force_volume_move)
+{
+ get_selection().notify_instance_update(-1, -1);
+ m_canvas.do_move(operation_name, force_volume_move);
+}
+
+bool GLGizmoAlignment::validate_selection_for_align() const
+{
+ const Selection& selection = get_selection();
+
+ if (selection.is_single_full_object() ||
+ selection.is_single_volume() ||
+ selection.is_single_modifier()) {
+ return true;
+ }
+
+ return selection.get_volume_idxs().size() >= 2;
+}
+
+bool GLGizmoAlignment::validate_selection_for_distribute() const
+{
+ const Selection& selection = get_selection();
+
+ if (selection.is_single_full_object() || selection.is_multiple_full_object()) {
+ std::set object_indices;
+ for (int volume_idx : selection.get_volume_idxs()) {
+ const GLVolume* volume = selection.get_volume(volume_idx);
+ if (volume) {
+ object_indices.insert(volume->object_idx());
+ }
+ }
+ return object_indices.size() >= 3;
+ }
+
+ return selection.get_volume_idxs().size() >= 3;
+}
+
+} // namespace GUI
+} // namespace Slic3r
\ No newline at end of file
diff --git a/src/slic3r/GUI/Gizmos/GLGizmoAlignment.hpp b/src/slic3r/GUI/Gizmos/GLGizmoAlignment.hpp
new file mode 100644
index 0000000000..5bbeceb7a6
--- /dev/null
+++ b/src/slic3r/GUI/Gizmos/GLGizmoAlignment.hpp
@@ -0,0 +1,95 @@
+#ifndef slic3r_GLGizmoAlignment_hpp_
+#define slic3r_GLGizmoAlignment_hpp_
+
+#include "libslic3r/Point.hpp"
+#include "libslic3r/BoundingBox.hpp"
+#include "slic3r/GUI/Selection.hpp"
+#include
+#include
+
+namespace Slic3r {
+namespace GUI {
+
+class GLCanvas3D;
+
+class GLGizmoAlignment
+{
+public:
+ enum class AlignType {
+ NONE = -1,
+ CENTER_X,
+ CENTER_Y,
+ CENTER_Z,
+ Y_MAX,
+ Y_MIN,
+ X_MAX,
+ X_MIN,
+ Z_MAX,
+ Z_MIN,
+ DISTRIBUTE_X,
+ DISTRIBUTE_Y,
+ DISTRIBUTE_Z
+ };
+ struct ObjectInfo {
+ int object_idx;
+ int instance_idx;
+ BoundingBoxf3 bbox;
+ Vec3d center;
+
+ ObjectInfo(int obj_idx, int inst_idx, const BoundingBoxf3& bb)
+ : object_idx(obj_idx), instance_idx(inst_idx), bbox(bb), center(bb.center()) {}
+ };
+
+ explicit GLGizmoAlignment(GLCanvas3D& canvas);
+ ~GLGizmoAlignment() = default;
+
+ bool align_objects(AlignType type,bool align_parent = false);
+ bool distribute_objects(AlignType type);
+
+ bool align_to_center(AlignType type,bool align_parent = false);
+ bool align_to_y_max(bool align_parent = false);
+ bool align_to_y_min(bool align_parent = false);
+ bool align_to_x_max(bool align_parent = false);
+ bool align_to_x_min(bool align_parent = false);
+ bool align_to_z_max(bool align_parent = false);
+ bool align_to_z_min(bool align_parent = false);
+
+ bool distribute_x();
+ bool distribute_y();
+ bool distribute_z();
+
+ bool can_align(AlignType type) const;
+ bool can_distribute(AlignType type) const;
+
+ std::vector get_selected_objects_info(BoundingBoxf3 &big_bb) const;
+ double get_current_coord(std::string operation_name, BoundingBoxf3 &bbox);
+ Vec3d generate_displacement(std::string operation_name, double offset);
+ bool is_part_align_parent();
+ void set_parent_box(const BoundingBoxf3 &bb);
+
+private:
+ GLCanvas3D& m_canvas;
+
+ template
+ bool align_objects_generic(GetCoordFunc get_coord, SetCoordFunc set_coord, const std::string &operation_name, bool align_parent = false);
+
+ template
+ bool distribute_objects_generic(GetCoordFunc get_coord, int axis,
+ const std::string& operation_name);
+
+ Selection& get_selection() const;
+ bool take_snapshot(const std::string& name);
+ void apply_transformation(int obj_idx, int inst_idx, const Vec3d& displacement);
+ void finish_operation(const std::string &operation_name, bool force_volume_move = false);
+
+ bool validate_selection_for_align() const;
+ bool validate_selection_for_distribute() const;
+
+private:
+ BoundingBoxf3 m_parent_box;
+};
+
+} // namespace GUI
+} // namespace Slic3r
+
+#endif // slic3r_GLGizmoAlignment_hpp_
\ No newline at end of file
diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp
index 41d4811664..a5a3122b85 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp
@@ -470,6 +470,37 @@ bool GLGizmosManager::check_gizmos_closed_except(EType type) const
return true;
}
+// Switches the active plate to the one containing the first selected object,
+// so that subsequent operations (align/distribute) act on a plate the user
+// can actually see.
+void GLGizmosManager::check_object_located_outside_plate(bool change_plate)
+{
+ PartPlateList& plate_list = wxGetApp().plater()->get_partplate_list();
+ auto curr_plate_index = plate_list.get_curr_plate_index();
+ Selection& selection = m_parent.get_selection();
+ auto idxs = selection.get_volume_idxs();
+ if (idxs.empty())
+ return;
+
+ const GLVolume* v = selection.get_volume(*idxs.begin());
+ int object_idx = v->object_idx();
+ const Model* model = m_parent.get_model();
+ if (object_idx < 0 || object_idx >= (int) model->objects.size())
+ return;
+
+ ModelObject* model_object = model->objects[object_idx];
+ for (size_t i = 0; i < plate_list.get_plate_count(); ++i) {
+ auto plate = plate_list.get_plate(i);
+ for (auto object : plate->get_objects_on_this_plate()) {
+ if (model_object == object) {
+ if (change_plate && curr_plate_index != (int) i)
+ plate_list.select_plate(i);
+ return;
+ }
+ }
+ }
+}
+
void GLGizmosManager::set_hover_id(int id)
{
// Measure and assembly handles hover by itself
diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp
index 0914f8d958..cba59de9f1 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp
@@ -261,6 +261,7 @@ public:
void reset_all_states();
bool open_gizmo(EType type);
bool check_gizmos_closed_except(EType) const;
+ void check_object_located_outside_plate(bool change_plate = true);
void set_hover_id(int id);
diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp
index cf9dddeee7..da828527f2 100644
--- a/src/slic3r/GUI/Plater.cpp
+++ b/src/slic3r/GUI/Plater.cpp
@@ -245,6 +245,7 @@
#include "Widgets/MultiNozzleSync.hpp" // NozzleOption, tryPopUpMultiNozzleDialog, setExtruderNozzleCount
#include "DeviceCore/DevNozzleSystem.h" // DevNozzle, GetExtNozzles / GetRackNozzles
#include "ProjectDirtyStateManager.hpp"
+#include "Gizmos/GLGizmoAlignment.hpp"
#include "Gizmos/GLGizmoSimplify.hpp" // create suggestion notification
#include "Gizmos/GLGizmoSVG.hpp" // Drop SVG file
#include "Gizmos/GizmoObjectManipulation.hpp"
@@ -7484,6 +7485,18 @@ struct Plater::priv
void delete_all_objects_from_model();
void reset(bool apply_presets_change = false, bool reload_presets = true);
void center_selection();
+ void distribute_selection_x();
+ void distribute_selection_y();
+ void distribute_selection_z();
+ void align_selection_x_min();
+ void align_selection_x_center();
+ void align_selection_x_max();
+ void align_selection_y_min();
+ void align_selection_y_center();
+ void align_selection_y_max();
+ void align_selection_z_min();
+ void align_selection_z_center();
+ void align_selection_z_max();
void drop_selection();
void mirror(Axis axis);
void split_object(bool auto_drop = true);
@@ -10913,6 +10926,78 @@ void Plater::priv::center_selection()
view3D->center_selected();
}
+void Plater::priv::distribute_selection_x()
+{
+ GLGizmoAlignment alignment_helper(*view3D->get_canvas3d());
+ alignment_helper.distribute_objects(GLGizmoAlignment::AlignType::DISTRIBUTE_X);
+}
+
+void Plater::priv::distribute_selection_y()
+{
+ GLGizmoAlignment alignment_helper(*view3D->get_canvas3d());
+ alignment_helper.distribute_objects(GLGizmoAlignment::AlignType::DISTRIBUTE_Y);
+}
+
+void Plater::priv::distribute_selection_z()
+{
+ GLGizmoAlignment alignment_helper(*view3D->get_canvas3d());
+ alignment_helper.distribute_objects(GLGizmoAlignment::AlignType::DISTRIBUTE_Z);
+}
+
+void Plater::priv::align_selection_x_min()
+{
+ GLGizmoAlignment alignment_helper(*view3D->get_canvas3d());
+ alignment_helper.align_objects(GLGizmoAlignment::AlignType::X_MIN);
+}
+
+void Plater::priv::align_selection_x_center()
+{
+ GLGizmoAlignment alignment_helper(*view3D->get_canvas3d());
+ alignment_helper.align_objects(GLGizmoAlignment::AlignType::CENTER_X);
+}
+
+void Plater::priv::align_selection_x_max()
+{
+ GLGizmoAlignment alignment_helper(*view3D->get_canvas3d());
+ alignment_helper.align_objects(GLGizmoAlignment::AlignType::X_MAX);
+}
+
+void Plater::priv::align_selection_y_min()
+{
+ GLGizmoAlignment alignment_helper(*view3D->get_canvas3d());
+ alignment_helper.align_objects(GLGizmoAlignment::AlignType::Y_MIN);
+}
+
+void Plater::priv::align_selection_y_center()
+{
+ GLGizmoAlignment alignment_helper(*view3D->get_canvas3d());
+ alignment_helper.align_objects(GLGizmoAlignment::AlignType::CENTER_Y);
+}
+
+void Plater::priv::align_selection_y_max()
+{
+ GLGizmoAlignment alignment_helper(*view3D->get_canvas3d());
+ alignment_helper.align_objects(GLGizmoAlignment::AlignType::Y_MAX);
+}
+
+void Plater::priv::align_selection_z_min()
+{
+ GLGizmoAlignment alignment_helper(*view3D->get_canvas3d());
+ alignment_helper.align_objects(GLGizmoAlignment::AlignType::Z_MIN);
+}
+
+void Plater::priv::align_selection_z_center()
+{
+ GLGizmoAlignment alignment_helper(*view3D->get_canvas3d());
+ alignment_helper.align_objects(GLGizmoAlignment::AlignType::CENTER_Z);
+}
+
+void Plater::priv::align_selection_z_max()
+{
+ GLGizmoAlignment alignment_helper(*view3D->get_canvas3d());
+ alignment_helper.align_objects(GLGizmoAlignment::AlignType::Z_MAX);
+}
+
void Plater::priv::drop_selection()
{
view3D->drop_selected();
@@ -22226,6 +22311,18 @@ void Plater::suppress_background_process(const bool stop_background_process)
BackgroundSlicingProcess& Plater::background_process() { return p->background_process; }
void Plater::center_selection() { p->center_selection(); }
+void Plater::distribute_selection_x() { p->distribute_selection_x(); }
+void Plater::distribute_selection_y() { p->distribute_selection_y(); }
+void Plater::distribute_selection_z() { p->distribute_selection_z(); }
+void Plater::align_selection_x_min() { p->align_selection_x_min(); }
+void Plater::align_selection_x_center() { p->align_selection_x_center(); }
+void Plater::align_selection_x_max() { p->align_selection_x_max(); }
+void Plater::align_selection_y_min() { p->align_selection_y_min(); }
+void Plater::align_selection_y_center() { p->align_selection_y_center(); }
+void Plater::align_selection_y_max() { p->align_selection_y_max(); }
+void Plater::align_selection_z_min() { p->align_selection_z_min(); }
+void Plater::align_selection_z_center() { p->align_selection_z_center(); }
+void Plater::align_selection_z_max() { p->align_selection_z_max(); }
void Plater::drop_selection() { p->drop_selection(); }
void Plater::mirror(Axis axis) { p->mirror(axis); }
void Plater::split_object(bool auto_drop) { p->split_object(auto_drop); }
diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp
index 0bb2d65add..a270eea1c3 100644
--- a/src/slic3r/GUI/Plater.hpp
+++ b/src/slic3r/GUI/Plater.hpp
@@ -762,6 +762,18 @@ public:
//BBS: add clone logic
void clone_selection();
void center_selection();
+ void distribute_selection_x();
+ void distribute_selection_y();
+ void distribute_selection_z();
+ void align_selection_x_min();
+ void align_selection_x_center();
+ void align_selection_x_max();
+ void align_selection_y_min();
+ void align_selection_y_center();
+ void align_selection_y_max();
+ void align_selection_z_min();
+ void align_selection_z_center();
+ void align_selection_z_max();
void drop_selection();
void search(bool plater_is_active, Preset::Type type, wxWindow *tag, TextInput *etag, wxWindow *stag);
void mirror(Axis axis);