diff --git a/op_texel_checker_map.py b/op_texel_checker_map.py index 4fd0d81..fe0a375 100644 --- a/op_texel_checker_map.py +++ b/op_texel_checker_map.py @@ -12,7 +12,6 @@ texture_modes = ['UV_GRID','COLOR_GRID','GRAVITY','NONE'] - class op(bpy.types.Operator): bl_idname = "uv.textools_texel_checker_map" bl_label = "Checker Map" @@ -34,8 +33,6 @@ def execute(self, context): return {'FINISHED'} - - def assign_checker_map(size_x, size_y): # Force Object mode previous_mode = bpy.context.active_object.mode @@ -55,7 +52,6 @@ def assign_checker_map(size_x, size_y): if space.type == 'VIEW_3D': space.shading.type = 'MATERIAL' - if len(objects) > 0: # Detect current Checker modes @@ -84,6 +80,8 @@ def assign_checker_map(size_x, size_y): image_sizes_x.append(image.size[0]) if image.size[1] not in image_sizes_y: image_sizes_y.append(image.size[1]) + else: + utilities_texel.store_materials(obj) mode_count[mode]+=1 @@ -95,7 +93,6 @@ def assign_checker_map(size_x, size_y): for key,val in mode_max_count: print("{} = {}".format(key, val)) - # Determine next mode mode = 'NONE' if mode_max_count[0][1] == 0: @@ -120,16 +117,23 @@ def assign_checker_map(size_x, size_y): else: # Next mode mode = texture_modes[ (index+1)%len(texture_modes) ] - - - print("Mode: "+mode) - - if mode == 'NONE': + + if mode == 'UV_GRID': + name = utilities_texel.get_checker_name(mode, size_x, size_y) + image = get_image(name, mode, size_x, size_y) for obj in objects: - remove_material(obj) + apply_image(obj, image) + + elif mode == 'NONE': + utilities_texel.restore_materials(objects) elif mode == 'GRAVITY': - image = load_image("checker_map_gravity") + for area in bpy.context.screen.areas: + if area.type == 'IMAGE_EDITOR': + editorImage = area.spaces[0].image + image = load_image("checker_map_gravity") + area.spaces[0].image = editorImage + break for obj in objects: apply_image(obj, image) @@ -159,8 +163,8 @@ def load_image(name): pathTexture = icons_dir = os.path.join(os.path.dirname(__file__), "resources/{}.png".format(name)) image = bpy.ops.image.open(filepath=pathTexture, relative_path=False) if "{}.png".format(name) in bpy.data.images: - bpy.data.images["{}.png".format(name)].name = name #remove extension in name - return bpy.data.images[name]; + bpy.data.images["{}.png".format(name)].name = name #remove extension in name + return bpy.data.images[name] @@ -169,27 +173,11 @@ def get_valid_objects(): objects = [] for obj in bpy.context.selected_objects: if obj.type == 'MESH' and obj.data.uv_layers: - objects.append(obj) - + objects.append(obj) return objects - - - - -def remove_material(obj): - bpy.ops.object.mode_set(mode='OBJECT') - bpy.ops.object.select_all(action='DESELECT') - obj.select_set( state = True, view_layer = None) - bpy.context.view_layer.objects.active = obj - count = len(obj.material_slots) - for i in range(count): - bpy.ops.object.material_slot_remove() - - - def apply_image(obj, image): bpy.ops.object.mode_set(mode='OBJECT') @@ -209,7 +197,8 @@ def apply_image(obj, image): # Assign material if len(obj.data.materials) > 0: - obj.data.materials[0] = material + for m in range(len(obj.data.materials)): + obj.data.materials[m] = material else: obj.data.materials.append(material) @@ -233,19 +222,20 @@ def apply_image(obj, image): links.new(nodo1.outputs['Color'], nodo2.inputs['Base Color']) + def get_image(name, mode, size_x, size_y): # Image already exists? if name in bpy.data.images: # Update texture UV checker mode bpy.data.images[name].generated_type = mode - return bpy.data.images[name]; + return bpy.data.images[name] # Create new image instead image = bpy.data.images.new(name, width=size_x, height=size_y) image.generated_type = mode #UV_GRID or COLOR_GRID image.generated_width = int(size_x) image.generated_height = int(size_y) - return image + bpy.utils.register_class(op) diff --git a/utilities_bake.py b/utilities_bake.py index 97b93bb..1a26ae7 100644 --- a/utilities_bake.py +++ b/utilities_bake.py @@ -9,7 +9,6 @@ from . import settings from . import utilities_color -# from . import op_bake keywords_low = ['lowpoly','low','lowp','lp','lo','l'] @@ -132,7 +131,7 @@ def store_materials(obj): bpy.context.view_layer.objects.active = obj bpy.ops.object.mode_set(mode='EDIT') - bm = bmesh.from_edit_mesh(obj.data); + bm = bmesh.from_edit_mesh(obj.data) # for each slot backup the material for s in range(len(obj.material_slots)): @@ -157,7 +156,7 @@ def restore_materials(): # Enter edit mode bpy.context.view_layer.objects.active = obj bpy.ops.object.mode_set(mode='EDIT') - bm = bmesh.from_edit_mesh(obj.data); + bm = bmesh.from_edit_mesh(obj.data) # Restore slots for index in range(len(stored_materials[obj])): @@ -177,7 +176,7 @@ def restore_materials(): bpy.ops.object.mode_set(mode='OBJECT') # Remove material slots if none before - if len(stored_materials[obj]) == 0: + if len(stored_materials[obj]) == 0 : for i in range(len(obj.material_slots)): bpy.ops.object.material_slot_remove() diff --git a/utilities_texel.py b/utilities_texel.py index 83df452..3bd3dcb 100644 --- a/utilities_texel.py +++ b/utilities_texel.py @@ -136,3 +136,88 @@ def get_area_triangle(A,B,C): # Use abs(s-a) for values that otherwise generate negative values e.g. pinched UV verts, otherwise math domain error return math.sqrt(s * abs(s-a) * abs(s-b) * abs(s-c)) + + + +stored_materials = {} +stored_material_faces = {} +def store_materials_clear(): + stored_materials.clear() + stored_material_faces.clear() + + + +def store_materials(obj): + stored_materials[obj] = [] + stored_material_faces[obj] = [] + + # Enter edit mode + bpy.ops.object.select_all(action='DESELECT') + obj.select_set( state = True, view_layer = None) + bpy.context.view_layer.objects.active = obj + + bpy.ops.object.mode_set(mode='EDIT') + bm = bmesh.from_edit_mesh(obj.data) + + # for each slot backup the material + for s in range(len(obj.material_slots)): + slot = obj.material_slots[s] + + stored_materials[obj].append(slot.material) + stored_material_faces[obj].append( [face.index for face in bm.faces if face.material_index == s] ) + + # print("Faces: {}x".format( len(stored_material_faces[obj][-1]) )) + + if slot and slot.material: + slot.material.name = "backup_"+slot.material.name + slot.material.use_fake_user = True + print("- Store {} = {}".format(obj.name,slot.material.name)) + + # Back to object mode + bpy.ops.object.mode_set(mode='OBJECT') + + + +def restore_materials(objs): + if len(objs) == 0 : + return + else: + for obj in objs : + if stored_materials.get(obj) == None : + bpy.ops.object.mode_set(mode='OBJECT') + bpy.ops.object.select_all(action='DESELECT') + obj.select_set( state = True, view_layer = None) + bpy.context.view_layer.objects.active = obj + count = len(obj.material_slots) + for i in range(count): + bpy.ops.object.material_slot_remove() + objs = [obj for obj in objs if obj in stored_materials] + + for obj in objs : + # Enter edit mode + bpy.context.view_layer.objects.active = obj + bpy.ops.object.mode_set(mode='EDIT') + bm = bmesh.from_edit_mesh(obj.data) + + # Restore slots + for index in range(len(stored_materials[obj])): + material = stored_materials[obj][index] + faces = stored_material_faces[obj][index] + + if material: + material.name = material.name.replace("backup_","") + obj.material_slots[index].material = material + material.use_fake_user = False + + # Face material indexies + for face in bm.faces: + if face.index in faces: + face.material_index = index + + # Back to object mode + bpy.ops.object.mode_set(mode='OBJECT') + + # Remove material slots if none before + if len(stored_materials[obj]) == 0 : + for i in range(len(obj.material_slots)): + bpy.ops.object.material_slot_remove() \ No newline at end of file