feat: Add File header G-code option and print_time_sec/filament_length_m placeholders (#12186)

## Problem

Some Creality printers (e.g. Ender-3 V3 SE) rely on metadata comments in the first lines of G-code files to display print info on the screen (estimated time, filament usage, layer height). This follows a format originally used by Cura/Creality Print:
```
;FLAVOR:Marlin
;TIME:3708.97
;Filament used:6.21m
;Layer height:0.2
```

OrcaSlicer currently has no way to write content before the `HEADER_BLOCK` in the G-code output, and does not expose `print_time_sec` or `filament_length_m` as usable placeholders. As a result, these printers show zeroed-out print info on screen.

## Changes

### 1. New placeholders (post-processing)
Added two new G-code placeholders resolved during post-processing:
- `{print_time_sec}` — total estimated print time in seconds (double)
- `{filament_length_m}` — total filament length in meters (double)

These values are only available after G-code generation, so they use inline marker replacement (`@PRINT_TIME_SEC@`, `@FILAMENT_LENGTH_M@`) that `GCodeProcessor::run_post_process()` substitutes with actual computed values — the same pattern used by existing M73 and layer count placeholders.

### 2. New "File header G-code" option (`machine_top_gcode`)
Added a new G-code field in **Printer Settings > Machine G-code** that writes content at the very top of the output file, before `HEADER_BLOCK_START`. This allows users to add firmware-specific metadata that must appear in the first lines.

### 3. Creality Ender-3 V3 SE profile update
Pre-configured the Ender-3 V3 SE profiles (all 4 nozzle variants) with a default `machine_top_gcode` value matching the Cura-compatible header format, so print info displays correctly out of the box.

# Screenshots

| Before (current OrcaSlicer) | After (this PR) |
|---|---|
| ![IMG_5285](https://github.com/user-attachments/assets/fdd2cc96-6593-4108-83f4-e272d5547467) | ![IMG_5286](https://github.com/user-attachments/assets/6cb4091a-4560-4596-93d9-49f2ff8f0a2b) |

## Tests

- Sliced test model with Ender-3 V3 SE profile
- Verified G-code output contains correct values in first lines:
  - `;TIME:` with actual print time in seconds
  - `;Filament used:` with filament length in meters
  - `;Layer height:` with correct layer height
- Verified `{print_time_sec}` and `{filament_length_m}` work in both Machine Start G-code and File header G-code fields
- Verified empty `machine_top_gcode` produces no extra output
- Built and tested on macOS (arm64)
This commit is contained in:
davyd
2026-02-08 12:56:28 -03:00
committed by GitHub
parent 1663dab6ff
commit 2f2f0df6af
11 changed files with 99 additions and 3 deletions

View File

@@ -4434,6 +4434,17 @@ void TabPrinter::build_fff()
const int gcode_field_height = 15; // 150
const int notes_field_height = 25; // 250
page = add_options_page(L("Machine G-code"), "custom-gcode_gcode"); // ORCA: icon only visible on placeholders
optgroup = page->new_optgroup(L("File header G-code"), L"param_gcode", 0);
optgroup->m_on_change = [this, &optgroup_title = optgroup->title](const t_config_option_key& opt_key, const boost::any& value) {
validate_custom_gcode_cb(this, optgroup_title, opt_key, value);
};
optgroup->edit_custom_gcode = edit_custom_gcode_fn;
option = optgroup->get_option("file_start_gcode");
option.opt.full_width = true;
option.opt.is_code = true;
option.opt.height = 8;
optgroup->append_single_option_line(option);
optgroup = page->new_optgroup(L("Machine start G-code"), L"param_gcode", 0);
optgroup->m_on_change = [this, &optgroup_title = optgroup->title](const t_config_option_key& opt_key, const boost::any& value) {
validate_custom_gcode_cb(this, optgroup_title, opt_key, value);