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