5
$\begingroup$

I try to remove all the faces of different objects that have a certain material assigned to its face. But I can't get the select part to work.

import bpy import bmesh scene = bpy.context.scene mat1 = bpy.data.materials['c1'] #This is the material name that I want for ob in scene.objects: #For all objects if ob.type == 'MESH': for mat in ob.material_slots: if mat.material == mat1: bpy.ops.object.editmode_toggle() mat.material.material_slot_select() # This doesnt work and i dont know if the later code work aswell me = ob.data bm = bmesh.from_edit_mesh(me) faces_select = [f for f in bm.faces if f.select] bmesh.ops.delete(bm, geom=faces_select, context=5) bmesh.update_edit_mesh(me, True) else: ob.select = False 

What is wrong, what shall I write?

Br

$\endgroup$
1
  • $\begingroup$ You can select faces based on material with Shift G > Material in edit mode.. $\endgroup$ Commented Jan 28, 2015 at 7:27

2 Answers 2

6
$\begingroup$
import bpy import bmesh mat_c1 = bpy.data.materials['c1'] for ob in bpy.context.scene.objects: if ob.type == 'MESH': # get all the slot indexes to which mat_c1 is assigned c1_slots = [id for id, mat in enumerate(ob.data.materials) if mat == mat_c1] # you can also change active_material with # ob.active_material_index = some_number # and then run operators to deselect all faces and select material with # bpy.ops.material_slot_select() # but operators are bad so we will do it differently faces_mat_c1 = [] bm = bmesh.new() bm.from_mesh(ob.data) # no need to swith into edit mode for face in bm.faces: if face.material_index in c1_slots: # face has mat_c1 assigned faces_mat_c1.append(face) # delete faces with mat_c1 bmesh.ops.delete(bm, geom=faces_mat_c1, context=5) bm.to_mesh(ob.data) bm.free() else: ob.select = False 
$\endgroup$
3
  • $\begingroup$ thank you for a really helpful answer! It worked perfectly! $\endgroup$ Commented Jan 28, 2015 at 10:22
  • $\begingroup$ Glad it helped, you can mark it as correct for others to know, thx.) $\endgroup$ Commented Jan 28, 2015 at 10:38
  • $\begingroup$ @JaroslavJerrynoNovotny I want to go over all materials and select (or get indices of) faces to which that specific material has been applied to, without using bmesh (if possible). I haven't been able to find a good solution for doing that as of now. I would appreciate if you can take a look at my question here and see if you can offer a solution? $\endgroup$ Commented Mar 17, 2018 at 4:54
0
$\begingroup$

Excellent question and answer. If you are changing a single object, this code should help.

This code is a script that changes the size of the UV layer of the selected active material's UV.

For Blender 3.2

import bpy import bmesh factor = 1.01 # Get the active material for the object obj = bpy.context.active_object mat = obj.active_material savemode = str(bpy.context.mode) if savemode == "EDIT_MESH": savemode = "EDIT" bpy.ops.object.mode_set(mode='EDIT') obj = bpy.context.active_object mat_c1 = mat c1_slots = [id for id, mat in enumerate(obj.data.materials) if mat == mat_c1] me = obj.data bm = bmesh.new() bm = bmesh.from_edit_mesh(me) uv_layer = bm.loops.layers.uv.verify() # currently blender needs both layers. bm.faces.layers.face_map.verify() # scale UVs xfactor for f in bm.faces: if f.material_index in c1_slots: for l in f.loops: l[uv_layer].uv *= factor bmesh.update_edit_mesh(me) bpy.ops.object.mode_set(mode=savemode) 
$\endgroup$

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.