Skip to content

Instantly share code, notes, and snippets.

@CGArtPython
Created May 3, 2024 07:15
Show Gist options
  • Save CGArtPython/8994ad884c0f85fbb2501eead47487c4 to your computer and use it in GitHub Desktop.
Save CGArtPython/8994ad884c0f85fbb2501eead47487c4 to your computer and use it in GitHub Desktop.
Example of how context managers work for mesh editing in Blender
import contextlib
import bpy
import bmesh
class Mode:
Edit = "EDIT_MESH"
Object = "OBJECT"
@contextlib.contextmanager
def get_bmesh_from_edit_mode(mesh_obj):
# create a new bmesh and initialize it from mesh data in Edit Mode
bm = bmesh.from_edit_mesh(mesh_obj.data)
yield bm
bm.normal_update()
# writes the bmesh data into the mesh data in Edit Mode
bmesh.update_edit_mesh(mesh_obj.data)
# clean up/free memory that was allocated for the bmesh
bm.free()
@contextlib.contextmanager
def get_bmesh_from_object_mode(mesh_obj):
# create a new bmesh
bm = bmesh.new()
# initialize the bmesh data using the mesh data
bm.from_mesh(mesh_obj.data)
yield bm
bm.normal_update()
# writes the bmesh data into the mesh data
bm.to_mesh(mesh_obj.data)
# [Optional] update the mesh data (helps with redrawing the mesh in the viewport)
mesh_obj.data.update()
# clean up/free memory that was allocated for the bmesh
bm.free()
@contextlib.contextmanager
def get_bmesh(mesh_obj):
if bpy.context.mode not in (Mode.Object, Mode.Edit):
raise RuntimeError(f"{bpy.context.mode} mode is not supported for creating bmesh representation of mesh data")
if bpy.context.mode == Mode.Object:
get_bmesh_impl = get_bmesh_from_object_mode
else:
get_bmesh_impl = get_bmesh_from_edit_mode
with get_bmesh_impl(mesh_obj) as bm:
yield bm
# get a reference to the active object
mesh_obj = bpy.context.active_object
with get_bmesh(mesh_obj) as bm:
bmesh.ops.bevel(bm, geom=bm.edges, offset=0.2, segments=4, affect="EDGES", profile=0.5)
import bpy
import bmesh
def create_bmesh_from_object_mode(mesh_obj):
# create a new bmesh
bm = bmesh.new()
# initialize the bmesh data using the mesh data
bm.from_mesh(mesh_obj.data)
return bm
def apply_bmesh_to_object_mesh(mesh_obj):
# writes the bmesh data into the mesh data
bm.to_mesh(mesh_obj.data)
# [Optional] update the mesh data (helps with redrawing the mesh in the viewport)
mesh_obj.data.update()
def create_bmesh_from_edit_mode(mesh_data):
# create a new bmesh and initialize it from mesh data in Edit Mode
bm = bmesh.from_edit_mesh(mesh_obj.data)
return bm
def apply_bmesh_to_edit_mesh(mesh_data):
# writes the bmesh data into the mesh data in Edit Mode
bmesh.update_edit_mesh(mesh_obj.data)
class BmeshManager:
EditMode = "EDIT_MESH"
ObjectMode = "OBJECT"
def __init__(self, mesh_obj):
if bpy.context.mode not in (BmeshManager.ObjectMode, BmeshManager.EditMode):
raise RuntimeError(f"{bpy.context.mode} mode is not supported for creating bmesh representation of mesh data")
self.mesh_obj = mesh_obj
if bpy.context.mode == BmeshManager.ObjectMode:
self.create_bmesh = create_bmesh_from_object_mode
self.apply_bmesh_to_mesh = apply_bmesh_to_object_mesh
else:
self.create_bmesh = create_bmesh_from_edit_mode
self.apply_bmesh_to_mesh = apply_bmesh_to_edit_mesh
def __enter__(self):
self.bm = self.create_bmesh(self.mesh_obj)
return self.bm
def __exit__(self, exc_type, exc_value, exc_traceback):
self.bm.normal_update()
self.apply_bmesh_to_mesh(self.mesh_obj)
# clean up/free memory that was allocated for the bmesh
self.bm.free()
# get a reference to the active object
mesh_obj = bpy.context.active_object
with BmeshManager(mesh_obj) as bm:
bmesh.ops.bevel(bm, geom=bm.edges, offset=0.2, segments=4, affect="EDGES", profile=0.5)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment