macroScript remap_psd ButtonText:"remap_psd" category:"3dhippie" toolTip:"remap_psd" Icon:#("remap",1) ( /* 26.04.2012 - v0.3 bugfix-try by pixhellmann www.pixhellmann.com Added the Convert to ValidFilename_v_0.3 Funktion by swami*, a.k.a. "codeWarrior()", swami@cfl.rr.com See below for comments and the whole script! The Problem was a variable filename without double backslashes. So I used the function to convert it. and replaced in various places the old variable. look for comments: --CHANGE by pixhellmann */ -- ConvertToValidFilename-v0_3.ms -- -- 08.21.2k, swami*, a.k.a. "codeWarrior()", swami@cfl.rr.com -- -- August Johnston wrote: --" --I am trying to write batch script tool that deals with files and their paths. I have a path that looks like this : --B4 = stringstream "d:\here\there\everywhere\file.ext" --But I get errors when launching it from utility panel. --I need it to look like this: --AFT = "d:\\here\\there\\everywhere\\file.ext" --is there a simple way to get maxscript to add the extra "\"? --I just can't figure it out. --thanx, --august --" -- Then August wrote: --" --Thanks swami. But my problem is not just do to the escape character problem. it's because of some third party --max script "promotions" handlers want either "\\" or "/" for ALL cases of "\" in a string. --The setSkeletonFile call is the problem child. the funny part is getSkeletonFile doesn't help the problem --which are from the same promotion tool. --thanx --aug --" -- -- Using the function below... -- B4="d:\here\there\everywhere\file.ext" -- AFT=stringstream (convertToValidFilename B4) -- NOTE: This will put an extra backslash for EVERY backslash found. -- So, the output is> StringStream:"d:\\here\\there\\everywhere\\file.ext" -- -- Here's my attempt... ------------------ -- FUNCTION (convertToValidFilename) -- -- Given a filename ('theFilename') as a string, return a valid filename ('theValidFilename') as a string. -- If 'theFilename' is not a string, return 'undefined' -- The function detects escape character sequences defined by a backslash~letter combo (see below...) -- and builds a new string with an extra backslash to negate the escape character sequence. -- NOTE: A "string" returned by 'getOpenFileName', 'getSavePath', 'getFiles', 'getDirectories', etc. -- does NOT need to get converted. It is already properly defined. If you print the string to the Listener, -- it will appear with SINGLE backslashes, becacuse the escape character sequence is handled transparently. So, -- 'convertToValidFilename' should be used when a string is procedurally built or when a string is explicitly -- defined within the code. -- USAGE: -- - Create new filename: outputFilename=convertToValidFilename inputFilename -- - Replace filename: inputFilename=convertToValidFilename inputFilename -- E.g. input: "c:\not\really\the\filename.ext", output: "c:\\not\\really\\the\filename.ext" -- -- Escape Character Sequences: -- (NOTE: These ARE case sensitive.) -- \n => a newline character. -- \r => a carriage return character. -- \t => a TAB character. -- \x{d} => a hexadecimal character. *NOTE: This sequence must be handled as a separate, special case -- due to the '{d}' part. This has been PARTIALLY implemented. -- Many strings with '\x' still will NOT be processed properly. -- For details, see comments in the associated code section below... -- fn convertToValidFilename theFilename = ( local escCharSeqArray=#("\n","\r","\t","\x") -- Array of possible escape character sequences in 'theFilename' local escCharSeqArrayLetter=#("n","r","t","x") -- Array of corresponding letters for building the valid filelname. try ( filterString theFilename "" == undefined -- Test that 'theFilename' is a string. ( -- We are here if 'theFilename' is a string... -- Add a backslash for every backslash found. -- (this loop addresses the requirement from the 'third party max script "promotions" handlers') theValidFilename="" for i = 1 to theFilename.count do ( theValidFilename+=theFilename[i] if theFilename[i]=="\\" then theValidFilename+="\\" ) -- Now, handle the escape character sequences... theFilename=theValidFilename local theValidFilename="" -- Loop thru and search for possible escape character sequences in 'theFilename' for i = 1 to escCharSeqArray.count-1 do ( -- Filter 'theFilename' based on the escape character sequence token string. local fnArray=filterString theFilename escCharSeqArray[i] -- 'fn' => filename. local fnACount=fnArray.count -- 'fnA' => filename array. -- If an escape character sequence is present, the resulting filterString array -- will have more than one element. if fnACount>1 then ( -- We are here if an escape character sequence was found... theValidFilename=fnArray[1] for j = 2 to fnACount do ( theValidFilename+="\\\\"+escCharSeqArrayLetter[i]+fnArray[j] -- Build the valid filename string. ) theFilename=theValidFilename -- Assign 'theValidFilename' to 'theFilename' for next iteration's filterSring command. ) ) if theValidFilename=="" then theValidFilename=theFilename -- No escape character sequences were found! -- Handle special case of '\x{d}' -- *Correction for this case is quite problematic. -- The following code is a PARTIAL solution, at best. -- The way MAXScript interprets the {d} part is the crux of the problem. ---- "\x1" = "\x01" = "\x001", etc.! So, there is no way to distinguish between them! This could be a show-stopper. ---- "\xa9"=CopyrightSymbol, but "\xa90" does NOT equal CopyrightSymbol + "0". Show-stopper? ---- "\xff"= "y" with an umlaut, but so does "\xfff", while "\xff0" is something altogher different! Show-stopper? -- Conclusion: It appears that the Discreet MAXScript programmers will have to address these issues before a -- complete solution is possible :( -- -- Examples: -- "\x80\x81" returns "\\x80\\81" -- "\x80good" returns "\\x80good" -- "\x80bad" returns "\\xad" !? Something to do with x80bad being a valid hex#, I suspect. char01="0189abcdef" -- 20h thru 7fh are the standard printbable characters, so we need to exclude these. char02="0123456789abcdef" -- Build arrays for escape character sequence processing. escXArray=#() -- Holds the special characters defined by the escape character sequences. escXArrayAsLetters=#() -- Holds the strings which define the escape character sequences. for i=1 to char01.count do ( for j=1 to char02.count do ( -- The following two lines of code will generate and output to the Listener a table of -- the special characters and their hex equivalents used for handling the '\x{d}' case. -- s=execute("\"\\x"+char01[i]+char02[j]+"\"") -- format "%% %\n" char01[i] char02[j] s append escXArray (execute("\"\\x"+char01[i]+char02[j]+"\"")) append escXArrayAsLetters ("\\\\x"+char01[i]+char02[j]) ) ) -- Loop thru the special characters and check for their occurrence(s) in 'theValidFilename' -- If found, build a new, corrected string. for i = 1 to escXArray.count do ( while ((xPos=findstring theValidFilename escXArray[i]);xPos!=undefined) do ( -- Get all characters BEFORE the match. theValidFilename01=subString theValidFilename 1 (xPos-1) -- Get all characters AFTER the match. theValidFilename02=subString theValidFilename (xPos+1) (theValidFilename.count) -- Concatenate BEFORE; escape character sequence letters; and AFTER. theValidFilename=theValidFilename01+escXArrayAsLetters[i]+theValidFilename02 -- format "%: %\n" i theValidFilename -- Uncomment for debugging purposes. ) ) -- Done handling special case of '\x{d}' theValidFilename -- Return the valid filename string. ) ) catch (theValidFilename=undefined) -- 'theFilename' was NOT a string, so return 'undefined' ) prepare_str = " function select_mask () { var idslct = charIDToTypeID( \"slct\" ); var desc74 = new ActionDescriptor(); var idnull = charIDToTypeID( \"null\" ); var ref49 = new ActionReference(); var idChnl = charIDToTypeID( \"Chnl\" ); var idChnl = charIDToTypeID( \"Chnl\" ); var idMsk = charIDToTypeID( \"Msk \" ); ref49.putEnumerated( idChnl, idChnl, idMsk ); desc74.putReference( idnull, ref49 ); executeAction( idslct, desc74, DialogModes.NO ); } function delete_mask() { var idDlt = charIDToTypeID( \"Dlt \" ); var desc109 = new ActionDescriptor(); var idnull = charIDToTypeID( \"null\" ); var ref67 = new ActionReference(); var idChnl = charIDToTypeID( \"Chnl\" ); var idOrdn = charIDToTypeID( \"Ordn\" ); var idTrgt = charIDToTypeID( \"Trgt\" ); ref67.putEnumerated( idChnl, idOrdn, idTrgt ); desc109.putReference( idnull, ref67 ); executeAction( idDlt, desc109, DialogModes.NO ); } function hasMask(layerRef) { var lm = true, pmd; try { pmd = layerRef.layerMaskDensity; layerRef.layerMaskDensity = 50.0; layerRef.layerMaskDensity = pmd; } catch(e) { lm = false }; return lm; } function hasVectorMask() { var lvm = true, pmd; try { pmd = doc.activeLayer.vectorMaskDensity; doc.activeLayer.vectorMaskDensity = 50.0; doc.activeLayer.vectorMaskDensity = pmd; } catch(e) { lvm = false }; return lvm; }; function seperate_masks() { select_mask() docRef = app.activeDocument docRef.selection.selectAll() docRef.selection.copy() var layername = docRef.activeLayer.name delete_mask() var layerRef = docRef.artLayers.add() layerRef.name = (layername.substring(0,25))+\"_MASK\" layerRef.blendMode = BlendMode.NORMAL docRef.activeLayer = layerRef docRef.paste() } function collect_all_layers (theSet) { var result = new Array() for (var i = 0; i < theSet.length; i++) { layerRef = theSet[i] result.push(layerRef) if (layerRef.typename == \"LayerSet\") {result = result.concat(collect_all_layers (layerRef.layers))} } layerRef = null return result } var docRef = app.activeDocument var allLayers = collect_all_layers(docRef.layers) //var answer = confirm(\"Do you want to rasterize all text and vector layers? If not, those layers will be ignored by 3ds Max\") //if (answer == true) { try {docRef.rasterizeAllLayers()} catch(none){} //} for (var i = 0; i < allLayers.length; i++) { layerRef = allLayers[i] //layerRef.name = layerRef.name.replace(/\//g, 'FwdSlash') if (layerRef.typename == \"LayerSet\") { layerRef.name = i+\"_SET_\"+\"v\"+(layerRef.visible)+\"__\"+layerRef.name } else { layerRef.name = i+\"_v\"+(layerRef.visible)+\"__\"+layerRef.name } docRef.activeLayer = layerRef if (hasMask(layerRef) == true) { try {seperate_masks()} catch (none) {} } //layerRef.name = \"hasamask\"} } docRef = null " update_str = " function place_layer ( path ) { var idPlc = charIDToTypeID( \"Plc \" ); var desc7 = new ActionDescriptor(); var idnull = charIDToTypeID( \"null\" ); desc7.putPath( idnull, new File( path ) ); var idFTcs = charIDToTypeID( \"FTcs\" ); var idQCSt = charIDToTypeID( \"QCSt\" ); var idQcsa = charIDToTypeID( \"Qcsa\" ); desc7.putEnumerated( idFTcs, idQCSt, idQcsa ); var idOfst = charIDToTypeID( \"Ofst\" ); var desc8 = new ActionDescriptor(); var idHrzn = charIDToTypeID( \"Hrzn\" ); var idRlt = charIDToTypeID( \"#Rlt\" ); desc8.putUnitDouble( idHrzn, idRlt, 0.000000 ); var idVrtc = charIDToTypeID( \"Vrtc\" ); var idRlt = charIDToTypeID( \"#Rlt\" ); desc8.putUnitDouble( idVrtc, idRlt, 0.000000 ); var idOfst = charIDToTypeID( \"Ofst\" ); desc7.putObject( idOfst, idOfst, desc8 ); executeAction( idPlc, desc7, DialogModes.NO ); } function create_mask() { var idMk = charIDToTypeID( \"Mk \" ); var desc57 = new ActionDescriptor(); var idNw = charIDToTypeID( \"Nw \" ); var idChnl = charIDToTypeID( \"Chnl\" ); desc57.putClass( idNw, idChnl ); var idAt = charIDToTypeID( \"At \" ); var ref26 = new ActionReference(); var idChnl = charIDToTypeID( \"Chnl\" ); var idChnl = charIDToTypeID( \"Chnl\" ); var idMsk = charIDToTypeID( \"Msk \" ); ref26.putEnumerated( idChnl, idChnl, idMsk ); desc57.putReference( idAt, ref26 ); var idUsng = charIDToTypeID( \"Usng\" ); var idUsrM = charIDToTypeID( \"UsrM\" ); var idRvlS = charIDToTypeID( \"RvlS\" ); desc57.putEnumerated( idUsng, idUsrM, idRvlS ); executeAction( idMk, desc57, DialogModes.NO ); } function paste_mask() { var idShw = charIDToTypeID( \"Shw \" ); var desc80 = new ActionDescriptor(); var idnull = charIDToTypeID( \"null\" ); var list5 = new ActionList(); var ref44 = new ActionReference(); var idChnl = charIDToTypeID( \"Chnl\" ); var idOrdn = charIDToTypeID( \"Ordn\" ); var idTrgt = charIDToTypeID( \"Trgt\" ); ref44.putEnumerated( idChnl, idOrdn, idTrgt ); list5.putReference( ref44 ); desc80.putList( idnull, list5 ); executeAction( idShw, desc80, DialogModes.NO ); // ======================================================= var idpast = charIDToTypeID( \"past\" ); var desc81 = new ActionDescriptor(); var idAntA = charIDToTypeID( \"AntA\" ); var idAnnt = charIDToTypeID( \"Annt\" ); var idAnno = charIDToTypeID( \"Anno\" ); desc81.putEnumerated( idAntA, idAnnt, idAnno ); executeAction( idpast, desc81, DialogModes.NO ); // ======================================================= var idHd = charIDToTypeID( \"Hd \" ); var desc82 = new ActionDescriptor(); var idnull = charIDToTypeID( \"null\" ); var list6 = new ActionList(); var ref45 = new ActionReference(); var idChnl = charIDToTypeID( \"Chnl\" ); var idOrdn = charIDToTypeID( \"Ordn\" ); var idTrgt = charIDToTypeID( \"Trgt\" ); ref45.putEnumerated( idChnl, idOrdn, idTrgt ); list6.putReference( ref45 ); desc82.putList( idnull, list6 ); executeAction( idHd, desc82, DialogModes.NO ); } function select_mask_channel() { var idslct = charIDToTypeID( \"slct\" ); var desc62 = new ActionDescriptor(); var idnull = charIDToTypeID( \"null\" ); var ref30 = new ActionReference(); var idChnl = charIDToTypeID( \"Chnl\" ); var idOrdn = charIDToTypeID( \"Ordn\" ); var idTrgt = charIDToTypeID( \"Trgt\" ); ref30.putEnumerated( idChnl, idOrdn, idTrgt ); desc62.putReference( idnull, ref30 ); var idMkVs = charIDToTypeID( \"MkVs\" ); desc62.putBoolean( idMkVs, false ); executeAction( idslct, desc62, DialogModes.NO ); } function merge_layer () { var idMrgtwo = charIDToTypeID( \"Mrg2\" ); var desc9 = new ActionDescriptor(); executeAction( idMrgtwo, desc9, DialogModes.NO ); } function select_alpha() { var idsetd = charIDToTypeID( \"setd\" ); var desc304 = new ActionDescriptor(); var idnull = charIDToTypeID( \"null\" ); var ref187 = new ActionReference(); var idChnl = charIDToTypeID( \"Chnl\" ); var idfsel = charIDToTypeID( \"fsel\" ); ref187.putProperty( idChnl, idfsel ); desc304.putReference( idnull, ref187 ); var idT = charIDToTypeID( \"T \" ); var ref188 = new ActionReference(); var idChnl = charIDToTypeID( \"Chnl\" ); ref188.putName( idChnl, \"Alpha 1\" ); desc304.putReference( idT, ref188 ); executeAction( idsetd, desc304, DialogModes.NO ); } function selectRGB() { var idslct = charIDToTypeID( \"slct\" ); var desc306 = new ActionDescriptor(); var idnull = charIDToTypeID( \"null\" ); var ref190 = new ActionReference(); var idChnl = charIDToTypeID( \"Chnl\" ); var idChnl = charIDToTypeID( \"Chnl\" ); var idRGB = charIDToTypeID( \"RGB \" ); ref190.putEnumerated( idChnl, idChnl, idRGB ); desc306.putReference( idnull, ref190 ); executeAction( idslct, desc306, DialogModes.NO ); } function getFileNameWithoutExtension( filename ) { var index = filename.lastIndexOf('.'); var result = filename.substring(0, index) return result } function collect_all_layers (theSet) { var result = new Array() for (var i = 0; i < theSet.length; i++) { layerRef = theSet[i] result.push(layerRef) if (layerRef.typename == \"LayerSet\") {result = result.concat(collect_all_layers (layerRef.layers))} } layerRef = null return result } var docRef = app.activeDocument var allLayers = collect_all_layers(docRef.layers) origRulerUnits = app.preferences.rulerUnits origTypeUnits = app.preferences.typeUnits origPointSize = app.preferences.pointSize app.preferences.rulerUnits = Units.PIXELS app.preferences.typeUnits = TypeUnits.PIXELS app.preferences.pointSize = PointType.POSTSCRIPT var thefolder = new Folder() thefolder.changePath(app.activeDocument.path.fsName+\"\\\\\"+getFileNameWithoutExtension(app.activeDocument.name)+\"\\\\\") var bakedImages = thefolder.getFiles() var importLayerRefs = new Array(bakedImages.length) var selBounds = new Array(4) var newSel = new Array(4) numMasks = 0 while (allLayers[numMasks].name.indexOf('MASK') != -1) { numMasks ++} // Import all Layers from Folder for (var i = 0; i < bakedImages.length; i++) { layerName = getFileNameWithoutExtension(bakedImages[i].displayName) importLayerRefs[i] = app.open(bakedImages[i]) otherImage = app.activeDocument = importLayerRefs[i] if (layerName.indexOf('MASK') == -1) { select_alpha() } else { otherImage.selection.selectAll() } selBounds = otherImage.selection.bounds newSel = Array(Array(selBounds[0],selBounds[1]), Array(selBounds[2],selBounds[1]), Array(selBounds[2],selBounds[3]), Array(selBounds[0],selBounds[3])) otherImage.selection.copy() if (i == 0) { if ((docRef.width != otherImage.width)||(docRef.height != otherImage.height)) { var doResize = true var resizeWidth = otherImage.width var resizeHeight = otherImage.height } } otherImage.close() if (layerName.indexOf('MASK') != -1) {layerRef = app.activeDocument.activeLayer = app.activeDocument.layers[layerName]} else {layerRef = app.activeDocument.activeLayer = allLayers[parseInt(layerName.substring(0,layerName.indexOf ('_')))+numMasks] } if (doResize == true) { docRef.resizeImage(resizeWidth,resizeHeight) } if (layerRef.typename != 'LayerSet' && layerRef.kind == LayerKind.NORMAL) { layerRef.clear() } docRef.selection.select(newSel) docRef.paste() if (layerName.indexOf('vfalse') != -1) {app.activeDocument.activeLayer.visible = false} } // merge masks and rename for (var i = 0; i < allLayers.length; i++) { layerRef = allLayers[i] if (layerRef.name.indexOf('MASK') != -1) { app.activeDocument.activeLayer = layerRef layerName = layerRef.name app.activeDocument.selection.selectAll() app.activeDocument.selection.copy() app.activeDocument.layers[layerName].remove() app.activeDocument.activeLayer = allLayers[parseInt(layerName.substring(0,layerName.indexOf ('_')))+numMasks] app.activeDocument.activeLayer.name = app.activeDocument.activeLayer.name.replace(/FwdSlash/g, '/') create_mask() paste_mask() } else { layerRef.name = layerRef.name.substring(layerRef.name.indexOf('__')+2,layerRef.name.length) } } app.preferences.rulerUnits = origRulerUnits app.preferences.typeUnits = origTypeUnits app.preferences.pointSize = origPointSize " fn FindByElementName obj str = -- will find a texture bake element by name. default funtion didn't seem to work properly. ( counter = 1 try ( while (obj.iNodeBakeProperties.getBakeElement counter).elementname != str do counter += 1 ) catch (counter = 0) counter ) try (gTextureBakeDialog.close()) catch() failed = false changeLights = false noMat = noMap = wrongMat = false if $ == undefined then ( messagebox "please select an object first." failed = true ) else if selection.count != 1 then ( messagebox "please select one object only." failed = true ) if not failed do ( if $.material == undefined then ( noMat = true ) else if hasproperty $.material "diffusemap" then ( if $.material.diffusemap == undefined or (classof $.material.diffusemap) != Bitmaptexture then ( noMap = true ) )else wrongMat = true if noMat or noMap or wrongMat then ( psdfileName = getOpenFileName types:"Photoshop(*.psd)|*.psd|Tiff(*.tif)|*.tif|" if psdfileName == undefined then failed = true )else ( psdfileName = $.material.diffusemap.fileName ) if lights.count > 0 and not failed then ( changeLights = false answer = yesnocancelbox "The output will only be correct if all lights are turned off. Do you want to turn all lights off?" if answer == #yes then ( changeLights = true allLights = for l in (lights as array) where classof l != targetobject collect #(l,l.on) for l in allLights do l[1].on = false ) if answer == #cancel then failed = true ) ) if not failed then ( global obj = $ max create mode -- because subobject modifications are slow with modify panel it's better to view the create panel -- progress rollout rollout progress_rollout "TO CANCEL, PRESS ESCAPE FOR 10 SECONDS" width:328 height:216 ( dotNetControl total_pb "Windows.Forms.Progressbar" pos:[9,40] width:311 height:14 --height:24 label total_lbl "Total Compositing:" pos:[8,16] width:134 height:18 --button cancel_btn "Cancel" pos:[248,8] width:72 height:24 GroupBox grp1 "Progress" pos:[8,70] width:312 height:96 label time_last_lb "Last Frame Time" pos:[16,136-40] width:168 height:16 label Time_elapsed_lb "Elapsed Time:" pos:[16,160-40] width:168 height:16 label time_remaining_lb "Time Remaining:" pos:[16,184-40] width:168 height:16 label cancel_lbl "TO CANCEL, PRESS ESCAPE FOR 10 SECONDS" pos:[8,185] ) fn get2Zeros theNum = (substring "00" 1 (2-(theStr = theNum as string).count) + theStr ) --*************** --PREPARATION --*************** pshop=CreateOLEObject"Photoshop.Application" -- Open Photoshop pshop.Visible=true rollout psAtWork "photoshop at work" width:329 height:115 ( label lbl1 "Photoshop is preparing the file. Depending on the number of layers this can take a while. You can open photoshop and watch the progress." pos:[20,36] width:290 height:48 ) createdialog psAtWork if not noMat do oldmat = obj.material -- store old material if one exists pshop.open(psdFileName) -- open the texture pshop.doJavaScript(prepare_str) -- run the first preparation java script in photoshop. destroydialog psAtWork --save the file under a different name original_name = psdFileName -- CHANGE by pixhellmann -- HERE is the problem: the remapped_name generates a pathname with single \ and later we need double \\. remapped_name = (getFilenamePath original_name)+(getFilenameFile original_name)+"_remapped.psd" pshop.activeDocument.saveAs(remapped_name) psdfile = openbitmap psdfilename sizeX = psdfile.width sizeY = psdfile.height close psdfile -- assign a new material and save the old one -- CHANGE by pixhellmann -- the new remapped_name is generated with the help of the convertToValidFilename Function new_remapped_name = convertToValidFilename remapped_name command = "BitmapLayerManager.getLayerCount \""+ new_remapped_name +"\"" numlayers = execute command newmat = standard() newmat.Diffuse = color 0 0 0 newmat.Ambient = color 0 0 0 newmat.selfIllumAmount = 100 obj.material = newmat -- save original bakeElements element_states = #() for i = 1 to obj.iNodeBakeProperties.numBakeElements() do ( element = obj.iNodeBakeProperties.getBakeElement i append element_states #(i,element.enabled) element.enabled = false ) -- look for the REMAP element and create one if it doesn't exist if (FindByElementName obj "REMAP") == 0 then ( remap_element = CompleteMap() -- although diffuse maps is more appropriate, only the complete map also saves an alpha channel obj.iNodeBakeProperties.addBakeElement remap_element remap_element.elementname = "REMAP" automate = true ) else ( remap_element = obj.iNodeBakeProperties.getBakeElement (FindByElementName $ "REMAP") automate = false ) remap_element.enabled = true -- if REMAP bake element hasn't been setup use default settings if automate then ( remap_element.outputSzX = sizeX -- use texture size from the psd file remap_element.outputSzY = sizeY obj.iNodeBakeProjProperties.enabled = true -- enable projection mapping obj.INodeBakeProperties.BakeChannel = 2 -- bake to channel 2 obj.iNodeBakeProjProperties.subObjBakeChannel = 1 -- bake from channel 1 ) --$.INodeBakeProperties.ndilations = 2 -- open the Bake dialog and make changes macros.run "Render" "BakeDialog" oldpath = gTextureBakeDialog.rollouts.commonBakeProps.eFilePath.text global newpath = ( (getfilenamepath remapped_name)+(getfilenamefile remapped_name)) -- create a remapped folder at the same hierarchy as the psd file removeDir = substituteString newpath "\\" "\\\\" dotnetdir = dotNetClass "System.IO.Directory" if dotnetdir.exists removedir then dotnetdir.delete removedir true makeDir newpath gTextureBakeDialog.rollouts.commonBakeProps.eFilePath.text = newpath -- use the new folder for output gTextureBakeDialog.rollouts.bakedMtlProps.cbRenderToFilesOnly.checked = true -- make sure files are rendered only! createdialog progress_rollout lasttime = timestamp() begin = timestamp() cont = true pshop.visible = false renderscenedialog.close() orig_rendTimeType = rendTimeType rendTimeType = 1 --**************** --BAKE TEXTURES --**************** for i = 1 to numLayers do ( if cont then ( -- load next layer and make it the material's diffuse map. -- CHANGE by pixhellmann: new_remapped_name is used instead of the old one command = "BitmapLayerManager.loadLayer \""+ new_remapped_name +"\" "+ ((i-1)as string)+ " true" theTexture = bitmapTexture bitmap:(execute command) obj.material.diffusemap = theTexture -- apply the same map to the opacity channel theOpacity = bitmapTexture bitmap:(execute command) theOpacity.monoOutput = 1 obj.material.opacitymap = theOpacity -- CHANGE by pixhellmann: new_remapped_name is used instead of the old one command = "BitmapLayerManager.getLayerName \""+ new_remapped_name +"\" "+ ((i-1)as string) layerName = execute command --be1 = (obj.iNodeBakeProperties.getBakeElement 1) remap_element.fileType = (newpath +"\\"+layername+".tga") remap_element.fileName = filenameFromPath remap_element.fileType gTextureBakeDialog.rollouts.selectedElementProps.eFilename.text = layername+".tga" gTextureBakeDialog.rollouts.selectedElementProps.eFilename.entered (layername+".tga") gTextureBakeDialog.bRender.pressed() progress_rollout.total_pb.value = (100/numLayers)*(i-1) time_last_caption = stringstream "" now = timestamp() frametime = ((now-lasttime)/1000.0) format "Last Frame Time: % s" frametime to:time_last_caption Time_elapsed_caption = stringstream "" format "Time Elapsed: %:%:%" (get2zeros((((now-begin)/1000)/60)/60)) (get2zeros(((now-begin)/1000)/60)) (get2zeros((mod ((now-begin)/1000) 60) as integer)) to:Time_elapsed_caption Time_remaining_caption = stringstream "" remaintime = (frametime*(numlayers-i) ) format "Time Remaining: %:%:%" (get2zeros(((( remaintime )/60.0)/60.0) as integer)) (get2zeros(((remaintime)/60.0) as integer)) (get2zeros(((mod (remaintime) 60.0) as integer))) to:Time_remaining_caption progress_rollout.time_last_lb.caption = time_last_caption as string progress_rollout.time_elapsed_lb.caption = time_elapsed_caption as string progress_rollout.time_remaining_lb.caption = time_remaining_caption as string lasttime = timestamp() if keyboard.escPressed do cont = false; ) ) destroydialog progress_rollout --******************* --POST OPERATIONS --******************** pshop.visible = true pshop.doJavaScript(update_str) -- Load all layers back into the psd file pshop.activeDocument.save() -- save the remapped file if not noMat then ( obj.material = oldmat -- reassign old material if not wrongmat and not noMap do ( -- CHANGE by pixhellmann: new_remapped_name is used instead of the old one obj.material.diffusemap.bitmap = openbitmap new_remapped_name -- apply the remapped file to the diffuse channel obj.material.diffusemap.coordinates.mapchannel = obj.INodeBakeProperties.BakeChannel -- use the new mapping channel ) )else obj.material = undefined gTextureBakeDialog.rollouts.commonBakeProps.eFilePath.text = oldpath -- reset the bake dialog path -- use dotnet to remove the directory with temporary files removeDir = substituteString newpath "\\" "\\\\" dotnetdir = dotNetClass "System.IO.Directory" --if dotnetdir.exists removedir then dotnetdir.delete removedir true rendtimetype = orig_rendTimeType ) if changeLights then for l in allLights do l[1].on = l[2] -- turn all lights back on )