Selaa lähdekoodia

code to import curves and rigs in io

note that this does NOT implement everything that I could ever conceivably
want to do, such as e.g. bbone settings

future work: add option to import operator to do this or not
also option to only import/export this stuff as metarig (?)
Joseph Brandenburg 2 kuukautta sitten
vanhempi
commit
aa8f0698cf
2 muutettua tiedostoa jossa 95 lisäystä ja 23 poistoa
  1. 27 21
      i_o.py
  2. 68 2
      utilities.py

+ 27 - 21
i_o.py

@@ -261,7 +261,7 @@ def get_curve_for_pack(object):
                         tilt   = point.tilt,
                         w      = point.co[3],
                 )
-                points.append(export_pnt)
+                points.append(asdict(export_pnt))
         export_spl = spline_data(
                 type                  = spline.type,
                 points                = points,
@@ -297,17 +297,11 @@ class metabone_data:
 
 def get_armature_for_pack(object):
     metarig_data = {}
-    armature_data = metabone_data( object_name = object.name,
-        name=object.name, type='ARMATURE',
-        matrix=matrix_as_tuple(object.matrix_world),
-        parent="", # NOTE that this is not always a fair assumption!
-        length = -1.0, children =[],)
-    metarig_data[object.name] = asdict(armature_data)
-    metarig_data["MANTIS_RESERVED"] = asdict(armature_data) # just in case a bone is named the same as the armature
+    armature_children = []
     for bone in object.data.bones:
         parent_name = ''
         if bone.parent is None:
-            armature_data.children.append(bone.name)
+            armature_children.append(bone.name)
         else:
             parent_name=bone.parent.name
         children=[]
@@ -319,6 +313,13 @@ def get_armature_for_pack(object):
             parent=parent_name, length = bone.length, children = children,
         )
         metarig_data[bone.name]=asdict(bone_data)
+    armature_data = metabone_data( object_name = object.name,
+        name=object.name, type='ARMATURE',
+        matrix=matrix_as_tuple(object.matrix_world),
+        parent="", # NOTE that this is not always a fair assumption!
+        length = -1.0, children = armature_children,)
+    metarig_data[object.name] = asdict(armature_data)
+    metarig_data["MANTIS_RESERVED"] = asdict(armature_data) # just in case a bone is named the same as the armature
     return metarig_data
 
 def get_socket_data(socket, ignore_if_default=False):
@@ -889,6 +890,23 @@ def do_import(data, context, search_multi_files=False, filepath=''):
         tree_info = tree_data[0]
         tree_in_out = tree_data[1]
 
+
+        # TODO: IMPORT THIS DATA HERE!!!
+        try:
+            curves = tree_data[4]
+            armatures = tree_data[5]
+        except IndexError: # shouldn't happen but maybe someone has an old file
+            curves = {}
+            armatures = {}
+        
+        for curve_name, curve_data in curves.items():
+            from .utilities import import_curve_data_to_object, import_metarig_data
+            import_curve_data_to_object(curve_name, curve_data)
+            for armature_name, armature_data in armatures.items():
+                import_metarig_data(armature_data)
+        
+
+
         # need to make a new tree; first, try to get it:
         tree = bpy.data.node_groups.get(tree_info["name"])
         if tree is None:
@@ -1071,18 +1089,6 @@ def do_import(data, context, search_multi_files=False, filepath=''):
                 n.parent = p
             # otherwise the frame node is missing because it was not included in the data e.g. when grouping nodes.
         
-        # TODO: IMPORT THIS DATA HERE!!!
-        # try:
-        #     curves = tree_data[4]
-        #     armatures = tree_data[5]
-        # except KeyError: # shouldn't happen but maybe someone has an old file
-        #     curves = {}
-        #     armatures = {}
-        
-        # for curve_name, curve_data in curves.items():
-        #     from .utilities import import_curve_data_to_object
-        #     import_curve_data_to_object(curve_name, curve_data)
-        
         tree.is_executing = False
         tree.do_live_update = True
         

+ 68 - 2
utilities.py

@@ -407,14 +407,80 @@ def import_object_from_file(path):
         return import_widget_obj(path,)
     else:
         raise RuntimeError(f"Failed to parse filename {path}")
+
+def import_metarig_data(metarig_data : dict, ):
+    from bpy import data, context
+    from mathutils import Matrix
+    from collections import deque
+    # the metarig data is a dict with a bunch of nodes in it
+    # start at node 'MANTIS_RESERVED'
+    armature_data = metarig_data['MANTIS_RESERVED']
+    children = deque(armature_data["children"].copy())
+    armature = data.armatures.new(armature_data['name'])
+    armature_object = data.objects.new(armature_data['name'], object_data=armature)
+    armature_object.matrix_world = Matrix(
+            (   armature_data['matrix'][:4],
+                armature_data['matrix'][4:8],
+                armature_data['matrix'][8:12],
+                armature_data['matrix'][12:16], )
+        )
+    
+    # have to add it to the view layer to switch modes.
+    context.collection.objects.link(armature_object)
+    switch_mode('EDIT', objects = [armature_object])
+    
+    while (children):
+        child_name = children.pop()
+        child_data = metarig_data[child_name]
+        eb = armature.edit_bones.new(name=child_data['name'])
+        if parent_name := child_data['parent']:
+            eb.parent = armature.edit_bones[parent_name]
+        eb.length = child_data['length']
+        eb.matrix = Matrix(
+            (   child_data['matrix'][:4],
+                child_data['matrix'][4:8],
+                child_data['matrix'][8:12],
+                child_data['matrix'][12:16],   )
+            )
+        displacement = eb.matrix.to_3x3().transposed().row[1] * child_data['length']
+        eb.tail = eb.matrix.decompose()[0] + displacement
+        children.extendleft (child_data['children'].copy())
+    switch_mode('OBJECT', objects = [armature_object])
+
+    return armature_object
+    
         
 def import_curve_data_to_object(curve_name, curve_data):
     # the curve data will come as a single curve's data
     from bpy import data
     curve_object = data.objects.new(curve_name, data.curves.new(name=curve_name, type='CURVE'))
+    curve_object.data.dimensions = '3D'
+    prGreen (curve_name)
+
+    for spline_data in curve_data:
+        prWhite ('spline')
+        spline = curve_object.data.splines.new(type=spline_data['type'])
+        points_data = spline_data['points']
+        points_collection = spline.points
+        if spline.type == 'BEZIER':
+            # the points are bez_pts
+            spline.bezier_points.add(len(points_data)-1)
+            points_collection = spline.bezier_points
+        else:
+            spline.points.add(len(points_data)-1) # it starts with 1 already
+        for i, point_data in enumerate(points_data):
+            pt = spline.bezier_points[i]
+            for prop in dir(pt):
+                if prop in point_data.keys():
+                    setattr(pt, prop, point_data[prop])
+            prPurple (pt.co)
+        for prop in dir(spline):
+            if prop in spline_data.keys():
+                if prop in ['points', 'type', 'index']: continue
+                setattr(spline, prop, spline_data[prop])
+    return curve_object
+
 
-    for spline in curve_data:
-        curve_object.data.splines.new(type=spline['type'])
 
 ##############################
 #  READ TREE and also Schema Solve!