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