The Blender script (2.8) that erases only the skirt is completed

** * Blender version is 2.8 ***

To be precise, it is a script that ** erases the vertices on which the weight of the bone containing an arbitrary character string is placed **, but since it is interesting, I tried to put the skirt on the front for the time being. There may also be practicality (?) In modification. I also struggled with Blender's API so much, so I've added a commentary about that.

State of application

Before application

image.png

After application

image.png

When targeting Hair

image.png

When targeting Chest

image.png

Source code

import bpy

for ob in bpy.data.objects:
    try:
        me = ob.to_mesh()
        bpy.context.view_layer.objects.active = ob
        vg = ob.vertex_groups
        for v in bpy.data.meshes[me.name].vertices:
            v.select = False
            for g in v.groups:
                if "Skirt" in vg[g.group].name or "skirt" in vg[g.group].name: #Specify the character string of the bone you want to erase here
                    v.select = True 
        bpy.ops.object.mode_set(mode='EDIT', toggle=False)
        bpy.ops.mesh.delete(type='VERT')
        bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
        print(ob.name + "... completed")
    except:
        print(ob.name + "... no mesh!")

Commentary

Weights are managed in correspondence with vertex groups. If a vertex is in a group of vertices with the name of a bone, it is considered to have weights. It searches all vertices to determine if they are in a vertex group that contains skirt or Skirt, and if so, removes them.

First, explore all the objects.

for ob in bpy.data.objects:

Next, get the mesh data that contains the object. The data structure around here is also explained in my work Following Blender's data structure and extracting vertex coordinates from fbx. I would appreciate it if you could read it.

    me = ob.to_mesh()

Also, this instruction throws an error for objects that do not have a mesh (such as Camera or ʻArmature), so it is escaped by the try: `clause. It's not a very smart way.

    bpy.context.view_layer.objects.active = ob

At this time, the target object is activated. Please note that the bpy.context.scene.objects.active that was available by the 2.7 era is no longer available. If you get the error message bpy_prop_collection: attribute" active "not found, this is most likely.

    vg = ob.vertex_groups

Then get the list of vertex groups contained in the object. Note that this is contained in the object, not the mesh. The names of vertex groups such as Hips and Chest are included here. You can get the name in the form bpy.data.objects [x] .vertex_groups [x] .name.

        for v in bpy.data.meshes[me.name].vertices:

Then search for all the vertices. Vertex data is included in the mesh. You can get the list in the form bpy.data.meshes [x] .vertices. At first, I tried to extract the vertex data from the me defined earlier, but it seems that a variable with a different id has been generated, and the vertex of the object does not change even if I mess with the me. Since it happened, I am forced to refer to the mesh data in the form of meshes ['mesh name']. Both ʻobjects []andmeshes []` can be referenced numerically or by name, such as dictionary types.

            v.select = False
            for g in v.groups:
                if "Skirt" in vg[g.group].name or "skirt" in vg[g.group].name: #Specify the character string of the bone you want to erase here
                    v.select = True 

For every vertex, we are checking to see if there is a vertex group that contains the letters Skirt or skirt. If you use regular expressions around here, you will be able to cover various conditions more coolly. Since a vertex can be included in multiple types of vertex groups (although in reality, one or two examples are overwhelmingly common), it is necessary to go through a loop to investigate. There is. From a vertex, the vertex groups that contain it can be accessed with bpy.data.meshes [x] .vertices [x] .groups, so search for it withfor g in v.groups:.

It's confusing after this, but since you can see the ** number ** of the vertex group in bpy.data.meshes [x] .vertices [x] .groups.group, you've been looking for it before bpy.data You can find the name of the vertex group by referencing it to .objects [x] .vertex_groups. Roundabout!

After that, if you include the specified string, make bpy.data.meshes [x] .vertices [x] .select`` True, otherwise make it False,

        bpy.ops.object.mode_set(mode='EDIT', toggle=False)
        bpy.ops.mesh.delete(type='VERT')
        bpy.ops.object.mode_set(mode='OBJECT', toggle=False)

This command erases the selected part.

trouble shooting

If you run this script in its original state, it seems that all the meshes of the object may disappear for some reason. This seems to be due to the fact that all vertices are selected in the initial state (and ** I can't change it for some reason **), so I can change it by switching to edit mode once and deselecting vertices. Become. What is this specification ... In object mode, with the object with the mesh selected, press ʻa to select all-> press Tabto switch to edit mode-> all vertices are selected, so ʻa All you have to do is pressto deselect-> Tab to return to object mode. The cause of this is research required. If you are familiar with it, please take corrective action ....

Page that was taken care of

[Blender Python Mesh Data Access Cheat Sheet](Blender Python Mesh Data Access Cheat Sheet) Making a python script that can be used in Blender Part 13 (Selecting vertices from mesh information)

Recommended Posts

The Blender script (2.8) that erases only the skirt is completed
[Blender] Script to check if the selected one is a mesh
[Blender] Use OpenGL from inside the script
[Blender] Prepare the Blender script debugging environment (Eclipse + PyDev)
This is the only basic review of Python ~ 1 ~
This is the only basic review of Python ~ 2 ~
This is the only basic review of Python ~ 3 ~
A script that keeps looking up until the URL is bookmarked with Hatena Bookmark