I just started a try at implement something like 3dsMax smoothgroups in blender.
Not very far jet, but the basics work.
here’s the code. I was wondering if someone else is working on the same thing?
# Edit vertex normals. Only works in edit mode with a Mesh.
# for now just a very basic implementation.
# I think it works like 3dsMax with two smooth groups
# first smoothgroup is the total mesh, second one is selected faces.
# 3D viewport is not automatically refreshed after this script runs, need to rotate the view to make it update.
import bpy
import bmesh
# Get the active mesh
me = bpy.context.object.data
# todo: use mesh ID-Property to store a lsit of integers that define faces in a smoothgrop
# Get a BMesh representation
smooth_group_bm = bmesh.new() # create an empty BMesh
smooth_group_bm.from_mesh(me) # fill it in from a Mesh
face_seq = smooth_group_bm.faces
for face in face_seq:
if not face.select:
#remove faces from that are not selected.
# edges and verts stay. vertex indices should not be changed
face_seq.remove(face)
smooth_group_bm.normal_update() # should smooth normals of the mesh with only the selected faces
vert_seq = smooth_group_bm.verts
bm = bmesh.new()
bm = bmesh.from_edit_mesh(me)
for vert in vert_seq:
if vert.select:
bm.verts[vert.index].normal = vert.normal
# todo: refresh 3d viewports. currently you have to rotate the view in order to see the changed vertex normals
The normal edit stays if you go out of edit mode, but is lost if you go back into edit mode. The edit is also lost if you edit the mesh.
I’m gona try saving the face selection as an ID-Property of the mesh, then the script can run again with the old selection (smoothgroup) to recalculate the normals after they are lost.
Blender seems to smooth the vertex normals automatically. If anyone knows how to disable this automatic smoothing that would be very nice.
Blender seems to smooth the vertex normals automatically. If anyone knows how to disable this automatic smoothing that would be very nice.
Blender auto-calcs normals you can’t disable it. You can, however, set shading of faces to flat or smooth and mark edges as sharp (e.g. to split sharp edges with edge split modifier).
as an ID-Property of the mesh
we don’t have ID props in python, we can only store object references as stringprops.
todo: refresh 3d viewports. currently you have to rotate the view in order to see the changed vertex normals
And saving the face selection in an integer list in the meshes id properties seems to work
# save selected face indices as an ID-Property of the mesh
# can be seen in Custom Properties
import bpy
import bmesh
# Get the active mesh
me = bpy.context.object.data
face_selection_bm = bmesh.from_edit_mesh(me)
face_seq = face_selection_bm.faces
selected_face_indices = []
for face in face_seq:
if face.select:
selected_face_indices.append(face.index)
me["smooth_group_1"] = selected_face_indices
for index in me["smooth_group_1"]:
print(index)
It creates a panel called Smooth Groups in the object data of meshes. Click the + icon to add a smoothgroup, assign some faces to it, then press Smooth.
The smoothing is lost when entering edit mode or changing editing the mesh. Face selection is stored thow, so simply press Smooth again.
Feels a bit hacky because the script stores data in the custom properties of the mesh. If you don’t edit these properties everything should work fine.
hmm, the down side of this script is that if an edge split modifyer is added then the modifyer will do the smoothing again, and the smoothing by the script is lost. Workaround is to apply the edge split modifyer, but that’s destructive
Is there actually ways to script modifyers in python? I would like to turn my script into a modifyer. Using it after an edge split modifyer would be very helpfull.
the tricky thing about bmesh custom data layers is that you need to get the layer handle back after loading .blend, but there is a way, i already managed this. Question is rather if the custom data itself stays and if it’s synced correctly…
Other than that, you could also use a CollectionProperty.
hmm, for me the bigger issue is to get the code to run after an edge split modifyer, without having to apply the modifyer.
Unfortunately I don’t see a way to do that without getting into the c code, and that’s beyond my capabilities at the moment.
not sure if this works as expected in editmode. The funny thing: you can get bm from edit mesh, then do from_object and is_wrapped will still be true lol?!