PDA

View Full Version : Python + MXS


Pages : 1 [2]

ndufort
02-20-2009, 09:41 AM
It's a copy of the code from the first post with the comments removed:

The Max part, which when run, returns "OK":


[/indent]The python part, which throws no errors, but fails to do anything:


I know quite a bit of MEL and some C++. I also know a little MaxScript. I'd say I'm probably an intermediate user. I understand how code works, and can look up things if I don't know them. The weird thing about Python is the use of indenting as a way of demarcating code blocks, as opposed to using parenthesis, etc. I'm not indenting any of the lines in the Python part, and I don't know if maybe I'm missing something, or maybe I'm not running it the right way in the Idle interface? I type it in, and hit return, but it doens't do anything. I've managed to get some simple code (i.e. "hello world" type stuff) to work in Python. So, I don't know :D

I copied and pasted your code, with the exception of the MAX.Application version, and everything worked fine.

Have your registered Max properly? Adam has shared some great code that does it for you - and other things (I like his code as it allows you to share data between Max and Python). Look up his page and download the zip file and look under 6_COM:
http://techarttiki.blogspot.com/2008/03/gdc-wrap-up.html

As for learning Python, if you have experience with other languages, why not start with the official Python docs/tutorial, and look up some of the online books. Dive Into Python is fun if you already know how to code, and I also like the O'Reilly books. I'm not a programmer myself, but I like to learn by looking at people's code as well. Online forums are a good place for this.

RyanT
02-23-2009, 05:48 AM
Forgive me for my ignorance guys. I use Python in Maya and used maxscript for years but have yet to try Python in Max. I am trying to get the code on post 93 to work link here:

http://forums.cgsociety.org/showpost.php?p=4686517&postcount=93

The python and maxscript works. But I am not clear on how I am to execute this process. I have Python 1.6 installed now. I opened up 3ds max and I opened up the IDLE Python Shell. I copy/paste the Python code into the Shell which executes with no errors.

Then in max I run the maxscript portion. Which prints this:

GetComObj()
"error create ole object"
Rollout:pyprompt
"error create ole object"
true

I type this into the top portion of the UI:

foo = 10

And I press the submit button. And now it errors and prints this:

GetComObj()-- Error occurred in btn_submit.pressed()
-- Frame:
-- t: undefined
>> MAXScript Rollout Handler Exception: -- Unknown property: "RunCom" in false <<

"error create ole object"
Rollout:pyprompt
"error create ole object"
true

What am I doing wrong?

vScourge
02-23-2009, 11:39 AM
Are you sure the Python code is fully executing? If you paste that Python code into IDLE shell exactly as-is from that post and hit Enter it probably won't work. The code has indents at the start of each line, and the "if __name__" statement at the bottom won't execute and register the COM server. It has to be run from a file (or remove the "if" and outdent the register command).

Try hitting File/New Window in IDLE and pasting it into the new script window. Fix the indents, save, then run it.

RyanT
02-23-2009, 05:52 PM
You said:

"It has to be run from a file"

Well I did not copy it exactly, I did fix the indents. But I did copy paste that into the IDLE which "worked". But your saying it has to be run from a file. I will try opening up the window saving and running.

Thanks,

RyanT
02-24-2009, 07:32 AM
Ok got it to work.

# Steps to make this script work:

# Step 1: Download Python Version x.x any version will do I think.
# Step 2: Download and install pywin32 which has the win32com python module in it here: http://sourceforge.net/projects/pywin32/
# Step 3: Make sure to download the win32com for the python version you have downloaded
# Step 4: Open up the Python IDLE Shell and select File\New Window
# Step 5: Open up the Python module or create a new one with the Python Com Class code
# Step 6: Select from the menu with the Python module the menu Run\Run Module or hit F5
# Step 7: Open 3ds Max
# Step 8: Open the script editor and run the maxscript code.

My main step missed was the win32com module. I didnt see anyone talking about it here, but I must have missed it.

ndufort
02-24-2009, 09:43 AM
Ok got it to work.

# Step 2: Download and install pywin32 which has the win32com python module in it here: http://sourceforge.net/projects/pywin32/
# Step 3: Make sure to download the win32com for the python version you have downloaded

My main step missed was the win32com module. I didnt see anyone talking about it here, but I must have missed it.
I'm surprised you did not get an error earlier when trying to import win32com.server.register (looking at the code of post #93).

JamSession
02-26-2009, 06:42 PM
I am really trying to help build a python community for Max in the hopes they integrate it like Maya and XSI.

I am going to try to post some code snippets and small procedures to keep building interest and a user base.

This is a small script to select the hierarchy of one selected object using vScourge/Volition's max com setup from GDC.



