11
$\begingroup$

With objects, there you can add Custom Properties to an object, though it only seems to let you specify numeric values.

Is there any way that I can add a color value as a custom property, such as through Blender's python API?

EDIT: To clarify what I am doing: I am making a set of character models for use in a web comic I am making. The character models will be "generic" ones for ordinary characters (ie: bystanders, pedestrians, etc.). What I want to do is put some color field properties onto the armature (which is the parent of all the model pieces and clothing), and then use drivers in the model pieces so that they can pull the color data for the clothing, eyes, and skin.

I wish to use this method because I want to use models in a linked fashion, where I import one or more generic models and set the colors in the scene they are used in after importing, so that I don't fill up my hard drive (or my cloud drive) with dozens of .blend files for every color variation I use.

EDIT 2: To clarify further, I wish for a solution that can be applied on a per-model basis, rather than needing to create an addon that adds the same set of properties to all models.

$\endgroup$
3
  • $\begingroup$ This should help: wiki.blender.org/index.php/Doc:2.6/Manual/Extensions/Python/… $\endgroup$
    – Mike Pan
    Feb 12, 2014 at 5:16
  • 1
    $\begingroup$ Does it need to appear in the Custom Properties panel? I would use a FloatVectorProperty() instead, which wouldn't show in tha panel, but can be added to any panel with a custom draw function. It would give you a color field, click to open color picker. $\endgroup$
    – CodeManX
    Feb 12, 2014 at 8:56
  • $\begingroup$ CoDEmanX: Yes, that's pretty much what I want. How do I set that up? $\endgroup$ Feb 12, 2014 at 14:04

4 Answers 4

11
$\begingroup$

Here is condensed heavily edited sample add-on an artist requested t use blender as the middleman to mass convert vertex colors data from custom data source, the latter being removed as its not related to the question.

The color value was selected using FloatVectorProperty, specifically with subtype COLOR. This also has the advantage that if exposed through the UI is visualised by the nice UI Color wheel/hex-widget.

The code is split into properties.py and ui.py as this is done for ease of maintainance and separation of concerns, ie storage and display. You can store the custom property anywhere you want I choose object as per the question, the same applies for where the ui appears.

You can also combine it into one script, just need to change registration from module to class and supply each class name.

I generally use a properties group when working with multiple properties, but you can just define a single custom property to attach. properties.py

import bpy
from bpy.props import FloatVectorProperty, StringProperty, PointerProperty

class ObjectProperties(bpy.types.PropertyGroup):
    @classmethod
    def register(cls):

        bpy.types.Object.custom = PointerProperty(
            name="Custom properties",
            description="Custom Properties for Objects",
            type=cls,
            )

        #Add in the properties you want      
        cls.hexwidget = FloatVectorProperty(name="Hex Value", 
                                        subtype='COLOR', 
                                        default=[0.0,0.0,0.0])

        cls.test_string = StringProperty(name="Test String",
                                        default="I am a string")

    @classmethod
    def unregister(cls):
        del bpy.types.Object.custom

def register():
    bpy.utils.register_class(ObjectProperties)

def unregister():
    bpy.utils.unregister_class(ObjectProperties)

This module has specific registration handling as we prefer to get rid of custom info if the addon is not install, design decision.

Here is the UI which will display the value stored in the defined property ui.py

import bpy

class UtilityPanel(bpy.types.Panel):
    bl_label = "Utilites Panel"
    bl_idname = "OBJECT_PT_utilities"

    bl_space_type = "PROPERTIES"
    bl_region_type = "WINDOW"
    bl_context = "object"

    def draw(self, context):
        layout = self.layout       

        box = layout.box()
        row = box.row()
        row.prop(context.active_object.custom, "hexwidget")
        row = box.row()
        row.prop(context.active_object.custom, "test_string")

__init__.py for completeness

#--- ### Header
bl_info = {
    "name": "Custom Property: Color",
    "category": "Object",
}

import bpy
import bpy.props

from <folder_name> import ui, properties

def register():
    properties.register()
    bpy.utils.register_module(__name__)


def unregister():
    properties.unregister()
    bpy.utils.unregister_module(__name__)

if __name__ == "__main__":
    register()

When enabled the add-on adds a custom propertygroup to each Object, which can be altered or expanded as you need.

Custom Panel Object Tab

