/ utils.py
utils.py
 1  import c4d
 2  from c4d.modules import mograph as mg
 3  
 4  
 5  def average_color(color1, color2):
 6      # gives the correct average of two colors
 7      x1 = color1.x
 8      y1 = color1.y
 9      z1 = color1.z
10  
11      x2 = color2.x
12      y2 = color2.y
13      z2 = color2.z
14  
15      average_x = (x1**2 + x2**2) / 2**0.5
16      average_y = (y1**2 + y2**2) / 2**0.5
17      average_z = (z1**2 + z2**2) / 2**0.5
18  
19      average_color = c4d.Vector(average_x, average_y, average_z)
20      return average_color
21  
22  def match_indices(indices1, indices2):
23      # matches indices in the most natural way
24      if indices1 >= indices2:
25          m = indices1
26          n = indices2
27      else:
28          m = indices2
29          n = indices1
30      divider, rest = divmod(m, n)
31      indices_m = range(m)
32      indices_n = []
33      for j in range(n):
34          indices_n += [j] * divider
35          if rest > 0:
36              indices_n += [j]
37              rest -= 1
38      if indices1 >= indices2:
39          return indices_m, indices_n
40      else:
41          return indices_n, indices_m
42  
43  def connect_nearest_clones(*matrices, n=5, max_distance=False):
44      # dynamically creates edges between clones based on proximity
45      
46      def create_splines_null():
47          # checks whether a splines null exists
48          document = c4d.documents.GetActiveDocument()
49          splines_null = document.SearchObject("SplineCache")
50  
51      def get_clones(*matrices):
52          # gets the combined clones of all input matrices
53          all_clones = []
54          for matrix in matrices:
55              mo_data = mg.GeGetMoData(matrix)
56              clones = mo_data.GetArray(c4d.MODATA_MATRIX)
57              all_clones += clones
58          return all_clones
59  
60      def delete_previous_splines():
61          document = c4d.documents.GetActiveDocument()
62          temp_splines_null = document.SearchObject("SplineCache")
63          temp_splines = temp_splines_null.GetChildren()
64          for temp_spline in temp_splines:
65              temp_spline.Remove()
66      
67      def create_connection_splines(clones, n, max_distance):
68          # for every clone loops over other clones and finds the n closest clones
69          # (with optional max distance) then connects them with a spline
70          for clone in clones:
71              other_clones = clones.copy()
72              other_clones.remove(clone)
73              other_clones.sort(key=lambda other_clone: (clone.off - other_clone.off).GetLength())
74              nearest_clones = other_clones[:n]
75              for nearest_clone in nearest_clones:
76                  # check max distance
77                  if max_distance:
78                      distance = (clone.off - nearest_clone.off).GetLength()
79                      if distance > max_distance:
80                          break
81                  # create spline
82                  temp_spline = c4d.BaseObject(c4d.Ospline)
83                  spline_points = [clone.off, nearest_clone.off]
84                  temp_spline.ResizeObject(2)
85                  temp_spline.SetAllPoints(spline_points)
86                  document = c4d.documents.GetActiveDocument()
87                  temp_splines_null = document.SearchObject("SplineCache")
88                  document.InsertObject(temp_spline)
89                  temp_spline.InsertUnder(temp_splines_null)
90  
91      create_splines_null()
92      clones = get_clones(*matrices)
93      delete_previous_splines()
94      create_connection_splines(clones, n, max_distance)