source: trunk/packages/vizservers/vtkvis/RpVtkDataSet.cpp @ 3492

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

First pass at handling user level errors in vtkvis.

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