ScriptSpot

Forum topic · Scripts Wanted

how to make array and select this after cloning

By W DIGITAL · 2010-11-21

Description

hi, can anyone help me with this, its very simple, i simply want to select the clones after script has run,
select mycyl does not work, and i have tried others stuff as well (also reading anubis array tutorial), i still cant get it, and cannot find help in maxscript documentation

isnt mycyl already an array, or if not, how do i make this one, and then how do i select this array?

thanks for your help!

on btndo pressed Do (sel = getCurrentSelection()
sf = sel
if (Clone.state == 1) then(
c=objCount.value
for i=1 to c do (
mycyl = copy sf
)
)

Comments (32)

W DIGITAL · 2010-11-22

its beautiful anubis
you did a great job!!!!!!!!!!!!!!!!!!!

and soon ill show u why i needed this so badly :)

Anubis · 2010-11-22

i realy need to go :) but will reply on this.

1st - if you wish to end with 50 objects then insted to use insert + loop to num-1, you can just rid of your original/source objects after cloning by deleting them.

2nd - to access this var - cloneCollection after reopening the dialog it should be global variable.

ok, here is my last assistance on this script ;-)
changes in v.1.1:

on btndo pressed do
(
	objs = selection as array
	if objs.count > 0 do
	(
		num = objCount.value
		type = Clone.state
		objArray = #()
		for c = 1 to num do (
			CloneAndSelect objs type
			join objArray (getCurrentSelection())
		)
		select objArray
	)
	delete objs -- delete source objects
	-- for the select button - make your cloneCollection global var
	global cloneCollection = objArray
)
on btnCselect pressed Do
(
	if cloneCollection != undefined do
		select (for i in cloneCollection where isValidObj i collect i)
)
Attachments

W DIGITAL · 2010-11-22

hehe

ok :)

for c = 1 to (num-1) do (

ok that was the line i also needed to change, so i press 50 clones now
and i have 50 objects selected

for the user, simple and straightforward

for the code- headache! :D

-------------------------
i try to make a button to select this array, so when i deselect it later i can still get back to it

similar to SFlowCollection,

------------------------------

for c = 1 to (num-1) do (
CloneAndSelect objs type
join objArray (getCurrentSelection())

)
--insertItem objs objArray 1
select objArray

sel = objArray
cloneCollection = sel
)
)

on btnCselect pressed Do
(
if cloneCollection != undefined do
--select (for i in cloneCollection where isValidObj i collect i)
)

W DIGITAL · 2010-11-22

newObjs = for i = (currObjs+0) to objects.count collect objects[i]

changed 1 to 0

got it!!!

see i have no idea what i do there :)
trial and error ^_^

Anubis · 2010-11-22

dont worry,
even some mediate scripters hit problems on such codes,
also even some advanced scripters not know/understand mapping get/set operations at all.

after a time of learning everything will become clear to you :)
now i have job to do and leave you to continue alone on this.

cheers

W DIGITAL · 2010-11-22

hey

how come this line dont work anymore?

would like ALL objects to be selected :D

insertItem objs objArray 1

Anubis · 2010-11-22

oh, this come from previous example where the var hold single object.

W DIGITAL · 2010-11-22

oh my god
thank you

if i could i would give you a hug now :)

what i learn from all this?

functions are great, but dont use inside button :)

case types are also great, save yourself some code

but most of all-

anubis- greatest maxscripter of all time :D

haha, thanksbut what you

Anubis · 2010-11-22

haha, thanks
but what you mean not use functions inside button?
you can use them anywhere in the code :)

see attachment

Anubis · 2010-11-22

oh man :) i knew you can fight easy with this script, so i wrote it and attached.

log whats new:
- new function to clone as copy/inst/ref.
- modification of button event (using Join() function)

-- new CloneAndSelect function:
fn CloneAndSelect objArray type = (
	currObjs = objects.count
	case type of (
		1: copy objArray
		2: instance objArray
		3: reference objArray
	)
	newObjs = for i = (currObjs+1) to objects.count collect objects[i]
	select newObjs
)
-- new button event:
on btndo pressed do
(
	objs = selection as array
	if objs.count > 0 do
	(
		num = objCount.value
		type = Clone.state
		objArray = #() -- empty array
		for c = 1 to num do (
			CloneAndSelect objs type
			join objArray (getCurrentSelection())
		)
		select objArray
	)
)

get attached script and enjoy

Attachments

W DIGITAL · 2010-11-22

anubis
i really appreciate your help
and i have been trying for past 4hours to get this stupid code to work
the clones was no problem, only this silly selection at the end

