Using the Particle Module in Python
The cee_envision.pt module exposes the Particle Component to Python via SWIG bindings.
The API mirrors the C++ cee::pt namespace exactly — all classes, methods and constants are
available under the same names.
Opening a Model
from cee_envision import pt
model = pt.ParticleModel()
err = pt.Error()
if not model.openFile("data/particles.ptfx", err):
print("Error:", err.errorCode())
openFile() is a Python-only convenience wrapper that calls the C++ open(filePath) overload.
To use a pre-constructed reader instead, call openWithReader(reader, err). Python ownership of
the reader is transferred to C++ and the reader must not be used afterwards.
Adding the Model to a View and Rendering
from cee_envision import vis, osmesa, core
context_group = osmesa.OSMesaComponent.createOpenGLContextGroupForOSMesa()
viewer = osmesa.ViewerOSMesa(context_group)
view = vis.View()
viewer.setView(view)
viewer.resize(1024, 768)
view.addModel(model)
model.updateVisualization()
box = view.boundingBox()
if box.isValid():
view.camera().fitView(box, core.Vec3d(0, 0, 1), core.Vec3d(0, 1, 0))
See Particle Model for the full C++ model API.
Scalar Mapping
fields = model.scalarFieldNames() # returns a list of strings
if fields:
model.setActiveScalarField(fields[0])
mapper = vis.ScalarMapperContinuous()
scalar_range = model.scalarRangeAsTuple() # Python-only: returns (min, max) or None
if scalar_range:
mapper.setRange(scalar_range[0], scalar_range[1])
mapper.setColors(vis.ColorTableFactory.BLUE_RED)
model.setScalarMapper(mapper)
scalarRangeAsTuple() is a Python-only helper. The underlying C++ method scalarRange() takes
output pointer arguments and is not directly callable from Python.
Note
ParticleModel automatically adds a color legend overlay to the view when a scalar mapper is
set. There is no need to add one manually via view.overlay().
Frame Animation
frame_count = model.frameCount()
# Pre-load frames into the cache for smooth playback
model.preloadFrames(0, frame_count)
for i in range(frame_count):
model.setCurrentFrameIndex(i)
model.updateVisualization()
# render frame ...
See Frame Iteration and Scalars and Frame Cache for details.
Low-level Data Access
Use a reader directly to inspect raw frame data without rendering:
reader = pt.createReader("data/particles.ptfx") # auto-detects format
err = pt.Error()
if not reader.open("data/particles.ptfx", err):
print("Error:", err.errorCode())
header = reader.header()
print("Frames:", header.frameCount)
print("Fields:", list(header.scalarFieldNames))
frame = reader.getFrameDataAsPtr(0) # Python-only: returns FrameData* (or None)
if frame:
print("Particles:", frame.particleCount)
print("Positions:", frame.positions[:6]) # first two XYZ triples
getFrameDataAsPtr() is a Python-only wrapper around the C++ getFrameData() which returns a
unique_ptr that cannot be expressed directly in Python. The returned object is owned by Python
and will be freed when it goes out of scope.
See Particle Dataset Readers for the full reader API.
Writing PTFX Files
writer = pt.PtfxDatasetWriter()
err = pt.Error()
scalar_infos = [pt.PtfxScalarFieldInfo()]
scalar_infos[0].name = "Temperature"
scalar_infos[0].minValue = 273.0
scalar_infos[0].maxValue = 1500.0
writer.open("output.ptfx", max_particles, frame_count,
bbox_min, bbox_max, scalar_infos, err)
for frame_idx in range(frame_count):
writer.writeFrame(ids, positions, scalars, err)
writer.close(err)
See Writing PTFX Files for the full writer API.
Example Scripts
Four ready-to-run scripts are provided in Examples/ParticleExamples/:
render_particles.py— renders a single mid-animation frame to a PNG.animate_particles.py— renders all frames to PNGs and optionally assembles an MP4 (requirespip install opencv-python).particles_with_decimation.py— renders the same frame at 10 %, 50 % and 100 % density.read_and_write_particles.py— reads frame data and writes a subset to a new.ptfxfile.
All scripts default to the demo datasets in Examples/DemoFiles/particles/ but accept a custom
file path as a command-line argument:
python render_particles.py path/to/my/particles.vtp