3
$\begingroup$

I am using the rock generator add-on and dropping rocks into a container (consisting of 4 reshaped cubes) - see attached picture.

The rocks are dropped from a random height into the container and I want to look at the stacking of the rocks.

When the rocks fall into the container, the initial rocks settle, but as more rocks are added the rocks begin to move more erratically upon collision with other rocks, If I leave the simulation long enough most of the rocks are flung out of the container, leaving just the base layer of rocks.

I had previously set my rocks to 'convex hull' for the rigid body simulation and this prevented this effect, but introduced inaccuracies, I have now changed this to 'mesh' which gives the current problem.

I have found various bits of information online but nothing has resolved my issue.

I am using split impulse and the steps per second and solver iterations should be satisfactory.

The container consists of 4 cubes each 10cm thick which make up the walls of the container and the base. Each cube is passive in the rigid body simulation .

The rocks are on the mm range in diameter (which is small but wasnt an issue when using convex hull), I am using a collision margin of zero (rocks must be able to touch), I am applying 0.9 linear and angular damping and have tried using deactivation below a given linear and angular velocity, but with no success.

I have tried changing multiple aspects of my scene and objects, and currently have the following parameters for my active objects (rocks):

  • Collison Shape = Mesh

  • Mesh Source=Deform

  • Use Deform=On

  • Scaling is applied

  • Origin set to Center of Mass

  • Deactivation =On (but having no effect)

  • Collision Margin = 0.001

  • Linear Damping Factor = Rotation Damping Factor =0.5

Scene Parameters:

  • Split Impulse=On

  • Steps per Second=1000 (changed since I replied to a comment below (no effect on issue))

  • Solver Iterations=1000 (changed since I replied to a comment below (no effect on issue))

enter image description here

Here is the python code used to generate the attached blend file.

import bpy
import random
import time
import cProfile, pstats,io
from datetime import datetime
from pathlib import Path
import math

Xmax=0.5
Ymax=0.2
Zmax=0.4

V=Xmax*Ymax*Zmax
maxframe=800

def container_genration(Xmax,Ymax,Zmax):

    bpy.ops.mesh.primitive_cube_add(size=1, enter_editmode=False, align='WORLD', location=(Xmax/2, Ymax/2, -(Zmax/10)), scale=(1, 1, 1))
    bpy.data.objects["Cube"].scale[0]=Xmax*1.2
    bpy.data.objects["Cube"].scale[1]=Ymax*1.2
    bpy.data.objects["Cube"].scale[2]=(1/10)
    bpy.ops.rigidbody.object_add()
    bpy.context.object.rigid_body.type = 'PASSIVE'
    bpy.data.scenes["Scene"].rigidbody_world.steps_per_second=800
    bpy.data.scenes["Scene"].rigidbody_world.solver_iterations=800
    bpy.data.scenes["Scene"].rigidbody_world.use_split_impulse

    bpy.data.scenes["Scene"].rigidbody_world.point_cache.frame_start = 1
    bpy.data.scenes["Scene"].rigidbody_world.point_cache.frame_end = maxframe+100

    bpy.ops.mesh.primitive_cube_add(size=0.6, enter_editmode=False, align='WORLD', location=(0-0.03, Ymax/2, Zmax*(1/2)), scale=(1, 1, 1))
    bpy.data.objects["Cube.001"].scale[0]=(Zmax*5/3)
    bpy.data.objects["Cube.001"].scale[1]=(Ymax*(20/6))
    bpy.data.objects["Cube.001"].scale[2]=(0.6/6)
    bpy.context.object.rotation_euler[0] = 0
    bpy.context.object.rotation_euler[1] = 1.570796
    bpy.context.object.rotation_euler[2] = 0
    bpy.ops.rigidbody.object_add()
    bpy.context.object.rigid_body.type = 'PASSIVE'

    bpy.ops.mesh.primitive_cube_add(size=0.6, enter_editmode=False, align='WORLD', location=(Xmax+0.03, Ymax/2, Zmax*(1/2)), scale=(1, 1, 1))
    bpy.data.objects["Cube.002"].scale[0]=(Zmax*5/3)
    bpy.data.objects["Cube.002"].scale[1]=(Ymax*(20/6))
    bpy.data.objects["Cube.002"].scale[2]=(0.6/6)
    bpy.context.object.rotation_euler[0] = 0
    bpy.context.object.rotation_euler[1] = 1.570796
    bpy.context.object.rotation_euler[2] = 0
    bpy.ops.rigidbody.object_add()
    bpy.context.object.rigid_body.type = 'PASSIVE'

    bpy.ops.mesh.primitive_cube_add(size=1.2, enter_editmode=False, align='WORLD', location=(Xmax/2, 0-0.03, Zmax*(1/2)), scale=(1, 1, 1))
    bpy.data.objects["Cube.003"].scale[0]=(Zmax*5/6)
    bpy.data.objects["Cube.003"].scale[1]=(Xmax)
    bpy.data.objects["Cube.003"].scale[2]=(0.3/6)
    bpy.context.object.rotation_euler[0] = 1.570796
    bpy.context.object.rotation_euler[1] = 1.570796
    bpy.context.object.rotation_euler[2] = 0
    bpy.ops.rigidbody.object_add()
    bpy.context.object.rigid_body.type = 'PASSIVE'

    bpy.ops.mesh.primitive_cube_add(size=1.2, enter_editmode=False, align='WORLD', location=(Xmax/2, Ymax+0.03, Zmax/2), scale=(1, 1, 1))
    bpy.data.objects["Cube.004"].scale[0]=Zmax*5/6
    bpy.data.objects["Cube.004"].scale[1]=(Xmax)
    bpy.data.objects["Cube.004"].scale[2]=(0.3/6)
    bpy.context.object.rotation_euler[0] = 1.570796
    bpy.context.object.rotation_euler[1] = 1.570796
    bpy.context.object.rotation_euler[2] = 0
    bpy.ops.rigidbody.object_add()
    bpy.context.object.rigid_body.type = 'PASSIVE'
    
    container_genration(Xmax,Ymax,Zmax)

