bs_head.png

FireAlpaca ブラシスクリプト仕様書

firealpaca.com

1. 概要

FireAlpaca はブラシ処理でスクリプト(Lua) を用いたプログラム制御が行えます。プログラム制御をすることで、プリセットに用意したような自由度の高いブラシを作成することが可能です。ブラシスクリプトは、拡張子 bs (*.bs) のUTF-8 (BOMなし) で作成します。

作成したブラシスクリプトは、

・ブラシリストウィンドウにドロップ

・ブラシリストウィンドウの下、左から3番目のアイコン (追加(スクリプト)) から追加

の二通りの方法で使用することができます。

一番シンプルなスクリプトは、こんな具合です。

function  main( x, y, p )

 
local  r,g,b,a = bs_pixel_get( x, y )
 bs_pixel_set( x,y,
255 -r, 255 -g, 255 -b, 255  )
 
return   1
end

ブラシ描画に使うマウスやタブレット座標の各頂点間を、1/100ずつ進むごとに、main( x,y,p ) 関数が呼ばれます。かなりの頻度で呼ばれる事になるので、 間隔調整が必要 になります。

bs0.png

上記のスクリプトの場合、bs_pixel_get 命令で、x,y座標のRGBA値 (色と不透明度) を取得し、bs_pixel_set 命令で、RGB値を反転した値のピクセルを書き込むような処理になっています。

何かしら描画した場合は return 1 を、何も描かなかった場合は return 0 してください。

次はもう少し複雑なスクリプトを見てみましょう。

function  main( x, y, p )

 
local  w = bs_width()
 
if  w < 5   then
   w =
5
 
end

 
if   not  firstDraw then
   
local  distance = bs_distance( lastDrawX - x, lastDrawY - y )
   
if  distance < w then
     
return   0
   
end
 
end

 
local  dx,dy = bs_dir()
 
local  nx,ny = bs_normal()

 bs_polygon( x + nx * w/
3 , y + ny * w/ 3  )
 bs_polygon( x - nx * w/
3 , y - ny * w/ 3  )
 bs_polygon( x + dx * w, y + dy * w )

 
local  r,g,b = bs_fore()
 bs_fill( r,g,b,
255  )

 lastDrawX = x
 lastDrawY = y
 firstDraw =
false

 
return   1
end

lastDrawX =
0
lastDrawY =
0
firstDraw =
true

20100425220548.png

このようなブラシになります。順を追って説明します。

lastDrawX = 0
lastDrawY =
0
firstDraw =
true

最後の3行に注目してください。ここはグローバル宣言部なので、 main(x,y,p) が呼び出される前 に、 一度だけ 必ず実行されます。ここでは、firstDraw = true といったように、 最初の描画を判定 する為の変数を初期化しています。

local  w = bs_width()
if  w < 5   then
 w =
5
end

bs_width() は現在のブラシ幅(直径)を所得する関数です (筆圧適用した幅)。5 pixel 以下のブラシ幅にしないように調整しています。

if   not  firstDraw then
 
local  distance = bs_distance( lastDrawX - x, lastDrawY - y )
 
if  distance < w then
   
return   0
 
end
end

最初の描画でない時、あまりにブラシが進んでいない場合は描画を避けるような処理をしています。bs_distance() で差分の距離を測っています。

local  dx,dy = bs_dir()
local  nx,ny = bs_normal()

bs_dir() はブラシの進行方向の正規ベクトル、bs_normal() はブラシの進行方向の垂直方向の正規ベクトルを取得する関数です。正規ベクトルとは、大きさが1になるベクトルのことです。進行方向が必要なので取得しています。

bs1.png

bs_polygon( x + nx * w/ 3 , y + ny * w/ 3  )
bs_polygon( x - nx * w/
3 , y - ny * w/ 3  )
bs_polygon( x + dx * w, y + dy * w )

bs_polygon() は多角形を設定する命令です。現在の座標値 x, y をベースに、進行方向を指す3頂点を指定しています。

bs2.png

local  r,g,b = bs_fore()
bs_fill( r,g,b,
255  )

bs_fore() で前景色のRGB値を取得し、その色を使い bs_fill() で先ほど定義した3頂点を塗りつぶしています。

ストロークの最後だけ何かしたい

全てのストローク処理が終わった後、last関数が呼ばれます。このスクリプトを参考にしてください。 last関数は実装されていなくても構いません

function  last( x, y, p )

 
local  r,g,b = bs_fore()
 
