SVolumeDatabase.h
Go to the documentation of this file.
1 
2 #pragma once
3 
4 #include <glad/glad.h>
5 
6 #include "SVolume.h"
7 #include "IDatabase.h"
8 #include "IDataRecord.h"
9 
10 
11 namespace ion
12 {
13 
14  template <typename T>
16 
17  template <typename T>
18  struct SVolumeDataRecord : public IDataRecord<T>
19  {
20 
24 
25  T GetField(std::string const & Field) const;
26  T & GetField(std::string const & Field);
27 
28  std::vector<T> Values;
30 
31  };
32 
33  template <typename T>
34  struct SVolumeDatabase : public IDatabase<T>, public SVolume<SVolumeDataRecord<T>>
35  {
36 
38  using SVolume<SVolumeDataRecord<T>>::Dimensions;
39  using SVolume<SVolumeDataRecord<T>>::Get;
40 
43  {}
44 
45  void Allocate()
46  {
47  Values.resize(Dimensions.X * Dimensions.Y * Dimensions.Z, SVolumeDataRecord<T>(* this));
48  }
49 
50  void AddField(std::string const & Field)
51  {
52  if (HasField(Field))
53  return;
54 
55  Fields.push_back(Field);
56 
57  for (auto it = Values.begin(); it != Values.end(); ++ it)
58  it->Values.resize(Fields.size());
59  }
60 
61  bool HasField(std::string const & Field)
62  {
63  auto it = std::find(Fields.begin(), Fields.end(), Field);
64  return it != Fields.end();
65  }
66 
67  SRange<T> GetFieldRange(std::string const & Field, T const OutlierCutoff = 5, SRange<T> const & acceptedValues = SRange<T>::Full) const
68  {
69  // Calculate mean
70  T Mean = 0;
71  size_t Count = Values.size();
72  for (auto it = Values.begin(); it != Values.end(); ++ it)
73  {
74  T const v = it->GetField(Field);
75  if (! acceptedValues.Contains(v) || v != v)
76  Count --;
77  else
78  Mean += v;
79  }
80  Mean /= Count;
81 
82  // Calculate standard absolute value deviation
83  T StdDeviation = 0;
84  for (auto it = Values.begin(); it != Values.end(); ++ it)
85  {
86  double const v = it->GetField(Field);
87  if (acceptedValues.Contains(v) && v == v)
88  StdDeviation += abs(v - Mean);
89  }
90  StdDeviation /= Count - 1;
91 
92  // Find min/max
93  T Min = std::numeric_limits<T>::max(), Max = -std::numeric_limits<T>::max();
94  for (auto it = Values.begin(); it != Values.end(); ++ it)
95  {
96  T const v = it->GetField(Field);
97  if (v < Mean + OutlierCutoff * StdDeviation && v > Mean - OutlierCutoff * StdDeviation)
98  {
99  if (v > Max)
100  Max = v;
101  if (v < Min)
102  Min = v;
103  }
104  }
105 
106  return SRange<T>(Min, Max);
107  }
108 
109  void MakeOpenGLVolume(uint const VolumeHandle, IColorMapper * ColorMapper)
110  {
111  ColorMapper->PreProcessValues(* this);
112 
113  byte * const VolumeData = new byte[Dimensions.X * Dimensions.Y * Dimensions.Z * 4];
114 
115  for (int k = 0; k < Dimensions.Z; ++ k)
116  for (int j = 0; j < Dimensions.Y; ++ j)
117  for (int i = 0; i < Dimensions.X; ++ i)
118  {
119  int const Index = i + j * Dimensions.X + k * Dimensions.X * Dimensions.Y;
120  color4i const Color = ColorMapper->GetColor(Get(i, j, k));
121 
122  for (int t = 0; t < 4; ++ t)
123  VolumeData[Index * 4 + t] = Color[t];
124  }
125 
126  glBindTexture(GL_TEXTURE_3D, VolumeHandle);
127  glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
128  glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
129  glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
130  glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
131  glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
132  glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, Dimensions.X, Dimensions.Y, Dimensions.Z, 0, GL_RGBA, GL_UNSIGNED_BYTE, VolumeData);
133  glBindTexture(GL_TEXTURE_3D, 0);
134  }
135 
136  void WriteToFile(std::ofstream & File)
137  {
138  // Write Dimensions
139  File.write((char *) & Dimensions.X, sizeof(uint));
140  File.write((char *) & Dimensions.Y, sizeof(uint));
141  File.write((char *) & Dimensions.Z, sizeof(uint));
142 
143  // Write Fields
144  size_t const FieldCount = Fields.size();
145  File.write((char *) & FieldCount, sizeof(size_t));
146  for (auto it = Fields.begin(); it != Fields.end(); ++ it)
147  {
148  size_t const Length = it->size();
149  File.write((char *) & Length, sizeof(size_t));
150  File.write(it->c_str(), Length);
151  }
152 
153  // Write Records
154  size_t const RecordCount = Values.size();
155  File.write((char *) & RecordCount, sizeof(size_t));
156 
157  for (auto it = Values.begin(); it != Values.end(); ++ it)
158  File.write((char *) & it->Values.begin(), sizeof(T));
159  }
160 
161  void ReadFromFile(std::ifstream & File)
162  {
163  Values.clear();
164  Fields.clear();
165 
166  // Read Dimensions
167  File.read((char *) & Dimensions.X, sizeof(uint));
168  File.read((char *) & Dimensions.Y, sizeof(uint));
169  File.read((char *) & Dimensions.Z, sizeof(uint));
170 
171  // Read Fields
172  size_t FieldCount;
173  File.read((char *) & FieldCount, sizeof(size_t));
174 
175  for (size_t i = 0; i < FieldCount; ++ i)
176  {
177  size_t Length;
178  File.read((char *) & Length, sizeof(size_t));
179 
180  char * Buffer = new char[Length + 1];
181  File.read(Buffer, Length);
182  Buffer[Length] = '\0';
183 
184  Fields.push_back(Buffer);
185  delete[] Buffer;
186  }
187 
188  // Read Records
189  size_t RecordCount;
190  File.read((char *) & RecordCount, sizeof(size_t));
191  Values.reserve(RecordCount);
192 
193  for (size_t i = 0; i < RecordCount; ++ i)
194  {
195  SVolumeDataRecord<T> Record(* this);
196  for (size_t t = 0; t < FieldCount; ++ t)
197  {
198  T Value;
199  File.read((char *) & Value, sizeof(T));
200  Record.Values.push_back(Value);
201  }
202 
203  Values.push_back(Record);
204  }
205  }
206 
207  std::vector<std::string> Fields;
208 
209  };
210 
211  template <typename T>
213  : Database()
214  {}
215 
216  template <typename T>
218  : Database(& database)
219  {
220  Values.resize(Database->Fields.size(), 0);
221  }
222 
223  template <typename T>
225  {
226  if (!Database)
227  {
228  Database = other.Database;
229  Values.resize(Database->Fields.size(), 0);
230  }
231 
232  assert(Database == other.Database);
233  Values = other.Values;
234 
235  return * this;
236  }
237 
238  template <typename T>
239  T SVolumeDataRecord<T>::GetField(std::string const & Field) const
240  {
241  if (!Database->HasField(Field))
242  return 0;
243 
244  auto it = std::find(Database->Fields.begin(), Database->Fields.end(), Field);
245  assert(it != Database->Fields.end());
246 
247  return Values[std::distance(Database->Fields.begin(), it)];
248  }
249 
250  template <typename T>
251  T & SVolumeDataRecord<T>::GetField(std::string const & Field)
252  {
253  Database->AddField(Field);
254 
255  auto it = std::find(Database->Fields.begin(), Database->Fields.end(), Field);
256  assert(it != Database->Fields.end());
257 
258  return Values[std::distance(Database->Fields.begin(), it)];
259  }
260 
261 }
std::vector< T > Values
Definition: SVolumeDatabase.h:28
void Allocate()
Definition: SVolumeDatabase.h:45
Definition: SVolumeDatabase.h:18
unsigned char byte
Definition: ionTypes.h:45
SRange< T > GetFieldRange(std::string const &Field, T const OutlierCutoff=5, SRange< T > const &acceptedValues=SRange< T >::Full) const
Definition: SVolumeDatabase.h:67
Definition: IDatabase.h:12
void MakeOpenGLVolume(uint const VolumeHandle, IColorMapper *ColorMapper)
Definition: SVolumeDatabase.h:109
SVolumeDataRecord< T > & operator=(SVolumeDataRecord< T > const &other)
Definition: SVolumeDatabase.h:224
Definition: CCatmullRomAdvancedSplineInterpolator.h:7
unsigned int uint
Definition: ionTypes.h:42
SVolumeDatabase< T > * Database
Definition: SVolumeDatabase.h:29
Definition: SVolumeDatabase.h:15
Customized variant of vec4 that intelligently handles conversion between floating point and integer c...
Definition: color4.h:14
void ReadFromFile(std::ifstream &File)
Definition: SVolumeDatabase.h:161
void AddField(std::string const &Field)
Definition: SVolumeDatabase.h:50
Definition: IDataRecord.h:9
Definition: SVolume.h:12
virtual color4f const GetColor(IDataRecord< double > const &DataRecord)=0
bool HasField(std::string const &Field)
Definition: SVolumeDatabase.h:61
void WriteToFile(std::ofstream &File)
Definition: SVolumeDatabase.h:136
Definition: IColorMapper.h:14
SVolumeDataRecord()
Definition: SVolumeDatabase.h:212
T GetField(std::string const &Field) const
Definition: SVolumeDatabase.h:239
SVolumeDatabase()
Definition: SVolumeDatabase.h:41
Definition: SRange.h:11
std::vector< std::string > Fields
Definition: SVolumeDatabase.h:207
Helper methods for dealing with files.
Definition: File.h:14
virtual void PreProcessValues(IDatabase< double > &Database)=0