8

I would very much like to get the Convex Hull (of the Rigid Body Collision shape) as an actual mesh.

Is there any way?

Allosteric
  • 643
  • 4
  • 19

2 Answers2

13

Edit mode(Tab) > Select All(a) > Mesh > Vertices (Ctrl+v)> Convex Hull (h):

Edit mode(<kbd>Tab</kbd>) > Select All(<kbd>a</kbd>) > Mesh > Vertices (<kbd>Ctrl</kbd>+<kbd>v</kbd>)> Convex Hull (<kbd>h</kbd>)

Martynas Žiemys
  • 24,274
  • 2
  • 34
  • 77
10

Convex hull bmesh operator

bmesh.ops.convex_hull(bm, input, use_existing_faces)

Convex Hull

Builds a convex hull from the vertices in ‘input’.

If ‘use_existing_faces’ is true, the hull will not output triangles that are covered by a pre-existing face.

All hull vertices, faces, and edges are added to ‘geom.out’. Any input elements that end up inside the hull (i.e. are not used by an output face) are added to the ‘interior_geom’ slot. The ‘unused_geom’ slot will contain all interior geometry that is completely unused. Lastly, ‘holes_geom’ contains edges and faces that were in the input and are part of the hull.

Test script, creates a convex hull for the active mesh object.

EDIT Update for 2.8. Removes interior geometry of convex hull.

import bpy
import bmesh
from mathutils import Vector, Matrix

context = bpy.context scene = context.scene ob = context.object me = ob.data bm = bmesh.new() bm.from_mesh(me) copy = ob.copy()

me = bpy.data.meshes.new("%s convexhull" % me.name) ch = bmesh.ops.convex_hull(bm, input=bm.verts) bmesh.ops.delete( bm, geom=ch["geom_unused"] + ch["geom_interior"], context='VERTS', ) bm.to_mesh(me) copy.name = "%s (convex hull)" % ob.name copy.data = me

scene.collection.objects.link(copy)

enter image description here Suzanne and convex hull Suzanne

Horror mesh.

If the input is a horror mesh of overlapping faces it may be an idea to reduce the mesh to verts only before using the convex hull operator.

import bpy
import bmesh
from math import radians

Create a cube

bpy.ops.mesh.primitive_cube_add(location=(0,0,0), size=2) me = bpy.context.object.data

Get a BMesh representation

bm = bmesh.new() # create an empty BMesh bm.from_mesh(me) # fill it in from a Mesh

Spin the cube 45deg around the y-axis in 2 steps

ret = bmesh.ops.spin(bm, geom=bm.verts[:] + bm.edges[:], angle=radians(45.0), steps=2, axis=(0.,1.,0.), cent=(0.0, 0.0, 0.0))

reduce to verts only.

bmesh.ops.delete(bm, geom=bm.edges, context='EDGES_FACES')

Create the resulting convex hull of the spin operation

ch = bmesh.ops.convex_hull(bm, input=bm.verts)

Remove everything but the convex hull

bmesh.ops.delete( bm, geom=ch["geom_unused"] + ch["geom_interior"], context='VERTS', )

Export the bmesh back to the original mesh

bm.to_mesh(me) bm.free()

Dov Grobgeld
  • 113
  • 3
batFINGER
  • 84,216
  • 10
  • 108
  • 233