PreonPy API 6.1¶
Examples¶
The following example shows how to create a new scene. Here we create some objects, set keyframes and save the scene.
import preonpy
s = preonpy.Scene()
s.create_object("Preon Solver")
source = s.create_object("Area source")
box = s.create_object("Box")
position_keyframes = [(0, 0, "Linear"), (1, -1, "Linear"), (2, 0, "Linear"), (3, 2.5, "Linear")]
source.set_keyframes("position x", position_keyframes)
box.set_keyframes("position x", position_keyframes)
s.save("~/moving_box.prscene")
We can also manipulate existing scenes. The next example opens the previous scene again, changes some properties, like the particle size and runs a simulation.
s = preonpy.Scene("~/moving_box.prscene")
solver = s.find_object("PreonSolver_1")
solver["particle size"] = 0.1
s.simulate(0, 30)
s.save()
The scene class¶
-
class
Scene
(scene_path=None, load_only_object_creations=False, close_existing=None, *, do_not_load_resources=False)¶ Bases:
preonpy.objects.Object
Opening new or existing scenes is done by creating Scene objects. Operations on an invalid scene or its objects result in an exception of type
preonpy.exceptions.ObjectInvalid
. Whether a scene (or object) is valid or not can be determined by theis_valid()
method.Note: This function is not available from the PreonLab Console (read more).
- Parameters
scene_path (
Union
[str
,PathLike
,None
]) – If passed, an existing scene is loaded from the specified path. If omitted, a new scene is created.load_only_object_creations (
bool
) –If load_only_object_creations is passed in addition to scene_path, only the basic structure of the scene will be loaded without any properties, keyframes or connections. Additionally, the statistics, properties and keyframes of the scene are loaded but not for other objects.
Deprecated since version 6.1: This option is deprecated and will be removed in PreonLab 7.0.
close_existing (
Optional
[bool
]) – If close_existing is set toTrue
, all currently existing scenes are closed. If it is set toFalse
, other scenes will be kept open. The default behavior depends onpreonpy.multiple_scenes
.do_not_load_resources (
bool
) – If do_not_load_resources is passed in addition to scene_path, objects in the scene will not load data-heavy resources, e.g., geometries, air flows, pathlines etc.
- Raises
SceneLoadFailed – If the scene could not be loaded.
Deprecated since version 6.1: From version 7.0 on, all arguments except scene_path have to be passed as keyword argument.
Usage example:
>>> scene = preonpy.Scene() >>> other_box = preonpy.Scene("/share/example.prscene", close_existing=False).find_object("SpecialBox_1") >>> box = scene.create_object("Box", other_box.name) >>> box["p"] = other_box.get_property("position") >>> scene.save("/share/example_2.prscene")
-
close
()¶ Closes this scene.
Note: This function is not available from the PreonLab Console (read more).
-
collider
()¶ Retrieves the collider from scene.
- Return type
- Returns
The collider object of scene.
-
create_object
(typename, name=None)¶ Creates a new object of the given type.
- Parameters
typename (
str
) – The type is specified as a string. You can find the list of supported type names by opening PreonLab and inspecting the Add menu. The type names in preonpy always match the names found in this menu (for instance “Preon Solver” or “Cuboid”).name (
Optional
[str
]) – The object name is an optional parameter. If no name is given, a name is generated.
- Return type
Union
[Object
,Scene
,FloatFieldObject
,SensorObject
,Rigid
,CarSuspensionModel
,VehicleSimulationModel
,Camera
,PreonRenderer
,PointCloudResource
,StatisticResource
,SolverObject
,LiquidSolver
,VectorFieldObject
,Group
,SensorPlane
,Pathlines
]- Returns
The created object.
- Raises
ObjectCreateError – If object could not be created.
-
crop_left
(crop_time)¶ Removes all previously generated data before the specified point in time. This includes data that is currently loaded into memory as well as files that store frame specific information. Note, that files containing data, valid for the entire simulation range (e.g. statistic files) are not touched. They can only be deleted as a whole using
reset_simulationdata()
.
-
crop_right
(crop_time)¶ Removes all previously generated data after the specified point in time. See
crop_left()
for more information.
-
delete_object
(object)¶ Deletes the given object.
- Parameters
object (
Object
) – Object to be deleted.- Raises
ObjectInvalid – If the given object or the scene is invalid.
ObjectDeleteError – If the object could not be deleted (e.g. because it is a static object).
-
property
elapsed_time
¶ Returns the current elapsed time of the simulation.
- Return type
float
-
find_object
(name)¶ Retrieves an object with the given name or
None
if the object could not be found.- Parameters
name (
str
) – The object name.- Return type
Union
[Object
,Scene
,FloatFieldObject
,SensorObject
,Rigid
,CarSuspensionModel
,VehicleSimulationModel
,Camera
,PreonRenderer
,PointCloudResource
,StatisticResource
,SolverObject
,LiquidSolver
,VectorFieldObject
,Group
,SensorPlane
,Pathlines
,None
]- Returns
The object or
None
if no object with the given name could be found.
-
get_files
(categories=None)¶ Returns all files from this scene. This includes the files located inside and outside the scene directory. Relative paths are relative to the scene directory. Note, that only existing files are returned.
- Parameters
categories (
Union
[None
,str
,List
[str
]]) – If passed, only files matching the given categories are returned. Can be either one category or a list of categories. Valid values are documented here:DataCategory
. If omitted, all existing files are returned.- Return type
List
[str
]- Returns
A list with all existing files matching the given categories.
Usage example:
>>> print("Input files") >>> for f in scene.get_files(DataCategory.RESOURCE): >>> print(f) >>> print("Output files") >>> for f in scene.get_files([DataCategory.SIMULATION_DATA, DataCategory.RESULTS, DataCategory.STATISTICS]): >>> print(f)
-
get_resource_files
()¶ Returns the files needed to start a simulation. This includes the files located inside and outside of the scene directory. Relative paths are relative to the scene directory. Note, that only existing files are returned.
- Return type
List
[str
]- Returns
A list with all resource files.
-
import_mesh
(path, separate_resource, single_mesh, units='mm', *, convert_to_prmesh=False, path_for_generated_prmesh='', compress_prmesh=False, linear_deflection=Quantity(0.15, mm), angular_deflection=Quantity(0.5, rad))¶ Import mesh. Not both of separate_resource and single_mesh can be False. For STEP files, you can provide two parameters to guide the tessellation linear_deflection and angular_deflection.
Note: The parameters angular_deflection, linear_deflection, compress_prmesh, path_for_generated_prmesh and convert_to_prmesh can only be passed as keyword arguments.
Usage example:
>>> resource_obj, mesh_obj = scene.import_mesh("car.stp", True, True, linear_deflection=0.3)
- Parameters
path (
Union
[str
,PathLike
]) – Path of the fileseparate_resource (
bool
) – IfTrue
, a separate resource object is created.single_mesh (
bool
) – IfTrue
, only one rigid object is created, even if the mesh file contains submeshes.units (
str
) – One of “mm”, “cm”, “m” or “km”. The unit will be set in the resource object if separate_resource isTrue
or else as scale factor in the mesh object.convert_to_prmesh (
bool
) – IfTrue
, the imported mesh will be converted to a ‘prmesh’. This option will be applied to supported mesh formats excluding ‘prmesh’. You are required to provide a path_for_generated_prmesh, where to place the generated file.path_for_generated_prmesh (
str
) – The absolute path where the generated ‘prmesh’ file will be placed. The user needs to have write-access to the provided folder. This option is only required in conjunction with convert_to_prmesh=True.compress_prmesh (
bool
) – IfTrue
, the converted ‘prmesh’ file will be compressed. This will decrease the file size, but will increase subsequent file imports due to decompression.linear_deflection (
Union
[float
,Quantity
]) – The linear deflection parameter is used for importing STEP files. It specifies the distance between a curve and its tessellation. The parameter is known as Chordal distance. The provided value should be in “mm” or in a compatible lengthQuantity
.angular_deflection (
Union
[float
,Quantity
]) – The angular deflection is used for importing STEP files. It specifies the angle between subsequent segments in a polyline. The provided value should be in “rad” or in a compatible angleQuantity
.
- Returns
A list of all created objects. If separate_resource is
True
, the resource object will be the first object in the list.- Raises
InvalidFileFormat – If the mesh import has failed.
-
is_portable
()¶ Returns if the scene is self-contained, i.e., all resource files reside withing the scene directory and copying this directory is sufficient to start a simulation. A portable scene can be copied to another machine and will still work.
- Return type
bool
- Returns
True
if there are no resource files specified outside the scene directory.
-
is_valid
()¶ Returns
True
if the object is valid.- Return type
bool
-
load_frame
(frame)¶ Loads the given simulation frame.
- Return type
None
-
load_initial_resources
()¶ Loads initial resources of an object (e.g., geometries, pathlines, air flow data). This allows to load this data if this scene was opened before without loading the resources.
-
property
object_names
¶ A list of all object names in the scene.
- Return type
List
[str
]
-
property
path
¶ Path of the scene file.
- Return type
str
-
post_process
(start=None, stop=None, whitelist=None)¶ Runs post-processing on an existing simulation from the given start to the given end. If no start and/or stop are given, the postprocess will run in the range defined in the scene.
- Parameters
start (
Union
[int
,str
,Frame
,Second
,Quantity
,None
]) – Postprocess start. Can be either an integer representing the frame number, a time string, aFrame
, aSecond
, aQuantity
representing time orNone
. If it isNone
, the scene property “playback/postprocess start” will be used.stop (
Union
[int
,str
,Frame
,Second
,Quantity
,None
]) – Postprocess end. Can be either an integer representing the frame number, a time string, aFrame
, aSecond
, aQuantity
representing time orNone
. If it is None, the scene property “playback/postprocess end” will be used.whitelist (
Union
[Object
,List
[Object
],None
]) – Allows to define a whitelist of objects that should be postprocessed while other objects are skipped. If empty orNone
, all objects will be postprocessed.
Usage example:
>>> scene.post_process(0, 100) # using view frame rate >>> scene.post_process("0s", "200ms") >>> scene.post_process(preonpy.Frame(0, view=False), preonpy.Frame(100, view=False)) # using simulation frame rate >>> scene.post_process(preonpy.Second(0), preonpy.Second(1.5)) # using seconds >>> scene.post_process("0s", "1s", [scene.find_object("WettingSensor_1")])
-
reset_simulationdata
()¶ Removes all previously generated simulation data and sets the current time to zero. This includes data in memory as well as data files written to disk.
Note: This function is not available from the PreonLab Console (read more).
-
save
(scene_path=None, as_portable=False, compression=None, subsample=1, force_overwrite=False)¶ Saves the scene.
Note: This function is not available from the PreonLab Console (read more).
- Parameters
scene_path (
Union
[str
,PathLike
,None
]) – If scene_path is given, the scene will be saved to the given location. Otherwise, the loaded scene file will be overwritten.as_portable (
bool
) – If as_portable isTrue
, dependent resources will be copied into the scene directory if necessary, so that it is simple to transfer the scene and all resources to another place.compression (
Optional
[float
]) – Compression of fluid data can be enabled by setting compression to a non-zero allowed compression error which is a percentage of the used fluid particle size.subsample (
int
) – Setting subsample to an integer value greater than 1 reduces the number of written frames. For instance, pass 2 in order to halve the frame rate, discarding every second frame.force_overwrite (
bool
) – Overwrites possibly existing scenes at the scene_path location. This parameter is ignored ifscene_path=None
.
- Raises
ValueError – If the scene_path was not valid.
SceneSaveFailed – If the scene could not be saved.
-
simulate
(start=None, stop=None)¶ Runs the simulation from the given start to the given end. If no start and/or stop is given, the simulation will use the “simulation start” and “simulation end” scene properties.
- Parameters
start (
Union
[int
,str
,Frame
,Second
,Quantity
,None
]) – Simulation start. Can be either an integer representing the frame number, a time string, aFrame
, aSecond
, aQuantity
representing time orNone
. If it isNone
, the scene property “simulation start” will be used.stop (
Union
[int
,str
,Frame
,Second
,Quantity
,None
]) – Simulation end. Can be either an integer representing the frame number, a time string, aFrame
, aSecond
, aQuantity
representing time orNone
. If it isNone
, the scene property “simulation end” will be used.
Usage example:
>>> scene.simulate(0, 100) # using simulation frame rate >>> scene.simulate("0s", "200ms") >>> scene.simulate(preonpy.Frame(0, view=True), preonpy.Frame(100, view=True)) # using view frame rate >>> scene.simulate(preonpy.Second(0), preonpy.Second(1.5)) # using seconds
-
simulate_step
()¶ Used to run single simulation steps, which may be less than a frame. This method returns a context manager in the first place. The context then is a function that can be used to advance the simulation by one step.
Usage example:
>>> with current_scene.simulate_step() as step: >>> for _ in range(100): >>> step()
-
property
working_dir
¶ Working directory of the scene.
- Return type
str
The object class¶
-
class
Object
¶ Base class for all objects in the scene.
Object property access is performed using the [] operator. For instance, you can access the position of an object using object[“position”]. The available property names match the property names displayed in the property editor of PreonLab. You can also view a list of available properties by calling object.property_names.
-
__getitem__
(property_name)¶ Returns the value of the property with the given name.
- Parameters
property_name (
str
) – Name of the property, which should be returned.- Raises
PropertyNotFound – If the property name could not be found.
Usage example:
>>> property_value = object["property_name"]
-
__setitem__
(property_name, new_value)¶ Sets the value of the property with the given name.
- Parameters
property_name (
str
) – Name of the property, which should be set.new_value – Value to be set.
- Raises
PropertyNotFound – If the property name could not be found.
Usage example:
>>> object["property_name"] = new_value
-
apply_preset
(preset_name)¶ Apply a preset to this object. You can query the available presets for this object with the preset_names property.
- Parameters
preset_name (
str
) – The name of the preset.- Raises
LookupError – If the given preset_name is not available.
-
associated_scene
()¶ Access to the scene this object belongs to.
- Return type
- Returns
The scene this object belongs to. If this is called on the scene itself, the same scene is returned.
Usage example:
>>> print(box.associated_scene().path)
-
property
category
¶ Returns the category of the object as a string, like “Sensors” or “Sources”. For the scene object it returns “Scene”.
Usage example:
>>> # Print the name of all sensors in the scene >>> for obj_name in scene.object_names: >>> obj = scene.find_object(obj_name) >>> if obj.category == "Sensors": >>> print(obj_name + " is a Sensor")
- Return type
str
-
get_connected_objects
(slot_name, outgoing, include_target_slot_name=False)¶ Retrieves a list of connected objects for the given slot.
- Parameters
slot_name (
str
) – The name of the connection slot. The name is the same that is displayed in the PreonLab connection editor, for instance “Transform”.outgoing (
bool
) – Specifies whether outgoing or incoming connections should be returned.include_target_slot_name (
bool
) – Specifies whether the name of the connected object (target) slot should be included per connected object as well.
- Return type
List
[Union
[Object
,Scene
,FloatFieldObject
,SensorObject
,Rigid
,CarSuspensionModel
,VehicleSimulationModel
,Camera
,PreonRenderer
,PointCloudResource
,StatisticResource
,SolverObject
,LiquidSolver
,VectorFieldObject
,Group
,SensorPlane
,Pathlines
,Tuple
[Union
[Object
,Scene
,FloatFieldObject
,SensorObject
,Rigid
,CarSuspensionModel
,VehicleSimulationModel
,Camera
,PreonRenderer
,PointCloudResource
,StatisticResource
,SolverObject
,LiquidSolver
,VectorFieldObject
,Group
,SensorPlane
,Pathlines
],str
]]]- Returns
List of objects. In case the include_target_slot_name property is set to
True
for each connected object a pair of the object and its slot name is returned.- Raises
ConnectionError – If an error occurs.
-
get_connection_slots
(outgoing, include_target_slot_name=False)¶ Retrieves a list of slot names together with a list of connected objects for each respective slot.
- Parameters
outgoing (
bool
) – Specifies whether outgoing or incoming slots should be returned.include_target_slot_name (
bool
) – Specifies whether the name of the connected object (target) slot should be included per connected object as well.
- Return type
List
[Tuple
[str
,List
[Union
[Object
,Scene
,FloatFieldObject
,SensorObject
,Rigid
,CarSuspensionModel
,VehicleSimulationModel
,Camera
,PreonRenderer
,PointCloudResource
,StatisticResource
,SolverObject
,LiquidSolver
,VectorFieldObject
,Group
,SensorPlane
,Pathlines
,Tuple
[Union
[Object
,Scene
,FloatFieldObject
,SensorObject
,Rigid
,CarSuspensionModel
,VehicleSimulationModel
,Camera
,PreonRenderer
,PointCloudResource
,StatisticResource
,SolverObject
,LiquidSolver
,VectorFieldObject
,Group
,SensorPlane
,Pathlines
],str
]]]]]- Returns
List of pairs of slot name and a list of connected objects to that slot. In case the include_target_slot_name is set to
True
for each connected object a pair of the object and its slot name is returned.- Raises
ConnectionError – If an error occurs.
-
get_keyframes
(sequence_name)¶ Retrieves the keyframes for the given sequence. Loop keyframes are not included in the returned list. Use
get_loop_keyframes()
instead.- Parameters
sequence_name (
str
) – The name of the keyframe sequence, for instance “position x”.- Return type
List
[Tuple
[float
,Any
,str
]]- Returns
A list of triples, in which the first triple value indicates the time, the second the value and the third the interpolation string type for the following segment.
- Raises
KeyframeError – If an error occurs.
-
get_loop_keyframes
(sequence_name)¶ Retrieves the loop keyframes for the given sequence. The list includes invalid loop keyframes, too. Examples for invalid keyframes:
The loop keyframe overlaps with other loop keyframes.
Less keyframes are preceding the loop keyframe than is required by it.
- Parameters
sequence_name (
str
) – The name of the keyframe sequence, for instance “position x”.- Return type
List
[Tuple
[float
,int
,bool
]]- Returns
A list of triples, in which the first value indicates the time, the second value the number of preceding keyframes that define the loop and the third value indicating whether it is valid.
- Raises
KeyframeError – If an error occurs.
-
get_parent_group
()¶ Returns the parent
Group
to which this object belongs, orNone
if it is not part of a group.
-
get_property
(property_name)¶ Returns the value of the property with the given name. If the property has a unit, it will be returned as
Quantity
.Usage example:
>>> particle_size_mm = solver.get_property("particle size").value_as("mm")
- Parameters
property_name – Name of the property that should be returned.
- Raises
PropertyNotFound – If the property name could not be found.
- Return type
Union
[Quantity
,str
,int
,float
,Vec3
,EulerAngles
,SymmetricMatrix33
,Color
]
-
get_property_default
(property_name)¶ Returns the default value of the property with the given name. If the property has a unit, it will be returned as
Quantity
.Usage example:
>>> different = solver.get_property_default("particle size").convert_baseunit() == solver.get_property("particle size").convert_baseunit()
- Parameters
property_name (
str
) – Name of the property that should be returned.- Raises
PropertyNotFound – If the property name could not be found.
- Return type
Union
[Quantity
,str
,int
,float
,Vec3
,EulerAngles
,SymmetricMatrix33
,Color
]
-
get_property_enum_values
(name)¶ Returns valid enum values.
- Parameters
name (
str
) – Name of the property. Must be an enum property.- Return type
List
[str
]- Returns
The possible values for the given property.
- Raises
PropertyError – If the property is no enum.
PropertyNotFound – If the property name could not be found.
-
get_property_grouping
(name)¶ Returns the grouping in which the given property is organized in the PreonLab UI. Note: This grouping might change more often to archive a structuring, whereas the property name itself is tried to be kept fairly stable.
- Parameters
name (
str
) – Name of the property.- Return type
List
[str
]- Returns
A list containing the grouping hierarchy for this property, starting with the top level group.
- Raises
PropertyNotFound – If the property name could not be found.
Usage example:
>>> property_name = "some property name") >>> print(" -> ".join([obj.category, obj.name] + obj.get_property_grouping(property_name) + [property_name])) >>> # prints e.g. Solvers -> PreonSolver_1 -> Physics -> Some sub group -> some property name
-
get_property_help
(name)¶ Returns property description.
- Parameters
name (
str
) – Name of the property.- Return type
str
- Returns
A short description of the given property.
- Raises
PropertyNotFound – If the property name could not be found.
-
get_property_keyframe_sequence_names
(name)¶ Returns the list of keyframe sequences for the provided property.
- Parameters
name (
str
) – Name of the property.- Return type
Optional
[List
[str
]]- Returns
A list of keyframe sequences for the given property, or
None
in case the property does not support key framing.
-
get_property_type
(name)¶ Returns property type.
- Parameters
name (
str
) – Name of the property.- Return type
str
- Returns
The type of the property with the given name.
- Raises
PropertyNotFound – If the property name could not be found.
-
get_spline
(sequence_name)¶ Retrieves the keyframes as a spline curve for the given sequence. Information on interpolation types of the curve segments is stripped away. Furthermore, loop keyframes are not included in the returned list. Use
get_loop_keyframes()
instead.- Parameters
sequence_name (
str
) – The name of the keyframe sequence, for instance “position x”.- Return type
List
[Tuple
[float
,Any
]]- Returns
A list of tuples, in which the first value indicates the time and the second the value.
- Raises
KeyframeError – If an error occurs.
-
is_property_keyable
(name)¶ Returns
True
if keyframes can be set for the property. Note that properties can be keyframed even though they are not writable. Example: track time-avg::heat flux in the Thermal sensor requires keyframes for a clear definition of the intervals.- Parameters
name (
str
) – Name of the property.- Return type
bool
- Returns
True
if keyframes can be set for the property ,False
if not.- Raises
PropertyNotFound – If the property name could not be found.
-
is_property_writable
(name)¶ Returns if a property is writable or read-only.
- Parameters
name (
str
) – Name of the property.- Return type
bool
- Returns
True
if the property is writable,False
if not.- Raises
PropertyNotFound – If the property name could not be found.
-
is_valid
()¶ Returns
True
if the object is valid.- Return type
bool
-
property
keyframe_sequence_names
¶ Returns a list of keyframe sequences. Sequences can be accessed via the index operator.
Note that the list of keyframe sequence names depends on the current state of the object. It could grow or shrink depending on changes made to the object in subsequent calls.
- Return type
List
[str
]
-
property
name
¶ Returns the name of the object as a string, like “PreonSolver_1” or “Box_1”. For the scene object it returns “Scene”.
Usage example:
>>> # Print all transform connections of an object >>> for out_connections in cuboid.get_connected_objects("Transform", True): >>> print(cuboid.name + " is connected to " + out_connections.name)
- Return type
str
-
property
preset_names
¶ A list of the available presets for this object.
- Return type
List
[str
]- Returns
A list of strings where each one can be used in the apply_preset method.
-
property
property_names
¶ Returns a list of property names. Properties can be accessed via the index operator.
Note that the list of property names depends on the current state of the object. It could grow or shrink depending on changes made to the object in subsequent calls.
- Return type
List
[str
]
-
reload_statistics
()¶ Reload statistics for this object from the filesystem. This can be used to get updated values if another instance also works with the current scene. It also can be used to load statistics for a specific object, if the scene was opened with the load_only_object_creations flag.
-
set_keyframes
(sequence_name, keyframes)¶ Sets the keyframes for the given sequence name.
- Parameters
sequence_name (
str
) – The name of the keyframe sequence, for instance “position x”.keyframes (
List
[Tuple
[float
,Any
,str
]]) – A list of triples, in which the first triple value indicates the time, the second the value and the third the interpolation string type for the following segment (pass “Linear” for linear interpolation or “Step” for step interpolation).
- Raises
KeyframeError – If an error occurs.
-
set_loop_keyframes
(sequence_name, loop_keyframes)¶ Adds a list of loop keyframes to the sequence with the respective name. Each loop keyframe is defined via a sequence interval consisting of at least two keyframes. This interval is repeated (i.e. looped) until a specified point in time (end time).
Notes:
The end time must be less or equal to potential subsequent keyframes.
The sequence interval defined with num_keyframes must not contain a loop keyframe (i.e. loop definitions must not overlap).
- Parameters
sequence_name (
str
) – The name of the keyframe sequence, for instance “position x”.loop_keyframes (
List
[Tuple
[float
,int
]]) – A list of tuples, in which the first value gives the point in time until which a sequence interval should be repeated and the second value the number of keyframes preceding this point in time that make up the sequence interval to be looped.
- Raises
KeyframeError – If an error occurs.
-
set_spline
(sequence_name, keyframes)¶ Sets the keyframes with spline as interpolation type for the given sequence name.
- Parameters
sequence_name (
str
) – The name of the keyframe sequence, for instance “position x”.keyframes (
List
[Tuple
[float
,Any
]]) – A list of tuples, in which the first value indicates the time and the second the value.
- Raises
KeyframeError – If an error occurs.
-
statistic
(name)¶ Access to a statistic.
Note that some statistics consist of multiple components (e.g. the
Vec3
statistic Position). However, they are also accessed via a singleStatistic
object.Usage example:
>>> num_particles = scene.statistic("Solver Particles") >>> print(num_particles.min().value) >>> print(box.statistic("Position").at("1s").value_as("mm").x)
- Parameters
name – The name of the statistic which must be one of the statistics that is displayed in PreonLab in the Plot Dialog (for instance “Volume Flow Rate” for sensor planes).
- Return type
- Returns
The statistic object.
-
statistic_buffers
(fixed_time_interval=True, unit=UnitSetting.DISPLAY_UNIT, as_scalars=None)¶ Exports the statistics data of the object as a BufferSet. Read more about buffer usage.
Access the columns of the BufferSet by the statistics name. In order to relate the row entries to points in time, access the “time” column for the timestamps in seconds. If a certain statistic value is not present at a point in time, it is exported as NaN value.
- Parameters
fixed_time_interval (
bool
) – IfTrue
, exports samples at a constant frame rate, i.e., the view frame rate. Set toFalse
if you have keyframed the view frame rate to avoid oversampling.unit (
UnitSetting
) – Specifies the requested units. The default is the unit that is also shown in the Plot Dialog (DISPLAY_UNIT
). Other options areINTERNAL_UNIT
andBASE_UNIT
.as_scalars (
Optional
[bool
]) –If
False
, vector statistics are exported as a single buffer containing vector values. Set toTrue
if you need a distinct buffer for each vector component. By default,False
is used.Deprecated since version 5.3: Parameter
as_scalars
is deprecated and will be removed in 7.0.
- Return type
- Returns
A
BufferSet
containing the statistic values.
Usage example:
>>> stats = obj.statistic_buffers() >>> stats_time = numpy.array(stats["time"], copy=False) >>> stats_val = numpy.array(stats["Statistic name"], copy=False) >>> for t, v in zip(stats_time, stats_val): >>> print(t, v)
-
property
statistic_names
¶ A list with names of the available statistics. Note that statistic data might not be available.
Usage example:
>>> print(f"Statistic of Object {obj.name}:") >>> for stat_name in obj.statistic_names: >>> print(f"* {stat_name}")
The entries of the returned list can be used to request a
Statistic
object viastatistic()
. Note that if you need a list with all availableStatistic
objects, you can directly usestatistics
.The returned list contains only one statistic name per vector-valued statistic. Example: Only ‘Linear Velocity’ will be returned instead of ‘Linear Velocity Norm’, ‘Linear Velocity X’, ‘Linear Velocity Y’ and ‘Linear Velocity Z’. If you need the names of the individual sequences, please get a
Statistic
object and then use thesequences
property.- Return type
List
[str
]- Returns
A list of the object’s statistic names.
-
property
statistics
¶ A list of the available statistics.
- Return type
List
[Statistic
]- Returns
A list of the object’s statistics.
-
property
type
¶ Returns the type of the object as a string, like “Preon Solver” or “Camera”. For the scene object it returns “Scene”.
Usage example:
>>> # Deactivate all renderers >>> for obj_name in scene.object_names: >>> obj = scene.find_object(obj_name) >>> if obj.type == "Preon Renderer": >>> obj["behavior"] = "inactive"
- Return type
str
-
write_statistics_to_csv
(file_path, fixed_time_interval=True, separator=';')¶ Write statistics data as CSV to the given file.
- Parameters
file_path (
Union
[str
,PathLike
]) – Defines the file to which the statistics are written.fixed_time_interval (
bool
) – IfTrue
, exports samples at a constant frame rate, i.e., the view frame rate. Set toFalse
if you have keyframed the view frame rate to avoid oversampling.separator (
str
) – Defines the separator used in the CSV export.
-
Object specific functionality¶
-
class
GlobalTransformMixin
¶ -
global_transform
()¶ Returns the global transformation matrix of this object. It describes the transformation of the objects position, rotation and scale from its untransformed origin to the current state.
- Return type
List
[List
[float
]]- Returns
Returns the components of the transformation matrix as a list of lists where each sub-list contains one row of the matrix.
Usage example:
>>> transformation_matrix = np.array(obj.global_transform()) >>> transformed_points = transformation_matrix @ np.array([[1, 2, 3, 1], [4, 5, 6, 1]]).transpose()
-
-
class
ParticleDataAccessMixin
¶ -
ensight_exportable_data
()¶ Returns names of data that is exportable to ensight using the export_sample_data_to_ensight method.
- Return type
List
[str
]- Returns
A list of strings. You can use this list, or a subset, as the data argument of the export_sample_data_to_ensight method.
-
export_sample_data_to_ensight
(start, stop, path, per_node=True, id=False, data=None)¶ Exports the particle data in the EnSight Gold format. All particles are exported as point elements. It’s possible to export additional variables by specifying the data parameter.
- Parameters
start (
int
) – First view frame of the export.stop (
int
) – Last view frame of the export.path (
str
) – Path to the empty target directory.per_node (
bool
) – Specifies if additional data is exported per node or per point element.id (
bool
) – If set toTrue
the particle id is also exported per point element.data (
Optional
[List
[str
]]) – List of strings, specifying the additional data, that should be exported. See ensight_exportable_data for possible values.
- Raises
DataNotAvailable – If an element in the data parameter is not available or if the specified start/stop contains no particle data.
DirectoryIsNotEmpty – If path is not empty.
DirectoryDoesNotExist – If path does not exist.
-
particle_buffer_names
()¶ Returns the list of names of particle buffers that can be accessed via
particle_buffers()
orparticle_buffers_list()
.- Return type
List
[str
]- Returns
Returns a list of strings. You can provide a subset of this list to
particle_buffers()
orparticle_buffers_list()
for a limited but potentially more efficient access.
-
particle_buffers
(buffer_names=None)¶ This function provides direct access to the particle buffers. This includes position and other per-particle data. A buffer may contain NaN values for particles that cannot provide information on the respective quantity stored in the buffer. In order to safely use this functionality, certain rules need to be followed. Read more about buffer access. Note that for rigid objects, dynamic sampling is required to be turned off in order to access the particle buffers with this method. See
particle_buffers_list()
if you want to use it with dynamic sampling turned on.- Parameters
buffer_names (
Optional
[List
[str
]]) – List of strings, specifying the buffers that should be accessible. Seeparticle_buffer_names()
for possible values. If none are specified, all accessible buffers are returned.- Raises
DataNotAvailable – If an element in the buffers parameter is not available.
- Return type
AbstractContextManager
[BufferSetRef
]- Returns
A context manager for accessing the
BufferSetRef
containing the particle buffers.
Usage example:
>>> with obj.particle_buffers() as buffers: >>> print(buffers.keys()) >>> del buffers
-
particle_buffers_list
(buffer_names=None)¶ This function provides direct access to the particle buffers. This includes position and other per-particle data. In order to safely use this functionality, certain rules need to be followed. Read more about buffer access. Compared to
particle_buffers()
this method supports dynamic sampling. If dynamic sampling is turned off, it will always return a single element list.- Parameters
buffer_names (
Optional
[List
[str
]]) – List of strings, specifying the buffers that should be accessible. Seeparticle_buffer_names()
for possible values. If none are specified, all accessible buffers are returned.- Raises
DataNotAvailable – If an element in the buffers parameter is not available.
- Return type
AbstractContextManager
[List
[BufferSetRef
]]- Returns
A context manager for accessing the list of
BufferSetRef
containing the particle buffers.
Usage example:
>>> with obj.particle_buffers_list() as buffers_list: >>> for buffers in buffers_list: >>> use_buffers(buffers) >>> del buffers >>> del buffers_list
-
Solid objects¶
-
class
Rigid
¶ Bases:
preonpy.objects.Object
,preonpy.objects.GlobalTransformMixin
,preonpy.objects.ParticleDataAccessMixin
PreonPy class for the following object types:
Alembic Mesh
Box
Capsule
Cuboid
Cylinder
Mesh
Plane
Porous Rigid
Sphere
-
apply_connected_point_cloud
()¶ Maps the quantities stored in the point cloud (e.g. temperature) to the surface sampling of the rigid.
- Raises
RuntimeError – If no point cloud is connected, or the rigid´s system type is not set to ‘ClosedFixed’.
-
compute_system
()¶ Computes the local coordinate system of a rigid by performing a principal component analysis on its triangle mesh. This method changes (pivot) position and (pivot) orientation of the rigid.
Attention: The result of this method might not match expectation, e.g. the resulting position and orientation might not be useful to rotate a gear around its rotation axis.
-
export_sample_data_to_csv
(start, stop, local_coords, separator=';')¶ Exports the sample data of a rigid as CSV file(s). The frame number is used for naming the file(s). The exported files are stored in the folder ‘SimData/RigidData/<rigid_name>’ in the scene directory.
- Parameters
start (
int
) – First view frame.stop (
int
) – Last view frame. Can be equal to start.local_coords (
bool
) – IfTrue
, the data is saved in the local space of the rigid, else the global scene space is used.separator (
str
) – Specifies the separator used for the CSV export.
-
get_texture3d
()¶ Compute and return the rigid coloring texture. This is a 3D texture that contains the coloring of the rigid based on connected sensors or the coloring property of the rigid.
- Return type
Optional
[Texture3D
]- Returns
The texture or None is returned. The latter is the case if the rigid is not
yet sampled with particles or if all particles have the default color.
-
raycast
(ray_origin, ray_dir)¶ Casts a ray from the given origin into the given direction and returns the distance to the closest hit. Returns -1 if no hit was found. This function may be computationally very expensive depending on the amount of triangles in the mesh.
- Parameters
- Return type
float
- Returns
The distance in “m” to the closest hit or -1 of not hit was found.
-
reset_pivot
()¶ Resets the pivot of an object. This function can be used to undo
compute_system()
-
triangle_buffers
()¶ This function provides direct access to the geometry of this rigid, i.e., its triangle mesh. This includes positions and the per-position normals. In order to safely use this functionality, certain rules need to be followed. Read more about buffer access.
- Return type
AbstractContextManager
[TriangleDataRef
]- Returns
A context manager for accessing the
TriangleDataRef
containing the buffers.
Usage example:
>>> with rigid.triangle_buffers() as triangle_data: >>> triangles_indices = np.array(triangle_data.triangles(), copy=False) >>> positions = np.array(triangle_data.positions(), copy=False) >>> for indices in triangles_indices: >>> print("Triangle at ", positions[indices]) >>> del triangle_data >>> del triangles_indices >>> del positions
Sensors (Plane, Mesh, Wetting, Force, Thermal, Height, Y+), Air Flow Visualizer, Height Field and Velocity Projection Field, Pathlines¶
-
class
FloatFieldObject
¶ Bases:
preonpy.objects.Object
,preonpy.objects.GlobalTransformMixin
PreonPy class for the following object types:
Velocity Projection Field
Vector Field Visualizer
Height Field
-
get_image
()¶ Get direct access to texture of the float field object, i.e., its image data including width, height and per-pixel color as a buffer. Since the color buffer gives direct access to the memory of preonpy, certain rules need to be followed in order to safely use this functionality. Read more about buffer access.
- Return type
AbstractContextManager
[ImageRef
]- Returns
A context manager for accessing the
ImageRef
containing the image data.
Usage example:
>>> with floatfield.get_image() as image: >>> width = image.width() >>> height = image.height() >>> pixel_data = numpy.array(image.data(), copy=False) >>> print(pixel_data) >>> del pixel_data >>> del image
-
get_projected_value
(position, default)¶ Projects position on the 2D field and returns the value stored at that position. If the projected point is outside the 2D field, the default value is returned.
-
class
SensorObject
¶ Bases:
preonpy.objects.Object
PreonPy class for the following object types:
Force Sensor
Height Sensor
Y+ Sensor
Thermal Sensor
Wetting Sensor
Sensor Mesh
-
export_sample_data_to_csv
(start, stop, local_coords, quantity_names=None, separator=';')¶ Exports the sample data of the sensor as CSV file(s). The frame number is used for naming the file(s). The exported files are stored in the respective subfolder of the folder ‘SensorData’ in the scene directory.
- Parameters
start (
int
) – First view frame.stop (
int
) – Last view frame. Can be equal to start.local_coords (
bool
) – IfTrue
, the data is saved in the local space of the object, else the global scene space is used.quantity_names (
Optional
[List
[str
]]) – A list of names of measured values. IfNone
, all measured values are saved to the file. If you want to save a subset of the measured values only, use names_of_measured_values() to get a list of valid names.separator (
str
) – Specifies the separator that is used for the CSV export.
-
names_of_measured_values
()¶ Returns the list of names for the values measured by the sensor.
- Return type
List
[str
]
-
sensor_buffers
(local_coords, quantity_names=None)¶ Exports the current sensor data as a BufferSet. Read more about buffer usage.
- Parameters
local_coords (
bool
) – IfTrue
, the data is saved in the local space of the object, else the global scene space is used.quantity_names (
Optional
[List
[str
]]) – A list of names of measured values. IfNone
, all measured values are saved to the file. If you want to save a subset of the measured values only, use names_of_measured_values() to get a list of valid names.
- Return type
- Returns
A
BufferSet
containing the requested values.
Usage example:
>>> force.sensor_buffers(False)["Pressure"]
-
class
SensorPlane
¶ Bases:
preonpy.objects.SensorObject
,preonpy.objects.FloatFieldObject
PreonPy class for the object type ‘Sensor Plane’.
-
class
Pathlines
¶ Bases:
preonpy.objects.SpatialObject
PreonPy class for the object type ‘Pathlines’.
-
export_mesh
(file_path, diameter_scale=1, length_threshold_scale=1, angle_threshold=Quantity(0.0, °), number_of_edges=9, binary_file=True, mesh_unit='m')¶ This function exports the pathlines as mesh.
- Parameters
file_path (
Union
[str
,PathLike
]) – Defines the file to which the mesh is written and its format. Supported formats: ‘{“.obj”, “.ply”, “.dae”, “.assbin”, “.stl”}’diameter_scale (
float
) – Defines the diameter of the tubes representing the pathlines, given as factor of the (minimum) particle size of the connected solver.length_threshold_scale (
float
) – The segments that are shorter than the provided value will be merged together. Given as factor of the (minimum) particle size of the connected solver.angle_threshold (
Union
[Quantity
,float
]) – If set, the consecutive segments that diverge by an angle smaller than ‘angle_threshold’ will be merged together. The provided value should be in “°” or in a compatible angleQuantity
.number_of_edges (
int
) – The number of edges on the cross-section of the tubes.binary_file (
bool
) – Outputs a binary file if true else the file would be written in ASCII. Only available for “.ply” and “.stl”.mesh_unit (
str
) – The mesh will be scaled to the given unit upon export. Possible values can be retrieved from the “length” row of the units table.
Usage example:
>>> # Export pathlines to PLY binary file using default mesh export unit (m), diameter (particle size) and length filter >>> pathlines.export_mesh("C:\pathlines_mesh.ply") >>> # Export pathlines to PLY ASCII file >>> pathlines.export_mesh("C:\pathlines_mesh.stl", binary_file=False)
-
get_line_data
()¶ This function provides direct access to the pathline data. The returned BufferSet contains one buffer per pathline. Each pathline consists of a sequence of points. Each point then consists of X,Y,Z values and a value that represents what is visualized in the GUI. All sequences have the same length, but they might have NaN values if no data is present at respective frames.
Usage example:
>>> lines = obj.get_line_data() >>> print(lines.keys())
-
Preon Renderer¶
-
class
PreonRenderer
¶ Bases:
preonpy.objects.Object
PreonPy class for the object type ‘Preon Renderer’.
-
render
(start, stop=None, cam_objects=None)¶ Render the frames in the given range for one or multiple cameras.
- Parameters
start (
Union
[int
,str
,Frame
,Second
,Quantity
]) – Rendering start. Can be either an integer representing the frame number, a time string, aFrame
, aSecond
object or aQuantity
representing time.stop (
Union
[int
,str
,Frame
,Second
,Quantity
,None
]) – Rendering end (can be equal to start). Can be either an integer representing the frame number, a time string, aFrame
, aSecond
or aQuantity
representing time object orNone
. IfNone
, only the start frame is rendered.cam_objects (
Union
[Camera
,List
[Camera
],None
]) – Camera object or list of camera objects. Renderer uses connected camera, if omitted.
Usage example:
>>> renderer = scene.find_object("MyRenderer") >>> renderer.render("0s", "1s") >>> cam_x = scene.find_object("CamX") >>> renderer.render(0, 5, cam_x)
-
Solvers¶
-
class
SolverObject
¶ Bases:
preonpy.objects.Object
,preonpy.objects.ParticleDataAccessMixin
PreonPy class for the following object types:
Preon Solver
Solid Volume Solver
Snow Solver
Periodic Boundary Solver
-
export_sample_data_to_csv
(start, stop, separator=';')¶ Exports the particle data of a fluid as CSV file(s). The frame number is used for naming the file(s). The exported files are stored in the folder ‘SimData/FluidData/<solver_name>’ in the scene directory.
- Parameters
start (
int
) – First view frame.stop (
int
) – Last view frame. Can be equal to start.separator (
str
) – Specifies the separator used for the CSV export.
Statistic Resource, Point Cloud Resource, Tensor Fields¶
-
class
StatisticResource
¶ Bases:
preonpy.objects.Object
PreonPy class for the object type ‘Statistic Resource’.
-
import_stats
(filePath)¶ Imports the content of a CSV file (.csv) or PreonLab Statistic file (.stats) to the statistic resource.
- Parameters
filePath (
Union
[str
,PathLike
]) – The path to the file that should be imported.- Raises
FileNotFoundError – If the file could not be found.
InvalidFileFormat – If the file could not be imported.
-
-
class
PointCloudResource
¶ Bases:
preonpy.objects.Object
PreonPy class for the object type ‘Point Cloud Resource’.
-
import_from_csv
(file_path, separator=';')¶ Imports the content of a CSV file (.csv) to the point cloud resource. Make sure that you have set the correct column names employed in the CSV file in the respective properties of the point cloud resource object.
- Parameters
file_path (
Union
[str
,PathLike
]) – The path to the file that should be imported.separator (
str
) – The character used to separate the column entries in the CSV file.
- Raises
FileNotFoundError – If the file could not be found.
InvalidFileFormat – If the file could not be imported.
-
-
class
VectorFieldObject
¶ Bases:
preonpy.objects.Object
,preonpy.objects.GlobalTransformMixin
PreonPy class for the following object types:
Air Flow
Acceleration Field
-
import_from_csv
(file_path, columnHeaders, separator=';')¶ Imports the content of a CSV file (.csv) to an object.
- Parameters
file_path (
Union
[str
,PathLike
]) – The path to the file that should be imported.separator (
str
) – The character used to separate the column entries in the CSV file.columnHeaders (
List
[str
]) – A list of three position column names, followed by three column names of the entity. Order is x, y, z.
- Raises
FileNotFoundError – If the file could not be found.
InvalidFileFormat – If the file could not be imported.
Usage example:
>>> air_flow.import_from_csv("C:/test.csv", ["# PositionX","PositionY","PositionZ","VelocityX","VelocityY","VelocityZ"]) >>> acceleration_field.import_from_csv("C:/test.csv", ["# PositionX","PositionY","PositionZ","AccelerationX","AccelerationY","AccelerationZ"])
Car Suspension Model, Vehicle Simulation Model¶
-
class
CarSuspensionModel
¶ Bases:
preonpy.objects.Object
PreonPy class for the object type ‘Car Suspension Model’.
-
position_base_transform
(transform_group, position)¶ Positions a transform group (TG) which is the transform parent of the car suspension model (CSM), i.e., connected to the Transform input slot of the CSM. Use this function to re-position the TG without changing the global positioning of sprung and unsprung car geometries.
- Parameters
-
-
class
VehicleSimulationModel
¶ Bases:
preonpy.objects.Object
PreonPy class for the object type ‘Vehicle Simulation Model’.
Group¶
-
class
Group
¶ Bases:
preonpy.objects.Object
PreonPy class for the object type ‘Group’. Only objects of one category can be grouped.
-
__iter__
()¶ Iterate over subitems of this group.
- Return type
Iterable
[Object
]- Returns
iterator over subitems
Usage example:
>>> for sub in group: >>> print(sub.name)
-
add
(obj)¶ Adds an object to the object group.
- Parameters
obj (
Object
) – The object to be added to the group.- Raises
GroupError – If the passed object can not be added or is already part of this group.
Usage example:
>>> group.add(scene.create_object("Box"))
-
remove
(obj)¶ Removes an object from the object group.
- Parameters
obj (
Object
) – The object to be removed from the group.- Raises
GroupError – If the passed object is not part of this group.
Usage example:
>>> group.remove(scene.find_object("Box_1"))
-
Object connections¶
-
connect_objects
(obj1, obj2, slot_name, input_slot_name=None)¶ Creates a connection from obj1 to obj2 for the given connection slot name.
- Parameters
obj1 (
Object
) – Object from which the connection should go out.obj2 (
Object
) – Object into which the connection should go in.slot_name (
str
) – The name of the connection slot. The name is the same that is displayed in the PreonLab connection editor, for instance “Transform”.input_slot_name (
Optional
[str
]) – The name of the slot at obj2. If not given this will be assumed to be the same as slot_name.
- Raises
ConnectionError – If the objects could not be connected.
Usage example:
>>> tg1 = scene.create_object("Transform Group") >>> box = scene.find_object("Box_1") >>> preonpy.connect_objects(tg1, box, "Transform")
-
disconnect_objects
(obj1, obj2, slot_name, input_slot_name=None)¶ Removes the connection from obj1 to obj2 for the given connection slot name.
- Parameters
obj1 (
Object
) – Object from which the connection goes out.obj2 (
Object
) – Object into which the connection goes in.slot_name (
str
) – The name of the connection slot. The name is the same that is displayed in the PreonLab connection editor, for instance “Transform”.input_slot_name (
Optional
[str
]) – The name of the slot at obj2. If not given this will be assumed to be the same as slot_name.
- Raises
ConnectionError – If the objects could not be connected.
Usage example:
>>> tg1 = scene.find_object("TransformGroup_1") >>> box = scene.find_object("Box_1") >>> preonpy.disconnect_objects(tg1, box, "Transform")
Utility classes¶
-
class
Vec3
¶ -
property
norm
¶ Norm of the vector.
-
replace
(self: preonpy._preonpy.Vec3, **kwargs) → preonpy._preonpy.Vec3¶ Returns a copy of this object with one or more components replaced. The replaced components can be specified as keyword argument.
-
property
x
¶ X coordinate.
-
property
y
¶ Y coordinate.
-
property
z
¶ Z coordinate.
-
property
-
class
EulerAngles
¶ -
property
phi
¶ PHI component.
-
property
psi
¶ PSI component.
-
replace
(self: preonpy._preonpy.EulerAngles, **kwargs) → preonpy._preonpy.EulerAngles¶ Returns a copy of this object with one or more components replaced. The replaced components can be specified as keyword argument.
-
property
theta
¶ THETA component.
-
property
-
class
Color
(r, g, b, a)¶ -
a
¶ Alias for field number 3
-
b
¶ Alias for field number 2
-
g
¶ Alias for field number 1
-
r
¶ Alias for field number 0
-
-
class
SymmetricMatrix33
¶ -
replace
(self: preonpy._preonpy.SymmetricMatrix33, **kwargs) → preonpy._preonpy.SymmetricMatrix33¶ Returns a copy of this object with one or more components replaced. The replaced components can be specified as keyword argument.
-
property
xx
¶ XX component.
-
property
xy
¶ XY/YX components.
-
property
xz
¶ XZ/ZX components.
-
property
yy
¶ YY component.
-
property
yz
¶ YZ/ZY components.
-
property
zz
¶ ZZ component.
-
-
class
Second
(seconds)¶ Specifies a point in time of the simulation, represented in seconds. To be used as a parameter of various functions.
-
class
Frame
(frame_number, view=None, obj=False)¶ Specifies a point in time of the simulation, represented as a frame number. To be used as a parameter of various functions. By default, the view frame rate is used. If the frame number refers to the simulation frame rate, view has to be set to
False
. If you want to refer to the objects frame rate, then set obj toTrue
. This defaults to the view frame rate or the model framerate, but can be overridden for some objects.
Units¶
Starting from PreonLab 5.1, the support for units has been greatly improved. Many methods are built around the
Quantity
utility class. For example, it is possible to use it in property assignments or to
retrieve and work with statistics as quantities:
solver["particle size"] = preonpy.Quantity(10, "mm")
kelvin_at_20ms = solver.statistic("Avg. Temperature").at("20ms").value_as("K")
This allows scripts to be more readable, as the units can be explicitly stated in the code, and more robust against
wrong assumptions about how a value is returned. In scripts that are meant to be reusable we encourage you to
favor base_value
and value_as()
over
value
.
-
class
Quantity
(value, unit='')¶ -
property
base_unit
¶ Gives access to the SI base unit. See
base_value
and units table.Usage example:
>>> print("SI base unit of " + str(quantity.unit) + " is "+ quantity.base_unit)
- Return type
str
- Returns
The SI base unit for the specified unit of this quantity.
-
property
base_value
¶ Gives access to the value in the SI base unit (see
base_unit
, units table).Usage example:
>>> print(str(quantity.base_value) + " in SI base unit " + quantity.base_unit)
- Return type
Union
[float
,Vec3
,EulerAngles
,SymmetricMatrix33
]- Returns
The value in the SI base unit. The value can be a
float
or a compound type containing multiplefloat
elements.
-
convert
(unit)¶ Provides conversion to a given unit.
Usage example:
>>> print(Quantity(0.1, "m").convert("mm"))
- Parameters
unit (
str
) – The unit the returned quantity should be converted to.- Return type
- Returns
A new converted quantity object.
-
convert_baseunit
()¶ Provides conversion to the SI base unit (see units table).
Usage example:
>>> print(Quantity(110, "mm").convert_baseunit().unit == "m") >>> print(Quantity(110, "mm").convert_baseunit().value > 0.1)
- Return type
- Returns
A new converted quantity object.
-
property
unit
¶ Gives access to the specified unit (see
value
).Usage example:
>>> print("Quantity has unit " + quantity.unit)
- Return type
str
- Returns
The specified unit.
-
property
value
¶ Gives access to the value in the specified
unit
.Usage example:
>>> print(str(quantity.value) + " in unit " + quantity.unit)
- Return type
Union
[float
,Vec3
,EulerAngles
,SymmetricMatrix33
]- Returns
The value in the specified unit. The value can be a
float
or a compound type containing multiplefloat
elements.
-
value_as
(unit)¶ Quick access to the value in a given unit.
Usage example:
>>> q = Quantity(0.1, "m") >>> print("0.1 m equals " + str(q.value_as("mm")) + " mm")
- Parameters
unit (
str
) – The unit the returned value should be converted to.- Return type
Union
[float
,Vec3
,EulerAngles
,SymmetricMatrix33
]- Returns
The converted value.
-
property
Class UnitSetting
is used as an argument for e.g. statistic_buffers()
.
-
class
UnitSetting
¶ Members:
DISPLAY_UNIT : Represents what e.g. the Plot dialog shows. It is defined by the default units of the scene and per-statistic-and-object user overrides.
BASE_UNIT : Base SI unit. See units table for the exact units used.
INTERNAL_UNIT : The unit PreonLab uses internally.
-
BASE_UNIT
= UnitSetting.BASE_UNIT¶
-
DISPLAY_UNIT
= UnitSetting.DISPLAY_UNIT¶
-
INTERNAL_UNIT
= UnitSetting.INTERNAL_UNIT¶
-
property
name
¶
-
property
value
¶
-
-
get_unit_alternatives
(unit)¶ Provides alternative units to a given unit.
Usage example:
>>> if "mm" in preonpy.get_unit_alternatives("m"): >>> print("Things can be small.")
- Parameters
unit (
str
) – Unit for which the alternatives should be returned.- Return type
List
[str
]- Returns
All supported alternatives for the given unit. Includes the given unit itself.
The following table shows which units are compatible with each other and which unit is the SI base unit used in several places.
Quantity |
SI base unit |
Compatible units |
---|---|---|
acceleration |
m s^-2 |
|
angle |
rad |
|
area |
m^2 |
|
compressibility |
m^2 N^-1 |
|
concentration |
% |
|
damper rate |
N s m^-1 |
|
data |
B |
|
density |
kg m^-3 |
|
dynamic viscosity |
Pa s |
|
energy |
J |
|
font size |
pt |
|
force |
N |
|
force density |
N m^-3 |
|
frequency |
s^-1 |
|
heat flux |
W m^-2 |
|
heat transfer coefficient |
W m^-2 K^-1 |
|
length |
m |
|
mass |
kg |
|
mass flow rate |
kg s^-1 |
|
moment of inertia |
kg m^2 |
|
momentum |
kg m s^-1 |
|
power |
W |
|
power density |
W m^-3 |
|
precipitation rate |
mm min^-1 |
|
pressure |
Pa |
|
rotational velocity |
rad s^-1 |
|
specific heat capacity |
J kg^-1 K^-1 |
|
surface tension |
N m^-1 |
|
temperature |
K |
|
thermal conductivity |
W m^-1 K^-1 |
|
time |
s |
|
torque |
N m |
|
velocity |
m s^-1 |
|
volume |
m^3 |
|
volume flow rate |
m^3 s^-1 |
|
Statistics¶
-
class
Statistic
(id, obj)¶ -
WeightMode
¶ alias of
preonpy._preonpy.StatisticWeightMode
-
at
(time, unit=UnitSetting.DISPLAY_UNIT)¶ Returns the value of the statistic at the given time.
Usage example:
>>> num_particles = scene.statistic("Solver Particles") >>> print(num_particles.at("10ms").value)
- Parameters
time (
Union
[float
,str
,Frame
,Second
,Quantity
]) – The time at which the statistic is queried. Can be either a number representing seconds, a time string, aFrame
, aSecond
or aQuantity
representing time.unit (
UnitSetting
) – Specifies the requested units. The default is the unit that is also shown in the Plot Dialog (DISPLAY_UNIT
). Other options areINTERNAL_UNIT
andBASE_UNIT
.
- Return type
- Returns
The interpolated value of the statistic if the given time is inside the data range, i.e., if there are both earlier and later points for which statistic values exist. In case a statistic value exists only for one of the two time points (earlier or later), that value is returned.
- Raises
StatisticNotAvailable – If the statistic does not exist.
DataNotAvailable – If the statistic exists, but does not have any data.
-
avg
(start_time, end_time, unit=UnitSetting.DISPLAY_UNIT, weight=StatisticWeightMode.UNIFORM)¶ - Returns the average of the statistic values in the given time range. For statistics consisting of multiple
components (e.g.
Vec3
), the component-wise average is taken.
Usage example:
>>> avg_liters = volume_sensor.statistic("Volume").avg("500ms", "4s").value_as("L")
- Parameters
start_time (
Union
[float
,str
,Frame
,Second
,Quantity
]) – The start time for statistic averaging. Can be either a number representing seconds, a time string, aFrame
, aSecond
or aQuantity
representing time.end_time (
Union
[float
,str
,Frame
,Second
,Quantity
]) – The end time for statistic averaging. Can be either a number representing seconds, a time string, aFrame
, aSecond
or aQuantity
representing time.unit (
UnitSetting
) – Specifies the requested units. The default is the unit that is also shown in the Plot Dialog (DISPLAY_UNIT
). Other options areINTERNAL_UNIT
andBASE_UNIT
.weight (
StatisticWeightMode
) – Specifies how the samples are weighted in the average computation.
- Return type
- Returns
The value of the statistic at the given time.
- Raises
StatisticNotAvailable – If the statistic does not exist.
DataNotAvailable – If the statistic does not have any data in the requested time range.
-
property
base_unit
¶ SI base unit for this statistic.
- Raises
StatisticNotAvailable – If the statistic does not exist.
- Return type
str
-
property
display_unit
¶ Unit which is e.g. used in the Plot Dialog.
- Raises
StatisticNotAvailable – If the statistic does not exist.
- Return type
str
-
property
has_data
¶ Returns
True
if the statistic has any data point.- Raises
StatisticNotAvailable – If the statistic does not exist.
- Return type
bool
-
property
internal_unit
¶ Unit in which this statistic is stored internally. Note: This property is read-only.
- Raises
StatisticNotAvailable – If the statistic does not exist.
- Return type
str
-
max
(unit=UnitSetting.DISPLAY_UNIT)¶ - Returns the maximum value that this statistic has over time. For statistics consisting of multiple
components (e.g.
Vec3
), the component-wise maximum is taken.
Usage example:
>>> max_flow_rate_quantity = sensor_plane.statistic("Volume Flow Rate").max() >>> max_box_z_component = box.statistic("Position").max().value.z
- Parameters
unit (
UnitSetting
) – Specifies the requested units. The default is the unit that is also shown in the Plot Dialog (DISPLAY_UNIT
). Other options areINTERNAL_UNIT
andBASE_UNIT
.- Return type
- Returns
The maximum value over time of the statistic.
- Raises
StatisticNotAvailable – If the statistic does not exist.
DataNotAvailable – If the statistic does not have any data.
-
min
(unit=UnitSetting.DISPLAY_UNIT)¶ - Returns the minimum value that this statistic has over time. For statistics consisting of multiple
components (e.g.
Vec3
), the component-wise minimum is taken.
Usage example:
>>> num_particles = scene.statistic("Solver Particles") >>> print("There are at least " + str(num_particles.min().value) + " particles.")
- Parameters
unit (
UnitSetting
) – Specifies the requested units. The default is the unit that is also shown in the Plot Dialog (DISPLAY_UNIT
). Other options areINTERNAL_UNIT
andBASE_UNIT
.- Return type
- Returns
The minimum value over time of the statistic.
- Raises
StatisticNotAvailable – If the statistic does not exist.
DataNotAvailable – If the statistic does not have any data.
-
property
name
¶ Returns the full name of this statistic, which is composed of the reduction type abbreviation followed by the quantity name.
- Return type
str
-
property
quantity_name
¶ Returns the name of the quantity this statistic holds.
- Return type
str
-
property
reduction_type
¶ Returns the reduction type of this statistic.
- Return type
str
-
property
sequences
¶ Returns the sequences of this statistic.
- Return type
List
[StatisticSequence
]
-
property
value_type
¶ Returns the type the data of this statistic has.
- Return type
type
-
-
class
StatisticSequence
¶ -
property
buffer_name
¶ Returns the name of this statistic in the statistics buffer set. For compatibility reasons, this name may differ from the full name.
-
property
color
¶ The color of the plot line for this sequence.
-
property
full_name
¶ Returns the full name of the sequence, i.e., the statistic name with the sequence suffix appended.
-
property
suffix
¶ Returns the sequence suffix used for representing the sequence in the statistic.
-
property
-
class
StatisticWeightMode
¶ Members:
UNIFORM : In this mode, averaging a statistic will assign uniform weights to the data points. The average is the sum of all data divided by the number of data points.
TIME : In this mode, averaging a statistic will assign a weight to each data point that is proportional to the summed time differences to its neighboring data points. This is a typical way to time-average time series of physical quantities.
-
TIME
= StatisticWeightMode.TIME¶
-
UNIFORM
= StatisticWeightMode.UNIFORM¶
-
property
name
¶
-
property
value
¶
-
Licensing¶
-
checkout_license
(license_main, license_boost=None, license_model=None, license_model_boost=None)¶ Checks out the given licenses and checks in all currently used licenses.
- Parameters
license_main (
str
) – The main license to be checked out. It must be either aLicenseTypes.BASE
or aLicenseTypes.PREPOST
.license_boost (
Union
[str
,int
,None
]) – The boost license to be checked out. It must be either aLicenseTypes.MPI_UNLIMITED
,LicenseTypes.SIM_THREADS_MAX
, an integer specifying the number of simulation thread licenses,LicenseTypes.GPU
,LicenseTypes.GPU_NODE_UNLIMITED
orNone
.license_model (
Optional
[str
]) – The licensing model of the main license to be checked out. It must be either aLicenseModels.NODELOCKED
, aLicenseModels.FLOATING
, aLicenseModels.METERED
orNone
which means that floating or nodelocked can be checked out.license_model_boost (
Optional
[str
]) – The licensing model that should be used for the boost license. It must be either aLicenseModels.NODELOCKED
, aLicenseModels.FLOATING
, aLicenseModels.METERED
orNone
which means that floating license can be checked out. If omitted, the parameter from license_model is used.
- Raises
InvalidLicenseError – If an invalid combination of license types was requested (more details are stated in the error message) or if the requested license was not available for checkout.
Usage example:
>>> # Checkout a base license >>> preonpy.checkout_license(preonpy.LicenseTypes.BASE) >>> # Checkout a nodelocked prepost license with enough simulation thread licenses to use all cores. >>> preonpy.checkout_license(preonpy.LicenseTypes.PREPOST, >>> preonpy.LicenseTypes.SIM_THREADS_MAX, preonpy.LicenseModels.NODELOCKED)
-
get_license
()¶ Returns a tuple containing the currently used licenses.
- Return type
Tuple
[Optional
[str
],Union
[str
,int
,None
],Optional
[str
],Optional
[str
]]- Returns
A tuple (main, boost, model, model_boost): main could be either
LicenseTypes.BASE
orLicenseTypes.PREPOST
. boost is eitherNone
,LicenseTypes.MPI_UNLIMITED
, or the number of checked out licenses. model is eitherLicenseModels.FLOATING
,LicenseModels.NODELOCKED
orLicenseModels.METERED
and describes the license model of the main license. model_boost is eitherLicenseModels.FLOATING
orLicenseModels.METERED
and describes the license model of the boost license.
-
get_license_path
()¶ Returns the path on which the license file is expected.
- Return type
str
-
get_license_sim_threads
()¶ Returns the maximum number of simulation threads that the currently used license(s) permit. -1 Indicates no limit.
- Return type
int
-
class
LicenseTypes
¶ -
BASE
= 'BASE'¶
-
FULL
= 'FULL'¶ Exists to ensure backwards compatibility.
Deprecated since version 6.0: Please use
BASE
instead. Will be removed in PreonLab 7.0.
-
GPU
= 'GPU'¶
-
GPU_NODE_UNLIMITED
= 'GPU_NODE_UNLIMITED'¶
-
MPI_UNLIMITED
= 'MPI_UNLIMITED'¶
-
PREPOST
= 'PREPOST'¶
-
SIM_THREADS_MAX
= 'SIM_THREADS_MAX'¶
-
SOLVER
= 'SOLVER'¶
-
Conversion (Seconds, Frames, Time Strings)¶
-
to_seconds
(time_string=None, frame=None, scene=None, view=None, obj=None)¶ Converts time formatted string or frame to seconds.
- Parameters
time_string (
Optional
[str
]) – String using the time format.frame (
Optional
[int
]) – Frame number.scene (
Optional
[Scene
]) – The scene object. Only needed if converting from a frame number. Must not be used if obj is employed.obj (
Optional
[Object
]) – An object in the scene. Needed if you want to convert to the object´s frame number.view (
Optional
[bool
]) – Specifies, if the passed frame number relates to view or simulation frame rate. By default the view frame rate is used. Only needed if converting from a frame number. Must not be set if obj is used.
- Return type
float
- Returns
Seconds
Usage example:
>>> preonpy.to_seconds("1s") >>> preonpy.to_seconds(frame=10, scene=my_scene) >>> preonpy.to_seconds(frame=5, view=False, scene=my_scene) >>> preonpy.to_seconds(frame=4, obj=my_renderer)
-
to_frame
(time, scene=None, view=None, ceil=False, floor=False, obj=None)¶ Converts time formatted string or seconds to frames.
- Parameters
time (
Union
[str
,float
]) – Time as a number representing seconds or as a time string.scene (
Optional
[Scene
]) – The scene object. Must not be used if obj is employed.view (
Optional
[bool
]) – Specifies, if the returned frame number relates to view or simulation frame rate. By default, the view frame rate is used. Must not be set if obj is used.ceil (
bool
) – IfTrue
, the returned frame number is rounded to the next value.floor (
bool
) – IfTrue
, the returned frame number is rounded to the previous value.obj (
Optional
[Object
]) – An object in the scene. Needed if you want to convert to the object´s frame number.
- Return type
int
- Returns
Frame number
Usage example:
>>> preonpy.to_frame("1s", scene=my_scene) >>> preonpy.to_frame(1, scene=my_scene) >>> preonpy.to_frame("100ms", view=False, scene=my_scene) >>> preonpy.to_frame("1ms", ceil=True, scene=my_scene) >>> preonpy.to_frame("1s", obj=my_renderer)
-
to_time_string
(seconds=None, frame=None, scene=None, view=None, obj=None)¶ Convert frame or seconds to time formatted string. All parameters must be passed as keyword argument (keyword=value).
- Parameters
seconds (
Optional
[float
]) – Simulation time as a number representing seconds.frame (
Optional
[int
]) – Frame number.scene (
Optional
[Scene
]) – The scene object. Only needed if converting from a frame number. Must not be used if obj is employed.view (
Optional
[bool
]) – Specifies, if the passed frame number relates to view or simulation frame rate. By default the view frame rate is used. Only needed if converting from a frame number.obj (
Optional
[Object
]) – An object in the scene. Needed if you want to convert to the object´s frame number. Must not be set if obj is used.
- Returns
Usage example:
>>> preonpy.to_time_string(seconds=1.5) >>> preonpy.to_time_string(frame=10, scene=my_scene) >>> preonpy.to_time_string(frame=5, view=False, scene=my_scene) >>> preonpy.to_time_string(frame=4, obj=my_renderer)
Miscellaneous¶
-
preonpy.
current_scene
¶ Holds the current scene. Only meant for read access.
Deprecated since version 5.0: Use
get_scenes()
instead orpreonlab.current_scene
for PreonLab. Will be removed in PreonLab 7.0.
-
get_logfile_path
()¶ Returns the path of the log file.
- Return type
str
-
get_log_dir
()¶ Returns the path of the directory where log files should be written to.
- Return type
str
-
set_log_dir
(new_dir)¶ Sets the path of the directory where log files should be written to.
- Parameters
new_dir (
Union
[str
,PathLike
]) – Path of the directory.
-
get_version
()¶ Returns the version string of PreonLab.
- Return type
str
-
get_default_scene_dir
()¶ Returns the default scene directory used when creating a new scene.
- Return type
str
-
set_default_scene_dir
(default_scene_dir)¶ Sets the default scene directory used when creating a new scene.
- Parameters
default_scene_dir (
Union
[str
,PathLike
]) – Path of the directory.
-
set_features
(*, gpu=None, **kwargs)¶ Enable or disable features.
The “gpu” feature is disabled by default. If enabled in the beginning, when no license was checkout out directly with
checkout_license()
or indirectly e.g. by creating or loading a Scene, then the initial license checkout will try to check out a suitable license. If you later want to switch to a GPU license you have to first change the licensing to include a GPU license and then enable the gpu feature. Note that GPU license swtiching is only possible when all scenes are closed. Also changing the gpu feature has no effect on already opened scenes.Usage example:
>>> import preonpy >>> preonpy.set_features(gpu=True) >>> preonpy.Scene("some/path.prscene").simulate() # Will check out GPU license and simulate with GPU support.
Usage example in case initial licensing already happend:
>>> for scene in preonpy.get_scenes() >>> scene.close() # Closes all currently opened scenes! >>> preonpy.checkout_license(preonpy.LicenseTypes.FULL, preonpy.LicenseTypes.GPU) >>> preonpy.set_features(gpu=True) >>> preonpy.Scene("some/path.prscene").simulate() # Will simulate with GPU support.
Usage example to release a previously checked out GPU license:
>>> for scene in preonpy.get_scenes() >>> scene.close() # Closes all currently opened scenes! >>> preonpy.set_features(gpu=False) >>> preonpy.checkout_license(preonpy.LicenseTypes.FULL, None)
- Return type
None
-
plugin_args
(**kwargs)¶ Used to define plugin-specific arguments. Currently, this is only used for the gpuSelection argument of the GPU plugin.
Note: It is not possible to change the specified settings after the Preon Core has booted, e.g. after a scene has been loaded.
Usage example:
>>> import preonpy >>> preonpy.set_features(gpu=True) >>> preonpy.plugin_args(gpuSelection=1) >>> # or select to run on two GPUs. >>> preonpy.plugin_args(gpuSelection=[1,3]) >>> preonpy.Scene("some/path.prscene").simulate() # Will check out GPU license and simulate with GPU support.
- Return type
None
-
preonpy.
show_progress
¶ Configures if progress output is shown for some long running tasks like simulate or post_process. The default value is
True
.
-
preonpy.
show_progressbar
¶ Alias to
preonpy.show_progress
.Deprecated since version 5.2: Use
preonpy.show_progress
instead. Will be removed in PreonLab 7.0.
-
preonpy.
multiple_scenes
¶ This configures the default behavior of the close_existing parameter of
Scene
. By default it is set toTrue
, which means that no scene is closed automatically. Set this toFalse
in order close all existing scenes if you open or load a new one.
-
class
DataCategory
¶ -
LOG
= 'LOG'¶ Log files, like the action log file or the version file.
-
RESOURCE
= 'RESOURCE'¶ All input files required for a scene
-
RESULTS
= 'RESULTS'¶ Data that can be created during post-processing or in addition to simulation data during simulation runs. Doesn’t include simulation data.
-
SIMULATION_DATA
= 'SIMULATION_DATA'¶ Data that was written during a simulation. Doesn’t include post-processing data.
-
STATISTICS
= 'STATISTICS'¶ Statistic data, that was created during post-processing or simulation runs.
-
Functionality excluded from PreonLab Console¶
Some functionality, implemented in the preonpy
module, is NOT accessible via PreonLab Console. You can only use it in when using PreonPy as an installed preonpy package or when executing scripts via PreonCLI:
Opening existing or creating new scenes with
Scene()
Closing scenes with
close()
Saving scenes with
save()
Resetting simulation data with
reset_simulationdata()
Loading initial resources
load_initial_resources()
PreonLab-only functionality¶
The following items, defined in the preonlab
module, are only accessible via PreonLab Console. You can use them either in scripts that are executed in the Console or via the input field. Note that the preonpy
and preonlab
modules are already imported to be used in the input field, i.e., calling import preonpy
and import preonlab
is not necessary.
-
preonlab.
current_scene
¶ Holds the scene currently opened in PreonLab. Note: Reassigning another scene to this variable is prohibited.
Usage example:
import preonlab print(preonlab.current_scene.path)
-
preonlab.
selection
()¶ Returns all objects selected in the scene inspector as a list.
Usage example:
import preonlab for obj in preonlab.selection(): print(obj["name"])
Time Format¶
- Times can be specified using the format:
<value><unit>[:<value><unit>…]
<unit> is one of mo (months), d (days), h (hours), m (minutes), s (seconds), ms (milliseconds), and <value> is an integer value. Multiple value/unit pairs can be concatenated using “:”.
Examples:
50ms
6m:10d
Buffer access¶
With PreonPy it is possible to have direct access to particle data without copying data from one memory location to another, i.e., direct access to the data structures of PreonCore. In order to do this in a safe way, certain rules have to be followed.
The three Python types that handle the memory access are Buffer
, BufferSet
, BufferSetRef
and TriangleDataRef
. The first represents a chunk of memory. It is a (potentially multi-dimensional) array of a certain data type. It implements Python’s Buffer Protocol, which enables other libraries to access this data. A BufferSet
represents a set of Buffer
objects. This also holds for BufferSetRef
and TriangleDataRef
objects, with the difference that they give access to data still used by PreonCore. This imposes some rules described in the next section but has the benefit of a more efficient access.
Safe usage of BufferSetRef
¶
When working with BufferSetRef
or TriangleDataRef
objects, it is crucial to remove the references to both, buffers and their containers, before altering the scene by, e.g., adding or deleting objects, simulating, post processing, changing properties or loading frames. The following code snippet shows how this works:
import preonpy
s = preonpy.Scene("someScene.prscene")
solver = s.find_object("PreonSolver_1")
with solver.particle_buffers() as buffers:
position_buffer = buffers["Position"]
[...] # work with position_buffer
del position_buffer
del buffers
[...] # continue altering scene
In this example, position_buffer
is a Buffer
object containing the positions of the fluid. It was retrieved from buffers
which is the BufferSetRef
containing all the fluid data. The buffer set can be requested from, in this case, the solver via a so-called context manager. In the code, it is represented by the with
keyword and the indentation. solver.particle_buffers()
returns the context manager and the with ... as buffers:
part enters the context and provides the buffer set. Within this context, i.e., inside of the indented code block, the buffer set can be used. At the end and before leaving this context, the del
keyword has to be used to remove all references to both, buffer sets and buffer objects.
If not all references are deleted, a warning is printed on leaving the with
block. Please note that we reserve the right to raise an exception or to enforce an application exit in future versions.
Furthermore, as long as references to buffers or buffer sets exist, it is not safe to call functions that alter the scene. If such functionality is used nonetheless, a warning is printed.
Warning
Ignoring such a warning may cause application crashes or lead to other undesired behavior.
Note that BufferSet
objects can be used without all the mechanisms described above, since the referenced memory is not used by PreonCore anymore:
sensor_buffers = force_sensor.sensor_buffers(False)
pressure_01 = numpy.array(sensor_buffers["Pressure"], copy=False)
[...] # continue altering scene
Buffer usage, NumPy¶
As mentioned above, Buffer
objects implement Python’s Buffer Protocol. This means a reference to internal memory and some meta data about size, shape, data type and indexing scheme can be retrieved from it. Usually, this is not directly used by Python code, but by other Python libraries that provide a nice API. A popular library for such tasks is NumPy. The following code contains an example of how to use PreonPy together with NumPy.
import preonpy
import numpy
s = preonpy.Scene("someScene.prscene")
solver = s.find_object("PreonSolver_1")
with solver.particle_buffers() as buffers:
position_buffer = numpy.array(buffers["Position"], copy=False)
x = position_buffer[:, 0] # get the x coordinate of all particles
if numpy.all((-6 < x) & (x < -4)):
print("All particles lie between -6 and -4")
del position_buffer
del x
del buffers
Note that copy=False
is telling NumPy that the data should not be copied. Consequently, subsequent operations work on the memory exposed from PreonCore. The x
variable is a view of a slice of the position data containing the x coordinates. More complex indexing may result in a copy of the data. Consider the NumPy documentation on when a copy is returned rather than a view. The comparison of the x coordinates with the -6
/-4
is executed in a performance optimized way, but it will return a new array containing boolean values. There are Python libraries available able to avoid those intermediate copies (e.g. numexpr).
Please note that copies do not need to be removed using del
and can be used after exiting the with
block.
Note, that it is not possible to alter buffers of BufferSetRef
, TriangleDataRef
or ImageRef
objects.
Working with multiple buffer sets¶
It is possible to access multiple buffersets at the same time using the following syntax:
with solver.particle_buffers() as fluid_buffers, rigid.particle_buffers() as rigid_buffers:
[...] # use buffers of both buffer sets
del fluid_buffers, rigid_buffers
BufferSet, BufferSetRef, Texture3D, TriangleDataRef, ImageRef, and Buffer¶
-
class
BufferSet
¶ This is a container of one or more
Buffer
objects. The contained buffers can be of different type, but always contain the same number of elements.-
__getitem__
(self: preonpy._preonpy.BufferSet, buffer_name: str) → preonpy._preonpy.Buffer¶ Returns the requested buffer object.
Usage example:
>>> pos = buffers["Position"]
-
items
(self: object) → list¶ - Returns
A list of tuples containing the buffer name and buffer object.
-
keys
(self: preonpy._preonpy.BufferSet) → List[str]¶ - Returns
A list of buffer names that can be requested using the [] operator.
-
values
(self: object) → list¶ - Returns
A list of buffer objects in this buffer set.
-
-
class
BufferSetRef
¶ This is a container of one or more
Buffer
objects. The contained buffers can be of different type, but always contain the same number of elements. In contrast to aBufferSet
, objects of this class expose memory which is still used by PreonCore. Read more about safe usage.-
__getitem__
(self: preonpy._preonpy.BufferSetRef, buffer_name: str) → preonpy._preonpy.Buffer¶ Returns the requested buffer object.
Usage example:
>>> pos = buffers["Position"]
-
items
(self: preonpy._preonpy.BufferSetRef) → List[Tuple[str, preonpy._preonpy.Buffer]]¶ - Returns
A list of tuples containing the buffer name and buffer object.
-
keys
(self: preonpy._preonpy.BufferSetRef) → List[str]¶ - Returns
A list of buffer names that can be requested using the [] operator.
-
values
(self: preonpy._preonpy.BufferSetRef) → List[preonpy._preonpy.Buffer]¶ - Returns
A list of buffer objects in this buffer set.
-
-
class
Texture3D
¶ This object contains 3D texture information. The 3D texture is represented by voxel organized in an axis-aligned box. To know the size and location of voxel, this object provides
size()
,cell_size()
, andmin_pos()
methods. The voxel color data can be retrieved withdata()
. Note that the 3D texture may be unaligned with the rigid or not fully cover the rigid if the rigid is not sampled with particles (e.g,, when there is no solver in the scene).-
cell_size
(self: preonpy._preonpy.Texture3D) → float¶ The side length of a single cubic cell of the 3D texture.
-
data
(self: preonpy._preonpy.Texture3D) → preonpy._preonpy.Buffer¶ Returns a buffer object containing a two-dimensional array. The first dimension represents the texture voxel and the second dimension, which has always the size 3, contains the red, green, blue value of the respective voxel.
-
min_pos
(self: preonpy._preonpy.Texture3D) → preonpy._preonpy.Vec3¶ The minimal position of the axis-aligned bounding box of the 3D texture. This position is in the global coordinate system independent of the transformation of the rigid this texture belongs to.
-
size
(self: preonpy._preonpy.Texture3D) → List[int[3]]¶ Size of the 3D texture in x/y/z dimensions.
-
-
class
TriangleDataRef
¶ This is a container for geometry data. The data consists of lists of
positions()
and the correspondingnormals()
at those positions. Furthermore, there is a list oftriangles()
where each triangle contains indices to the other two lists. Note, that this class exposes memory which is still used by PreonCore. Read more about safe usage.-
normals
(self: preonpy._preonpy.TriangleDataRef) → preonpy._preonpy.Buffer¶ List of normal vectors that apply to the respective
positions()
.
-
positions
(self: preonpy._preonpy.TriangleDataRef) → preonpy._preonpy.Buffer¶ List of position vectors.
-
triangles
(self: preonpy._preonpy.TriangleDataRef) → preonpy._preonpy.Buffer¶ Returns a buffer object containing a two-dimensional array. The first dimension represents the triangles and the second dimension, which has always the size 3, describes the indices of the vertices a triangle is made of. These indices relate to
positions()
andnormals()
.
-
-
class
ImageRef
¶ This object contains image data. This includes the
width()
andheight()
of the image as well as the pixeldata()
. Note, that this class exposes memory which is still used by PreonCore. Read more about safe usage.-
data
(self: preonpy._preonpy.ImageRef) → preonpy._preonpy.Buffer¶ Returns a buffer object containing a two-dimensional array. The first dimension represents the image pixels and the second dimension, which has always the size 4, contains the red, green, blue and alpha value of the respective pixel.
-
height
(self: preonpy._preonpy.ImageRef) → int¶ Height of the image in number of pixel.
-
width
(self: preonpy._preonpy.ImageRef) → int¶ Width of the image in number of pixel.
-
-
class
Buffer
¶ Represents memory that contains a (potentially multi-dimensional) array of a certain data type. Read more about buffer usage.
Exceptions¶
-
class
PreonpyException
¶ Base class for all Exceptions preonpy raises.
-
class
ObjectInvalid
¶ Raised whenever an invalid object (or scene) was accessed.
-
class
PropertyError
¶ Base type for exceptions related to property access.
-
class
PropertyNotFound
¶ Raised if the property could not be found.
-
class
PropertyReadTypeError
(key)¶ Raised on property read access if the property type is not readable.
-
class
PropertyWriteTypeError
(key)¶ Raised on property write access if the property type is not writeable.
-
class
PropertyReadonlyError
(key)¶ Raised on property write access if the property is read-only.
-
class
PropertyWriteError
(key, item_type, value, prop_wrapper)¶ Raised if a property write failed, because of the given value was invalid.
-
class
KeyframeError
¶ Raised on errors related to keyframe access.
-
class
ConnectionError
¶ Raised on errors related to object connections.
-
class
StatisticNotAvailable
(name)¶ Raised if statistic is not available.
-
class
SceneLoadFailed
(scene_path)¶ Raised if scene load failed.
-
class
SceneSaveFailed
(scene_path)¶ Raised if scene save failed.
-
class
ObjectCreateError
(typename)¶ Raised if object could not be created.
-
class
ObjectDeleteError
(objname)¶ Raised if object could not be deleted.
-
class
NoCamerasConnected
¶ Raised if no cameras are connected.
-
class
InvalidFileFormat
¶ Raised if the given file format was not correct.
-
class
FileNotFoundError
¶ Raised if a file could not be found.
-
class
InvalidLicenseError
¶ Raised if an invalid license identifier was passed.
-
class
DirectoryDoesNotExist
(dirname)¶ Raised if the directory does not exist.
-
class
DirectoryIsNotEmpty
(dirname)¶ Raised if the directory is not empty.
-
class
DataNotAvailable
(name=None, frame_range=None)¶ Raised if the requested data is not available.
-
class
GroupError
¶ Raised if an invalid license identifier was passed.
-
class
SubsamplingError
¶ Raised for subsampling related errors.
-
class
PluginNotAvailable
¶ Raised if a plugin is requested, but is either not available or failed to initialize.
FAQ¶
How can I load the last simulated frame?¶
Loading the last simulation frame is not directly available in PreonPy, but can be achieved easily by using statistic
, max
, time-to-frame conversion
and preonpy.objects.Scene.load_frame()
. The following code shows the idea:
import preonpy
def load_last_simulated_frame(scene):
time_stat = scene.statistic("Time") # Read the last simulated time
if time_stat.has_data:
actual_time = time_stat.max().value_as("s")
else:
actual_time = 0 # Default to 0, if statistics are not available
actual_frame = preonpy.to_frame(actual_time, scene, view=False, floor=True) # convert time to last simulation frame
scene.load_frame(actual_frame) # load the frame
s = preonpy.Scene("/path/to/scene.prscene")
load_last_simulated_frame(s)