Joshua Lamusga

Brush Factory v1.5 (August 10th, 2017)

Recommended Posts

Thanks, Anthony!

 

I think that Brush Factory will be a favorite for many users.

 

Request:

- A mouse speed controller, if I move the mouse too slow the brush will be recreated too many times.On the other hand, if I move the mouse too fast it will leave important gaps between the repeated images. Perhaps matching the "Minimum Draw Distance" with a "Maximum Draw Distance" could do it.

brush-factory-speedy-511d051.png

 

Edited by Eli

Share this post


Link to post
Share on other sites

@Eli I attempted it, but it was countered by lag. I think I'd have to rewrite this plugin to do something like that. I hope that's not a deal-breaker. Alternatively, you or another person can try to implement it.

 

@homebrew We make all of our plugins on an external canvas because it's the only way to hack in these kinds of features. PDN does not lend itself to canvas-type plugins; there is no way to make it native. Rick would have to modify the API to allow us to write tool plugins or something.

Edited by AnthonyScoffler
Updated information

Share this post


Link to post
Share on other sites

Version 1.1 has been released.

You can find the changes in the changelog at the bottom, just above the download. I didn't get a big response for the initial release (but then, it had no publicity). Now that a few people have seen it, I would like some feedback if you have the time :)

 

@Eli I haven't given up on that idea. I might create an alternate way to draw. I was trying to draw as a percent of image size, but now I'm thinking of running a timer that every few ticks will look at the mouse position and add X images at some fixed distance (that might still be %-based). If I get it to work, I'll have it as an optional way to draw under the 'other' tab.

  • Upvote 2

Share this post


Link to post
Share on other sites

Have you been able to investigate the possibility of using pyrochild's CanvasPanel UserControl?

I may want to use it in a future plugin of mine, so I'd be curious of your findings.

 

 

On an unrelated note, please see this post:

https://forums.getpaint.net/index.php?/topic/110458-the-plugin-browser-v1102-updated-dec-30-2016/&do=findComment&comment=525886

Share this post


Link to post
Share on other sites
6 minutes ago, toe_head2001 said:

Have you been able to investigate the possibility of using pyrochild's CanvasPanel UserControl?

I may want to use it in a future plugin of mine, so I'd be curious of your findings

I won't tear the two plugins apart to fuse a canvas for this plugin. They are both well-integrated into the rest of their respective application, so it would be begging for instability if I did that to Brush Factory. I have plans to implement the two things it does that I don't: use the clipboard image and mark the selected area.

 

Quote

I never had enough plugins installed to use or look at that. The use of AssemblyCompany for the author is rather bizarre, but I suppose I can.

Share this post


Link to post
Share on other sites

That was enlightening, BoltBait. Thanks.

 

@toe_head2001 I added myself as a company and changed the functionality of lock alpha so it applies after each stroke instead of at the end of the image, which is a more useful method. I can't lock alpha & copy after every individual brush stroke without doing some crazy size calculations (esp. with a rotated brush) and other things like that, so I think doing it after a brush stroke is better. It might be plausibly useful, now.

Edited by AnthonyScoffler
  • Upvote 1

Share this post


Link to post
Share on other sites

@AnthonyScoffler  I keep my "brushes"in a folder inside the "Pictures folder" and every time I want to  "add a new brush" the browser defaults to the "Desktop" . Can something be done so it will remember the last opened folder when adding brushes?

  • Upvote 1

Share this post


Link to post
Share on other sites