#import the win32
import win32com.client
#connect to Max
mx = win32com.client.Dispatch('Max.Application')
#start the com in Max
mx._FlagAsMethod('command_from_python')
#create an empty variable to populate the selected object with
mx.command_from_python ('getSel = #()')
#create another max variable to store the hierarchy to call the selction.
mx.command_from_python ('sel = #()')
#populate the variable
mx.command_from_python ('for o in selection do (append getSel o)')
#Currently on works on a single selected object, but query the first selected object
sel= (mx.command_from_python('getSel[1].name'))

#create a python array to store the loops in
lhier = [sel]

def SelHier(obj):
childNum = (mx.command_from_python('$%s.children.count' % obj))
for i in range (childNum):
#since max starts arrays with 1 instead of 0, we need to add one first!
i+=1
child=mx.command_from_python('$%s.children[%i].name' %(obj,i))
lhier.append(child)
SelHier(child)

#call the def to traverse through the hierarchy
SelHier(sel)
#populate the max variable sel
for node in lhier:
mx.command_from_python('append sel $%s' % node)
#select it in max
mx.command_from_python('select (sel)')
#cleanup
del(lhier,SelHier,sel)

ndufort
02-27-2009, 09:42 AM
I am really trying to help build a python community for Max in the hopes they integrate it like Maya and XSI.

I am going to try to post some code snippets and small procedures to keep building interest and a user base.

This is a small script to select the hierarchy of one selected object using vScourge/Volition's max com setup from GDC.
This is a nice idea, and I really hope people will go this way. While not a Max user, I have tried to talk people into using Python with Max at work.

Thanks to Adam's notes, I managed to get work done without having to touch Max. I made a quick script that could convert all our shot cameras to .chan for later use in Nuke (went from two and a half minutes to convert a cam by hand to only a few seconds). This could have been done in Maxscript; but I don't know Maxscript and none of the processing needed Maxscript per se--and I could use my own Python tools to take care of shot/seq information.

While I really don't care for Max, it would be neat indeed if Python were properly integrated into it. It just amazes me that all other major apps, closed and open source, have had Python support for years and not Max.

nico

labbejason
03-09-2009, 04:11 AM
I'm trying to do the first example to create a box from Python. I think the script is failing when it reaches to this point:
win32com.client.Dispatch("MAX.Application.9")
I'm using max 2008 though, so I tried changing the 9 to a bunch of variations. I feel stupid for asking but, what would that be for max 2008? :D

ndufort
03-09-2009, 10:40 AM
I'm trying to do the first example to create a box from Python. I think the script is failing when it reaches to this point:
win32com.client.Dispatch("MAX.Application.9")
I'm using max 2008 though, so I tried changing the 9 to a bunch of variations. I feel stupid for asking but, what would that be for max 2008? :D
How did you register Max? You should be able to read your registry (w/ 'regedit') and find under HKEY_CLASSES_ROOT a key called Max.Application.# (# being 9, 10, etc.) Given the Max history (http://en.wikipedia.org/wiki/3ds_Max_release_history), I guess 2008 would be 10.

In case you did not register Max properly, try Adam Pletcher's script (can be found under GDC Wrapup on this page (http://techarttiki.blogspot.com/search/label/gdc)). Look under the COM folder.

madAzrael
07-28-2009, 08:47 PM
Hi there!

First of all: Thank you all for this great thread. It helped me VERY much.
I learned how to use a python script in maxscript! yay!
I learned how to send maxscript-commands to 3ds max from python! yay!
(both over COM)

That really helped me out, thx!!!

...but now i'm stuck. :(

I have a python application (a GUI built with wxPython) and like i said, i can send maxscript-commands to 3ds max. so i can create objects or get all selected objects and things like that. Now i want the gui to update itself if for example in 3dsmax the selection has changed (or on any other event). How can i do that?

I tried to execute a pythonscript from maxscript, which gets an instance of my GUI and executes a method that updates the GUI. 3ds max crashed... i think because 3dsmax was still waiting for a return value when the gui tried to update (and therefore connected to 3dsmax) and BAM! Okay, next thing i tried was using thread to update the GUI asynchronously. Well, 3dsmax didnt crash but nothing happend. At least i dont see anything. I think this approach is a dead end. Perhaps the GUI should poll 3dsmax but that's not a nice solution, either...

So, how can i send an event from maxscript to a python GUI? Has anyone done something similiar? What's the (best) solution?


Greetings,
Az

vScourge
07-29-2009, 12:25 AM
Try creating a COM server inside your Python app, and connecting to it from MaxScript (with createOLEObject). There's some details on making Python COM servers earlier in this thread. Getting bi-directional COM going in one app can be tricky, but it's definitely doable.

madAzrael
08-02-2009, 04:11 PM
The last few days i learned much about COM but i'm not sure i got it all right. So if i am mistaken, please correct me!
Links for information to COM:
http://oreilly.com/catalog/pythonwin32/chapter/ch12.html
http://www.zanshu.com/ebook/74_python-programming-on-win32/pythonwin32_snode222.html

