Developer Documentation
PropertyNameListModel.cc
1 /*===========================================================================*\
2 * *
3 * OpenFlipper *
4  * Copyright (c) 2001-2015, RWTH-Aachen University *
5  * Department of Computer Graphics and Multimedia *
6  * All rights reserved. *
7  * www.openflipper.org *
8  * *
9  *---------------------------------------------------------------------------*
10  * This file is part of OpenFlipper. *
11  *---------------------------------------------------------------------------*
12  * *
13  * Redistribution and use in source and binary forms, with or without *
14  * modification, are permitted provided that the following conditions *
15  * are met: *
16  * *
17  * 1. Redistributions of source code must retain the above copyright notice, *
18  * this list of conditions and the following disclaimer. *
19  * *
20  * 2. Redistributions in binary form must reproduce the above copyright *
21  * notice, this list of conditions and the following disclaimer in the *
22  * documentation and/or other materials provided with the distribution. *
23  * *
24  * 3. Neither the name of the copyright holder nor the names of its *
25  * contributors may be used to endorse or promote products derived from *
26  * this software without specific prior written permission. *
27  * *
28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
29  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
31  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
33  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
34  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
35  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
36  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
37  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
38  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
39 * *
40 \*===========================================================================*/
41 
42 
43 
44 #include "PropertyNameListModel.hh"
45 
46 #include <OpenMesh/Core/Utils/Property.hh>
47 #include <ACG/Math/VectorT.hh>
48 
49 #include <iostream>
50 
51 const PropertyNameListModel::TypeInfoWrapper PropertyNameListModel::proptype_bool =
53 const PropertyNameListModel::TypeInfoWrapper PropertyNameListModel::proptype_int =
55 const PropertyNameListModel::TypeInfoWrapper PropertyNameListModel::proptype_uint =
57 const PropertyNameListModel::TypeInfoWrapper PropertyNameListModel::proptype_double =
59 const PropertyNameListModel::TypeInfoWrapper PropertyNameListModel::proptype_Vec3d =
61 const PropertyNameListModel::TypeInfoWrapper PropertyNameListModel::proptype_Vec3f =
63 const PropertyNameListModel::TypeInfoWrapper PropertyNameListModel::proptype_Vec2d =
65 const PropertyNameListModel::TypeInfoWrapper PropertyNameListModel::proptype_Vec2f =
67 
68 #ifdef ENABLE_SKELETON_SUPPORT
69  #include <ObjectTypes/Skeleton/BaseSkin.hh>
70  const PropertyNameListModel::TypeInfoWrapper PropertyNameListModel::proptype_SkinWeights =
72 #endif
73 
74 /*
75  * I'd love to do this with boost::assign but I'm not allowed to. :-(
76  */
77 
78 const PropertyNameListModel::TypeInfoWrapper PropertyNameListModel::prop_types[] = {
79  proptype_bool,
80  proptype_int,
81  proptype_uint,
82  proptype_double,
83  proptype_Vec3d,
84  proptype_Vec3f,
85  proptype_Vec2d,
86  proptype_Vec2f,
87 #ifdef ENABLE_SKELETON_SUPPORT
88  proptype_SkinWeights,
89 #endif
90 };
91 
92 #ifdef ENABLE_SKELETON_SUPPORT
93 const PropertyNameListModel::TYPE_INFO_SET PropertyNameListModel::sane_prop_types(prop_types, prop_types + 9);
94 #else
95 const PropertyNameListModel::TYPE_INFO_SET PropertyNameListModel::sane_prop_types(prop_types, prop_types + 8);
96 #endif
97 
98 const char *PropertyNameListModel::entity2str(ENTITY_FILTER entity) {
99  switch (entity) {
100  case EF_EDGE:
101  return "→";
102  case EF_FACE:
103  return "△";
104  case EF_HALFEDGE:
105  return "⇀";
106  case EF_VERTEX:
107  return "•";
108  default:
109  return "error";
110  }
111 }
112 
113 
114 PropertyNameListModel::PropertyNameListModel(QObject *parent) :
115  QAbstractListModel(parent) {
116 }
117 
118 PropertyNameListModel::~PropertyNameListModel() {
119 }
120 
121 int PropertyNameListModel::rowCount(const QModelIndex & parent) const {
122  return propList_.size();
123 }
124 
125 QVariant PropertyNameListModel::data(const QModelIndex & index, int role) const {
126  switch (role) {
127  case Qt::DisplayRole:
128  return propList_[index.row()].toString();
129  default:
130  return QVariant::Invalid;
131  }
132 }
133 
134 QVariant PropertyNameListModel::headerData(int section, Qt::Orientation orientation, int role) const {
135  switch (role) {
136  case Qt::DisplayRole:
137  return tr("Some header. %1 %2").arg(section).arg(orientation);
138  break;
139  default:
140  return QAbstractListModel::headerData(section, orientation, role);
141  }
142 }
143 
144 namespace {
145 class InsDel {
146  public:
147  enum OP { INS, DEL };
148  InsDel(OP op, int first, int count, int before) : op(op), first(first), count(count), before(before) {}
149  OP op;
150  int first, count, before;
151 };
152 }
153 
154 bool PropertyNameListModel::tryInsertionsDeletions(std::vector<PROP_INFO> &propList) {
155 
156  std::vector<InsDel> result;
157  typedef std::vector<PROP_INFO>::iterator IT;
158  int correction = 0;
159  IT oldIt, newIt;
160  for (oldIt = propList_.begin(), newIt = propList.begin(); oldIt < propList_.end() && newIt < propList.end(); ++oldIt, ++newIt) {
161  if (*oldIt == *newIt) continue;
162  const IT nextNew = std::find(newIt+1, propList.end(), *oldIt);
163  if (nextNew != propList.end()) {
164  const int count = std::distance(newIt, nextNew);
165  result.push_back(InsDel(InsDel::INS, std::distance(propList.begin(), newIt), count, std::distance(propList_.begin(), oldIt) + correction));
166  correction += count;
167  newIt += count;
168  continue;
169  }
170  const IT nextOld = std::find(oldIt+1, propList_.end(), *newIt);
171  if (nextOld != propList_.end()) {
172  const int count = std::distance(oldIt, nextOld);
173  result.push_back(InsDel(InsDel::DEL, std::distance(propList_.begin(), oldIt) + correction, count, 0));
174  correction -= count;
175  oldIt += count;
176  continue;
177  }
178  return false;
179  }
180  if (oldIt < propList_.end() && newIt < propList.end()) {
181  return false;
182  }
183 
184  if (oldIt < propList_.end())
185  result.push_back(InsDel(InsDel::DEL, std::distance(propList_.begin(), oldIt) + correction, std::distance(oldIt, propList_.end()), 0));
186  if (newIt < propList.end())
187  result.push_back(InsDel(InsDel::INS, std::distance(propList.begin(), newIt), std::distance(newIt, propList.end()), propList_.size() + correction));
188 
189  for (std::vector<InsDel>::iterator it = result.begin(); it != result.end(); ++it) {
190  if (it->op == InsDel::INS) {
191  beginInsertRows(QModelIndex(), it->before, it->before + it->count - 1);
192  propList_.insert(propList_.begin() + it->before, propList.begin() + it->first, propList.begin() + it->first + it->count);
193  endInsertRows();
194  } else {
195  beginRemoveRows(QModelIndex(), it->first, it->first + it->count - 1);
196  propList_.erase(propList_.begin() + it->first, propList_.begin() + it->first + it->count);
197  endRemoveRows();
198  }
199  }
200 
201  if (propList_ != propList) {
202  std::cerr << "Apparently, the function PropertyNameListModel::tryInsertionsDeletions() has an implementation error." << std::endl;
203  throw std::logic_error("Apparently, the function PropertyNameListModel::tryInsertionsDeletions() has an implementation error.");
204  }
205 
206  return true;
207 }
bool tryInsertionsDeletions(std::vector< PROP_INFO > &propList)
Default property class for any type T.
Definition: Property.hh:89