Notifications
Clear all

[Closed] How can i format a string to remove certain Text?

Hey there,

i try to do some maxscripting for automating my parameter wiring. So far so good. Im at a point now where i can actually make this work with a FOR Loop. But the problem is, that i always have to put in numbers as start and end. And if objects are named, like “Sphere_001”, the “001” isnt recognized as it is no number the FOR Loop can use to iterate.

So i now want to use arrays. This is how far i am at the moment:


   MyArray = selection as array
   
   for i = 1 to MyArray.count do 
   (
   	k = MyArray[i] as string
   	print k
   )
   

When i select several objects, like Spheres for example, and i run this script i get the values in the Array printed as Strings like this:

“$Sphere:Sphere022 @ [26.603012,97.618546,0.000000]”

So this is what the variable “k” always has inside. Thats not bad. But i now need a function to strip things off from this text, so that only the actual name of the object is left. Meaning: “$Sphere:Sphere022 @ [26.603012,97.618546,0.000000]” must somehow be converted to “Sphere022”. This is what i then can use in the Execute Function inside the FOR Loop to do the parameter wiring for the selected objects.

My problem is now: I dont know how to strip this text out I tried trimleft and trimright but im actually quite bad at scripting and i dont really know the syntax for all of this. Could you guys please help me out in that? That would be insane!!

Many thanks in advance
subb

11 Replies
MyArray = selection as array
   
   for i = 1 to MyArray.count do 
   (
   	k = MyArray[i] 
   	format "%
" k.name
   )

Most if not all nodes in Max script have a .name property you can access.

The format statement is a sort of like a print statement but it allows you to easily populate the output with variables. each “%” in the format string gets swapped with the variables at the end. It’s very handy for outputting info

MyArray = selection as array
   
   for i = 1 to MyArray.count do 
   (
   	k = MyArray[i] 
   	format "Name:% Position:% Class: %
" k.name k.pos (classof k)
   )

I just read your post more closely

When you do things like param wire objects (or assign modifiers or controllers etc) it is best to not use and just pass the nodes themselves.

that is instead of getting selection[i].name just operate on selection[i]

Amazing !!! Thank you very much for this.

With your info i was able to play around and reconstruct the script. It now looks like this:

MyArray = selection as array
    
 for i = 1 to MyArray.count do 
 (
 	   k = MyArray[i] 
 	   objectName = k.name as string
 	
 	 rnd1 = random 0.1 1
 	 rnd2 = random 0.3 1
 	 rnd = random rnd1 rnd2
 	
 	 execute ("paramWire.connect $Audio_Controller.baseObject[#Angle] $" + objectName + ".modifiers[#Face_Extrude][#Amount] \"Angle*" + rnd as string + "\"")
 )
 

And it works! \o/ The assignment is made only to the selection that i have. I can now start to explore how i can actually get the values from the objects (like position, scale, modifiers and so on) to replace the static entry in the Execute. And if i find this out i can make a GUI Script out of this for later use Do you have any tipps on this? Getting object data and putting this into a GUI?

Anyway – thank you very much !! This makes my day now
All the best, subb

There is no need to extract the name of MyArray[i]
and then build a giant string to pass to execute()
and in this case it is quite wasteful

If MyArray[i] is an object called Sphere_001 then
both of these expressions are identical to max script

 MyArray[i]
$Sphere_001

if you skip the string building and execute()
it will be faster (and more elegant)

