/** * \file * \author Karsten Rink * \date 2011-02-07 * \brief Implementation of the GeoTreeModel class. * * \copyright * Copyright (c) 2012-2014, OpenGeoSys Community (http://www.opengeosys.org) * Distributed under a Modified BSD License. * See accompanying file LICENSE.txt or * http://www.opengeosys.org/project/license * */ // ThirdParty/logog #include "logog/include/logog.hpp" #include "GeoObjectListItem.h" #include "GeoTreeItem.h" #include "GeoTreeModel.h" #include "OGSError.h" /** * Constructor. */ GeoTreeModel::GeoTreeModel( QObject* parent ) : TreeModel(parent) { QList<QVariant> rootData; delete _rootItem; rootData << "Id" << "x" << "y" << "z" << "name "; _rootItem = new GeoTreeItem(rootData, NULL, NULL); } GeoTreeModel::~GeoTreeModel() { } void GeoTreeModel::addPointList(QString geoName, GeoLib::PointVec const& pointVec) { const std::vector<GeoLib::Point*>* points = pointVec.getVector(); QList<QVariant> geoData; geoData << QVariant(geoName) << "" << "" << "" << ""; GeoTreeItem* geo (new GeoTreeItem(geoData, _rootItem)); _lists.push_back(geo); _rootItem->appendChild(geo); QList<QVariant> pointData; pointData << "Points" << "" << "" << "" << ""; GeoObjectListItem* pointList = new GeoObjectListItem(pointData, geo, points, GeoLib::GEOTYPE::POINT); geo->appendChild(pointList); size_t nPoints = points->size(); for (size_t j = 0; j < nPoints; j++) { const GeoLib::Point &pnt(*(*points)[j]); QList<QVariant> pnt_data; pnt_data.reserve(5); pnt_data << static_cast<unsigned>(j) << QString::number(pnt[0], 'f') << QString::number(pnt[1], 'f') << QString::number(pnt[2], 'f') << ""; pointList->appendChild(new GeoTreeItem(pnt_data, pointList, static_cast<const GeoLib::Point*>(&pnt))); } for (auto pnt = pointVec.getNameIDMapBegin(); pnt != pointVec.getNameIDMapEnd(); ++pnt) QVariant pnt_data (pointList->child(pnt->second)->setData(4, QString::fromStdString(pnt->first))); INFO("Geometry \"%s\" built. %d points added.", geoName.toStdString().c_str(), nPoints); reset(); } void GeoTreeModel::addPolylineList(QString geoName, GeoLib::PolylineVec const& polylineVec) { int nLists = _rootItem->childCount(); TreeItem* geo(NULL); for (int i = 0; i < nLists; i++) { if (_rootItem->child(i)->data(0).toString().compare(geoName) == 0) geo = _rootItem->child(i); } if (geo == NULL) { ERR("GeoTreeModel::addPolylineList(): No corresponding geometry for \"%s\" found.", geoName.toStdString().c_str()); return; } const std::vector<GeoLib::Polyline*>* lines = polylineVec.getVector(); QList<QVariant> plyData; plyData << "Polylines" << "" << "" << ""; GeoObjectListItem* plyList = new GeoObjectListItem(plyData, geo, lines, GeoLib::GEOTYPE::POLYLINE); geo->appendChild(plyList); this->addChildren(plyList, polylineVec, 0, lines->size()); reset(); } void GeoTreeModel::appendPolylines(const std::string &name, GeoLib::PolylineVec const& polylineVec) { for (size_t i = 0; i < _lists.size(); i++) { if ( name.compare( _lists[i]->data(0).toString().toStdString() ) == 0 ) for (int j = 0; j < _lists[i]->childCount(); j++) { GeoObjectListItem* parent = static_cast<GeoObjectListItem*>(_lists[i]->child(j)); if (GeoLib::GEOTYPE::POLYLINE == parent->getType()) { this->addChildren(parent, polylineVec, parent->childCount(), polylineVec.getVector()->size()); reset(); parent->vtkSource()->Modified(); return; } } } OGSError::box("Error adding polyline to geometry."); } void GeoTreeModel::addChildren(GeoObjectListItem* plyList, GeoLib::PolylineVec const& polyline_vec, size_t start_index, size_t end_index) { const std::vector<GeoLib::Polyline*> lines = *(polyline_vec.getVector()); for (size_t i = start_index; i < end_index; i++) { QList<QVariant> line_data; line_data.reserve(4); line_data << "Line " + QString::number(i) << "" << "" << ""; const GeoLib::Polyline &line(*(lines[i])); GeoTreeItem* lineItem(new GeoTreeItem(line_data, plyList, &line)); plyList->appendChild(lineItem); int nPoints = static_cast<int>(lines[i]->getNumberOfPoints()); for (int j = 0; j < nPoints; j++) { const GeoLib::Point pnt(*(line.getPoint(j))); QList<QVariant> pnt_data; pnt_data.reserve(4); pnt_data << static_cast<int>(line.getPointID(j)) << QString::number(pnt[0], 'f') << QString::number(pnt[1], 'f') << QString::number(pnt[2], 'f'); lineItem->appendChild(new TreeItem(pnt_data, lineItem)); } } for (auto pnt = polyline_vec.getNameIDMapBegin(); pnt != polyline_vec.getNameIDMapEnd(); ++pnt) QVariant pnt_data (plyList->child(pnt->second)->setData(4, QString::fromStdString(pnt->first))); INFO("%d polylines added.", end_index - start_index); } void GeoTreeModel::addSurfaceList(QString geoName, GeoLib::SurfaceVec const& surfaceVec) { int nLists = _rootItem->childCount(); TreeItem* geo(NULL); for (int i = 0; i < nLists; i++) { if (_rootItem->child(i)->data(0).toString().compare(geoName) == 0) geo = _rootItem->child(i); } if (geo == nullptr) { ERR("GeoTreeModel::addSurfaceList(): No corresponding geometry for \"%s\" found.", geoName.toStdString().c_str()); return; } const std::vector<GeoLib::Surface*>* surfaces = surfaceVec.getVector(); QList<QVariant> sfcData; sfcData << "Surfaces" << "" << "" << ""; GeoObjectListItem* sfcList = new GeoObjectListItem(sfcData, geo, surfaces, GeoLib::GEOTYPE::SURFACE); geo->appendChild(sfcList); this->addChildren(sfcList, surfaceVec, 0, surfaces->size()); reset(); } void GeoTreeModel::appendSurfaces(const std::string &name, GeoLib::SurfaceVec const& surfaceVec) { for (size_t i = 0; i < _lists.size(); i++) { if ( name.compare( _lists[i]->data(0).toString().toStdString() ) == 0 ) { int nChildren = _lists[i]->childCount(); for (int j = 0; j < nChildren; j++) { GeoObjectListItem* parent = static_cast<GeoObjectListItem*>(_lists[i]->child(j)); if (GeoLib::GEOTYPE::SURFACE == parent->getType()) { this->addChildren(parent, surfaceVec, parent->childCount(), surfaceVec.getVector()->size()); parent->vtkSource()->Modified(); reset(); return; } } } } OGSError::box("Error adding surface to geometry."); } void GeoTreeModel::addChildren(GeoObjectListItem* sfcList, GeoLib::SurfaceVec const& surface_vec, size_t start_index, size_t end_index) { const std::vector<GeoLib::Surface*>* surfaces = surface_vec.getVector(); const std::vector<GeoLib::Point*> &nodesVec(*((*surfaces)[start_index]->getPointVec())); for (size_t i = start_index; i < end_index; i++) { QList<QVariant> surface; surface.reserve(4); std::string sfc_name(""); surface_vec.getNameOfElementByID(i, sfc_name); surface << "Surface " + QString::number(i) << QString::fromStdString(sfc_name) << "" << ""; const GeoLib::Surface &sfc(*(*surfaces)[i]); GeoTreeItem* surfaceItem(new GeoTreeItem(surface, sfcList, &sfc)); sfcList->appendChild(surfaceItem); int nElems = static_cast<int>((*surfaces)[i]->getNTriangles()); for (int j = 0; j < nElems; j++) { QList<QVariant> elem; elem.reserve(4); const GeoLib::Triangle &triangle(*sfc[j]); elem << j << static_cast<int>(triangle[0]) << static_cast<int>(triangle[1]) << static_cast<int>(triangle[2]); TreeItem* child(new TreeItem(elem, surfaceItem)); surfaceItem->appendChild(child); for (int k = 0; k < 3; k++) { QList<QVariant> node; node.reserve(4); const GeoLib::Point &pnt(*(nodesVec[triangle[k]])); node << static_cast<int>(triangle[k]) << QString::number(pnt[0], 'f') << QString::number(pnt[1], 'f') << QString::number(pnt[2], 'f'); child->appendChild(new TreeItem(node, child)); } } } INFO("%d surfaces added.", end_index - start_index); } /** * Removes the TreeItem with the given name including all its children */ void GeoTreeModel::removeGeoList(const std::string &name, GeoLib::GEOTYPE type) { for (size_t i = 0; i < _lists.size(); i++) if ( name.compare( _lists[i]->data(0).toString().toStdString() ) == 0 ) { for (int j = 0; j < _lists[i]->childCount(); j++) if (type == static_cast<GeoObjectListItem*>(_lists[i]->child(j))->getType()) { QModelIndex index = createIndex(j, 0, _lists[i]->child(j)); removeRows(0, _lists[i]->child(j)->childCount(), index); removeRows(j, 1, parent(index)); break; } if (_lists[i]->childCount() == 0) { _lists.erase(_lists.begin() + i); removeRows(i, 1, QModelIndex()); } } } vtkPolyDataAlgorithm* GeoTreeModel::vtkSource(const std::string &name, GeoLib::GEOTYPE type) const { size_t nLists = _lists.size(); for (size_t i = 0; i < nLists; i++) { if ( name.compare( _lists[i]->data(0).toString().toStdString() ) == 0 ) for (int j = 0; j < _lists[i]->childCount(); j++) { GeoObjectListItem* item = dynamic_cast<GeoObjectListItem*>(_lists[i]->child(j)); if (item->getType() == type) return item->vtkSource(); } } return NULL; } void GeoTreeModel::setNameForItem(const std::string &name, GeoLib::GEOTYPE type, size_t id, std::string item_name) { std::string geo_type_str(""); int col_idx(1); switch(type) { case GeoLib::GEOTYPE::POINT: geo_type_str = "Points"; col_idx = 4; // for points the name is at a different position break; case GeoLib::GEOTYPE::POLYLINE: geo_type_str = "Polylines"; break; case GeoLib::GEOTYPE::SURFACE: geo_type_str = "Surfaces"; break; case GeoLib::GEOTYPE::VOLUME: geo_type_str = "Volumes"; break; default: geo_type_str = ""; } auto it = find_if(_lists.begin(), _lists.end(), [&name](GeoTreeItem* geo) { return (name.compare( geo->data(0).toString().toStdString() ) == 0); }); for (int i = 0; i < (*it)->childCount(); i++) { if ( geo_type_str.compare( (*it)->child(i)->data(0).toString().toStdString() ) == 0 ) { TreeItem* item = (*it)->child(i)->child(id); item->setData(col_idx, QString::fromStdString(item_name)); break; } } }