On 01/07/2016 at 04:55, xxxxxxxx wrote:
///////////////////////////////////////////////////////////////////////////////
// d_PolySize Effector
//
// Coffee Effector by douwe - 2012 - http://vimeo.com/douwe4d
//
// Scales MoGraph clones that are being cloned onto a Polygonal Object,
// based on the size of the Polygons.
//
// Requires a MoGraph Cloner Object in Object Mode, Distribution set to Polygon Center.
//
// Works with other Effectors;
// just make sure d_PolySize appears last in the Effectors list
// of the Effector Tab on your Cloner.
//
// Requires a Coffee Effector set to Full Control, with 3 User Data Sliders :
// 1: "Scale Factor" - Float Slider / Real / Step: 0.01 / Min: 0.01 / Max: 1.99 / Default: 1
// 2: "Range Minimum" - Float Slider / Real / Step: 0.01 / Min: 0.01 / Max: 1.99 / Default: 0.01
// 3: "Range Maximum" - Float Slider / Real / Step: 0.01 / Min: 0.01 / Slider Max: 1.99 / No Max Limit / Default: 1.99
//
//
// I patched together homemade solutions for a few obstacles I bumped into.
// If you find any bugs, or come up with ways to make this better or more efficient,
// or if you add new functionality --->
// Make me a happy camper, and please let me know, so I can learn..
//
// cheers,
// d
//
// credits to Sandi Dolšak and Nick Woolridge for the Surface Calculation Formulas
// and to Sataneev for the challenge.
///////////////////////////////////////////////////////////////////////////////
map(input, inMin, inMax, outMin, outMax)
{
var inrange;
if((inMax-inMin) != 0) { inrange = (input-inMin)/(inMax-inMin); }
else inrange = 0;
return inrange * (outMax-outMin) + outMin;
}
main(doc,op)
{
var md = GeGetMoData(op);
if (!md) return false;
var cnt = md->GetCount();
var marr = md->GetArray(MODATA_MATRIX);
var fall = md->GetFalloffs();
var cloner = md->GetGenerator();
var obj = cloner#MG_OBJECT_LINK;
var polycount = obj -> GetPolygonCount();
var poly = obj -> GetPolygons();
var points = obj -> GetPoints();
var ud_scale_factor = op#ID_USERDATA:1;
var ud_min_scale = op#ID_USERDATA:2;
var ud_max_scale = op#ID_USERDATA:3;
var i, scale, map_surface;
var hi_pol_size = 0;
var lo_pol_size = 9999999999999999999999999999;
var part_1,part_2,a,b,c,d,e,f,s;
var area = new(array,100000);
var arr_A = new(array,100000);
var arr_B = new(array,100000);
var arr_C = new(array,100000);
var arr_D = new(array,100000);
for (i = 0; i < (polycount\*4); i++) {
if (i % 4 == 0) arr_A[i/4] = points[poly _];
if (i % 4 == 1) arr_B[i/4] = points[poly _];
if (i % 4 == 2) arr_C[i/4] = points[poly _];
if (i % 4 == 3) arr_D[i/4] = points[poly _];
}
for (i = 0; i < polycount; i++) {
a = vlen(arr_A _\- arr_B _);
b = vlen(arr_B _\- arr_C _);
c = vlen(arr_A _\- arr_C _);
s = (a+b+c)/2;
part_1 = sqrt (s\*(s-a)\*(s-b)\*(s-c));
d = vlen(arr_A _\- arr_C _);
e = vlen(arr_A _\- arr_D _);
f = vlen(arr_D _\- arr_C _);
s = (d+e+f)/2;
part_2 = sqrt (s\*(s-d)\*(s-e)\*(s-f));
area _= part_1 + part_2;
if (area _< lo_pol_size){ lo_pol_size = area _; }
if (area _> hi_pol_size){ hi_pol_size = area _; }
}
for (i = cnt - 1; i >= 0; --i)
{
if (!area _){ area _= lo_pol_size; } // line for yader. in surface mode if clones > polys
map_surface = map(area _, lo_pol_size, hi_pol_size, ud_min_scale, ud_max_scale);
scale = map_surface * (ud_scale_factor) ;
marr _- >SetV1(marr _- >GetV1()\*scale);
marr _- >SetV2(marr _- >GetV2()*scale);
marr _- >SetV3(marr _- >GetV3()*scale);
}
md->SetArray(MODATA_MATRIX, marr, true);
return true;
}