Notifications
Clear all

[Closed] shadowtype and Dropdownlist

hello all,
i need he;p for this one. im trying to do a tool to change light propertie in a massive ways so they are ALL the same. (not very useful its mainly to learn)
so anyways i’m trying to add a drop downlist for the shadowtype.
it work ie. not error message but the shadow doesnt change. So here the script for those who dare.

BTW its not the main point of the thread but if some of you found better way to build script or optimisation trick, i’ll be more than happy to heard from .

--modificateur de proprieter massive du meme type d'object
  -- par exemple change les multiplier des lumieres
  -- creer par David "Daedalus" Bordeleau
  --premier script qui marche (sans jambe)
  --========================================================
  --creation des omni de test
  --for i =  1 to 19 do omnilight()
  --for  i in $omni* do i.pos = random [-500,-500,-500] [500,500,500]
  
  
  
  
  FN  SelectIsLight   = 
  (
  select (for o in lights where hasproperty o "multiplier" collect o )  
  )
  
  utility  test "light test"
  (
  button SelectL "EnWouye Batard!"
  group"light Properties"
  (
  	checkbox LghtOnOff "use Light" 
  	colorpicker lghtCLR "light Color" color:[0,0,0] 
  	--checkbox ShadowOnOff "Shadow On/Off" 
  
  	dropdownlist ShadowType "ShadowType" items:#("Shadow map","raytraced","area Light")
  	)
  Group "multiplicateur"
  	(
  	spinner multiplier "multiplier" range:[-100.0,100.0,1.0] type:#float 
  	)
  
  group "NEAR ATTENUATION"
  	(
  	Checkbox UseNearAtt "use near Attenuation ??" 
  	Checkbox ShowNearAtt "Show Near Attenuation ??"  align:#Left
  
  	-- choisit d'utiliser le nearAttenuation
  	spinner nearAttenStart "Near Att Start" range:[-1000.0,1000.0,1.0] type:#float
  	spinner nearAttenEnd "Near Att End" range:[-1000.0,1000.0,1.0] type:#float
  	)
  
  Group "FAR ATTENUATION"
  (
  	Checkbox UseFarAtt "use far Attenuation ??"  align:#Left
  	Checkbox ShowFarAtt "Show far Attenuation ??"  align:#Left
  
  	-- choisit d'utiliser le FarAttenuation
  	spinner FarAttenStart "Far Att Start" range:[-1000.0,1000.0,1.0] type:#float
  	spinner FarAttenEnd "Far Att End" range:[-1000.0,1000.0,1.0] type:#float
  	)
  	
  	
  	--=========================================
  	-- setting des controleur /bouton / etc 
  	--=========================================
  
  on SelectL pressed do SelectIsLight() -- choisit toute les lumiere
  
  on  LghtOnOff   changed state do $.enabled = state 
  --  ShadowOnOff chaged state do $.  = state
  on  multiplier  changed val do  $.multiplier = val -- modifie le multiplpicateur
  
  on shadowtype.selection  changed state do 
  	(
  			
  	if shadowtype.state == 1  then $.shadowgenerator = shadowmap()
  	if shadowtype.state == 2  then $.shadowgenerator = raytrace_shadow()
  	if shadowtype.state == 3  then $.shadowgenerator = area_shadow()
  	)
  
  on lghtCLR changed val do  $.color = val 
  
  --near attenuation control
  
  on UseNearAtt changed state do $.useNearAtten  = state
  on ShowNearAtt changed state do $.ShowNearAtten  = state
  on  nearAttenStart  changed val do  $.nearAttenstart = val
  on  nearAttenEnd  changed val do  $.nearAttenEnd = val
  
  --Far attenuation control
  
  on UseFarAtt changed state do $.useFarAtten  = state
  on ShowFarAtt changed state do $.ShowFarAtten  = state
  on  farAttenstart  changed val do  $.FarAttenStart = val
  on  farAttenEnd  changed val do  $.FarAttenEnd = val
  
   
  
  )
  
  
9 Replies

This is what you’ve got:

on shadowtype.selection changed state do 
(	
  if shadowtype.state == 1 then $.shadowgenerator = shadowmap()
  if shadowtype.state == 2 then $.shadowgenerator = raytrace_shadow()
  if shadowtype.state == 3 then $.shadowgenerator = area_shadow()
)

This is how it should look:

 on shadowtype selected state do 
(
  if state == 1 then $.shadowGenerator = shadowMap()
  if state == 2 then $.shadowGenerator = raytraceShadow() 
  if state == 3 then $.shadowGenerator = area_Shadows()
)

I wouldn’t recommend selecting your objects with a function the way you have it set up. You should store the lights in an array or something, and manipulate the items in the array, or base it on current selection.

