Field3D
main.cpp
Go to the documentation of this file.
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 //----------------------------------------------------------------------------//