my messy code

Become a member of the CGSociety

Connect, Share, and Learn with our Large Growing CG Art Community. It's Free!

THREAD CLOSED
 
Thread Tools Search this Thread Display Modes
  11 November 2013
my messy code

I have code which should check are there some specific controller exist in selection of object.
This specific controllers is 12 different controllers.
I handled with it however it's slow and time consuming.
I have to go by all controllers so on the beginning is loop x 1000 to repeat operation because i dont know how to repeat for all objects.
Rest of code is

a=check if there is audio_float.controller in group of objects
if a=audio_float then do ...
a=check if there is bezier_float.controller in group of objects
if a=bezier_float then do ...
...... etc..etc


so I have to repeat for all kinds of controllers. I'm wondering how can I do this like:

list_of_controllers="audio_float,bezier_float,biped_subani,....etc"
a=check if there is list_of_controllers.controller in group of objects
if a=list_of_controllers then do ...



so my code is:

select geometry
for t=0 to 1 do
(
for o in selection do
(
---------- deselecting FLOAT WIRE
-- position
er1= classof o.pos.x_position.controller == float_wire --- returns true
if er1==true then animationonscene=1
er1= classof o.pos.y_position.controller == float_wire --- returns true
if er1==true then animationonscene=1
er1= classof o.pos.z_position.controller == float_wire --- returns true
if er1==true then animationonscene=1
-- rotation
er1= classof o.rotation.x_rotation.controller == float_wire --- returns true
if er1==true then animationonscene=1
er1= classof o.rotation.y_rotation.controller == float_wire --- returns true
if er1==true then animationonscene=1
er1= classof o.rotation.z_rotation.controller == float_wire --- returns true
if er1==true then animationonscene=1
-- scale
er1= classof o.scale.controller == scale_wire --- returns true
if er1==true then animationonscene=1

---------- deselecting FLOAT LIMIT
-- position
er1= classof o.pos.x_position.controller == float_limit --- returns true
if er1==true then animationonscene=1
er1= classof o.pos.y_position.controller == float_limit--- returns true
if er1==true then animationonscene=1
er1= classof o.pos.z_position.controller == float_limit --- returns true
if er1==true then animationonscene=1
-- rotation
er1= classof o.rotation.x_rotation.controller == float_limit --- returns true
if er1==true then animationonscene=1
er1= classof o.rotation.y_rotation.controller == float_limit --- returns true
if er1==true then animationonscene=1
er1= classof o.rotation.z_rotation.controller == float_limit --- returns true
if er1==true then animationonscene=1
-- no scale for float limit

---------- deselecting FLOAT LIST
-- position
er1= classof o.pos.x_position.controller == float_list --- returns true
if er1==true then animationonscene=1
er1= classof o.pos.y_position.controller == float_list --- returns true
if er1==true then animationonscene=1
er1= classof o.pos.z_position.controller == float_list --- returns true
if er1==true then animationonscene=1
-- rotation
er1= classof o.rotation.x_rotation.controller == float_list --- returns true
if er1==true then animationonscene=1
er1= classof o.rotation.y_rotation.controller == float_list --- returns true
if er1==true then animationonscene=1
er1= classof o.rotation.z_rotation.controller == float_list --- returns true
if er1==true then animationonscene=1
-- scale
er1= classof o.scale.controller == scale_list --- returns true
if er1==true then animationonscene=1

--etc,etc

)
)

I was trying different ways to optymize it but always i get some error.
This script is pretty slow, with rest of my list it take 1 minute to check 100 objects
 
  11 November 2013
running code on selected objects is generally slow. convert your selection to an array, and iterate that.


  
   local objList = $selection as array
  clearSelection()
  
  for o in objList do
  (
  ....
  )
 

you dont need that for t=0 to 1 either, unless thats doing something i'm missing.


also you're doing 2 checks in one. instead of caching a true/false value, and then comparing it. Just one line it.

So instead of..


   er1= classof o.pos.x_position.controller ==  float_wire --- returns true
    if er1==true then animationonscene=1
   


