def execute(self, context): self.init_data() if self.dm.predicted_data_type == DataType.Categorical and self.data_type_as_enum() == DataType.Numerical: self.report({'ERROR'}, 'Cannot convert categorical data into numerical!') return {'CANCELLED'} self.create_container() if self.data_type_as_enum() == DataType.Numerical: self.data = get_data_in_range(self.data, self.axis_settings.x_range) sorted_data = sorted(self.data, key=lambda x: x[0]) else: sorted_data = self.data tick_labels = [] if self.data_type_as_enum() == DataType.Numerical: normalized_vert_list = [(normalize_value(entry[0], self.axis_settings.x_range[0], self.axis_settings.x_range[1]), 0.0, normalize_value(entry[1], self.axis_settings.z_range[0], self.axis_settings.z_range[1])) for entry in sorted_data] else: normalized_vert_list = [(normalize_value(i, self.axis_settings.x_range[0], self.axis_settings.x_range[1]), 0.0, normalize_value(entry[1], self.axis_settings.z_range[0], self.axis_settings.z_range[1])) for i, entry in enumerate(sorted_data)] tick_labels = list(zip(*sorted_data))[0] edges = [[i - 1, i] for i in range(1, len(normalized_vert_list))] self.create_curve(normalized_vert_list, edges) self.add_bevel_obj() if self.use_shader: mat = NodeShader(self.get_name(), self.color_shade, location_z=self.container_object.location[2]).create_geometry_shader() else: mat = ColorGen(self.color_shade, ColorType.Constant, self.axis_settings.z_range).get_material() self.curve_obj.data.materials.append(mat) self.curve_obj.active_material = mat if self.axis_settings.create: AxisFactory.create( self.container_object, self.axis_settings, 2, self.chart_id, labels=self.labels, tick_labels=(tick_labels, [], []) ) if self.series_label: self.create_series_label(mat) if self.header_settings.create: self.create_header() self.select_container() return {'FINISHED'}
def normalize_value(self, value, direction): axis_range = None size = None if direction == 'x': axis_range = self.axis_settings.x_range size = self.container_size[0] elif direction == 'y': axis_range = self.axis_settings.y_range size = self.container_size[1] elif direction == 'z': axis_range = self.axis_settings.z_range size = self.container_size[2] if axis_range is None or size is None: return 0.5 return size * normalize_value(value, axis_range[0], axis_range[1])
def execute(self, context): self.init_data(subtype=self.determine_subtype()) self.create_container() color_factory = ColoringFactory( self.get_name(), self.color_settings.color_shade, ColorType.str_to_type(self.color_settings.color_type), self.color_settings.use_shader) color_gen = color_factory.create(self.axis_settings.z_range, self.container_size[2], self.container_object.location[2]) w_idx = 2 if self.dimensions == '2' else 3 w_range = self.dm.get_range('w') v_idx = w_idx - 1 for i, entry in enumerate(self.data): if not self.in_axis_range_bounds_new(entry): continue bpy.ops.mesh.primitive_uv_sphere_add(segments=16, ring_count=8) bubble_obj = context.active_object bubble_obj.scale *= ( self.bubble_size[1] - self.bubble_size[0]) * normalize_value( entry[w_idx], w_range[0], w_range[1]) + self.bubble_size[0] x_norm = self.normalize_value(entry[0], 'x') z_norm = self.normalize_value(entry[v_idx], 'z') if self.dimensions == '2': bubble_obj.location = (x_norm, 0.0, z_norm) else: y_norm = self.normalize_value(entry[1], 'y') bubble_obj.location = (x_norm, y_norm, z_norm) mat = color_gen.get_material(entry[v_idx]) bubble_obj.data.materials.append(mat) bubble_obj.active_material = mat bubble_obj.parent = self.container_object if self.anim_settings.animate: frame_n = context.scene.frame_current if self.anim_type == 'z': bubble_obj.keyframe_insert(data_path='location', frame=frame_n) elif self.anim_type == 'size': bubble_obj.keyframe_insert(data_path='scale', frame=frame_n) anim_data = self.dm.parsed_data[i][w_idx + 1:] for j in range(len(anim_data)): frame_n += self.anim_settings.key_spacing zn_norm = self.normalize_value(anim_data[j], 'z') if self.anim_type == 'z': bubble_obj.location[2] = zn_norm bubble_obj.keyframe_insert(data_path='location', frame=frame_n) elif self.anim_type == 'size': scale = (self.bubble_size[1] - self.bubble_size[0]) * normalize_value( anim_data[j], w_range[0], w_range[1]) + self.bubble_size[0] bubble_obj.scale = (scale, scale, scale) bubble_obj.keyframe_insert(data_path='scale', frame=frame_n) if self.axis_settings.create: AxisFactory.create( self.container_object, self.axis_settings, int(self.dimensions), self.chart_id, labels=self.labels, container_size=self.container_size, ) self.select_container() return {'FINISHED'}
def execute(self, context): self.init_data() if self.dimensions == '2': value_index = 1 else: if len(self.data[0]) == 2: self.report({'ERROR'}, 'Data are only 2D!') return {'CANCELLED'} value_index = 2 self.create_container() color_factory = ColoringFactory( self.get_name(), self.color_settings.color_shade, ColorType.str_to_type(self.color_settings.color_type), self.color_settings.use_shader) color_gen = color_factory.create(self.axis_settings.z_range, 1.0, self.container_object.location[2]) for i, entry in enumerate(self.data): # skip values outside defined axis range if not self.in_axis_range_bounds_new(entry): continue bpy.ops.mesh.primitive_uv_sphere_add(segments=16, ring_count=8) point_obj = context.active_object point_obj.scale = Vector( (self.point_scale, self.point_scale, self.point_scale)) mat = color_gen.get_material(entry[value_index]) point_obj.data.materials.append(mat) point_obj.active_material = mat # normalize height x_norm = normalize_value(entry[0], self.axis_settings.x_range[0], self.axis_settings.x_range[1]) z_norm = normalize_value(entry[value_index], self.axis_settings.z_range[0], self.axis_settings.z_range[1]) if self.dimensions == '2': point_obj.location = (x_norm, 0.0, z_norm) else: y_norm = normalize_value(entry[1], self.axis_settings.y_range[0], self.axis_settings.y_range[1]) point_obj.location = (x_norm, y_norm, z_norm) point_obj.parent = self.container_object if self.anim_settings.animate and self.dm.tail_length != 0: frame_n = context.scene.frame_current point_obj.keyframe_insert(data_path='location', frame=frame_n) dif = 2 if self.dimensions == '2' else 1 for j in range(value_index + 1, value_index + self.dm.tail_length + dif): frame_n += self.anim_settings.key_spacing zn_norm = normalize_value(self.data[i][j], self.axis_settings.z_range[0], self.axis_settings.z_range[1]) point_obj.location[2] = zn_norm point_obj.keyframe_insert(data_path='location', frame=frame_n) if self.axis_settings.create: AxisFactory.create(self.container_object, self.axis_settings, self.chart_id, int(self.dimensions), labels=self.labels) if self.header_settings.create: self.create_header() self.select_container() return {'FINISHED'}
def execute(self, context): self.init_data() tick_labels = [] if self.dm.predicted_data_type == DataType.Categorical and self.data_type_as_enum( ) == DataType.Numerical: self.report({'ERROR'}, 'Cannot convert categorical data into numerical!') return {'CANCELLED'} if self.dm.override(self.data_type_as_enum(), int(self.dimensions)): self.init_ranges() self.create_container() color_factory = ColoringFactory( self.get_name(), self.color_settings.color_shade, ColorType.str_to_type(self.color_settings.color_type), self.color_settings.use_shader) color_gen = color_factory.create(self.axis_settings.z_range, 2.0, self.container_object.location[2]) if self.dimensions == '2': value_index = 1 else: value_index = 2 for i, entry in enumerate(self.data): if not self.in_axis_range_bounds_new(entry): continue if self.use_obj == 'Bar' or (self.use_obj == 'Custom' and self.custom_obj_name == ''): bpy.ops.mesh.primitive_cube_add() bar_obj = context.active_object elif self.use_obj == 'Cylinder': bpy.ops.mesh.primitive_cylinder_add(vertices=16) bar_obj = context.active_object elif self.use_obj == 'Custom': if self.custom_obj_name not in bpy.data.objects: self.report( {'ERROR'}, 'Selected object is part of the chart or is deleted!') return {'CANCELLED'} src_obj = bpy.data.objects[self.custom_obj_name] bar_obj = src_obj.copy() bar_obj.data = src_obj.data.copy() context.collection.objects.link(bar_obj) if self.data_type_as_enum() == DataType.Numerical: x_value = entry[0] else: tick_labels.append(entry[0]) x_value = i x_norm = normalize_value(x_value, self.axis_settings.x_range[0], self.axis_settings.x_range[1]) z_norm = normalize_value(entry[value_index], self.axis_settings.z_range[0], self.axis_settings.z_range[1]) if z_norm >= 0.0 and z_norm <= 0.0005: z_norm = 0.0005 if self.dimensions == '2': bar_obj.scale = (self.bar_size[0], self.bar_size[1], z_norm * 0.5) bar_obj.location = (x_norm, 0.0, z_norm * 0.5) else: y_norm = normalize_value(entry[1], self.axis_settings.y_range[0], self.axis_settings.y_range[1]) bar_obj.scale = (self.bar_size[0], self.bar_size[1], z_norm * 0.5) bar_obj.location = (x_norm, y_norm, z_norm * 0.5) mat = color_gen.get_material(entry[value_index]) bar_obj.data.materials.append(mat) bar_obj.active_material = mat bar_obj.parent = self.container_object if self.anim_settings.animate and self.dm.tail_length != 0: frame_n = context.scene.frame_current bar_obj.keyframe_insert(data_path='location', frame=frame_n) bar_obj.keyframe_insert(data_path='scale', frame=frame_n) dif = 2 if self.dimensions == '2' else 1 for j in range(value_index + 1, value_index + self.dm.tail_length + dif): frame_n += self.anim_settings.key_spacing zn_norm = normalize_value(self.data[i][j], self.axis_settings.z_range[0], self.axis_settings.z_range[1]) if zn_norm >= 0.0 and zn_norm <= 0.0005: zn_norm = 0.0005 bar_obj.scale[2] = zn_norm * 0.5 bar_obj.location[2] = zn_norm * 0.5 bar_obj.keyframe_insert(data_path='location', frame=frame_n) bar_obj.keyframe_insert(data_path='scale', frame=frame_n) if self.axis_settings.create: AxisFactory.create( self.container_object, self.axis_settings, int(self.dimensions), self.chart_id, labels=self.labels, tick_labels=(tick_labels, [], []), ) if self.header_settings.create: self.create_header() self.select_container() return {'FINISHED'}
def execute(self, context): self.init_data() self.create_container() x = np.linspace(self.axis_settings.x_range[0], self.axis_settings.x_range[1], self.density) y = np.linspace(self.axis_settings.x_range[0], self.axis_settings.y_range[1], self.density) X, Y = np.meshgrid(x, y) px = [entry[0] for entry in self.data] py = [entry[1] for entry in self.data] f = [entry[2] for entry in self.data] rbfi = interpolate.Rbf(px, py, f, function=self.rbf_function) res = rbfi(X, Y) faces = [] verts = [] for row in range(self.density): for col in range(self.density): x_norm = row / self.density y_norm = col / self.density z_norm = normalize_value(res[row][col], self.axis_settings.z_range[0], self.axis_settings.z_range[1]) verts.append((x_norm, y_norm, z_norm)) if row < self.density - 1 and col < self.density - 1: fac = self.face(col, row) faces.append(fac) mesh = bpy.data.meshes.new('DV_SurfaceChart_Mesh') mesh.from_pydata(verts, [], faces) obj = bpy.data.objects.new('SurfaceChart_Mesh_Obj', mesh) bpy.context.scene.collection.objects.link(obj) obj.parent = self.container_object mat = NodeShader(self.get_name(), self.color_shade, location_z=self.container_object.location[2]).create_geometry_shader() obj.data.materials.append(mat) obj.active_material = mat if self.anim_settings.animate: verts = obj.data.vertices sk_basis = obj.shape_key_add(name='Basis') frame_n = context.scene.frame_current sk_basis.keyframe_insert(data_path='value', frame=frame_n) start_idx = 3 # cause of 3 dimensions supported and already parsed # Create shape keys for n in range(start_idx, start_idx + self.dm.tail_length): f = [entry[n] for entry in self.data] rbfi = interpolate.Rbf(px, py, f, function=self.rbf_function) res = rbfi(X, Y) sk = obj.shape_key_add(name='Column: ' + str(n)) for i in range(len(verts)): z_norm = normalize_value(res[i % self.density][i // self.density], self.axis_settings.z_range[0], self.axis_settings.z_range[1]) sk.data[i].co.z = z_norm sk.value = 0 # add animation for sk in obj.data.shape_keys.key_blocks: frame_n += self.anim_settings.key_spacing sk.value = 1 sk.keyframe_insert(data_path='value', frame=frame_n) for sko in obj.data.shape_keys.key_blocks: if sko != sk: sko.value = 0 sko.keyframe_insert(data_path='value', frame=frame_n) if self.axis_settings.create: AxisFactory.create( self.container_object, self.axis_settings, 3, self.chart_id, labels=self.labels, ) if self.header_settings.create: self.create_header() self.select_container() return {'FINISHED'}