now i really try with your copy function

but of course it not work-
your versionworked
but it only made 2 copies, and not the value given in the spinner objCount-
so i try, i really try to make it work but of course it doesnt

on btndo pressed Do
(
--local boxes = selection as array

fn CopyAndSelect objArray = (
currObjs = objects.count
c = objcount.value
copy objArray
newObjs = for i = (currObjs+1) to c collect objects[i]
select newObjs
)

CopyAndSelect (getCurrentSelection())

)

W DIGITAL · 2010-11-22

haha

i tried exactly that line
local boxes = selection as array

but of course it not work :)

but i guess with your copy and select function it should work
trying now

W DIGITAL · 2010-11-22

ok now i am totally confused, head is spinning :|

on btnClone pressed Do (
local boxes = selection as array
--obj = selection[1]
num = objCount.value-1
type = Clone.state
objArray = (
case type of (
1: for c = 1 to num collect (copy obj)
2: for c = 1 to num collect (instance obj)
3: for c = 1 to num collect (reference obj)
)
)
insertItem boxes objArray 1

select objArray

)

can you just tell me how i can have this (your code) on more than one object
the code i had before worked fine on more objects, and now it doesnt :(

write your custom functions

Anubis · 2010-11-22

hehe, you replace the single node with array of objects:

local boxes = selection as array
--obj = selection[1]

while still using Max builtin mapped functions - copy(), instance() and reference(). ah, nor yet change the variable 'obj' into the 'copy obj' and so on.

you have a CopyAndSelect function from me. you can a) extend it to clone instances and references, or b) write another 2 functions for that purpose. and finally rewrite the code dependent on how you wrote your function(s).

Copy is a mapped function

Anubis · 2010-11-22

Most mapped functions (like Copy) return OK, not array of objects then called on objectset/collection of objects.

-- simple explanation:
b1 = box()
b2 = copy b1
b2 -->> $Box:Box02 @ [0.000000,0.000000,0.000000]
-- that mean you can set to variable the new clone and operate on it
b3 = copy #(b1,b2) -->> OK
b3 -->> OK
-- that mean you can't do anything usefully with this value,
-- i.e. you can't assign the new array of clones to variable (directly)
-- and need to collect your new clones to select them (or do something else).

-- function that copy multiple objects and select the new clones at the end:
fn CopyAndSelect objArray = (
	currObjs = objects.count
	copy objArray
	newObjs = for i = (currObjs+1) to objects.count collect objects[i]
	select newObjs
)
-- exaple usage of the function:
CopyAndSelect (getCurrentSelection())

hope this help ;-)

W DIGITAL · 2010-11-21

hi anubis

now i realize
it only lets me clone one object :(

obj = selection[1]

but i want freedom to clone 2 or 10 objects
instantly

how i change it?

W DIGITAL · 2010-11-21

yes anubis

i really wish i could program
have so many ideas as you know :)

ok, just one question

how can i make a button
which just selects this array?

Button btncselect "C"

on btnCselect pressed Do (

select objArray

)

does not work :D

W DIGITAL · 2010-11-21

yes ok i forgot in the code here to write obj_copy #()

but i have done it

the code from budi i still get error

> MAXScript Rollout Handler Exception: -- Runtime error: operation requires a collection of nodes, got: OK <<

code:
rollout roClone "clone"
(
spinner objCount "#:" range:[1,100,50] type:#integer across:2 align:#left width:60
button btndo
radiobuttons clone labels:#("Copy", "Instance","Reference") across:2

on btndo pressed Do
(-- start btndo
sel = getCurrentSelection()
sf = sel
obj_copy=#() -- empty array
----------------------
if (Clone.state == 1) then
(
c=objCount.value
for i=1 to c do
(
mycyl = copy sf
append obj_copy mycyl -- append
)
)
----------------------
select obj_copy -- select copy array colection only

--selectmore obj_copy -- select copy array colection with original selection
)-- end btndo

)createDialog roClone 120 100

i am happy i have ur solution that works

but if i can know why first solution not work
then i learn something even more :D

nice to see you wish to learn :)

Anubis · 2010-11-21

hehe, i see you made 2 forum topics for the same question.
ok, i'll write (soon) an example to help on understanding difference btw single/multiple cloning ;-)

Budi G · 2010-11-22

so, a problem has been resolved ... :D
congratulation V

My English is poor to explain a lot about it.
so sorry for that...

and thanks to anubis ;D

W DIGITAL · 2010-11-22

budi i wrote u email

still thanks for your help as well!

