-
-
Save zeffii/db9001094fe91b676b34 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import bpy | |
import bmesh | |
import mathutils | |
from mathutils import Vector, Matrix | |
from bpy.props import BoolProperty, FloatVectorProperty, StringProperty | |
from node_s import * | |
from util import * | |
import random | |
def get_random_init(): | |
greek_alphabet = [ | |
'Alpha', 'Beta', 'Gamma', 'Delta', | |
'Epsilon', 'Zeta', 'Eta', 'Theta', | |
'Iota', 'Kappa', 'Lamda', 'Mu', | |
'Nu', 'Xi', 'Omicron', 'Pi', | |
'Rho', 'Sigma', 'Tau', 'Upsilon', | |
'Phi', 'Chi', 'Psi', 'Omega'] | |
return random.choice(greek_alphabet) | |
def make_or_update_instance(node, context, obj_name, matrix): | |
scene = context.scene | |
meshes = bpy.data.meshes | |
objects = bpy.data.objects | |
clone_mesh_name = n.object_to_clone | |
if obj_name in objects: | |
sv_object = objects[obj_name] | |
else: | |
instance_mesh = meshes[clone_mesh_name] | |
sv_object = objects.new(obj_name, instance_mesh) | |
scene.objects.link(sv_object) | |
scene.update() | |
# apply matrices | |
if matrix: | |
sv_object.matrix_local = list(zip(*matrix)) | |
class SvInstancerOp(bpy.types.Operator): | |
bl_idname = "node.instancer_config" | |
bl_label = "Sverchok instancer op" | |
bl_options = {'REGISTER', 'UNDO'} | |
obj_name = StringProperty(default="") | |
def execute(self, context): | |
n = context.node | |
n.object_to_clone = bpy.data.objects[obj_name].data.name | |
return {'FINISHED'} | |
class SvInstancerNode(Node, SverchCustomTreeNode): | |
bl_idname = 'InstancerNode' | |
bl_label = 'Instancer Node' | |
bl_icon = 'OUTLINER_OB_EMPTY' | |
activate = BoolProperty( | |
name='Show', description='Activate node?', | |
default=True, | |
update=updateNode) | |
basemesh_name = StringProperty(default='Alpha', update=updateNode) | |
grouping = BoolProperty(default=False) | |
object_to_clone = StringProperty(default='', update=updateNode) | |
def init(self, context): | |
self.inputs.new('MatrixSocket', 'matrix', 'matrix') | |
def draw_buttons(self, context, layout): | |
row = layout.row(align=True) | |
row.prop(self, "activate", text="Update") | |
row = layout.row(align=True) | |
row.label('name of object') | |
row = layout.row(align=True) | |
row.prop(self, "object_to_clone") | |
row.operator(self, "node.instancer_config", text="use") | |
row = layout.row() | |
row.prop(self, "grouping", text="to Group") | |
layout.label("Base mesh name(s)", icon='OUTLINER_OB_MESH') | |
col = layout.column(align=True) | |
row = col.row(align=True) | |
row.prop(self, "basemesh_name", text="") | |
def abort_processing(self): | |
try: | |
l = bpy.data.node_groups[self.id_data.name] | |
except Exception as e: | |
print(self.name, "cannot run during startup, press update.") | |
return True | |
def get_corrected_data(self, socket_name, socket_type): | |
inputs = self.inputs | |
socket = inputs[socket_name].links[0].from_socket | |
if isinstance(socket, socket_type): | |
socket_in = SvGetSocketAnyType(self, inputs[socket_name]) | |
return dataCorrect(socket_in) | |
else: | |
return [] | |
def update(self): | |
if self.abort_processing() and not self.activate: | |
return | |
s_name, s_type = ['matrices', MatrixSocket] | |
if s_name in inputs and inputs[s_name].links: | |
matrices = self.get_corrected_data(s_name, s_type) | |
if not matrices: | |
return | |
# we have matrices, we can process, go go go! | |
for obj_index, matrix in enumerate(matrices): | |
obj_name = self.basemesh_name + "_" + str(obj_index) | |
make_or_update_instance(self, context, obj_name, matrix) | |
# obj_index is now the last index fond in matrices | |
self.remove_non_updated_objects(obj_index, self.basemesh_name) | |
if self.grouping: | |
self.to_group() | |
def to_group(self): | |
objs = bpy.data.objects | |
if not self.basemesh_name in bpy.data.groups: | |
newgroup = bpy.data.groups.new(self.basemesh_name) | |
else: | |
newgroup = bpy.data.groups[self.basemesh_name] | |
for obj in objs: | |
if self.basemesh_name in obj.name: | |
if obj.name not in newgroup.objects: | |
newgroup.objects.link(obj) | |
def remove_non_updated_objects(self, obj_index, _name): | |
meshes = bpy.data.meshes | |
objects = bpy.data.objects | |
objects_to_reselect = [] | |
for i in (i for i in objects if i.select): | |
objects_to_reselect.append(i.name) | |
i.select = False | |
objs = [obj for obj in objects if obj.type == 'MESH'] | |
objs = [obj for obj in objs if obj.name.startswith(_name)] | |
objs = [obj.name for obj in objs if int(obj.name.split("_")[-1]) > obj_index] | |
# select and finally remove all excess objects | |
for object_name in objs: | |
objects[object_name].select = True | |
bpy.ops.object.delete() | |
# reselect | |
for name in objects_to_reselect: | |
bpy.data.objects[name].select = True | |
# fingers crossed. | |
def update_socket(self, context): | |
self.update() | |
def register(): | |
bpy.utils.register_class(SvInstancerNode) | |
bpy.utils.register_class(SvInstancerOp) | |
def unregister(): | |
bpy.utils.unregister_class(SvInstancerNode) | |
bpy.utils.unregister_class(SvInstancerOp) | |
if __name__ == '__main__': | |
register() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment