math_containers.py 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. from .node_container_common import *
  2. from .base_definitions import MantisNode, NodeSocket
  3. def TellClasses():
  4. return [
  5. MathStaticInt,
  6. MathStaticFloat,
  7. MathStaticVector,
  8. ]
  9. def math_operation(operation, a, b):
  10. match operation:
  11. case "ADD":
  12. return a+b
  13. case "SUBTRACT":
  14. return a-b
  15. case "MULTIPLY":
  16. return a*b
  17. case "DIVIDE":
  18. return a/b
  19. case "FLOOR_DIVIDE":
  20. return a//b
  21. case "MODULUS":
  22. return a%b
  23. case "POWER":
  24. return a**b
  25. case "ABSOLUTE":
  26. return abs(a)
  27. case "MAXIMUM":
  28. return max(a, b)
  29. case "MINIMUM":
  30. return min(a, b)
  31. case "GREATER THAN":
  32. return float(a > b)
  33. case "LESS THAN":
  34. return float(a < b)
  35. case" ARCTAN2":
  36. from math import atan2
  37. return atan2(a,b)
  38. #*#-------------------------------#++#-------------------------------#*#
  39. # M A T H N O D E S
  40. #*#-------------------------------#++#-------------------------------#*#
  41. class MathStaticInt(MantisNode):
  42. '''A node representing an armature object'''
  43. def __init__(self, signature, base_tree):
  44. super().__init__(signature, base_tree)
  45. inputs = [
  46. "Operation",
  47. "Int A",
  48. "Int B",
  49. ]
  50. outputs = [
  51. "Result Int",
  52. ]
  53. additional_parameters = {}
  54. self.inputs.init_sockets(inputs)
  55. self.outputs.init_sockets(outputs)
  56. self.init_parameters(additional_parameters=additional_parameters)
  57. self.node_type = "UTILITY"
  58. def bPrepare(self, bContext = None,):
  59. a = self.evaluate_input("Int A"); b = self.evaluate_input("Int B")
  60. result = math_operation(self.evaluate_input("Operation"), a, b)
  61. self.parameters["Result Int"] = int(result)
  62. self.prepared, self.executed = True, True
  63. class MathStaticFloat(MantisNode):
  64. '''A node representing an armature object'''
  65. def __init__(self, signature, base_tree):
  66. super().__init__(signature, base_tree)
  67. inputs = [
  68. "Operation",
  69. "Float A",
  70. "Float B",
  71. ]
  72. outputs = [
  73. "Result Float",
  74. ]
  75. additional_parameters = {}
  76. self.inputs.init_sockets(inputs)
  77. self.outputs.init_sockets(outputs)
  78. self.init_parameters(additional_parameters=additional_parameters)
  79. self.node_type = "UTILITY"
  80. def bPrepare(self, bContext = None,):
  81. a = self.evaluate_input("Float A"); b = self.evaluate_input("Float B")
  82. result = math_operation(self.evaluate_input("Operation"), a, b)
  83. self.parameters["Result Float"] = result
  84. self.prepared, self.executed = True, True
  85. class MathStaticVector(MantisNode):
  86. '''A node representing an armature object'''
  87. def __init__(self, signature, base_tree):
  88. super().__init__(signature, base_tree)
  89. inputs = [
  90. "Operation",
  91. "Vector A",
  92. "Vector B",
  93. "Scalar A",
  94. ]
  95. outputs = [
  96. "Result Vector",
  97. "Result Float",
  98. ]
  99. additional_parameters = {}
  100. self.inputs.init_sockets(inputs)
  101. self.outputs.init_sockets(outputs)
  102. self.init_parameters(additional_parameters=additional_parameters)
  103. self.node_type = "UTILITY"
  104. def bPrepare(self, bContext = None,):
  105. from mathutils import Vector
  106. a = Vector(self.evaluate_input("Vector A")).copy()
  107. b = Vector(self.evaluate_input("Vector B")).copy()
  108. s = self.evaluate_input("Scalar A")
  109. if hasattr(s, '__iter__'):
  110. average = lambda iterable : sum(iterable)/len(iterable)
  111. s = average(s)
  112. f_result = float("NaN")
  113. v_result = None
  114. if self.evaluate_input("Operation") == "ADD":
  115. v_result = a+b
  116. if self.evaluate_input("Operation") == "SUBTRACT":
  117. v_result = a-b
  118. if self.evaluate_input("Operation") == "MULTIPLY":
  119. v_result = a*b
  120. if self.evaluate_input("Operation") == "DIVIDE":
  121. v_result = a/b
  122. if self.evaluate_input("Operation") == "POWER":
  123. v_result = a**b
  124. # since these are unary, we need to make a copy lest we create spooky effects elsewhere.
  125. a = a.copy()
  126. if self.evaluate_input("Operation") == "SCALE":
  127. v_result = a.normalized() * s
  128. if self.evaluate_input("Operation") == "LENGTH":
  129. f_result = a.magnitude
  130. if self.evaluate_input("Operation") == "CROSS":
  131. v_result = a.cross(b)
  132. if self.evaluate_input("Operation") == "DOT":
  133. f_result = a.dot(b)
  134. if self.evaluate_input("Operation") == "NORMALIZE":
  135. v_result = a.normalized()
  136. if self.evaluate_input("Operation") == "LINEAR_INTERP":
  137. v_result = a.lerp(b, s).copy()
  138. self.parameters["Result Float"] = f_result
  139. # if v_result:
  140. self.parameters["Result Vector"] = v_result
  141. self.prepared = True
  142. self.executed = True