def draw_point(self, event, x, y, flags, param):

        #global point, drawing, pointContainer, radius, plot

        if event == cv2.EVENT_LBUTTONDOWN:
            # set drawing mode
            self.drawing = True

            # create point and point container to append them to history for memento design pattern
            self.point = Point(x, y, self.radius)
            self.pointContainer.points.append(self.point)
            self.plot.history.append(copy.deepcopy(self.pointContainer))

        elif event == cv2.EVENT_MOUSEMOVE:

            if self.drawing == True:
                self.point = Point(x, y, self.radius)
                self.pointContainer.points.append(self.point)
                self.plot.history.append(copy.deepcopy(self.pointContainer))
                self.draw_circle(self.point.x, self.point.y)

        elif event == cv2.EVENT_MOUSEWHEEL:

            if flags > 0:
                self.radius += 2
            else:
                # prevent issues with < 0
                if self.radius > 5:
                    self.radius -= 2

        elif event == cv2.EVENT_LBUTTONUP:
            self.drawing = False
Esempio n. 2
0
    def test_moving(self):
        project = CADProject()

        # Add figures
        point1 = Point((1, 1))
        point1_name = project.add_figure(point1)
        point2 = Point((5, 6))
        point2_name = project.add_figure(point2)
        segment1 = Segment((0, 0), 0, 10)
        segment1_name = project.add_figure(segment1)

        # Move point to (3, 4)
        bb = choose_best_bindings(project.bindings, 1.1, 1)[0]
        project.move_figure(bb, 3, 4)
        correct_figures = {
            point1_name: (3, 4),
            point2_name: (5, 6),
            segment1_name: (0, 0, 10, 0),
        }
        assert self._is_figures_correct(project.figures, correct_figures)
        project.commit()

        # Move segment end to (7, 7)
        bb = choose_best_bindings(project.bindings, 10, 0)[0]
        project.move_figure(bb, 7, 7)
        correct_figures = {
            point1_name: (3, 4),
            point2_name: (5, 6),
            segment1_name: (0, 0, 7, 7),
        }
        assert self._is_figures_correct(project.figures, correct_figures)
        project.commit()
Esempio n. 3
0
    def controller_add_point(self, cmd):
        self._logger.debug(f'controller_add_point start with status {cmd}')

        if cmd == ControllerCmd.SUBMIT:
            figure_coo = self._created_figure.get_base_representation()
            self._project.add_figure(Point.from_coordinates(*figure_coo))
            self.reset()

            self.controller_add_point(ControllerCmd.SHOW)

        elif cmd == ControllerCmd.SHOW:
            if self.action_st == ActionSt.NOTHING:
                self._reset_behind_statuses()
                self.controller_st = ControllerSt.ADD_POINT
                self.creation_st = CreationSt.POINT_SET
                self._created_figure = Point.from_coordinates(
                    self.field_x_add_point.value(),
                    self.field_y_add_point.value(),
                )
                self.button_add_point.setChecked(True)

            self.widget_add_point.show()
            self.field_x_add_point.setFocus()
            self.field_x_add_point.selectAll()

        elif cmd == ControllerCmd.HIDE:
            self.reset()

        self.update()
Esempio n. 4
0
    def test_save_and_load(self):
        project1 = CADProject()

        # Add figures
        point1 = Point((1, 2))
        point1_name = project1.add_figure(point1, 'p1')
        assert point1_name in project1.figures

        # Save
        filename = 'test_save_and_load.scad'
        project1.save(filename)

        # Load 1
        project2 = CADProject()
        project2.load(filename)
        assert point1_name in project2.figures

        # One more project
        project3 = CADProject()
        point2 = Point((0, 0))
        point2_name = project3.add_figure(point2, 'p2')
        assert point2_name in project3.figures
        assert point1_name not in project3.figures

        project3.load(filename)
        assert point2_name not in project3.figures
        assert point1_name in project3.figures

        os.remove(filename)