@AnthonyScoffler - these routine saves (and recalls) the last directory path to/from a registry key. These will allow you to solve the inconsistent path issue @Eli is referring to

 

        public static string AuthorName = "Ego Eram Reputo";
        public static string PluginName = "A Brand New Plugin";     

   /// <summary>
        /// Saves the path of the last folder the user navigated to (either load or save). 
        /// Thanks to TechnoRobbo for this and the sister routine getlastFolder()
        /// </summary>
        public static void savelastFolder(string fp)
        {
            RegistryKey key;
            key = Microsoft.Win32.Registry.CurrentUser.CreateSubKey(AuthorName);
            key.SetValue(PluginName, Path.GetDirectoryName(fp));
            key.Close();
        }



        public static string getlastFolder()
        {
            string glF = Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
            // registry key under HKCU is my username. 
            RegistryKey LastFolder = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(AuthorName);

            if (LastFolder != null)
            {
                try
                {
                    // Multiple plugins might use the use the same Key Name - this sets the sub-key specifically for this plugin.
                    glF = (string)LastFolder.GetValue(PluginName);
                    if (!Directory.Exists(glF)) glF = Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
                }
                catch
                {
                    glF = Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
                }
            }
            return glF;
        }


 

  • Upvote 2

Share this post


Link to post
Share on other sites
Quote

 I keep my "brushes" in a folder inside the "Pictures folder" and... can something be done so it will remember the last opened folder when adding brushes?

I was going to add an .ini file to the Effects folder as sort of a workaround, but using the registry is much better. I will add a preferences option under miscellaneous. It will open a little dialog for all that stuff. Rather than just remembering the location to load, I will definitely have auto-loading of locations (I was already planning that :)).

 

Thank you @Ego Eram Reputo for the code. That makes this a lot faster :)

Thanks for the great idea @Eli! I appreciate the feedback, and it helps me organize which issues to tackle next.

 

...I'd also like to thank everybody that gave me positive feedback! I like to know when I'm doing something right ;)

 

Version 1.2 is released and it addresses some of the concerns @toe_head2001 had. User selections are now shown in the canvas, and you can right-click to set the background image if you'd like (courtesy of Pyrochild's open-source Liquify plugin). Keep the feedback coming :D

Edited by AnthonyScoffler
  • Upvote 3

Share this post


Link to post
Share on other sites

@AnthonyScoffler One observation regarding the sliders when I use the keyboard arrows : 

 

- if I use the LEFT keyboard arrow (<) the values decrease. So this is OK.

- It is also OK when I use the RIGHT keyboard arrow (>) The values increase.

 

However, the UP and DOWN arrows confuse me a little :

- if I press the UP arrow I would expect the values to increase but they don't, they decrease

- and if I press DOWN arrow I would expect it to decrease but the values increase instead.

 

Is this behavior OK?

Share this post


Link to post
Share on other sites
3 minutes ago, Eli said:

One observation regarding the sliders when I use the keyboard arrows

That's the standard behavior of a TrackBar in WinForms.

It makes perfect sense when TrackBars are orientated vertically, but that is rarely the case.

Share this post


Link to post
Share on other sites
52 minutes ago, toe_head2001 said:

That's the standard behavior of a TrackBar in WinForms.

It makes perfect sense when TrackBars are orientated vertically, but that is rarely the case.

Thanks toe_head2001, I thought the UP and Down keyboard assignments had been inverted.

Share this post


Link to post
Share on other sites
13 hours ago, AnthonyScoffler said:

Thanks for the great idea

I have one more idea but I do not know if it is great :D.

 

Take for instance this rocket that will travel in space .

brush-rocket-01-5153828.png

 

Look at the first image, when I draw a path using only one stroke around the planets, with Rotate with Mouse activated, the rocket looks like it is a little bit lost in space.  Could an option be added so the tip of the rocket will always head in the right direction as in the second image? 

rocket-space-travel-001-51538ab.png

 

One more thing. I do not know why but some of the rockets are smaller than what they should be.

Edited by Eli
  • Upvote 1

Share this post


Link to post
Share on other sites
7 hours ago, Eli said:

Look at the first image, when I draw a path using only one stroke around the planets, with Rotate with Mouse activated, the rocket looks like it is a little bit lost in space.  Could an option be added so the tip of the rocket will always head in the right direction as in the second image? 

The picture of the spaceship could point in any direction. When you use it as a brush, it could've been upside-down, pointing in a diagonal, etc. The computer doesn't know what direction it points to, so it assumes it points to the right. This is a standard practice with similar algorithms.

 

The fix is easy: go to the first tab and increase Brush Rotation by 90 degrees. It should point to the right when drawn, which means it will work.

