[Closed] Possible to automate the creation of 1000s of objects?
Hey guys,
Firstly I’m not looking for scripting at first, I’m just after some advice on whether what I have in mind is possible or not, and the best methods to use.
What I need to figure out is how would be the best way to create 1000s of variations of photos in different sizes and frame styles.
Let me explain further, each photo in a library can come in numerous sizes, and each size can have several frames. What I’m looking to do is automate a procedure to create these variations in 3D. My initial thoughts are to create a script for making the photos to a certain size, applying a frame to it and moving it into position. Each variation would then only be visible on 1 frame, so all the variations can be rendered out and run through compositing software.
What I’m thinking is perhaps there would be a way to write a text file which contains the size, photo and frame style info, which then the Max script would read to create all the variations? I guess perhaps it wouldn’t make much difference doing it inside the script it’s self, but if it were separate then there’s less chance of someone accidentally modifying the script.
The frames would be modelled inside Max, and made using a Sweep modifier, so this should make scripting this straight forward, right? The pictures would also need to be positioned on a wall in a pre-defined place.
The amount of variations will be in the 1000s so it needs to be automated, as hand making each variation would be too time consuming.
I hope that makes sense. If anyone want to message me then that’s fine too.
Cheers,
Dean
this is a task for some script for sure… your case is a good challenge to make a setup where is only one node (call it picture), and it changes its size, frame, position, content on-fly…
I guess what I’d need is define the variables which would be –
Photo Height
Photo Width
Photo Image
Frame Style
And then a script could read these variables and then create the photos and frames from this data.
My main query is how a scripter would go about this, to make it as easy and automated as possible.
If I had a text document, is there any limitations as to how Max could read the files? For example if I had all the photo info on one line like –
PhotoHeight, PhotoWidth, PhotoImage, FrameStyle
so in the text file it would look like this for multiple variations…
300, 500, ImageA, FrameC
400, 700, ImageG, FrameB
600, 100, ImageP, FrameF
Would Max be then able to read this info, build the photos and frames, and then assign each variation to a frame in the timeline?
Thanks,
Dean
It certainly would. In fact, that’s exactly the text file format I usually use. Comma separated properties, new line for a new object/loop/whatever.
Re: time in the timeline, that’s a bit trickier. You could have a system of keyframed hiding and unhiding, or an animated camera so that each object appears to be the only one in the scene, but they are actually right next to each other.
What would you do with this information? Render each frame? Would the data be needed afterwards? I’m just thinking that a max file with 1,000’s of objects might start to get a bit heavy at the end. Would they be rendered on a render farm of some sort?
Hi Dan,
I’m looking at creating the variations, and then rendering them on some kind of render farm. This is very much a brute-force method, but this is the way we want to explore.
I see what you mean about the file size and the difficulty with the time line. I’m guessing the file size and ram usage would be the biggest problems.
Would it be possible for the script to read a line of the text file, create the photo and frame, render that variation, save the image with a unique file name (numbered in order perhaps), then delete the photo and frame, then repeat onto the next variation?
Perhaps the text file could read –
PhotoHeight, PhotoWidth, PhotoImage, FrameStyle, VariationNumber
eg…
300, 500, ImageA, FrameC, 0001
400, 700, ImageG, FrameB, 0002
600, 100, ImageP, FrameF, 0003
where the file name for the rendered image would be VariationNumber.exr which would also allow to re-render any variations if needed quite easily?
Cheers for your input!
Dean
your format is “comma delimitted cvs”. so you can use Excel to make the file.
before i’ve started use XML almost everywhere, i used CVS a lot. the thing that is good to support is a commented line. CVS uses # symbol at the begging of line to make the line commented.
if you need to regenerate/update/re-render some elements you can run the same data file but with ‘excluded’ elements using comments.
Hi Denis,
That sounds perfect and straight forward, as I’m looking for a solution where someone with no technical know-how can input the data to generate these variations. I think I’m getting somewhere now!
Cheers,
Dean
it’s cool and funny challenge… i’d like to show how i would do it step by step if of course anyone is interested.
Hi Denis,
Yes that would be great, it’s always useful to see more in-depth, and might be useful for other applications too.
Cheers,
Dean
ok. my idea is to make a pipeline for generate all frames/images on-fly using external CVS file…
step #1 MAKE A SCRIPTED SIMPLE OBJECT TO PLAY WITH
here is it:
/* denisT collection 2013 */
plugin simpleObject FramePlus name:"FramePlus"
classID:#(0x00001967, 0x1a23099f)
category:"Standard Plus"
version:1
(
local coneobject
parameters params rollout:params
(
width type:#worldUnits default:0 ui:ui_width
height type:#worldUnits default:0 ui:ui_height
depth type:#worldUnits default:0 ui:ui_depth
topWidth type:#worldUnits default:0 ui:ui_topWidth
sideWidth type:#worldUnits default:0 ui:ui_sideWidth
bottomWidth type:#worldUnits default:0 ui:ui_bottomWidth
mapCoords type:#boolean default:on ui:ui_mapCoords
realWorldMapSize type:#boolean default:off ui:ui_realWorldMapSize
)
rollout params "Parameters"
(
group "Dimension: "
(
spinner ui_width "Width: " type:#worldUnits range:[0,1e9,0] fieldwidth:50 align:#right offset:[4,0]
spinner ui_height "Height: " type:#worldUnits range:[0,1e9,0] fieldwidth:50 align:#right offset:[4,-2]
spinner ui_depth "Depth: " type:#worldUnits range:[0,1e9,0] fieldwidth:50 align:#right offset:[4,-2]
)
group "Thickness: "
(
spinner ui_topWidth "Top: " type:#worldUnits range:[0,1e9,0] fieldwidth:50 align:#right offset:[4,0]
spinner ui_sideWidth "Side: " type:#worldUnits range:[0,1e9,0] fieldwidth:50 align:#right offset:[4,-2]
spinner ui_bottomWidth "Bottom: " type:#worldUnits range:[0,1e9,0] fieldwidth:50 align:#right offset:[4,-2]
)
checkbox ui_mapCoords "Generate Mapping Coords." align:#left offset:[-8,4]
checkbox ui_realWorldMapSize "Real-World map Size" align:#left offset:[-8,0]
)
local body, window
fn domesh =
(
body = createinstance box width:width length:depth height:height mapcoords:mapcoords realWorldMapSize:realWorldMapSize \
widthsegs:1 lengthsegs:1 heightsegs:1
window = createinstance box width:(width-sideWidth*2) length:(depth+1) height:(height-topWidth-bottomWidth) mapcoords:mapcoords realWorldMapSize:realWorldMapSize \
widthsegs:1 lengthsegs:1 heightsegs:1
bm = copy body.mesh
wm = copy window.mesh
meshop.movevert wm #all [0,0,bottomWidth]
mesh = bm - wm
)
on buildmesh do domesh()
tool create
(
on mousePoint click do case click of
(
1: nodeTM.translation = gridPoint
3: #stop
)
on mouseMove click do case click of
(
2:
(
width = abs gridDist.x
depth = abs gridDist.y
sideWidth = amin depth (0.1*width)
height = 0.001
)
3:
(
height = abs gridDist.z
sideWidth = topWidth = bottomWidth = amin depth (0.1*width) (0.1*height)
)
)
)
on update do domesh()
)
as you see it’s all parameters are animatable… that mean we can generate all possible variation of the frame.
PS. this plugin leaks in memory use! i left it in purpose to make your life not too easy.
You certainly could render it like that, Dean (re: deleting them after rendering). However, due to the network overheads and time it takes to boot up max, it might be best to perhaps send them in batches of 10 or 50 – so create 50 objects, keyframe the hiding/unhiding, send job to render farm, delete all, continue for 51-100 etc.
Another sexy thing about using an external file like a CSV file is that you could actually build a UI that generates this file for you, if you know any other languages (or even in MaxScript, but I guess the non-techy people that’d be using this system wouldn’t have a copy of Max handy?) This simple UI could have a few options (ie ALL the large frames, only the black and red curvy frames) and the .csv file is generated automatically for them. You feed this into your script and hey presto.