Pārlūkot izejas kodu

metarig cache scaffolding

this commit halfway implements a metarig cache
it isn't actually called or used anywhere yet, but i tested it and it works
soon I will make the metarig node use this to get the data from the tree
and to refresh the metarig data whenever it is modified
Joseph Brandenburg 3 dienas atpakaļ
vecāks
revīzija
0d1adf3908
2 mainītis faili ar 72 papildinājumiem un 6 dzēšanām
  1. 28 6
      mantis_dataclasses.py
  2. 44 0
      misc_nodes.py

+ 28 - 6
mantis_dataclasses.py

@@ -64,12 +64,12 @@ class MantisBoneTransform():
 
 @dataclass(slots=True)
 class MantisBBoneTransform():
-    num_bbone_segmetns: int = field(default=1)
+    bbone_segments: int = field(default=1)
     # Offsets & Curve Handles
     bbone_curveinx: float = field(default=0.0)
-    bbone_curveiny: float = field(default=0.0)
+    bbone_curveinz: float = field(default=0.0)
     bbone_curveoutx: float = field(default=0.0)
-    bbone_curveouty: float = field(default=0.0)
+    bbone_curveoutz: float = field(default=0.0)
     # Easing
     bbone_easein: float = field(default=1.0)
     bbone_easeout: float = field(default=1.0)
@@ -82,13 +82,35 @@ class MantisBBoneTransform():
     bbone_scaleout: Tuple[float, float, float] = field(
         default_factory=lambda: (1.0, 1.0, 1.0) )
     # Custom Handles
-    use_bbone_custom_handles: bool = field(default=False)
-    bbone_custom_handle_start: str = field(default=None)
-    bbone_custom_handle_end: str = field(default=None)
+    bbone_handle_type_start: str = field(default="AUTO")
+    bbone_handle_type_end:   str = field(default="AUTO")
+    bbone_custom_handle_start: str = field(default="")
+    bbone_custom_handle_end:   str = field(default="")
+
+    @classmethod
+    def bbone_transform_from_bone(cls, bone):
+        return cls(
+            bbone_segments = bone.bbone_segments,
+            bbone_curveinx = bone.bbone_curveinx,
+            bbone_curveinz = bone.bbone_curveinz,
+            bbone_curveoutx = bone.bbone_curveoutx,
+            bbone_curveoutz = bone.bbone_curveoutz,
+            bbone_easein = bone.bbone_easein,
+            bbone_easeout = bone.bbone_easeout,
+            bbone_rollin = bone.bbone_rollin,
+            bbone_rollout = bone.bbone_rollout,
+            bbone_scalein = bone.bbone_scalein,
+            bbone_scaleout = bone.bbone_scaleout,
+            bbone_handle_type_start = bone.bbone_handle_type_start,
+            bbone_handle_type_end = bone.bbone_handle_type_end,
+            bbone_custom_handle_start = bone.bbone_custom_handle_start,
+            bbone_custom_handle_end = bone.bbone_custom_handle_end,
+        )
 
 # used to apply values or drivers to blender properties in a generic way
 @dataclass(slots=True)
 class MantisSocketFiller():
+
     socket_name: str = field(default="")
     property_group : str = field(default="")
     property_name : str = field(default="")

+ 44 - 0
misc_nodes.py

@@ -79,6 +79,7 @@ CURVE_LUT_CACHE = {}
 CURVE_HASHES = {}
 SPLINE_HASHES ={}
 
+
 # todo: make a "matrix from 2 u" function, a "matrix for segments" function
 # basically I want the SplineLUT to handle all curve matrix getters
 class SplineLUT:
@@ -233,6 +234,43 @@ def get_from_curve_lut(curve_name, spline_index, bContext, node_for_error=None)
     return spline_lookup
 
 
+# Store this stuff so we can reuse it or check it for updates
+METARIG_DATA_CACHE = {}
+
+# recursing like this is slightly easier than managing state myself
+# and it is easier to read/understand
+# it is unlikely that this will run into Recursion Depth Limit
+# if it does, I'll rewrite this without recursion
+def calculate_matrix_recursive_branching(parent_matrix, children, cache):
+    from collections import deque
+    from .mantis_dataclasses import MantisBoneTransform, MantisBBoneTransform
+    from mathutils import Matrix
+    children = deque( children )
+    for child in children:
+        m = parent_matrix @ child.matrix
+        transform_matrix = Matrix.Translation(child.head_local) @ m.to_4x4()
+        cache[child.name] = ( MantisBoneTransform(
+            matrix = transform_matrix, matrix_space = 'OBJECT', length=child.length),
+            MantisBBoneTransform.bbone_transform_from_bone(child)
+        )
+        calculate_matrix_recursive_branching(m, child.children, cache)
+
+def fill_metarig_cache_for_object(armature):
+    from .mantis_dataclasses import MantisBoneTransform, MantisBBoneTransform
+    from mathutils import Matrix
+    my_cache = {}
+    # recursively fill the armature with local matrices
+    roots = [ b for b in armature.data.bones if b.parent is None]
+    for b in roots:
+        parent_matrix = b.matrix
+        transform_matrix = Matrix.Translation(b.head_local) @ parent_matrix.to_4x4()
+        my_cache[b.name] = ( MantisBoneTransform(
+            matrix = transform_matrix, matrix_space = 'OBJECT', length=b.length),
+            MantisBBoneTransform.bbone_transform_from_bone(b)
+        )
+        calculate_matrix_recursive_branching(parent_matrix, b.children, my_cache)
+    METARIG_DATA_CACHE[armature.name] = my_cache
+
 def matrix_from_head_tail(head, tail, normal=None):
     from mathutils import Vector, Matrix
     if normal is None:
@@ -767,6 +805,12 @@ class UtilityMetaRig(MantisMiscNode):
     __slots__ = ()
     socket_templates = MetaRigSockets
 
+    def bDataFromScene(self):
+        # TWO possibilities:
+        #   - this node has no real dependencies and is ready to prep
+        #   - this node has dependencies and can't be prepped until building the tree
+        pass
+
     def bPrepare(self, bContext = None,):
         #kinda clumsy, whatever
         import bpy