Hay cyfer!
Hay, I could be completely wrong here, as I said, I have no experience in this particular area, but from you original post, that's what jumped out at me
conn.DoSomething("Box position:[10,10,10] length:10 Width:10 height:10")
conn.DoSomething("Box position:[i*10,i*10,i*10] length:10 Width:10 height:10")
The second statment says to me, pass the string value "Box position:[i*10,i*10,i*10] length:10 Width:10 height:10" to max and max is going "I don't know what [i][b]i [/b][/i]is and [i][b]undefined * 10[/b][/i] is not a valid calculation!?"
I just had a look at this line
"Box position:[' + i*10 +',' + i*10 + ',' + i*10 + '] length:10 Width:10 height:10"
and I’d be interested to know, is the ” i * 10 ” been evaluated to a final value (ie i = 10; i * 10 = 100) or been passed through as a string literal “i*10”
Basically, what you want to do is evaludate the result of " i*10 " before it gets to max and pass that [b]result[/b] through, not the calculation...
Have you tried assigning the final result to a string value first and passing that in???
result = i * 10
evaluateThis = "Box position:[" + result + "," + result + "," + result"] length:10 Width:10 height:10"
conn.DoSomething(evaluateThis)
And yes, I want to concat the “evaluteThis” string
So that max will recieve the string:
Box position:[100,100,100] length:10 Width:10 height:10
Assuming that i is 10
“python is passing what to maxscript ? only strings ? “
This is essentially the case.
joel & rustyknight
thanks guys , now there is no confusion … but frustration !
Try compiling a C++ solution then talk to me about frustration!! Glad we could be of help!!
Hi Guys,
First off Martin, Shane your more than welcome, I'm just glad that I can give something back to the community. One of these day we will have to get together and paint the town red...
As Shane and Joel correctly pointed out, in this case just strings are being parsed, that is not to say that other data type cannot be parsed across. When it come to formating strings for things like this I would typically format it this way:
for i in range(1,11):
conn.DoSomething("Box position:[%s*10,%s*10,%s*10] length:10 Width:10 height:10" % (i,i,i))
In this case the "%" character which marks the start of the 'specifier'. "s" will convert any python objects into a string, the same as going str(i). At the end of the string we give it a tuple of out variables, in this case we want i there each time so its just (i,i,i) these variable could had have been any python obj!
Cheers
Dave
So using Com, would there be a way to pass a bitmap object to max somehow? or would the best method be to open a PIL image, convert it to an array, pass that to max & use set pixels or something to recreate an bitmap? I’m guessing that would be fairly slow…
Hi Chris,
That would work just fine but as you rightly pointed out it would be pretty slow, other alternatives would be to just parse the path to the image to max and open it that way. I guess it depends on what you doing, you could also use PIL to save a temp image and then parse the temp file path to max…
Cheers
Dave
Hi Guys,
This is a little script I quickly through together for a mate and thought some of you might like it. You can parse commands from max to python and have the tracbacks and stdout returned to you.
Here is a simple example:
http://forums.cgsociety.org/attachment.php?attachmentid=118728&stc=1
Here is an example of a traceback:
http://forums.cgsociety.org/attachment.php?attachmentid=118729&stc=1
Anyways time for some code:
here is the python code:
"""
Simple Com Class for parsing commands to the python.
Will return sys.stout or in the event of a exception, it will catch the error
and return the traceback.
Crafted By
David Mackenzie
Notes:
- If you get a error in max that is something like "Cannot create instance of (com class)
try registering the Com Class from a admin account.
- This is just a hack, so if for some reason your computer self destructs its not my fault.
"""
import sys
import os
import win32com.server.register
Writing = True
def TBWrite():
"""Returns the traceback as a string, VERY handy dandy biatch"""
import traceback
return traceback.format_exc()
#Catch sys.stdout, this is what would normaly be returned to the screen by python
class CatchOut:
def __init__(self, obj):
"""obj requires the method COut"""
self.Obj = obj
def write(self, data):
"""This method catches sys.stdout, stdout expects a write method"""
self.Obj.COut(data)
#global Writing
#Writing = False
class MXSPrompt:
_public_methods_ = [ 'RunCom' ]
_reg_progid_ = "DaveTools.MXSPrompt"
_reg_clsid_ = '{CF24CDE3-680B-4A38-82E0-958C57921AF7}'
def __init__(self):
self.Buffer = ""
self.StdOut = CatchOut(self)
#sys.stderr = self.StdOut
sys.stdout = self.StdOut
def RunCom(self, commstr):
"""Method that is visible to COM"""
try:
global Writing
self.Buffer = ""
exec commstr
"""
while(Writing):
pass
Writing = True
"""
return self.Buffer
except:
return TBWrite()
def COut(self, dstr):
"""Just Updates the Buffer"""
self.Buffer = self.Buffer + dstr
if __name__ == "__main__":
win32com.server.register.UseCommandLine(MXSPrompt)
And now for the max code:
/*
Just a quick hack to demonstraight some python in max. This is a very script on both ends.
If there is any interest I will develop it further.
crafted by, David Mackenize
Notes:
-Any strange errors, python or max please send to me.
-I would recomend, where ever you would like to place a tab insert 4 'spaces'
-You might find that if you have 2 or more Dialogs open (of this script) the previous ones
will drop/loose there connection with COM.
Cheers
Dave
*/
fn GetComObj = (
try(
o = createOLEObject "DaveTools.MXSPrompt"
return o
)catch(
print "error create ole object"
return False
)
)
rollout pyprompt "Python Prompter" (
group "Py Prompt" (
edittext py_out "" height:125
edittext py_in "" height:150
)
button btn_submit "Submit" align:#right
local obj = GetComObj()
on btn_submit pressed do(
t = obj.RunCom py_in.text
py_out.text = t
)
)
createDialog pyprompt 450 350
Cheers
Dave
Hi Guys,
A couple people following the thread have asked about some database code, I did have some stuff I wrote ages ago, which for whatever reason has seemingly disappeared from my hard drive! None the less I had been promising to post some code for a long time, I finally got off my ass and wrote some new stuff…
So here a really simple class to demo straight saving maxfiles to (or any data for that matter) to a database (I was using MySQL i have tested the code with anything else).
I will post a com version later tonight… anyways enough jibba jabba here is the code, if you get any errors just post them or pm me and yes I was lazy and did not comment my code I will fix this later though…
Cheers
Dave
"""
Demo Class showing interaction with MySQLdb.
The Class assumes there is db called 'mymaxfiles' and that it has a table called 'maxfiles'. Its just a basic example of how one
my want to store some files etc...
All the methods below assume the database mymaxfile exists as well.
Crafted By,
David Mackenzie
First off I don't pretend to be some SQL hacker! I just know what I need to....
This is a simple class for interacting with simple db and table. It could easily be modified to do allot more.
You will also require MySQLdb for this to work you can download here "http://sourceforge.net/projects/mysql-python".
I should also point out that I have not debugged this a great deal, I have however had no errors thrown in all my testing,
if you do get an error just shoot it acrros to me...
Cheers
Dave
"""
import MySQLdb as mys
import os
import os.path as pt
def InsertMaxFile(thefile):
db = mys.connect(host="localhost", user="root", passwd="daveRoot", db="mymaxfiles")
mycurs = db.cursor()
mycurs.execute("INSERT INTO maxfiles (files) values('%s')" % (thefile))
db.commit()
return True
def CreateTable(self):
try:
db = mys.connect(host="localhost", user="root", passwd="daveRoot", db="mymaxfiles")
mycurs = db.cursor()
db.commit("CREATE TABLE maxfiles (id INT NOT NULL AUTO_INCREMENT, files varchar(256) NOT NULL, primary key(id));")
return True
except:
return [False, TBWrite()]
def TBWrite():
import traceback
return traceback.format_exc()
class MaxFileSaver:
def __init__(self, server, username, password, database):
try:
self.db = mys.connect(host=server, user=username, passwd=password, db=database)
self.Cursor = self.db.cursor()
self.Connected = True
self.Commited = True
except:
self.Connected = False
self.db = None
self.Cursor = None
self.Commited = True
print TBWrite()
def InsertFile(self, thefile):
if self.Connected == True:
try:
self.Cursor.execute("INSERT INTO maxfiles (files) values('%s')" % (thefile))
self.Commited = False
return True
except:
return [False, TBWrite()]
else:
return [False, "Something went wrong"]
def CommitChanges(self, yayorney):
if self.Connected:
if yayorney == True:
try:
self.db.commit()
self.Commited = True
return True
except:
self.Commited = False
return [False, TBWrite()]
else:
return [False, "Not Connected"]
def GetFiles(self):
if self.Connected:
try:
self.Cursor.execute("SELECT * FROM maxfiles")
return (self.Cursor.fetchall())
except:
return [False, TBWrite()]
def SetFile(self, theid, thevalue):
if self.Connected:
try:
print self.Cursor.execute("UPDATE maxfiles
SET files='%s' WHERE id='%s'" % (thevalue, theid))
return True
except:
return [False, TBWrite()]
else:
return [False, "Not Connected"]
def DeleteFile(self, theid):
if self.Connected:
try:
self.Cursor.execute("DELETE FROM maxfiles WHERE id=%s" % (theid))
return True
except:
return [False, TBWrite()]
else:
return [False, "Not Connected"]
def RollBackChanges(self, yayorney):
if self.Commited == True:
return [False,"Data already commited, better luck next time"]
if self.Connected:
if yayorney:
try:
self.db.rollback()
return True
except:
return [False, TBWrite()]
else:
return [False, "Not Connected"]
def ReConnect(self, server, username, password, database):
self.Connected = False
self.db = None
self.Cursor = None
self.Commited = True
try:
self.db = mys.connect(host=server, user=username, passwd=password, db=database)
self.Cursor = self.db.cursor()
self.Connected = True
except:
return [False, TBWrite()]
if __name__ == "__main__":
con = MaxFileSaver("localhost", "root", "daveRoot", "mymaxfiles")
print con.InsertFile("C:\\\\With Any luck this will work.max")
print con.CommitChanges(True)
for i in con.GetFiles():
print i
print con.DeleteFile("14")
print con.SetFile("23", "C:\\\\SomeNewFile")
print con.CommitChanges(True)
Hi guys,
Just wrote a new com class for MySQL connections. It works well and is simple to implement.
Here is the code:
"""
MySql com class, provides basic connection to MySQL across com.
Crafted By,
David Mackenzie
Notes:
-All errors are handled, if an exception is caught, a list is returned as [False, the traceback]
-Requires MySQLdb, http://sourceforge.net/projects/mysql-python
-If you get any tracebacks please post them or send them to me!
-I pulled this code from a larger implementation im working on so there may be some bugs, although there should not.
Max Usage:
>> a = createOLEObject "DavesTools.ComSql"
<OLEObject:DavesTools.ComSql>
>> a.Connect "localhost" "root" "daveRoot" "mymaxfiles"
true
>> a.Execute("SELECT files FROM maxfiles WHERE id=3")
true
>> a.Fetch()
SafeArrayWrapper #("Somemaxfile.max") #(0)
"""
import MySQLdb as mys
import traceback
class ComSql:
"""Com interface for parsing SQL commands."""
_public_methods_ = ['GetCommited',
'GetConnected',
'Connect',
'Execute',
'Fetch',
'RollBack',
'Commit']
_reg_progid_ = 'DavesTools.ComSql'
_reg_clsid_ = '{3B165F3B-6E90-4E1B-AA34-D6B3E51C9115}'
def __init__(self):
self.Connected = False
self.Commited = True
self.Cursor = None
self.db = None
def GetCommited(self):
return self.Commited
def GetConnected(self):
return self.Connected
def Connect(self, server, username, password, database):
"""Connect to the database"""
try:
self.db = mys.connect(host=server, user=username, passwd=password, db=database)
self.Cursor = self.db.cursor()
self.Connected = True
self.Commited = True
return True
except:
self.Connected = False
self.Commited = True
self.Cursor = None
self.db = None
return [False, self.__sqlerror()]
def Execute(self, command):
"""Execute the parsed command."""
if self.Connected:
try:
self.Cursor.execute(command)
self.Commited = False
return True
except:
return [False, self.__sqlerror()]
else:
return [False, "Not Connected"]
def Fetch(self):
"""Return Data from the db, the appropiate command should had have been parsed to execute before hand"""
if self.Connected:
try:
return self.Cursor.fetchall()
except:
return [False, self.__sqlerror()]
else:
return [False, "Not Connected"]
def RollBack(self):
"""Roll back any un-commited changes"""
if self.Commited:
return [False, "Data already commited"]
else:
if self.Connected:
try:
self.db.rollback()
return True
except:
return [False, self.__sqlerror()]
else:
return [False, self.__sqlerror()]
def Commit(self):
"""Commit changes to database"""
if self.Connected:
try:
if self.Commited == False:
self.db.commit()
self.Commited = True
return True
except:
return [False, self.__sqlerror()]
else:
return [False, self.__sqlerror()]
def __sqlerror(self):
return traceback.format_exc()
if __name__ == "__main__":
TESTING = False
if TESTING:
print "Testing
"
con = ComSql()
print "Connect:
", con.Connect("localhost", "root", "daveRoot", "mymaxfiles")
print "Execute:
", con.Execute("INSERT INTO maxfiles (files) values('C:\\\\SomeNewFile.max')")
print "Commint:
", con.Commit()
print "Execute:
", con.Execute("SELECT * FROM maxfiles")
print "Fetching:
", con.Fetch()
print "
Done"
else:
print "Registering COM server..."
import win32com.server.register
win32com.server.register.UseCommandLine(ComSql)
Cheers
Dave