由 Truth » 12日 8月 2002年, 19:48
.addon 是 2.X 才能夠用的
還是貼成文字版本方便大家
var oSurface, oObject;
main();
function main() {
// Get the user pick his objects
if ( ! PickObjects() ) {
logmessage( "Cancelled by user" );
return;
}
// Build a PPG
ppg = DoPPG( "Dup" );
// and do the duplication and surface constraints
doDup( oSurface, oObject, ppg );
}
////////////////////////////////////////////////////////
//
// Do the object duplication and constraining.
// an option here would be to use instances instead
// especially for large duplications
//
// currently no facility for groups
// Maybe it works, I don't know, I haven't tried it.
//
///////////////////////////////////////////////////////
//{{{
function doDup( oSurface, oObject, ppg ) {
var uFrom, uTo;
var vFrom, vTo;
var uDither, vDither;
var uCount, vCount;
var doConstrain;
var u,v;
// get the user params from the Dup ppg
uFrom = getValue( ppg + ".uFrom" );
uTo = getValue( ppg + ".uTo" );
vFrom = getValue( ppg + ".vFrom" );
vTo = getValue( ppg + ".vTo" );
doConstrain = getValue( ppg + ".Tangency" );
uCount = getValue( ppg + ".uCount" ) - 1;
vCount = getValue( ppg + ".vCount" ) - 1;
// calculate the u and v step size for the dup loop
var uStep = (uTo - uFrom)/uCount;
var vStep = (vTo - vFrom)/vCount;
uDither = getValue( ppg + ".uDither" ) / 100 * uStep;
vDither = getValue( ppg + ".vDither" ) / 100 * vStep;
vSave = vFrom
// a null to parent all these new objects to
// We don't want a cluttered Explorer and Schematic, do we.
var theRoot = GetPrim("Null", "SurfDup", null);
var Row = 1; // we can name each row of dups sensibly
// The u/v build loop
while ( uFrom <= uTo ) {
vFrom = vSave
// a null to act as parent to this v Row
var theRow = GetPrim("Null", "Row_" + Row++, null);
while ( vFrom <= vTo ) {
// duplicate the object
oDup = Duplicate( oObject, null, 2, 1, 1, 0, 0, 1, 0, 1, null, null, null, null, null, null, null, null, null, null);
// and constrain it
ApplyCns( "Surface", oDup, oSurface, null);
// do the normal constraint if our user wants us to
if ( doConstrain ) {
SetValue( oDup + ".kine.surfcns.upvct_active", true, null);
}
// calculate the u/v offset param for the surface constraint
var uOff = uFrom + (Math.random()-0.5) * uDither;
var vOff = vFrom + (Math.random()-0.5) * vDither;
// clamp to 0-1 range
uOff = Clamp( uOff );
vOff = Clamp( vOff );
SetValue( oDup + ".kine.surfcns.posu", uOff, null);
SetValue( oDup + ".kine.surfcns.posv", vOff, null);
ParentObj( theRow, oDup);
vFrom += vStep;
}
// and finally, parent this row of objects to the root null
ParentObj( theRoot, theRow);
uFrom += uStep;
}
}
///}}}
/////////////////////////////////////////
// clamp a number to lie in the range 0-2
/////////////////////////////////////////
//{{{
function Clamp( t ) {
if ( t < 0 ) {
t = 0;
}
if ( t > 1 ) {
t = 1;
}
return t;
}
//}}}
/////////////////////////////////////////
//
// build a ppg so our user can give us some
// parameters
//
// We don't build a ppg if one named 'Name'
// already exists. That way, by not deleting
// the ppg when we've finished, our user
// can get to keep the parameters for this
// script in case he needs to use them
// again. Saves some typing
//
///////////////////////////////////////////
function DoPPG( Name ) {
var ppg;
try {
// try and get a param from our ppg
var i = getvalue( Name + ".uFrom" );
// it's succeeded so get it as object
// This gets a collection of kids
var oCollection = EnumElements( Application.ActiveProject.ActiveScene.Root + "." + Name,null,null )
var e = new Enumerator(oCollection);
// so enum back up to the first element's parent
// which will be our 'name' property set.
oCollection = EnumElements( e.item(), false, null );
e = new Enumerator(oCollection);
ppg = e.item();
} catch(e) { // it's failed, so build a new ppg
ppg = buildPPG( Name );
}
// show it to the user.
InspectObj( ppg,"","SurfaceDup" ,siModal );
return ppg;
}
function buildPPG( Name ) {
var Root = Application.ActiveProject.ActiveScene.Root
var ppg = Root.AddProperty("Custom_parameter_list",false, Name);
SIAddCustomParameter( ppg, "uFrom", siDouble, 0, 0, 1, null, 5, 0, 1, null, null);
SIAddCustomParameter( ppg, "uTo", siDouble, 1, 0, 1, null, 5, 0, 1, null, null);
SIAddCustomParameter( ppg, "uDither", siDouble, 0, 0, 100, null, 5, 0, 100, null, "U Dither %");
SIAddCustomParameter( ppg, "vFrom", siDouble, 0, 0, 1, null, 5, 0, 1, null, null);
SIAddCustomParameter( ppg, "vTo", siDouble, 1, 0, 1, null, 5, 0, 1, null, null);
SIAddCustomParameter( ppg, "vDither", siDouble, 0, 0, 100, null, 5, 0, 100, null, "V Dither %");
SIAddCustomParameter( ppg, "Tangency", siBool, 0, 0, 1, null, 5, 0, 1, null, "Keep Tangency Constrained" );
SIAddCustomParameter( ppg, "uCount", siInt4, 3, 0, 100, null, 5, 0, 100, null, null);
SIAddCustomParameter( ppg, "vCount", siInt4, 3, 0, 100, null, 5, 0, 100, null, null);
return ppg;
}
///////////////////////////////////////
//
// Get the user to pick our objects
// surface first, then the object we
// want to duplicate
//
// return 0 if the user middle clicks
//
//////////////////////////////////////
//{{{
function PickObjects() {
var oBuffer = PickElement( "surface_mesh", "Pick Surface", "Pick Surface", null, null );
if ( !oBuffer.value( "ButtonPressed" ) ) {
// User cancelled pick session
return( 0 );
}
oSurface = oBuffer.value( "PickedElement" );
oBuffer = PickElement( "object", "Pick Object to Duplicate", "Pick Object to Duplicate", null, null );
if ( !oBuffer.value( "ButtonPressed" ) ) {
// User cancelled pick session
return( 0 );
}
oObject = oBuffer.value( "PickedElement" );
return 1;
}
//}}}