@@ -31,20 +31,41 @@ jobs:
3131 uses : ultimaker/cura-workflows/.github/workflows/check-actor.yml@main
3232 secrets : inherit
3333
34+ find-ticket-packages :
35+ name : Extract ticket and find packages
36+ uses : ultimaker/cura-workflows/.github/workflows/extract-ticket-and-find-packages.yml@main
37+ secrets : inherit
38+
3439 gcodeanalyzer :
3540 name : Run GCodeAnalyzer on the engine
41+ needs : [check_actor, find-ticket-packages]
42+ if : >-
43+ needs.check_actor.outputs.proceed == 'true' &&
44+ needs.find-ticket-packages.result == 'success'
3645 runs-on : ubuntu-latest
3746 steps :
3847 - name : Setup the build environment
3948 uses : ultimaker/cura-workflows/.github/actions/setup-build-environment@main
4049 with :
4150 install_system_dependencies : true
4251
52+ - name : Resolve GCodeAnalyzer branch
53+ id : resolve_gca_branch
54+ env :
55+ GH_TOKEN : ${{ secrets.CURA_BENCHMARK_PAT }}
56+ run : |
57+ branch="${{ github.head_ref || github.ref_name }}"
58+ if gh api "repos/Ultimaker/GCodeAnalyzer/branches/$branch" --silent 2>/dev/null; then
59+ echo "ref=$branch" >> $GITHUB_OUTPUT
60+ else
61+ echo "ref=main" >> $GITHUB_OUTPUT
62+ fi
63+
4364 - name : Checkout GCodeAnalyzer
4465 uses : actions/checkout@v4
4566 with :
4667 repository : ' Ultimaker/GCodeAnalyzer'
47- ref : ' main '
68+ ref : ${{ steps.resolve_gca_branch.outputs.ref }}
4869 path : ' GCodeAnalyzer'
4970 fetch-depth : 1
5071 token : ${{ secrets.CURA_BENCHMARK_PAT }}
6384 pip install pandas
6485 pip install git+https://github.com/ultimaker/libcharon@CURA-9495_analyzer_requisites#egg=charon
6586
87+ - name : Set package overrides
88+ id : set_overrides
89+ if : needs.find-ticket-packages.outputs.package_overrides != ''
90+ uses : ultimaker/cura-workflows/.github/actions/set-package-overrides@main
91+ with :
92+ package_overrides : ${{ needs.find-ticket-packages.outputs.package_overrides }}
93+ profile : cura.jinja
94+
6695 - name : Install dependencies and build CuraEngine
67- run : conan build . -s build_type=Release --build=missing --update -g VirtualRunEnv -o "curaengine/*:with_cura_resources=True"
96+ run : conan build . --profile ${{ steps.set_overrides.outputs.profile || 'cura.jinja' }} - s build_type=Release --build=missing --update -g VirtualRunEnv -o "curaengine/*:with_cura_resources=True"
6897
6998 - name : Collect STL-files, run CuraEngine, output GCode-files
7099 run : |
@@ -76,138 +105,14 @@ jobs:
76105 ( time ./build/Release/CuraEngine slice --force-read-parent --force-read-nondefault -v -p -j $CURA_RESOURCES/definitions/ultimaker_s3.def.json -l $file -o `basename $file .stl`.gcode ) 2> `basename $file .stl`.time
77106 done
78107
79- # TODO: Move this to GCodeAnalyzer
80108 - name : Run GCodeAnalyzer on generated GCode files
81109 id : gcode_out
82- shell : python
83- working-directory : GCodeAnalyzer
84- run : |
85- import sys
86- import os
87- import json
88- import re
89- from Charon.filetypes.GCodeFile import GCodeFile
90-
91- sys.path.append(".")
92- import GCodeAnalyzer
93- GCodeFile.SkipHeaderValidation = True
94-
95- folder_path = ".."
96- jzon = []
97- for filename in os.listdir(folder_path):
98- basename = os.path.basename(filename)
99- _base, ext = os.path.splitext(basename)
100- if ext.lower() != ".gcode":
101- continue
102- infilename = os.path.join(folder_path, filename)
103- with open(infilename.rsplit(".", 1)[0] + ".time", "r") as f:
104- content = f.read()
105- match = re.search(r"^real\s+(\d+)m(\d+\.\d+)s", content, re.MULTILINE)
106- if match:
107- timer = float(match.group(1)) * 60 + float(match.group(2))
108- else:
109- timer = 0
110-
111- frame = GCodeAnalyzer.DataFrame(infilename)
112-
113- line_lengths = frame.gc.extrusions['length'].describe()
114- all_lengths = frame.gc.travels['length'].describe()
115- extrusion_values = frame.gc.extrusions['E'].describe()
116- temperatures = frame['T_0_nozzle'].describe()
117- print_time = frame.time.max()
118- no_retractions = len(frame.gc.retractions)
119- total_travel_length = frame.gc.travels.length.sum()
120-
121- # microsegments violations
122- queue = 16
123- seg_sec = 80
124- violation_threshold = queue / seg_sec
125- microsegments_wall_skin = frame.gc.extrusions.duration[(frame.type == 'WALL-OUTER') | (frame.type == 'WALL-INNER') | (frame.type == 'SKIN')].rolling(queue).sum()
126- no_violations_wall_skin = microsegments_wall_skin[microsegments_wall_skin < violation_threshold].count()
127-
128- microsegments_infill = frame.gc.extrusions.duration[frame.type == 'FILL'].rolling(queue).sum()
129- no_violations_infill = microsegments_infill[microsegments_infill < violation_threshold].count()
130-
131- jzon += [
132- {
133- "name": f"Print time {basename}",
134- "unit": "s",
135- "value": print_time,
136- },
137- {
138- "name": f"Microsegment violations in wall-skin {basename}",
139- "unit": "-",
140- "value": int(no_violations_wall_skin),
141- },
142- {
143- "name": f"Microsegment violations in infill {basename}",
144- "unit": "-",
145- "value": int(no_violations_infill),
146- },
147- {
148- "name": f"Number of retractions {basename}",
149- "unit": "-",
150- "value": no_retractions,
151- },
152- {
153- "name": f"Total travel length {basename}",
154- "unit": "mm",
155- "value": total_travel_length,
156- },
157- {
158- "name": f"Minimum Line Length {basename}",
159- "unit": "mm",
160- "value": line_lengths["min"],
161- },
162- {
163- "name": f"Line Lengths 25 Percentile {basename}",
164- "unit": "mm",
165- "value": line_lengths["25%"],
166- },
167- {
168- "name": f"Minimum All Distances {basename}",
169- "unit": "mm",
170- "value": all_lengths["min"],
171- },
172- {
173- "name": f"All Distances 25 Percentile {basename}",
174- "unit": "mm",
175- "value": all_lengths["25%"],
176- },
177- {
178- "name": f"Extrusion-Axis {basename}",
179- "unit": "mm",
180- "value": extrusion_values["min"],
181- },
182- {
183- "name": f"Extrusion Lengths 25 Percentile {basename}",
184- "unit": "mm",
185- "value": extrusion_values["25%"],
186- },
187- {
188- "name": f"Number Of Temperature Commands {basename}",
189- "unit": "#",
190- "value": temperatures["count"],
191- },
192- {
193- "name": f"Mean Temperature {basename}",
194- "unit": "Celcius",
195- "value": temperatures["50%"],
196- },
197- {
198- "name": f"Slicing time {basename}",
199- "unit": "s",
200- "value": timer,
201- },
202- ]
203-
204- with open("../output.json", "w") as outfile:
205- outfile.write(json.dumps(jzon))
110+ run : python3 GCodeAnalyzer/scripts/analyze_gcode.py --input-dir . --output-file output.json
206111
207112 - name : Store benchmark result
208113 uses : benchmark-action/github-action-benchmark@v1
209114 with :
210- name : CGcodeAnalyzer
115+ name : GCodeAnalyzer
211116 output-file-path : output.json
212117 gh-repository : github.com/Ultimaker/CuraEngineBenchmarks
213118 gh-pages-branch : main
0 commit comments