PlottPaint transforms your gantry-style plotter into an automated painting machine with intelligent brush stroke profiles, color management, and advanced path optimization.
- Multi-Color Painting: Define multiple paint wells with custom colors and positions
- Intelligent Paint Management: Automatic wash/wipe sequences on color changes
- Paint Refresh Control: Configurable paint refresh intervals to maintain consistent brush loading
- Paint Order Tracking: Respects the sequence in which colors were assigned to strokes
- Dynamic Z-Axis Control: Apply pressure curves to strokes for realistic brush effects
- Custom Profiles: Create and manage reusable brush stroke profiles with pressure curves
- Visual Profile Editor: Interactive Bézier curve editor for designing brush behaviors
- Profile Parameters:
- Customizable sample count for smooth curves
- Adjustable stroke speed per profile
- Min/Max Z depth control
- Paint Only Mode Integration: Assign brush profiles to painting strokes after G-code generation
- Vector Drawing: Lines, rectangles, circles, polylines, and Bézier curves
- Object Grouping: Group/ungroup strokes, hierarchical parent groups
- Subdivision: Add intermediate points to strokes for finer control
- Selection & Transform: Select, move, copy, paste, and delete strokes
- Snap Features: Snap to endpoints, grid snapping with customizable spacing
- Reference Images: Load reference images for tracing and alignment
- Paint Canvas Definition: Define working area within the plotter bed
- Popular Canvas Presets: Quick selection of A-series, US Letter/Legal, and common art canvas sizes
- Individual Margins: Set different safe margins for each side
- Margin Lock to Canvas: Calculate margins from paint canvas edges
- Auto-Rotation: Automatically rotate canvas 90° to optimize bed usage
- Zoom & Pan: Smooth canvas navigation with mouse wheel zoom
- Smart Path Optimization: Minimize travel distance with nearest-neighbor optimization
- Paint Mode Optimization: Direction-only optimization that preserves paint order
- Coordinate Transformation: Automatic bed-to-work coordinate conversion
- Custom G-code: Configurable start/end G-code sequences
- GRBL Integration: Direct serial communication with GRBL controllers
- G-code Path Visualizer: Visual debugging of generated tool paths
- Segment Analysis: Find backtracks, long rapids, and disconnected segments
- Paint Mode Visualization: Color-coded painting strokes with sequence numbers
- Brush Profile Indicators: Visual markers for segments using brush profiles
- Mark Bad Segments: Flag problematic G-code segments for analysis
- Post-Generation Editing: Assign brush profiles to painting strokes after G-code generation
- Stroke Selection: Select individual or multiple painting strokes
- Visual Feedback: Color-coded strokes with stroke numbers and paint well indicators
- Context Menu Actions: Right-click to assign profiles or select all strokes
- Live G-code Regeneration: Automatically regenerates G-code when profiles are assigned
- Dark/Light Theme: Toggle between dark and light modes
- Themed Components: Consistent theming across all windows and controls
- Drag Value Controls: Drag numeric fields up/down to adjust values
- Responsive Layout: Adaptive UI that works at different window sizes
- Tool Palette: Floating tool selection window
- Windows 10/11
- .NET 8.0 Runtime
- GRBL-based CNC plotter (for physical plotting)
- Clone the repository:
git clone https://github.com/teryakisan/PlottPaint.git
cd PlottPaint- Open the solution:
start NVSPlotter.sln- Build and run:
- Press F5 in Visual Studio, or
dotnet buildfollowed bydotnet run
-
Configure Machine Settings (⚙ Machine Settings)
- Set plotter bed size
- Configure home position
- Define safe margins
-
Draw Your Design
- Use drawing tools (Line, Rectangle, Circle, Bezier, etc.)
- Group related strokes for easier management
- Load reference images if needed
-
Set Up Paint Wells (🎨 Painting Mode)
- Click "🎨 Quick Setup" for default wells (Red, Green, Blue, Wash, Wipe)
- Or add custom paint wells manually
- Position wells on the canvas
- Configure dip depth, dwell time, and refresh intervals
-
Assign Colors
- Select strokes
- Click on a paint well chip to assign that color
- Use "None" to clear paint assignment
-
Create Brush Profiles (🖌 Profiles button)
- Open Brush Stroke Profiles window
- Create new profiles with custom pressure curves
- Save profiles to your project
-
Assign Brush Profiles (Paint Only Mode)
- Toggle "🎨 Paint Only" view
- Select painting strokes
- Right-click → "🖌 Assign Brush Profiles"
- Choose which profiles to enable for selected strokes
-
Generate G-code
- Click "Export .gcode" or "Copy G-code"
- Review in the G-code visualizer (🔍 Path Debug)
- Look for brush profile markers in the output
-
Send to Plotter
- Connect to GRBL plotter via serial port
- Click "Send G-code" to execute the plot
Strokes are painted in the order colors were assigned, not the drawing order. This allows you to:
- Draw everything first, then decide painting sequence
- Change colors on existing strokes without redrawing
- Have multiple objects use the same color at different times
Brush profiles control the Z-axis depth dynamically along a stroke, creating realistic brush effects:
- t = 0.0: Start of stroke
- t = 1.0: End of stroke
- The profile curve (0-1 on Y axis) maps to Z depth from ZUp to ZDown
- Profiles can simulate dabs, tapers, pressure variations, and more
A special view mode that shows the actual painting sequence from generated G-code:
- View strokes in painting order with sequence numbers
- Assign brush profiles to individual painting strokes
- See stroke boundaries clearly (where pen goes up/down)
- Changes automatically regenerate G-code
- Paint Wells: Colored paint sources
- Wash Well: Rinse/clean well (generates spiral swirl pattern)
- Wipe Well: Drying surface (generates zig-zag wipe pattern)
Each paint well has:
- Position & Size: Bounds on the plotter bed
- Dip Depth: How deep to dip into the paint
- Dwell Time: How long to wait while dipped
- Refresh Distance: Random range (min-max) for paint reload
- Interactive Curve: Click to add control points, drag to adjust
- Bézier Interpolation: Smooth curves between control points
- Sample Count: Control smoothness (20-200 samples)
- Stroke Speed: Override default feed rate
- Z Range: Min/Max Z depth limits
The profile editor supports creating various stroke styles:
- Gentle Dab: Light touch with gradual pressure
- Hard Press: Strong, consistent pressure
- Taper In/Out: Gradual pressure changes at start/end
- Staccato: Quick up-down motions
- Variable Pressure: Complex pressure curves
Profiles are applied at the G-code level:
- The profile's Y curve (0-1) maps to Z depth
Y=0→Z=ZUp(pen up/travel height)Y=1→Z=ZDown(maximum depth)- Samples are distributed evenly along the stroke's physical length
- Normal Mode: Full nearest-neighbor optimization (reorders all strokes)
- Paint Mode: Direction-only optimization (preserves color sequence)
- Toggle via "Optimize stroke order" checkbox
- Document Space: User-facing coordinates (origin at top-left, Y positive down)
- Bed Space: Transformed to plotter bed with scaling/rotation/margins
- Work Space: GRBL work coordinates (X positive, Y negative, origin at home)
Save and load complete projects including:
- All strokes and grouping information
- Paint wells and their configurations
- Brush stroke profiles
- Machine settings
- Canvas size and margins
Ctrl+N- New ProjectCtrl+O- Open ProjectCtrl+S- Save ProjectCtrl+Shift+S- Save Project AsCtrl+Z- Undo
Ctrl+A- Select AllCtrl+C- CopyCtrl+X- CutCtrl+V- PasteDel- DeleteEsc- Deselect / Cancel operation
Ctrl+G- Group selected strokesCtrl+Shift+G- Ungroup
Mouse Wheel- Zoom in/outMiddle Mouse + Drag- PanRight Mouse- Context menu
B- Mark/unmark segment as badF- Fit to viewEsc- Deselect segment
- GcodeGeneratorService: Generates G-code from document strokes
- GcodePaintingStrokeService: Parses G-code to extract painting strokes
- CoordinateTransformService: Handles coordinate system transformations
- CanvasRendererService: Renders strokes on the WPF canvas
- PaintWellController: Manages paint well state and color assignments
- PaintOnlyModeController: Handles Paint Only view interactions
- SelectionController: Manages stroke selection and clipboard operations
- GrblManagerService: Serial communication with GRBL controllers
- PlotDocument: Main document containing strokes and paint wells
- LineStroke: Individual line segment with paint/group metadata
- PaintWell: Paint source definition with position and parameters
- BrushProfile: Brush stroke profile with Bézier curve
- GcodePaintingStroke: Parsed painting stroke from G-code
- ProjectFile: Complete project serialization
- MainWindow: Primary application window with canvas and controls
- BrushStrokeProfilesWindow: Profile editor with curve designer
- GcodePathVisualizerWindow: G-code debugging and analysis
- MachineSettingsWindow: Plotter configuration
- ReferenceImageWindow: Reference image management
- ToolsWindow: Floating tool palette
- ConsoleWindow: GRBL console for manual commands
Contributions are welcome! Please feel free to submit issues and pull requests.
- Install Visual Studio 2022 or later with .NET 8.0 SDK
- Clone the repository
- Open
NVSPlotter.sln - Build and run
- Follow C# naming conventions
- Use nullable reference types
- Add XML documentation for public APIs
- Keep methods focused and single-purpose
- Built with WPF and .NET 8
- GRBL firmware compatibility
- Uses WpfAnimatedGif for loading indicators
- Emoji.Wpf for emoji rendering support
- FontAwesome for Icons
- GitHub: @teryakisan
- Project: PlottPaint
- SVG import/export
- Job queue management
- Machine calibration wizard
Made with ❤️ for the plotter art community by NVSInk Art Studio
