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 Answers 2

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.

$\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
$\endgroup$
2
  • $\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, 2020 at 7:10
  • 1
    $\begingroup$ No problem with that :) $\endgroup$
    – Gorgious
    Jul 8, 2020 at 7:16

You must log in to answer this question.

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