コード例 #1
0
ファイル: boardviewwidget.py プロジェクト: deactivated/pcbre
    def mouseMoveEvent(self, event):
        if self.lastPoint is None:
            self.lastPoint = event.pos()
            return

        delta_px = event.pos() - self.lastPoint
        lastpoint_real = self.viewState.tfV2P(Point2(self.lastPoint))
        newpoint_real = self.viewState.tfV2P(Point2(event.pos()))
        lx,ly = lastpoint_real
        nx,ny = newpoint_real
        delta = nx-lx, ny-ly

        self.lastPoint = event.pos()

        needs_update = False
        if (event.buttons() & MOVE_MOUSE_BUTTON) and self.move_dragging:
            self.move_dragged = True

            self.viewState.transform = M.translate(*delta).dot(self.viewState.transform)
            needs_update = True

        elif (event.buttons() & QtCore.Qt.MiddleButton):
            delta = -10 * delta_px.y()

            self.wheelEvent(QtGui.QWheelEvent(event.pos(),delta, event.buttons(), event.modifiers()))
            needs_update = True
        elif not self.move_dragging and not self.mwemu:
            if self.interactionDelegate is not None:
                self.interactionDelegate.mouseMoveEvent(event)
                needs_update = True

        if needs_update:
            self.update()
コード例 #2
0
ファイル: basicsmd.py プロジェクト: mrhlogic/pcbre
    def __update_matrix(self):
        rot = rotate(self.__theta)

        if self.side == SIDE.Top:
            sign = -1
        else:
            sign = 1

        self.matrix = translate(self.center.x, self.center.y).dot(rotate(self.__theta))
コード例 #3
0
ファイル: rectalign.py プロジェクト: deactivated/pcbre
    def render_handle(self, position, color, diagonal=False, filled=False):
        if diagonal:
            r = rotate(math.pi/4)
        else:
            r = numpy.identity(3)

        m = self.viewState.glWMatrix.dot(translate(*position).dot(r))
        GL.glUniformMatrix3fv(self.mat_loc, 1, True, m.astype(numpy.float32))
        GL.glUniform4f(self.col_loc, *color)
        GL.glDrawArrays(GL.GL_TRIANGLE_FAN if filled else GL.GL_LINE_LOOP, 0, 4)
コード例 #4
0
ファイル: keypointalign.py プロジェクト: 0nelight/pcbre
    def render(self, vs):
        self.vs = vs

        # Standard alpha-blending. We emit alpha=1 or alpha=0 (no real blending),
        # but the text rendering needs transparency for font rendering
        GL.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA)

        # transform from center of keypoint to edge-of-text
        tmove = translate(-self.d1 + 2, -self.d1 - 3).dot(scale(14, -14))

        count = len(self.model.kp.keypoints)
        for n, kp in enumerate(self.model.kp.keypoints):

            # In unaligned view mode we don't need to show any keypoints that aren't in use
            if self.model.view_mode == 0 and not kp.use:
                continue

            # Generate a number of colors, separated by as far in hue-space as possible
            color = colorsys.hsv_to_rgb(float(n) / count, 1,0.8) + (1,)

            # use colors based on current selection
            selected = n == self.model.kp.selected_idx
            frame_color = [1,1,1,1] if selected else color
            text_color = [0,0,0,1] if selected else [1,1,1,1]

            p = self.get_keypoint_viewport_center(kp)

            # Coordinates in view-space
            center_point = vs.glWMatrix.dot(translate(p.x, p.y))
            text_point = center_point.dot(tmove)

            with self.prog, self.handle_vao:
                GL.glUniformMatrix3fv(self.prog.uniforms.mat, 1, True, center_point.astype(numpy.float32))
                GL.glUniform4f(self.prog.uniforms.color, *frame_color)
                # Render the frame
                GL.glDrawArrays(GL.GL_LINES, 0, 12)

                # and the text flag background
                GL.glDrawArrays(GL.GL_TRIANGLE_STRIP, 12, 4)

            # Render the text for the flag
            s = self._parent.view.text_batch.get_string("%d" % (n+1))
            self._parent.view.text_batch.submit(s, text_point, text_color)
