Delete UTILS.PY
This commit is contained in:
parent
c8f5b6f03b
commit
b2fc706797
|
@ -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)
|
Loading…
Reference in New Issue