Render outputSize that fit the object

Hi man! :)

How do I set the width and height measurements in rendering (setup) that fit a selected object in the top view?

Situation:

I have an object
I create a freecamera in Top Viewport
Renders the camera
The image (vfb) must correspond to an BoundigBox surrounding object

For the first three steps and dummy box are successful, but the last I do not understand how to do...

Do you have any suggestions?

Ciao
Michele

Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
Graph's picture

ok i had an hour to kill so i

ok i had an hour to kill so i thought why not improve the code and document it.. reason being that i so far havent seen one working approach to scripted baking on any forum

if selection.count > 0 do
(
 
	fn addBP obj =
	(
		with undo false
		(
			local oldTM = obj.transform --store the original transformation
			obj.transform *= inverse obj.transform  --transform back into identity matrix
			local size = obj.max - obj.min 
 
			local bb=plane width:size.x length:size.y lengthsegs:1 widthsegs:1 name:(obj.name + "_bp") mapCoords:true realWorldMapSize:false
 
			obj.transform = oldTM  --return back to original transformation
			bb.transform = obj.transform --set rotation and scale of the bbox to match object
			bb.center=obj.center  --center bbox
			bb.pos.z = obj.min.z
		)
		return #(bb, size)
	)
 
	fn resizeBMP file tSize filter:false =	
	(
		with undo false
		(
			if doesFileExist file do
			(
				local tBMP = bitmaptex filename:file 
 
				local bmp = bitmap tSize.x tSize.y
 
				renderMap tBMP into:bmp size:[bmp.width, bmp.height] filter:filter display:false
 
				tBMP = tSize = factor = undefined
			)
			return bmp
		)
	)
 
	fn makeHeightmap objs baseFileName AA:0 =	--main baking function obj:needs a nodeArray to bake, baseFileName:needs a fileName to extent by obj name-s for the baked files, AA: needs an integer 0 1 or 2 ; 0 is no filtering wich is fast and 2 is full filtering wich is slower
	(
		with undo false	--no need to undo this stuff so to make it faster disable undo buffer
		(
			for obj in objs while baseFileName != undefined where isValidNode obj do	--loop through the supplied nodeArray as long as the baseFileName is not undefined --saves an extra if statement and also make sure the current obj is valid
			(
				max create mode	--switch to create mode --faster
 
				local fileName = getfilenamepath baseFileName + getFilenameFile baseFileName + "_" + obj.name + getFilenameType baseFileName	--create the fileName per object based on the baseFileName and obj.name
				local oldRender = renderers.current ; renderers.current  = Default_Scanline_Renderer()	--save the old renderer to var and assign scanline to render faster --for 2011 id suggest quicksilver over scanline
				local oldMat = obj.material ; obj.material = standardmaterial()	--save the obj's material to var and assign standard mat so it works fine with any renderer
 
				local temp = (addBP obj)	--create the baking plane below the obj --function returns the plane and the boxSize of the obj
				local bakingGeo = temp[1] ; select bakingGeo	--make new ref to the plane and select it
				local bmpSize = if bakingGeo.width > bakingGeo.length then bakingGeo.width else bakingGeo.length	--check if its wider than high and set square size accordingly 
 
				max modify mode	--switch to modify mode so the cage can update
 
				local projMod = Projection()	--create a projection mod
				addmodifier bakingGeo projMod	--add the mod to the plane
				projMod.addObjectNode obj	--add  the obj to the mod
				projMod.autowrapCage()	--and update the cage
				projMod.autoWrapAlwaysUpdate = true	--just to be on the save side enable option to always update
 
				max create mode	--and back to the faster create mode
 
				local bi = bakingGeo.INodeBakeProperties	--add some baking props to the plane
					bi.bakeChannel=1	--set map channel used to 1
					bi.bakeEnabled = true	--enable it 
 
				local bp = bakingGeo.INodeBakeProjProperties	--add some projection properties to the plane
					bp.enabled = true	--enable projection
					bp.projectionMod = projMod	--add the proj/cage mod 
					bp.BakeSubObjLevels = true	--make it use sub object levels
					bp.useCage = true	--make it use a cage
					bp.hitResolveMode = #closest	--set hit mode to closest
					bp.hitWorkingModel = true	--make use of the plane too so we got a 'floor'
					bp.heightMapMax = temp[2][3]	--set the max height to the relative height of the obj --important
					bp.heightMapMin = 0	--set min height to the 'floor' --after all its a flat plane
 
				local currentMapType = HeightMap()	--create a heightmap bake element
				(
					currentMapType.outputSzX=bmpSize ; currentMapType.outputSzY=bmpSize	--set width and height of the map
 					currentMapType.fileType= getFilenameType fileName	--set the fileType 
					currentMapType.filterOn = case AA of (0 : false ; 1 : false ; 2 : true)	--and en/disable filtering based on AA setting 
 
					bi.addBakeElement currentMapType	--now add the new heightmap to bake to the bake props
 
					render rendertype:#bakeSelected outputwidth:bmpSize outputheight:bmpSize progressbar:true vfb:false	--render/bake the selected plane with the squaresize previously defined, show progress but no vfb
					local newBMP = currentMapType.bitmap	--heres the trick, get the bitmap out of the bake element :P
 
					if newBMP != undefined do	--check if the bake wasnt aborted
					(
						newBMP.fileName = fileName	--assign the defined fileName to the bitmap
						save newBMP	--save it
						newBMP = resizeBMP fileName [temp[2][1], temp[2][2]] filter:(if AA != 0 then true else false)	--now resize it with the function at the top and the given filtering option
						newBMP.fileName = fileName	--assign the same fileName to the bitmap
						save newBMP	--and save again
					)
					newBMP = undefined	--to give the gc something to work with and make sure you dont fill up the ram make the map undefined
				)
 
				delete bakingGeo	--delete the bakingPlane
				obj.material = oldMat	--reAssign the old mat to the obj
				renderers.current  = oldRender	--and the old renderer
				--next loop
			)
		)
	)
 
	-----------------------------------------------------------------------------------------
	-----------------------------------------------------------------------------------------	
 
	local bFileName = getSaveFileName types:"JPEG File(*.jpg)|*.jpg|Tiff Image File(*.tif)|*.tif|Targa Image File(*.tga)|*.tga|PNG Image File(*.png)|*.png|BMP Image File(*.bmp)|*.bmp|"	--get a base-FileName to work with later on
 
	local sel = (selection as array)	--save the current selection to a fixed array --important or you might end up baking planes to planes
 
	makeHeightmap sel bFileName AA:1	--call the baking function
 
	select sel	--reSelect the old selection
 
)--END

