# How to smooth the appearance of a specified subset of faces without topology changes with a script?

This is a magnetic pole piece for an electric motor (there will be 12 in a circle). The bottom face is a hyperbola, the the top is a circle, and the sides are straight.

I would like the top and bottom curved surfaces to appear smooth when rendering in Cycles, but not create any visible rounding of the corners, or affect the large flat faces, so that even when illuminated sideways the top and bottom surfaces would appear smoothly curving.

I'll be doing a lot more to them algorithmically, so I need something that doesn't modify the topology of the mesh by adding/deleting edges, faces, vertices, etc.

edit: Since I'm generating the mesh algorithmically, I will know the indices of the faces that need to be smoothed. If I can target them for smoothing specifically, this would be the best way for me.

Below is a simplified script that shows how I generate them (I've skipped the math, happy to include it if it helps).

xpts_sharp = [ 7.196,  5.606,  4.009,  2.407, 0.803, -0.803, -2.407,
-4.009, -5.606, -7.196, -5.08, -4.298, -3.517, -2.735,
-1.954, -1.172, -0.391,  0.391, 1.172,  1.954,  2.735,
3.517,  4.298,  5.08 ]

ypts_sharp = [ 45.434, 45.657, 45.825, 45.937, 45.993, 45.993, 45.937,
45.825, 45.657, 45.434, 32.072, 31.832, 31.605, 31.398,
31.219, 31.084, 31.01,  31.01,  31.084, 31.219, 31.398,
31.605, 31.832, 32.072 ]

import bpy
import numpy as np

xpts = np.array(xpts_sharp)
ypts = np.array(ypts_sharp)
zpts = np.array([-50.0, 50.0])
scale = 0.1

xptss, yptss, zptss = scale*xpts, scale*ypts, scale*zpts
nxy, nz = len(xptss), len(zptss)

verts = []
for zpt in zptss:
zapt  = zpt + np.zeros_like(xptss)
vertz = list(zip(xptss, zapt, yptss))
verts += vertz
nverts = len(verts)

faces = []
for iz in range(nz-1):
for ixy in range(nxy):
v1 = (iz+0)*nxy + (ixy+0)%nxy
v2 = (iz+0)*nxy + (ixy+1)%nxy
v3 = (iz+1)*nxy + (ixy+1)%nxy
v4 = (iz+1)*nxy + (ixy+0)%nxy
faces.append((v1, v2, v3, v4)[::-1])
face = list(range(nxy))
faces.append(face)
face = list(range(nverts-nxy, nverts))[::-1]
faces.append(face)

if 1 == 1:
name = "pole_piece"

me = bpy.data.meshes.new(name)
ob = bpy.data.objects.new(name, me)

me.from_pydata(verts, [], faces)

bpy.data.objects[name].select = False
bpy.data.objects[name].select = True


Add an edge split modifier. Apply it if you wish.

Depending on the angle setting in the edge split modifier, surfaces will appear smooth shaded preserving sharp edges.

Internally, the modifier splits edges based on the angle of the adjacent faces.

This will add the edge split modifier and "apply" it. The topology will change.

if 1 == 1:
name = "pole_piece"

me = bpy.data.meshes.new(name)
ob = bpy.data.objects.new(name, me)

scene = bpy.context.scene

me.from_pydata(verts, [], faces)

bpy.data.objects[name].select = False
bpy.data.objects[name].select = True

for p in ob.data.polygons:
p.use_smooth = True
mod = ob.modifiers.new("edge", type='EDGE_SPLIT')
ob.data = ob.to_mesh(scene, True, 'PREVIEW')
ob.modifiers.remove(mod)

• You can easily add and apply modifiers with python as well. I can extend the answer if you wish. – Leander Nov 1 '16 at 10:03
• I added the code, why don't you add the edge split modifier as the last step. Or don't apply it and leave it as a modifier. Maybe edit your answer to what your final goal is. – Leander Nov 1 '16 at 10:16
• Ah, I see what you mean - that sounds like one solution - leaving it 'un-applied'. I'll edit the question to explain I don't want to modify the mesh topology. Thanks. – uhoh Nov 1 '16 at 10:19
• I've adjusted the question a bit. Oh, since I know which faces I want to smooth - I can just apply p.use_smooth to the ones on the curved surfaces! Since I'm creating them programmatically, I can do something like for i, p in enumerate(ob.data.polygons): if not i in [9, 23, 24, 25]: p.use_smooth = True but nicer of course. I"ll adjust the question again - this is a perfect answer. Thanks! – uhoh Nov 1 '16 at 10:48
• Yes, that will be the best solution. I will add this to the answer completeness later. My solution is a more generic approach, since I wasn't sure if you would use this for other objects as well. – Leander Nov 1 '16 at 11:15