I am using Blender 2.82a. My code seems to be working but creates "Dependency Cycle" messages from the command line, so I hope to understand why they are happening and if they are a cause of concern.
My particular use case is dropping a ball into a bag, where both the ball and bag (implemented as a half-sphere) have the cloth and collision modifiers, based on one of my answers here, but the use case is less important to me than understanding what causes dependency cycles. Here's what Blender looks like after running my Minimal Working Example:
Here is the Minimal Working Example script I am running:
import bpy
def clear_scene():
"""Clear existing objects in scene."""
for block in bpy.data.meshes:
if block.users == 0:
bpy.data.meshes.remove(block)
bpy.ops.object.mode_set(mode='OBJECT')
bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.delete()
def make_plane():
"""Underlying plane. Use collision to support the fabrics."""
bpy.ops.mesh.primitive_plane_add(location=(0, 0, 0))
bpy.ops.transform.resize(value=(6.0, 6.0, 6.0))
bpy.ops.object.modifier_add(type='COLLISION')
def make_object():
"""Make an object that goes inside the bag.
We may only need the cloth modifier (collision might not be needed). Make
sure the pressure is high to avoid the cloth 'ball' from collapsing.
"""
bpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, location=(0, 0, 2))
bpy.ops.object.modifier_add(type='CLOTH')
bpy.ops.object.modifier_add(type='COLLISION')
bpy.context.object.modifiers["Cloth"].settings.quality = 10
bpy.context.object.modifiers["Cloth"].collision_settings.collision_quality = 5
bpy.context.object.modifiers["Cloth"].settings.use_pressure = True
bpy.context.object.modifiers["Cloth"].settings.uniform_pressure_force = 10
def make_bag(radius=0.8, x=0.0, y=0.0, z=2.0, z_thresh=0.0):
"""We still use the cloth modifier, but the actual mesh is a UV sphere.
Make the mesh at height z=2.0, then for any vertices with z values are
*above* z_thresh, we delete. NOTE: it's actually local, so getting z
coordinates of the sphere will still be 'centered' at 0. Also, adding
collision modifier so that it can act as a 'bag' and support items.
"""
bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, location=(x, y, z))
# Delete vertices that are ABOVE z_thresh.
bpy.ops.object.mode_set(mode="EDIT") # Activating Edit mode
bpy.ops.mesh.select_all(action="DESELECT") # Deselecting all
bpy.ops.object.mode_set(mode="OBJECT") # Going back to Object mode
vert = bpy.context.object.data.vertices
for v in vert:
if v.co[2] >= z_thresh:
v.select = True
bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.mesh.delete(type='VERT')
bpy.ops.object.mode_set(mode='OBJECT')
# Add some cloth-related modifiers.
bpy.ops.object.modifier_add(type='CLOTH')
bpy.ops.object.modifier_add(type='COLLISION')
bpy.context.object.modifiers["Cloth"].settings.quality = 10
bpy.context.object.modifiers["Cloth"].collision_settings.collision_quality = 5
bpy.context.object.modifiers["Cloth"].collision_settings.use_self_collision = True
if __name__ == '__main__':
clear_scene()
make_plane()
# BOTH of the following lines must be un-commented to create dependency cycles.
make_object()
make_bag(radius=0.8, x=0.0, z=0.9, z_thresh=0.40)
If this is in a file called test-dependency.py
then running blender -P test-dependency.py
will produce the following:
$ blender -P test-dependency.py
Read prefs: /Users/anon/Library/Application Support/Blender/2.82/config/userpref.blend
found bundled python: /Applications/Blender.app/Contents/Resources/2.82/python
Warning: property 'release_confirm' not found in keymap item 'OperatorProperties'
Info: Deleted 3 object(s)
Dependency cycle detected:
OBSphere.001/Geometry Component/GEOMETRY_EVAL() depends on
OBSphere/Geometry Component/GEOMETRY_EVAL() via 'Cloth Collision'
OBSphere.001/Geometry Component/GEOMETRY_EVAL() via 'Cloth Collision'
Dependency cycle detected:
OBSphere.001/PointCache Component/POINT_CACHE_RESET() depends on
OBSphere/Geometry Component/GEOMETRY_EVAL() via 'Point Cache'
OBSphere.001/Geometry Component/GEOMETRY_EVAL() via 'Cloth Collision'
OBSphere.001/PointCache Component/POINT_CACHE_RESET() via 'Point Cache -> Geometry'
Detected 2 dependency cycles
Both of the objects must be created for the dependency cycle to be created. Creating just the ball, or just the "sack", will not result in dependency cycles, interestingly. I am not sure why.
I am curious why these messages appear and if they are harmful. I'm having difficulty figuring this out based on various references. These are what Google shows me when I search for dependency cycles in Blender:
- These questions: (question one, question two, question three) deal with dependency cycles with armatures. I am not using any armatures here and am not sure how to use insights from the answers there.
- This question might be more relevant but doesn't have much information (and no answer).
- This blog post looks like it might be useful for a high-level overview on dependencies, but is from 2014 (might be outdated) and again uses armatures.
- There's a post from Blender Artists but looks even older (from 2009), and seems to suggest the warnings are important.
- This Wiki reference perhaps provides the most comprehensive overview. It starts with saying that "The main goal of dependency graph is to make sure scene data is properly updated after any change in the most efficient way" ... so does that imply that it's an efficiency issue? If so then I'm probably fine with dependency cycles, since I have powerful machines that I can use.
Thanks for any feedback you may provide.
Dependency cycle detected
Blender starts to behave non-deterministic. It seems that actions that I do will be executed up to the point of dependency cycle and the rest of the action is silently ignored. This results in different glitches that look like major rendering errors. I think it may also cause corrupted.blend
files but I'm not sure about that. $\endgroup$