Esempio n. 5
0
    def test_choosing_best_bindings(self):
        figures = {
            'point1': Point((1, 1)),
            'point2': Point((2, 3)),
            'segment1': Segment((0, 0), 0, 7),
            'segment2': Segment.from_coordinates(3, 8, 7, 4),
            'segment3': Segment((5, 5), np.pi / 2, 5),
        }

        bindings = create_bindings(
            figures, circle_bindings_radius=0.5, segment_bindings_margin=0.2
        )

        def get_binding(figure_names, binding_type, spot_type=None):
            for binding in bindings:
                objects_names = binding.get_object_names()
                if is_sequences_equal(
                    figure_names, objects_names
                ) and isinstance(binding, binding_type):
                    if (
                        binding_type != SegmentSpotBinding
                        or binding.spot_type == spot_type
                    ):
                        return binding

        figures['point2'].set_param('x', 3).set_param('y', 8)

        # No bindings
        bb = choose_best_bindings(bindings, 10, 10)
        assert is_sequences_equal(bb, [])

        # Just point
        bb = choose_best_bindings(bindings, 1.1, 1.1)
        point1_b = get_binding(['point1'], PointBinding)
        assert is_sequences_equal(bb, [point1_b], use='is')

        # Full segment
        bb = choose_best_bindings(bindings, 3, 0.15)
        segment1_full_b = get_binding(['segment1'], FullSegmentBinding)
        assert is_sequences_equal(bb, [segment1_full_b], use='is')

        # Segment center beat full segment
        bb = choose_best_bindings(bindings, 3.5, 0.15)
        segment1_center_b = get_binding(
            ['segment1'], SegmentSpotBinding, 'center'
        )
        # No full binding!
        assert is_sequences_equal(bb, [segment1_center_b], use='is')

        # To points with same coordinates
        bb = choose_best_bindings(bindings, 2.9, 7.9)
        s2_start_b = get_binding(['segment2'], SegmentSpotBinding, 'start')
        point2_b = get_binding(['point2'], PointBinding)
        answer_v1 = [s2_start_b, point2_b]
        answer_v2 = [point2_b, s2_start_b]
        assert is_sequences_equal(
            bb, answer_v1, use='is', sort=False
        ) or is_sequences_equal(bb, answer_v2, use='is', sort=False)
Esempio n. 6
0
    def test_diffrent_color_place(self):
        p = Point.parse({
            'x': 10,
            'y': 2,
            'color': 'cos'
        }, {'cos': "#123456"}, Color("#990011"))
        self.assertEqual(p.color, Color("#123456"))

        p = Point.parse({'x': 10, 'y': 2}, {'cos': "123456"}, Color("#123456"))
        self.assertEqual(p.color, Color("#123456"))
Esempio n. 7
0
    def test_undo_redo_commit_rollback(self):
        project = CADProject()

        with pytest.raises(ActionImpossible):
            project.undo()

        # Add figures
        point1 = Point((1, 2))
        _ = project.add_figure(point1)
        point2 = Point((5, 6))
        point2_name = project.add_figure(point2)

        # Undo, redo, _commit inside
        with pytest.raises(ActionImpossible):
            project.redo()

        project.undo()
        assert point2_name not in project.figures
        project.redo()
        assert point2_name in project.figures

        project.undo()
        assert point2_name not in project.figures
        segment1 = Segment((0, 0), 0, 10)
        segment1_name = project.add_figure(segment1)
        with pytest.raises(ActionImpossible):
            project.redo()

        project.undo()
        assert segment1_name not in project.figures
        project.undo()
        assert not project.figures
        assert not project.bindings
        with pytest.raises(ActionImpossible):
            project.undo()

        # Commit & rollback
        point3 = Point((1, 1))
        point3_name = project.add_figure(point3)
        bb = choose_best_bindings(project.bindings, 1, 1)[0]
        project.move_figure(bb, 5, 5)
        assert project.figures[point3_name].get_params()['x'] == 5
        project.commit()
        assert project.figures[point3_name].get_params()['x'] == 5

        bb = choose_best_bindings(project.bindings, 5, 5)[0]
        project.move_figure(bb, 7, 7)
        assert project.figures[point3_name].get_params()['x'] == 7
        project.rollback()
        assert project.figures[point3_name].get_params()['x'] == 5
        project.rollback()
        assert project.figures[point3_name].get_params()['x'] == 5
