Hello!
I’m trying to make a little add-on for myself where I enter an integer and I receive a bunch of buttons that will assign vertex weights to selected vertices when the buttons are clicked from 0-1 in increments dependent on what number I input.
I can get the buttons working perfectly. What I can’t seem to do right is the user input. Please help!
Here’s my code:
import bpy
def main(context, denom):
"""The vertex weight is set based upon variable denom (like denominator in fractions/divisions) and then assigned to a vertex"""
bpy.context.tool_settings.vertex_group_weight=denom
bpy.ops.object.vertex_group_assign()
class SetNAssign(bpy.types.Operator):
"""Setting up my operation to use elsewhere"""
bl_idname = "myops.set_n_assign"
bl_label = "Set Vertex Weight and Assign to Vertex"
@classmethod
def poll(cls, context):
return context.active_object is not None
def execute(self, context):
main(context)
return {'FINISHED'}
class vWeightIncPanel(bpy.types.Panel):
"""Creates a Panel in the data context of the properties editor where a user may input a denominator for the creation of easy access incremental vertex weights"""
bl_label = "Vertex Weight Increments"
bl_idname = "DATA_vWeightInc"
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "data"
def draw(self, context):
from bpy.props import (StringProperty)
layout = self.layout
scene = context.scene
mytool = scene.my_tool
layout.prop(mytool, 'my_string') #this is where I'm trying to get the user's input but to no avail. mytool needs to be defined or something
denom = 10 #this where I'd like to store the user's input though I'm not really sure as to how
my_string = StringProperty(
name="Number of Verticies",
description=":",
default="",
maxlen=1024,
) #this is how others import a string input
row = layout.row()
row.label(text="Vertex Weight Increments")
split = layout.split(align=True)
col = split.column()
for num in range(denom+1): #this creates a button for each vertex weight
col.label(text = str(num)) #this was just to show me when the operator wasn't working
col.operator("myops.set_n_assign()", text = str(num) + "/" + str(denom)) #this works however I don't know how to pass set_n_assign() denom so that it changes interactively
#I will also need an go button somewhere around here to take the user input and do its thing
def register():
bpy.utils.register_class(SetNAssign)
bpy.utils.register_class(vWeightIncPanel)
def unregister():
bpy.utils.unregister_class(SetNAssign)
bpy.utils.unregister_class(vWeightIncPanel)
if __name__ == "__main__":
register()
# test call
# bpy.ops.myops.set_n_assign()
1 Like
Well, I’ve made some progress and I got the user input to work, however, now it won’t run my operator in order to apply the vertex weight to the vertices. Any thoughts?
import bpy
from bpy.props import (StringProperty, PointerProperty)
from bpy.types import (Panel, PropertyGroup)
class MySettings(PropertyGroup):
my_string = StringProperty(
name="User Input",
description=":",
default="",
maxlen=1024
)
class SetNAssign(bpy.types.Operator):
"""Setting up my operation to use elsewhere"""
bl_idname = "myops.set_n_assign"
bl_label = "Set Vertex Weight and Assign to Vertex"
def execute(self, context):
scene = context.scene
mytool = scene.my_tool
numb = mytool.my_string
bpy.context.tool_settings.vertex_group_weight = mytool.my_string
bpy.ops.object.vertex_group_assign()
print("numb = ", mytool.my_string)
return {"FINISHED"}
class vWeightIncPanel(Panel):
bl_label = "Vertex Weight Increments"
bl_idname = "DATA_vWeightInc"
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "data"
@classmethod
def poll(self, context):
return context.active_object is not None
def draw(self, context):
layout = self.layout
scene = context.scene
mytool = scene.my_tool
layout.prop(mytool, "my_string")
denom = mytool.my_string
#print(denom)
row = layout.row()
row.label(text="Vertex Weight Increments")
row.prop(scene, "Text", slider = True)
split = layout.split(align=True)
col = split.column()
for num in range(int(denom)+1):
col.label(text = str(num))
col.operator("myops.set_n_assign()", text = str(num) + "/" + str(denom))
def register():
#bpy.utils.register_module(__name__)
bpy.utils.register_class(SetNAssign)
bpy.utils.register_class(vWeightIncPanel)
#bpy.types.Scene.my_tool = PointerProperty(type=MySettings)
def unregister():
#bpy.utils.unregister_module(__name__)
bpy.utils.unregister_class(SetNAssign)
bpy.utils.unregister_class(vWeightIncPanel)
#del bpy.types.Scene.my_tool
if __name__ == "__main__":
register()
# test call
# bpy.ops.myops.set_n_assign()
Okay, so I’ve made some great progress! The user input shows up (I copied this other guy’s code in how he did it. Sometimes it worked and sometimes it didn’t, but now it does every time…idk why lol), the buttons populate according to the user input. The problem now is that I need to pass set_n_assign (or SetNAssign) the for loop’s iteration count so that it will assign the correct weight to each button. I’ve done single line comments on the lines that are problematic. Any ideas anyone?
import bpy
from bpy.props import (StringProperty, PointerProperty)
from bpy.types import (Panel, PropertyGroup)
class MySettings(PropertyGroup):
my_string = StringProperty(
name="User Input",
description=":",
default="",
maxlen=1024
)
class SetNAssign(bpy.types.Operator):
"""Setting up my operation to use elsewhere"""
bl_idname = "myops.set_n_assign"
bl_label = "Set Vertex Weight and Assign to Vertex"
def execute(self, context):
scene = context.scene
mytool = scene.my_tool
numb = 1 / int(mytool.my_string) # HERE! '1' needs to be a variable so that it changes each time with the for loop below but how can I pass that value to it?
bpy.context.tool_settings.vertex_group_weight = float(numb)
bpy.ops.object.vertex_group_assign()
print("numb = ", mytool.my_string)
return {"FINISHED"}
class vWeightIncPanel(Panel):
bl_label = "Vertex Weight Increments"
bl_idname = "DATA_vWeightInc"
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "data"
@classmethod
def poll(self, context):
return context.active_object is not None
def draw(self, context):
layout = self.layout
scene = context.scene
mytool = scene.my_tool
layout.prop(mytool, "my_string")
denom = mytool.my_string
#print(denom)
row = layout.row()
row.label(text="Vertex Weight Increments")
row.prop(scene, "Text", slider = True)
split = layout.split(align=True)
col = split.column()
for num in range(int(denom)+1): # HERE! How can I give num to set_n_assign so that it can give each button the correct weight?
col.label(text = str(num))
col.operator("myops.set_n_assign", text = str(num) + "/" + str(denom))
def register():
bpy.utils.register_class(SetNAssign)
bpy.utils.register_class(vWeightIncPanel)
def unregister():
bpy.utils.unregister_class(SetNAssign)
bpy.utils.unregister_class(vWeightIncPanel)
if __name__ == "__main__":
register()
# bpy.ops.myops.set_n_assign()
Not sure if you’ve already found them, but I’m working on something similar and I found these two pages invaluable:
https://wiki.blender.org/index.php/Dev:Py/Scripts/Cookbook/Code_snippets/Interface
(this one in particular, have a look at the section on pop up dialogues)