Calculate Object Render Region

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
Old 02 February 2012   #1
Calculate Object Render Region

I want to calculate the Render Region for a group of object, and it needs to be done without using ViewportTM as this is a pre-render script.

I always get confused when working in camera space. Needs to return a box2 value as with regionrender values.

Will attempt to solve it but if anyone has the code to hand or feels like a challenge, feel free to contribute.
__________________
Maxscript Made Easy...
http://davewortley.wordpress.com/
 
Old 02 February 2012   #2
Sorry, are you saying you want to know the coordinates of the object in the viewport's coordinate space without knowing the viewport's coordinate space?
 
Old 02 February 2012   #3
I might be wrong but I don't think this will work the way you want it to for two reasons:
1. I don't think you can change render settings with a pre-render script because Max takes a snapshot of the render settings before the script is run.
2. As lo said, region render uses viewport coordinate space.

However, I tried to do something like this a while back but didn't use it for anything in the end. Sorry it's a bit messy but you're welcome to use any of this if it helps:
try (destroyDialog BBautoRegion) catch ()

rollout BBautoRegion "AutoRegion"
(
	fn bb2rect =
	(
		if $ != undefined then
		(
			renderSceneDialog.close()
			vpSize = getViewSize()
			gw.setTransform(Matrix3 1)
			sel = getCurrentselection() as array
			BBmask = sel[1]
			gwMin = gw.wTransPoint BBmask.center
			gwMax =  gw.wTransPoint BBmask.center
			
			for BBmask in sel do
			(
				objBB = nodeGetBoundingBox BBmask (Matrix3 1) --get selection BB in worldspace co-ordsys
				for zi = 1 to 2 do
				(
					for yi = 1 to 2 do
					(
						for xi = 1 to 2 do
						(
							gw.setTransform(Matrix3 1)
							wsPt = point3 obJBB[xi][1] objBB[yi][2] objBB[zi][3]
							gwPnt = gw.wTransPoint wsPt
							
							if (gwPnt.x < gwMin.x) then
							(
								if (gwPnt.x > 0) then (gwMin.x = gwPnt.x) else (gwMin.x = 0) --set gwMin.x
							)
							if (gwPnt.y < gwMin.y) then
							(
								if (gwPnt.y > 0) then (gwMin.y = gwPnt.y) else (gwMin.y = 0) --set gwMin.y
							)
							if (gwPnt.x > gwMax.x) then
							(
								if (gwPnt.x < vpSize.x) then (gwMax.x = gwPnt.x) else (gwMax.x = vpSize.x) --set gwMax.x
							)
							if (gwPnt.y > gwMax.y) then
							(
								if (gwPnt.y < vpSize.y) then (gwMax.y = gwPnt.y) else (gwMax.y = vpSize.y) --set gwMax.x
							)
						) --end x loop
					) --end y loop
				)--end z loop
			)--end o loop
			
			if getRendImageAspect() < (vpSize.x/vpSize.y) then
			(
				roScale = (renderHeight/vpSize.y)
				roPad = ((vpSize.x*roScale)-(renderWidth))/2
				roRegion = box2 (point2 ((gwMin.x*roScale)-roPad) (gwMin.y*roScale)) (point2 ((gwMax.x*roScale)-roPad) (gwMax.y*roScale))
			)
			else
			(
				roScale = (renderWidth/vpSize.x)
				roPad = ((vpSize.y*roScale)-(renderHeight))/2
				roRegion = box2 (point2 (gwMin.x*roScale) ((gwMin.y*roScale)-roPad)) (point2 (gwMax.x*roScale) ((gwMax.y*roScale)-roPad))
			)
			
			EditRenderRegion.IsEditable = true
			if viewport.activeViewport != 0 then viewport.setRegionRect viewport.activeViewport roRegion
			EditRenderRegion.UpdateRegion()
			setRenderType #region
			renderSceneDialog.open() --need test for previous state
			displaySafeFrames  = true --need test for previous state
		)
	)--end fn bb2rect
	
	fn autobb2rect ev nd =
	(
		registerRedrawViewsCallback bb2rect
		redrawViews()
		unregisterRedrawViewsCallback bb2rect
		redrawViews()
	)
	
	local sfState
	
	on BBautoRegion open do
	(
		sfState = displaySafeFrames
		displaySafeFrames = true
		unregisterRedrawViewsCallback bb2rect
	)
	
	on BBautoRegion close do
	(
		displaySafeFrames = BBautoRegion.sfState
		unregisterRedrawViewsCallback bb2rect
	)

	button setRegion "Set Region" pos:[5,10]
	checkButton autoRegion "Auto Region" pos:[80,10]

		on setRegion pressed do
		(
			if selection.count == 1 then
			(
				autobb2rect 1 1
			)
		)
		
		on autoRegion changed state do
		(
			if state == true then
			(
				autobb2rect 1 1
				selChanged = NodeEventCallback mouseUp:true selectionChanged:autobb2rect all:autobb2rect
			)
			else
			(
				selChanged = undefined
				gc light:true
			)
		)
	)--end rollout
