-
Posts
3,025 -
Joined
-
Last visited
-
Days Won
125
Posts posted by Red ochre
-
-
Why not use the grid maker plugin: http://forums.getpaint.net/index.php?showtopic=4175
- on a transparent layer with foreground only checked. Then use it as a guide to line up your objects?
I think a snap to grid plugin could be very decieving as the anti-aliased pixels around an object mean that edges are not always where they seem to be. So for it to look correct you would need a fine adjustment - so you may as well do it the long way I've suggested and decide if it 'looks' correct.
Have you tried the align object plugin ? : http://forums.getpaint.net/index.php?showtopic=4193 -
Hello NMD,
There are many that do something similar - did you mean this one?
http://forums.getpaint.net/index.php?/topic/13535-isolate-lineart/
-
That looks interesting Midora, particularly 'Tabs'.
'LabelMin' and 'LabelMax' would certainly make it easier to align the words correctly and I like the option to show units too.
I have a few ideas that may or may not be sensible (I simply don't have the knowledge yet to know how difficult or practical these things are to do using a customU.I.).
1. I find the 'reset to default' buttons for the trackbars very useful. There doesn't appear to be this function for the checkboxes, drop-down lists or radio buttons - perhaps there could be one 'reset all to default' button for all the controls?
Aha! - I've just noticed you have included this for checkboxes in your example.
2. I find the drop-down lists very useful as they save a lot of space on the U.I compared to radio buttons. I wonder if there could be a drop-down list of ckeckboxes too?
3. Possibly an 'Info' button to show a message box where the plugin author can write basic instuctions?
Just thought I would suggest these in case they have not already been considered.
The OptionBased library looks very promising! - thanks for posting the example.
-
Perhaps this may be relevant too?
http://forums.getpaint.net/index.php?/topic/26657-wsq-file-plugin/
-
^^Wow! - thanks - and many thanks to Null54 for making it possible too!
And Pixey - I think I used to have a 'candlewick' bedspread with that texture - (all duvets these days) - thanks for posting.
-
Trackbar labels: - Yes, much as EER says.
I do try to make the UI tidy and logical, but explaining the function to the user takes precedence. Also, personally, I find breaking up the visually uniform look of a 'wall' of trackbar sliders makes it quicker to find the one I want. -
Daniels - please do - I find simply 'playing' with plugins the best way to learn and discover new techniques.
EER - I should nominate that to the Galeria (but there could be copyright issues) - it does make me chuckle!
YM - stunning! - great use of the plugin and the image itself is a pleasure - great colours & textures!
Dug - looking forward to seeing what surreal uses you find for it.
Pixey - That looks great! - original use of Furblur for the icicles. 'Clever' - I wish! (Null54 is the clever one for getting it working).
Helen - you can hug me anytime! - looking forward to seeing your results - perhaps some candyfloss trees for your candy house?
Good to see what you're all creating.- 1
-
^^ I agree with EER.
Thank you!
I think I will be refering to your explanation many times;-) -
Good work Sasha - does your hamster share a cage with a hedgehog?! - thanks for posting.
Nice wallpaper from BBQ and magnet from WB - pleased you are having fun with this one.
-
Hi Null54,
Imagine a preset called say 'very large curls' created on a standard 800 by 600 canvas.
The user next uses this preset on a 1600 by 1200 canvas and eventually sees a very small curly texture.
The effect the user sees is very dependant upon the selection size.
I think the presets idea would be more relevant for a 'Render' effect where the size, especially line width, can be related to the selection size. If FurBlur had used GDI+ to draw the lines it would have been relatively easy to change the line width based on selection size. But then it would be a different effect.
Thanks for the example XML - I can see presets being useful for other effects but not really convinced it is needed for this one.
Do I understand correctly, XML presets could only be used with a Windows Forms based effect (or the 'OptionBasedLibrary' in the future) but are not possible with the current IndirectUI?
Sorry for my confusing explanations!
-
Aaaah - too many people to thank - you're posting fasting than I can type!
TR - Thanks for the support on this one and brilliant images too!
BB - Thanks - it started life in codelab!
EER - Thanks for all the VS tips and encouragement too.
doughty - glad you reposted the prevoius 2 and the furryworm is great!
BBQ - hope you are getting decent results now.
WB - love the Obama one!
Drew' - Thanks for reposting Fircraft and hairy target and adding the clipwarped one too.
Oceana - That's given me vertigo!
NN - Cheers - you know me too well!
Should be ok to use on layer after 'Curly Line' - If using Furblur repeatedly on the same object layer you may need to lower the 'Start object transparency' slider a little. That's because it is a blur and mixes the opaque object with the transparent surrounding pixels.
To all - many thanks all who tested and have reposted or added new examples. Glad you seem to be having fun with it and many thanks to Null54 for getting it to work!- 2
-
Midora - the OptionBasedLibrary sounds very promising!
TR - Thanks for the example code and .dll - I can just about get the idea of how it works. It could be a useful technique for future plugins. (Update: Midora has just posted - so, still interesting but looks like the long way is best - many thanks anyway)
Regarding presets or user saveable settings for FurBlur, I'm not sure it would make the effect any easier to use or understand. Because it is a blur on a pixel size scale, any preset would look very different on different selection sizes. If it was a GDI+ based render effect, then the preset sizes could take selection size into account - and presets would be a better idea.
I have used a drop-down list and switch block before, to make presets that change the way the control values are used (or ignore them). (e.g. 'Highlight' and 'Object2colour'). - Haven't tried anything saveable though.
I tend to think some users will want a plugin to work perfectly with the default values and others are happy to explore all the controls to get the effect they want. I'm not sure the first type would be bothered to create and save settings and the second type possibly wouldn't need to?
For Effects more generally, I tend to either use an effect with different settings each time or consecutively run the same effect with same 'auto-remembered' settings. If I really need to record exact settings for a plugin I write them down - (useful equations for 3D Object plugin for example).
So, I don't intend to add presets to Furblur but will consider it for future plugins. Many thanks for all the suggestions and info though. Some of it will sink in eventually!
-
- Popular Post
- Popular Post
Furblur update 30th July 2014
A versatile blur/trail effect. Useful for Fur, false beards and grass textures and also for paper textures, watercolour effects and 'scribbled' drawing effects.
Found under: Effects/Blurs/FurBlur Dll name = FurBlur.
An updated version is in my V10 Plugin pack hereRed ochre v10 plugin pack
I would like thank 'Null54' who made this plugin possible. I spent days trying to get it to work and he solved the problem in hours! - greatly indebted. I would also like to thank EER, without whose diplomatic skills I would have left the forum months ago. Finally I must thank the many people who tested this for me over on developers central - the difficulty with random effects is that the bugs can be quite random too, it appears. So many people testing has been very useful.
I am updating Furblur. It still works in much the same way on default settings, but I have added some more 'fun' stuff.
Changes:
1. I wanted to make some feathers and needed more control over the curl direction, so have added this.
2. Started running out of U.I. space, so put these new curl choices in a drop-down list with the direction choices.
3. Took the liberty of removing some of the titles to the drop-down boxes - again to save space.
4. Have removed the colouring choice - now it only colours along the fur. (The fur can easily be recoloured later if the 'only keep fur' box is checked).
5. Have improved the antialiasing.
6. Have slightly increased the speed.
7. The fun bit - have included 12 new curl shapes.
8. Changed the icon pussycat colour to ginger - so you can easily tell which version you have!
HistoryHidden Content:v1 = 459 downloads
As before, best to experiment as described below - the UI has changed but all the previous examples are still possible.
Here is the new U.I. and example curl shapes:
How to use:
Be very wary of using the plugin on large selections with large 'reps' or 'length' as it will be very slow!
I suggest you try the plugin out in the following way, just to get an idea of how it works.
1. New image 800 * 600 - make background black.
2. New layer (transparent)
3. Draw 10 pix wiggly lines. nice bright colours
4. Possibly select around these lines with the lasso tool (leave plenty of room for the effect!)
5. Effects/Blurs/Furblur - lower the 'rep' slider and increase the 'length' slider to start.
6. Try each slider seperately to see what they do.
Hopefully the following images will give you some ideas. Please feel free to post your FurBlur images in this thread and any tips you have discovered. Enjoy!
- 1
- 11
-
Nice work Oceana! - glad the instructions helped.
EER - just about to publish - perhaps we can work on the XML idea for future updates.
All - you've made some good images here - please feel free to repost them on the published FurBlur thread. Thanks for testing!
-
TR - love it!
EER - That is a good idea - I must admit I haven't got a clue where to start though and have never used that Shape3D option. If you would like to help me, I/we can either delay publication or add this as an update later?
I would favour publishing sooner - so people have a proper thread to show all these great images.
YM - great fun!
BBQ - I hope you are getting decent results now - if not, please post back. I am useless at explaining things (not great at understanding sometimes either!).
WB - I'm hoping this will be useful for textures and chromatography/watercolour type effects as well as photo-manips (which are great fun!).
-
^^ Haven't yet - have seen the trailers - waiting till it comes on the TV! (too 'tight' to buy)
Tiger on a boat - they love to swim! + how are they at navigation? -
- Just typed a long reply BBQ - then bashed the mouse and I've got to type it all again!
Ok. Best not to use on all of a large canvas to start with.
The calculations are run single threadedly - so none of the speed advantages of a powerful machine.
I suspect the little lines are the effect - it operates on a pixel size scale so may be hard to see on a huge canvas.
Suggest to test:
1. New image 800 * 600 - make background black.
2. New layer (transparent)
3. Draw 10 pix wiggly lines. nice bright colours
4. Possibly select around these lines with the lasso tool (leave plenty of room for the effect!)
5. Effects/Blurs/Furblur - lower the 'rep' slider and increase the 'length' slider to start.
6. Try each slider seperately to see what they do.
If still no joy report back please!
I am working on getting some examples together at the moment with screenshots.
- 2
-
No crashes yet then ? good! - thanks all for testing and positive feedback. I will publish it properly soon.
doughty - I really like that one. Interesting 'grunge' texture + the 'curve variation' slider way up = looks good!
Drew - another good result! - that aeroplane needs a shave! - thanks for checking this one out.
TR - Thanks for the compliment - knowing your programming skills I am very flattered!
Regarding presets: I don't intend to add them - partly due to my laziness and also because I would rather users 'play' with all the controls to get an idea of what this can do. I generally like to give users as many options as practical but I know this can sometimes make the U.I. a bit intimidating. I will include some example settings and results in the publishing thread but hopefully users will experiment and come up with new uses.
That tiger has walked a long way!
- 1
-
I am attaching the newest version of Furblur for testing. I've added quite a lot including the circular option for the curve, which gives much better results. However, I like the previous, slightly dotted (spiral) version as it can look like grass seeds, so am keeping that option.
Now doesn't mix the colour with the transparent white!
Added a slider to choose the transparency threshold of an 'object'. At around 250 will only put fur on 'objects', at 0 will work on whole selection (only seen if colour turned up).
Speeded up slightly too.
Changed radio buttons to checkboxes to save space.
I would be grateful if you can give it try and report any crashes. There shouldn't be any - but I thought that with the last one! - Many thanks
Also removing old versions of the .dll to avoid confusion.
The .dllSome more examples:
VS source code:
Hidden Content:// Compiler options: /unsafe /optimize /res:"C:\Users\john\Code experiments\PLUGIN pack stuff\pdn plugin graphics\plugin pack icons\FurBlurIcon.png","FurBlurEffect.FurBlurIcon.png" /debug- /target:library /out:"C:\Program Files\Paint.NET\Effects\FurBlur2.dll" using System; using System.Collections.Generic; using System.Drawing; using System.Reflection; using System.Runtime.InteropServices; using PaintDotNet; using PaintDotNet.Effects; using PaintDotNet.IndirectUI; using PaintDotNet.PropertySystem; [assembly: AssemblyTitle("FurBlurPlugin")] [assembly: AssemblyDescription("FurBlur Plugin for Paint.NET")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("Red ochre (John Robbins)")] [assembly: AssemblyProduct("FurBlurPlugin")] [assembly: AssemblyCopyright("Copyright © Red ochre (John Robbins)helped by Null54")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] [assembly: ComVisible(false)] [assembly: AssemblyVersion("1.0.1")] namespace FurBlurEffect { public class PluginSupportInfo : IPluginSupportInfo { public string Author { get { return "Red ochre (John Robbins)helped by Null54"; } } public string Copyright { get { return ((AssemblyCopyrightAttribute)base.GetType().Assembly.GetCustomAttributes(typeof(AssemblyCopyrightAttribute), false)[0]).Copyright; } } public string DisplayName { get { return ((AssemblyProductAttribute)base.GetType().Assembly.GetCustomAttributes(typeof(AssemblyProductAttribute), false)[0]).Product; } } public Version Version { get { return base.GetType().Assembly.GetName().Version; } } public Uri WebsiteUri { get { return new Uri("http://www.getpaint.net/redirect/plugins.html"); } } } [PluginSupportInfo(typeof(PluginSupportInfo), DisplayName = "FurBlur")] public class FurBlurEffectPlugin : PropertyBasedEffect {// add another surface in "public class ....Plugin : PropertyBasedEffect" private Surface destSurface; protected override void OnDispose(bool disposing)//added { if (disposing) { if (destSurface != null) { destSurface.Dispose(); destSurface = null; } } base.OnDispose(disposing); } public static string StaticName { get { return "Furblur"; } } public static Image StaticIcon { get { return FurBlur.Properties.Resources.FurBlurIcon; } } public FurBlurEffectPlugin() : base(StaticName, StaticIcon, "Blurs", EffectFlags.Configurable) { instanceSeed = unchecked((int)DateTime.Now.Ticks); } public enum PropertyNames { StartC, Reps, MaxL, LenV, Mang, Bid, AngV, CurT, CurA, CurV, FriV, Sooo, BTrat, ColT, ColM, Qual, JustF, ReSeed } [ThreadStatic] private static Random RandomNumber; private int instanceSeed; protected override PropertyCollection OnCreatePropertyCollection() { List<Property> props = new List<Property>(); props.Add(new BooleanProperty(PropertyNames.StartC, false)); props.Add(new DoubleProperty(PropertyNames.Reps, 10, 0, 100)); props.Add(new Int32Property(PropertyNames.MaxL, 30, 1, 300)); props.Add(new DoubleProperty(PropertyNames.LenV, 0.10, 0, 1)); props.Add(new DoubleProperty(PropertyNames.Mang, 90, -180, +180)); props.Add(new BooleanProperty(PropertyNames.Bid, false)); props.Add(new DoubleProperty(PropertyNames.AngV, 0.10, 0, 1)); props.Add(new BooleanProperty(PropertyNames.CurT, true)); props.Add(new DoubleProperty(PropertyNames.CurA, 0.10, 0, 1)); props.Add(new DoubleProperty(PropertyNames.CurV, 0.10, 0, 1)); props.Add(new DoubleProperty(PropertyNames.FriV, 0.10, 0, 1)); props.Add(new Int32Property(PropertyNames.Sooo, 250, 0, 255)); props.Add(new DoubleProperty(PropertyNames.BTrat, 0, 0, 1)); props.Add(new BooleanProperty(PropertyNames.ColT, true)); props.Add(new DoubleProperty(PropertyNames.ColM, 0, 0, 1)); props.Add(new BooleanProperty(PropertyNames.Qual, true)); props.Add(new BooleanProperty(PropertyNames.JustF, false)); props.Add(new Int32Property(PropertyNames.ReSeed, 0, 0, 255)); List<PropertyCollectionRule> propRules = new List<PropertyCollectionRule>(); propRules.Add(new ReadOnlyBoundToBooleanRule("StartC", "JustF", false)); return new PropertyCollection(props, propRules); } protected override ControlInfo OnCreateConfigUI(PropertyCollection props) { ControlInfo configUI = CreateDefaultConfigUI(props); configUI.SetPropertyControlValue(PropertyNames.StartC, ControlInfoPropertyNames.DisplayName, string.Empty); configUI.SetPropertyControlValue(PropertyNames.StartC, ControlInfoPropertyNames.Description, "0 = Src(original): tick = Dst(fur on fur)"); configUI.SetPropertyControlValue(PropertyNames.Reps, ControlInfoPropertyNames.DisplayName, "Repetitions: big reps & big length = slow!"); configUI.SetPropertyControlValue(PropertyNames.MaxL, ControlInfoPropertyNames.DisplayName, "Main length"); configUI.SetPropertyControlValue(PropertyNames.LenV, ControlInfoPropertyNames.DisplayName, "Length variations"); configUI.SetPropertyControlValue(PropertyNames.LenV, ControlInfoPropertyNames.SliderLargeChange, 0.25); configUI.SetPropertyControlValue(PropertyNames.LenV, ControlInfoPropertyNames.SliderSmallChange, 0.05); configUI.SetPropertyControlValue(PropertyNames.LenV, ControlInfoPropertyNames.UpDownIncrement, 0.01); configUI.SetPropertyControlValue(PropertyNames.Mang, ControlInfoPropertyNames.DisplayName, "Main angle"); configUI.SetPropertyControlType(PropertyNames.Mang, PropertyControlType.AngleChooser); configUI.SetPropertyControlValue(PropertyNames.Bid, ControlInfoPropertyNames.DisplayName, string.Empty); configUI.SetPropertyControlValue(PropertyNames.Bid, ControlInfoPropertyNames.Description, "Both directions"); configUI.SetPropertyControlValue(PropertyNames.AngV, ControlInfoPropertyNames.DisplayName, "Angle variation"); configUI.SetPropertyControlValue(PropertyNames.AngV, ControlInfoPropertyNames.SliderLargeChange, 0.25); configUI.SetPropertyControlValue(PropertyNames.AngV, ControlInfoPropertyNames.SliderSmallChange, 0.05); configUI.SetPropertyControlValue(PropertyNames.AngV, ControlInfoPropertyNames.UpDownIncrement, 0.01); configUI.SetPropertyControlValue(PropertyNames.CurT, ControlInfoPropertyNames.DisplayName, string.Empty); configUI.SetPropertyControlValue(PropertyNames.CurT, ControlInfoPropertyNames.Description, "0 = spiral(original - dotty): tick = circular(smooth!)"); configUI.SetPropertyControlValue(PropertyNames.CurA, ControlInfoPropertyNames.DisplayName, "Curl curvature"); configUI.SetPropertyControlValue(PropertyNames.CurA, ControlInfoPropertyNames.SliderLargeChange, 0.25); configUI.SetPropertyControlValue(PropertyNames.CurA, ControlInfoPropertyNames.SliderSmallChange, 0.05); configUI.SetPropertyControlValue(PropertyNames.CurA, ControlInfoPropertyNames.UpDownIncrement, 0.01); configUI.SetPropertyControlValue(PropertyNames.CurV, ControlInfoPropertyNames.DisplayName, "Curl variation"); configUI.SetPropertyControlValue(PropertyNames.CurV, ControlInfoPropertyNames.SliderLargeChange, 0.25); configUI.SetPropertyControlValue(PropertyNames.CurV, ControlInfoPropertyNames.SliderSmallChange, 0.05); configUI.SetPropertyControlValue(PropertyNames.CurV, ControlInfoPropertyNames.UpDownIncrement, 0.01); configUI.SetPropertyControlValue(PropertyNames.FriV, ControlInfoPropertyNames.DisplayName, "Frizz curvature"); configUI.SetPropertyControlValue(PropertyNames.FriV, ControlInfoPropertyNames.SliderLargeChange, 0.25); configUI.SetPropertyControlValue(PropertyNames.FriV, ControlInfoPropertyNames.SliderSmallChange, 0.05); configUI.SetPropertyControlValue(PropertyNames.FriV, ControlInfoPropertyNames.UpDownIncrement, 0.01); configUI.SetPropertyControlValue(PropertyNames.Sooo, ControlInfoPropertyNames.DisplayName, "Start object transparency"); configUI.SetPropertyControlValue(PropertyNames.BTrat, ControlInfoPropertyNames.DisplayName, "Blur......................................................................Trail"); configUI.SetPropertyControlValue(PropertyNames.BTrat, ControlInfoPropertyNames.SliderLargeChange, 0.25); configUI.SetPropertyControlValue(PropertyNames.BTrat, ControlInfoPropertyNames.SliderSmallChange, 0.05); configUI.SetPropertyControlValue(PropertyNames.BTrat, ControlInfoPropertyNames.UpDownIncrement, 0.01); configUI.SetPropertyControlValue(PropertyNames.ColT, ControlInfoPropertyNames.DisplayName, string.Empty); configUI.SetPropertyControlValue(PropertyNames.ColT, ControlInfoPropertyNames.Description, "0 = simple mix: tick = along fur"); configUI.SetPropertyControlValue(PropertyNames.ColM, ControlInfoPropertyNames.DisplayName, "Src Color............................................... Primary Color"); configUI.SetPropertyControlValue(PropertyNames.ColM, ControlInfoPropertyNames.SliderLargeChange, 0.25); configUI.SetPropertyControlValue(PropertyNames.ColM, ControlInfoPropertyNames.SliderSmallChange, 0.05); configUI.SetPropertyControlValue(PropertyNames.ColM, ControlInfoPropertyNames.UpDownIncrement, 0.01); configUI.SetPropertyControlValue(PropertyNames.Qual, ControlInfoPropertyNames.DisplayName, string.Empty); configUI.SetPropertyControlValue(PropertyNames.Qual, ControlInfoPropertyNames.Description, "0 = 1pix: tick = 4 pix anti-aliased"); configUI.SetPropertyControlValue(PropertyNames.JustF, ControlInfoPropertyNames.DisplayName, string.Empty); configUI.SetPropertyControlValue(PropertyNames.JustF, ControlInfoPropertyNames.Description, "Only keep fur (src Start colour only)"); configUI.SetPropertyControlValue(PropertyNames.ReSeed, ControlInfoPropertyNames.DisplayName, string.Empty); configUI.SetPropertyControlType(PropertyNames.ReSeed, PropertyControlType.IncrementButton); configUI.SetPropertyControlValue(PropertyNames.ReSeed, ControlInfoPropertyNames.ButtonText, "Reseed"); return configUI; } protected override void OnSetRenderInfo(PropertyBasedEffectConfigToken newToken, RenderArgs dstArgs, RenderArgs srcArgs) { this.startColour = newToken.GetProperty<BooleanProperty>(PropertyNames.StartC).Value; this.repCount = newToken.GetProperty<DoubleProperty>(PropertyNames.Reps).Value; this.maxLength = newToken.GetProperty<Int32Property>(PropertyNames.MaxL).Value; this.lengthVariation = newToken.GetProperty<DoubleProperty>(PropertyNames.LenV).Value; this.mainAngle = newToken.GetProperty<DoubleProperty>(PropertyNames.Mang).Value; this.biDirectional = newToken.GetProperty<BooleanProperty>(PropertyNames.Bid).Value; this.angleVariation = newToken.GetProperty<DoubleProperty>(PropertyNames.AngV).Value; this.curtype = newToken.GetProperty<BooleanProperty>(PropertyNames.CurT).Value; this.curvature = newToken.GetProperty<DoubleProperty>(PropertyNames.CurA).Value; this.curvVari = newToken.GetProperty<DoubleProperty>(PropertyNames.CurV).Value; this.frizz = newToken.GetProperty<DoubleProperty>(PropertyNames.FriV).Value; this.startOnObject = newToken.GetProperty<Int32Property>(PropertyNames.Sooo).Value; this.blurAmount = newToken.GetProperty<DoubleProperty>(PropertyNames.BTrat).Value; this.coltype = newToken.GetProperty<BooleanProperty>(PropertyNames.ColT).Value; this.colmix = newToken.GetProperty<DoubleProperty>(PropertyNames.ColM).Value; this.quality = newToken.GetProperty<BooleanProperty>(PropertyNames.Qual).Value; this.justF = newToken.GetProperty<BooleanProperty>(PropertyNames.JustF).Value; this.randomSeed = (byte)newToken.GetProperty<Int32Property>(PropertyNames.ReSeed).Value; if (destSurface == null) { destSurface = new Surface(dstArgs.Surface.Width, dstArgs.Surface.Height); } Rectangle selection = this.EnvironmentParameters.GetSelection(srcArgs.Surface.Bounds).GetBoundsInt(); this.Render(destSurface, srcArgs.Surface, selection); // clip the rendering to the selection. base.OnSetRenderInfo(newToken, dstArgs, srcArgs); } protected override void OnCustomizeConfigUIWindowProperties(PropertyCollection props) { // Change the effect's window title props[ControlInfoPropertyNames.WindowTitle].Value = "Fur Blur Aug 2013 Red Ochre/Null54"; base.OnCustomizeConfigUIWindowProperties(props); } protected override unsafe void OnRender(Rectangle[] rois, int startIndex, int length) { if (length == 0) return; DstArgs.Surface.CopySurface(destSurface, rois, startIndex, length); } #region User Entered Code /* =================================================== */ /* Furblur */ /* Name */ /* (c) 2013 Red Ochre */ /* comment */ /* Description:random trail/blur */ /* */ /* ========================================== ======== */ // Name: Furblur // Author: Red ochre (John Robbins) // Submenu: Blur // URL: http://www.getpaint.net/redirect/plugins.html // Title:Fur Blur Aug 2013 Red Ochre/Null54 #region UICode bool startColour = false; // [1] Start colour|Src (original)| Dst ( fur on fur ) double repCount = 10; // [0,100] Repetitions int maxLength = 20; // [1,200] Maximum length double lengthVariation = 0; // [0,1] Length variations double mainAngle = 45; // [-180,180] Main angle bool biDirectional = true; // [0,1] Both directions double angleVariation = 0; // [0,1] Angle variation bool curtype = true; // [0,1] Curve type double curvature = 0; // [0,1] Curl curvature double curvVari = 0; //[0,1] Curl variation double frizz = 0; // [0,1] Frizz curvature int startOnObject = 250; // [0,1] Start on object only double blurAmount = 0; // [0,1] Blur......................................................................Trail bool coltype = true; //[0,1] simple mix|along fur double colmix = 0; // [0,1] Src Color............................................... Primary Color bool quality = true; // [1] Quality|4 pixel Anti-alias (smoother)| 1 pixel (only slightly faster) bool justF = false; // [0,1] Only keep fur (src Start colour only) byte randomSeed = 0; // [255] Reseed #endregion void Render(Surface dest, Surface src, Rectangle rect) { dest.CopySurface(src, rect.Location, rect);// copy surface quicker than looping through if (justF) { ColorBgra klear = ColorBgra.Transparent; dest.Clear(klear); startColour = false; }//keep only blur/trail int H = rect.Bottom - rect.Top; int W = rect.Right - rect.Left; int N = (int)((repCount * W * H) / (100)); int Lmain = maxLength; double Lvari = lengthVariation; double PI = Math.PI; double Amain = (mainAngle + 360) * 17.45329252;// add 360 so that angle can vary less than 0 (360) easier for random min & max // now in radians - note (PI * 1000)/180 = 17.453292519943295769236907684886 bool Bidi = biDirectional; double Avar = angleVariation; bool Ctype = curtype; double Curve = curvature / 5; int CVari = (int)(curvVari * 1000); double Frizz = frizz / 50; int Athresh = startOnObject; double BlurV = 1 - blurAmount; double PriRat = colmix; double invPriRat = 1 - PriRat; bool Qual = quality; if (RandomNumber == null) { RandomNumber = new Random(instanceSeed ^ (randomSeed << 16) ^ (rect.X << 8) ^ rect.Y); } ColorBgra PrimC = base.EnvironmentParameters.PrimaryColor; ColorBgra LT, RT, LB, RB, stLT, stRT, stLB, stRB; int nB = 0; int nG = 0; int nR = 0; int nA = 255;// just to set a value int AngMax = (int)(Amain * (1 + Avar)); int AngMin = (int)(Amain * (1 - Avar));// radians times 1000 for randoms double Angle = AngMax;//moved these out of loop int Lmax = Lmain + (int)(Lmain * Lvari); int Lmin = Lmain - (int)(Lmain * Lvari); int L = Lmax;//and these int CurMin = (int)(Curve * (1 - curvVari) * 1000);// times 1000 to use randoms int CurMax = (int)(Curve * (1 + curvVari) * 1000); for (int n = 0; n < N; n++)//number of 'stabs' at random locations { double Randx = RandomNumber.Next(rect.Left, rect.Right - 1); int Randxi = (int)(Randx); double Randy = RandomNumber.Next(rect.Top, rect.Bottom - 1); int Randyi = (int)(Randy); // note: start position to allow for 4 pixel square, so Randx < Right - 1 , Randy < Top -1 if (Lmin < Lmax) { L = (int)RandomNumber.Next(Lmin, Lmax); }//Length of line //for RANDOMS - protection - Min MUST be less than Max or out of bounds exception if (AngMin < AngMax) { Angle = (double)(RandomNumber.Next(AngMin, AngMax)); }//Angle of line (rads * 1000 still) if (Avar == 0) { Angle = AngMax; }//bodge for odd unsolved bug when Avar = 0?????? - works! Angle = Angle / 1000;// back in radians int AngDir = RandomNumber.Next(0, 2);//Angle direction random 0 or 1 if (Bidi && AngDir >= 1) { Angle += PI; }//randomly reverse angle int CurDir = (int)RandomNumber.Next(0, 2);//Curve direction random 0 or 1 if (CurMin < CurMax) { Curve = (double)(RandomNumber.Next(CurMin, CurMax) / 1000.0); }//divide by 1000 to get back to value range Curve = Curve - (Curve * CurDir * 2);//easier to read - randomly changes curve direction // need to know start alpha later stLT = src.GetPointUnchecked(Randxi, Randyi); stRT = src.GetPointUnchecked(Randxi + 1, Randyi); stLB = src.GetPointUnchecked(Randxi, Randyi + 1); stRB = src.GetPointUnchecked(Randxi + 1, Randyi + 1); int startA = (stLT.A + stRT.A + stLB.A + stRB.A) / 4; if (!startColour) { nB = (int)((stLT.B + stRT.B + stLB.B + stRB. / 4); nG = (int)((stLT.G + stRT.G + stLB.G + stRB.G) / 4); nR = (int)((stLT.R + stRT.R + stLB.R + stRB.R) / 4); nA = (int)((stLT.A + stRT.A + stLB.A + stRB.A) / 4); } else if (startColour) { stLT = dest.GetPointUnchecked(Randxi, Randyi); stRT = dest.GetPointUnchecked(Randxi + 1, Randyi); stLB = dest.GetPointUnchecked(Randxi, Randyi + 1); stRB = dest.GetPointUnchecked(Randxi + 1, Randyi + 1); nB = (stLT.B + stRT.B + stLB.B + stRB. / 4; nG = (stLT.G + stRT.G + stLB.G + stRB.G) / 4; nR = (stLT.R + stRT.R + stLB.R + stRB.R) / 4; nA = (stLT.A + stRT.A + stLB.A + stRB.A) / 4; } if (!coltype)// original Primary color blending see innner loop for along the fur { nB = (int)((nB * invPriRat) + (PrimC.B * PriRat));//mix src or dest colour with Primary Color nG = (int)((nG * invPriRat) + (PrimC.G * PriRat)); nR = (int)((nR * invPriRat) + (PrimC.R * PriRat)); nA = (int)((nA * invPriRat) + (PrimC.A * PriRat));//potentially transparent fur! } double oldx = Randx; double oldy = Randy; for (int l = 1; l < L; l++)// distance to loop out from that random location { if (frizz != 0)// don't calculate if not needed - slow as within inner loop { double frangle = Angle; int frizmin = (int)((Angle - (Angle * Frizz)) * 1000); int frizmax = (int)((Angle + (Angle * Frizz)) * 1000); if (frizmin < frizmax) { frangle = (double)(RandomNumber.Next(frizmin, frizmax)) / 1000; } int Lfra = (int)((1 - frizz) * L); int frazz = RandomNumber.Next(0, Lfra);//added to increase frizz if (frazz < l) { Angle = frangle; } } double Cang = Math.Cos(Angle); double Sang = -Math.Sin(Angle); double Nx = Randx + (l * Cang); int Lxi = (int)(Nx); int Rxi = Lxi + 1;//this is angle from start double Ny = Randy + (l * Sang); int Tyi = (int)(Ny); int Byi = Tyi + 1; if (curtype) { Nx = oldx + (Cang); Lxi = (int)(Nx); Rxi = Lxi + 1;//this is angle from last point Ny = oldy + (Sang); Tyi = (int)(Ny); Byi = Tyi + 1; }// CIRCLES! - no gaps either //start position is within bounds, however the loop may take it out of bounds! // therefore protection required or use get sample clamped? if (Lxi > rect.Left && Rxi < rect.Right && Tyi > rect.Top && Byi < rect.Bottom) { double blur = (double)(L - (l * BlurV)) / (double)(L);//BlurV is less than 1 so blur is too double iblur = 1 - blur; double colblur = (double)(L - l) / (double)(L); double icolblur = 1 - colblur; if (coltype)//colour along the fur { nB = (int)((nB * colblur) + (((PrimC.B * PriRat) + (nB * invPriRat)) * icolblur));//add primary color along fur nG = (int)((nG * colblur) + (((PrimC.G * PriRat) + (nG * invPriRat)) * icolblur)); nR = (int)((nR * colblur) + (((PrimC.R * PriRat) + (nR * invPriRat)) * icolblur)); nA = (int)((nA * colblur) + (((PrimC.A * PriRat) + (nA * invPriRat)) * icolblur));//potentially transparent fur! } //4 pixel AA //if (Qual && (!Obtest || startA > Athresh))// assume objects have alpha greater than 250 or object-edge pixels trail transparency across object if (Qual && startA >= Athresh) { LT = dest.GetPointUnchecked(Lxi, Tyi); int Blt = LT.B; int Glt = LT.G; int Rlt = LT.R; int Alt = LT.A; if (LT.A <= Athresh) { Blt = nB; Glt = nG; Rlt = nR; }// to stop it blending colour with clear (white) RT = dest.GetPointUnchecked(Rxi, Tyi); int Brt = RT.B; int Grt = RT.G; int Rrt = RT.R; int Art = RT.A; if (RT.A <= Athresh) { Brt = nB; Grt = nG; Rrt = nR; } LB = dest.GetPointUnchecked(Lxi, Byi); int Blb = LB.B; int Glb = LB.G; int Rlb = LB.R; int Alb = LB.A; if (LB.A <= Athresh) { Blb = nB; Glb = nG; Rlb = nR; } RB = dest.GetPointUnchecked(Rxi, Byi); int Brb = RB.B; int Grb = RB.G; int Rrb = RB.R; int Arb = RB.A; if (RB.A <= Athresh) { Brb = nB; Grb = nG; Rrb = nR; } double Nxd = Nx - Lxi; double iNxd = 1 - Nxd; double Nyd = Ny - Tyi; double iNyd = 1 - Nyd; // interesting - I think my previous calculations were correct but too complex? // worked for 3 pixels then colours went strange with 4 pixels // hence the long winded version below //left top double Blt1 = (nB * blur) + (Blt * iblur); double Blt2 = (Blt1 * iNxd) + (Blt * Nxd); double Blt3 = (Blt2 * iNyd) + (Blt * Nyd); int nBlt = (int)(Blt3); double Glt1 = (nG * blur) + (Glt * iblur); double Glt2 = (Glt1 * iNxd) + (Glt * Nxd); double Glt3 = (Glt2 * iNyd) + (Glt * Nyd); int nGlt = (int)(Glt3); double Rlt1 = (nR * blur) + (Rlt * iblur); double Rlt2 = (Rlt1 * iNxd) + (Rlt * Nxd); double Rlt3 = (Rlt2 * iNyd) + (Rlt * Nyd); int nRlt = (int)(Rlt3); double Alt1 = (nA * blur) + (Alt * iblur); double Alt2 = (Alt1 * iNxd) + (Alt * Nxd); double Alt3 = (Alt2 * iNyd) + (Alt * Nyd); int nAlt = (int)(Alt3); LT = ColorBgra.FromBgra(Int32Util.ClampToByte(nBlt), Int32Util.ClampToByte(nGlt), Int32Util.ClampToByte(nRlt), Int32Util.ClampToByte(nAlt)); dest[Lxi, Tyi] = LT; //right top double Brt1 = (nB * blur) + (Brt * iblur); double Brt2 = (Brt1 * Nxd) + (Brt * iNxd); double Brt3 = (Brt2 * iNyd) + (Brt * Nyd); int nBrt = (int)(Brt3); double Grt1 = (nG * blur) + (Grt * iblur); double Grt2 = (Grt1 * Nxd) + (Grt * iNxd); double Grt3 = (Grt2 * iNyd) + (Grt * Nyd); int nGrt = (int)(Grt3); double Rrt1 = (nR * blur) + (Rrt * iblur); double Rrt2 = (Rrt1 * Nxd) + (Rrt * iNxd); double Rrt3 = (Rrt2 * iNyd) + (Rrt * Nyd); int nRrt = (int)(Rrt3); double Art1 = (nA * blur) + (Art * iblur); double Art2 = (Art1 * Nxd) + (Art * iNxd); double Art3 = (Art2 * iNyd) + (Art * Nyd); int nArt = (int)(Art3); RT = ColorBgra.FromBgra(Int32Util.ClampToByte(nBrt), Int32Util.ClampToByte(nGrt), Int32Util.ClampToByte(nRrt), Int32Util.ClampToByte(nArt)); dest[Rxi, Tyi] = RT; //left bottom double Blb1 = (nB * blur) + (Blb * iblur); double Blb2 = (Blb1 * iNxd) + (Blb * Nxd); double Blb3 = (Blb2 * Nyd) + (Blb * iNyd); int nBlb = (int)(Blb3); double Glb1 = (nG * blur) + (Glb * iblur); double Glb2 = (Glb1 * iNxd) + (Glb * Nxd); double Glb3 = (Glb2 * Nyd) + (Glb * iNyd); int nGlb = (int)(Glb3); double Rlb1 = (nR * blur) + (Rlb * iblur); double Rlb2 = (Rlb1 * iNxd) + (Rlb * Nxd); double Rlb3 = (Rlb2 * Nyd) + (Rlb * iNyd); int nRlb = (int)(Rlb3); double Alb1 = (nA * blur) + (Alb * iblur); double Alb2 = (Alb1 * iNxd) + (Alb * Nxd); double Alb3 = (Alb2 * Nyd) + (Alb * iNyd); int nAlb = (int)(Alb3); LB = ColorBgra.FromBgra(Int32Util.ClampToByte(nBlb), Int32Util.ClampToByte(nGlb), Int32Util.ClampToByte(nRlb), Int32Util.ClampToByte(nAlb)); dest[Lxi, Byi] = LB; //right bottom double Brb1 = (nB * blur) + (Brb * iblur); double Brb2 = (Brb1 * Nxd) + (Brb * iNxd); double Brb3 = (Brb2 * Nyd) + (Brb * iNyd); int nBrb = (int)(Brb3); double Grb1 = (nG * blur) + (Grb * iblur); double Grb2 = (Grb1 * Nxd) + (Grb * iNxd); double Grb3 = (Grb2 * Nyd) + (Grb * iNyd); int nGrb = (int)(Grb3); double Rrb1 = (nR * blur) + (Rrb * iblur); double Rrb2 = (Rrb1 * Nxd) + (Rrb * iNxd); double Rrb3 = (Rrb2 * Nyd) + (Rrb * iNyd); int nRrb = (int)(Rrb3); double Arb1 = (nA * blur) + (Arb * iblur); double Arb2 = (Arb1 * Nxd) + (Arb * iNxd); double Arb3 = (Arb2 * Nyd) + (Arb * iNyd); int nArb = (int)(Arb3); RB = ColorBgra.FromBgra(Int32Util.ClampToByte(nBrb), Int32Util.ClampToByte(nGrb), Int32Util.ClampToByte(nRrb), Int32Util.ClampToByte(nArb)); dest[Rxi, Byi] = RB; } //single pixel //if (!Qual && (!Obtest || startA > Athresh))// assume objects have alpha greater than 250 or object-edge pixels trail transparency across object if (!Qual && startA >= Athresh) { LT = dest.GetPointUnchecked(Lxi, Tyi); int Blt = LT.B; int Glt = LT.G; int Rlt = LT.R; int Alt = LT.A; if (LT.A <= Athresh) { Blt = nB; Glt = nG; Rlt = nR; }// to stop it blending colour with clear (white) int nBlt = (int)((nB * blur) + (Blt * iblur)); int nGlt = (int)((nG * blur) + (Glt * iblur)); int nRlt = (int)((nR * blur) + (Rlt * iblur)); int nAlt = (int)((nA * blur) + (Alt * iblur)); LT = ColorBgra.FromBgra(Int32Util.ClampToByte(nBlt), Int32Util.ClampToByte(nGlt), Int32Util.ClampToByte(nRlt), Int32Util.ClampToByte(nAlt)); dest[Lxi, Tyi] = LT; } oldx = Nx; oldy = Ny;// new point becomes old point for next l Angle = Angle + Curve; } } } } #endregion } }
- 1
-
I see you are all coming up with good uses for this! Thanks for the encouragement and enthusiasm.
Cool image Drew.
Love the ZZtop one Sasha - I think the drummer is called Frank Beard too!
TR - Grass effects are definitely one of the uses I had in mind for this one.
I'm still working on this one - the 'beta' above will crash occassionally (sorry) - so, if testing, always save everything before running it. Thanks Welshy and Doughty for testing.
Hopefully I will get a better (stable) version finished soon.
Cheers all
(just seen Doughty's American gothic - subtle but funny! - good work)
Sorry Mottoman - Only just seen yours too - good work - I think we should have a bearded lady comp once this plugin is finished!
A few of my tests:
http://i.imgur.com/CYZtKT3.png">http://i.imgur.com/CYZtKT3.png http://i.imgur.com/nMuAbk5.jpg">http://i.imgur.com/nMuAbk5.jpg
-
Hi Welshy,
Thanks for reporting that - It happened to me just now - I think I've fixed it (hopefully) - It uses a lot of random numbers between a maximum and minimum, and somewhere the minimum was larger than the max - computer says no!
Also working on varying the amount of curvature randomly and blending in the Primary Color in a more interesting way + some other ideas.
Nice pic!
Have got some good results just running it on a 20pix paintbrush line (on transparent layer) with 'Only keep fur' checked.
@ Null54 - thanks for that tip - I may be changing some of the controls - will bear this in mind.
@ EER - thanks!
@ Pdnnoob - monsters are great!
-
That's cheating! - I rely on 'lucky' words.
I find maths far more interesting if I can see what it's doing - I'm actually starting to understand some of the maths I was supposed to have learnt 30 odd years ago.
It's also good to see how much can be achieved with so few lines of code. -
Nice work - how do you write them so fast?!
-
I love my furry balls too!
It's going to be difficult steering away from the inuendo when I publish! - trouble is it sounds even worse as hairy spheres?
- 1
Pixey's Gallery ~ A Pumpkin ~ New on 5/12/24.
in The Pictorium
Posted
Hi Pixey - nice work on the new sig!
Love the grapes, vine leaves, apple and mouse.
(- bit confused as to what that is behind the mouses head in front of the apple - tail? tendril?)
Rest of it looks great though, and your gallery works perfectly and loads quickly too!
(often a problem on other galleries - with my sluggish broadband).