black2hack Posted August 26, 2011 Share Posted August 26, 2011 (edited) I'm coding my new (and actually first) Paint.NET plugin now and I can't solve a trouble. I've been trying for almost a day but this is a hard nut to crack. I have no idea why it happens. I thought I had eliminated all possible causes but this error is still here. As I'm new with CodeLab and C# I think it's relative to some compiler rule which I don't know. An idea of my plugin is simple. It splits an image to a few pieces and then move them aside. I use a matrix to keep vertexes of splitting. It works perfectly there. But if I add 'fluctuations' to change fragments (from rectangle to arbitrary quadrilaterals) Paint.NET renders a strange thing. I attached a piece of code. It's only a part of my plugin but it shows the error well. I'd really appreciate any ideas why the plugin works incorrectly. [The new code is placed below] Shatter.zip Edited November 3, 2011 by black2hack Quote Link to comment Share on other sites More sharing options...
black2hack Posted August 26, 2011 Author Share Posted August 26, 2011 Some extra information. For short I'll call my problem teh BUG. Function Interpolate seems to be working well. Even if it's bugged it shouldn't relate to teh BUG. Function PointInQuadrilateral was written by myself so I thought the error is there. But I've tested it a lot and it seems to be working too. But I'm still not sure cause a bug in the function can cause teh BUG. I use 2 matrices - MatNet and MatFragments - and they could have some errors. But it shouldn't cause such a teh BUG. If vertexes were simply messed my plugin would render messed quadrilaterals. But it renders a total **** (teh BUG), not quadrilaterals at all. So... I'm stunned. It must be sorta a type conversion or overflow mistake but I can't find it. Quote Link to comment Share on other sites More sharing options...
Ego Eram Reputo Posted August 27, 2011 Share Posted August 27, 2011 Just from the screenshots, I think you've a problem with the ROI (rectangle of interest). Read about the ROI and how paint.net uses it here: http://www.boltbait.com/pdn/CodeLab/help/overview.asp Here's another thread on the subject: 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...
black2hack Posted August 28, 2011 Author Share Posted August 28, 2011 Just from the screenshots, I think you've a problem with the ROI (rectangle of interest). Read about the ROI and how paint.net uses it here: http://www.boltbait....lp/overview.asp Here's another thread on the subject: http://forums.getpai...ing-to-pdn-336/ Thank you for an answer. I'm not really good at ROI. Is an entire program called when a new ROI is rendered or Render function only? In the second case all should work well. Quote Link to comment Share on other sites More sharing options...
Rick Brewster Posted September 3, 2011 Share Posted September 3, 2011 The way it works is, 1. Your Effect is instantiated (your constructor is called) 2. The user configures stuff (your CreateEffectConfigDialog() is called, or IndirectUI just does it for you) 3. OnSetRenderInfo() is called with the new token. 4. OnRender() is called many times, once for each section of the region of interest. These calls are made in parallel on multiple threads. 5. If the user changes the configuration (the token), then IsCancelRequested is set to true and Paint.NET waits for any pending OnRender() calls to finish. Go back to step 3. (IsCancelRequested is also reset to false) If you want you can do all your rendering in OnSetRenderInfo() and then OnRender() would be implemented to do nothing. It doesn't provide a great user experience though. 2 Quote The Paint.NET Blog: https://blog.getpaint.net/ Donations are always appreciated! https://www.getpaint.net/donate.html Link to comment Share on other sites More sharing options...
black2hack Posted September 18, 2011 Author Share Posted September 18, 2011 And after less than a month I've returned to my plugin =) Ok, I've found out that teh BUG is caused by ROI. So Eer, you was right. Rick, your post seems to be very helpful but there is a problem - no function OnSetRenderInfo() nor OnRender() in my program exist. I use CodeLab, and there is Render function only. Is it possible to create a piece of code called like OnSetRenderInfo() and another called like OnRender() (I think Render function works that way)? If it's impossible to do that in CodeLab please give me a link to a guide 'how to write Paint.NET plugins with C' or something like this. Quote Link to comment Share on other sites More sharing options...
Ego Eram Reputo Posted September 18, 2011 Share Posted September 18, 2011 You can write plugins in Visual Studio. I use the Express Edition (it's a free download from Microsoft). With Visual Studio you can code in C# - just like Codelab uses. Here's an effect template should you wish to go down that path: http://forums.getpaint.net/index.php?/topic/2248-visual-studio-2005-effect-plugin-template/ (Note: read the whole thread - especially BoltBait's how-to post!) I have not heard of Codelab being used with OnSetRender, I'd also be interested if it can be done. 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...
black2hack Posted September 19, 2011 Author Share Posted September 19, 2011 Thank you. I'll try that soon. Quote Link to comment Share on other sites More sharing options...
black2hack Posted September 24, 2011 Author Share Posted September 24, 2011 I've encountered a error during a compilation. (MS Visual Studio 2005) 1. I deleted PdnLib reference and added PaintDotNet.Core. Then I tried to build and ------ Build started: Project: EffectsPluginTemplate2, Configuration: Debug Any CPU ------ C:\Windows\Microsoft.NET\Framework\v2.0.50727\Csc.exe /noconfig /nowarn:1701,1702 /errorreport:prompt /warn:4 /define:DEBUG;TRACE /reference:"..\..\..\..\..\..\..\Program Files\Paint.NET\PaintDotNet.Core.dll" /reference:"..\..\..\..\..\..\..\Program Files\Paint.NET\PaintDotNet.Effects.dll" /reference:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.dll /reference:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Drawing.dll /reference:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Windows.Forms.dll /debug+ /debug:full /optimize- /out:obj\Debug\EffectsPluginTemplate2.dll /resource:obj\Debug\EffectsPluginTemplate2.EffectPluginConfigDialog.resources /resource:obj\Debug\EffectsPluginTemplate2.EffectPluginIcon.png /target:library EffectPluginToken.cs EffectPlugin.cs EffectPluginConfigDialog.cs Properties\AssemblyInfo.cs C:\Users\Yara\Documents\Visual Studio 2005\Projects\EffectsPluginTemplate2\EffectsPluginTemplate2\EffectPluginConfigDialog.cs(12,18): error CS0012: The type 'PaintDotNet.Threading.IDispatcherObject' is defined in an assembly that is not referenced. You must add a reference to assembly 'PaintDotNet.Base, Version=3.58.4081.24574, Culture=neutral, PublicKeyToken=null'. c:\Program Files\Paint.NET\PaintDotNet.Core.dll: (Related file) c:\Program Files\Paint.NET\PaintDotNet.Effects.dll: (Related file) Compile complete -- 1 errors, 0 warnings ========== Build: 0 succeeded or up-to-date, 1 failed, 0 skipped ========== 2. I added PaintDotNetBase reference and ------ Build started: Project: EffectsPluginTemplate2, Configuration: Debug Any CPU ------ C:\Windows\Microsoft.NET\Framework\v2.0.50727\Csc.exe /noconfig /nowarn:1701,1702 /errorreport:prompt /warn:4 /define:DEBUG;TRACE /reference:"..\..\..\..\..\..\..\Program Files\Paint.NET\PaintDotNet.Base.dll" /reference:"..\..\..\..\..\..\..\Program Files\Paint.NET\PaintDotNet.Core.dll" /reference:"..\..\..\..\..\..\..\Program Files\Paint.NET\PaintDotNet.Effects.dll" /reference:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.dll /reference:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Drawing.dll /reference:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Windows.Forms.dll /debug+ /debug:full /optimize- /out:obj\Debug\EffectsPluginTemplate2.dll /resource:obj\Debug\EffectsPluginTemplate2.EffectPluginConfigDialog.resources /resource:obj\Debug\EffectsPluginTemplate2.EffectPluginIcon.png /target:library EffectPluginToken.cs EffectPlugin.cs EffectPluginConfigDialog.cs Properties\AssemblyInfo.cs C:\Users\Yara\Documents\Visual Studio 2005\Projects\EffectsPluginTemplate2\EffectsPluginTemplate2\EffectPlugin.cs(37,16): error CS0619: 'PaintDotNet.Effects.Effect.Effect(string, System.Drawing.Image, string, bool)' is obsolete: '' Compile complete -- 1 errors, 0 warnings ========== Build: 0 succeeded or up-to-date, 1 failed, 0 skipped ========== Blah. I miss Pascal so much. Quote Link to comment Share on other sites More sharing options...
pyrochild Posted September 24, 2011 Share Posted September 24, 2011 Instead of the Output window, you'll probably have an easier time deciphering error messages in the Errors window. It'll even take you to the offending line. In this case, you are using an obsolete overload of the Effect constructor. The obsolete ones are kept around for compatibility with legacy plugins, but new plugins can't use them. 1 Quote ambigram signature by Kemaru [i write plugins and stuff] If you like a post, upvote it! Link to comment Share on other sites More sharing options...
black2hack Posted September 25, 2011 Author Share Posted September 25, 2011 2 pyrochild. I don't know how to open Error window in Visual Studio. I'd appreciate if you reveal that =) Ok, I've noticed this in the topic that EER had linked. public EffectPlugin() //: base(EffectPlugin.StaticName, EffectPlugin.StaticIcon, EffectPlugin.StaticSubMenuName, true) // Obsolete //: base(EffectPlugin.StaticName, EffectPlugin.StaticIcon, EffectPlugin.StaticSubMenuName, EffectFlags.Configurable | EffectFlags.SingleThreaded) : base(EffectPlugin.StaticName, EffectPlugin.StaticIcon, EffectPlugin.StaticSubMenuName, EffectFlags.Configurable) { } And the template has been built finally. Awesome! Two questions. Can anybody fix that template? The template seems to be very handy. And I don't think it would take a bunch of time to replace a few strings of code and save poor newbies from their brains crashed =) Is it possible to work with the template in CodeGear RAD Studio? I tried to check it but I didn't find the way to open the template there. Quote Link to comment Share on other sites More sharing options...
pyrochild Posted September 25, 2011 Share Posted September 25, 2011 2 pyrochild. I don't know how to open Error window in Visual Studio. I'd appreciate if you reveal that =) View -> Error List It's open by default, but you may have closed it at some point. It autohides to a tab. Quote ambigram signature by Kemaru [i write plugins and stuff] If you like a post, upvote it! Link to comment Share on other sites More sharing options...
black2hack Posted October 30, 2011 Author Share Posted October 30, 2011 (edited) And after less than a month I've returned to my plugin © =) 2pyrochild. Thank you, I've found Error List in View -> Other windows -> Error List. I've received evidence that The BUG is caused by ROI. When I delete ROI everything works - slowly but correctly. I've attached a piece of code (C# now) just in case someone can find a problem faster than me. I suspect the problem is similar to this one http://forums.getpai...ing-to-pdn-336/ but I haven't understood this topic yet. public override void Render(EffectConfigToken parameters, RenderArgs dstArgs, RenderArgs srcArgs, Rectangle[] rois, int startIndex, int length) { PdnRegion selectionRegion = EnvironmentParameters.GetSelection(srcArgs.Bounds); //Surface src = srcArgs.Surface; //Surface dst = dstArgs.Surface; Rectangle selection = EnvironmentParameters.GetSelection(srcArgs.Surface.Bounds).GetBoundsInt(); int CenterX = ((selection.Right - selection.Left) / 2) + selection.Left; int CenterY = ((selection.Bottom - selection.Top) / 2) + selection.Top; ColorBgra PrimaryColor = (ColorBgra)EnvironmentParameters.PrimaryColor; ColorBgra SecondaryColor = (ColorBgra)EnvironmentParameters.SecondaryColor; int BrushWidth = (int)EnvironmentParameters.BrushWidth; ColorBgra CurrentPixel; int Amount1 = 5; //[1,10]CountOfColumns int Amount2 = 5; //[1,10]CountOfRows int Amount3 = 50; //[0,50]Shifting(pixels) int Amount4 = 10; //[0,100]Fluctuation(%) int Amount5 = 0; //[0,359]MaxAngle(degrees) int n = Amount1; int m = Amount2; int shift = Amount3; double a = (selection.Right - selection.Left) / n; double b = (selection.Bottom - selection.Top) / m; double dFluct = (double)Amount4 / 100.0 * 0.95; double dAngle = (double)Amount5 / 360.0 * 3.1415926535897932384626433832795; int CenterN = (int)Math.Floor(n / 2.0); int CenterM = (int)Math.Floor(m / 2.0); double tempX, tempY; double tempCenterX, tempCenterY; double tempAngle; double tempCos, tempSin; double tempShiftX, tempShiftY; bool bGotcha; Random rand = new Random(); //Creating a matrix splitting the initial picture, [,,0] - x, [,,1] - y double[, ,] MatNet = new double[m + 1, n + 1, 2]; MatNet[0, 0, 0] = selection.Left; MatNet[0, 0, 1] = selection.Top; MatNet[m, 0, 0] = selection.Left; MatNet[m, 0, 1] = selection.Bottom; MatNet[0, n, 0] = selection.Right; MatNet[0, n, 1] = selection.Top; MatNet[m, n, 0] = selection.Right; MatNet[m, n, 1] = selection.Bottom; for (int j = 1; j < n; j++) { MatNet[0, j, 0] = selection.Left + a * ((double)j + dFluct * (rand.NextDouble() - 0.5)); MatNet[0, j, 1] = selection.Top; MatNet[m, j, 0] = selection.Left + a * ((double)j + dFluct * (rand.NextDouble() - 0.5)); MatNet[m, j, 1] = selection.Bottom; } for (int i = 1; i < m; i++) { MatNet[i, 0, 0] = selection.Left; MatNet[i, 0, 1] = selection.Top + b * ((double)i + dFluct * (rand.NextDouble() - 0.5)); MatNet[i, n, 0] = selection.Right; MatNet[i, n, 1] = selection.Top + b * ((double)i + dFluct * (rand.NextDouble() - 0.5)); for (int j = 1; j < n; j++) { MatNet[i, j, 0] = selection.Left + a * ((double)j + dFluct * (rand.NextDouble() - 0.5)); MatNet[i, j, 1] = selection.Top + b * ((double)i + dFluct * (rand.NextDouble() - 0.5)); } } //Creating a matrix of fragments of the shattered picture, [,,0,]..[,,3,] - vertexes, [,,4,] - rotating center, [,,,0] - x, [,,,1] - y, [,,5,] - Cos & Sin double[, , ,] MatFragments = new double[m, n, 7, 2]; // 01 - vertexes' position for (int i = 0; i < m; i++) // 23 { for (int j = 0; j < n; j++) { tempAngle = dAngle * rand.NextDouble(); tempCos = Math.Cos(tempAngle); tempSin = Math.Sin(tempAngle); tempShiftX = shift * (j - CenterN); //how much we should move the fragment tempShiftY = shift * (i - CenterM); tempCenterX = (double)selection.Left + a * ((double)j + 0.5); //a (rotating) center of the fragment tempCenterY = (double)selection.Top + b * ((double)i + 0.5); tempX = MatNet[i, j, 0] - tempCenterX; tempY = MatNet[i, j, 1] - tempCenterY; MatFragments[i, j, 0, 0] = tempX * tempCos - tempY * tempSin + tempCenterX + tempShiftX; //rotating and moving MatFragments[i, j, 0, 1] = tempY * tempCos + tempX * tempSin + tempCenterY + tempShiftY; tempX = MatNet[i, j + 1, 0] - tempCenterX; tempY = MatNet[i, j + 1, 1] - tempCenterY; MatFragments[i, j, 1, 0] = tempX * tempCos - tempY * tempSin + tempCenterX + tempShiftX; MatFragments[i, j, 1, 1] = tempY * tempCos + tempX * tempSin + tempCenterY + tempShiftY; tempX = MatNet[i + 1, j, 0] - tempCenterX; tempY = MatNet[i + 1, j, 1] - tempCenterY; MatFragments[i, j, 2, 0] = tempX * tempCos - tempY * tempSin + tempCenterX + tempShiftX; MatFragments[i, j, 2, 1] = tempY * tempCos + tempX * tempSin + tempCenterY + tempShiftY; tempX = MatNet[i + 1, j + 1, 0] - tempCenterX; tempY = MatNet[i + 1, j + 1, 1] - tempCenterY; MatFragments[i, j, 3, 0] = tempX * tempCos - tempY * tempSin + tempCenterX + tempShiftX; MatFragments[i, j, 3, 1] = tempY * tempCos + tempX * tempSin + tempCenterY + tempShiftY; MatFragments[i, j, 4, 0] = tempCenterX; MatFragments[i, j, 4, 1] = tempCenterY; MatFragments[i, j, 5, 0] = tempCos; MatFragments[i, j, 5, 1] = tempSin; MatFragments[i, j, 6, 0] = tempShiftX; MatFragments[i, j, 6, 1] = tempShiftY; } } for (int L = startIndex; L < startIndex + length; ++L) { Rectangle rect = rois[L]; for (int y = rect.Top; y < rect.Bottom; ++y) { for (int x = rect.Left; x < rect.Right; ++x) { CurrentPixel = srcArgs.Surface[x, y]; bGotcha = false; for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { //if (x,y) is inside the fragment (i,j) we should restore a colour of the pixel (x,y) if (PointInQuadrilateral((double)x + 0.5, (double)y + 0.5, MatFragments[i, j, 0, 0], MatFragments[i, j, 0, 1], MatFragments[i, j, 1, 0], MatFragments[i, j, 1, 1], MatFragments[i, j, 2, 0], MatFragments[i, j, 2, 1], MatFragments[i, j, 3, 0], MatFragments[i, j, 3, 1])) { tempX = (double)x - MatFragments[i, j, 6, 0] - MatFragments[i, j, 4, 0]; tempY = (double)y - MatFragments[i, j, 6, 1] - MatFragments[i, j, 4, 1]; tempX = tempX * MatFragments[i, j, 5, 0] + tempY * MatFragments[i, j, 5, 1] + MatFragments[i, j, 4, 0]; tempY = tempY * MatFragments[i, j, 5, 0] - tempX * MatFragments[i, j, 5, 1] + MatFragments[i, j, 4, 1]; CurrentPixel = Interpolate(srcArgs.Surface, selection, tempX - 0.5, tempY - 0.5); dstArgs.Surface[x, y] = CurrentPixel; bGotcha = true; i = m; j = n; } } } //if (x,y) is beyond all fragments we should make the pixel (x,y) transparent if (!bGotcha) { CurrentPixel.R = (byte)PrimaryColor.R; CurrentPixel.G = (byte)PrimaryColor.G; CurrentPixel.B = (byte)PrimaryColor.B; CurrentPixel.A = 10; dstArgs.Surface[x, y] = CurrentPixel; } } } } } Edited October 30, 2011 by black2hack Quote Link to comment Share on other sites More sharing options...
Alfred8100 Posted January 17, 2012 Share Posted January 17, 2012 Really done nice job there....one of my friend tell me about this to see and isee is really good...... i appreciate you... Quote Link to comment Share on other sites More sharing options...
black2hack Posted January 17, 2012 Author Share Posted January 17, 2012 Hey, thank you pal. I've been occupied by different annoying stuff (like my studies ^_^) so I kinda neglected my work with this plugin. I hope I'll be able to find time to cope with Teh BUG soon. I also have some ideas for a new plugin. Though there is a high probability I'll never start doing it =) Quote 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.