its not verry dynamic but i think with the comments anyOne can fit it to their needs

its still using a cage not a ray offset value but i bet ill be bored again the next few days so look forward to another improvement, still unsure on how to get the projection going without the mod.. but well see

Raphael Steves

Michele71's picture

Thank you again for taking

Thank you again for taking the time and patience for my problem :)
You have been extremely useful and very clear :) :) I hope to learn something more from your help ;)

Grazie
Michele

Michele71's picture

Thanks again for your clear

Thanks again for your clear and precise explanations Insanto! :)

Graph's picture

the size is always the max x

the size is always the max x or y depending on whats bigger, the only thing is that its squared.. i know there is a solution but oh well .. at the verry least you could rendermap resize it with filtering on should be ok

your approach is valid too but it doesnt work with objects using real world map coords thats why i used this way. and its the same speed to render. (mine doesnt use lighting but needs to resize the map at the end (new code))
there are always many solutions to 1 problem, like my hacky one to the aspect issue :P
you could've tried to solve it propperly but i already know that if you dont switch to scanline and bake with MR you cant solve it so rendermap it is, have phun

if selection.count > 0 do
(
	local sel = selection as array
 
	local baseFileName = getSaveFileName types:"JPEG File(*.jpg)|*.jpg|Tiff Image File(*.tif)|*.tif|Targa Image File(*.tga)|*.tga|PNG Image File(*.png)|*.png|BMP Image File(*.bmp)|*.bmp|"
	-----------------------------------------------------------------------------------------
	-----------------------------------------------------------------------------------------
	fn addBP obj =
	(
		with undo off
		(
			local oldTM = obj.transform --store the original transformation
			obj.transform *= inverse obj.transform  --transform back into identity matrix
			local size = obj.max - obj.min 
 
			local bb=plane width:size.x length:size.y lengthsegs:1 widthsegs:1 name:(obj.name + "_bp") mapCoords:true realWorldMapSize:false
 
			obj.transform = oldTM  --return back to original transformation
			bb.transform = obj.transform --set rotation and scale of the bbox to match object
			bb.center=obj.center  --center bbox
			bb.pos.z = 0
			bb.xray=true
			bb.wireColor = obj.wirecolor
		)
		return #(bb, size)
	)
 
	fn resizeBMP file tSize =
	(
		if doesFileExist file do
		(
			local tBMP = bitmaptex filename:file 
 
			local bmp = bitmap tSize.x tSize.y
 
			renderMap tBMP into:bmp size:[bmp.width, bmp.height] filter:false display:false		--to reduce AA enable filtering here
 
			tBMP = tSize = factor = undefined
		)
		return bmp
	)
 
	for obj in sel while baseFileName != undefined where isValidNode obj do
	(
		max create mode
 
		local fileName = getfilenamepath baseFileName + getFilenameFile baseFileName + "_" + obj.name + getFilenameType baseFileName
 
		local temp = (addBP obj)
		local bakingGeo = temp[1]
		local bmpSize = if bakingGeo.width > bakingGeo.length then [bakingGeo.width, bakingGeo.width] else [bakingGeo.length, bakingGeo.length]	--fuck around with this to change the given bmp size
		bakingGeo.pos.z = obj.min.z
		select bakingGeo
 
		local oldMat = obj.material
		obj.material = standardmaterial()
 
		max modify mode
 
		local projMod = Projection()
		addmodifier bakingGeo projMod
		projMod.addObjectNode obj
		projMod.autowrapCage()
		projMod.autoWrapAlwaysUpdate = true
 
		completeRedraw()
 
		local oldRender = renderers.current 
		renderers.current  = Default_Scanline_Renderer()
 
		local fPath=getFilenamePath fileName
		local fName=getFilenameFile fileName
		local fType = getFilenameType fileName
		local bi = bakingGeo.INodeBakeProperties
		local bp = bakingGeo.INodeBakeProjProperties
 
		bp.enabled = true
		bp.projectionMod = projMod
		bp.BakeSubObjLevels = true
 
		bp.useCage = true
		bp.hitResolveMode = #closest
 
		bp.hitWorkingModel = true
 
		bp.heightMapMax = temp[2][3]
 
		bi.bakeChannel=1
		bi.bakeEnabled = true
 
		local currentMapType = HeightMap()
		(
			currentMapType.autoSzOn = false
			currentMapType.outputSzX=bmpSize[1]
			currentMapType.outputSzY=bmpSize[2]
			currentMapType.filename=fName
			currentMapType.fileType=fType
			currentMapType.targetMapSlotName = "none"
			currentMapType.filterOn = false
 
			bi.addBakeElement currentMapType
 
			render rendertype:#bakeSelected outputSize:bmpSize outputwidth:bmpSize[1] outputheight:bmpSize[2] progressbar:true /*outputfile:newfileName*/ vfb:false
			local newBMP = currentMapType.bitmap
			if newBMP != undefined do
			(
				newBMP.fileName = fileName --(FPath + FName + FType)
				save newBMP
				newBMP = resizeBMP fileName [temp[2][1], temp[2][2]]
				newBMP.fileName = fileName
				save newBMP
			)
			newBMP = undefined
		)
		bi.removeAllBakeElements()
		bi.bakeEnabled = false
 
		renderers.current  = oldRender
 
		clearSelection()
 
		delete bakingGeo
		obj.material = oldMat
	)
)--END Bake

