Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gltf2_blender_gather_cache.py « exp « blender « io_scene_gltf2 - git.blender.org/blender-addons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 7e49ac02f61bfc9d8a55811190861da39f7f2496 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# SPDX-License-Identifier: Apache-2.0
# Copyright 2018-2021 The glTF-Blender-IO authors.

import functools
import bpy
from io_scene_gltf2.blender.exp import gltf2_blender_get


def cached(func):
    """
    Decorate the cache gather functions results.

    The gather function is only executed if its result isn't in the cache yet
    :param func: the function to be decorated. It will have a static __cache member afterwards
    :return:
    """
    @functools.wraps(func)
    def wrapper_cached(*args, **kwargs):
        assert len(args) >= 2 and 0 <= len(kwargs) <= 1, "Wrong signature for cached function"
        cache_key_args = args
        # make a shallow copy of the keyword arguments so that 'export_settings' can be removed
        cache_key_kwargs = dict(kwargs)
        if kwargs.get("export_settings"):
            export_settings = kwargs["export_settings"]
            # 'export_settings' should not be cached
            del cache_key_kwargs["export_settings"]
        else:
            export_settings = args[-1]
            cache_key_args = args[:-1]

        __by_name = [bpy.types.Object, bpy.types.Scene, bpy.types.Material, bpy.types.Action, bpy.types.Mesh, bpy.types.PoseBone]

        # we make a tuple from the function arguments so that they can be used as a key to the cache
        cache_key = ()
        for i in cache_key_args:
            if type(i) in __by_name:
                cache_key += (i.name,)
            else:
                cache_key += (i,)
        for i in cache_key_kwargs.values():
            if type(i) in __by_name:
                cache_key += (i.name,)
            else:
                cache_key += (i,)

        # invalidate cache if export settings have changed
        if not hasattr(func, "__export_settings") or export_settings != func.__export_settings:
            func.__cache = {}
            func.__export_settings = export_settings
        # use or fill cache
        if cache_key in func.__cache:
            return func.__cache[cache_key]
        else:
            result = func(*args)
            func.__cache[cache_key] = result
            return result
    return wrapper_cached

def bonecache(func):

    def reset_cache_bonecache():
        func.__current_action_name = None
        func.__current_armature_name = None
        func.__bonecache = {}

    func.reset_cache = reset_cache_bonecache

    @functools.wraps(func)
    def wrapper_bonecache(*args, **kwargs):
        if args[2] is None:
            pose_bone_if_armature = gltf2_blender_get.get_object_from_datapath(args[0],
                                                                args[1][0].data_path)
        else:
            pose_bone_if_armature = args[0].pose.bones[args[2]]

        if not hasattr(func, "__current_action_name"):
            func.reset_cache()
        if args[6] != func.__current_action_name or args[0] != func.__current_armature_name:
            result = func(*args)
            func.__bonecache = result
            func.__current_action_name = args[6]
            func.__current_armature_name = args[0]
            return result[args[7]][pose_bone_if_armature.name]
        else:
            return func.__bonecache[args[7]][pose_bone_if_armature.name]
    return wrapper_bonecache

# TODO: replace "cached" with "unique" in all cases where the caching is functional and not only for performance reasons
call_or_fetch = cached
unique = cached

def skdriverdiscovercache(func):

    def reset_cache_skdriverdiscovercache():
        func.__current_armature_name = None
        func.__skdriverdiscover = {}

    func.reset_cache = reset_cache_skdriverdiscovercache

    @functools.wraps(func)
    def wrapper_skdriverdiscover(*args, **kwargs):
        if not hasattr(func, "__current_armature_name") or func.__current_armature_name is None:
            func.reset_cache()

        if args[0] != func.__current_armature_name:
            result = func(*args)
            func.__skdriverdiscover[args[0]] = result
            func.__current_armature_name = args[0]
            return result
        else:
            return func.__skdriverdiscover[args[0]]
    return wrapper_skdriverdiscover

def skdrivervalues(func):

    def reset_cache_skdrivervalues():
        func.__skdrivervalues = {}

    func.reset_cache = reset_cache_skdrivervalues

    @functools.wraps(func)
    def wrapper_skdrivervalues(*args, **kwargs):
        if not hasattr(func, "__skdrivervalues") or func.__skdrivervalues is None:
            func.reset_cache()

        if args[0].name not in func.__skdrivervalues.keys():
            func.__skdrivervalues[args[0].name] = {}
        if args[1] not in func.__skdrivervalues[args[0].name]:
            vals = func(*args)
            func.__skdrivervalues[args[0].name][args[1]] = vals
            return vals
        else:
            return func.__skdrivervalues[args[0].name][args[1]]
    return wrapper_skdrivervalues