Stev

thank stev for the tips
also i got some prob with the .castshadows
i use


 checkbox  ShadowOn "use shadow"  
  on  ShadowOn	changed state do $.castshadows = state 
 

but nothing seem to work the strange part is ,i used the same line but for omni.enable and it work fine. i tough since they are both boolean they should work the same but look like i was wrong.

It is a special case. READ THE MANUAL!

<light>.castShadows Boolean default: false

When on, the light will cast shadows on objects.

Note:

In 3ds Max, all node-level properties are searched before base-object-level properties. If a base-object property has the same name as a node-level property, you need to search in the base object for the base object property. You should use <light>.baseObject.castShadows instead,

For example

$Omni01.baseObject.castShadows = false

Edit: Oh, That’s Why.

ok well i should have specified that i read it but didnt understand.
also when i try with the .baseobject.enabled i got a “unknow propety’ error message
Dont worry i always have the Reference open. The problem i i dont always understand what in it

You should use a loop instead of $ if you want to set a property in the baseobject.

$.castshadows
is mappable, but would set the flag in the node properties (whether the object is seen by shadow-casting lights if it is a geometry object)

$.baseobject.castshadows = true
would work with single object only, but not with multiple. Property assignment is mappable, but mappable functions can only operate one level deep (bla.property), and this is two levels (bla.bla.property).

Use
for o in selection where superclassof o == Light do o.baseobject.castshadows = true
to affect the selected lights.

The text in the Reference explains that since nodes have a .castshadows property (right-click an object > Properties… > Cast Shadows), when you select a light and try to set the identically-named property .castshadows, you are affecting the node and not the light object. This is technically a bug (somebody forgot to name the light property correctly and then it was left for backwards compatibility, with the Reference note as the fix ;))

Hope this helps.

ok lets see if i understand everything . the .CastShadows is a bug because the same word is use for light who generate the shadow and objet who create them!!

So if i want an objet to cast shadows it preferable to use the .baseobjet.castshadow = true
and a light will use $light*.castshadows = true ?
If its not that, i’m too slow for maxscript !!sigh

Btw thanks bobo and stev for your patience and help. its appreciated

1 Reply
(@bobo)
Joined: 11 months ago

Posts: 0

Exactly the opposite, but you are close.

Here is the story from the beginning:

Max 1.0 was designed to be object-oriented. This means that everything under the hood is implemented using objects (in the programming meaning of the word), with classes that define common object types, hierarchies of such classes that inherit from their ancestors and instances of these classes that inherit the properties of the classes. This way, the developers could program common behaviours once and they would propagate down to all objects deriving from these classes.

So when it came to scene objects, a NODE class object was defined that is responsible for ANY class of scene object – geometry, helpers, cameras, lights, splines, really anything that can appear in the viewport. This NODE class is what contains the visibility track, the transformation track with all its PRS etc. controllers, the object track where different plugins plug in to define what object the node will really be, the material track where a material can be attached to the node and so on.

This means that at NODE level, a light, a box and a point helper are NOT distinguishable. All these classes inherit ALL node properties, even when these properties make no sense. For example, a poin helper has a .material property in MAXScript because all NODES have a material property, eventhough a point cannot be rendered.

To see what really is going on, create a Box01 and an omni light Omni01. Open TrackView and check out their trees – you will see a track called Omni01 which IS THE NODE, with the Transform track and an Object track below it. The Object is what defines what the node will really represent.
Now type in the Listener
$Omni01.baseobject = $Box01.baseobject

Surprise!!! Instead of a Box and an Omni, now you have TWO BOXES! We instanced the base object track from the one node into the other node and turned the light into a box. As you can see, Max does not care what a NODE will represent – it depends on its baseobject track, but the rest of the node-level properties suddenly start making sense being always there…
Since the two unique nodes now use the SAME baseobject, we technically created an instance of the box – changing base object properties of either of them will change both.
(NOTE: I have covered this and more in great detail in my first DVD available from CG-Academy!)

The .castShadows property is also a node property and is used by the renderer to determine whether a geometry object will cast a shadow or not.
Because of the above, a light ALSO has the same .castShadows property in its node, although it does not make sense, as a light is not renderable like a geometry object.

When the Light classes were implemented, somebody forgot the above fact and gave the same name to the light’s property which controls whether the light will generate shadows. Without MAXScript, this does not cause any problems inside of Max. But when you try to set the Cast Shadows checkbox in the light’s UI using .castShadows, MAXScript first checks the NODE, finds a property with that name and sets it there, thus never coming to the UI you wanted to affect. Using .baseobject.castShadows tells MAXScript where the property really is and it affects the UI and not the NODE properties…

wow! thank for the little story
it explain a lot of thing.
thank you

-D-