### rock generation ###
def zlocations(noparticles):
    zcords=[]
    for i in range(int(noparticles)):
        zcords.append(0.2+(0.065*i))
    return zcords



def rockgenerator(particles,minsize,maxsize,zcords,Xmax,Ymax,dampingfactor=0.8,angular_damping=0.8):
    for i in range(particles):
        bpy.ops.mesh.add_mesh_rock(scale_X=(minsize, maxsize), skew_X=0, scale_Y=(minsize, maxsize), skew_Y=0, scale_Z=(minsize, maxsize), skew_Z=0, use_scale_dis=True, scale_fac=(1.2, 1.2, 1.2))   
        bpy.ops.rigidbody.object_add()
        bpy.context.object.rigid_body.collision_shape = 'MESH'
        bpy.context.object.rigid_body.collision_margin=0
        bpy.context.object.rigid_body.linear_damping=dampingfactor
#        bpy.context.object.rigid_body.angular_damping = angular_damping
        bpy.context.object.rotation_euler[0] = random.uniform(0,6.265732)
        bpy.context.object.rotation_euler[1] = random.uniform(0,6.265732)
        bpy.context.object.rotation_euler[2] = random.uniform(0,6.265732)
        bpy.context.object.location[0] = random.uniform(0.05,(Xmax-0.05))    
        bpy.context.object.location[1] = random.uniform(0.05,(Ymax-0.05))
        zloc=random.choice(zcords)
        bpy.context.object.location[2] = float(zloc)
        zcords.remove(zloc) 
    return zcords

nop60=int(round(810*V))

noparticles=nop60
zcords=zlocations(noparticles)
zcords=rockgenerator(nop60,0.05,0.06,zcords,Xmax,Ymax,0.98,0.98)

print("Baking Physics")
override = {'scene': bpy.context.scene,
            'point_cache': bpy.context.scene.rigidbody_world.point_cache}
bpy.context.scene.frame_current = maxframe
bpy.ops.ptcache.bake(override, bake=False)

UPDATE: Ive added the blend file in case this is more helpful, Ive also updated the python script to the script used for the last blend. Any help is greatly appreciated. The blend and python example contain less rocks than the original image.

$\endgroup$
8
  • $\begingroup$ What is the timestep, by chance? $\endgroup$ Commented Dec 7, 2020 at 20:34
  • $\begingroup$ 400 time steps per second, 400 solver iterations $\endgroup$
    – MattC1990
    Commented Dec 7, 2020 at 20:52
  • $\begingroup$ maybe share your file so that those who know rigid body can help you? blend-exchange.giantcowfilms.com $\endgroup$
    – moonboots
    Commented Dec 10, 2020 at 17:56
  • $\begingroup$ Adding Python File Example now, thanks $\endgroup$
    – MattC1990
    Commented Dec 14, 2020 at 14:36
  • $\begingroup$ rigidbody simulations in blender usually suck unless you increase your time steps and solver iterations by a bunch $\endgroup$
    – ETHAN DAY
    Commented Jan 5, 2021 at 14:30

1 Answer 1

1
$\begingroup$

Your container is simply too small. Blender has a hard time with extreme scales in simulations, so increase the size of the container. Also, the rocks, should be convex hull to stabilize the simulation.


To fix things I did the following:

Parented the container parts together to scale uniformly. See the gif below for an illustration:

enter image description here

Next, as the simulation is still unstable, the rocks need to be changed to convex hull. To do this in one go, change one, and select the rest and then reselect the convex hull and then choose Object>Rigid Body>Copy From From Active

Here is the result, hopefully this gets you going in the right direction:

enter image description here

$\endgroup$
4
  • $\begingroup$ Thank you, the original purpose of the change from convex hull to mesh, was because the rocks wernt actually touching (despite setting collision margin to zero). Ill attempt your solution now, but do you think a larger container with a mesh collision could work, or do you know any other way to get the rocks to touch ? $\endgroup$
    – MattC1990
    Commented Jan 5, 2021 at 15:34
  • $\begingroup$ @MattC1990 friction on the rock objects can be adjusted. Read the manual entry on surface response... $\endgroup$ Commented Jan 5, 2021 at 16:33
  • 1
    $\begingroup$ Thank you for your help $\endgroup$
    – MattC1990
    Commented Jan 5, 2021 at 17:21
  • $\begingroup$ welcome, good luck with your project :) $\endgroup$ Commented Jan 5, 2021 at 17:24

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .