Mini Kabibi Habibi
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 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,
// 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.
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 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 patternSizeForDialogMax = Math.max (patternSize.x, patternSize.y)
var patternSizeForDialogMin = Math.min (patternSize.x, patternSize.y)
// For the script to work with a menu with preview, you need to define a run method with the following three parameters:
// 1. api - render api to be used. Do not use RenderAPI directly, since preview uses a different renderer
// 2. parameter - contains model parameters. Do not refer directly to modelParameters inside the run method or methods called from it.
// 3. scale - preview can be scaled up or down depending on the size of the input pattern. Accomodate scale inside the run method.
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 ) ) )
// 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;
// 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)
var sizeStep = (patternSize.x + 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
// don't use % since sizeStep may not be integer
var xRel = outputOrigin.x - Math.floor (outputOrigin.x / sizeStep) * sizeStep
var yRel = outputOrigin.y - Math.floor (outputOrigin.y / sizeStep) * sizeStep
api.translateRel ( -xRel, -yRel)
var row = Math.floor( outputOrigin.y / sizeStep )
var column = Math.floor( outputOrigin.x / sizeStep )
var mult = ((row*0 + column) % 2) == 0 ? 1 : -1;
api.translate(-(column%2)* (patternSize.y - patternSize.x)/2, 0)
var margin_y = Math.max(patternSize.x+patternSize.y, -parameters.spacing)
for (var y = -patternSize.y/2; y < outputSize.y + margin_y; row++)
{
api.pushMatrix()
// shift each second row
api.translate(-mult*(row%2)* (patternSize.y - patternSize.x)/2 - 2*sizeStep, y)
var col = column
var margin_x = Math.max(4*sizeStep, -parameters.spacing)
for (var x = 0; x < outputSize.x + margin_x; x+= rotatedSizeX, col++)
{
// 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+ col * 2531011) %0x7fffffff //
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))
var angle = 90 * (col + row + Math.floor(Engine.rand()*2)*2)
var side = (angle / 90) % 2
rotatedSizeX = (1-side) * patternSize.x + side * patternSize.y
// Use this computation if angle is not a multiple of 90
//var sinA = Math.abs(Math.sin(angle / 180 * 3.141529) )
//var cosA = Math.abs(Math.cos(angle / 180 * 3.141529) )
//var rotatedSizeX = patternSize.x * cosA + patternSize.y * sinA
//var rotatedSizeY = patternSize.x * sinA + patternSize.y * cosA
api.translate(rotatedSizeX/2, 0)
// the pattern is centered
api.pushMatrix()
api.scale (scale, scale)
api.rotate(angle)
api.scale(parameters.patternScale)
pattern.render(api)
api.popMatrix()
api.translate(rotatedSizeX/2, 0)
}
y+=sizeStep
api.popMatrix()
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 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/CrossWeave/CrossWeave=Cross Weave"),
menuBackground : [0.93, 0.93, 0.93, 1],
previewBackground : [1, 1, 1, 1],
panels : [
{ panelName : "",
leftColumnWidth : 180,
unitsWidth : 65,
panelMenu : [
{ itemName : localize("$$$/DecoScripts/PatternScale=Pattern Scale:") ,
itemUnit : "", itemType : 'slider', itemValue : modelParameters.patternScale, itemMin : 0.10, itemMax : 1.25, itemStep : 0.01, varName : 'patternScale' },
{ itemName : localize("$$$/DecoScripts/CrossWeave/Spacing=Spacing:"),
itemUnit : localize("$$$/DecoScripts/Units/pixels=pixels"),
itemType : 'slider', itemValue : modelParameters.spacing, itemMin : Math.max(-patternSizeForDialogMin+1, Math.floor(-patternSizeForDialogMin*(1 - 0.05*Math.log(patternSizeForDialogMin)/Math.LN10))),
itemMax : Math.max(100, 3 * patternSizeForDialogMax), itemStep : 1, varName : 'spacing' },
{ 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' }
] }
] // 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)