ラベル Photoshop Script の投稿を表示しています。 すべての投稿を表示
ラベル Photoshop Script の投稿を表示しています。 すべての投稿を表示

2014年2月24日月曜日

PhotoshopCC : レンガ塗りの改造とか



PhotoshopCCには塗りつぶしパターンに、
スクリプトが使えるようになった。

レンガのスクリプトがあったのだけど
ランダムの回転が無かったので足してみた。

本当はタイルパターンに対応させてみたかったのだけど、
色の変化は、ランダムに付けられるので、ちょっと見送り。

感触としては悪くないかも


ソース

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Here are a few parameters that you can change to modify the behavior of the patterm
// Feel free to modify the values, don't change the variable names

modelParameters = {
    // scaling of the input pattern
    patternScale : 1,
    
    // Offset between rows of pattern expressed in percent of pattern width. 
    // For example 50% is half the width.
    offset : 50,    // use a value between 0 and 100. The default is 50.

    // Spacing between patterns in pixels. 
    // For example,1 creates 1 pixel gap between patterns
    spacing : 0,    // use a value between -10 to 20. The default is 0.

    // Variation of color of the pattern. 
    // For example, value of 0.2 means that each of the red, green, and blue color components
    // will be multiplied by a DIFFERENT random value from interval 0.8 and 1.2. 
    // Set to 0 if you do not want to modify the pattern color.
    colorRandomness : 0.05,    // use a value between 0 and 1. The default is 0.05.

    // Variation of pattern brightness. 
    // For example, value of 0.6 means that each of the red, green, and blue color components
    // will be multiplied by THE SAME random value from interval 0.4 and 1.6. 
    // Set to 0 if you do not want to modify the pattern brightness.
    brightnessRandomness : 0.1,   // use a value between 0 and 1. The default is 0.1.

    // Rotation of individual patterns.
    rotateAngle : 0, // Use a value between -180 and 180. The default is 0.
    
    //Rotate Randmaize
    rotateAngleRandomness : 0
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// You can modify the code below but keep in mind that as with any scripting
// you can break things. Keep a backup copy.
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


// Get pattern and its size
var pattern = RenderAPI.getParameter(kpsPattern)
var patternSize = pattern.getParameter(kpsSize)
var patternSizeForDialog = Math.max (patternSize.x, patternSize.y) 


function run (api, parameters, scale)
{
    // get the size of the output area  
    var outputSize = api.getParameter(kpsSize)
    // get the location of the top left corner of the bounding rectangle around the selected area
    var outputOrigin = api.getParameter(kpsOrigin)

    var patternSize = pattern.getParameter(kpsSize)
    patternSize *= parameters.patternScale
   
    // to finetune the progress bar, specify how many pixels are covered by patterns - the bigger the spacing the lower the value, for example
    api.setParameter(kpsPixelCoverage, 0.5 * (patternSize.x * patternSize.y) / ((patternSize.x + parameters.spacing) * (patternSize.y + parameters.spacing ) ) )
    
    // compute the pattern size in x and y after rotation
    var rotSizeX = patternSize.x * Math.abs( Math.cos(parameters.rotateAngle / 180.0 * Math.PI)) +  patternSize.y * Math.abs( Math.sin(parameters.rotateAngle / 180.0 * Math.PI))
    var rotSizeY = patternSize.x * Math.abs( Math.sin(parameters.rotateAngle / 180.0 * Math.PI)) +  patternSize.y * Math.abs( Math.cos(parameters.rotateAngle / 180.0 * Math.PI))
    
    // possibly add spacing
    if (patternSize.x + parameters.spacing >= Math.min (5, patternSize.x) )
        patternSize.x += parameters.spacing
    else
        patternSize.x = Math.min (5, patternSize.x)
        
     if (patternSize.y + parameters.spacing >= Math.min (5, patternSize.y))
        patternSize.y += parameters.spacing
    else
        patternSize.y = Math.min (5, patternSize.y)

    // scale up if the patternsize is 1 to avoid long loop
    if (patternSize.x == 1 && patternSize.y == 1)
    {
        if (scale == 1)
        scale = 20
     }

    patternSize *= scale
    //patternSize *= 2

    api.translateRel (patternSize.x/2, patternSize.y/2)
 
    // negative origin may happen for preview of very small documents
    if (outputOrigin.x < 0)
        outputOrigin.x = 0
    if (outputOrigin.y < 0)
        outputOrigin.y = 0
    
    api.translateRel ( -(outputOrigin.x % patternSize.x), -(outputOrigin.y % patternSize.y))

    var row = Math.floor( outputOrigin.y / patternSize.y ) 
    var column = Math.floor( outputOrigin.x / patternSize.x )
    var extraRows = 0            // on each side, if needed
    var extraColumns = 0
    if (parameters.rotateAngle != 0 || parameters.spacing < 0)
    {
        // start a few rows or columns earlier because the tips of rotated patterns may show up in the selection 
        // or because the spacing is negative and transparent patterns to the left would still show up
        extraRows = Math.floor (rotSizeY / (2 * patternSize.y) + 0.4999)
        extraColumns = Math.floor (rotSizeX / (2 * patternSize.x) + 0.4999)
        
        row -= extraRows;
        column -= extraColumns;
        api.translateRel ( -patternSize.x * extraColumns, -patternSize.y * extraRows)
    }

    pattern.setParameter (kpsColorBlendMode, kpsBlendMultiply)
    //pattern.setParameter (kpsColorBlendMode, kpsBlendLinearLight)
    
    //Add Trea patern BlendMode
    //RenderAPI.setParameter(kpsUseOpenGL, 0)
    //pattern.setParameter(kpsPatternBlendMode,kpsBlendLighterColor)
    //pattern.setParameter(kpsPatternBlendMode,kpsBlendDarkerColor)

    //var margin_y = Math.max(patternSize.y, -parameters.spacing)
    var margin_y = patternSize.y + 2 * extraRows * patternSize.y
        
    for (var y = 0; y < outputSize.y + margin_y;  y+= patternSize.y, row++)
    {
        api.pushMatrix()
        
        var x = 0
        
        
        //if ( (row%2) == 1)
        {
            var shift = parameters.offset*0.01 * row
            api.translateRel( ((shift - Math.floor(shift)) - 1)* patternSize.x, 0)
             x = - patternSize.x // one extra, just in case
        }
       
        //var margin_x = Math.max(patternSize.x * (1 + parameters.offset*0.01), -parameters.spacing)
        var margin_x = patternSize.x + 2 * extraColumns * patternSize.x
            
        for (var c = column; x < outputSize.x + margin_x;  x+= patternSize.x, c ++)
        {           
            api.pushMatrix()
            
            // Set the seed based on the current row and column - this assures that the color will be modified
            // in the same way for the pattern in the neighboring selected area
            var seed =  (row * 214013+ c * 2531011) % 0x7fffffff // 
            //Engine.rand(seed)
            //Engine.rand(); // it helps to call rand a few times beforor using it since we are forcing the seed.

            var rc = parameters.colorRandomness  // color randomness
            var br = 1 - parameters.brightnessRandomness + Engine.rand(seed) * parameters.brightnessRandomness*2  // brightness
            api.Color (kFillColor, br *(1 - rc + Engine.rand()*rc*2), br*(1 - rc + Engine.rand()*rc*2), br*(1 - rc + Engine.rand()*rc*2))
             
            //api.scale(rand()*0.1 + 1)
            //api.rotate(-4 + Math.floor(rand()*60) / 7.5)  // 60 distinct rotations - to help cache
            //api.rotate (Math.floor(rand()*10) * 18)
            api.rotate (parameters.rotateAngle)
            
            //追加
            api.rotate (parameters.rotateAngleRandomness * Engine.rand() )
            
            api.scale(scale)
            api.scale(parameters.patternScale)
            pattern.render(api)
            
            api.popMatrix()
            api.translateRel(patternSize.x, 0)
            
            if (restart)
                return;
        }

        api.popMatrix()
        api.translateRel(0, patternSize.y)
    }
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Menu start
// If you want to create a menu in which you change some of the script parameters, include the following code:
// For shipped scripts we can include localized strings, prefixed with $$$/ - call method localize(string) on the prefixed string
// For your own strings, you can query app.locale and select several language versions (for example, your native language and english). Try alert ("Language is: " + app.locale)

var decoMenu = {    //  an object that defines the menu
   menuTitle : localize("$$$/DecoScripts/BrickFill/BrickFill=Brick Fill"),
   menuBackground : [0.93, 0.93, 0.93, 1],
   previewBackground : [1, 1, 1, 1],
   panels : [
    { panelName : "", 
       leftColumnWidth : 180,
       unitsWidth : 65, 
       editTextWidth : 37, 
       panelMenu : [
        { itemName : localize("$$$/DecoScripts/PatternScale=Pattern Scale:") ,  
             itemUnit :  "", itemType : 'slider', itemValue : modelParameters.patternScale, itemMin : 0.1, itemMax : 1.25, itemStep : 0.01, varName : 'patternScale'  }, 
        { itemName : localize("$$$/DecoScripts/BrickFill/Spacing=Spacing:"),  
             itemUnit : localize("$$$/DecoScripts/Units/pixels=pixels"), 
             itemType : 'slider', itemValue : modelParameters.spacing, itemMin : -patternSizeForDialog+1, itemMax : Math.max(100, 3 * patternSizeForDialog), itemStep : 1, varName : 'spacing'  },
         
         { itemName : localize("$$$/DecoScripts/BrickFill/Offset=Offset between rows:") ,
             itemUnit : localize("$$$/DecoScripts/Units/percentOfWidth=% of width"),  
             itemType : 'slider', itemValue : modelParameters.offset, itemMin : -100, itemMax : 100, itemStep : 0.1, varName : 'offset'  }, 
         
         { itemName : localize("$$$/DecoScripts/ColorRandomness=Color randomness:"),  
             itemUnit : "",  itemType : 'slider', itemValue : modelParameters.colorRandomness, itemMin : 0, itemMax : 1, itemStep : 0.01, varName : 'colorRandomness'  }, 
         
          { itemName : localize("$$$/DecoScripts/BrightnessRandomness=Brightness randomness:"),  
             itemUnit : "",  itemType : 'slider' , itemValue : modelParameters.brightnessRandomness, itemMin : 0, itemMax : 1, itemStep : 0.01, varName : 'brightnessRandomness'  }, 
         
        { itemName : localize("$$$/DecoScripts/BrickFill/rotateAngle=Pattern rotate angle:"),  
             itemUnit : localize("$$$/DecoScripts/Units/degrees=degrees"),  
             itemType : 'slider', itemValue : modelParameters.rotateAngle, itemMin : -180, itemMax : 180, itemStep : 1, varName : 'rotateAngle'  }
         
         //追加
         ,
        { itemName : localize("$$$/DecoScripts/BrickFill/rotateAngleRandomness=Pattern random rotate angle:"),  
             itemUnit : localize("$$$/DecoScripts/Units/degrees=degrees"),  
             itemType : 'slider', itemValue : modelParameters.rotateAngleRandomness, itemMin : 0, itemMax : 180, itemStep : 0.1, varName : 'rotateAngleRandomness'  }
         
         //追加おわり
       
       ] }
   ]  // end of panels
 }; // end of menu

// If livePreview is set to 1, the preview image is updated live. Note that due to limitations of scripted menus the update is slow and the flickering may be disturbing. 
livePreview = 0 // recommended value is 0

// Call Photoshop Script that creates the menu
Engine.evalFile ("_Deco Menu.jsx") 

// Menu finished
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

if (typeof skipRun == 'undefined' || !skipRun)  // run unles we exited the preview window without pressing a button
    run(RenderAPI, modelParameters, 1)



気づいた事


・マスクが使えない(重なり合う所はNG)

2013年9月2日月曜日

Photoshop Script : EF-12 DDS書き出しツール

最近のシェーダーは複数のテクスチャを利用し、
表現力をあげるのですが、
EF-12も例外ではありません

EF-12 スタンダーとマテリアルの設定
リンク先にあるように非常にたくさんの設定があります。

が、以下の作業がとても面倒でした。

異なるテクスチャ素材から、目的のフォーマットのDDSを制作する

スーパー超絶面倒。
なのでPhotoshopのスクリプトで自動化します

目的

Photoshopで異なる複数のテクスチャから、
目的のDDSを書き出す



EF-12より、この辺りの作業です


ツール

・Windows (Nvidiaのツールが動くのがWIndowsなので)
・Photoshop CS5(スクリプトが使えれば多分OK)
・Photoshop Plugin Nvidia DDS

PluginであるNvidiaのDDSツールもスクリプトから制御出来ました。
超便利。コレだけでも調査したかいがあった〜


素材


以下のテクスチャ素材

そのままDDSに書き出す素材
・_d デカール
・_n ノーマル

Dentに合成するテクスチャ
・_h 高さ
・_ao 遮蔽

Glossに合成するテクスチャ
・_s 輝度
・_pow 硬度

です。ちょっとここらアタリ、調査不足でしたので命名規則は適当です orz


流れ


画面の開発環境はCS6です、実行はCS5でした :p


Photoshopで以上の6種類のテクスチャを開きます。

で、こういった順で処理をします。

_dnttテクスチャの作成
_h > dnt の Rチャンネルに
_ao > dnt のBチャンネルに
_dnt > DDS(DTX5_NM形式) で保存

_glossテクスチャの作成
_s >glossのRチャンネルに
_pow > glossのBチャンネルに
_gloss > DDS(DTX5_NM形式) で保存

_d > DDS(可変あり) で保存
_n > DDS(DTX5_NM形式) で保存


です。計6種類のテクスチャを
4種のDDSテクスチャにまとめ書き出しました


Photoshop Script


そのコードです
1日で作った付け焼き刃ですので、
エラー処理など、効率化などはしておりません

サンプルとして見てください
//mergeTex
//20120831 savedds
//EF12用にカスタム

debug = true


// 初期設定===========================================================
ex1 = ["dnt","h","ao","",""]
ex2 = ["gloss","s","pow","",""]
strDeffuse = "d"
strNormal = "n"

DXT1_RGB        = 0;
DXT1_RGBA_1Bit  = 1;
DXT5_RGBA       = 3;
DXT5_NM         = 24;

closeNewDoc = true;

function log(in_data){
    if (debug ) alert(in_data)
    }


//SAVEDDS =======================================================
function saveDDS(in_path,in_ddsType){
 var idsave = charIDToTypeID( "save" );
  var desc14 = new ActionDescriptor();
  var idAs = charIDToTypeID( "As  " );
   var desc15 = new ActionDescriptor();
   var idbarF = charIDToTypeID( "barF" );
   desc15.putBoolean( idbarF, true );
   var idfdev = charIDToTypeID( "fdev" );
   desc15.putDouble( idfdev, 3.000000 );
   var idfbia = charIDToTypeID( "fbia" );
   desc15.putDouble( idfbia, 0.000000 );
   var idurad = charIDToTypeID( "urad" );
   desc15.putDouble( idurad, 5.000000 );
   var iduamo = charIDToTypeID( "uamo" );
   desc15.putDouble( iduamo, 0.500000 );
   var iduthr = charIDToTypeID( "uthr" );
   desc15.putDouble( iduthr, 0.000000 );
   var idxstf = charIDToTypeID( "xstf" );
   desc15.putDouble( idxstf, 1.000000 );
   var idxthf = charIDToTypeID( "xthf" );
   desc15.putDouble( idxthf, 1.000000 );
   var idqual = charIDToTypeID( "qual" );
   desc15.putInteger( idqual, 71 );
   var iderdi = charIDToTypeID( "erdi" );
   desc15.putBoolean( iderdi, false );
   var iderdw = charIDToTypeID( "erdw" );
   desc15.putInteger( iderdw, 1 );
   var idusfa = charIDToTypeID( "usfa" );
   desc15.putBoolean( idusfa, false );
   var idtxfm = charIDToTypeID( "txfm" );
   desc15.putInteger( idtxfm, in_ddsType );//ddsType
   var idweig = charIDToTypeID( "weig" );
   desc15.putInteger( idweig, 0 );
   var idtmty = charIDToTypeID( "tmty" );
   desc15.putInteger( idtmty, 0 );
   var idmmty = charIDToTypeID( "mmty" );
   desc15.putInteger( idmmty, 32 );
   var idsmip = charIDToTypeID( "smip" );
   desc15.putInteger( idsmip, 0 );
   var idbina = charIDToTypeID( "bina" );
   desc15.putBoolean( idbina, false );
   var idprem = charIDToTypeID( "prem" );
   desc15.putBoolean( idprem, false );
   var idfilm = charIDToTypeID( "film" );
   desc15.putBoolean( idfilm, false );
   var idalpb = charIDToTypeID( "alpb" );
   desc15.putBoolean( idalpb, false );
   var idbord = charIDToTypeID( "bord" );
   desc15.putBoolean( idbord, false );
   var idbrdr = charIDToTypeID( "brdr" );
   desc15.putDouble( idbrdr, 0.000000 );
   var idbrdg = charIDToTypeID( "brdg" );
   desc15.putDouble( idbrdg, 0.000000 );
   var idbrdb = charIDToTypeID( "brdb" );
   desc15.putDouble( idbrdb, 0.000000 );
   var idmmft = charIDToTypeID( "mmft" );
   desc15.putInteger( idmmft, 2 );
   var idfdcl = charIDToTypeID( "fdcl" );
   desc15.putBoolean( idfdcl, false );
   var idfdaf = charIDToTypeID( "fdaf" );
   desc15.putBoolean( idfdaf, false );
   var idftworl = charIDToTypeID( "f2rl" );
   desc15.putDouble( idftworl, 0.500000 );
   var idftwogl = charIDToTypeID( "f2gl" );
   desc15.putDouble( idftwogl, 0.500000 );
   var idftwobl = charIDToTypeID( "f2bl" );
   desc15.putDouble( idftwobl, 0.500000 );
   var idftwoal = charIDToTypeID( "f2al" );
   desc15.putDouble( idftwoal, 0.500000 );
   var idfddl = charIDToTypeID( "fddl" );
   desc15.putInteger( idfddl, 0 );
   var idfafm = charIDToTypeID( "fafm" );
   desc15.putDouble( idfafm, 0.150000 );
   var idbafh = charIDToTypeID( "bafh" );
   desc15.putDouble( idbafh, 0.500000 );
   var iddthc = charIDToTypeID( "dthc" );
   desc15.putBoolean( iddthc, false );
   var iddthzero = charIDToTypeID( "dth0" );
   desc15.putBoolean( iddthzero, false );
   var idsmth = charIDToTypeID( "smth" );
   desc15.putInteger( idsmth, 0 );
   var idfilg = charIDToTypeID( "filg" );
   desc15.putDouble( idfilg, 2.200000 );
   var idfieg = charIDToTypeID( "fieg" );
   desc15.putBoolean( idfieg, false );
   var idfilw = charIDToTypeID( "filw" );
   desc15.putDouble( idfilw, 10.000000 );
   var idover = charIDToTypeID( "over" );
   desc15.putBoolean( idover, false );
   var idfblr = charIDToTypeID( "fblr" );
   desc15.putDouble( idfblr, 1.000000 );
   var idnmcv = charIDToTypeID( "nmcv" );
   desc15.putBoolean( idnmcv, false );
   var idncnv = charIDToTypeID( "ncnv" );
   desc15.putInteger( idncnv, 1009 );
   var idnflt = charIDToTypeID( "nflt" );
   desc15.putInteger( idnflt, 1040 );
   var idnmal = charIDToTypeID( "nmal" );
   desc15.putInteger( idnmal, 1033 );
   var idnmbr = charIDToTypeID( "nmbr" );
   desc15.putBoolean( idnmbr, false );
   var idnmix = charIDToTypeID( "nmix" );
   desc15.putBoolean( idnmix, false );
   var idnmiy = charIDToTypeID( "nmiy" );
   desc15.putBoolean( idnmiy, false );
   var idnmiz = charIDToTypeID( "nmiz" );
   desc15.putBoolean( idnmiz, false );
   var idnmah = charIDToTypeID( "nmah" );
   desc15.putBoolean( idnmah, true );
   var idnswp = charIDToTypeID( "nswp" );
   desc15.putBoolean( idnswp, false );
   var idnmsc = charIDToTypeID( "nmsc" );
   desc15.putDouble( idnmsc, 4.000000 );
   var idnmnz = charIDToTypeID( "nmnz" );
   desc15.putInteger( idnmnz, 0 );
   var idusbi = charIDToTypeID( "usbi" );
   desc15.putBoolean( idusbi, false );
   var idlien = charIDToTypeID( "lien" );
   desc15.putBoolean( idlien, false );
   var idshdi = charIDToTypeID( "shdi" );
   desc15.putBoolean( idshdi, false );
   var idshfi = charIDToTypeID( "shfi" );
   desc15.putBoolean( idshfi, false );
   var idshmm = charIDToTypeID( "shmm" );
   desc15.putBoolean( idshmm, true );
   var idshan = charIDToTypeID( "shan" );
   desc15.putBoolean( idshan, true );
   var idclrc = charIDToTypeID( "clrc" );
   desc15.putInteger( idclrc, 0 );
   var idvdxone = charIDToTypeID( "vdx1" );
   desc15.putBoolean( idvdxone, true );
   var idvdxtwo = charIDToTypeID( "vdx2" );
   desc15.putBoolean( idvdxtwo, true );
   var idvdxthree = charIDToTypeID( "vdx3" );
   desc15.putBoolean( idvdxthree, true );
   var idvdxfive = charIDToTypeID( "vdx5" );
   desc15.putBoolean( idvdxfive, true );
   var idvfourfourfour = charIDToTypeID( "v444" );
   desc15.putBoolean( idvfourfourfour, true );
   var idvfivefivefive = charIDToTypeID( "v555" );
   desc15.putBoolean( idvfivefivefive, true );
   var idvfivesixfive = charIDToTypeID( "v565" );
   desc15.putBoolean( idvfivesixfive, true );
   var idveighteighteight = charIDToTypeID( "v888" );
   desc15.putBoolean( idveighteighteight, true );
   var idalph = charIDToTypeID( "alph" );
   desc15.putBoolean( idalph, false );
   var idusra = charIDToTypeID( "usra" );
   desc15.putBoolean( idusra, false );
   var idusfs = charIDToTypeID( "usfs" );
   desc15.putInteger( idusfs, 0 );
   var idprev = charIDToTypeID( "prev" );
   desc15.putBoolean( idprev, false );
   var idrdep = charIDToTypeID( "rdep" );
   desc15.putInteger( idrdep, 3000 );
   var idlomm = charIDToTypeID( "lomm" );
   desc15.putBoolean( idlomm, false );
   var idsflp = charIDToTypeID( "sflp" );
   desc15.putBoolean( idsflp, false );
   var idlflp = charIDToTypeID( "lflp" );
   desc15.putBoolean( idlflp, false );
   var idscar = charIDToTypeID( "scar" );
   desc15.putDouble( idscar, 1.000000 );
   var idscag = charIDToTypeID( "scag" );
   desc15.putDouble( idscag, 1.000000 );
   var idscab = charIDToTypeID( "scab" );
   desc15.putDouble( idscab, 1.000000 );
   var idscaa = charIDToTypeID( "scaa" );
   desc15.putDouble( idscaa, 1.000000 );
   var idbiar = charIDToTypeID( "biar" );
   desc15.putDouble( idbiar, 0.000000 );
   var idbiag = charIDToTypeID( "biag" );
   desc15.putDouble( idbiag, 0.000000 );
   var idbiab = charIDToTypeID( "biab" );
   desc15.putDouble( idbiab, 0.000000 );
   var idbiaa = charIDToTypeID( "biaa" );
   desc15.putDouble( idbiaa, 0.000000 );
   var idsiar = charIDToTypeID( "siar" );
   desc15.putDouble( idsiar, 1.000000 );
   var idsiag = charIDToTypeID( "siag" );
   desc15.putDouble( idsiag, 1.000000 );
   var idsiab = charIDToTypeID( "siab" );
   desc15.putDouble( idsiab, 1.000000 );
   var idsiaa = charIDToTypeID( "siaa" );
   desc15.putDouble( idsiaa, 1.000000 );
   var idbiir = charIDToTypeID( "biir" );
   desc15.putDouble( idbiir, 0.000000 );
   var idbiig = charIDToTypeID( "biig" );
   desc15.putDouble( idbiig, 0.000000 );
   var idbiib = charIDToTypeID( "biib" );
   desc15.putDouble( idbiib, 0.000000 );
   var idbiia = charIDToTypeID( "biia" );
   desc15.putDouble( idbiia, 0.000000 );
   var idoutw = charIDToTypeID( "outw" );
   desc15.putBoolean( idoutw, false );
   var idclcL = charIDToTypeID( "clcL" );
   desc15.putBoolean( idclcL, true );
  var idNVIDIADthreeD_DDS = stringIDToTypeID( "NVIDIA D3D/DDS" );
  desc14.putObject( idAs, idNVIDIADthreeD_DDS, desc15 );
  var idIn = charIDToTypeID( "In  " );
  desc14.putPath( idIn, new File( in_path ) );
 executeAction( idsave, desc14, DialogModes.NO );
}


// メモ===========================================================
function folderserch(in_folderPath,aTex,bTex){
    }

function OpneFile(){
filename = "Macintosh HD:ps_text:headline.txt";
fileObj = new File(filename);
flag = fileObj.open("r");
if (flag == true)
{
alert("ファイルを開きました");
fileObj.close();
}else{
alert("ファイルが開けませんでした");
}
}

// チャンネルの移動===========================================================
function moveChannel(sDoc, tDoc, tChan)
    {
        app.activeDocument = sDoc
        //ソースのドキュメントの複製
        dupDoc = activeDocument.duplicate();
        //log(dupDoc.name)
        //統合
        dupDoc.flatten();
        //グレースケール
        dupDoc.changeMode(ChangeMode.GRAYSCALE);

        //コピー
        dupDoc.selection.selectAll();
        dupDoc.activeLayer.copy();
        
        //閉じる
        dupDoc.close(SaveOptions.DONOTSAVECHANGES);
        
        //移動
        //ターゲットをアクティブドキュメントに
        app.activeDocument = tDoc
        
        //チャンネルを指定
        if(tChan == "r") app.activeDocument.activeChannels = [app.activeDocument.channels.getByName( localize('$$$/ColorModes/RGB/ChannelName/Red=Red'))]
        else if(tChan == "g") app.activeDocument.activeChannels = [app.activeDocument.channels.getByName( localize('$$$/ColorModes/RGB/ChannelName/Green=Green'))]
        else if(tChan == "b") app.activeDocument.activeChannels = [app.activeDocument.channels.getByName( localize('$$$/ColorModes/RGB/ChannelName/Blue=Blue'))]
        else if(tChan == "a") { activeDocument.channels.add() }
        //app.activeDocument.activeChannels = activeDocument.channels.length - 1
            
        
        //ペースト
        activeDocument.paste()
        
        return true
        }


// ターゲドキュメント作成===========================================================
function createTragetDoc(in_name)
{
    preferences.rulerUnits = Units.PIXELS;
    w = activeDocument.width.value;
    h = activeDocument.height.value;
    tagetDoc = documents.add(w,h,72,in_name);
    return tagetDoc;
    }
 
 
// ソースファイルの取得===========================================================
function getSorceDoc(in_name){
    docs = documents;
    for ( var i = 0; i < docs.length; i++){
        var dName = docs[i].name
        dName = dName.substring( 0, dName.lastIndexOf(".") );
        if( dName == in_name){
            return docs[i]
            }
        }
    
    return false
    }

// マージのメイン関数===========================================================
function merge(base,r,g,b,a,outname,fPath){
    //最初にドキュメントを作成する
    var newDocName = base + "_" + outname
    var targetDoc = createTragetDoc(newDocName)
    var sorceDoc = false
    
    //r を移動
    if ( r != ""){
        sorceName = base + "_" + r;
        sorceDoc = getSorceDoc(sorceName);
        if ( sorceDoc ){
            moveChannel(sorceDoc,targetDoc,"r")
            }
     }
 
    //g を移動
    if ( g != ""){
        sorceName = base + "_" + g;
        sorceDoc = getSorceDoc(sorceName);
        if ( sorceDoc ){
            moveChannel(sorceDoc,targetDoc,"g")
            }
     }
    
    //b を移動
    if ( b != ""){
        sorceName = base + "_" + b;
        sorceDoc = getSorceDoc(sorceName);
        if ( sorceDoc ){
            moveChannel(sorceDoc,targetDoc,"b")
            }
     }
    
    //a を移動
    if ( a != ""){
        sorceName = base + "_" + a;
        sorceDoc = getSorceDoc(sorceName);
        if ( sorceDoc ){
            moveChannel(sorceDoc,targetDoc,"a")
            }
     }
 
    //savedds
    savePath = fPath + "\\" + base + "_" + outname + ".dds";
    //log(savePath)
    if ( a == "" && b == ""){
        saveDDS(savePath,DXT5_NM);
        }
    else if (a == "") {
        saveDDS(savePath,DXT1_RGB);
        }
    else {
        svaDDS(savePath,DXT5_RGBA);
        }
    
    //ddsを閉じる
    if(closeNewDoc) activeDocument.close();
    
    return true
    }

// sorce2ddsSave dds保存===========================================================
function sorce2ddsSave(baseName, dds,in_prefix, fPath){
    targetName = baseName + "_" + in_prefix;
    sorceDoc = getSorceDoc(targetName);
    if(sorceDoc == false) return;
    
    //アクティブドキュメントの変更(おまじない)
    app.activeDocument = sorceDoc;
    
    //ddsのチェック
    ddsType = 3
    if(String(dds) == "DXT1_RGB") ddsType = DXT1_RGB;
    if(String(dds) == "DXT1_RGBA_1Bit") ddsType = DXT1_RGBA_1Bit;
    if(String(dds) == "DXT5_RGBA") ddsType = DXT5_RGBA;
    if(String(dds) == "DXT5_NM") ddsType = DXT5_NM;
        
    //log(ddsType)
    
    //複製
    dupDoc = activeDocument.duplicate()
    
    //保存
    savePath = fPath + "\\" + targetName + ".dds";
    saveDDS(savePath,ddsType)

    //ddsを閉じる
    if(closeNewDoc) activeDocument.close();
    
    return true
    }


// メイン===========================================================
function main(){
    
    if (app.documents.length ==0){
        alert("Cancel No Docment")
        return;
        //ドキュメントが開かれていない場合処理なし
        }
    try { fPath = activeDocument.path }
    catch ( e ) { alert("pleas saveDocments"); return }
        
    dName = activeDocument.name
    dName = dName.substring( 0, dName.lastIndexOf(".") );
    dName = dName.substring( 0, dName.lastIndexOf("_") );
    
    uDlg = new Window('dialog','サンプル',[200,100,580,380]);
    
    uDlg.sText = uDlg.add("statictext",[10,10,275,10+45], "BaseName");  uDlg.eText = uDlg.add("edittext",[100,10,275,10+20], dName);
    
    uDlg.cBox1 = uDlg.add("checkbox",[10,50,275,50+25], "Merge 1");
    uDlg.r1  = uDlg.add("edittext",[020,80,020+30,080+20], ex1[1]);
    uDlg.g1  = uDlg.add("edittext",[070,80,070+30,080+20], ex1[2]);
    uDlg.b1  = uDlg.add("edittext",[120,80,120+30,080+20], ex1[3]);
    uDlg.a1  = uDlg.add("edittext",[170,80,170+30,080+20], ex1[4]);
    uDlg.out1 = uDlg.add("edittext",[220,80,220+60,080+20], ex1[0]);
    
    uDlg.cBox2 = uDlg.add("checkbox",[10,120,275,120+25], "Merge 2");
    uDlg.r2  = uDlg.add("edittext",[020,150,020+30,150+20], ex2[1]);
    uDlg.g2  = uDlg.add("edittext",[070,150,070+30,150+20], ex2[2]);
    uDlg.b2  = uDlg.add("edittext",[120,150,120+30,150+20], ex2[3]);
    uDlg.a2  = uDlg.add("edittext",[170,150,170+30,150+20], ex2[4]);
    uDlg.out2 = uDlg.add("edittext",[220,150,220+60,150+20],ex2[0]);
    
    uDlg.cBox3 = uDlg.add("checkbox",[10,180,100,180+25], "ddsSave");
    uDlg.deffuse  = uDlg.add("edittext",[80,180,80+30,180+20], strDeffuse);
    uDlg.dList3 = uDlg.add("dropdownlist",[130,180,130+200,180+25],["DXT1_RGB","DXT1_RGBA_1Bit","DXT5_RGBA","DXT5_NM"]);
    uDlg.dList3.selection = 0;
    
    uDlg.cBox4 = uDlg.add("checkbox",[10,210,100,210+25], "ddsSave");
    uDlg.normal  = uDlg.add("edittext",[80,210,80+30,210+20], strNormal); 
    uDlg.dList4 = uDlg.add("dropdownlist",[130,210,130+200,210+25],["DXT1_RGB","DXT1_RGBA_1Bit","DXT5_RGBA","DXT5_NM"]);
    uDlg.dList4.selection = 3  
    
    
    uDlg.okBtn = uDlg.add("button",[220,240,320,240+25], "Create", { name:"ok"});
    

    //ボタンを押されたときの設定
    
    //view_1
    uDlg.okBtn.onClick = function (){
        if(uDlg.cBox1.value) merge(uDlg.eText.text,uDlg.r1.text, uDlg.g1.text, uDlg.b1.text, uDlg.a1.text, uDlg.out1.text,fPath);
        if(uDlg.cBox2.value) merge(uDlg.eText.text,uDlg.r2.text, uDlg.g2.text, uDlg.b2.text, uDlg.a2.text, uDlg.out2.text,fPath);
        if(uDlg.cBox3.value) sorce2ddsSave(uDlg.eText.text, uDlg.dList3.selection, uDlg.deffuse.text, fPath);
        if(uDlg.cBox4.value) sorce2ddsSave(uDlg.eText.text, uDlg.dList4.selection, uDlg.normal.text,  fPath);
        refresh();
        uDlg.close()
        alert("Finish")
    }

    uDlg.show();
    }

main()


これで、テクスチャの作業に集中出来ます。
といっても、PSD1枚からの必要テクスチャの書き出しが必要かもしれませんが(w


まとめ

で、完成したのが9/1でコンテスト提出日の早朝でした :p
アフォすぎる w

まあ、とりあえずコンテストに応募しました :p
背景ですので、競合は少ないと思いますがw

一番開発に必要なのは
スケジューリングでしたとさw


追記

3D人さんから教わったんだけど。
こんな便利なツールが・・・。

QSM
Quick Save Maps v0.6.4 日本語版 - 勝手に制作!Photoshopにて複数テクスチャを手軽に書き出せる拡張ツール

もうコレで良いよね orz


情報を制したものが強い :p ってことでした。 コード参考にしよう orz

2013年6月1日土曜日

PhotoshopScript : SwitchLayers v01 レイヤーの表示切り替え

相変わらず忙しいので、いつもながらチラ裏です スミマセン
いつかまともなサイトを作りたい物です・・・


今回もPhotoshopのスクリプトです


Photoshopで画像の差分制作を行います

エロではありません。
いや、むしろエロでつかったら俺にください!!!


・・・というわけで、差分のレイヤー表示を簡単に
するべく作ったスクリプトです


説明


命名法則により、表示、非表示を
一括で切り替えるスクリプトです

■Unhide
名前がマッチした場合、表示する

■Hide Group
名前がマッチした場合、非表示にする
※表示に入っている場合は無視されます

■その他
・その他のレイヤーの表示は変更しません
・レイヤーセットの名前が適合した場合、
 それ以下のレイヤーの表示は変更しません


SwitchLayers


//SwitchLayers
// 05 28 2013

//Global
var LEFT = 20
var TOP  = 20
var BUTTON_W = 100
var OFFSET_W = 125
var BUTTON_H = 25
var OFFSET_H = 40

//初期に設定されるグループネーム
var textChkGroupName = "p1,p2,p3,p4,p5,p6,p7,p8,p9";
var gUnHideObjectName = "homhom"
var gHideObjectNameGroup = ["hamham"]


//レイヤーに対するアクションA
function layerActionA( in_Layer ){
    //alert( "ActionA Match " + in_Layer.name )
    in_Layer.visible = true
    }


//レイヤーに対するアクションB
function layerActionB( in_Layer ){
    //alert( "ActionB GMatch " + in_Layer.name )    
    in_Layer.visible = false
    }


//名前検索(グループ)
function chkNameGroup( trget_Name )
{
    for ( var i = 0; i < gHideObjectNameGroup.length; i++)
    {
        if (trget_Name.match( gHideObjectNameGroup[i] ) ){
            return true
            }
        }
    return false
    }


//名前検索
function chkName( trget_Name ){
    //alert(gUnHideObjectName)
    if ( trget_Name.match( gUnHideObjectName ) ){
        return true
        }
    return false
    }


//再帰関数
function getAllLayer(parent){
    //alert(gUnHideObjectName)
 var ChildLayers= parent.layers;
 for (var i = 0; i < ChildLayers.length; i++){
  if (ChildLayers[i].typename == "LayerSet"){
   //レイヤーセットの場合の処理            
             //alert("LayerSet Name = " + ChildLayers[i].name)
             if( chkName( ChildLayers[i].name ) ){
                layerActionA( ChildLayers[i] )
                continue;
                }
                else{
                    //該当する名前がグループのみにあった場合
                    if ( chkNameGroup( ChildLayers[i].name) ){
                        layerActionB( ChildLayers[i] )
                        continue;
                        }
                    }
   //再帰処理
   getAllLayer(ChildLayers[i]);
  }else{
            //通常のレイヤーの場合の処理
           // alert("Layer    Name = " + ChildLayers[i].name)
            if( chkName( ChildLayers[i].name ) ){
                layerActionA( ChildLayers[i] )
                }else{
                    //該当する名前がグループのみにあった場合
                    if ( chkNameGroup( ChildLayers[i].name) ){
                        layerActionB( ChildLayers[i] )
                        }
                }
            }
 }
}


function switchLayers(uDlg){
    //alert("changeViewVis")
    
    //ダイアログからグローバル変数の設定
    gUnHideObjectName = uDlg.unhideName.text
    gHideObjectNameGroup =  uDlg.hideGroupName.text.split(",")
    
    //alert(gUnHideObjectName)
    //for ( var i = 0; i < gHideObjectNameGroup.length;i++)
    //    alert(gHideObjectNameGroup[i])
    
    
    //実作業
    var parent = activeDocument;//作業するドキュメントの参照
    getAllLayer(parent);
    
    
    refresh();
    }



function main(){
 
    app.bringToFront();
    //ドキュメントが開かれているかどうか判別
    if (app.documents.length ==0){
        alert("No Docment")
        return;
        //ドキュメントが開かれていない場合処理なし
    }
    var uDlg = new Window('dialog','switchLayers');
    uDlg.bounds = [200,300,580,420];   
    //uDlg.opacity = .9;

    
    uDlg.sText = uDlg.add("statictext",      [ 20, 10, 140, 10 + BUTTON_H], "UnHide (Unique)");
    uDlg.unhideName = uDlg.add("edittext",   [150, 10, 250, 10 + BUTTON_H], "p1");
    
    uDlg.sText = uDlg.add("statictext",      [ 20, 40, 140, 40 + BUTTON_H], "HideGroup(split(','))");
    uDlg.hideGroupName = uDlg.add("edittext",[150, 40, 360, 40 + BUTTON_H], textChkGroupName);
    
    uDlg.btnCancel = uDlg.add("button",      [150, 70, 250, 70 + BUTTON_H], "Close");
    uDlg.btn00 = uDlg.add("button",          [270, 70, 360, 70 + BUTTON_H], "Apply");

    uDlg.btnCancel.onClick = function () {
        //alert("キャンセルされました。");
        uDlg.close();
    }


    //ボタンを押されたときの設定
    uDlg.btn00.onClick = function ()
    {
        //switchLayers(uDlg);
        activeDocument.suspendHistory('switchLayers', 'switchLayers(uDlg)'); //margin(gap);
    }

    uDlg.show()
    
    //alert("finish")
    }

main()


展望


現在、表示レイヤーをtga保存する
ところまでいけました
次は一括出力です。
この手の作業はなるべく自動化しておきたい物ですヨ