local  w = bs_width_max()
 bs_ellipse( x, y, w*
2 , w, 0 , r,g,b, bs_opaque()* 255  )
 
return   1
end

function  main( x, y, p )
 
return   1
end

パラメータの扱い

function  param1()
 
return   "param1" , 0 , 100 , 50
end

function  param2()
 
return   "param2" , 50 , 100 , 75
end

function  param3()
 
return   "param3" , 10 , 20 , 15
end

function  param4()
 
return   "checked" , 0 , 1 , 0
end

function  param5()
 
return   "unchecked" , 0 , 1 , 1
end

スクリプト内に param1(), param2(), param3() ... という関数を定義しておくと、ブラシコントロールウィンドウでパラメータ設定、取得できるようになります (最大10個。param1 から param10 まで)。

第1 戻り値

  ブラシコントロール上に表示される文字です (UTF8 の文字列)

第2 戻り値

  設定の 最小値 です(0~100まで)

第3 戻り値

  設定の 最大値 です(0~100まで)

第4 戻り値

  設定の デフォルト値 です(0~100まで)

設定値はスクリプト内で、

local  param1 = bs_param1()
local  param2 = bs_param2()
local  param3 = bs_param3()
local  param4 = bs_param4()
local  param5 = bs_param5()

といった形で取得できます。

最小値が 0、最大値が 1 の場合、チェックボックス表示 になります。チェックされている場合は1、チェックされていない場合は 0 が戻り値になります。

params.png

デフォルトのサイズ(幅・最小サイズ)

ブラシによっては、細いものを推奨するものもあれば、太いものを推奨するものもあります。

function  default_size()
 
return   17 , 0.25
end

という関数をスクリプト内で定義しておけば、デフォルトの幅、デフォルトの最小サイズを指定することができます。この場合、最大幅は17px、最小サイズは 25% になります。

基点の指定  

左右対称・回転対称ブラシなど、基点(基準点)が必要な場合があります。基点が必要なブラシは、 キャンバス上でCtrl (Command) +クリック をする事で基点が指定できます。

基点を使いたいスクリプトは、スクリプト内で、

function  use_base()
 
return   true
end

と定義しておきます。設定された起点は、

local  bsx,bsy = bs_base()

という形で、bs_base()命令を使い取得できます。

基点が指定されてない場合は、(-1,-1) が返ります。(-1,-1)の場合は、特別処理を入れておくと良いでしょう。

描画モード

指定のない通常のモードでは、カラーレイヤーならRGB好きな色を指定して描画できます。しかし、半透明で描画した際に、 重なる部分が濃く なってしまいます。滑らかなブラシ処理には向きません。そこで、

bs_setmode( 1  )

というコードを初期化部分に追加すると、通常のペンのように、半透明部分の合成が綺麗になるモードになります。ただし、RGB任意の色で図形を描画することはできず、 前景色を使った描画 になります。

bs_setmode は「最初に」「一度だけ」呼ぶようにしてください。

・通常のモード

bs0.png

・bs_setmode( 1 ) を指定

bs1.png

プレビュー中か判定する

ブラシのプレビュー画像が描画されない場合があります (マウスやタブレットの場合は問題ないのに)。時間情報 (bs_ms()) を使った場合に起こりやすい問題です。

if  bs_preview() then
 プレビュー時の特殊処理をここに挟む
end

のような感じで、bs_preview() 関数を使ってプレビュー中か判定できます。

2. API一覧 (基本命令)  

w = bs_width()
w = bs_width_max()
w = bs_width_min()

bs_width()

  筆圧を適用したブラシ幅(直径)を取得します

bs_width_max()

  ブラシの最大幅を取得します (最大筆圧時の直径)

bs_width_min()

  ブラシの最小幅を取得します (最小筆圧時の直径)

distance = bs_distance( x, y )
rad = bs_atan( x, y )
x, y = bs_rotate( x, y, radAngle )
value = bs_grand( ave, std )
milisec = bs_ms()
num = bs_count()

bs_distance( x, y )

  原点から (x,y) の距離を取得します

bs_atan( x, y )

  原点から (x,y) の角度を取得します (ラジアン)

bs_rotate( x, y, radAngle )

  x,y座標を、原点を中心に、radAngle(ラジアン) だけ回転させます

bs_grand( ave, sd1 )

  aveを中心に、±sd1の範囲に約68%の確率で収まるようなガウス分布の乱数値を取得します

bs_ms()

  OS起動時からの経過ミリ秒を取得します

