1 # ##### BEGIN GPL LICENSE BLOCK #####
3 # This program is free software; you can redistribute it and/or
4 # modify it under the terms of the GNU General Public License
5 # as published by the Free Software Foundation; either version 2
6 # of the License, or (at your option) any later version.
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
13 # You should have received a copy of the GNU General Public License
14 # along with this program; if not, write to the Free Software Foundation,
15 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 # ##### END GPL LICENSE BLOCK #####
22 import multiprocessing
23 from multiprocessing
import Process
, Pool
26 n_threads
= multiprocessing
.cpu_count()
28 class ThreadVertexGroup(threading
.Thread
):
29 def __init__ ( self
, id, vertex_group
, n_verts
):
31 self
.vertex_group
= vertex_group
32 self
.n_verts
= n_verts
33 threading
.Thread
.__init
__ ( self
)
38 verts
= np
.arange(int(self
.n_verts
/8))*8 + self
.id
41 weight
[v
] = self
.vertex_group
.weight(v
)
45 def thread_read_weight(_weight
, vertex_group
):
51 threads
= [ThreadVertexGroup(i
, vertex_group
, n_verts
) for i
in range(n_threads
)]
52 for t
in threads
: t
.start()
53 for t
in threads
: t
.join()
56 def process_read_weight(id, vertex_group
, n_verts
):
59 verts
= np
.arange(int(self
.n_verts
/8))*8 + self
.id
62 weight
[v
] = self
.vertex_group
.weight(v
)
67 def read_weight(_weight
, vertex_group
):
73 n_cores
= multiprocessing
.cpu_count()
74 pool
= Pool(processes
=n_cores
)
75 multiple_results
= [pool
.apply_async(process_read_weight
, (i
, vertex_group
, n_verts
)) for i
in range(n_cores
)]
76 #processes = [Process(target=process_read_weight, args=(i, vertex_group, n_verts)) for i in range(n_threads)]
77 #for t in processes: t.start()
78 #for t in processes: t.join()
81 #Recursively transverse layer_collection for a particular name
82 def recurLayerCollection(layerColl
, collName
):
84 if (layerColl
.name
== collName
):
86 for layer
in layerColl
.children
:
87 found
= recurLayerCollection(layer
, collName
)
91 def auto_layer_collection():
92 # automatically change active layer collection
93 layer
= bpy
.context
.view_layer
.active_layer_collection
94 layer_collection
= bpy
.context
.view_layer
.layer_collection
95 if layer
.hide_viewport
or layer
.collection
.hide_viewport
:
96 collections
= bpy
.context
.object.users_collection
98 lc
= recurLayerCollection(layer_collection
, c
.name
)
99 if not c
.hide_viewport
and not lc
.hide_viewport
:
100 bpy
.context
.view_layer
.active_layer_collection
= lc
103 return a
+ (b
- a
) * t
105 def _lerp2(v1
, v2
, v3
, v4
, v
):
106 v12
= v1
.lerp(v2
,v
.x
) # + (v2 - v1) * v.x
107 v34
= v3
.lerp(v4
,v
.x
) # + (v4 - v3) * v.x
108 return v12
.lerp(v34
, v
.y
)# + (v34 - v12) * v.y
110 def lerp2(v1
, v2
, v3
, v4
, v
):
111 v12
= v1
+ (v2
- v1
) * v
.x
112 v34
= v3
+ (v4
- v3
) * v
.x
113 return v12
+ (v34
- v12
) * v
.y
115 def lerp3(v1
, v2
, v3
, v4
, v
):
116 loc
= lerp2(v1
.co
, v2
.co
, v3
.co
, v4
.co
, v
)
117 nor
= lerp2(v1
.normal
, v2
.normal
, v3
.normal
, v4
.normal
, v
)
119 return loc
+ nor
* v
.z
121 def _convert_object_to_mesh(ob
, apply_modifiers
=True, preserve_status
=True):
122 if not apply_modifiers
:
123 mod_visibility
= [m
.show_viewport
for m
in ob
.modifiers
]
124 for m
in ob
.modifiers
:
125 m
.show_viewport
= False
128 mode
= bpy
.context
.object.mode
129 selected
= bpy
.context
.selected_objects
130 active
= bpy
.context
.object
132 bpy
.ops
.object.mode_set(mode
='OBJECT')
133 bpy
.ops
.object.select_all(action
='DESELECT')
135 new_ob
.data
= ob
.data
.copy()
136 bpy
.context
.collection
.objects
.link(new_ob
)
137 bpy
.context
.view_layer
.objects
.active
= new_ob
138 new_ob
.select_set(True)
139 bpy
.ops
.object.convert(target
='MESH')
142 bpy
.ops
.object.select_all(action
='DESELECT')
143 for o
in selected
: o
.select_set(True)
144 bpy
.context
.view_layer
.objects
.active
= active
145 bpy
.ops
.object.mode_set(mode
=mode
)
146 if not apply_modifiers
:
147 for m
,vis
in zip(ob
.modifiers
,mod_visibility
):
148 m
.show_viewport
= vis
151 def convert_object_to_mesh(ob
, apply_modifiers
=True, preserve_status
=True):
152 if not ob
.name
: return None
153 if ob
.type != 'MESH':
154 if not apply_modifiers
:
155 mod_visibility
= [m
.show_viewport
for m
in ob
.modifiers
]
156 for m
in ob
.modifiers
: m
.show_viewport
= False
157 #ob.modifiers.update()
158 #dg = bpy.context.evaluated_depsgraph_get()
159 #ob_eval = ob.evaluated_get(dg)
160 #me = bpy.data.meshes.new_from_object(ob_eval, preserve_all_data_layers=True, depsgraph=dg)
161 me
= simple_to_mesh(ob
)
162 new_ob
= bpy
.data
.objects
.new(ob
.data
.name
, me
)
163 new_ob
.location
, new_ob
.matrix_world
= ob
.location
, ob
.matrix_world
164 if not apply_modifiers
:
165 for m
,vis
in zip(ob
.modifiers
,mod_visibility
): m
.show_viewport
= vis
169 new_ob
.data
= simple_to_mesh(ob
)
172 new_ob
.data
= ob
.data
.copy()
173 new_ob
.modifiers
.clear()
174 bpy
.context
.collection
.objects
.link(new_ob
)
176 new_ob
.select_set(False)
178 for o
in bpy
.context
.view_layer
.objects
: o
.select_set(False)
179 new_ob
.select_set(True)
180 bpy
.context
.view_layer
.objects
.active
= new_ob
183 def simple_to_mesh(ob
):
184 dg
= bpy
.context
.evaluated_depsgraph_get()
185 ob_eval
= ob
.evaluated_get(dg
)
186 me
= bpy
.data
.meshes
.new_from_object(ob_eval
, preserve_all_data_layers
=True, depsgraph
=dg
)
190 # Prevent Blender Crashes with handlers
191 def set_animatable_fix_handler(self
, context
):
193 blender_handlers
= bpy
.app
.handlers
.render_init
194 for h
in blender_handlers
:
195 if "turn_off_animatable" in str(h
):
196 old_handlers
.append(h
)
197 for h
in old_handlers
: blender_handlers
.remove(h
)
198 blender_handlers
.append(turn_off_animatable
)
201 def turn_off_animatable(scene
):
202 for o
in bpy
.data
.objects
:
203 o
.tissue_tessellate
.bool_run
= False
204 o
.reaction_diffusion_settings
.run
= False