3DS Max Python scripting - python

I have been looking for hours how to perform a very simple script in Python for 3DS Max (v2017), but the APIs are terrible - to say the least.
I can't even get how to select an existing object in the scene..
Plus I do not understand if I should use pymxs wrapper or MaxPlus.
What I need to do is simply tell to 3ds Max to change a Rendering Effect Attribute when a certain scene camera is selected - or the view is switched to that camera.
I will write you down the script in pseudo code so you can - hopefully - better understand the topic:
camera_1 = MaxPlus.Factory.SelectCameraObject("36x24_MoreDof")
# camera name is 36x24_MoreDof
camera_2 = MaxPlus.Factory.SelectCameraObject("36x24_LessDof")
# camera name is 36x24_LessDof
effect1 = RenderingTab.EnvironmentAndEffects.Effects.Attribute1
effect2 = RenderingTab.EnvironmentAndEffects.Effects.Attribute2
effect1.active = False
effect2.active = False
while True:
if camera_1.isSelected == True:
effect1.active = True
effect2.active = False
elif camera_2.isSelected == True:
effect1.active = False
effect2.active = True
I hope it is clear enough..
Do you have any idea how to translate this in actual Python code for 3DS Max?
Thanks you all in advance,
Riccardo

Below is python script to use as a guide for your request.
PyMXS; my advice is to use this primarily. It wraps almost all of MaxScript (except for some exotic MaxScript syntax features). It has been continuously developed for decades, is robust, and offers a lot of helper functionality and simplifications compared to the 3ds Max SDK which it's build on.
MaxPlus; my advice is to use certain bits of this which aren't covered by PyMXS (for example the function MaxPlus.GetQMaxMainWindow() for creating a Qt-based UI), but don't use this as the primary tool in Python. It is newer, and while it might prove better for Python exposure of the 3ds Max SDK in the long term, you might prefer PyMXS for coverage and simplicity in the short term.
Basically, I recommend thinking of yourself as a MaxScript programmer who uses Python for the language benefits. To access the 3ds Max scene, go through MaxScript (via PyMXS). Then you employ Python's strengths for string processing and data management (dictionaries!). Use MaxPlus when necessary for certain lower-level SDK access.
The script below fetches an object by name, fetches a render effect by index, and enables/disables the render effect according to the object selection:
import pymxs
mxs = pymxs.runtime
object_1 = mxs.getNodeByName( "Camera001" )
effect_1 = mxs.getEffect(1)
effect_1.camera
mxs.setActive(effect_1, mxs.false)
if object_1.isSelected:
mxs.setActive(effect_1, mxs.true)
Hope this helps!

Related

Converting Intersystems cache objectscript into a python function

I am accessing an Intersystems cache 2017.1.xx instance through a python process to get various attributes about the database in able to monitor the database.
One of the items I want to monitor is license usage. I wrote a objectscript script in a Terminal window to access license usage by user:
s Rset=##class(%ResultSet).%New("%SYSTEM.License.UserListAll")
s r=Rset.Execute()
s ncol=Rset.GetColumnCount()
While (Rset.Next()) {f i=1:1:ncol w !,Rset.GetData(i)}
But, I have been unable to determine how to convert this script into a Python equivalent. I am using the intersys.pythonbind3 import for connecting and accessing the cache instance. I have been able to create python functions that accessing most everything else in the instance but this one piece of data I can not figure out how to translate it to Python (3.7).
Following should work (based on the documentation):
query = intersys.pythonbind.query(database)
query.prepare_class("%SYSTEM.License","UserListAll")
query.execute();
# Fetch each row in the result set, and print the
# name and value of each column in a row:
while 1:
cols = query.fetch([None])
if len(cols) == 0: break
print str(cols[0])
Also, notice that InterSystems IRIS -- successor to the Caché now has Python as an embedded language. See more in the docs
Since the noted query "UserListAll" is not defined correctly in the library; not SqlProc. So to resolve this issue would require a ObjectScript with the query and the use of #Result set or similar in Python to get the results. So I am marking this as resolved.
Not sure which Python interface you're using for Cache/IRIS, but this Open Source 3rd party one is worth investigating for the kind of things you're trying to do:
https://github.com/chrisemunt/mg_python

Getting a selection in 3ds Max into a list in Python

