constraint.py 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. # ##### BEGIN GPL LICENSE BLOCK #####
  2. #
  3. # This program is free software; you can redistribute it and/or
  4. # modify it under the terms of the GNU General Public License
  5. # as published by the Free Software Foundation; either version 2
  6. # of the License, or (at your option) any later version.
  7. #
  8. # This program is distributed in the hope that it will be useful,
  9. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. # GNU General Public License for more details.
  12. #
  13. # You should have received a copy of the GNU General Public License
  14. # along with this program; if not, write to the Free Software Foundation,
  15. # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  16. #
  17. # ##### END GPL LICENSE BLOCK #####
  18. # <pep8-80 compliant>
  19. from bpy.types import (
  20. Operator,
  21. )
  22. from bpy.props import (
  23. IntProperty,
  24. )
  25. class CONSTRAINT_OT_add_target(Operator):
  26. """Add a target to the constraint"""
  27. bl_idname = "constraint.add_target"
  28. bl_label = "Add Target"
  29. bl_options = {'UNDO', 'INTERNAL'}
  30. def execute(self, context):
  31. context.constraint.targets.new()
  32. return {'FINISHED'}
  33. class CONSTRAINT_OT_remove_target(Operator):
  34. """Remove the target from the constraint"""
  35. bl_idname = "constraint.remove_target"
  36. bl_label = "Remove Target"
  37. bl_options = {'UNDO', 'INTERNAL'}
  38. index: IntProperty()
  39. def execute(self, context):
  40. tgts = context.constraint.targets
  41. tgts.remove(tgts[self.index])
  42. return {'FINISHED'}
  43. class CONSTRAINT_OT_normalize_target_weights(Operator):
  44. """Normalize weights of all target bones"""
  45. bl_idname = "constraint.normalize_target_weights"
  46. bl_label = "Normalize Weights"
  47. bl_options = {'UNDO', 'INTERNAL'}
  48. def execute(self, context):
  49. tgts = context.constraint.targets
  50. total = sum(t.weight for t in tgts)
  51. if total > 0:
  52. for t in tgts:
  53. t.weight = t.weight / total
  54. return {'FINISHED'}
  55. class CONSTRAINT_OT_disable_keep_transform(Operator):
  56. """Set the influence of this constraint to zero while """ \
  57. """trying to maintain the object's transformation. Other active """ \
  58. """constraints can still influence the final transformation"""
  59. bl_idname = "constraint.disable_keep_transform"
  60. bl_label = "Disable and Keep Transform"
  61. bl_options = {'UNDO', 'INTERNAL'}
  62. @classmethod
  63. def poll(cls, context):
  64. constraint = getattr(context, "constraint", None)
  65. return constraint and constraint.influence > 0.0
  66. def execute(self, context):
  67. """Disable constraint while maintaining the visual transform."""
  68. # This works most of the time, but when there are multiple constraints active
  69. # there could still be one that overrides the visual transform.
  70. #
  71. # Note that executing this operator and then increasing the constraint
  72. # influence may move the object; this happens when the constraint is
  73. # additive rather than replacing the transform entirely.
  74. # Get the matrix in world space.
  75. is_bone_constraint = context.space_data.context == 'BONE_CONSTRAINT'
  76. ob = context.object
  77. if is_bone_constraint:
  78. bone = context.pose_bone
  79. mat = ob.matrix_world @ bone.matrix
  80. else:
  81. mat = ob.matrix_world
  82. context.constraint.influence = 0.0
  83. # Set the matrix.
  84. if is_bone_constraint:
  85. bone.matrix = ob.matrix_world.inverted() @ mat
  86. else:
  87. ob.matrix_world = mat
  88. return {'FINISHED'}
  89. classes = (
  90. CONSTRAINT_OT_add_target,
  91. CONSTRAINT_OT_remove_target,
  92. CONSTRAINT_OT_normalize_target_weights,
  93. CONSTRAINT_OT_disable_keep_transform,
  94. )