cgv
Loading...
Searching...
No Matches
volume.cxx
1#include "volume.h"
2#include <fstream>
3#include <stdio.h>
4#include <cgv/utils/file.h>
5#include <cgv/utils/scan.h>
6#include <cgv/utils/tokenizer.h>
7
8#pragma warning(disable:4996)
9
10namespace cgv {
11 namespace media {
12 namespace volume {
13
14 volume::volume() : extent(1, 1, 1), df("uint8[L]")
15 {
16 }
17
19 volume::volume(const volume& V) : extent(V.extent), df(V.df)
20 {
21 new (&dv) cgv::data::data_view(&df);
22 std::copy(V.dv.get_ptr<cgv::type::uint8_type>(), V.dv.get_ptr<cgv::type::uint8_type>() + df.get_nr_bytes(), dv.get_ptr<cgv::type::uint8_type>());
23 }
24
27 {
28 return
29 df.get_nr_dimensions() > 2 ?
30 dimension_type(int(df.get_width()), int(df.get_height()), int(df.get_depth())) :
31 dimension_type(0, 0, 0);
32 }
33
36 {
37 return box_type(coord_type(-0.5) * extent, coord_type(0.5) * extent);
38 }
39
42 {
44 return extent_type(extent(0) / dims(0), extent(1) / dims(1), extent(2) / dims(2));
45 }
46
49 {
50 const data::data_format* existing_format_ptr = dv.get_format();
51 const data::data_format* component_format_ptr = component_dv.get_format();
52 cgv::type::info::TypeId existing_component_type = existing_format_ptr->get_component_type();
53
54 if(existing_component_type != component_format_ptr->get_component_type())
55 {
56 std::cerr << "Can not add different component types." << std::endl;
57 return false;
58 }
59
60 unsigned int nr_existing_components = existing_format_ptr->get_component_format().get_nr_components();
61 unsigned int nr_component_components = component_format_ptr->get_component_format().get_nr_components();
62
63 if(nr_existing_components < 1)
64 {
65 std::cerr << "Existing data view has no component." << std::endl;
66 return false;
67 }
68 if(nr_existing_components > 3)
69 {
70 std::cerr << "Existing data view already more than 3 components (" << std::to_string(nr_existing_components) << "). Cant add to that." << std::endl;
71 return false;
72 }
73
74 if(nr_component_components != 1)
75 {
76 std::cerr << "New component may only have one component, but has" << std::to_string(nr_component_components) << "." << std::endl;
77 return false;
78 }
79
80 unsigned int component_number_of_dimensions = component_format_ptr->get_nr_dimensions();
81 unsigned int existing_number_of_dimensions = existing_format_ptr->get_nr_dimensions();
82
83 if(component_number_of_dimensions < 3 || component_number_of_dimensions > 4 || component_number_of_dimensions != existing_number_of_dimensions)
84 {
85 std::cerr << "Both data views need to have 3 or 4 dimensions (and both the same number). They have " << std::to_string(existing_number_of_dimensions) << " (existing) and" << std::to_string(component_number_of_dimensions) << " (new component)." << std::endl;
86 return false;
87 }
88
89 if(component_format_ptr->get_height() != existing_format_ptr->get_height() || component_format_ptr->get_width() != existing_format_ptr->get_width() || component_format_ptr->get_depth() != existing_format_ptr->get_depth())
90 {
91 std::cerr << "The dimensions do not match: existing (" << std::to_string(existing_format_ptr->get_width()) << ", " << std::to_string(existing_format_ptr->get_height()) << ", " << std::to_string(existing_format_ptr->get_depth()) << ") vs. new component ("<< std::to_string(component_format_ptr->get_width()) << ", "<< std::to_string(component_format_ptr->get_height()) << ", " << std::to_string(component_format_ptr->get_depth()) <<")." << std::endl;
92 return false;
93 }
94
95 data::ComponentFormat result_component_format = data::CF_RG;
96 switch(nr_existing_components+nr_component_components) {
97 case 3: result_component_format = data::CF_RGB; break;
98 case 4: result_component_format = data::CF_RGBA; break;
99 default: result_component_format = data::CF_RG; break;
100 }
101
102 size_t w = existing_format_ptr->get_width();
103 size_t h = existing_format_ptr->get_height();
104 size_t d = existing_format_ptr->get_depth();
105 size_t t = 1;
106 if(component_number_of_dimensions == 4)
107 t = existing_format_ptr->get_nr_time_steps();
108
109 unsigned mask_t = 0;
110 if(component_number_of_dimensions == 4)
111 mask_t = 1;
112
113
114 data::data_format* result_data_format_ptr = new data::data_format(w, h, d, existing_component_type, result_component_format);
115
116 cgv::data::data_view combined_dv = data::data_view(result_data_format_ptr);
117
118 //component_type
119 unsigned component_size = cgv::type::info::get_type_size(existing_component_type);
120
121 for (unsigned x = 0; x < w; ++x) {
122 for (unsigned y = 0; y < h; ++y) {
123 for (unsigned z = 0; z < d; ++z) {
124 for (unsigned i = 0; i < t; ++i) {
125
126 unsigned char* existing_ptr = dv.get_ptr<unsigned char>(x, y, z , mask_t* i);
127 unsigned char* component_ptr = component_dv.get_ptr<unsigned char>(x, y, z, mask_t* i);
128 unsigned char* result_ptr = combined_dv.get_ptr<unsigned char>(x, y, z, mask_t* i);
129
130 const unsigned copy_size = component_size * nr_existing_components;
131 memcpy(result_ptr, existing_ptr, copy_size);
132 memcpy(result_ptr, component_ptr, component_size);
133
134 }
135 }
136 }
137 }
138
139 dv = combined_dv;
140 return true;
141
142 }
143
144 bool volume::replace_component(unsigned i, data::data_view& component_dv)
145 {
146 const data::data_format* existing_format_ptr = dv.get_format();
147 const data::data_format* component_format_ptr = component_dv.get_format();
148 if(existing_format_ptr->get_component_type() != component_format_ptr->get_component_type())
149 {
150 std::cerr << "Can not replace with different component types." << std::endl;
151 return false;
152 }
153
154 unsigned int nr_components = component_format_ptr->get_component_format().get_nr_components();
155 if(nr_components != 1)
156 {
157 std::cerr << "Replacement component may only have one component, but has" << std::to_string(nr_components) << "." << std::endl;
158 return false;
159 }
160
161 unsigned int component_number_of_dimensions = component_format_ptr->get_nr_dimensions();
162
163 if(component_number_of_dimensions < 3 || component_number_of_dimensions > 4)
164 {
165 std::cerr << "The replacement data view needs to have 3 or 4 dimensions, but has " << std::to_string(component_number_of_dimensions) << "." << std::endl;
166 return false;
167 }
168 if(component_number_of_dimensions != dv.get_format()->get_nr_dimensions())
169 {
170 std::cerr << "The replacement data view needs to have the same number of dimensions, but has " << std::to_string(component_number_of_dimensions) << " (existing has "<< std::to_string(dv.get_format()->get_nr_dimensions()) <<")." << std::endl;
171 return false;
172 }
173
174 if(component_format_ptr->get_height() != existing_format_ptr->get_height() || component_format_ptr->get_width() != existing_format_ptr->get_width() || component_format_ptr->get_depth() != existing_format_ptr->get_depth())
175 {
176 std::cerr << "The dimensions do not match: existing (" << std::to_string(existing_format_ptr->get_width()) << ", " << std::to_string(existing_format_ptr->get_height()) << ", " << std::to_string(existing_format_ptr->get_depth()) << ") vs. new component ("<< std::to_string(component_format_ptr->get_width()) << ", "<< std::to_string(component_format_ptr->get_height()) << ", " << std::to_string(component_format_ptr->get_depth()) <<")." << std::endl;
177 return false;
178 }
179
180 size_t w = existing_format_ptr->get_width();
181 size_t h = existing_format_ptr->get_height();
182 size_t d = existing_format_ptr->get_depth();
183 size_t t = 1;
184 if(component_number_of_dimensions == 4)
185 t = existing_format_ptr->get_nr_time_steps();
186
187
188 unsigned mask_t = 0;
189 if(component_number_of_dimensions == 4)
190 mask_t = 1;
191
192 unsigned component_size = cgv::type::info::get_type_size(existing_format_ptr->get_component_type());
193
194 for (unsigned i = 0; i < t; ++i) {
195 for (unsigned z = 0; z < d; ++z) {
196 for (unsigned y = 0; y < h; ++y) {
197 for (unsigned x = 0; x < w; ++x) {
198
199 unsigned char* existing_ptr = dv.get_ptr<unsigned char>(x, y, z, mask_t * i);
200 unsigned char* component_ptr = component_dv.get_ptr<unsigned char>(x, y, z, mask_t * i);
201
202 memcpy(existing_ptr, component_ptr, component_size);
203
204 }
205 }
206 }
207 }
208
209 return false;
210 }
211
212 std::size_t volume::get_nr_voxels() const
213 {
214 dimension_type dimensions = get_dimensions();
215 std::size_t n = dimensions(0);
216 n *= dimensions(1);
217 n *= dimensions(2);
218 return n;
219 }
220
222 {
223 df.set_width(S(0));
224 df.set_height(S(1));
225 df.set_depth(S(2));
227 }
228 }
229 }
230}
complete implementation of method actions that only call one method when entering a node
Definition action.h:113
cgv::type::info::TypeId get_component_type() const
return the component type
unsigned int get_nr_components() const
return the number of components
A data_format describes a multidimensional data block of data entries.
Definition data_format.h:17
unsigned get_nr_dimensions() const
return the number of dimensions of the data set
size_t get_depth() const
return the resolution in the third dimension, or 1 if not defined
void set_height(size_t _height)
set the resolution in the second dimension, add dimensions if necessary
void set_width(size_t _width)
set the resolution in the first dimension, add dimensions if necessary
size_t get_nr_time_steps() const
return the resolution in the highest dimension, or 1 if not defined
size_t get_width() const
return the resolution in the first dimension, or 1 if not defined
void set_depth(size_t _depth)
set the resolution in the third dimension, add dimensions if necessary
size_t get_height() const
return the resolution in the second dimension, or 1 if not defined
size_t get_nr_bytes() const
return the total number of bytes necessary to store the data
const component_format & get_component_format() const
return the component_format info by simple conversion of the this pointer
const data_format * get_format() const
return the component format
Definition data_view.cxx:73
cgv::type::func::transfer_const< P, S * >::type get_ptr() const
return a data pointer to type S
Definition data_view.h:61
the data view gives access to a data array of one, two, three or four dimensions.
Definition data_view.h:153
An axis aligned box, defined by to points: min and max.
extent_type extent
extent of the volume in each coordinate direction
Definition volume.h:29
cgv::data::data_format df
format description of volume data
Definition volume.h:25
cgv::data::data_view dv
data storage of volume data
Definition volume.h:27
box_type get_box() const
return the bounding box in volume coordinates, which is computed from spacing and dimensions and cent...
Definition volume.cxx:35
volume()
construct empty volume with unit cube as box and "uint8[L]" as component type
Definition volume.cxx:14
virtual void resize(const dimension_type &S)
resize the volume
Definition volume.cxx:221
size_t get_nr_voxels() const
return the total number of voxels
Definition volume.cxx:212
bool replace_component(unsigned i, data::data_view &component_dv)
replace the i-th component in the volume data by the given data
Definition volume.cxx:144
extent_type get_spacing() const
return the voxel spacing, computed by extent/dimensions
Definition volume.cxx:41
virtual dimension_type get_dimensions() const
return the dimensions or (0,0,0) if not available
Definition volume.cxx:26
bool add_new_component(data::data_view &component_dv)
add new component on the end (if result has <=4 components)
Definition volume.cxx:48
ComponentFormat
define standard formats, which should be used to avoid wrong assignment of component names
@ CF_RGBA
color format with components R, G and B
@ CF_RGB
color format with two components R and G
@ CF_RG
color format with intensity and alpha components: I and A
unsigned int get_type_size(TypeId tid)
function that returns the size of a type specified through TypeId
Definition type_id.cxx:18
TypeId
ids for the different types and type constructs
Definition type_id.h:12
the cgv namespace
Definition print.h:11
Helper functions to process strings.