Isis 3.0 Object Programmers' Reference |
Home |
00001 #include "ControlPointGraphicsItem.h" 00002 00003 #include <float.h> 00004 #include <iostream> 00005 00006 #include <QGraphicsScene> 00007 #include <QGraphicsSceneContextMenuEvent> 00008 #include <QMenu> 00009 #include <QMessageBox> 00010 00011 #include "Constants.h" 00012 #include "ControlMeasure.h" 00013 #include "ControlPoint.h" 00014 #include "FileName.h" 00015 #include "MosaicGraphicsView.h" 00016 #include "MosaicSceneWidget.h" 00017 #include "SerialNumberList.h" 00018 #include "Statistics.h" 00019 00020 using namespace std; 00021 00022 namespace Isis { 00027 ControlPointGraphicsItem::ControlPointGraphicsItem(QPointF center, 00028 QPointF apriori, ControlPoint *cp, SerialNumberList *snList, 00029 MosaicSceneWidget *boundingRectSrc, QGraphicsItem *parent) : 00030 QGraphicsRectItem(parent) { 00031 m_centerPoint = new QPointF(center); 00032 m_mosaicScene = boundingRectSrc; 00033 m_controlPoint = cp; 00034 m_showArrow = false; 00035 m_colorByMeasureCount = false; 00036 m_colorByResidualMagnitude = false; 00037 00038 m_measureCount = -1; 00039 m_residualMagnitude = Null; 00040 00041 setZValue(DBL_MAX); 00042 00043 m_origPoint = new QPointF(apriori); 00044 00045 if(cp->IsIgnored()) 00046 setPen(QPen(Qt::red)); 00047 else if(cp->IsEditLocked()) 00048 setPen(QPen(Qt::magenta)); 00049 else if(cp->GetType() == ControlPoint::Fixed) 00050 setPen(QPen(Qt::green)); 00051 else if(cp->GetType() == ControlPoint::Constrained) 00052 setPen(QPen(Qt::darkGreen)); 00053 else // Free 00054 setPen(QPen(Qt::blue)); 00055 00056 setBrush(Qt::NoBrush); 00057 00058 setToolTip(makeToolTip(snList)); 00059 00060 setRect(calcRect()); 00061 } 00062 00063 00064 ControlPointGraphicsItem::~ControlPointGraphicsItem() { 00065 if(m_centerPoint) { 00066 delete m_centerPoint; 00067 m_centerPoint = NULL; 00068 } 00069 00070 if(m_origPoint) { 00071 delete m_origPoint; 00072 m_origPoint = NULL; 00073 } 00074 00075 m_mosaicScene = NULL; 00076 } 00077 00078 00079 void ControlPointGraphicsItem::paint(QPainter *painter, 00080 const QStyleOptionGraphicsItem *style, QWidget * widget) { 00081 QRectF fullRect = calcRect(); 00082 QRectF crosshairRect = calcCrosshairRect(); 00083 00084 if(crosshairRect.isNull()) 00085 return; 00086 00087 if(rect() != fullRect) { 00088 setRect(fullRect); 00089 } 00090 else { 00091 painter->setPen(pen()); 00092 painter->setBrush(brush()); 00093 00094 QPointF center = crosshairRect.center(); 00095 00096 QPointF centerLeft(crosshairRect.left(), center.y()); 00097 QPointF centerRight(crosshairRect.right(), center.y()); 00098 QPointF centerTop(center.x(), crosshairRect.top()); 00099 QPointF centerBottom(center.x(), crosshairRect.bottom()); 00100 00101 painter->drawLine(centerLeft, centerRight); 00102 painter->drawLine(centerTop, centerBottom); 00103 00104 if(!m_origPoint->isNull() && *m_origPoint != *m_centerPoint 00105 && m_showArrow) { 00106 00107 if (!m_colorByMeasureCount && !m_colorByResidualMagnitude) { 00108 painter->setPen(Qt::black); 00109 painter->setBrush(Qt::black); 00110 } 00111 else { 00112 QColor zeroColor(Qt::black); 00113 QColor fullColor(Qt::green); 00114 00115 bool isColored = false; 00116 00117 if (m_colorByMeasureCount) { 00118 int fullColorMeasureCount = qMax(1, m_measureCount); 00119 int measureCount = m_controlPoint->getMeasures(true).count(); 00120 isColored = (measureCount >= fullColorMeasureCount); 00121 } 00122 else { 00123 fullColor = QColor(Qt::red); 00124 00125 double fullColorErrorMag = 0.0; 00126 00127 if (!IsSpecial(m_residualMagnitude)) { 00128 fullColorErrorMag = m_residualMagnitude; 00129 } 00130 00131 Statistics residualStats; 00132 foreach (ControlMeasure *cm, m_controlPoint->getMeasures(true)) { 00133 residualStats.AddData(cm->GetResidualMagnitude()); 00134 } 00135 00136 if (residualStats.Average() != Null) { 00137 double errorMag = residualStats.Maximum(); 00138 if (errorMag >= fullColorErrorMag) { 00139 isColored = true; 00140 } 00141 } 00142 } 00143 00144 QColor finalColor = isColored? fullColor : zeroColor; 00145 00146 painter->setPen(finalColor); 00147 painter->setBrush(finalColor); 00148 } 00149 00150 painter->drawLine(*m_origPoint, *m_centerPoint); 00151 00152 QPolygonF arrowHead = calcArrowHead(); 00153 painter->drawPolygon(arrowHead); 00154 } 00155 } 00156 } 00157 00158 00159 void ControlPointGraphicsItem::contextMenuEvent( 00160 QGraphicsSceneContextMenuEvent * event) { 00161 QMenu menu; 00162 00163 QAction *title = menu.addAction( 00164 m_controlPoint->GetId()); 00165 title->setEnabled(false); 00166 menu.addSeparator(); 00167 00168 QAction *infoAction = menu.addAction("Show Point Info"); 00169 00170 QAction *selected = menu.exec(event->screenPos()); 00171 00172 if(selected == infoAction) { 00173 QMessageBox::information(m_mosaicScene, "Control Point Information", 00174 toolTip()); 00175 } 00176 } 00177 00178 00179 QRectF ControlPointGraphicsItem::calcRect() const { 00180 QRectF pointRect(calcCrosshairRect()); 00181 00182 if(!m_origPoint->isNull() && pointRect.isValid()) { 00183 // Make the rect contain the orig point 00184 if(pointRect.left() > m_origPoint->x()) { 00185 pointRect.setLeft(m_origPoint->x()); 00186 } 00187 else if(pointRect.right() < m_origPoint->x()) { 00188 pointRect.setRight(m_origPoint->x()); 00189 } 00190 00191 if(pointRect.top() > m_origPoint->y()) { 00192 pointRect.setTop(m_origPoint->y()); 00193 } 00194 else if(pointRect.bottom() < m_origPoint->y()) { 00195 pointRect.setBottom(m_origPoint->y()); 00196 } 00197 } 00198 00199 QPolygonF arrowHead = calcArrowHead(); 00200 00201 if(arrowHead.size() > 2) { 00202 pointRect = pointRect.united(arrowHead.boundingRect()); 00203 } 00204 00205 return pointRect; 00206 } 00207 00208 00209 QRectF ControlPointGraphicsItem::calcCrosshairRect() const { 00210 QRectF pointRect; 00211 00212 if(m_centerPoint && !m_centerPoint->isNull() && m_mosaicScene) { 00213 static const int size = 12; 00214 QPoint findSpotScreen = 00215 m_mosaicScene->getView()->mapFromScene(*m_centerPoint); 00216 QPoint findSpotTopLeftScreen = 00217 findSpotScreen - QPoint(size / 2, size / 2); 00218 00219 QRect pointRectScreen(findSpotTopLeftScreen, QSize(size, size)); 00220 00221 pointRect = 00222 m_mosaicScene->getView()->mapToScene(pointRectScreen).boundingRect(); 00223 } 00224 00225 return pointRect; 00226 } 00227 00228 00229 QPolygonF ControlPointGraphicsItem::calcArrowHead() const { 00230 QPolygonF arrowHead; 00231 00232 if(m_showArrow && !m_origPoint->isNull() && 00233 *m_origPoint != *m_centerPoint) { 00234 QRectF crosshairRect = calcCrosshairRect(); 00235 double headSize = crosshairRect.width() * 4.0 / 5.0; 00236 00237 double crosshairSize = headSize; 00238 00239 // Draw arrow 00240 QPointF lineVector = *m_centerPoint - *m_origPoint; 00241 double lineVectorMag = sqrt(lineVector.x() * lineVector.x() + 00242 lineVector.y() * lineVector.y()); 00243 double thetaPointOnLine = crosshairSize / (2 * (tanf(PI / 6) / 2) * 00244 lineVectorMag); 00245 QPointF pointOnLine = *m_centerPoint - thetaPointOnLine * lineVector; 00246 00247 QPointF normalVector = QPointF(-lineVector.y(), lineVector.x()); 00248 double thetaNormal = crosshairSize / (2 * lineVectorMag); 00249 00250 QPointF leftPoint = pointOnLine + thetaNormal * normalVector; 00251 QPointF rightPoint = pointOnLine - thetaNormal * normalVector; 00252 00253 arrowHead << leftPoint << crosshairRect.center() << rightPoint; 00254 } 00255 00256 return arrowHead; 00257 } 00258 00259 00260 QString ControlPointGraphicsItem::makeToolTip(SerialNumberList *snList) { 00261 QString toolTip = "<div>Point ID: " + 00262 m_controlPoint->GetId(); 00263 toolTip += "<br />Point Type: " + 00264 m_controlPoint->GetPointTypeString(); 00265 toolTip += "<br />Number of Measures: "; 00266 toolTip += toString(m_controlPoint->GetNumMeasures()); 00267 toolTip += "<br />Ignored: "; 00268 toolTip += m_controlPoint->IsIgnored() ? "Yes" : "No"; 00269 toolTip += "<br />Edit Locked: "; 00270 toolTip += m_controlPoint->IsEditLocked() ? "Yes" : "No"; 00271 00272 toolTip += "<br />"; 00273 00274 if(snList == NULL) { 00275 toolTip += QStringList(m_controlPoint->getCubeSerialNumbers()).join("\n"); 00276 } 00277 else { 00278 QStringList serialNums(m_controlPoint->getCubeSerialNumbers()); 00279 00280 for(int snIndex = 0; snIndex < serialNums.size(); snIndex ++) { 00281 QString serialNum = serialNums[snIndex]; 00282 00283 if(snIndex > 0) 00284 toolTip += "<br />"; 00285 00286 if(snList->HasSerialNumber(serialNum)) { 00287 toolTip += 00288 FileName(snList->FileName(serialNum)).name(); 00289 toolTip += " (" + serialNum + ")"; 00290 } 00291 else { 00292 toolTip += serialNum; 00293 } 00294 00295 double residMag = m_controlPoint->GetMeasure(serialNum)->GetResidualMagnitude(); 00296 if (residMag != Null) { 00297 toolTip += " [residual: <font color='red'>" + toString(residMag) + "</font>]"; 00298 } 00299 } 00300 } 00301 00302 toolTip += "</div>"; 00303 00304 return toolTip; 00305 } 00306 } 00307