Do

   if ClassOf  o.pos.x_position.controller ==  float_wire then animationonscene=1
   


there are many ways of cleaning this up, but that's a start.
 
  11 November 2013
Dont Work

thanks,
I wrote simple code from elements which was given to me to test it.
I selected couple of geometry objects and fire up your code and there were error raporting in listner immediately after code is start:

-- Error occurred in anonymous codeblock; filename: E:\WORK\doctor\visual\t1.ms; position: 14; line: 1
-- Compile error: no local declarations at top level: objlist
-- In line: local objList =



local objList = $selection as array
clearSelection()

for o in objList do
(
if ClassOf o.pos.x_position.controller == float_wire then animationonscene=1
)

I also tried with local objList = $selection as array instead local objList = $selection as array and don't work to. How to fix it?
 
  11 November 2013
that error means you are trying to declare a variable in at the top level. All of your code should be within parenthesis. This is good practice in general, otherwise anything you write is 'global', which could have several undesired results.


So your code should look like
 
    (
     	
     local  objList = $selection as array
       clearSelection()
       
       for o in objList do
       (
          if ClassOf  o.pos.x_position.controller ==  float_wire then animationonscene=1
    ....
       )
    
    )
     
 
  11 November 2013
don't work and work

This code behave strange. I created box with
.pos.x_position.controller == float_list
+ another two objects with standard controllers.

and play with your code:
(
animationonscene==1
local objList = $selection as array
clearSelection()

for o in objList do
(
if ClassOf o.pos.x_position.controller == float_list then animationonscene=1
--- ....
)

)
if animationonscene==1 then messagebox "sssssss"

when I fire it up on object with float_list controller for the first time script wont work properly but next time was ok, so I repeated for next objects and first time was failed then ok,
for next object this same. So it hard to say it work or not Anyway I wondering how can I do such a code for my future projects referred to my initial problem:

list_of_items="meshsmooth,skin,skew,uvwmap.....etc.."
check modyfier list in selected objects if any of them meth list_of items do..

or
A="aa"
list_of_items="aa,ab,ac,ad.....etc"
check if my variable A= list_of_items do ...
 
  11 November 2013
your first line is actually a compare, not a declaration
 
   animationonscene==1	
   

is actually asking "is animationonscene equivalent to 1", which will be false in this regard as animationonscene is undeclared and will be 'undefined'

it should be


  animationonscene = 1
  


if thats what you are trying to do.


   if animationonscene==1 then messagebox "sssssss"
   


should be inside the ( )

The reason it doesnt work, is because you are declaring 'animationonscene' inside the ( ), where it should be...but you are asking for its value outside of the ( )..so it has no idea what 'animationonscene' is.

all code should be inside the parenthesis.

( -- should be at start of file

) -- should be at end of file.

If you put it inside the ( ), and fix your first line, it should fix those errors.


I'm not sure what the second half of your post is asking. what are you trying to accomplish?
 
  11 November 2013
Originally Posted by Hobbs: running code on selected objects is generally slow. convert your selection to an array, and iterate that...

It is doubtful statement:
delete objects
num = 5000
for k=1 to num do box()
(
	select objects

	t1 = timestamp()
	for n in objects do n
	format "objects\t\t\t\t >> nun:% time:%\n" num (timestamp()-t1)

	t1 = timestamp()
	for n in objects as array do n
	format "objects as array\t >> num:% time:%\n" num (timestamp()-t1)

	t1 = timestamp()
	for n in selection do n
	format "selection\t\t\t >> num:% time:%\n" num (timestamp()-t1)

	t1 = timestamp()
	nn = selection as array
	for n in nn do n
	format "selection as array\t >> num:% time:%\n" num (timestamp()-t1)

	t1 = timestamp()
	nn = selection as array
	clearselection()
	for n in nn as array do n
	format "array and deselect\t >> num:% time:%\n" num (timestamp()-t1)
)
 
  11 November 2013
