diff --git a/◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/TISSUE-MASTER/UTILS.PY b/◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/TISSUE-MASTER/UTILS.PY deleted file mode 100644 index e40c268b..00000000 --- a/◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/TISSUE-MASTER/UTILS.PY +++ /dev/null @@ -1,462 +0,0 @@ -# ##### BEGIN GPL LICENSE BLOCK ##### -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# -# ##### END GPL LICENSE BLOCK ##### - -import bpy -import threading -import numpy as np -import multiprocessing -from multiprocessing import Process, Pool -from mathutils import Vector -try: from .numba_functions import numba_lerp2 -except: pass - -weight = [] -n_threads = multiprocessing.cpu_count() - -class ThreadVertexGroup(threading.Thread): - def __init__ ( self, id, vertex_group, n_verts): - self.id = id - self.vertex_group = vertex_group - self.n_verts = n_verts - threading.Thread.__init__ ( self ) - - def run (self): - global weight - global n_threads - verts = np.arange(int(self.n_verts/8))*8 + self.id - for v in verts: - try: - weight[v] = self.vertex_group.weight(v) - except: - pass - -def thread_read_weight(_weight, vertex_group): - global weight - global n_threads - print(n_threads) - weight = _weight - n_verts = len(weight) - threads = [ThreadVertexGroup(i, vertex_group, n_verts) for i in range(n_threads)] - for t in threads: t.start() - for t in threads: t.join() - return weight - -def process_read_weight(id, vertex_group, n_verts): - global weight - global n_threads - verts = np.arange(int(self.n_verts/8))*8 + self.id - for v in verts: - try: - weight[v] = self.vertex_group.weight(v) - except: - pass - - -def read_weight(_weight, vertex_group): - global weight - global n_threads - print(n_threads) - weight = _weight - n_verts = len(weight) - n_cores = multiprocessing.cpu_count() - pool = Pool(processes=n_cores) - multiple_results = [pool.apply_async(process_read_weight, (i, vertex_group, n_verts)) for i in range(n_cores)] - #processes = [Process(target=process_read_weight, args=(i, vertex_group, n_verts)) for i in range(n_threads)] - #for t in processes: t.start() - #for t in processes: t.join() - return weight - -#Recursivly transverse layer_collection for a particular name -def recurLayerCollection(layerColl, collName): - found = None - if (layerColl.name == collName): - return layerColl - for layer in layerColl.children: - found = recurLayerCollection(layer, collName) - if found: - return found - -def auto_layer_collection(): - # automatically change active layer collection - layer = bpy.context.view_layer.active_layer_collection - layer_collection = bpy.context.view_layer.layer_collection - if layer.hide_viewport or layer.collection.hide_viewport: - collections = bpy.context.object.users_collection - for c in collections: - lc = recurLayerCollection(layer_collection, c.name) - if not c.hide_viewport and not lc.hide_viewport: - bpy.context.view_layer.active_layer_collection = lc - -def lerp(a, b, t): - return a + (b - a) * t - -def _lerp2(v1, v2, v3, v4, v): - v12 = v1.lerp(v2,v.x) # + (v2 - v1) * v.x - v34 = v3.lerp(v4,v.x) # + (v4 - v3) * v.x - return v12.lerp(v34, v.y)# + (v34 - v12) * v.y - -def lerp2(v1, v2, v3, v4, v): - v12 = v1 + (v2 - v1) * v.x - v34 = v3 + (v4 - v3) * v.x - return v12 + (v34 - v12) * v.y - -def lerp3(v1, v2, v3, v4, v): - loc = lerp2(v1.co, v2.co, v3.co, v4.co, v) - nor = lerp2(v1.normal, v2.normal, v3.normal, v4.normal, v) - nor.normalize() - return loc + nor * v.z - -def np_lerp2(v00, v10, v01, v11, vx, vy): - #try: - # co2 = numba_lerp2(v00, v10, v01, v11, vx, vy) - #except: - co0 = v00 + (v10 - v00) * vx - co1 = v01 + (v11 - v01) * vx - co2 = co0 + (co1 - co0) * vy - return co2 - - -# Prevent Blender Crashes with handlers -def set_animatable_fix_handler(self, context): - old_handlers = [] - blender_handlers = bpy.app.handlers.render_init - for h in blender_handlers: - if "turn_off_animatable" in str(h): - old_handlers.append(h) - for h in old_handlers: blender_handlers.remove(h) - ################ blender_handlers.append(turn_off_animatable) - return - -def turn_off_animatable(scene): - for o in bpy.data.objects: - o.tissue_tessellate.bool_run = False - o.reaction_diffusion_settings.run = False - #except: pass - return - -### OBJECTS ### - -def convert_object_to_mesh(ob, apply_modifiers=True, preserve_status=True): - try: ob.name - except: return None - if ob.type != 'MESH': - if not apply_modifiers: - mod_visibility = [m.show_viewport for m in ob.modifiers] - for m in ob.modifiers: m.show_viewport = False - #ob.modifiers.update() - #dg = bpy.context.evaluated_depsgraph_get() - #ob_eval = ob.evaluated_get(dg) - #me = bpy.data.meshes.new_from_object(ob_eval, preserve_all_data_layers=True, depsgraph=dg) - me = simple_to_mesh(ob) - new_ob = bpy.data.objects.new(ob.data.name, me) - new_ob.location, new_ob.matrix_world = ob.location, ob.matrix_world - if not apply_modifiers: - for m,vis in zip(ob.modifiers,mod_visibility): m.show_viewport = vis - else: - if apply_modifiers: - new_ob = ob.copy() - new_me = simple_to_mesh(ob) - new_ob.modifiers.clear() - new_ob.data = new_me - else: - new_ob = ob.copy() - new_ob.data = ob.data.copy() - new_ob.modifiers.clear() - bpy.context.collection.objects.link(new_ob) - if preserve_status: - new_ob.select_set(False) - else: - for o in bpy.context.view_layer.objects: o.select_set(False) - new_ob.select_set(True) - bpy.context.view_layer.objects.active = new_ob - return new_ob - -def simple_to_mesh(ob): - dg = bpy.context.evaluated_depsgraph_get() - ob_eval = ob.evaluated_get(dg) - me = bpy.data.meshes.new_from_object(ob_eval, preserve_all_data_layers=True, depsgraph=dg) - me.calc_normals() - return me - -def join_objects(objects, link_to_scene=True, make_active=False): - C = bpy.context - bm = bmesh.new() - - materials = {} - faces_materials = [] - dg = C.evaluated_depsgraph_get() - for o in objects: - bm.from_object(o, dg) - # add object's material to the dictionary - for m in o.data.materials: - if m not in materials: materials[m] = len(materials) - for f in o.data.polygons: - index = f.material_index - mat = o.material_slots[index].material - new_index = materials[mat] - faces_materials.append(new_index) - bm.verts.ensure_lookup_table() - bm.edges.ensure_lookup_table() - bm.faces.ensure_lookup_table() - # assign new indexes - for index, f in zip(faces_materials, bm.faces): f.material_index = index - # create object - me = bpy.data.meshes.new('joined') - bm.to_mesh(me) - me.update() - ob = bpy.data.objects.new('joined', me) - if link_to_scene: C.collection.objects.link(ob) - # make active - if make_active: - for o in C.view_layer.objects: o.select_set(False) - ob.select_set(True) - C.view_layer.objects.active = ob - # add materials - for m in materials.keys(): ob.data.materials.append(m) - return ob - -### MESH FUNCTIONS - -def get_vertices_numpy(mesh): - n_verts = len(mesh.vertices) - verts = [0]*n_verts*3 - mesh.vertices.foreach_get('co', verts) - verts = np.array(verts).reshape((n_verts,3)) - return verts - -def get_vertices_and_normals_numpy(mesh): - n_verts = len(mesh.vertices) - verts = [0]*n_verts*3 - normals = [0]*n_verts*3 - mesh.vertices.foreach_get('co', verts) - mesh.vertices.foreach_get('normal', normals) - verts = np.array(verts).reshape((n_verts,3)) - normals = np.array(normals).reshape((n_verts,3)) - return verts, normals - -def get_edges_numpy(mesh): - n_edges = len(mesh.edges) - edges = [0]*n_edges*2 - mesh.edges.foreach_get('vertices', edges) - edges = np.array(edges).reshape((n_edges,2)).astype('int') - return edges - -def get_edges_id_numpy(mesh): - n_edges = len(mesh.edges) - edges = [0]*n_edges*2 - mesh.edges.foreach_get('vertices', edges) - edges = np.array(edges).reshape((n_edges,2)) - indexes = np.arange(n_edges).reshape((n_edges,1)) - edges = np.concatenate((edges,indexes), axis=1) - return edges - -def get_vertices(mesh): - n_verts = len(mesh.vertices) - verts = [0]*n_verts*3 - mesh.vertices.foreach_get('co', verts) - verts = np.array(verts).reshape((n_verts,3)) - verts = [Vector(v) for v in verts] - return verts - -def get_faces(mesh): - faces = [[v for v in f.vertices] for f in mesh.polygons] - return faces - -def get_faces_numpy(mesh): - faces = [[v for v in f.vertices] for f in mesh.polygons] - return np.array(faces) - -def get_faces_edges_numpy(mesh): - faces = [v.edge_keys for f in mesh.polygons] - return np.array(faces) - -#try: -#from numba import jit, njit -#from numba.typed import List -''' -@jit -def find_curves(edges, n_verts): - #verts_dict = {key:[] for key in range(n_verts)} - verts_dict = {} - for key in range(n_verts): verts_dict[key] = [] - for e in edges: - verts_dict[e[0]].append(e[1]) - verts_dict[e[1]].append(e[0]) - curves = []#List() - loop1 = True - while loop1: - if len(verts_dict) == 0: - loop1 = False - continue - # next starting point - v = list(verts_dict.keys())[0] - # neighbors - v01 = verts_dict[v] - if len(v01) == 0: - verts_dict.pop(v) - continue - curve = []#List() - curve.append(v) # add starting point - curve.append(v01[0]) # add neighbors - verts_dict.pop(v) - loop2 = True - while loop2: - last_point = curve[-1] - #if last_point not in verts_dict: break - v01 = verts_dict[last_point] - # curve end - if len(v01) == 1: - verts_dict.pop(last_point) - loop2 = False - continue - if v01[0] == curve[-2]: - curve.append(v01[1]) - verts_dict.pop(last_point) - elif v01[1] == curve[-2]: - curve.append(v01[0]) - verts_dict.pop(last_point) - else: - loop2 = False - continue - if curve[0] == curve[-1]: - loop2 = False - continue - curves.append(curve) - return curves -''' -def find_curves(edges, n_verts): - verts_dict = {key:[] for key in range(n_verts)} - for e in edges: - verts_dict[e[0]].append(e[1]) - verts_dict[e[1]].append(e[0]) - curves = [] - while True: - if len(verts_dict) == 0: break - # next starting point - v = list(verts_dict.keys())[0] - # neighbors - v01 = verts_dict[v] - if len(v01) == 0: - verts_dict.pop(v) - continue - curve = [] - if len(v01) > 1: curve.append(v01[1]) # add neighbors - curve.append(v) # add starting point - curve.append(v01[0]) # add neighbors - verts_dict.pop(v) - # start building curve - while True: - #last_point = curve[-1] - #if last_point not in verts_dict: break - - # try to change direction if needed - if curve[-1] in verts_dict: pass - elif curve[0] in verts_dict: curve.reverse() - else: break - - # neighbors points - last_point = curve[-1] - v01 = verts_dict[last_point] - - # curve end - if len(v01) == 1: - verts_dict.pop(last_point) - if curve[0] in verts_dict: continue - else: break - - # chose next point - new_point = None - if v01[0] == curve[-2]: new_point = v01[1] - elif v01[1] == curve[-2]: new_point = v01[0] - #else: break - - #if new_point != curve[1]: - curve.append(new_point) - verts_dict.pop(last_point) - if curve[0] == curve[-1]: - verts_dict.pop(new_point) - break - curves.append(curve) - return curves - -def curve_from_points(points, name='Curve'): - curve = bpy.data.curves.new(name,'CURVE') - for c in points: - s = curve.splines.new('POLY') - s.points.add(len(c)) - for i,p in enumerate(c): s.points[i].co = p.xyz + [1] - ob_curve = bpy.data.objects.new(name,curve) - return ob_curve - -def curve_from_pydata(points, indexes, name='Curve', skip_open=False, merge_distance=1, set_active=True): - curve = bpy.data.curves.new(name,'CURVE') - curve.dimensions = '3D' - for c in indexes: - # cleanup - pts = np.array([points[i] for i in c]) - if merge_distance > 0: - pts1 = np.roll(pts,1,axis=0) - dist = np.linalg.norm(pts1-pts, axis=1) - count = 0 - n = len(dist) - mask = np.ones(n).astype('bool') - for i in range(n): - count += dist[i] - if count > merge_distance: count = 0 - else: mask[i] = False - pts = pts[mask] - - bool_cyclic = c[0] == c[-1] - if skip_open and not bool_cyclic: continue - s = curve.splines.new('POLY') - n_pts = len(pts) - s.points.add(n_pts-1) - w = np.ones(n_pts).reshape((n_pts,1)) - co = np.concatenate((pts,w),axis=1).reshape((n_pts*4)) - s.points.foreach_set('co',co) - s.use_cyclic_u = bool_cyclic - ob_curve = bpy.data.objects.new(name,curve) - bpy.context.collection.objects.link(ob_curve) - if set_active: - bpy.context.view_layer.objects.active = ob_curve - return ob_curve - -def curve_from_vertices(indexes, verts, name='Curve'): - curve = bpy.data.curves.new(name,'CURVE') - for c in indexes: - s = curve.splines.new('POLY') - s.points.add(len(c)) - for i,p in enumerate(c): s.points[i].co = verts[p].co.xyz + [1] - ob_curve = bpy.data.objects.new(name,curve) - return ob_curve - -### WEIGHT FUNCTIONS ### - -def get_weight(vertex_group, n_verts): - weight = [0]*n_verts - for i in range(n_verts): - try: weight[i] = vertex_group.weight(i) - except: pass - return weight - -def get_weight_numpy(vertex_group, n_verts): - weight = [0]*n_verts - for i in range(n_verts): - try: weight[i] = vertex_group.weight(i) - except: pass - return np.array(weight)