vtkGenericDataArrayLookupHelper.h 3.9 KB
Newer Older
1
2
3
/*=========================================================================

  Program:   Visualization Toolkit
4
  Module:    vtkGenericDataArrayLookupHelper.h
5
6
7
8
9
10
11
12
13
14

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
15
16
// .NAME vtkGenericDataArrayLookupHelper - internal class used by
// vtkGenericDataArray to support LookupValue.
17
18
// .SECTION Description

19
20
#ifndef vtkGenericDataArrayLookupHelper_h
#define vtkGenericDataArrayLookupHelper_h
21
22
23
24
25
26
27
28
29
30
31
32

#include <algorithm>
#include "vtkIdList.h"

namespace detail
{
  // this can be removed when C++11 is required.
  template< class T > struct remove_const { typedef T type; };
  template< class T > struct remove_const<const T> { typedef T type; };
}

template <class ArrayTypeT>
33
class vtkGenericDataArrayLookupHelper
34
35
36
37
38
39
40
{
public:
  typedef ArrayTypeT ArrayType;
  typedef typename ArrayType::ScalarType ScalarType;
  typedef typename ArrayType::TupleIteratorType TupleIteratorType;

  // Constructor.
41
  vtkGenericDataArrayLookupHelper(ArrayType& associatedArray)
42
43
44
45
    : AssociatedArray(associatedArray),
    SortedArray(NULL)
    {
    }
46
  ~vtkGenericDataArrayLookupHelper()
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
    {
    this->ClearLookup();
    }

  vtkIdType LookupValue(ScalarType elem)
    {
    this->UpdateLookup();
    ValueWithIndex temp;
    temp.Value = elem;
    ValueWithIndex* pos =
      std::lower_bound(this->SortedArray, this->SortedArray + this->SortedArraySize, temp);
    if (pos == (this->SortedArray + this->SortedArraySize))
      {
      return -1;
      }
    if (pos->Value != elem)
      {
      return -1;
      }
    return pos->Index;
    }

  void LookupValue(ScalarType elem, vtkIdList* ids)
    {
    this->UpdateLookup();
    ValueWithIndex temp;
    temp.Value = elem;
    std::pair<ValueWithIndex*, ValueWithIndex*> range =
      std::equal_range(this->SortedArray, this->SortedArray + this->SortedArraySize, temp);
    while (range.first != range.second)
      {
      // assert(range.first->Value == elem);
      ids->InsertNextId(range.first->Index);
      ++range.first;
      }
    }

  // Description:
  // Release any allocated memory for internal data-structures.
  void ClearLookup()
    {
    free(this->SortedArray);
    this->SortedArray = NULL;
    this->SortedArraySize = 0;
    }

private:
94
95
  vtkGenericDataArrayLookupHelper(const vtkGenericDataArrayLookupHelper&); // Not implemented.
  void operator=(const vtkGenericDataArrayLookupHelper&); // Not implemented.
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135

  struct ValueWithIndex
    {
    typename detail::remove_const<ScalarType>::type Value;
    vtkIdType Index;
    inline bool operator<(const ValueWithIndex& other) const
      {
      return this->Value < other.Value;
      }
    };

  void UpdateLookup()
    {
    if (this->SortedArray) { return; }

    int numComps = this->AssociatedArray.GetNumberOfComponents();
    this->SortedArraySize = this->AssociatedArray.GetNumberOfTuples() * numComps;

    if (this->SortedArraySize == 0) { return; }

    this->SortedArray = reinterpret_cast<ValueWithIndex*>(malloc(this->SortedArraySize * sizeof(ValueWithIndex)));
    for (TupleIteratorType iter = this->AssociatedArray.Begin(); iter != this->AssociatedArray.End(); ++iter)
      {
      for (int cc=0; cc < numComps; ++cc)
        {
        ValueWithIndex& item = this->SortedArray[iter.GetIndex()*numComps+cc];
        item.Value = iter[cc];
        item.Index = iter.GetIndex();
        // not preserving component index for now.
        }
      }
    std::sort(this->SortedArray, this->SortedArray + this->SortedArraySize);
    }

  ArrayTypeT& AssociatedArray;
  ValueWithIndex* SortedArray;
  vtkIdType SortedArraySize;
};

#endif