Loading isis/src/control/objs/ControlNet/ControlNet.cpp +83 −46 Original line number Diff line number Diff line Loading @@ -12,6 +12,7 @@ #include <QPair> #include <QScopedPointer> #include <QSet> #include <QStringList> #include <QTime> #include <QVariant> #include <QVector> Loading Loading @@ -384,7 +385,9 @@ namespace Isis { } } foreach(ControlMeasure* measure, point->getMeasures()) { QList< ControlMeasure * > measures = point->getMeasures(); for(int i = 0; i < measures.size(); i++) { ControlMeasure* measure = measures[i]; // Add the measure to the corresponding node QString serial = measure->GetCubeSerialNumber(); m_controlGraph[m_vertexMap[serial]].measures[measure->Parent()] = measure; Loading @@ -392,26 +395,18 @@ namespace Isis { // In this measure's node add connections to the other nodes reachable from // its point if (!point->IsIgnored() && !measure->IsIgnored()) { for (int i = 0; i < point->GetNumMeasures(); i++) { ControlMeasure *cm = point->GetMeasure(i); for (int j = i + 1; j < measures.size(); j++) { ControlMeasure *cm = measures[j]; if (!cm->IsIgnored()) { QString sn = cm->GetCubeSerialNumber(); if (QString::compare(sn, serial) != 0) { // If the edge doesn't already exist, this adds and returns the edge. // If the edge already exists, this just returns it. (The use of a set // forces the edges to be unique.) ImageConnection connection; bool edgeAdded; boost::tie(connection, edgeAdded) = boost::add_edge(m_vertexMap[serial], ImageConnection connection = boost::add_edge(m_vertexMap[serial], m_vertexMap[sn], m_controlGraph); m_controlGraph).first; m_controlGraph[connection].strength++; if (edgeAdded) { emit networkModified(GraphModified); } } } } } Loading @@ -428,41 +423,57 @@ namespace Isis { QString ControlNet::GraphToString() const { QString graphString; typedef boost::graph_traits<Network>::edge_iterator edge_iter; edge_iter ei, ei_end; QStringList images = GetCubeSerials(); images.sort(); for (tie(ei, ei_end) = edges(m_controlGraph); ei != ei_end; ++ei) { ImageVertex sourceImage = source(*ei, m_controlGraph); ImageVertex targetImage = target(*ei, m_controlGraph); if (sourceImage != targetImage) { graphString.append(m_controlGraph[sourceImage].serial); graphString.append( " [" ); QList<ControlPoint*> sourcePoints = m_controlGraph[sourceImage].measures.keys(); for (int i=0; i < sourcePoints.size(); i++) { if (i>0) { graphString.append(", "); QHash<QString, QStringList> imagePointIds; foreach(QString imageSerial, images) { QList<ControlPoint *> imagePoints = m_controlGraph[m_vertexMap[imageSerial]].measures.keys(); QStringList pointIds; foreach(ControlPoint *point, imagePoints) { pointIds.append(point->GetId()); } pointIds.sort(); imagePointIds.insert(imageSerial, pointIds); } graphString.append(sourcePoints[i]->GetId()); foreach(QString imageSerial, images) { QStringList adjacentImages = getAdjacentImages(imageSerial); adjacentImages.sort(); foreach(QString adjacentSerial, adjacentImages) { if (QString::compare(adjacentSerial, imageSerial) < 0) { continue; } // graphString.append(QString::number(m_controlGraph[sourceImage].measures.size())); graphString.append("] --------- "); graphString.append(m_controlGraph[targetImage].serial); graphString.append(" ["); QList<ControlPoint*> targetPoints = m_controlGraph[targetImage].measures.keys(); for (int i=0; i < targetPoints.size(); i++) { if (i>0) { graphString.append(", "); QStringList commonPoints; QList<QString>::const_iterator imageIt = imagePointIds[imageSerial].cbegin(); QList<QString>::const_iterator adjacentIt = imagePointIds[adjacentSerial].cbegin(); while (imageIt != imagePointIds[imageSerial].cend() && adjacentIt != imagePointIds[adjacentSerial].cend()) { int stringDiff = QString::compare(*imageIt, *adjacentIt); if (stringDiff < 0) { imageIt++; } else if(stringDiff == 0) { commonPoints.append(*imageIt); imageIt++; adjacentIt++; } else { adjacentIt++; } graphString.append(targetPoints[i]->GetId()); } // graphString.append(QString::number(m_controlGraph[targetImage].measures.size())); graphString.append("]");// edge strength: ["); // graphString.append(QString::number(m_controlGraph[*ei].strength)); graphString.append(imageSerial); graphString.append(" ----["); graphString.append(commonPoints.join(",")); graphString.append("]---- "); graphString.append(adjacentSerial); graphString.append("\n"); } } return graphString; } Loading Loading @@ -652,7 +663,7 @@ namespace Isis { void ControlNet::measureDeleted(ControlMeasure *measure) { ASSERT(measure); QString serial = measure->GetCubeSerialNumber(); ASSERT(m_vertexGraph->contains(serial)); ASSERT(m_vertexMap.contains(serial)); emit measureRemoved(measure); Loading Loading @@ -904,6 +915,32 @@ namespace Isis { } /** * Get all images connected to a given image by common control points. * * @param serialNumber the serial number of the image to find images adjacent to. * * @returns @b QList<QString> The serial numbers of all adjacent images. */ QList< QString > ControlNet::getAdjacentImages(QString serialNumber) const { if (!ValidateSerialNumber(serialNumber)) { QString msg = "Cube Serial Number [" + serialNumber + "] not found in " "the network"; throw IException(IException::Programmer, msg, _FILEINFO_); } QList< QString > adjacentSerials; AdjacencyIterator adjIt, adjEnd; boost::tie(adjIt, adjEnd) = boost::adjacent_vertices(m_vertexMap[serialNumber], m_controlGraph); for( ; adjIt != adjEnd; adjIt++) { adjacentSerials.append(m_controlGraph[*adjIt].serial); } return adjacentSerials; } /** * Get all the measures pertaining to a given cube serial number * Loading isis/src/control/objs/ControlNet/ControlNet.h +16 −8 Original line number Diff line number Diff line Loading @@ -52,7 +52,8 @@ class QString; namespace Isis { class Camera; class ControlCubeGraphNode; class ControlMeasure; class ControlPoint; class Distance; class Progress; class Pvl; Loading Loading @@ -232,6 +233,12 @@ namespace Isis { * group to set radii values to those ingested from the versioner * if they exist. Otherwise, we call SetTarget with the targetname. * Fixes #5361. * @history 2018-06-06 Jesse Mapel - Added a method to get all adjacent images to ControlNet. * Previously this functionality was only available through the * ControlCubeGraphNode class. References #5434. * @history 2018-06-06 Jesse Mapel - Added a method to get all adjacent images to ControlNet. * Previously this functionality was only available through the * ControlCubeGraphNode class. References #5434. * @history 2018-06-15 Adam Goins & Jesse Mapel - Added the ModType enum, as well as a series * of signals that are emitted whenever a change is made to a * Control Point or any of it's measures, or to the network itself. Loading @@ -252,10 +259,6 @@ namespace Isis { GraphModified }; QList< ControlCubeGraphNode * > GetCubeGraphNodes() { QList<ControlCubeGraphNode *> lst; return lst;} ; // TEMPORARY DELETE ControlNet(); ControlNet(const ControlNet &other); ControlNet(const QString &filename, Progress *progress = 0); Loading @@ -278,6 +281,7 @@ namespace Isis { QString GraphToString() const; QList< QList< QString > > GetSerialConnections() const; int getEdgeCount() const; QList< QString > getAdjacentImages(QString serialNumber) const; QList< ControlMeasure * > GetMeasuresInCube(QString serialNumber); QList< ControlMeasure * > GetValidMeasuresInCube(QString serialNumber); QList< ControlMeasure * > sortedMeasureList(double(ControlMeasure::*statFunc)() const, Loading Loading @@ -400,8 +404,6 @@ namespace Isis { //! hash ControlPoints by ControlPoint Id QHash< QString, ControlPoint * > * points; //! hash ControlCubeGraphNodes by CubeSerialNumber // structs and typedefs for the boost graph struct Image { QString serial; Loading @@ -412,12 +414,18 @@ namespace Isis { int strength = 0; }; typedef boost::adjacency_list<boost::setS, boost::listS, boost::undirectedS, Image, Connection> Network; typedef boost::adjacency_list<boost::setS, boost::listS, boost::undirectedS, Image, Connection> Network; typedef Network::vertex_descriptor ImageVertex; typedef Network::edge_descriptor ImageConnection; typedef std::map<ImageVertex, size_t> VertexIndexMap; typedef boost::associative_property_map<VertexIndexMap> VertexIndexMapAdaptor; typedef Network::out_edge_iterator ConnectionIterator; typedef boost::graph_traits<Network>::adjacency_iterator AdjacencyIterator; QHash<QString, ImageVertex> m_vertexMap; //!< The SN -> vertex hash for the boost graph Network m_controlGraph; //!< The boost graph QStringList *pointIds; Loading Loading
isis/src/control/objs/ControlNet/ControlNet.cpp +83 −46 Original line number Diff line number Diff line Loading @@ -12,6 +12,7 @@ #include <QPair> #include <QScopedPointer> #include <QSet> #include <QStringList> #include <QTime> #include <QVariant> #include <QVector> Loading Loading @@ -384,7 +385,9 @@ namespace Isis { } } foreach(ControlMeasure* measure, point->getMeasures()) { QList< ControlMeasure * > measures = point->getMeasures(); for(int i = 0; i < measures.size(); i++) { ControlMeasure* measure = measures[i]; // Add the measure to the corresponding node QString serial = measure->GetCubeSerialNumber(); m_controlGraph[m_vertexMap[serial]].measures[measure->Parent()] = measure; Loading @@ -392,26 +395,18 @@ namespace Isis { // In this measure's node add connections to the other nodes reachable from // its point if (!point->IsIgnored() && !measure->IsIgnored()) { for (int i = 0; i < point->GetNumMeasures(); i++) { ControlMeasure *cm = point->GetMeasure(i); for (int j = i + 1; j < measures.size(); j++) { ControlMeasure *cm = measures[j]; if (!cm->IsIgnored()) { QString sn = cm->GetCubeSerialNumber(); if (QString::compare(sn, serial) != 0) { // If the edge doesn't already exist, this adds and returns the edge. // If the edge already exists, this just returns it. (The use of a set // forces the edges to be unique.) ImageConnection connection; bool edgeAdded; boost::tie(connection, edgeAdded) = boost::add_edge(m_vertexMap[serial], ImageConnection connection = boost::add_edge(m_vertexMap[serial], m_vertexMap[sn], m_controlGraph); m_controlGraph).first; m_controlGraph[connection].strength++; if (edgeAdded) { emit networkModified(GraphModified); } } } } } Loading @@ -428,41 +423,57 @@ namespace Isis { QString ControlNet::GraphToString() const { QString graphString; typedef boost::graph_traits<Network>::edge_iterator edge_iter; edge_iter ei, ei_end; QStringList images = GetCubeSerials(); images.sort(); for (tie(ei, ei_end) = edges(m_controlGraph); ei != ei_end; ++ei) { ImageVertex sourceImage = source(*ei, m_controlGraph); ImageVertex targetImage = target(*ei, m_controlGraph); if (sourceImage != targetImage) { graphString.append(m_controlGraph[sourceImage].serial); graphString.append( " [" ); QList<ControlPoint*> sourcePoints = m_controlGraph[sourceImage].measures.keys(); for (int i=0; i < sourcePoints.size(); i++) { if (i>0) { graphString.append(", "); QHash<QString, QStringList> imagePointIds; foreach(QString imageSerial, images) { QList<ControlPoint *> imagePoints = m_controlGraph[m_vertexMap[imageSerial]].measures.keys(); QStringList pointIds; foreach(ControlPoint *point, imagePoints) { pointIds.append(point->GetId()); } pointIds.sort(); imagePointIds.insert(imageSerial, pointIds); } graphString.append(sourcePoints[i]->GetId()); foreach(QString imageSerial, images) { QStringList adjacentImages = getAdjacentImages(imageSerial); adjacentImages.sort(); foreach(QString adjacentSerial, adjacentImages) { if (QString::compare(adjacentSerial, imageSerial) < 0) { continue; } // graphString.append(QString::number(m_controlGraph[sourceImage].measures.size())); graphString.append("] --------- "); graphString.append(m_controlGraph[targetImage].serial); graphString.append(" ["); QList<ControlPoint*> targetPoints = m_controlGraph[targetImage].measures.keys(); for (int i=0; i < targetPoints.size(); i++) { if (i>0) { graphString.append(", "); QStringList commonPoints; QList<QString>::const_iterator imageIt = imagePointIds[imageSerial].cbegin(); QList<QString>::const_iterator adjacentIt = imagePointIds[adjacentSerial].cbegin(); while (imageIt != imagePointIds[imageSerial].cend() && adjacentIt != imagePointIds[adjacentSerial].cend()) { int stringDiff = QString::compare(*imageIt, *adjacentIt); if (stringDiff < 0) { imageIt++; } else if(stringDiff == 0) { commonPoints.append(*imageIt); imageIt++; adjacentIt++; } else { adjacentIt++; } graphString.append(targetPoints[i]->GetId()); } // graphString.append(QString::number(m_controlGraph[targetImage].measures.size())); graphString.append("]");// edge strength: ["); // graphString.append(QString::number(m_controlGraph[*ei].strength)); graphString.append(imageSerial); graphString.append(" ----["); graphString.append(commonPoints.join(",")); graphString.append("]---- "); graphString.append(adjacentSerial); graphString.append("\n"); } } return graphString; } Loading Loading @@ -652,7 +663,7 @@ namespace Isis { void ControlNet::measureDeleted(ControlMeasure *measure) { ASSERT(measure); QString serial = measure->GetCubeSerialNumber(); ASSERT(m_vertexGraph->contains(serial)); ASSERT(m_vertexMap.contains(serial)); emit measureRemoved(measure); Loading Loading @@ -904,6 +915,32 @@ namespace Isis { } /** * Get all images connected to a given image by common control points. * * @param serialNumber the serial number of the image to find images adjacent to. * * @returns @b QList<QString> The serial numbers of all adjacent images. */ QList< QString > ControlNet::getAdjacentImages(QString serialNumber) const { if (!ValidateSerialNumber(serialNumber)) { QString msg = "Cube Serial Number [" + serialNumber + "] not found in " "the network"; throw IException(IException::Programmer, msg, _FILEINFO_); } QList< QString > adjacentSerials; AdjacencyIterator adjIt, adjEnd; boost::tie(adjIt, adjEnd) = boost::adjacent_vertices(m_vertexMap[serialNumber], m_controlGraph); for( ; adjIt != adjEnd; adjIt++) { adjacentSerials.append(m_controlGraph[*adjIt].serial); } return adjacentSerials; } /** * Get all the measures pertaining to a given cube serial number * Loading
isis/src/control/objs/ControlNet/ControlNet.h +16 −8 Original line number Diff line number Diff line Loading @@ -52,7 +52,8 @@ class QString; namespace Isis { class Camera; class ControlCubeGraphNode; class ControlMeasure; class ControlPoint; class Distance; class Progress; class Pvl; Loading Loading @@ -232,6 +233,12 @@ namespace Isis { * group to set radii values to those ingested from the versioner * if they exist. Otherwise, we call SetTarget with the targetname. * Fixes #5361. * @history 2018-06-06 Jesse Mapel - Added a method to get all adjacent images to ControlNet. * Previously this functionality was only available through the * ControlCubeGraphNode class. References #5434. * @history 2018-06-06 Jesse Mapel - Added a method to get all adjacent images to ControlNet. * Previously this functionality was only available through the * ControlCubeGraphNode class. References #5434. * @history 2018-06-15 Adam Goins & Jesse Mapel - Added the ModType enum, as well as a series * of signals that are emitted whenever a change is made to a * Control Point or any of it's measures, or to the network itself. Loading @@ -252,10 +259,6 @@ namespace Isis { GraphModified }; QList< ControlCubeGraphNode * > GetCubeGraphNodes() { QList<ControlCubeGraphNode *> lst; return lst;} ; // TEMPORARY DELETE ControlNet(); ControlNet(const ControlNet &other); ControlNet(const QString &filename, Progress *progress = 0); Loading @@ -278,6 +281,7 @@ namespace Isis { QString GraphToString() const; QList< QList< QString > > GetSerialConnections() const; int getEdgeCount() const; QList< QString > getAdjacentImages(QString serialNumber) const; QList< ControlMeasure * > GetMeasuresInCube(QString serialNumber); QList< ControlMeasure * > GetValidMeasuresInCube(QString serialNumber); QList< ControlMeasure * > sortedMeasureList(double(ControlMeasure::*statFunc)() const, Loading Loading @@ -400,8 +404,6 @@ namespace Isis { //! hash ControlPoints by ControlPoint Id QHash< QString, ControlPoint * > * points; //! hash ControlCubeGraphNodes by CubeSerialNumber // structs and typedefs for the boost graph struct Image { QString serial; Loading @@ -412,12 +414,18 @@ namespace Isis { int strength = 0; }; typedef boost::adjacency_list<boost::setS, boost::listS, boost::undirectedS, Image, Connection> Network; typedef boost::adjacency_list<boost::setS, boost::listS, boost::undirectedS, Image, Connection> Network; typedef Network::vertex_descriptor ImageVertex; typedef Network::edge_descriptor ImageConnection; typedef std::map<ImageVertex, size_t> VertexIndexMap; typedef boost::associative_property_map<VertexIndexMap> VertexIndexMapAdaptor; typedef Network::out_edge_iterator ConnectionIterator; typedef boost::graph_traits<Network>::adjacency_iterator AdjacencyIterator; QHash<QString, ImageVertex> m_vertexMap; //!< The SN -> vertex hash for the boost graph Network m_controlGraph; //!< The boost graph QStringList *pointIds; Loading