8
$\begingroup$

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

Is there any way?

$\endgroup$
13
$\begingroup$

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>)

$\endgroup$
9
$\begingroup$

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()
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.