Skip to content
Snippets Groups Projects
bTrace.py 52.9 KiB
Newer Older
  • Learn to ignore specific revisions
  • 
                    # Black and white color
                    def colorblenderBW():
    
                        if engine == 'CYCLES' or engine == 'BLENDER_EEVEE':
                            Principled_BSDF = madMat.node_tree.nodes[1]
    
                            mat_color = rand_choice(bwColors)
                            r, g, b = mat_color[0], mat_color[1], mat_color[2]
    
                            Principled_BSDF.inputs[0].default_value = [r, g, b, 1]
                            madMat.diffuse_color = mat_color[0], mat_color[1], mat_color[2], 1
    
                        else:
                            madMat.diffuse_color = rand_choice(bwColors)
    
                    # Bright colors
                    def colorblenderBright():
    
                        if engine == 'CYCLES' or engine == 'BLENDER_EEVEE':
                            Principled_BSDF = madMat.node_tree.nodes[1]
    
                            mat_color = rand_choice(brightColors)
                            r, g, b = mat_color[0], mat_color[1], mat_color[2]
    
                            Principled_BSDF.inputs[0].default_value = [r, g, b, 1]
                            madMat.diffuse_color = mat_color[0], mat_color[1], mat_color[2], 1
    
                        else:
                            madMat.diffuse_color = rand_choice(brightColors)
    
                    # Earth Tones
                    def colorblenderEarth():
    
                        if engine == 'CYCLES' or engine == 'BLENDER_EEVEE':
                            Principled_BSDF = madMat.node_tree.nodes[1]
    
                            mat_color = rand_choice(earthColors)
                            r, g, b = mat_color[0], mat_color[1], mat_color[2]
    
                            Principled_BSDF.inputs[0].default_value = [r, g, b, 1]
                            madMat.diffuse_color = mat_color[0], mat_color[1], mat_color[2], 1
    
                        else:
                            madMat.diffuse_color = rand_choice(earthColors)
    
                    # Green to Blue Tones
                    def colorblenderGreenBlue():
    
                        if engine == 'CYCLES' or engine == 'BLENDER_EEVEE':
                            Principled_BSDF = madMat.node_tree.nodes[1]
    
                            mat_color = rand_choice(greenblueColors)
                            r, g, b = mat_color[0], mat_color[1], mat_color[2]
    
                            Principled_BSDF.inputs[0].default_value = [r, g, b, 1]
                            madMat.diffuse_color = mat_color[0], mat_color[1], mat_color[2], 1
    
                        else:
                            madMat.diffuse_color = rand_choice(greenblueColors)
    
                    # define frame start/end variables
                    scn = context.scene
                    start = scn.frame_start
                    end = scn.frame_end
    
                    # Go to each frame in iteration and add material
                    while start <= (end + (skip - 1)):
                        bpy.context.scene.frame_set(frame=start)
    
                        # Check what colors setting is checked and run the appropriate function
                        if Btrace.mmColors == 'RANDOM':
                            colorblenderRandom()
                        elif Btrace.mmColors == 'CUSTOM':
                            colorblenderCustom()
                        elif Btrace.mmColors == 'BW':
                            colorblenderBW()
                        elif Btrace.mmColors == 'BRIGHT':
                            colorblenderBright()
                        elif Btrace.mmColors == 'EARTH':
                            colorblenderEarth()
                        elif Btrace.mmColors == 'GREENBLUE':
                            colorblenderGreenBlue()
                        else:
                            pass
    
                        # Add keyframe to material
    
                        if engine == 'CYCLES' or engine == 'BLENDER_EEVEE':
    
                            madMat.node_tree.nodes[
    
                                    1].inputs[0].keyframe_insert('default_value')
    
                            # not sure if this is need, it's viewport color only
                            madMat.keyframe_insert('diffuse_color')
                        else:
                            madMat.keyframe_insert('diffuse_color')
    
                        # Increase frame number
                        start += skip
    
                return{'FINISHED'}
    
            except Exception as e:
                error_handlers(self, "object.colorblender", e,
                               "Color Blender could not be completed")
    
                return {'CANCELLED'}
    
    # This clears the keyframes
    class OBJECT_OT_clearColorblender(Operator):
        bl_idname = "object.colorblenderclear"
        bl_label = "Clear colorblendness"
        bl_description = "Clear the color keyframes"
    
        bl_options = {'REGISTER', 'UNDO'}
    
        def invoke(self, context, event):
    
            try:
                colorObjects = context.selected_objects
                engine = context.scene.render.engine
    
                # Go through each selected object and run the operator
                for i in colorObjects:
                    theObj = i
                    # assign the first material of the object to "mat"
                    matCl = theObj.data.materials[0]
    
                    # define frame start/end variables
                    scn = context.scene
                    start = scn.frame_start
                    end = scn.frame_end
    
                    # Remove all keyframes from diffuse_color, super sloppy
                    while start <= (end + 100):
                        context.scene.frame_set(frame=start)
                        try:
    
                            if engine == 'CYCLES' or engine == 'BLENDER_EEVEE':
    
                                matCl.node_tree.nodes[
    
                                    1].inputs[0].keyframe_delete('default_value')
    
                            elif engine == 'BLENDER_RENDER':
                                matCl.keyframe_delete('diffuse_color')
                        except:
                            pass
                        start += 1
    
                return{'FINISHED'}
    
            except Exception as e:
                error_handlers(self, "object.colorblenderclear", e,
                               "Reset Keyframes could not be completed")
    
                return {'CANCELLED'}
    
    # F-Curve Noise
    # will add noise modifiers to each selected object f-curves
    # change type to: 'rotation' | 'location' | 'scale' | '' to effect all
    # first record a keyframe for this to work (to generate the f-curves)
    
    class OBJECT_OT_fcnoise(Operator):
    
        bl_idname = "object.btfcnoise"
        bl_label = "Btrace: F-curve Noise"
        bl_options = {'REGISTER', 'UNDO'}
    
        def execute(self, context):
    
            try:
                Btrace = context.window_manager.curve_tracer
                amp = Btrace.fcnoise_amp
                timescale = Btrace.fcnoise_timescale
                addkeyframe = Btrace.fcnoise_key
    
                # This sets properties for Loc, Rot and Scale
                # if they're checked in the Tools window
                noise_rot = 'rotation'
                noise_loc = 'location'
                noise_scale = 'scale'
                if not Btrace.fcnoise_rot:
                    noise_rot = 'none'
                if not Btrace.fcnoise_loc:
                    noise_loc = 'none'
                if not Btrace.fcnoise_scale:
                    noise_scale = 'none'
    
                # Add settings from panel for type of keyframes
                types = noise_loc, noise_rot, noise_scale
                amplitude = amp
                time_scale = timescale
    
                for i in context.selected_objects:
                    # Add keyframes, this is messy and should only
                    # add keyframes for what is checked
                    if addkeyframe is True:
                        bpy.ops.anim.keyframe_insert(type="LocRotScale")
                    for obj in context.selected_objects:
                        if obj.animation_data:
                            for c in obj.animation_data.action.fcurves:
                                if c.data_path.startswith(types):
                                    # clean modifiers
                                    for m in c.modifiers:
                                        c.modifiers.remove(m)
                                    # add noide modifiers
                                    n = c.modifiers.new('NOISE')
                                    n.strength = amplitude
                                    n.scale = time_scale
                                    n.phase = rand_randint(0, 999)
    
                return {'FINISHED'}
    
            except Exception as e:
                error_handlers(self, "object.btfcnoise", e,
                               "F-curve Noise could not be completed")
    
                return {'CANCELLED'}
    
    
    # Curve Grow Animation
    # Animate curve radius over length of time
    
    class OBJECT_OT_curvegrow(Operator):
        bl_idname = "curve.btgrow"
        bl_label = "Run Script"
        bl_description = "Keyframe points radius"
    
        bl_options = {'REGISTER', 'UNDO'}
    
        @classmethod
        def poll(cls, context):
            return (context.object and context.object.type in {'CURVE'})
    
        def execute(self, context):
    
            try:
                # not so nice with the nested try blocks, however the inside one
                # is used as a switch statement
                Btrace = context.window_manager.curve_tracer
                anim_f_start, anim_length, anim_auto = Btrace.anim_f_start, \
                                                       Btrace.anim_length, \
                                                       Btrace.anim_auto
                curve_resolution, curve_depth = Btrace.curve_resolution, \
                                                Btrace.curve_depth
                # make the curve visible
                objs = context.selected_objects
                # Execute on multiple selected objects
                for i in objs:
    
                    context.view_layer.objects.active = i
    
                    obj = context.active_object
                    try:
                        obj.data.fill_mode = 'FULL'
                    except:
                        obj.data.dimensions = '3D'
                        obj.data.fill_mode = 'FULL'
                    if not obj.data.bevel_resolution:
                        obj.data.bevel_resolution = curve_resolution
                    if not obj.data.bevel_depth:
                        obj.data.bevel_depth = curve_depth
                    if anim_auto:
                        anim_f_start = bpy.context.scene.frame_start
                        anim_length = bpy.context.scene.frame_end
                    # get points data and beautify
                    actual, total = anim_f_start, 0
                    for sp in obj.data.splines:
                        total += len(sp.points) + len(sp.bezier_points)
                    step = anim_length / total
                    for sp in obj.data.splines:
                        sp.radius_interpolation = 'BSPLINE'
                        po = [p for p in sp.points] + [p for p in sp.bezier_points]
                        if not Btrace.anim_keepr:
                            for p in po:
                                p.radius = 1
                        if Btrace.anim_tails and not sp.use_cyclic_u:
                            po[0].radius = po[-1].radius = 0
                            po[1].radius = po[-2].radius = .65
                        ra = [p.radius for p in po]
    
                        # record the keyframes
                        for i in range(len(po)):
    
                            po[i].radius = 0
    
                            po[i].keyframe_insert('radius', frame=actual)
                            actual += step
                            po[i].radius = ra[i]
                            po[i].keyframe_insert(
                                        'radius',
                                        frame=(actual + Btrace.anim_delay)
                                        )
    
                            if Btrace.anim_f_fade:
                                po[i].radius = ra[i]
                                po[i].keyframe_insert(
                                        'radius',
                                        frame=(actual + Btrace.anim_f_fade - step)
                                        )
                                po[i].radius = 0
                                po[i].keyframe_insert(
                                        'radius',
                                        frame=(actual + Btrace.anim_delay + Btrace.anim_f_fade)
                                        )
    
                    bpy.context.scene.frame_set(Btrace.anim_f_start)
    
                return{'FINISHED'}
    
            except Exception as e:
                error_handlers(self, "curve.btgrow", e,
                               "Grow curve could not be completed")
    
                return {'CANCELLED'}
    
    
    # Remove animation and curve radius data
    class OBJECT_OT_reset(Operator):
        bl_idname = "object.btreset"
        bl_label = "Clear animation"
        bl_description = "Remove animation / curve radius data"
    
        bl_options = {'REGISTER', 'UNDO'}
    
        def execute(self, context):
    
            try:
                objs = context.selected_objects
                for i in objs:  # Execute on multiple selected objects
    
                    context.view_layer.objects.active = i
    
                    obj = context.active_object
                    obj.animation_data_clear()
                    if obj.type == 'CURVE':
                        for sp in obj.data.splines:
                            po = [p for p in sp.points] + [p for p in sp.bezier_points]
                            for p in po:
                                p.radius = 1
    
                return{'FINISHED'}
    
            except Exception as e:
                error_handlers(self, "object.btreset", e,
                               "Clear animation could not be completed")
    
                return {'CANCELLED'}