Esempio n. 8
0
    def test_complex(self):
        project = CADProject()

        # Add figures
        point1 = Point((1, 2))
        point1_name = project.add_figure(point1)
        point2 = Point((5, 6))
        point2_name = project.add_figure(point2)
        segment1 = Segment.from_coordinates(0, 0, 10, 1)
        segment1_name = project.add_figure(segment1)

        # Fix point1
        r = PointFixed(1, 2)
        _ = project.add_restriction(r, (point1_name,))
        correct_figures = {
            point1_name: (1, 2),
            point2_name: (5, 6),
            segment1_name: (0, 0, 10, 1),
        }
        assert self._is_figures_correct(project.figures, correct_figures)

        # Join point1 and start of segment1
        r = PointAndSegmentSpotJoint(spot_type='start')
        _ = project.add_restriction(r, (point1_name, segment1_name))
        correct_figures = {
            point1_name: (1, 2),
            point2_name: (5, 6),
            segment1_name: (1, 2, 10, 1),
        }
        assert self._is_figures_correct(project.figures, correct_figures)

        # Move segment end
        bb = choose_best_bindings(project.bindings, 10, 0)[0]
        project.move_figure(bb, 12, 2)
        correct_figures = {
            point1_name: (1, 2),
            point2_name: (5, 6),
            segment1_name: (1, 2, 12, 2),  # Segment set. save length and angle
        }
        assert self._is_figures_correct(project.figures, correct_figures)
        project.commit()

        # Change length
        project.change_figure(segment1_name, 'length', 11)
        correct_figures = {
            point1_name: (1, 2),
            point2_name: (5, 6),
            segment1_name: (1, 2, 12, 2),
        }
        assert self._is_figures_correct(project.figures, correct_figures)
 def __init__(self):
     self.point = Point(0, 0, 0)
     self.drawing = False
     self.pointContainer = PointContainerMemento()
     self.radius = 10
     self.plot = PlotHistory()
     self.img = np.zeros((384, 384, 3), np.uint8)
Esempio n. 10
0
 def test_parse(self):
     p = Point.parse({
         'x': 10,
         'y': 2,
         'color': '(255, 0, 255)'
     }, {}, Color("#990011"))
     self.assertEqual(p.x, 10)
     self.assertEqual(p.y, 2)
     self.assertEqual(p.color, Color("#ff00ff"))
Esempio n. 11
0
    def test_changing_parameters(self):
        project = CADProject()

        # Add figures
        point1 = Point((1, 1))
        point1_name = project.add_figure(point1)
        point2 = Point((5, 6))
        point2_name = project.add_figure(point2)
        segment1 = Segment((0, 0), 0, 10)
        segment1_name = project.add_figure(segment1)

        project.change_figure(point1_name, 'y', 2)
        correct_figures = {
            point1_name: (1, 2),
            point2_name: (5, 6),
            segment1_name: (0, 0, 10, 0),
        }
        assert self._is_figures_correct(project.figures, correct_figures)

        new_len = 7
        project.change_figure(segment1_name, 'length', new_len)
        answer_1 = {
            point1_name: (1, 2),
            point2_name: (5, 6),
            segment1_name: ((10 - new_len) / 2, 0, 10 - (10 - new_len) / 2, 0),
        }
        answer_2 = {
            point1_name: (1, 2),
            point2_name: (5, 6),
            segment1_name: (0, 0, new_len, 0),
        }
        answer_3 = {
            point1_name: (1, 2),
            point2_name: (5, 6),
            segment1_name: (10 - new_len, 0, 10, 0),
        }
        assert (
            self._is_figures_correct(project.figures, answer_1)
            or self._is_figures_correct(project.figures, answer_2)
            or self._is_figures_correct(project.figures, answer_3)
        )
