Notifications
Clear all

[Closed] Python + MXS

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.

1 Reply
(@rustyknight)
Joined: 11 months ago

Posts: 0

A nice and simple response…I like it

joel & rustyknight

thanks guys , now there is no confusion … but frustration !

1 Reply
(@rustyknight)
Joined: 11 months ago

Posts: 0

Try compiling a C++ solution then talk to me about frustration!! Glad we could be of help!!

failed to learn it 8 years ago ! lol

 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

1 Reply
(@cyfer)
Joined: 11 months ago

Posts: 0

thanks dave for the help
i’ll reRead this thread from the beginning …

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

Page 8 / 26