[Closed] instancing lights
hey guys, i’m working on a script that instances similar lights on its own. it should loop trough all lights and compare each light in another loop with every other light based on their properties instead of a script that would require manually picking a base-object and targets. it kinda works but i’m left with more instances than i intended to have and i lack the idea how to collect the surplus objects/instances into another array which i could delete afterwards.
here is the code:
select(lights)
light_array = #()
delete_light = #()
for i=1 to selection.count do
(
if classof selection[i]==VRaySun do (deselect selection[i])
if classof selection[i]==VRayIES do (deselect selection[i])
if classof selection[i]==VRayAmbientLight do (deselect selection[i])
if classof selection[i]==mr_Sky do (deselect selection[i])
if classof selection[i]==mr_Sun do (deselect selection[i])
if superclassof selection[i]==light do
(
append light_array selection[i]
)
)
for c=1 to light_array.count do
(
current_light = light_array[c]
for n=1 to light_array.count do
(
next_light = light_array[n]
if current_light.type == #Free_Point OR
current_light.type == #Free_Line OR
current_light.type == #Free_Rectangle OR
current_light.type == #Free_Disc OR
current_light.type == #Free_Sphere OR
current_light.type == #Free_Cylinder OR
current_light.type == #Target_Point OR
current_light.type == #Target_Line OR
current_light.type == #Target_Rectangle OR
current_light.type == #Target_Disc OR
current_light.type == #Target_Sphere OR
current_light.type == #Target_Cylinder do
(
if current_light.type == next_light.type do
(
if current_light.rgbFilter == next_light.rgbFilter do
(
if current_light.intensity == next_light.intensity do
(
if current_light.castShadows == next_light.castShadows do
(
if current_light.light_length == next_light.light_length do
(
if current_light.light_radius == next_light.light_radius do
(
if current_light.webFile == next_light.webFile do
(
if current_light.affectSpecular == next_light.affectSpecular do
(
if current_light.affectDiffuse == next_light.affectDiffuse do
(
if current_light.ambientOnly == next_light.ambientOnly do
(
appendIfUnique delete_light next_light
appendIfUnique delete_light current_light
light_instance = instance(next_light)
light_instance.rotation = current_light.rotation
light_instance.position = current_light.position
light_instance.scale = current_light.scale
light_instance.name = current_light.name
light_instance.wirecolor = [255,229,0]
)
)
)
)
)
)
)
)
)
)
)
)
)
for d=1 to delete_light.count do
(
delete delete_light[d]
)
if i have 2 lights and run the script then im left with 2×2 instances. if i have 3 lights then 3×3 (…)
does anybody have an idea how to adress that?
my script also compares standard and vray lights, but i have shortened it to photometric lights only for testing purpose
you should learn getproperty, setproperty , get propnames in max help file …also to get instance object from current object you could use instanceMgr.GetInstance…try to read them.
for i=1 to selection.count do
(
if classof selection[i]==VRaySun do (deselect selection[i])
if classof selection[i]==VRayIES do (deselect selection[i])
if classof selection[i]==VRayAmbientLight do (deselect selection[i])
if classof selection[i]==mr_Sky do (deselect selection[i])
if classof selection[i]==mr_Sun do (deselect selection[i])
if superclassof selection[i]==light do
(
append light_array selection[i]
)
)
you could replace that function to like this :
theLigths=#()
sel= selection as array -- save selection into memory
clearSelection()
mapped fn collectLightonSel nodes &theLights = --collect object in selection where is light superclass
(
if (findItem theLights nodes)==0 and isKindOf nodes light do append theLights nodes
) --it will return OK, and this function do not filter instanced object ..to get main obj from instanced obj you must play with instanceMgr..which I left for you to play with
collectLightonSel sel &theLigths --run this to get light array in selection but only return array
free sel -- free-ing array that is unused anymore
theLigths -- this is return array
---your next function........
Hope this help little …
this is the right direction…
but it would be more helpful if your code works exactly right. but it doesn’t.
the idea was to collect not all lights, but some lights excepting specific classes…
ok. i can show how i would do it:
(
excludeLightClasses = #(VRaySun, VRayIES, VRayAmbientLight, mr_Sky, mr_Sun)
fn collectLights nodes exclude:#() =
(
for node in nodes where iskindof node Light and (finditem exclude (classof node)) == 0 collect node
)
mylights = collectLights selection exclude:excludeLightClasses -- selection, list of nodes, lights, etc.
)
next task is to compare nodes by their property values…
first you have to be sure that the current light is right:
(
rightTypes =
#(
#Free_Point, #Free_Line, #Free_Rectangle,
#Free_Disc, #Free_Sphere, #Free_Cylinder,
#Target_Point, #Target_Line, #Target_Rectangle,
#Target_Disc, #Target_Sphere, #Target_Cylinder
)
fn isRightLightType node types:#() =
(
hasproperty node #type and (finditem types (getproperty node #type)) > 0
)
isRightLightType currentLight types:rightTypes
)
next is to compare by properties:
(
checkProps = #(#intensity, #castShadows, #light_length, #light_radius, #webFile, #affectSpecular, #affectDiffuse, #ambientOnly)
fn areLightsEqual node1 node2 props:#() =
(
equal = true
for p in props while equal do
(
equal = ((hasproperty node1 p) and (hasproperty node2 p) and ((getproperty node1 p) == (getproperty node2 p)))
)
equal
)
if areLightsEqual currentLight someLight props:checkProps do ()
)
and finally… make one node an instance of another…
all that you need is to replace a source’s baseobject with a target’s one:
(
replaceinstances someLight currentLight
)
thanks guys! this is very helpful, yet when i put together those code snippets i get a error:
>> MAXScript Fehler beim Makroskript Ausnahme:
-- Nein ""showProperties"" Funktion für undefined <<
sorry, it’s german… i use max 2016 if that is an issue
your way of coding is way beyond my capabilities as you surely noticed and i really appreciate your help. i’m going to read through the max help files as suggested and see if i can get this to work