Forked from
ogs / ogs
23607 commits behind the upstream repository.
-
Karsten Rink authoredKarsten Rink authored
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
GeoTreeModel.cpp 10.37 KiB
/**
* \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;
}
}
}