The COM Server is called 'server', but i think it is a bit misleading, because it only publishes an object that can be used by other processes. You can execute the methods of this object, but it is always a new instance. Btw: The default seems to be that this method runs in the thread you called it from (inProc).

If i call python from maxscript, the class i published per COM is intanciated and i have no way to get the instance of my GUI, except communicating with my GUI thread per inter process communication. For example with the pythonmodule asyncore/asynchat see this link (http://www.doughellmann.com/PyMOTW/ipc.html) or with a library like pyro or twisted. Right?

But this seems a bit complicated. Starting a pyro server, registering a PythonCom server, calling the pythoncomserver in maxscript that then calls the pyro server which then triggers an event in the GUI...
Is this the way to go?

I didn't find anything about establishing a connection from maxscript directly.

One thing makes me wonder though:
If i send a command to maxscript from python (using the maxscriptcode in the first post of this thread), it is like sending a command to a server. But how does it work? This direction is so easy, why is the direction back to a python GUI so complicated?

I feel like i missed something. Some option that i can set when registering the pythoncom server, so everything works like i want it to. :D

If i get it working, i hope i can post a minimalistic example here to contribute something usefull to this thread.

BigMacchia
08-17-2009, 03:48 PM
Hi at all,
I tryed but python gived me error because it doesn't found max application.
I try to search max.application to regedit but I don't found nothing...
I don't know what I wrong...

what could it be?

thx a lot :-)

vScourge
09-20-2009, 12:51 PM
Hi at all,
I tryed but python gived me error because it doesn't found max application.
I try to search max.application to regedit but I don't found nothing...

See my post above (http://forums.cgsociety.org/showthread.php?p=5436099#post5436099). Max does not register any COM servers for itself by default, you have to tell it to do that. The registerPythonCom.ms script I mentioned will do that for you.

BigMacchia
09-24-2009, 01:29 PM
Yes I found it... I did and everything run good!!! thx!!! :-)

jedie
10-02-2009, 11:12 AM
Sure thing. I also added the code from that script to registerPythonCom.ms in my sample files (http://www.volition-inc.com/gdc/GDC2008_AdamPletcher_PythonSamples.zip) from my GDC talk (http://www.volition-inc.com/gdc/).

If anyone was having problems getting my COM samples to work before, grab the updated ZIP and give it a go.
I have run registerPythonCom.ms from GDC2008_AdamPletcher_PythonSamples.zip in 3dsmax 2009 x64 on vista. I get this error:
command_from_python()
OK
-- Error occurred in create_reg_key(); filename: D:\3DS Scripts\registerPythonCom.ms; position: 530
-- Frame:
-- key_name: "MAX.Application"
-- key_value_name: ""
-- key_value_type: #REG_SZ
-- key_value: "OLE Automation MAX Application"
-- reg_key: undefined
-- HKey: HKEY_CLASSES_ROOT
-- called in anonymous codeblock
-- Frame:
-- max_version: "11"
-- create_reg_key: create_reg_key()
-- reg_key: undefined
-- write_sub_key_data: write_sub_key_data()
-- Type error: HKey requires HKey, got: undefined
create_python_return_value()
command_from_python()
OK

Is there a problem to create reg keys without admin rights???
Where can i find the last scripts from you?

ehulser
10-16-2009, 04:59 AM
Hey guys,

Just letting you know, I started a new thread to get a little more visibility of it -

http://forums.cgsociety.org/showthread.php?p=6156251#post6156251

But we've released our code on a new blur-dev website:

http://blur-dev.googlecode.com

This contains full Python support in 3dsMax, along with a wiki on how to install and run everything. There is no more "python in maxscript" or "python through com" in it - its a direct implementation of python.

Also, for added fun, rollouts and dotNet can be done away with - all of our code supports and is driven by PyQt (http://qt.nokia.com/) which is a very powerful and fast framework.

Enjoy!

Eric Hulser
Tools Developer
Blur Studio

Vsai
10-16-2009, 03:57 PM
Eric, awesome news, and amazing that you guys share it so freely! thanks.

instinct-vfx
01-21-2010, 07:25 AM
Hi there,

is there any eta on the publication of the sources ? The reason beeing that this is basically kind of a break even for putting it in our pipeline. As with only binaries Version changes etc could kill a lot of dev time and effort as we can never know when/if recompiles will be there.

On a second note while installing on a different dev machine the problem with the system path variable beeing wiped occured again. I thought it was a different install but it is definately one of the Blur installers. I suspect the QT one as it seemed to hang on "adding to system path" on trying to install again.

Also for deploying it seems kinda bad currently. Can we simply copy over and set the correct env variables to deploy to a lot of machines ?

Kind Regards,
Thorsten

loocas
03-04-2010, 02:29 PM
Hi guys,

since I know a lot of you (including me!) would love to have native Python language integrated in 3ds Max, I’d like to share some of our very own stuff we’ve done on this front!

We’ve taken a different approach to Blur’s Python integration, which I have to admit is absolutely fabulous and much more deep and complex than ours, however, Blur’s implementation is very hard to adopt in any production pipeline since it’s completely proprietary, it’s not open source and Blur doesn’t ensure availability for any particular 3ds Max version you might be using.

Our approach, on the other hand, completely leverages on the .NET framework and thus makes our implementation 100% independent on the 3ds Max version or even platform you decide to use! I can run it on Max 9 32bit or Max 2010 64bit at the same time, no need for recompile or anything! Also, when a new IronPython comes out, or if you compile it yourself, just replace the libs and it’ll use that as the scripting engine immediately!

So, here are more technical details as well as a 13 minute features demo video (at the end)!

http://blog.duber.cz/3ds-max/duberpython-features-demonstration

Please, let me know what you think :)

I’m considering releasing this library of ours to the public, so, that’s why I’m showing it here.

instinct-vfx
03-04-2010, 02:45 PM
Hey there,

nice effort! Just wanted to point out that blur did a new version of their integration that seems a lot better then the initial approach, allows for QT and is indeed open source.

http://forums.cgsociety.org/showthread.php?f=98&t=816475

Here's the thread and you can get the sources at google code
http://blur-dev.googlecode.com/

Might be helpful in your ironpython approach too i guess

Regards,
Thorsten

loocas
03-04-2010, 03:27 PM
Thanks, I know about the new Blur approach, however, it's irrelevant to ours since Blur leverages on the CPython code, but we're using IronPython, written in C#, leveraging on dotNET. These are two entirely different worlds leading to one place - Python :)

As I said, Blur has done an amazing job and their version is much more complex, however, their version still need recompilation each time you install a new version of Max etc... ours doesn't.

Also, we chose to develop on .NET and its GUI libraries (including WPF) since we don't need to use other tools that aren't bound to Microsoft platform. We strictly use Max for all our 3D vfx work, so leveraging on .NET was the best way to go, for us.

As for other tools we use, like Nuke, we run our code written in IronPython, but we load different modules so that the GUI can be written in Qt, but the raw scripting can be done platform independent and thus works in both 3ds Max and Nuke.

Hey there,

nice effort! Just wanted to point out that blur did a new version of their integration that seems a lot better then the initial approach, allows for QT and is indeed open source.

http://forums.cgsociety.org/showthread.php?f=98&t=816475

Here's the thread and you can get the sources at google code
http://blur-dev.googlecode.com/

Might be helpful in your ironpython approach too i guess

Regards,
Thorsten

instinct-vfx
03-05-2010, 08:24 AM
Ah, got it. One reason i really dig Py3dsmax + PyQT over .net in native maxscript is that i still find dotNet incredibly slow. Even if it only is on first open per session i find it untolerable and it makes me go nuts even with the builtin dotNet tools. How's you're experience with the IronPython approach ? Is it the same or better ?

Regards,
Thorsten

loocas
03-05-2010, 01:30 PM
Well, there is a lag at first run, about 2-4s, but then it's instant, since we then keep IronPython in the memory, so anything else run through our IronPython bridge is instant.

As for GUI. Well, since it's all based on .NET, the raw Python GUI code is quite fast and I don't have problems with it. But, you can gain some speed by compiling the GUI into a DLL which you can then reference in your script, which makes it even faster for some super complex GUIs, which is cool. But I'm perfectly happy with the raw Python, scripted, GUI.

Ah, got it. One reason i really dig Py3dsmax + PyQT over .net in native maxscript is that i still find dotNet incredibly slow. Even if it only is on first open per session i find it untolerable and it makes me go nuts even with the builtin dotNet tools. How's you're experience with the IronPython approach ? Is it the same or better ?

Regards,
Thorsten

Kel Solaar
05-05-2010, 08:15 PM
Hello,

Anyone got luck making the COM Server works on Windows 7 ?

I registered it with the registerPythonCom.ms, I checked my registry, it seems to me the keys are there and correct, when I try this in a python interpreter :

>>> import win32com.client
>>> mx = win32com.client.Dispatch('Max.Application')

I have that sad message :

Traceback (most recent call last):
File "<pyshell#1>", line 1, in <module>
mx = win32com.client.Dispatch('Max.Application')
File "D:\Softwares\Developement\Python26\lib\site-packages\win32com\client\__init__.py", line 95, in Dispatch
dispatch, userName = dynamic._GetGoodDispatchAndUserName(dispatch,userName,clsctx)
File "D:\Softwares\Developement\Python26\lib\site-packages\win32com\client\dynamic.py", line 104, in _GetGoodDispatchAndUserName
return (_GetGoodDispatch(IDispatch, clsctx), userName)
File "D:\Softwares\Developement\Python26\lib\site-packages\win32com\client\dynamic.py", line 84, in _GetGoodDispatch
IDispatch = pythoncom.CoCreateInstance(IDispatch, None, clsctx, pythoncom.IID_IDispatch)
com_error: (-2147221164, 'Class not registered', None, None)

Funny thing is that I restarted the python interpreter an reran the same code, without any errors ... but now when I try registering a method like this :

>>> mx._FlagAsMethod('ExecuteSIBLLoaderScript')

I get a nasty :

Traceback (most recent call last):
File "<pyshell#6>", line 1, in <module>
mx._FlagAsMethod('ExecuteSIBLLoaderScript')
File "D:\Softwares\Developement\Python26\lib\site-packages\win32com\client\dynamic.py", line 427, in _FlagAsMethod
details = build.MapEntry(self.__AttrToID__(name), (name,))
File "D:\Softwares\Developement\Python26\lib\site-packages\win32com\client\dynamic.py", line 432, in __AttrToID__
return self._oleobj_.GetIDsOfNames(0,attr)
com_error: (-2147352570, 'Unknown name.', None, None)

which make sense since there is no reason it would have failed earlier and not now, though I don't understand the Dispatch method didn't made errors this time oO

:banghead:

ncxxf
06-18-2010, 03:49 AM
It's so Good

duke
07-22-2010, 04:34 AM
I'm a big .net fan so i'm really keen on this approach. Have you thought more about if you'll release it? :)

loocas
07-22-2010, 09:33 AM
I'm a big .net fan so i'm really keen on this approach. Have you thought more about if you'll release it? :)

Was this question aimed at me?

If so, I still haven't decided on a public release yet. We've just ironed out a few tiny kinks in the plugin, so, it seems we're good on this part, however, I still want to test drive the plugin before a public release.

Currently I've been working with an outside studio for the first time to use our Pythoner plugin for their production management system with Python API. So far I've ported all the native Python methods over to 3ds Max for direct Max <-> Server Python communication, so, this also seems good.

I'll let everyone know via this thread once our plugin is ready for the public.

If the question wasn't aimed at me, then, please, happily ignore this reply. :D

duke
07-26-2010, 06:25 AM
Was this question aimed at me?


It certainly was! Thanks for the update.

Tosyk
12-15-2010, 11:44 PM
Hi, i'm new in max scripting and want integrating python function in 3ds max. Firstly i toad that i need to totally re-wright full *.py script into maxscript language, but after i see this thread i really think about integrating. And for clean up for my self all of the previous posts i want ask for help. Please show to me how to run functions of python script into 3d max.

this is python script
import bpy,struct,os
import Blender
from Blender import *
from struct import *
from Blender.Mathutils import *
from Blender import Armature as A
from Blender.Window import DrawProgressBar
import math



#=========== open file ======================
extends=['bma','bms']
dir = os.getcwd()
g = os.listdir(dir)
bool={}
draw={}
block=[]
texpath="D:\\3D\\==SOURCES==\\king bounty\\textures"
for plik in g:
extend = plik[plik.lower().find('.')+1:]
if extend in extends:
bool[plik] = False
draw[plik] = Draw.Create(bool[plik])
block.append((plik,draw[plik]))
Draw.PupBlock("bma files",block)
for file in bool:
bool[file] = draw[file].val
if bool[file]==True:
filename = dir+os.sep+file
object = file
else:
Draw.Exit()
plik = open(filename,'rb')
vertexy=[]
uvcoord=[]
faceslist=[]
normalne=[]

print '============================================================='
print filename
print '============================================================='

def word(long):
s=''
for j in range(0,long):
s+=struct.unpack('c',plik.read(1))[0]
return s


print struct.unpack(16*'B',plik.read(16))
print struct.unpack('i',plik.read(4))

print
print "===skeleton==="
print
numbones = struct.unpack('i',plik.read(4))[0]
print 'numbones = ',numbones

a=10
b=1


scn = Scene.GetCurrent()
newarmature = A.Armature('arm')
newarmobj = Object.New('Armature','armature')
newarm = A.Get('arm')
newarm.drawType = Armature.STICK
newarmobj.link(newarm)
scn.link(newarmobj)

bonenames=[]
for i in range(numbones):
id = struct.unpack('i',plik.read(4))[0]
namebone = word(id)
#print namebone
namebone =str(i)
bonenames.append(namebone)
eb = A.Editbone()
struct.unpack('b',plik.read(1))
parent = struct.unpack('i',plik.read(4))[0]
p1 = struct.unpack(3*'f',plik.read(12)) #szkielet nr 1
p2 = struct.unpack(3*'f',plik.read(12)) #szkielet nr 2
p3 = struct.unpack(3*'f',plik.read(12)) #szkielet nr 3
if 'box' not in namebone and 'tipp' not in namebone:
newarm.makeEditable()
newarm.bones[namebone] = eb
newarm.bones[namebone].head=Vector(p1[0]*a*b,p1[2]*a*b,p1[1]*a*b)
newarm.bones[namebone].tail=Vector(p1[0]*a*b+0.01,p1[2]*a*b,p1[1]*a*b)
if i!=0:
newarm.bones[namebone].parent=newarm.bones[bonenames[parent]]
newarm.update()
struct.unpack(3*'f',plik.read(12))
struct.unpack(3*'f',plik.read(12))
struct.unpack(3*'f',plik.read(12))
struct.unpack(3*'f',plik.read(12))
struct.unpack(3*'f',plik.read(12))
struct.unpack(3*'f',plik.read(12))

print
print "===material==="
print
struct.unpack(4*'h',plik.read(8))#to samo

keywords = ['k_specularenvspecmask','k_specularenvspecmask_uvanim',\
'texDiffuse','k_specularenv',\
'texSpecular',\
'texEnv',\
'cLuminosity','tgLumiMap',\
'cDiffuse','k_diffuselumi','texLumiMap',\
'cSpecular',\
'cEnv',\
'fShadowTransp',\
'tgDiffuse',\
'tgSpecular',\
'k_diffuse','diffuse','k_specular']



id = struct.unpack('i',plik.read(4))[0]
key = word(id)
materials=[]
print key
numtex=0
while key in keywords:
if key == 'k_specular':
#plik.read(62)
print struct.unpack(62*'b',plik.read(62))
if key == 'k_specularenvspecmask':
plik.read(62)
if key == 'k_specularenvspecmask_uvanim':
plik.read(62)
if key == 'k_diffuse':
plik.read(62)
if key == 'k_diffuselumi':
plik.read(62)
if key == 'k_specularenv':
plik.read(62)
if key == 'diffuse':
plik.read(2)
info = struct.unpack(15*'i',plik.read(60))
print info
if info[11]==0:
print struct.unpack(4*'b',plik.read(4))
if key == 'texDiffuse':
newmat = Material.New(object[:-4]+'-M-'+str(numtex))
plik.read(5)
id = struct.unpack('i',plik.read(4))[0]
texdiff = word(id)
print 'texdiff = ',texdiff
imagepath = texpath+os.sep+texdiff
tex = Texture.New('tex'+str(numtex))
try:
img = Blender.Image.Load(imagepath)
tex.image = img
except:
print 'no found',imagepath
plik.read(1)
numtex=numtex+1
newmat.setTexture(0,tex,Texture.TexCo.UV,Texture.MapTo.COL)
materials.append(newmat)
if key == 'texSpecular':
plik.read(5)
id = struct.unpack('i',plik.read(4))[0]
texspec = word(id)
print 'texspec = ',texspec
plik.read(1)
if key == 'texLumiMap':
plik.read(5)
id = struct.unpack('i',plik.read(4))[0]
texspec = word(id)
print 'texspec = ',texspec
plik.read(1)
if key == 'texEnv':
plik.read(5)
id = struct.unpack('i',plik.read(4))[0]
texenv = word(id)
print 'texenv = ',texenv
plik.read(1)
if key == 'cLuminosity':
plik.read(21)
if key == 'cDiffuse':
plik.read(21)
if key == 'cSpecular':
plik.read(21)
if key == 'cEnv':
plik.read(21)
if key == 'fShadowTransp':
plik.read(9)
if key == 'tgDiffuse':
plik.read(1)
#print struct.unpack(84*'b',plik.read(84))
info = struct.unpack(24*'b',plik.read(24))
print info
if info[8]!=0:
print struct.unpack(60*'b',plik.read(60))
if key == 'tgSpecular':
plik.read(85)
if key == 'tgLumiMap':
plik.read(85)
back = plik.tell()
id = struct.unpack('i',plik.read(4))[0]
#print id
if id > 70:
plik.seek(back)
break
key = word(id)
print key


print
print'====mesh===='
print
numfacespermesh=[]
weightsgroup={}
struct.unpack(2*'H',plik.read(2*2))# TO SAMO W KAZDYM PLIKU
numobjects = struct.unpack('i',plik.read(4))[0]
print 'nummeshes = ',numobjects
texpermesh=[]
for i in range(numobjects):
info = struct.unpack(5*'i',plik.read(5*4))
texpermesh.append(info[1])
numfacespermesh.append(info[3]/3)
wg = struct.unpack(16*'B',plik.read(16))
weightsgroup[str(i)]=[]
for g in wg:
weightsgroup[str(i)].append(g)
struct.unpack('i',plik.read(4))[0]# TO SAMO W KAZDYM PLIKU
numvertices = struct.unpack('i',plik.read(4))[0]
print 'total numvertices = ',numvertices
groups={}
vertgroup=[]
for i in range(numvertices):
xyz = struct.unpack(3*'h',plik.read(6))
v1 = a*xyz[0]*2**-14
v2 = a*xyz[1]*2**-14
v3 = a*xyz[2]*2**-14
vertexy.append([v1,v3,v2])
dane = struct.unpack(5*'H',plik.read(10))
u = 2*dane[3]*2**-12
v = 2*dane[4]*2**-12
uvcoord.append([u,1-v])
dane = struct.unpack(8*'B',plik.read(8))
for j in range(4):
if dane[j]!=84:
if 'grupa'+str(dane[j]) not in groups:
groups['grupa'+str(dane[j])]=[]
#print dane[j]
groups['grupa'+str(dane[j])].append([i,float(dane[j+4])/255])
struct.unpack('i',plik.read(4))
numfaces = struct.unpack('i',plik.read(4))[0]/3
print 'total numfaces = ',numfaces
for i in range(numfaces):
f= struct.unpack('HHH',plik.read(3*2))
faceslist.append([f[0],f[1],f[2]])

mesh = bpy.data.meshes.new(object[:-4])
mesh.verts.extend(vertexy)
mesh.faces.extend(faceslist,ignoreDups=True)
for i in range(len(materials)):
mesh.materials += [materials[i]]

for faceID in range(0,len(mesh.faces)):
face = mesh.faces[faceID]
index1 = faceslist[faceID][0]
index2 = faceslist[faceID][1]
index3 = faceslist[faceID][2]
uv1 = Vector(uvcoord[index1])
uv2 = Vector(uvcoord[index2])
uv3 = Vector(uvcoord[index3])
face.uv = [uv1, uv2, uv3]
face.smooth=True
scene = bpy.data.scenes.active
scene.objects.new(mesh,object[:-4])
mesh.recalcNormals(0)

for i in range(16):
mesh.addVertGroup('grupa'+str(i))
mesh.update()
for vgroup in groups:
for dane in groups[vgroup]:
mesh.assignVertsToGroup(vgroup,[dane[0]],dane[1],1)
mesh.update()


def selectfaces(id,object,id1,id2):
obj = Object.Get(object)
mesh=obj.getData(mesh=1)
for i in range(16):
newgrup= str(weightsgroup[str(id)][i])
if newgrup not in mesh.getVertGroupNames():
mesh.addVertGroup(newgrup)
mesh.update()

for fid in range(id1,id2):
face = mesh.faces[fid]
face.mat = texpermesh[id]
for namegroup in mesh.getVertGroupNames():
if 'grupa' in namegroup:
listvert = mesh.getVertsFromGroup(namegroup)
#print listvert
for v in face.v:
if v.index in listvert:
for inf in groups[namegroup]:
if v.index == inf[0]:
nowagrupa=str(weightsgroup[str(id)][int(namegroup[5:])])
mesh.assignVertsToGroup(nowagrupa,[v.index],inf[1],1)

id1=0
for i in range(len(numfacespermesh)):
id2=id1+numfacespermesh[i]
#print id1,id2
selectfaces(i,object[0:-4],id1,id2)
id1=id2

DrawProgressBar (i/len(numfacespermesh),"%s"%i)
DrawProgressBar (1,"wczytano")

Redraw()

this python script imports *.bms 3d models into blender, so all i want that *.bms 3d models imports in 3d max.

jedie
05-03-2011, 09:03 AM
Hay everyone seen this: https://autodesk.uservoice.com/forums/80701-publicsdkandscriptingenhancements/suggestions/1489587-python?ref=title
Please vote, if you like to see python in 3dsmax!

denisT
05-03-2011, 10:51 AM
Hay everyone seen this: https://autodesk.uservoice.com/forums/80701-publicsdkandscriptingenhancements/suggestions/1489587-python?ref=title
Please vote, if you like to see python in 3dsmax!
if i don't can i vote against? ;)

jedie
05-03-2011, 11:25 AM
write a comment, why this is not good for you... ;)