bs_count()

  FireAlpaca の起動後、ブラシスクリプトが呼ばれた回数を取得します

  1ストローク毎に何かを変えたい場合などに用います

w = bs_canvas_width()
h = bs_canvas_height()
dpi = bs_canvas_dpi()
rad = bs_canvas_angle()

bs_canvas_width()

  キャンバスの幅を取得します

bs_canvas_height()

  キャンバスの高さを取得します

bs_canvas_dpi()

  キャンバスのdpiを取得します

bs_canvas_angle()

  キャンバスの回転角度を取得します (ラジアン角)

r,g,b = bs_fore()
r,g,b = bs_bg()
r,g,b = bs_forebg( t )
alpha = bs_opaque()

bs_fore()

  前景色のRGB値を取得します

bs_bg()

  背景色のRGB値を取得します

bs_forebg( t )

  前景色と背景色の補間値を取得します (0.0~1.0)

  0.0: 背景色, 0.5:中間色, 1.0: 前景色

bs_opaque()

  ブラシの不透明度 (0.0~1.0) を取得します。

  ブラシコントロールのUI上で設定されている不透明度です。

dx,dy = bs_dir()
nx,ny = bs_normal()

bs_dir()

  ブラシの進行方向のベクトルを取得します (正規ベクトル)

bs_normal()

  ブラシの進行方向から90度傾けたベクトル(法線方向) を取得します (正規ベクトル)

3. API一覧 (描画命令)

r,g,b,a = bs_pixel_get( x, y )
alpha = bs_pixel_get_alpha( x, y )
bs_pixel_set( x, y, r,g,b,a )

bs_pixel_get( x, y )

  x,y座標のRGBA値を取得します

R,G,B,A = 0~255

  1,8bppレイヤーのA値は、常に255です

bs_pixel_get_alpha( x, y )

  x,y座標のA値 (不透明度・濃度) を取得します

  alpha = 0~255

  1bppレイヤーの場合は、0 または 255 です

bs_pixel_set( x, y, r,g,b,a )

  x,y座標に、RGB値を不透明度Aで描画します

  R,G,B,A = 0~255

  bs_pixel_set を使って沢山描画するのは現実的ではありません

bs_polygon( x, y )
bs_polygon_move( dx, dy )
bs_polygon_move_center()
bs_polygon_rotate( radAngle )
bs_polygon_mul( zx, zy )
bs_polygon_clear()
rx,ry,rw,rh = bs_polygon_region()

bs_polygon( x, y )

  多角形を定義する為、頂点x,yを追加します

  三角形を定義する場合は、bs_polygon命令を三回実行します

bs_polygon_move( dx, dy )

  追加されている多角形の頂点を、dx,dyだけ移動させます

bs_polygon_move_center()

  追加されている多角形の頂点を、重心を原点に移動させます

bs_polygon_rotate( radAngle )

  追加されている多角形の頂点を、原点を中心に radAngle だけ回転させます

bs_polygon_mul( zx, zy )

  追加されている多角形の頂点を、x方向にzx倍、y方向にzy倍にします

bs_polygon_clear()

  追加されている多角形をクリアします (bs_fill 直後にも自動的にクリアされます)

rx,ry,rw,rh = bs_polygon_region()

  追加されている多角形の範囲を取得します (rx:X始点、ry:Y始点、rw:幅、rh:高さ)

  多角形が設定されていない場合、面積のない場合の戻り値は不定です

bs_bezier_begin( x, y )
bs_bezier_c( x1, y1, x2, y2, x3, y3 )
bs_bezier_v( x2, y2, x3, y3 )
bs_bezier_y( x1, y1, x3, y3 )
bs_bezier_l( x3, y3 )
bs_bezier_m( x, y )
bs_bezier_move( dx, dy )
bs_bezier_move_center()
bs_bezier_rotate( rad )
bs_bezier_mul( zx, zy )
bs_bezier_clear()
rx,ry,rw,rh = bs_bezier_region()

bs_bezier_begin( x, y )

  (x,y)を始点にベジェ曲線を定義します

  サンプルコードはこちら。ハート形状をセットする関数 set_heart を参照ください。

function  param1()
 
return   "interval" , 10 , 100 , 50
end

function  set_heart( w )
 bs_bezier_begin(
0 , 0  )
 bs_bezier_c( -
1 , - 1 , - 0.5 , - 2 , 0 , - 1.3  )
 bs_bezier_c(
0.5 , - 2 , 1 , - 1 , 0 , 0  )
 bs_bezier_mul( w, w*
0.7  )
 bs_bezier_move_center()
