[Bf-extensions-cvs] [093e1eb5] master: Initial commit Animated Text: T51285

meta-androcto noreply at git.blender.org
Sat Apr 22 11:51:10 CEST 2017


Commit: 093e1eb58a8908647b4342c08344042e54183f49
Author: meta-androcto
Date:   Sat Apr 22 19:50:46 2017 +1000
Branches: master
https://developer.blender.org/rBAC093e1eb58a8908647b4342c08344042e54183f49

Initial commit Animated Text: T51285

===================================================================

A	animation_text_types.py

===================================================================

diff --git a/animation_text_types.py b/animation_text_types.py
new file mode 100644
index 00000000..27106bcc
--- /dev/null
+++ b/animation_text_types.py
@@ -0,0 +1,599 @@
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+#  This program is free software; you can redistribute it and/or
+#  modify it under the terms of the GNU General Public License
+#  as published by the Free Software Foundation; either version 2
+#  of the License, or (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# ##### END GPL LICENSE BLOCK #####
+## by LeoMoon Studios, Marcin Zielinski, Martin Wacker, Bassam Kurdali, Jared Felsman, meta-androcto ##
+
+bl_info = {
+    "name": "Animated Text",
+    "author": "LeoMoon Studios, Marcin Zielinski, Martin Wacker, "
+    "Bassam Kurdali, Jared Felsman, meta-androcto",
+    "version": (0, 3, 0),
+    "blender": (2, 74, 5),
+    "location": "Properties Editor > Font",
+    "description": "Typing & Counting Animated Text",
+    "warning": "",
+    "wiki_url": "",
+    "category": "Animation"
+}
+
+import bpy
+import string
+import random
+from bpy.props import (
+    FloatProperty, PointerProperty, BoolProperty,
+    IntProperty, EnumProperty, StringProperty
+)
+from bpy.app.handlers import persistent
+
+
+def formatCounter(input, timeSeparators, timeLeadZeroes, timeTrailZeroes, timeModulo):
+    f = 0
+    s = 0
+    m = 0
+    h = 0
+    out = ''
+    neg = ''
+    if input < 0:
+        neg = '-'
+        input = abs(input)
+
+    if timeSeparators >= 0:
+        if timeSeparators == 0:
+            out = int(input)
+            out = format(out, '0' + str(timeLeadZeroes) + 'd')
+        else:
+            s, f = divmod(int(input), timeModulo)
+            out = format(f, '0' + str(timeLeadZeroes) + 'd')
+
+    if timeSeparators >= 1:
+        if timeSeparators == 1:
+            out = format(s, '0' + str(timeTrailZeroes) + 'd') + ":" + out
+        else:
+            m, s = divmod(s, 60)
+            out = format(s, '02d') + ":" + out
+
+    if timeSeparators >= 2:
+        if timeSeparators == 2:
+            out = format(m, '0' + str(timeTrailZeroes) + 'd') + ":" + out
+        else:
+            h, m = divmod(m, 60)
+            out = format(m, '02d') + ":" + out
+
+    if timeSeparators >= 3:
+        out = format(h, '0' + str(timeTrailZeroes) + 'd') + ":" + out
+
+    return neg + out
+
+
+class TextCounter_Props(bpy.types.PropertyGroup):
+
+    def val_up(self, context):
+        textcounter_update_val(context.object, context.scene)
+
+    ifAnimated = BoolProperty(
+        name='Counter Active', default=False, update=val_up
+    )
+    counter = FloatProperty(
+        name='Counter', update=val_up
+    )
+    padding = IntProperty(
+        name='Padding', update=val_up, min=1
+    )
+    ifDecimal = BoolProperty(
+        name='Decimal', default=False, update=val_up
+    )
+    decimals = IntProperty(
+        name='Decimal', update=val_up, min=0
+    )
+    typeEnum = EnumProperty(
+        items=[
+            ('ANIMATED', 'Animated', 'Counter values from f-curves'),
+            ('DYNAMIC', 'Dynamic', 'Counter values from expression')
+        ],
+        name='Type', update=val_up, default='ANIMATED'
+    )
+    formattingEnum = EnumProperty(
+        items=[
+            ('NUMBER', 'Number', 'Counter values as numbers'),
+            ('TIME', 'Time', 'Counter values as time')
+        ],
+        name='Formatting Type', update=val_up, default='NUMBER'
+    )
+    expr = StringProperty(
+        name='Expression', update=val_up, default=''
+    )
+    prefix = StringProperty(
+        name='Prefix', update=val_up, default=''
+    )
+    sufix = StringProperty(
+        name='Sufix', update=val_up, default=''
+    )
+    ifTextFile = BoolProperty(
+        name='Override with Text File', default=False, update=val_up
+    )
+    textFile = StringProperty(
+        name='Text File', update=val_up, default=''
+    )
+    ifTextFormatting = BoolProperty(
+        name='Numerical Formatting', default=False, update=val_up
+    )
+    timeSeparators = IntProperty(
+        name='Separators', update=val_up, min=0, max=3
+    )
+    timeModulo = IntProperty(
+        name='Last Separator Modulo', update=val_up, min=1, default=24
+    )
+    timeLeadZeroes = IntProperty(
+        name='Leading Zeroes', update=val_up, min=1, default=2
+    )
+    timeTrailZeroes = IntProperty(
+        name='Trailing Zeroes', update=val_up, min=1, default=2
+    )
+
+    def dyn_get(self):
+        context = bpy.context
+        C = context
+        scene = C.scene
+
+        try:
+            return str(eval(self.expr))
+        except Exception as e:
+            print('Expr Error: ' + str(e.args))
+
+    dynamicCounter = StringProperty(name='Dynamic Counter', get=dyn_get, default='')
+
+    def form_up(self, context):
+        textcounter_update_val(context.object, context.scene)
+
+    def form_get(self):
+        f = 0
+        s = 0
+        m = 0
+        h = 0
+        out = ''
+        input = 0
+        if self.typeEnum == 'ANIMATED':
+            input = float(self.counter)
+        elif self.typeEnum == 'DYNAMIC':
+            input = float(self.dynamicCounter)
+        return formatCounter(input, self.timeSeparators, self.timeLeadZeroes, self.timeTrailZeroes, self.timeModulo)
+
+    def form_set(self, value):
+        counter = 0
+        separators = value.split(':')
+        for idx, i in enumerate(separators[:-1]):
+            counter += int(i) * 60**(len(separators) - 2 - idx) * self.timeModulo
+        counter += int(separators[-1])
+        self.counter = float(counter)
+
+    formattedCounter = StringProperty(name='Formatted Counter', get=form_get, set=form_set, default='')
+
+
+def textcounter_update_val(text, scene):
+    text.update_tag(refresh={'DATA'})
+    props = text.data.text_counter_props
+    counter = 0
+    line = ''
+    out = ''
+    neg = ''
+
+    if props.typeEnum == 'ANIMATED':
+        counter = props.counter
+    elif props.typeEnum == 'DYNAMIC':
+        try:
+            counter = eval(props.expr)
+        except Exception as e:
+            print('Expr Error: ' + str(e.args))
+
+    isNumeric = True  # always true for counter not overrided
+    if props.ifTextFile:
+        txt = bpy.data.texts[props.textFile]
+        clampedCounter = max(0, min(int(counter), len(txt.lines) - 1))
+        line = txt.lines[clampedCounter].body
+        if props.ifTextFormatting:
+            try:
+                line = float(line)
+            except Exception:
+                isNumeric = False
+                out = line
+        else:
+            isNumeric = False
+            out = line
+    else:
+        line = counter
+
+    if isNumeric:
+        if props.formattingEnum == 'NUMBER':
+            # add minus before padding zeroes
+            neg = '-' if line < 0 else ''
+            line = abs(line)
+            # int / decimal
+            if not props.ifDecimal:
+                line = int(line)
+            out = ('{:.' + str(props.decimals) + 'f}').format(line)
+
+            # padding
+            arr = out.split('.')
+            arr[0] = arr[0].zfill(props.padding)
+            out = arr[0]
+            if len(arr) > 1:
+                out += '.' + arr[1]
+        elif props.formattingEnum == 'TIME':
+            out = formatCounter(line, props.timeSeparators, props.timeLeadZeroes, props.timeTrailZeroes, props.timeModulo)
+
+    # prefix/sufix
+    if props.ifTextFile:
+        text.data.body = out
+        if props.ifTextFormatting and isNumeric:
+            text.data.body = props.prefix + neg + out + props.sufix
+    else:
+        text.data.body = props.prefix + neg + out + props.sufix
+
+
+ at persistent
+def textcounter_text_update_frame(scene):
+    for text in scene.objects:
+        if text.type == 'FONT' and text.data.text_counter_props.ifAnimated:
+            textcounter_update_val(text, scene)
+
+### text scrambler ###
+
+
+ at persistent
+def textscrambler_update_frame(scene):
+    for text in scene.objects:
+        if text.type == 'FONT' and text.data.use_text_scrambler:
+            uptext(text.data)
+
+
+def update_func(self, context):
+    uptext(self)
+# Register all operators and panels
+
+
+def uptext(text):
+    source = text.source_text
+    if source in bpy.data.texts:
+        r = bpy.data.texts[source].as_string()
+    else:
+        r = source
+
+    base = len(r)
+    prog = text.scrambler_progress / 100.0
+
+    c = int(base * prog)
+
+    clean = r[:base - c]
+    scrambled = ""
+    for i in range(c):
+        scrambled += random.choice(text.characters)
+    text.body = clean + scrambled
+
+### Typing Text ###
+
+
+def animate_text(scene):
+
+    objects = scene.objects
+
+    for obj in objects:
+        if obj.type == "FONT" and "runAnimation" in obj and obj.runAnimation:
+            endFrame = obj.startFrame + (len(obj.defaultTextBody) * obj.typeSpeed)
+            if obj.manualEndFrame:
+                endFrame = obj.endFrame
+
+            if scene.frame_current < obj.startFrame:
+                obj.data.body = ""
+
+            elif scene.frame_current >= obj.startFrame and scene.frame_current <= endFrame:
+                frameStringLength = (scene.frame_current - obj.startFrame) / obj.typeSpeed
+                obj.data.body = obj.defaultTextBody[0:int(frameStringLength)]
+
+            elif scene.frame_current > endFrame:
+                obj.data.body = obj.defaultTextBody
+
+### Typewriter ###
+
+
+def uptext1(text):
+    '''
+   slice the source text up to the character_count
+   '''
+    source = text.source_text
+    if source in bpy.data.texts:
+        text.body = bpy.data.texts[source].as_string()[:text.character_count]
+    else:
+        text.body = source[:text.character_count]
+
+
+ at persistent
+def

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-extensions-cvs mailing list