myara CG blog

CG Design Blog. Thoughts, experiments and experiences.

SI | Align Equal Spacing : 等間隔に整列

mAlignerに入っている「Align Equidistant」という機能があります。

等距離で整列という機能です。


昨日は仕事でメカ系のモデリングをしていた時に、ボタンがいっぱいある所がありましたが形はそれぞれ違っていました。

AlignES0.gif


このボタンを綺麗に並べたくて mAligner を使ってみたけど残念な結果でした。


AlignES1.gif

全然綺麗じゃない。


オブジェクトの場合はオブジェクトのセンターとセンターの間しか計算しないため、形状が違うとオブジェクトとオブジェクトの間隔はバラバラになってしまいます。


BBoxで計算すれば綺麗に並べられるかもと思い、昨日の夜に書いてみました。

おしいところまでいったんですけど、多分眠かったせいか、計算が可笑しくなっていて全然うまくいきませんでした。

今日はもう一度コードを見たら、一番の原因は:

距離 / (オブジェクトの数 - 1)

という所に()が入っていなかった!・・・。恥ずかしいミスです。


AlignES2.gif

これはグローバル座標しか対応していません。
位置と回転はバラバラだったらローカルは無理でしょうね。


まぁ、結局スクリプトは上手く行ったので、公開しちゃいます。


mAlign Equal Spacing

DOWNLOAD


次の mAligner に入れておこうかな。


ではでは、上手くできたっぽいからスッキリして寝ます!


おやすみ!

// Align Equal Spacing
//---------------------
// 2012/07/05
// myara

var oPSet = XSIFactory.CreateObject ( "CustomProperty" );

oPSet.name = "mAligner: Equal Spacing"

var oLay = oPSet.PPGLayout;
oLay.AddRow();
var oItem = oLay.AddButton ("esX","X");
oItem.SetAttribute( siUICX, 104);
var oItem = oLay.AddButton ("esY","Y");
oItem.SetAttribute( siUICX, 104);
var oItem = oLay.AddButton ("esZ","Z");
oItem.SetAttribute( siUICX, 104);
oLay.EndRow();

oLay.Logic = esX_OnClicked.toString()
+esY_OnClicked.toString()
+esZ_OnClicked.toString()
+alignES.toString()
;

oLay.Language = "JScript" ;

InspectObj( oPSet,null,null,3 ) ;

function esX_OnClicked(){
alignES(0)
}
function esY_OnClicked(){
alignES(1);
}
function esZ_OnClicked(){
alignES(2);
}

function alignES(opt){
// opt: 0 = X , 1 = Y, 2 = Z
var oSel = SIFilter(selection, siPolyMeshFilter)

if (oSel != null && oSel.Count > 2 ) {

// Turn Log Off
var prefs = Application.Preferences;
prefs.SetPreferenceValue( "scripting.cmdlog", false );

var AllObjs = []
var totBB = 0
for ( var i=0, a = oSel.Count; i < a; i++ ) {
var bbox = GetBBox(oSel(i))
if (opt == 0) var objMin = bbox(0), objMax = bbox(3)
if (opt == 1) var objMin = bbox(1), objMax = bbox(4)
if (opt == 2) var objMin = bbox(2), objMax = bbox(5)

if (i == 0) var totMax = objMax, totMin = objMin

if (objMin < totMin) totMin = objMin
if (objMax > totMax) totMax = objMax

totBB = totBB + (objMax - objMin)

AllObjs[i] = new Array();
AllObjs[i][0] = oSel(i) // Object
AllObjs[i][1] = (objMin + objMax) / 2 // BB Center
AllObjs[i][2] = objMax // BB Max
AllObjs[i][3] = objMin // BB Min
}

var totLength = totMax - totMin
var ES = (totLength - totBB) / (oSel.Count -1)

/*--------------------------------------
totLength = Total Bounding Box Length
totBB = Sum of objects Bounding Boxes
totLength - totBB = Space
ES = Equal Space distance
--------------------------------------*/

// Sort Array by objs position
function sortbypos (a, b){ return a[1] - b[1] }
var AllObjsSorted = AllObjs.sort(sortbypos);

// Loop the sorted Array (without the first and last obj)
for ( var i=1, a = AllObjsSorted.length; i < a-1; i++ ) {
var x = 0, y = 0, z = 0

// Calculate distance to move
if (opt == 0) x = AllObjsSorted[i-1][2] - AllObjsSorted[i][3] + ES
if (opt == 1) y = AllObjsSorted[i-1][2] - AllObjsSorted[i][3] + ES
if (opt == 2) z = AllObjsSorted[i-1][2] - AllObjsSorted[i][3] + ES

Translate(AllObjsSorted[i][0], x, y, z, siRelative, siGlobal, siObj, siXYZ);

// Update distance
if (opt == 0) AllObjsSorted[i][2] = AllObjsSorted[i][2] + x
if (opt == 1) AllObjsSorted[i][2] = AllObjsSorted[i][2] + y
if (opt == 2) AllObjsSorted[i][2] = AllObjsSorted[i][2] + z
}
}
else logmessage ("You need to select at least 3 polymesh objects", siError)
}

Comments

Comment is pending approval.

Comment is pending administrator's approval.

  • 2016/08/12(金) 23:00:23 |
  • |
  • #
  • [ Edit ]

Post a comment


Only the blog author may view the comment.

Trackbacks

Trackbacks URL
http://myara.blog.fc2.com/tb.php/144-f4acc5b1
Use trackback on this entry.