Budi G · 2010-11-22

I've replied to your email philz

W DIGITAL · 2010-11-21

thanks anubis
your code worked perfectly
and nicer to have only small amount of code

but since i do want to understand it

i do not understand the error still, single noder or cloned collection of objects

i dont understand waht the problem was :)

Anubis · 2010-11-21

hmm, i wrote about this. then you clone collection of nodes Max return OK, and that 'value' cant helps to do anything with it :)

W DIGITAL · 2010-11-21

>> MAXScript Rollout Handler Exception: -- No ""append"" function for undefined <<

rollout roClone "clone"
(
spinner objCount "#:" range:[1,100,50] type:#integer across:2 align:#left width:60
button btndo
radiobuttons clone labels:#("Copy", "Instance","Reference") across:2

on btndo pressed Do
(
sel = getCurrentSelection()
sf = sel
if (Clone.state == 1) then
(
c=objCount.value
for i=1 to c do
(
mycyl = copy sf
append obj_copy mycyl
)
)

select obj_copy
)
)createDialog roClone 120 100

your array is undefined

Anubis · 2010-11-21

-- No ""append"" function for undefined
of course :) , you miss/remove array definition for 'obj_copy'
see the Budi example:

on btndo pressed Do 
(-- start btndo
   sel = getCurrentSelection()
   sf = sel
   obj_copy=#() -- empty array
----------------------
...

also check my example below.

try this

Anubis · 2010-11-21

on btndo pressed do
(
	-- setup var's (for clear reading):
	obj = selection[1] -- your src obj to clone
	num = objCount.value -- your spinner amout value
	type = Clone.state -- your rbtn state
	-- clone and collect new obj's in one step:
	objArray = (
		case type of (
			1: for c = 1 to num collect (copy obj)
			2: for c = 1 to num collect (instance obj)
			3: for c = 1 to num collect (reference obj)
		)
	)
	select objArray -- select new obj's
	-- Note: that not select your src obj (only the new clones)
)
-- in case you need to select the src obj as well,
-- you can use append() to select it at the end (last item)
-- or use insertItem() to put it where needed.
-- For example, if you insert next line before 'select objArray':
insertItem obj objArray 1
-- ...then your scr obj will be the 1st selected object.
-- 
-- cheers!

W DIGITAL · 2010-11-21

:(

>> MAXScript Rollout Handler Exception: -- Runtime error: operation requires a collection of nodes, got: OK <<

the way you said it now is the way i implemented it
with this error :(

it come from multi-cloning

Anubis · 2010-11-21

if you copy single node then the return value is the node, else - then clone collection of objects - Max return OK. there is why you get this error ;-)

quote form the help:

getCurrentSelection()
--Returns the current selection as an array.

W DIGITAL · 2010-11-21

hi budi, thanks alot for your help
but i get runtime error when inserting into my script:
>> MAXScript Rollout Handler Exception: -- Runtime error: operation requires a collection of nodes, got: OK <<

also i try .ms with just this nothing else:
rollout roClone "clone"
(
spinner objCount "#:" range:[1,100,50] type:#integer across:2 align:#left width:60
button btndo
radiobuttons clone labels:#("Copy", "Instance","Reference") across:2

on btndo pressed Do
(
obj_copy=#() ---make empty array colection
----------------------
-- put here your other script
for i=1 to c do
(
mycyl = copy sf -- copy the object
append obj_copy mycyl -- this add new object into obj_copy colection
)

----------------------
--- select array colection after looping

)select obj_copy

)createDialog roClone 120 100

and with this script i get this error:
>> MAXScript Rollout Handler Exception: -- Unable to convert: undefined to type: Integer <<

Budi G · 2010-11-21

ok sorry, I have edited and put it together with your script :)


on btndo pressed Do 
(-- start btndo
   sel = getCurrentSelection()
   sf = sel
   obj_copy=#() -- empty array
----------------------
  if (Clone.state == 1) then
  (
    c=objCount.value
    for i=1 to c do 
    (
      mycyl = copy sf
      append obj_copy mycyl -- append
    )
  )
----------------------
 select obj_copy -- select copy array colection only
 --selectmore obj_copy -- select copy array colection with original selection
)-- end btndo

Budi G · 2010-11-21


on btndo pressed Do
(
obj_copy=#() ---make empty array colection
----------------------
-- put here the other scripts
for i=1 to c do 
(    
  mycyl = copy sf -- copy the object
  append obj_copy mycyl -- this add new object into obj_copy colection
)

----------------------
select obj_copy --- select array colection after looping
)