View Full Version : simple move in Python
EdBever 08-30-2010, 10:08 PM All the stuff with Python got me enthausiastic, so I checked some scene files from Chris Smith and from the Python site and started to play around.
(Chris if you read this Thanks a lot for your work with Python)
But I stumble upon some basic problems, Years ago I did some actionscripting and at first this look a bit like it. So I tried some basic movement with the following code:
import c4d, math, random
from c4d import bitmaps, documents, gui, modules, plugins, storage, symbols as sy, utils
#Python tag gives doc and op (except op is the tag)
#used for script: doc = documents.GetActiveDocument()
obj = op.GetObject()
tag = op
fps = doc.GetFps()
delta = 1/float(fps)
posX = 0
def CS_Time(fs):
t = doc.GetTime().Get()
return utils.Clamp(0, 999999, (t-(fs*delta)))
def main():
t = CS_Time(0) #Arg is frame to start time as zero
posx = posx + 100
obj.SetPos(c4d.Vector(posx,0,0))
In actionscript "posx = posx + 100" would make the object move a 100 units every frame, but with Python nothing happens, although i've seen syntax like this in exaple-files
Can't it be done like this or am I missing something
TIA
EdBever
|
|
Horganovski
08-30-2010, 10:44 PM
There are some typos in your code, for example you define 'posX' then use 'posx'. Also some of your lines are not properly indented.
Even with that though it doesn't work, it seems to be something to do with global/local variables as with the code cleaned up I get this error 'UnboundLocalError : local variable 'posx' referenced before assignment.
I don't know enough Python yet to fix this, but I'm guessing that rather than defining posx at the start you'd need to get the x position of the object in the main function and then increment it.
It seems to me though, that a simpler approach is just to use the variable 't' that Chris already set up in the file, like this for example :
import c4d, math, random
from c4d import bitmaps, documents, gui, modules, plugins, storage, symbols as sy, utils
#Python tag gives doc and op (except op is the tag)
#used for script: doc = documents.GetActiveDocument()
obj = op.GetObject()
tag = op
fps = doc.GetFps()
delta = 1/float(fps)
def CS_Time(fs):
t = doc.GetTime().Get()
return utils.Clamp(0, 999999, (t-(fs*delta)))
def main():
t = CS_Time(0) #Arg is frame to start time as zero
posx = t*100
print (posx)
obj.SetPos(c4d.Vector(posx,0,0))
Cheers,
Brian
Horganovski
08-30-2010, 10:52 PM
Seems like my idea for fixing it works, this version gets the current position x first, then increments it and works as you'd expect. Not as handy as Chris' version though as because it's not tied any more to the actual frame number you have to reset the position when you rewind the timeline or the object will get lost in space eventually ;)
import c4d, math, random
from c4d import bitmaps, documents, gui, modules, plugins, storage, symbols as sy, utils
#Python tag gives doc and op (except op is the tag)
#used for script: doc = documents.GetActiveDocument()
obj = op.GetObject()
tag = op
fps = doc.GetFps()
delta = 1/float(fps)
def CS_Time(fs):
t = doc.GetTime().Get()
return utils.Clamp(0, 999999, (t-(fs*delta)))
def main():
t = CS_Time(0) #Arg is frame to start time as zero
position = obj.GetPos() # - where is the object right now? (returns a vector x,y,z)
posx = position.x # - what is the current x value?
posx = posx +100
print (posx)
#posx = t*100
obj.SetPos(c4d.Vector(posx,0,0))
I'm very new to Python myself, but I can offer one piece of advice that helps me - open the Python console and keep an eye on it as you code, it will report errors and without seeing those you are shooting in the dark really ;)
Cheers,
Brian
Scott Ayers
08-31-2010, 02:26 AM
This example will tie the object's movement to Chris's time line code.
I threw in a speed control too: import c4d
from c4d import utils
obj = op.GetObject() #move the object the python tag is on
fps = doc.GetFps()
delta = 1/float(fps)
def CS_Time(fs):
t = doc.GetTime().Get()
return utils.Clamp(0, 999999, (t-(fs*delta)))
speed = 10 #Edit this value to control the speed of the movement
def main():
t = CS_Time(20) #Don't move until frame 20
pos = obj.GetPos()
pos.x = pos.x + t*speed
obj.SetPos(c4d.Vector(pos,0,0))
Python uses the same kind of prepass& main sections that Coffee uses.
So all the same rules about using the prepass section for storing variables that you don't want to change. Unless something in the main section tells it to change when the code cycles. Also applies to Python code in the same manner.
-ScottA
mayajunky
08-31-2010, 03:59 AM
hey cool guys, these little tid-bit's gonna help me out a ton! So easy question I'm sure, but where do these print value calls get written to? I was thinking the console or the script log but nothing is showing up there? Thanks!
Horganovski
08-31-2010, 04:10 AM
Go to the Python menu and you'll see it has it's own console where these show up ;)
Cheers,
Brian
EdBever
08-31-2010, 06:42 AM
Thanks a lot Brian, I still have to learn so much!
But than again thats the fun of it.
The typos came from the translation to englisch so they weren't in the org file, but is still sloppy.
Your solution works great, a bit tricky is to copy/paste code for tabs get copied but make the script invallid.
I'm trying to combine some random movement with the damping trick I saw in the AixSponza videoexplanation, so you get a random shake but with a nice organic feel.
npos = opos + dist * spring
spread = spread * inertia + dist * spring
npos = opos + spread
But whenever I try to do something with the spread the spript stops and gives me the following error:
UnboundLocalError: local variable 'spreadX' referenced before assignment
I tried to put spreadX,YandZ on onther places but nothing works
import c4d, math, random
from c4d import bitmaps, documents, gui, modules, plugins, storage, symbols as sy, utils
#Python tag gives doc and op (except op is the tag)
#used for script: doc = documents.GetActiveDocument()
obj = op.GetObject()
tag = op
fps = doc.GetFps()
delta = 1/float(fps)
def CS_Time(fs):
t = doc.GetTime().Get()
return utils.Clamp(0, 999999, (t-(fs*delta)))
spreadX = 1
spreadY = 1
spreadZ = 1
def main():
t = CS_Time(0) #Arg is frame to start time as zero
spring = tag[sy.ID_USERDATA,3]
inertia = tag[sy.ID_USERDATA, 8]
rangeX = tag[sy.ID_USERDATA, 1]
rangeY = tag[sy.ID_USERDATA, 2]
rangeZ = tag[sy.ID_USERDATA, 4]
posXold = obj.GetPos().x
posYold = obj.GetPos().y
posZold = obj.GetPos().z
posXnew = 500 +(rangeX * random.random())
posYnew = 500 +(rangeY * random.random())
posZnew = 500 +(rangeZ * random.random())
distX = posXnew - posXold
distY = posYnew - posYold
distZ = posZnew - posZold
spreadX = spreadX * inertia + distX * spring
spreadY = spreadY * inertia + distY * spring
spreadZ = spreadZ * inertia + distZ * spring
NposX = posXold + spreadX
NposY = posYold + spreadY
NposZ = posZold + spreadZ
print (spreadX)
obj.SetPos(c4d.Vector(NposX,NposY,NposZ))
Probably a basis mistake I make but I gan't figure out what I'm doing wrong
TIA
EdBever
mayajunky
08-31-2010, 01:34 PM
Go to the Python menu and you'll see it has it's own console where these show up ;)
Cheers,
Brian
Awesome thanks Brian. Man thats one thing I wish I could do in xpresso, have the ability to print out values from lets say an iterated loop, per frame. Then again maybe you can and I'm missing something? I suppose with the coffee node you can?
Scott Ayers
08-31-2010, 03:14 PM
@EdBever,
The error is coming from the fact that you already defined spreadX,Y & Z in the prepass section. And then you're trying to do it again in the main section.
Here's the fixed code: import c4d, math, random
from c4d import bitmaps, documents, gui, modules, plugins, storage, symbols as sy, utils
obj = op.GetObject()
tag =op
spreadX=1
spreadY=1
spreadZ=1
def main():
spring = tag[sy.ID_USERDATA,1]
inertia = tag[sy.ID_USERDATA, 2]
rangeX = tag[sy.ID_USERDATA, 3]
rangeY = tag[sy.ID_USERDATA, 4]
rangeZ = tag[sy.ID_USERDATA, 5]
posXold = obj.GetPos().x
posYold = obj.GetPos().y
posZold = obj.GetPos().z
posXnew = 500 +(rangeX * random.random())
posYnew = 500 +(rangeY * random.random())
posZnew = 500 +(rangeZ * random.random())
distX = posXnew - posXold
distY = posYnew - posYold
distZ = posZnew - posZold
spreadX = inertia + distX * spring
spreadY = inertia + distY * spring
spreadZ = inertia + distZ * spring
NposX = posXold + spreadX
NposY = posYold + spreadY
NposZ = posZold + spreadZ
print (spreadX)
obj.SetPos(c4d.Vector(NposX,NposY,NposZ))
BTW: This is a little pet peeve of mine. But it's a little bit annoying to troubleshoot code problems when the UserData entries are not listed in numerical order in the code. And also don't match up 1:1 sequentially with the UserData entries.
If you don't provide a scene file. The person who is troubleshooting the code for you needs to make the UD entries. And if they are not in sequential order and match the code. It adds more confusion to the whole troubleshooting process.
@ mayajunkie,
Yes, you can print to the Coffee console with Xpresso.
But there's an odd little quirk(bug?) with it. And you need to include a result node for it to work.
See the attached image for an example.
-ScottA
mayajunky
08-31-2010, 03:37 PM
Scott's the man, rock on dude! :applause: ( hmm my little rocker guy icon disappeared? )
I've been wanting the ability to do that for so long, thanks man. I suppose now that I'm more familiar in general with C4D, giving another go at learning some scripting might now be as painful this time. I better throw that code with a result node linked up in an xgroup into my library because I'll probably forget that little bug next time I need it. Thanks again!
EdBever
08-31-2010, 07:50 PM
Scott thanks for your answer, but its not exectly what I meant.
When you use the code "spreadX = inertia + distX * spring" you get the wrong starting point and there wont be any damping. Its essential to take in account the previous value of spreadX. So it realy must be "spreadX = spreadX * inertia + distX * spring" But like you said there was no scenefile and my explanation was not precise enough. I've attached a scenefile this time, I hope it makes sense.
In the scene file there is a green ball witch is coded with Expresso and with the motion I want (thanks to Aixponza for this file). But you have to move the target to get the motion, don't want that.
So I create a random movement (see the red cube), but this is very brisk. To dampen it you can use the code shown in the doodle from the Aixsponza-file, you only need part 2.
But how do I get this code in Python? Everything works exept the part with delta/spread. (I've used spread instead of delta because there is already a delta declared in the header)
In the Pythoncode for the blue cube, I've written all the code as I think it should be but then it does not work.(in the scenefile I've commented-out the parts that give the problem, line 45-47 and line 50-52)
I hope this all makes sence, and perhaps it can be done way easier.
So much to learn so little time ;-)
TIA
EdBever
Scott Ayers
08-31-2010, 09:42 PM
Sorry about that Ed,
Now that I see the Coffee code you're trying to recreate. I think I understand what you're trying to do.
The act of changing a previously declared variable's value is called "overloading".
As it turns out. Python does not support overloading the same way as other languages.
I have almost no coding experience with Python. So I just learned something new.:cool:
I took a quick look at the Python docs. And there does seem to be a way to do this kind of thing by declaring the first instance of your variables as global. But I still need to do more research on this before I can offer any more help on this. So you might get a faster reply from someone who knows Python better.
-ScottA
EdBever
08-31-2010, 10:17 PM
No problems Scott,
You've pointed me in the right direction so I can search further.
Thanks again for the help so far.
EdBever
rustEdge
09-01-2010, 01:02 AM
@ED,
most likely the reason it's not working is it spreadX, Y, and Z have not been initialized in your main loop.
in the CS_Time() function, spreadX, Y, and Z are local variables, only callable within the function.
Just drop spreadX = 1, etc. above the CS_Time() function. IIRC, variables written before any function definitions should be considered global variables.
EDIT:
my bad. did a little googling. seems that you need to write global inside the functions if you want to write stuff into them... i'll try a few experiments, i'll give you an update about my findings.
def main():
global spreadX
global spreadY
global spreadZ
something like that.
Scott Ayers
09-01-2010, 01:05 AM
I have some old videos about Python that I've been meaning to look at. So I took a quick scan through them. And in one of them the guy mentions that it's "common" in Python to do lots of referencing because variables are not mutable.
Meaning that instead of overloading variables and sort of recycling them like in most languages. You just create another variable and point it to the other variable.
For example:
x = 5
newx = x #Results in the value 5
This seems like a bad idea to me because you'll end up with tons of extra variables this way. And in most languages this results in more memory usage.
But since you aren't building a game where minute memory usage is very critical. And since this guy says this in normal in Python. I guess it's ok to use this method for basic scripting purposes.:shrug:
So try putting this code in the Blue cube's python tag. And play with the sliders: import c4d, math, random
from c4d import bitmaps, documents, gui, modules, plugins, storage, symbols as sy, utils
#Python tag gives doc and op (except op is the tag)
#used for script: doc = documents.GetActiveDocument()
obj = op.GetObject()
tag = op
fps = doc.GetFps()
delta = 1/float(fps)
def CS_Time(fs):
t = doc.GetTime().Get()
return utils.Clamp(0, 999999, (t-(fs*delta)))
spreadX = 1
spreadY = 1
spreadZ = 1
def main():
t = CS_Time(0) #Arg is frame to start time as zero
spring = tag[sy.ID_USERDATA,3]
inertia = tag[sy.ID_USERDATA, 8]
rangeX = tag[sy.ID_USERDATA, 1]
rangeY = tag[sy.ID_USERDATA, 2]
rangeZ = tag[sy.ID_USERDATA, 4]
posXold = obj.GetPos().x
posYold = obj.GetPos().y
posZold = obj.GetPos().z
posXnew = 500 +(rangeX * random.random())
posYnew = 500 +(rangeY * random.random())
posZnew = 500 +(rangeZ * random.random())
distX = posXnew - posXold
distY = posYnew - posYold
distZ = posZnew - posZold
newspreadX = spreadX * inertia + distX * spring
newspreadY = spreadY * inertia + distY * spring
newspreadZ = spreadZ * inertia + distZ * spring
NposX = newspreadX / spreadX
NposY = newspreadY / spreadY
NposZ = newspreadZ / spreadZ
obj.SetPos(c4d.Vector(NposX,NposY,NposZ))
This will make the sliders control how the cube moves around.
This might not be exactly what you wanted. But it might get you closer to your goal.
You could of course just put those variables in the main section like rustEdge suggested.
But remember that if you do that then they would get reset to their initial values every time the script loops(every frame).
And sometimes that resetting behavior is unwanted, and will prevent you from doing certain tasks.
-ScottA
mayajunky
09-01-2010, 01:50 AM
Hey is there a setting to be able to tab inside the python editor window?
Every time I do it jumps out the text field, and if it's docked next to another pallet will jump to the first field there?
import c4d, math, random
from c4d import bitmaps, documents, gui, modules, plugins, storage, symbols as sy, utils
#Python tag gives doc and op (except op is the tag)
#used for script: doc = documents.GetActiveDocument()
obj = op.GetObject()
tag = op
word = " cinema4D "
def main():
print ("Hello C4D World")
max = len(word)
x = 0
while x < max: #uses < instead of <= since array starts at zero
print word[x]
x += 1
My first py4d code thanks to CS! Thanks for the headers. Here's my uber complex print iteration. :P But yea ended up having to use notepad++ since was getting errors because of my indenting? Now I just need to figure out how many children the object currently has? Hmmm must be something like obj.somethingsomething() ?
Okay so this is what I'm catching and not catching onto so far. A primitive object like a cube is an object born from the BaseObject class. So when I'm looking at the docs on py4d.com and the available functions for the class, the "BaseObject" from BaseObject.GetPos() is just a placeholder string? So I could do something like myObjPos = obj.GetPos() and it will automatically define my myObjPos as an array or vector based on the object the tag is on? Hmmm I think I've read this before but whats op again? ( Oh okay had to find and blow the digital dust of Rui's coffee book, so the "op" is the object that contains the python tag... correct? So when he passes reference to "tag" in the header, why does he do that again? )
I mean from the examples above can you do something like...
myObjPos = obj.GetPos()
obj2.SetPos(myObjPos)
if not then why is it written like this again? ( Sorry gotta blow the cobwebs off the scripting side of my brain too ) Okay okay one last thing, so in oop world, objects inherit their parents (superclasses?) functions?
Well this doesn't seem to work... objChildren = obj.GetChilds() obviously am missing an aspect of the syntax here.
Scott Ayers
09-01-2010, 04:04 AM
In py4D op is the tag. Or the python generator if that's used.
In Coffee op is the active object.
This is probably going to really confuse the heck out of many Coffee users.;)
Which is why Chris Smith declares the op with the variable word "tag". So he can visually remember that op is the python tag and not an object.
Here's an example of op used in it's native format: import c4d
from c4d import symbols as sy
#The user data is on the tag.....Or another way to say this the UserData is on the "op"
def main():
UD = op[sy.ID_USERDATA, 1]=50
print UD
As I talk about in my Coffee videos.
Using op is a shortcut. And it can be very confusing, and get you into trouble, if you're new at coding.
I recommend creating your own variables for most things. And using "op" as little as possible until you get comfortable with scripting. Which is what Chris is doing when he assigns "tag" to op.
GetPos() & SetPos() are functions that are designed to be applied to objects just like in Coffee.
Objects are defined by variables to the computer's memory.
So if you have a cube. And you assign it the variable name of myCube and want to use those position functions on it. Then you would write:
import c4d
def main():
myCube = doc.SearchObject("Cube") #finds the object named Cube
myCube.GetPos()
myCube.SetPos(c4d.Vector(0,0,0))
If you want to deal with the individual axis separately instead of all three vectors at once. Then you can assign both the object, and the function that's applied to it, to a variable. And through inheritance that will let you assign an integer value to any single one axis like this:
import c4d
def main():
myCube = doc.SearchObject("Cube") #finds the object named Cube
position = myCube.GetPos()
position.x = 0
position.y = 0
position.z = 0
myCube.SetPos(c4d.Vector(position.x,position.y,position.z))
-ScottA
mayajunky
09-01-2010, 04:13 AM
I'm still a bit gray why you have to call the Vector function inside the SetPos function as a parameter?
myCube.SetPos(c4d.Vector(position.x,position.y,position.z))
what you mean by this exactly? "Then you can assign both the object, and the function that's applied to it, to a variable." I might have to check back in the morning though. Python be keeping me up past my bedtime. :P
Scott Ayers
09-01-2010, 05:05 AM
The reason you need to type the vectors in the SetPos() function is because that function is trying set the position of the object for all three axis locations(vector locations).
Not any one single axis location. And you have to tell it what those positions are.
It might help to think of this in steps.
All functions perform a base level task. The basic reason for which they are built.
The base task for the SetPos() function is to do this: SetPos(c4d.Vector(0,0,0))
The next step is to take that basic task. And see if you can apply other things you know about coding to it. And maybe find a way to combine them with that basic task that the person who created the function maybe didn't even think of when he created it.
So that's where someone came up with the idea that taking the object.GetPos() and assigning it to a variable results in the ability to control each axis vector position separately.
It's one of those things you might not understand initially until you learn more about coding in general. So you just take a leap of faith and use it without really understanding it all. Then one day it will just click.
I wrote code for weeks just copying other people's code before I had a clue about what it all meant.
My Coffee videos cover a lot of these basics.
And even though the syntax is different from Python. The basic rules of coding are the same.
If you haven't watched them they might help clear up some of the basics.
Coffee Videos (https://sites.google.com/site/scottayersmedia/scripting)
-ScottA
EdBever
09-01-2010, 07:57 AM
Been trying so more options, but still no solution. Whatever I do I don't get a smooth movement.
Attached is a scenefile from the "Python scene expamples" from the Python site. In there you see at line 57 (of the scenefile) that there is a case of "overloading" or am I mistaken.
# Camera distance adaptive subdivision Expression
from c4d import symbols as sy
min_Subdivision = 1; # Minimum subdivisions of Hypernurbs
max_Subdivision = 4; # Maximum subdivisions of Hypernurbs
low_Res_Distance = 5000; # Distance at which the Hypernurbs is at minimum subdivision
high_Res_Distance = 500; # Distance at which the Hybernurbs is at maximum subdivision
def main():
camera = doc.SearchObject("Camera")
if not camera: return #if error, give up
hn = op.GetObject()
camera_Position = camera.GetPos()
the_Position = hn.GetPos()
the_Distance = (the_Position - camera_Position).GetLength()
if the_Distance >= low_Res_Distance:
hn[sy.HYPERNURBSOBJECT_SUBEDITOR] = min_Subdivision
elif the_Distance <= high_Res_Distance:
hn[sy.HYPERNURBSOBJECT_SUBEDITOR] = max_Subdivision
else:
subdivision = 1 - the_Distance / ( low_Res_Distance - high_Res_Distance )
subdivision = min_Subdivision + subdivision * ( max_Subdivision - min_Subdivision )
subdivision = round(subdivision) #round, otherwise you might get 0
hn[sy.HYPERNURBSOBJECT_SUBEDITOR] = int(subdivision)
subdivision = min_Subdivision + subdivision * ( max_Subdivision - min_Subdivision )
So there should be a possibility to do "spread = spread * inertia + dist * spring"
I'll keep searching
EdBever
mayajunky
09-01-2010, 01:16 PM
Cool thanks for the explanation and the tutorials link Scott ( easy to find link from your gallery page? ). I should probably watch those and go through Rui's book again... well not exactly again, didn't make it very far last time. :P Before i start attacking the boards with questions on general structure I suppose. :)
mayajunky
09-01-2010, 01:24 PM
Oh yea, so was I the only one having tab issues in the python editor available inside c4d then? I also tried copying my code out of the code window here and it had messed with my tab structure.
EdBever
09-01-2010, 03:51 PM
having the same problems with the Tab.
Ed
Scott Ayers
09-01-2010, 04:29 PM
Attached is a scenefile from the "Python scene expamples" from the Python site. In there you see at line 57 (of the scenefile) that there is a case of "overloading" or am I mistaken.
According to the videos I've seen. That's called referencing.
The act of creating a brand new variable. Then assigning it to a previously declared variable like this:
x = 5
newx = x
Overloading is when you assign a variable a value. Then later on take that same variable and assign it to a new variable like this:
x = 5
x = 10
According to what I've read. This kind of overloading is not allowed in Python. So you have to use referencing instead. And also make sure that any custom methods you build (def) are global in nature.
That also means that you'll need to make more variables in Python compared to Coffee. Which results in more memory usage.
However we're only talking a few bytes per variable here. So for scripting purposes, that probably won't be too much of a big deal.
This kind of thing is only important if you're building a game where every single byte of memory is crucial.
I'm still a learner myself. So make sure you double check on what I'm saying here.
Don't just take what I say as the gospel truth. :)
-ScottA
mayajunky
09-01-2010, 05:35 PM
Yea for me there are a lot of gray areas still. But I mean I ran this code...
x = 0
while x < max: #uses < instead of <= since array starts at zero
print word[x]
x += 1
I'm changing the value of x here during each iteration. From what I've read out of my python book so far I believe variables are "immutable" (unable to change - mutate) as far as there data type is concerned, not their associated value. In other works you can do lots of operations that involve different data types and they will never-ever be type-casted automatically. As for overloading ( and I'll have to check again ) isn't that used for different functionality?
Oh guess I was wrong, the value is immutable and really behind the scenes a new object is created, and variable x is rebound to reference the new object (old hits clean up). Of course to me, since I don't quite know the intricacies of that yet it almost means data types are completely mutable. lol
Scott Ayers
09-01-2010, 07:56 PM
Apparently there actually are a couple of mutable things in Python. One of them being sets. And I think the other one was possibly lists(not tuples) if I remember correctly.
But what Ed and I were doing was trying to overload a variable that's in the prepass section from the same variable named inside of the main section. And that's apparently not supported in Python.
As for what overloading is. Watch those videos.:)
I spent a lot of time describing how the prepass section works along with the main section. And how using them, along with overloading variables, can do things that you can't do if you always put all the variables inside of the main section.
I never actually use the term "overloading" in them because I didn't want to use any of those big fancy technical terms that frightens people away from learning this stuff.
I've also seen people debate the proper usage of the term "overloading". Apparently it's kind of a loosely used term. Like the way everyone uses the word function even when they're talking about methods.
Some people prefer to categorize what we're doing as a characteristic of polymorphism.
But if I use the word Polymorphism with new users. I will definitely scare them away. ;)
-ScottA
MWelter
09-02-2010, 06:52 AM
Overloading is usually the thing with functions and methods. Here is the relevant Wikipedia entry for instance.
Constructor and method overloading (http://en.wikipedia.org/wiki/Method_overloading), in computer science, a type of polymorphism (http://en.wikipedia.org/wiki/Polymorphism_in_object-oriented_programming) where different functions with the same name are invoked based on the data types of the parameters passed
Operator overloading (http://en.wikipedia.org/wiki/Operator_overloading), a form of functional or method overloading where the action being overloaded is an operator, such as + or -
Don't think Python supports this actually, since you cannot specify which types the arguments should have.
To add to further confusion ... ;)
In your previous example:
myCube.SetPos(position)
should be perfectly fine since position already refers to a vector. No need to construct a new one from it.
"Local" functions are also supported. Something like
def doit():
prefix = "it says"
def printit(x):
print prefix, x
for i in range(10):
printit(i)
works.
Most things in Python are mutable. Lists, dicts, sets, classes (or rather instances thereof) are. Tuples are not. Not sure about strings. I think they are immutable.
I think you can change a global variable from within a function.
somevar = 5
def changesSomeVar():
global somevar
somevar = 1
edit2: ... removed this for clarity
edit: bah, damn forum keeps destroying my code indentation
Scott Ayers
09-02-2010, 04:09 PM
Coming from the other standard bracketed languages. Not being able to use the same name for variables and overload them (or whatever we decide to call it) from inside of the main section of the program is very weird for me to deal with.
I initailly thought the formatting and the indentation stuff was going to be the hardest part for me to get used to. But surprisingly that turned out to be relatively easy to grasp.
But the more I look into it and play around with it. The more problems I'm having just trying to do the same simple things that I can easily do with the other languages.
It's such an odd language compared to everything else I code in.
It's going to take a long time to to unlearn everything I've learned. And do things the Python way.
I don't mind it being different. I just wish it was so different. If you know what I mean.
-ScottA
MWelter
09-02-2010, 08:53 PM
Err sorry, what i wanted to say is that once you use the global statement the respective name refers to the global variable. So you cannot declare another local variable with the same name which hides the global one. If you don't use global then everything is as expected:
x = 5
def test(): x=1; print x;
test()
print x
gives
1
5
but
x = 5
def test(): global x; x=1; print x;
test()
print x
gives
1
1
Scott Ayers
09-02-2010, 10:03 PM
Thanks Michael,
I'm sure I'm going to refer to that example many times until it finally becomes something I don't have to think about anymore. It's just so strange to be forced to create a whole new function just so you can set a variable as global. But I will get used to it eventually.
Just as a double check. You can't just define a variable as global without using it inside of a function(def) right?
For example. Something like this is not possible right?:
x = 5
global x
x = 1
print x
-ScottA
mayajunky
09-03-2010, 12:30 AM
myCube.SetPos(c4d.Vector(0,0,0))
-ScottA
Man I was still so stumped on this at first.... I remember a bit now after reading a bit more. So your calling the "function" as a return parameter for the object's "method". Just read a bit about dynamic typing (cast typing), sounds slick but watch out if you forget about it. haha
Oh just read an indentation is 4 spaces too, guess is no need for the tab.
MWelter
09-03-2010, 07:44 AM
Just as a double check. You can't just define a variable as global without using it inside of a function(def) right?
For example. Something like this is not possible right?:
x = 5
global x
x = 1
print x
Well, it doesn't create an error but i don't know if it does anything usefull.
Btw. you can easily try things outside of cinema. Python is available as stand alone package for every system.
For windows it comes with a simple installer. Upon installation, make sure python is in the search paths. Start cmd.exe. Type python, and you will get a simple interactive shell. For lengthier stuff you can just launch some .py scripts.
Python is extremely versatile and it is easy to read and understand the code which is why i like it so much. Once one is somewhat familiar with the language it can have many applications.
Learned it like two years ago and been using it for like, batch renaming copying and conversion of image sequences and other files, scripting in place of sh+awk scripts in the linux world, generating thumbnails and some html snippets for my image gallery, data analysis and graph plotting, compiling my plugins via a python based build system, and even "remote" controlling photoshop. :)
EdBever
09-03-2010, 08:36 AM
Learning and learning
Thank you guys for all the info.
The solustion for me was to make spreadX a vector
spreadX = c4d.vector(0)
This vector can be updates al the time, but I made a thinking mistake at start. Because the rando movement happend every frame, so the cube jumped every frame is was not even possible to get a smooth movement.
So working on that now and hopefully it will all work in the end.
Thanks again
Ed Bever
You may want to check
http://mograph.net/board/index.php?showtopic=23744&st=0&p=185340&#entry185340
I've asked the question there also and ESC gives a good explenation.
Scott Ayers
09-03-2010, 02:54 PM
Btw. you can easily try things outside of cinema. Python is available as stand alone package for every system.
I've been toying around with it a little bit for a few weeks. But I haven't really spent much serious effort on it yet. I'm still learning other languages.
I don't like winging it when I'm learning this stuff. Because it's easy to invent bad habits that way.
So I like to ask people with more experience to double check my thinking from time to time just to make sure I'm doing things the right way.
-ScottA
CGTalk Moderation
09-03-2010, 02:54 PM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.
vBulletin v3.0.5, Copyright ©2000-2012, Jelsoft Enterprises Ltd.