def __init__(self, tr_log, pieces, args):
        visualizer.Visualizer.__init__(self, args)
        AncestryPlotter.__init__(self, tr_log.total_file_size(), tr_log.lastchunktime(), args)

        self._remaining_pieces = copy.copy(pieces)
        self._completion_time = None
        self._line_onset_time = {}

        if args.node_style == CIRCLE:
            self._node_plot_method = self._draw_node_circle
            self._nodes = {}
        else:
            self._node_plot_method = None

        if args.node_size_envelope:
            self._node_size_envelope = AdsrEnvelope.from_string(args.node_size_envelope)
        else:
            self._node_size_envelope = None

        if args.root_node_size_envelope:
            self._root_node_size_envelope = AdsrEnvelope.from_string(args.root_node_size_envelope)
        else:
            self._root_node_size_envelope = self._node_size_envelope

        if args.sway_envelope:
            self._sway_envelope = AdsrEnvelope.from_string(args.sway_envelope)
        else:
            self._sway_envelope = None

        if args.prune_envelope:
            self._prune_envelope = AdsrEnvelope.from_string(args.prune_envelope)
    def __init__(self, tr_log, pieces, args):
        visualizer.Visualizer.__init__(self, args)
        AncestryPlotter.__init__(self, tr_log.total_file_size(), tr_log.lastchunktime(), args)

        if args.unfold == BACKWARD:
            for piece in pieces:
                self.add_piece(piece["id"], piece["t"], piece["begin"], piece["end"])
        elif args.unfold == FORWARD:
            self._remaining_pieces = copy.copy(pieces)

        self._autozoom = (args.geometry == CIRCLE and self.args.autozoom)
        if self._autozoom:
            self._max_pxy = 0
            self._zoom_smoother = Smoother()

        if args.node_style == CIRCLE:
            self._node_plot_method = self._draw_node_circle
            self._nodes = {}
        else:
            self._node_plot_method = None

        if args.node_size_envelope:
            attack, decay, sustain = args.node_size_envelope.split(",")
            self._node_size_envelope = AdsrEnvelope(
                attack, decay, sustain, args.node_size_envelope_slope)
        else:
            self._node_size_envelope = None

        if args.sway_envelope:
            attack, decay, sustain = args.sway_envelope.split(",")
            self._sway_envelope = AdsrEnvelope(attack, decay, sustain)
        else:
            self._sway_envelope = None
示例#3
0
 def test_attack_and_decay(self):
     env = AdsrEnvelope(attack=1, decay=3, sustain=0.5)
     self.assertAlmostEquals(0.0,  env.value(0.0))
     self.assertAlmostEquals(0.5,  env.value(0.5))
     self.assertAlmostEquals(1.0,  env.value(1.0))
     self.assertAlmostEquals(0.75, env.value(2.5))
     self.assertAlmostEquals(0.5,  env.value(4.0))
     self.assertAlmostEquals(0.5,  env.value(4.5))
     self.assertAlmostEquals(0.5,  env.value(10))
示例#4
0
 def test_default_is_constant_at_1(self):
     env = AdsrEnvelope()
     self.assertAlmostEquals(1.0, env.value(0.0))
     self.assertAlmostEquals(1.0, env.value(10.0))
     self.assertAlmostEquals(1.0, env.value(100.0))
示例#5
0
 def test_attack_and_stay_at_1(self):
     env = AdsrEnvelope(attack=3, decay=0, sustain=1)
     self.assertAlmostEquals(0.0, env.value(0.0))
     self.assertAlmostEquals(0.5, env.value(1.5))
     self.assertAlmostEquals(1.0, env.value(3.0))
     self.assertAlmostEquals(1.0, env.value(10.0))
示例#6
0
 def test_decay_to_0(self):
     env = AdsrEnvelope(attack=0, decay=3, sustain=0)
     self.assertAlmostEquals(1.0, env.value(0.0))
     self.assertAlmostEquals(0.5, env.value(1.5))
     self.assertAlmostEquals(0.0, env.value(3.0))
     self.assertAlmostEquals(0.0, env.value(10.0))
