class EMItem3DInspector(QtGui.QTabWidget): """ Class to make the EMItem GUI controls """ def __init__(self, name, item3d): QtGui.QTabWidget.__init__(self) self.item3d = weakref.ref(item3d) self.name = name self.inspector = None self.transfromboxmaxheight = 400 # This might be problematic self.addTabs() def setInspector(self, inspector): """ This is a reference back to the main inspector, which holds all the item inspectors""" self.inspector = weakref.ref(inspector) def addTabs(self): """ Add a tab for each 'column' """ tabwidget = QtGui.QWidget() gridbox = QtGui.QGridLayout() EMItem3DInspector.addControls(self, gridbox) tabwidget.setLayout(gridbox) self.addTab(tabwidget, "basic") def addControls(self, gridbox): """ Construct all the widgets in this Item Inspector """ # selection box and label font = QtGui.QFont() font.setBold(True) label = QtGui.QLabel(self.name, self) label.setFont(font) label.setAlignment(QtCore.Qt.AlignCenter) gridbox.addWidget(label, 0, 0, 1, 1) databox = QtGui.QHBoxLayout() self.boundingbox = None if self.item3d().boundingboxsize: self.boundingbox = QtGui.QLabel( "Size: " + self.item3d().boundingboxsize, self) databox.addWidget(self.boundingbox) gridbox.addLayout(databox, 1, 0, 1, 1) # angluar controls xformframe = QtGui.QFrame() xformframe.setFrameShape(QtGui.QFrame.StyledPanel) xformbox = QtGui.QGridLayout() xformlabel = QtGui.QLabel("Transformation", xformframe) xformlabel.setFont(font) xformlabel.setAlignment(QtCore.Qt.AlignCenter) xformbox.addWidget(xformlabel, 0, 0, 1, 2) # Rotations self.rotcombobox = QtGui.QComboBox() xformbox.addWidget(self.rotcombobox, 1, 0, 1, 2) self.rotstackedwidget = QtGui.QStackedWidget() self.addRotationWidgets() xformbox.addWidget(self.rotstackedwidget, 2, 0, 1, 2) #translations txlabel = QtGui.QLabel("TX", xformframe) txlabel.setAlignment(QtCore.Qt.AlignCenter) xformbox.addWidget(txlabel, 3, 0, 1, 1) tylabel = QtGui.QLabel("TY", xformframe) tylabel.setAlignment(QtCore.Qt.AlignCenter) xformbox.addWidget(tylabel, 3, 1, 1, 1) self.tx = EMSpinWidget(0.0, 1.0) self.ty = EMSpinWidget(0.0, 1.0) xformbox.addWidget(self.tx, 4, 0, 1, 1) xformbox.addWidget(self.ty, 4, 1, 1, 1) tzlabel = QtGui.QLabel("TZ", xformframe) tzlabel.setAlignment(QtCore.Qt.AlignCenter) xformbox.addWidget(tzlabel, 5, 0, 1, 1) zoomlabel = QtGui.QLabel("Zoom", xformframe) zoomlabel.setAlignment(QtCore.Qt.AlignCenter) xformbox.addWidget(zoomlabel, 5, 1, 1, 1) self.tz = EMSpinWidget(0.0, 1.0) self.zoom = EMSpinWidget(1.0, 0.1, postivemode=True, wheelstep=0.1) xformbox.addWidget(self.tz, 6, 0, 1, 1) xformbox.addWidget(self.zoom, 6, 1, 1, 1) self.resetbuttontx = QtGui.QPushButton("Reset Tx") self.resetbuttonrot = QtGui.QPushButton("Reset Rot") xformbox.addWidget(self.resetbuttontx, 7, 0, 1, 1) xformbox.addWidget(self.resetbuttonrot, 7, 1, 1, 1) xformframe.setLayout(xformbox) xformframe.setMaximumWidth(350) xformframe.setMaximumHeight(self.transfromboxmaxheight) xformframe.setLayout(xformbox) gridbox.addWidget(xformframe, 2, 0, 1, 1) # set to default, but run only as a base class if type(self) == EMItem3DInspector: self.updateItemControls() QtCore.QObject.connect(self.tx, QtCore.SIGNAL("valueChanged(int)"), self._on_translation) QtCore.QObject.connect(self.ty, QtCore.SIGNAL("valueChanged(int)"), self._on_translation) QtCore.QObject.connect(self.tz, QtCore.SIGNAL("valueChanged(int)"), self._on_translation) QtCore.QObject.connect(self.zoom, QtCore.SIGNAL("valueChanged(int)"), self._on_scale) QtCore.QObject.connect(self.resetbuttontx, QtCore.SIGNAL("clicked()"), self._on_resettx) QtCore.QObject.connect(self.resetbuttonrot, QtCore.SIGNAL("clicked()"), self._on_resetrot) def _on_translation(self, value): """ Need to contain the right coords. And do translation in the correct corrd system """ tt = t = Transform({ "tx": self.tx.getValue(), "ty": self.ty.getValue(), "tz": self.tz.getValue() }) tp = self.item3d().getParentMatrixProduct() if tp: tt = tp.inverse() * t self.item3d().getTransform().set_trans(tt.get_trans()) self.inspector().updateSceneGraph() def _on_scale(self, value): self.item3d().getTransform().set_scale(self.zoom.getValue()) self.inspector().updateSceneGraph() def _on_resettx(self): self.item3d().getTransform().set_trans(0.0, 0.0, 0.0) self.updateItemControls() self.inspector().updateSceneGraph() def _on_resetrot(self): self.item3d().getTransform().set_rotation({ "type": "eman", "az": 0.0, "alt": 0.0, "phi": 0.0 }) self.updateItemControls() self.inspector().updateSceneGraph() def _isRotNaN(self, rot1, rot2, rot3): """ Better check to make sure get_rotation did not return Nan, so to prevent a crash """ if rot1 != rot1: return True if rot2 != rot2: return True if rot3 != rot3: return True return False def updateItemControls(self): """ Updates this item inspector. Function is called by the item it observes""" # Translation update stdtransfrom = self.item3d().getTransformStdCoord() translation = stdtransfrom.get_trans() self.tx.setValue(translation[0]) self.ty.setValue(translation[1]) self.tz.setValue(translation[2]) # Rotation update rotation = stdtransfrom.get_rotation( str(self.rotcombobox.currentText())) is_identity = stdtransfrom.is_rot_identity() comboboxidx = self.rotcombobox.currentIndex() if comboboxidx == 0: if self._isRotNaN(rotation["az"], rotation["alt"], rotation["phi"]): return self.emanazslider.setValue(rotation["az"], quiet=1) self.emanaltslider.setValue(rotation["alt"], quiet=1) self.emanphislider.setValue(rotation["phi"], quiet=1) if comboboxidx == 1: if self._isRotNaN(rotation["gamma"], rotation["beta"], rotation["alpha"]): return self.imagicgammaslider.setValue(rotation["gamma"], quiet=1) self.imagicbetaslider.setValue(rotation["beta"], quiet=1) self.imagicalphaslider.setValue(rotation["alpha"], quiet=1) if comboboxidx == 2: if self._isRotNaN(rotation["psi"], rotation["theta"], rotation["phi"]): return self.spiderpsislider.setValue(rotation["psi"], quiet=1) self.spiderthetaslider.setValue(rotation["theta"], quiet=1) self.spiderphislider.setValue(rotation["phi"], quiet=1) if comboboxidx == 3: if self._isRotNaN(rotation["phi"], rotation["theta"], rotation["omega"]): return self.mrcpsislider.setValue(rotation["phi"], quiet=1) self.mrcthetaslider.setValue(rotation["theta"], quiet=1) self.mrcomegaslider.setValue(rotation["omega"], quiet=1) if comboboxidx == 4: if self._isRotNaN(rotation["ztilt"], rotation["ytilt"], rotation["xtilt"]): return self.xyzzslider.setValue(rotation["ztilt"], quiet=1) self.xyzyslider.setValue(rotation["ytilt"], quiet=1) self.xyzxslider.setValue(rotation["xtilt"], quiet=1) if comboboxidx == 5: if self._isRotNaN(rotation["n1"], rotation["n2"], rotation["n3"]): return if is_identity and self.spinn1slider.getValue( ) == 0.0 and self.spinn2slider.getValue( ) == 0.0 and self.spinn3slider.getValue() == 0.0: self.spinomegaslider.setValue(0.0, quiet=1) self.spinn1slider.setValue(0.0, quiet=1) self.spinn2slider.setValue(0.0, quiet=1) self.spinn3slider.setValue(1.0, quiet=1) else: self.spinomegaslider.setValue(rotation["omega"], quiet=1) # Don't change slider if reult is Nan if rotation["n1"] == rotation["n1"]: self.spinn1slider.setValue(rotation["n1"], quiet=1) if rotation["n2"] == rotation["n2"]: self.spinn2slider.setValue(rotation["n2"], quiet=1) if rotation["n3"] == rotation["n3"]: self.spinn3slider.setValue(rotation["n3"], quiet=1) if comboboxidx == 6: if self._isRotNaN(rotation["n1"], rotation["n2"], rotation["n3"]): return if is_identity and self.spinn1slider.getValue( ) == 0.0 and self.spinn2slider.getValue( ) == 0.0 and self.spinn3slider.getValue() == 0.0: self.spinomegaslider.setValue(0.0, quiet=1) self.sgirotn1slider.setValue(0.0, quiet=1) self.sgirotn2slider.setValue(0.0, quiet=1) self.sgirotn3slider.setValue(1.0, quiet=1) else: self.spinomegaslider.setValue(rotation["q"], quiet=1) # Don't change slider if reult is Nan if rotation["n1"] == rotation["n1"]: self.sgirotn1slider.setValue(rotation["n1"], quiet=1) if rotation["n2"] == rotation["n2"]: self.sgirotn2slider.setValue(rotation["n2"], quiet=1) if rotation["n3"] == rotation["n3"]: self.sgirotn3slider.setValue(rotation["n3"], quiet=1) if comboboxidx == 7: if self._isRotNaN(rotation["e1"], rotation["e2"], rotation["e3"]): return if is_identity: self.quaternione0slider.setValue(1.0, quiet=1) self.quaternione1slider.setValue(0.0, quiet=1) self.quaternione2slider.setValue(0.0, quiet=1) self.quaternione3slider.setValue(0.0, quiet=1) else: self.quaternione0slider.setValue(rotation["e0"], quiet=1) self.quaternione1slider.setValue(rotation["e1"], quiet=1) self.quaternione2slider.setValue(rotation["e2"], quiet=1) self.quaternione3slider.setValue(rotation["e3"], quiet=1) # Scaling update self.zoom.setValue(self.item3d().getTransform().get_scale()) def updateMetaData(self): """ I didn't want to put this in update b/c this data doesn't change very often, and I don't want to waste CPU Its a judgement call really, less coupling vs. more efficiency """ if self.boundingbox: self.boundingbox.setText("Size: " + self.item3d().boundingboxsize) def addRotationWidgets(self): """ Add alll the widgets for the various EMAN2 rotation conventions """ EMANwidget = QtGui.QWidget() Imagicwidget = QtGui.QWidget() Spiderwidget = QtGui.QWidget() MRCwidget = QtGui.QWidget() XYZwidget = QtGui.QWidget() spinwidget = QtGui.QWidget() sgirotwidget = QtGui.QWidget() quaternionwidget = QtGui.QWidget() # EMAN emanbox = QtGui.QVBoxLayout() self.emanazslider = ValSlider(EMANwidget, (0.0, 360.0), " Az", rounding=1) self.emanaltslider = ValSlider(EMANwidget, (0.0, 180.0), "Alt", rounding=1) self.emanphislider = ValSlider(EMANwidget, (0.0, 360.0), "Phi", rounding=1) emanbox.addWidget(self.emanazslider) emanbox.addWidget(self.emanaltslider) emanbox.addWidget(self.emanphislider) EMANwidget.setLayout(emanbox) # Imagic imagicbox = QtGui.QVBoxLayout() self.imagicgammaslider = ValSlider(Imagicwidget, (0.0, 360.0), "Gamma", rounding=1) self.imagicbetaslider = ValSlider(Imagicwidget, (0.0, 180.0), " Beta", rounding=1) self.imagicalphaslider = ValSlider(Imagicwidget, (0.0, 360.0), " Alpha", rounding=1) imagicbox.addWidget(self.imagicgammaslider) imagicbox.addWidget(self.imagicbetaslider) imagicbox.addWidget(self.imagicalphaslider) Imagicwidget.setLayout(imagicbox) # Spider spiderbox = QtGui.QVBoxLayout() self.spiderpsislider = ValSlider(Spiderwidget, (0.0, 360.0), " Psi", rounding=1) self.spiderthetaslider = ValSlider(Spiderwidget, (0.0, 180.0), "Theta", rounding=1) self.spiderphislider = ValSlider(Spiderwidget, (0.0, 360.0), " Phi", rounding=1) spiderbox.addWidget(self.spiderpsislider) spiderbox.addWidget(self.spiderthetaslider) spiderbox.addWidget(self.spiderphislider) Spiderwidget.setLayout(spiderbox) # MRC mrcbox = QtGui.QVBoxLayout() self.mrcpsislider = ValSlider(MRCwidget, (0.0, 360.0), " Psi", rounding=1) self.mrcthetaslider = ValSlider(MRCwidget, (0.0, 180.0), " Theta", rounding=1) self.mrcomegaslider = ValSlider(MRCwidget, (0.0, 360.0), "Omega", rounding=1) mrcbox.addWidget(self.mrcpsislider) mrcbox.addWidget(self.mrcthetaslider) mrcbox.addWidget(self.mrcomegaslider) MRCwidget.setLayout(mrcbox) # XYZ xyzbox = QtGui.QVBoxLayout() self.xyzzslider = ValSlider(XYZwidget, (0.0, 360.0), "Z", rounding=1) self.xyzyslider = ValSlider(XYZwidget, (0.0, 180.0), "Y", rounding=1) self.xyzxslider = ValSlider(XYZwidget, (0.0, 360.0), "X", rounding=1) xyzbox.addWidget(self.xyzzslider) xyzbox.addWidget(self.xyzyslider) xyzbox.addWidget(self.xyzxslider) XYZwidget.setLayout(xyzbox) # spin spinbox = QtGui.QVBoxLayout() self.spinomegaslider = ValSlider(spinwidget, (0.0, 180.0), "Omega", rounding=1) self.spinn1slider = ValSlider(spinwidget, (0.0, 1.0), " N1", rounding=4) self.spinn2slider = ValSlider(spinwidget, (0.0, 1.0), " N2", rounding=4) self.spinn3slider = ValSlider(spinwidget, (0.0, 1.0), " N3", rounding=4) spinbox.addWidget(self.spinomegaslider) spinbox.addWidget(self.spinn1slider) spinbox.addWidget(self.spinn2slider) spinbox.addWidget(self.spinn3slider) spinwidget.setLayout(spinbox) # sgirot sgirotbox = QtGui.QVBoxLayout() self.sgirotqslider = ValSlider(sgirotwidget, (0.0, 180.0), " Q", rounding=1) self.sgirotn1slider = ValSlider(sgirotwidget, (0.0, 1.0), "N1", rounding=4) self.sgirotn2slider = ValSlider(sgirotwidget, (0.0, 1.0), "N2", rounding=4) self.sgirotn3slider = ValSlider(sgirotwidget, (0.0, 1.0), "N3", rounding=4) sgirotbox.addWidget(self.sgirotqslider) sgirotbox.addWidget(self.sgirotn1slider) sgirotbox.addWidget(self.sgirotn2slider) sgirotbox.addWidget(self.sgirotn3slider) sgirotwidget.setLayout(sgirotbox) # quaternion quaternionbox = QtGui.QVBoxLayout() self.quaternione0slider = ValSlider(quaternionwidget, (0.0, 1.0), "E0", rounding=4) self.quaternione1slider = ValSlider(quaternionwidget, (0.0, 1.0), "E1", rounding=4) self.quaternione2slider = ValSlider(quaternionwidget, (0.0, 1.0), "E2", rounding=4) self.quaternione3slider = ValSlider(quaternionwidget, (0.0, 1.0), "E3", rounding=4) quaternionbox.addWidget(self.quaternione0slider) quaternionbox.addWidget(self.quaternione1slider) quaternionbox.addWidget(self.quaternione2slider) quaternionbox.addWidget(self.quaternione3slider) quaternionwidget.setLayout(quaternionbox) # Add widgets to the stack self.rotstackedwidget.addWidget(EMANwidget) self.rotstackedwidget.addWidget(Imagicwidget) self.rotstackedwidget.addWidget(Spiderwidget) self.rotstackedwidget.addWidget(MRCwidget) self.rotstackedwidget.addWidget(XYZwidget) self.rotstackedwidget.addWidget(spinwidget) self.rotstackedwidget.addWidget(sgirotwidget) self.rotstackedwidget.addWidget(quaternionwidget) # add choices to combobox self.rotcombobox.addItem("EMAN") self.rotcombobox.addItem("Imagic") self.rotcombobox.addItem("Spider") self.rotcombobox.addItem("MRC") self.rotcombobox.addItem("XYZ") self.rotcombobox.addItem("spin") self.rotcombobox.addItem("sgirot") self.rotcombobox.addItem("quaternion") # Signal for all sliders QtCore.QObject.connect(self.rotcombobox, QtCore.SIGNAL("activated(int)"), self._rotcombobox_changed) QtCore.QObject.connect(self.emanazslider, QtCore.SIGNAL("valueChanged"), self._on_EMAN_rotation) QtCore.QObject.connect(self.emanaltslider, QtCore.SIGNAL("valueChanged"), self._on_EMAN_rotation) QtCore.QObject.connect(self.emanphislider, QtCore.SIGNAL("valueChanged"), self._on_EMAN_rotation) QtCore.QObject.connect(self.imagicgammaslider, QtCore.SIGNAL("valueChanged"), self._on_Imagic_rotation) QtCore.QObject.connect(self.imagicbetaslider, QtCore.SIGNAL("valueChanged"), self._on_Imagic_rotation) QtCore.QObject.connect(self.imagicalphaslider, QtCore.SIGNAL("valueChanged"), self._on_Imagic_rotation) QtCore.QObject.connect(self.spiderpsislider, QtCore.SIGNAL("valueChanged"), self._on_Spider_rotation) QtCore.QObject.connect(self.spiderthetaslider, QtCore.SIGNAL("valueChanged"), self._on_Spider_rotation) QtCore.QObject.connect(self.spiderphislider, QtCore.SIGNAL("valueChanged"), self._on_Spider_rotation) QtCore.QObject.connect(self.mrcpsislider, QtCore.SIGNAL("valueChanged"), self._on_MRC_rotation) QtCore.QObject.connect(self.mrcthetaslider, QtCore.SIGNAL("valueChanged"), self._on_MRC_rotation) QtCore.QObject.connect(self.mrcomegaslider, QtCore.SIGNAL("valueChanged"), self._on_MRC_rotation) QtCore.QObject.connect(self.xyzzslider, QtCore.SIGNAL("valueChanged"), self._on_XYZ_rotation) QtCore.QObject.connect(self.xyzyslider, QtCore.SIGNAL("valueChanged"), self._on_XYZ_rotation) QtCore.QObject.connect(self.xyzxslider, QtCore.SIGNAL("valueChanged"), self._on_XYZ_rotation) QtCore.QObject.connect(self.spinomegaslider, QtCore.SIGNAL("valueChanged"), self._on_spin_rotation) QtCore.QObject.connect(self.spinn1slider, QtCore.SIGNAL("valueChanged"), self._on_spin_rotation) QtCore.QObject.connect(self.spinn2slider, QtCore.SIGNAL("valueChanged"), self._on_spin_rotation) QtCore.QObject.connect(self.spinn3slider, QtCore.SIGNAL("valueChanged"), self._on_spin_rotation) QtCore.QObject.connect(self.sgirotqslider, QtCore.SIGNAL("valueChanged"), self._on_sgirot_rotation) QtCore.QObject.connect(self.sgirotn1slider, QtCore.SIGNAL("valueChanged"), self._on_sgirot_rotation) QtCore.QObject.connect(self.sgirotn2slider, QtCore.SIGNAL("valueChanged"), self._on_sgirot_rotation) QtCore.QObject.connect(self.sgirotn3slider, QtCore.SIGNAL("valueChanged"), self._on_sgirot_rotation) QtCore.QObject.connect(self.quaternione0slider, QtCore.SIGNAL("valueChanged"), self._on_quaternion_rotation) QtCore.QObject.connect(self.quaternione1slider, QtCore.SIGNAL("valueChanged"), self._on_quaternion_rotation) QtCore.QObject.connect(self.quaternione2slider, QtCore.SIGNAL("valueChanged"), self._on_quaternion_rotation) QtCore.QObject.connect(self.quaternione3slider, QtCore.SIGNAL("valueChanged"), self._on_quaternion_rotation) def _rotcombobox_changed(self, idx): self.rotstackedwidget.setCurrentIndex(idx) self.updateItemControls() def _on_EMAN_rotation(self, value): self._set_rotation_std_coords( Transform({ "type": "eman", "az": self.emanazslider.getValue(), "alt": self.emanaltslider.getValue(), "phi": self.emanphislider.getValue() })) self.inspector().updateSceneGraph() def _on_Imagic_rotation(self, value): self._set_rotation_std_coords( Transform({ "type": "imagic", "gamma": self.imagicgammaslider.getValue(), "beta": self.imagicbetaslider.getValue(), "alpha": self.imagicalphaslider.getValue() })) self.inspector().updateSceneGraph() def _on_Spider_rotation(self, value): self._set_rotation_std_coords( Transform({ "type": "spider", "psi": self.spiderpsislider.getValue(), "theta": self.spiderthetaslider.getValue(), "phi": self.spiderphislider.getValue() })) self.inspector().updateSceneGraph() def _on_MRC_rotation(self, value): self._set_rotation_std_coords( Transform({ "type": "mrc", "phi": self.mrcpsislider.getValue(), "theta": self.mrcthetaslider.getValue(), "omega": self.mrcomegaslider.getValue() })) self.inspector().updateSceneGraph() def _on_XYZ_rotation(self, value): self._set_rotation_std_coords( Transform({ "type": "xyz", "ztilt": self.xyzzslider.getValue(), "ytilt": self.xyzyslider.getValue(), "xtilt": self.xyzxslider.getValue() })) self.inspector().updateSceneGraph() def _on_spin_rotation(self, value): v = Vec3f(self.spinn1slider.getValue(), self.spinn2slider.getValue(), self.spinn3slider.getValue()) v.normalize() self._set_rotation_std_coords( Transform({ "type": "spin", "omega": self.spinomegaslider.getValue(), "n1": v[0], "n2": v[1], "n3": v[2] })) self.inspector().updateSceneGraph() def _on_sgirot_rotation(self, value): v = Vec3f(self.sgirotn1slider.getValue(), self.sgirotn2slider.getValue(), self.sgirotn3slider.getValue()) v.normalize() self._set_rotation_std_coords( Transform({ "type": "sgirot", "q": self.sgirotqslider.getValue(), "n1": v[0], "n2": v[1], "n3": v[2] })) self.inspector().updateSceneGraph() def _on_quaternion_rotation(self, value): v = Vec4f(self.quaternione0slider.getValue(), self.quaternione1slider.getValue(), self.quaternione2slider.getValue(), self.quaternione3slider.getValue()) v.normalize() self._set_rotation_std_coords( Transform({ "type": "quaternion", "e0": v[0], "e1": v[1], "e2": v[2], "e3": v[3] })) self.inspector().updateSceneGraph() def _set_rotation_std_coords(self, rotation): """ This function sets the rotation as if there were no preceeding ones, otherwise a rot around Z could be arounf y,x, etc. Works by transforming local coords into global corrds""" tt = rotation tp = self.item3d().getParentMatrixProduct() if tp: tt = tp.inverse() * rotation self.item3d().getTransform().set_rotation(tt.get_rotation())
class EMItem3DInspector(QtGui.QTabWidget): """ Class to make the EMItem GUI controls """ def __init__(self, name, item3d): QtGui.QTabWidget.__init__(self) self.item3d = weakref.ref(item3d) self.name = name self.inspector = None self.transfromboxmaxheight = 400 # This might be problematic self.addTabs() def setInspector(self, inspector): """ This is a reference back to the main inspector, which holds all the item inspectors""" self.inspector = weakref.ref(inspector) def addTabs(self): """ Add a tab for each 'column' """ tabwidget = QtGui.QWidget() gridbox = QtGui.QGridLayout() EMItem3DInspector.addControls(self, gridbox) tabwidget.setLayout(gridbox) self.addTab(tabwidget, "basic") def addControls(self, gridbox): """ Construct all the widgets in this Item Inspector """ # selection box and label font = QtGui.QFont() font.setBold(True) label = QtGui.QLabel(self.name,self) label.setFont(font) label.setAlignment(QtCore.Qt.AlignCenter) gridbox.addWidget(label, 0, 0, 1, 1) databox = QtGui.QHBoxLayout() self.boundingbox = None if self.item3d().boundingboxsize: self.boundingbox = QtGui.QLabel("Size: "+self.item3d().boundingboxsize,self) databox.addWidget(self.boundingbox) gridbox.addLayout(databox, 1, 0, 1, 1) # angluar controls xformframe = QtGui.QFrame() xformframe.setFrameShape(QtGui.QFrame.StyledPanel) xformbox = QtGui.QGridLayout() xformlabel = QtGui.QLabel("Transformation", xformframe) xformlabel.setFont(font) xformlabel.setAlignment(QtCore.Qt.AlignCenter) xformbox.addWidget(xformlabel, 0, 0, 1, 2) # Rotations self.rotcombobox = QtGui.QComboBox() xformbox.addWidget(self.rotcombobox, 1, 0, 1, 2) self.rotstackedwidget = QtGui.QStackedWidget() self.addRotationWidgets() xformbox.addWidget(self.rotstackedwidget, 2, 0, 1, 2) #translations txlabel = QtGui.QLabel("TX",xformframe) txlabel.setAlignment(QtCore.Qt.AlignCenter) xformbox.addWidget(txlabel, 3, 0, 1, 1) tylabel = QtGui.QLabel("TY",xformframe) tylabel.setAlignment(QtCore.Qt.AlignCenter) xformbox.addWidget(tylabel, 3, 1, 1, 1) self.tx = EMSpinWidget(0.0, 1.0) self.ty = EMSpinWidget(0.0, 1.0) xformbox.addWidget(self.tx, 4, 0, 1, 1) xformbox.addWidget(self.ty, 4, 1, 1, 1) tzlabel = QtGui.QLabel("TZ",xformframe) tzlabel.setAlignment(QtCore.Qt.AlignCenter) xformbox.addWidget(tzlabel, 5, 0, 1, 1) zoomlabel = QtGui.QLabel("Zoom",xformframe) zoomlabel.setAlignment(QtCore.Qt.AlignCenter) xformbox.addWidget(zoomlabel, 5, 1, 1, 1) self.tz = EMSpinWidget(0.0, 1.0) self.zoom = EMSpinWidget(1.0, 0.1, postivemode=True, wheelstep=0.1) xformbox.addWidget(self.tz, 6, 0, 1, 1) xformbox.addWidget(self.zoom, 6, 1, 1, 1) self.resetbuttontx = QtGui.QPushButton("Reset Tx") self.resetbuttonrot = QtGui.QPushButton("Reset Rot") xformbox.addWidget(self.resetbuttontx, 7, 0, 1, 1) xformbox.addWidget(self.resetbuttonrot, 7, 1, 1, 1) xformframe.setLayout(xformbox) xformframe.setMaximumWidth(350) xformframe.setMaximumHeight(self.transfromboxmaxheight) xformframe.setLayout(xformbox) gridbox.addWidget(xformframe, 2, 0, 1, 1) # set to default, but run only as a base class if type(self) == EMItem3DInspector: self.updateItemControls() QtCore.QObject.connect(self.tx,QtCore.SIGNAL("valueChanged(int)"),self._on_translation) QtCore.QObject.connect(self.ty,QtCore.SIGNAL("valueChanged(int)"),self._on_translation) QtCore.QObject.connect(self.tz,QtCore.SIGNAL("valueChanged(int)"),self._on_translation) QtCore.QObject.connect(self.zoom,QtCore.SIGNAL("valueChanged(int)"),self._on_scale) QtCore.QObject.connect(self.resetbuttontx,QtCore.SIGNAL("clicked()"),self._on_resettx) QtCore.QObject.connect(self.resetbuttonrot,QtCore.SIGNAL("clicked()"),self._on_resetrot) def _on_translation(self, value): """ Need to contain the right coords. And do translation in the correct corrd system """ tt = t = Transform({"tx":self.tx.getValue(),"ty":self.ty.getValue(),"tz":self.tz.getValue()}) tp = self.item3d().getParentMatrixProduct() if tp: tt = tp.inverse()*t self.item3d().getTransform().set_trans(tt.get_trans()) self.inspector().updateSceneGraph() def _on_scale(self, value): self.item3d().getTransform().set_scale(self.zoom.getValue()) self.inspector().updateSceneGraph() def _on_resettx(self): self.item3d().getTransform().set_trans(0.0, 0.0, 0.0) self.updateItemControls() self.inspector().updateSceneGraph() def _on_resetrot(self): self.item3d().getTransform().set_rotation({"type":"eman","az":0.0,"alt":0.0,"phi":0.0}) self.updateItemControls() self.inspector().updateSceneGraph() def _isRotNaN(self, rot1, rot2, rot3): """ Better check to make sure get_rotation did not return Nan, so to prevent a crash """ if rot1 != rot1: return True if rot2 != rot2: return True if rot3 != rot3: return True return False def updateItemControls(self): """ Updates this item inspector. Function is called by the item it observes""" # Translation update stdtransfrom = self.item3d().getTransformStdCoord() translation = stdtransfrom.get_trans() self.tx.setValue(translation[0]) self.ty.setValue(translation[1]) self.tz.setValue(translation[2]) # Rotation update rotation = stdtransfrom.get_rotation(str(self.rotcombobox.currentText())) is_identity = stdtransfrom.is_rot_identity() comboboxidx = self.rotcombobox.currentIndex() if comboboxidx == 0: if self._isRotNaN(rotation["az"],rotation["alt"],rotation["phi"]): return self.emanazslider.setValue(rotation["az"], quiet=1) self.emanaltslider.setValue(rotation["alt"], quiet=1) self.emanphislider.setValue(rotation["phi"], quiet=1) if comboboxidx == 1: if self._isRotNaN(rotation["gamma"],rotation["beta"],rotation["alpha"]): return self.imagicgammaslider.setValue(rotation["gamma"], quiet=1) self.imagicbetaslider.setValue(rotation["beta"], quiet=1) self.imagicalphaslider.setValue(rotation["alpha"], quiet=1) if comboboxidx == 2: if self._isRotNaN(rotation["psi"],rotation["theta"],rotation["phi"]): return self.spiderpsislider.setValue(rotation["psi"], quiet=1) self.spiderthetaslider.setValue(rotation["theta"], quiet=1) self.spiderphislider.setValue(rotation["phi"], quiet=1) if comboboxidx == 3: if self._isRotNaN(rotation["phi"],rotation["theta"],rotation["omega"]): return self.mrcpsislider.setValue(rotation["phi"], quiet=1) self.mrcthetaslider.setValue(rotation["theta"], quiet=1) self.mrcomegaslider.setValue(rotation["omega"], quiet=1) if comboboxidx == 4: if self._isRotNaN(rotation["ztilt"],rotation["ytilt"],rotation["xtilt"]): return self.xyzzslider.setValue(rotation["ztilt"], quiet=1) self.xyzyslider.setValue(rotation["ytilt"], quiet=1) self.xyzxslider.setValue(rotation["xtilt"], quiet=1) if comboboxidx == 5: if self._isRotNaN(rotation["n1"],rotation["n2"],rotation["n3"]): return if is_identity and self.spinn1slider.getValue() == 0.0 and self.spinn2slider.getValue() == 0.0 and self.spinn3slider.getValue() == 0.0: self.spinomegaslider .setValue(0.0, quiet=1) self.spinn1slider.setValue(0.0, quiet=1) self.spinn2slider.setValue(0.0, quiet=1) self.spinn3slider.setValue(1.0, quiet=1) else: self.spinomegaslider .setValue(rotation["omega"], quiet=1) # Don't change slider if reult is Nan if rotation["n1"] == rotation["n1"]: self.spinn1slider.setValue(rotation["n1"], quiet=1) if rotation["n2"] == rotation["n2"]: self.spinn2slider.setValue(rotation["n2"], quiet=1) if rotation["n3"] == rotation["n3"]: self.spinn3slider.setValue(rotation["n3"], quiet=1) if comboboxidx == 6: if self._isRotNaN(rotation["n1"],rotation["n2"],rotation["n3"]): return if is_identity and self.spinn1slider.getValue() == 0.0 and self.spinn2slider.getValue() == 0.0 and self.spinn3slider.getValue() == 0.0: self.spinomegaslider.setValue(0.0, quiet=1) self.sgirotn1slider.setValue(0.0, quiet=1) self.sgirotn2slider.setValue(0.0, quiet=1) self.sgirotn3slider.setValue(1.0, quiet=1) else: self.spinomegaslider.setValue(rotation["q"], quiet=1) # Don't change slider if reult is Nan if rotation["n1"] == rotation["n1"]: self.sgirotn1slider.setValue(rotation["n1"], quiet=1) if rotation["n2"] == rotation["n2"]: self.sgirotn2slider.setValue(rotation["n2"], quiet=1) if rotation["n3"] == rotation["n3"]: self.sgirotn3slider.setValue(rotation["n3"], quiet=1) if comboboxidx == 7: if self._isRotNaN(rotation["e1"],rotation["e2"],rotation["e3"]): return if is_identity: self.quaternione0slider.setValue(1.0, quiet=1) self.quaternione1slider.setValue(0.0, quiet=1) self.quaternione2slider.setValue(0.0, quiet=1) self.quaternione3slider.setValue(0.0, quiet=1) else: self.quaternione0slider.setValue(rotation["e0"], quiet=1) self.quaternione1slider.setValue(rotation["e1"], quiet=1) self.quaternione2slider.setValue(rotation["e2"], quiet=1) self.quaternione3slider.setValue(rotation["e3"], quiet=1) # Scaling update self.zoom.setValue(self.item3d().getTransform().get_scale()) def updateMetaData(self): """ I didn't want to put this in update b/c this data doesn't change very often, and I don't want to waste CPU Its a judgement call really, less coupling vs. more efficiency """ if self.boundingbox: self.boundingbox.setText("Size: "+self.item3d().boundingboxsize) def addRotationWidgets(self): """ Add alll the widgets for the various EMAN2 rotation conventions """ EMANwidget = QtGui.QWidget() Imagicwidget = QtGui.QWidget() Spiderwidget = QtGui.QWidget() MRCwidget = QtGui.QWidget() XYZwidget = QtGui.QWidget() spinwidget = QtGui.QWidget() sgirotwidget = QtGui.QWidget() quaternionwidget = QtGui.QWidget() # EMAN emanbox = QtGui.QVBoxLayout() self.emanazslider = ValSlider(EMANwidget, (0.0, 360.0), " Az", rounding = 1) self.emanaltslider = ValSlider(EMANwidget, (0.0, 180.0), "Alt", rounding = 1) self.emanphislider = ValSlider(EMANwidget, (0.0, 360.0), "Phi", rounding = 1) emanbox.addWidget(self.emanazslider) emanbox.addWidget(self.emanaltslider) emanbox.addWidget(self.emanphislider) EMANwidget.setLayout(emanbox) # Imagic imagicbox = QtGui.QVBoxLayout() self.imagicgammaslider = ValSlider(Imagicwidget, (0.0, 360.0), "Gamma", rounding = 1) self.imagicbetaslider = ValSlider(Imagicwidget, (0.0, 180.0), " Beta", rounding = 1) self.imagicalphaslider = ValSlider(Imagicwidget, (0.0, 360.0), " Alpha", rounding = 1) imagicbox.addWidget(self.imagicgammaslider) imagicbox.addWidget(self.imagicbetaslider) imagicbox.addWidget(self.imagicalphaslider) Imagicwidget.setLayout(imagicbox) # Spider spiderbox = QtGui.QVBoxLayout() self.spiderpsislider = ValSlider(Spiderwidget, (0.0, 360.0), " Psi", rounding = 1) self.spiderthetaslider = ValSlider(Spiderwidget, (0.0, 180.0), "Theta", rounding = 1) self.spiderphislider = ValSlider(Spiderwidget, (0.0, 360.0), " Phi", rounding = 1) spiderbox.addWidget(self.spiderpsislider) spiderbox.addWidget(self.spiderthetaslider) spiderbox.addWidget(self.spiderphislider) Spiderwidget.setLayout(spiderbox) # MRC mrcbox = QtGui.QVBoxLayout() self.mrcpsislider = ValSlider(MRCwidget, (0.0, 360.0), " Psi", rounding = 1) self.mrcthetaslider = ValSlider(MRCwidget, (0.0, 180.0), " Theta", rounding = 1) self.mrcomegaslider = ValSlider(MRCwidget, (0.0, 360.0), "Omega", rounding = 1) mrcbox.addWidget(self.mrcpsislider) mrcbox.addWidget(self.mrcthetaslider) mrcbox.addWidget(self.mrcomegaslider) MRCwidget.setLayout(mrcbox) # XYZ xyzbox = QtGui.QVBoxLayout() self.xyzzslider = ValSlider(XYZwidget, (0.0, 360.0), "Z", rounding = 1) self.xyzyslider = ValSlider(XYZwidget, (0.0, 180.0), "Y", rounding = 1) self.xyzxslider = ValSlider(XYZwidget, (0.0, 360.0), "X", rounding = 1) xyzbox.addWidget(self.xyzzslider) xyzbox.addWidget(self.xyzyslider) xyzbox.addWidget(self.xyzxslider) XYZwidget.setLayout(xyzbox) # spin spinbox = QtGui.QVBoxLayout() self.spinomegaslider = ValSlider(spinwidget, (0.0, 180.0), "Omega", rounding = 1) self.spinn1slider = ValSlider(spinwidget, (0.0, 1.0), " N1", rounding = 4) self.spinn2slider = ValSlider(spinwidget, (0.0, 1.0), " N2", rounding = 4) self.spinn3slider = ValSlider(spinwidget, (0.0, 1.0), " N3", rounding = 4) spinbox.addWidget(self.spinomegaslider) spinbox.addWidget(self.spinn1slider) spinbox.addWidget(self.spinn2slider) spinbox.addWidget(self.spinn3slider) spinwidget.setLayout(spinbox) # sgirot sgirotbox = QtGui.QVBoxLayout() self.sgirotqslider = ValSlider(sgirotwidget, (0.0, 180.0), " Q", rounding = 1) self.sgirotn1slider = ValSlider(sgirotwidget, (0.0, 1.0), "N1", rounding = 4) self.sgirotn2slider = ValSlider(sgirotwidget, (0.0, 1.0), "N2", rounding = 4) self.sgirotn3slider = ValSlider(sgirotwidget, (0.0, 1.0), "N3", rounding = 4) sgirotbox.addWidget(self.sgirotqslider) sgirotbox.addWidget(self.sgirotn1slider) sgirotbox.addWidget(self.sgirotn2slider) sgirotbox.addWidget(self.sgirotn3slider) sgirotwidget.setLayout(sgirotbox) # quaternion quaternionbox = QtGui.QVBoxLayout() self.quaternione0slider = ValSlider(quaternionwidget, (0.0, 1.0), "E0", rounding = 4) self.quaternione1slider = ValSlider(quaternionwidget, (0.0, 1.0), "E1", rounding = 4) self.quaternione2slider = ValSlider(quaternionwidget, (0.0, 1.0), "E2", rounding = 4) self.quaternione3slider = ValSlider(quaternionwidget, (0.0, 1.0), "E3", rounding = 4) quaternionbox.addWidget(self.quaternione0slider) quaternionbox.addWidget(self.quaternione1slider) quaternionbox.addWidget(self.quaternione2slider) quaternionbox.addWidget(self.quaternione3slider) quaternionwidget.setLayout(quaternionbox) # Add widgets to the stack self.rotstackedwidget.addWidget(EMANwidget) self.rotstackedwidget.addWidget(Imagicwidget) self.rotstackedwidget.addWidget(Spiderwidget) self.rotstackedwidget.addWidget(MRCwidget) self.rotstackedwidget.addWidget(XYZwidget) self.rotstackedwidget.addWidget(spinwidget) self.rotstackedwidget.addWidget(sgirotwidget) self.rotstackedwidget.addWidget(quaternionwidget) # add choices to combobox self.rotcombobox.addItem("EMAN") self.rotcombobox.addItem("Imagic") self.rotcombobox.addItem("Spider") self.rotcombobox.addItem("MRC") self.rotcombobox.addItem("XYZ") self.rotcombobox.addItem("spin") self.rotcombobox.addItem("sgirot") self.rotcombobox.addItem("quaternion") # Signal for all sliders QtCore.QObject.connect(self.rotcombobox, QtCore.SIGNAL("activated(int)"), self._rotcombobox_changed) QtCore.QObject.connect(self.emanazslider,QtCore.SIGNAL("valueChanged"),self._on_EMAN_rotation) QtCore.QObject.connect(self.emanaltslider,QtCore.SIGNAL("valueChanged"),self._on_EMAN_rotation) QtCore.QObject.connect(self.emanphislider,QtCore.SIGNAL("valueChanged"),self._on_EMAN_rotation) QtCore.QObject.connect(self.imagicgammaslider,QtCore.SIGNAL("valueChanged"),self._on_Imagic_rotation) QtCore.QObject.connect(self.imagicbetaslider,QtCore.SIGNAL("valueChanged"),self._on_Imagic_rotation) QtCore.QObject.connect(self.imagicalphaslider,QtCore.SIGNAL("valueChanged"),self._on_Imagic_rotation) QtCore.QObject.connect(self.spiderpsislider,QtCore.SIGNAL("valueChanged"),self._on_Spider_rotation) QtCore.QObject.connect(self.spiderthetaslider,QtCore.SIGNAL("valueChanged"),self._on_Spider_rotation) QtCore.QObject.connect(self.spiderphislider,QtCore.SIGNAL("valueChanged"),self._on_Spider_rotation) QtCore.QObject.connect(self.mrcpsislider,QtCore.SIGNAL("valueChanged"),self._on_MRC_rotation) QtCore.QObject.connect(self.mrcthetaslider,QtCore.SIGNAL("valueChanged"),self._on_MRC_rotation) QtCore.QObject.connect(self.mrcomegaslider,QtCore.SIGNAL("valueChanged"),self._on_MRC_rotation) QtCore.QObject.connect(self.xyzzslider,QtCore.SIGNAL("valueChanged"),self._on_XYZ_rotation) QtCore.QObject.connect(self.xyzyslider,QtCore.SIGNAL("valueChanged"),self._on_XYZ_rotation) QtCore.QObject.connect(self.xyzxslider,QtCore.SIGNAL("valueChanged"),self._on_XYZ_rotation) QtCore.QObject.connect(self.spinomegaslider,QtCore.SIGNAL("valueChanged"),self._on_spin_rotation) QtCore.QObject.connect(self.spinn1slider,QtCore.SIGNAL("valueChanged"),self._on_spin_rotation) QtCore.QObject.connect(self.spinn2slider,QtCore.SIGNAL("valueChanged"),self._on_spin_rotation) QtCore.QObject.connect(self.spinn3slider,QtCore.SIGNAL("valueChanged"),self._on_spin_rotation) QtCore.QObject.connect(self.sgirotqslider,QtCore.SIGNAL("valueChanged"),self._on_sgirot_rotation) QtCore.QObject.connect(self.sgirotn1slider,QtCore.SIGNAL("valueChanged"),self._on_sgirot_rotation) QtCore.QObject.connect(self.sgirotn2slider,QtCore.SIGNAL("valueChanged"),self._on_sgirot_rotation) QtCore.QObject.connect(self.sgirotn3slider,QtCore.SIGNAL("valueChanged"),self._on_sgirot_rotation) QtCore.QObject.connect(self.quaternione0slider,QtCore.SIGNAL("valueChanged"),self._on_quaternion_rotation) QtCore.QObject.connect(self.quaternione1slider,QtCore.SIGNAL("valueChanged"),self._on_quaternion_rotation) QtCore.QObject.connect(self.quaternione2slider,QtCore.SIGNAL("valueChanged"),self._on_quaternion_rotation) QtCore.QObject.connect(self.quaternione3slider,QtCore.SIGNAL("valueChanged"),self._on_quaternion_rotation) def _rotcombobox_changed(self, idx): self.rotstackedwidget.setCurrentIndex(idx) self.updateItemControls() def _on_EMAN_rotation(self, value): self._set_rotation_std_coords(Transform({"type":"eman","az":self.emanazslider.getValue(),"alt":self.emanaltslider.getValue(),"phi":self.emanphislider.getValue()})) self.inspector().updateSceneGraph() def _on_Imagic_rotation(self, value): self._set_rotation_std_coords(Transform({"type":"imagic","gamma":self.imagicgammaslider.getValue(),"beta":self.imagicbetaslider.getValue(),"alpha":self.imagicalphaslider.getValue()})) self.inspector().updateSceneGraph() def _on_Spider_rotation(self, value): self._set_rotation_std_coords(Transform({"type":"spider","psi":self.spiderpsislider.getValue(),"theta":self.spiderthetaslider.getValue(),"phi":self.spiderphislider.getValue()})) self.inspector().updateSceneGraph() def _on_MRC_rotation(self, value): self._set_rotation_std_coords(Transform({"type":"mrc","phi":self.mrcpsislider.getValue(),"theta":self.mrcthetaslider.getValue(),"omega":self.mrcomegaslider.getValue()})) self.inspector().updateSceneGraph() def _on_XYZ_rotation(self, value): self._set_rotation_std_coords(Transform({"type":"xyz","ztilt":self.xyzzslider.getValue(),"ytilt":self.xyzyslider.getValue(),"xtilt":self.xyzxslider.getValue()})) self.inspector().updateSceneGraph() def _on_spin_rotation(self, value): v = Vec3f(self.spinn1slider.getValue(), self.spinn2slider.getValue(), self.spinn3slider.getValue()) v.normalize() self._set_rotation_std_coords(Transform({"type":"spin","omega":self.spinomegaslider.getValue(),"n1":v[0],"n2":v[1],"n3":v[2]})) self.inspector().updateSceneGraph() def _on_sgirot_rotation(self, value): v = Vec3f(self.sgirotn1slider.getValue(), self.sgirotn2slider.getValue(), self.sgirotn3slider.getValue()) v.normalize() self._set_rotation_std_coords(Transform({"type":"sgirot","q":self.sgirotqslider.getValue(),"n1":v[0],"n2":v[1],"n3":v[2]})) self.inspector().updateSceneGraph() def _on_quaternion_rotation(self, value): v = Vec4f(self.quaternione0slider.getValue(), self.quaternione1slider.getValue(), self.quaternione2slider.getValue(), self.quaternione3slider.getValue()) v.normalize() self._set_rotation_std_coords(Transform({"type":"quaternion","e0":v[0],"e1":v[1],"e2":v[2],"e3":v[3]})) self.inspector().updateSceneGraph() def _set_rotation_std_coords(self, rotation): """ This function sets the rotation as if there were no preceeding ones, otherwise a rot around Z could be arounf y,x, etc. Works by transforming local coords into global corrds""" tt = rotation tp = self.item3d().getParentMatrixProduct() if tp: tt = tp.inverse()*rotation self.item3d().getTransform().set_rotation(tt.get_rotation())