to not forget the original topic for anyone who would like to know, here is what I get so far, if you want to mimic the rhino light properties page behavior
if your user has changed a color/falloff/intensity control in your UI, you need to do something along these lines
if (input.name() == "color")
{
foreach (var lo in GetSelectedObjects<LightObject>())
{
lo.LightGeometry.Diffuse = ((Color4f)value).ToSys();
lo.CommitChanges();
}
_doc.Views.Redraw();
}
else if (input.name() == "falloff")
{
foreach (var lo in GetSelectedObjects<LightObject>())
{
var scaleBefore = lo.LightGeometry.IntensityScale(_doc);
lo.LightGeometry.SetFalloff(value as string);
var scaleAfter = lo.LightGeometry.IntensityScale(_doc);
var scaleFactor = scaleBefore / scaleAfter;
lo.LightGeometry.Intensity *= scaleFactor;
lo.CommitChanges();
}
_doc.Views.Redraw();
}
else if (input.name() == "intensity")
{
foreach (var lo in GetSelectedObjects<LightObject>())
{
var scaleFactorInv = lo.LightGeometry.IntensityScaleInv(_doc);
lo.LightGeometry.Intensity = (double)value * scaleFactorInv;
lo.CommitChanges();
}
_doc.Views.Redraw();
}
then, when reading rhino light values to set your UI control values, you need to do something like this
foreach (var ui in _section.AttrUIs)
{
if (ui.Key == "color")
{
(ui.Value.Ctrl as UI.ColorSlider).Value = lo.LightGeometry.Diffuse.ToRgba();
}
else if (ui.Key == "falloff")
{
switch (lo.LightGeometry.Falloff())
{
case Extensions.FalloffType.Constant: (ui.Value.Ctrl as UI.DropDown).SelectedIndex = 2; break;
case Extensions.FalloffType.Linear: (ui.Value.Ctrl as UI.DropDown).SelectedIndex = 1; break;
default: /* InvSq or other */ (ui.Value.Ctrl as UI.DropDown).SelectedIndex = 0; break;
}
}
else if (ui.Key == "intensity")
{
var scaleFactor = lo.LightGeometry.IntensityScale(doc);
(ui.Value.Ctrl as UI.NumericSlider).Value = lo.LightGeometry.Intensity * scaleFactor;
}
}
and this code uses these extension methods, to simplify the light falloff api, encapsulate the document model units involvement, and make it usable while targeting the rhino 6 sdk, which lacks the Constant/Linear/InverseSquaredAttenuationVector
static properties that define the falloff modes
public enum FalloffType
{
Constant,
Linear,
InvSquare
}
public static FalloffType Falloff(this Light light)
{
if (light == null)
return FalloffType.InvSquare;
var constant = new Vector3d(1.0, 0.0, 0.0);
var linear = new Vector3d(0.0, 1.0, 0.0);
var invSquare = new Vector3d(0.0, 0.0, 1.0);
if (light.AttenuationVector.Equals(constant))
return FalloffType.Constant;
else if (light.AttenuationVector.Equals(linear))
return FalloffType.Linear;
else if (light.AttenuationVector.Equals(invSquare))
return FalloffType.InvSquare;
return FalloffType.InvSquare;
}
public static void SetFalloff(this Light light, string mode)
{
if (light == null)
return;
var constant = new Vector3d(1.0, 0.0, 0.0);
var linear = new Vector3d(0.0, 1.0, 0.0);
var invSquare = new Vector3d(0.0, 0.0, 1.0);
if (mode == "constant")
light.AttenuationVector = constant;
else if (mode == "linear")
light.AttenuationVector = linear;
else
light.AttenuationVector = invSquare;
}
public static bool NeedsIntensityScaling(this Light light)
{
return light.Falloff() != FalloffType.Constant;
}
public static double IntensityScale(this Light light, RhinoDoc doc)
{
var scale = 1.0;
if (light.NeedsIntensityScaling())
scale *= util.DocScale(doc);
return scale;
}
public static double IntensityScaleInv(this Light light, RhinoDoc doc)
{
var scale = 1.0;
if (light.NeedsIntensityScaling())
scale /= util.DocScale(doc);
return scale;
}
(there are some other helpers involved but you can infer what they do)