$\endgroup$
11
  • $\begingroup$ Okay, going to try this out. Will ask if I have any trouble. $\endgroup$ Feb 12, 2014 at 18:58
  • $\begingroup$ Okay, I have all three scripts copied into the text editor and registered. How do I hook them up to an object, though? $\endgroup$ Feb 12, 2014 at 19:03
  • $\begingroup$ This is the bare bones of an addon. Create a new folder in your addon directory and enable the new add-on. $\endgroup$
    – neomonkeus
    Feb 12, 2014 at 19:11
  • $\begingroup$ Okay, and after that, how do I use it? Also, I am going to edit the original question to put my use case down so that it fits into the context. $\endgroup$ Feb 12, 2014 at 19:12
  • $\begingroup$ You need to edit the <folder_name> of init to whatever you called the folder you created. Some slight corrections, works and displays in the Properties -> Object tab. See screenshot $\endgroup$
    – neomonkeus
    Feb 12, 2014 at 20:10
5
$\begingroup$

I'm not sure if this is a recent feature (tested on blender 3.1) or not (otherwise I don't see why nobody mentioned it before), but you can add a color property without using any sort of python, with or without alpha by simply using the type Float Array, set dimension to 3 (4 if you want alpha), and the Subtype should be Linear Color or Gamma Corrected Colors:

enter image description here

enter image description here

$\endgroup$
1
  • $\begingroup$ This is actually the correct answer to the original question. Thank you! That Subtype field only shows up when using 'Float Array'-- totally eluded me. I wish it was higher up in the list of parameters. $\endgroup$
    – j-conrad
    Apr 27, 2022 at 21:52
4
$\begingroup$

I don't know whether this would be the intended way, but at least it works:

You could add a string representation of other datatypes than integer from the edit dialog, there you could paste a color value Ctrl-V copied from e.g. material settings, this would add a list with 4 floats.

enter image description here

To access your custom properties attached to your object e.g.

o=bpy.data.objects["Cube"]
c = Color( o["customColor"][:3] )
print( c )
>>> <Color (r=0.8000, g=0.2236, b=0.2440)>

To set a color programmatically:

c = Color((1,2,3))
o["customColor"]=c

c2=o["customColor"]
print(c2)
>>> <bpy id property array [3]>

print(Color(c2))
>>> <Color (r=1.0000, g=2.0000, b=3.0000)>

See also:

$\endgroup$
4
$\begingroup$

Just want do add:

Similar to python properties, the properties from bpy.props basically provide setter/getter methods for custom properties which actually are items of an ID dictionary.

Creating such a property

bpy.types.Object.test = bpy.props.IntProperty()

has no effect on an object until you assign a value to its test attribute

obj.test = 4
#calls the default setter if not specified which sets the custom property
obj["test"] = 4

The getter method returns the default value if nothing has been set for this attribute

obj.test
#calls the default setter if not specified which either returns the custom property,
#if it exists, or the default value
if "test" in obj:
    return obj["test"]
else:
    return default_value

Custom properties will be saved to the .blend file.

Correct me if i am wrong.

In this case:

#addon bl_info to be inserted here - see Templates -> Addon Add Object
import bpy

def hndl_draw(self, context):
    row = self.layout.row()
    #if "myColor" in context.object.data:
    row.prop(context.object.data, "myColor")

def register():   
    bpy.types.Armature.myColor = bpy.props.FloatVectorProperty(
                                     name = "myColor",
                                     subtype = "COLOR",
                                     size = 4,
                                     min = 0.0,
                                     max = 1.0,
                                     default = (0.75,0.0,0.8,1.0)
                                     )
    bpy.types.DATA_PT_display.append(hndl_draw)

def unregister():
    bpy.types.DATA_PT_display.remove(hndl_draw)
    del bpy.types.Armature.myColor

if __name__ == "__main__":
    register()

For all armatures the specified default color will be displayed in Properties Area -> Armature -> Display
ColorPicker

If you don't change the color no data will be added to the armature.

You can hide this color picker for objects without the custom property "myColor" by uncommenting the if-line. However you will have to set obj.data["myColor"] = (0.0,0.0,0.0,1.0) manually then (via console, script or UI).

$\endgroup$
6
  • $\begingroup$ How would I apply this to a specific object? $\endgroup$ Feb 13, 2014 at 18:25
  • $\begingroup$ You can simply assign a custom property. obj["myColor"] = (100, 255, 0). If you create a bpy.props.IntVectorProperty the end result will be the same when saved to the .blend file. $\endgroup$ Feb 13, 2014 at 18:51
  • $\begingroup$ My problem is I'm trying to get it to show up with a color picker. $\endgroup$ Feb 13, 2014 at 18:59
  • $\begingroup$ Added an example. $\endgroup$ Feb 13, 2014 at 19:32
  • $\begingroup$ Tried that, and it appears to work. However, it appears that if the code is run more than once, the MyColor fields get added multiple times. $\endgroup$ Feb 13, 2014 at 19:45

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .