source: branches/blt4/packages/vizservers/vtkvis/RpVtkDataSet.cpp @ 2681

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