for i = 1 to MyArray.count do 
 (
	rnd = random (random 0.1 1)  (random 0.3 1)
	paramWire.connect $Audio_Controller.baseObject[#Angle] MyArray[i].modifiers[#Face_Extrude][#Amount] ("Angle*" + rnd as string )
)


I can now start to explore how i can actually get the values from the objects (like position, scale, modifiers and so on) to replace the static entry in the Execute.

once you get away form excute() and string building it is easy


MyArray[i].pos
MyArray[i].scale
MyArray[i].modfiers

Name dependant code is perilous and inefficient. As a general philosophy operating directly on max nodes (not names + execute() ) is best.

Thanks! This also seems to be more readable in the end. Although i dont understand Maxscript that good yet i get a clue on what the lines do already I will have a look into this, for sure!

In the meantime i have another question if you have the time for it: Do you know why i cant add a controller to the Weights inside a Controller List with Maxscript? I can when i do it directly and by activating the listener i see, that Max is also using Maxscript here. Its this line in the output:

$Sphere001_920.modifiers[#Face_Extrude].amount.controller.weight.controller = Noise_float ()

Strange thing is: As soon as i execute this in the Listener or in the Script Editor, it executes fine but the Controller isnt there. It has not added it. If i do it manually in the Curve Editor it does add it though. Having a look at the command i start to wonder how he knows to which Weight he should apply that controller.

Do you know what that is?

well, not sure exactly what your are trying to do but

$Sphere001_920.modifiers[#Face_Extrude].amount.controller.weight.controller 

looks awkward and possibly incorrect
check for undefined (non-existant) nodes in your node paths.
type each piece into the listener and see if they actually exist

$Sphere001_920.modifiers[#Face_Extrude].amount.controller.weight.controller
$Sphere001_920.modifiers[#Face_Extrude].amount.controller.weight
$Sphere001_920.modifiers[#Face_Extrude].amount.controller
$Sphere001_920.modifiers[#Face_Extrude].amount

1 Reply
(@subbz2k)
Joined: 10 months ago

Posts: 0

Im with you in that. This is exactly my thought as well. But this is also exactly the line that the Listener is writing when i add a controller to the weight of another controller in the curve editor. So i assumed that this must be the code to use for that. But its not. I tried everything you mentioned already but it only gets more weird for me:

$Sphere001_920.modifiers[#Face_Extrude].amount.controller.weight.controller
-> returns “undefined”

$Sphere001_920.modifiers[#Face_Extrude].amount.controller.weight
-> returns “#(100.0, 100.0)”, an array

and $Sphere001_920.modifiers[#Face_Extrude].amount.controller
-> returns “Controller:Float_List”, which is absolutely plausible because the List Controller is the first controller in the List for the Amount-Parameter

I checked the help and the Help says that the Weights inside a list controller are actually Arrays. If i add more controllers to the Available-Slot of the List Controller, the array gets bigger and returns more values.

So in turn this means: I actually add a controller to a value inside of this Weight Array the moment i add that controller manually in the curve editor. And the listener is telling me the line above, which obviously cant be correct.

So the question now is: What is Max actually really doing here? How can i add a controller to that weight array? Is this even possible??

Btw: I added a screenshot to the thread so you can see the position in the curve Editor where i try to do this.

Thanks for your help in advance
subb

$Sphere001_920.modifiers[#Face_Extrude].amount.controller.weight[n].controller 

#weight is floattab parameter. you have to specify the list index

it’s not. this is what a developer wants to print out.

I was confused by the results of manually adding controllers at first too. Max does not make it very clear that as you add controllers you are actually creating subAnims (which are just controllers) and adding to the array of a List controller. It took me some time adding and removing controllers via scripts and manually , with the curve editor open to see what was really happening. I never trust what the recorder outputs, it is generally useless

Here is what Max is thinking:

<node>.modifiers[#Face_Extrude].amount is a float parameter, it requires a Float value or Float controller
<node>.modifiers[#Face_Extrude].amount.controller is a Float_List: an array of possible floats

In your case:
<node>.modifiers[#Face_Extrude].amount.controller[1] is a Float_Wire (the parameter you wired earlier , presumably)
<node>.modifiers[#Face_Extrude].amount.controller[2] is a Noise_Float

<node>.modifiers[#Face_Extrude].amount.controller.weight
gives you the array of weights for each controller

so the weight of
<node>.modifiers[#Face_Extrude].amount.controller[1]
is <node>.modifiers[#Face_Extrude].amount.controller.weight[1]

the weight of
<node>.modifiers[#Face_Extrude].amount.controller[2]
is <node>.modifiers[#Face_Extrude].amount.controller.weight[2]

you can set these indivdually
<node>.modifiers[#Face_Extrude].amount.controller.weight[1]=0
<node>.modifiers[#Face_Extrude].amount.controller.weight[2]=100

or pass the array to .controller.weight
<node>.modifiers[#Face_Extrude].amount.controller.weight=#(0,100)

normally you can add a new controller to a list controller using
<node>.controller.available = bezier_float() –or any other controller class instance

but in your case MaxScript seems to want [#Face_Extrude].amount to always be a float value
It still seems to allow you to manually assign a new controller in the curve editor however

hope that helps

Page 1 / 2