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,
// This variable defines the type of symmetry.:
// Try 6, 7(*),16, 19, 21(*), 23, 26(*), 27, 29, 31(*), 32(**)
symmetryType : 32, // use an integer value between 0 and 32. The default is 32.
// Here is the list of supported symmetries
// 0: line reflection
// 1: point reflection, frameZero
// 2: rotation symmetry with 4 elements around the center
// 3: translation symmetry
// 4: glide reflection
// 5: dilatation symmetry
// 6: dilative rotation symmetry
// 7: a different dilative rotation symmetry
// 8: infinite dilative rotation symmetry
// The Frieze tilings (1D tilings on an infinite line
// 9: translation frieze
// 10: glide reflection frieze
// 11: translation line reflection frieze
// 12: translation mirror reflection frieze
// 13: translation point reflection frieze
// 14: translation double reflection frieze
// 15: glide reflection rotation frieze
// The Wallpaper tilings 2D tilings on an infinite plane
// 16: wallpaperP1 symmetry
// 17: wallpaperP2 symmetry
// 18: wallpaperPM symmetry
// 19: wallpaperPG symmetry
// 20: wallpaperPMM symmetry
// 21: wallpaperCM symmetry
// 22: wallpaperPMG symmetry
// 23: wallpaperPGG symmetry
// 24: wallpaperCMM symmetry
// 25: wallpaperP4 symmetry
// 26: wallpaperP4M symmetry
// 27: wallpaperP4G symmetry
// 28: wallpaperP3 symmetry
// 29: wallpaperP3M1 symmetry
// 30: wallpaperP31M symmetry
// 31: wallpaperP6 symmetry
// 32: wallpaperP6M symmetry
// Pattern translation (in percantage of width and height)
// By modifying this value you will change the layout of the pattern.
// Try the following pairs of values: 0, 0 or 0, 75 or 75, 0
// Note that the behavior is different when your pattern is thin in x or y .
patternTranslationX : 75, // The default is 75
patternTranslationY : 75, // The default is 75
// 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.
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
var pattern = RenderAPI.getParameter(kpsPattern)
function PatternModule(parameters, scale, patternSize)
{
this.parameters = parameters
this.scale = scale
this.patternSize = patternSize
}
PatternModule.prototype.render = function (api)
{
api.pushMatrix()
// Set the random seed based on the current position - this assures that the color will be modified
// in the same way for the pattern in the neighboring selected area
var currentFrame = api.getFrame()
var seed = (Math.floor(currentFrame.position().x * 2531011) + Math.floor(currentFrame.position().y * 2531011)) % 2147483647
if (this.parameters.symmetryType >= 0 && this.parameters.symmetryType <= 8)
seed = Math.random()*2531011
//Engine.message ("rendering at position " + currentFrame.position().x + ", " + currentFrame.position().y)
var rc = this.parameters.colorRandomness // color randomness
var br = 1 - this.parameters.brightnessRandomness + Engine.rand(seed) * this.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.translateRel (this.patternSize.x * this.parameters.patternTranslationX * 0.01, this.patternSize.y * this.parameters.patternTranslationY * 0.01)
api.scale(this.scale)
if (skipRotation)
{
var angle = 180 / Math.PI * Math.atan2 (currentFrame.heading().x, currentFrame.heading().y) // get current rotation
api.rotate (-angle) // negate the rotation
}
//api.scale(this.parameters.patternScale)
pattern.render(api)
api.popMatrix()
}
var frameZero = new Frame2();
var frameOrigin = new Frame2();
frameOrigin.setPosition(0, 0);
frameOrigin.rotateDeg(0.0);
//symmetry.frame = frameOrigin; // no need to set the frame if it is a default frame at position (0,0) and no rotation
function setSymmetry(symmetry, parameters, patternSize)
{
switch (parameters.symmetryType)
{
case 0:
symmetry.set(kSymmetryLineReflection, frameZero, kTransformToLocal);
break;
case 1:
symmetry.set(kSymmetryPointReflection, frameZero, kTransformToLocal);
break;
case 2:
// Type, number of elements around the center, frame specifying local position of an element, optional center of rotation (must be a point)
symmetry.set(kSymmetryRotation, 4, frameZero);
break;
case 3:
symmetry.set(kSymmetryTranslation, 4, 1.0, frameZero, kTransformToLocal);
break;
case 4:
symmetry.set(kSymmetryGlideReflection, 5, 4.0, frameZero, kTransformToLocal);
break;
// Number, initial angle, angle increment, initial scale, scale ratio
case 5:
symmetry.set(kSymmetryDilatation, 600, 1.0, 1.0 / 1.01, frameZero, kTransformToLocal);
break;
case 6:
symmetry.set(kSymmetryDilativeRotation, 600, 0.0, kFibonacciAngleInDegrees, 1.0, 1.0 / 1.01, frameZero, kTransformToLocal);
break;
case 7:
symmetry.set(kSymmetryDilativeRotation, 200, 0.0, kFibonacciAngleInDegrees, 0.0333, 1.02, frameZero, kTransformToLocal);
break;
case 8:
symmetry.set(kSymmetryInfiniteDilativeRotation, 100, 0.0, kFibonacciAngleInDegrees, 0.5, 1.01, frameZero, kTransformToLocal);
}
var uStep = patternSize.y * 1.25;
var vStep = patternSize.x * 1.25;
// The Frieze tilings (1D tilings on an infinite line
switch (parameters.symmetryType)
{
case 9:
symmetry.set(kSymmetryFriezeTranslation, Math.max(uStep, vStep), frameZero, kTransformToLocal);
break;
case 10:
symmetry.set(kSymmetryFriezeGlideReflection, Math.max(uStep, vStep), frameZero, kTransformToLocal);
break;
case 11:
symmetry.set(kSymmetryFriezeTranslationLineReflection, Math.max(uStep, vStep), frameZero, kTransformToLocal);
break;
case 12:
symmetry.set(kSymmetryFriezeTranslationMirrorReflection, Math.max(uStep, vStep), frameZero, kTransformToLocal);
break;
case 13:
symmetry.set(kSymmetryFriezeTranslationPointReflection, Math.max(uStep, vStep), frameZero, kTransformToLocal);
break;
case 14:
symmetry.set(kSymmetryFriezeTranslationDoubleReflection, Math.max(uStep, vStep), frameZero, kTransformToLocal);
break;
case 15:
symmetry.set(kSymmetryFriezeGlideReflectionRotation, Math.max(uStep, vStep), frameZero, kTransformToLocal);
break;
}
uStep = uStep //* 2.5;
vStep = vStep //* 2.5
// The Wallpaper tilings 2D tilings on an infinite plane
switch (parameters.symmetryType)
{
case 16:
symmetry.set(kSymmetryWallpaperP1, uStep, vStep, frameZero, kTransformToLocal);
break;
case 17:
symmetry.set(kSymmetryWallpaperP2, uStep, vStep, frameZero, kTransformToLocal);
break;
case 18:
symmetry.set(kSymmetryWallpaperPM, uStep, vStep, frameZero, kTransformToLocal);
break;
case 19:
symmetry.set(kSymmetryWallpaperPG, uStep, vStep, frameZero, kTransformToLocal);
break;
}
uStep = uStep * 1.5;
vStep = vStep * 1.5;
switch (parameters.symmetryType)
{
case 20:
symmetry.set(kSymmetryWallpaperPMM, uStep, vStep, frameZero, kTransformToLocal);
break;
case 21:
symmetry.set(kSymmetryWallpaperCM, uStep, vStep, frameZero, kTransformToLocal);
break;
}
uStep = uStep * 0.75;
vStep = vStep * 0.75;
switch (parameters.symmetryType)
{
case 22:
symmetry.set(kSymmetryWallpaperPMG, uStep, vStep, frameZero, kTransformToLocal);
break;
case 23:
symmetry.set(kSymmetryWallpaperPGG, uStep, vStep, frameZero, kTransformToLocal);
break;
case 24:
symmetry.set(kSymmetryWallpaperCMM, uStep, vStep, frameZero, kTransformToLocal);
break;
case 25:
symmetry.set(kSymmetryWallpaperP4, Math.max(uStep, vStep), frameZero, kTransformToLocal);
break;
case 26:
symmetry.set(kSymmetryWallpaperP4M, Math.max(uStep, vStep), frameZero, kTransformToLocal);
break;
case 27:
symmetry.set(kSymmetryWallpaperP4G, Math.max(uStep, vStep), frameZero, kTransformToLocal);
break;
}
uStep = uStep * 1.75;
vStep = vStep * 1.75;
switch (parameters.symmetryType)
{
case 28:
symmetry.set(kSymmetryWallpaperP3, Math.max(uStep, vStep), frameZero, kTransformToLocal);
break;
case 29:
symmetry.set(kSymmetryWallpaperP3M1, Math.max(uStep, vStep), frameZero, kTransformToLocal);
break;
case 30:
symmetry.set(kSymmetryWallpaperP31M, Math.max(uStep, vStep), frameZero, kTransformToLocal);
break;
case 31:
symmetry.set(kSymmetryWallpaperP6, Math.max(uStep, vStep), frameZero, kTransformToLocal);
break;
case 32:
symmetry.set(kSymmetryWallpaperP6M, Math.max(uStep, vStep), frameZero, kTransformToLocal);
break;
}
return 1
}
var skipRotation = false
// 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)
var maxPatternSize = Math.max ( patternSize.x, patternSize.y) // before patternScale is applied
patternSize *= parameters.patternScale
if (parameters == previewParameters)
{
// set scale so that we show about 10-15 patterns
if (maxPatternSize < previewSize / 5)
scale = previewSize / 5 / maxPatternSize
else if (maxPatternSize > previewSize / 4)
scale = previewSize / 4 / maxPatternSize
}
scale *= parameters.patternScale
// 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
skipRotation = true // 1x1 patterns that are scaled up do not rotate gracefully
}
// 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, 1.5)
var patternModule = new PatternModule(parameters, scale, patternSize * scale);
// Symmetry - module should be added to the system before modules that
// are part of the symmetry
var symmetry = new Symmetry;
// set the symmetry type
setSymmetry (symmetry, parameters, patternSize * scale )
Engine.addModule (symmetry)
Engine.addModule (patternModule)
// Add to the symmetry
symmetry.addModule (patternModule)
if (parameters.symmetryType >= 16)
// Setting the bounding box like this will insure that neighboring fills are aligned for 2D tilings
api.setSceneBBox (outputOrigin.x, outputOrigin.x + outputSize.x, outputOrigin.y, outputOrigin.y + outputSize.y)
else
{
// Other symmetries will be centered around the center of the selection bounding box
api.setSceneBBox (-outputSize.x/2, outputSize.x/2, -outputSize.y/2, outputSize.y/2)
}
if (parameters == previewParameters)
{
api.pushMatrix()
Engine.render (api)
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/SymmetryFill/SymmetryFill=Symmetry Fill"),
menuBackground : [0.93, 0.93, 0.93, 1],
previewBackground : [1, 1, 1, 1],
panels : [
{ panelName : "",
leftColumnWidth : 200,
unitsWidth : 65,
dropdownlistWidth : 200,
panelMenu : [
{ itemName : localize("$$$/DecoScripts/SymmetryFill/SymmetryType=Symmetry type:"),
itemUnit : '',
itemType : 'dropdownlist', itemList :
[
{ item: localize("$$$/DecoScripts/SymmetryFill//Symmetry1= 1: line reflection"), image : "Symmetry Fill/s0.png" },
{ item: localize("$$$/DecoScripts/SymmetryFill//Symmetry2= 2: point reflection"), image : "Symmetry Fill/s1.png" },
{ item: localize("$$$/DecoScripts/SymmetryFill//Symmetry3= 3: rotation symmetry with 4 elements around the center"), image : "Symmetry Fill/s2.png" },
{ item: localize("$$$/DecoScripts/SymmetryFill//Symmetry4= 4: translation symmetry"), image : "Symmetry Fill/s3.png" },
{ item: localize("$$$/DecoScripts/SymmetryFill//Symmetry5= 5: glide reflection"), image : "Symmetry Fill/s4.png" },
{ item: localize("$$$/DecoScripts/SymmetryFill//Symmetry6= 6: dilatation symmetry"), image : "Symmetry Fill/s5.png" },
{ item: localize("$$$/DecoScripts/SymmetryFill//Symmetry7= 7: dilative rotation symmetry"), image : "Symmetry Fill/s6.png" },
{ item: localize("$$$/DecoScripts/SymmetryFill//Symmetry8= 8: a different dilative rotation symmetry"), image : "Symmetry Fill/s7.png" },
{ item: localize("$$$/DecoScripts/SymmetryFill//Symmetry9= 9: infinite dilative rotation symmetry"), image : "Symmetry Fill/s8.png" },
// The Frieze tilings (1D tilings on an infinite line
{ item: localize("$$$/DecoScripts/SymmetryFill//Symmetry10=10: translation frieze"), image : "Symmetry Fill/s9.png" },
{ item: localize("$$$/DecoScripts/SymmetryFill//Symmetry11=11: glide reflection frieze"), image : "Symmetry Fill/s10.png" },
{ item: localize("$$$/DecoScripts/SymmetryFill//Symmetry12=12: translation line reflection frieze"), image : "Symmetry Fill/s11.png" },
{ item: localize("$$$/DecoScripts/SymmetryFill//Symmetry13=13: translation mirror reflection frieze"), image : "Symmetry Fill/s12.png" },
{ item: localize("$$$/DecoScripts/SymmetryFill//Symmetry14=14: translation point reflection frieze"), image : "Symmetry Fill/s13.png" },
{ item: localize("$$$/DecoScripts/SymmetryFill//Symmetry15=15: translation double reflection frieze"), image : "Symmetry Fill/s14.png" },
{ item: localize("$$$/DecoScripts/SymmetryFill//Symmetry16=16: glide reflection rotation frieze"), image : "Symmetry Fill/s15.png" },
// The Wallpaper tilings 2D tilings on an infinite plane
{ item: localize("$$$/DecoScripts/SymmetryFill//Symmetry17=17: wallpaperP1 symmetry"), image : "Symmetry Fill/s16.png" },
{ item: localize("$$$/DecoScripts/SymmetryFill//Symmetry18=18: wallpaperP2 symmetry"), image : "Symmetry Fill/s17.png" },
{ item: localize("$$$/DecoScripts/SymmetryFill//Symmetry19=19: wallpaperPM symmetry"), image : "Symmetry Fill/s18.png" },
{ item: localize("$$$/DecoScripts/SymmetryFill//Symmetry20=20: wallpaperPG symmetry"), image : "Symmetry Fill/s19.png" },
{ item: localize("$$$/DecoScripts/SymmetryFill//Symmetry21=21: wallpaperPMM symmetry"), image : "Symmetry Fill/s20.png" },
{ item: localize("$$$/DecoScripts/SymmetryFill//Symmetry22=22: wallpaperCM symmetry"), image : "Symmetry Fill/s21.png" },
{ item: localize("$$$/DecoScripts/SymmetryFill//Symmetry23=23: wallpaperPMG symmetry"), image : "Symmetry Fill/s22.png" },
{ item: localize("$$$/DecoScripts/SymmetryFill//Symmetry24=24: wallpaperPGG symmetry"), image : "Symmetry Fill/s23.png" },
{ item: localize("$$$/DecoScripts/SymmetryFill//Symmetry25=25: wallpaperCMM symmetry"), image : "Symmetry Fill/s24.png" },
{ item: localize("$$$/DecoScripts/SymmetryFill//Symmetry26=26: wallpaperP4 symmetry"), image : "Symmetry Fill/s25.png" },
{ item: localize("$$$/DecoScripts/SymmetryFill//Symmetry27=27: wallpaperP4M symmetry"), image : "Symmetry Fill/s26.png" },
{ item: localize("$$$/DecoScripts/SymmetryFill//Symmetry29=28: wallpaperP4G symmetry"), image : "Symmetry Fill/s27.png" },
{ item: localize("$$$/DecoScripts/SymmetryFill//Symmetry30=29: wallpaperP3 symmetry"), image : "Symmetry Fill/s28.png" },
{ item: localize("$$$/DecoScripts/SymmetryFill//Symmetry31=30: wallpaperP3M1 symmetry"), image : "Symmetry Fill/s29.png" },
{ item: localize("$$$/DecoScripts/SymmetryFill//Symmetry32=31: wallpaperP31M symmetry"), image : "Symmetry Fill/s30.png" },
{ item: localize("$$$/DecoScripts/SymmetryFill//Symmetry33=32: wallpaperP6 symmetry"), image : "Symmetry Fill/s31.png" },
{ item: localize("$$$/DecoScripts/SymmetryFill//Symmetry34=33: wallpaperP6M symmetry"), image : "Symmetry Fill/s32.png" },
],
itemValue : modelParameters.symmetryType, itemMin : 0, itemMax : 0, varName : 'symmetryType' },
{ itemName : localize("$$$/DecoScripts/PatternScale=Pattern Scale:") ,
itemUnit : "", itemType : 'slider', itemValue : modelParameters.patternScale, itemMin : 0.25, itemMax : 1.25, itemStep : 0.01, varName : 'patternScale' },
{ itemName : localize("$$$/DecoScripts/SymmetryFill/PatternTranslationX=Pattern translation along width:") ,
itemUnit : localize("$$$/DecoScripts/Units/percentOfWidth=% of width"),
itemType : 'slider', itemValue : modelParameters.patternTranslationX, itemMin : -100, itemMax : 100, itemStep : 1, varName : 'patternTranslationX' },
{ itemName : localize("$$$/DecoScripts/SymmetryFill/PatternTranslationY=Pattern translation along height:") ,
itemUnit : localize("$$$/DecoScripts/Units/percentOfHeight=% of height"),
itemType : 'slider', itemValue : modelParameters.patternTranslationY, itemMin : -100, itemMax : 100, itemStep : 1, varName : 'patternTranslationY' },
{ 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)