end

function  main( x, y, p )

 
local  w = bs_width_max()
 
if  w < 5   then
   w =
5
 
end

 
if   not  firstDraw then
   
local  distance = bs_distance( lastDrawX - x, lastDrawY - y )
   
if  distance < w* 2.0  * bs_param1()/ 100   then
     
return   0
   
end
 
end

 
local  dx,dy = bs_dir()
 
local  nx,ny = bs_normal()
 
local  r,g,b = bs_forebg( p )

 set_heart( w )
 bs_bezier_rotate( bs_atan( dx, dy ) )
 bs_bezier_move( x, y )
 bs_fill( r,g,b,
255  )

 lastDrawX = x
 lastDrawY = y
 firstDraw =
false

 
return   1
end

lastDrawX =
0
lastDrawY =
0
firstDraw =
true

heart.png

bs_bezier_c( x1, y1, x2, y2, x3, y3 )

  制御点1 (x1,y1) 制御点2 (x2,y2)、次点 (x3,y3) の辺を追加します

bs_bezier_v( x2, y2, x3, y3 )

  制御点1は現在位置、制御点2 (x2,y2)、次点 (x3,y3) の辺を追加します

bs_bezier_y( x1, y1, x3, y3 )

  制御点1 (x1,y1)、制御点2&次点 (x3,y3) の辺を追加します

bs_bezier_l( x3, y3 )

  直線の辺を加えます

bs_bezier_m( x, y )

  新規サブパスを生成します

  重なる部分は、抜けが起こります (奇偶規則)

function  main( x, y, p )

 
if   not  firstDraw then
   
local  distance = bs_distance( lastDrawX - x, lastDrawY - y )
   
if  distance < 50   then
     
return   0
   
end
 
end

 
local  r,g,b = bs_fore()

 
-- first path
 bs_bezier_begin( x,y )
 bs_bezier_l( x +
100 , y )
 bs_bezier_l( x +
100 , y + 100  )
 bs_bezier_l( x, y +
100  )
 bs_bezier_l( x, y )

 
-- second path
 bs_bezier_m( x+
10 ,y+ 10  )
 bs_bezier_l( x +
100 - 10 , y+ 10  )
 bs_bezier_l( x +
100 - 10 , y + 100 - 10  )
 bs_bezier_l( x +
10 , y + 100 - 10  )
 bs_bezier_l( x +
10 , y + 10  )

 bs_fill( r,g,b,
255  )

 lastDrawX = x
 lastDrawY = y
 firstDraw =
false

 
return   1
end

lastDrawX =
0
lastDrawY =
0
firstDraw =
true

bs_bezier_move( dx, dy )

  追加されているベジェ曲線を、dx,dyだけ移動させます

bs_bezier_move_center()

  追加されているベジェ曲線の頂点を、重心を原点に移動させます

bs_bezier_rotate( rad )

  追加されているベジェ曲線の頂点を、原点を中心に radAngle だけ回転させます

bs_bezier_mul( zx, zy )

  追加されているベジェ曲線の頂点を、x方向にzx倍、y方向にzy倍にします

bs_bezier_clear()

  追加されているパスをクリアします (bs_fill 直後にも自動的にクリアされます)

rx,ry,rw,rh = bs_bezier_region()

  追加されているパスの範囲を取得します (rx:X始点、ry:Y始点、rw:幅、rh:高さ)

  パスが設定されていない場合、面積のない場合の戻り値は不定です

bs_fill( r, g, b, a )

bs_fill( r, g, b, a )

  定義されている多角形・ベジェ曲線をRGBA値で塗りつぶします。

  アンチエイリアシングの有無はブラシ設定に依存します

  実行後、多角形・ベジェ曲線の定義はクリアされます

bs_rect( x, y, w, h, r,g,b,a )
bs_ellipse( mx, my, w, h, radAngle , r,g,b,a )

bs_rect( x, y, w, h, r,g,b,a )

  座標(x,y) に、幅高さ (w,h) の矩形を描画します

bs_ellipse( mx, my, w, h, radAngle , r,g,b,a )

  座標(mx,my) を中心に、幅高さ (w,h) 角度 (radAngle) の楕円を描画します

  アンチエイリアシングの有無はブラシ設定に依存します

  真円 (w == h) の場合、高速描画 されます

bs_foot.png