Эх сурвалжийг харах

Add: option to Use Offset in Morph Deform

also fixed bug in Armature Deform with incorrect context when selecting
or deselecting pose bones via bpy.ops.
Joseph Brandenburg 8 сар өмнө
parent
commit
7ef6b11076

+ 7 - 4
__init__.py

@@ -17,7 +17,7 @@ from .utilities import prRed
 
 MANTIS_VERSION_MAJOR=0
 MANTIS_VERSION_MINOR=9
-MANTIS_VERSION_SUB=7
+MANTIS_VERSION_SUB=8
 
 
 classLists = [module.TellClasses() for module in [
@@ -118,6 +118,8 @@ utility_category = [
         NodeItem("MathStaticFloat"),
         NodeItem("MathStaticVector"),
         NodeItem("UtilityCatStrings"),
+        NodeItem("UtilityGeometryOfXForm"),
+        NodeItem("UtilityNameOfXForm"),
         NodeItem("UtilityCombineThreeBool"),
         NodeItem("UtilityCombineVector"),
         NodeItem("UtilityIntToString"),
@@ -261,13 +263,14 @@ def version_update_handler(filename):
                         if (n.bl_idname, socket.identifier) in SOCKETS_REMOVED:
                             print(f"INFO: removing socket {socket.identifier} of node {n.name} of type {n.bl_idname} because it has been deprecated.")
                             n.outputs.remove(socket)
-                    for bl_idname, in_out, socket_type, socket_name, index in SOCKETS_ADDED:
+                    for bl_idname, in_out, socket_type, socket_name, index, use_multi_input, default_val in SOCKETS_ADDED:
                         if n.bl_idname != bl_idname:
                             continue
                         if in_out == 'INPUT' and n.inputs.get(socket_name) is None:
                             print(f"INFO: adding socket \"{socket_name}\" of type {socket_type} to node {n.name} of type {n.bl_idname}.")
-                            s = n.inputs.new(socket_type, socket_name)
-                            # n.inputs.move(len(n.inputs), index)
+                            s = n.inputs.new(socket_type, socket_name, use_multi_input=use_multi_input)
+                            s.default_value = default_val
+                            n.inputs.move(len(n.inputs), index)
                 
                 
 

+ 3 - 1
base_definitions.py

@@ -356,7 +356,9 @@ SOCKETS_REMOVED=[("UtilityDriverVariable","Transform Channel"),
                  ("xFormRootNode","World Out"),
                  ("UtilitySwitch","xForm")]
 SOCKETS_RENAMED=[]
-SOCKETS_ADDED=[("DeformerMorphTargetDeform", 'INPUT', 'BooleanSocket', "Use Shape Key", 1),]
+                # NODE CLASS NAME             IN_OUT    SOCKET TYPE     SOCKET NAME     INDEX   MULTI     DEFAULT
+SOCKETS_ADDED=[("DeformerMorphTargetDeform", 'INPUT', 'BooleanSocket', "Use Shape Key", 1,      False,    False),
+               ("DeformerMorphTargetDeform", 'INPUT', 'BooleanSocket', "Use Offset", 2,         False,     True),]
 
 # replace names with bl_idnames for reading the tree and solving schemas.
 replace_types = ["NodeGroupInput", "NodeGroupOutput", "SchemaIncomingConnection",

+ 1 - 1
blender_manifest.toml

@@ -3,7 +3,7 @@ schema_version = "1.0.0"
 # Example of manifest file for a Blender extension
 # Change the values according to your extension
 id = "mantis"
-version = "0.9.7"
+version = "0.9.8"
 name = "Mantis"
 tagline = "Mantis is a rigging nodes toolkit"
 maintainer = "Nodespaghetti <josephbburg@protonmail.com>"

+ 26 - 11
deformer_containers.py

@@ -207,18 +207,22 @@ class DeformerArmature:
                                   'active_pose_bone':deform_bones[0],
                                   'selected_pose_bones':deform_bones,}
             #
-            with bContext.temp_override(**{'active_object':armOb}):
-                bpy.ops.object.mode_set(mode='POSE')
-                bpy.ops.pose.select_all(action='SELECT')
+            # with bContext.temp_override(**{'active_object':armOb}):
+            #     bpy.ops.object.mode_set(mode='POSE')
+            #     bpy.ops.pose.select_all(action='SELECT')
+            for b in armOb.data.bones:
+                b.select = True
             with bContext.temp_override(**context_override):
                 bpy.ops.paint.weight_paint_toggle()
                 bpy.ops.paint.weight_from_bones(type='AUTOMATIC')
                 bpy.ops.paint.weight_paint_toggle()
+            for b in armOb.data.bones:
+                b.select = False
                 #
-            with bContext.temp_override(**{'active_object':armOb}):
-                bpy.ops.object.mode_set(mode='POSE')
-                bpy.ops.pose.select_all(action='DESELECT') 
-                bpy.ops.object.mode_set(mode='OBJECT')
+            # with bContext.temp_override(**{'active_object':armOb}):
+            #     bpy.ops.object.mode_set(mode='POSE')
+            #     bpy.ops.pose.select_all(action='DESELECT') 
+            #     bpy.ops.object.mode_set(mode='OBJECT')
             # TODO: modify Blender to make this available as a Python API function.
         elif skin_method == "EXISTING_GROUPS":
             pass
@@ -371,6 +375,7 @@ class DeformerMorphTargetDeform:
         self.inputs = {
           "Deformer"            : NodeSocket(is_input = True, name = "Deformer", node = self),
           "Use Shape Key"       : NodeSocket(is_input = True, name = "Use Shape Key", node = self),
+          "Use Offset"          : NodeSocket(is_input = True, name = "Use Offset", node = self),
         }
         self.outputs = {
           "Deformer" : NodeSocket(is_input = False, name = "Deformer", node=self), }
@@ -378,7 +383,9 @@ class DeformerMorphTargetDeform:
           "Name"                : None,
           "Deformer"            : None,
           "Deformer"            : None,
-          "Use Shape Key"       : None,}
+          "Use Shape Key"       : None,
+          "Use Offset"          : None,
+          }
         # now set up the traverse target...
         self.inputs["Deformer"].set_traverse_target(self.outputs["Deformer"])
         self.outputs["Deformer"].set_traverse_target(self.inputs["Deformer"])
@@ -425,7 +432,8 @@ class DeformerMorphTargetDeform:
         rest_position = ng.nodes.new("GeometryNodeInputNamedAttribute")
         rest_position.inputs["Name"].default_value="rest_position"
         rest_position.data_type = 'FLOAT_VECTOR'
-        # rest_position = position
+        if self.evaluate_input("Use Offset") == False:
+            rest_position = position
         add_these = []
 
         props_sockets={}
@@ -496,13 +504,20 @@ class DeformerMorphTargetDeform:
         # prev_node = ng.nodes.new("ShaderNodeVectorMath"); prev_node.operation="SUBTRACT"
         # ng.links.new(position.outputs[0], output=prev_node.inputs[0])
         # ng.links.new(rest_position.outputs[0], output=prev_node.inputs[1])
-        prev_node = ng.nodes.new("FunctionNodeInputVector")
+
+        if self.evaluate_input("Use Offset") == True:
+            prev_node = ng.nodes.new("FunctionNodeInputVector")
+        else:
+            prev_node = position
         for i, node in enumerate(add_these):
             add = ng.nodes.new("ShaderNodeVectorMath"); add.operation="ADD"
             ng.links.new(prev_node.outputs[0], output=add.inputs[0])
             ng.links.new(node.outputs[0], output=add.inputs[1])
             prev_node = add
-        ng.links.new(add.outputs[0], output=set_position.inputs["Offset"])
+        if self.evaluate_input("Use Offset") == True:
+            ng.links.new(add.outputs[0], output=set_position.inputs["Offset"])
+        else:
+            ng.links.new(add.outputs[0], output=set_position.inputs["Position"])
         
         from .utilities import SugiyamaGraph
         SugiyamaGraph(ng, 12)

+ 10 - 2
deformer_definitions.py

@@ -124,6 +124,8 @@ class DeformerMorphTargetDeform(Node, DeformerNode):
         self.id_data.do_live_update = False
         self.inputs.new('DeformerSocket', 'Deformer', )
         self.inputs.new('BooleanSocket', 'Use Shape Key', )
+        s = self.inputs.new('BooleanSocket', 'Use Offset', )
+        s.default_value = True
         self.inputs.new('WildcardSocket', '', identifier='__extend__')
         self.outputs.new('DeformerSocket', "Deformer")
         self.update()
@@ -132,6 +134,7 @@ class DeformerMorphTargetDeform(Node, DeformerNode):
         if self.id_data.is_executing:
             return # so that we don't update it while saving/loading the tree
         self.initialized = False
+        # use_offset = self.inputs["Use Offset"].default_value
         input_map = get_socket_maps(self)[0]
         # checc to see if targets have been removed... then modify the input map if necessary
         targets_deleted = 0 # this should usually be either 0 or 1
@@ -150,6 +153,8 @@ class DeformerMorphTargetDeform(Node, DeformerNode):
         self.inputs.clear()
         self.inputs.new('DeformerSocket', 'Deformer', )
         self.inputs.new('BooleanSocket', 'Use Shape Key', )
+        self.inputs.new('BooleanSocket', 'Use Offset', )
+        # s.default_value = use_offset
         # have to do this manually to avoid making things harder elsewhere
         # input_map
         for i in range(self.num_targets):
@@ -157,18 +162,21 @@ class DeformerMorphTargetDeform(Node, DeformerNode):
             self.inputs.new("FloatSocket", "Value."+str(i).zfill(3))
         # if self.num_targets > 0:
         simple_do_relink(self, input_map, in_out='INPUT')
-        if len(self.inputs)<2 or self.inputs[-1].bl_idname not in ["WildcardSocket"]:
+        if self.inputs[-1].bl_idname not in ["WildcardSocket"]:
             self.inputs.new('WildcardSocket', '', identifier='__extend__')
         self.initialized = True
     
     def display_update(self, parsed_tree, context):
         if self.inputs["Deformer"].is_linked:
-            if self.inputs["Deformer"].links[0].from_node.bl_idname != self.bl_idname:
+            if self.inputs["Deformer"].links[0].from_node.bl_idname not in [self.bl_idname, "NodeGroupInput"]:
                 self.inputs["Use Shape Key"].default_value = False
                 self.inputs["Use Shape Key"].hide = True
             elif self.inputs["Deformer"].links[0].from_node.inputs["Use Shape Key"].default_value == False:
                 self.inputs["Use Shape Key"].default_value = False
                 self.inputs["Use Shape Key"].hide = True
+        if self.inputs["Use Offset"] == False:
+                self.inputs["Use Shape Key"].hide = True
+                self.inputs["Use Shape Key"].default_value = False
 
 
 # TODO: there is no reason for this to be a separate node!