class Ancestry(visualizer.Visualizer, AncestryPlotter):
    def __init__(self, tr_log, pieces, args):
        visualizer.Visualizer.__init__(self, args)
        AncestryPlotter.__init__(self, tr_log.total_file_size(), tr_log.lastchunktime(), args)

        if args.unfold == BACKWARD:
            for piece in pieces:
                self.add_piece(piece["id"], piece["t"], piece["begin"], piece["end"])
        elif args.unfold == FORWARD:
            self._remaining_pieces = copy.copy(pieces)

        self._autozoom = (args.geometry == CIRCLE and self.args.autozoom)
        if self._autozoom:
            self._max_pxy = 0
            self._zoom_smoother = Smoother()

        if args.node_style == CIRCLE:
            self._node_plot_method = self._draw_node_circle
            self._nodes = {}
        else:
            self._node_plot_method = None

        if args.node_size_envelope:
            attack, decay, sustain = args.node_size_envelope.split(",")
            self._node_size_envelope = AdsrEnvelope(
                attack, decay, sustain, args.node_size_envelope_slope)
        else:
            self._node_size_envelope = None

        if args.sway_envelope:
            attack, decay, sustain = args.sway_envelope.split(",")
            self._sway_envelope = AdsrEnvelope(attack, decay, sustain)
        else:
            self._sway_envelope = None


    @staticmethod
    def add_parser_arguments(parser):
        AncestryPlotter.add_parser_arguments(parser)
        visualizer.Visualizer.add_parser_arguments(parser)
        parser.add_argument("-z", dest="timefactor", type=float, default=1.0)

    def InitGL(self):
        visualizer.Visualizer.InitGL(self)
        glClearColor(0.0, 0.0, 0.0, 0.0)

        if self.args.node_style == CIRCLE:
            self._node_circle_lists = []
            for n in range(0, NODE_SIZE_PRECISION):
                display_list = self.new_display_list_id()
                self._node_circle_lists.append(display_list)
                glNewList(display_list, GL_COMPILE)
                self._render_node_circle(0, 0, n)
                glEndList()

    def ReSizeGLScene(self, width, height):
        visualizer.Visualizer.ReSizeGLScene(self, width, height)
        self._size = min(width, height) - 2*MARGIN
        AncestryPlotter.set_size(self, self._size, self._size)

    def render(self):
        glTranslatef(MARGIN + (self.width - self._size)/2, MARGIN, 0)
        glLineWidth(self.args.line_width)
        glEnable(GL_LINE_SMOOTH)
        glHint(GL_LINE_SMOOTH_HINT, GL_NICEST)
        glEnable(GL_BLEND)
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
        glColor3f(1,1,1)

        if self.args.unfold == BACKWARD:
            self._cursor_t = self._duration - self._adjusted_current_time() % self._duration
        elif self.args.unfold == FORWARD:
            if self.args.ff:
                self._add_oldest_remaining_piece()
            else:
                while (len(self._remaining_pieces) > 0 and
                       self._remaining_pieces[0]["t"] <= self._adjusted_current_time()):
                    self._add_oldest_remaining_piece()

        if self._autozoom:
            self._zoom = self._zoom_smoother.value()
            if self._zoom is None:
                self._zoom = 0.0
        else:
            self._zoom = 1.0

        self.plot()

        if self._autozoom:
            if self._max_pxy == 0:
                zoom = 0.5
            else:
                zoom = 0.5 + self._cursor_t/self._duration * 0.5 / self._max_pxy
            self._zoom_smoother.smooth(zoom, self.time_increment)

    def _add_oldest_remaining_piece(self):
        piece = self._remaining_pieces.pop(0)
        self.add_piece(piece["id"], piece["t"], piece["begin"], piece["end"])

    def finished(self):
        return self.current_time() > (self._duration / self.args.timefactor + SUSTAIN_TIME)

    def _adjusted_current_time(self):
        return self.current_time() * self.args.timefactor

    def _follow_piece(self, piece, child=None):
        self._update_and_draw_node(piece, piece.t, (piece.begin + piece.end) / 2)

        if len(piece.growth) > 0:
            path = [(piece.t,
                    (piece.begin + piece.end) / 2)]
            for older_version in reversed(piece.growth):
                if self.args.unfold == FORWARD or self._cursor_t < older_version.t:
                    path.append((older_version.t,
                                 (older_version.begin + older_version.end) / 2))
            self.draw_path(piece, path)
            self._update_and_draw_node(piece, path[-1][0], path[-1][1])

        for parent in piece.parents.values():
            if self.args.unfold == FORWARD or self._cursor_t < parent.t:
                self._connect_generations(parent, piece, child)
                self._follow_piece(parent, piece)
            else:
                if self.args.unfold == BACKWARD:
                    t = self._cursor_t - pow(self._cursor_t - parent.t, 0.7)
                else:
                    t = self._cursor_t
                self._connect_generations(parent, piece, child, t)
                self._update_and_draw_node(parent, t, (parent.begin + parent.end) / 2)

    def _rect_position(self, t, byte_pos):
        x = float(byte_pos) / self._total_size * self._width
        y = (1 - t / self._duration) * self._height
        return Vector2d(x, y)

    def _circle_position(self, t, byte_pos):
        angle = float(byte_pos) / self._total_size * 2*math.pi
        rel_t = 1 - t / self._duration
        px = rel_t * math.cos(angle)
        py = rel_t * math.sin(angle)
        x = self._width / 2 + (px * self._zoom) * self._width / 2
        y = self._height / 2 + (py * self._zoom) * self._height / 2
        if self._autozoom:
            self._max_pxy = max([self._max_pxy, abs(px), abs(py)])
        return Vector2d(x, y)

    def draw_path(self, piece, points):
        if self.args.sway:
            piece_sway_magnitude = self._sway_magnitude(piece)
        glBegin(GL_LINE_STRIP)
        n = 0
        for (t, b) in points:
            x, y = self._position(t, b)
            if self.args.sway:
                magnitude = (1 - float(n) / len(points)) * piece_sway_magnitude
                x += piece.sway.sway.x * magnitude * self._size
                y += piece.sway.sway.y * magnitude * self._size
                n += 1
            glVertex2f(x, y)
        glEnd()

    def draw_curve(self, x1, y1, x2, y2):
        control_points = [
            Vector2d(x1, y1),
            Vector2d(x1 + (x2 - x1) * 0.3, y1),
            Vector2d(x1 + (x2 - x1) * 0.7, y2),
            Vector2d(x2, y2)
            ]
        bezier = make_bezier([(p.x, p.y) for p in control_points])
        points = bezier(CURVE_PRECISION)
        glBegin(GL_LINE_STRIP)
        for x, y in points:
            glVertex2f(x, y)
        glEnd()

    def draw_line(self, x1, y1, x2, y2):
        glBegin(GL_LINES)
        glVertex2f(x1, y1)
        glVertex2f(x2, y2)
        glEnd()

    def _update_and_draw_node(self, piece, t, b):
        if self.args.sway:
            self._update_sway(piece)
        if self._node_plot_method:
            self._node_plot_method(piece, t, b)

    def _update_sway(self, piece):
        if not hasattr(piece, "sway"):
            piece.sway = Sway(self.args.sway_magnitude)
        piece.sway.update(self.time_increment)

    def _draw_node_circle(self, piece, t, b):
        age = self._age(piece)
        size = self._node_size(age)
        cx, cy = self._position(t, b)
        if self.args.sway:
            piece_sway_magnitude = self._sway_magnitude(piece)
            cx += piece.sway.sway.x * piece_sway_magnitude * self._size
            cy += piece.sway.sway.y * piece_sway_magnitude * self._size
        glPushMatrix()
        glTranslatef(cx, cy, 0)
        glCallList(self._node_circle_lists[size])
        glPopMatrix()

    def _age(self, piece):
        try:
            appearance_time = piece.appearance_time
        except AttributeError:
            appearance_time = piece.appearance_time = self._adjusted_current_time()
        return self._adjusted_current_time() - appearance_time

    def _node_size(self, age):
        if self._node_size_envelope:
            return int(self._node_size_envelope.value(age) * (NODE_SIZE_PRECISION-1))
        else:
            return NODE_SIZE_PRECISION-1

    def _sway_magnitude(self, piece):
        age = self._age(piece)
        if self._sway_envelope:
            return self._sway_envelope.value(age)
        else:
            return 1

    def _render_node_circle(self, cx, cy, size):
        # glColor3f(0,0,0)
        # self._render_filled_circle(cx, cy, size)
        # glColor3f(1,1,1)
        # self._render_circle_outline(cx, cy, size)

        # glColor3f(1,1,1)
        # self._render_filled_circle(cx, cy, size)

        glColor3f(1,1,1)
        glEnable(GL_POINT_SMOOTH)
        radius = max(self.args.node_size * self.width * size / (NODE_SIZE_PRECISION-1), 0.1)
        glPointSize(radius * 2)
        glBegin(GL_POINTS)
        glVertex2f(cx, cy)
        glEnd()

    def _render_filled_circle(self, cx, cy, size):
        glBegin(GL_TRIANGLE_FAN)
        glVertex2f(cx, cy)
        angle = 0
        radius = self.args.node_size * self.width * size / (NODE_SIZE_PRECISION-1)
        while angle < 2*math.pi:
            x = cx + math.cos(angle) * radius
            y = cy + math.sin(angle) * radius
            glVertex2f(x, y)
            angle += 0.1
        x = cx + math.cos(0) * radius
        y = cy + math.sin(0) * radius
        glVertex2f(x, y)
        glEnd()

    def _render_circle_outline(self, cx, cy, size):
        glBegin(GL_LINE_STRIP)
        angle = 0
        radius = self.args.node_size * self.width * size / (NODE_SIZE_PRECISION-1)
        while angle < 2*math.pi:
            x = cx + math.cos(angle) * radius
            y = cy + math.sin(angle) * radius
            glVertex2f(x, y)
            angle += 0.1
        glEnd()