This ended up getting really lost over in RoboPaint land, and eventually got so complicated that we lost it.
And yes, I tried to reel it in 100 times and failed every time. I think what I want from this is the ability to make real paintings and drawings. For watercolor, this quite commonly requires both pens and watercolor, so we need the ability to parse an SVG file and get the information about that, AND to be able to swap out configurations in the app for whatever is needed. And wouldn't it be great to be able to just load a project file and have pre-loaded a set of colors that a person can source and use immediately to make their own?
I'm going to lay out the plan and discussion can happen. But I need to reel this in as much as possible to make sure this isn't yet again the hill that the project dies on.
We need to be able to save the data we would need to do awesome things, even if we're not using it yet.
An implement contains:
type: Brush (requires refreshing from a tool position) or pen (contains its own ink). Other options at this point are just a distraction.
width: The effective maximum width of the implement as it draws. This is used for preview.
length: Applies to brushes and brush pens, it's the first element to account for the amount of flex from the fulcrum.
stiffness: (0 to 1), 1 being the same as a pen, 0 being a wet noodle? This plus length can be used to correct for brush lag around corners!
drawLength: The amount that a brush can draw before needing a refresh. Ignored for pens, or it can be "0". We could probably calculate this by estimating volume based on width & length and assuming a round brush, but this is a safer bet. "How long do you want to draw before getting more?"
handleWidth: If used in conjunction with an idea of how this affects printing offset (x/y +/-), can be accounted for and should allow for matching draw positions for smaller/larger implements (not to mention getting paint more effectively without destroying anything).
A colorset item contains:
id: a unique ID for the item
title: A short human readable title for listing
color: RGB color that the item is meant to represent
tool: Machine name of the tool that we expect to change to. This really just means that either we have a place on the bot that we go to to change to this, and if we don't then it's a manual change and the user is alerted and printing stops until the implement can be changed. This means we can just add a new colorset item for any tool (water, etc), or a pen on top of any existing watercolor set.
selectionMethods: This is where the rubber meets the road. An array of rules that express when a colorset item will be picked when walking through the final set of paths, based on three criteria: Color, transparency, and thickness.
For any given drawing made with at least some intent to be drawn, we should be able to set rules so that allow for a user to easily create a new pen that draws only on lines that were originally thicker, or only draw water on lines with transparency below a specific percentage.
This also needs some storage for the specific option values for the rules, but it can likely fit in here.
implement: A full implement object, but with a third option for type: inherit. If the type for the item is set to this, it will use the colorset level implement, if anything else it defines what type of implement it is.
If you're using a standard paint palette and brush, this brush implement is setup once in the colorset, and all colorset items that don't define their own implement, will fully inherit this colorset level brush. Allowing for simple setup and addition of overriding colorset item implements like adding an outlining pen for watercolor.
With this setup, we also gain the ability to override the implement with a different brush, allowing for even more effects (even if they're limited by color or other selection rule).
A colorset contains:
title: A short human readable title for listing
name: machine name used to save or load the custom colorset, by default derived from the title or its source preset.
description: A detailed description of what this colorset is or is for.
implement: the required default implement
items: A machine name keyed map of colorset items.
tools: Coming with all of these changes, is a very basic one: the default watercolorbot bot level configuration file will no longer hard code positions of the colors, but only what its default base plate has cutouts for: 3 waters, and a pan to put paint into. Now colorsets can define not just x/y tool positions, but also tool shapes (anything between an oval and a rectangle), allowing for real paint filling, or even a bunch of tiny square color spots.
Path toward completion, work so far in #116
Colorsets API
[x] Save any external changes to current colorset to JSON file based on name.
[x] Figure out how object colorset edits happen without adding too many endpoints.
[x] Load JSON and list custom colorsets next to presets
[x] Move Presets to groupings of self referencing internal storage formatted JSON
[x] Solve for implement storage, loading, creation, and updating
[x] Apply colorset selection logic for work groupings.
[x] Solve for tool change logic storage and defaults
[x] Solve for tool change fill tool
[x] Validate current implement and swap status with tool-less and tooled setup. More state is probably necessary.
Frontend UI
[ ] ~Tool position editor (part of colors view?)~ Not required for launch.
[x] Implement preset loader for both internal and custom presets.
[ ] ~Implement draw length indicator~ Not Required beyond implement status for launch
[x] Wire up actual backend data saving for each component of the editor (and juice up the client wrapper)
[x] Current Implement status element (socket update, color, details, maybe top right?)
This ended up getting really lost over in RoboPaint land, and eventually got so complicated that we lost it.
And yes, I tried to reel it in 100 times and failed every time. I think what I want from this is the ability to make real paintings and drawings. For watercolor, this quite commonly requires both pens and watercolor, so we need the ability to parse an SVG file and get the information about that, AND to be able to swap out configurations in the app for whatever is needed. And wouldn't it be great to be able to just load a project file and have pre-loaded a set of colors that a person can source and use immediately to make their own?
I'm going to lay out the plan and discussion can happen. But I need to reel this in as much as possible to make sure this isn't yet again the hill that the project dies on.
We need to be able to save the data we would need to do awesome things, even if we're not using it yet.
An
implement
contains:type
: Brush (requires refreshing from a tool position) or pen (contains its own ink). Other options at this point are just a distraction.width
: The effective maximum width of the implement as it draws. This is used for preview.length
: Applies to brushes and brush pens, it's the first element to account for the amount of flex from the fulcrum.stiffness
: (0 to 1), 1 being the same as a pen, 0 being a wet noodle? This plus length can be used to correct for brush lag around corners!drawLength
: The amount that a brush can draw before needing a refresh. Ignored for pens, or it can be "0". We could probably calculate this by estimating volume based on width & length and assuming a round brush, but this is a safer bet. "How long do you want to draw before getting more?"handleWidth
: If used in conjunction with an idea of how this affects printing offset (x/y +/-), can be accounted for and should allow for matching draw positions for smaller/larger implements (not to mention getting paint more effectively without destroying anything).A
colorset item
contains:id
: a unique ID for the itemtitle
: A short human readable title for listingcolor
: RGB color that the item is meant to representtool
: Machine name of the tool that we expect to change to. This really just means that either we have a place on the bot that we go to to change to this, and if we don't then it's a manual change and the user is alerted and printing stops until the implement can be changed. This means we can just add a new colorset item for any tool (water, etc), or a pen on top of any existing watercolor set.selectionMethods
: This is where the rubber meets the road. An array of rules that express when a colorset item will be picked when walking through the final set of paths, based on three criteria: Color, transparency, and thickness.implement
: A full implement object, but with a third option for type:inherit
. If the type for the item is set to this, it will use the colorset level implement, if anything else it defines what type of implement it is.A
colorset
contains:title
: A short human readable title for listingname
: machine name used to save or load the custom colorset, by default derived from the title or its source preset.description
: A detailed description of what this colorset is or is for.implement
: the required default implementitems
: A machine name keyed map of colorset items.tools
: Coming with all of these changes, is a very basic one: the default watercolorbot bot level configuration file will no longer hard code positions of the colors, but only what its default base plate has cutouts for: 3 waters, and a pan to put paint into. Now colorsets can define not just x/y tool positions, but also tool shapes (anything between an oval and a rectangle), allowing for real paint filling, or even a bunch of tiny square color spots.Path toward completion, work so far in #116
Colorsets API
Frontend UI