Raphael Steves

Michele71's picture

Wow! is completely different

Wow! is completely different from what I imagined! It works great and now, I study your solution (very interesting)...

It would be wonderful to determine the size of the bitmap :) Now I see how can proceed.

My solution script for heightmap is not valid? What do you think?

Thank you enormously for the response, resolution and patience you had with me

Best Regards
Michele

Graph's picture

its a scope issue, you didnt

its a scope issue, you didnt define d as local higher up than the for loop.. so when the loop ends d ref is gone

aanyways, heres my approach to this:

if selection.count > 0 do
(
	local sel = selection as array
 
	local baseFileName = getSaveFileName types:"JPEG File(*.jpg)|*.jpg|Tiff Image File(*.tif)|*.tif|Targa Image File(*.tga)|*.tga|PNG Image File(*.png)|*.png|BMP Image File(*.bmp)|*.bmp|"
	-----------------------------------------------------------------------------------------
	-----------------------------------------------------------------------------------------
	fn addBP obj =
	(
		with undo off
		(
			local oldTM = obj.transform --store the original transformation
			obj.transform *= inverse obj.transform  --transform back into identity matrix
			local size = obj.max - obj.min 
 
			local bb=plane width:size.x length:size.y lengthsegs:1 widthsegs:1 name:(obj.name + "_bp") mapCoords:true realWorldMapSize:false
 
			obj.transform = oldTM  --return back to original transformation
			bb.transform = obj.transform --set rotation and scale of the bbox to match object
			bb.center=obj.center  --center bbox
			bb.pos.z = 0
			bb.xray=true
			bb.wireColor = obj.wirecolor
		)
		return #(bb, size)
	)
 
	for obj in sel while baseFileName != undefined where isValidNode obj do
	(
		max create mode
 
		local fileName = getfilenamepath baseFileName + getFilenameFile baseFileName + "_" + obj.name + getFilenameType baseFileName
 
		local temp = (addBP obj)
		local bakingGeo = temp[1]
		local bmpSize = if bakingGeo.width > bakingGeo.length then [bakingGeo.width, bakingGeo.width] else [bakingGeo.length, bakingGeo.length]	--fuck around with this to change the given bmp size
		bakingGeo.pos.z = obj.min.z
		select bakingGeo
 
		local oldMat = obj.material
		obj.material = standardmaterial()
 
		max modify mode
 
		local projMod = Projection()
		addmodifier bakingGeo projMod
		projMod.addObjectNode obj
		projMod.autowrapCage()
		projMod.autoWrapAlwaysUpdate = true
 
		completeRedraw()
 
		local oldRender = renderers.current 
		renderers.current  = Default_Scanline_Renderer()
 
		local fPath=getFilenamePath fileName
		local fName=getFilenameFile fileName
		local fType = getFilenameType fileName
		local bi = bakingGeo.INodeBakeProperties
		local bp = bakingGeo.INodeBakeProjProperties
 
		bp.enabled = true
		bp.projectionMod = projMod
		bp.BakeSubObjLevels = true
 
		bp.useCage = true
		bp.hitResolveMode = #closest
 
		bp.hitWorkingModel = true
 
		bp.heightMapMax = temp[2][3]
 
		bi.bakeChannel=1
		bi.bakeEnabled = true
 
		local currentMapType = HeightMap()
		(
			currentMapType.autoSzOn = false
			currentMapType.outputSzX=bmpSize[1]
			currentMapType.outputSzY=bmpSize[2]
			currentMapType.filename=fName
			currentMapType.fileType=fType
			currentMapType.targetMapSlotName = "none"
			currentMapType.filterOn = false
 
			bi.addBakeElement currentMapType
 
			render rendertype:#bakeSelected outputSize:bmpSize outputwidth:bmpSize[1] outputheight:bmpSize[2] progressbar:true /*outputfile:newfileName*/ vfb:false
			local newBMP = currentMapType.bitmap
			if newBMP != undefined do
			(
				newBMP.fileName = (FPath + FName + FType)
				save newBMP
			)
			newBMP = undefined
		)
		bi.removeAllBakeElements()
		bi.bakeEnabled = false
 
		renderers.current  = oldRender
 
		clearSelection()
 
		delete bakingGeo
		obj.material = oldMat
	)
)--END Bake

