null54 Posted September 6, 2013 Posted September 6, 2013 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? You are correct regarding IndirectUI, that XML snippet was created by serializing the EffectConfigToken used by a Windows Forms version of the FurBlur dialog. 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
midora Posted September 7, 2013 Posted September 7, 2013 Very nice explanation of the plugin system Midora! Thank you for making it so clear. It's a pleasure to share an explanation in exchange to other support like the plugin index or plugins like FurBlur. But also think about, why is it possible to explain the concept in just a few words? The reason is a well designed software. This is not the standard if you are looking under the hood. Quote
midora Posted September 7, 2013 Posted September 7, 2013 Red Ochre: You are quite often 'misusing' the DisplayName to add start and end labels. Is this a usual requirement to add labels to trackbars? Quote
Ego Eram Reputo Posted September 7, 2013 Posted September 7, 2013 Start and end labels often convey more information than a single DisplayName. A plugin developer understands how the Trackbar values work. New users do not have this luxury. How often do you maximize and minimize a control to find out what it does in a new plugin UI? I hope you're asking because you are considering adding the labels to your OptionBased library? 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
Red ochre Posted September 7, 2013 Author Posted September 7, 2013 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. Quote Red ochre Plugin pack.............. Diabolical Drawings ................Real Paintings
midora Posted September 8, 2013 Posted September 8, 2013 I hope you're asking because you are considering adding the labels to your OptionBased library? Yes ;-) 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. Totally agree, PropertyBased would need void and container properties (proposed sometime ago). Here an example which keeps the basic look of PropertyBased but adds small variations: This is the ui code new OptionPage(OptionNames.FurBlur, optContext) { new OptionDoubleSlider(OptionNames.FBRepetitions, optContext, 10, 0, 100), new OptionInt32Slider(OptionNames.FBLengthBasic, optContext, 30, 1, 300) { Unit = "px", }, new OptionInt32Slider(OptionNames.FBLengthVariation, optContext, 10, 0, 100) { Unit = "%", }, new OptionDoubleRotator(OptionNames.FBAngleBasic, optContext, 90) { Unit = "\u00B0", }, new OptionBooleanCheckBox(OptionNames.FBAddOppositeDirection, optContext), new OptionInt32Slider(OptionNames.FBAngleVariation, optContext, 10, 0, 100) { Unit = "%", }, new OptionEnumRadioButtons<FBCurvatureType>(OptionNames.FBCurvatureType, optContext), new OptionInt32Slider(OptionNames.FBCurvatureBasic, optContext, 10, 0, 100) { Unit = "%", }, new OptionInt32Slider(OptionNames.FBCurvatureVariation, optContext, 10, 0, 100) { Unit = "%", }, new OptionInt32Slider(OptionNames.FBCurvatureFrizz, optContext, 10, 0, 100) { Unit = "%", }, }, plus the translation file FBRepetitions.DisplayName=Density and Length of Lines FBRepetitions.Prefix=Density: FBLengthBasic.DisplayName= FBLengthBasic.Prefix=Basic Lenght: FBLengthVariation.DisplayName= FBLengthVariation.Prefix=Deviation: FBLengthVariation.LabelMin=Small FBLengthVariation.LabelMax=Large FBLengthVariation.Description=Hint: Large density or length values will increase the execution time of the effect a lot! FBAngleBasic.DisplayName=Direction of Lines FBAngleBasic.Prefix=Basic Angle: FBAngleVariation.DisplayName= FBAngleVariation.Prefix=Deviation: FBAngleVariation.LabelMin=Small FBAngleVariation.LabelMax=Large FBAddOppositeDirection.DisplayName= FBAddOppositeDirection.Prefix= FBAddOppositeDirection.Text=Add opposite direction FBCurvatureType.DisplayName=Curvature of Lines FBCurvatureType.Prefix=Type: FBCurvatureBasic.DisplayName= FBCurvatureBasic.Prefix=Curl: FBCurvatureVariation.DisplayName= FBCurvatureVariation.Prefix=Deviation: FBCurvatureVariation.LabelMin=Small FBCurvatureVariation.LabelMax=Large FBCurvatureFrizz.DisplayName= FBCurvatureFrizz.Prefix=Frizz: 1 Quote
Red ochre Posted September 10, 2013 Author Posted September 10, 2013 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. Quote Red ochre Plugin pack.............. Diabolical Drawings ................Real Paintings
midora Posted September 10, 2013 Posted September 10, 2013 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.). It's a lot of work to write your own UI to get a good look and feel. PropertyBased is fine but for good reasons quite restrictive. OptionBased i.e. allows custom controls derived from the basic OptionControl but doing this also means it is your responsibility that it works. 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. For some reason not all PropertyBased controls provide a reset button. OptionBased does for all editable controls. Plus a "Reset All" button. 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? The difference between DropDown lists and RadioButtons on one side and checkboxes on the other is that the first return a 1 of N result and the second N of N. OptionBased has an OptionEnumCheckBoxes handling a list of booleans (see example at the bottom of the pathtools). To save space RadioButtons and CheckBoxes allow to define the number of columns to use. I^m not quite sure how Checkboxes in a DropDown could work for the user. 3. Possibly an 'Info' button to show a message box where the plugin author can write basic instuctions? OptionBased provides an overridable 'about' dialog in the menu at the bottom of the dialog which shows basic information extracted from the assembly and a text defined in the translation file. Maybe tooltips would be usefull. But we are misusing your thread... Quote
midora Posted September 10, 2013 Posted September 10, 2013 Forgot to ask you to use SubmenuNames.Blurs instead of "Blurs" in the constructor. Quote
Red ochre Posted September 21, 2013 Author Posted September 21, 2013 I have just updated the plugin with more curl shapes and a better way to treat transparency (for the 4pix version). Have incuded your SubmenuNames suggestion Midora - thanks! Here's the updated code. Hidden Content: Quote Red ochre Plugin pack.............. Diabolical Drawings ................Real Paintings
MJW Posted October 18, 2013 Posted October 18, 2013 Red ochre, I'm confused about something, which I hope you'll explain so I don't go down the wrong path in understanding your FurBlur code. As we all know (or at least I think I know), Paint.NET plugins are repeatedly passed small slices of the destination buffer to process, and can only write into that slice. The FurBlur plugin uses a random process for generating the fur strands, so I'm not clear how strands that begin in one slice cross over into adjacent slices, which may be processed before or after the current slice. (I hope that question makes sense.) Quote
Ego Eram Reputo Posted October 18, 2013 Posted October 18, 2013 Good question! Over to you Red Ochre....... 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
midora Posted October 18, 2013 Posted October 18, 2013 FurBlur does all rendering in OnSetRenderInfo to a temporary bitmap. On Render just copies the slices from the temporary bitmap to the destination. Red: The question reminds me that I forgot to propose to simplify the job. - Throw away the temporary bitmap and render directly to the destination bitmap. - Remove any code from OnRender In general plugin authors should avoid to do the rendering in OnSetRenderInfo because you are killing the multithreading support in Paint.NET. But sometimes there are reasons to do it. 1 Quote
MJW Posted October 18, 2013 Posted October 18, 2013 (edited) Thank you, midora. I was fooled by the fact the routine was called Render like the normal render routine, and didn't notice the modifications to OnSetRenderInfo and OnRender. That's another reason for me to switch from CodeLab to Visual Studio. I've made CodeLab plugins that perform one-time initialization operations using a firstTime flag, but that only works for things that don't have to write the destination buffer. Killing multithreading may be undesirable, but lots of algorithms require access to the whole output buffer. Edited October 18, 2013 by MJW Quote
midora Posted October 18, 2013 Posted October 18, 2013 Killing multithreading may be undesirable, but lots of algorithms require access to the whole output buffer. There are reasons. But you should aways think about if there is 'inverse' algorithm. For sure this algorithm may not look as elegant as the intuitive one. Still try to think in the way what is needed to generate a destination pixel. If you got it then it is easy to iterate a destination slice. 1 Quote
Red ochre Posted October 18, 2013 Author Posted October 18, 2013 @EER - thanks! "There are known knowns; there are things we know that we know.There are known unknowns; that is to say, there are things that we now know we don't know.But there are also unknown unknowns – there are things we do not know we don't know." - Donald Rumsfeld.@ MJW - as Midora has described.@ Midora - I'm going on what Null54 said in the second post "Strangely the single-threaded OnSetRenderInfo version performs 100x better than the multi-threaded version".Personally I find understanding multithreading perplexing and although I can see that it should be possible to make a multithreaded version of Furblur avoiding ROI striping, I haven't got a clue how to do it.I get the idea of considering the dst pixel being rendered first and writing the algorithm backwards to the src pixels but I can't see a sensible way to do this for FurBlur. If you have a good idea of the structure of a multithreaded version, I would be interested to see how you would rewrite it.Actually I am quite pleased with the speed of Furblur as it is, but I do have another plugin - 'Bevel Object', which I would love to make multithreaded. Perhaps, (when I have tidied up the code and finished some other projects), I may start a thread to attempt this and try to understand multithreading a bit better too.Many thanks for your input. Quote Red ochre Plugin pack.............. Diabolical Drawings ................Real Paintings
midora Posted October 19, 2013 Posted October 19, 2013 Red: My comment to you was just about removing the temporary bitmap because it is not necessary. The rest was a general hint to us the developers. Quote
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.