Esempio n. 12
0
    def test_addition_and_deletion_figures(self):
        project = CADProject()

        # Add figures
        point1 = Point((1, 2))
        point1_name = project.add_figure(point1)
        correct_types = {point1_name: Point}
        assert check_objects_types(project.figures, correct_types)

        point2 = Point((5, 6))
        point2_name = project.add_figure(point2)
        correct_types = {point1_name: Point, point2_name: Point}
        assert check_objects_types(project.figures, correct_types)

        segment1 = Segment((0, 0), 0, 10)
        segment1_name = project.add_figure(segment1)
        correct_types = {
            point1_name: Point,
            point2_name: Point,
            segment1_name: Segment,
        }
        assert check_objects_types(project.figures, correct_types)

        # Remove figures
        project.remove_figure(point2_name)
        correct_types = {point1_name: Point, segment1_name: Segment}
        assert check_objects_types(project.figures, correct_types)

        with pytest.raises(IncorrectParamValue):
            project.remove_figure(point2_name)

        project.remove_figure(segment1_name)
        correct_types = {point1_name: Point}
        assert check_objects_types(project.figures, correct_types)

        project.remove_figure(point1_name)
        correct_types = {}
        assert check_objects_types(project.figures, correct_types)
Esempio n. 13
0
def load_figures(json_figures):
    figs = []
    for fig in json_figures:
        t = fig['type']
        if t == "point":
            figs.append(Point(int(fig['x']), int(fig['y'])))
        elif t == "polygon":
            figs.append(Polygon(fig['points']))
        elif t == "rectangle":
            figs.append(
                Rectangle(int(fig['x']), int(fig['y']), int(fig['width']),
                          int(fig['height'])))
        elif t == "square":
            figs.append(Square(int(fig['x']), int(fig['y']), int(fig['size'])))
        elif t == "circle":
            figs.append(
                Circle(int(fig['x']), int(fig['y']), int(fig['radius'])))
        if "color" in fig:
            figs[-1].color = fig['color']
    return figs
Esempio n. 14
0
    def handle_all(self, event):
        """
        En mode point on s'interesse aux clics gauches de souris et on dessine un point
        """
        handled = self.handle(event)

        # commun a tous les handler qui verifie si on change de mode ou on quitte
        if handled:
            return
        if event.type == pygame.MOUSEBUTTONDOWN:
            if event.dict["button"] != 1:
                return
            coord = event.dict["pos"]
            to_draw = Point(coord,
                            self.whiteboard.get_config(["active_color"]),
                            self.whiteboard.get_config(["font_size"]),
                            self.whiteboard.get_config(["toolbar_y"]))
            now = datetime.now()
            timestamp = datetime.timestamp(now)
            self.whiteboard.draw(to_draw, timestamp)
Esempio n. 15
0
    def test_errors(self):
        with self.assertRaises(ValueError):
            Point.parse({
                'x': 10,
                'color': '(255, 0, 255)'
            }, {}, Color("#990011"))
            Point.parse({
                'y': 2,
                'color': '(255, 0, 255)'
            }, {}, Color("#990011"))

        with self.assertRaises(TypeError):
            Point.parse({
                'x': 10,
                'y': "",
                'color': '(255, 0, 255)'
            }, {}, Color("#990011"))
            Point.parse({
                'x': {},
                'y': 2,
                'color': '(255, 0, 255)'
            }, {}, Color("#990011"))
