def egg3dQuaternion(self, a, b, c, d): self._quatHist = np.roll(self._quatHist, 1) self._quatHist[0] = Quaternion(a, c, b, d) q0 = Quaternion(0, 0, 0, 0) for q, w in zip(self._quatHist, self._quatWeights): q0 = q0 + q * w self.transform.setQuaternion(q0)
def center(self): self.quatRot = Quaternion() self.cameraZ = 5. self.zoom = 1. self.scaleAll = 1. self.setBounds(-1, 1., -1, 1, -1, 1) self.setTranslate(0, 0, 0) self.update() self._transformChanged.emit()
def addRotation(self, angle, x, y, z, from_left = True): q = Quaternion(np.cos(angle), np.sin(angle) * x, np.sin(angle) * y, np.sin(angle) * z) if from_left: q_new = q*self.quatRot else: q_new = self.quatRot *q self.setQuaternion(q_new)
def mouseMoveEvent(self, event): # c = append(self.cubeCoords,ones(24)[:,newaxis],axis=1) # cUser = dot(c,self.finalMat) # cUser = cUser[:,:3]/cUser[:,-1,newaxis] # print self.finalMat # print c[0], cUser[0] # Rotation if event.buttons() == QtCore.Qt.LeftButton: x1, y1, z1 = self.posToVec3(event.x(), event.y()) logger.debug("mouse position: %s %s %s " % (x1, y1, z1)) n = np.cross(np.array([self._x0, self._y0, self._z0]), np.array([x1, y1, z1])) nnorm = linalg.norm(n) if np.abs(nnorm) >= 1.: nnorm *= 1. / np.abs(nnorm) w = np.arcsin(nnorm) n *= 1. / (nnorm + 1.e-10) q = Quaternion(np.cos(.5 * w), *(np.sin(.5 * w) * n)) self.transform.setQuaternion(self.transform.quatRot * q) # Translation if event.buttons() == QtCore.Qt.RightButton: x, y = self.posToVec2(event.x(), event.y()) dx, dy, foo = np.dot(self._invRotM, [x - self._x0, y - self._y0, 0]) self.transform.addTranslate(dx, dy, foo) self._x0, self._y0 = x, y self.refresh()
def center(self): self.quatRot = Quaternion() self.cameraZ = 5. self.zoom = 1. self.scaleAll = 1. self.setBounds(-1, 1., -1, 1, -1, 1) self.setTranslate(0, 0, 0) self.update() self._transformChanged.emit()
def spimagine_show_volume_numpy(numpy_array, stackUnits=(1, 1, 1), \ interpolation="nearest", cmap="grays"): # Spimagine OpenCL volume renderer. volfig() spim_widget = \ volshow(numpy_array, stackUnits=stackUnits, interpolation=interpolation) spim_widget.set_colormap(cmap) spim_widget.transform.setQuaternion(Quaternion(-0.005634209439510011,\ 0.00790509382124309,\ -0.0013812284289010514,\ -0.9999519273706857))
def connectEgg3d(self): try: self.egg3d.listener._quaternionChanged.connect(self.egg3dQuaternion) self.egg3d.listener._zoomChanged.connect(self.egg3dZoom) N = 45 self._quatHist = [Quaternion() for i in range(N)] self._quatWeights = np.exp(-2.*np.linspace(0,1,N)) self._quatWeights *= 1./sum(self._quatWeights) self.egg3d.start() except Exception as e: print(e) self.settingsView.checkEgg.setCheckState(QtCore.Qt.Unchecked)
def setQuaternion(self, quat): logger.debug("set quaternion to %s", quat.data) self.quatRot = Quaternion.copy(quat) self._rotationChanged.emit() self._transformChanged.emit()
def setRotation(self, angle, x, y, z): self.setQuaternion(Quaternion(np.cos(angle), np.sin(angle) * x, np.sin(angle) * y, np.sin(angle) * z))
class TransformModel(QtCore.QObject): _maxChanged = QtCore.pyqtSignal(float) _minChanged = QtCore.pyqtSignal(float) _gammaChanged = QtCore.pyqtSignal(float) _boxChanged = QtCore.pyqtSignal(int) _isoChanged = QtCore.pyqtSignal(bool) _interpChanged = QtCore.pyqtSignal(bool) _perspectiveChanged = QtCore.pyqtSignal(int) # _rotationChanged = QtCore.pyqtSignal(float,float,float,float) _rotationChanged = QtCore.pyqtSignal() _translateChanged = QtCore.pyqtSignal(float, float, float) _slicePosChanged = QtCore.pyqtSignal(int) _sliceDimChanged = QtCore.pyqtSignal(int) _boundsChanged = QtCore.pyqtSignal(float, float, float, float, float, float) _transformChanged = QtCore.pyqtSignal() _stackUnitsChanged = QtCore.pyqtSignal(float, float, float) _alphaPowChanged = QtCore.pyqtSignal(float) def __init__(self): super(TransformModel, self).__init__() self.reset() def _update_value(self, name, newval): """update self.name to newval and returns True if the new value indeed was different than the new""" if not hasattr(self, name): setattr(self, name, newval) return True oldval = getattr(self, name) is_equal = True if isinstance(oldval, np.ndarray): is_equal = np.array_equal(oldval, newval) elif isinstance(oldval, Quaternion): is_equal = np.array_equal(oldval.data, newval.data) else: is_equal = (oldval == newval) if not is_equal: setattr(self, name, newval) return not is_equal def setModel(self, dataModel): self.dataModel = dataModel def reset(self, minVal=0., maxVal=256., stackUnits=None): logger.debug("reset: min = %s max = %s" % (minVal, maxVal)) self.dataPos = 0 self.slicePos = 0 self.sliceDim = 0 self.zoom = 1. self.setIso(False) self.isPerspective = True self.setPerspective() self.setValueScale(minVal, maxVal) self.setGamma(1.) self.setAlphaPow(0) self.setBox(True) self.setInterpolate(True) self.setOccStrength() self.setOccRadius() self.setOccNPoints() self.eye_dist_proj = 0 self.eye_dist_cam = 0 if not hasattr(self, "isSlice"): self.setShowSlice(False) if not stackUnits: stackUnits = [.1, .1, .1] self.setStackUnits(*stackUnits) self.center() def setIso(self, isIso): logger.debug("setting Iso %s" % isIso) if self._update_value("isIso", isIso): self._isoChanged.emit(isIso) self._transformChanged.emit() def setInterpolate(self, is_interpolate): logger.debug("setting interpolation %s" % is_interpolate) if self._update_value("is_interpolate", is_interpolate): self._interpChanged.emit(is_interpolate) self._transformChanged.emit() def setOccStrength(self, occ_strength=.15): if self._update_value("occ_strength", occ_strength): self._transformChanged.emit() def setOccRadius(self, val=21): if self._update_value("occ_radius", val): self._transformChanged.emit() def setOccNPoints(self, val=31): if self._update_value("occ_n_points", val): self._transformChanged.emit() def center(self): self.quatRot = Quaternion() self.cameraZ = 5. self.zoom = 1. self.scaleAll = 1. self.setBounds(-1, 1., -1, 1, -1, 1) self.setTranslate(0, 0, 0) self.update() self._transformChanged.emit() def setTranslate(self, x, y, z): newtrans = np.array([x, y, z]) if self._update_value("translate", newtrans): self._translateChanged.emit(x, y, z) self._transformChanged.emit() def addTranslate(self, dx, dy, dz): self.translate = self.translate + np.array([dx, dy, dz]) self._translateChanged.emit(*self.translate) self._transformChanged.emit() def setBounds(self, x1, x2, y1, y2, z1, z2): self.bounds = np.array([x1, x2, y1, y2, z1, z2]) self._boundsChanged.emit(x1, x2, y1, y2, z1, z2) self._transformChanged.emit() def setShowSlice(self, isSlice=True): self.isSlice = isSlice self._transformChanged.emit() def setSliceDim(self, dim): logger.debug("setSliceDim(%s)", dim) if dim >= 0 and dim < 3: self.sliceDim = dim self._sliceDimChanged.emit(dim) self._transformChanged.emit() else: raise ValueError("dim should be in [0,1,2]!") def setSlicePos(self, pos): logger.debug("setSlicePos(%s)", pos) self.slicePos = pos self._slicePosChanged.emit(pos) self._transformChanged.emit() def setPos(self, pos): logger.debug("setPos(%s)", pos) self.dataPos = pos self.dataModel.setPos(pos) self._transformChanged.emit() def setGamma(self, gamma): logger.debug("setGamma(%s)", gamma) self.gamma = gamma self._gammaChanged.emit(self.gamma) self._transformChanged.emit() def setAlphaPow(self, alphaPow): logger.debug("setAlphaPow(%s)", alphaPow) self.alphaPow = alphaPow self._alphaPowChanged.emit(self.alphaPow) self._transformChanged.emit() def setValueScale(self, minVal, maxVal): logger.debug("set scale to %s,%s" % (minVal, maxVal)) self.setMin(minVal) self.setMax(maxVal) def setMin(self, minVal): self.minVal = max(1.e-6, minVal) logger.debug("set min to %s" % (self.minVal)) self._minChanged.emit(self.minVal) self._transformChanged.emit() def setMax(self, maxVal): self.maxVal = maxVal logger.debug("set max to %s" % (self.maxVal)) self._maxChanged.emit(self.maxVal) self._transformChanged.emit() def setStackUnits(self, px, py, pz): self.stackUnits = px, py, pz self._stackUnitsChanged.emit(px, py, pz) self._transformChanged.emit() def setBox(self, isBox=True): self.isBox = isBox self._boxChanged.emit(isBox) self._transformChanged.emit() def setZoom(self, zoom=1.): # self.zoom = np.clip(zoom,.5,2) self.zoom = np.clip(zoom, .3, 2) self.update() self._transformChanged.emit() def addRotation(self, angle, x, y, z, from_left = True): q = Quaternion(np.cos(angle), np.sin(angle) * x, np.sin(angle) * y, np.sin(angle) * z) if from_left: q_new = q*self.quatRot else: q_new = self.quatRot *q self.setQuaternion(q_new) def setRotation(self, angle, x, y, z): self.setQuaternion(Quaternion(np.cos(angle), np.sin(angle) * x, np.sin(angle) * y, np.sin(angle) * z)) def setQuaternion(self, quat): logger.debug("set quaternion to %s", quat.data) self.quatRot = Quaternion.copy(quat) self._rotationChanged.emit() self._transformChanged.emit() def setEyeDistProj(self, eye_dist_proj=0): self.eye_dist_proj = eye_dist_proj self.update() print(self.eye_dist_proj) self._transformChanged.emit() def setEyeDistCam(self, eye_dist_cam=0.): self.eye_dist_cam = eye_dist_cam print(self.eye_dist_cam) self.update() self._transformChanged.emit() def update(self): if self.isPerspective: self.cameraZ = 4 * (1 - np.log(self.zoom) / np.log(2.)) self.scaleAll = 1. else: self.cameraZ = 0. self.scaleAll = 2.5 ** (self.zoom - 1.) def setPerspective(self, isPerspective=True): self.isPerspective = isPerspective if isPerspective: self.projection = mat4_perspective(60., 1., .1, 10) else: self.projection = mat4_ortho(-2., 2., -2., 2., -1.5, 1.5) self.update() self._perspectiveChanged.emit(isPerspective) self._transformChanged.emit() def getProjection(self): return self.projection def getModelView(self): """ returns the modelview with the added internal scale from the rendered volume this should be used when drawing standard opengl primitives with the same trasnformation as the rendered model""" modelView = self.getUnscaledModelView() # scale the interns if hasattr(self, "dataModel"): Nz, Ny, Nx = self.dataModel.size()[1:] dx, dy, dz = self.stackUnits maxDim = max(d * N for d, N in zip([dx, dy, dz], [Nx, Ny, Nz])) mScale = mat4_scale(1. * dx * Nx / maxDim, 1. * dy * Ny / maxDim, 1. * dz * Nz / maxDim) modelView = np.dot(modelView, mScale) return modelView def getUnscaledModelView(self): """this one should be given to the render kernel""" view = mat4_translate(0, 0, -self.cameraZ) model = mat4_scale(*[self.scaleAll] * 3) model = np.dot(model, self.quatRot.toRotation4()) model = np.dot(model, mat4_translate(*self.translate)) # return model return np.dot(view, model) def fromTransformData(self, transformData): self.setQuaternion(transformData.quatRot) self.setZoom(transformData.zoom) self.setPos(transformData.dataPos) self.setBounds(*transformData.bounds) self.setBox(transformData.isBox) self.setIso(transformData.isIso) self.setAlphaPow(transformData.alphaPow) self.setTranslate(*transformData.translate) self.setValueScale(transformData.minVal,transformData.maxVal) self.setGamma(transformData.gamma) self.setValueScale(transformData.minVal, transformData.maxVal) # self.setGamma(transformData.gamma) def toTransformData(self): return TransformData(quatRot=self.quatRot, zoom=self.zoom, dataPos=self.dataPos, minVal=self.minVal, maxVal=self.maxVal, gamma=self.gamma, translate=self.translate, bounds=self.bounds, isBox=self.isBox, isIso=self.isIso, alphaPow=self.alphaPow)
def mat4_rotation(w=0, x=1, y=0, z=0): n = np.array([x, y, z], np.float32) n *= 1./np.sqrt(1.*np.sum(n**2)) q = Quaternion(np.cos(.5*w), *(np.sin(.5*w)*n)) return q.toRotation4()
def addRotation(self, angle, x, y, z): q = Quaternion(np.cos(angle), np.sin(angle) * x, np.sin(angle) * y, np.sin(angle) * z) self.setQuaternion(self.quatRot * q)
def setQuaternion(self, quat): logger.debug("set quaternion to %s", quat.data) self.quatRot = Quaternion.copy(quat) self._rotationChanged.emit() self._transformChanged.emit()
class TransformModel(QtCore.QObject): _maxChanged = QtCore.pyqtSignal(float) _minChanged = QtCore.pyqtSignal(float) _gammaChanged = QtCore.pyqtSignal(float) _boxChanged = QtCore.pyqtSignal(int) _isoChanged = QtCore.pyqtSignal(bool) _interpChanged = QtCore.pyqtSignal(bool) _perspectiveChanged = QtCore.pyqtSignal(int) # _rotationChanged = QtCore.pyqtSignal(float,float,float,float) _rotationChanged = QtCore.pyqtSignal() _translateChanged = QtCore.pyqtSignal(float, float, float) _slicePosChanged = QtCore.pyqtSignal(int) _sliceDimChanged = QtCore.pyqtSignal(int) _boundsChanged = QtCore.pyqtSignal(float, float, float, float, float, float) _transformChanged = QtCore.pyqtSignal() _stackUnitsChanged = QtCore.pyqtSignal(float, float, float) _alphaPowChanged = QtCore.pyqtSignal(float) def __init__(self): super(TransformModel, self).__init__() self.reset() def _update_value(self, name, newval): """update self.name to newval and returns True if the new value indeed was different than the new""" if not hasattr(self, name): setattr(self, name, newval) return True oldval = getattr(self, name) is_equal = True if isinstance(oldval, np.ndarray): is_equal = np.array_equal(oldval, newval) elif isinstance(oldval, Quaternion): is_equal = np.array_equal(oldval.data, newval.data) else: is_equal = (oldval == newval) if not is_equal: setattr(self, name, newval) return not is_equal def setModel(self, dataModel): self.dataModel = dataModel def reset(self, minVal=0., maxVal=256., stackUnits=None): logger.debug("reset: min = %s max = %s" % (minVal, maxVal)) self.dataPos = 0 self.slicePos = 0 self.sliceDim = 0 self.zoom = 1. self.setIso(False) self.isPerspective = True self.setPerspective() self.setValueScale(minVal, maxVal) self.setGamma(1.) self.setAlphaPow(0) self.setBox(True) self.setInterpolate(True) self.setOccStrength() self.setOccRadius() self.setOccNPoints() self.eye_dist_proj = 0 self.eye_dist_cam = 0 if not hasattr(self, "isSlice"): self.setShowSlice(False) if not stackUnits: stackUnits = [.1, .1, .1] self.setStackUnits(*stackUnits) self.center() def setIso(self, isIso): logger.debug("setting Iso %s" % isIso) if self._update_value("isIso", isIso): self._isoChanged.emit(isIso) self._transformChanged.emit() def setInterpolate(self, is_interpolate): logger.debug("setting interpolation %s" % is_interpolate) if self._update_value("is_interpolate", is_interpolate): self._interpChanged.emit(is_interpolate) self._transformChanged.emit() def setOccStrength(self, occ_strength=.15): if self._update_value("occ_strength", occ_strength): self._transformChanged.emit() def setOccRadius(self, val=21): if self._update_value("occ_radius", val): self._transformChanged.emit() def setOccNPoints(self, val=31): if self._update_value("occ_n_points", val): self._transformChanged.emit() def center(self): self.quatRot = Quaternion() self.cameraZ = 5. self.zoom = 1. self.scaleAll = 1. self.setBounds(-1, 1., -1, 1, -1, 1) self.setTranslate(0, 0, 0) self.update() self._transformChanged.emit() def setTranslate(self, x, y, z): newtrans = np.array([x, y, z]) if self._update_value("translate", newtrans): self._translateChanged.emit(x, y, z) self._transformChanged.emit() def addTranslate(self, dx, dy, dz): self.translate = self.translate + np.array([dx, dy, dz]) self._translateChanged.emit(*self.translate) self._transformChanged.emit() def setBounds(self, x1, x2, y1, y2, z1, z2): self.bounds = np.array([x1, x2, y1, y2, z1, z2]) self._boundsChanged.emit(x1, x2, y1, y2, z1, z2) self._transformChanged.emit() def setShowSlice(self, isSlice=True): self.isSlice = isSlice self._transformChanged.emit() def setSliceDim(self, dim): logger.debug("setSliceDim(%s)", dim) if dim >= 0 and dim < 3: self.sliceDim = dim self._sliceDimChanged.emit(dim) self._transformChanged.emit() else: raise ValueError("dim should be in [0,1,2]!") def setSlicePos(self, pos): logger.debug("setSlicePos(%s)", pos) self.slicePos = pos self._slicePosChanged.emit(pos) self._transformChanged.emit() def setPos(self, pos): logger.debug("setPos(%s)", pos) self.dataPos = pos self.dataModel.setPos(pos) self._transformChanged.emit() def setGamma(self, gamma): logger.debug("setGamma(%s)", gamma) self.gamma = gamma self._gammaChanged.emit(self.gamma) self._transformChanged.emit() def setAlphaPow(self, alphaPow): logger.debug("setAlphaPow(%s)", alphaPow) self.alphaPow = alphaPow self._alphaPowChanged.emit(self.alphaPow) self._transformChanged.emit() def setValueScale(self, minVal, maxVal): logger.debug("set scale to %s,%s" % (minVal, maxVal)) self.setMin(minVal) self.setMax(maxVal) def setMin(self, minVal): self.minVal = max(1.e-6, minVal) logger.debug("set min to %s" % (self.minVal)) self._minChanged.emit(self.minVal) self._transformChanged.emit() def setMax(self, maxVal): self.maxVal = maxVal logger.debug("set max to %s" % (self.maxVal)) self._maxChanged.emit(self.maxVal) self._transformChanged.emit() def setStackUnits(self, px, py, pz): self.stackUnits = px, py, pz self._stackUnitsChanged.emit(px, py, pz) self._transformChanged.emit() def setBox(self, isBox=True): self.isBox = isBox self._boxChanged.emit(isBox) self._transformChanged.emit() def setZoom(self, zoom=1.): # self.zoom = np.clip(zoom,.5,2) self.zoom = np.clip(zoom, .3, 2) self.update() self._transformChanged.emit() def addRotation(self, angle, x, y, z, from_left = True): q = Quaternion(np.cos(angle), np.sin(angle) * x, np.sin(angle) * y, np.sin(angle) * z) if from_left: q_new = q*self.quatRot else: q_new = self.quatRot *q self.setQuaternion(q_new) def setRotation(self, angle, x, y, z): self.setQuaternion(Quaternion(np.cos(angle), np.sin(angle) * x, np.sin(angle) * y, np.sin(angle) * z)) def setQuaternion(self, quat): logger.debug("set quaternion to %s", quat.data) self.quatRot = Quaternion.copy(quat) self._rotationChanged.emit() self._transformChanged.emit() def setEyeDistProj(self, eye_dist_proj=0): self.eye_dist_proj = eye_dist_proj self.update() print(self.eye_dist_proj) self._transformChanged.emit() def setEyeDistCam(self, eye_dist_cam=0.): self.eye_dist_cam = eye_dist_cam print(self.eye_dist_cam) self.update() self._transformChanged.emit() def update(self): if self.isPerspective: self.cameraZ = 4 * (1 - np.log(self.zoom) / np.log(2.)) self.scaleAll = 1. else: self.cameraZ = 0. self.scaleAll = 2.5 ** (self.zoom - 1.) def setPerspective(self, isPerspective=True): self.isPerspective = isPerspective if isPerspective: self.projection = mat4_perspective(60., 1., .1, 10) else: self.projection = mat4_ortho(-2., 2., -2., 2., -1.5, 1.5) self.update() self._perspectiveChanged.emit(isPerspective) self._transformChanged.emit() def getProjection(self): return self.projection def getModelView(self): """ returns the modelview with the added internal scale from the rendered volume this should be used when drawing standard opengl primitives with the same trasnformation as the rendered model""" modelView = self.getUnscaledModelView() # scale the interns if hasattr(self, "dataModel"): Nz, Ny, Nx = self.dataModel.size()[1:] dx, dy, dz = self.stackUnits maxDim = max(d * N for d, N in zip([dx, dy, dz], [Nx, Ny, Nz])) mScale = mat4_scale(1. * dx * Nx / maxDim, 1. * dy * Ny / maxDim, 1. * dz * Nz / maxDim) modelView = np.dot(modelView, mScale) return modelView def getUnscaledModelView(self): """this one should be given to the render kernel""" view = mat4_translate(0, 0, -self.cameraZ) model = mat4_scale(*[self.scaleAll] * 3) model = np.dot(model, self.quatRot.toRotation4()) model = np.dot(model, mat4_translate(*self.translate)) # return model return np.dot(view, model) def fromTransformData(self, transformData): self.setQuaternion(transformData.quatRot) self.setZoom(transformData.zoom) self.setPos(transformData.dataPos) self.setBounds(*transformData.bounds) self.setBox(transformData.isBox) self.setIso(transformData.isIso) self.setAlphaPow(transformData.alphaPow) self.setTranslate(*transformData.translate) self.setValueScale(transformData.minVal,transformData.maxVal) self.setGamma(transformData.gamma) self.setValueScale(transformData.minVal, transformData.maxVal) self.setShowSlice(transformData.isSlice) self.setSlicePos(transformData.slicePos) self.setSliceDim(transformData.sliceDim) # self.setGamma(transformData.gamma) def toTransformData(self): return TransformData(quatRot=self.quatRot, zoom=self.zoom, dataPos=self.dataPos, minVal=self.minVal, maxVal=self.maxVal, gamma=self.gamma, translate=self.translate, bounds=self.bounds, isBox=self.isBox, isIso=self.isIso, alphaPow=self.alphaPow, isSlice=self.isSlice, slicePos=self.slicePos, sliceDim = self.sliceDim )
def mat4_rotation(w=0, x=1, y=0, z=0): n = np.array([x, y, z], np.float32) n *= 1. / np.sqrt(1. * np.sum(n**2)) q = Quaternion(np.cos(.5 * w), *(np.sin(.5 * w) * n)) return q.toRotation4()