๐ Blender Python API Referenceยถ
Every public class and method listed here is reachable after from bl_ext.user_default.ppf_contact_solver.ops.api import solver.
See ๐ Blender Python API for a narrative walkthrough of the same surface.
Classes:
- class Solverยถ
Top-level entry point for the ZOZO Contact Solver.
Available as
solverwhen imported via:from bl_ext.user_default.ppf_contact_solver.ops.api import solverScene parameters are accessed via
param(aSceneParamproxy). Groups, pins, and invisible colliders are created via the methods below.Unrecognized attribute access falls through to
bpy.ops.zozo_contact_solver.<name>(), so every operator registered under that namespace (including every MCP handler) can be called as a method onsolver.Example:
solver.param.gravity = (0, 0, -9.8) group = solver.create_group("Sphere", type="SOLID") group.add("Sphere") group.param.solid_density = 1000
- create_group(name: str = '', type: str = 'SOLID') Groupยถ
Create a new dynamics group.
- Parameters:
name โ Display name for the group. Empty string leaves the auto-generated name in place.
type โ One of
"SOLID","SHELL","ROD","STATIC".
- Returns:
A
Groupproxy for the newly created group.
Example:
group = solver.create_group("Shirt", type="SHELL") group.add("Shirt")
- get_group(group_uuid: str) Groupยถ
Look up a group by UUID.
- Parameters:
group_uuid โ UUID string of the group.
- Returns:
A
Groupproxy.- Raises:
KeyError โ If the group does not exist.
Example:
uuid = solver.get_groups()[0].uuid group = solver.get_group(uuid)
- get_groups() list[Group]ยถ
Return
Groupproxies for every active group.Example:
for group in solver.get_groups(): print(group.uuid)
- delete_all_groups() Solverยถ
Delete every active group and the pins they own.
- Returns:
selffor chaining.
Example:
solver.delete_all_groups()
- clear() Solverยถ
Reset the entire solver state to defaults.
Deletes every active group, resets scene parameters to their property defaults, clears merge pairs, invisible colliders, dynamic parameters, previously fetched frames, saved pin keyframes, and any residual
MESH_CACHEmodifiers on mesh objects. Call this at the top of any script that needs a clean slate.- Returns:
selffor chaining.
Example:
solver.clear() solver.param.gravity = (0, 0, -9.8)
- create_curve(name: str, *, bevel_depth: float = 0.0, bevel_resolution: int = 2, resolution_u: int = 4, dimensions: str = '3D', clear_existing: bool = True) Curveยถ
Start building a multi-spline Bezier curve object.
Returns a
Curvebuilder. UseCurve.add_spline()for each spline, optionallyCurve.set_material()to color them, thenCurve.finalize()to link the resulting object into the scene.- Parameters:
name โ Object name. When
clear_existingis true (the default) any existing object with this name is removed first so re-running the script starts from a clean slate.bevel_depth โ Tube radius for visualization (Blenderโs
Curve.bevel_depth).0leaves the curve as a wireframe.bevel_resolution โ Tube cross-section subdivisions (
Curve.bevel_resolution).resolution_u โ Spline interpolation resolution (
Curve.resolution_u).dimensions โ
"3D"(default) or"2D".clear_existing โ Set
Falseto skip the same-name cleanup.
- Returns:
A
Curvebuilder.
Example:
curve = solver.create_curve("Strands", bevel_depth=3e-3) for points, closed in strands: curve.add_spline(points, closed=closed) obj = curve.finalize()
- snap(object_a: str, object_b: str) Solverยถ
Translate object_a so its nearest vertex lands on object_b.
- Parameters:
object_a โ Name of the mesh that moves.
object_b โ Name of the mesh that stays in place.
- Returns:
selffor chaining.- Raises:
ValueError โ If either object is missing, not a mesh, or validation in the underlying mutation service fails.
Example:
solver.snap("Shirt", "Mannequin")
- add_merge_pair(object_a: str, object_b: str) Solverยถ
Mark two objects to be merged at their shared contact.
- Parameters:
object_a โ Name of the first mesh.
object_b โ Name of the second mesh.
- Returns:
selffor chaining.- Raises:
ValueError โ If either object is missing, not a mesh, or the pair is invalid.
Example:
solver.add_merge_pair("SleeveLeft", "BodyLeft")
- remove_merge_pair(object_a: str, object_b: str) Solverยถ
Remove a previously added merge pair.
The ordering of object_a and object_b does not matter; the pair is matched by UUID in either direction.
- Parameters:
object_a โ Name of the first mesh.
object_b โ Name of the second mesh.
- Returns:
selffor chaining.- Raises:
ValueError โ If validation fails for the given pair.
Example:
solver.remove_merge_pair("SleeveLeft", "BodyLeft")
- get_merge_pairs() list[tuple[str, str]]ยถ
Return every merge pair as a list of
(object_a, object_b)tuples.Example:
for a, b in solver.get_merge_pairs(): print(f"{a} <-> {b}")
- clear_merge_pairs() Solverยถ
Remove every merge pair.
- Returns:
selffor chaining.
Example:
solver.clear_merge_pairs()
- add_wall(position, normal) Wallยถ
Add an invisible infinite-plane wall collider.
- Parameters:
position โ
(x, y, z)world-space point on the plane.normal โ
(nx, ny, nz)outward-facing plane normal. Need not be unit-length.
- Returns:
A chainable
Wallbuilder bound to the newly added collider.- Raises:
ValueError โ If the position or normal fails vec3 validation.
Example:
solver.add_wall(position=(0, 0, 0), normal=(0, 0, 1))
- add_sphere(position, radius) Sphereยถ
Add an invisible sphere collider.
- Parameters:
position โ
(x, y, z)world-space center.radius โ Sphere radius.
- Returns:
A chainable
Spherebuilder bound to the newly added collider.- Raises:
ValueError โ If the position or radius fails validation.
Example:
solver.add_sphere(position=(0, 0, 1.0), radius=0.25)
- get_invisible_colliders() listยถ
Return every invisible collider as a list of
(type, name)tuples.type is one of
"WALL"or"SPHERE".Example:
for kind, name in solver.get_invisible_colliders(): print(kind, name)
- class SceneParamยถ
Attribute proxy for scene and SSH/connection parameters.
Accessed as
Solver.param. Supports both get and set via attribute access. Writes go through thezozo_contact_solver.setoperator (with auto type coercion), reads fall through to the sceneโs addon state or SSH state.gravityis an alias forgravity_3d.Example:
solver.param.step_size = 0.004 print(solver.param.gravity)
Dynamic (keyframed) parameters are accessed via
dyn():solver.param.dyn("gravity").time(60).hold().time(61).change((0, 0, 9.8))- dyn(key: str) DynParamยถ
Select a parameter for dynamic keyframing.
- Parameters:
key โ One of
"gravity","wind","air_density","air_friction","vertex_air_damp".- Returns:
A chainable
DynParambuilder.- Raises:
ValueError โ If key is not one of the valid dynamic keys.
Example:
solver.param.dyn("gravity").time(60).hold().time(61).change((0, 0, 9.8))
- class DynParamยถ
Fluent builder for dynamic scene parameter keyframes.
Mirrors the frontend
session.param.dyn()API but uses frames instead of seconds. Obtained fromSceneParam.dyn().Valid parameter keys:
"gravity","wind","air_density","air_friction","vertex_air_damp".Frames must be strictly increasing within a chain. Every mutating method returns
selfso operations chain.Example:
solver.param.dyn("gravity").time(60).hold().time(61).change((0, 0, 9.8)) solver.param.dyn("wind").time(30).hold().time(31).change((0, 1, 0), strength=5.0)
- time(frame: int) DynParamยถ
Advance the frame cursor.
- Parameters:
frame โ Target frame (must be strictly greater than the current cursor position).
- Returns:
selffor chaining.- Raises:
ValueError โ If frame is not strictly increasing.
Example:
solver.param.dyn("gravity").time(60).hold().time(61).change((0, 0, 9.8))
- hold() DynParamยถ
Hold the previous value at the current cursor frame (step function).
- Returns:
selffor chaining.
Example:
solver.param.dyn("gravity").time(60).hold().time(61).change((0, 0, 9.8))
- change(value, strength=None) DynParamยถ
Set a new value at the current cursor frame.
- Parameters:
value โ For
"gravity", an(x, y, z)tuple. For"wind", an(x, y, z)direction tuple. For scalar keys ("air_density","air_friction","vertex_air_damp"), afloat.strength โ Wind strength (only for
"wind").
- Returns:
selffor chaining.
Example:
solver.param.dyn("wind").time(30).hold().time(31).change((0, 1, 0), strength=5.0)
- class Groupยถ
A dynamics group proxy.
Created via
Solver.create_group(). Material parameters are accessed viaparam. Every mutating method returnsselfso operations chain.Example:
group = solver.create_group("Shirt", type="SHELL") group.add("Shirt").set_overlay_color(0.9, 0.2, 0.1) group.param.friction = 0.5 group.param.shell_density = 1.0
- property uuidยถ
- Type:
str
The UUID of this group. Stable across renames.
Example:
group = solver.create_group("Shirt", type="SHELL") same_group = solver.get_group(group.uuid)
- property nameยถ
- Type:
str
Display name of this group.
Example:
for g in solver.get_groups(): if g.name == "WovenStrands": g.delete()
- property paramยถ
- Type:
Material and simulation parameter proxy. See
GroupParam.Example:
group.param.friction = 0.5 group.param.shell_density = 1.0
- set_overlay_color(r: float, g: float, b: float, a: float = 1.0) Groupยถ
Set the viewport overlay color for this group and enable it.
- Parameters:
r โ Red channel in
[0, 1].g โ Green channel in
[0, 1].b โ Blue channel in
[0, 1].a โ Alpha in
[0, 1](default1.0).
- Returns:
selffor chaining.
Example:
group.set_overlay_color(0.9, 0.2, 0.1) # red overlay
- add(*object_names: str) Groupยถ
Add mesh objects to this group by name.
- Parameters:
*object_names โ One or more Blender object names.
- Returns:
selffor chaining.
Example:
group.add("Shirt", "Skirt", "Sleeve")
- remove(object_name: str) Groupยถ
Remove an object from this group.
- Parameters:
object_name โ Name of the object to remove.
- Returns:
selffor chaining.
Example:
group.remove("Sleeve")
- set_velocity(object_name: str, direction: tuple[float, float, float], speed: float, frame: int = 1) Groupยถ
Keyframe a velocity on an object assigned to this group.
Appends an entry to the assigned objectโs
velocity_keyframescollection. Call once withframe=1for an initial-velocity launch; call again with higherframevalues to build a velocity schedule.- Parameters:
object_name โ Name of an object already added to this group via
add().direction โ
(dx, dy, dz)velocity direction; normalized by the solver before use.speed โ Velocity magnitude in m/s.
frame โ Frame at which the keyframe takes effect.
1(the default) is the initial-velocity slot.
- Returns:
selffor chaining.- Raises:
ValueError โ If the object is not assigned to this group, or a keyframe already exists at the requested frame.
Example:
ball = solver.create_group("Ball", type="SOLID") ball.add("Sphere") ball.set_velocity("Sphere", direction=(1, 0, 0), speed=2.3)
- create_pin(object_name: str, vertex_group_name: str, indices: list[int] | None = None) Pinยถ
Pin a vertex group (mesh) or set of control points (curve).
- Parameters:
object_name โ Name of the mesh or curve object.
vertex_group_name โ For meshes, the name of an existing vertex group on the object. For curves, the logical name used for the curveโs
_pin_<vertex_group_name>custom property holding the pinned control-point indices.indices โ Control-point indices for curves only. When given, the curveโs
_pin_<vertex_group_name>property is written before the pin is registered, so the same call both defines and binds the pin. Must beNonefor meshes (meshes use existing vertex groups).
- Returns:
A
Pinproxy for the newly created pin.- Raises:
ValueError โ If the object is missing, not a mesh or curve, the vertex group does not exist on a mesh, the
_pin_<name>property is missing on a curve and noindiceswere supplied, orindicesis passed for a mesh.
Example:
# Mesh: vertex group must already exist. pin = group.create_pin("Cloth", "collar") pin.move_by(delta=(0, 0, 0.2), frame_start=1, frame_end=60) # Curve: pass control-point indices to define and bind in # one call. rod_pin = rod_group.create_pin( "WovenCylinder", "left", indices=[0, 7, 14, 21], )
- get_pins() list[Pin]ยถ
Return all pins in this group as
Pinproxies.Example:
for pin in group.get_pins(): print(pin.object_name, pin.vertex_group_name)
- delete() Noneยถ
Delete this group and every pin it owns.
Example:
group.delete()
- class GroupParamยถ
Proxy for material and simulation parameters on a group.
Accessed via
Group.param. Attribute access is whitelisted: reading or writing a name outside the whitelist raisesAttributeError.Whitelisted attributes:
Solver model:
solid_model,shell_modelDensity:
solid_density,shell_density,rod_densityYoungโs modulus:
solid_young_modulus,shell_young_modulus,rod_young_modulusPoisson ratio:
solid_poisson_ratio,shell_poisson_ratioContact:
friction,use_group_bounding_box_diagonal,contact_gap,contact_gap_rat,contact_offset,contact_offset_rat. Whenuse_group_bounding_box_diagonalisTrue(the default), the solver consumescontact_gap_rat* bbox-diagonal andcontact_offset_rat* bbox-diagonal; set it toFalseto consume the absolutecontact_gap/contact_offsetvalues directly.Strain limit:
enable_strain_limit,strain_limitInflation:
enable_inflate,inflate_pressurePlasticity:
enable_plasticity,plasticity,plasticity_thresholdBend plasticity:
enable_bend_plasticity,bend_plasticity,bend_plasticity_threshold,bend_rest_angle_sourceShell-specific:
bend,shrink,shrink_x,shrink_y,stitch_stiffness
Example:
# Solver model group.param.solid_model = "ARAP" group.param.shell_model = "ARAP" # Density (kg/m^3 for solid/shell, kg/m for rod) group.param.solid_density = 1000.0 group.param.shell_density = 0.3 group.param.rod_density = 0.05 # Young's modulus (Pa) and Poisson ratio group.param.solid_young_modulus = 1.0e6 group.param.shell_young_modulus = 5.0e5 group.param.rod_young_modulus = 1.0e7 group.param.solid_poisson_ratio = 0.45 group.param.shell_poisson_ratio = 0.30 # Contact (absolute mode) group.param.use_group_bounding_box_diagonal = False group.param.friction = 0.5 group.param.contact_gap = 0.001 group.param.contact_offset = 0.002 # Contact (ratio mode -- defaults) group.param.use_group_bounding_box_diagonal = True group.param.contact_gap_rat = 0.1 group.param.contact_offset_rat = 0.2 # Strain limit group.param.enable_strain_limit = True group.param.strain_limit = 1.05 # Inflation group.param.enable_inflate = True group.param.inflate_pressure = 100.0 # Plasticity (shells and tets only) group.param.enable_plasticity = True group.param.plasticity = 0.3 group.param.plasticity_threshold = 0.2 group.param.enable_bend_plasticity = True group.param.bend_plasticity = 0.5 group.param.bend_plasticity_threshold = 0.1 group.param.bend_rest_angle_source = "REST" # Shell-specific group.param.bend = 1.0e-4 group.param.shrink = 0.98 group.param.shrink_x = 0.99 group.param.shrink_y = 0.97 group.param.stitch_stiffness = 5.0e4
- class Pinยถ
A pinned vertex group bound to a dynamics group.
Created via
Group.create_pin(object_name, vertex_group_name). Every mutating method returnsselfso operations chain.Example:
pin = group.create_pin("Cloth", "hem") pin.move_by(delta=(0, 0, 1.0), frame_start=1, frame_end=60) pin.unpin(frame=120)
- property object_nameยถ
- Type:
str
Name of the mesh object this pin belongs to.
Example:
pin = group.create_pin("Cloth", "hem") print(pin.object_name) # "Cloth"
- property vertex_group_nameยถ
- Type:
str
Name of the vertex group this pin targets.
Example:
pin = group.create_pin("Cloth", "hem") print(pin.vertex_group_name) # "hem"
- pull(strength: float = 1.0) Pinยถ
Use pull force instead of hard pin constraint.
Pull allows the vertices to move but applies a restoring force toward their target position.
- Parameters:
strength โ Pull force strength (default 1.0).
- Returns:
selffor chaining.
Example:
group.create_pin("Cloth", "shoulder").pull(strength=2.5)
- spin(axis: tuple[float, float, float] = (1, 0, 0), angular_velocity: float = 360.0, flip: bool = False, center: tuple[float, float, float] | None = None, center_mode: str | None = None, center_direction: tuple[float, float, float] | None = None, center_vertex: int | None = None, frame_start: int = 1, frame_end: int = 60, transition: str = 'LINEAR') Pinยถ
Add a spin operation to this pin.
- Parameters:
axis โ Rotation axis vector.
angular_velocity โ Degrees per second.
flip โ Reverse spin direction.
center โ Center of rotation (for ABSOLUTE mode).
center_mode โ
"CENTROID","ABSOLUTE","MAX_TOWARDS", or"VERTEX". IfNone, inferred from other args (Nonecenter โ"CENTROID").center_direction โ Direction for
MAX_TOWARDSmode.center_vertex โ Vertex index for
VERTEXmode.frame_start โ Start frame.
frame_end โ End frame.
transition โ
"LINEAR"or"SMOOTH".
- Returns:
selffor chaining.
Example:
# Spin about the centroid at 180 deg/s for frames 1-60 pin.spin(axis=(0, 0, 1), angular_velocity=180.0) # Spin about an absolute world-space pivot pin.spin(axis=(0, 1, 0), center=(0, 0, 1), frame_start=30, frame_end=90)
- scale(factor: float = 1.0, center: tuple[float, float, float] | None = None, center_mode: str | None = None, center_direction: tuple[float, float, float] | None = None, center_vertex: int | None = None, frame_start: int = 1, frame_end: int = 60, transition: str = 'LINEAR') Pinยถ
Add a scale operation to this pin.
- Parameters:
factor โ Scale factor.
center โ Center point (for
ABSOLUTEmode).center_mode โ
"CENTROID","ABSOLUTE","MAX_TOWARDS", or"VERTEX". IfNone, inferred from other args (Nonecenter โ"CENTROID").center_direction โ Direction for
MAX_TOWARDSmode.center_vertex โ Vertex index for
VERTEXmode.frame_start โ Start frame.
frame_end โ End frame.
transition โ
"LINEAR"or"SMOOTH".
- Returns:
selffor chaining.
Example:
# Shrink to 50% over frames 1-60 about the centroid pin.scale(factor=0.5, transition="SMOOTH")
- torque(magnitude: float = 1.0, axis_component: str = 'PC3', flip: bool = False, frame_start: int = 1, frame_end: int = 60) Pinยถ
Add a torque operation to this pin.
Applies a rotational force around a PCA-computed axis.
- Parameters:
magnitude โ Torque in Nยทm.
axis_component โ
"PC1"(major),"PC2"(middle), or"PC3"(minor).flip โ Reverse torque direction.
frame_start โ Start frame.
frame_end โ End frame.
- Returns:
selffor chaining.
Example:
pin.torque(magnitude=2.0, axis_component="PC1", frame_start=1, frame_end=30)
- move_by(delta: tuple[float, float, float] = (0, 0, 0), frame_start: int = 1, frame_end: int = 60, transition: str = 'LINEAR') Pinยถ
Ramp a translation of the pinned vertices over a frame range.
- Parameters:
delta โ
(dx, dy, dz)offset.frame_start โ Start frame.
frame_end โ End frame.
transition โ
"LINEAR"or"SMOOTH".
- Returns:
selffor chaining.
Example:
# Lift 1.0m along +Z between frames 10 and 90 pin.move_by(delta=(0, 0, 1.0), frame_start=10, frame_end=90, transition="SMOOTH")
- unpin(frame: int) Pinยถ
Mark this pin to be released at the given frame.
Sets the duration on the underlying pin item so the encoder knows when to stop enforcing the pin constraint.
- Parameters:
frame โ Frame number at which the pin is released.
- Returns:
selffor chaining.
Example:
pin.move_by(delta=(0, 0, 1.0), frame_start=1, frame_end=60) pin.unpin(frame=120)
- delete() Noneยถ
Remove this pin from its group.
- Raises:
ValueError โ If the owning group or pin item can no longer be found (for example, after
solver.clear()).
Example:
pin = group.create_pin("Cloth", "hem") pin.delete() # remove the pin entry from the group
- class Wallยถ
Chainable builder for invisible wall colliders.
Returned by
Solver.add_wall(). Keyframe frames must be strictly increasing. Every mutating method returnsself.Example:
solver.add_wall((0, 0, 0), (0, 0, 1)).param.friction = 0.5 (solver.add_wall((0, 0, 0), (0, 1, 0)) .time(60).hold().time(61).move_to((0, 1, 0)))
- property paramยถ
- Type:
Collider parameter proxy. See
ColliderParam.Example:
wall = solver.add_wall((0, 0, 0), (0, 0, 1)) wall.param.friction = 0.5
- time(frame: int) Wallยถ
Advance the keyframe cursor.
- Parameters:
frame โ Target frame (must be strictly greater than the current cursor position).
- Returns:
selffor chaining.- Raises:
ValueError โ If frame is not strictly increasing.
Example:
(solver.add_wall((0, 0, 0), (0, 0, 1)) .time(60).move_to((0, 0, 0.5)))
- hold() Wallยถ
Hold the previous position at the current cursor frame.
- Returns:
selffor chaining.
Example:
(solver.add_wall((0, 0, 0), (0, 0, 1)) .time(60).hold().time(90).move_to((0, 0, 0.5)))
- move_to(position) Wallยถ
Keyframe a new absolute position at the current cursor frame.
- Parameters:
position โ
(x, y, z)world-space position.- Returns:
selffor chaining.
Example:
(solver.add_wall((0, 0, 0), (0, 0, 1)) .time(60).move_to((0, 0, 1.0)))
- move_by(delta) Wallยถ
Keyframe a position offset from the previous keyframe.
- Parameters:
delta โ
(dx, dy, dz)offset added to the previous keyframed position.- Returns:
selffor chaining.
Example:
(solver.add_wall((0, 0, 0), (0, 0, 1)) .time(60).move_by((0, 0, 0.25)))
- delete() Noneยถ
Remove this wall collider from the scene.
Example:
wall = solver.add_wall((0, 0, 0), (0, 0, 1)) wall.delete()
- class Sphereยถ
Chainable builder for invisible sphere colliders.
Returned by
Solver.add_sphere(). Keyframe frames must be strictly increasing. Every mutating method returnsself.Example:
solver.add_sphere((0, 0, 0), 0.98).invert().hemisphere() (solver.add_sphere((0, 0, 0), 1.0) .time(60).hold().time(61).radius(0.5))
- property paramยถ
- Type:
Collider parameter proxy. See
ColliderParam.Example:
sphere = solver.add_sphere((0, 0, 0), 1.0) sphere.param.friction = 0.3
- invert() Sphereยถ
Flip the sphere inside-out so contact is on the inside surface.
- Returns:
selffor chaining.
Example:
solver.add_sphere((0, 0, 0), 1.0).invert()
- hemisphere() Sphereยถ
Treat this collider as a hemisphere rather than a full sphere.
- Returns:
selffor chaining.
Example:
solver.add_sphere((0, 0, 0), 1.0).hemisphere()
- time(frame: int) Sphereยถ
Advance the keyframe cursor.
- Parameters:
frame โ Target frame (must be strictly greater than the current cursor position).
- Returns:
selffor chaining.- Raises:
ValueError โ If frame is not strictly increasing.
Example:
(solver.add_sphere((0, 0, 0), 1.0) .time(60).move_to((0, 0, 1.0)))
- hold() Sphereยถ
Hold the previous position and radius at the current cursor frame.
- Returns:
selffor chaining.
Example:
(solver.add_sphere((0, 0, 0), 1.0) .time(60).hold().time(90).radius(0.5))
- move_to(position) Sphereยถ
Keyframe a new absolute position at the current cursor frame.
- Parameters:
position โ
(x, y, z)world-space position.- Returns:
selffor chaining.
Example:
(solver.add_sphere((0, 0, 0), 1.0) .time(60).move_to((0, 0, 2.0)))
- radius(r) Sphereยถ
Keyframe a new radius at the current cursor frame.
- Parameters:
r โ New radius.
- Returns:
selffor chaining.
Example:
(solver.add_sphere((0, 0, 0), 1.0) .time(60).radius(0.25)) # shrink over 60 frames
- transform_to(position, radius) Sphereยถ
Keyframe both position and radius together.
- Parameters:
position โ
(x, y, z)world-space position.radius โ New radius.
- Returns:
selffor chaining.
Example:
(solver.add_sphere((0, 0, 0), 1.0) .time(60).transform_to((0, 0, 1.0), 0.5))
- delete() Noneยถ
Remove this sphere collider from the scene.
Example:
sphere = solver.add_sphere((0, 0, 0), 1.0) sphere.delete()
- class ColliderParamยถ
Attribute proxy for invisible-collider parameters.
Accessed via
Wall.paramorSphere.param. Attribute access is whitelisted: reading or writing a name outside the whitelist raisesAttributeError.Whitelisted attributes:
friction: contact friction coefficientcontact_gap: contact gap thicknessthickness: wall/sphere shell thicknessenable_active_duration:Trueto limit collider lifetimeactive_duration: number of frames the collider is active whenenable_active_durationis set
Example:
wall = solver.add_wall((0, 0, 0), (0, 0, 1)) wall.param.friction = 0.5 wall.param.contact_gap = 0.002 wall.param.thickness = 0.01 wall.param.enable_active_duration = True wall.param.active_duration = 60 # active for frames 1-60 sphere = solver.add_sphere((0, 0, 1), 0.5) sphere.param.friction = 0.3
- class Curveยถ
Builder for a multi-spline Bezier curve object.
Created via
Solver.create_curve(). Eachadd_spline()appends one Bezier spline to the underlying curve datablock;finalize()links the resulting object into the active scene and returns it.Pin definition is not part of this builder. Pass the control-point indices to
Group.create_pin()instead, which writes the_pin_<name>custom property and registers the pin in one call.Example:
curve = solver.create_curve("WovenCylinder", bevel_depth=3e-3) for points, closed in strands: curve.add_spline(points, closed=closed) obj = curve.finalize() rod = solver.create_group("Strands", type="ROD") rod.add(obj.name) rod.create_pin(obj.name, "left", indices=left_indices)
- property nameยถ
- Type:
str
Object name this builder will create on
finalize().
- add_spline(points, *, closed: bool = False) intยถ
Append a Bezier spline with AUTO handles.
- Parameters:
points โ Iterable of
(x, y, z)control-point coordinates (a NumPy array of shape(n, 3)works).closed โ Set
Trueto make the spline cyclic.
- Returns:
Zero-based index of the new spline within this curve. Use it with
set_material().- Raises:
ValueError โ If
pointshas fewer than two coordinates.
- set_material(spline_index: int, material: 'bpy.types.Material') Curveยถ
Bind a material to a spline by index.
The material is appended to the curveโs slots if it isnโt already present. Pre-existing slots are reused so repeated calls with the same material donโt grow the slot list.
- Parameters:
spline_index โ Index returned by
add_spline().material โ An existing
bpy.types.Material. Create it withbpy.data.materials.new(...)before calling.
- Returns:
selffor chaining.- Raises:
IndexError โ If
spline_indexis out of range.
- finalize() 'bpy.types.Object'ยถ
Create the
bpy.types.Object, link it to the scene, and return it.- Raises:
RuntimeError โ If called more than once on the same builder.