00001 #include "trafu_data.h" 00002 #include "trafupoint.h" 00003 00004 #include <algorithm> 00005 #include <fstream> 00006 #include <sstream> 00007 00008 TraFuData::TraFuData(const char *tfd_filename) 00009 { 00010 if(tfd_filename) 00011 { 00012 this->load_file(tfd_filename); 00013 }else 00014 { 00015 Init(); 00016 } 00017 } 00018 00019 void TraFuData::Init() 00020 { 00021 this->m_mapping_points.clear(); 00022 this->m_mapping_points.push_back(Mapping_point_t(0, 0, 0, 0, 0, TFP_START)); 00023 this->m_mapping_points.push_back(Mapping_point_t(1, 1, 255, 255, 255, TFP_END)); 00024 } 00025 00026 Mapping_point_t TraFuData::mapDensity(float density) const 00027 { 00028 Mapping_point_t calc_point; 00029 Mapping_point_iterator_const_t first, second; 00030 00031 second = first = std::upper_bound(this->m_mapping_points.begin(), 00032 this->m_mapping_points.end(), 00033 calc_point); 00034 00035 if(second != this->m_mapping_points.end()) 00036 { 00037 first--; 00038 00039 Mapping_point_t range = *second - *first; 00040 float current = (density - first->m_density) / range.m_density; 00041 00042 Mapping_point_t step = range * current; 00043 00044 calc_point = (*first) + range * current; 00045 }else 00046 { 00047 calc_point = this->m_mapping_points.back(); 00048 } 00049 00050 return calc_point; 00051 } 00052 00054 struct PointChange_s 00055 { 00056 float density; 00057 float opacity; 00058 00061 float red; 00062 float green; 00063 float blue; 00065 00067 PointChange_s(float n_density, float n_opacity, float n_red, float n_green, float n_blue) 00068 : density(n_density) 00069 , opacity(n_opacity) 00070 , red(n_red) 00071 , green(n_green) 00072 , blue(n_blue) 00073 { 00074 } 00075 00077 friend Mapping_point_t operator *(const PointChange_s &change, const int scalar) 00078 { 00079 return Mapping_point_t(change.density * scalar, 00080 change.opacity * scalar, 00081 change.red * scalar, 00082 change.green * scalar, 00083 change.blue * scalar); 00084 } 00085 }; 00086 00087 void TraFuData::createDensityVectorPart(Mapping_point_vector_t &vec, 00088 int first_element, 00089 int number_of_elements, 00090 const Mapping_point_iterator_const_t &lower, 00091 const Mapping_point_iterator_const_t &upper) const 00092 { 00093 Mapping_point_t range = *upper - *lower; 00094 PointChange_s change(range.m_density / number_of_elements, 00095 range.m_opacity / number_of_elements, 00096 static_cast<float>(range.m_colour.red) / number_of_elements, 00097 static_cast<float>(range.m_colour.green) / number_of_elements, 00098 static_cast<float>(range.m_colour.blue) / number_of_elements); 00099 00100 vec[first_element] = *lower; 00101 for(int i = 0; i < number_of_elements; i++) 00102 { 00103 vec[first_element + i] = *lower + (change * i); 00104 } 00105 } 00106 00107 Mapping_point_vector_t TraFuData::createDensityVector(int number_of_elements) const 00108 { 00109 Mapping_point_vector_t vec(number_of_elements); 00110 Mapping_point_iterator_const_t first = m_mapping_points.begin(); 00111 Mapping_point_iterator_const_t second = m_mapping_points.begin(); 00112 ++second; 00113 00114 int free_elements = number_of_elements - 1; 00115 int current_elements = 0; 00116 float free_density = 1; 00117 float density_range = 0; 00118 int last_element = 0; 00119 00120 while(second != m_mapping_points.end()) 00121 { 00122 density_range = (second->m_density - first->m_density); 00123 current_elements = free_elements * (density_range / free_density); 00124 createDensityVectorPart(vec, last_element, current_elements, first, second); 00125 last_element += current_elements; 00126 free_density -= density_range; 00127 free_elements -= current_elements; 00128 first = second++; 00129 } 00130 00131 vec[number_of_elements - 1] = *first; 00132 00133 return vec; 00134 } 00135 00136 void TraFuData::load_file(const char *tfd_filename) 00137 { 00138 std::ifstream in(tfd_filename, std::ios::in | std::ios::binary); 00139 in.exceptions(std::ios::failbit | std::ios::badbit); 00140 00141 int size = 0; 00142 Mapping_point_t *new_element = new Mapping_point_t(); 00143 00144 this->m_mapping_points.clear(); 00145 00146 try 00147 { 00148 in.read((char*)&size, sizeof(int)); 00149 00150 while(1) 00151 { 00152 in.read(reinterpret_cast<char*>(new_element), sizeof(Mapping_point_t)); 00153 this->m_mapping_points.push_back(*new_element); 00154 } 00155 }catch(...) 00156 { 00157 00158 } 00159 00160 delete new_element; 00161 } 00162 00163 void TraFuData::save_file(const char *tfd_filename) 00164 { 00165 std::string filename(tfd_filename); 00166 if(std::string::npos == filename.rfind(".")) 00167 { 00168 filename.append(std::string(".tf")); 00169 } 00170 00171 std::ofstream out(filename.c_str(), std::ios::out | std::ios::binary); 00172 out.exceptions(std::ios::failbit | std::ios::badbit); 00173 00174 int size = (int)this->m_mapping_points.size(); 00175 00176 out.write((char*)&size, sizeof(int)); 00177 00178 for(Mapping_point_iterator_t iterPoint = this->m_mapping_points.begin(); 00179 iterPoint != this->m_mapping_points.end(); 00180 iterPoint++) 00181 { 00182 out.write(reinterpret_cast<char*>(&(*iterPoint)), sizeof(*iterPoint)); 00183 } 00184 }