Jump to content
Paint.NET 5.1 is now available! ×

Recommended Posts

Posted

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.

 

PdnSig.png

Plugin Pack | PSFilterPdn | Content Aware Fill | G'MICPaint 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

 

Posted

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.

midoras signature.gif

Posted

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?

  • Upvote 1
Posted

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.

 

Red ochre Plugin pack.............. Diabolical Drawings ................Real Paintings

 

PdnForumSig2.jpg

Posted

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:

 

post-79572-0-73116200-1378630689_thumb.j

 

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:

  • Upvote 1

midoras signature.gif

Posted

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.
 

 

Red ochre Plugin pack.............. Diabolical Drawings ................Real Paintings

 

PdnForumSig2.jpg

Posted

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).

 

post-79572-0-34331300-1378788375_thumb.j

 

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...

midoras signature.gif

  • 2 weeks later...
  • 4 weeks later...
Posted

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.)

Posted

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.

  • Upvote 1

midoras signature.gif

Posted (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 by MJW
Posted

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.

  • Upvote 1

midoras signature.gif

Posted

@EER - thanks! :lol:
"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.
 

 

Red ochre Plugin pack.............. Diabolical Drawings ................Real Paintings

 

PdnForumSig2.jpg

Posted

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.

midoras signature.gif

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...