this is an example using a context manager in Bender to help with switching modes for running a tool.
its also an example of setting a material on a face using python in Blender. the mesh is assumed to be topologically symmetric and it only works with the source side in +x.
the tool may have bugs so please use/modify at your own risk. (tested in Blender 2.79)
before:
after:
import bpy from mathutils import Vector from math import sqrt import logging logger = logging.getLogger(__name__) logging.basicConfig(level=logging.DEBUG) #without this info logs wouldnt show in class EnterModeContext(object): """gives ability to enter a needed mode > then run needed > then return to original mode ex entering into edit mode: #subdivide selected mesh in edit mode with EnterModeContext("EDIT"): bpy.ops.mesh.subdivide() """ def __init__(self, toMode): """ @param toMode (str) mode to go into ex: 'EDIT' or 'POSE' etc """ self._toMode = toMode #mode to go into def __enter__(self): #print("enter") self._currentMode = bpy.context.object.mode #go into to mode if not already in it if self._currentMode != self._toMode: bpy.ops.object.mode_set(mode=self._toMode) def __exit__(self, ext, exv, trb): #print("exiting") logger.info("ext:{}".format(ext)) logger.info("exv:{}".format(exv)) logger.info("trb:{}".format(trb)) #return into starting mode if not already in it if self._currentMode != self._toMode: bpy.ops.object.mode_set(mode=self._currentMode) return True def makeMaterialSymmetric(meshName): """make materials symmetric. given a topology symmetric mesh. Args: meshName (str) data object name for mesh we want to make material symmetric Returns: (bool) whether successfully made material symmetric """ epsilon = 0.000001 #how close is enough to say found a matched point numFaces = len(bpy.data.objects[meshName].data.polygons) faceMirrorData = [] for faceIndex in range(0, numFaces): facePos = bpy.data.objects[meshName].data.polygons[faceIndex].center #we are only editing right side faces if facePos >= 0: continue #loop through all faces trying to find closest face to mirror point #negate x to get left side mirror face position mirrorPos = Vector((-1*facePos.x, facePos.y, facePos.z)) for f in range(0, numFaces): fPos = bpy.data.objects[meshName].data.polygons[f].center #ignore left side faces as they are not on right side of mesh if fPos <= 0: continue #check if found a mirrored face dist = sqrt((fPos.x - mirrorPos.x)**2 + (fPos.y - mirrorPos.y)**2 + (fPos.z - mirrorPos.z)**2) #if distance too big we know we havent found our mirrored face yet if dist > epsilon: continue #we found our mirrored face dat = dict(faceIndex=faceIndex, mirrorIndex=f) faceMirrorData.append(dat) break #exit loop as we dont need to check any others #continue to next left side face we want to search for a mirror #done with loops #appy the material on mirror side for data in faceMirrorData: sourceIndex = data.get('faceIndex', None) destinationIndex = data.get('mirrorIndex', None) if (not sourceIndex) or (not destinationIndex): print("cannot find a mirrored face for source face {}. mesh is more than likely not symmetric".format(sourceIndex)) continue sourceMaterialIndex = bpy.data.objects[meshName].data.polygons[sourceIndex].material_index #set mirror side material bpy.data.objects[meshName].data.polygons[destinationIndex].material_index = sourceMaterialIndex return True """ import imp testTool = imp.load_source("tool","/Users/Nathaniel/Documents/src_blender/python/snippets/texture_snippets.py") #for mac. change to path to python file with testTool.EnterModeContext("OBJECT"): testTool.makeMaterialSymmetric("Sphere") """
Thanks for looking