This tool is used for Directly Connected Palette 2/2S to your Klipper Printer, like Voron using https://www.klipper3d.org/Config_Reference.html#palette2
It uses built.in Slicer wipe tower, there are plans to make calculation of wiping different, and this software recommending how much you need to add to not have short splices.
B) If possible set everything in Printer Settings, Single Extruder MM Setup everything to 0, but this should be optional, if it does not work when you set some value, please create Issue, my goal is to strip all Prusa Commands so you have smallest setup possible
C) Print Settings => Output Settings => Post Processing Script => C:\Users\richa\source\repos\p2pp\dotnet-p2pp-poc\bin\Debug\net10.0\P2KLPU.exe;
D) In Printer => Custom GCode => Start GCode you add options below listed, for example my personal options are:
;P2KLPU PRINTERPROFILE=e666315ff39d9c78
; Printer Profile is random number you create, which represents your printer, I will in the future implement way to calculate this hash out of your printer name in slicer
;P2KLPU SPLICEOFFSET=38
; Splice offset is offset of your mixing hotend part, if you have short hotend, you can have low offset (Almost 0), if you have long hotend, it can be up to 60. I have Dragon Water Cooled, with longer offset, 38mm works for me
; If your splices come too soon, make offset larger, if they come too late, make it smaller. Start at 25 and see. Depending on your tube length, one layer of large rectangle with 4 colors can be enough to do this.
;P2KLPU MINSTARTSPLICE=100
; This is just checking for your first splice, so it has at least 100mm, Palette 2S manual states so 85 is minimum, but I found 100mm as safe where filament does not break (It has tension from moving around Palete)
;P2KLPU MINSPLICE=70
; This is just checking for every remaining splice, so it is not shorter. If splice is too short, sometimes they can break inside Palette, Palette 2S Manual states 60mm minimum, I found 70 mm safe.
;P2KLPU EXTRAENDFILAMENT=150
; This is how much extra filament there is at the end, if you have like me hotend/extruder path 100 mm, its nice to have 50mm above to grip the filament and pull it out
;P2KLPU LINEARPINGLENGTH=1000
; This is how often Palette PINGS with Klipper, Depending on your tube length, your result may wary. Too small number means overcompensating too often, too large number, means no compensation at all
;P2KLPU MATERIAL_PETG_PETG_3_-1_-5
; This says, if you meet PETG and PETG, and there are no other directives, 3 heat, -1 Compression and -5 cooling
;P2KLPU MATERIAL_IN1_IN3_2_0_-5
; This says, even if you know material mixing, if you are mixing INPUT 1 and INPUT 3, 2 heat, 0 Compression and -5 cooling
;P2KLPU MATERIAL_IN3_IN1_2_0_-5
; This says, even if you know material mixing, if you are mixing INPUT 3 and INPUT 1, 2 heat, 0 Compression and -5 cooling
;P2KLPU MATERIAL_IN4_IN3_2_0_-5
; This says, even if you know material mixing, if you are mixing INPUT 4 and INPUT 3, 2 heat, 0 Compression and -5 cooling
;P2KLPU MATERIAL_IN3_IN4_2_0_-5
; This says, even if you know material mixing, if you are mixing INPUT 3 and INPUT 4, 2 heat, 0 Compression and -5 cooling
; You can also redefine materials as PETG2, see below, but point is, I have Gray PETG in Input 1 and Blue Matte in Input 3, Yellow Matte in Input 4, even tho all are PETG, 3 and 4 mix great, 1 and 3 mix horribly, and 1 and 4 mix horribly, I am giving extra control to user to decide
This script requires .NET Runtime 10.0.1 https://dotnet.microsoft.com/en-us/download/dotnet/10.0
=== P2KLPU Analysis ===
Display name: xxx_-_sga_top_pylons.mcf.gcode
Extrusion mode: Relative (M83)
Total positive extrusion: 116421.693 mm
RAW_MMU effective positive extrusion: 116421.693 mm
Tower effective extrusion: 32600.053 mm
Model effective extrusion: 83821.64 mm
Tower XY bounds (from ;TYPE markers): X[60.698,100.7] Y[55.336,171.396]
Splices detected: 236
Palette pings (O31) planned: 118
O31 encodes a ping location along the extruded filament.
- In Palette 2/2S connected mode, P2PP uses O31 Dxxxxxxxx where Dxxxxxxxx is the hex of the float32 bit-pattern (little-endian) representing millimeters.
- In Palette 3 mode, it can appear as O31 L<mm> mm.
Ping plan (1-based):
# O31 Location(mm)
1 O31 D44757335 981.80
2 O31 D44f5866b 1964.20
3 O31 D453841ad 2948.10
4 O31 D45759afe 3929.69
5 O31 D45997819 4911.01
6 O31 D45b821a7 5892.21
7 O31 D45d6cdd5 6873.73
8 O31 D45f57673 7854.81
9 O31 D460a10f3 8836.24
10 O31 D46196b78 9818.87
11 O31 D4628c25a 10800.59
12 O31 D463816bc 11781.68
13 O31 D46476cde 12763.22
14 O31 D4656c480 13745.13
15 O31 D46661944 14726.32
16 O31 D46756ed1 15707.70
17 O31 D4682617c 16688.74
18 O31 D468a0bc0 17669.88
19 O31 D4691b5d8 18650.92
20 O31 D4699609e 19632.31
21 O31 D46a10b07 20613.51
22 O31 D46a8b511 21594.53
23 O31 D46b05f2b 22575.58
24 O31 D46b8092c 23556.59
25 O31 D46bfb343 24537.63
26 O31 D46c75d44 25518.63
27 O31 D46cf0948 26500.64
28 O31 D46d6b373 27481.73
29 O31 D46de5d7b 28462.74
30 O31 D46e607e8 29443.95
31 O31 D46edb1fb 30424.99
32 O31 D46f561c1 31408.88
33 O31 D46fd0ccd 32390.40
34 O31 D47025b74 33371.45
35 O31 D4706307e 34352.49
36 O31 D470a058f 35333.56
37 O31 D470ddaa9 36314.66
38 O31 D4711afb5 37295.71
39 O31 D47158505 38277.02
40 O31 D47195ab3 39258.70
41 O31 D471d2fc1 40239.76
42 O31 D47210553 41221.32
43 O31 D4724dac7 42202.78
44 O31 D4728afc9 43183.79
45 O31 D472c84ef 44164.93
46 O31 D47305a02 45146.01
47 O31 D47342f2b 46127.17
48 O31 D47380438 47108.22
49 O31 D473bd938 48089.22
50 O31 D473fae58 49070.34
51 O31 D47438382 50051.51
52 O31 D47475893 51032.57
53 O31 D474b2e68 52014.41
54 O31 D474f041d 52996.11
55 O31 D4752da42 53978.26
56 O31 D4756af51 54959.32
57 O31 D475a8466 55940.40
58 O31 D475e5ad6 56922.84
59 O31 D47622fe7 57903.90
60 O31 D476604f6 58884.96
61 O31 D4769da31 59866.19
62 O31 D476dafa6 60847.65
63 O31 D477184ac 61828.67
64 O31 D477559ad 62809.68
65 O31 D47792f04 63791.02
66 O31 D477d0410 64772.06
67 O31 D47806ca0 65753.25
68 O31 D47825739 66734.45
69 O31 D478441c2 67715.51
70 O31 D47862c43 68696.53
71 O31 D478817e3 69679.78
72 O31 D478a0269 70660.82
73 O31 D478becf3 71641.90
74 O31 D478dd77e 72622.99
75 O31 D478fc200 73604.00
76 O31 D4791acd6 74585.67
77 O31 D47939780 75567.00
78 O31 D47958269 76548.82
79 O31 D47976cea 77529.83
80 O31 D479957b4 78511.40
81 O31 D479b4237 79492.43
82 O31 D479d2ce9 80473.82
83 O31 D479f17a5 81455.29
84 O31 D47a10292 82437.14
85 O31 D47a2ed4f 83418.62
86 O31 D47a4d801 84400.00
87 O31 D47a6c282 85381.02
88 O31 D47a8ad04 86362.03
89 O31 D47aa97ae 87343.36
90 O31 D47ac822e 88324.36
91 O31 D47ae6de8 89307.81
92 O31 D47b058b8 90289.44
93 O31 D47b24343 91270.53
94 O31 D47b42df2 92251.89
95 O31 D47b61878 93232.94
96 O31 D47b80334 94214.40
97 O31 D47b9ee1a 95196.21
98 O31 D47bbd8fc 96177.97
99 O31 D47bdc3f3 97159.90
100 O31 D47bfae79 98140.94
101 O31 D47c19915 99122.16
102 O31 D47c383f6 100103.92
103 O31 D47c56ed6 101085.67
104 O31 D47c7598d 102067.10
105 O31 D47c9443c 103048.47
106 O31 D47cb2ed7 104029.68
107 O31 D47cd1983 105011.03
108 O31 D47cf0441 105992.50
109 O31 D47d0eeeb 106973.83
110 O31 D47d2d96b 107954.84
111 O31 D47d4c428 108936.31
112 O31 D47d6aeb0 109917.37
113 O31 D47d899bd 110899.48
114 O31 D47da84a3 111881.28
115 O31 D47dc6f7f 112863.00
116 O31 D47de5a1c 113844.22
117 O31 D47e044d1 114825.63
118 O31 D47e22f5b 115806.71
Splice plan (1-based inputs):
# From->To Location(mm) Length(mm) Algo (Heat, Compression, Cooling) [h,c,k]
1 4->1 5783.66 5783.66 3,-1,-5
2 1->4 7084.91 1301.25 3,-1,-5
3 4->1 11152.06 4067.14 3,-1,-5
4 1->4 12455.33 1303.27 3,-1,-5
5 4->1 16519.65 4064.32 3,-1,-5
6 1->4 17828.22 1308.57 3,-1,-5
7 4->1 18879.15 1050.93 3,-1,-5
8 1->4 20322.88 1443.73 3,-1,-5
9 4->1 21254.48 931.60 3,-1,-5
10 1->3 21465.84 211.36 2,0,-5
11 3->1 21721.28 255.44 2,0,-5
12 1->4 21930.83 209.55 3,-1,-5
13 4->1 22748.67 817.84 3,-1,-5
14 1->3 22958.32 209.65 2,0,-5
15 3->1 23210.52 252.20 2,0,-5
16 1->4 23421.93 211.41 3,-1,-5
17 4->1 24245.07 823.14 3,-1,-5
18 1->3 24453.64 208.57 2,0,-5
19 3->1 24707.96 254.32 2,0,-5
20 1->4 24922.54 214.58 3,-1,-5
21 4->1 25739.78 817.24 3,-1,-5
22 1->3 25954.62 214.84 2,0,-5
23 3->1 26211.21 256.60 2,0,-5
24 1->4 26423.50 212.29 3,-1,-5
25 4->1 27240.46 816.96 3,-1,-5
26 1->3 27459.31 218.85 2,0,-5
27 3->1 27711.50 252.20 2,0,-5
28 1->4 27930.04 218.53 3,-1,-5
29 4->1 28751.78 821.75 3,-1,-5
30 1->3 28966.01 214.23 2,0,-5
31 3->1 29220.33 254.32 2,0,-5
32 1->4 29435.22 214.89 3,-1,-5
33 4->1 30252.54 817.33 3,-1,-5
34 1->3 30466.53 213.99 2,0,-5
35 3->1 30723.13 256.60 2,0,-5
36 1->4 30933.76 210.63 3,-1,-5
37 4->1 31748.49 814.73 3,-1,-5
38 1->3 31961.54 213.05 2,0,-5
39 3->1 32213.74 252.20 2,0,-5
40 1->4 32426.11 212.37 3,-1,-5
41 4->1 33248.39 822.28 3,-1,-5
42 1->3 33458.69 210.30 2,0,-5
43 3->1 33713.01 254.32 2,0,-5
44 1->4 33924.99 211.98 3,-1,-5
45 4->1 34741.37 816.38 3,-1,-5
46 1->3 34951.57 210.21 2,0,-5
47 3->1 35208.17 256.60 2,0,-5
48 1->4 35417.26 209.10 3,-1,-5
49 4->1 36234.11 816.84 3,-1,-5
50 1->3 36444.15 210.04 2,0,-5
51 3->1 36696.35 252.20 2,0,-5
52 1->4 36906.07 209.73 3,-1,-5
53 4->1 37728.42 822.35 3,-1,-5
54 1->3 37936.44 208.02 2,0,-5
55 3->1 38190.76 254.32 2,0,-5
56 1->4 38398.12 207.36 3,-1,-5
57 4->1 39214.63 816.50 3,-1,-5
58 1->3 39422.56 207.94 2,0,-5
59 3->1 39681.95 259.39 2,0,-5
60 1->4 39888.98 207.03 3,-1,-5
61 4->1 40706.71 817.73 3,-1,-5
62 1->3 40914.43 207.73 2,0,-5
63 3->1 41180.67 266.23 2,0,-5
64 1->4 41388.64 207.97 3,-1,-5
65 4->1 42214.55 825.91 3,-1,-5
66 1->3 42420.71 206.16 2,0,-5
67 3->1 42692.80 272.09 2,0,-5
68 1->4 42900.02 207.22 3,-1,-5
69 4->1 43720.53 820.51 3,-1,-5
70 1->3 43928.13 207.60 2,0,-5
71 3->1 44209.93 281.80 2,0,-5
72 1->4 44414.05 204.12 3,-1,-5
73 4->1 45242.94 828.89 3,-1,-5
74 1->3 45448.39 205.45 2,0,-5
75 3->1 45732.90 284.51 2,0,-5
76 1->4 45937.14 204.23 3,-1,-5
77 4->1 46770.61 833.48 3,-1,-5
78 1->3 46973.57 202.96 2,0,-5
79 3->1 47259.56 285.99 2,0,-5
80 1->4 47465.49 205.92 3,-1,-5
81 4->1 48286.50 821.02 3,-1,-5
82 1->3 48490.22 203.72 2,0,-5
83 3->1 48821.95 331.73 2,0,-5
84 1->4 49025.13 203.18 3,-1,-5
85 4->1 49911.74 886.61 3,-1,-5
86 1->3 50115.13 203.39 2,0,-5
87 3->1 50434.85 319.72 2,0,-5
88 1->4 50646.31 211.46 3,-1,-5
89 4->1 51739.14 1092.83 3,-1,-5
90 1->3 51949.79 210.65 2,0,-5
91 3->1 52258.88 309.09 2,0,-5
92 1->4 52466.79 207.91 3,-1,-5
93 4->1 53484.31 1017.52 3,-1,-5
94 1->3 53694.52 210.21 2,0,-5
95 3->1 54183.85 489.33 2,0,-5
96 1->4 54392.91 209.06 3,-1,-5
97 4->1 55048.74 655.83 3,-1,-5
98 1->3 55255.47 206.73 2,0,-5
99 3->1 56052.41 796.94 2,0,-5
100 1->4 56260.43 208.02 3,-1,-5
101 4->1 56546.19 285.77 3,-1,-5
102 1->3 56749.17 202.98 2,0,-5
103 3->1 57555.38 806.21 2,0,-5
104 1->4 57756.66 201.28 3,-1,-5
105 4->1 58043.21 286.55 3,-1,-5
106 1->3 58245.95 202.74 2,0,-5
107 3->1 59024.88 778.94 2,0,-5
108 1->4 59232.97 208.09 3,-1,-5
109 4->1 59519.31 286.34 3,-1,-5
110 1->3 59727.89 208.58 2,0,-5
111 3->1 60460.91 733.03 2,0,-5
112 1->4 60669.73 208.82 3,-1,-5
113 4->1 60955.50 285.77 3,-1,-5
114 1->3 61161.95 206.46 2,0,-5
115 3->1 61896.54 734.58 2,0,-5
116 1->4 62104.97 208.44 3,-1,-5
117 4->1 62391.52 286.55 3,-1,-5
118 1->3 62615.15 223.64 2,0,-5
119 3->1 63357.75 742.60 2,0,-5
120 1->4 63559.88 202.12 3,-1,-5
121 4->1 63912.37 352.50 3,-1,-5
122 1->3 64112.75 200.37 2,0,-5
123 3->1 64858.64 745.89 2,0,-5
124 1->4 65060.63 201.99 3,-1,-5
125 4->1 65411.66 351.03 3,-1,-5
126 1->3 65613.67 202.01 2,0,-5
127 3->1 66360.41 746.74 2,0,-5
128 1->4 66560.66 200.25 3,-1,-5
129 4->1 66942.63 381.97 3,-1,-5
130 1->3 67146.92 204.29 2,0,-5
131 3->1 67958.91 811.99 2,0,-5
132 1->4 68164.58 205.67 3,-1,-5
133 4->1 68835.19 670.60 3,-1,-5
134 1->3 68989.58 154.39 2,0,-5
135 3->1 69587.84 598.26 2,0,-5
136 1->4 69739.55 151.70 3,-1,-5
137 4->1 70909.63 1170.09 3,-1,-5
138 1->3 71061.49 151.86 2,0,-5
139 3->1 71330.80 269.30 2,0,-5
140 1->4 71482.65 151.85 3,-1,-5
141 4->1 72753.59 1270.94 3,-1,-5
142 1->3 72905.32 151.73 2,0,-5
143 3->1 73152.09 246.77 2,0,-5
144 1->4 73303.87 151.78 3,-1,-5
145 4->1 74407.99 1104.12 3,-1,-5
146 1->3 74559.84 151.85 2,0,-5
147 3->1 74806.54 246.70 2,0,-5
148 1->4 74958.25 151.71 3,-1,-5
149 4->1 75930.82 972.57 3,-1,-5
150 1->3 76082.62 151.79 2,0,-5
151 3->1 76381.40 298.78 2,0,-5
152 1->4 76533.23 151.83 3,-1,-5
153 4->1 78037.54 1504.31 3,-1,-5
154 1->3 78189.24 151.70 2,0,-5
155 3->1 78518.61 329.37 2,0,-5
156 1->4 78670.41 151.80 3,-1,-5
157 4->1 80004.46 1334.05 3,-1,-5
158 1->3 80156.30 151.84 2,0,-5
159 3->1 80516.39 360.10 2,0,-5
160 1->4 80668.10 151.71 3,-1,-5
161 4->1 82187.67 1519.57 3,-1,-5
162 1->3 82339.47 151.80 2,0,-5
163 3->1 82709.13 369.66 2,0,-5
164 1->4 82860.96 151.83 3,-1,-5
165 4->1 84438.00 1577.05 3,-1,-5
166 1->3 84589.72 151.71 2,0,-5
167 3->1 85181.71 591.99 2,0,-5
168 1->4 85333.51 151.80 3,-1,-5
169 4->1 86462.88 1129.37 3,-1,-5
170 1->3 86614.70 151.83 2,0,-5
171 3->1 87178.35 563.65 2,0,-5
172 1->4 87330.06 151.71 3,-1,-5
173 4->1 88518.33 1188.27 3,-1,-5
174 1->3 88670.14 151.81 2,0,-5
175 3->1 89211.32 541.18 2,0,-5
176 1->4 89363.14 151.82 3,-1,-5
177 4->1 90233.94 870.80 3,-1,-5
178 1->3 90385.67 151.73 2,0,-5
179 3->1 90917.21 531.54 2,0,-5
180 1->4 91069.02 151.81 3,-1,-5
181 4->1 91946.40 877.38 3,-1,-5
182 1->3 92098.20 151.80 2,0,-5
183 3->1 92557.09 458.89 2,0,-5
184 1->4 92708.82 151.73 3,-1,-5
185 4->1 93529.74 820.92 3,-1,-5
186 1->3 93681.55 151.80 2,0,-5
187 3->1 93959.72 278.17 2,0,-5
188 1->4 94111.52 151.80 3,-1,-5
189 4->1 95985.58 1874.06 3,-1,-5
190 1->3 96137.31 151.73 2,0,-5
191 3->1 96528.76 391.46 2,0,-5
192 1->4 96680.56 151.80 3,-1,-5
193 4->1 98780.08 2099.52 3,-1,-5
194 1->3 98931.87 151.79 2,0,-5
195 3->1 99258.95 327.08 2,0,-5
196 1->4 99410.67 151.73 3,-1,-5
197 4->1 101520.26 2109.59 3,-1,-5
198 1->3 101672.05 151.79 2,0,-5
199 3->1 101979.69 307.64 2,0,-5
200 1->4 102131.47 151.78 3,-1,-5
201 4->1 104459.43 2327.95 3,-1,-5
202 1->3 104611.16 151.73 2,0,-5
203 3->1 104877.86 266.71 2,0,-5
204 1->4 105029.65 151.79 3,-1,-5
205 4->1 105860.49 830.84 3,-1,-5
206 1->3 106012.27 151.79 2,0,-5
207 3->1 106291.71 279.44 2,0,-5
208 1->4 106443.39 151.68 3,-1,-5
209 4->1 107394.32 950.93 3,-1,-5
210 1->3 107546.08 151.76 2,0,-5
211 3->4 107833.84 287.76 2,0,-5
212 4->3 108825.33 991.49 2,0,-5
213 3->4 109324.91 499.58 2,0,-5
214 4->3 110013.64 688.73 2,0,-5
215 3->4 110825.74 812.10 2,0,-5
216 4->3 111199.33 373.59 2,0,-5
217 3->4 111901.04 701.72 2,0,-5
218 4->3 112188.30 287.25 2,0,-5
219 3->4 112412.33 224.03 2,0,-5
220 4->3 112631.98 219.65 2,0,-5
221 3->4 112859.96 227.99 2,0,-5
222 4->3 113080.76 220.80 2,0,-5
223 3->4 113300.28 219.52 2,0,-5
224 4->3 113519.38 219.10 2,0,-5
225 3->4 113738.66 219.28 2,0,-5
226 4->3 113954.98 216.32 2,0,-5
227 3->4 114128.39 173.41 2,0,-5
228 4->3 114345.70 217.31 2,0,-5
229 3->4 114494.03 148.33 2,0,-5
230 4->3 114753.05 259.02 2,0,-5
231 3->4 114900.55 147.50 2,0,-5
232 4->3 115141.78 241.22 2,0,-5
233 3->4 115290.26 148.48 2,0,-5
234 4->3 115524.21 233.95 2,0,-5
235 3->4 115672.54 148.33 2,0,-5
236 4->3 115866.70 194.15 2,0,-5
Input usage summary:
Input Material Used(mm) Min splice(mm) Max splice(mm)
██ DI1 PETG 24200.60 151.68 1443.73
██ DI3 PETG 24855.82 147.50 812.10
██ DI4 PETG 67403.28 194.15 5783.66
Overall splice lengths: min #231 (3->4) 147.50 mm, max #1 (4->1) 5783.66 mm
Wrote G-code: C:\Users\richa\AppData\Local\Temp\.48308_4.gcode.pp
Press any key to exit...
Please report any bugs with Github Issues, this script was heavily inspired by P2PP https://github.com/tomvandeneede/p2pp and https://github.com/vhspace/p2pp to both @tomvandeneede and @vhspace I am giving my respects to keeping this alive
Last final warning, this code was half written by GPT5.2, I have reviewed and written large part of code myself, but the project was too huge to analyze over weekened alone.... I will work on improvements myself.
Foot note, for development, clone the repo, have .NET 10 SDK, and use Visual Studio Code or Visual Studio 2026 Community, no special anything required, its console app
This folder contains a .NET C# proof-of-concept for a future rewrite.
Current focus:
- Drop GUI entirely.
- Primary target: Klipper + Palette 2/2S connected mode.
- Keep configuration inside the G-code via
;P2KLPU ...comment directives (so PrusaSlicer can drive it). - Normalize emitted pauses (
G4) to be more Klipper-friendly and optionally hook macros around ping blocks.
- Accepts PrusaSlicer post-processing style invocation:
input.gcode [output.gcode]. - Reads G-code, detects tool changes (
T0,T1, … /ACTIVATE_EXTRUDER), tracks extrusion, and prints a splice plan. - With
--dry-run, writes nothing (analysis only). - No CLI configuration flags besides
--dry-runand--verbose. - Supports in-file directives anywhere in the G-code (usually in slicer start-gcode comments), for example:
;P2KLPU SPLICE_OFFSET=0;P2KLPU DEFAULT_ALGO=10,5,3;P2KLPU ALGO 1-2=12,7,0- Material-based algorithm overrides (no
=form; legacy style):;P2KLPU MATERIAL_DEFAULT_0_0_0(setsDEFAULT_ALGO);P2KLPU MATERIAL_PETG_PLA_3_-1_-6(applies to any transition wherefilament_typematches);P2KLPU MATERIAL_DI1_DI2_3_-1_-6(directly sets the algorithm for input transition DI1 → DI2)
;P2KLPU SYNC_BEFORE_G4=1(default is on);P2KLPU G4_ZERO_TO_M400=1(default is on);P2KLPU REWRITE_M0_M1=1(default is on);P2KLPU DROP_M0_M1_AFTER_O1=1(default is on);P2KLPU SYNC_PING_MACRO_OVERRIDE=MyOwnMacro(replaces the ping-block sync barrier line);P2KLPU PING_MACRO_BEFORE=PING_BEGIN;P2KLPU PING_MACRO_AFTER=PING_END;P2KLPU OCTOPRINT_STRIP_O_COMMANDS=1(advanced; see OctoPrint section)
- Normalizes
G4:- Rewrites
G4 S<seconds>toG4 P<milliseconds>. - In Klipper mode, replaces
G4 S0/G4 P0withM400(configurable viaG4_ZERO_TO_M400). - In Klipper mode, inserts
M400before non-zeroG4(configurable viaSYNC_BEFORE_G4).
- Rewrites
- Normalizes slicer pauses:
- Rewrites
M0/M1toPAUSE(configurable viaREWRITE_M0_M1). - Drops an
M0/M1immediately after anO1 ...line (configurable viaDROP_M0_M1_AFTER_O1), because Klipper’s[palette2]O1handler already pauses.
- Rewrites
- If a ping block is detected (the file contains
; --- ... INSERT PING CODE ...), optional macros are inserted before the pingG4and after theO31line. - In console analysis output,
O31pings are decoded to millimeters:O31 Dxxxxxxxxis a legacy “hex float32” encoding of the ping position in mm (matches the commonhexify_floatbehavior).O31 L<mm> mmis a more human-readable form seen in some Palette 3 workflows.
RAW_MMU hardening / diagnostics:
- In
RAW_MMUmode, the analysis prints both:- Total positive extrusion (all positive E, including toolchange prime/unload/reload), and
- Effective positive extrusion (positive E excluding E-only toolchange logistics).
- When PrusaSlicer
;TYPE:...markers are present, the analysis also breaks effective extrusion into:- Tower effective extrusion (
;TYPE:Wipe tower/;TYPE:Prime tower), and - Model effective extrusion (everything else).
- Tower effective extrusion (
- The scanner prefers explicit toolchange markers when present:
; CP TOOLCHANGE START/ENDand; TOOLCHANGE START/END.- This makes it much more resilient to PrusaSlicer wipe tower sparse layers and other layout changes, because we don’t rely solely on a fixed “N lines after Tn” heuristic.
dotnet build- Dry-run analysis:
dotnet run --project .\\P2KLPU.csproj --framework net10.0 -- input.gcode --dry-run
PrusaSlicer runs post-processing scripts like:
<script> <input.gcode> <output.gcode>
So in PrusaSlicer you typically only enter the executable path; PrusaSlicer supplies the input/output file paths.
Windows examples:
- If you built the project and want to run via the .NET host:
dotnet "C:\\path\\to\\tool\\bin\\Release\\net10.0\\P2KLPU.dll"
- If you published a self-contained executable:
"C:\\path\\to\\your-tool.exe"
Where to put it in PrusaSlicer:
- Print Settings → Output options → Post-processing scripts
Notes:
- Quote paths with spaces.
- You do not need to add placeholders for input/output; PrusaSlicer appends them.
Usually: no — just add the post-processing script.
You may need additional PrusaSlicer configuration depending on the workflow:
- RAW_MMU auto-enable: this POC can auto-enable
RAW_MMUwhen PrusaSlicer footer containssingle_extruder_multi_material = 1and the file contains tool changes and does not already look Omega-processed. - OctoPrint workflow (see below): to allow auto-detection of “printing via host”, PrusaSlicer must be configured to print to a host so it sets
SLIC3R_PP_HOST.
- This is not a full-featured tool yet: it does not implement a full purge/tower rewrite pipeline.
- Today it’s most useful as a Klipper compatibility pass over connected-mode output (e.g., fixing
G4 S0and letting you hook macros around ping blocks).
Slicer feature edge cases (why Python cared more than this POC):
- Features like variable layer height and combine infill mainly matter when a processor is doing geometry- or layer-structured rewrite (e.g., purge tower geometry / per-layer heuristics), because those slicer options change layer structure and how extrusion is distributed across layers.
- This .NET POC’s RAW_MMU pipeline is primarily stream/timeline based: it plans splices and pings from toolchange events plus “effective positive extrusion” (E-distance excluding E-only toolchange logistics), and otherwise tries to keep print moves intact.
- Practically: variable layer height / combined infill may change where a ping falls along the E timeline, but they are not expected to break processing correctness the way they can for tower-geometry rewrite.
Klipper safety:
- Palette 2/2S “Omega” uses
O..commands (non-standard G-code). On Klipper, the built-in[palette2]module registers theO0..O32commands directly (seeklippy/extras/palette2.py), so a file likesamples/output/example_processed.gcodecan work without defininggcode_macro O21, etc.
Firmware flavor:
- PrusaSlicer writes
; gcode_flavor = ...into the generated G-code (typically in the config footer).- If the file is marked as
klipper, the POC enables Klipper-specific pause/sync fixes. - If the file is marked as a Marlin flavor, the POC is pass-through by default (no
G4orM0/M1rewrites), but explicit ping-block overrides (e.g.;P2KLPU SYNC_PING_MACRO_OVERRIDE=...,;P2KLPU PING_MACRO_BEFORE=...,;P2KLPU PING_MACRO_AFTER=...) are still honored.
- If the file is marked as
Directives are case-insensitive and can appear anywhere in the file.
General:
;P2KLPU RAW_MMU=0|1;P2KLPU PRINTERPROFILE=<hex>(Palette2 printer profile ID);P2KLPU AUTOLOADINGOFFSET=<mm>(see note below);P2KLPU FILAMENTOVERRIDE_DI<n>=<name>(overrides PrusaSlicerfilament_type[n-1]for MATERIAL matching);P2KLPU FILAMENTOVERRIDE=<name>(alias forFILAMENTOVERRIDE_DI1);P2KLPU EXTRAENDFILAMENT=<mm>;P2KLPU MINSTARTSPLICE=<mm>;P2KLPU MINSPLICE=<mm>;P2KLPU SPLICEOFFSET=<mm>;P2KLPU SPLICE_OFFSET=<mm>(alias ofSPLICEOFFSET)
About FILAMENTOVERRIDE:
- This changes the material name used for
MATERIAL_<FROM>_<TO>_h_c_kmatching and for Omega’s material table. - Use it to introduce custom names like
PETG-MATTE/PETG2even if PrusaSlicer’sfilament_typeis more generic.
Material aliases (Spoolman-style, recommended):
- You can attach a stable material token to the filament profile itself, so it follows whichever tool/extruder it is assigned to.
- Add
p2klpu_materialper-filament in PrusaSlicer metadata; the tool reads (first found wins):custom_parameters_filament,filament_custom_variables,filament_notes. - Supported formats per filament entry:
- JSON object (common in
custom_parameters_filament):{"p2klpu_material":"PETG-MATTE"} - Key/value text (notes/custom variables):
p2klpu_material=PETG-MATTE
- JSON object (common in
About AUTOLOADINGOFFSET:
- In connected mode, Palette schedules splices/pings in terms of “mm of filament fed”.
- Some setups effectively have a fixed offset between what the Palette counts and what the printer has already consumed when printing starts (autoload / preloaded length).
- The processor uses this offset to shift Omega distances (notably
O30splice positions,O31ping positions, and the total inO1) by the specified millimeters.
About MINSTARTSPLICE / MINSPLICE:
- These set minimum splice-length thresholds used for analysis warnings.
- When a computed splice length is below the configured minimum, the tool reports a warning in console output.
About EXTRAENDFILAMENT:
- This adds extra “tail” filament to the Omega
O1total length so there is additional filament available after printing finishes.
Ping planning:
;P2KLPU PING_INTERVAL=<mm>;P2KLPU PING_MAX_INTERVAL=<mm>;P2KLPU PING_LENGTH_MULTIPLIER=<float>
RAW_MMU toolchange stripping heuristics:
;P2KLPU MMU_TOOLCHANGE_WINDOW_LINES=<int>;P2KLPU MMU_E_ONLY_STRIP_THRESHOLD=<mm>
Algorithm selection:
;P2KLPU DEFAULT_ALGO=h,c,k;P2KLPU ALGO 1-2=h,c,k(accepts=or:between the key/value);P2KLPU MATERIAL_DEFAULT_h_c_k;P2KLPU MATERIAL_<FROM>_<TO>_h_c_kwhere<FROM>/<TO>are either material names (from PrusaSlicerfilament_type) orDI1..DI4.
Ping-block macro hooks (applies when a ping block is present or inserted):
;P2KLPU PING_MACRO_BEFORE=<gcode>;P2KLPU PING_MACRO_AFTER=<gcode>;P2KLPU PING_MACRO=<gcode>(sets both before and after);P2KLPU SYNC_PING_MACRO_OVERRIDE=<gcode>(replaces the ping-block sync line when it is a zero-length dwell)
Klipper-oriented normalization:
;P2KLPU SYNC_BEFORE_G4=0|1;P2KLPU G4_ZERO_TO_M400=0|1;P2KLPU REWRITE_M0_M1=0|1;P2KLPU DROP_M0_M1_AFTER_O1=0|1
Spoolman integration:
;P2KLPU SPOOLMAN_SET_ACTIVE_SPOOL=0|1- When enabled, the tool looks for per-filament spool IDs in PrusaSlicer metadata (
custom_parameters_filament,filament_custom_variables, orfilament_notes). - Supported key names inside those fields:
spoolman_id,spool_id,target_spool. - When a tool change happens, it emits
SET_ACTIVE_SPOOL ID=<n>(Klipper macro) when an ID is available for that tool.
- When enabled, the tool looks for per-filament spool IDs in PrusaSlicer metadata (
OctoPrint/Marlin compatibility:
;P2KLPU OCTOPRINT_STRIP_O_COMMANDS=0|1- When enabled, the processor rewrites Omega
O*commands into comment markers (;P2KLPU_OCTO O31 ...) so Marlin never sees unknownO*commands. - This is intended for Marlin workflows without an OctoPrint Palette2 plugin.
- If the processor detects host printing via PrusaSlicer (
SLIC3R_PP_HOST) and the file is Marlin flavor, it assumes OctoPrint is in the loop and automatically disables this option to remain compatible with the OctoPrint Palette2 plugin (which requires realO*lines).
- When enabled, the processor rewrites Omega
The community OctoPrint Palette2 plugin intercepts Omega commands (O21, O1, O31, etc.) directly from the outgoing G-code stream.
Practical implications:
- For OctoPrint + Palette2 plugin workflows, the output must contain real
O*lines (not commented out). - The plugin typically suppresses
O*lines so they are not sent to the printer, and replaces pings (O31) with a short dwell.
Auto-detection in this POC:
- If the slicer config indicates Marlin and PrusaSlicer provides
SLIC3R_PP_HOST, the POC assumes printing via host (OctoPrint) and keeps OmegaO*commands intact.