its got that nasty habbit of keeping a 1:1 aspect ratio.. i knew the answer to that prob a while back but forgot it again ;) your a smart gal, youll figure it out
have phun

Raphael Steves

Graph's picture

?yes it is?but you know that

?yes it is?
but you know that d is undefined in your code right?

Global ca
 
rollout ch "Create Quick HeightMap"
(
	button cm "Create HeightMap"
 
 
	on cm pressed do
	(
		if $ != undefined then
		(
			NewObj = snapshot $
			hide $
			select NewObj
			NewObj.material = StandardMaterial color:(color 150 150 150) Glossiness:0.0 specularLevel:0.0 adTextureLock:true adLock:true showInViewport:true		
			NewObj.material.diffuseMap = Gradient_Ramp()
			NewObj.material.diffuseMap.coordinates.W_Angle = -90
			addModifier NewObj (Uvwmap axis:1)
			collapseStack NewObj
			Sky_Light = Skylight()
 
			local d 
			--- Part taken from "Translated Bounding Box" v.0.2 [2009-12-20] by Anubis
			for i in selection do with undo off 
			(
				c = snapshot i
				c.transform = matrix3 1
				d = dummy boxsize:(c.max - c.min)
				delete c
				d.transform = i.transform
				d.pos = i.center
				d.name = "Dummy_Box"
			)
			--------------------------------------------------------------------
 
			c = freecamera ()
			c.name = "CameraTest"
			c.pos = [d.pos.x, d.pos.y, d.pos.z+200]
 
			ca = render camera:$CameraTest outputSize:d.boxsize 
 
 
		)
		else messagebox "Select Object!" 
	)
 
)
createdialog ch

