def process(self): if not all([sock.is_linked for sock in [self.inputs['Verts'], self.inputs['Faces']]]): return inputs = self.inputs params = [s.sv_get(deepcopy=False, default=[[]]) for s in self.inputs] max_len = max(map(len, params)) out = [] for i, v, e, f, fd, m, t, d in zip(range(max_len), *make_repeaters(params)): out.append(inset_faces(v, f, t, d, e, fd, m, self.inset_type, self.mask_type, set(prop for prop in self.bool_properties if getattr(self, prop)))) # verts = inputs['Verts'].sv_get() # edges = inputs['Edges'].sv_get() if inputs['Edges'].is_linked else cycle([None]) # faces = inputs['Faces'].sv_get() # face_data = chain(inputs['Face data'].sv_get(), cycle([inputs['Face data'].sv_get()[-1]]))\ # if inputs['Face data'].is_linked else cycle([None]) # face_mask = chain(inputs['Face mask'].sv_get(), cycle([inputs['Face mask'].sv_get()[-1]]))\ # if inputs['Face mask'].is_linked else cycle([None]) # thickness = chain(inputs['Thickness'].sv_get(), cycle([inputs['Thickness'].sv_get()[-1]])) # depth = chain(inputs['Depth'].sv_get(), cycle([inputs['Depth'].sv_get()[-1]])) # # out = [] # for v, e, f, t, d, fd, m in zip(verts, edges, faces, thickness, depth, face_data, face_mask): # out.append(inset_faces(v, f, t, d, e, fd, m, self.inset_type, self.mask_type, # set(prop for prop in self.bool_properties if getattr(self, prop)))) out_verts, out_edges, out_faces, out_face_data, out_mask = zip(*out) self.outputs['Verts'].sv_set(out_verts) self.outputs['Edges'].sv_set(out_edges) self.outputs['Faces'].sv_set(out_faces) self.outputs['Face data'].sv_set(out_face_data) self.outputs['Mask'].sv_set(out_mask)
def euler_matrices(params, euler_order, angle_units): mat_num = max(map(len, params)) params2 = make_repeaters(params) matrices = [] for i, location, angleX, angleY, angleZ, scale in zip( range(mat_num), *params2): # translation mat_t[0][3] = location[0] mat_t[1][3] = location[1] mat_t[2][3] = location[2] # rotation angles = (angleX * angle_units, angleY * angle_units, angleZ * angle_units) euler = Euler(angles, euler_order) # mat_r = euler.to_quaternion().to_matrix().to_4x4() mat_r = euler.to_matrix().to_4x4() # scale mat_s[0][0] = scale[0] mat_s[1][1] = scale[1] mat_s[2][2] = scale[2] # composite matrix m = mat_t @ mat_r @ mat_s matrices.append(m) return matrices
def process(self): i = self.inputs o = self.outputs if not o['vertices'].is_linked: return all_verts = Vector_generate(i['vertices'].sv_get(deepcopy=False)) all_polys = i['polygons'].sv_get(deepcopy=False) all_inset_rates = i['inset'].sv_get(deepcopy=False) all_distance_vals = i['distance'].sv_get(deepcopy=False) # silly auto ugrade. if not i['ignore'].prop_name: i['ignore'].prop_name = 'ignore' i['make_inner'].prop_name = 'make_inner' all_ignores = i['ignore'].sv_get(deepcopy=False) all_make_inners = i['make_inner'].sv_get(deepcopy=False) data = all_verts, all_polys, all_inset_rates, all_distance_vals, all_ignores, all_make_inners verts_out = [] polys_out = [] ignored_out = [] inset_out = [] for v, p, inset_rates_s, distance_vals_s, ignores_s, make_inners_s in zip_long_repeat( *data): inset_rates, distance_vals, ignores, make_inners = make_repeaters( [inset_rates_s, distance_vals_s, ignores_s, make_inners_s]) func_args = { 'vertices': v, 'faces': p, 'inset_rates': inset_rates, 'distances': distance_vals, 'make_inners': make_inners, 'ignores': ignores, 'zero_mode': self.zero_mode } res = inset_special(**func_args) if not res: res = v, p, [], [] verts_out.append(res[0]) polys_out.append(res[1]) ignored_out.append(res[2]) inset_out.append(res[3]) # deal with hooking up the processed data to the outputs o['vertices'].sv_set(verts_out) o['polygons'].sv_set(polys_out) o['ignored'].sv_set(ignored_out) o['inset'].sv_set(inset_out)
def process_data(self, params): o = self.outputs output = [[] for s in self.outputs] output_old_face_id = o['Original face idx'].is_linked output_old_vert_id = o['Original verts idx'].is_linked output_pols_groups = o['Pols group'].is_linked output_new_verts_mask = o['New verts mask'].is_linked for verts, pols, inset_rates_s, distance_vals_s, ignores_s, make_inners_s, custom_normals, matrices in zip_long_repeat( *params): if self.implementation == 'mathutils': inset_rates, distance_vals, ignores, make_inners = make_repeaters( [inset_rates_s, distance_vals_s, ignores_s, make_inners_s]) func_args = { 'vertices': [Vector(vec) for vec in verts], 'faces': pols, 'inset_rates': inset_rates, 'distances': distance_vals, 'ignores': ignores, 'make_inners': make_inners, 'zero_mode': self.zero_mode } res = inset_special_mathutils(**func_args) else: func_args = { 'vertices': verts, 'faces': pols, 'inset_rates': inset_rates_s, 'distances': distance_vals_s, 'ignores': ignores_s, 'make_inners': make_inners_s, 'custom_normals': custom_normals, 'matrices': matrices, 'zero_mode': self.zero_mode, 'offset_mode': self.offset_mode, 'proportional': self.proportional, 'concave_support': self.concave_support, 'output_old_face_id': output_old_face_id, 'output_old_v_id': output_old_vert_id, 'output_pols_groups': output_pols_groups, 'output_new_verts_mask': output_new_verts_mask } res = inset_special_np(**func_args) if not res: res = verts, pols, [], [], [], [], [], [] for sub_res, socket in zip(res, output): socket.append(sub_res) return output
def quaternion_matrices(params): matrices = [] mat_num = max(map(len, params)) params2 = make_repeaters(params) for i, location, quaternion, scale in zip(range(mat_num), *params2): # translation mat_t[0][3] = location[0] mat_t[1][3] = location[1] mat_t[2][3] = location[2] # rotation mat_r = quaternion.to_matrix().to_4x4() # scale mat_s[0][0] = scale[0] mat_s[1][1] = scale[1] mat_s[2][2] = scale[2] # composite matrix m = mat_t @ mat_r @ mat_s matrices.append(m) return matrices
def axis_angle_matrices(params, angle_units): max_len = max(map(len, params)) params2 = make_repeaters(params) # params2 = match_long_repeat([ll, xl, al, sl]) matrices = [] for i, location, axis, angle, scale in zip(range(max_len), *params2): # for location, axis, angle, scale in zip(*params2): # translation mat_t[0][3] = location[0] mat_t[1][3] = location[1] mat_t[2][3] = location[2] # rotation mat_r = Quaternion(axis, angle * angle_units).to_matrix().to_4x4() # scale mat_s[0][0] = scale[0] mat_s[1][1] = scale[1] mat_s[2][2] = scale[2] # composite matrix m = mat_t @ mat_r @ mat_s matrices.append(m) return matrices
def process(self): inputs = self.inputs outputs = self.outputs if not (inputs['Vertices'].is_linked and inputs['Polygons'].is_linked): return if not any(socket.is_linked for socket in outputs): return need_mask_out = 'Mask' in outputs and outputs['Mask'].is_linked vector_in = self.scale_socket_type vertices_s = inputs['Vertices'].sv_get(deepcopy=False) edges_s = inputs['Edges'].sv_get(default=[[]], deepcopy=False) faces_s = inputs['Polygons'].sv_get(default=[[]], deepcopy=False) masks_s = inputs['Mask'].sv_get(default=[[1]], deepcopy=False) heights_s = inputs['Height'].sv_get(deepcopy=False) scales_s = inputs['Scale'].sv_get(deepcopy=False) if 'Matrix' in inputs: matrixes_s = inputs['Matrix'].sv_get(default=[[Matrix()]], deepcopy=False) else: matrixes_s = [[Matrix()]] if 'FaceData' in inputs: face_data_s = self.inputs['FaceData'].sv_get(default=[[]], deepcopy=False) else: face_data_s = [[]] if type(matrixes_s[0]) == Matrix: matrixes_s = [matrixes_s] linked_extruded_polygons = outputs['ExtrudedPolys'].is_linked linked_other_polygons = outputs['OtherPolys'].is_linked result_vertices = [] result_edges = [] result_faces = [] result_extruded_faces = [] result_other_faces = [] result_mask = [] result_face_data = [] meshes = match_long_repeat([ vertices_s, edges_s, faces_s, masks_s, heights_s, scales_s, matrixes_s, face_data_s ]) for vertices, edges, faces, masks_, heights_, scales_, matrixes_, face_data in zip( *meshes): new_extruded_faces = [] new_extruded_faces_append = new_extruded_faces.append heights, scales, matrixes, masks = make_repeaters( [heights_, scales_, matrixes_, masks_]) if face_data: face_data_matched = repeat_last_for_length( face_data, len(faces)) bm = bmesh_from_pydata(vertices, edges, faces, markup_face_data=True, normal_update=True) mask_layer = bm.faces.layers.int.new('mask') bm.faces.ensure_lookup_table() fill_faces_layer(bm, masks, 'mask', int, OUT) if self.mask_mode == 'NOEXTRUDE': faces_to_extrude = [ face for face, mask in zip(bm.faces, masks) if mask ] else: faces_to_extrude = bm.faces extruded_faces = bmesh.ops.extrude_discrete_faces( bm, faces=faces_to_extrude)['faces'] if self.mask_mode == 'NOEXTRUDE': extruded_face_items = zip(extruded_faces, heights, scales, matrixes) else: extruded_face_items = [ (face, height, scale, matrix) for (face, mask, height, scale, matrix) in zip( extruded_faces, masks, heights, scales, matrixes) if mask ] for face, height, scale, matrix in extruded_face_items: vec = scale if vector_in else (scale, scale, scale) # preparing matrix normal = face.normal if normal[0] == 0 and normal[1] == 0: m_r = Matrix() if normal[2] >= 0 else Matrix.Rotation( pi, 4, 'X') else: z_axis = normal x_axis = (Vector( (z_axis[1] * -1, z_axis[0], 0))).normalized() y_axis = (z_axis.cross(x_axis)).normalized() m_r = Matrix(list([*zip(x_axis[:], y_axis[:], z_axis[:]) ])).to_4x4() dr = face.normal * height center = face.calc_center_median() translation = Matrix.Translation(center) space = (translation @ m_r).inverted() if self.extrude_mode == 'NORMAL': # inset, scale and push operations bmesh.ops.scale(bm, vec=vec, space=space, verts=face.verts) bmesh.ops.translate(bm, verts=face.verts, vec=dr) else: bmesh.ops.transform(bm, matrix=matrix, space=space, verts=face.verts) if linked_extruded_polygons or linked_other_polygons: new_extruded_faces_append([v.index for v in face.verts]) if face_data: new_vertices, new_edges, new_faces, new_face_data = pydata_from_bmesh( bm, face_data_matched) else: new_vertices, new_edges, new_faces = pydata_from_bmesh(bm) new_face_data = [] new_other_faces = [ f for f in new_faces if f not in new_extruded_faces ] if linked_other_polygons else [] if need_mask_out: new_mask = self.get_out_mask(bm, extruded_faces) result_mask.append(new_mask) bm.free() result_vertices.append(new_vertices) result_edges.append(new_edges) result_faces.append(new_faces) result_extruded_faces.append(new_extruded_faces) result_other_faces.append(new_other_faces) result_face_data.append(new_face_data) outputs['Vertices'].sv_set(result_vertices) outputs['Edges'].sv_set(result_edges) outputs['Polygons'].sv_set(result_faces) outputs['ExtrudedPolys'].sv_set(result_extruded_faces) outputs['OtherPolys'].sv_set(result_other_faces) if need_mask_out: outputs['Mask'].sv_set(result_mask) if 'FaceData' in outputs: outputs['FaceData'].sv_set(result_face_data)