Jump to content

Plugin development : Nuggets of wisdom I learned


Recommended Posts

If there,


Since I am learning to use codelab. Codelab is plugin which you can use to program and write plugin. Apart from the tutorial and programming lessons, you come learn many things from experience and by asking questions. As I am learning things here, I think I should compile these little bits which in course of programming, I am learning here.. Best place would be this forum, because here it is mostly related to codelab and C# programming. List is likely to increase with time. :biggrin:


#001 - Sum of scaling factors should equal to divisor.


Explanation: When you are using linear extrapolation between two variable to get intermediate values, you should make sure that divisor should be equal to sum of scaling factors. Mistake in this can result in lesser values or less values or boundary condition not matched.


On 1/19/2018 at 9:29 PM, MadJik said:


@Pratyush the last right shade isn't equal to secondary color...



On 1/20/2018 at 1:56 AM, MJW said:
On 1/19/2018 at 10:02 PM, Pratyush said:

g1 = (PrimaryColor.R *(n - i) + (i -1)*SecondaryColor.R)/n 



I don't think that's quite correct. Your scaling factors are (n - i) and (i - 1), and your divisor is n. But in situations like this, the sum of the scaling factors should equal the divisor, which it doesn't. I assume i runs from 0 to (n - 1), in which case you want (n - 1 - i) and i as the scaling factors and (n - 1) as the divisor.


#002 - rect.Width is width of ROI. You can't use to for rectangle of selection or rectangle of canvas. 

Explanation: Using rect.Width will lead to some issues, it's not analogus to rect.Height. For these issue you can try this (suggested by MJW).

On 1/23/2018 at 2:05 AM, MJW said:

I believe using the surface height and width will fix your problem. You might consider putting the setup in PreRender. If you want do some setup that can't be done in PreRender, you should ask yourself if you're doing it right. The only additional information you have in Render is about the ROI, and it's a rare plugin, indeed, that needs that for anything other than controlling which destination pixels to process.



On 1/21/2018 at 11:52 PM, Pratyush said:


I added feature for repeating stripes. I was trying to add choice of vertical and horizontal stripes.

In case of vertical stripes it's working fine. But when I try to create horizontal stripes it gets some problem.


On 1/21/2018 at 11:52 PM, Pratyush said:

But in case of horizontal I get following. 




On 1/23/2018 at 2:05 AM, MJW said:

Consider one of the lines:

divide = (float)rect.Width / Amount1;

That's wrong. "rect" is the rectangle for the ROI. You can't have values that are used in the calculations depend on the dimensions of the ROI. It may work sometimes, especially when there's no selection, but it won't work in general. Values like that can only depend on the surface dimensions or the selection dimensions, never on the ROI dimensions. The  choice between the surface dimensions or the selection dimensions depends on what you're trying to do. (Instead of "selection dimensions," it would be more precise to say the dimensions of the selection's  bounding rectangle.)


#003 - Codelab has Autocomplete tool tips which can tell you about signature, returntype of functions. 

Explanation: Not much Explanation is needed. 

On 1/24/2018 at 1:51 AM, toe_head2001 said:
On 1/24/2018 at 1:43 AM, Pratyush said:

what's return type of this function?

If only we had something in CodeLab to inform us... oh, wait, we do!  At least 3! :D


- AutoComplete tooltips



- Editor tooltips


- F12 to lookup on docs.microsoft.com


#004 -  Use  Math class for mathematical calculation.

Explanation: Math class provides constants and static methods for trigonometric, logarithmic, and other common mathematical functions. It is part of .NET framework and comes under namespace system. 


Link of Documentation.


On 1/24/2018 at 1:41 AM, toe_head2001 said:

@Pratyush, the Math.Sin() and Math.Cos().


#005 -  Methods for Unit Conversion between radians and degrees for angles.

Explanation: Math.Sin() and Math.Cos()an use radians so you need to conversion from degree to radians, radians are all needed for mathematical functions and  calculation, and degree we may need from UI point of view.

On 1/24/2018 at 2:44 AM, Ego Eram Reputo said:
On 1/24/2018 at 1:41 AM, toe_head2001 said:

@Pratyush, the Math.Sin() and Math.Cos() trigonometric functions use radians rather than degrees, so don't forget to do conversions if needs be.


A little help on this.....


Write yourself a couple of helper functions to do the conversions


public double DegreeToRadians(double angle)
        return (Math.PI / 180) * angle;


private double RadianToDegrees(double angle)
   return angle * (180.0 / Math.PI);


You can call these from your code like this...

double angle = Math.Cos(DegreeToRadians(45));




#006 -  Be careful while naming the version number in DLL as it won't replace older versions.


Version number field:



On 1/23/2018 at 10:45 AM, MadJik said:


Please don't name the DLL with the version number as it won't replace older versions in the effect menu..



#007 -  Code for Increment all channels.

Explanation: Sometime you need all channels be incremented and reduced with same value, you may need a function to do that.



On 1/14/2018 at 12:15 PM, Pratyush said:

Can such object operations be defined, which let to change all of the channels together such these codes can to changed together as Instead of this


CurrentPixel.R = PrimaryColor.R + 25;
CurrentPixel.G = PrimaryColor.G + 25;
CurrentPixel.B = PrimaryColor.B + 25;
CurrentPixel.A = PrimaryColor.A + 25;

we can simply use.

CurrentPixel = PrimaryColor + 25;





On 1/15/2018 at 2:25 AM, toe_head2001 said:

You could create a function for that.

void Render(Surface dst, Surface src, Rectangle rect)
    ColorBgra PrimaryColorColor = EnvironmentParameters.PrimaryColor;

    ColorBgra CurrentPixel;
    for (int y = rect.Top; y < rect.Bottom; y++)
        if (IsCancelRequested) return;
        for (int x = rect.Left; x < rect.Right; x++)
            CurrentPixel = IncrementAllChannels(PrimaryColorColor, 25);
            dst[x,y] = CurrentPixel;

ColorBgra IncrementAllChannels(ColorBgra color, int amount)
    return ColorBgra.FromBgraClamped(color.B + amount, color.G + amount, color.B + amount, color.A + amount);




#008 -  Limitations in calling internal effects like blur in Codelab.

Explanation: While it is possible to call blur effect in codelab, but it depends on the code itself.


On 1/30/2018 at 12:04 PM, Pratyush said:

Is there a way I can call blur effect after doing all that render? so that I can soften rough edges. :(.


On 1/30/2018 at 12:14 PM, toe_head2001 said:

It depends on how your script works. Generally, you can't.

Show us your current script, and we'll let you know.



#009 -  Find the error.


I don't understand what is happening here, I want declare a method  and call it. How to make it work?




22 hours ago, toe_head2001 said:

Don't declare types in the call.



sf1 = SmoothingFactor(int k, int stepR);


sf1 = SmoothingFactor(k, stepR);




#010 -  How to use radiobuttons in Codelab.



On 2/3/2018 at 11:45 AM, Pratyush said:

Hi @BoltBait, Can you help how to use radio button, when there are more and one options. This time I did it using if-else since it was only two option, but can you explain how more options can be included in coding.



RadioButtonControl Amount4 = 0; // [1] To do|Cool Thing| Cooler Thing| More Cooler Thing| Coolest Thing


On 2/3/2018 at 11:53 AM, toe_head2001 said:


Use a switch.

switch (Amount3)
  case 0:
    // do something cool
  case 1:
    // do something cooler
  case 2:
    // do something more cooler
  case 3:
    // do the coolest thing



#010 -  <Template for next point>.




Edited by Pratyush
  • Like 1
  • Upvote 2


Link to comment
Share on other sites

In your Render() function, you should always include the line "if (IsCancelRequested) return;" in your Y loop so that if the user changes a user control (slider, checkbox, etc.) the UI will feel more responsive.  This causes it to check for UI updates at the end of each line rendered.


If your X loop is very slow, you should move that line into your X loop instead... therefore it will check between every pixel!


However, if your code is calling a function in a library that doesn't have access to the IsCancelRequested property, try this:


On 1/23/2010 at 12:57 PM, Rick Brewster said:

If you have code which doesn't have access to the property (outside of your Effect class), then just pass it a delegate which it can poll.

void OnSetRenderInfo(...)
   for (y = ...)
       if (IsCancelRequested) return;

       HelperClass.ComputeSomethingExpensiveOmg(y, ..., () => IsCancelRequested);

class HelperClass
   bool ComputeSomethingExpensiveOmg(int y, ..., Func cancelPollFn)
       if (cancelPollFn()) return false;
       return true;

This is what Auto-Levels does, for instance.


  • Like 1
  • Upvote 1
Link to comment
Share on other sites

Join the conversation

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

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