def regenerate_objects(self, object_names: List[str], data_blocks, collections: List[bpy.types.Collection] = None, object_template: List[bpy.types.Object] = None): """ It will generate new or remove old objects, number of generated objects will be equal to given data_blocks Object_names list can contain one name. In this case Blender will add suffix to next objects (.001, .002,...) :param object_template: optionally, object which properties should be grabbed for instanced object :param collections: objects will be putted into collections if given, only one in list can be given :param data_blocks: nearly any data blocks - mesh, curves, lights ... :param object_names: usually equal to name of data block :param data_blocks: for now it is support only be bpy.types.Mesh """ if collections is None: collections = [None] if object_template is None: object_template = [None] correct_collection_length(self.object_data, len(data_blocks)) prop_group: SvObjectData input_data = zip(self.object_data, data_blocks, cycle(object_names), cycle(collections), cycle(object_template)) for prop_group, data_block, name, collection, template in input_data: prop_group.ensure_object(data_block, name, template) prop_group.ensure_link_to_collection(collection) prop_group.check_object_name(name)
def process(self): objects = self.inputs['Object'].sv_get(deepcopy=False, default=[]) attr_name = self.inputs['Attr name'].sv_get(deepcopy=False, default=[]) sock_name = 'Value' if self.value_type in ['FLOAT', 'INT', 'BOOLEAN'] else \ 'Vector' if self.value_type in ['FLOAT_VECTOR', 'FLOAT2'] else 'Color' values = self.inputs[sock_name].sv_get(deepcopy=False, default=[]) # first step remove attributes from previous update if necessary iter_attr_names = chain(flat_iter(attr_name), cycle([None])) for last, obj, attr in zip(self.last_objects, chain(objects, cycle([None])), iter_attr_names): if last.obj != obj or last.attr != attr: last.remove_attr() correct_collection_length(self.last_objects, len(objects)) # assign new attribute iter_attr_names = fixed_iter(flat_iter(attr_name), len(objects)) for last, obj, attr, val in zip(self.last_objects, objects, iter_attr_names, fixed_iter(values, len(objects))): last.add_attr(obj, attr) set_attribute_node(obj=obj, values=val, attr_name=attr, domain=self.domain, value_type=self.value_type) self.outputs['Object'].sv_set(objects)
def process(self): objects = self.inputs['Object'].sv_get(deepcopy=False, default=[]) collections = self.inputs['Collection'].sv_get(deepcopy=False, default=[]) # first step is undo previous changes by the node if necessary len_last = len(self.last_objects) for last, obj, col in zip(self.last_objects, chain(objects, cycle([None])), fixed_iter(collections, len_last)): last.unlink() correct_collection_length(self.last_objects, len(objects)) # save and assign new collections for last, obj, col in zip(self.last_objects, objects, fixed_iter(collections, len(objects))): last.link(obj, col) self.outputs['Object'].sv_set(objects)
def process(self): if not self.is_active or not self.inputs[1].is_linked: return child_objects = self.inputs['child'].sv_get(deepcopy=False) transforms = self.inputs['matr/vert'].sv_get(deepcopy=False) if not child_objects: return child = child_objects[0] if transforms and len(transforms[0]) > 0: verts, faces = generate_mesh_data(transforms, child, self.mode, self.ignore_base_offset) correct_collection_length(self.mesh_data, 1) self.mesh_data[0].regenerate_mesh(self.base_data_name, verts, [], faces, None, self.fast_mesh_update) self.regenerate_objects([self.base_data_name], [d.mesh for d in self.mesh_data], [self.collection]) ob = self.object_data[0].obj ob.instance_type = self.mode ob.use_instance_faces_scale = self.scale ob.show_instancer_for_viewport = self.show_instancer_for_viewport ob.show_instancer_for_render = self.show_instancer_for_render childs_name = [] for child in child_objects: child.parent = ob child.hide_set(not self.show_base_child) childs_name.append(child.name) self.name_child = str(childs_name) if self.auto_release: auto_release(ob.name, childs_name) self.outputs['Objects'].sv_set( [obj_data.obj for obj_data in self.object_data])
def process(self): if not self.is_active: return verts = self.inputs['vertices'].sv_get(deepcopy=False, default=[]) edges = self.inputs['edges'].sv_get(deepcopy=False, default=[[]]) faces = self.inputs['faces'].sv_get(deepcopy=False, default=[[]]) mat_indexes = self.inputs['material_idx'].sv_get(deepcopy=False, default=[[]]) matrices = self.inputs['matrix'].sv_get(deepcopy=False, default=[]) # first step is merge everything if the option if self.is_merge: if matrices: objects_number = max([len(verts), len(matrices)]) mat_indexes = [[ i for _, obj, mat_i in zip(range( objects_number), cycle(faces), cycle(mat_indexes)) for f, i in zip(obj, cycle(mat_i)) ]] _, *join_mesh_data = list( zip(*zip(range(objects_number), cycle(verts), cycle(edges), cycle(faces), cycle(matrices)))) verts, edges, faces = apply_and_join_python( *join_mesh_data, True) matrices = [] else: mat_indexes = [[ i for obj, mat_i in zip(faces, cycle(mat_indexes)) for f, i in zip(obj, cycle(mat_i)) ]] verts, edges, faces = mesh_join(verts, edges if edges[0] else [], faces) # function has good API verts, edges, faces = [verts], [edges], [faces] objects_number = max([len(verts), len(matrices)]) if verts else 0 # extract mesh matrices if self.apply_matrices_to == 'mesh': if matrices: mesh_matrices = matrices else: mesh_matrices = cycle([None]) else: mesh_matrices = cycle([None]) # extract object matrices if self.apply_matrices_to == 'object': if matrices: obj_matrices = matrices else: if self.is_lock_origin: obj_matrices = cycle([Matrix.Identity(4)]) else: obj_matrices = [] else: if self.is_lock_origin: obj_matrices = cycle([Matrix.Identity(4)]) else: obj_matrices = [] # regenerate mesh data blocks correct_collection_length(self.mesh_data, objects_number) create_mesh_data = zip(self.mesh_data, cycle(verts), cycle(edges), cycle(faces), cycle(mesh_matrices), cycle(mat_indexes)) for me_data, v, e, f, m, mat_i in create_mesh_data: me_data.regenerate_mesh(self.base_data_name, v, e, f, m, self.fast_mesh_update) if self.material: me_data.mesh.materials.clear() me_data.mesh.materials.append(self.material) if mat_indexes: mat_i = [ mi for _, mi in zip(me_data.mesh.polygons, cycle(mat_i)) ] me_data.mesh.polygons.foreach_set('material_index', mat_i) me_data.set_smooth(self.is_smooth_mesh) # regenerate object data blocks self.regenerate_objects([self.base_data_name], [d.mesh for d in self.mesh_data], [self.collection]) [ setattr(prop.obj, 'matrix_local', m) for prop, m in zip(self.object_data, cycle(obj_matrices)) ] [ setattr(prop.obj, 'show_wire', self.show_wireframe) for prop in self.object_data ] self.outputs['Objects'].sv_set( [obj_data.obj for obj_data in self.object_data])
def process(self): if not self.is_active: return vertices = self.inputs['vertices'].sv_get(deepcopy=False, default=[]) matrices = self.inputs['matrix'].sv_get(deepcopy=False, default=[]) radius = self.inputs['radius'].sv_get(deepcopy=False) tilt = self.inputs['tilt'].sv_get(deepcopy=False) bevel_objects = self.inputs['bevel object'].sv_get(default=[]) if 'Cyclic' in self.inputs: cyclic = self.inputs['Cyclic'].sv_get(deepcopy=False)[0] else: cyclic = [self.close] # first step is merge everything if the option if self.is_merge: objects_number = max([len(vertices), len(matrices)]) meshes = [] for i, verts, matrix in zip( range(objects_number), repeat_last(vertices), repeat_last(matrices if matrices else [[]])): mesh = me.to_mesh(verts) if matrix: mesh.apply_matrix(matrix) meshes.append(mesh) vertices = [m.vertices.data for m in meshes] matrices = [] objects_number = max([len(vertices), len(matrices) ]) if len(vertices) else 0 # extract mesh matrices if self.apply_matrices_to == 'mesh': if matrices: mesh_matrices = matrices else: mesh_matrices = [None] else: mesh_matrices = [None] # extract object matrices if self.apply_matrices_to == 'object': if matrices: obj_matrices = matrices else: if self.is_lock_origin: obj_matrices = [Matrix.Identity(4)] else: obj_matrices = [] else: if self.is_lock_origin: obj_matrices = [Matrix.Identity(4)] else: obj_matrices = [] # regenerate curve data blocks if self.is_merge: correct_collection_length(self.curve_data, 1) self.curve_data[0].regenerate_curve(self.base_data_name, vertices, self.curve_type, radius, cyclic, self.use_smooth, tilt) else: correct_collection_length(self.curve_data, objects_number) for cu_data, verts, matrix, r, t, close in zip( self.curve_data, repeat_last(vertices), repeat_last(mesh_matrices), repeat_last(radius), repeat_last(tilt), repeat_last(cyclic)): if matrix: mesh = me.to_mesh(verts) mesh.apply_matrix(matrix) verts = mesh.vertices.data cu_data.regenerate_curve(self.base_data_name, [verts], self.curve_type, [r], [close], self.use_smooth, [t]) # assign curve properties for cu_data, bevel_object in zip(self.curve_data, repeat_last(bevel_objects or [None])): cu_data.curve.dimensions = self.curve_dimensions cu_data.curve.bevel_depth = self.bevel_depth cu_data.curve.bevel_resolution = self.resolution cu_data.curve.resolution_u = self.preview_resolution_u cu_data.curve.bevel_object = bevel_object cu_data.curve.use_fill_caps = self.caps print(type(cu_data.curve), ) for spline in cu_data.curve.splines: spline.use_endpoint_u = self.last_point if self.material: cu_data.curve.materials.clear() cu_data.curve.materials.append(self.material) # regenerate object data blocks self.regenerate_objects([self.base_data_name], [d.curve for d in self.curve_data], [self.collection]) [ setattr(prop.obj, 'matrix_local', m) for prop, m in zip(self.object_data, repeat_last(obj_matrices)) ] [ setattr(prop.obj, 'show_wire', self.show_wire) for prop in self.object_data ] self.outputs['Objects'].sv_set( [obj_data.obj for obj_data in self.object_data])
def process(self): if not self.is_active: return origins = self.inputs['Origin'].sv_get(deepcopy=False, default=[None]) sizes_sq = self.inputs['Size'].sv_get(deepcopy=False, default=[None]) sizes_x = self.inputs['Size X'].sv_get(deepcopy=False, default=[None]) sizes_y = self.inputs['Size Y'].sv_get(deepcopy=False, default=[None]) spot_sizes = self.inputs['Spot Size'].sv_get(deepcopy=False, default=[None]) spot_blends = self.inputs['Spot Blend'].sv_get(deepcopy=False, default=[None]) strengths = self.inputs['Strength'].sv_get(deepcopy=False, default=[None]) colors = self.inputs['Color'].sv_get(deepcopy=False, default=[None]) objects_number = 0 if origins == [None] else max([ len(i) if i != [None] else 0 for i in [ origins, sizes_sq, sizes_x, sizes_y, spot_sizes, spot_blends, strengths, colors ] ]) correct_collection_length(self.light_data, objects_number) [ props.regenerate_light(self.base_data_name, self.light_type) for props in self.light_data ] self.regenerate_objects([self.base_data_name], [prop.light for prop in self.light_data], [self.collection]) [ setattr(prop.obj, 'matrix_local', m) for prop, m in zip(self.object_data, cycle(origins)) ] for prop, size, size_x, size_y, strength, color, spot_size, spot_blend in zip( self.light_data, cycle(sizes_sq), cycle(sizes_x), cycle(sizes_y), cycle(strengths), cycle(colors), cycle(spot_sizes), cycle(spot_blends)): prop.light.energy = strength[0] prop.light.color = color[0][:3] if self.light_type in ('POINT', 'SUN'): prop.light.shadow_soft_size = size[0] elif self.light_type == 'SPOT': prop.light.shadow_soft_size = size[0] prop.light.spot_size = spot_size[0] prop.light.spot_blend = spot_blend[0] prop.light.show_cone = self.show_cone elif self.light_type == 'AREA': prop.light.shape = self.shape_type if self.shape_type in ('SQUARE', 'DISK'): prop.light.shadow_soft_size = size[0] else: prop.light.size = size_x[0] prop.light.size_y = size_y[0] if bpy.context.scene.render.engine == 'BLENDER_EEVEE': prop.light.use_shadow = self.cast_shadow elif bpy.context.scene.render.engine == 'CYCLES': prop.light.cycles.cast_shadow = self.cast_shadow self.outputs['Objects'].sv_set( [obj_data.obj for obj_data in self.object_data])
def process(self): if not self.is_active: return verts = self.inputs['vertices'].sv_get(deepcopy=False, default=[]) edges = self.inputs['edges'].sv_get(deepcopy=False, default=[[]]) faces = self.inputs['faces'].sv_get(deepcopy=False, default=[[]]) mat_indexes = self.inputs['material_idx'].sv_get(deepcopy=False, default=[[]]) matrices = self.inputs['matrix'].sv_get(deepcopy=False, default=[]) # first step is merge everything if the option if self.is_merge: objects_number = max([len(verts), len(matrices)]) meshes = [] for i, *elements, materials, matrix in zip( range(objects_number), repeat_last(verts), repeat_last(edges), repeat_last(faces), repeat_last(mat_indexes), repeat_last(matrices if matrices else [[]])): mesh = me.to_mesh(*elements) if materials: mesh.polygons['material'] = materials if matrix: mesh.apply_matrix(matrix) meshes.append(mesh) base_mesh = reduce(lambda m1, m2: m1.add_mesh(m2), meshes) verts, edges, faces = [base_mesh.vertices.data], [base_mesh.edges.data], [base_mesh.polygons.data] mat_indexes = [base_mesh.polygons.get_attribute('material', [])] matrices = [] objects_number = max([len(verts), len(matrices)]) if verts else 0 # extract mesh matrices if self.apply_matrices_to == 'mesh': if matrices: mesh_matrices = matrices else: mesh_matrices = cycle([None]) else: mesh_matrices = cycle([None]) # extract object matrices if self.apply_matrices_to == 'object': if matrices: obj_matrices = matrices else: if self.is_lock_origin: obj_matrices = cycle([Matrix.Identity(4)]) else: obj_matrices = [] else: if self.is_lock_origin: obj_matrices = cycle([Matrix.Identity(4)]) else: obj_matrices = [] # regenerate mesh data blocks correct_collection_length(self.mesh_data, objects_number) create_mesh_data = zip(self.mesh_data, cycle(verts), cycle(edges), cycle(faces), cycle(mesh_matrices), cycle(mat_indexes)) for me_data, v, e, f, m, mat_i in create_mesh_data: me_data.regenerate_mesh(self.base_data_name, v, e, f, m, self.fast_mesh_update) if self.material: me_data.mesh.materials.clear() me_data.mesh.materials.append(self.material) if mat_indexes: mat_i = [mi for _, mi in zip(me_data.mesh.polygons, cycle(mat_i))] me_data.mesh.polygons.foreach_set('material_index', mat_i) me_data.set_smooth(self.is_smooth_mesh) # regenerate object data blocks self.regenerate_objects([self.base_data_name], [d.mesh for d in self.mesh_data], [self.collection]) [setattr(prop.obj, 'matrix_local', m) for prop, m in zip(self.object_data, cycle(obj_matrices))] [setattr(prop.obj, 'show_wire', self.show_wireframe) for prop in self.object_data] self.outputs['Objects'].sv_set([obj_data.obj for obj_data in self.object_data])