I am writing in Python, sometimes calling certain aspects of maxscript and I have gotten most of the basics to work. However, I still don't understand FPValues. I don't even understand while looking through the examples and the max help site how to get anything meaningful out of them. For example:
import MaxPlus as MP
import pymxs
MPEval = MP.Core.EvalMAXScript
objectList = []
def addBtnCheck():
select = MPEval('''GetCurrentSelection()''')
objectList.append(select)
print(objectList)
MPEval('''
try (destroyDialog unnamedRollout) catch()
rollout unnamedRollout "Centered" width:262 height:350
(
button 'addBtn' "Add Selection to List" pos:[16,24] width:88 height:38
align:#left
on 'addBtn' pressed do
(
python.Execute "addBtnCheck()"
)
)
''')
MP.Core.EvalMAXScript('''createDialog unnamedRollout''')
(I hope I got the indentation right, pretty new at this)
In the above code I successfully spawned my rollout, and used a button press to call a python function and then I try to put the selection of a group of objects in a variable that I can control through python.
The objectList print gives me this:
[<MaxPlus.FPValue; proxy of <Swig Object of type 'Autodesk::Max::FPValue *' at 0x00000000846E5F00> >]
When used on a selection of two objects. While I would like the object names, their positions, etc!
If anybody can point me in the right direction, or explain FPValues and how to use them like I am an actual five year old, I would be eternally grateful!
Where to start, to me the main issue seems to be the way you're approaching it:
why use MaxPlus at all, that's an low-level SDK wrapper as unpythonic (and incomplete) as it gets
why call maxscript from python for things that can be done in python (getCurrentSelection)
why use maxscript to create UI, you're in python, use pySide
if you can do it in maxscript, why would you do it in python in the first place? Aside from faster math ops, most of the scene operations will be orders of magnitude slower in python. And if you want, you can import and use python modules in maxscript, too.
import MaxPlus as MP
import pymxs
mySel = mp.SelectionManager.Nodes
objectList = []
for each in mySel:
x = each.Name
objectList.append(x)
print objectList
The easiest way I know is with the
my_selection = rt.selection
command...
However, I've found it works a little better for me to throw it into a list() function as well so I can get it as a Python list instead of a MAXscript array. This isn't required but some things get weird when using the default return from rt.selection.
my_selection = list(rt.selection)
Once you have the objects in a list you can just access its attributes by looking up what its called for MAXscript.
for obj in my_selection:
print(obj.name)

Maya/Arnold scripting, rendering ambient occlusion to the map using arnold utilities

I using the following action to generate ambient occlusion maps for models in maya:
Create and assign aiAmbientOcclusion to my model (the one I want to generate oa maps for).
Then, I go Arnold>Utilities>Render Selection To Texture.
Since this process is always the same I want to write a python script to automate it unfortunately I haven't found many useful examples about writing scripts for Arnold.
To add this functionality I must:
import mtoa.renderToTexture
that script is located in
the_way_to_my_install_folder/solidangle/mtoa/2017/scripts/mtoa
I saw that the script defines the class MtoARenderToTexture and I should pass an object to it. Now.
What kind of object I mush use and is there some sort of documentation for MtoARenderToTexture class?
I was able to do what I wanted using ether this tutorial and extending MtoARenderToTexture class.
I do not iclude all my scripts that load scene and manage scenes files as they very specific to my needs, but still think it's a good idea to share some very basic and fundamental elements that may be useful for some new entries as myself.
This is how my extended class looks like
import mtoa.renderToTexture as renderToTexture
import maya.cmds as cmds
class rkMtoaRtoT(renderToTexture.MtoARenderToTexture):
def __init__(self):
renderToTexture.MtoARenderToTexture.__init__(self)
self.dFolder = '~'
self.dResolution = 1024
self.dCameraSamples = 5
def doAutomaticExport(self):
renderToTexture.MtoARenderToTexture.create(self)
cmds.textFieldButtonGrp('outputFolder', e=True, tx=self.dFolder)
cmds.intFieldGrp('resolution', e=True, v1=self.dResolution)
cmds.intFieldGrp('aa_samples', e=True, v1=self.dCameraSamples)
renderToTexture.MtoARenderToTexture.doExport(self)

How to get around using eval in python

