Browse Source

Fix: Schema Index input erases custom property

this one was caused by an overly aggressive automation that deleted some
node inputs and replaced them with evaluated values. Custom properties,
however, need their sockets. The result was that the custom property was not only
not set correctly, but not created at all!

this commit just makes it check first if it is safe to erase
Joseph Brandenburg 5 months ago
parent
commit
3367be124c
5 changed files with 49 additions and 14 deletions
  1. 13 0
      base_definitions.py
  2. 9 2
      readtree.py
  3. 6 1
      schema_solve.py
  4. 12 5
      xForm_containers.py
  5. 9 6
      xForm_socket_templates.py

+ 13 - 0
base_definitions.py

@@ -643,6 +643,19 @@ array_output_types = [
     'UtilityArrayGet', 'UtilityKDChoosePoint', 'UtilityKDChooseXForm',
     'UtilityArrayGet', 'UtilityKDChoosePoint', 'UtilityKDChooseXForm',
 ]
 ]
 
 
+def can_remove_socket_for_autogen(node, socket) -> bool:
+    """ Whether to enable socket removal optimization for the socket
+        This should be disallowed if e.g. it is a custom property.
+    """
+    if node.socket_templates:
+        for s_template in node.socket_templates:
+            if s_template.name == socket:
+                # raise NotImplementedError
+                return True
+    elif node.node_type == 'UTILITY':
+        return True # HACK because most utilities don't have socket templates yet
+    return False
+
 # TODO:
 # TODO:
 #   - get the execution context in the execution code
 #   - get the execution context in the execution code
 #   - from there, begin to use it for stuff I can't do without it
 #   - from there, begin to use it for stuff I can't do without it

+ 9 - 2
readtree.py

@@ -416,15 +416,22 @@ def parse_tree(base_tree, error_popups=False):
             continue
             continue
         # cleanup autogen nodes
         # cleanup autogen nodes
         if nc.signature[0] == "MANTIS_AUTOGENERATED" and len(nc.inputs) == 0 and len(nc.outputs) == 1:
         if nc.signature[0] == "MANTIS_AUTOGENERATED" and len(nc.inputs) == 0 and len(nc.outputs) == 1:
+            from .base_definitions import can_remove_socket_for_autogen
             output=list(nc.outputs.values())[0]
             output=list(nc.outputs.values())[0]
             value=list(nc.parameters.values())[0]   # IDEA modify the dependecy get function to exclude these nodes completely
             value=list(nc.parameters.values())[0]   # IDEA modify the dependecy get function to exclude these nodes completely
+            keep_me = False
             for l in output.links:
             for l in output.links:
                 to_node = l.to_node; to_socket = l.to_socket
                 to_node = l.to_node; to_socket = l.to_socket
+                # do not remove the socket if it is a custom property.
+                if not can_remove_socket_for_autogen(to_node, to_socket):
+                    keep_me = True; continue
                 l.die()
                 l.die()
                 to_node.parameters[to_socket] = value
                 to_node.parameters[to_socket] = value
                 del to_node.inputs[to_socket]
                 del to_node.inputs[to_socket]
-                init_dependencies(to_node)
-            continue
+                init_dependencies(to_node) # to remove the autogen node we no longer need.
+            if not keep_me:
+                continue
+            init_connections(nc) # because we have removed many connections.
 
 
         if (nc.node_type in ['XFORM']) and ("Relationship" in nc.inputs.keys()):
         if (nc.node_type in ['XFORM']) and ("Relationship" in nc.inputs.keys()):
             if (new_nc := insert_lazy_parents(nc)):
             if (new_nc := insert_lazy_parents(nc)):

+ 6 - 1
schema_solve.py

@@ -192,9 +192,12 @@ class SchemaSolver:
             mantis_node.mContext=mContext
             mantis_node.mContext=mContext
 
 
     def handle_link_from_index_input(self, index, frame_mantis_nodes, ui_link):
     def handle_link_from_index_input(self, index, frame_mantis_nodes, ui_link):
+        from .base_definitions import can_remove_socket_for_autogen
         _from_name, to_name = get_link_in_out(ui_link)
         _from_name, to_name = get_link_in_out(ui_link)
         to_node = frame_mantis_nodes[ (*self.autogen_path_names, to_name+self.index_str()) ]
         to_node = frame_mantis_nodes[ (*self.autogen_path_names, to_name+self.index_str()) ]
