Notifications
Clear all

[Closed] dynamic object creation

Hi everybody,

I am try to make an ui that will create object by changing the spinner value.
I wrote this code:


[b][b]Sph=#()
rollout testSpin "test Spinner" width:205 height:130
(
   spinner 'spn1' "nombre de Spheres" pos:[34,54] width:50 height:16 align:#left type: #integer
   
   on spn1 buttonup do
   (
      for i =1 to 1 do
      (
         s=sphere radius:10 pos:(random [-100,50,10] [100,50,10])
         append Sph s
      )
      
   )
   on spn1 buttondown do
   (
      if Sph.count> 0 do
      (
         obj=Sph[Sph.count]
         deleteitem Sph Sph.count
         delete obj
      )
   )
)
try(DestroyDialog testSpin)catch()
CreateDialog testSpin[/b][/b]

what I don’t understand is why when I increase the spinner number, it create always a new sphere but delete the old one…

Thanks.

5 Replies

I think you’ve got a few bugs in there. I’m not totally clear what you are trying to do, but I think it’s create the number of spheres in the spinner at a random location.
The following seems to work for me.

Changes:

  1. Sph is not global. It’s good practice to avoid globals.
  2. random values were set incorrectly
  3. no need to make a variable when appending the object
  4. for loop had a typo. 1 to 1 won’t get anywhere.
  5. It’s faster to Copy objects than to Create objects.
  6. On ButtonUp / ButtonDown was confusing and does not handle when you type a number with the keyboard.

rollout testSpin "test Spinner" width:205 height:130
(
   local Sph=#()
   spinner 'spn1' "nombre de Spheres" pos:[34,54] width:80 height:16 align:#left type: #integer
   on spn1 entered spinning cancel do
   (
      if not cancel do
      (
         delete Sph
         Sph=#()
         
         if (spnVal = spn1.value) != 0 do
         (
            append Sph (newSphere = sphere radius:10 pos:(random [-100,-50,-10] [100,50,10]))
            
            for i = 2 to spnVal do
            (
               append Sph (copy newSphere pos:(random [-100,-50,-10] [100,50,10]))
            )
         )
      )
   )
)
try(DestroyDialog testSpin)catch()
CreateDialog testSpin

Hi Martinez,

thanks for reply, I didn’t know this approach with cancel.
well exactly what I want to do is, when I increase the spinner or enter a value, it create the number of sphere in the spinner, BUT!
let’s say i enter 4 in the spinner, it creates 4 sphere, and it’s ok, but now I decrease the spinner at 2, i want the script to delete the 2 last spheres created, but let the 2 first sphere in the scene.
I don’t want it create from scratch the number of spheres in the spinner value, when I change the value.

Thanks

Try this:


rollout testSpin "test Spinner" width:205 height:130
(
   local Sph=#()
   local SphCount = 0
   spinner 'spn1' "nombre de Spheres" pos:[34,54] width:80 height:16 align:#left type: #integer
   on spn1 changed spnVal do
   (
    if (spnVal >= SphCount) then
    (
      for sp = (SphCount+1) to spnVal do
      (
         s=sphere radius:10 pos:(random [-100,50,10] [100,50,10])
         append Sph s
      )
    )
    else
    (
       objectsToDelete = for sp = SphCount to (spnVal+1) by -1 collect (sd = Sph[sp]; deleteItem Sph sp; sd)
       delete objectsToDelete
    )
   SphCount = spnVal
   )
)
try(DestroyDialog testSpin)catch()
CreateDialog testSpin

If you want to keep all this for all your 3dsMax session, the two local variables should be outside the rollout definition as globals.
If you increase the value spinning but cancel with right mouse button, works OK.
Left to you to implement when spinning down and then cancel (old spheres are replaced by new ones in my code).

Hi,
Thanks andres, this is it !
I have a few questions as I am a maxscript noob, but I try to health me…

inthe line : “for sp = (SphCount+1) to spnVal do…” I don’t understand why its working, let’s say i create 4 spheres and the sphere count is 2 so
for sp = 3 to 4 do…
here it would create one sphere in theory speaking no?

and here in this line:
objectsToDelete = for sp = SphCount to (spnVal+1) by -1 collect “(sd = Sph[sp]; deleteItem Sph sp; sd)” in the part between quotes, what is this syntax? can you explain me how it works?

Thanks a lot Andres!

No, this for loop would have two cycles: one for ‘sp = 3’ and another one for ‘sp = 4’

There’s nothing really extrange there:

  • The ‘for-collect loop’ collects the result of the ‘collect’ group (what you have written between quotes) into an array (‘objectsToDelete’ in this case).
  • As you are deleting items from the Sph array, the for-loop has to be counting down (decreasing value)
  • So:
    sd = Sph[sp] –> collect the last object of the Shp array (could be: sd = Sph[Sph.count] )
    deleteItem Sph sp –> delete this last item from the Shp array (could be: deleteItem Sph Sph.count). You have to do it of course after the previous line.
    sd –> as this is the last group instruction, this is the result of the ‘collect cycle’, so you store the object in the ‘objectsToDelete’ array.

Once you have all the objects to delete in an array, you delete all them at once.

P.S.: As my English is not good at all, if you can’t understand it don’t hesitate to write me a private message in French or Spanish.