So I wish to create and object and set it's shading to 'smooth' using python. It seems simple enough but after trying every method I could find on the internet none of them worked for me. Here's a short example script where the object needs to have smooth shading:

import bpy
from mathutils import Vector

verts = [(0,0,0),(0,5,0),(0.25,5,0),(0.25,0,0),(0,0,5),(0,5,5),(0.25,5,5),(0.25,0,5)]
faces = [(0,1,2,3), (4,5,6,7), (0,4,5,1), (1,5,6,2), (2,6,7,3), (3,7,4,0)]

grat1mesh = bpy.data.meshes.new("grat1")
grat1obj = bpy.data.objects.new("grat1", grat1mesh)
grat1obj.location = (5, -5, 0)

grat2obj = grat1obj.copy()
grat2obj.data = grat1mesh.copy()
grat2obj.location += Vector((-0.125, 1.25, 1.25))
grat2obj.scale = (2, 0.5, 0.5)

bm = grat1obj.modifiers.new("Chop", 'BOOLEAN')
bm.object = grat2obj
bm.operation = 'DIFFERENCE'
bpy.context.scene.objects.active = grat1obj

I found this online and tried to place it at the end of the script:

smoothings = []
me_ob.faces.foreach_set("use_smooth", smoothings)

However this just returned an error on the second line, perhaps as it was from an older website. Obviously using a simple bpy.ops.object.shade_smooth() didn't work and I'm kind of stumped as of what to do here!

  • 1
    $\begingroup$ If you get an error, please include the text of that error in the question. $\endgroup$ – Ray Mairlot Oct 5 '17 at 17:00
  • $\begingroup$ @RayMairlot Apologies... On blender 2.79 it returns "Python script fail, look in the console for now..." I don't know of a way of getting a more detailed error response, however. $\endgroup$ – Jordan Abbott Oct 5 '17 at 17:01
  • 1
    $\begingroup$ You need to look in the console. See: blender.stackexchange.com/questions/6173/… $\endgroup$ – Ray Mairlot Oct 5 '17 at 17:04

Can set face to smooth in bmesh with

for f in bm.faces:
    f.smooth = True

Or in object mode

mesh = context.object.data
for f in mesh.polygons:
    f.use_smooth = True

The foreach set routines need a correctly sized value list for example

values = [True] * len(mesh.polygons)
mesh.polygons.foreach_set("use_smooth", values)

which is the equivalent of the for loop above.

Remember that when blender started to handle ngons (faces with more than 4 verts) it changed the mesh.faces collection was renamed to mesh.polygons.

  • $\begingroup$ Thanks! After a while of being a dumbo and thinking that just sticking in 'mesh' instead of 'grat1mesh' it finally worked. oops! $\endgroup$ – Jordan Abbott Oct 5 '17 at 19:00
  • $\begingroup$ Hey, I was wondering if there is a point in trying to optimize the values array used in the foreach_set with a numpy array like values = np.full(len(mesh.polygons), True, dtype=bool) ? I did a few tests but did not find any speed improvement $\endgroup$ – Gorgious Mar 23 at 17:16
  • $\begingroup$ Sure python is going to make a list of single value pretty quickly.. it's what is done in between. for example inverting the value for a high poly count. np.invert(values) is going to pants a for loop and prob also a list comp [not v for v in values] $\endgroup$ – batFINGER Mar 23 at 18:11

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.