prusa3d / PrusaSlicer

G-code generator for 3D printers (RepRap, Makerbot, Ultimaker etc.)
https://www.prusa3d.com/prusaslicer/
GNU Affero General Public License v3.0
7.76k stars 1.93k forks source link

gcode substitutionhard to get to work, would benefit from test/preview in application #7955

Open KimmoHop opened 2 years ago

KimmoHop commented 2 years ago

Version

Version 2.4.1-beta1+win64

Operating system type + version

W10 64-bit

3D printer brand / version + firmware version (if known)

Should not matter

Behavior

gcode substitution with regex is promising feature, but difficult to use. A simple way to test expressions is needed, because

Example from end of gcode file: gcode_substitutions = (?:M73.P)([0-9]+)(?:.R)([0-9]+);"M117 ${1}% ${2} min left";rs; In regex101 site substitution 'M117 $1% $2 min left' converts 'M73 P9 R104' to 'M117 9% 104 min left' as expected image

In PS M73 lines are not converted.

Well, this should probably go to separate issue, but even if find string is plain 'M73' and replace with is 'M117', nothing is replaced and it's stored as gcode_substitutions = M117;M117;; which looks wrong. These lines are added at the beginning and end of gcode file for unknown reason: ;_GP_FIRST_LINE_M117_PLACEHOLDER ;_GP_LAST_LINE_M117_PLACEHOLDER

Jebtrix commented 2 years ago

A test section would be nice though programs that allow regex usually leave creating/debugging up to dedicated resources ie regex101

substitution format is different ${x} than in regex101 site $x - or is it? (regex itself seems similar)

Regex is always a bit confusing with the mountain of implementations. The Boost-Extended format string that PS uses for replace pattern supports all flavors of numbered capture groups ie:

But in regex101 depending on engine you select your capture group syntax will be specific to that engine. In the end whatever works in regex101 will work in PS in this regard.

In PS M73 lines are not converted.

You are correct, PS does not like to replace M73 it generates. Internally it is one of the few reserved tags and since find-replace post-processor is called before GCodePostProcessor those M73 lines are still placeholder tags. I'm assuming the reason is ensure correct gcodereader preview with layer times functionality.

but even if find string is plain 'M73' and replace with is 'M117', nothing is replaced and it's stored as gcode_substitutions = M117;M117;; which looks wrong. These lines are added at the beginning and end of gcode file for unknown reason: ;_GP_FIRST_LINE_M117_PLACEHOLDER ;_GP_LAST_LINE_M117_PLACEHOLDER

You managed to break some of it by circumstance though. The original internal tag was ;_GP_FIRST_LINE_M73_PLACEHOLDER, your plain text replace changed that to ;_GP_FIRST_LINE_M117_PLACEHOLDER so by the time GCodePostProcessor came along the placeholder tag name was invalid and not processed. I'm guessing some protection of placeholder tags will be implemented. The ; gcode_substitutions = M117;M117;; suffered the same kind of fate and needs to be exempted from itself.

I don't understand why find-replace isn't done dead last, or at least an option to (excluding thumbnail, embedded prusa config, etc). You can easily create invalid gcode that preview, gcodeviewer, printer or even time estimation routines itself won't like any way in its current execution.

bubnikv commented 2 years ago

but even if find string is plain 'M73' and replace with is 'M117', nothing is replaced and it's stored as gcode_substitutions = M117;M117;; which looks wrong. These lines are added at the beginning and end of gcode file for unknown reason:

That was fixed with https://github.com/prusa3d/PrusaSlicer/issues/7952, however we expect complaints that now the comments cannot be post-processed.

substitution format is different ${x} than in regex101 site $x - or is it? (regex itself seems similar)

Substitution format is described in https://www.boost.org/doc/libs/1_78_0/libs/regex/doc/html/boost_regex/format/boost_format_syntax.html as referenced by the release log.

if substition fails, there is no way to know why (or is there)

Substitution failing is a perfectly fine situation for a regular expression. It is perfectly fine if a match is not found.

even if regex or substitution is bogus, there is no error

If a regex fails to compile, G-code export is stopped and a notification is shown. However most of the regular expressions compile just fine even if they don't do what you expect.

documentation does not exist yet

If you click on the "G-code substitutions" label

image

following opens: https://help.prusa3d.com/en/article/g-code-substitutions_301694

bubnikv commented 2 years ago

The G-code is generated first, then post-processed with the regexp find / replace post-processor, then processed with a firmware simulator which estimates times. Then first the M117 lines are inserted into the final G-code. Thus the find / replace post-processor cannot replace M73 lines. This is a chicken - egg problem as we want to see the results of G-code find / replace post processor in G-code time estimates, while you want also the find / replace to modify M73 lines which are produced afterwards.

For Klipper / Voron users, we should really implement a M73 macro as part of Klipper configuration. BTW I got my first successful print on my Voron 2.4 yesterday. Alternatively, we may implement a switch to produce M117 instead of M73, however if we do, I would like to cover all possible M73 / M117 / whatever alternatives in one implementation round.

KimmoHop commented 2 years ago

There has been a PR for M117 remaining time for a long time, but since it's done in source code, it's a bit complicated and when there are changes in master, it breaks often. Postprocessing would be a lot easier.

I would rank "proper" postprocessing above (and after) possible print time changes caused by postprocessing. Or postprocess some known g-codes in second pass at the very end.

Marlin 2 has support for M73, if it is compiled in. Our 2nd printer with custom FW has it enabled, I don't know if original has it. Is it commonly enabled in Ender 3 and clones? Marlin estimation is very poor at beginning though it converges to "done" at the end... Our 1st printer had it in custom Marlin 1.x + some borrowed code from MK3 FW (including scaling with print rate), original and "common" custom FWs do not have it. So I'm OK with whatever solution, M73 from PS and M73 (I made this part) or M117 from Cura postprocessing work for us and cover 99% of what we do.