@@ -12,6 +12,34 @@ describe 'Concentric Infill Generation', ->
1212
1313 slicer = new Polyslice ({progressCallback : null })
1414
15+ # Parse X/Y coordinates from all infill extrusion (G1 ... E) lines in a G-code string.
16+ parseFillExtrusionCoords = (gcode ) ->
17+
18+ lines = gcode .split (' \n ' )
19+ inFill = false
20+ coords = []
21+
22+ for line in lines
23+
24+ if line .includes (' ; TYPE: FILL' )
25+ inFill = true
26+ else if line .includes (' ; TYPE:' ) and not line .includes (' ; TYPE: FILL' )
27+ inFill = false
28+
29+ if inFill and line .includes (' G1' ) and line .includes (' E' )
30+
31+ xMatch = line .match (/ X([\d. -] + )/ )
32+ yMatch = line .match (/ Y([\d. -] + )/ )
33+
34+ if xMatch and yMatch
35+ coords .push ({ x : parseFloat (xMatch[1 ]), y : parseFloat (yMatch[1 ]) })
36+
37+ return coords
38+
39+ # Tolerance (mm) applied to hole-radius assertions to absorb polygon approximation
40+ # of circular hole boundaries (sliced as polygons, not true circles).
41+ HOLE_TOLERANCE = 0.5
42+
1543 describe ' Pattern Generation Tests' , ->
1644
1745 test ' should generate infill for middle layers' , ->
@@ -199,35 +227,16 @@ describe 'Concentric Infill Generation', ->
199227
200228 # Verify that infill doesn't generate in the hole area.
201229 # Extract coordinates from infill sections.
202- inFill = false
203- fillCoords = []
204-
205- for line in lines
206-
207- if line .includes (' ; TYPE: FILL' )
208- inFill = true
209- else if line .includes (' ; TYPE:' ) and not line .includes (' ; TYPE: FILL' )
210- inFill = false
211-
212- if inFill and line .includes (' G1' ) and line .includes (' E' )
213-
214- # Parse X and Y coordinates from G-code.
215- # Regex captures numeric value after X or Y (e.g., "X110.5" → match[1] = "110.5").
216- xMatch = line .match (/ X([\d. -] + )/ )
217- yMatch = line .match (/ Y([\d. -] + )/ )
218-
219- if xMatch and yMatch
220- fillCoords .push ({ x : parseFloat (xMatch[1 ]), y : parseFloat (yMatch[1 ]) })
230+ fillCoords = parseFillExtrusionCoords (result)
221231
222232 # Check that no infill points are in the center hole area.
223233 # Derive build plate center from slicer configuration to avoid hardcoding.
224234 centerX = slicer .getBuildPlateWidth () / 2
225235 centerY = slicer .getBuildPlateLength () / 2
226236
227237 # For a torus with radius 5 and tube 2, the hole radius is approximately 3mm.
238+ # Use HOLE_TOLERANCE to absorb polygon approximation of the circular hole.
228239 holeRadius = 3
229-
230- # Count how many infill points are near the hole center.
231240 pointsNearHole = 0
232241
233242 for coord in fillCoords
@@ -236,7 +245,7 @@ describe 'Concentric Infill Generation', ->
236245 dy = coord .y - centerY
237246 distToCenter = Math .sqrt (dx * dx + dy * dy)
238247
239- if distToCenter < holeRadius
248+ if distToCenter < holeRadius - HOLE_TOLERANCE
240249 pointsNearHole++
241250
242251 # Should have no points in the hole area after the fix.
@@ -286,29 +295,14 @@ describe 'Concentric Infill Generation', ->
286295
287296 lines = result .split (' \n ' )
288297
289- # Extract infill extrusion G-code coordinates.
290- inFill = false
291- fillCoords = []
292-
293- for line in lines
294-
295- if line .includes (' ; TYPE: FILL' )
296- inFill = true
297- else if line .includes (' ; TYPE:' ) and not line .includes (' ; TYPE: FILL' )
298- inFill = false
299-
300- if inFill and line .includes (' G1' ) and line .includes (' E' )
301-
302- xMatch = line .match (/ X([\d. -] + )/ )
303- yMatch = line .match (/ Y([\d. -] + )/ )
304-
305- if xMatch and yMatch
306- fillCoords .push ({ x : parseFloat (xMatch[1 ]), y : parseFloat (yMatch[1 ]) })
298+ # Extract infill extrusion G-code coordinates using shared helper.
299+ fillCoords = parseFillExtrusionCoords (result)
307300
308301 centerX = slicer .getBuildPlateWidth () / 2
309302 centerY = slicer .getBuildPlateLength () / 2
310303
311- # The circular hole has radius 6mm — no infill point should fall inside it.
304+ # The circular hole has radius 6mm. Use HOLE_TOLERANCE to absorb
305+ # polygon approximation of the circular hole boundary.
312306 holeRadius = 6
313307 pointsNearHole = 0
314308
@@ -318,7 +312,7 @@ describe 'Concentric Infill Generation', ->
318312 dy = coord .y - centerY
319313 distToCenter = Math .sqrt (dx * dx + dy * dy)
320314
321- if distToCenter < holeRadius
315+ if distToCenter < holeRadius - HOLE_TOLERANCE
322316 pointsNearHole++
323317
324318 # No infill should be generated inside the circular hole.
0 commit comments