imo you really should propperly define your scopes and make the code a little neater

what you wanna do is create heightmaps for all objects in the scene?
hang on a sec ill whip something up

Raphael Steves

Michele71's picture

This script is a work in

This script is a work in progress this is the reason why it is so messy in the development...

The heightmap must be only for the object selected.

Why d (dummy) is undefined? it is defined when I create dummy or not?

Graph's picture

why not make a bbplane below

why not make a bbplane below the scene and bake your stuff to it?!

can you upLoad or send me a sample maxScene to clarify and tell what you want as a result?

Raphael Steves

Michele71's picture

Ok,try this: Create a Teapot

Ok,try this: Create a Teapot in any viewport and run the script_test below (still under construction):

Global ca
 
rollout ch "Create Quick HeightMap"
(
	button cm "Create HeightMap"
 
 
	on cm pressed do
	(
		if $ != undefined then
		(
		NewObj = snapshot $
		hide $
		select NewObj
		NewObj.material = StandardMaterial color:(color 150 150 150) Glossiness:0.0 specularLevel:0.0 adTextureLock:true adLock:true showInViewport:true		
		NewObj.material.diffuseMap = Gradient_Ramp()
		NewObj.material.diffuseMap.coordinates.W_Angle = -90
		addModifier NewObj (Uvwmap axis:1)
		collapseStack NewObj
		Sky_Light = Skylight()
 
--- Part taken from "Translated Bounding Box" v.0.2 [2009-12-20] by Anubis
for i in selection do with undo off (
				c = snapshot i
				c.transform = matrix3 1
				d = dummy boxsize:(c.max - c.min)
				delete c
				d.transform = i.transform
				d.pos = i.center
				d.name = "Dummy_Box"
			)
--------------------------------------------------------------------
 
c = freecamera ()
c.name = "CameraTest"
c.pos = [d.pos.x, d.pos.y, d.pos.z+200]
 
ca = render camera:$CameraTest outputSize:d.boxsize 
 
 
)
 
 
		else messagebox "Select Object!" 
		)
 
)
createdialog ch

As you can see, the measure (outputSize) of final rendering (Top) IS NOT EQUAL to measure of BoundingBox... For example, if BoundingBox measure 30X30 (Width/Heigth), the outputSize of renderig must be 30x30

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.