Red ochre Posted August 27, 2013 Share Posted August 27, 2013 I have successfully used Null54's method of using another surface to get around ROI banding in other plugins. However, I am stumped with this one! There are 2 main differences between this and the successful ones: 1. I am trying to copy the src to the dst, then randomly trail/blur lines across the ROIs. 2. I am trying to use random numbers in the same way they are generated by codelab. I'm not sure which (or both) is causing the problems, or even if this way of doing things is possible. I would prefer to attack the canvas in a random way as if I used the normal y/x loops I think it would give a diagonal woven appearance.I am attaching the .dll for the version still only using src and dst surfaces (only slightly adapted from the codelab version), to give an idea of what the plugin could potentially do (try it on an object). I am also attaching the corresponding VS code. I think it could useful for watercolour/paper effects and grass/fur textures as well as bearded ladies and bald patches! Here is the code with my 'attempt' at using another surface called 'dest'. It builds without errors in VS2010 but when used in Pdn it crashes the program with null reference and threading errors? Any help would be greatly appreciated. I will, of course, give credit for co-authorship if anyone can get this working. I will probably need to fine tune the controls a bit before publishing too. Successful or not - many thanks. 1 Quote Red ochre Plugin pack.............. Diabolical Drawings ................Real Paintings Link to comment Share on other sites More sharing options...
null54 Posted August 27, 2013 Share Posted August 27, 2013 The fixed code is attached. Strangely the single-threaded OnSetRenderInfo version performs 100x better than the multi-threaded version. FurBlurdestSurface.zip 2 Quote Plugin Pack | PSFilterPdn | Content Aware Fill | G'MIC | Paint Shop Pro Filetype | RAW Filetype | WebP Filetype The small increase in performance you get coding in C++ over C# is hardly enough to offset the headache of coding in the C++ language. ~BoltBait Link to comment Share on other sites More sharing options...
Red ochre Posted August 27, 2013 Author Share Posted August 27, 2013 Hurray - it works!Brilliant - many many thanks Null54 (to the rescue again!).So far I have only compiled and a quick test - I can now work on fine tuning the effect and seeing where I went wrong. Really pleased the principle is possible as it could lead to many other effects. I'm thinking artistic sketch effects like the Jimi Hendrix 'Cry of love' album cover:http://checkthisart.com/wp-content/uploads/2011/12/100_1695.jpgI had all but given up on this one - so really appreciate this. Thank you. Quote Red ochre Plugin pack.............. Diabolical Drawings ................Real Paintings Link to comment Share on other sites More sharing options...
Ego Eram Reputo Posted August 27, 2013 Share Posted August 27, 2013 Album cover reminds me of the PS plugin Fractalius. Good luck with this Red! 1 Quote ebook: Mastering Paint.NET | resources: Plugin Index | Stereogram Tut | proud supporter of Codelab plugins: EER's Plugin Pack | Planetoid | StickMan | WhichSymbol+ | Dr Scott's Markup Renderer | CSV Filetype | dwarf horde plugins: Plugin Browser | ShapeMaker Link to comment Share on other sites More sharing options...
DrewDale Posted August 28, 2013 Share Posted August 28, 2013 I really look forward to this plug in, soon I hope. Good luck also 1 Quote Link to comment Share on other sites More sharing options...
Red ochre Posted August 30, 2013 Author Share Posted August 30, 2013 Many thanks for the encouragement EER and Drew. I had some problems getting the anti-aliasing right - well actually I think I was right but possibly exceeded the limits of one of the variables. Anyway fixed now and getting exciting results.Am attaching the 'beta' .dll if you would like to preview/test (can be a little slow if reps set large on large objects/selections - but useful to have the choice for smaller areas). Also attaching the code - if anything looks wrong please report back. I hope to publish properly soon. Hidden Content: Again thanks Null54 - this could be another addictive one. I leave this image of my furry balls - don't have nightmares! 3 Quote Red ochre Plugin pack.............. Diabolical Drawings ................Real Paintings Link to comment Share on other sites More sharing options...
barbieq25 Posted August 31, 2013 Share Posted August 31, 2013 Between your furry balls & Welshy's "Don't be Afraid of the Dark" image we will be having nightmares aplenty!! Dare I say: I love your furry balls! I really do love the transition from metallic to furry. This is going to be so much fun... Quote Knowledge is no burden to carry. April Jones, 2012 Gallery My DA Gallery Link to comment Share on other sites More sharing options...
Red ochre Posted August 31, 2013 Author Share Posted August 31, 2013 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 Quote Red ochre Plugin pack.............. Diabolical Drawings ................Real Paintings Link to comment Share on other sites More sharing options...
null54 Posted August 31, 2013 Share Posted August 31, 2013 Regarding the updated source code instead of casting the StartColor enum values you could change the type of the startColour variable. StartColor startColour = StartColor.FromSrc; this.startColour = (StartColor)newToken.GetProperty<StaticListChoiceProperty>(PropertyNames.StartC).Value; 1 Quote Plugin Pack | PSFilterPdn | Content Aware Fill | G'MIC | Paint Shop Pro Filetype | RAW Filetype | WebP Filetype The small increase in performance you get coding in C++ over C# is hardly enough to offset the headache of coding in the C++ language. ~BoltBait Link to comment Share on other sites More sharing options...
pdnnoob Posted August 31, 2013 Share Posted August 31, 2013 That is...amazing. Now everyone can make furry monsters like this one! Quote No, Paint.NET is not spyware...but, installing it is an IQ test. ~BoltBait Blend modes are like the filling in your sandwich. It's the filling that can change your experience of the sandwich. ~Ego Eram Reputo Link to comment Share on other sites More sharing options...
Ego Eram Reputo Posted August 31, 2013 Share Posted August 31, 2013 ^ Wow! Great job 'noob. @Red: This is AMAZING! Quote ebook: Mastering Paint.NET | resources: Plugin Index | Stereogram Tut | proud supporter of Codelab plugins: EER's Plugin Pack | Planetoid | StickMan | WhichSymbol+ | Dr Scott's Markup Renderer | CSV Filetype | dwarf horde plugins: Plugin Browser | ShapeMaker Link to comment Share on other sites More sharing options...
Red ochre Posted August 31, 2013 Author Share Posted August 31, 2013 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! Quote Red ochre Plugin pack.............. Diabolical Drawings ................Real Paintings Link to comment Share on other sites More sharing options...
doughty Posted August 31, 2013 Share Posted August 31, 2013 So fun...but crashed several times. I'll try something on a smaller image. Quote Link to comment Share on other sites More sharing options...
barbieq25 Posted September 1, 2013 Share Posted September 1, 2013 Lovely outcomes on both of those Welshy! Facial hair, body hair...brillo Quote Knowledge is no burden to carry. April Jones, 2012 Gallery My DA Gallery Link to comment Share on other sites More sharing options...
DrewDale Posted September 1, 2013 Share Posted September 1, 2013 Good examples posted. Cool plugin Here is a fur target: Quote Link to comment Share on other sites More sharing options...
sashwilko Posted September 1, 2013 Share Posted September 1, 2013 Interesting plug-in with some nice examples of what it can do Finally ZZ Top can match 2 Quote Link to comment Share on other sites More sharing options...
TechnoRobbo Posted September 1, 2013 Share Posted September 1, 2013 (edited) Bravo Dude!!!! Very Visionary. worked great, I had no issues whatsoever. I Blame Global Warming Edited September 1, 2013 by TechnoRobbo 1 Quote Go out there and be amazing. Have Fun, TRSome Pretty Pictures Some Cool Plugins Link to comment Share on other sites More sharing options...
mottoman Posted September 1, 2013 Share Posted September 1, 2013 Talk of bearded ladies - and now thanks for this plugin. French artist Alizee has a new David Grohl look. Nice work RedOchre. Thank you. Quote Link to comment Share on other sites More sharing options...
doughty Posted September 1, 2013 Share Posted September 1, 2013 Computer was behaving itself today. I think curl was bothering it yesterday. Sasha - Cool. 1 Quote Link to comment Share on other sites More sharing options...
Red ochre Posted September 1, 2013 Author Share Posted September 1, 2013 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 Quote Red ochre Plugin pack.............. Diabolical Drawings ................Real Paintings Link to comment Share on other sites More sharing options...
Red ochre Posted September 3, 2013 Author Share Posted September 3, 2013 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 .dll Some 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 Quote Red ochre Plugin pack.............. Diabolical Drawings ................Real Paintings Link to comment Share on other sites More sharing options...
doughty Posted September 3, 2013 Share Posted September 3, 2013 (edited) Happy and it didn't crash. Edit:Picture was missing. Hope I replaced it with the correct one. Edited September 18, 2015 by doughty 1 Quote Link to comment Share on other sites More sharing options...
DrewDale Posted September 3, 2013 Share Posted September 3, 2013 Just tested - no crash. Top work Red. Here's a Furcraft 1 Quote Link to comment Share on other sites More sharing options...
TechnoRobbo Posted September 3, 2013 Share Posted September 3, 2013 (edited) Worked Great- This will definitely be one of the most significant Plugins for PDN. The "Only Keep Fur" Checkbox is key in my book. This stuff looks real. Oh Yeah , one suggestion -- Presets!!!! Edited September 3, 2013 by TechnoRobbo 1 Quote Go out there and be amazing. Have Fun, TRSome Pretty Pictures Some Cool Plugins Link to comment Share on other sites More sharing options...
Red ochre Posted September 3, 2013 Author Share Posted September 3, 2013 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 Quote Red ochre Plugin pack.............. Diabolical Drawings ................Real Paintings Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.