def restoreTransform(self, tr): try: #self.userTranslate = pg.Point(tr['trans']) #self.userRotate = tr['rot'] self.userTransform = pg.SRTTransform(tr) self.updateTransform() self.selectBoxFromUser() ## move select box to match self.sigTransformChanged.emit(self) self.sigTransformChangeFinished.emit(self) except: #self.userTranslate = pg.Point([0,0]) #self.userRotate = 0 self.userTransform = pg.SRTTransform() debug.printExc("Failed to load transform:")
def update(): # recalculate and redraw the fractal curve depth = depthSpin.value() pts = baseLine.getState()['points'] nbseg = len(pts) - 1 nseg = nbseg**depth # Get a transformation matrix for each base segment trs = [] v1 = pts[-1] - pts[0] l1 = v1.length() for i in range(len(pts)-1): p1 = pts[i] p2 = pts[i+1] v2 = p2 - p1 t = p1 - pts[0] r = v2.angle(v1) s = v2.length() / l1 trs.append(pg.SRTTransform({'pos': t, 'scale': (s, s), 'angle': r})) basePts = [np.array(list(pt) + [1]) for pt in baseLine.getState()['points']] baseMats = np.dstack([tr.matrix().T for tr in trs]).transpose(2, 0, 1) # Generate an array of matrices to transform base points global transformMap if transformMap[:2] != [depth, nbseg]: # we can cache the transform index to save a little time.. nseg = nbseg**depth matInds = np.empty((depth, nseg), dtype=int) for i in range(depth): matInds[i] = np.tile(np.repeat(np.arange(nbseg), nbseg**(depth-1-i)), nbseg**i) transformMap = [depth, nbseg, matInds] # Each column in matInds contains the indices referring to the base transform # matrices that must be multiplied together to generate the final transform # for each segment of the fractal matInds = transformMap[2] # Collect all matrices needed for generating fractal curve mats = baseMats[matInds] # Magic-multiply stacks of matrices together def matmul(a, b): return np.sum(np.transpose(a,(0,2,1))[..., None] * b[..., None, :], axis=-3) mats = reduce(matmul, mats) # Transform base points through matrix array pts = np.empty((nseg * nbseg + 1, 2)) for l in range(len(trs)): bp = basePts[l] pts[l:-1:len(trs)] = np.dot(mats, bp)[:, :2] # Finish the curve with the last base point pts[-1] = basePts[-1][:2] # update fractal curve with new points fc.setData(pts[:,0], pts[:,1])
def mirrorY(self): if not self.isMovable(): return #flip = self.transformGui.mirrorImageCheck.isChecked() #tr = self.userTransform.saveState() inv = pg.SRTTransform() inv.scale(-1, 1) self.userTransform = self.userTransform * inv self.updateTransform() self.selectBoxFromUser() self.sigTransformChangeFinished.emit(self)
def _STTransform_to_pg(self, tr): import pyqtgraph if tr.dims == (2, 2): ptr = pyqtgraph.SRTTransform() ptr.setScale(tr.scale) ptr.setTranslate(tr.offset) return ptr elif tr.dims == (3, 3): ptr = pyqtgraph.SRTTransform3D() ptr.setScale(tr.scale) ptr.setTranslate(tr.offset) return ptr else: raise TypeError("Converting STTransform of dimension %r to pyqtgraph is not supported." % tr.dims)
def __init__(self, item, **opts): defOpts = { 'name': None, 'z': None, 'movable': True, 'scalable': False, 'rotatable': True, 'visible': True, 'parent': None } #'pos': [0,0], 'scale': [1,1], 'angle':0, defOpts.update(opts) self.opts = defOpts self.selectedAlone = False ## whether this item is the only one selected QtCore.QObject.__init__(self) self.canvas = None self._graphicsItem = item parent = self.opts['parent'] if parent is not None: self._graphicsItem.setParentItem(parent.graphicsItem()) self._parentItem = parent else: self._parentItem = None z = self.opts['z'] if z is not None: item.setZValue(z) self.ctrl = QtGui.QWidget() self.layout = QtGui.QGridLayout() self.layout.setSpacing(0) self.layout.setContentsMargins(0, 0, 0, 0) self.ctrl.setLayout(self.layout) self.alphaLabel = QtGui.QLabel("Alpha") self.alphaSlider = QtGui.QSlider() self.alphaSlider.setMaximum(1023) self.alphaSlider.setOrientation(QtCore.Qt.Horizontal) self.alphaSlider.setValue(1023) self.layout.addWidget(self.alphaLabel, 0, 0) self.layout.addWidget(self.alphaSlider, 0, 1) self.resetTransformBtn = QtGui.QPushButton('Reset Transform') self.copyBtn = QtGui.QPushButton('Copy') self.pasteBtn = QtGui.QPushButton('Paste') self.transformWidget = QtGui.QWidget() self.transformGui = TransformGuiTemplate.Ui_Form() self.transformGui.setupUi(self.transformWidget) self.layout.addWidget(self.transformWidget, 3, 0, 1, 2) self.transformGui.mirrorImageBtn.clicked.connect(self.mirrorY) self.transformGui.reflectImageBtn.clicked.connect(self.mirrorXY) self.layout.addWidget(self.resetTransformBtn, 1, 0, 1, 2) self.layout.addWidget(self.copyBtn, 2, 0, 1, 1) self.layout.addWidget(self.pasteBtn, 2, 1, 1, 1) self.alphaSlider.valueChanged.connect(self.alphaChanged) self.alphaSlider.sliderPressed.connect(self.alphaPressed) self.alphaSlider.sliderReleased.connect(self.alphaReleased) #self.canvas.sigSelectionChanged.connect(self.selectionChanged) self.resetTransformBtn.clicked.connect(self.resetTransformClicked) self.copyBtn.clicked.connect(self.copyClicked) self.pasteBtn.clicked.connect(self.pasteClicked) self.setMovable( self.opts['movable']) ## update gui to reflect this option if 'transform' in self.opts: self.baseTransform = self.opts['transform'] else: self.baseTransform = pg.SRTTransform() if 'pos' in self.opts and self.opts['pos'] is not None: self.baseTransform.translate(self.opts['pos']) if 'angle' in self.opts and self.opts['angle'] is not None: self.baseTransform.rotate(self.opts['angle']) if 'scale' in self.opts and self.opts['scale'] is not None: self.baseTransform.scale(self.opts['scale']) ## create selection box (only visible when selected) tr = self.baseTransform.saveState() if 'scalable' not in opts and tr['scale'] == (1, 1): self.opts['scalable'] = True ## every CanvasItem implements its own individual selection box ## so that subclasses are free to make their own. self.selectBox = SelectBox(scalable=self.opts['scalable'], rotatable=self.opts['rotatable']) #self.canvas.scene().addItem(self.selectBox) self.selectBox.hide() self.selectBox.setZValue(1e6) self.selectBox.sigRegionChanged.connect( self.selectBoxChanged) ## calls selectBoxMoved self.selectBox.sigRegionChangeFinished.connect( self.selectBoxChangeFinished) ## set up the transformations that will be applied to the item ## (It is not safe to use item.setTransform, since the item might count on that not changing) self.itemRotation = QtGui.QGraphicsRotation() self.itemScale = QtGui.QGraphicsScale() self._graphicsItem.setTransformations( [self.itemRotation, self.itemScale]) self.tempTransform = pg.SRTTransform( ) ## holds the additional transform that happens during a move - gets added to the userTransform when move is done. self.userTransform = pg.SRTTransform( ) ## stores the total transform of the object self.resetUserTransform()
def resetTemporaryTransform(self): self.tempTransform = pg.SRTTransform( ) ## don't use Transform.reset()--this transform might be used elsewhere. self.updateTransform()
def as2D(self): """Return a QTransform representing the x,y portion of this transform (if possible)""" return pg.SRTTransform(self)