createDialog BBautoRegion

Select a perspective or camera viewport and run the script and press the 'auto region' button. Select one or more objects and the region render box will automatically fit to anything your selection.

Dan
 
Old 02 February 2012   #4
Thanks Dan, I'm going to pass these point2 value to Deadline so it's not really a pre-render script, as it'll be set before submission, but needs to be automatic.

I'll test it in a bit and see how I get on... Cheers..

Dave
__________________
Maxscript Made Easy...
http://davewortley.wordpress.com/
 
Old 02 February 2012   #5
It works, but a) is really really slow and b) if the object goes off the edge of the Frame the region is rendering into negative space, which causes issues when rendering.

I'll have a look at it and see what I can do, cheers for the base though
__________________
Maxscript Made Easy...
http://davewortley.wordpress.com/
 
Old 02 February 2012   #6
Yes it is slow. Like I said, it was never really finished or used for anything. I thought it did clip the region to the viewport if the object went off the frame though.
 
Old 02 February 2012   #7
fn bb2rect =
	(
		if $ != undefined then
		(
			renderSceneDialog.close()
			vpSize = getViewSize()
			gw.setTransform(Matrix3 1)
			sel = getCurrentselection() as array
			BBmask = sel[1]
			gwMin = gw.wTransPoint BBmask.center
			gwMax =  gw.wTransPoint BBmask.center
			
			for BBmask in sel do
			(
				objBB = nodeGetBoundingBox BBmask (Matrix3 1) --get selection BB in worldspace co-ordsys
				for zi = 1 to 2 do
				(
					for yi = 1 to 2 do
					(
						for xi = 1 to 2 do
						(
							gw.setTransform(Matrix3 1)
							wsPt = point3 obJBB[xi][1] objBB[yi][2] objBB[zi][3]
							gwPnt = gw.wTransPoint wsPt
							
							if (gwPnt.x < gwMin.x) then
							(
								if (gwPnt.x > 0) then (gwMin.x = gwPnt.x) else (gwMin.x = 0) --set gwMin.x
							)
							if (gwPnt.y < gwMin.y) then
							(
								if (gwPnt.y > 0) then (gwMin.y = gwPnt.y) else (gwMin.y = 0) --set gwMin.y
							)
							if (gwPnt.x > gwMax.x) then
							(
								if (gwPnt.x < vpSize.x) then (gwMax.x = gwPnt.x) else (gwMax.x = vpSize.x) --set gwMax.x
							)
							if (gwPnt.y > gwMax.y) then
							(
								if (gwPnt.y < vpSize.y) then (gwMax.y = gwPnt.y) else (gwMax.y = vpSize.y) --set gwMax.x
							)
						) --end x loop
					) --end y loop
				)--end z loop
			)--end o loop
			global roRegion
			if getRendImageAspect() < (vpSize.x/vpSize.y) then
			(
				roScale = (renderHeight/vpSize.y)
				roPad = ((vpSize.x*roScale)-(renderWidth))/2
				roRegion = box2 (point2 ((gwMin.x*roScale)-roPad) (gwMin.y*roScale)) (point2 ((gwMax.x*roScale)-roPad) (gwMax.y*roScale))
			)
			else
			(
				roScale = (renderWidth/vpSize.x)
				roPad = ((vpSize.y*roScale)-(renderHeight))/2
				roRegion = box2 (point2 (gwMin.x*roScale) ((gwMin.y*roScale)-roPad)) (point2 (gwMax.x*roScale) ((gwMax.y*roScale)-roPad))
			)
			
			if roRegion.x < 0 then (roRegion.w += roRegion.x; roRegion.x = 0)
			if roRegion.y < 0 then (roRegion.h += roRegion.y; roRegion.y = 0)
			if roRegion.w + roRegion.x > Renderwidth then roRegion.w = Renderwidth - roRegion.x
			if roRegion.h + roRegion.y > RenderHeight then roRegion.h = RenderHeight - roRegion.y
			
			EditRenderRegion.IsEditable = true
			if viewport.activeViewport != 0 then viewport.setRegionRect viewport.activeViewport roRegion
			EditRenderRegion.UpdateRegion()
			setRenderType #region
			renderSceneDialog.open() --need test for previous state
			displaySafeFrames  = true --need test for previous state
		)
	)--end fn bb2rect


Updated it to fix the values if they're outside of the range.

I've got to have a re-think for how this is going to work... I thought I could pass the values to Deadline, but as the scene builds itself on the render slave I won't know what the area will before I kick it off... hhmmmm....
__________________
Maxscript Made Easy...
http://davewortley.wordpress.com/
 
Old 02 February 2012   #8
You could always send the script to deadline as a postLoad script. That way it will set the region for the chosen objects before it starts rendering.

Postload scripts allow layers and objects to be hidden and unhidden, materials to be changed and a few other things. Prerender is very restrictive and won't allow any of the previous things mentioned to be changed.
 
Old 10 October 2012   #9
Hmmm...I wonder where you got that idea from Tim! :-)
 
Old 10 October 2012   #10
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.
 
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 07:23 AM.


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