import FreeCAD as App import Sketcher import Part def generate_hole_pattern(): """Generate parametric hole grid from spreadsheet values.""" doc = App.ActiveDocument if not doc: App.Console.PrintError("No active document\n") return # Create/get spreadsheet sheet = doc.getObject('Spreadsheet') if not sheet: sheet = doc.addObject('Spreadsheet::Sheet', 'Spreadsheet') sheet.set('A1', 'hole_spacing'); sheet.set('B1', '10 mm'); sheet.setAlias('B1', 'hole_spacing') sheet.set('A2', 'hole_radius'); sheet.set('B2', '2.5 mm'); sheet.setAlias('B2', 'hole_radius') sheet.set('A3', 'grid_offset_x'); sheet.set('B3', '10 mm'); sheet.setAlias('B3', 'grid_offset_x') sheet.set('A4', 'grid_offset_y'); sheet.set('B4', '10 mm'); sheet.setAlias('B4', 'grid_offset_y') sheet.set('A5', 'grid_cols'); sheet.set('B5', '5'); sheet.setAlias('B5', 'grid_cols') sheet.set('A6', 'grid_rows'); sheet.set('B6', '5'); sheet.setAlias('B6', 'grid_rows') doc.recompute() App.Console.PrintMessage("Created Spreadsheet with default parameters\n") # Read grid size cols = int(sheet.grid_cols) rows = int(sheet.grid_rows) # Get/create sketch sketch = doc.getObject('HolePatternSketch') if not sketch: body = doc.getObject('Body') if body: sketch = body.newObject('Sketcher::SketchObject', 'HolePatternSketch') sketch.AttachmentSupport = [(body.Origin.XY_Plane, '')] sketch.MapMode = 'FlatFace' else: sketch = doc.addObject('Sketcher::SketchObject', 'HolePatternSketch') App.Console.PrintMessage("Created HolePatternSketch\n") # Clear existing geometry for i in range(sketch.GeometryCount - 1, -1, -1): sketch.delGeometry(i) # Generate pattern for i in range(cols): for j in range(rows): circle_idx = sketch.addGeometry( Part.Circle(App.Vector(0, 0, 0), App.Vector(0, 0, 1), 1), False ) cx = sketch.addConstraint(Sketcher.Constraint('DistanceX', -1, 1, circle_idx, 3, 10)) sketch.setExpression(f'Constraints[{cx}]', f'Spreadsheet.grid_offset_x + {i} * Spreadsheet.hole_spacing') cy = sketch.addConstraint(Sketcher.Constraint('DistanceY', -1, 1, circle_idx, 3, 10)) sketch.setExpression(f'Constraints[{cy}]', f'Spreadsheet.grid_offset_y + {j} * Spreadsheet.hole_spacing') r = sketch.addConstraint(Sketcher.Constraint('Radius', circle_idx, 1)) sketch.setExpression(f'Constraints[{r}]', 'Spreadsheet.hole_radius') doc.recompute() App.Console.PrintMessage(f"Generated {cols}x{rows} hole pattern ({cols*rows} holes)\n") # Run when macro is executed if __name__ == '__main__': generate_hole_pattern()