$search
00001 /********************************************************************* 00002 * Software License Agreement (BSD License) 00003 * 00004 * Copyright (c) 2009, Willow Garage, Inc. 00005 * All rights reserved. 00006 * 00007 * Redistribution and use in source and binary forms, with or without 00008 * modification, are permitted provided that the following conditions 00009 * are met: 00010 * 00011 * * Redistributions of source code must retain the above copyright 00012 * notice, this list of conditions and the following disclaimer. 00013 * * Redistributions in binary form must reproduce the above 00014 * copyright notice, this list of conditions and the following 00015 * disclaimer in the documentation and/or other materials provided 00016 * with the distribution. 00017 * * Neither the name of the Willow Garage nor the names of its 00018 * contributors may be used to endorse or promote products derived 00019 * from this software without specific prior written permission. 00020 * 00021 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00022 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00023 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 00024 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 00025 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 00026 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 00027 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00028 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00029 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00030 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 00031 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00032 * POSSIBILITY OF SUCH DAMAGE. 00033 *********************************************************************/ 00034 00035 // Author(s): Matei Ciocarlie 00036 00037 #include <iostream> 00038 #include <fstream> 00039 #include <vector> 00040 #include <string> 00041 00042 #include <boost/filesystem.hpp> 00043 00044 #include "household_objects_database/objects_database.h" 00045 #include "household_objects_database/database_original_model.h" 00046 #include "household_objects_database/database_scaled_model.h" 00047 #include "household_objects_database/database_file_path.h" 00048 00049 #include "mesh_loader.h" 00050 00051 void usage() 00052 { 00053 std::cerr << "Usage: insert_model geometry_file thumbnail_file\n"; 00054 } 00055 00056 std::string getNonEmptyString(const std::string &display_name) 00057 { 00058 std::string ret_string; 00059 while(1) 00060 { 00061 std::cout << "Enter " << display_name << ": "; 00062 std::getline(std::cin, ret_string); 00063 if (!ret_string.empty()) break; 00064 std::cout << "Non-empty string required \n"; 00065 } 00066 return ret_string; 00067 } 00068 00069 std::string getString(const std::string &display_name) 00070 { 00071 std::string ret_string; 00072 std::cout << "Enter " << display_name << " (leave empty for none):"; 00073 std::getline(std::cin, ret_string); 00074 return ret_string; 00075 } 00076 00077 bool copyFile(std::string old_path, std::string new_root, std::string &filename) 00078 { 00079 //get just the filename part of the original file 00080 size_t slash_position = old_path.find_last_of('/'); 00081 if (slash_position == std::string::npos) 00082 { 00083 //no slash 00084 filename = old_path; 00085 } 00086 else if (slash_position >= old_path.size() - 1) 00087 { 00088 //slash is the last character 00089 std::cerr << "Failed to parse input filename: " << old_path << "\n"; 00090 return false; 00091 } 00092 else 00093 { 00094 //skip the last slash 00095 filename = old_path.substr(slash_position+1, std::string::npos); 00096 } 00097 std::string new_path(new_root); 00098 if (new_path.at(new_path.size() - 1) != '/') 00099 { 00100 new_path.append("//"); 00101 } 00102 new_path.append(filename); 00103 if ( boost::filesystem::exists(new_path) ) 00104 { 00105 std::cerr << "File " << new_path << " already exists; skipping copy.\n"; 00106 return true; 00107 } 00108 boost::filesystem::copy_file(old_path, new_path); 00109 if ( !boost::filesystem::exists(new_path) ) 00110 { 00111 std::cerr << "Failed to copy file " << filename << " to " << new_path << "\n"; 00112 return false; 00113 } 00114 return true; 00115 } 00116 00117 bool loadGeometry(household_objects_database::DatabaseMesh &mesh, std::string filename) 00118 { 00119 return true; 00120 } 00121 00122 void getOriginalModelInfo(household_objects_database::DatabaseOriginalModel &original_model) 00123 { 00124 std::vector<std::string> tags; 00125 00126 /* 00127 //hard-coded for als object entries 00128 std::string name = getNonEmptyString("name"); 00129 original_model.source_.data() = "3dwarehouse"; 00130 original_model.acquisition_method_.data() = "cad"; 00131 original_model.maker_.data() = "na"; 00132 original_model.model_.data() = name; 00133 original_model.description_.get() = name; 00134 tags.push_back(name); 00135 tags.push_back("als_object"); 00136 */ 00137 /* 00138 original_model.source_.data() = getNonEmptyString("object source"); 00139 original_model.acquisition_method_.data() = getNonEmptyString("acquisition method"); 00140 original_model.maker_.data() = getNonEmptyString("object maker"); 00141 original_model.model_.data() = getNonEmptyString("object model"); 00142 original_model.barcode_.get() = getString("object barcode"); 00143 original_model.description_.get() = getString("object description"); 00144 std::cout << "Enter tags one at a time; enter an empty line when done\n"; 00145 while(1) 00146 { 00147 std::string tag; 00148 std::getline(std::cin,tag); 00149 if (!tag.empty()) tags.push_back(tag); 00150 else break; 00151 } 00152 */ 00153 00154 //hard-coded for TOD objects 00155 original_model.source_.data() = "Household"; 00156 original_model.acquisition_method_.data() = "TOD"; 00157 original_model.maker_.data() = getNonEmptyString("object maker"); 00158 original_model.model_.data() = getNonEmptyString("object model"); 00159 original_model.barcode_.get() = getString("object barcode"); 00160 original_model.description_.get() = getString("object description"); 00161 std::cout << "Enter tags one at a time; enter an empty line when done\n"; 00162 while(1) 00163 { 00164 std::string tag; 00165 std::getline(std::cin,tag); 00166 if (!tag.empty()) tags.push_back(tag); 00167 else break; 00168 } 00169 00170 if (!tags.empty()) 00171 { 00172 original_model.tags_.data() = tags; 00173 original_model.tags_.setWriteToDatabase(true); 00174 } 00175 if (!original_model.barcode_.get().empty()) 00176 { 00177 original_model.barcode_.setWriteToDatabase(true); 00178 } 00179 if (!original_model.description_.get().empty()) 00180 { 00181 original_model.description_.setWriteToDatabase(true); 00182 } 00183 00184 } 00185 00186 int main(int argc, char **argv) 00187 { 00188 //connect to database 00189 //hard-coded for now 00190 household_objects_database::ObjectsDatabase database("wgs36", "5432", "willow", "willow", "household_objects"); 00191 if (!database.isConnected()) 00192 { 00193 std::cerr << "Database failed to connect"; 00194 return -1; 00195 } 00196 00197 //parse the input 00198 //first argument is always the geometry filename which must exist 00199 if (argc < 3) 00200 { 00201 usage(); 00202 return -1; 00203 } 00204 00205 //check that the geometry file exists 00206 std::string geometry_filename(argv[1]); 00207 if ( !boost::filesystem::exists(geometry_filename) ) 00208 { 00209 std::cerr << "Geometry file " << geometry_filename << " not found\n"; 00210 return -1; 00211 } 00212 00213 //check that thumbnail file exists 00214 std::string thumbnail_filename(argv[2]); 00215 if ( !boost::filesystem::exists(thumbnail_filename) ) 00216 { 00217 std::cout << "Thumbnail file " << thumbnail_filename << " not found\n"; 00218 return -1; 00219 } 00220 00221 //read in the geometry of the model from the ply file 00222 household_objects_database::DatabaseMesh mesh; 00223 household_objects_database::PLYModelLoader loader; 00224 if (loader.readFromFile(geometry_filename, mesh.vertices_.data(), mesh.triangles_.data()) < 0) 00225 { 00226 std::cerr << "Failed to read geometry from file\n"; 00227 return -1; 00228 } 00229 if (mesh.vertices_.data().empty() || mesh.triangles_.data().empty()) 00230 { 00231 std::cerr << "No geometry read from file\n"; 00232 return -1; 00233 } 00234 00235 //the original model we will insert 00236 household_objects_database::DatabaseOriginalModel original_model; 00237 //ask use for info to populate fields 00238 getOriginalModelInfo(original_model); 00239 00240 //copy the file(s) over to the model root 00241 std::string model_root; 00242 if (!database.getModelRoot(model_root) || model_root.empty()) 00243 { 00244 std::cerr << "Failed to get model root from database\n"; 00245 return -1; 00246 } 00247 std::string geometry_relative_filename; 00248 if (!copyFile(geometry_filename, model_root, geometry_relative_filename)) return -1; 00249 std::string thumbnail_relative_filename; 00250 if (!copyFile(thumbnail_filename, model_root, thumbnail_relative_filename)) return -1; 00251 00252 //insert the original model into the database 00253 if (!database.insertIntoDatabase(&original_model)) 00254 { 00255 std::cerr << "Failed to insert original model in database\n"; 00256 return -1; 00257 } 00258 int original_model_id = original_model.id_.data(); 00259 00260 //insert the geometry 00261 mesh.id_.data() = original_model_id; 00262 if (!database.insertIntoDatabase(&mesh)) 00263 { 00264 std::cerr << "Failed to insert mesh in database\n"; 00265 return -1; 00266 } 00267 if (!database.saveToDatabase(&mesh.triangles_) || !database.saveToDatabase(&mesh.vertices_)) 00268 { 00269 std::cerr << "Failed to write mesh data to database\n"; 00270 return -1; 00271 } 00272 00273 // insert a scaled model at range 1.0 00274 household_objects_database::DatabaseScaledModel scaled_model; 00275 scaled_model.original_model_id_.data() = original_model_id; 00276 scaled_model.scale_.data() = 1.0; 00277 if (!database.insertIntoDatabase(&scaled_model)) 00278 { 00279 std::cerr << "Failed to insert scaled model in database\n"; 00280 return -1; 00281 } 00282 00283 //insert the paths to the files in the database 00284 household_objects_database::DatabaseFilePath geometry_file_path; 00285 geometry_file_path.original_model_id_.data() = original_model_id; 00286 geometry_file_path.file_type_.data() = "GEOMETRY_BINARY_PLY"; 00287 geometry_file_path.file_path_.data() = geometry_relative_filename; 00288 if (!database.insertIntoDatabase(&geometry_file_path)) 00289 { 00290 std::cerr << "Failed to insert geometry file path in database\n"; 00291 return -1; 00292 } 00293 household_objects_database::DatabaseFilePath thumbnail_file_path; 00294 thumbnail_file_path.original_model_id_.data() = original_model_id; 00295 thumbnail_file_path.file_type_.data() = "THUMBNAIL_BINARY_PNG"; 00296 thumbnail_file_path.file_path_.data() = thumbnail_relative_filename; 00297 if (!database.insertIntoDatabase(&thumbnail_file_path)) 00298 { 00299 std::cerr << "Failed to insert thumbnail file path in database\n"; 00300 return -1; 00301 } 00302 00303 std::cerr << "Insertion succeeded\n"; 00304 return 0; 00305 }