5
$\begingroup$

How can internal meshes be created for object like shown in the answer for this question - Soft Body - Preserve Volume when deformed

enter image description here

The answer provided a manual process that only works for object that can be extruded, and requires a lot of steps. Are there plugins or other ways to create a mesh like this for softbody simulations?

$\endgroup$
1
  • $\begingroup$ I’m thinking the new Geometry Nodes functionality might be able to do this as it matures more (can’t do it just yet) or perhaps Animation Nodes (but I don’t know enough about that). $\endgroup$ Mar 10 at 8:25
3
$\begingroup$

Creating generic internal geometry is tricky since it needs to connect to the existing vertices and it should ideally be relatively evenly spaced. Here's one way of achieving it with Python scripting :

import bpy

active_object = bpy.context.active_object
#TODO : Check that active_object is actually an object

current_mode = bpy.context.object.mode

#if not in Edit mode, go into Edit mode and select all vertices
#if already in Edit mode, check that some vertices are already selected - these will be used for the 'fill' (otherwise, select all)
if current_mode == "EDIT":
    bpy.ops.mesh.select_mode(type="VERT")
    selected_verts = [v for v in active_object.data.vertices if v.select]
    if len(selected_verts) == 0:
        bpy.ops.mesh.select_all(action='SELECT')
elif current_mode == "OBJECT":
    bpy.ops.object.mode_set (mode = "EDIT")
    bpy.ops.mesh.select_mode(type="VERT")
    bpy.ops.mesh.select_all(action='SELECT')


#....need to be able to specify the upper range for the 'fill'
num_levels = 4

for level in range(num_levels,1,-1):
    bpy.ops.mesh.extrude_edges_indiv()
    scale = (level-1)/level
    bpy.ops.transform.resize(value=(scale,scale,scale))
    
    if level == num_levels:
        #First level - store it as we need it to be able to remove faces
        firstlevel_verts = [v for v in active_object.data.vertices if v.select]
    
    print(scale)

bpy.ops.mesh.extrude_edges_indiv()    
bpy.ops.mesh.merge(type='CENTER')

#Find the new geometry :
#Centre vertex should already be selected from above 'merge' operation
for level in range(num_levels,1,-1):
    bpy.ops.mesh.select_more()
#All 'internal' geometry should now be selected

#Create a vertex group containing internal geometry
selected_verts = [v for v in active_object.data.vertices if v.select]
vertexgroup = bpy.context.object.vertex_groups.new()
vertexgroup.name = ("InternalGeometry")
bpy.ops.object.vertex_group_assign()

# TODO: Internal geometry will have faces. Possibly need to add code here to remove faces from internal geometry.

Paste the above text into a new Text Editor text block, select your object and click the 'Run' button in the Text Editor.

The script uses the selected geometry (or the whole object is nothing is selected or you're currently in 'Object' mode) and extrudes it inwards repeatedly until it merges at the centre. The created geometry is automatically added to a new vertex group named 'InternalGeometry' so that you can easily re-select it if required.

So starting from a default cube with a single sub-division to give it more edges :

subdivided cube

Run the script and you have internal geometry :

internal geometry

The way the script works is to undertake a number of actions to extrude the geometry into sucessively smaller "shells". This is achieved by triggering the extrude in 'edges' mode then scaling by sucessive factors or 3/4, 2/3, 1/2, and finally merging down to a point. This should create fairly balanced geometry in most cases.

If you need more subdivisions you can set the 'num_levels' to a larger number and the proportions for the scale operations should be automatically calculated to suit.

The script isn't fully robust - so should only be run in 'Object' or 'Edit' mode (you can use 'Edit' mode if you just want to select a sub-set of the geometry for the "fill" - just select the required vertices before running the script). Also, it doesn't currently attempt to remove the 'faces' of the created geometry... this might be preferable in some cases anyway since if you're running a Cloth simulation rather than a Soft Body simulation you need to have faces present for those faces to be simulated as struture of the cloth (edges without faces are treated as sewing edges).

Finally, the new geometry is selected (by selecting the cetral vertex and selecting 'more' the correct number of times for all levels), a new 'InternalGeometry' Vertex Group added and those vertices assigned.

If you desire a more evenly spaced geometry you could potentially run this with a larger number of levels to fill the space with vertices and then run a 'Merge by Distance' to merge the resultant internal geometry into more evenly spaced vertices at that set minimum distance.

$\endgroup$
1
  • $\begingroup$ If I get the chance I’ll make this more robust and configurable and bring it together as a small add-on. $\endgroup$ Mar 14 at 15:48

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.