-        if to_node.node_type in ['DUMMY', 'DUMMY_SCHEMA']:
+
+        if (not can_remove_socket_for_autogen(to_node, ui_link.to_socket.name)) or \
+                                    to_node.node_type in ['DUMMY', 'DUMMY_SCHEMA']:
             from .utilities import gen_nc_input_for_data
             from .utilities import gen_nc_input_for_data
             nc_cls = gen_nc_input_for_data(ui_link.from_socket)
             nc_cls = gen_nc_input_for_data(ui_link.from_socket)
             if (nc_cls): #HACK
             if (nc_cls): #HACK
@@ -220,6 +223,8 @@ class SchemaSolver:
                 from_node = nc_from
                 from_node = nc_from
                 self.solved_nodes[sig]=from_node
                 self.solved_nodes[sig]=from_node
                 _connection = from_node.outputs[ui_link.from_socket.name].connect(node=to_node, socket=ui_link.to_socket.identifier)
                 _connection = from_node.outputs[ui_link.from_socket.name].connect(node=to_node, socket=ui_link.to_socket.identifier)
+            else:
+                raise RuntimeError()
             return 
             return 
         # Since the index is already determined, it is safe to remove the socket and just keep the value.
         # Since the index is already determined, it is safe to remove the socket and just keep the value.
         to_node.parameters[ui_link.to_socket.name] = index
         to_node.parameters[ui_link.to_socket.name] = index

+ 12 - 5
xForm_containers.py

@@ -249,6 +249,9 @@ class xFormBone(xFormNode):
         ]
         ]
         self.inputs.init_sockets(bone_inputs)
         self.inputs.init_sockets(bone_inputs)
         self.outputs.init_sockets(outputs)
         self.outputs.init_sockets(outputs)
+        self.socket_templates=xFormBoneSockets
+        # TODO: implement socket templates completely for Bone
+        # currently it is waiting on BBone and refactoring/cleanup.
         self.init_parameters()
         self.init_parameters()
         self.set_traverse([("Relationship", "xForm Out")])
         self.set_traverse([("Relationship", "xForm Out")])
     
     
@@ -422,11 +425,16 @@ class xFormBone(xFormNode):
 
 
         # detect custom inputs
         # detect custom inputs
         for i, inp in enumerate(self.inputs.values()):
         for i, inp in enumerate(self.inputs.values()):
-            if inp.name in bone_inputs:
-                continue
-            
-            
+            custom_prop=False
+            for s_template in self.socket_templates:
+                if s_template.name == inp.name:
+                    break
+            else:
+                custom_prop=True
+            if custom_prop == False: continue
+            prPurple (inp.name)
             name = inp.name
             name = inp.name
+
             try:
             try:
                 value = self.evaluate_input(inp.name)
                 value = self.evaluate_input(inp.name)
             except KeyError as e:
             except KeyError as e:
@@ -534,7 +542,6 @@ class xFormBone(xFormNode):
             # important TODO... all of the drivers and stuff should be handled this way, right?
             # important TODO... all of the drivers and stuff should be handled this way, right?
         # time to set up drivers!
         # time to set up drivers!
 
 
-
         # just gonna add this to the end and build off it I guess
         # just gonna add this to the end and build off it I guess
         props_sockets = {
         props_sockets = {
             "lock_location"               : ("Lock Location", [False, False, False]),
             "lock_location"               : ("Lock Location", [False, False, False]),

+ 9 - 6
xForm_socket_templates.py

@@ -113,6 +113,9 @@ xFormBoneSockets = [
             name='Custom Object Scale to Bone Length', category='Display',
             name='Custom Object Scale to Bone Length', category='Display',
             blender_property='use_custom_shape_bone_size',
             blender_property='use_custom_shape_bone_size',
             default_value=True,),
             default_value=True,),
+    CustomObjectWireframeTemplate := replace(HideRenderTemplate,
+            name='Custom Object Wireframe', category='Display',
+            blender_property='show_wire', default_value=True,),
     CustomObjectScaleTemplate := SockTemplate(name="Custom Object Scale",
     CustomObjectScaleTemplate := SockTemplate(name="Custom Object Scale",
             is_input=True, bl_idname='VectorScaleSocket',
             is_input=True, bl_idname='VectorScaleSocket',
             category='Display', default_value=(1.0,1.0,1.0),),
             category='Display', default_value=(1.0,1.0,1.0),),
@@ -135,22 +138,22 @@ xFormBoneSockets = [
             name='Envelope Multiply', bl_idname = 'BooleanSocket',
             name='Envelope Multiply', bl_idname = 'BooleanSocket',
             blender_property='use_envelope_multiply', default_value=False,),
             blender_property='use_envelope_multiply', default_value=False,),
     EnvelopeWeightTemplate := replace(EnvelopeDistanceTemplate,
     EnvelopeWeightTemplate := replace(EnvelopeDistanceTemplate,
-        name='Head Radius', blender_property='head_radius', default_value=0.0,),
+        name='Envelope Head Radius', blender_property='head_radius', default_value=0.0,),
     EnvelopeWeightTemplate := replace(EnvelopeDistanceTemplate,
     EnvelopeWeightTemplate := replace(EnvelopeDistanceTemplate,
-        name='Tail Radius', blender_property='tail_radius', default_value=0.0,),
+        name='Envelope Tail Radius', blender_property='tail_radius', default_value=0.0,),
     # BBone Stuff
     # BBone Stuff