find controllers by class is fast and easy:
(
	delete objects
	for k=1 to 1000 do dummy name:(k as string)
	gc()

	cc = for c in FloatController.classes where c.creatable collect c 
	for c in getclassinstances Bezier_Float do replaceinstances c (createinstance cc[random 1 cc.count])
)
for c in cc do
(
	format ">> %\n" c  
	nodes = #()
	t1 = timestamp()
	for i in (ii = getclassinstances c) where (node = refs.dependentnodes i firstonly:on) != undefined do appendifunique nodes node
	format "\tnodes:% controllers:% search time:%\n" nodes.count ii.count ((timestamp()-t1)/1000.0)
)
 
  11 November 2013
In this case it isnt really an issue, but as it seems he is new to maxscript, i was referring to the general practice. Basically when doing any commands that might make the mod panel refresh. it seems faster to do the commands without anything selected..or to be in create mode. As is my experience anyways.
 
  11 November 2013
Originally Posted by Hobbs: Basically when doing any commands that might make the mod panel refresh. it seems faster to do the commands without anything selected..or to be in create mode. As is my experience anyways.

everything said above is true. but it doesn't mean that the iterating through selected objects is slower than iterating through unselected.
 
  11 November 2013
Help - It's not over yet, Remove and compare elements

Nice code for making 5000 boxes Denis, I fired it up and it blow my computer memory up so I write this again.Hobbs
You are right. For me Denis code is a black magic, I think he is guru, he see blode hot girls in red dressed and I see only numbers and letters, exclamation and question marks You both explan me a lot but I need Hobbs level of approach.
No I'm pretty confused because now my code base on selecting and deselecting object on scene but Denis maintain it's no different between operation on selection and arrays and Hobbs Claim oposite. Denis code crash my computer, who's right gentlemen?

Anyway operating on selection list (arrays) give me ability I need for some of my functions.

I have two problems I have to solve it before I start:

CASE 1) HOW TO REMOVE ELEMENT(S)(in this case object(s)) FROM LIST,

below I submit my code.Example: I want get all objects and put it to list then remove t objects from my list(t=geometry, it's important that t must be variable)
and then select objects in my selection(without geometry) :

select objects
myArray = #()
---- collect all object on scene
for o in selection do
(
append myArray o
)
clearSelection()
sleep 2
--- remove from collection geometry objects
select geometry
for t in selection do
(
deleteitem myArray t
)
clear
select myArray
--- end of code

It seems like deleteitem myArray cause error:
-- Error occurred in t loop; filename: E:\WORK\doctor\patents\operating on list of elements\adding to list.ms; position: 250; line: 14
-- Frame:
-- t: $Torus001
-- Runtime error: array index must be positive number, got: $Torus:Torus001 @ [50.070679,-15.374176,0.000000]




CASE 2) HOW TO COMPARE ELEMENTS(in this case controller(s)) FROM LIST WITH EXISTING,

Second example it's pretty much self explanatory, so my code is:

---- script search for controllers from mycontrollerlist
select geometry
mycontrollerlist=#(Position_XYZ,audioposition,atta chment)
for o in selection do (
if clasacontrolerB=classof o.position.controller == mycontrollerlist then messagebox "I found my controllers"
)

But it won't work.
 
  11 November 2013
you can access all objects in the scene through the key word, 'objects'

this here

  select objects
   myArray = #()
   ---- collect all object on scene
   for o in selection do 
   (
   append myArray o
   )
  


is equivalent to

  myArray = $selection as array
  


there are even more ways to store a group of objects as well. Say you want to collect all objects with the name 'box'?


  myArray = for obj in objects where matchpattern obj.name pattern:("*box*") collect obj
  

that basically translates..
" look through all the objects in the scene, and give me all the ones that have box in their name."

Now the * is a special character. since its before box, and after box, it means it will accept any character in front, and any character in back.. this means, if an object is named 'aboxa' it will collect it. If you remove the *'s it will only find objects named 'box'. Make sense?

