How can I save Python variables in a Maya scene?
For example I create a variable x in Maya's Script Editor and I save the scene. When I reopen Maya and reopen the saved scene, x variable doesn't exist anymore.
Is it possible?
Yes, use a script node, use a optionVar or store the variable in a attribute.
In general
Scene persistence is supposed to be built with nodes. In fact everything in Maya is supposed to be a node or built out of a node tree. The bonus is if you make your computation a node then maya will automatically handle all the stuff for you. This is how render engines for example store the data. They register a special node and read the data from the node.
Needing to ask this question, "How can I save Python variables in a Maya scene?", is a indication that you indeed should have built a nodal solution. There are a few exceptions to this and those are related to general user GUI preferences that should be saved as optionVars.
Maya does not actually enforce that you do things sanely. You are free to do whatever you want, sane or not. So it is possible, tough a bit fishy, to use a scene save scriptjob to store the snapshot of your environment to a script node that auto runs on load. This is undesirable in the same way as using global variables is undesirable for code in general. It is also slightly unreliable, as a user can disable auto running of on load scriptNodes, for good reason.
About nodal solutions
Maya as a rule does not work the way most people intuitively expect at first glance. Just like the text you write in code is not what your computer generally executes, but rather the compiled code is what gets executed. The compiler has a bit of leeway on what i can do in this context and usually throws away some stuff. So in code its not really sane to think in terms of what the text looks like in code but rather what structures it builds.
In Maya the structures you should be building are nodes. There are two extra use cases outside this and those are:
Exporters (Importers but due to their nature they are node bound because they target Maya)
Graphical user interfaces that introspect Mayas current state or bring external info to the user
These two could only specialize in reading nodes. Mayas object auxiliary function nature can quite efficiently hide the fact from the user but this is essentially want your doing. Anything outside this scope does not benefit form using Maya. So whenever you use maya you want to capitalize on nodes. Think of it as if you are using a second language on top of your own programming language. This one is the actual language of Maya.
Let us start with a naive approach for randomizing point positions for a mesh (note i avoid the term object as Maya has no such concept):
import maya.cmds as cmds
import random
def randomize_points(scale):
sel = cmds.polyListComponentConversion(ff=1, fe=1, fuv=1, fvf=1, tv=1)
sel = cmds.ls(sel ,fl=1)
for item in sel:
cmds.move((random.random()-0.5)*scale,
(random.random()-0.5)*scale,
(random.random()-0.5)*scale,
item, r=1)
It works, but has three deficiencies:
You can not know what it looks like until you run it.
You can undo tough so test and undo. Maybe youd need a seed variable for the random too?
You need to build a GUI for this so the user can work it.
There's is no way to specify the profile of the randomness.
(This one is here so it easy for you to run the code i could use one of many pythons noise implementations. I will fix this nonetheless.)
The code is straightforward in sense id does what a user would do in the GUI. But what really happens? Where do the changes go? Simply put the answer is 2 fold they go either to the tweak array (most likely), or the objects position array. But there is a better way i can use Maya primitives to manipulate a similar behavior. Enter nodes.
First you need to go a bit node shopping, what nodes could actually provide a noise functionality? The thing is there does not seem to be many contenders here. There is despite this one node that's basically roll your own deformation and that is the particle node. So this is how you'd attack the problem with a particle node, some noise and a few attributes:
... to be continued ...
Here is the simple example to saving a python variable inside maya file.
lets Save Variable X in Maya file and the value of X is 100.
and we dont want see this error:
# Error: NameError: name 'x' is not defined #
To Save Variable in Maya file Execute this code before you save your Maya file.
import maya.cmds as cmds
var_node = cmds.scriptNode(scriptType=1, name='CustomVariable', beforeScript='python("x = 100")')
cmds.scriptNode( var_node, executeBefore=True )
open file again and execute:
print x
Related
I am trying to write a python script so that I can add an element to a diagram in Sparx Enterprise Architect.
TestDiagEl=TestDiag.DiagramObjects.AddNew("l=10;r=110;t=-20;b=-80","")
TestDiagEl.ElementID=TestEl.ElementID
TestDiagEl.Update
TestDiag.Update
eaRep.ReloadDiagram(TestDiag.DiagramID)
It doesn't seem to work, what am I doing wrong?
EDIT
It seems that #geert was right, additionally i didnt add () after Update.
When writing code you should know what each line of code does, and why you are writing it.
In this case
TestDiagEl=TestDiag.DiagramObjects.AddNew("l=10;r=110;t=-20;b=-80","")
Creates a new diagramObject in memory
TestDiagEl.ElementID=TestEl.ElementID
Sets the elementID of the diagramObject to the elementID of my element
TestDiagEl.Update
Save the diagramObject to the database
TestDiag.Update
Save the current diagram in memory to the database
eaRep.ReloadDiagram(TestDiag.DiagramID)
Get the diagramDetails from the database and show them in the GUI
One problem is the TestDiag.Update. Since your diagram in memory doesn't know about the new DiagramObject yet, you are effectively undoing the addition of the new DiagramObject. Remove that line, and all should be OK.
Another problem is the parameter you pass to the DiagramObjects.AddNew method. The top and bottom values should be positive as you can see in the provided documentation So:
TestDiagEl=TestDiag.DiagramObjects.AddNew("l=10;r=110;t=20;b=80","")
I've got a kind of weird question--but would be immensely useful if it is possible--in Maya using Python, can I take in several points of user input and have Python create a separate script for me? In this instance, I want to take in controller and locator names and have Python spit out a complete IKFK match script also in Python (it's really just a lot of getAttr and setAttr commands, although with 6 if statements per limb for PV matching.) The only other wrinkle there is that it has to be able to prefix hierarchy names in the script if necessary if the rig is imported into a new scene rather than just opened. There's an expression component to my switches that it would be nice if Python could make for me, too.
Is this possible or am I crazy?
That's no problem. Just write a textfile with a .py extension into a path where maya can find it. Then you have to import it somewhere. Creating expressions is not a problem either.
Maybe it could make sense to think about the approach you choose. Imagine you have written a dozen of these new python files and you discover a problem in the script, you will have to redo it. I'd try to collect all data and only write the required informations into a textfile e.g. in json format. Then you can read the data and rebuild your skeletons.
I have many abaqus plugins that perform actions in Abaqus CAE through a scripting interface. For many actions after they are executed Abaqus performs some display refresh procedures that take some time. If the models are small and the script does not do too much it is alright. However, e.g. one of my scripts takes a part and replicates it in the assembly at the coordinates specified by user's CSV file. Sometimes there might be up to 2000 such replications. In this case it takes forever to complete the procedure and most of the time you only see "Setting display..."
Furthermore this "Setting display..." overwrites your scripts' progress (milestone) so it is difficult to see how far the script had advanced.
Is there any way to suspend this display updating behavior until the script finishes? Maybe there is a hack that you could redefine abaqus update function until the script is done or something because according to the manual the only thing you can do is to prevent the updating of the color scheme, but that does not help at all.
Any tips will be appreciated, thanks!
EDIT: To clarify I used folowing methods on a viewport object with no vain:
disableRefresh()
disableColorCodeUpdates()
What does the disableColorCodeUpdates() do is quite clear and the benefit is apparent when color coding is used in the model viewport. However, I see no difference between using and not using disableRefresh().
EDIT: Sorry for such a long wait, only now I had a chance to get back at abaqus. Here is a simple example script that takes a part and places it in assembly:
import random
modelName='Model-1'
partName='Part-1'
noInst=1000
i = 0
lists = []
for i in range(noInst):
lists.append([random.random()*10,random.random()*10,random.random()*10])
totalParts = len(lists)
session.Viewport(name='Viewport: 2', origin=(6.63750028610229,
20.7638893127441), width=335.746887207031, height=149.77685546875)
session.viewports['Viewport: 2'].makeCurrent()
session.viewports['Viewport: 2'].maximize()
session.viewports['Viewport: 1'].restore()
for n,l in enumerate(lists):
milestone('Replicating parts', 'parts', n+1, totalParts)
a = mdb.models[modelName].rootAssembly
p = mdb.models[modelName].parts[partName]
a.Instance(name='Random_'+'-'+str(n), part=p, dependent=ON)
a = mdb.models[modelName].rootAssembly
a.translate(instanceList=('Random_'+'-'+str(n), ), vector=(float(l[0]), float(l[1]), float(l[2])))
If I try to create viewport object without specifying displayed object. Viewport defaults to current displayed object in initial Viewport. I noticed if I change a module from amssembly to any other e.g. Part, I gain speed improvement, but it relies that the part is sufficiently empty. If I have model with parts that are large and complex it is still rather slow on "setting display.." also my milestone is overwritten by "setting display.." by any case.
I think I've seen this before in a similar situation, where I was creating elements one-by-one in a GUI CAE session. I could not figure out how to disable the screen refresh, and it was maddeningly slow. There were two workarounds:
1. Use an alternative command, if one exists, that creates many items at once. In my example above, instead of creating each new element one at a time using the Element method, I was able to generate an entire Part and the mesh at once with makePartFromNodesAndElements which was significantly faster. In your case, it might be possible to do something similar.
2. If you do not need an active GUI, run the script from the system shell: abaqus cae noGui=script.py. You can even pass arguments to the script from the command line interface.
Another (untested) possibility I just thought of is that you may be able to create and switch to a new viewport without specifying the displayed object. Then try your code and see if that speeds things up.
I want to create a polyhedron by giving its coordinates, and then get a specific section. Maybe something like:
Points = [A(0,0,0),B(1,0,0),C(1,1,0),D(0,1,0),A"(0,0,1),B"(1,0,1),C"(1,1,1),D"(0,1,1)]
Body = BodyGenerate(Points)
section1 = Body.section(z = 0.5)
section2 = Body.section(x+y= 1)
#And then I can get properties like `area`, `width` of these sections.
How can I do that? Is there any lib for that?
Here is what I find so far:
Vpython is pretty what I need, but it seems too basic, and cannot create a polyhedron
Blender and Rhino are good tools. But they focus more on modelling rather than programming. Python is more like a interactive commandline rather than a program itself.
Three.js seems what I need, but js cannot perform scientific computation.
As a blender user my opinion is biased that way. Yes it focuses on being a gui tool for end users, but it deeply integrates python for defining the user interface all the way to adding features through python addons. It also includes a python console that lets you type in commands that alter data directly, allowing you to see changes in the 3dview. It is also possible to add extra python modules that can then be used within blender.
Blender's python api can be read and searched online.
You should find some examples to help create a polyhedron in the extra objects addon. It is included with blender so you can also find the scripts in your blender install.
Maybe look into how the intersect tool works, you can call the intersect operator yourself, there is also a boolean modifier that may be better to get a closed mesh to calculate the volume.
For calculating the volume there is BMesh.calc_volume, it is used by the 3d printing toolbox.
You might want to add blender.stackexchange.com to your list to get blender specific python help.
Is there a emacs plugin which lists all the methods in the module in a side pane.
I am looking for a plugin which has keyboard shortcuts to show/hide all the methods in python module file currently opened.
I suggest using elpy.
C-c C-o runs elpy-occur-definitions which creates a new buffer with a list of all the class and function signatures.
You can navigate the list using C-n and C-p.
The mode works with next-error-follow minor mode.
So C-c C-f inside the buffer enables jumping to the class or function definition selected.
Here's an example of the contents of that buffer:
8 matches for "^ *\(def\|class\) " in buffer: leveling_utils.py
11:def leveling(episodes_with_potential_associations_by_member):
26:def _apply_leveling(sorted_episodes):
41:def _set_non_chronic_associations(episode):
73:def _apply_sub_to_procedural_association(assoc):
94:def _set_chronic_associations(episode):
102:def _set_associations_for_self(episode):
118:def _set_to_actual(association):
122:def _log_actual_associations(member, leveled_episodes):
By the way, it has many other useful features that to me, make it a necessary addition to python-mode.
For the first question, use M-xspeed-bar, like Alex suggested.
For the second, enable hs-minor-mode, M-xhs-minor-mode, and use C-cC-#C-S-h to hide all methods, and C-cC-#C-S-s to show.
You can look to ECB (it's better to take my fork of it, as it's adapted to fresh Emacs & CEDET) - it can display information about source code fetching it from Semantic (CEDET subpackage) or via imenu (for languages that aren't supported by Semantic).
Speedbar (included into GNU Emacs) can also show a list of top level objects, but doesn't show differences between imports, functions of other top-level stuff
For me, the easiest and most convenient method to quickly lookup methods is the command helm-occur (C-x c M-s o). You start typing the name of the method you want to jump to and suggestions start popping in as you type. Then you hit enter to select the one you want and your cursor jumps right there in the code. Helm-occur wasn't strictly written for this purpose, but works quite well that way.
Speedbar is good, and another nice alternative is helm-imenu. I've bind several keys to access it quicky from different contexts and use it most of the time