Viewport Capture

Become a member of the CGSociety

Connect, Share, and Learn with our Large Growing CG Art Community. It's Free!

THREAD CLOSED
 
Thread Tools Search this Thread Display Modes
  06 June 2013
Viewport Capture

Hi,
Based on previous threads and code examples such as:
http://forums.cgsociety.org/showthr...44&page=1&pp=15
I have 2 issues with viewport capturing in 3dsMax:

1. ForcecompleteRedraw() or completeRedraw() sometimes randomly crashes the code below
2. .NET memory is not freed even though this struct is instantiated each time its used. I have to exit 3dsMax to free the memory.

Any ideas?

		fn ResizeViewport width height=
		(
			compensation = 4
			ViewportHwnd = for w in (windows.getChildrenHWND #max) where w[4] == "ViewPanel" do exit with w[1]
			
			source = "using System;\n"
			source += "using System.Runtime.InteropServices;\n"
			source += "using System.Text;\n"
			source += "class assembly\n"
			source += "{\n"
			source += " [DllImport(\"user32.dll\")]\n"
			source += " public static extern bool SetWindowPos(IntPtr hWnd, int hWndArg, int Left, int Top, int Width, int Height, int hWndFlags);\n"
			source += " [DllImport(\"user32.dll\")]\n"
			source += "	static extern bool GetWindowRect(IntPtr hWnd, out RECT rect);\n"
			source += "	public struct RECT\n"
			source += "	{\n"
			source += "	 public int Left;\n"
			source += "	 public int Top;\n"
			source += "	 public int Right;\n"
			source += "	 public int Bottom;\n"
			source += "	}\n"
			source += "	public int[] getWindowRect(IntPtr hWnd)\n"
			source += "	{\n"
			source += "	 RECT rect;\n"
			source += "	 if ( GetWindowRect(hWnd, out rect) )\n"
			source += "	 {\n"
			source += "	 return new int[] { rect.Left, rect.Top, rect.Right - rect.Left, rect.Bottom - rect.Top };\n"
			source += "	 }\n"
			source += "	 return null;\n"
			source += "	}\n"
			source += "}\n"
			
			csharpProvider = dotnetobject "Microsoft.CSharp.CSharpCodeProvider"
			compilerParams = dotnetobject "System.CodeDom.Compiler.CompilerParameters"
			compilerParams.GenerateInMemory = on
			compilerResults = csharpProvider.CompileAssemblyFromSource compilerParams #(source)
			assembly = compilerResults.CompiledAssembly.createInstance "assembly"
			assembly.setwindowpos (dotNetObject "System.IntPtr" ViewportHwnd) 0 0 0 (width+compensation) (height+compensation) 0x0026
			ForcecompleteRedraw()
		)
 
  06 June 2013
Hi Mike,

What is it you are trying to do with this code, get a viewport thumbnail?
__________________
Regards,
Pete

Read my technical blog - lonerobot.net
 
  06 June 2013
Hi Pete,
Screen grab but at a high resolution, so after scaling down, the image looks good at something like 1024 768. Thumbnail size is no good for my needs, so I can't take a different route such as .Net rip the file thumbnail.
Mike
 
  06 June 2013
Cant you just use max tool maximize and then grab the viewport resize the image and restore viewport layouts?
__________________
Artur Leao | Co-Founder / Project Manager
You can do it! VFX
Porto/Lisbon - Portugal
http://www.ycdivfx.com
 
  06 June 2013
That's how I'd do it, but maybe Mike needs a capture bigger than HD?
__________________
Regards,
Pete

Read my technical blog - lonerobot.net
 
  06 June 2013
Yeah, I thought about it too, and I guess he needs to capture a res higher the one setup for the display, from what I understood.

Another quick "hack" would just use quicksilver to render the thumbnail in whatever resolution you need.
__________________
Artur Leao | Co-Founder / Project Manager
You can do it! VFX
Porto/Lisbon - Portugal
http://www.ycdivfx.com
 
  06 June 2013
Thanks guys. Higher res is indeed the challenge here.

Anyway, after lots of testing by a colleague of mine + combined with a bit of a random thought/head scratching and it would seem that changing the 3dsMax graphics driver to OpenGL has now stabilised the code. I have a sneaking suspicion that the Direct3D driver and its directX caching of textures/viewport was causing an issue when it came to a forced refresh.

We have some more testing to carry out, but at least we think we are on the right tracks to squashing this bug now.

Sorry, I should add, that we still haven't got to the bottom of why .NET memory isn't purged when the struct is thrown away. [insert another sarcastic reason why I love 3dsMax/mxs]

Thanks again for your comments.
Mike

Last edited by MikeOwen : 06 June 2013 at 10:36 PM.
 
  06 June 2013
Hey Mike. Hope all is well!

Have you tried disposing all the dotNet objects in the struct, undefining it, and then running a garbage collection?

gc() or gc light:true

Hopefully that should clear some memory.

Last edited by TimHawker : 06 June 2013 at 07:16 AM.
 
  06 June 2013
Hi Tim,
Yep, tried both these options and all .Net objects are also disposed off prior to this as well. So, at the moment, it looks like a combo of graphics driver in 3dsMax and a later .NET function which resize's the screen-grabs is causing the issue. We are running more tests today...
Thanks,
Mike
 
  06 June 2013
Originally Posted by MikeOwen: Hi,
Based on previous threads and code examples such as:
http://forums.cgsociety.org/showthr...44&page=1&pp=15
I have 2 issues with viewport capturing in 3dsMax:

1. ForcecompleteRedraw() or completeRedraw() sometimes randomly crashes the code below
2. .NET memory is not freed even though this struct is instantiated each time its used. I have to exit 3dsMax to free the memory.

Any ideas?

		fn ResizeViewport width height=
  		(
  			compensation = 4
  			ViewportHwnd = for w in (windows.getChildrenHWND #max) where w[4] == "ViewPanel" do exit with w[1]
  			
  			source = "using System;\n"
  			source += "using System.Runtime.InteropServices;\n"
  			source += "using System.Text;\n"
  			source += "class assembly\n"
  			source += "{\n"
  			source += " [DllImport(\"user32.dll\")]\n"
  			source += " public static extern bool SetWindowPos(IntPtr hWnd, int hWndArg, int Left, int Top, int Width, int Height, int hWndFlags);\n"
  			source += " [DllImport(\"user32.dll\")]\n"
  			source += "	static extern bool GetWindowRect(IntPtr hWnd, out RECT rect);\n"
  			source += "	public struct RECT\n"
  			source += "	{\n"
  			source += "	 public int Left;\n"
  			source += "	 public int Top;\n"
  			source += "	 public int Right;\n"
  			source += "	 public int Bottom;\n"
  			source += "	}\n"
  			source += "	public int[] getWindowRect(IntPtr hWnd)\n"
  			source += "	{\n"
  			source += "	 RECT rect;\n"
  			source += "	 if ( GetWindowRect(hWnd, out rect) )\n"
  			source += "	 {\n"
  			source += "	 return new int[] { rect.Left, rect.Top, rect.Right - rect.Left, rect.Bottom - rect.Top };\n"
  			source += "	 }\n"
  			source += "	 return null;\n"
  			source += "	}\n"
  			source += "}\n"
  			
  			csharpProvider = dotnetobject "Microsoft.CSharp.CSharpCodeProvider"
  			compilerParams = dotnetobject "System.CodeDom.Compiler.CompilerParameters"
  			compilerParams.GenerateInMemory = on
  			compilerResults = csharpProvider.CompileAssemblyFromSource compilerParams #(source)
  			assembly = compilerResults.CompiledAssembly.createInstance "assembly"
  			assembly.setwindowpos (dotNetObject "System.IntPtr" ViewportHwnd) 0 0 0 (width+compensation) (height+compensation) 0x0026
  			ForcecompleteRedraw()
  		)


first of all you shouldn't create a new assembly every time you resizing viewport... it will save the memory
second you have to return viewpanel in normal size ... and it helps to protect the max from a crash
see my post http://forums.cgsociety.org/showpos...99&postcount=10
 
  06 June 2013
Post

Originally Posted by TimHawker: Hey Mike. Hope all is well!

Have you tried disposing all the dotNet objects in the struct, undefining it, and then running a garbage collection?

gc() or gc light:true

Hopefully that should clear some memory.


You can also tell the dotNet system to do its own specific clear-up, this might do the trick:

gc light:true
(dotnetClass "System.GC").Collect()


If that doesn't do the trick, this might?

gc light:true
(dotnetClass "System.GC").Collect()
(dotnetClass "System.GC").WaitForPendingFinalizers()
(dotnetClass "System.GC").Collect()
 
  06 June 2013
Thread automatically closed

This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.
__________________
CGTalk Policy/Legalities
Note that as CGTalk Members, you agree to the terms and conditions of using this website.
 
Thread Closed share thread



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
CGSociety
Society of Digital Artists
www.cgsociety.org

Powered by vBulletin
Copyright 2000 - 2006,
Jelsoft Enterprises Ltd.
Minimize Ads
Forum Jump
Miscellaneous

All times are GMT. The time now is 03:59 AM.


Powered by vBulletin
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.