source: trunk/packages/vizservers/vtkvis/DataSet.cpp @ 3704

Last change on this file since 3704 was 3704, checked in by ldelgass, 11 years ago

Read all field types

  • Property svn:eol-style set to native
File size: 30.0 KB
Line 
1/* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2/*
3 * Copyright (C) 2004-2012  HUBzero Foundation, LLC
4 *
5 * Author: Leif Delgass <ldelgass@purdue.edu>
6 */
7
8#include <cassert>
9#include <cstring>
10#include <cfloat>
11#include <cmath>
12
13#include <vtkCharArray.h>
14#include <vtkDataSetReader.h>
15#include <vtkDataSetWriter.h>
16#include <vtkPolyData.h>
17#include <vtkStructuredPoints.h>
18#include <vtkStructuredGrid.h>
19#include <vtkRectilinearGrid.h>
20#include <vtkUnstructuredGrid.h>
21#include <vtkProperty.h>
22#include <vtkPointData.h>
23#include <vtkCellData.h>
24#include <vtkCell.h>
25#include <vtkLookupTable.h>
26
27#include "DataSet.h"
28#include "Trace.h"
29
30using namespace VtkVis;
31
32DataSet::DataSet(const std::string& name) :
33    _name(name),
34    _visible(true),
35    _opacity(1),
36    _cellSizeAverage(0)
37{
38    _cellSizeRange[0] = -1;
39    _cellSizeRange[1] = -1;
40}
41
42DataSet::~DataSet()
43{
44}
45
46/**
47 * \brief Set opacity of DataSet outline
48 *
49 * This method is used for record-keeping and opacity of the
50 * DataSet bounds outline.  The renderer controls opacity
51 * of other related graphics objects.
52 */
53void DataSet::setOpacity(double opacity)
54{
55    _opacity = opacity;
56}
57
58/**
59 * \brief Set visibility flag in DataSet
60 *
61 * This method is used for record-keeping and visibility of the
62 * DataSet bounds outline.  The renderer controls visibility
63 * of other related graphics objects.
64 */
65void DataSet::setVisibility(bool state)
66{
67    _visible = state;
68}
69
70/**
71 * \brief Get visibility flag in DataSet
72 *
73 * This method is used for record-keeping.  The renderer controls
74 * the visibility of related graphics objects.
75 */
76bool DataSet::getVisibility() const
77{
78    return _visible;
79}
80
81void DataSet::writeDataFile(const char *filename)
82{
83    if (_dataSet == NULL)
84        return;
85   
86    vtkSmartPointer<vtkDataSetWriter> writer = vtkSmartPointer<vtkDataSetWriter>::New();
87
88    writer->SetFileName(filename);
89#ifdef USE_VTK6
90    writer->SetInputData(_dataSet);
91#else
92    writer->SetInput(_dataSet);
93#endif
94    writer->Write();
95}
96
97/**
98 * \brief Read a VTK data file
99 */
100bool DataSet::setDataFile(const char *filename)
101{
102    vtkSmartPointer<vtkDataSetReader> reader = vtkSmartPointer<vtkDataSetReader>::New();
103
104#if defined(WANT_TRACE) && defined(DEBUG)
105    reader->DebugOn();
106#endif
107
108    reader->SetFileName(filename);
109    reader->ReadAllNormalsOn();
110    reader->ReadAllTCoordsOn();
111    reader->ReadAllScalarsOn();
112    reader->ReadAllColorScalarsOn();
113    reader->ReadAllVectorsOn();
114    reader->ReadAllTensorsOn();
115    reader->ReadAllFieldsOn();
116
117    return setData(reader);
118}
119
120/**
121 * \brief Read a VTK data file from a memory buffer
122 */
123bool DataSet::setData(char *data, int nbytes)
124{
125    vtkSmartPointer<vtkDataSetReader> reader = vtkSmartPointer<vtkDataSetReader>::New();
126    vtkSmartPointer<vtkCharArray> dataSetString = vtkSmartPointer<vtkCharArray>::New();
127
128#if defined(WANT_TRACE) && defined(DEBUG)
129    reader->DebugOn();
130    dataSetString->DebugOn();
131#endif
132
133    dataSetString->SetArray(data, nbytes, 1);
134    reader->SetInputArray(dataSetString);
135    reader->ReadFromInputStringOn();
136    reader->ReadAllNormalsOn();
137    reader->ReadAllTCoordsOn();
138    reader->ReadAllScalarsOn();
139    reader->ReadAllColorScalarsOn();
140    reader->ReadAllVectorsOn();
141    reader->ReadAllTensorsOn();
142    reader->ReadAllFieldsOn();
143
144    return setData(reader);
145}
146
147void DataSet::print() const
148{
149    print(_dataSet);
150}
151
152void DataSet::print(vtkDataSet *ds)
153{
154    if (ds == NULL)
155        return;
156
157    TRACE("DataSet class: %s", ds->GetClassName());
158
159    TRACE("DataSet memory: %g MiB", ds->GetActualMemorySize()/1024.);
160
161    double bounds[6];
162    ds->GetBounds(bounds);
163
164    // Topology
165    TRACE("DataSet bounds: %g %g %g %g %g %g",
166          bounds[0], bounds[1],
167          bounds[2], bounds[3],
168          bounds[4], bounds[5]);
169    TRACE("Points: %d Cells: %d", ds->GetNumberOfPoints(), ds->GetNumberOfCells());
170
171    double dataRange[2];
172    if (ds->GetPointData() != NULL) {
173        TRACE("PointData arrays: %d", ds->GetPointData()->GetNumberOfArrays());
174        for (int i = 0; i < ds->GetPointData()->GetNumberOfArrays(); i++) {
175            if (ds->GetPointData()->GetArray(i) != NULL) {
176                ds->GetPointData()->GetArray(i)->GetRange(dataRange, -1);
177                TRACE("PointData[%d]: '%s' comp:%d, (%g,%g)", i,
178                      ds->GetPointData()->GetArrayName(i),
179                      ds->GetPointData()->GetAbstractArray(i)->GetNumberOfComponents(),
180                      dataRange[0], dataRange[1]);
181            } else {
182                TRACE("PointData[%d]: '%s' comp:%d", i,
183                      ds->GetPointData()->GetArrayName(i),
184                      ds->GetPointData()->GetAbstractArray(i)->GetNumberOfComponents());
185            }
186        }
187        if (ds->GetPointData()->GetScalars() != NULL) {
188            TRACE("Active point scalars: %s", ds->GetPointData()->GetScalars()->GetName());
189        }
190        if (ds->GetPointData()->GetVectors() != NULL) {
191            TRACE("Active point vectors: %s", ds->GetPointData()->GetVectors()->GetName());
192        }
193    }
194    if (ds->GetCellData() != NULL) {
195        TRACE("CellData arrays: %d", ds->GetCellData()->GetNumberOfArrays());
196        for (int i = 0; i < ds->GetCellData()->GetNumberOfArrays(); i++) {
197            if (ds->GetCellData()->GetArray(i) != NULL) {
198                ds->GetCellData()->GetArray(i)->GetRange(dataRange, -1);
199                TRACE("CellData[%d]: '%s' comp:%d, (%g,%g)", i,
200                      ds->GetCellData()->GetArrayName(i),
201                      ds->GetCellData()->GetAbstractArray(i)->GetNumberOfComponents(),
202                      dataRange[0], dataRange[1]);
203            } else {
204                TRACE("CellData[%d]: '%s' comp:%d", i,
205                      ds->GetCellData()->GetArrayName(i),
206                      ds->GetCellData()->GetAbstractArray(i)->GetNumberOfComponents());
207            }
208        }
209        if (ds->GetCellData()->GetScalars() != NULL) {
210            TRACE("Active cell scalars: %s", ds->GetPointData()->GetScalars()->GetName());
211        }
212        if (ds->GetCellData()->GetVectors() != NULL) {
213            TRACE("Active cell vectors: %s", ds->GetPointData()->GetVectors()->GetName());
214        }
215    }
216    if (ds->GetFieldData() != NULL) {
217        TRACE("FieldData arrays: %d", ds->GetFieldData()->GetNumberOfArrays());
218        for (int i = 0; i < ds->GetFieldData()->GetNumberOfArrays(); i++) {
219            if (ds->GetFieldData()->GetArray(i) != NULL) {
220                ds->GetFieldData()->GetArray(i)->GetRange(dataRange, -1);
221                TRACE("FieldData[%d]: '%s' comp:%d, tuples:%d (%g,%g)", i,
222                      ds->GetFieldData()->GetArrayName(i),
223                      ds->GetFieldData()->GetAbstractArray(i)->GetNumberOfComponents(),
224                      ds->GetFieldData()->GetAbstractArray(i)->GetNumberOfTuples(),
225                      dataRange[0], dataRange[1]);
226            } else {
227                TRACE("FieldData[%d]: '%s' comp:%d, tuples:%d", i,
228                      ds->GetFieldData()->GetArrayName(i),
229                      ds->GetFieldData()->GetAbstractArray(i)->GetNumberOfComponents(),
230                      ds->GetFieldData()->GetAbstractArray(i)->GetNumberOfTuples());
231            }
232        }
233    }
234}
235
236void DataSet::setDefaultArrays()
237{
238    if (_dataSet->GetPointData() != NULL &&
239        _dataSet->GetPointData()->GetScalars() == NULL &&
240        _dataSet->GetPointData()->GetNumberOfArrays() > 0) {
241        for (int i = 0; i < _dataSet->GetPointData()->GetNumberOfArrays(); i++) {
242            if (_dataSet->GetPointData()->GetArray(i) != NULL &&
243                _dataSet->GetPointData()->GetArray(i)->GetNumberOfComponents() == 1) {
244                TRACE("Setting point scalars to '%s'", _dataSet->GetPointData()->GetArrayName(i));
245                _dataSet->GetPointData()->SetActiveScalars(_dataSet->GetPointData()->GetArrayName(i));
246                break;
247            }
248        }
249    }
250    if (_dataSet->GetPointData() != NULL &&
251        _dataSet->GetPointData()->GetVectors() == NULL &&
252        _dataSet->GetPointData()->GetNumberOfArrays() > 0) {
253        for (int i = 0; i < _dataSet->GetPointData()->GetNumberOfArrays(); i++) {
254            if (_dataSet->GetPointData()->GetArray(i) != NULL &&
255                _dataSet->GetPointData()->GetArray(i)->GetNumberOfComponents() == 3) {
256                TRACE("Setting point vectors to '%s'", _dataSet->GetPointData()->GetArrayName(i));
257                _dataSet->GetPointData()->SetActiveVectors(_dataSet->GetPointData()->GetArrayName(i));
258                break;
259            }
260        }
261    }
262    if (_dataSet->GetCellData() != NULL &&
263        _dataSet->GetCellData()->GetScalars() == NULL &&
264        _dataSet->GetCellData()->GetNumberOfArrays() > 0) {
265        for (int i = 0; i < _dataSet->GetCellData()->GetNumberOfArrays(); i++) {
266            if (_dataSet->GetCellData()->GetArray(i) != NULL &&
267                _dataSet->GetCellData()->GetArray(i)->GetNumberOfComponents() == 1) {
268                TRACE("Setting cell scalars to '%s'", _dataSet->GetCellData()->GetArrayName(i));
269                _dataSet->GetCellData()->SetActiveScalars(_dataSet->GetCellData()->GetArrayName(i));
270                break;
271            }
272        }
273    }
274    if (_dataSet->GetCellData() != NULL &&
275        _dataSet->GetCellData()->GetVectors() == NULL &&
276        _dataSet->GetCellData()->GetNumberOfArrays() > 0) {
277        for (int i = 0; i < _dataSet->GetCellData()->GetNumberOfArrays(); i++) {
278            if (_dataSet->GetCellData()->GetArray(i) != NULL &&
279                _dataSet->GetCellData()->GetArray(i)->GetNumberOfComponents() == 3) {
280                TRACE("Setting cell vectors to '%s'", _dataSet->GetCellData()->GetArrayName(i));
281                _dataSet->GetCellData()->SetActiveVectors(_dataSet->GetCellData()->GetArrayName(i));
282                break;
283            }
284        }
285    }
286}
287
288/**
289 * \brief Read dataset using supplied reader
290 *
291 * Pipeline information is removed from the resulting
292 * vtkDataSet, so that the reader and its data can be
293 * released
294 */
295bool DataSet::setData(vtkDataSetReader *reader)
296{
297    TRACE("Enter");
298    // Force reading data set
299    reader->SetLookupTableName("");
300    reader->Update();
301
302    _dataSet = reader->GetOutput();
303    if (_dataSet == NULL)
304        return false;
305#ifndef USE_VTK6
306    _dataSet->SetPipelineInformation(NULL);
307#endif
308    if (_dataSet->GetPointData() != NULL &&
309        _dataSet->GetPointData()->GetScalars() != NULL &&
310        _dataSet->GetPointData()->GetScalars()->GetLookupTable() != NULL) {
311        USER_ERROR("No lookup table should be specified in VTK data sets");
312    }
313
314    setDefaultArrays();
315
316#ifdef WANT_TRACE
317    print();
318#endif
319    TRACE("Leave");
320    return true;
321}
322
323/**
324 * \brief Set DataSet from existing vtkDataSet object
325 *
326 * Pipeline information is removed from the supplied vtkDataSet
327 */
328bool DataSet::setData(vtkDataSet *ds)
329{
330    _dataSet = ds;
331#ifndef USE_VTK6
332    _dataSet->SetPipelineInformation(NULL);
333#endif
334
335    if (_dataSet->GetPointData() != NULL &&
336        _dataSet->GetPointData()->GetScalars() != NULL &&
337        _dataSet->GetPointData()->GetScalars()->GetLookupTable() != NULL) {
338        USER_ERROR("No lookup table should be specified in VTK data sets");
339    }
340
341    setDefaultArrays();
342
343#ifdef WANT_TRACE
344    print();
345#endif
346    return true;
347}
348
349/**
350 * \brief Copy an existing vtkDataSet object
351 *
352 * Pipeline information is not copied from the supplied vtkDataSet
353 * into this DataSet, but pipeline information in the supplied
354 * vtkDataSet is not removed
355 */
356vtkDataSet *DataSet::copyData(vtkDataSet *ds)
357{
358    if (vtkPolyData::SafeDownCast(ds) != NULL) {
359        _dataSet = vtkSmartPointer<vtkPolyData>::New();
360        _dataSet->DeepCopy(vtkPolyData::SafeDownCast(ds));
361    } else if (vtkStructuredPoints::SafeDownCast(ds) != NULL) {
362        _dataSet = vtkSmartPointer<vtkStructuredPoints>::New();
363        _dataSet->DeepCopy(vtkStructuredPoints::SafeDownCast(ds));
364    } else if (vtkStructuredGrid::SafeDownCast(ds) != NULL) {
365        _dataSet = vtkSmartPointer<vtkStructuredGrid>::New();
366        _dataSet->DeepCopy(vtkStructuredGrid::SafeDownCast(ds));
367    } else if (vtkRectilinearGrid::SafeDownCast(ds) != NULL) {
368        _dataSet = vtkSmartPointer<vtkRectilinearGrid>::New();
369        _dataSet->DeepCopy(vtkRectilinearGrid::SafeDownCast(ds));
370    } else if (vtkUnstructuredGrid::SafeDownCast(ds) != NULL) {
371        _dataSet = vtkSmartPointer<vtkUnstructuredGrid>::New();
372        _dataSet->DeepCopy(vtkUnstructuredGrid::SafeDownCast(ds));
373    } else {
374        ERROR("Unknown data type");
375        return NULL;
376    }
377
378#ifdef WANT_TRACE
379    print();
380#endif   
381    return _dataSet;
382}
383
384/**
385 * \brief Does DataSet lie in the XY plane (z = 0)
386 */
387bool DataSet::isXY() const
388{
389    double bounds[6];
390    getBounds(bounds);
391    return (bounds[4] == 0. && bounds[4] == bounds[5]);
392}
393
394/**
395 * \brief Returns the dimensionality of the AABB
396 */
397int DataSet::numDimensions() const
398{
399    double bounds[6];
400    getBounds(bounds);
401    int numDims = 0;
402    if (bounds[0] != bounds[1])
403        numDims++;
404    if (bounds[2] != bounds[3])
405        numDims++;
406    if (bounds[4] != bounds[5])
407        numDims++;
408
409    return numDims;
410}
411
412/**
413 * \brief Determines if DataSet lies in a principal axis plane
414 * and if so, returns the plane normal and offset from origin
415 */
416bool DataSet::is2D(PrincipalPlane *plane, double *offset) const
417{
418    double bounds[6];
419    getBounds(bounds);
420    if (bounds[4] == bounds[5]) {
421        // Zmin = Zmax, XY plane
422        if (plane != NULL) {
423            *plane = PLANE_XY;
424        }
425        if (offset != NULL)
426            *offset = bounds[4];
427        return true;
428    } else if (bounds[0] == bounds[1]) {
429        // Xmin = Xmax, ZY plane
430        if (plane != NULL) {
431            *plane = PLANE_ZY;
432        }
433        if (offset != NULL)
434            *offset = bounds[0];
435        return true;
436    } else if (bounds[2] == bounds[3]) {
437        // Ymin = Ymax, XZ plane
438        if (plane != NULL) {
439            *plane = PLANE_XZ;
440         }
441        if (offset != NULL)
442            *offset = bounds[2];
443        return true;
444    }
445    return false;
446}
447
448/**
449 * \brief Determines a principal plane with the
450 * largest two dimensions of the AABB
451 */
452PrincipalPlane DataSet::principalPlane() const
453{
454    double bounds[6];
455    getBounds(bounds);
456    double xlen = bounds[1] - bounds[0];
457    double ylen = bounds[3] - bounds[2];
458    double zlen = bounds[5] - bounds[4];
459    if (zlen <= xlen && zlen <= ylen) {
460        return PLANE_XY;
461    } else if (xlen <= ylen && xlen <= zlen) {
462        return PLANE_ZY;
463    } else {
464        return PLANE_XZ;
465    }
466}
467
468/**
469 * \brief Determines if mesh is a point cloud (has no cells)
470 */
471bool DataSet::isCloud() const
472{
473    vtkPolyData *pd = vtkPolyData::SafeDownCast(_dataSet);
474    if (pd) {
475        // If PolyData, is a cloud if there are no cells other than vertices
476        if (pd->GetNumberOfLines() == 0 &&
477            pd->GetNumberOfPolys() == 0 &&
478            pd->GetNumberOfStrips() == 0) {
479            return true;
480        } else {
481            // Has cells
482            return false;
483        }
484    } else {
485        return (_dataSet->GetNumberOfCells() == 0);
486    }
487}
488
489/**
490 * \brief Get the name/id of this dataset
491 */
492const std::string& DataSet::getName() const
493{
494    return _name;
495}
496
497/**
498 * \brief Get the underlying VTK DataSet object
499 */
500vtkDataSet *DataSet::getVtkDataSet()
501{
502    return _dataSet;
503}
504
505/**
506 * \brief Get the underlying VTK DataSet subclass class name
507 */
508const char *DataSet::getVtkType() const
509{
510    return _dataSet->GetClassName();
511}
512
513/**
514 * \brief Set the ative scalar array to the named field
515 */
516bool DataSet::setActiveScalars(const char *name)
517{
518    bool found = false;
519    if (_dataSet != NULL) {
520        if (_dataSet->GetPointData() != NULL) {
521            if (_dataSet->GetPointData()->SetActiveScalars(name) >= 0) {
522                TRACE("Set active point data scalars to %s", name);
523                found = true;
524            }
525        }
526        if (_dataSet->GetCellData() != NULL) {
527            if (_dataSet->GetCellData()->SetActiveScalars(name) >= 0) {
528                TRACE("Set active cell data scalars to %s", name);
529                found = true;
530            }
531        }
532    }
533#ifdef WANT_TRACE
534    if (_dataSet->GetPointData() != NULL) {
535        if (_dataSet->GetPointData()->GetScalars() != NULL) {
536            TRACE("Point data scalars: %s", _dataSet->GetPointData()->GetScalars()->GetName());
537        } else {
538            TRACE("NULL point data scalars");
539        }
540    }
541    if (_dataSet->GetCellData() != NULL) {
542        if (_dataSet->GetCellData()->GetScalars() != NULL) {
543            TRACE("Cell data scalars: %s", _dataSet->GetCellData()->GetScalars()->GetName());
544        } else {
545            TRACE("NULL cell data scalars");
546        }
547    }
548#endif
549    return found;
550}
551
552/**
553 * \brief Get the active scalar array field name
554 */
555const char *DataSet::getActiveScalarsName() const
556{
557    if (_dataSet != NULL) {
558         if (_dataSet->GetPointData() != NULL &&
559             _dataSet->GetPointData()->GetScalars() != NULL) {
560            return _dataSet->GetPointData()->GetScalars()->GetName();
561        }
562        TRACE("No point scalars");
563        if (_dataSet->GetCellData() != NULL &&
564            _dataSet->GetCellData()->GetScalars() != NULL) {
565            return _dataSet->GetCellData()->GetScalars()->GetName();
566        }
567        TRACE("No cell scalars");
568    }
569    return NULL;
570}
571
572/**
573 * \brief Get the active scalar array default attribute type
574 */
575DataSet::DataAttributeType DataSet::getActiveScalarsType() const
576{
577    if (_dataSet != NULL) {
578         if (_dataSet->GetPointData() != NULL &&
579             _dataSet->GetPointData()->GetScalars() != NULL) {
580            return POINT_DATA;
581        }
582        TRACE("No point scalars");
583        if (_dataSet->GetCellData() != NULL &&
584            _dataSet->GetCellData()->GetScalars() != NULL) {
585            return CELL_DATA;
586        }
587        TRACE("No cell scalars");
588    }
589    return POINT_DATA;
590}
591
592/**
593 * \brief Set the ative vector array to the named field
594 */
595bool DataSet::setActiveVectors(const char *name)
596{
597    bool found = false;
598    if (_dataSet != NULL) {
599        if (_dataSet->GetPointData() != NULL) {
600            if (_dataSet->GetPointData()->SetActiveVectors(name) >= 0) {
601                TRACE("Set active point data vectors to %s", name);
602                found = true;
603            }
604        }
605        if (_dataSet->GetCellData() != NULL) {
606            if (_dataSet->GetCellData()->SetActiveVectors(name) >= 0) {
607                TRACE("Set active cell data vectors to %s", name);
608                found = true;
609            }
610        }
611    }
612
613    return found;
614}
615
616/**
617 * \brief Get the active vector array default attribute type
618 */
619DataSet::DataAttributeType DataSet::getActiveVectorsType() const
620{
621    if (_dataSet != NULL) {
622         if (_dataSet->GetPointData() != NULL &&
623             _dataSet->GetPointData()->GetVectors() != NULL) {
624            return POINT_DATA;
625        }
626        TRACE("No point vectors");
627        if (_dataSet->GetCellData() != NULL &&
628            _dataSet->GetCellData()->GetVectors() != NULL) {
629            return CELL_DATA;
630        }
631        TRACE("No cell vectors");
632    }
633    return POINT_DATA;
634}
635
636/**
637 * \brief Get the active vector array field name
638 */
639const char *DataSet::getActiveVectorsName() const
640{
641    if (_dataSet != NULL) {
642        if (_dataSet->GetPointData() != NULL &&
643            _dataSet->GetPointData()->GetVectors() != NULL) {
644            return _dataSet->GetPointData()->GetVectors()->GetName();
645        }
646        TRACE("No point vectors");
647        if (_dataSet->GetCellData() != NULL &&
648            _dataSet->GetCellData()->GetVectors() != NULL) {
649            return _dataSet->GetCellData()->GetVectors()->GetName();
650        }
651        TRACE("No cell vectors");
652    }
653    return NULL;
654}
655
656bool DataSet::getFieldInfo(const char *fieldName,
657                           DataAttributeType *type,
658                           int *numComponents) const
659{
660    if (_dataSet->GetPointData() != NULL &&
661        _dataSet->GetPointData()->GetAbstractArray(fieldName) != NULL) {
662        if (type != NULL)
663            *type = POINT_DATA;
664        if (numComponents != NULL)
665            *numComponents = _dataSet->GetPointData()->GetAbstractArray(fieldName)->GetNumberOfComponents();
666        return true;
667    } else if (_dataSet->GetCellData() != NULL &&
668               _dataSet->GetCellData()->GetAbstractArray(fieldName) != NULL) {
669        if (type != NULL)
670            *type = CELL_DATA;
671        if (numComponents != NULL)
672            *numComponents = _dataSet->GetCellData()->GetAbstractArray(fieldName)->GetNumberOfComponents();
673        return true;
674    } else if (_dataSet->GetFieldData() != NULL &&
675               _dataSet->GetFieldData()->GetAbstractArray(fieldName) != NULL) {
676        if (type != NULL)
677            *type = FIELD_DATA;
678        if (numComponents != NULL)
679            *numComponents = _dataSet->GetFieldData()->GetAbstractArray(fieldName)->GetNumberOfComponents();
680        return true;
681    }
682    return false;
683}
684
685bool DataSet::getFieldInfo(const char *fieldName,
686                           DataAttributeType type,
687                           int *numComponents) const
688{
689    switch (type) {
690    case POINT_DATA:
691        if (_dataSet->GetPointData() != NULL &&
692            _dataSet->GetPointData()->GetAbstractArray(fieldName) != NULL) {
693            if (numComponents != NULL)
694                *numComponents = _dataSet->GetPointData()->GetAbstractArray(fieldName)->GetNumberOfComponents();
695            return true;
696        } else
697            return false;
698        break;
699    case CELL_DATA:
700        if (_dataSet->GetCellData() != NULL &&
701            _dataSet->GetCellData()->GetAbstractArray(fieldName) != NULL) {
702            if (numComponents != NULL)
703                *numComponents = _dataSet->GetCellData()->GetAbstractArray(fieldName)->GetNumberOfComponents();
704            return true;
705        } else
706            return false;
707        break;
708    case FIELD_DATA:
709        if (_dataSet->GetFieldData() != NULL &&
710            _dataSet->GetFieldData()->GetAbstractArray(fieldName) != NULL) {
711            if (numComponents != NULL)
712                *numComponents = _dataSet->GetFieldData()->GetAbstractArray(fieldName)->GetNumberOfComponents();
713            return true;
714        } else
715            return false;
716        break;
717    default:
718        ;
719    }
720    return false;
721}
722
723/**
724 * \brief Get the list of field names in the DataSet
725 *
726 * \param[in,out] names The field names will be appended to this list
727 * \param[in] type The DataAttributeType: e.g. POINT_DATA, CELL_DATA
728 * \param[in] numComponents Filter list by number of components, -1 means to
729 * return all fields regardless of dimension
730 */
731void DataSet::getFieldNames(std::vector<std::string>& names,
732                            DataAttributeType type, int numComponents) const
733{
734    if (_dataSet == NULL)
735        return;
736    switch (type) {
737    case POINT_DATA:
738        if (_dataSet->GetPointData() != NULL) {
739            for (int i = 0; i < _dataSet->GetPointData()->GetNumberOfArrays(); i++) {
740                if (numComponents == -1 ||
741                    (_dataSet->GetPointData()->GetAbstractArray(i) != NULL &&
742                     _dataSet->GetPointData()->GetAbstractArray(i)->GetNumberOfComponents() == numComponents)) {
743                    names.push_back(_dataSet->GetPointData()->GetArrayName(i));
744                }
745            }
746        }
747        break;
748    case CELL_DATA:
749        if (_dataSet->GetCellData() != NULL) {
750            for (int i = 0; i < _dataSet->GetCellData()->GetNumberOfArrays(); i++) {
751                if (numComponents == -1 ||
752                    (_dataSet->GetCellData()->GetAbstractArray(i) != NULL &&
753                     _dataSet->GetCellData()->GetAbstractArray(i)->GetNumberOfComponents() == numComponents)) {
754                    names.push_back(_dataSet->GetCellData()->GetArrayName(i));
755                }
756            }
757        }
758        break;
759    case FIELD_DATA:
760        if (_dataSet->GetFieldData() != NULL) {
761            for (int i = 0; i < _dataSet->GetFieldData()->GetNumberOfArrays(); i++) {
762                if (numComponents == -1 ||
763                    (_dataSet->GetFieldData()->GetAbstractArray(i) != NULL &&
764                     _dataSet->GetFieldData()->GetAbstractArray(i)->GetNumberOfComponents() == numComponents)) {
765                    names.push_back(_dataSet->GetFieldData()->GetArrayName(i));
766                }
767            }
768        }
769        break;
770    default:
771        ERROR("Unknown DataAttributeType %d", type);
772    }
773}
774
775/**
776 * \brief Get the range of scalar values in the DataSet
777 */
778void DataSet::getScalarRange(double minmax[2]) const
779{
780    if (_dataSet == NULL)
781        return;
782    if (_dataSet->GetPointData() != NULL &&
783        _dataSet->GetPointData()->GetScalars() != NULL) {
784        _dataSet->GetPointData()->GetScalars()->GetRange(minmax, -1);
785    } else if (_dataSet->GetCellData() != NULL &&
786               _dataSet->GetCellData()->GetScalars() != NULL) {
787        _dataSet->GetCellData()->GetScalars()->GetRange(minmax, -1);
788    }
789}
790
791/**
792 * \brief Get the range of a vector component in the DataSet
793 *
794 * \param[out] minmax The data range
795 * \param[in] component The field component, -1 means magnitude
796 */
797void DataSet::getVectorRange(double minmax[2], int component) const
798{
799    if (_dataSet == NULL)
800        return;
801    if (_dataSet->GetPointData() != NULL &&
802        _dataSet->GetPointData()->GetVectors() != NULL) {
803        _dataSet->GetPointData()->GetVectors()->GetRange(minmax, component);
804    } else if (_dataSet->GetCellData() != NULL &&
805               _dataSet->GetCellData()->GetVectors() != NULL) {
806        _dataSet->GetCellData()->GetVectors()->GetRange(minmax, component);
807    }
808}
809
810/**
811 * \brief Get the range of values for the named field in the DataSet
812 *
813 * \param[out] minmax The data range
814 * \param[in] fieldName The array name
815 * \param[in] type The DataAttributeType
816 * \param[in] component The field component, -1 means magnitude
817 * \return boolean indicating if field was found
818 */
819bool DataSet::getDataRange(double minmax[2], const char *fieldName,
820                           DataAttributeType type, int component) const
821{
822    if (_dataSet == NULL)
823        return false;
824    switch (type) {
825    case POINT_DATA:
826        if (_dataSet->GetPointData() != NULL &&
827            _dataSet->GetPointData()->GetArray(fieldName) != NULL) {
828            _dataSet->GetPointData()->GetArray(fieldName)->GetRange(minmax, component);
829            return true;
830        } else {
831            return false;
832        }
833        break;
834    case CELL_DATA:
835        if (_dataSet->GetCellData() != NULL &&
836            _dataSet->GetCellData()->GetArray(fieldName) != NULL) {
837            _dataSet->GetCellData()->GetArray(fieldName)->GetRange(minmax, component);
838            return true;
839        } else {
840            return false;
841        }
842        break;
843    case FIELD_DATA:
844        if (_dataSet->GetFieldData() != NULL &&
845            _dataSet->GetFieldData()->GetArray(fieldName) != NULL) {
846            _dataSet->GetFieldData()->GetArray(fieldName)->GetRange(minmax, component);
847            return true;
848        } else {
849            return false;
850        }
851        break;
852    default:
853        ERROR("Unknown DataAttributeType %d", type);
854        break;
855    }
856    return false;
857}
858
859/**
860 * \brief Get the bounds the DataSet
861 */
862void DataSet::getBounds(double bounds[6]) const
863{
864    _dataSet->GetBounds(bounds);
865}
866
867/**
868 * \brief Get the range of cell AABB diagonal lengths in the DataSet
869 */
870void DataSet::getCellSizeRange(double minmax[2], double *average)
871{
872    // Check for cached values
873    if (_cellSizeRange[0] >= 0.0) {
874        minmax[0] = _cellSizeRange[0];
875        minmax[1] = _cellSizeRange[1];
876        *average = _cellSizeAverage;
877        return;
878    }
879
880    getCellSizeRange(_dataSet, minmax, average);
881
882    // Save values in cache
883    _cellSizeRange[0] = minmax[0];
884    _cellSizeRange[1] = minmax[1];
885    _cellSizeAverage = *average;
886}
887
888/**
889 * \brief Get the range of cell AABB diagonal lengths in the DataSet
890 */
891void DataSet::getCellSizeRange(vtkDataSet *dataSet, double minmax[2], double *average)
892{
893    if (dataSet == NULL ||
894        dataSet->GetNumberOfCells() < 1) {
895        minmax[0] = 1;
896        minmax[1] = 1;
897        *average = 1;
898        return;
899    }
900
901    minmax[0] = DBL_MAX;
902    minmax[1] = -DBL_MAX;
903
904    *average = 0;
905    for (int i = 0; i < dataSet->GetNumberOfCells(); i++) {
906        double length2 = dataSet->GetCell(i)->GetLength2();
907        if (length2 < minmax[0])
908            minmax[0] = length2;
909        if (length2 > minmax[1])
910            minmax[1] = length2;
911        *average += length2;
912    }
913    if (minmax[0] == DBL_MAX)
914        minmax[0] = 1;
915    if (minmax[1] == -DBL_MAX)
916        minmax[1] = 1;
917
918    minmax[0] = sqrt(minmax[0]);
919    minmax[1] = sqrt(minmax[1]);
920    *average = sqrt(*average/((double)dataSet->GetNumberOfCells()));
921}
922
923/**
924 * \brief Get nearest data value given world coordinates x,y,z
925 *
926 * Note: no interpolation is performed on data
927 *
928 * \param[in] x World x coordinate to probe
929 * \param[in] y World y coordinate to probe
930 * \param[in] z World z coordinate to probe
931 * \param[out] value On success, contains the data value
932 * \return boolean indicating success or failure
933 */
934bool DataSet::getScalarValue(double x, double y, double z, double *value) const
935{
936    if (_dataSet == NULL)
937        return false;
938    if (_dataSet->GetPointData() == NULL ||
939        _dataSet->GetPointData()->GetScalars() == NULL) {
940        return false;
941    }
942    vtkIdType pt = _dataSet->FindPoint(x, y, z);
943    if (pt < 0)
944        return false;
945    *value = _dataSet->GetPointData()->GetScalars()->GetComponent(pt, 0);
946    return true;
947}
948
949/**
950 * \brief Get nearest vector data value given world coordinates x,y,z
951 *
952 * Note: no interpolation is performed on data
953 *
954 * \param[in] x World x coordinate to probe
955 * \param[in] y World y coordinate to probe
956 * \param[in] z World z coordinate to probe
957 * \param[out] vector On success, contains the data values
958 * \return boolean indicating success or failure
959 */
960bool DataSet::getVectorValue(double x, double y, double z, double vector[3]) const
961{
962    if (_dataSet == NULL)
963        return false;
964    if (_dataSet->GetPointData() == NULL ||
965        _dataSet->GetPointData()->GetVectors() == NULL) {
966        return false;
967    }
968    vtkIdType pt = _dataSet->FindPoint(x, y, z);
969    if (pt < 0)
970        return false;
971    assert(_dataSet->GetPointData()->GetVectors()->GetNumberOfComponents() == 3);
972    _dataSet->GetPointData()->GetVectors()->GetTuple(pt, vector);
973    return true;
974}
Note: See TracBrowser for help on using the repository browser.