why do you against it?

denisT
05-03-2011, 11:32 AM
write a comment, why this is not good for you... ;)




why do you against it?

i want to see c# fully integrated in max. from my experience i know when the system tries to support two alternative ways, it makes both of them clumsy.

ehulser
05-13-2011, 12:02 AM
Hey all -

I know its been a hell of a long time - but the Blur support for Python in 3dsMax is back online. It has been working in production for us for a year now, so a lot of the bugs and clunks from the initial go at it have been worked out.

You can download the project (including source code) here:

blur-dev.googlecode.com (http://blur-dev.googlecode.com)

Cheers,
Eric

holycause
05-20-2011, 12:27 PM
Thx a lot for it Eric :)

Malequus
07-05-2011, 08:14 PM
Eric - thanks for this - its awesome to have both the source and the plugins to tinker with! Much nicer than the current state of Maxsharp, and more pythonic too. Any chance Autodesk will adopt this in the same way they did Pymel?

Anyone had good luck getting the latest to work? Any stumbling blocks?

I've been tinkering with it a bit on Win7x64, Max2011x64, and it does seem to have some rough patches. I've been able to get python executing from Maxscript and vice-versa, but I've not had much luck getting the logger to come online.

Update: All the logger issues seemed to stem from Qt being unhappy. removing all installs except the one that comes with the blur installer seems to have done the trick :-)

