I am trying to model my own 20 sided die and to add the numbers on each face. I am having trouble getting them centered on each triangular face. Any suggestions on how to achieve this?
2 Answers
Here is the script to do that
import bpy
import bmesh
def addText(text, location, rotation, mat, fact = .2, extrude = .005):
myFont = bpy.data.curves.new(type="FONT", name="myFont")
fontOb = bpy.data.objects.new(fontObjName, myFont)
fontOb.data.body = text
bpy.context.scene.objects.link(fontOb)
bpy.context.scene.update()
fontOb.select = True
bpy.context.scene.objects.active = fontOb
fontOb.dimensions = (fontOb.dimensions[0] * fact, fontOb.dimensions[1] * fact, fontOb.dimensions[2] * fact)
fontOb.data.extrude = extrude
bpy.ops.object.origin_set(type='ORIGIN_GEOMETRY')
fontOb.location = location
fontOb.rotation_mode = 'QUATERNION'
fontOb.active_material = mat
fontOb.rotation_quaternion = rotation.to_track_quat('Z','Y')
fontOb.select = False
return fontOb
def labelObjFaces(obj, mat):
bpy.ops.object.mode_set(mode = 'EDIT', toggle = False)
bm = bmesh.from_edit_mesh(obj.data).copy()
bpy.ops.object.mode_set(mode = 'OBJECT', toggle = False)
for f in bm.faces:
fontOb = addText(str(f.index), f.calc_center_median(), f.normal, mat)
fontOb.parent = obj
fontObjName = "__fontObj123"
matName = '__labelMat123'
deleteOldFs = [fObj for fObj in bpy.data.objects if fObj.name.startswith(fontObjName)]
#clean-up
for delF in deleteOldFs:
bpy.data.objects.remove(delF)
if(matName in bpy.data.materials):
bpy.data.materials.remove(bpy.data.materials[matName])
mat = bpy.data.materials.new(matName)
mat.diffuse_color = (0.3731134057044983, 0.59569658041000366, 0.3000000715255737)
labelObjFaces(bpy.context.object, mat)
To execute the script.
- open the blend file that has your object
- switch to script view
- click new button
- paste the code
- deselect all the objects (move the mouse to 3d view and press a)
- select the object on which you want to put the labels by right clicking on it
- click the 'Run Script' button
-
$\begingroup$ Thanks this is exactly what I want! However I am really new to blender how to I apply this script so I can use it? $\endgroup$– ChrisOct 3, 2018 at 11:44
-
$\begingroup$ Glad that it's of use to you. I have updated the answer. $\endgroup$ Oct 3, 2018 at 12:23
-
$\begingroup$ Sorry I do have one more question, I can only run this script once. After I run it for the first time there is an error on line 31 (mat = bpy.data.materials...). How do I fix this so I can run this script over and over? $\endgroup$– ChrisOct 4, 2018 at 1:06
-
$\begingroup$ Actually I forgot to test that condition :) I have fixed it now. Also the labels are parented to the object, so if you move/rotate/scale the object the labels undergo the same transformation. You can change the color by setting different value of mat.diffuse_color. Make sure you select the object (and nothing else) before running the script. The fact value will change the size of the label. If you want the size to be different based on the face size, you will have to calculate face area and make the factor dependent on it. You can play with the other settings. Please let me know if any issues. $\endgroup$ Oct 4, 2018 at 5:05
UV mapping.
As an alternative to using 20 font objects, I propose this can also be done with a UV map and an image editor. Here is a very quick run down on how this can be achieved.
For a 20 sided dice like above can add a single division icosphere. Check generate UVs
Here is the generated UV map. For whatever reason drawing on this map comes out A about T, so select all and scale -1 in X to mirror. A S X - 1
Choose the menu Image Editor > UV > Export Layout to File
choose a filename, then open in your fave image editor.
Add the numbers to the triangles.