source: vtkvis/tags/1.7.1/DataSet.cpp @ 4832

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

Add volume blendmode option for VTK volume renderer. Also, don't change field
active scalar if requested field not found in dataset (previously, active
scalar field would be cleared to NULL if field not found).

  • Property svn:eol-style set to native
File size: 30.9 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 (!hasField(name)) {
395            ERROR("No field named %s in %s", name, getName().c_str());
396        } else {
397            if (_dataSet->GetPointData() != NULL) {
398                if (_dataSet->GetPointData()->SetActiveScalars(name) >= 0) {
399                    TRACE("Set active point data scalars for %s to %s", getName().c_str(), name);
400                    found = true;
401                }
402            }
403            if (_dataSet->GetCellData() != NULL) {
404                if (_dataSet->GetCellData()->SetActiveScalars(name) >= 0) {
405                    TRACE("Set active cell data scalars for %s to %s", getName().c_str(), name);
406                    found = true;
407                }
408            }
409        }
410    }
411#ifdef WANT_TRACE
412    if (_dataSet->GetPointData() != NULL) {
413        if (_dataSet->GetPointData()->GetScalars() != NULL) {
414            TRACE("Point data scalars for %s: %s", getName().c_str(), _dataSet->GetPointData()->GetScalars()->GetName());
415        } else {
416            TRACE("NULL point data scalars for %s", getName().c_str());
417        }
418    }
419    if (_dataSet->GetCellData() != NULL) {
420        if (_dataSet->GetCellData()->GetScalars() != NULL) {
421            TRACE("Cell data scalars for %s: %s", getName().c_str(), _dataSet->GetCellData()->GetScalars()->GetName());
422        } else {
423            TRACE("NULL cell data scalars for %s", getName().c_str());
424        }
425    }
426#endif
427    return found;
428}
429
430/**
431 * \brief Get the active scalar array field name
432 */
433const char *DataSet::getActiveScalarsName() const
434{
435    if (_dataSet != NULL) {
436         if (_dataSet->GetPointData() != NULL &&
437             _dataSet->GetPointData()->GetScalars() != NULL) {
438            return _dataSet->GetPointData()->GetScalars()->GetName();
439        }
440#ifdef DEBUG
441        TRACE("No point scalars");
442#endif
443        if (_dataSet->GetCellData() != NULL &&
444            _dataSet->GetCellData()->GetScalars() != NULL) {
445            return _dataSet->GetCellData()->GetScalars()->GetName();
446        }
447#ifdef DEBUG
448        TRACE("No cell scalars");
449#endif
450    }
451    return NULL;
452}
453
454/**
455 * \brief Get the active scalar array default attribute type
456 */
457DataSet::DataAttributeType DataSet::getActiveScalarsType() const
458{
459    if (_dataSet != NULL) {
460         if (_dataSet->GetPointData() != NULL &&
461             _dataSet->GetPointData()->GetScalars() != NULL) {
462            return POINT_DATA;
463        }
464#ifdef DEBUG
465        TRACE("No point scalars");
466#endif
467        if (_dataSet->GetCellData() != NULL &&
468            _dataSet->GetCellData()->GetScalars() != NULL) {
469            return CELL_DATA;
470        }
471#ifdef DEBUG
472        TRACE("No cell scalars");
473#endif
474    }
475    return POINT_DATA;
476}
477
478/**
479 * \brief Set the ative vector array to the named field
480 */
481bool DataSet::setActiveVectors(const char *name)
482{
483    bool found = false;
484    if (_dataSet != NULL) {
485        if (_dataSet->GetPointData() != NULL) {
486            if (_dataSet->GetPointData()->SetActiveVectors(name) >= 0) {
487                TRACE("Set active point data vectors to %s", name);
488                found = true;
489            }
490        }
491        if (_dataSet->GetCellData() != NULL) {
492            if (_dataSet->GetCellData()->SetActiveVectors(name) >= 0) {
493                TRACE("Set active cell data vectors to %s", name);
494                found = true;
495            }
496        }
497    }
498
499    return found;
500}
501
502/**
503 * \brief Get the active vector array default attribute type
504 */
505DataSet::DataAttributeType DataSet::getActiveVectorsType() const
506{
507    if (_dataSet != NULL) {
508         if (_dataSet->GetPointData() != NULL &&
509             _dataSet->GetPointData()->GetVectors() != NULL) {
510            return POINT_DATA;
511        }
512#ifdef DEBUG
513        TRACE("No point vectors");
514#endif
515        if (_dataSet->GetCellData() != NULL &&
516            _dataSet->GetCellData()->GetVectors() != NULL) {
517            return CELL_DATA;
518        }
519#ifdef DEBUG
520        TRACE("No cell vectors");
521#endif
522    }
523    return POINT_DATA;
524}
525
526/**
527 * \brief Get the active vector array field name
528 */
529const char *DataSet::getActiveVectorsName() const
530{
531    if (_dataSet != NULL) {
532        if (_dataSet->GetPointData() != NULL &&
533            _dataSet->GetPointData()->GetVectors() != NULL) {
534            return _dataSet->GetPointData()->GetVectors()->GetName();
535        }
536#ifdef DEBUG
537        TRACE("No point vectors");
538#endif
539        if (_dataSet->GetCellData() != NULL &&
540            _dataSet->GetCellData()->GetVectors() != NULL) {
541            return _dataSet->GetCellData()->GetVectors()->GetName();
542        }
543#ifdef DEBUG
544        TRACE("No cell vectors");
545#endif
546    }
547    return NULL;
548}
549
550void DataSet::setDefaultArrays()
551{
552    if (_dataSet->GetPointData() != NULL &&
553        _dataSet->GetPointData()->GetScalars() == NULL &&
554        _dataSet->GetPointData()->GetNumberOfArrays() > 0) {
555        for (int i = 0; i < _dataSet->GetPointData()->GetNumberOfArrays(); i++) {
556            if (_dataSet->GetPointData()->GetArray(i) != NULL &&
557                _dataSet->GetPointData()->GetArray(i)->GetNumberOfComponents() == 1) {
558                TRACE("Setting point scalars to '%s'", _dataSet->GetPointData()->GetArrayName(i));
559                _dataSet->GetPointData()->SetActiveScalars(_dataSet->GetPointData()->GetArrayName(i));
560                break;
561            }
562        }
563    }
564    if (_dataSet->GetPointData() != NULL &&
565        _dataSet->GetPointData()->GetVectors() == NULL &&
566        _dataSet->GetPointData()->GetNumberOfArrays() > 0) {
567        for (int i = 0; i < _dataSet->GetPointData()->GetNumberOfArrays(); i++) {
568            if (_dataSet->GetPointData()->GetArray(i) != NULL &&
569                _dataSet->GetPointData()->GetArray(i)->GetNumberOfComponents() == 3) {
570                TRACE("Setting point vectors to '%s'", _dataSet->GetPointData()->GetArrayName(i));
571                _dataSet->GetPointData()->SetActiveVectors(_dataSet->GetPointData()->GetArrayName(i));
572                break;
573            }
574        }
575    }
576    if (_dataSet->GetCellData() != NULL &&
577        _dataSet->GetCellData()->GetScalars() == NULL &&
578        _dataSet->GetCellData()->GetNumberOfArrays() > 0) {
579        for (int i = 0; i < _dataSet->GetCellData()->GetNumberOfArrays(); i++) {
580            if (_dataSet->GetCellData()->GetArray(i) != NULL &&
581                _dataSet->GetCellData()->GetArray(i)->GetNumberOfComponents() == 1) {
582                TRACE("Setting cell scalars to '%s'", _dataSet->GetCellData()->GetArrayName(i));
583                _dataSet->GetCellData()->SetActiveScalars(_dataSet->GetCellData()->GetArrayName(i));
584                break;
585            }
586        }
587    }
588    if (_dataSet->GetCellData() != NULL &&
589        _dataSet->GetCellData()->GetVectors() == NULL &&
590        _dataSet->GetCellData()->GetNumberOfArrays() > 0) {
591        for (int i = 0; i < _dataSet->GetCellData()->GetNumberOfArrays(); i++) {
592            if (_dataSet->GetCellData()->GetArray(i) != NULL &&
593                _dataSet->GetCellData()->GetArray(i)->GetNumberOfComponents() == 3) {
594                TRACE("Setting cell vectors to '%s'", _dataSet->GetCellData()->GetArrayName(i));
595                _dataSet->GetCellData()->SetActiveVectors(_dataSet->GetCellData()->GetArrayName(i));
596                break;
597            }
598        }
599    }
600}
601
602bool DataSet::getFieldInfo(const char *fieldName,
603                           DataAttributeType *type,
604                           int *numComponents) const
605{
606    if (_dataSet->GetPointData() != NULL &&
607        _dataSet->GetPointData()->GetAbstractArray(fieldName) != NULL) {
608        if (type != NULL)
609            *type = POINT_DATA;
610        if (numComponents != NULL)
611            *numComponents = _dataSet->GetPointData()->GetAbstractArray(fieldName)->GetNumberOfComponents();
612        return true;
613    } else if (_dataSet->GetCellData() != NULL &&
614               _dataSet->GetCellData()->GetAbstractArray(fieldName) != NULL) {
615        if (type != NULL)
616            *type = CELL_DATA;
617        if (numComponents != NULL)
618            *numComponents = _dataSet->GetCellData()->GetAbstractArray(fieldName)->GetNumberOfComponents();
619        return true;
620    } else if (_dataSet->GetFieldData() != NULL &&
621               _dataSet->GetFieldData()->GetAbstractArray(fieldName) != NULL) {
622        if (type != NULL)
623            *type = FIELD_DATA;
624        if (numComponents != NULL)
625            *numComponents = _dataSet->GetFieldData()->GetAbstractArray(fieldName)->GetNumberOfComponents();
626        return true;
627    }
628    return false;
629}
630
631bool DataSet::getFieldInfo(const char *fieldName,
632                           DataAttributeType type,
633                           int *numComponents) const
634{
635    switch (type) {
636    case POINT_DATA:
637        if (_dataSet->GetPointData() != NULL &&
638            _dataSet->GetPointData()->GetAbstractArray(fieldName) != NULL) {
639            if (numComponents != NULL)
640                *numComponents = _dataSet->GetPointData()->GetAbstractArray(fieldName)->GetNumberOfComponents();
641            return true;
642        } else
643            return false;
644        break;
645    case CELL_DATA:
646        if (_dataSet->GetCellData() != NULL &&
647            _dataSet->GetCellData()->GetAbstractArray(fieldName) != NULL) {
648            if (numComponents != NULL)
649                *numComponents = _dataSet->GetCellData()->GetAbstractArray(fieldName)->GetNumberOfComponents();
650            return true;
651        } else
652            return false;
653        break;
654    case FIELD_DATA:
655        if (_dataSet->GetFieldData() != NULL &&
656            _dataSet->GetFieldData()->GetAbstractArray(fieldName) != NULL) {
657            if (numComponents != NULL)
658                *numComponents = _dataSet->GetFieldData()->GetAbstractArray(fieldName)->GetNumberOfComponents();
659            return true;
660        } else
661            return false;
662        break;
663    default:
664        ;
665    }
666    return false;
667}
668
669/**
670 * \brief Get the list of field names in the DataSet
671 *
672 * \param[in,out] names The field names will be appended to this list
673 * \param[in] type The DataAttributeType: e.g. POINT_DATA, CELL_DATA
674 * \param[in] numComponents Filter list by number of components, -1 means to
675 * return all fields regardless of dimension
676 */
677void DataSet::getFieldNames(std::vector<std::string>& names,
678                            DataAttributeType type, int numComponents) const
679{
680    if (_dataSet == NULL)
681        return;
682    switch (type) {
683    case POINT_DATA:
684        if (_dataSet->GetPointData() != NULL) {
685            for (int i = 0; i < _dataSet->GetPointData()->GetNumberOfArrays(); i++) {
686                if (numComponents == -1 ||
687                    (_dataSet->GetPointData()->GetAbstractArray(i) != NULL &&
688                     _dataSet->GetPointData()->GetAbstractArray(i)->GetNumberOfComponents() == numComponents)) {
689                    names.push_back(_dataSet->GetPointData()->GetArrayName(i));
690                }
691            }
692        }
693        break;
694    case CELL_DATA:
695        if (_dataSet->GetCellData() != NULL) {
696            for (int i = 0; i < _dataSet->GetCellData()->GetNumberOfArrays(); i++) {
697                if (numComponents == -1 ||
698                    (_dataSet->GetCellData()->GetAbstractArray(i) != NULL &&
699                     _dataSet->GetCellData()->GetAbstractArray(i)->GetNumberOfComponents() == numComponents)) {
700                    names.push_back(_dataSet->GetCellData()->GetArrayName(i));
701                }
702            }
703        }
704        break;
705    case FIELD_DATA:
706        if (_dataSet->GetFieldData() != NULL) {
707            for (int i = 0; i < _dataSet->GetFieldData()->GetNumberOfArrays(); i++) {
708                if (numComponents == -1 ||
709                    (_dataSet->GetFieldData()->GetAbstractArray(i) != NULL &&
710                     _dataSet->GetFieldData()->GetAbstractArray(i)->GetNumberOfComponents() == numComponents)) {
711                    names.push_back(_dataSet->GetFieldData()->GetArrayName(i));
712                }
713            }
714        }
715        break;
716    default:
717        ERROR("Unknown DataAttributeType %d", type);
718    }
719}
720
721/**
722 * \brief Get the range of scalar values in the DataSet
723 */
724void DataSet::getScalarRange(double minmax[2]) const
725{
726    if (_dataSet == NULL)
727        return;
728    if (_dataSet->GetPointData() != NULL &&
729        _dataSet->GetPointData()->GetScalars() != NULL) {
730        _dataSet->GetPointData()->GetScalars()->GetRange(minmax, -1);
731    } else if (_dataSet->GetCellData() != NULL &&
732               _dataSet->GetCellData()->GetScalars() != NULL) {
733        _dataSet->GetCellData()->GetScalars()->GetRange(minmax, -1);
734    }
735}
736
737/**
738 * \brief Get the range of a vector component in the DataSet
739 *
740 * \param[out] minmax The data range
741 * \param[in] component The field component, -1 means magnitude
742 */
743void DataSet::getVectorRange(double minmax[2], int component) const
744{
745    if (_dataSet == NULL)
746        return;
747    if (_dataSet->GetPointData() != NULL &&
748        _dataSet->GetPointData()->GetVectors() != NULL) {
749        _dataSet->GetPointData()->GetVectors()->GetRange(minmax, component);
750    } else if (_dataSet->GetCellData() != NULL &&
751               _dataSet->GetCellData()->GetVectors() != NULL) {
752        _dataSet->GetCellData()->GetVectors()->GetRange(minmax, component);
753    }
754}
755
756/**
757 * \brief Get the range of values for the named field in the DataSet
758 *
759 * \param[out] minmax The data range
760 * \param[in] fieldName The array name
761 * \param[in] type The DataAttributeType
762 * \param[in] component The field component, -1 means magnitude
763 * \return boolean indicating if field was found
764 */
765bool DataSet::getDataRange(double minmax[2], const char *fieldName,
766                           DataAttributeType type, int component) const
767{
768    if (_dataSet == NULL)
769        return false;
770    switch (type) {
771    case POINT_DATA:
772        if (_dataSet->GetPointData() != NULL &&
773            _dataSet->GetPointData()->GetArray(fieldName) != NULL) {
774            _dataSet->GetPointData()->GetArray(fieldName)->GetRange(minmax, component);
775            return true;
776        } else {
777            return false;
778        }
779        break;
780    case CELL_DATA:
781        if (_dataSet->GetCellData() != NULL &&
782            _dataSet->GetCellData()->GetArray(fieldName) != NULL) {
783            _dataSet->GetCellData()->GetArray(fieldName)->GetRange(minmax, component);
784            return true;
785        } else {
786            return false;
787        }
788        break;
789    case FIELD_DATA:
790        if (_dataSet->GetFieldData() != NULL &&
791            _dataSet->GetFieldData()->GetArray(fieldName) != NULL) {
792            _dataSet->GetFieldData()->GetArray(fieldName)->GetRange(minmax, component);
793            return true;
794        } else {
795            return false;
796        }
797        break;
798    default:
799        ERROR("Unknown DataAttributeType %d", type);
800        break;
801    }
802    return false;
803}
804
805/**
806 * \brief Get the bounds the DataSet
807 */
808void DataSet::getBounds(double bounds[6]) const
809{
810    _dataSet->GetBounds(bounds);
811}
812
813/**
814 * \brief Get the range of cell AABB diagonal lengths in the DataSet
815 */
816void DataSet::getCellSizeRange(double minmax[2], double *average)
817{
818    // Check for cached values
819    if (_cellSizeRange[0] >= 0.0) {
820        minmax[0] = _cellSizeRange[0];
821        minmax[1] = _cellSizeRange[1];
822        *average = _cellSizeAverage;
823        return;
824    }
825
826    getCellSizeRange(_dataSet, minmax, average);
827
828    // Save values in cache
829    _cellSizeRange[0] = minmax[0];
830    _cellSizeRange[1] = minmax[1];
831    _cellSizeAverage = *average;
832}
833
834/**
835 * \brief Get the range of cell AABB diagonal lengths in the DataSet
836 */
837void DataSet::getCellSizeRange(vtkDataSet *dataSet, double minmax[2], double *average)
838{
839    if (dataSet == NULL ||
840        dataSet->GetNumberOfCells() < 1) {
841        minmax[0] = 1;
842        minmax[1] = 1;
843        *average = 1;
844        return;
845    }
846
847    minmax[0] = DBL_MAX;
848    minmax[1] = -DBL_MAX;
849
850    *average = 0;
851    for (int i = 0; i < dataSet->GetNumberOfCells(); i++) {
852        double length2 = dataSet->GetCell(i)->GetLength2();
853        if (length2 < minmax[0])
854            minmax[0] = length2;
855        if (length2 > minmax[1])
856            minmax[1] = length2;
857        *average += length2;
858    }
859    if (minmax[0] == DBL_MAX)
860        minmax[0] = 1;
861    if (minmax[1] == -DBL_MAX)
862        minmax[1] = 1;
863
864    minmax[0] = sqrt(minmax[0]);
865    minmax[1] = sqrt(minmax[1]);
866    *average = sqrt(*average/((double)dataSet->GetNumberOfCells()));
867}
868
869/**
870 * \brief Get nearest data value given world coordinates x,y,z
871 *
872 * Note: no interpolation is performed on data
873 *
874 * \param[in] x World x coordinate to probe
875 * \param[in] y World y coordinate to probe
876 * \param[in] z World z coordinate to probe
877 * \param[out] value On success, contains the data value
878 * \return boolean indicating success or failure
879 */
880bool DataSet::getScalarValue(double x, double y, double z, double *value) const
881{
882    if (_dataSet == NULL)
883        return false;
884    if (_dataSet->GetPointData() == NULL ||
885        _dataSet->GetPointData()->GetScalars() == NULL) {
886        return false;
887    }
888    vtkIdType pt = _dataSet->FindPoint(x, y, z);
889    if (pt < 0)
890        return false;
891    *value = _dataSet->GetPointData()->GetScalars()->GetComponent(pt, 0);
892    return true;
893}
894
895/**
896 * \brief Get nearest vector data value given world coordinates x,y,z
897 *
898 * Note: no interpolation is performed on data
899 *
900 * \param[in] x World x coordinate to probe
901 * \param[in] y World y coordinate to probe
902 * \param[in] z World z coordinate to probe
903 * \param[out] vector On success, contains the data values
904 * \return boolean indicating success or failure
905 */
906bool DataSet::getVectorValue(double x, double y, double z, double vector[3]) const
907{
908    if (_dataSet == NULL)
909        return false;
910    if (_dataSet->GetPointData() == NULL ||
911        _dataSet->GetPointData()->GetVectors() == NULL) {
912        return false;
913    }
914    vtkIdType pt = _dataSet->FindPoint(x, y, z);
915    if (pt < 0)
916        return false;
917    assert(_dataSet->GetPointData()->GetVectors()->GetNumberOfComponents() == 3);
918    _dataSet->GetPointData()->GetVectors()->GetTuple(pt, vector);
919    return true;
920}
921
922void DataSet::print() const
923{
924    print(_dataSet);
925}
926
927void DataSet::print(vtkDataSet *ds)
928{
929    if (ds == NULL)
930        return;
931
932    TRACE("DataSet class: %s", ds->GetClassName());
933
934    TRACE("DataSet memory: %g MiB", ds->GetActualMemorySize()/1024.);
935
936    double bounds[6];
937    ds->GetBounds(bounds);
938
939    // Topology
940    TRACE("DataSet bounds: %g %g %g %g %g %g",
941          bounds[0], bounds[1],
942          bounds[2], bounds[3],
943          bounds[4], bounds[5]);
944    TRACE("Points: %d Cells: %d", ds->GetNumberOfPoints(), ds->GetNumberOfCells());
945
946    double dataRange[2];
947    if (ds->GetPointData() != NULL) {
948        TRACE("PointData arrays: %d", ds->GetPointData()->GetNumberOfArrays());
949        for (int i = 0; i < ds->GetPointData()->GetNumberOfArrays(); i++) {
950            if (ds->GetPointData()->GetArray(i) != NULL) {
951                ds->GetPointData()->GetArray(i)->GetRange(dataRange, -1);
952                TRACE("PointData[%d]: '%s' comp:%d, (%g,%g)", i,
953                      ds->GetPointData()->GetArrayName(i),
954                      ds->GetPointData()->GetAbstractArray(i)->GetNumberOfComponents(),
955                      dataRange[0], dataRange[1]);
956            } else {
957                TRACE("PointData[%d]: '%s' comp:%d", i,
958                      ds->GetPointData()->GetArrayName(i),
959                      ds->GetPointData()->GetAbstractArray(i)->GetNumberOfComponents());
960            }
961        }
962        if (ds->GetPointData()->GetScalars() != NULL) {
963            TRACE("Active point scalars: %s", ds->GetPointData()->GetScalars()->GetName());
964        }
965        if (ds->GetPointData()->GetVectors() != NULL) {
966            TRACE("Active point vectors: %s", ds->GetPointData()->GetVectors()->GetName());
967        }
968    }
969    if (ds->GetCellData() != NULL) {
970        TRACE("CellData arrays: %d", ds->GetCellData()->GetNumberOfArrays());
971        for (int i = 0; i < ds->GetCellData()->GetNumberOfArrays(); i++) {
972            if (ds->GetCellData()->GetArray(i) != NULL) {
973                ds->GetCellData()->GetArray(i)->GetRange(dataRange, -1);
974                TRACE("CellData[%d]: '%s' comp:%d, (%g,%g)", i,
975                      ds->GetCellData()->GetArrayName(i),
976                      ds->GetCellData()->GetAbstractArray(i)->GetNumberOfComponents(),
977                      dataRange[0], dataRange[1]);
978            } else {
979                TRACE("CellData[%d]: '%s' comp:%d", i,
980                      ds->GetCellData()->GetArrayName(i),
981                      ds->GetCellData()->GetAbstractArray(i)->GetNumberOfComponents());
982            }
983        }
984        if (ds->GetCellData()->GetScalars() != NULL) {
985            TRACE("Active cell scalars: %s", ds->GetCellData()->GetScalars()->GetName());
986        }
987        if (ds->GetCellData()->GetVectors() != NULL) {
988            TRACE("Active cell vectors: %s", ds->GetCellData()->GetVectors()->GetName());
989        }
990    }
991    if (ds->GetFieldData() != NULL) {
992        TRACE("FieldData arrays: %d", ds->GetFieldData()->GetNumberOfArrays());
993        for (int i = 0; i < ds->GetFieldData()->GetNumberOfArrays(); i++) {
994            if (ds->GetFieldData()->GetArray(i) != NULL) {
995                ds->GetFieldData()->GetArray(i)->GetRange(dataRange, -1);
996                TRACE("FieldData[%d]: '%s' comp:%d, tuples:%d (%g,%g)", i,
997                      ds->GetFieldData()->GetArrayName(i),
998                      ds->GetFieldData()->GetAbstractArray(i)->GetNumberOfComponents(),
999                      ds->GetFieldData()->GetAbstractArray(i)->GetNumberOfTuples(),
1000                      dataRange[0], dataRange[1]);
1001            } else {
1002                TRACE("FieldData[%d]: '%s' comp:%d, tuples:%d", i,
1003                      ds->GetFieldData()->GetArrayName(i),
1004                      ds->GetFieldData()->GetAbstractArray(i)->GetNumberOfComponents(),
1005                      ds->GetFieldData()->GetAbstractArray(i)->GetNumberOfTuples());
1006            }
1007        }
1008    }
1009}
1010
Note: See TracBrowser for help on using the repository browser.