-    BBoneSegmentsTemplate := SockTemplate(name="Name", is_input=True,
+    BBoneSegmentsTemplate := SockTemplate(name="BBone Segments", is_input=True,
         bl_idname='UnsignedIntSocket', category = 'bbone',
         bl_idname='UnsignedIntSocket', category = 'bbone',
         blender_property='bbone_segments', default_value=1 ),
         blender_property='bbone_segments', default_value=1 ),
     BBoneXSizeTemplate := replace(BBoneSegmentsTemplate, name='BBone X Size',
     BBoneXSizeTemplate := replace(BBoneSegmentsTemplate, name='BBone X Size',
         bl_idname='FloatSocket', blender_property='bbone_x', default_value=0.0025, ),
         bl_idname='FloatSocket', blender_property='bbone_x', default_value=0.0025, ),
-    BBoneYSizeTemplate := replace(BBoneXSizeTemplate, name='BBone Y Size',
+    BBoneYSizeTemplate := replace(BBoneXSizeTemplate, name='BBone Z Size',
         blender_property='bbone_y', ),
         blender_property='bbone_y', ),
     BBoneHQDeformation := replace(BBoneSegmentsTemplate, name='BBone HQ Deformation',
     BBoneHQDeformation := replace(BBoneSegmentsTemplate, name='BBone HQ Deformation',
         bl_idname='BooleanSocket', blender_property='', default_value=None ),
         bl_idname='BooleanSocket', blender_property='', default_value=None ),
     BBoneXCurveInTemplate := replace( BBoneXSizeTemplate, name="BBone X Curve-In",
     BBoneXCurveInTemplate := replace( BBoneXSizeTemplate, name="BBone X Curve-In",
         bl_idname='FloatSocket', blender_property='bbone_curveinx', default_value=0.0, ),
         bl_idname='FloatSocket', blender_property='bbone_curveinx', default_value=0.0, ),
-    BBoneZCurveInTemplate := replace(BBoneXCurveInTemplate, name="BBone X Curve-In",
+    BBoneZCurveInTemplate := replace(BBoneXCurveInTemplate, name="BBone Z Curve-In",
         blender_property='bbone_curveinz', ),
         blender_property='bbone_curveinz', ),
     BBoneXCurveOutTemplate := replace(BBoneXCurveInTemplate, name="BBone X Curve-Out",
     BBoneXCurveOutTemplate := replace(BBoneXCurveInTemplate, name="BBone X Curve-Out",
         blender_property='bbone_curveoutx', ),
         blender_property='bbone_curveoutx', ),
@@ -158,7 +161,7 @@ xFormBoneSockets = [
         blender_property='bbone_curveoutz', ),  # I'm tired of assigning variables, not gonna bother anymore lol
         blender_property='bbone_curveoutz', ),  # I'm tired of assigning variables, not gonna bother anymore lol
                                                 # it's just a conincidence that a lot of these are also unimplemented
                                                 # it's just a conincidence that a lot of these are also unimplemented
     replace(BBoneXCurveInTemplate, name="BBone Roll-In", blender_property='bbone_rollin', ), # CURRENTLY UNIMPLEMENTED
     replace(BBoneXCurveInTemplate, name="BBone Roll-In", blender_property='bbone_rollin', ), # CURRENTLY UNIMPLEMENTED
-    replace(BBoneXCurveInTemplate, name="BBone Roll-out", blender_property='bbone_rollout', ), # CURRENTLY UNIMPLEMENTED
+    replace(BBoneXCurveInTemplate, name="BBone Roll-Out", blender_property='bbone_rollout', ), # CURRENTLY UNIMPLEMENTED
     replace(BBoneXCurveInTemplate, name="BBone Inherit End Roll",
     replace(BBoneXCurveInTemplate, name="BBone Inherit End Roll",
             bl_idname='BooleanSocket',), # CURRENTLY UNIMPLEMENTED
             bl_idname='BooleanSocket',), # CURRENTLY UNIMPLEMENTED
     replace(BBoneXCurveInTemplate, name="BBone Scale-In",
     replace(BBoneXCurveInTemplate, name="BBone Scale-In",