You know what's cool? If you mentally rotate the spaceships in the first picture by 90 degrees, you'll have the second picture :)

 

If only that explanation could fit inside the tooltip!

Don't forget to check the tooltip at the bottom, though. It shows information for anything you hover the mouse over.

 

Quote

One more thing. I do not know why but some of the rockets are smaller than what they should be.

I've been fighting it for awhile. I need to resize the image to account for apparent shrinking based on rotation angle.

PucO0yV.png

Width = w·|cos φ| + h·|sin φ|

Height = w·|sin φ| + h·|cos φ|

 

The problem is that rotating the image increases the image dimensions. I'm trying to draw the image with an absolute size. The size can be larger by a factor as large as √2 at 45-degree angles. You probably know that drawing a 1000x1000 pixel image in a 16x16 space makes it look crummy. That's what's going on. Before I rotate, the image might by 100x100 pixels drawn in a 16x16 space. After rotation, it's 140x140 pixels drawn in the same space, which causes it to be visibly smaller.

 

I need to offset the visual decrease in size by increasing the radius of the brush at drawing time. In the past, I'd tried to increase the size of the brush before rotation, which doesn't work because it's drawn in an absolute size. I'll be tackling that again soon. I suspect drawing at (sqrt(2)cosφ, sqrt(2)sinφ) will do it.

Edited by AnthonyScoffler
  • Upvote 1

Share this post


Link to post
Share on other sites
56 minutes ago, AnthonyScoffler said:

The fix is easy: go to the first tab and increase Brush Rotation by 90 degrees. It should point to the right when drawn, which means it will work.

You know what's cool? If you mentally rotate the spaceships in the first picture by 90 degrees, you'll have the second picture :)

Thanks, that is a neat trick to know.

Share this post


Link to post
Share on other sites

Version 1.3 is released.

I fixed a rotation issue where angles close to 45 degrees were visibly smaller as a result of weirdness I described in a post above. Thanks to @Eli for bringing my attention back to that issue.

 

I made a Preferences button under the 'other' tab that opens a little window where you can browse and add folders on your computer that Brush Factory should scour when it starts. The textbox is editable, so you can type any reasonable folder or file path in there. It will handle both of them. The brush location settings are stored permanently.

 

I released it a little early (day after last update) because I start another quarter of college tomorrow, which means I'll focus less on this and more on school. But I'll still visit to see what I can do and what I can work on, so please keep addressing concerns. I'll have to face that alpha issue sometime :D

Edited by AnthonyScoffler
  • Upvote 1

Share this post


Link to post
Share on other sites

@AnthonyScoffler,

 

Sorry to disturb your studies. I managed to make it crash. How did I do it? I loaded a brush and just kept drawing for a very, very long time without releasing the mouse button (two or three minutes). I do not have a computer with lots of memory so I probably did run out of something. I am posting the crash log. 

 

Spoiler

This text file was created because paint.net crashed. Please e-mail this to crashlog4@getpaint.net so we can diagnose and fix the problem.

Application version: paint.net 4.0.13 (Final 4.13.6191.1824)
Time of crash: 1/10/2017 8:35:47 PM
Application uptime: 00:09:21.9266349
Application state: Running
Working set: 100,624 KiB
Handles and threads: 1609 handles, 29 threads, 232 gdi, 273 user
Install directory: C:\Program Files\paint.net
Current directory: C:\Program Files\Paint.NET
OS Version: 10.0.14393.0 Workstation x86
.NET version: CLR 4.0.30319.42000 x86, FX 4.6
Processor: "Intel(R) Core(TM)2 Quad  CPU   Q9550  @ 2.83GHz" @ ~2826MHz (4C/4T, DEP, SSE, SSE2, SSE3, SSSE3, SSE4_1)
Physical memory: 3325 MB
Video card: ATI Radeon HD 2400 XT (v:1002, d:94C1, r:0), Microsoft Basic Render Driver (v:1414, d:8C, r:0)
Hardware acceleration: False (default: True)
UI animations: True
UI DPI: 96.00 dpi (1.00x scale)
UI theme: Aero/Aero + DWM (Aero.msstyles)
Updates: False, 6/27/2016
Locale: pdnr.c: en-US, hklm: en-US, hkcu: en-US, cc: en-US, cuic: en-US
Flags:

