瀏覽代碼

Add Node: Mesh Deform

Joseph Brandenburg 4 月之前
父節點
當前提交
6ee46ac468
共有 3 個文件被更改,包括 75 次插入5 次删除
  1. 44 1
      deformer_containers.py
  2. 15 1
      deformer_definitions.py
  3. 16 3
      deformer_socket_templates.py

+ 44 - 1
deformer_containers.py

@@ -18,6 +18,7 @@ def TellClasses():
              DeformerMorphTarget,
              DeformerMorphTargetDeform,
              DeformerSurfaceDeform,
+             DeformerMeshDeform,
            ]
 
 # object instance probably can't use the deformer but it doesn't hurt to try.
@@ -41,7 +42,7 @@ class MantisDeformerNode(MantisNode):
         self.bObject=[]
     # we need evaluate_input to have the same behaviour as links.
     def evaluate_input(self, input_name, index=0):
-        if ('Target' in input_name):
+        if (input_name in ['Target', 'Object']):
             socket = self.inputs.get(input_name)
             if socket.is_linked:
                 return socket.links[0].from_node
@@ -597,3 +598,45 @@ class DeformerSurfaceDeform(MantisDeformerNode):
             target = d.target
             with bpy.context.temp_override(**{'active_object':ob, 'selected_objects':[ob, target]}):
                 bpy.ops.object.surfacedeform_bind(modifier=d.name)
+
+
+class DeformerMeshDeform(MantisDeformerNode):
+    '''A node representing a mesh deform modifier'''
+
+    def __init__(self, signature, base_tree):
+        super().__init__(signature, base_tree, MeshDeformSockets)
+        # now set up the traverse target...
+        self.init_parameters(additional_parameters={"Name":None})
+        self.set_traverse([("Deformer", "Deformer")])
+        self.prepared = True
+
+    def GetxForm(self, socket="Deformer"):
+        if socket == "Deformer":
+            return super().GetxForm()
+        else:
+            trace_xForm_back(self, socket)
+    
+    def bExecute(self, bContext = None,):
+        self.executed = True
+         
+    def bFinalize(self, bContext=None):
+        prGreen("Executing Mesh Deform Node")
+        mod_name = self.evaluate_input("Name")
+        for xf in self.GetxForm():
+            ob = xf.bGetObject()
+            d = ob.modifiers.new(mod_name, type='MESH_DEFORM')
+            if d is None:
+                raise RuntimeError(f"Modifier was not created in node {self} -- the object is invalid.")
+            self.bObject.append(d)
+            self.get_target_and_subtarget(d, input_name="Object")
+            props_sockets = self.gen_property_socket_map()
+            evaluate_sockets(self, d, props_sockets)
+            # now we have to bind it
+            import bpy
+            target = d.object
+            with bpy.context.temp_override(**{'active_object':ob, 'selected_objects':[ob, target]}):
+                bpy.ops.object.meshdeform_bind(modifier=d.name)
+            
+            # todo: add influence parameter and set it up with vertex group and geometry nodes
+            # todo: make cage object display as wireframe if it is not being used for something else
+            #          or add the option in the Geometry Object node

+ 15 - 1
deformer_definitions.py

@@ -15,6 +15,7 @@ def TellClasses():
              DeformerMorphTargetDeform,
              DeformerMorphTarget,
              DeformerSurfaceDeform,
+             DeformerMeshDeform,
            ]
 
 
@@ -213,7 +214,6 @@ class DeformerMorphTarget(Node, DeformerNode):
         self.initialized = True
 
 
-# TODO: there is no reason for this to be a separate node!
 class DeformerSurfaceDeform(Node, DeformerNode):
     '''A node representing a Surface Deform modifier'''
     bl_idname = 'DeformerSurfaceDeform'
@@ -227,6 +227,20 @@ class DeformerSurfaceDeform(Node, DeformerNode):
         self.init_sockets(SurfaceDeformSockets)
         self.initialized = True
 
+class DeformerMeshDeform(Node, DeformerNode):
+    '''A node representing a Mesh Deform modifier'''
+    bl_idname = 'DeformerMeshDeform'
+    bl_label = "Mesh Deform"
+    bl_icon = 'MOD_SOFT'
+    initialized : bpy.props.BoolProperty(default = False)
+    num_targets : bpy.props.IntProperty(default = 0)
+    mantis_node_class_name=bl_idname
+
+    def init(self, context):
+        self.init_sockets(MeshDeformSockets)
+        self.initialized = True
+
+
 # Set up the class property that ties the UI classes to the Mantis classes.
 for cls in TellClasses():
     cls.set_mantis_class()

+ 16 - 3
deformer_socket_templates.py

@@ -8,6 +8,7 @@ Target = SockTemplate(name="Target", bl_idname='xFormSocket',
         is_input=True,
     )
 
+
 HookSockets= [
     DeformerInput := SockTemplate(name="Deformer", bl_idname='DeformerSocket',
         is_input=True,),
@@ -25,11 +26,10 @@ HookSockets= [
         is_input=False,), 
 ]
 
+
 SurfaceDeformSockets= [
-    DeformerInput := SockTemplate(name="Deformer", bl_idname='DeformerSocket',
-        is_input=True,),
+    DeformerInput,
     SurfaceDeformTarget := replace(Target, name="Target",),
-    replace(SplineIndexTemplate,),
     Falloff := SockTemplate(name="Falloff", bl_idname='FloatSocket',
         is_input=True, default_value=4.0, blender_property="falloff", ),
     Strength := replace(Influence, name="Strength", bl_idname='FloatSocket',
@@ -40,6 +40,19 @@ SurfaceDeformSockets= [
         is_input=True, default_value=False, blender_property="invert_vertex_group"),
     SparseBind := SockTemplate(name="Sparse Bind", bl_idname='BooleanSocket',
         is_input=True, default_value=False, blender_property="use_sparse_bind"),
+    DeformerOutput,
+]
+
+MeshDeformSockets= [
+    DeformerInput := SockTemplate(name="Deformer", bl_idname='DeformerSocket',
+        is_input=True,),
+    MeshDeformTarget := replace(Target, name="Object",),
+    VertexGroup,
+    InvertVertexGroup,
+    MeshDeformPrecision := SockTemplate(name="Precision", bl_idname='UnsignedIntSocket',
+        is_input=True, default_value=4, blender_property="precision"),
+    DynamicBind := SockTemplate(name="Dynamic Bind", bl_idname='BooleanSocket',
+        is_input=True, default_value=False, blender_property="use_dynamic_bind"),
     DeformerOutput := SockTemplate(name="Deformer", bl_idname='DeformerSocket',
         is_input=False,), 
 ]