コード例 #5
0
ファイル: textrender.py プロジェクト: balr0g/pcbre
    def get_render_to_mat(self, rect):
        hscale = rect.width / self.__rect.width
        vscale = rect.height / self.__rect.height

        actual_scale = min(hscale, vscale)

        cx = self.__rect.center
        cx *= actual_scale

        return translate(rect.center.x - cx.x, rect.center.y - cx.y).dot(scale(actual_scale))
コード例 #6
0
ファイル: boardviewwidget.py プロジェクト: deactivated/pcbre
def fixed_center_dot(viewState, m, view_center=None):

    if view_center is None:
        view_center = Point2(viewState.width/2, viewState.height/2)

    world_center = viewState.tfV2W(view_center)

    proj_orig_center = projectPoint(viewState.transform, world_center)

    viewState.transform = viewState.transform.dot(m)

    proj_new_center = projectPoint(viewState.transform, world_center)

    dx = proj_new_center[0] - proj_orig_center[0]
    dy = proj_new_center[1] - proj_orig_center[1]

    viewState.transform = M.translate(-dx, -dy).dot(viewState.transform)
コード例 #7
0
ファイル: dip.py プロジェクト: mrhlogic/pcbre
    def update_matrix(self):

        rot = rotate(self.theta)

        if self.side == SIDE.Top:
            sign = -1
        else:
            sign = 1

        center_to_corner = Vec2(
            sign * self._model.pin_width / 2, self._model.pin_space * (self._model.pin_count / 2 - 1) / 2
        )

        center_to_corner_w = projectPoint(rot, center_to_corner)

        self.center = self.p1_point.get() - center_to_corner_w

        self.matrix = translate(self.center.x, self.center.y).dot(rotate(self.theta))
コード例 #8
0
ファイル: boardviewwidget.py プロジェクト: deactivated/pcbre
    def __init__(self, project):
        BaseViewWidget.__init__(self)
        self.project = project

        self.image_view_cache = { }

        self.pad_renderer = PadRender(self)
        self.dip_renderer = DIPRender(self)
        self.smd_renderer = SMDRender(self)
        self.trace_renderer = TraceRender(self)
        self.via_renderer = THRenderer(self)
        self.text_batch = TextBatcher(self.gls.text)
        self.poly_renderer = CachedPolygonRenderer(self)
        self.hairline_renderer = HairlineRenderer(self)
        self.passive_renderer = PassiveRender(self)

        # Initial view is a normalized 1-1-1 area.
        # Shift to be 10cm max
        self.viewState.transform = translate(-0.9, -0.9).dot(scale(1./100000))
コード例 #9
0
ファイル: pad.py プロジェクト: 0nelight/pcbre
    def __init__(self, parent, pad_no, rel_center, theta, w, l, th_diam=0, side=None):
        """
        :param parent: Parent
        :param rel_center:
        :type rel_center: Point2
        :param theta:
        :param w:
        :param l:
        :param r:
        :return:
        """
        self.parent = parent

        self.__rel_center = rel_center

        # Cached translation-only location matrix
        self.__translate_mat = translate(self.__rel_center.x, self.__rel_center.y)
        self.__theta = theta

        self.w = w
        self.l = l

        self.side = side

        # Throughhole diameter, 0 if not T/H
        self.th_diam = th_diam

        self.pad_no = pad_no

        if self.parent is not None:
            pmat = self.parent.matrix
        else:
            pmat = numpy.identity(3, dtype=numpy.float32)

        self.__pmat = pmat

        self.center = projectPoint(pmat, self.__rel_center)

        self.layer = self.parent._side_layer_oracle.stackup.layer_for_side(self.side)
コード例 #10
0
ファイル: rectalign.py プロジェクト: deactivated/pcbre
 def translate_matrix(self):
     pt = self.scale_matrix.dot(self.persp_matrix.dot(self.align_handles[self.origin_idx].homol()))
     pt /= pt[2]
     return translate(self.translate_x - pt[0], self.translate_y - pt[1])
