Field3D
|
00001 //----------------------------------------------------------------------------// 00002 00003 /* 00004 * Copyright (c) 2009 Sony Pictures Imageworks Inc. 00005 * 00006 * All rights reserved. 00007 * 00008 * Redistribution and use in source and binary forms, with or without 00009 * modification, are permitted provided that the following conditions 00010 * are met: 00011 * 00012 * Redistributions of source code must retain the above copyright 00013 * notice, this list of conditions and the following disclaimer. 00014 * Redistributions in binary form must reproduce the above copyright 00015 * notice, this list of conditions and the following disclaimer in the 00016 * documentation and/or other materials provided with the 00017 * distribution. Neither the name of Sony Pictures Imageworks nor the 00018 * names of its contributors may be used to endorse or promote 00019 * products derived from this software without specific prior written 00020 * permission. 00021 * 00022 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00023 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00024 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 00025 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 00026 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 00027 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 00028 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 00029 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00030 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 00031 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00032 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 00033 * OF THE POSSIBILITY OF SUCH DAMAGE. 00034 */ 00035 00036 //----------------------------------------------------------------------------// 00037 00038 #include <iostream> 00039 #include <vector> 00040 #include <map> 00041 #include <string> 00042 00043 #include <boost/program_options.hpp> 00044 #include <boost/foreach.hpp> 00045 00046 #include <Field3D/DenseField.h> 00047 #include <Field3D/MACField.h> 00048 #include <Field3D/SparseField.h> 00049 #include <Field3D/InitIO.h> 00050 #include <Field3D/Field3DFile.h> 00051 00052 //----------------------------------------------------------------------------// 00053 00054 using namespace std; 00055 using namespace Field3D; 00056 00057 //----------------------------------------------------------------------------// 00058 // Options struct 00059 //----------------------------------------------------------------------------// 00060 00061 struct Options { 00062 Options() 00063 : name("field_name"), attribute("field_attribute"), 00064 resolution(64), fieldType("DenseField"), fill("small_sphere"), 00065 bits(32), isVectorField(false) 00066 { } 00067 string filename; 00068 string name; 00069 string attribute; 00070 Imath::V3i resolution; 00071 string fieldType; 00072 string fill; 00073 int bits; 00074 bool isVectorField; 00075 }; 00076 00077 //----------------------------------------------------------------------------// 00078 // Function prototypes 00079 //----------------------------------------------------------------------------// 00080 00081 Options parseOptions(int argc, char **argv); 00082 00083 void createField(const Options &options); 00084 00085 void writeGlobalMetadata(Field3DOutputFile &out); 00086 00087 template <typename Data_T> 00088 void createConcreteScalarField(const Options &options); 00089 00090 template <typename Data_T> 00091 void createConcreteVectorField(const Options &options); 00092 00093 void setCommon(const FieldRes::Ptr field, const Options &options); 00094 00095 //----------------------------------------------------------------------------// 00096 // Function implementations 00097 //----------------------------------------------------------------------------// 00098 00099 int main(int argc, char **argv) 00100 { 00101 Field3D::initIO(); 00102 00103 Options options = parseOptions(argc, argv); 00104 00105 createField(options); 00106 } 00107 00108 //----------------------------------------------------------------------------// 00109 00110 Options parseOptions(int argc, char **argv) 00111 { 00112 namespace po = boost::program_options; 00113 00114 Options options; 00115 00116 po::options_description desc("Available options"); 00117 00118 desc.add_options() 00119 ("help", "Display help") 00120 ("output-file", po::value<vector<string> >(), "Output file(s)") 00121 ("name,n", po::value<string>(), "Field name") 00122 ("attribute,a", po::value<string>(), "Field attribute") 00123 ("type,t", po::value<string>(), "Field type (DenseField/SparseField/MACField)") 00124 ("fill,f", po::value<string>(), "Fill with (full_sphere/small_sphere)") 00125 ("xres,x", po::value<int>(), "X resolution") 00126 ("yres,y", po::value<int>(), "Y resolution") 00127 ("zres,z", po::value<int>(), "Z resolution") 00128 ("bits,b", po::value<int>(), "Bit depth (16/32/64)") 00129 ("vector,v", "Whether to create a vector field") 00130 ; 00131 00132 po::variables_map vm; 00133 po::store(po::parse_command_line(argc, argv, desc), vm); 00134 po::notify(vm); 00135 00136 po::positional_options_description p; 00137 p.add("output-file", -1); 00138 00139 po::store(po::command_line_parser(argc, argv). 00140 options(desc).positional(p).run(), vm); 00141 po::notify(vm); 00142 00143 if (vm.count("help")) { 00144 cout << desc << endl; 00145 exit(0); 00146 } 00147 00148 if (vm.count("output-file")) 00149 { 00150 if (vm.count("output-file") > 1) { 00151 cout << "WARNING: Got more than one output filename. " 00152 << "First entry will be used." << endl; 00153 } 00154 options.filename = vm["output-file"].as<vector<string> >()[0]; 00155 } else { 00156 cout << "No output file specified." << endl; 00157 exit(0); 00158 } 00159 00160 if (vm.count("name")) 00161 { 00162 options.name = vm["name"].as<string>(); 00163 } 00164 if (vm.count("attribute")) 00165 { 00166 options.attribute = vm["attribute"].as<string>(); 00167 } 00168 if (vm.count("type")) 00169 { 00170 options.fieldType = vm["type"].as<string>(); 00171 } 00172 if (vm.count("xres")) 00173 { 00174 options.resolution.x = vm["xres"].as<int>(); 00175 } 00176 if (vm.count("yres")) 00177 { 00178 options.resolution.y = vm["yres"].as<int>(); 00179 } 00180 if (vm.count("zres")) 00181 { 00182 options.resolution.z = vm["zres"].as<int>(); 00183 } 00184 if (vm.count("bits")) 00185 { 00186 options.bits = vm["bits"].as<int>(); 00187 } 00188 if (vm.count("vector")) 00189 { 00190 options.isVectorField = true; 00191 } 00192 00193 return options; 00194 } 00195 00196 //----------------------------------------------------------------------------// 00197 00198 void createField(const Options &options) 00199 { 00200 if (options.isVectorField) { 00201 switch (options.bits) { 00202 case 64: 00203 createConcreteVectorField<double>(options); 00204 break; 00205 case 32: 00206 createConcreteVectorField<float>(options); 00207 break; 00208 case 16: 00209 default: 00210 createConcreteVectorField<Field3D::half>(options); 00211 break; 00212 } 00213 } else { 00214 switch (options.bits) { 00215 case 64: 00216 createConcreteScalarField<double>(options); 00217 break; 00218 case 32: 00219 createConcreteScalarField<float>(options); 00220 break; 00221 case 16: 00222 default: 00223 createConcreteScalarField<Field3D::half>(options); 00224 break; 00225 } 00226 } 00227 } 00228 00229 //----------------------------------------------------------------------------// 00230 00231 void writeGlobalMetadata(Field3DOutputFile &out) 00232 { 00233 out.metadata().setFloatMetadata("float_global_metadata", 1.0f); 00234 out.metadata().setVecFloatMetadata("vec_float_global_metadata", V3f(1.0f)); 00235 out.metadata().setIntMetadata("int_global_metadata", 1); 00236 out.metadata().setVecIntMetadata("vec_int_global_metadata", V3i(1)); 00237 out.metadata().setStrMetadata("str_global_metadata", "string"); 00238 out.writeGlobalMetadata(); 00239 } 00240 00241 //----------------------------------------------------------------------------// 00242 00243 template <typename Data_T> 00244 void createConcreteScalarField(const Options &options) 00245 { 00246 typedef typename ResizableField<Data_T>::Ptr Ptr; 00247 Ptr field; 00248 00249 if (options.fieldType == "SparseField") { 00250 field = Ptr(new SparseField<Data_T>); 00251 } else { 00252 field = Ptr(new DenseField<Data_T>); 00253 } 00254 00255 field->setSize(options.resolution); 00256 setCommon(field, options); 00257 00258 Field3DOutputFile out; 00259 out.create(options.filename); 00260 out.writeScalarLayer<Data_T>(field); 00261 writeGlobalMetadata(out); 00262 } 00263 00264 //----------------------------------------------------------------------------// 00265 00266 template <typename Data_T> 00267 void createConcreteVectorField(const Options &options) 00268 { 00269 typedef typename ResizableField<FIELD3D_VEC3_T<Data_T> >::Ptr Ptr; 00270 Ptr field; 00271 00272 if (options.fieldType == "SparseField") { 00273 field = Ptr(new SparseField<FIELD3D_VEC3_T<Data_T> >); 00274 } else if (options.fieldType == "MACField") { 00275 field = Ptr(new MACField<FIELD3D_VEC3_T<Data_T> >); 00276 } else { 00277 field = Ptr(new DenseField<FIELD3D_VEC3_T<Data_T> >); 00278 } 00279 00280 field->setSize(options.resolution); 00281 setCommon(field, options); 00282 00283 Field3DOutputFile out; 00284 out.create(options.filename); 00285 out.writeVectorLayer<Data_T>(field); 00286 writeGlobalMetadata(out); 00287 } 00288 00289 //----------------------------------------------------------------------------// 00290 00291 void setCommon(const FieldRes::Ptr field, const Options &options) 00292 { 00293 field->name = options.name; 00294 field->attribute = options.attribute; 00295 field->metadata().setFloatMetadata("float_metadata", 1.0f); 00296 field->metadata().setVecFloatMetadata("vec_float_metadata", V3f(1.0f)); 00297 field->metadata().setIntMetadata("int_metadata", 1); 00298 field->metadata().setVecIntMetadata("vec_int_metadata", V3i(1)); 00299 field->metadata().setStrMetadata("str_metadata", "string"); 00300 00301 M44d localToWorld; 00302 localToWorld.setScale(options.resolution); 00303 localToWorld *= M44d().setTranslation(V3d(1.0, 2.0, 3.0)); 00304 00305 MatrixFieldMapping::Ptr mapping(new MatrixFieldMapping); 00306 mapping->setLocalToWorld(localToWorld); 00307 field->setMapping(mapping); 00308 } 00309 00310 //----------------------------------------------------------------------------//