Exception details:
System.ArgumentException: Parameter is not valid.
   at System.Drawing.Bitmap..ctor(Int32 width, Int32 height, PixelFormat format)
   at System.Drawing.Bitmap..ctor(Int32 width, Int32 height)
   at BrushFactory.Utils.RotateImage(Bitmap origBmp, Single angle)
   at BrushFactory.winBrushFactory.DrawBrush(Point loc, Int32 radius)
   at BrushFactory.winBrushFactory.displayCanvas_MouseMove(Object sender, MouseEventArgs e)
   at System.Windows.Forms.Control.OnMouseMove(MouseEventArgs e)
   at System.Windows.Forms.Control.WmMouseMove(Message& m)
   at System.Windows.Forms.Control.WndProc(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

Managed assemblies:
    mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 @ C:\Windows\Microsoft.NET\Framework\v4.0.30319\mscorlib.dll
    PaintDotNet, Version=4.13.6191.1824, Culture=neutral, PublicKeyToken=null @ C:\Program Files\Paint.NET\PaintDotNet.exe
    PaintDotNet.Base, Version=4.13.6191.1824, Culture=neutral, PublicKeyToken=null @ C:\Program Files\Paint.NET\PaintDotNet.Base.dll
    WindowsBase, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 @ C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\WindowsBase\v4.0_4.0.0.0__31bf3856ad364e35\WindowsBase.dll
    System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 @ C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Core\v4.0_4.0.0.0__b77a5c561934e089\System.Core.dll
    System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 @ C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System\v4.0_4.0.0.0__b77a5c561934e089\System.dll
    System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a @ C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Drawing\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Drawing.dll
    PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 @ C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\PresentationFramework\v4.0_4.0.0.0__31bf3856ad364e35\PresentationFramework.dll
    PresentationCore, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 @ C:\WINDOWS\Microsoft.Net\assembly\GAC_32\PresentationCore\v4.0_4.0.0.0__31bf3856ad364e35\PresentationCore.dll
    System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 @ C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Windows.Forms\v4.0_4.0.0.0__b77a5c561934e089\System.Windows.Forms.dll
    PaintDotNet.Core, Version=4.13.6191.1824, Culture=neutral, PublicKeyToken=null @ C:\Program Files\Paint.NET\PaintDotNet.Core.dll
    PaintDotNet.SystemLayer, Version=4.13.6191.1824, Culture=neutral, PublicKeyToken=null @ C:\Program Files\Paint.NET\PaintDotNet.SystemLayer.dll
    PaintDotNet.Framework, Version=4.13.6191.1824, Culture=neutral, PublicKeyToken=null @ C:\Program Files\Paint.NET\PaintDotNet.Framework.dll
    PaintDotNet.Resources, Version=4.13.6191.1824, Culture=neutral, PublicKeyToken=null @ C:\Program Files\Paint.NET\PaintDotNet.Resources.dll
    PaintDotNet.Data, Version=4.13.6191.1824, Culture=neutral, PublicKeyToken=null @ C:\Program Files\Paint.NET\PaintDotNet.Data.dll
    PaintDotNet.Effects, Version=4.13.6191.1824, Culture=neutral, PublicKeyToken=null @ C:\Program Files\Paint.NET\PaintDotNet.Effects.dll
    PaintDotNet.SystemLayer.Native.x86, Version=4.13.6191.1824, Culture=neutral, PublicKeyToken=null @ C:\Program Files\Paint.NET\PaintDotNet.SystemLayer.Native.x86.dll
    System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a @ C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Configuration\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Configuration.dll
    System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 @ C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Xml\v4.0_4.0.0.0__b77a5c561934e089\System.Xml.dll
    System.Xaml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 @ C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Xaml\v4.0_4.0.0.0__b77a5c561934e089\System.Xaml.dll

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now