2
$\begingroup$

started using blender recently (>2.8), and in particular I'm trying to do a lot of work via scripting and the use of modifiers.

In particular, I'm generating a circle via modifiers, with a changeable radius via the displacement modifier. However, when I create this via scripting, the displacement modifier doesn't update the visual until after I click on the mesh object.

How can I force this visual update programmatically?

(1) Before Script | (2) After Script | (3) After Click On Mesh Object Sequence of observing modifiers

I don't want to apply the modifiers just yet either.

The Code:

import bpy
import bmesh
from math import pi

# 1: Generate Mesh Object    
mesh = bpy.data.meshes.new("mesh")
obj = bpy.data.objects.new("object", mesh)
scene = bpy.context.scene
bpy.context.collection.objects.link(obj)

# 2: Generate Mesh - Verticies, Edges, and Faces
verts = [(0,0,0),(1,0,0)] #add a line
bm = bmesh.new()
bm_verts = []
for v in verts:
    bm_verts.append(bm.verts.new(v))
edges = [
    [bm_verts[i], bm_verts[i+1]] for i in range(len(bm_verts)-1)
]
bm_edges = []
for e in edges:
    bm_edges.append(bm.edges.new(e))
bm.to_mesh(mesh)
bm.free()

# 3: Create modifiers for object.
# length of the line object
radius_mod = obj.modifiers.new(name='length', type='DISPLACE')
radius_mod.show_in_editmode = True
radius_mod.show_on_cage = True
radius_mod.strength = -1
radius_mod.mid_level= 0.2
# create a circle
screw_mod = obj.modifiers.new(name="screw", type='SCREW')
screw_mod.axis = 'Z'
screw_mod.angle = 2 * pi
screw_mod.use_merge_vertices = True
screw_mod.merge_threshold = 0.01        
$\endgroup$
2
$\begingroup$

Update the mesh

After writing changes to an object mode (from_mesh(...)) mesh with bmesh, to see changes call Mesh.update()

eg

bm_edges = []
for e in edges:
    bm_edges.append(bm.edges.new(e))
bm.to_mesh(mesh)
bm.free()
mesh.update()

The from_pydata method as suggested by @Gorgious is both quicker and AFAICT updates the mesh when called. Weigh up its use against complexity of mesh to create. For a two vert one edge mesh definitely go with from_pydata.

| improve this answer | |
$\endgroup$
2
$\begingroup$

There is a handy from_pydata method (doc) when you have relatively simple mesh data. When I used this, I didn't have this disconnect after setting the modifiers.

By the way you are setting attributes to the screw modifier which are already default like the Zaxis or the 360° and the merge threshold distance.

Updated code :

import bpy
import bmesh

mesh = bpy.data.meshes.new("mesh")
obj = bpy.data.objects.new("object", mesh)
scene = bpy.context.scene
bpy.context.collection.objects.link(obj)

# 2: Generate Mesh - Verticies, Edges, and Faces
verts = [(0,0,0),(1,0,0)] #add a line
obj.data.from_pydata(verts, ((0,1),), [])

# 3: Create modifiers for object.
# length of the line object
radius_mod = obj.modifiers.new(name='length', type='DISPLACE')
radius_mod.show_in_editmode = True
radius_mod.show_on_cage = True
radius_mod.strength = -1
radius_mod.mid_level= 0.2
# create a circle
screw_mod = obj.modifiers.new(name="screw", type='SCREW')
screw_mod.use_merge_vertices = True
| improve this answer | |
$\endgroup$
  • $\begingroup$ It's really important that to recognize there are better methods for constructing objects, thanks. I'll accept @batFINGER's answer though for solving the specific code problem. $\endgroup$ – Mr G Jul 8 at 7:10
  • 1
    $\begingroup$ No problem with that :) $\endgroup$ – Gorgious Jul 8 at 7:16

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.