diff --git a/◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/ARRAY_TOOLS_1-2-1/AT_INTERFACE.PY b/◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/ARRAY_TOOLS_1-2-1/AT_INTERFACE.PY deleted file mode 100644 index 57af0098..00000000 --- a/◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/ARRAY_TOOLS_1-2-1/AT_INTERFACE.PY +++ /dev/null @@ -1,1223 +0,0 @@ -# -*- coding: utf-8 -*- -import bpy -import math - -from bpy.types import PropertyGroup -from mathutils import Vector - -from . import cfg -from . import at_panel -from . import at_operators -from . at_calc_func import( - x_axis, - y_axis, - z_axis, - xyz_axis, - at_all_in_one, - at_random, - sum_serie, - tsr -) - -"""not used yet -if check on update, may really slow the addon """ -def check_list(alist): - """check all the objects""" - for elem in alist: - if elem in bpy.data.objects: - pass - else: - cfg.display_error(str(elem)+" isn't valid.") - print("Check_list : a name isn't valid ", elem) - return False - return True - - -def elem_in_row(column, row, indice): - """Number of elements in a row""" - elements = column + (row - 1) * indice - # print("row elements =", elements) - return elements - - -# ---------------------------- Properties --------------------------- -class ArrayTools_props(PropertyGroup): - """Properties for array tools""" - - def add_in_column(self, row, nb_column=-1): - """Add nb_column element(s) in each row""" - column = cfg.at_count_values[0] - if nb_column == -1: - nb_column = cfg.at_count_values[1] - column - - ref_name = cfg.atools_objs[0][0] - if ref_name in bpy.data.objects: - ref_obj = bpy.data.objects[ref_name] - # update the ref_mtx if object's transforms have changed - cfg.ref_mtx = ref_obj.matrix_world.copy() - # with offset no need to replace all elements, only the last - if self.is_tr_off_last: - for i in range(row): - col = column + i*self.alter - for j in range(col, col + nb_column): - objcp = ref_obj.copy() - array_col = bpy.data.collections.get(cfg.col_name) - array_col.objects.link(objcp) - if self.is_copy: - objcp.data = ref_obj.data.copy() - cfg.atools_objs[i].append(objcp.name) - - self.transforms_lsr(j, i, cfg.ref_mtx, objcp.name) - # update the global ui - tr, sc, rot = self.calc_global() - self.up_ui_tr_global(tr) - self.up_ui_sc_global(sc) - self.up_ui_rot_global(rot) - - else: # replace all elements - for i in range(row): - col = column + i*self.alter - for j in range(col, col + nb_column): - objcp = ref_obj.copy() - array_col = bpy.data.collections.get(cfg.col_name) - array_col.objects.link(objcp) - if self.is_copy: - objcp.data = ref_obj.data.copy() - cfg.atools_objs[i].append(objcp.name) - self.update_global(bpy.context) - del objcp - del ref_obj - else: - message = "Problem with reference object's name." - cfg.display_error(message) - print("Error in 'add_in_column' : ", message) - - - def del_in_column(self, row, nb_column=-1): - """Remove nb_column element(s) in each row""" - if nb_column == -1: - nb_column = cfg.at_count_values[0] - cfg.at_count_values[1] - array_col = bpy.data.collections.get(cfg.col_name) - for i in range(row-1, -1, -1): - for j in range(nb_column): - del_name = cfg.atools_objs[i].pop() - if del_name in bpy.data.objects: - obj = bpy.data.objects[del_name] - array_col.objects.unlink(obj) - bpy.data.objects.remove(obj, do_unlink=True) - else: - cfg.display_error(del_name + " doesn't exist anymore.") - print("Error in 'del_in_column' : ", del_name) - - # if no more element in list, remove the row - if not cfg.atools_objs[i]: - cfg.atools_objs.pop() - self.up_ui_updateRow(row - 1) - continue - if not self.is_tr_off_last: - # if global is used last - self.update_global(bpy.context) - else: - tr, sc, rot = self.calc_global() - self.up_ui_tr_global(tr) - self.up_ui_sc_global(sc) - self.up_ui_rot_global(rot) - - - def add_in_col_alter(self, row, nb_column): - """Add elements in all rows except the first for variation""" - array_col = bpy.data.collections.get(cfg.col_name) - ref_name = cfg.atools_objs[0][0] - column = self.count - if ref_name in bpy.data.objects: - ref_obj = bpy.data.objects[ref_name] - cfg.ref_mtx = ref_obj.matrix_world.copy() - if self.is_tr_off_last: - for i in range(1, row): - for j in range(column, column + i * nb_column): - objcp = ref_obj.copy() - array_col = bpy.data.collections.get(cfg.col_name) - array_col.objects.link(objcp) - if self.is_copy: - objcp.data = ref_obj.data.copy() - cfg.atools_objs[i].append(objcp.name) - # print("objs=", cfg.atools_objs) - - self.update_offset(bpy.context) - else: # replace all elements - for i in range(1, row): - for j in range(column, column + i * nb_column): - objcp = ref_obj.copy() - array_col = bpy.data.collections.get(cfg.col_name) - array_col.objects.link(objcp) - if self.is_copy: - objcp.data = ref_obj.data.copy() - cfg.atools_objs[i].append(objcp.name) - self.update_global(bpy.context) - del objcp - del ref_obj - else: - message = "Problem with reference object's name." - cfg.display_error(message) - print("Error in 'add_in_column' : ", message) - - - def del_in_col_alter(self, row, nb_column): - """Remove elements in all rows except the first""" - array_col = bpy.data.collections.get(cfg.col_name) - for i in range(row -1 , 0, -1): - for j in range(nb_column * i): - del_name = cfg.atools_objs[i].pop() - # print("del name=", del_name) - if del_name in bpy.data.objects: - obj = bpy.data.objects[del_name] - array_col.objects.unlink(obj) - bpy.data.objects.remove(obj, do_unlink=True) - else: - cfg.display_error(del_name + " doesn't exist anymore.") - print("Error in 'del_in_column' : ", del_name) - if self.is_tr_off_last: - self.update_offset(bpy.context) - else: - self.update_global(bpy.context) - - def add_in_row(self, column, nb_row=-1): - """Add column elements in nb_row new row(s)""" - row = cfg.at_row_values[0] - if nb_row == -1: - nb_row = cfg.at_row_values[1] - row - - ref_name = cfg.atools_objs[0][0] - if ref_name in bpy.data.objects: - ref_obj = bpy.data.objects[ref_name] - cfg.ref_mtx = ref_obj.matrix_world.copy() - if self.is_tr_off_last: - for i in range(row, row + nb_row): - cfg.atools_objs.append([]) - for j in range(column + i*self.alter): - objcp = ref_obj.copy() - array_col = bpy.data.collections.get(cfg.col_name) - array_col.objects.link(objcp) - if self.is_copy: - objcp.data = ref_obj.data.copy() - cfg.atools_objs[i].append(objcp.name) - self.transforms_lsr(j, i, cfg.ref_mtx, objcp.name) - else: - for i in range(row, row + nb_row): - cfg.atools_objs.append([]) - for j in range(column): - objcp = ref_obj.copy() - array_col = bpy.data.collections.get(cfg.col_name) - array_col.objects.link(objcp) - if self.is_copy: - objcp.data = ref_obj.data.copy() - cfg.atools_objs[i].append(objcp.name) - self.update_global(bpy.context) - else: - message = "Problem with reference object's name." - cfg.display_error(message) - print("Error in 'add in row' : ", message) - - - def del_in_row(self, nb_row=-1): - """Remove nb_row row(s) : (column * nb_row) elements""" - if nb_row == -1: - nb_row = cfg.at_row_values[0] - cfg.at_row_values[1] - array_col = bpy.data.collections.get(cfg.col_name) - for i in range(nb_row): - names = cfg.atools_objs.pop() - for del_name in names: - if del_name in bpy.data.objects: - obj = bpy.data.objects[del_name] - array_col.objects.unlink(obj) - bpy.data.objects.remove(obj, do_unlink=True) - else: - cfg.display_error(del_name + " doesn't exist anymore.") - print("Error in 'del_in_column' : ", del_name) - - - def at_del_all(self, del_rall): - """Delete all copies and remove objects from lists - del_rall : boolean, True to del reference object from list - """ - array_col = bpy.data.collections.get(cfg.col_name) - ref_name = cfg.atools_objs[0][0] - for i in range(self.row): - names = cfg.atools_objs.pop() - for obj_name in reversed(names): - if obj_name == ref_name: - continue - # test if object exist - if obj_name in bpy.data.objects: - obj = bpy.data.objects[obj_name] - array_col.objects.unlink(obj) - bpy.data.objects.remove(obj, do_unlink=True) - else: - cfg.display_error(obj_name + " not exist!") - print("Error in 'del_all' : ", obj_name) - - if del_rall: - cfg.atools_objs.clear() - - # removing the collection if empty - if not array_col.objects: - bpy.data.collections.remove(array_col) - else: - cfg.atools_objs.append([ref_name]) - # print("Del_all done!") - - # ----------------------- UI update ----------------------------- - # --------------------------------------------------------------- - # ----------------------- count update -------------------------- - def updateCount(self, context): - """update the number of element(s) in column""" - if self.is_prog_change: - self.is_prog_change = False - else: - cfg.add_count(int(self.count)) - cfg.del_count() - - # cfg.count_values[0] always store old count value - difference = self.count - cfg.at_count_values[0] - - self.update_infos() - - if difference > 0: - self.add_in_column(self.row, difference) - elif difference < 0: - self.del_in_column(self.row, -difference) - # print("objs =", cfg.atools_objs) - - - def up_ui_updateCount(self, val): - """Update the value of the property count in UI""" - self.is_prog_change = True - self.count = val - - # ----------------------- row update ---------------------------- - def update_row(self, context): - """Update row property""" - cfg.add_row(self.row) - cfg.del_row() - if self.is_prog_change: - self.is_prog_change = False - else: - if self.alter < 0 and cfg.maxrow < self.row: - cfg.display_error("Maximun rows for these setting is : " + str(cfg.maxrow)) - self.up_ui_updateRow(cfg.maxrow) - return - - # cfg.at_row_values[0] always store old row value - difference = self.row - cfg.at_row_values[0] - if difference > 0: - self.add_in_row(self.count, difference) - elif difference < 0: - self.del_in_row(-difference) - - line = elem_in_row(self.count, self.row, self.alter) - - self.update_infos() - - def up_ui_updateRow(self, val): - """Update the value of the property row in UI""" - self.is_prog_change = True - self.row = val - - def update_alter(self, context): - """Update alter property""" - if self.is_prog_change: - self.is_prog_change = False - else: - # alter must have at least 2 rows - if self.row == 1 and self.alter != 0: - cfg.display_error("Add more rows first.") - self.up_ui_updateAlter(0) - return - if self.alter < 0: - # (column + (row-1)* variation) is the number of elements - # of the last row and must be at least >= 1 - alter = int((1 - self.count) / (self.row - 1)) - if self.alter < alter: - cfg.display_error("Min variation is '"+str(alter)+"' for these settings.") - self.up_ui_updateAlter(alter) - return - - cfg.add_alter(self.alter) - cfg.del_alter() - self.update_ralign() - - difference = self.alter - cfg.at_alter[0] - if difference > 0: - self.add_in_col_alter(self.row, difference) - elif difference < 0: - self.del_in_col_alter(self.row, -difference) - # print(f"count={self.count}, row={self.row}, alter={self.alter}") - line = elem_in_row(self.count, self.row, self.alter) - # print("elems in row =", line) - - self.update_infos() - - - def up_ui_updateAlter(self, val): - """Update the value of the property alter in UI""" - self.is_prog_change = True - self.alter = val - - - def update_ralign(self): - """Update the value of ralign""" - decal = -self.alter * self.tr_offset - if self.align == 'LEFT': - self.ralign = Vector((0.0, 0.0, 0.0)) - elif self.align == 'CENTER': - self.ralign = decal / 2 - elif self.align == 'RIGHT': - self.ralign = decal - - - def update_align(self, context): - """According to the value of align, calculate ralign""" - self.update_ralign() - - if self.is_tr_off_last: - self.update_offset(bpy.context) - else: - self.update_global(bpy.context) - - - def update_infos(self): - """Update properties total and erow""" - sum = sum_serie(self.row, self.alter) - square = self.count * self.row - if self.alter >= 0: - cfg.maxrow = self.row - else: - ca = self.count // -self.alter - cfg.maxrow = ca if self.count % self.alter == 0 else ca + 1 - self.total = str(int(square + sum)) - self.erow = str(elem_in_row(self.count, self.row, self.alter)) - - # ----------------------- translation update -------------------- - def up_ui_tr_offset(self, val): - """Update the value of the property tr_offset in UI""" - self.is_prog_change = True - self.tr_offset = val - - def up_ui_tr_global(self, val): - """Update the value of the property tr_global in UI""" - self.is_prog_change = True - self.tr_global = val - - # ----------------------- scale update -------------------------- - def up_ui_sc_offset(self, val): - """Update the value of the property sc_offset in UI""" - self.is_prog_change = True - self.sc_offset = val - - def up_ui_sc_global(self, val): - """Update the value of the property sc_global in UI""" - self.is_prog_change = True - self.sc_global = val - - # ----------------------- rotation update ----------------------- - def up_ui_rot_offset(self, val): - """Update the value of the property rot_offset in UI""" - self.is_prog_change = True - self.rot_offset = val - - def up_ui_rot_global(self, val): - """Update the value of the property rot_global in UI""" - self.is_prog_change = True - self.rot_global = val - - # --------------------------------------------------------------- - def calc_global(self): - """Calculate global for column""" - tg = (self.count-1) * self.tr_offset - sg = (xyz_axis() - (self.count-1) * - (cfg.ref_mtx.to_scale() - (self.sc_offset/100))) * 100 - rg = self.count * Vector(self.rot_offset) - return tg,sg,rg - - - def transforms_lsr(self, column, row, mat, ename): - """Calculate transforms according to the position of the element - column : indice of the element's column - row : indice of the element's row - mat : matrix of the reference object - ename : element's name to put in place - """ - localxyz = (x_axis(), y_axis(), z_axis()) - - translate, scaling, rotate = tsr(mat, column, row, self.tr_offset, self.tr_second, - self.sc_offset, self.sc_second, self.rot_offset, self.rot_second, self.ralign) - if ename in bpy.data.objects: - obj = bpy.data.objects[ename] - if self.at_pivot is not None: - obj.matrix_world = at_all_in_one(mat, rotate, localxyz, translate, - scaling, self.at_pivot.location) - else: - obj.matrix_world = at_all_in_one(mat, rotate, localxyz, translate, - scaling, mat.translation) - - - def apply_transforms(self, matx, nb_column, nb_row, tr, sc, rot): - """Move, scale and rotate the selected elements - tr : translation offset of the first row - sc : scale offset of the first row - rot : rotation offset of the first row - return global transforms - """ - # local axis always (1,0,0) (0,1,0) (0,0,1) - localxyz = (x_axis(), y_axis(), z_axis()) - - ref_scale = matx.to_scale() - # duplicate code but avoid looping the test - if self.at_pivot is not None: - for i in range(nb_row): - for j in range(nb_column + i*self.alter): - elem = cfg.atools_objs[i][j] - if elem in bpy.data.objects: - obj = bpy.data.objects[elem] - else: - cfg.display_error(elem + " no more exist !") - print("Error in 'apply_transforms', name no more exist : ", elem) - continue - t_off, s_off, r_off = tsr(matx, j, i, tr, self.tr_second, sc, - self.sc_second, rot, self.rot_second, self.ralign) - - obj.matrix_world = at_all_in_one(matx, r_off, - localxyz, t_off, s_off, self.at_pivot.location) - else: - for i in range(nb_row): - for j in range(nb_column + i*self.alter): - ref_loc = cfg.ref_mtx.translation - elem = cfg.atools_objs[i][j] - if elem in bpy.data.objects: - obj = bpy.data.objects[elem] - else: - cfg.display_error(elem + " no more exist !") - print("Error in 'apply_transforms', name no more exist : ", elem) - continue - t_off, s_off, r_off = tsr(matx, j, i, tr, self.tr_second, sc, - self.sc_second, rot, self.rot_second, self.ralign) - - obj.matrix_world = at_all_in_one(matx, r_off, - localxyz, t_off, s_off, ref_loc) - tr_col,sc_col,rot_col = self.calc_global() - return(tr_col, sc_col, rot_col) - - def update_offset(self, context): - """Update for all offsets""" - if self.is_prog_change: - self.is_prog_change = False - else: # user change offset - self.is_tr_off_last = True - - ref_name = cfg.atools_objs[0][0] - if bpy.data.objects[ref_name]: - cfg.ref_mtx = bpy.data.objects[ref_name].matrix_world.copy() - aloc, asc, arot = self.apply_transforms(cfg.ref_mtx, self.count, self.row, - self.tr_offset, self.sc_offset, Vector(self.rot_offset)) - - # since offset changes, global too - self.up_ui_tr_global(aloc) - self.up_ui_sc_global(asc) - self.up_ui_rot_global(arot) - - - def update_global(self, context): - """Update for all globals""" - if self.is_prog_change: - self.is_prog_change = False - else: # user change global - self.is_tr_off_last = False - - ref_name = cfg.atools_objs[0][0] - if bpy.data.objects[ref_name]: - cfg.ref_mtx = bpy.data.objects[ref_name].matrix_world.copy() - ref_scale = cfg.ref_mtx.to_scale() - - translation_offset = Vector(self.tr_global) / (self.count - 1) - scale_offset = ref_scale - ((ref_scale-(self.sc_global/100)) / (self.count - 1)) - rotation_offset = Vector(self.rot_global) / self.count - - self.apply_transforms(cfg.ref_mtx, self.count, self.row, translation_offset, - Vector(scale_offset)*100, rotation_offset) - - # since global changes, offset too - self.up_ui_tr_offset(translation_offset) - self.up_ui_sc_offset(Vector(scale_offset*100)) - self.up_ui_rot_offset(rotation_offset) - - - def update_second(self, context): - """Update the secondary transforms""" - ref_name = cfg.atools_objs[0][0] - if bpy.data.objects[ref_name]: - cfg.ref_mtx = bpy.data.objects[ref_name].matrix_world.copy() - self.apply_transforms(cfg.ref_mtx, self.count, self.row, self.tr_offset, - self.sc_offset, self.rot_offset) - - - # ----------------------- is_copy update ------------------------ - def up_ui_is_copy(self): - """Update the value of the property is_copy in UI""" - self.is_prog_change = True - self.is_copy = False - - - def update_is_copy(self, context): - """Allow a copy or duplicate(copy link by default)""" - if self.is_prog_change: - self.is_prog_change = False - else: - if self.is_copy: # no need to rebuild all - for i in range(self.row): - for j in range(self.count): - if i == 0 and j == 0: - continue - ref_name = cfg.atools_objs[0][0] - elem_name = cfg.atools_objs[i][j] - bpy.data.objects[elem_name].data = bpy.data.objects[ref_name].data.copy() - else: # since the value change (now duplicate), need to rebuild - count = self.count - row = self.row - ref_name = cfg.atools_objs[0][0] - array_col = bpy.data.collections.get(cfg.col_name) - - # DO NOT USE BLENDER CRASH WITH IT - # self.at_del_all(False) - - bpy.ops.object.delete({"selected_objects": array_col.objects}) - cfg.atools_objs.clear() - cfg.atools_objs.append([ref_name]) - - ref_obj = bpy.data.objects[ref_name] - for i in range(row): - if i != 0: - cfg.atools_objs.append([]) - for j in range(count + i*self.alter): - objcp = ref_obj.copy() - array_col.objects.link(objcp) - cfg.atools_objs[i].append(objcp.name) - del objcp - del ref_obj - - if self.is_tr_off_last: - self.update_offset(bpy.context) - else: - self.update_global(bpy.context) - - print("Rebuild done!") - - # ----------------------- random part --------------------------- - # --------------------------------------------------------------- - def update_seed(self, context): - if self.at_mode == 'ADV': - sc_min = (self.sc_min_x, self.sc_min_y, self.sc_min_z) - sc_max = (self.sc_max_x, self.sc_max_y, self.sc_max_z) - at_random(self.at_seed, self.count, self.row, self.tr_min, self.tr_max, sc_min, - sc_max, self.rot_min, self.rot_max, self.at_is_tr, self.at_is_sc, self.at_is_rot, - self.sc_all, self.tr_offset, self.tr_second, self.sc_offset, self.sc_second, - self.rot_offset, self.rot_second, self.at_pivot, self.alter, self.ralign) - else: # simple mode - vec = xyz_axis() - tr = self.tr_rand * vec - sc = self.sc_rand * vec - rot = self.rot_rand * vec - at_random(self.at_seed, self.count, self.row, -tr, tr, sc, 100*vec, -rot, rot, - self.at_is_tr, self.at_is_sc, self.at_is_rot, False, self.tr_offset, - self.tr_second, self.sc_offset, self.sc_second, self.rot_offset, - self.rot_second, self.at_pivot, self.alter, self.ralign) - - - def update_rtr(self, context): - """rtr in simple mode update adv mode""" - self.tr_max = self.tr_rand * Vector((1.0, 1.0, 1.0)) - self.tr_min = self.tr_rand * Vector((-1.0, -1.0, -1.0)) - - - def update_rsc(self, context): - """rsc in simple mode update adv mode""" - self.sc_max_x, self.sc_max_y, self.sc_max_z = (100.0, 100.0, 100.0) - rand = self.sc_rand - self.sc_min_x = rand - self.sc_min_y = rand - self.sc_min_z = rand - - - def update_rrot(self, context): - """rrot in simple mode update adv mode""" - self.rot_max = self.rot_rand * Vector((1.0, 1.0, 1.0)) - self.rot_min = self.rot_rand * Vector((-1.0, -1.0, -1.0)) - - - def up_ui_sc_min_x(self, val): - """Update the value of the property sc_min_x in UI""" - self.is_prog_change = True - self.sc_min_x = val - - - def up_ui_sc_min_y(self, val): - """Update the value of the property sc_min_y in UI""" - self.is_prog_change = True - self.sc_min_y = val - - - def up_ui_sc_min_z(self, val): - """Update the value of the property sc_min_z in UI""" - self.is_prog_change = True - self.sc_min_z = val - - - def up_ui_sc_max_x(self, val): - """Update the value of the property sc_max_x in UI""" - self.is_prog_change = True - self.sc_max_x = val - - - def up_ui_sc_max_y(self, val): - """Update the value of the property sc_max_y in UI""" - self.is_prog_change = True - self.sc_max_y = val - - - def up_ui_sc_max_z(self, val): - """Update the value of the property sc_max_z in UI""" - self.is_prog_change = True - self.sc_max_z = val - - # -------------- update min and max ----------------------------- - # if user enter a max value < min, change min and vice versa - def up_tr_min(self, context): - """Update tr_max if tr_min is higher""" - if self.is_prog_change: - self.is_prog_change = False - else: - for i in range(3): - if self.tr_min[i] > self.tr_max[i]: - self.is_prog_change = True - self.tr_max[i] = self.tr_min[i] - - - def up_tr_max(self, context): - """Update tr_min if tr_max is lower""" - if self.is_prog_change: - self.is_prog_change = False - else: - for i in range(3): - if self.tr_min[i] > self.tr_max[i]: - self.is_prog_change = True - self.tr_min[i] = self.tr_max[i] - - - def up_sc_min_x(self, context): - """Update sc_max_x if sc_min_x is higher""" - if self.is_prog_change: - self.is_prog_change = False - else: - test = self.sc_min_x > self.sc_max_x - if test and self.sc_all: - # case : min > max and uniform = True - self.up_ui_sc_max_x(self.sc_min_x) - # with uniform : min_x = min_y = min_z same for max_ - self.up_ui_sc_min_y(self.sc_min_x) - self.up_ui_sc_min_z(self.sc_min_x) - self.up_ui_sc_max_y(self.sc_min_x) - self.up_ui_sc_max_z(self.sc_min_x) - elif self.sc_all: - # case : min < max and uniform = True - self.up_ui_sc_min_y(self.sc_min_x) - self.up_ui_sc_min_z(self.sc_min_x) - self.up_ui_sc_max_y(self.sc_max_x) - self.up_ui_sc_max_z(self.sc_max_x) - elif test: - # case : min > max and uniform = False - self.up_ui_sc_max_x(self.sc_min_x) - - def up_sc_min_y(self, context): - """Update sc_max_y if sc_min_y is higher""" - if self.is_prog_change: - self.is_prog_change = False - else: - test = self.sc_min_y > self.sc_max_y - if test and self.sc_all: - # case : min > max and uniform = True - self.up_ui_sc_max_y(self.sc_min_y) - # with uniform : min_x = min_y = min_z same for max_ - self.up_ui_sc_min_x(self.sc_min_y) - self.up_ui_sc_min_z(self.sc_min_y) - self.up_ui_sc_max_x(self.sc_min_y) - self.up_ui_sc_max_y(self.sc_min_y) - elif self.sc_all: - # case : min < max and uniform = True - self.up_ui_sc_min_x(self.sc_min_y) - self.up_ui_sc_min_z(self.sc_min_y) - self.up_ui_sc_max_x(self.sc_max_y) - self.up_ui_sc_max_z(self.sc_max_y) - elif test: - # case : min > max and uniform = False - self.up_ui_sc_max_y(self.sc_min_y) - - def up_sc_min_z(self, context): - """Update sc_max_z if sc_min_z is higher""" - if self.is_prog_change: - self.is_prog_change = False - else: - test = self.sc_min_z > self.sc_max_z - if test and self.sc_all: - # case : min > max and uniform = True - self.up_ui_sc_max_z(self.sc_min_z) - # with uniform : min_x = min_y = min_z same for max_ - self.up_ui_sc_min_x(self.sc_min_z) - self.up_ui_sc_min_y(self.sc_min_z) - self.up_ui_sc_max_x(self.sc_min_z) - self.up_ui_sc_max_y(self.sc_min_z) - elif self.sc_all: - # case : min < max and uniform = True - self.up_ui_sc_min_x(self.sc_min_z) - self.up_ui_sc_min_y(self.sc_min_z) - self.up_ui_sc_max_x(self.sc_max_z) - self.up_ui_sc_max_y(self.sc_max_z) - elif test: - # case : min > max and uniform = False - self.up_ui_sc_max_y(self.sc_min_z) - - def up_sc_max_x(self, context): - """Update sc_min_x if sc_max_x is lower""" - if self.is_prog_change: - self.is_prog_change = False - else: - test = self.sc_min_x > self.sc_max_x - if test and self.sc_all: - # case : min > max and uniform = True - self.up_ui_sc_min_x(self.sc_max_x) - # with uniform : min_x = min_y = min_z same for max_ - self.up_ui_sc_max_y(self.sc_max_x) - self.up_ui_sc_max_z(self.sc_max_x) - self.up_ui_sc_min_y(self.sc_max_x) - self.up_ui_sc_min_z(self.sc_max_x) - elif self.sc_all: - # case : min < max and uniform = True - self.up_ui_sc_max_y(self.sc_max_x) - self.up_ui_sc_max_z(self.sc_max_x) - self.up_ui_sc_min_y(self.sc_min_x) - self.up_ui_sc_min_z(self.sc_min_x) - elif test: - # case : min > max and uniform = False - self.up_ui_sc_min_x(self.sc_max_x) - - def up_sc_max_y(self, context): - """Update sc_min_y if sc_max_y is lower""" - if self.is_prog_change: - self.is_prog_change = False - else: - test = self.sc_min_y > self.sc_max_y - if test and self.sc_all: - # case : min > max and uniform = True - self.up_ui_sc_min_y(self.sc_max_y) - # with uniform : min_x = min_y = min_z same for max_ - self.up_ui_sc_max_x(self.sc_max_y) - self.up_ui_sc_max_z(self.sc_max_y) - self.up_ui_sc_min_x(self.sc_max_y) - self.up_ui_sc_min_z(self.sc_max_y) - elif self.sc_all: - # case : min < max and uniform = True - self.up_ui_sc_max_x(self.sc_max_y) - self.up_ui_sc_max_z(self.sc_max_y) - self.up_ui_sc_min_x(self.sc_min_y) - self.up_ui_sc_min_z(self.sc_min_y) - elif test: - # case : min > max and uniform = False - self.up_ui_sc_min_y(self.sc_max_y) - - def up_sc_max_z(self, context): - """Update sc_min_z if sc_max_z is lower""" - if self.is_prog_change: - self.is_prog_change = False - else: - test = self.sc_min_z > self.sc_max_z - if test and self.sc_all: - # case : min > max and uniform = True - self.up_ui_sc_min_z(self.sc_max_z) - # with uniform : min_x = min_y = min_z same for max_ - self.up_ui_sc_max_x(self.sc_max_z) - self.up_ui_sc_max_y(self.sc_max_z) - self.up_ui_sc_min_x(self.sc_max_z) - self.up_ui_sc_min_y(self.sc_max_z) - elif self.sc_all: - # case : min < max and uniform = True - self.up_ui_sc_max_x(self.sc_max_z) - self.up_ui_sc_max_y(self.sc_max_z) - self.up_ui_sc_min_x(self.sc_min_z) - self.up_ui_sc_min_y(self.sc_min_z) - elif test: - # case : min > max and uniform = False - self.up_ui_sc_min_z(self.sc_max_z) - - def up_rot_min(self, context): - """Update rot_max if rot_min is higher""" - if self.is_prog_change: - self.is_prog_change = False - else: - for i in range(3): - if self.rot_min[i] > self.rot_max[i]: - self.is_prog_change = True - self.rot_max[i] = self.rot_min[i] - - def up_rot_max(self, context): - """Update rot_min if rot_max is lower""" - if self.is_prog_change: - self.is_prog_change = False - else: - for i in range(3): - if self.rot_min[i] > self.rot_max[i]: - self.is_prog_change = True - self.rot_min[i] = self.rot_max[i] - - # ----------------------- reset all properties ------------------ - def up_ui_reset(self): - """Reset all UI properties""" - self.up_ui_updateCount(2) - self.up_ui_updateRow(1) - self.up_ui_is_copy() - self.up_ui_tr_offset(Vector((2.0, 0.0, 0.0))) - self.up_ui_tr_global(Vector((2.0, 0.0, 0.0))) - self.up_ui_sc_offset((100, 100, 100)) - self.up_ui_sc_global((100, 100, 100)) - self.up_ui_rot_offset(Vector((0.0, 0.0, 0.0))) - self.up_ui_rot_global(Vector((0.0, 0.0, 0.0))) - self.up_ui_updateAlter(0) - self.total = "2" - self.erow = "2" - - - count: bpy.props.IntProperty( - name='Count', - description="Number of elements, original count as one", - default=2, - soft_min=2, - update=updateCount - ) - - row: bpy.props.IntProperty( - name="Row", - description="Number of row(s)", - default=1, - soft_min=1, - soft_max=100, - update=update_row - ) - - """Allow a variation in the row : - if row gets n elements, row +1 will get (n + variation) elements - only if n + variation > 0 - """ - alter: bpy.props.IntProperty( - name=" Row variation", - description="""Variation in the number of elements in a row. (between -5 and 5). - \n Be careful with it""", - default=0, - soft_min=-5, - soft_max=5, - update=update_alter - ) - - total: bpy.props.StringProperty( - name="Total", - description="Total of elements in array", - default="2" - ) - - erow: bpy.props.StringProperty( - description="Number of elements in the current row.", - default="2" - ) - - # if alter <> 0, how align the rows - align: bpy.props.EnumProperty( - name='Align', - description="Align of rows when variation is not zero", - items=[ - ('LEFT', 'Left', "Align to the left", 'ALIGN_LEFT', 0), - ('CENTER', 'Center', "Align to the center", 'ALIGN_CENTER', 1), - ('RIGHT', 'Right', "Align to the right", 'ALIGN_RIGHT', 2) - ], - default='LEFT', - update=update_align - ) - - # Vector alignment depends on align - ralign: bpy.props.FloatVectorProperty( - subtype='TRANSLATION', - unit='LENGTH', - default=(0.0, 0.0, 0.0) - ) - - # booleans use to know if user or prog change the value to avoid continuous loop - is_prog_change: bpy.props.BoolProperty(default=False) # True if prog change value - - # which one between offset and global user calls last, True is offset, False global - is_tr_off_last: bpy.props.BoolProperty(default=True) - - # True if addon is initialised - already_start: bpy.props.BoolProperty(default=False) - - # if the user need a single copy or a duplicate (link object) - is_copy: bpy.props.BoolProperty( - name="Copy only", - description="Duplicate or copy, default is duplicate", - default=False, - update=update_is_copy - ) - - # translation vector offset - tr_offset: bpy.props.FloatVectorProperty( - name='Offset', - description="Distance between elements", - default=(2.0, 0.0, 0.0), - subtype='TRANSLATION', - unit='LENGTH', - precision=2, - step=50, - options={'ANIMATABLE'}, - update=update_offset - ) - - # global translation distance - tr_global: bpy.props.FloatVectorProperty( - name='Global', - description="Distance between the original and the last element", - default=(2.0, 0.0, 0.0), - subtype='TRANSLATION', - unit='LENGTH', - precision=2, - step=50, - options={'ANIMATABLE'}, - update=update_global - ) - - tr_second: bpy.props.FloatVectorProperty( - name="Translation", - description="Additional offset distance for rows", - default=(0.0, 0.0, 0.0), - subtype='TRANSLATION', - unit='LENGTH', - precision=2, - step=50, - update=update_second - ) - - at_pivot: bpy.props.PointerProperty( - name='Pivot', - description="Object you want as pivot point. If none, pivot point is the object's origine", - type=bpy.types.Object - ) - - # scaling vector offset - sc_offset: bpy.props.FloatVectorProperty( - name='Offset', - description="Incremental scale of the next elements", - default=(100.0, 100.0, 100.0), - subtype='XYZ', - precision=1, - step=100, - options={'ANIMATABLE'}, - update=update_offset - ) - - # global scaling - sc_global: bpy.props.FloatVectorProperty( - name='Global', - description="Scale of the last element", - default=(100.0, 100.0, 100.0), - subtype='XYZ', - precision=1, - step=100, - options={'ANIMATABLE'}, - update=update_global - ) - - sc_second: bpy.props.FloatVectorProperty( - name='Scale', - description="Additionnal scale for rows", - default=(100.0, 100.0, 100.0), - subtype='XYZ', - precision=1, - step=100, - options={'ANIMATABLE'}, - update=update_second - ) - # rotation vector offset - rot_offset: bpy.props.FloatVectorProperty( - name='Offset', - description="Angle between each element", - default=(0.0, 0.0, 0.0), - subtype='XYZ', - unit='ROTATION', - step=500, # = 5 - options={'ANIMATABLE'}, - update=update_offset - ) - - # global rotation - rot_global: bpy.props.FloatVectorProperty( - name='Global', - description="Maximum angle from the reference to the last element", - default=(0.0, 0.0, 0.0), - subtype='XYZ', - unit='ROTATION', - step=500, # = 5 - options={'ANIMATABLE'}, - update=update_global - ) - - rot_second: bpy.props.FloatVectorProperty( - name='Rotation', - description="Additionnal rotation for rows", - default=(0.0, 0.0, 0.0), - subtype='XYZ', - unit='ROTATION', - step=500, - options={'ANIMATABLE'}, - update=update_second - ) - - # ----------------------- random part --------------------------- - at_seed: bpy.props.IntProperty( - name='Seed', - description="Seed value for random", - soft_min=0, - default=0, - update=update_seed - ) - - at_mode: bpy.props.EnumProperty( - name="Mode", - description="Choose between simple mode or advanced", - items=(('SIM', 'Simple', "Simple mode"), - ('ADV', 'Advanced', "Advanced mode")), - default='SIM' - ) - - at_is_tr: bpy.props.BoolProperty( - name="Add translation", - description="Add translation in random?", - default=False - ) - - at_is_sc: bpy.props.BoolProperty( - name="Add scale", - description="Add scale in random?", - default=False - ) - - at_is_rot: bpy.props.BoolProperty( - name="Add rotation", - description="Add rotation in random?", - default=False - ) - - tr_min: bpy.props.FloatVectorProperty( - name="min", - description="Minimum random value for translation", - unit='LENGTH', - default=(0.0, 0.0, 0.0), - update=up_tr_min - ) - - tr_max: bpy.props.FloatVectorProperty( - name="max", - description="Maximum random value for translation", - unit='LENGTH', - default=(0.0, 0.0, 0.0), - update=up_tr_max - ) - - tr_rand: bpy.props.FloatProperty( - name="Translation", - description="Random values for all axis", - unit='LENGTH', - default=0.0, - update=update_rtr - ) - - sc_all: bpy.props.BoolProperty( - name="uniform scale", - description="Uniform or non uniform scale, default is non uniform.", - default=False - ) - - sc_min_x: bpy.props.IntProperty( - name="min", - description="Minimum random value for x scale", - default=100, - update=up_sc_min_x - ) - - sc_min_y: bpy.props.IntProperty( - name="min", - description="Minimum random value for y scale", - default=100, - update=up_sc_min_y - ) - - sc_min_z: bpy.props.IntProperty( - name="min", - description="Minimum random value for z scale", - default=100, - update=up_sc_min_z - ) - - sc_max_x: bpy.props.IntProperty( - name="max", - description="Maximum random value for x scale", - default=100, - update=up_sc_max_x - ) - - sc_max_y: bpy.props.IntProperty( - name="max", - description="Maximum random value for y scale", - default=100, - update=up_sc_max_y - ) - - sc_max_z: bpy.props.IntProperty( - name="max", - description="Maximum random value for z scale", - default=100, - update=up_sc_max_z - ) - - sc_rand: bpy.props.IntProperty( - name="Scale", - description="Random scale value for all axis", - default=100, - update=update_rsc - ) - - rot_min: bpy.props.FloatVectorProperty( - name="min", - description="Minimum random value for rotation", - unit='ROTATION', - default=(0.0, 0.0, 0.0), - update=up_rot_min - ) - - rot_max: bpy.props.FloatVectorProperty( - name="max", - description="Maximum random value for rotation", - unit='ROTATION', - default=(0.0, 0.0, 0.0), - update=up_rot_max - ) - - rot_rand: bpy.props.FloatProperty( - name="Rotation", - description="Random rotation for all axis", - unit='ROTATION', - default=0.0, - update=update_rrot - )