コード例 #11
0
ファイル: keypointalign.py プロジェクト: 0nelight/pcbre
    def _image_transform_info(self):
        """
        Calculate the constraint level and the transform (if possible)
        :return: constraint_level, transform_matrix
        """
        relevant_keypoints = [i for i in self.keypoints if i.use]

        # Num keypoints = 0 - can't compute a transform
        if len(relevant_keypoints) == 0:
            return CONS_UNCONSTRAINED, numpy.identity(3)

        # Num keypoints = 1, just do a simple translate
        elif len(relevant_keypoints) == 1:
            kp = relevant_keypoints[0]

            # Pixel in worldspace
            layer_world = self.__image.p2n(kp.layer)

            # Just basic translation in worldspace
            vec = kp.world - layer_world
            return CONS_TRANSLATION, translate(vec.x, vec.y)

        # Calculate either translate-rotate, or translate-rotate-scale transforms
        elif len(relevant_keypoints) in (2,3):
            # Construct a system of equations to solve the positioning
            # Basic Ax = b, where x is the non-homologous terms of the translation matrix
            # 'A' is made from "rows"

            rows = []
            b = []

            # Add all of the keypoints as constraints
            for kp in relevant_keypoints:
                # normalized image / world coordinates for the keypoint
                lw = self.__image.p2n(kp.layer)
                w = kp.world

                #            a       b       c       d       e       f        #
                rows.append([lw.x,   lw.y,   1,      0,      0,      0,      ])
                rows.append([0,      0,      0,      lw.x,   lw.y,   1,      ])

                b.append(w.x)
                b.append(w.y)

            # If we only have two keypoints, constrain scale to equal on both axes
            if len(relevant_keypoints) == 2:
                rows.append([1,      0,      0,      0,      -1,     0       ])
                rows.append([0,      1,      0,      1,      0,      0       ])
                b.extend((0, 0))

            # Try to solve the system of equations
            a = numpy.vstack(rows)
            try:
                x = numpy.linalg.solve(a, b)

            except numpy.linalg.linalg.LinAlgError:
                # Cant solve, constructed matrix is singular
                return CONS_SINGULAR, numpy.identity(3)

            # Depending on the number of keypoints, we're either constrainted to translate/rotate/equal-scale
            # or full Orthogonal projection
            constraint = CONS_ORTHOGONAL
            if len(relevant_keypoints) == 2:
                constraint = CONS_ROTATE_SCALE

            return constraint, numpy.vstack((x.reshape(2, 3), (0,0,1)))

        elif len(relevant_keypoints) == 4:
            # Perspective transform
            # TODO: replace this with a LMS solver for overconstrained cases
            #       plus provide error estimations and visualize
            src = numpy.ones((4,2), dtype=numpy.float32)
            dst = numpy.ones((4,2), dtype=numpy.float32)
            src[:, :2] = [self.__image.p2n(kp.layer) for kp in relevant_keypoints]
            dst[:, :2] = [kp.world for kp in relevant_keypoints]

            return CONS_PERSPECTIVE, cv2.getPerspectiveTransform(src, dst)

        else:
            # Temporarily refuse to solve overconstrained alignments
            return CONS_OVERCONSTRAINED, numpy.identity(3)
コード例 #12
0
ファイル: pad.py プロジェクト: 0nelight/pcbre
 def __inv_p2p_mat(self):
     return translate(self.rel_center.x, self.rel_center.y).dot(rotate(self.theta))
コード例 #13
0
ファイル: pad.py プロジェクト: 0nelight/pcbre
 def __p2p_mat(self):
     return rotate(-self.theta).dot(translate(-self.rel_center.x, -self.rel_center.y))
コード例 #14
0
ファイル: component.py プロジェクト: 0nelight/pcbre
 def matrix(self):
     return translate(self.center.x, self.center.y).dot(rotate(self.theta).dot(cflip(self.side == SIDE.Bottom)))