You can use that similar command to collect objects that are just geometry, ones that have modifiers, etc. Might be a little advanced, but its a fun little macro.



Now in terms of your problem. DeleteItem is looking for an integer. So if you were trying to do that way, you would have to incorporate findItem.


  for obj in $selection do
  (
  local index = findItem myArray obj
  if index != 0 do 
  deleteItem myArray index
  )
  


we do the check if index != 0, because 0 will be returned from 'findItem' if the value isnt in the array.


In problem 2, you have to iterate through your 'mycontrollerList' and compare values to the objects controller


  select geometry
   mycontrollerlist=#(Position_XYZ,audioposition)
   
  for o in selection do 
  (
  local controller =  classof o.position.controller
  
  for item in mycontrollerlist do
  (
  if item == controller then
  (
  messagebox "I found my controllers"
  exit
  )
  )
  


the exit should stop you from running anymore loops. This is untested, but should work.

I'm not as skilled as Denis T, or some of the other guys on the forum, so they might have better ways of achieving this result, so keep that in mind.
 
  11 November 2013
-- make a sample scene
(
    -- delete all objects to make a clean scene
	delete objects 
	-- create 100 dummy objects just for test
	for k=1 to 100 do dummy name:(k as string)
	-- use garbage collection to free memory to make our performance measurement more accurate 
	gc()

	-- collect all available creatable float classes 
	cc = for c in FloatController.classes where c.creatable collect c 
	/*
	    getclassinstances - returns a list of all instances of a specified class in the scene 
		we are looking for Bezier_Float because it's default controller for any float controller
	
	    createinstance - creates an instance of a specified class if the class creatable 
		replaceinstances - replace an instance with another instance in all places where it was used   
	*/
    -- here we randomly populate all our float controllers with randomly picked class instance 
	for c in getclassinstances Bezier_Float do replaceinstances c (createinstance cc[random 1 cc.count])

	-- go through all float creatable classes and find its instances in the scene	
	for c in cc do
	(
		format ">> %\n" c  
		nodes = #()
		t1 = timestamp()
		/*
			refs.dependentnodes with extra argument firstonly - returns the first node which depends on specified object... 
			in our case it's a controller.
			because the same node might be controlled by many other controllers we have put append a node to the list if only it's not exist.
			we use appendifunique for that
		*/
		for i in (ii = getclassinstances c) where (node = refs.dependentnodes i firstonly:on) != undefined do appendifunique nodes node
		format "\tnodes:% controllers:% search time:%\n" nodes.count ii.count ((timestamp()-t1)/1000.0)
	)
)
 
  11 November 2013
here is another explore function:
fn queryAllFloatControllersByClass class =
(
	for c in getclassinstances class astrackviewpick:on do
	(
		node = refs.dependentnodes c.anim firstonly:on
		format "controller: %\n\tanim:\t\t%\n\tsubname:\t%\n\tclient:\t\t%\n\t  node:\t\t%\n\n" c.name c.anim (getSubAnimName c.client c.subnum) c.client (try(node.name) catch())
	)
)
queryAllFloatControllersByClass Bezier_Float
 
  11 November 2013
Thank You

Thank You, now it's time to push it in to action.

I used to programme in AmosBasic on Amiga when I was teenager just for my self.From what I remember Amos was much simpler language but way more limited, of course larger code bricks = lower programming ability but it was so easy and intuitive. Here it have to be 7 line of code to do such a simple stuff which actually could be describe in two lines of code:

myobjectlist #(Box,Sphere,Dummy)
search for object on scene if object=myobjectlist then do .....

However I cant use Amos to operate inside max
Without your help I would't be able to do much
 
Thread Closed share thread



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
CGSociety
Society of Digital Artists
www.cgsociety.org

Powered by vBulletin
Copyright 2000 - 2006,
Jelsoft Enterprises Ltd.
Minimize Ads
Forum Jump
Miscellaneous

All times are GMT. The time now is 06:52 PM.


Powered by vBulletin
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.