source: branches/blt4/packages/vizservers/vtkvis/DataSet.cpp @ 3958

Last change on this file since 3958 was 3958, checked in by gah, 11 years ago

sync with trunk

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