// Normalize Weight Maps 0.303
// 複数ウェイトマップの値を正規化
@name "NormalizeWMaps"
@version 2.5
@warnings
@script modeler
@define DESCRIPT "Normalize WgtMaps"
var l0;
var VMapNames;
var MapNum;
var InitBlock;
main
{
selmode(DIRECT);
var SelPts = pointcount();
// 90/92/93 はpoint/poly countでUndoバッファを消費する
@if version < 2.2
undo();
@end
@if version > 2.7
undo();
@end
if(!SelPts){
error("
Need Point Select");
return;
}
var vmap = VMap(VMWEIGHT);
if(vmap == nil){
error("
Not Found Map");
return;
}
var i = 1;
while(vmap && vmap.type == VMWEIGHT){
if(vmap.name != "Edge Weight"){
VMapNames += vmap.name;
InitBlock[i] = i;
i++;
}
vmap = vmap.next();
}
MapNum = VMapNames.size();
// SubPatch(base)が必ず存在する為、ユーザユニークなMap2+1=3が存在している必要がある
if(MapNum < 3){
info("
Need 2 or more Weight Maps");
return;
}
reqbegin(DESCRIPT);
reqsize(190,364);
l0 = ctllistbox("Weight Maps", 160, 307, "lb_Count", "lb_Name");
ctlposition(l0, 5, 3);
l1 = ctlbutton(" Select All", 80, "lb_AllSelect");
ctlposition(l1, 6,312);
l2 = ctlbutton("DeSelect All",80, "lb_AllDeselect");
ctlposition(l2,85,312);
return if !reqpost();
var SelMap = getvalue(l0);
reqend();
// SelMapはIndexの入った配列。選択無しならnil
if(SelMap == nil){
error("
No Select Map");
return;
}
var SelNum = SelMap.size();
if(SelNum < 2){
error("
Need 2 or more Maps");
return;
}
/*
}else if(SelNum == MapNum){
reqbegin(DESCRIPT);
reqsize(210,110);
t0 = ctltext("* Notice *","");
ctlposition(t0, 80, 1);
t1 = ctltext("","You chose all Weight Maps. [ " + string(SelNum) + " ]");
ctlposition(t1, 2, 16);
t2 = ctltext("","When Modeler had a lot of Weight Maps,");
ctlposition(t2, 2, 31);
t3 = ctltext("","it takes time.");
ctlposition(t3, 2, 46);
t4 = ctltext("** OK? **","");
ctlposition(t4, 78, 54);
return if !reqpost();
reqend();
}
*/
editbegin();
var SrcMaps[SelNum];
for(i = 1; i <= SelNum; i++) SrcMaps[i] = VMap(VMWEIGHT, VMapNames[SelMap[i]]);
var Val;
var StoreTotalVal;
var StoreVal[SelNum];
for(i = 1; i <= SelPts; i++){
StoreTotalVal = 0.0;
for(c = 1; c <= SelNum; c++){
// 配列で返る。配列に直接代入すると多次元化して破綻する(7.5のみ?)のでワンクッション置く
// マイナス値は無視する。
if(SrcMaps[c].isMapped(points[i])){
(Val) = SrcMaps[c].getValue(points[i]);
StoreVal[c] = Val;
if(Val > 0.0) StoreTotalVal = StoreTotalVal + Val;
}else{
StoreVal[c] = nil;
}
}
// 頂点のWMAP値総計が0なら何もしない。0除算の可能性も排除
if(StoreTotalVal != 0.0){
for(c = 1; c <= SelNum; c++){
if(StoreVal[c] != nil){
// 合計と等しい→それ以外のMapは0以下かnil→値に関係なく1.0(正規化)
if(StoreVal[c] == StoreTotalVal){
SrcMaps[c].setValue(points[i], 1.0);
}else if(StoreVal[c] != 0.0){
Val = StoreVal[c] / StoreTotalVal;
SrcMaps[c].setValue(points[i], Val);
}
}
}
}
}
editend();
info("
Normalized Weight Value");
}
// ------------------------
lb_Count
{ return(MapNum); }
lb_Name: Index
{ return(VMapNames[Index]); }
lb_AllSelect
{ setvalue(l0, InitBlock); }
lb_AllDeselect
{ setvalue(l0, nil); }