math_nodes.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. from .utilities.node_common import *
  2. from .base_definitions import MantisNode
  3. from .math_nodes_socket_templates import *
  4. def TellClasses():
  5. return [
  6. MathStaticInt,
  7. MathStaticFloat,
  8. MathStaticVector,
  9. ]
  10. def math_operation(operation, a, b):
  11. match operation:
  12. case "ADD":
  13. return a+b
  14. case "SUBTRACT":
  15. return a-b
  16. case "MULTIPLY":
  17. return a*b
  18. case "DIVIDE":
  19. return a/b
  20. case "FLOOR_DIVIDE":
  21. return a//b
  22. case "MODULUS":
  23. return a%b
  24. case "POWER":
  25. return a**b
  26. case "ABSOLUTE":
  27. return abs(a)
  28. case "MAXIMUM":
  29. return max(a, b)
  30. case "MINIMUM":
  31. return min(a, b)
  32. case "GREATER THAN":
  33. return float(a > b)
  34. case "LESS THAN":
  35. return float(a < b)
  36. case "ARCTAN2":
  37. from math import atan2
  38. return atan2(a,b)
  39. case "FLOOR":
  40. from math import floor
  41. return floor(a)
  42. case "CEIL":
  43. from math import ceil
  44. return ceil(a)
  45. case "ROUND":
  46. return round(a)
  47. #*#-------------------------------#++#-------------------------------#*#
  48. # M A T H N O D E S
  49. #*#-------------------------------#++#-------------------------------#*#
  50. class MathStaticInt(MantisNode):
  51. '''A node representing an integer math operation'''
  52. __slots__ = ()
  53. socket_templates = StaticIntSockets
  54. node_type = "UTILITY"
  55. def bPrepare(self, bContext = None,):
  56. a = self.evaluate_input("Int A"); b = self.evaluate_input("Int B")
  57. result = math_operation(self.evaluate_input("Operation"), a, b)
  58. self.parameters["Result Int"] = int(result)
  59. self.prepared, self.executed = True, True
  60. class MathStaticFloat(MantisNode):
  61. '''A node representing a float math operation'''
  62. __slots__ = ()
  63. socket_templates = StaticFloatSockets
  64. node_type = "UTILITY"
  65. def bPrepare(self, bContext = None,):
  66. a = self.evaluate_input("Float A"); b = self.evaluate_input("Float B")
  67. result = math_operation(self.evaluate_input("Operation"), a, b)
  68. self.parameters["Result Float"] = result
  69. self.prepared, self.executed = True, True
  70. class MathStaticVector(MantisNode):
  71. '''A node representing a vector math operation'''
  72. __slots__ = ()
  73. socket_templates = StaticVectorSockets
  74. node_type = "UTILITY"
  75. def bPrepare(self, bContext = None,):
  76. from mathutils import Vector
  77. a = Vector(self.evaluate_input("Vector A")).copy()
  78. b = Vector(self.evaluate_input("Vector B")).copy()
  79. s = self.evaluate_input("Scalar A")
  80. if hasattr(s, '__iter__'):
  81. average = lambda iterable : sum(iterable)/len(iterable)
  82. s = average(s)
  83. f_result = float("NaN")
  84. v_result = None
  85. if self.evaluate_input("Operation") == "ADD":
  86. v_result = a+b
  87. if self.evaluate_input("Operation") == "SUBTRACT":
  88. v_result = a-b
  89. if self.evaluate_input("Operation") == "MULTIPLY":
  90. v_result = a*b
  91. if self.evaluate_input("Operation") == "DIVIDE":
  92. v_result = Vector((0,0,0)) # channel-wise division
  93. for i, (axis_a, axis_b) in enumerate(zip(a,b)):
  94. v_result[i] = axis_a/axis_b
  95. if self.evaluate_input("Operation") == "POWER":
  96. v_result = a**b
  97. # since these are unary, we need to make a copy lest we create spooky effects elsewhere.
  98. a = a.copy()
  99. if self.evaluate_input("Operation") == "SCALE":
  100. v_result = a.normalized() * s
  101. if self.evaluate_input("Operation") == "LENGTH":
  102. f_result = a.magnitude
  103. if self.evaluate_input("Operation") == "CROSS":
  104. v_result = a.cross(b)
  105. if self.evaluate_input("Operation") == "DOT":
  106. f_result = a.dot(b)
  107. if self.evaluate_input("Operation") == "NORMALIZE":
  108. v_result = a.normalized()
  109. if self.evaluate_input("Operation") == "LINEAR_INTERP":
  110. v_result = a.lerp(b, s).copy()
  111. self.parameters["Result Float"] = f_result
  112. # if v_result:
  113. self.parameters["Result Vector"] = v_result
  114. self.prepared = True
  115. self.executed = True