Created
May 3, 2024 07:15
-
-
Save CGArtPython/8994ad884c0f85fbb2501eead47487c4 to your computer and use it in GitHub Desktop.
Example of how context managers work for mesh editing in Blender
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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