Search ProofOfProgress Blog

Sunday, March 27, 2011

Dynamically Created Rollout For Storing Matrices in Maxscript

I just found out I don't need to do this because I can place
matrices as constants within script controllers.
Doing that dynamically would be better than doing this.
But here it is anyways.


Function StoreMatrices
MatrixArray --An array of matrices to go into the "MatrixHolder" custom attribute.
HoldingObject --The object the custom attribute will be attached to.
--
--*****************************************************
--More Scripts at: www.ProofOfProgress.BlogSpot.com **
--*****************************************************
--
--Function Summary:
--Dynamically creates a custom attribute with MatrixArray.Count number of Matrices.
--Can then be accessed by: TheObject.BaseObject.MatrixHolder.Matrix5
=(
--MUST use global or execute function will not create attribute correctly.
global MatrixHolderDEF_586_214_3958;

DQ = "\""; --Double quote character.

--Header Assemble:
H01 = "MatrixHolderDEF_586_214_3958 = attributes MatrixHolder(" + "\n";
H02 = "parameters main rollout:ro_howMany(" + "\n";
H_X = H01 + H02;

--Body Code Assemble:
matrixMAXstring = MatrixArray.Count as string;
varList = "";
For i = 1 to MatrixArray.count do(
mn = i as string; --Matrix Number.
coreCode = "Matrix" + mn + " type:#matrix3;" + "\n";
varList = varList + coreCode;
)--Next i

--Footer Assemble:
F01 = ")--[params]" + "\n";
F02 = "rollout ro_howMany "+DQ+"MatrixHolder"+DQ+" (" + "\n";
F03 = "label lab1 "+DQ+"MatrixCount=="+matrixMaxString+DQ+ "\n";
F04 =")--[x]" + "\n";
F05 =")--[End Custom Attribute Def]" + "\n";
F_X = F01+F02+F03+F04+F05;

--Assemble and Execute Definition:
exe_def = H_X+varList+F_X;
Execute(exe_def);

--Add the Compiled Definition to the Object:
custAttributes.add HoldingObject MatrixHolderDEF_586_214_3958 Unique:True BaseObject:True; --*******************<<<<

--Now that your custom attribute is created with the correct number of matrix slots,
--Fill the values in.
--global global_m;

global global_HoldingObj;
global global_MatrixArray;
For m = 1 to MatrixArray.count do(
gm = m as string;
global_HoldingObj = HoldingObject.BaseObject.MatrixHolder;
global_MatrixArray = MatrixArray;
--eCode = "HoldingObject.BaseObject.MatrixHolder.Matrix" + gm +"= MatrixArray["+gm+"];"
eCode = "global_HoldingObj.Matrix" + gm + "=global_MatrixArray["+gm+"];";
Execute(eCode);
)--[next m]


--Edit: Put the adding custom attribute code into the actual EXE-string.
--The EXE-string is executing on a different thread than the rest of the code.
--So if you tried "custAttributes.add HoldingObject MatrixHolderDEF Unique:True BaseObject:True"
--After using the EXE string, it would not work. Even SLEEP would not fix the problem.

--UPDATE: It appears to be executing on a different thread..
--But it is actually a scope issue that can be fixed by using a GLOBAL.
--Look at: "Why does Execute return 'undefined' when accessing a loop variable?"
--In maxscript help for more information.

)--[FN:StoreMatrices]


--Example Code:
MatrixArray = #();
TheObject = $;
MatrixArray[1] = Matrix3 [1,1,1] [1,1,1] [1,1,1] [1,1,1];
MatrixArray[2] = Matrix3 [2,2,2] [2,2,2] [2,2,2] [2,2,2];
MatrixArray[3] = Matrix3 [3,3,3] [3,3,3] [3,3,3] [3,3,3];
MatrixArray[4] = Matrix3 [4,4,4] [4,4,4] [4,4,4] [4,4,4];
MatrixArray[5] = Matrix3 [5,5,5] [5,5,5] [5,5,5] [5,5,5];

--Test Code:
theOBJ = $;
StoreMatrices MatrixArray theOBJ;

--Test to see if one of the matrices exist.
theOBJ.BaseObject.MatrixHolder.Matrix5

No comments:

Post a Comment