1
$\begingroup$

This is a very basic question about scripting, but I'm unable to find a useful answer.

I created a new .blend file and did the following:

  • rename the default collection ("Collection") to my_collection
  • rename the default cube object inside to my_object
  • rename the mesh inside that to my_mesh

Now I want to write a Python script that will do the following:

  • delete the data in my_mesh and replace it with a new mesh generated by Python code.

The reason I want to overwrite the mesh rather than generating a new one is that I'll be adding modifiers to the mesh and don't want them to disappear every time I re-run the script.

Calling bpy.data.meshes['my_mesh'].from_pydata(...) doesn't work. (The error message is Runtime error: internal error setting the array, which isn't super helpful.)

There is a similar question, Update/overwrite an existing mesh within a collection Python Blender, but the answer there works by deleting the old mesh and creating a new one with the same name, which will not preserve modifiers. Preserving modifiers is my main goal.

I'm using Blender 4.0 beta if that makes a difference.

$\endgroup$
4
  • 1
    $\begingroup$ Try creating a new mesh and set the obj.data to the new mesh. All modifiers will remain same. $\endgroup$
    – JayReigns
    Oct 15, 2023 at 14:15
  • 1
    $\begingroup$ Hello. In Blender you don't add modifiers to the mesh data block, you add them to the object data block, so swapping meshes won't remove nor change your modifiers. $\endgroup$
    – Gorgious
    Oct 16, 2023 at 7:01
  • $\begingroup$ @JayReigns thank you, that worked - see my self-answer $\endgroup$
    – N. Virgo
    Oct 16, 2023 at 10:44
  • $\begingroup$ @Gorgious thank you also, that was helpful $\endgroup$
    – N. Virgo
    Oct 16, 2023 at 10:45

1 Answer 1

1
$\begingroup$

This is a self-answer, collecting information from @JayReigns and @Gorgious in the comments.

The trick is that you have to create a new mesh first, then set my_obj.data to the new mesh, then delete the old mesh. If you delete the old mesh first then it will delete the object as well, thus losing the modifiers. (You can also just not delete the mesh, but then you end up with a buildup of unused meshes. I guess they will disappear when you delete the file, but I prefer to delete them proactively.)

The following script works as intended. There should be an object called "my_object" inside a collection called "my_collection". Running the script will replace the object's mesh with a triangle. You can then apply modifiers and run the script again to update the mesh with the modifiers still applied.

import bpy

# dummy mesh for testing purpopses
vertices = [
    (0,0,0),
    (0,0,1),
    (0,1,1),
]
edges = []
faces = [[0,1,2]]


my_col = bpy.data.collections.get("my_collection")

my_obj = bpy.data.objects.get("my_object")
# will be created if it doesn't already exist

# create a new mesh:
my_mesh = bpy.data.meshes.new('my_mesh')
my_mesh.from_pydata(vertices, edges, faces)
my_mesh.update()

if not my_obj:
    # create the object if it doesn't exist
    # (useful because when iterating the script
    # I kept accidentally deleting it)
    my_obj = bpy.data.objects.new("my_obj",my_mesh)
    my_col.objects.link(my_obj)
else:
    # replace the mesh and delete the old one
    old_mesh = my_obj.data
    my_obj.data = my_mesh
    bpy.data.meshes.remove(old_mesh)
$\endgroup$
2
  • 1
    $\begingroup$ Thanks for sharing your answer ! To answer your comment, I think you don't need to deselect objects since you're accessing everything by name and it's context-independant. Cheers $\endgroup$
    – Gorgious
    Oct 16, 2023 at 10:59
  • $\begingroup$ @Gorgious thanks, that makes sense and it seems to work fine without it, so I've edited to remove that line $\endgroup$
    – N. Virgo
    Oct 16, 2023 at 11:43

You must log in to answer this question.

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