I have a game I've been working on for awhile. The core is C++, but I'm using Python for scripting and for Attacks/StatusEffects/Items etc.
I've kind of coded myself into a corner where I'm having to use eval to get the behaviout I want. Here's how it's arising:
I have an xml document that I use to spec attacks, like so:
<Attack name="Megiddo Flare" mp="144" accuracy="1.5" targetting="EnemyParty">
<Flags>
<IgnoreElements/>
<Unreflectable/>
<ConstantDamage/>
<LockedTargetting/>
</Flags>
<Components>
<ElementalWeightComponent>
<Element name="Fire" weight="0.5"/>
</ElementalWeightComponent>
<ConstantDamageCalculatorComponent damage="9995" index="DamageCalculatorComponent"/>
</Components>
</Attack>
I parse this file in python, and build my Attacks. Each Attack consist of any number of Components to implement different behaviour. In this Attack's case, I implement a DamageCalculatorComponent, telling python to use the ConstantDamage variant. I implement all these components in my script files. This is all well and good for component types I'm going to use often. There are some attacks where that attack will be the only attack to use that particular Component Variant. Rather then adding the component to my script files, I wanted to be able to specify the Component class in the xml file.
For instance, If I were to implement the classic White Wind attack from Final Fantasy (restores team HP by the amount of HP of the attacker)
<Attack name="White Wind" mp="41" targetting="AnyParty">
<Flags>
<LockedTargetting/>
</Flags>
<Components>
<CustomComponent index="DamageCalculatorComponent">
<![CDATA[
class WhiteWindDamageComponent(DamageCalculatorComponent):
def __init__(self, Owner):
DamageCalculatorComponent.__init__(self, Owner)
def CalculateDamage(self, Action, Mechanics):
Dmg = 0
character = Action.GetUsers().GetFirst()
SM = character.GetComponent("StatManagerComponent")
if (SM != None):
Dmg = -SM.GetCurrentHP()
return Dmg
return WhiteWindDamageComponent(Owner)
]]>
</CustomComponent>
</Components>
</Attack>
I was wondering if there might be a better way to do this? The only other way I can see is too put every possible Component variant definition into my python files, and expand my Component creators to check for the additional variant. Seems abit wasteful for a single use Component. Is there a better/safer alternative to generating types dynamically, or perhaps another solution I'm not seeing?
Thanks in advance
Inline Python is bad because
Your source code files cannot be understood by Python source code editors and you will miss syntax highlighting
All other tools, like pylint, which can be used to lint and validate source code will fail also
Alternative
In element <CustomComponent index="DamageCalculatorComponent">
... add parameter script:
<CustomComponent index="DamageCalculatorComponent" script="damager.py">
Then add file damager.py somewhere along the file system.
Load it as described here: What is an alternative to execfile in Python 3?
In your main game engine code construct the class out of loaded system module like:
damager_class = sys.modules["mymodulename"].my_factory_function()
All Python modules must share some kind of agreed class names / entry point functions.
If you want to have really pluggable architecture, use Python eggs and setup.py entry points
http://wiki.pylonshq.com/display/pylonscookbook/Using+Entry+Points+to+Write+Plugins
Example
https://github.com/miohtama/vvv/blob/master/setup.py

Modules or functions to obtain information from a network interface in Python

I wrote a little application that I use from the terminal in Linux to keep track of the amount of data up and down that I consume in a session of Internet connection (I store the info in MongoDB). The data up and down I write by hand and read them (visually) from the monitor system, the fact is that I would like to automate more my application and make it read data consumed up and down from the interface network i use to connect to internet (in my case ppp0), but the detail is in that I does not find the way to do in Python. I guess Python have a module to import or something that lets me do what I want, but until now I have researched I have not found a way to do it.
Do you know of any module, function or similar that allows me to do in python what I want?
any example?
thanks in advance
Well I answer myself
Found in the community PyAr this recipe to me me like a glove going to do what we wanted without having to use extra commands or other applications.
Slightly modifying the code to better suit my application and add a function that comvierta of bytes to Megabytes leave it like this:
def bytestomb(b):
mb = float(b) / (1024*1024)
return mb
def bytessubidatransferidos():
interface= 'ppp0'
for line in open('/proc/net/dev', 'r'):
if interface in line:
data = line.split('%s:' % interface)[1].split()
tx_bytes = (data[8])
return bytestomb(tx_bytes)
def bytesbajadatransferidos():
interface= 'ppp0'
for line in open('/proc/net/dev', 'r'):
if interface in line:
data = line.split('%s:' % interface)[1].split()
rx_bytes = (data[0])
return bytestomb(rx_bytes)
print bytessubidatransferidos()
print bytesbajadatransferidos()

Categories

Resources