Esempio n. 16
0
def scanline_fill(paint_area,
                  polygon,
                  painter=None,
                  color=Qt.black,
                  to_matrix=False):
    if not polygon.is_valid():
        raise Exception('多边形不合法,无法使用扫描线填充')

    area_width = paint_area.width()
    area_height = paint_area.height()
    area_xmin = 0
    area_ymin = 0
    area_xmax = area_width - 1
    area_ymax = area_height - 1

    if to_matrix:
        matrix = zeros((area_height, area_width), dtype=int)
    else:
        painter.setPen(color)

    for ynow in range(area_ymin, area_ymax + 1):
        xline = QLineF(area_xmin, ynow, area_xmax, ynow)

        # 求交点
        points = []
        sides = []
        similar_sides = []
        for index, side in enumerate(polygon.sides):
            if isclose(side.y1(), ynow) and isclose(side.y2(), ynow):  # 平行线段
                prev_index = index - 1
                next_index = index + 1 - len(polygon.sides)
                similar_sides.append((side, polygon.sides[prev_index],
                                      polygon.sides[next_index]))
                continue
            point = Point()
            intersect_type = side.intersect(xline, point)
            if intersect_type == QLineF.BoundedIntersection:  # 有交点
                points.append(point)
                sides.append(side)

        # 平行线段处理
        for side, prev_side, next_side in similar_sides:
            y0 = prev_side.y1()
            y3 = next_side.y2()
            # 异侧:丢弃一个交点
            if PLGFloat((y0 - ynow) * (y3 - ynow)) < PLGFloat(0):
                index = points.index(side.p2())
                points.pop(index)
                sides.pop(index)

        # 重复交点处理
        for point, count in count_list(points):
            if count == 1:
                continue
            elif count == 2:
                index1 = points.index(point)
                index2 = points.index(point, index1 + 1)
                side1 = sides[index1]
                side2 = sides[index2]
                if point in side1.points() and point in side2.points():  # 顶点
                    another_y1 = side1.get_another_vertice(point).y()
                    another_y2 = side2.get_another_vertice(point).y()
                    # 异侧:只留一个顶点
                    if PLGFloat((another_y1 - ynow) *
                                (another_y2 - ynow)) < PLGFloat(0):
                        points.pop(index2)
                        sides.pop(index2)
                else:  # 非顶点
                    pass
            else:
                raise Exception('交点个数不合法')

        # 交点排序、配对,线段涂色
        points = sorted(points, key=lambda p: p.x())
        for i in range(0, len(points), 2):
            try:
                x1 = round(points[i].x())
                x2 = round(points[i + 1].x())
                if to_matrix:
                    matrix[ynow][x1:x2 + 1].fill(1)
                else:
                    painter.drawLine(x1, ynow, x2, ynow)
            except:
                pass

    # 再单独画一次边框
    for side in polygon.sides:
        x1 = round(side.x1())
        y1 = round(side.y1())
        x2 = round(side.x2())
        y2 = round(side.y2())
        if to_matrix:
            if y1 == y2:
                matrix[y1][x1:x2 + 1].fill(1)
        else:
            painter.drawLine(x1, y1, x2, y2)

    if to_matrix:
        return matrix
    else:
        return
Esempio n. 17
0
    def test_bindings_and_bindings_creation(self):
        figures = {
            'point1': Point((1, 1)),
            'point2': Point((2, 3)),
            'segment1': Segment((0, 0), 0, 7),
            'segment2': Segment.from_coordinates(3, 8, 7, 4),
            'segment3': Segment((5, 5), np.pi / 2, 5),
        }

        bindings = create_bindings(
            figures, circle_bindings_radius=0.5, segment_bindings_margin=0.2
        )

        correct_bindings_types = (
            [PointBinding] * 2
            + ([SegmentSpotBinding] * 3 + [FullSegmentBinding]) * 3
            + [SegmentsIntersectionBinding] * 3
        )

        assert is_sequences_equal(
            list(map(type, bindings)), correct_bindings_types, sort=False
        )

        def get_binding(figure_names, binding_type, spot_type=None):
            for binding in bindings:
                objects_names = binding.get_object_names()
                if is_sequences_equal(
                    figure_names, objects_names
                ) and isinstance(binding, binding_type):
                    if (
                        binding_type != SegmentSpotBinding
                        or binding.spot_type == spot_type
                    ):
                        return binding

        # Point1
        point1_b = get_binding(['point1'], PointBinding)
        assert point1_b.check(10, 10) is None
        assert isclose(point1_b.check(1.2, 1.2), 0.2 * 2 ** 0.5)
        assert all(isclose(point1_b.bind(), (1, 1)))

        figures['point1'].move(dy=2)
        assert point1_b.check(1.4, 3.4) is None
        assert all(isclose(point1_b.bind(), (1, 3)))

        # Segment1
        segment1_center_b = get_binding(
            ['segment1'], SegmentSpotBinding, 'center'
        )
        assert isclose(segment1_center_b.check(3.5, 0.1), 0.1)
        assert all(isclose(segment1_center_b.bind(), (3.5, 0)))

        segment1_full_b = get_binding(['segment1'], FullSegmentBinding)
        assert isclose(segment1_full_b.check(3, 0.15), 0.15)
        assert isclose(segment1_full_b.check(7.15, 0), 0.15)
        assert segment1_full_b.check(7.15, 0.15) is None
        assert all(isclose(segment1_full_b.bind(2.3, -0.7), (2.3, 0)))

        # Intersections
        s1_s2_b = get_binding(
            ['segment1', 'segment2'], SegmentsIntersectionBinding
        )
        assert all(isclose(s1_s2_b.bind(), (11, 0)))

        s1_s3_b = get_binding(
            ['segment1', 'segment3'], SegmentsIntersectionBinding
        )
        assert all(isclose(s1_s3_b.bind(), (5, 0)))

        s2_s3_b = get_binding(
            ['segment2', 'segment3'], SegmentsIntersectionBinding
        )
        assert all(isclose(s2_s3_b.bind(), (5, 6)))
