def _placeDocs(self): """ Places documentation blocks on the documentation layer """ try: docs_dict = config.brd['documentation'] except: return for key in docs_dict: location = utils.toPoint(docs_dict[key]['location']) docs_dict[key]['location'] = [0, 0] shape_group = et.SubElement(self._layers['documentation']['layer'], 'g') shape_group.set('{'+config.cfg['ns']['pcbmode']+'}type', 'module-shapes') shape_group.set('{'+config.cfg['ns']['pcbmode']+'}doc-key', key) shape_group.set('transform', "translate(%s,%s)" % (location.x, config.cfg['invert-y']*location.y)) location = docs_dict[key]['location'] docs_dict[key]['location'] = [0, 0] shape = Shape(docs_dict[key]) style = Style(docs_dict[key], 'documentation') shape.setStyle(style) element = place.placeShape(shape, shape_group)
def fit(self, test_image, tol=0.1, max_iters=10000, initial_shape=None): """ Fits the shape model to the test image to find the shape :param test_image: The test image in the form of a numpy matrix :param tol: Fraction of points changed :param max_iters: Maximum number of iterations :param initial_shape: The starting Shape - if None get_default_initial_shape() is used :return: The final Shape, the fit error and the number of iterations performed """ if initial_shape is None: current_shape = self.get_default_initial_shape() else: current_shape = initial_shape.round() num_iter = 0 fit_error = float("inf") for num_iter in range(max_iters): previous_shape = Shape(current_shape.as_numpy_matrix().copy()) new_shape_grey, error_list = self._gm.search(test_image, current_shape) current_shape, fit_error, num_iters = self._pdm.fit(new_shape_grey) moved_points = np.sum( np.sum(current_shape.as_numpy_matrix().round() - previous_shape.as_numpy_matrix().round(), axis=1) > 0) if moved_points / float(self._pdm.get_size()) < tol: break return current_shape, fit_error, num_iter
def __init__(self, geometricName, contour): Shape.__init__(self, geometricName, contour) cornerList = [] self.minX = 1000 self.maxX = 0 self.minY = 1000 self.maxY = 0 contourCopy = contour if len(contourCopy) > 1: for corner in contourCopy: cornerList.append((corner.item(0), corner.item(1))) for corner in cornerList: if corner[0] > self.maxX: self.maxX = corner[0] if corner[1] > self.maxY: self.maxY = corner[1] if corner[0] < self.minX: self.minX = corner[0] if corner[1] < self.minY: self.minY = corner[1] else: self.minX = 0 self.maxX = 960 self.minY = 0 self.maxY = 720
def _processShapes(self): """ """ sheets = ['conductor', 'silkscreen', 'soldermask'] for sheet in sheets: try: shapes = self._footprint['layout'][sheet]['shapes'] except: shapes = [] for shape_dict in shapes: layers = utils.getExtendedLayerList(shape_dict.get('layers') or ['top']) for layer in layers: # Mirror the shape if it's text and on bottom later, # but let explicit shape setting override if layer == 'bottom': if shape_dict['type'] == 'text': shape_dict['mirror'] = shape_dict.get('mirror') or 'True' shape = Shape(shape_dict) style = Style(shape_dict, sheet) shape.setStyle(style) try: self._shapes[sheet][layer].append(shape) except: self._shapes[sheet][layer] = [] self._shapes[sheet][layer].append(shape)
def __init__(self, size, rotation, color="blue"): texture_path = Shape.build_texture_path(color, Octagon.shape_type) Shape.__init__(self, texture_path, size, rotation, Octagon.shape_type, color) self.sides = 8 self.color = color
def __init__(self): def initHandle(handle): self.handles.append(handle) QObject.connect(handle, SIGNAL("moved(QGraphicsObject*)"), self.handleMoved) Shape.__init__(self, BubbleItem(self)) # Item self.item.setFlag(QGraphicsItem.ItemIsSelectable) self.item.setBrush(COLOR) # Text item self.textItem = QGraphicsTextItem(self.item) self.textItem.setTextInteractionFlags(Qt.TextEditorInteraction) QObject.connect(self.textItem.document(), SIGNAL("contentsChanged()"), \ self.adjustSizeFromText) # Handles self.anchorHandle = Handle(self.item, 0, 0) # Position the bubble to the right of the anchor so that it can grow # vertically without overflowing the anchor self.bubbleHandle = Handle(self.item, ANCHOR_THICKNESS, -ANCHOR_THICKNESS) initHandle(self.anchorHandle) initHandle(self.bubbleHandle) self.setHandlesVisible(False) self.adjustSizeFromText()
def addShapes(self): """adds more shapes to the world""" # how many shapes to generate # we want roughly one piece per screen screenArea = self.displayGridSize[0] * self.displayGridSize[1] worldArea = self.world.cols * self.world.rows minTotalShapes = 1 + int(worldArea / screenArea) #logging.debug("generating {0} shape pieces...".format(minTotalShapes)) curTotalShapes = 0 shapes = [] while curTotalShapes < minTotalShapes: # until enough shape generated # create new shape, placed randomly num_sides = random.randint(3,6) newShape = Shape(self.display, self, self.character_size, num_sides) newShape.autonomous = True # all new shapes will be autonomous by default # add shape to the list of objects if(self.world.addObject(newShape)): curTotalShapes += 1 shapes.append(newShape) logging.debug ("shape #{0} added to the map, id {1} with position {2} and rect={3}".format(curTotalShapes, newShape, newShape.getMapTopLeft(), newShape.rect)) # now there's enough shape in the world self.shapes = shapes return shapes
def __init__(self, ps, color=None): Shape.__init__(self, color) self.vs = ps self.bound = AABox.from_vectors(*self.vs) self.half_planes = [] for i in xrange(len(self.vs)): h = HalfPlane(self.vs[i], self.vs[(i+1) % len(self.vs)]) self.half_planes.append(h)
def __init__(self, ps, color=None): Shape.__init__(self, color) mn = min(enumerate(ps), key=lambda (i,v): (v.y, v.x))[0] self.vs = list(ps[mn:]) + list(ps[:mn]) self.bound = Vector.union(*self.vs) self.half_planes = [] for i in xrange(len(self.vs)): h = HalfPlane(self.vs[i], self.vs[(i+1) % len(self.vs)]) self.half_planes.append(h)
def __init__(self): Shape.__init__(self, LineItem(self)) self.item.setFlag(QGraphicsItem.ItemIsSelectable) self.handles.append(Handle(self.item, 0, 0)) self.handles.append(Handle(self.item, 0, 0)) self.handles[1].setZValue(self.handles[0].zValue() + 1) for handle in self.handles: QObject.connect(handle, SIGNAL("moved(QGraphicsObject*)"), self.handleMoved) self.setHandlesVisible(False)
def __init__(self, theta1=0, theta2=360, *args, **kwargs): '''Create an ellipse ''' self._theta1 = theta1 self._theta2 = theta2 Shape.__init__(self, *args, **kwargs) self._fill_mode = GL_TRIANGLES self._line_mode = GL_LINE_LOOP self._update_position() self._update_shape()
def __init__(self, radius=0, *args, **kwargs): '''Create an (optionable) round rectangle. :Parameters: `radius` : int or tuple of 4 int Radius of corners. ''' self._radius = radius Shape.__init__(self,*args,**kwargs) self._update_position() self._update_shape()
def translate_errors(self, physical_error): encoded_error = Shape([]) for triplet in self.triplets: anticommute_count = 0 for op in triplet: if (not op.commutes_with(physical_error)): anticommute_count = anticommute_count + 1 if (anticommute_count > 1): raise RuntimeError("Invalid triplet\n" + str(triplet)) encoded_error.multiply_with_self(op) return encoded_error
def __init__(self, corners): """ Create Square self with vertices corners. Assume all sides are equal and corners are square. @param Square self: this Square object @param list[Point] corners: corners that define this Square @rtype: None >>> s = Square([Point(0, 0), Point(1, 0), Point(1, 1), Point(0, 0)]) """ Shape.__init__(self, corners)
def __init__(self, direction='up', *args, **kwargs): '''Create an oriented triangle. :Parameters: `direction` : str The triangle is oriented relative to its center to this property, which must be one of the alignment constants `left`, `right`, `up` or `down`. ''' self._direction = direction Shape.__init__(self,*args, **kwargs) self._update_position() self._update_shape()
def _processAssemblyShapes(self): """ """ try: shapes = self._footprint['layout']['assembly']['shapes'] except: return for shape_dict in shapes: layers = shape_dict.get('layer') or ['top'] for layer in layers: shape = Shape(shape_dict) style = Style(shape_dict, 'assembly') shape.setStyle(style) self._shapes['assembly'][layer].append(shape)
def __init__(self, thickness=.4, branches=5, *args, **kwargs): '''Create a cross. :Parameters: `thickness` : int Thickness of the cross `branches` : int Number of branches ''' self._thickness = thickness self._branches = branches Shape.__init__(self, *args, **kwargs) self._fill_mode = GL_TRIANGLES self._update_position() self._update_shape()
def __init__(self, corners): """ Create RightAngleTriangle self with vertices corners. Overrides Shape.__init__ Assume corners[0] is the 90 degree angle. @param RightAngleTriangle self: this RightAngleTriangle object @param list[Point] corners: corners that define this RightAngleTriangle @rtype: None >>> s = RightAngleTriangle([Point(0, 0), Point(1, 0), Point(0, 2)]) """ Shape.__init__(self, corners)
def __init__(self, screen): self.stat = "game" self.WIDTH = self.TILEW * self.W self.HEIGHT = self.TILEW * self.H self.screen = screen self.pause = False # the array save current situation # same as screen cood self.board = [] for i in xrange(self.H): line = [ None ] * self.W self.board.append(line) # will display self.level = 1 self.killed = 0 self.score = 0 # after this time, shape falls self.time = self.SPACE * 0.9 ** (self.level - 1) # save the elapsed time after last fail self.elapsed = 0 # used for judge pressed firstly or for a long time self.pressing = 0 # the moving shape self.shape = Shape(self.START, (self.WIDTH, self.HEIGHT), (self.W, self.H)) self.shape.set_board(self.board) self.board_image = pygame.Surface((self.WIDTH, self.HEIGHT)) # draw the background once self.screen.blit(pygame.image.load( util.file_path("background.jpg")).convert(), (0, 0)) self.display_info()
def __init__(self, *args, **kwargs): super(Canvas, self).__init__(*args, **kwargs) # Initialise local state. self.anno = [] self.mode = self.EDIT self.shapes = [] self.current = None self.selectedShape = None # save the selected shape here self.selectedShapeCopy = None self.lineColor = QColor(0, 0, 255) self.line = Shape(line_color=self.lineColor) self.prevPoint = QPointF() self.offsets = QPointF(), QPointF() self.scale = 1.0 self.pixmap = QPixmap() self.visible = {} self._hideBackround = False self.hideBackround = False self.hShape = None self.hVertex = None self._painter = QPainter() self._cursor = CURSOR_DEFAULT # Menus: self.menus = (QMenu(), QMenu()) # Set widget options. self.setMouseTracking(True) self.setFocusPolicy(Qt.WheelFocus)
def __init__(self, screen): self.stat = "game" self.WIDTH = self.TILEW * self.W self.HEIGHT = self.TILEW * self.H self.screen = screen self.pause = False self.board = [] #save current situation same as screen for i in xrange(self.H): line = [None] * self.W self.board.append(line) #next to display self.level = 1 self.killed = 0 self.score = 0 #delay for shape fall self.time = self.SPACE * 0.8 ** (self.level - 1) #save the elapsed time after last fail self.elapsed = 0 #pressd firstly time self.pressing = 0 #moving shape self.shape = Shape(self.START, \ (self.WIDTH, self.HEIGHT), (self.W, self.H)) self.shape.set_board(self.board) self.board_image = pygame.Surface((self.WIDTH, self.HEIGHT)) #draw background self.screen.blit(pygame.image.load( \ util.file_path("background.jpg")).convert(), (0, 0)) self.display_info()
def add_shape(self): assert not self.shape sh, col = random.choice(shape_color) self.shape = Shape(sh, self.window, col, self.width/2, 0, self.xinit, self.yinit) if self.collides(self.shape): raise GameOver() self.shape.draw()
def mousePressEvent(self, ev): pos = self.transformPos(ev.posF()) if ev.button() == Qt.LeftButton: if self.drawing(): if self.current and self.current.reachMaxPoints() is False: initPos = self.current[0] minX = initPos.x() minY = initPos.y() targetPos = self.line[1] maxX = targetPos.x() maxY = targetPos.y() self.current.addPoint(QPointF(maxX, minY)) self.current.addPoint(targetPos) self.current.addPoint(QPointF(minX, maxY)) self.current.addPoint(initPos) self.line[0] = self.current[-1] if self.current.isClosed(): self.finalise() elif not self.outOfPixmap(pos): self.current = Shape() self.current.addPoint(pos) self.line.points = [pos, pos] self.setHiding() self.drawingPolygon.emit(True) self.update() else: self.selectShapePoint(pos) self.prevPoint = pos self.repaint() elif ev.button() == Qt.RightButton and self.editing(): self.selectShapePoint(pos) self.prevPoint = pos self.repaint()
def _processSilkscreenShapes(self): """ """ try: shapes = self._footprint['layout']['silkscreen']['shapes'] except: return for shape_dict in shapes: layers = shape_dict.get('layers') or ['top'] shape = Shape(shape_dict) style = Style(shape_dict, 'silkscreen') shape.setStyle(style) for layer in layers: self._shapes['silkscreen'][layer].append(shape)
def _getOutline(self): """ Process the module's outline shape. Modules don't have to have an outline defined, so in that case return None. """ shape = None outline_dict = self._module_dict.get('outline') if outline_dict != None: shape_dict = outline_dict.get('shape') if shape_dict != None: shape = Shape(shape_dict) style = Style(shape_dict, 'outline') shape.setStyle(style) return shape
def __init__(self, a=1.0, b=1.0, c=0.0, d=0.0, e=0.0, f=-1.0, color=None): Shape.__init__(self, color) self.a = a self.b = b self.c = c self.d = d self.e = e self.f = f t = Transform(2 * a, c, 0, c, 2 * b, 0) self.center = t.inverse() * Vector(-d, -e) l1, l0 = quadratic(1, 2 * (-a - b), 4 * a * b - c * c) v = t.eigv() axes = [v[0] * ((l0 / 2) ** -0.5), v[1] * ((l1 / 2) ** -0.5)] self.bound = Vector.union(self.center - axes[0] - axes[1], self.center - axes[0] + axes[1], self.center + axes[0] - axes[1], self.center + axes[0] + axes[1])
def __init__(self, main, x, y, width, height=0): Window.__init__(self, main, x, y, width, height) self.grid_size = 10 self.grid_visible = True self.selected_point = None self.snap_to_grid = False self.shape = Shape()
def __init__(self, parent): QtGui.QFrame.__init__(self, parent) self.timer = QtCore.QBasicTimer() self.isWaitingAfterLine = False self.curPiece = Shape() self.nextPiece = Shape() self.curX = 0 self.curY = 0 self.numLinesRemoved = 0 self.board = [] self.setFocusPolicy(QtCore.Qt.StrongFocus) self.isStarted = False self.isPaused = False self.clearBoard() self.nextPiece.setRandomShape()
def generate(self, factors): """ Generates a shape based on a vector of factors of size equal to the number of modes of the model, with element values between -1 and 1 :param factors: A vector of size modes() with values between -1 and 1 :return: A Shape object containing the generated shape """ return Shape.from_collapsed_vector(self._model.generate(factors))
def _placeLayerIndex(self): """ Adds a drill index """ text_dict = config.stl['layout']['layer-index']['text'] text_dict['type'] = 'text' # Set the height (and width) of the rectangle (square) to the # size of the text rect_width = utils.parseDimension(text_dict['font-size'])[0] rect_height = rect_width rect_gap = 0.25 # Get location, or generate one try: location = config.brd['layer-index']['location'] except: # If not location is specified, put the drill index at the # top right of the board. The 'gap' defines the extra # spcae between the top of the largest drill and the # board's edge gap = 2 location = [self._width/2+gap, self._height/2-rect_height/2] location = utils.toPoint(location) rect_dict = {} rect_dict['type'] = 'rect' rect_dict['style'] = 'fill' rect_dict['width'] = rect_width rect_dict['height'] = rect_height # Create group for placing index for pcb_layer in utils.getSurfaceLayers(): for sheet in ['copper', 'soldermask', 'silkscreen', 'assembly', 'solderpaste']: layer = self._layers[pcb_layer][sheet]['layer'] transform = "translate(%s,%s)" % (location.x, config.cfg['invert-y']*location.y) group = et.SubElement(layer, 'g', transform=transform) group.set('{'+config.cfg['ns']['pcbmode']+'}type', 'layer-index') rect_shape = Shape(rect_dict) style = Style(rect_dict, sheet) rect_shape.setStyle(style) place.placeShape(rect_shape, group) text_dict['value'] = "%s %s" % (pcb_layer, sheet) #text_dict['location'] = [rect_width+rect_gap+text_width, 0] text_shape = Shape(text_dict) text_width = text_shape.getWidth() style = Style(text_dict, sheet) text_shape.setStyle(style) element = place.placeShape(text_shape, group) element.set("transform", "translate(%s,%s)" % (rect_width/2+rect_gap+text_width/2, 0)) location.y += config.cfg['invert-y']*(rect_height+rect_gap) location.y += config.cfg['invert-y']*(rect_height+rect_gap*2)
def detect(self, img, bndbox, initShape): mShape = Shape.shapeNorm2Real(self.meanShape, bndbox) for reg in self.regressors: affineT = Affine.fitGeoTrans(mShape, initShape) reg.detect(img, bndbox, initShape, affineT)
class Board(QFrame): msg2Statusbar = pyqtSignal(str) BoardWidth = 10 BoardHeight = 22 Speed = 300 def __init__(self, parent): super().__init__(parent) self.initBoard() def initBoard(self): '''initiates board''' self.timer = QBasicTimer() self.isWaitingAfterLine = False self.curX = 0 self.curY = 0 self.numLinesRemoved = 0 self.board = [] self.setFocusPolicy(Qt.StrongFocus) self.isStarted = False self.isPaused = False self.clearBoard() def shapeAt(self, x, y): '''determines shape at the board position''' return self.board[(y * Board.BoardWidth) + x] def setShapeAt(self, x, y, shape): '''sets a shape at the board''' self.board[(y * Board.BoardWidth) + x] = shape def squareWidth(self): '''returns the width of one square''' return self.contentsRect().width() // Board.BoardWidth def squareHeight(self): '''returns the height of one square''' return self.contentsRect().height() // Board.BoardHeight def start(self): '''starts game''' if self.isPaused: return self.isStarted = True self.isWaitingAfterLine = False self.numLinesRemoved = 0 self.clearBoard() self.msg2Statusbar.emit(str(self.numLinesRemoved)) self.newPiece() self.timer.start(Board.Speed, self) def pause(self): '''pauses game''' if not self.isStarted: return self.isPaused = not self.isPaused if self.isPaused: self.timer.stop() self.msg2Statusbar.emit("paused") else: self.timer.start(Board.Speed, self) self.msg2Statusbar.emit(str(self.numLinesRemoved)) self.update() def paintEvent(self, event): '''paints all shapes of the game''' painter = QPainter(self) rect = self.contentsRect() boardTop = rect.bottom() - Board.BoardHeight * self.squareHeight() for i in range(Board.BoardHeight): for j in range(Board.BoardWidth): shape = self.shapeAt(j, Board.BoardHeight - i - 1) if shape != Tetrominoe.NoShape: self.drawSquare(painter, rect.left() + j * self.squareWidth(), boardTop + i * self.squareHeight(), shape) if self.curPiece.shape() != Tetrominoe.NoShape: for i in range(4): x = self.curX + self.curPiece.x(i) y = self.curY - self.curPiece.y(i) self.drawSquare( painter, rect.left() + x * self.squareWidth(), boardTop + (Board.BoardHeight - y - 1) * self.squareHeight(), self.curPiece.shape()) def keyPressEvent(self, event): '''processes key press events''' if not self.isStarted or self.curPiece.shape() == Tetrominoe.NoShape: super(Board, self).keyPressEvent(event) return key = event.key() if key == Qt.Key_P: self.pause() return if self.isPaused: return elif key == Qt.Key_Left: self.tryMove(self.curPiece, self.curX - 1, self.curY) elif key == Qt.Key_Right: self.tryMove(self.curPiece, self.curX + 1, self.curY) elif key == Qt.Key_Down: self.tryMove(self.curPiece.rotateRight(), self.curX, self.curY) elif key == Qt.Key_Up: self.tryMove(self.curPiece.rotateLeft(), self.curX, self.curY) elif key == Qt.Key_Space: self.dropDown() elif key == Qt.Key_D: self.oneLineDown() else: super(Board, self).keyPressEvent(event) def timerEvent(self, event): '''handles timer event''' if event.timerId() == self.timer.timerId(): if self.isWaitingAfterLine: self.isWaitingAfterLine = False self.newPiece() else: self.oneLineDown() else: super(Board, self).timerEvent(event) def clearBoard(self): '''clears shapes from the board''' for i in range(Board.BoardHeight * Board.BoardWidth): self.board.append(Tetrominoe.NoShape) def dropDown(self): '''drops down a shape''' newY = self.curY while newY > 0: if not self.tryMove(self.curPiece, self.curX, newY - 1): break newY -= 1 self.pieceDropped() def oneLineDown(self): '''goes one line down with a shape''' if not self.tryMove(self.curPiece, self.curX, self.curY - 1): self.pieceDropped() def pieceDropped(self): '''after dropping shape, remove full lines and create new shape''' for i in range(4): x = self.curX + self.curPiece.x(i) y = self.curY - self.curPiece.y(i) self.setShapeAt(x, y, self.curPiece.shape()) self.removeFullLines() if not self.isWaitingAfterLine: self.newPiece() def removeFullLines(self): '''removes all full lines from the board''' numFullLines = 0 rowsToRemove = [] for i in range(Board.BoardHeight): n = 0 for j in range(Board.BoardWidth): if not self.shapeAt(j, i) == Tetrominoe.NoShape: n = n + 1 if n == 10: rowsToRemove.append(i) rowsToRemove.reverse() for m in rowsToRemove: for k in range(m, Board.BoardHeight): for l in range(Board.BoardWidth): self.setShapeAt(l, k, self.shapeAt(l, k + 1)) numFullLines = numFullLines + len(rowsToRemove) if numFullLines > 0: self.numLinesRemoved = self.numLinesRemoved + numFullLines self.msg2Statusbar.emit(str(self.numLinesRemoved)) self.isWaitingAfterLine = True self.curPiece.setShape(Tetrominoe.NoShape) self.update() def newPiece(self): '''creates a new shape''' self.curPiece = Shape() self.curPiece.setRandomShape() self.curX = Board.BoardWidth // 2 + 1 self.curY = Board.BoardHeight - 1 + self.curPiece.minY() if not self.tryMove(self.curPiece, self.curX, self.curY): self.curPiece.setShape(Tetrominoe.NoShape) self.timer.stop() self.isStarted = False self.msg2Statusbar.emit("Game over") def tryMove(self, newPiece, newX, newY): '''tries to move a shape''' for i in range(4): x = newX + newPiece.x(i) y = newY - newPiece.y(i) if x < 0 or x >= Board.BoardWidth or y < 0 or y >= Board.BoardHeight: return False if self.shapeAt(x, y) != Tetrominoe.NoShape: return False self.curPiece = newPiece self.curX = newX self.curY = newY self.update() return True def drawSquare(self, painter, x, y, shape): '''draws a square of a shape''' colorTable = [ 0x000000, 0xCC6666, 0x66CC66, 0x6666CC, 0xCCCC66, 0xCC66CC, 0x66CCCC, 0xDAAA00 ] color = QColor(colorTable[shape]) painter.fillRect(x + 1, y + 1, self.squareWidth() - 2, self.squareHeight() - 2, color) painter.setPen(color.lighter()) painter.drawLine(x, y + self.squareHeight() - 1, x, y) painter.drawLine(x, y, x + self.squareWidth() - 1, y) painter.setPen(color.darker()) painter.drawLine(x + 1, y + self.squareHeight() - 1, x + self.squareWidth() - 1, y + self.squareHeight() - 1) painter.drawLine(x + self.squareWidth() - 1, y + self.squareHeight() - 1, x + self.squareWidth() - 1, y + 1)
def __init__(self, x, y, color, width, height): Shape.__init__(self, x, y, color) self.width = width self.height = height
class Canvas(QWidget): zoomRequest = pyqtSignal(int) scrollRequest = pyqtSignal(int, int) newShape = pyqtSignal() selectionChanged = pyqtSignal(bool) shapeMoved = pyqtSignal() drawingPolygon = pyqtSignal(bool) CREATE, EDIT = range(2) epsilon = 11.0 def __init__(self, *args, **kwargs): super(Canvas, self).__init__(*args, **kwargs) # Initialise local state. self.mode = self.EDIT self.shapes = [] self.current = None self.selectedShape = None # save the selected shape here self.selectedShapeCopy = None self.lineColor = QColor(0, 0, 255) self.line = Shape(line_color=self.lineColor) self.prevPoint = QPointF() self.offsets = QPointF(), QPointF() self.scale = 1.0 self.pixmap = QPixmap() self.visible = {} self._hideBackround = False self.hideBackround = False self.hShape = None self.hVertex = None self._painter = QPainter() self._cursor = CURSOR_DEFAULT # Menus: self.menus = (QMenu(), QMenu()) # Set widget options. self.setMouseTracking(True) self.setFocusPolicy(Qt.WheelFocus) def enterEvent(self, ev): self.overrideCursor(self._cursor) def leaveEvent(self, ev): self.restoreCursor() def focusOutEvent(self, ev): self.restoreCursor() def isVisible(self, shape): return self.visible.get(shape, True) def drawing(self): return self.mode == self.CREATE def editing(self): return self.mode == self.EDIT def setEditing(self, value=True): self.mode = self.EDIT if value else self.CREATE if not value: # Create self.unHighlight() self.deSelectShape() def unHighlight(self): if self.hShape: self.hShape.highlightClear() self.hVertex = self.hShape = None def selectedVertex(self): return self.hVertex is not None def mouseMoveEvent(self, ev): """Update line with last point and current coordinates.""" pos = self.transformPos(ev.posF()) self.restoreCursor() # Polygon drawing. if self.drawing(): self.overrideCursor(CURSOR_DRAW) if self.current: color = self.lineColor if self.outOfPixmap(pos): # Don't allow the user to draw outside the pixmap. # Project the point to the pixmap's edges. pos = self.intersectionPoint(self.current[-1], pos) elif len(self.current) > 1 and self.closeEnough( pos, self.current[0]): # Attract line to starting point and colorise to alert the user: pos = self.current[0] color = self.current.line_color self.overrideCursor(CURSOR_POINT) self.current.highlightVertex(0, Shape.NEAR_VERTEX) self.line[1] = pos self.line.line_color = color self.repaint() self.current.highlightClear() return # Polygon copy moving. if Qt.RightButton & ev.buttons(): if self.selectedShapeCopy and self.prevPoint: self.overrideCursor(CURSOR_MOVE) self.boundedMoveShape(self.selectedShapeCopy, pos) self.repaint() elif self.selectedShape: self.selectedShapeCopy = self.selectedShape.copy() self.repaint() return # Polygon/Vertex moving. if Qt.LeftButton & ev.buttons(): if self.selectedVertex(): self.boundedMoveVertex(pos) self.shapeMoved.emit() self.repaint() elif self.selectedShape and self.prevPoint: self.overrideCursor(CURSOR_MOVE) self.boundedMoveShape(self.selectedShape, pos) self.shapeMoved.emit() self.repaint() return # Just hovering over the canvas, 2 posibilities: # - Highlight shapes # - Highlight vertex # Update shape/vertex fill and tooltip value accordingly. self.setToolTip("Image") for shape in reversed([s for s in self.shapes if self.isVisible(s)]): # Look for a nearby vertex to highlight. If that fails, # check if we happen to be inside a shape. index = shape.nearestVertex(pos, self.epsilon) if index is not None: if self.selectedVertex(): self.hShape.highlightClear() self.hVertex, self.hShape = index, shape shape.highlightVertex(index, shape.MOVE_VERTEX) self.overrideCursor(CURSOR_POINT) self.setToolTip("Click & drag to move point") self.setStatusTip(self.toolTip()) self.update() break elif shape.containsPoint(pos): if self.selectedVertex(): self.hShape.highlightClear() self.hVertex, self.hShape = None, shape self.setToolTip("Click & drag to move shape '%s'" % shape.label) self.setStatusTip(self.toolTip()) self.overrideCursor(CURSOR_GRAB) self.update() break else: # Nothing found, clear highlights, reset state. if self.hShape: self.hShape.highlightClear() self.update() self.hVertex, self.hShape = None, None def mousePressEvent(self, ev): pos = self.transformPos(ev.posF()) if ev.button() == Qt.LeftButton: if self.drawing(): if self.current: self.current.addPoint(self.line[1]) self.line[0] = self.current[-1] if self.current.isClosed(): self.finalise() elif not self.outOfPixmap(pos): self.current = Shape() self.current.addPoint(pos) self.line.points = [pos, pos] self.setHiding() self.drawingPolygon.emit(True) self.update() else: self.selectShapePoint(pos) self.prevPoint = pos self.repaint() elif ev.button() == Qt.RightButton and self.editing(): self.selectShapePoint(pos) self.prevPoint = pos self.repaint() def mouseReleaseEvent(self, ev): if ev.button() == Qt.RightButton: menu = self.menus[bool(self.selectedShapeCopy)] self.restoreCursor() if not menu.exec_(self.mapToGlobal(ev.pos()))\ and self.selectedShapeCopy: # Cancel the move by deleting the shadow copy. self.selectedShapeCopy = None self.repaint() elif ev.button() == Qt.LeftButton and self.selectedShape: self.overrideCursor(CURSOR_GRAB) def endMove(self, copy=False): assert self.selectedShape and self.selectedShapeCopy shape = self.selectedShapeCopy #del shape.fill_color #del shape.line_color if copy: self.shapes.append(shape) self.selectedShape.selected = False self.selectedShape = shape self.repaint() else: shape.label = self.selectedShape.label self.deleteSelected() self.shapes.append(shape) self.selectedShapeCopy = None def hideBackroundShapes(self, value): self.hideBackround = value if self.selectedShape: # Only hide other shapes if there is a current selection. # Otherwise the user will not be able to select a shape. self.setHiding(True) self.repaint() def setHiding(self, enable=True): self._hideBackround = self.hideBackround if enable else False def canCloseShape(self): return self.drawing() and self.current and len(self.current) > 2 def mouseDoubleClickEvent(self, ev): # We need at least 4 points here, since the mousePress handler # adds an extra one before this handler is called. if self.canCloseShape() and len(self.current) > 3: self.current.popPoint() self.finalise() def selectShape(self, shape): self.deSelectShape() shape.selected = True self.selectedShape = shape self.setHiding() self.selectionChanged.emit(True) self.update() def selectShapePoint(self, point): """Select the first shape created which contains this point.""" self.deSelectShape() if self.selectedVertex(): # A vertex is marked for selection. index, shape = self.hVertex, self.hShape shape.highlightVertex(index, shape.MOVE_VERTEX) return contours_txt = open("#selfshapes.txt", 'w') contours_txt.write(str(self.shapes)) contours_txt.close() for shape in reversed(self.shapes): if self.isVisible(shape) and shape.containsPoint(point): shape.selected = True self.selectedShape = shape self.calculateOffsets(shape, point) self.setHiding() self.selectionChanged.emit(True) return def calculateOffsets(self, shape, point): rect = shape.boundingRect() x1 = rect.x() - point.x() y1 = rect.y() - point.y() x2 = (rect.x() + rect.width()) - point.x() y2 = (rect.y() + rect.height()) - point.y() self.offsets = QPointF(x1, y1), QPointF(x2, y2) def boundedMoveVertex(self, pos): index, shape = self.hVertex, self.hShape point = shape[index] if self.outOfPixmap(pos): pos = self.intersectionPoint(point, pos) shape.moveVertexBy(index, pos - point) def boundedMoveShape(self, shape, pos): if self.outOfPixmap(pos): return False # No need to move o1 = pos + self.offsets[0] if self.outOfPixmap(o1): pos -= QPointF(min(0, o1.x()), min(0, o1.y())) o2 = pos + self.offsets[1] if self.outOfPixmap(o2): pos += QPointF(min(0, self.pixmap.width() - o2.x()), min(0, self.pixmap.height() - o2.y())) # The next line tracks the new position of the cursor # relative to the shape, but also results in making it # a bit "shaky" when nearing the border and allows it to # go outside of the shape's area for some reason. XXX #self.calculateOffsets(self.selectedShape, pos) dp = pos - self.prevPoint if dp: shape.moveBy(dp) self.prevPoint = pos return True return False def deSelectShape(self): if self.selectedShape: self.selectedShape.selected = False self.selectedShape = None self.setHiding(False) self.selectionChanged.emit(False) self.update() def deleteSelected(self): if self.selectedShape: shape = self.selectedShape self.shapes.remove(self.selectedShape) self.selectedShape = None self.update() return shape def copySelectedShape(self): if self.selectedShape: shape = self.selectedShape.copy() self.deSelectShape() self.shapes.append(shape) shape.selected = True self.selectedShape = shape self.boundedShiftShape(shape) return shape def boundedShiftShape(self, shape): # Try to move in one direction, and if it fails in another. # Give up if both fail. point = shape[0] offset = QPointF(2.0, 2.0) self.calculateOffsets(shape, point) self.prevPoint = point if not self.boundedMoveShape(shape, point - offset): self.boundedMoveShape(shape, point + offset) def paintEvent(self, event): if not self.pixmap: return super(Canvas, self).paintEvent(event) p = self._painter p.begin(self) p.setRenderHint(QPainter.Antialiasing) p.setRenderHint(QPainter.HighQualityAntialiasing) p.setRenderHint(QPainter.SmoothPixmapTransform) p.scale(self.scale, self.scale) p.translate(self.offsetToCenter()) p.drawPixmap(0, 0, self.pixmap) Shape.scale = self.scale for shape in self.shapes: if (shape.selected or not self._hideBackround) and self.isVisible(shape): shape.fill = shape.selected or shape == self.hShape shape.paint(p) if self.current: self.current.paint(p) self.line.paint(p) if self.selectedShapeCopy: self.selectedShapeCopy.paint(p) p.end() def transformPos(self, point): """Convert from widget-logical coordinates to painter-logical coordinates.""" return point / self.scale - self.offsetToCenter() def offsetToCenter(self): s = self.scale area = super(Canvas, self).size() w, h = self.pixmap.width() * s, self.pixmap.height() * s aw, ah = area.width(), area.height() x = (aw - w) / (2 * s) if aw > w else 0 y = (ah - h) / (2 * s) if ah > h else 0 return QPointF(x, y) def outOfPixmap(self, p): w, h = self.pixmap.width(), self.pixmap.height() return not (0 <= p.x() <= w and 0 <= p.y() <= h) def finalise(self): assert self.current self.current.close() self.shapes.append(self.current) self.current = None self.setHiding(False) self.newShape.emit() self.update() def closeEnough(self, p1, p2): #d = distance(p1 - p2) #m = (p1-p2).manhattanLength() #print "d %.2f, m %d, %.2f" % (d, m, d - m) return distance(p1 - p2) < self.epsilon def intersectionPoint(self, p1, p2): # Cycle through each image edge in clockwise fashion, # and find the one intersecting the current line segment. # http://paulbourke.net/geometry/lineline2d/ size = self.pixmap.size() points = [(0, 0), (size.width(), 0), (size.width(), size.height()), (0, size.height())] x1, y1 = p1.x(), p1.y() x2, y2 = p2.x(), p2.y() d, i, (x, y) = min(self.intersectingEdges((x1, y1), (x2, y2), points)) x3, y3 = points[i] x4, y4 = points[(i + 1) % 4] if (x, y) == (x1, y1): # Handle cases where previous point is on one of the edges. if x3 == x4: return QPointF(x3, min(max(0, y2), max(y3, y4))) else: # y3 == y4 return QPointF(min(max(0, x2), max(x3, x4)), y3) return QPointF(x, y) def intersectingEdges(self, (x1, y1), (x2, y2), points): """For each edge formed by `points', yield the intersection with the line segment `(x1,y1) - (x2,y2)`, if it exists. Also return the distance of `(x2,y2)' to the middle of the edge along with its index, so that the one closest can be chosen.""" for i in xrange(4): x3, y3 = points[i] x4, y4 = points[(i + 1) % 4] denom = (y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1) nua = (x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3) nub = (x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3) if denom == 0: # This covers two cases: # nua == nub == 0: Coincident # otherwise: Parallel continue ua, ub = nua / denom, nub / denom if 0 <= ua <= 1 and 0 <= ub <= 1: x = x1 + ua * (x2 - x1) y = y1 + ua * (y2 - y1) m = QPointF((x3 + x4) / 2, (y3 + y4) / 2) d = distance(m - QPointF(x2, y2)) yield d, i, (x, y)
def create_pyramid(position, size, color): pyramid, coordinates, I, n_coords = get_pyramid(size, color) pyramid = Shape("pyramid", pyramid, coordinates, I, position, size, color, n_coords) return pyramid
def run(dims: Tuple[int, int] = (400, 400)): reduced_dims = (dims[0] // 10, dims[1] // 10) pygame.init() screen = pygame.display.set_mode(dims) display_surf = pygame.Surface(reduced_dims) clock = pygame.time.Clock() rate = 5 done = False grid = Grid(reduced_dims) current_shape = Shape(reduced_dims) while not done: for event in pygame.event.get(): if event.type == pygame.QUIT: done = True elif event.type == KEYDOWN and event.key == K_LEFT: current_shape.move("l", grid.block_positions) elif event.type == KEYDOWN and event.key == K_RIGHT: current_shape.move("r", grid.block_positions) elif event.type == KEYDOWN and event.key == K_UP: current_shape.rotate(grid.block_positions) elif event.type == KEYDOWN and event.key == K_DOWN: current_shape.drop(grid.block_positions) grid.draw_grid(display_surf) current_shape.draw_shape(display_surf) current_shape.step(grid.block_positions) if not current_shape.can_move: if current_shape.game_over: grid.game_over(display_surf, screen, dims, clock) for event in pygame.event.get(): if event.type == KEYDOWN and event.key == "K_SPACE": print("restarting") grid = Grid(reduced_dims) current_shape = Shape(reduced_dims) else: sys.exit(0) grid.update(current_shape) current_shape = Shape(reduced_dims) rate = grid.clear_line(rate) surf = pygame.transform.scale(display_surf, dims) screen.blit(surf, (0, 0)) pygame.display.update() clock.tick(int(rate))
def __init__(self, centre_x, centre_y, width, height, name='Rectangle'): Shape.__init__(self, centre_x, centre_y, name) self.height = height self.width = width
def __init__(self, bbox, m, b, vel=[0.0, 0.0]): Shape.__init__(self, bbox, vel=vel) self.m = m self.b = b
def __init__(self, refdef, component): """ """ self._refdef = refdef self._layer = component.get('layer') or 'top' self._rotate = component.get('rotate') or 0 self._rotate_point = utils.toPoint(component.get('rotate-point') or [0, 0]) self._scale = component.get('scale') or 1 self._location = component.get('location') or [0, 0] # Get footprint definition and shapes try: self._footprint_name = component['footprint'] except: msg.error("Cannot find a 'footprint' name for refdef %s." % refdef) fname = os.path.join(config.cfg['base-dir'], config.cfg['locations']['components'], self._footprint_name + '.json') footprint_dict = utils.dictFromJsonFile(fname) footprint = Footprint(footprint_dict) footprint_shapes = footprint.getShapes() #------------------------------------------------ # Apply component-specific modifiers to footprint #------------------------------------------------ for sheet in ['copper', 'soldermask', 'solderpaste', 'silkscreen', 'assembly', 'drills']: for layer in utils.getSurfaceLayers() + utils.getInternalLayers(): for shape in footprint_shapes[sheet][layer]: # In order to apply the rotation we need to adust the location # of each element shape.rotateLocation(self._rotate, self._rotate_point) shape.transformPath(self._scale, self._rotate, self._rotate_point, False, True) #-------------------------------------- # Remove silkscreen and assembly shapes #-------------------------------------- for sheet in ['silkscreen','assembly']: try: shapes_dict = component[sheet].get('shapes') or {} except: shapes_dict = {} # If the setting is to not show silkscreen shapes for the # component, delete the shapes from the shapes' dictionary if shapes_dict.get('show') == False: for pcb_layer in utils.getSurfaceLayers(): footprint_shapes[sheet][pcb_layer] = [] #---------------------------------------------------------- # Add silkscreen and assembly reference designator (refdef) #---------------------------------------------------------- for sheet in ['silkscreen','assembly']: try: refdef_dict = component[sheet].get('refdef') or {} except: refdef_dict = {} if refdef_dict.get('show') != False: layer = refdef_dict.get('layer') or 'top' # Rotate the refdef; if unspecified the rotation is the same as # the rotation of the component refdef_dict['rotate'] = refdef_dict.get('rotate') or 0 # Sometimes you'd want to keep all refdefs at the same angle # and not rotated with the component if refdef_dict.get('rotate-with-component') != False: refdef_dict['rotate'] += self._rotate refdef_dict['rotate-point'] = utils.toPoint(refdef_dict.get('rotate-point')) or self._rotate_point refdef_dict['location'] = refdef_dict.get('location') or [0, 0] refdef_dict['type'] = 'text' refdef_dict['value'] = refdef refdef_dict['font-family'] = (config.stl['layout'][sheet]['refdef'].get('font-family') or config.stl['defaults']['font-family']) refdef_dict['font-size'] = (config.stl['layout'][sheet]['refdef'].get('font-size') or "2mm") refdef_shape = Shape(refdef_dict) refdef_shape.is_refdef = True refdef_shape.rotateLocation(self._rotate, self._rotate_point) style = Style(refdef_dict, sheet, 'refdef') refdef_shape.setStyle(style) # Add the refdef to the silkscreen/assembly list. It's # important that this is added at the very end since the # plcament process assumes the refdef is last footprint_shapes[sheet][layer].append(refdef_shape) #------------------------------------------------------ # Invert 'top' and 'bottom' if layer is on the 'bottom' #------------------------------------------------------ if self._layer == 'bottom': layers = utils.getSurfaceLayers() layers_reversed = reversed(utils.getSurfaceLayers()) for sheet in ['copper', 'soldermask', 'solderpaste', 'silkscreen', 'assembly']: sheet_dict = footprint_shapes[sheet] # TODO: this nasty hack won't work for more than two # layers, so when 2+ are supported this needs to be # revisited for i in range(0,len(layers)-1): sheet_dict['temp'] = sheet_dict.pop(layers[i]) sheet_dict[layers[i]] = sheet_dict.pop(layers[len(layers)-1-i]) sheet_dict[layers[len(layers)-1-i]] = sheet_dict.pop('temp') self._footprint_shapes = footprint_shapes
def __init__(self): Shape.__init__(self) self.drawing_type = GL_TRIANGLES self.setup_buffers()