One last useful thing - Autodesk posted some wonderful Py3dsmax tips that reflect the current build. Could this be a sign of beautiful things to come?

http://area.autodesk.com/blogs/chris/py3dsmax_python_scripting_for_3ds_max_from_blur_studios

FOLLYX
11-03-2011, 07:30 AM
Hi together,

please could anyone support the setup with 3dsMax 2012? Tried it a couple of times, changing the path's and so on without success.
I use the standard installationpaths.

jaydru
11-19-2011, 09:36 PM
hey guys, i'm trying to set up whats in the op and i'm getting this error in in python when i try to import win32com.client

File "C:\Python27\lib\site-packages\win32com\__init__.py", line 5, in <module>
import win32api, sys, os
ImportError: No module named win32api

anyone know whats up with this?

holycause
11-20-2011, 08:50 AM
it s a python module

http://code.google.com/p/blur-dev/wiki/Installing

How to get pywin32

Some of our tools will use the pywin32 package for Python, which is a 3rd-party package that can be found here:

pywin32 (http://sourceforge.net/projects/pywin32/files/pywin32/)

Direct links to the latest Python24 x32 version are here (http://sourceforge.net/projects/pywin32/files/pywin32/Build216/pywin32-216.win32-py2.4.exe/download).

Direct links to the latest Python26 x64 version are here (http://sourceforge.net/projects/pywin32/files/pywin32/Build216/pywin32-216.win-amd64-py2.6.exe/download)

Here are some instructions to get Python up and running in Softimage if you have not already done so:


http://xsisupport.wordpress.com/2010/02/22/getting-python-to-show-up-in-softimage/

jaydru
11-20-2011, 02:44 PM
yeah i have the pywin32 module, its just when i try to import win32com.client it fails, are you syaing i need to install all that blur-dev stuff aswell?

jaydru
11-22-2011, 12:17 AM
it works now, not sure why it wasn't before, strange

lucasky
01-01-2012, 08:47 PM
Hi,
I am trying the Py3dsMax (http://code.google.com/p/blur-dev/wiki/Py3dsMax) python tool.
I took this max script exemple and try to convert it in python.


macroScript QuickPreview category:"HowTo"

(
preview_name = (getDir #preview)+"/quickpreview.avi"
view_size = getViewSize()
anim_bmp = bitmap view_size.x view_size.y filename:preview_name
for t = animationrange.start to animationrange.end do
(
sliderTime = t
dib = gw.getViewportDib()
copy dib anim_bmp
save anim_bmp
)
close anim_bmp
gc()
ramplayer preview_name ""
)


I can't translate these commands anim_bmp = bitmap view_size.x view_size.y filename:preview_name
copy dib anim_bmp
save anim_bmp
in a pythonic syntax.

Does anybody have an idea or some code example for Py3dsMax (http://code.google.com/p/blur-dev/wiki/Py3dsMax)?

Thanks lucas

ehulser
01-16-2012, 10:53 PM
Most things are accessible via the mxs module, so you should be able to write that code as:

Maxscript:

anim_bmp = bitmap view_size.x view_size.y filename:preview_name
copy dib anim_bmp
save anim_bmp

Python:

anim_bmp = mxs.bitmap( view_size.x, view_size.y, filename = preview_name )
mxs.copy( anim_bmp )
mxs.save( anim_bmp )

I haven't actually tested that, but that SHOULD work.

chrsmrphy
02-24-2012, 07:19 PM
My question is basically as it reads in the title. I'm switching from just Maxscript to Python and Maxscript since I understand Python much more. My question is whether or not the built in object sets and arrays like "objects" or "geometry" are still accessible, and if so, what changes in how they are called? Thanks. You guys are very helpful with trying to figure out MaxScript.

irendeir
04-04-2012, 04:33 PM
Hi all! There is little question:
I need rotate in XForm gizmo. But I can not do that, tell me what the problem is and how to rotate it? Thank you for your attention.

from Py3dsMax import mxs

for obj in mxs.objects:
XForm = mxs.pyhelper.namify('XForm') # set flag
obj.modifiers[XForm].gizmo.rotation += mxs.quat(0.707107, 0, 0, 0.707107) # rotate 90"

irendeir
04-05-2012, 02:23 PM
I solved the problem though not completely in Python. I would like to make it completely in Python.

mxs.addModifier(obj, mxs.XForm())
XForm = mxs.pyhelper.namify('XForm') # set flag
mxs.execute('max modify mode')
mxs.modPanel.setCurrentObject(obj.modifiers[XForm])
mxs.execute('mod_obj = modPanel.getCurrentObject();gizmo_rotation = mod_obj.gizmo.rotation;mod_obj.gizmo.rotation += quat 0.707107 0 0 0.707107') # rotate 90"