Esempio n. 18
0
    def test_addition_and_deletion_restrictions(self):
        project = CADProject()

        # Add figures
        point1 = Point((1, 2))
        point1_name = project.add_figure(point1)
        point2 = Point((5, 6))
        point2_name = project.add_figure(point2)
        segment1 = Segment((0, 0), 0, 10)
        segment1_name = project.add_figure(segment1)

        # Fix point1
        r = PointFixed(1, 2)
        p1_fixed_name = project.add_restriction(r, (point1_name,))
        correct_types = {p1_fixed_name: PointFixed}
        assert check_objects_types(project.restrictions, correct_types)
        correct_figures = {
            point1_name: (1, 2),
            point2_name: (5, 6),
            segment1_name: (0, 0, 10, 0),
        }
        assert self._is_figures_correct(project.figures, correct_figures)

        # Join point1 and start of segment1
        r = PointAndSegmentSpotJoint(spot_type='start')
        p1_s1s_joint_name = project.add_restriction(
            r, (point1_name, segment1_name)
        )
        correct_types = {
            p1_fixed_name: PointFixed,
            p1_s1s_joint_name: PointAndSegmentSpotJoint,
        }
        assert check_objects_types(project.restrictions, correct_types)
        correct_figures = {
            point1_name: (1, 2),
            point2_name: (5, 6),
            segment1_name: (1, 2, 10, 0),  # Segment set. save length and angle
        }
        assert self._is_figures_correct(project.figures, correct_figures)

        # Fix end of segment1
        r = SegmentSpotFixed(1, 7, spot_type='end')
        s1e_fixed_name = project.add_restriction(r, (segment1_name,))
        correct_types = {
            p1_fixed_name: PointFixed,
            p1_s1s_joint_name: PointAndSegmentSpotJoint,
            s1e_fixed_name: SegmentSpotFixed,
        }
        assert check_objects_types(project.restrictions, correct_types)
        correct_figures = {
            point1_name: (1, 2),
            point2_name: (5, 6),
            segment1_name: (1, 2, 1, 7),
        }
        assert self._is_figures_correct(project.figures, correct_figures)

        # Remove fix end of segment1
        project.remove_restriction(s1e_fixed_name)
        correct_types = {
            p1_fixed_name: PointFixed,
            p1_s1s_joint_name: PointAndSegmentSpotJoint,
        }
        assert check_objects_types(project.restrictions, correct_types)
        correct_figures = {
            point1_name: (1, 2),
            point2_name: (5, 6),
            segment1_name: (1, 2, 1, 7),
        }
        assert self._is_figures_correct(project.figures, correct_figures)

        # Fix length of segment1
        r = SegmentLengthFixed(3)
        s1_fixed_length_name = project.add_restriction(r, (segment1_name,))
        correct_types = {
            p1_fixed_name: PointFixed,
            p1_s1s_joint_name: PointAndSegmentSpotJoint,
            s1_fixed_length_name: SegmentLengthFixed,
        }
        assert check_objects_types(project.restrictions, correct_types)
        correct_figures = {
            point1_name: (1, 2),
            point2_name: (5, 6),
            segment1_name: (1, 2, 1, 5),
        }
        assert self._is_figures_correct(project.figures, correct_figures)