Пример #1
0
    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'}
Пример #2
0
    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])
Пример #3
0
    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'}
Пример #4
0
    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'}
Пример #5
0
    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'}
Пример #6
0
    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'}