Getting Started with Python Scripting

This page walks you through writing and running your first SpinFire Python script. For what the package covers, see Overview.

Note

About this page: This page is based on the package source, SpinFire Insight’s user documentation, and a probe script run in SpinFire. It is not an official Tech Soft 3D quickstart. Where behavior is inferred rather than documented, it says so.

Run Your First Script

Scripts run inside SpinFire’s built-in script editor, not from a standalone Python install. The embedded interpreter is Python 3.9 (3.9.2 at the time these pages were checked).

  1. Open a model in SpinFire. Most API calls act on the open workspace, so the scripts on this page need a 3D model loaded. The samples use Filter.CATPart, which is installed with SpinFire Insight in the Samples\CATIA V5\Aquo Bottle folder. See Script Samples for details.

  2. Click the Scripting icon on the 3D toolbar and choose New Script….

  3. Open View > Python.NET Console. This is where print() output and error messages appear.

  4. Paste the script below into the editor and click Run.

1import spinfirescript as sfs
2
3print(sfs.SelectItem([0]))        # [0] is the model; prints its name
4props = sfs.GetPhysicalProperties()  # properties of the current selection
5print(props.Message)

If the model’s name and physical properties appear in the console, your setup works. The script editor toolbar also lets you save and reopen scripts, stop a running script, and open the built-in scripting reference (Documentation).

The One Import You Need

1import spinfirescript as sfs

spinfirescript is a top-level module that sits alongside the spinfireapi package (see Files). It re-exports every function and enum from the six spinfireapi modules. So sfs.SelectSurface, sfs.ZoomFit, sfs.RenderMode and the rest are all available from that one import, and you never need import spinfireapi or its submodules.

A few types come from SpinFire’s .NET layer rather than the Python package. StandardView is one of them, but graphics.py imports it, so sfs.StandardView.Front works as well as importing it directly. The coordinate-system parameter classes (CSPositionParams, CSOrientationParams, CSRotationParams) and AxisType are not in sfs, so import them directly when you need them:

1import SpinFire.Scripting.API.Geometry as sfgeom

Typical Script Shape

Most interactive scripts follow the same pattern: ask the user to pick something, stop cleanly if they cancel, then do the work.

1import spinfirescript as sfs
2
3surface = sfs.SelectSurface('Select a surface.')
4
5if surface is None:
6    print('No surface was selected.')
7else:
8    print(f'Selected surface has {len(surface.Points)} points.')

SelectPoint, SelectEdge and SelectSurface all return None when the user cancels, so use this check with any of them.

Check return values. Most functions report problems in their return value rather than by raising an exception. For example, SelectItem with a path that doesn’t exist returns Failed to get child item with index ‘999’ at level ‘1’., and the section-plane move, rotate and reset functions return an empty string on success. Functions that return objects, such as InsertLine (a LineData), usually carry a Message field as well. Printing the return value, as the module pages do, is the easiest way to see why a call didn’t do what you expected:

1print(sfs.MoveSectionPlane(sfs.Plane.YZ, 10, 0, 0))

The Classes page lists the return types and fields seen so far. Coordinates and distances are in the model’s units (mm for the Filter.CATPart model used in the samples).

Using Third-Party Packages (e.g. NumPy)

SpinFire uses its own embedded Python 3.9 environment, so packages installed in your system Python aren’t available to scripts. Any package you add has to support Python 3.9. The sample script installs NumPy on first run if it’s missing. Below is a corrected version of that snippet. The shipped sample omits import os.

 1try:
 2    import numpy as np
 3except ModuleNotFoundError:
 4    import os
 5    import sys
 6    import pip
 7
 8    currentPath = os.getcwd()
 9    newPath = os.path.join(os.path.dirname(sys.executable), "CPython")
10
11    try:
12        os.chdir(newPath)  # appears to target SpinFire's embedded CPython folder
13        print(pip.main(['install', 'numpy']))
14        import numpy as np
15    finally:
16        os.chdir(currentPath)

Keep these limitations in mind:

  • Network and permissions. The install needs internet access and write access to the SpinFire installation folder. It can fail on locked-down machines. If it does, ask your IT team to install the package once for everyone.

  • Unsupported pip API. pip.main() is an internal pip API and may break with future pip versions.

  • First run only. The install happens the first time the script runs. Later runs import the package normally.

How It Works Under the Hood

You don’t need this to write scripts, but it explains why they only run inside SpinFire.

Before each script starts, SpinFire sets two variables in spinfirecontext:

  • ScriptManager is the active session. Almost every API call passes it through.

  • DefaultScriptManager is used for opening and closing files.

When you import spinfirescript, it also uses pythonnet’s clr module to load the SpinFire.LinearAlgebra and SpinFire.Scripting.API .NET assemblies. Outside SpinFire, those assemblies can’t be found and ScriptManager stays None, so running a script from a normal Python prompt fails.

See also