OGS
GeoTreeModel.cpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright (c) OpenGeoSys Community (opengeosys.org)
2// SPDX-License-Identifier: BSD-3-Clause
3
4#include "GeoTreeModel.h"
5
6#include "Base/OGSError.h"
7#include "BaseLib/Logging.h"
8#include "GeoLib/Triangle.h"
9#include "GeoObjectListItem.h"
10#include "GeoTreeItem.h"
11
16{
17 QList<QVariant> rootData;
18 delete _rootItem;
19 rootData << "Id"
20 << "x"
21 << "y"
22 << "z"
23 << "name ";
24 _rootItem = new GeoTreeItem(rootData, nullptr, nullptr);
25}
26
28
29void GeoTreeModel::addPointList(QString geoName,
30 GeoLib::PointVec const& pointVec)
31{
32 beginResetModel();
33
34 auto const& points = pointVec.getVector();
35
36 QList<QVariant> geoData;
37 geoData << QVariant(geoName) << ""
38 << ""
39 << ""
40 << "";
41 auto* geo(new GeoTreeItem(geoData, _rootItem));
42 _lists.push_back(geo);
43 _rootItem->appendChild(geo);
44
45 QList<QVariant> pointData;
46 pointData << "Points"
47 << ""
48 << ""
49 << ""
50 << "";
51 auto* pointList =
52 new GeoObjectListItem(pointData, geo, &points, GeoLib::GEOTYPE::POINT);
53 geo->appendChild(pointList);
54
55 std::size_t nPoints = points.size();
56
57 for (std::size_t j = 0; j < nPoints; j++)
58 {
59 const GeoLib::Point& pnt(*points[j]);
60 QList<QVariant> pnt_data;
61 pnt_data.reserve(5);
62 pnt_data << static_cast<unsigned>(j) << QString::number(pnt[0], 'f')
63 << QString::number(pnt[1], 'f') << QString::number(pnt[2], 'f')
64 << "";
65 pointList->appendChild(new GeoTreeItem(
66 pnt_data, pointList, static_cast<const GeoLib::Point*>(&pnt)));
67 }
68
69 for (auto pnt = pointVec.getNameIDMapBegin();
70 pnt != pointVec.getNameIDMapEnd();
71 ++pnt)
72 {
73 QVariant pnt_data(pointList->child(pnt->second)
74 ->setData(4, QString::fromStdString(pnt->first)));
75 }
76
77 INFO("Geometry '{:s}' built. {:d} points added.", geoName.toStdString(),
78 nPoints);
79
80 endResetModel();
81}
82
83void GeoTreeModel::addPolylineList(QString geoName,
84 GeoLib::PolylineVec const& polylineVec)
85{
86 beginResetModel();
87
88 int nLists = _rootItem->childCount();
89 TreeItem* geo(nullptr);
90 for (int i = 0; i < nLists; i++)
91 {
92 if (_rootItem->child(i)->data(0).toString().compare(geoName) == 0)
93 {
94 geo = _rootItem->child(i);
95 }
96 }
97
98 if (geo == nullptr)
99 {
100 ERR("GeoTreeModel::addPolylineList(): No corresponding geometry for "
101 "'{:s}' found.",
102 geoName.toStdString());
103 return;
104 }
105
106 auto const& lines = polylineVec.getVector();
107
108 QList<QVariant> plyData;
109 plyData << "Polylines"
110 << ""
111 << ""
112 << "";
113 auto* plyList =
114 new GeoObjectListItem(plyData, geo, &lines, GeoLib::GEOTYPE::POLYLINE);
115 geo->appendChild(plyList);
116 this->addChildren(plyList, polylineVec, 0, lines.size());
117
118 endResetModel();
119}
120
121void GeoTreeModel::appendPolylines(const std::string& name,
122 GeoLib::PolylineVec const& polylineVec)
123{
124 for (auto& list : _lists)
125 {
126 if (name == list->data(0).toString().toStdString())
127 {
128 for (int j = 0; j < list->childCount(); j++)
129 {
130 auto* parent = static_cast<GeoObjectListItem*>(list->child(j));
131 if (GeoLib::GEOTYPE::POLYLINE == parent->getType())
132 {
133 beginResetModel();
134 this->addChildren(parent, polylineVec, parent->childCount(),
135 polylineVec.getVector().size());
136 endResetModel();
137 parent->vtkSource()->Modified();
138 return;
139 }
140 }
141 }
142 }
143 OGSError::box("Error adding polyline to geometry.");
144}
145
147 GeoLib::PolylineVec const& polyline_vec,
148 std::size_t start_index,
149 std::size_t end_index)
150{
151 auto const& lines = polyline_vec.getVector();
152
153 for (std::size_t i = start_index; i < end_index; i++)
154 {
155 QList<QVariant> line_data;
156 line_data.reserve(4);
157 line_data << "Line " + QString::number(i) << ""
158 << ""
159 << "";
160
161 const GeoLib::Polyline& line(*(lines[i]));
162 auto* lineItem(new GeoTreeItem(line_data, plyList, &line));
163 plyList->appendChild(lineItem);
164
165 auto nPoints = static_cast<int>(lines[i]->getNumberOfPoints());
166 for (int j = 0; j < nPoints; j++)
167 {
168 const GeoLib::Point pnt(*(line.getPoint(j)));
169 QList<QVariant> pnt_data;
170 pnt_data.reserve(4);
171 pnt_data << static_cast<int>(line.getPointID(j))
172 << QString::number(pnt[0], 'f')
173 << QString::number(pnt[1], 'f')
174 << QString::number(pnt[2], 'f');
175
176 lineItem->appendChild(new TreeItem(pnt_data, lineItem));
177 }
178 }
179
180 for (auto pnt = polyline_vec.getNameIDMapBegin();
181 pnt != polyline_vec.getNameIDMapEnd();
182 ++pnt)
183 {
184 QVariant pnt_data(plyList->child(pnt->second)
185 ->setData(1, QString::fromStdString(pnt->first)));
186 }
187
188 INFO("{:d} polylines added.", end_index - start_index);
189}
190
191void GeoTreeModel::addSurfaceList(QString geoName,
192 GeoLib::SurfaceVec const& surfaceVec)
193{
194 beginResetModel();
195
196 int nLists = _rootItem->childCount();
197 TreeItem* geo(nullptr);
198 for (int i = 0; i < nLists; i++)
199 {
200 if (_rootItem->child(i)->data(0).toString().compare(geoName) == 0)
201 {
202 geo = _rootItem->child(i);
203 }
204 }
205
206 if (geo == nullptr)
207 {
208 ERR("GeoTreeModel::addSurfaceList(): No corresponding geometry for "
209 "'{:s}' found.",
210 geoName.toStdString());
211 return;
212 }
213
214 auto const& surfaces = surfaceVec.getVector();
215
216 QList<QVariant> sfcData;
217 sfcData << "Surfaces"
218 << ""
219 << ""
220 << "";
221 auto* sfcList = new GeoObjectListItem(sfcData, geo, &surfaces,
223 geo->appendChild(sfcList);
224 this->addChildren(sfcList, surfaceVec, 0, surfaces.size());
225
226 endResetModel();
227}
228
229void GeoTreeModel::appendSurfaces(const std::string& name,
230 GeoLib::SurfaceVec const& surfaceVec)
231{
232 for (auto& list : _lists)
233 {
234 if (name == list->data(0).toString().toStdString())
235 {
236 int nChildren = list->childCount();
237 for (int j = 0; j < nChildren; j++)
238 {
239 auto* parent = static_cast<GeoObjectListItem*>(list->child(j));
240 if (GeoLib::GEOTYPE::SURFACE == parent->getType())
241 {
242 beginResetModel();
243 this->addChildren(parent, surfaceVec, parent->childCount(),
244 surfaceVec.getVector().size());
245 parent->vtkSource()->Modified();
246 endResetModel();
247 return;
248 }
249 }
250 }
251 }
252 OGSError::box("Error adding surface to geometry.");
253}
254
256 GeoLib::SurfaceVec const& surface_vec,
257 std::size_t start_index,
258 std::size_t end_index)
259{
260 auto const& surfaces = surface_vec.getVector();
261
262 const std::vector<GeoLib::Point*>& nodesVec(
263 *(surfaces[start_index]->getPointVec()));
264 for (std::size_t i = start_index; i < end_index; i++)
265 {
266 QList<QVariant> surface;
267 surface.reserve(4);
268 surface << "Surface " + QString::number(i) << ""
269 << ""
270 << "";
271
272 const GeoLib::Surface& sfc(*surfaces[i]);
273 auto* surfaceItem(new GeoTreeItem(surface, sfcList, &sfc));
274 sfcList->appendChild(surfaceItem);
275
276 auto nElems = static_cast<int>(surfaces[i]->getNumberOfTriangles());
277 for (int j = 0; j < nElems; j++)
278 {
279 QList<QVariant> elem;
280 elem.reserve(4);
281 const GeoLib::Triangle& triangle(*sfc[j]);
282 elem << j << static_cast<int>(triangle[0])
283 << static_cast<int>(triangle[1])
284 << static_cast<int>(triangle[2]);
285 auto* child(new TreeItem(elem, surfaceItem));
286 surfaceItem->appendChild(child);
287
288 for (int k = 0; k < 3; k++)
289 {
290 QList<QVariant> node;
291 node.reserve(4);
292 const GeoLib::Point& pnt(*(nodesVec[triangle[k]]));
293 node << static_cast<int>(triangle[k])
294 << QString::number(pnt[0], 'f')
295 << QString::number(pnt[1], 'f')
296 << QString::number(pnt[2], 'f');
297 child->appendChild(new TreeItem(node, child));
298 }
299 }
300 }
301
302 for (auto pnt = surface_vec.getNameIDMapBegin();
303 pnt != surface_vec.getNameIDMapEnd();
304 ++pnt)
305 {
306 QVariant pnt_data(sfcList->child(pnt->second)
307 ->setData(1, QString::fromStdString(pnt->first)));
308 }
309
310 INFO("{:d} surfaces added.", end_index - start_index);
311}
312
313void GeoTreeModel::renameGeometry(std::string const& old_name,
314 std::string const& new_name)
315{
316 for (auto tree_item_entry : _lists)
317 {
318 if (old_name == tree_item_entry->data(0).toString().toStdString())
319 {
320 QVariant new_entry(QString::fromStdString(new_name));
321 tree_item_entry->setData(0, new_entry);
322 break;
323 }
324 }
325 for (auto tree_item_entry : _lists)
326 {
327 if (new_name == tree_item_entry->data(0).toString().toStdString())
328 {
329 INFO("Found tree_item_entry with name '{:s}'.", new_name);
330 }
331 }
332}
333
337void GeoTreeModel::removeGeoList(const std::string& name, GeoLib::GEOTYPE type)
338{
339 for (std::size_t i = 0; i < _lists.size(); i++)
340 {
341 if (name == _lists[i]->data(0).toString().toStdString())
342 {
343 for (int j = 0; j < _lists[i]->childCount(); j++)
344 {
345 if (type == static_cast<GeoObjectListItem*>(_lists[i]->child(j))
346 ->getType())
347 {
348 QModelIndex index = createIndex(j, 0, _lists[i]->child(j));
349 removeRows(0, _lists[i]->child(j)->childCount(), index);
350 removeRows(j, 1, parent(index));
351 break;
352 }
353 }
354 if (_lists[i]->childCount() == 0)
355 {
356 _lists.erase(_lists.begin() + i);
357 removeRows(i, 1, QModelIndex());
358 }
359 }
360 }
361}
362
363vtkPolyDataAlgorithm* GeoTreeModel::vtkSource(const std::string& name,
364 GeoLib::GEOTYPE type) const
365{
366 std::size_t nLists = _lists.size();
367 for (std::size_t i = 0; i < nLists; i++)
368 {
369 if (name == _lists[i]->data(0).toString().toStdString())
370 {
371 for (int j = 0; j < _lists[i]->childCount(); j++)
372 {
373 auto* item =
374 dynamic_cast<GeoObjectListItem*>(_lists[i]->child(j));
375 if (item->getType() == type)
376 {
377 return item->vtkSource();
378 }
379 }
380 }
381 }
382 return nullptr;
383}
384
385void GeoTreeModel::setNameForItem(const std::string& name,
386 GeoLib::GEOTYPE type,
387 std::size_t id,
388 std::string item_name)
389{
390 std::string geo_type_str;
391 int col_idx(1);
392
393 switch (type)
394 {
396 geo_type_str = "Points";
397 col_idx = 4; // for points the name is at a different position
398 break;
400 geo_type_str = "Polylines";
401 break;
403 geo_type_str = "Surfaces";
404 break;
405 default:
406 geo_type_str = "";
407 }
408
409 auto it =
410 find_if(_lists.begin(), _lists.end(),
411 [&name](GeoTreeItem* geo)
412 { return (name == geo->data(0).toString().toStdString()); });
413
414 for (int i = 0; i < (*it)->childCount(); i++)
415 {
416 if (geo_type_str == (*it)->child(i)->data(0).toString().toStdString())
417 {
418 TreeItem* item = (*it)->child(i)->child(id);
419 item->setData(col_idx, QString::fromStdString(item_name));
420 break;
421 }
422 }
423}
void INFO(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:28
void ERR(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:40
This class manages pointers to Points in a std::vector along with a name. It also handles the deletio...
Definition PointVec.h:25
Class Polyline consists mainly of a reference to a point vector and a vector that stores the indices ...
Definition Polyline.h:29
std::size_t getPointID(std::size_t const i) const
Definition Polyline.cpp:149
const Point * getPoint(std::size_t i) const
returns the i-th point contained in the polyline
Definition Polyline.cpp:168
A Surface is represented by Triangles. It consists of a reference to a vector of (pointers to) points...
NameIdMap::const_iterator getNameIDMapBegin() const
Returns the begin of the name id mapping structure.
Definition TemplateVec.h:74
std::size_t size() const
Definition TemplateVec.h:88
std::vector< T * > const & getVector() const
Definition TemplateVec.h:94
NameIdMap::const_iterator getNameIDMapEnd() const
Returns the end of the name id mapping structure.
Definition TemplateVec.h:80
Class Triangle consists of a reference to a point vector and a vector that stores the indices in the ...
Definition Triangle.h:21
A TreeItem containing an additional GeoObject.
Definition GeoTreeItem.h:16
void appendPolylines(const std::string &name, GeoLib::PolylineVec const &polylineVec)
Appends polylines to the "Polyline"-subtree.
void addSurfaceList(QString geoName, GeoLib::SurfaceVec const &surfaceVec)
Adds a subtree "Surfaces" to an existing geometry with the given name.
void addPointList(QString geoName, GeoLib::PointVec const &pointVec)
vtkPolyDataAlgorithm * vtkSource(const std::string &name, GeoLib::GEOTYPE type) const
Returns the vtk-object indicated by type of the geometry indicated by name.
~GeoTreeModel() override
void renameGeometry(std::string const &old_name, std::string const &new_name)
void appendSurfaces(const std::string &name, GeoLib::SurfaceVec const &surfaceVec)
Appends surfaces to the "Surface"-subtree.
void setNameForItem(const std::string &name, GeoLib::GEOTYPE type, std::size_t id, std::string item_name)
void addPolylineList(QString geoName, GeoLib::PolylineVec const &polylineVec)
Adds a subtree "Polylines" to an existing geometry with the given name.
void addChildren(GeoObjectListItem *plyList, GeoLib::PolylineVec const &polyline_vec, std::size_t start_index, std::size_t end_index)
Adds children to the "Polylines" node.
void removeGeoList(const std::string &name, GeoLib::GEOTYPE type)
GeoTreeModel(QObject *parent=nullptr)
std::vector< GeoTreeItem * > _lists
static void box(const QString &e)
Definition OGSError.cpp:13
Objects nodes for the TreeModel.
Definition TreeItem.h:17
void appendChild(TreeItem *item)
Definition TreeItem.cpp:31
TreeItem * child(int row) const
Definition TreeItem.cpp:41
virtual bool setData(int column, const QVariant &value)
Definition TreeItem.cpp:91
bool removeRows(int position, int count, const QModelIndex &parent) override
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const override
Definition TreeModel.cpp:39
QVariant data(const QModelIndex &index, int role) const override
QModelIndex parent(const QModelIndex &index) const override
Definition TreeModel.cpp:70
TreeModel(QObject *parent=nullptr)
Definition TreeModel.cpp:15
TreeItem * _rootItem
Definition TreeModel.h:47
GEOTYPE
Definition GeoType.h:12
TemplateVec< GeoLib::Surface > SurfaceVec
Definition SurfaceVec.h:17
TemplateVec< GeoLib::Polyline > PolylineVec
class PolylineVec encapsulate a std::vector of Polylines additional one can give the vector of polyli...
Definition PolylineVec.h:16