gmsh-TingyuanDoc  0.1
An Open-Source Timing-driven Analytical Mixed-size FPGA Placer
PViewData.cpp
Go to the documentation of this file.
1 // Gmsh - Copyright (C) 1997-2022 C. Geuzaine, J.-F. Remacle
2 //
3 // See the LICENSE.txt file in the Gmsh root directory for license information.
4 // Please report all issues on https://gitlab.onelab.info/gmsh/gmsh/issues.
5 
6 #include "PViewData.h"
7 #include "adaptiveData.h"
8 #include "Numeric.h"
9 #include "GmshMessage.h"
10 #include "OctreePost.h"
11 #include "fullMatrix.h"
12 
13 std::map<std::string, interpolationMatrices> PViewData::_interpolationSchemes;
14 
16  : _dirty(true), _fileIndex(0), _octree(nullptr), _pc2kdtree(_pc),
17  _kdtree(nullptr), _adaptive(nullptr)
18 {
19 }
20 
22 {
23  if(_adaptive) delete _adaptive;
24  for(auto it = _interpolation.begin(); it != _interpolation.end(); it++)
25  for(std::size_t i = 0; i < it->second.size(); i++) delete it->second[i];
26  if(_octree) delete _octree;
27  if(_kdtree) delete _kdtree;
28 }
29 
30 bool PViewData::finalize(bool computeMinMax,
31  const std::string &interpolationScheme)
32 {
33  _dirty = false;
34  return true;
35 }
36 
37 void PViewData::initAdaptiveData(int step, int level, double tol)
38 {
39  if(!_adaptive) {
40  Msg::Debug("Initializing adaptive data %p interp size=%d", this,
41  _interpolation.size());
42  _adaptive = new adaptiveData(this);
43  _adaptive->changeResolution(step, level, tol);
44  }
45 }
46 
47 void PViewData::initAdaptiveDataLight(int step, int level, double tol)
48 {
49  if(!_adaptive) {
50  Msg::Debug("Initializing adaptive data %p interp size=%d", this,
51  _interpolation.size());
52  // _outData in adaptive.h is only used for visualization of adapted views in
53  // the GMSH GUI. In some cases (export of adapted views under pvtu format,
54  // use of GMSH as external lib), this object is not needed so avoid its
55  // allocation in order to limit memory consumption
56  bool outDataInit = false;
57  _adaptive = new adaptiveData(this, outDataInit);
58  }
59 }
60 
61 void PViewData::saveAdaptedViewForVTK(const std::string &guifileName,
62  int useDefaultName, int step, int level,
63  double tol, int npart, bool isBinary)
64 {
65  if(_adaptive) {
66  // _adaptiveData has already been allocated from the adaptive view panel of
67  // the GUI for instance.
68  _adaptive->changeResolutionForVTK(step, level, tol, npart, isBinary,
69  guifileName, useDefaultName);
70  }
71  else {
72  initAdaptiveDataLight(step, level, tol);
73  _adaptive->changeResolutionForVTK(step, level, tol, npart, isBinary,
74  guifileName, useDefaultName);
76  }
77 }
78 
80 {
81  if(_adaptive) delete _adaptive;
82  _adaptive = nullptr;
83 }
84 
86 {
87  return (!getNumElements() && !getNumStrings2D() && !getNumStrings3D());
88 }
89 
90 bool PViewData::skipElement(int step, int ent, int ele, bool checkVisibility,
91  int samplingRate)
92 {
93  if(samplingRate <= 1) return false;
94  return ele % samplingRate;
95 }
96 
97 void PViewData::getScalarValue(int step, int ent, int ele, int nod, double &val,
98  int tensorRep, int forceNumComponents,
99  int componentMap[9])
100 {
101  int numComp = getNumComponents(step, ent, ele);
102  if(forceNumComponents && componentMap) {
103  std::vector<double> d(forceNumComponents);
104  for(int i = 0; i < forceNumComponents; i++) {
105  int comp = componentMap[i];
106  if(comp >= 0 && comp < numComp)
107  getValue(step, ent, ele, nod, comp, d[i]);
108  else
109  d[i] = 0.;
110  }
111  val = ComputeScalarRep(forceNumComponents, &d[0], tensorRep);
112  }
113  else if(numComp == 1) {
114  getValue(step, ent, ele, nod, 0, val);
115  }
116  else {
117  std::vector<double> d(numComp);
118  for(int comp = 0; comp < numComp; comp++)
119  getValue(step, ent, ele, nod, comp, d[comp]);
120  val = ComputeScalarRep(numComp, &d[0], tensorRep);
121  }
122 }
123 
124 void PViewData::setNode(int step, int ent, int ele, int nod, double x, double y,
125  double z)
126 {
127  Msg::Error("Cannot change node coordinates in this view");
128 }
129 
130 void PViewData::setValue(int step, int ent, int ele, int nod, int comp,
131  double val)
132 {
133  Msg::Error("Cannot change field value in this view");
134 }
135 
137 {
138  Msg::Error("Cannot get model from this view");
139  return nullptr;
140 }
141 
142 GEntity *PViewData::getEntity(int step, int ent)
143 {
144  Msg::Error("Cannot get entity from this view");
145  return nullptr;
146 }
147 
148 MElement *PViewData::getElement(int step, int ent, int ele)
149 {
150  Msg::Error("Cannot get element from this view");
151  return nullptr;
152 }
153 
155  const fullMatrix<double> &coefVal,
156  const fullMatrix<double> &expVal)
157 {
158  if(!type || _interpolation[type].size()) return;
159  _interpolation[type].push_back(new fullMatrix<double>(coefVal));
160  _interpolation[type].push_back(new fullMatrix<double>(expVal));
161 }
162 
164  const fullMatrix<double> &coefVal,
165  const fullMatrix<double> &expVal,
166  const fullMatrix<double> &coefGeo,
167  const fullMatrix<double> &expGeo)
168 {
169  if(!type || _interpolation[type].size()) return;
170  _interpolation[type].push_back(new fullMatrix<double>(coefVal));
171  _interpolation[type].push_back(new fullMatrix<double>(expVal));
172  _interpolation[type].push_back(new fullMatrix<double>(coefGeo));
173  _interpolation[type].push_back(new fullMatrix<double>(expGeo));
174 }
175 
177  std::vector<fullMatrix<double> *> &p)
178 {
179  if(_interpolation.count(type)) {
180  p = _interpolation[type];
181  return p.size();
182  }
183  return 0;
184 }
185 
187 {
188  if(!type)
189  return !_interpolation.empty();
190  else
191  return _interpolation.count(type) ? true : false;
192 }
193 
195 {
196  _interpolation.erase(type);
197 }
198 
199 void PViewData::removeInterpolationScheme(const std::string &name)
200 {
201  auto it = _interpolationSchemes.find(name);
202  if(it != _interpolationSchemes.end()) {
203  for(auto it2 = it->second.begin(); it2 != it->second.end(); it2++)
204  for(std::size_t i = 0; i < it2->second.size(); i++) delete it2->second[i];
205  _interpolationSchemes.erase(it);
206  }
207 }
208 
210 {
211  auto it = _interpolationSchemes.begin();
212  for(; it != _interpolationSchemes.end(); it++)
213  for(auto it2 = it->second.begin(); it2 != it->second.end(); it2++)
214  for(std::size_t i = 0; i < it2->second.size(); i++) delete it2->second[i];
215  _interpolationSchemes.clear();
216  std::map<std::string, interpolationMatrices>().swap(_interpolationSchemes);
217 }
218 
219 void PViewData::addMatrixToInterpolationScheme(const std::string &name,
220  int type,
221  fullMatrix<double> &mat)
222 {
223  _interpolationSchemes[name][type].push_back(new fullMatrix<double>(mat));
224 }
225 
227 {
228  return _interpolationSchemes.size();
229 }
230 
232 {
233  Msg::Error("Smoothing is not implemented for this type of data");
234 }
235 
237 {
238  Msg::Error("Combine time is not implemented for this type of data");
239  return false;
240 }
241 
243 {
244  Msg::Error("Combine space is not implemented for this type of data");
245  return false;
246 }
247 
248 double PViewData::findClosestNode(double &xn, double &yn, double &zn, int step)
249 {
250  double x = xn, y = yn, z = zn;
251 
252 #if 0
253 
254  // slow, naive implementation; beware that iterations on view data is
255  // currently not thread-safe (it uses a cache for the current element/node)
256  double dist2 = 1e200;
257 #pragma omp critical
258  {
259  if(step < 0) step = getFirstNonEmptyTimeStep();
260  for(int ent = 0; ent < getNumEntities(step); ent++) {
261  for(int ele = 0; ele < getNumElements(step, ent); ele++) {
262  int numNodes = getNumNodes(step, ent, ele);
263  for(int nod = 0; nod < numNodes; nod++) {
264  double xx, yy, zz;
265  getNode(step, ent, ele, nod, xx, yy, zz);
266  double d2 =
267  (x - xx) * (x - xx) + (y - yy) * (y - yy) + (z - zz) * (z - zz);
268  if(d2 < dist2) {
269  dist2 = d2;
270  xn = xx;
271  yn = yy;
272  zn = zz;
273  }
274  }
275  }
276  }
277  }
278  return sqrt(dist2);
279 
280 #else
281 
282 #pragma omp critical
283  if(!_kdtree) {
284  Msg::Debug("Rebuilding kdtree for view data '%s'", _name.c_str());
285  _pc.pts.clear();
286  // FIXME: should directly iterate on mesh nodes for model-based views
287  if(step < 0) step = getFirstNonEmptyTimeStep();
288  for(int ent = 0; ent < getNumEntities(step); ent++) {
289  for(int ele = 0; ele < getNumElements(step, ent); ele++) {
290  int numNodes = getNumNodes(step, ent, ele);
291  for(int nod = 0; nod < numNodes; nod++) {
292  double xx, yy, zz;
293  getNode(step, ent, ele, nod, xx, yy, zz);
294  _pc.pts.push_back(SPoint3(xx, yy, zz));
295  }
296  }
297  }
300  _kdtree->buildIndex();
301  }
302 
303  double query_pt[3] = {x, y, z};
304  std::size_t idx;
305  double squ_dist = 0.;
306  nanoflann::KNNResultSet<double> resultSet(1);
307  resultSet.init(&idx, &squ_dist);
308  _kdtree->findNeighbors(resultSet, &query_pt[0], nanoflann::SearchParams(10));
309  if(idx < _pc.pts.size()) {
310  xn = _pc.pts[idx].x();
311  yn = _pc.pts[idx].y();
312  zn = _pc.pts[idx].z();
313  return sqrt(squ_dist);
314  }
315  else{
316  return -1.;
317  }
318 
319 #endif
320 }
321 
322 bool PViewData::searchScalar(double x, double y, double z, double *values,
323  int step, double *size, int qn, double *qx,
324  double *qy, double *qz, bool grad, int dim)
325 {
326  if(!_octree) {
327 #pragma omp barrier
328 #pragma omp single
329  {
330  Msg::Debug("Rebuilding octree for view data '%s'", _name.c_str());
331  _octree = new OctreePost(this);
332  }
333  }
334  return _octree->searchScalar(x, y, z, values, step, size, qn, qx, qy, qz,
335  grad, dim);
336 }
337 
338 bool PViewData::searchScalarClosest(double x, double y, double z,
339  double &distance, double *values,
340  int step, double *size,
341  int qn, double *qx, double *qy,
342  double *qz, bool grad, int dim)
343 {
344  bool ret = searchScalar(x, y, z, values, step, size, qn, qx, qy, qz, grad,
345  dim);
346  if(ret) {
347  distance = 0.;
348  }
349  else if(distance) {
350  double xn = x, yn = y, zn = z, distanceMax = distance;
351  distance = findClosestNode(xn, yn, zn, step);
352  if(distanceMax < 0. || distance <= distanceMax)
353  ret = searchScalar(xn, yn, zn, values, step, size, qn, qx, qy, qz, grad,
354  dim);
355  }
356  else {
357  distance = -1.;
358  }
359  return ret;
360 }
361 
362 bool PViewData::searchVector(double x, double y, double z, double *values,
363  int step, double *size, int qn, double *qx,
364  double *qy, double *qz, bool grad, int dim)
365 {
366  if(!_octree) {
367 #pragma omp barrier
368 #pragma omp single
369  {
370  Msg::Debug("Rebuilding octree for view data '%s'", _name.c_str());
371  _octree = new OctreePost(this);
372  }
373  }
374  return _octree->searchVector(x, y, z, values, step, size, qn, qx, qy, qz,
375  grad, dim);
376 }
377 
378 bool PViewData::searchVectorClosest(double x, double y, double z,
379  double &distance, double *values,
380  int step, double *size,
381  int qn, double *qx, double *qy,
382  double *qz, bool grad, int dim)
383 {
384  bool ret = searchVector(x, y, z, values, step, size, qn, qx, qy, qz, grad,
385  dim);
386  if(ret) {
387  distance = 0.;
388  }
389  else if(distance) {
390  double xn = x, yn = y, zn = z, distanceMax = distance;
391  distance = findClosestNode(xn, yn, zn, step);
392  if(distanceMax < 0. || distance <= distanceMax)
393  ret = searchVector(xn, yn, zn, values, step, size, qn, qx, qy, qz, grad,
394  dim);
395  }
396  else {
397  distance = -1.;
398  }
399  return ret;
400 }
401 
402 bool PViewData::searchTensor(double x, double y, double z, double *values,
403  int step, double *size, int qn, double *qx,
404  double *qy, double *qz, bool grad, int dim)
405 {
406  if(!_octree) {
407 #pragma omp barrier
408 #pragma omp single
409  {
410  Msg::Debug("Rebuilding octree for view data '%s'", _name.c_str());
411  _octree = new OctreePost(this);
412  }
413  }
414  return _octree->searchTensor(x, y, z, values, step, size, qn, qx, qy, qz,
415  grad, dim);
416 }
417 
418 bool PViewData::searchTensorClosest(double x, double y, double z,
419  double &distance, double *values,
420  int step, double *size,
421  int qn, double *qx, double *qy,
422  double *qz, bool grad, int dim)
423 {
424  bool ret = searchTensor(x, y, z, values, step, size, qn, qx, qy, qz, grad,
425  dim);
426  if(ret) {
427  distance = 0.;
428  }
429  else if(distance) {
430  double xn = x, yn = y, zn = z, distanceMax = distance;
431  distance = findClosestNode(xn, yn, zn, step);
432  if(distanceMax < 0 || distance <= distanceMax)
433  ret = searchTensor(xn, yn, zn, values, step, size, qn, qx, qy, qz, grad,
434  dim);
435  }
436  else {
437  distance = -1.;
438  }
439  return ret;
440 }
nanoflann::KDTreeSingleIndexAdaptor::findNeighbors
bool findNeighbors(RESULTSET &result, const ElementType *vec, const SearchParams &searchParams) const
Definition: nanoflann.hpp:906
PViewData::searchVector
bool searchVector(double x, double y, double z, double *values, int step=-1, double *size=nullptr, int qn=0, double *qx=nullptr, double *qy=nullptr, double *qz=nullptr, bool grad=false, int dim=-1)
Definition: PViewData.cpp:362
OctreePost::searchScalar
bool searchScalar(double x, double y, double z, double *values, int step=-1, double *size=nullptr, int qn=0, double *qx=nullptr, double *qy=nullptr, double *qz=nullptr, bool grad=false, int dim=-1)
Definition: OctreePost.cpp:578
PViewData::skipElement
virtual bool skipElement(int step, int ent, int ele, bool checkVisibility=false, int samplingRate=1)
Definition: PViewData.cpp:90
distance
double distance(MVertex *v1, MVertex *v2)
Definition: MVertex.h:245
PViewData::getNumStrings3D
virtual int getNumStrings3D()
Definition: PViewData.h:187
PViewData::combineSpace
virtual bool combineSpace(nameData &nd)
Definition: PViewData.cpp:242
PViewData::getNumStrings2D
virtual int getNumStrings2D()
Definition: PViewData.h:186
PViewData::setValue
virtual void setValue(int step, int ent, int ele, int nod, int comp, double val)
Definition: PViewData.cpp:130
Msg::Debug
static void Debug(const char *fmt,...)
Definition: GmshMessage.cpp:752
PViewData::_name
std::string _name
Definition: PViewData.h:34
OctreePost.h
PViewData::getNode
virtual int getNode(int step, int ent, int ele, int nod, double &x, double &y, double &z)
Definition: PViewData.h:141
Msg::Error
static void Error(const char *fmt,...)
Definition: GmshMessage.cpp:482
PViewData::_pc
SPoint3Cloud _pc
Definition: PViewData.h:43
PViewData::getInterpolationMatrices
int getInterpolationMatrices(int type, std::vector< fullMatrix< double > * > &p)
Definition: PViewData.cpp:176
SPoint3
Definition: SPoint3.h:14
PViewData::getValue
virtual void getValue(int step, int ent, int ele, int idx, double &val)
Definition: PViewData.h:159
PViewData::searchVectorClosest
bool searchVectorClosest(double x, double y, double z, double &distance, double *values, int step=-1, double *size=nullptr, int qn=0, double *qx=nullptr, double *qy=nullptr, double *qz=nullptr, bool grad=false, int dim=-1)
Definition: PViewData.cpp:378
nameData
Definition: PView.h:169
OctreePost
Definition: BoundaryLayers.cpp:23
PViewData::_octree
OctreePost * _octree
Definition: PViewData.h:41
PViewData::_interpolation
interpolationMatrices _interpolation
Definition: PViewData.h:51
adaptiveData::changeResolution
void changeResolution(int step, int level, double tol, GMSH_PostPlugin *plug=nullptr)
Definition: adaptiveData.cpp:1564
PViewData::setNode
virtual void setNode(int step, int ent, int ele, int nod, double x, double y, double z)
Definition: PViewData.cpp:124
GmshMessage.h
PViewData::getNumEntities
virtual int getNumEntities(int step=-1)
Definition: PViewData.h:127
PViewData.h
PViewData::haveInterpolationMatrices
bool haveInterpolationMatrices(int type=0)
Definition: PViewData.cpp:186
GEntity
Definition: GEntity.h:31
PViewData::searchScalarClosest
bool searchScalarClosest(double x, double y, double z, double &distance, double *values, int step=-1, double *size=nullptr, int qn=0, double *qx=nullptr, double *qy=nullptr, double *qz=nullptr, bool grad=false, int dim=-1)
Definition: PViewData.cpp:338
adaptiveData::changeResolutionForVTK
void changeResolutionForVTK(int step, int level, double tol, int npart=1, bool isBinary=true, const std::string &guifileName="unknown", int useDefaultName=1)
Definition: adaptiveData.cpp:2649
PViewData::initAdaptiveData
void initAdaptiveData(int step, int level, double tol)
Definition: PViewData.cpp:37
PViewData::_kdtree
SPoint3KDTree * _kdtree
Definition: PViewData.h:45
adaptiveData.h
SPoint3KDTree
nanoflann::KDTreeSingleIndexAdaptor< nanoflann::L2_Simple_Adaptor< double, SPoint3CloudAdaptor< SPoint3Cloud > >, SPoint3CloudAdaptor< SPoint3Cloud >, 3 > SPoint3KDTree
Definition: SPoint3KDTree.h:46
fullMatrix< double >
nanoflann::KDTreeSingleIndexAdaptor::buildIndex
void buildIndex()
Definition: nanoflann.hpp:863
PViewData::setInterpolationMatrices
void setInterpolationMatrices(int type, const fullMatrix< double > &coefVal, const fullMatrix< double > &expVal)
Definition: PViewData.cpp:154
PViewData::PViewData
PViewData()
Definition: PViewData.cpp:15
nanoflann::SearchParams
Definition: nanoflann.hpp:419
PViewData::_pc2kdtree
SPoint3CloudAdaptor< SPoint3Cloud > _pc2kdtree
Definition: PViewData.h:44
PViewData::getScalarValue
void getScalarValue(int step, int ent, int ele, int nod, double &val, int tensorRep=0, int forceNumComponents=0, int componentMap[9]=nullptr)
Definition: PViewData.cpp:97
SPoint3Cloud::pts
std::vector< SPoint3 > pts
Definition: SPoint3KDTree.h:13
adaptiveData
Definition: adaptiveData.h:640
Numeric.h
GModel
Definition: GModel.h:44
PViewData::initAdaptiveDataLight
void initAdaptiveDataLight(int step, int level, double tol)
Definition: PViewData.cpp:47
PViewData::removeAllInterpolationSchemes
static void removeAllInterpolationSchemes()
Definition: PViewData.cpp:209
PViewData::addMatrixToInterpolationScheme
static void addMatrixToInterpolationScheme(const std::string &name, int type, fullMatrix< double > &mat)
Definition: PViewData.cpp:219
nanoflann::KNNResultSet::init
void init(IndexType *indices_, DistanceType *dists_)
Definition: nanoflann.hpp:90
PViewData::destroyAdaptiveData
void destroyAdaptiveData()
Definition: PViewData.cpp:79
PViewData::_dirty
bool _dirty
Definition: PViewData.h:32
PViewData::~PViewData
virtual ~PViewData()
Definition: PViewData.cpp:21
PViewData::getModel
virtual GModel * getModel(int step)
Definition: PViewData.cpp:136
PViewData::getNumNodes
virtual int getNumNodes(int step, int ent, int ele)
Definition: PViewData.h:137
PViewData::deleteInterpolationMatrices
void deleteInterpolationMatrices(int type=0)
Definition: PViewData.cpp:194
PViewData::searchScalar
bool searchScalar(double x, double y, double z, double *values, int step=-1, double *size=nullptr, int qn=0, double *qx=nullptr, double *qy=nullptr, double *qz=nullptr, bool grad=false, int dim=-1)
Definition: PViewData.cpp:322
PViewData::combineTime
virtual bool combineTime(nameData &nd)
Definition: PViewData.cpp:236
MElement
Definition: MElement.h:30
PViewData::removeInterpolationScheme
static void removeInterpolationScheme(const std::string &name)
Definition: PViewData.cpp:199
PViewData::getElement
virtual MElement * getElement(int step, int entity, int element)
Definition: PViewData.cpp:148
PViewData::_interpolationSchemes
static std::map< std::string, interpolationMatrices > _interpolationSchemes
Definition: PViewData.h:53
nanoflann::KDTreeSingleIndexAdaptorParams
Definition: nanoflann.hpp:409
PViewData::empty
virtual bool empty()
Definition: PViewData.cpp:85
PViewData::getNumComponents
virtual int getNumComponents(int step, int ent, int ele)
Definition: PViewData.h:152
OctreePost::searchVector
bool searchVector(double x, double y, double z, double *values, int step=-1, double *size=nullptr, int qn=0, double *qx=nullptr, double *qy=nullptr, double *qz=nullptr, bool grad=false, int dim=-1)
Definition: OctreePost.cpp:634
z
const double z
Definition: GaussQuadratureQuad.cpp:56
PViewData::_adaptive
adaptiveData * _adaptive
Definition: PViewData.h:49
nanoflann::KNNResultSet
Definition: nanoflann.hpp:79
PViewData::getSizeInterpolationScheme
static int getSizeInterpolationScheme()
Definition: PViewData.cpp:226
PViewData::getNumElements
virtual int getNumElements(int step=-1, int ent=-1)
Definition: PViewData.h:131
PViewData::searchTensorClosest
bool searchTensorClosest(double x, double y, double z, double &distance, double *values, int step=-1, double *size=nullptr, int qn=0, double *qx=nullptr, double *qy=nullptr, double *qz=nullptr, bool grad=false, int dim=-1)
Definition: PViewData.cpp:418
PViewData::saveAdaptedViewForVTK
void saveAdaptedViewForVTK(const std::string &guifileName, int useDefaultName, int step, int level, double tol, int npart, bool isBinary)
Definition: PViewData.cpp:61
PViewData::smooth
virtual void smooth()
Definition: PViewData.cpp:231
PViewData::searchTensor
bool searchTensor(double x, double y, double z, double *values, int step=-1, double *size=nullptr, int qn=0, double *qx=nullptr, double *qy=nullptr, double *qz=nullptr, bool grad=false, int dim=-1)
Definition: PViewData.cpp:402
PViewData::finalize
virtual bool finalize(bool computeMinMax=true, const std::string &interpolationScheme="")
Definition: PViewData.cpp:30
fullMatrix.h
PViewData::findClosestNode
double findClosestNode(double &xn, double &yn, double &zn, int step)
Definition: PViewData.cpp:248
ComputeScalarRep
double ComputeScalarRep(int numComp, double *val, int tensorRep)
Definition: Numeric.cpp:506
OctreePost::searchTensor
bool searchTensor(double x, double y, double z, double *values, int step=-1, double *size=nullptr, int qn=0, double *qx=nullptr, double *qy=nullptr, double *qz=nullptr, bool grad=false, int dim=-1)
Definition: OctreePost.cpp:690
PViewData::getEntity
virtual GEntity * getEntity(int step, int entity)
Definition: PViewData.cpp:142
PViewData::getFirstNonEmptyTimeStep
virtual int getFirstNonEmptyTimeStep(int start=0)
Definition: PViewData.h:91