[AddOn] RE:Phrase+ 1.3 for Blender 2.6.1 (CAPs,Kerning and More!)

Hello All,

Here is another revision to the RE:Phrase+ AddOn. Fixed for Blender 2.6.1 API. r43973.


New Features Are: Sub mesh vertex parenting allows entire phrase to use mesh based modifiers to affect layout.
Cap generation for characters with z-offset cap lift-off.
Automatic material mapping from the RE:Phrase+ master object to all characters (slot1=base,slot2=cap).
Render bug fix reduces the chance of ever having two character exactly overlapping (removes that black flicker in animations)
Multiple phrases support.
Selection tool to select all characters that make up a phrase.
Can use the first particle system of a mesh emitter for the LOC/ROT of characters on a per-phrase basis.
Experimental crash recovery system.
New auto-kerning feature for the layout engine.
Spin characters around their baseline.
Justification and per-word or per-character deployment.
Handler based processing.

After adding RE:Phrase+ to the scene via the SHIFT-A nothing apparently happens. But, behind the scenes, a frame_rephrase.py script has been installed to enable the RE:Phrase+ font extensions for the standard font object. Just use Blender as normal, you only have to install RE:Phrase+ once per BLEND file. When you save your BLEND file the frame_rephrase.py script will be saved with it.

Basic Usage: (after adding RE:Phrase+ to the scene)Create a standard Font object.
Activate the Object Context TAB and scroll to the bottom.
Click the button to convert the standard font into a RE:Phrase+ object.
A new panel will appear with lots of options.
Play with or animate the sliders to change the RE:Phrase+ font in the scene.
Animate the Active Phrase Index (very bottom) to cause phrases to change over time.

Re:Phrase continues to be totally awesome - now I just pray that there aren’t any compatibility issues with 2.62!

Here’s one instance where I used it in a video I did for fun: www.youtube.com/watch?v=TJAHpzXbPLE&t=1m16s

Thanks so much!

Cool, nice to see others using it.

I am using 2.6.2 and it seems to work fine. I actually tested all my AddOns with 2.6.2 release and with a quick review they all came up and functioned without errors.

I am currently working on my own typography animation that I hope to release very soon. I have been doing some more tinkering with the code. Minor fixes for render stability and a new feature that puts a halo spotlight behind each character.

I love what you have made here. Great work. So no chance of a refresh button to update things like materials etc? Save you fiddling with values you tweaked. Also a copy function between phrase objects would be usefull. So you could propogate many iterations of a base text then vary it later.

Where is the link to download the addon?

Hey there!
For my bachelor thesis I’m working on a 3D presentation Blender plugin and right now I’m trying to figure out, how to fix the kerning. I realize this post is 10 years old, but thought it might be worth a shot…
From the screenshot it seems that you either found a solution, or just fixed it manually.
Either way I would really appreciate any comments on tips on how to (automatically) fix texts kerning in Blender with a script or something…
Thanks :slight_smile:

Sure, lets revive this necro thread.

Here is the basic concept I took, code wise. I visually grouped characters into categories and gave them weights.

def returnCharacterWidthViaImportance (passedCharacters, passedStyleWeight, passedWordSpacing):
    # Rank character weight by most important to least important, following these guide lines by Emil Ruder.
    # Gaps occur, for example, around letters whose forms angle outward or frame an open space (W, Y, V, T, L).
    # In short always try to have a keen eye for the spacing between lettering at large sizes.
    # Emil Ruder refers to a pattern of grey.
    # A wider set text will produce a lighter grey.
    # And closer set will produce a denser black grey.
    # The correct measure for a text should be something between 7-12 words per line.
    # Leading is the pace between lines of text in a given paragraph.
    # Generally a leading of 120% is roughly correct.                        
    # The counter or interior "white" also shares in the form of a letter in greyscale considered layouts.
    result = 0.0
    for ch in passedCharacters:
        # Set defaults if character fails all tests.
        width_modifier = 1.0        # Weight based upon the width of the character.
        greyscale_modifier = 1.0    # Weight based upon the greyscale value of the character.
        # Do not have the same character in two strings.
        s_LEVEL0 = "W"                          # Extreme width characters go here.
        s_LEVEL1 = "YVTLF7Zmw"                  # Large characters with sloping angles deserve more space.
        s_LEVEL2 = "ABCDEGHJKMNOPQRSUX"         # Other large characters.
        s_LEVEL3 = "nhkrpqdba#@&%_=-+~?"        # Other medium characters.
        s_LEVEL4 = "ijlI`1!+[](){}|\:'/.,*^"    # Thinner characters.
        s_LEVEL5 = " "                          # Control spacing directly.
        if s_LEVEL0.find(ch) != -1: width_modifier = 1.75
        if s_LEVEL1.find(ch) != -1: width_modifier = 1.25      # Make up these values for yourself.
        if s_LEVEL2.find(ch) != -1: width_modifier = 1.0
        if s_LEVEL3.find(ch) != -1: width_modifier = 0.9
        if s_LEVEL4.find(ch) != -1: width_modifier = 0.75
        if s_LEVEL5.find(ch) != -1: width_modifier = 1.0 * passedWordSpacing       # Space for width based layout.
        # Do not have the same character in two strings.
        s_OPEN0 = "0OPBCDRQUGS"                 # Characters with large round open areas.
        s_OPEN1 = "HWMNFKEZX%=#&@"              # Characters with dense blocky areas.
        s_OPEN2 = "abdp689"                     # Characters with small round open areas.
        s_OPEN3 = "4Ae57<>vxzw"                 # Characters with angular open areas.
        s_OPEN4 = " "                           # Control spacing directly.
        if s_OPEN0.find(ch) != -1: greyscale_modifier = 1.2    # Make up these values for yourself.
        if s_OPEN1.find(ch) != -1: greyscale_modifier = 1.1
        if s_OPEN2.find(ch) != -1: greyscale_modifier = 0.9
        if s_OPEN3.find(ch) != -1: greyscale_modifier = 0.8
        if s_OPEN4.find(ch) != -1: greyscale_modifier = 1.15 * passedWordSpacing    # Space is worth a little more in a greyscale considered layout.
        # We now have two measurements of our character weight.
        # Mix them together based upon the passedWeighStyle.
        if passedStyleWeight < 0.0: passedStyleWeight = 0.0
        if passedStyleWeight > 1.0: passedStyleWeight = 1.0
        wm = width_modifier * (1.0-passedStyleWeight)
        gm = greyscale_modifier * passedStyleWeight
        result = result + (wm + gm)  # Add the two weights together for the final result.
    return result
def returnTotalCharactersWidth(passedListOfChars, passedEntry):
    result = 0.0
    widthList = []
    #Scan the list of characters.
    for ch in passedListOfChars:
        # Get each characters width from our new kerning def.
        tempWidth = returnCharacterWidthViaImportance(ch,passedEntry.style_weight, passedEntry.space_word) * passedEntry.space_character
        result = result + tempWidth 
    return result,widthList
1 Like