hi All, been working all day on this thing. its a script that exports an objects UVWs from 3ds max into photoshop as a selection. its currently very rough, mostly because i'm not a coder,
and because i started messing with javascript 2 days ago :P
its mostly for practice and proof of concept.
if selection.count > 0 then
(
output_file = createfile "C:UVWscript.js"
docusize = 1024
format "var docSize = %;n" docusize to:output_file--write to file
for i = 1 to NMV = polyOp.getNumMapVerts $ 1 do
--start of map vertex array. this goes into the V = Array(x,x,x) part.
(
format "var V% = Array(" i to:output_file--write to file
mapvert = polyOp.getmapvert $ 1 i
--write the first map vertex
arrayvert = mapvert[1]*docusize
intarray = arrayvert as integer
format "%," intarray to:output_file--write to file
--write the second map vertex. this one is inverted, because of 3ds max's non-conformity!!
arrayvert = (1-mapvert[2])*docusize--the mapvert is a value from 0 to 1
intarray = arrayvert as integer
format "%" intarray to:output_file--write to file
format ");n" to:output_file--write to file
)--end for i
for i = 1 to NMF = polyOp.getNumMapfaces $ 1 do
--start of map face array. this is the
(
format "selRegion = Array(" to:output_file--write to file
mapface = polyOp.getmapface $ 1 i
for E = 1 to 4 do
(
arrayfacevert = mapface[E]
format "V%"arrayfacevert to:output_file--write to file
if E < 4 then ( format ","arrayfacevert to:output_file)
)--end for E
format ");n activeDocument.selection.select(selRegion, SelectionType.EXTEND);n" to:output_file--write to file
)--end for i
close output_file
)--end if
its also got several limitations currently.
1: doesn't work on anything else but quads
2: doesn't work on mesh objects, or primitives, or anything else that isn't a poly object.
3: 3ds max exports it into a .js file. to open it in photoshop, you need to click file>scripts>browse
4:oh forgot, for some reason photoshop acts as if the file is open even though i told it to close the script in max.
so you need to create another script file, and copy-paste the output into that.
5: painfully slow
5: i don't know if it works with anything else but max 8, but i doubt it does.
6: same goes for photoshop. i was using photoshop CS1 for this one.
7: you have to manually set the document size of the photoshop file. docusize = 1024
for example tells it that the photoshop document is a 1024x1024 map.
then browse to C: \ and open the UVWscript.js file
todo:
1: make it work with other things than just quads.
2: port it to VB, once i'm done with the proofing, and make it so that
ah well, got lots to do, i'll be messing with this thing for the next few hours.
i don't think my brain has ever hurt this much before...
Replies
meshu[7]
currently looking at some way to increase meshu[X] until it returns undefined, and then
somehow break, and then save X into a variable.
Cheers!
while i < 10 do
(
i = i+1
print "lal"
if mapface == undefined then exit
)
short answer: no.
long answer: NOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO.
edit: got it working with full polys now:
if selection.count > 0 then ( output_file = createfile "C:Program Files (x86)AdobePhotoshop CSUVWscript.js" docusize = 1024 format "var docSize = %;n" docusize to:output_file--write to file for i = 1 to NMV = polyOp.getNumMapVerts $ 1 do --start of map vertex array. this goes into the V = Array(x,x,x) part. ( format "var V% = Array(" i to:output_file--write to file mapvert = polyOp.getmapvert $ 1 i --write the first map vertex arrayvert = mapvert[1]*docusize intarray = arrayvert as integer format "%," intarray to:output_file--write to file --write the second map vertex. this one is inverted, because of 3ds max's non-conformity!! arrayvert = (1-mapvert[2])*docusize--the mapvert is a value from 0 to 1 intarray = arrayvert as integer format "%" intarray to:output_file--write to file format ");n" to:output_file--write to file )--end for i for i = 1 to NMF = polyOp.getNumMapfaces $ 1 do --start of map face array. this is the ( format "selRegion = Array(" to:output_file--write to file mapface = polyOp.getmapface $ 1 i NumFaceCons = 0 while i < 1000 do ( i = i+1 if mapface[i] == undefined then (NumFaceCons = i-1 exit) ) for E = 1 to NumFaceCons do ( arrayfacevert = mapface[E] format "V%"arrayfacevert to:output_file--write to file if E < NumFaceCons then ( format ","arrayfacevert to:output_file) )--end for E format ");n activeDocument.selection.select(selRegion, SelectionType.EXTEND);n" to:output_file--write to file )--end for i close output_file )--end ifif selection.count > 0 then ( output_file = createfile "C:Program Files (x86)AdobePhotoshop CSUVWscript.js" docusize = 1024 format "var docSize = %;n" docusize to:output_file--write to file for i = 1 to NMV = polyOp.getNumMapVerts $ 1 do --start of map vertex array. this goes into the V = Array(x,x,x) part. ( format "var V% = Array(" i to:output_file--write to file mapvert = polyOp.getmapvert $ 1 i --write the first map vertex arrayvert = mapvert[1]*docusize intarray = arrayvert as integer format "%," intarray to:output_file--write to file --write the second map vertex. this one is inverted, because of 3ds max's non-conformity!! arrayvert = (1-mapvert[2])*docusize--the mapvert is a value from 0 to 1 intarray = arrayvert as integer format "%" intarray to:output_file--write to file format ");n" to:output_file--write to file )--end for i for i = 1 to NMF = polyOp.getNumMapfaces $ 1 do --start of map face array. this is the ( format "selRegion = Array(" to:output_file--write to file mapface = polyOp.getmapface $ 1 i NumFaceCons = 0 F = 1 while F < 50 do ( F = F+1 if mapface[F] == undefined then (NumFaceCons = F-1 exit) ) for E = 1 to NumFaceCons do ( arrayfacevert = mapface[E] format "V%"arrayfacevert to:output_file--write to file if E < NumFaceCons then ( format ","arrayfacevert to:output_file) )--end for E NumFaceCons = 0 format ");n activeDocument.selection.select(selRegion, SelectionType.EXTEND);n" to:output_file--write to file )--end for i close output_file )--end ifnow for optimization.
oh, and here's a picture of the selection:
1280 polygons, took some time to autoselect in photoshop :P
but try and do THAT with the lasso tool in photoshop
I've always used a photoshop action that looks for specific colors that I have set to be the default in the render UV dialog box. I render a template, open it in photoshop, hit F12 and it puts the solid pieces on one layer, and the wires on another. It also sets up some folders and layers with names. I agree it can be a bit tedious to wand select all the shapes... so hopefully your script does what I think it does ha!
/crosses fingers.
pretty much, yeah, but i still need to simplify the operations.
currently its probably as slow as rendering out a template of an object, and loading it into photoshop.
ideally its going to be a single-click, and the UV selection is instantly in photoshop,
but i think i might have hit the limit of what i can do with javascripting photoshop.
[edit] I'm an idiot, I should have tried it first. renderhjs's just copies it to the clipboard, not any photoshop-side stuff. Ignore me!
but i added an "expand" function to it now, so that the borders are increased by 2 pixels:
if selection.count > 0 then ( output_file = createfile "C:Program Files (x86)AdobePhotoshop CSUVWscript.js" docusize = 1024 format "var docSize = %;n" docusize to:output_file--write to file for i = 1 to NMV = polyOp.getNumMapVerts $ 1 do --start of map vertex array. this goes into the V = Array(x,x,x) part. ( format "var V% = Array(" i to:output_file--write to file mapvert = polyOp.getmapvert $ 1 i --write the first map vertex arrayvert = mapvert[1]*docusize intarray = arrayvert as integer format "%," intarray to:output_file--write to file --write the second map vertex. this one is inverted, because of 3ds max's non-conformity!! arrayvert = (1-mapvert[2])*docusize--the mapvert is a value from 0 to 1 intarray = arrayvert as integer format "%" intarray to:output_file--write to file format ");n" to:output_file--write to file )--end for i for i = 1 to NMF = polyOp.getNumMapfaces $ 1 do --start of map face array. this is the ( format "selRegion = Array(" to:output_file--write to file mapface = polyOp.getmapface $ 1 i NumFaceCons = 0 F = 1 while F < 50 do ( F = F+1 if mapface[F] == undefined then (NumFaceCons = F-1 exit) ) for E = 1 to NumFaceCons do ( arrayfacevert = mapface[E] format "V%"arrayfacevert to:output_file--write to file if E < NumFaceCons then ( format ","arrayfacevert to:output_file) )--end for E NumFaceCons = 0 format ");n activeDocument.selection.select(selRegion, SelectionType.EXTEND);n" to:output_file--write to file )--end for i format "activeDocument.selection.expand(2);n" to:output_file--write to file close output_file )--end ifi need some way to disable redraw in photoshop...
Nice work Deja. Could definitely be useful for making good layer masks.
isn`t there a way by passing through some parameters to photoshop?
e.g here is a maxscript that opens the current texture in photoshop using parameters that are passed through to photoshop
http://www.scriptspot.com/3ds-max/photoshopselectedmaterial
now if one could do the same with the scripts to be executed (e.g path to temporary script file) that would be nice. I was already searching but did not found anything yet.
In Unwrap UVW, you can do Tools > Render UVW Template > Mode (choose solid) > Render UV Template.
This will export an image with solid blocks for the UV elements, and it also includes Alpha. This alpha can be loaded as a selection in Photoshop.
- not dynamic in size so you would have to define each time what resolution to use for the photoshop texture.
- requires to select the UV template so that there is a selection
- manually delete the layer afterwards after the selection
in a ideal way you would have:
- 3dsmax and photoshop running
then you select the faces in the UV editor - run the script and you would get instantly the selection of that in photohop in the same texture document that matches the objects texture from 3dsmax.
I remember someone posted this a while back. It seems to do exactly what you are doing. Not sure how fast it is, didn't try it yet - but from the video it seems to be very quick. Maybe you can take a look at it?
http://www.scriptspot.com/3ds-max/photoshopselectedmaterial
is particlary interesting as it passes additional parameters to photoshop
the snippet of the particular part I mean
for b in bitmapsToLoad do ( pathsToExec += """ + b + "" " ) --DOSCommand execMe shellLaunch photoshopPath (""" + pathsToExec + """)some info about the command 'shellLaunch'
http://www.cgarchitect.com/vb/4328-blow-up-net-render-2.html#post31906
e.g launches the the t.avi file and tells the media player that supports the parameters /play /loop to play and loop the animation.
So what I would like to know where to read up the parameters Photoshop supports. I am hoping that there might be one that supports to pass through a script to be executed which would solve the misery of the runScript thing in photoshop.
http://www.photoshoplab.com/droplets-for-the-lazy.html
Also it's worth noting that if you save as a .jsx file and have #target photoshop in the script, it'll launch the app if it's not running. Might be possible to pass parameters to a script too?
This is VBS example but may work for Javascript too...
http://dreamweaverforum.info/photoshop-scripting/144009-re-passing-arguments-jsx-file-command-line.html
anyways i'm back, and i figured some way to launch the script from 3ds max.
here's the modified maxscript first:
macroScript saveUVstophotoshop category:"Dejascripts" tooltip:"unwrap UVWs into photoshop selection" Icon:#("GameTools",2) ( if selection.count > 0 then ( output_file = createfile "C:UVWscript.js" docusize = 1024 format "var docSize = %;n" docusize to:output_file--write to file for i = 1 to NMV = polyOp.getNumMapVerts $ 1 do --start of map vertex array. this goes into the V = Array(x,x,x) part. ( format "var V% = Array(" i to:output_file--write to file mapvert = polyOp.getmapvert $ 1 i --write the first map vertex arrayvert = mapvert[1]*docusize intarray = arrayvert as integer format "%," intarray to:output_file--write to file --write the second map vertex. this one is inverted, because of 3ds max's non-conformity!! arrayvert = (1-mapvert[2])*docusize--the mapvert is a value from 0 to 1 intarray = arrayvert as integer format "%" intarray to:output_file--write to file format ");n" to:output_file--write to file )--end for i for i = 1 to NMF = polyOp.getNumMapfaces $ 1 do --start of map face array. this is the portion that prints "selRegion = Array(VX,VX,VX.....);" ( format "selRegion = Array(" to:output_file--write to file mapface = polyOp.getmapface $ 1 i NumFaceCons = 0 F = 1 while F < 50 do ( F = F+1 if mapface[F] == undefined then (NumFaceCons = F-1 exit) ) for E = 1 to NumFaceCons do ( arrayfacevert = mapface[E] format "V%"arrayfacevert to:output_file--write to file if E < NumFaceCons then ( format ","arrayfacevert to:output_file) )--end for E NumFaceCons = 0 format ");n activeDocument.selection.select(selRegion, SelectionType.EXTEND);n" to:output_file--write to file )--end for i format "activeDocument.selection.expand(2);n" to:output_file--write to file close output_file )--end if shellLaunch "C:openscriptinphotoshop.exe" "" )and here's a link to the visual basic application (might only work with photoshop CS1, or on my computer)
http://www.dejawolf.com/polycount/scripts/openscriptinphotoshop.rar
put that stuff in C: \
i found this in the photoshop CS scripting guide:
Dim appRef As Photoshop.Application
Set appRef = CreateObject("Photoshop.Application")
appRef.DoJavaScriptFile ("D: \\Scripts\\MosaicTiles.js")
just pasted that code into a visual basic console project, changed the name of the script and path, and added a reference for photoshop, and seems to run nicely.
i'm now going to tinker and see if i can somehow get more stuff done in VB, and see if its faster too.
oh btw, that console window will show up until the script is done "rendering" the UVs.
and also, remember to have a picture open in photoshop, or it won't work.
oh and don't forget to have an object selected in max too.
very very hacky :P
oh, and last, its now a macroscript, so you can run it from a button.
but if you want to test if it works on your computer first, just put -- in front of the line that says macroscript.... etc.
now i just need to work around these VB 2008 incompatibility issues.. hrm.
DAMN YOU MICROSOFT!
doesn't seem to be faster though.. hmm.
guess i need to work on my selection algorithm then.
a black and white image of the UV template that max has rendered, and load that into the photoshop selection quickmask area or something.
this one exports the UVs as vectors into photoshop.
it doesn't work on objects with more than 1000 polygons though, photoshop just throws an error.
trying to figure out how to work around this currently:
( if selection.count > 0 then ( output_file = createfile "C:UVWscript.js" docusize = 1024 format"app.preferences.rulerUnits = Units.PIXELS;n" to:output_file--write to file format"app.preferences.typeUnits = TypeUnits.PIXELS;n" to:output_file--write to file format"app.displayDialogs = DialogModes.NO;n" to:output_file--write to file format"var docRef = app.activeDocument;n"to:output_file--write to file format"var letterSubPaths = new Array();n"to:output_file--write to file format"AddLetterHPath(letterSubPaths);n"to:output_file--write to file format"nfunction AddLetterHPath(inOutSubpaths)n{n"to:output_file--write to file -------------------------------------------------------------------------------------------- --start of vertex operation portion -------------------------------------------------------------------------------------------- for i = 1 to NMV = polyOp.getNumMapVerts $ 1 do --start of map vertex array. this goes into the V = Array(x,x) part. ( format "var V% = Array(" i to:output_file--write to file mapvert = polyOp.getmapvert $ 1 i --write the first map vertex arrayvert = mapvert[1]*docusize intarray = arrayvert as integer format "%," intarray to:output_file--write to file --write the second map vertex. this one is inverted, because of 3ds max's non-conformity!! arrayvert = (1-mapvert[2])*docusize--the mapvert is a value from 0 to 1 intarray = arrayvert as integer format "%" intarray to:output_file--write to file format ");n" to:output_file--write to file )--end for i --------------------------------------------------------------------------------- --start of face operations portion --------------------------------------------------------------------------------- for i = 1 to NMF = polyOp.getNumMapfaces $ 1 do ( format"var letterPoints = new Array();nn"to:output_file--write to file mapface = polyOp.getmapface $ 1 i--gets the currently active mapface in the array NumFaceCons = 0 --variable to hold the number of vertices in the map face array F = 1 while F < 50 do-- loop that finds out how many vertices is in this map face array ( F = F+1 if mapface[F] == undefined then (NumFaceCons = F exit) ) for E = 1 to NumFaceCons do ( UX = E-1 arrayfacevert = mapface[E] if mapface[E] == undefined then (arrayfacevert = mapface[1]) format " letterPoints[%] = new PathPointInfo;n" UX to:output_file format " letterPoints[%].kind = PointKind.CORNERPOINT;n" UX to:output_file format " letterPoints[%].anchor = V%;n" UX arrayfacevert to:output_file format " letterPoints[%].leftDirection = letterPoints[%].anchor;n" UX UX to:output_file format " letterPoints[%].rightDirection = letterPoints[%].anchor;nn"UX UX to:output_file )--end for E NumFaceCons = 0 format "var insertIndex = inOutSubpaths.length; ninOutSubpaths[insertIndex] = new SubPathInfo();n" to:output_file format "inOutSubpaths[insertIndex].operation = ShapeOperation.SHAPEXOR; ninOutSubpaths[insertIndex].closed = false;n" to:output_file format "inOutSubpaths[insertIndex].entireSubPath = letterPoints;nn" to:output_file )--end for i format "}n" to:output_file format "var myPathItem = docRef.pathItems.add("", letterSubPaths);n" to:output_file ) )oh, and here's a modified UV selection script that only exports the selected UVs in 3ds max into photoshop.
spent some hours banging my head into the wall trying to figure out how to make UVs render out into a render window. so far i can draw single pixels.
--macroScript saveUVstophotoshop category:"Dejascripts" tooltip:"unwrap UVWs into photoshop selection" Icon:#("GameTools",2) ( if selection.count > 0 then ( output_file = createfile "C:UVWscript.js" docusize = 1024 format "activeDocument.selection.deselect();" docusize to:output_file--write to file format "var docSize = %;n" docusize to:output_file--write to file --get the vertex selection first into the array I, and loop through it. for i = 1 to NMV = polyOp.getNumMapVerts $ 1 do --start of map vertex array. this goes into the V = Array(x,x,x) part. ( format "var V% = Array(" i to:output_file--write to file mapvert = polyOp.getmapvert $ 1 i --write the first map vertex arrayvert = mapvert[1]*docusize intarray = arrayvert as integer format "%," intarray to:output_file--write to file --write the second map vertex. this one is inverted, because of 3ds max's non-conformity!! arrayvert = (1-mapvert[2])*docusize--the mapvert is a value from 0 to 1 intarray = arrayvert as integer format "%" intarray to:output_file--write to file format ");n" to:output_file--write to file )--end for i for i in polyOp.getFaceSelection $ do ( --start of map face array. this is the portion that prints "selRegion = Array(VX,VX,VX.....);" format "selRegion = Array(" to:output_file--write to file mapface = polyOp.getmapface $ 1 i NumFaceCons = 0 --variable to hold number of vertices bound together by a map face F = 1 while F < 50 do --loops through the number of vertices in a face to get the number of faces. ( F = F+1 if mapface[F] == undefined then (NumFaceCons = F-1 exit) ) for E = 1 to NumFaceCons do ( arrayfacevert = mapface[E] format "V%"arrayfacevert to:output_file--write to file if E < NumFaceCons then ( format ","arrayfacevert to:output_file) )--end for E NumFaceCons = 0 format ");n activeDocument.selection.select(selRegion, SelectionType.EXTEND);n" to:output_file--write to file )--end for i format "activeDocument.selection.expand(2);n" to:output_file--write to file close output_file )--end if shellLaunch "C:openscriptinphotoshop.exe" "" )this time it will automatically figure out the size of your bitmap, based on the size of the diffuse texture applied to the selected object.
macroScript saveUVstophotoshop category:"Dejascripts" tooltip:"unwrap UVWs into photoshop selection" Icon:#("GameTools",2) ( if selection.count > 0 then ( if $.material.maps[2].bitmap != undefined then ( output_file = createfile "C:UVWscript.js" docusize = $.material.maps[2].bitmap.width format "activeDocument.selection.deselect();" docusize to:output_file--write to file format "var docSize = %;n" docusize to:output_file--write to file --get the vertex selection first into the array I, and loop through it. for i = 1 to NMV = polyOp.getNumMapVerts $ 1 do --start of map vertex array. this goes into the V = Array(x,x,x) part. ( format "var V% = Array(" i to:output_file--write to file mapvert = polyOp.getmapvert $ 1 i --write the first map vertex arrayvert = mapvert[1]*docusize intarray = arrayvert as integer format "%," intarray to:output_file--write to file --write the second map vertex. this one is inverted, because of 3ds max's non-conformity!! arrayvert = (1-mapvert[2])*docusize--the mapvert is a value from 0 to 1 intarray = arrayvert as integer format "%" intarray to:output_file--write to file format ");n" to:output_file--write to file )--end for i for i in polyOp.getFaceSelection $ do ( --start of map face array. this is the portion that prints "selRegion = Array(VX,VX,VX.....);" format "selRegion = Array(" to:output_file--write to file mapface = polyOp.getmapface $ 1 i NumFaceCons = 0 --variable to hold number of vertices bound together by a map face F = 1 while F < 50 do --loops through the number of vertices in a face to get the number of faces. ( F = F+1 if mapface[F] == undefined then (NumFaceCons = F-1 exit) ) for E = 1 to NumFaceCons do ( arrayfacevert = mapface[E] format "V%"arrayfacevert to:output_file--write to file if E < NumFaceCons then ( format ","arrayfacevert to:output_file) )--end for E NumFaceCons = 0 format ");n activeDocument.selection.select(selRegion, SelectionType.EXTEND);n" to:output_file--write to file )--end for i format "activeDocument.selection.expand(2);n" to:output_file--write to file close output_file )--end if shellLaunch "C:openscriptinphotoshop.exe" "" )--end undefined bitmap for selection )--end undefined selectionthanks.
its not a big change, just changed docusize = 1024 to docusize = $.material.maps[2].bitmap.width