# Animate a metaball which is a collection of meta elements import sys, code, random, os, math, bpy, canvas, colorsys from math import pi, sin, cos, ceil from mathutils import Vector, Quaternion from random import TWOPI

sys.path.append(os.path.dirname(os.path.dirname(__file__))) import helpers

class Metaballs(canvas.Canvas):

TYPES =  ['BALL', 'CAPSULE', 'PLANE', 'ELLIPSOID', 'CUBE']

def render(self):
  diameter = 4.0
  sz = 2.125 / diameter
  latitude = 10
  longitude = latitude * 2
  invlatitude = 1.0 / (latitude - 1)
  current_frame = 0
  jprc = 0.0
  phi = 0.0
  theta = 0.0
  pt = Vector((0.0, 0.0, 0.0))
  rotpt = Vector((0.0, 0.0, 0.0))
  center = Vector((0.0, 0.0, 0.0))
  baseaxis = Vector((0.0, 1.0, 0.0))
  axis = Vector((0.0, 0.0, 0.0))
  metaball_type = random.choice(self.TYPES)
  mbdata = bpy.data.metaballs.new('meta_balls')
  mbdata.render_resolution = 0.075
  mbdata.resolution = 0.1
  mbobj = bpy.data.objects.new("meta_bollocks", mbdata)
  bpy.context.scene.objects.link(mbobj)
  helpers.assign_material(mbobj, helpers.random_material(self.MATERIALS_NAMES))
  for i in range(0, latitude, 1):
      phi = pi * (i + 1) * invlatitude
      pt.z = cos(phi) * diameter
      for j in range(0, longitude, 1):
          theta = TWOPI * j / longitude
          pt.y = center.y + sin(phi) * sin(theta) * diameter
          pt.x = center.x + sin(phi) * cos(theta) * diameter
          mbelm = mbdata.elements.new(type=metaball_type)
          mbelm.co = (latitude, longitude, 6)
          mbelm.radius = 0.15 + sz * abs(sin(phi)) * 1.85
          mbelm.stiffness = 1.0
          if i % 7 == j % 3:
              mbelm.use_negative = True
          for f in range(0, self.NUMBER_OF_FRAMES, 1):
              fprc = f / (self.NUMBER_OF_FRAMES - 1)
              bpy.context.scene.frame_set(f)
              mbelm.co = helpers.rotate_vector(TWOPI * fprc, axis, pt)
              mbelm.keyframe_insert(data_path='co')