
PyAxisVM - The official Python package for AxisVM¶

Note
The documentation is under heavy development. Expect changes more often than usual, and enjoy what is alraeady out. This only affects the documentation, not the code base. Until we het to the end of it, browse the examples and the notebooks to get a glimpse of what the library can provide!
The PyAxisVM project offers a high-level interface to AxisVM, making its operations available directly from Python. It builds on top of Microsoft’s COM technology and supports all the features of the original AxisVM COM type library, making you able to
build, manipulate and analyse AxisVM models
find better solutions with iterative methods
combine the power of AxisVM with third-party Python libraries
build extension modules
On top of that, PyAxisVM enhances the type library with Python’s slicing mechanism, context management and more, that enables writing clean, concise, and readable code.
Getting Started¶
Installation and testing¶
Register AxisVM’s Type Library¶
If this is not your first time using AxisVM through a COM interface on your machine, you should already have a registered type library and you can skip this step. Otherwise, you have to register the type library of your AxisVM application. Different versions come with different type libraries, so you might redo this step when you update to a new version. At all times, older versions must be unregistered from the Windows registry before new registrations!
To have your AxisVM registered, locate the folder on your filesystem AxisVM is installed into. In that folder you should see a file called !REGISTER_AXISVM_X64 and !REGISTER_AXISVM. Double click on the first for a 64-bit, or the second one for a 32-bit installation. It is important to register only the version that is required and matches with the version of installed AxisVM.
To unregister a type library, the step is similar, but now you use the files !UNREGISTER_AXISVM_X64 and !UNREGISTER_AXISVM.
Install PyAxisVM¶
This is optional, but we suggest you to create a dedicated virtual enviroment at all times to avoid conflicts with your other projects. Create a folder, open a command shell in that folder and use the following command
>>> python -m venv venv_name
Once the enviroment is created, activate it via typing
>>> .\venv_name\Scripts\activate
The AxisVM python package can be installed (either in a virtual enviroment or globally) from PyPI using pip
on Python >= 3.6:
>>> pip install axisvm
Launch AxisVM from Python¶
The axisvm.com.client
submodule implements various tools to handle the client side operations of creating a COM connection. Import the module and start a new application instance with the start_AxisVM
method:
from axisvm.com.client import start_AxisVM
axapp = start_AxisVM(visible=True)
To test the connection, you can query the path of the executable being run by typing axapp.FullExePath
.
How to use the API¶
pyaxisvm
has two layers. The first one is the raw type library extracted from AxisVM using the comptypes
package. We are working on an online version of it, until that the documentation of this layer is only available in pdf format, that you should already posess at the moment of reading this notebook. If you don’t have it yet, go to our website, and look for it under downloads. Be careful to download the documentation that matches the version of your AxisVM instance.
Basic API usage¶
Firts of all, we need a runnning AxisVM either in the background, or with the graphical interface.
from axisvm.com.client import start_AxisVM
axvm = start_AxisVM(visible=True, daemon=True)
As a consequence of the hierarchical structure of the models in AxisVM, every model creation proccess starts with nodes. To create nodes we need an interface to the nodes of the application. This is achieved by the IAxisVMNodes
class of the type library. If you look it up in the pdf document, you will see this:
Just like other interfaces, the documentation of IAxisVMNodes
begins with listing the enumerations and records specific to nodes. Below these, you can see the functions of the interface.
After all the functions, the documentation of the interface is finished by listing the properties of the interface.
from axisvm.com.client import start_AxisVM
axvm = start_AxisVM(visible=True, daemon=True)
modelId = axvm.Models.New()
model = axvm.Models[modelId]
Right below the Add
function, there is the AddWithDOF
, with the following documentation:
It tells, that the function needs to be called with specifying three scalar values and a fourth one specifying a DOF component. The enumeration EDegreeOfFreedom
was listed at the beginning of the documentation of the interface.
from axisvm.com.tlb import dofFree
id1 = model.Nodes.AddWithDOF(-1, -1, 0, dofFree)
id2 = model.Nodes.AddWithDOF(1, -1, 0, dofFree)
id3 = model.Nodes.AddWithDOF(1, 1, 0, dofFree)
id4 = model.Nodes.AddWithDOF(-1, 1, 0, dofFree)
After the session has ended, close the application by
axvm.Quit()
Tips and Tricks¶
This page sums up the changes in syntax, compared to the ‘raw’ usage of the COM type library. Everything the API provides out of the box is still available and is working as ever, but the syntax of Python provides a few shortcuts to make coding easier.
Collections and Slicing¶
When accessing items of collection-like COM classes (like IAxisVMDomains
, IAxisVMSurfaces
, anything having an Item
method), you can use the slicing mechanism of Python. Suppose that we have an IAxisVMModel
instance called axm
. The model has several domains, each of them having the property Weight
. Let say we want to calculate the weight of all domains. The out of box solution for this would be something like
weights=[]
for i in range(axm.Surfaces.Count):
weights.append(axm.Surfaces.Item[i+1].Weight)
weight = sum(weights)
or using a list comprehension
weight = sum([axm.Surfaces.Item[i+1].Weight for i in range(axm.Surfaces.Count)])
or maybe even this
surfaces = [axm.Surfaces.Item[i+1] for i in range(axm.Surfaces.Count)]
weight = sum(map(lambda s : s.Weight, surfaces))
Anyhow, although there is nothing inherently wrong with these approaches, they clearly doesn’t measure up to
# if you are new to this, the colon means 'all indices in range'
weight = sum(axm.Surfaces[:].Weight)
or
weight = sum(s.Weight for s in axm.Surfaces)
or maybe
weight = sum(map(lambda s : s.Weight, axm.Surfaces))
Notice how the loops here are carried out over the collection object itself. This is because collection types implement the so-called iterator protocol.
It is also possible to provide negative indices:
axm.Surfaces[-1].Weight # equivalent to axm.Surfaces[axm.Surfaces.Count].Weight
axm.Surfaces[-2].Weight # equivalent to axm.Surfaces[axm.Surfaces.Count - 1].Weight
Without further due, some other use cases that exploit Python’s slicing mechanism:
axm.Surfaces[1, 5, 7].Weight
axm.Surfaces[1:4].Weight # equivalent to axm.Surfaces[1, 2, 3].Weight
axm.Surfaces[1:8:2].Weight # equivalent to axm.Surfaces[1, 3, 5, 7].Weight
axm.Surfaces[8:1:-2].Weight # equivalent to axm.Surfaces[8, 6, 4, 2].Weight
Furthermore, instead of typing axm.Surfaces.Count
, you can use len(axm.Surfaces)
to get the number of surfaces in the model.
Be aware here, that the index of the first item in any iterable COM object is 1, opposed to the zero-indexed nature of Python.
Context Management¶
If you have some experience with AxisVM and COM, you know about the methods BeginUpdate
and EndUpdate
. With python, you don’t need to care about this, instead you can simply use the with
statement like this
with axm as model:
# do some modification here on the model
...
Accessing the Type Library¶
When a new instace of IAxisVMApplication
is created, the type library is generated on demand. After that, the type library can be accessed as
import axisvm.com.tlb as axtlb
daemon=True
¶
When creating a new interface, you can do it like
from axisvm.com.client import start_AxisVM
axvm = start_AxisVM(visible=True, daemon=True)
The keyword argument daemon=True
is a simple shortcut, equivalent to
from axisvm.com.client import start_AxisVM
import axisvm.com.tlb as axtlb
axapp = start_AxisVM(visible=True, daemon=False)
axapp.CloseOnLastReleased = True
axapp.AskCloseOnLastReleased = False
axapp.AskSaveOnLastReleased = False
axapp.ApplicationClose = axtlb.acEnableNoWarning
As a result of these settings, if the COM server is shut down, AxisVM shuts down either, hence the term daemon
. Shutting down the COM server can be done with typing
axapp.Quit()