0
$\begingroup$

I'm trying to create a simple script that appends '.L' and '.R' to my existing vertex groups respectively. They already have an existing naming convention that begins with 'b__R' and 'b__L' and I don't want to change that, you can see that's actually an important part of my 'if'.

The mirror modifier does not recognise the L and R in its current format, so I just want to append the .L and .R then be able to remove it when I'm ready to import to my game. I want it to ignore central groups I have that do not have b__R/b__L in the name so that those just mirrors themselves into their existing groups.

Here's what I currently have, and it's not working:

import bpy
obj = bpy.context.active_object

vg = obj.vertex_groups[:]

for g in vg:
    if g.name.beginswith(‘b__R’):
        g.name = g.name+’.R’
    if g.name.beginswith(‘b__L’):
        g.name = g.name+’.L’

To reverse:

import bpy
obj = bpy.context.active_object

vg = obj.vertex_groups[:]

for g in vg:
    if g.name.beginswith(‘b__R’):
        g.name = g.name.replace(’.R’,’’)
    if g.name.beginswith(‘b__L’):
        g.name = g.name.replace(’.L’,’’)

I am COMPLETELY unfamiliar with Python just keep that in mind, I'm just taking guesses here. I'm really just using Python as a means to an end and copied and edited the script from an answer to a similar question on here (linked below).

How to remove a common prefix from vertex-group names?

Also, importantly - your opinion. Is this the best way to do it? I already have an L and R with assigned weights and groups BEFORE deleting half of my mesh (in order to use the modifier). I'm working with a pre existing mesh here. Or should I delete the groups associated with the side of vertices I have deleted to use the modifier, then use the script to also CREATE the other side's groups again? I ask this because I'm not really sure how the data transfer works in the former case and whether those groups will be holding onto information from the deleted vertices.

If it turned out that the latter is the better way to do it (make the script create the other side's groups again), how would I do this?

Sorry for the load of questions, I've avoided this aspect of mirroring the weights in the past because I'm not too clear on its effects in my situation. I'm more than happy to answer any questions for clarification.

Here's the error I'm getting when I Run Script in Blender. error message in Blender

$\endgroup$
0
$\begingroup$

There are three problems currently.

  1. You seem to have pasted the code into a text-editing programm with has encoded the script, then opened it up in Blender. Most likely the ending of your file was .rtf. As you can see in the text editor of Blender, this introduced numerous characters which we don't want. Right now your script starts with {\rtf\ansi ...
    You have to simply open the text editor in Blender, paste the script directly, then press Run Script.
    If you really want to edit your script externally, use the ending .txt or better .py (the python extension).
  2. You have replaced the command startswith with beginswith (accidentally probably).
  3. You are not using single quotes ', but other special characters and . The were probably generated by your text-editor as well. Use a simple texteditor instead, such as Blenders builtin text editor.

Here is the corrected script.

import bpy
obj = bpy.context.active_object

vg = obj.vertex_groups[:]
for g in vg:
    if g.name.startswith('b__R'):
        g.name = g.name+'.R'
    if g.name.startswith('b__L'):
        g.name = g.name+'.L'

However, I would suggest more changes.

  • Using the same script to toggle the ending on and off.
  • Comparing parts of the name with the slice notation.
    E.g. to compare the first four characters: my_name[:4]
  • Replacing the ending letter with the fourth (fixed) L or R character.

These are a lot of obstacles for a beginner, here is the improved (changed) script, the benefit beeing to only need one.

import bpy

obj = bpy.context.active_object
for g in obj.vertex_groups:
    if g.name[:4] in ['b__R', 'b__L']:
        if g.name[-2:] in ['.R', '.L']:
            g.name = g.name[:-2]
        else:
            g.name = g.name + '.' + g.name[3:4]
$\endgroup$
  • $\begingroup$ You're a wiz Leander. I appreciate your explanations on the process and where I made mistakes. The doc was indeed an rtf that I changed to py but that didn't help obviously. I wouldn't be able to implement those further changes myself but that will be really helpful for somebody more experienced. Thanks for providing the toggled script, it works great now and toggles easily. Marked as answered! $\endgroup$ – thetundraco Jun 29 '18 at 1:48
  • $\begingroup$ I've added an update to my original post! Turns out after some testing that the groups do need to be deleted and duplicated. I'm mentioning you because I'd like to give you the opportunity to change it and potentially have it as a response for other "how can I mirror my weights after already weight painting" questions :). @Leander $\endgroup$ – thetundraco Jun 29 '18 at 6:43
  • $\begingroup$ Bump, really would love some help with this please. Thanks. $\endgroup$ – thetundraco Jun 30 '18 at 8:26
  • $\begingroup$ @thetundraco I'd advise to roll back the edit to this question in this case and open up a new one with the new information. As it is, the question seems a little convoluted with different pieces of information. $\endgroup$ – Leander Jun 30 '18 at 23:58
  • $\begingroup$ apologies, it’s my first time posting here and I’m finding the situation a little hard to explain. I’ve opened up my question as a new ask. $\endgroup$ – thetundraco Jul 1 '18 at 0:09
0
$\begingroup$

Ultimately what was missing here was another look at the core issue. Only toggling a suffix on and off was not the answer. My groups had names that differed by one character to their counterpart and regardless of having the correct .L/.R suffix, meant they could not link to each other with the mirror modifier. Deleting the groups was not part of the answer as I had thought.

This is the code you're after if you need to achieve something similar.

In my case, remove the prefix that caused the group names to no longer be linked to their counterparts [4:]. Add the correct suffixes. Revert both of these changes when the script is run again for import back to game.

import bpy
active_object = bpy.context.active_object

vertex_groups = active_object.vertex_groups[:]

for vertex_group in vertex_groups:
    if vertex_group.name.endswith('.L'):
        vertex_group.name = 'b__L' + vertex_group.name.replace('.L', '')
        continue
    if vertex_group.name.endswith('.R'):
        vertex_group.name = 'b__R' + vertex_group.name.replace('.R', '')
        continue
    if (vertex_group.name.startswith('b__L') | vertex_group.name.startswith('b__R')):
        suffix = '.L' if vertex_group.name.startswith('b__L') else '.R'
        vertex_group.name = vertex_group.name[4:] + suffix

Thanks to my lovely sister for this script. Hope it can help someone else out there!

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.