primitives_nodes.py 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. from .utilities.node_common import *
  2. from .base_definitions import MantisNode, NodeSocket
  3. def TellClasses():
  4. return [
  5. # Primitives
  6. CirclePrimitive,
  7. GeometryLattice,
  8. ]
  9. #*#-------------------------------#++#-------------------------------#*#
  10. # P R I M I T I V E S
  11. #*#-------------------------------#++#-------------------------------#*#
  12. class PrimitiveNode(MantisNode):
  13. __slots__ = ()
  14. node_type = "UTILITY"
  15. def __init__(self, signature, base_tree, socket_templates=[]):
  16. super().__init__(signature, base_tree, socket_templates)
  17. self.prepared = True
  18. def reset_execution(self):
  19. super().reset_execution()
  20. self.prepared=True
  21. class CirclePrimitive(PrimitiveNode):
  22. '''A node representing a Circle Primitive mesh'''
  23. __slots__ = ()
  24. def __init__(self, signature, base_tree):
  25. super().__init__(signature, base_tree)
  26. inputs = [
  27. "Name",
  28. "Radius",
  29. "Number of Points",
  30. ]
  31. outputs = [
  32. "Circle",
  33. ]
  34. additional_parameters = {}
  35. self.inputs.init_sockets(inputs)
  36. self.outputs.init_sockets(outputs)
  37. self.init_parameters(additional_parameters=additional_parameters)
  38. # mode is unused but needed for interface consistency
  39. def bGetObject(self, mode=''):
  40. from bpy import data
  41. # first try Curve, then try Mesh
  42. bObject = data.curves.get(self.evaluate_input("Name"))
  43. if not bObject:
  44. bObject = data.meshes.get(self.evaluate_input("Name"))
  45. return bObject
  46. def bTransformPass(self, bContext = None,):
  47. # Get the datablock
  48. data = self.bGetObject()
  49. import bpy
  50. if not data:
  51. data = bpy.data.meshes.new( self.evaluate_input("Name") )
  52. # make the circle
  53. import bmesh; bm = bmesh.new()
  54. bmesh.ops.create_circle( # lazy but easy
  55. bm,
  56. cap_ends=False,
  57. radius=max(self.evaluate_input("Radius"), 0.0001),
  58. segments=min( max( self.evaluate_input("Number of Points"), 3), 1024),
  59. )
  60. # this is rotated 90 degrees, we need Y-up instead of Z-up
  61. from mathutils import Matrix
  62. from math import pi
  63. for v in bm.verts:
  64. v.co = Matrix.Rotation(pi/2, 4, 'X') @ v.co
  65. # done with this, push it to the data and free the bmesh.
  66. bm.to_mesh(data); bm.free()
  67. self.executed = True
  68. from .primitives_sockets import LatticeSockets
  69. class GeometryLattice(PrimitiveNode):
  70. '''A node representing a Circle Primitive mesh'''
  71. __slots__ = ()
  72. def __init__(self, signature, base_tree):
  73. super().__init__(signature, base_tree, LatticeSockets)
  74. self.init_parameters(additional_parameters= {})
  75. self.prepared = False
  76. def reset_execution(self):
  77. super().reset_execution()
  78. self.prepared=False
  79. self.executed=False
  80. # mode is unused but needed for interface consistency
  81. def bGetObject(self, mode=''):
  82. from bpy import data
  83. bObject = data.lattices.get(self.evaluate_input("Name"))
  84. return bObject
  85. def bPrepare(self, bContext = None,):
  86. # Get the datablock
  87. data = self.bGetObject()
  88. import bpy
  89. if not data:
  90. data = bpy.data.lattices.new( self.evaluate_input("Name") )
  91. props_sockets = self.gen_property_socket_map()
  92. evaluate_sockets(self, data, props_sockets)
  93. self.prepared = True; self.executed = True