Go to the documentation of this file.00001
00031 #include <urdf2inventor/Helpers.h>
00032
00033 #include <ros/ros.h>
00034 #include <ros/package.h>
00035
00036 #define BOOST_NO_CXX11_SCOPED_ENUMS
00037 #include <boost/filesystem.hpp>
00038 #undef BOOST_NO_CXX11_SCOPED_ENUMS
00039
00040 #include <fcntl.h>
00041 #include <fstream>
00042 #include <string>
00043
00044
00053
00054 int stdout_fd;
00055
00056 void urdf2inventor::helpers::resetStdOut()
00057 {
00058 if (stdout_fd < 0)
00059 {
00060 return;
00061 }
00062 fflush(stdout);
00063 if (dup2(stdout_fd, STDOUT_FILENO) < 0)
00064 {
00065 ROS_ERROR("Could not restore stdout");
00066 return;
00067 }
00068 close(stdout_fd);
00069
00070
00071 }
00072
00073
00074 void urdf2inventor::helpers::redirectStdOut(const char * toFile)
00075 {
00076 fflush(stdout);
00077
00078 mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
00079 int file = open(toFile, O_CREAT | O_APPEND | O_WRONLY, mode);
00080 if (file < 0)
00081 {
00082 ROS_ERROR("could not create new output stream %s: %s", toFile, strerror(errno));
00083 return;
00084 }
00085 stdout_fd = dup(STDOUT_FILENO);
00086 if (dup2(file, STDOUT_FILENO) < 0)
00087 {
00088 ROS_ERROR("could not redirect output stream");
00089 return;
00090 }
00091
00092
00093
00094 }
00095
00096
00097
00098 bool urdf2inventor::helpers::writeFiles(const std::map<std::string, std::set<std::string> >& files, const std::string& outputDir)
00099 {
00100 bool ret = true;
00101 boost::filesystem::path _outputDir(boost::filesystem::absolute(outputDir));
00102
00103 for (std::map<std::string, std::set<std::string> >::const_iterator mit = files.begin(); mit != files.end(); ++mit)
00104 {
00105 for (std::set<std::string>::const_iterator tit = mit->second.begin(); tit != mit->second.end(); ++tit)
00106 {
00107 boost::filesystem::path fullPath;
00108 boost::filesystem::path tFile(mit->first);
00109 if (tFile.is_relative())
00110 {
00111 fullPath = _outputDir;
00112 }
00113 else
00114 {
00115
00116 std::string testRelParent;
00117 if (!urdf_traverser::helpers::getSubdirPath(outputDir, tFile.string(), testRelParent))
00118 {
00119 ROS_WARN_STREAM("File " << tFile.string() << " given as absolute path, but it is not in a subdirectory of " << outputDir);
00120 }
00121 }
00122 fullPath /= tFile;
00123
00124
00125
00126 std::string targetTexDir = urdf_traverser::helpers::getDirectory(fullPath.string());
00127 if (!urdf_traverser::helpers::makeDirectoryIfNeeded(targetTexDir.c_str()))
00128 {
00129 ROS_ERROR_STREAM("Could not create directory " << targetTexDir);
00130 ret = false;
00131 continue;
00132 }
00133
00134 try
00135 {
00136
00137
00138 boost::filesystem::copy_file(*tit, fullPath, boost::filesystem::copy_option::overwrite_if_exists);
00139 }
00140 catch (const boost::filesystem::filesystem_error& ex)
00141 {
00142 ROS_ERROR_STREAM("Could not copy file: " << ex.what());
00143 ret = false;
00144 continue;
00145 }
00146 }
00147 }
00148
00149 return ret;
00150 }
00151
00152
00153 bool urdf2inventor::helpers::fixFileReferences(
00154 const std::string& modelDir,
00155 const std::string& fileDir,
00156 const std::string& fileRootDir,
00157 const std::set<std::string>& filesInUse,
00158 std::string& modelString,
00159 std::map<std::string, std::set<std::string> >& filesToCopy)
00160 {
00161 if (filesInUse.empty()) return true;
00162
00163 std::string _fileDir(fileDir);
00164 urdf_traverser::helpers::enforceDirectory(_fileDir, false);
00165
00166
00167 std::string testCommonParent;
00168 if (!urdf_traverser::helpers::getCommonParentPath(filesInUse, testCommonParent))
00169 {
00170 ROS_ERROR_STREAM("Could not find common parent path of all files");
00171 return false;
00172 }
00173
00174 std::string testRelParent;
00175 if (!urdf_traverser::helpers::getSubdirPath(fileRootDir, testCommonParent, testRelParent))
00176 {
00177 ROS_ERROR_STREAM("File " << testCommonParent << " is not in a subdirectory of " << fileRootDir);
00178 return false;
00179 }
00180
00181
00182
00183 for (std::set<std::string>::iterator itFile = filesInUse.begin(); itFile != filesInUse.end(); ++itFile)
00184 {
00185 std::string absFile = *itFile;
00186 std::string file;
00187 if (!urdf_traverser::helpers::getSubdirPath(fileRootDir, absFile, file))
00188 {
00189 ROS_ERROR_STREAM("File " << absFile << " is not in a subdirectory of " << fileRootDir);
00190 continue;
00191 }
00192
00193
00194 std::stringstream filePath;
00195 filePath << _fileDir << file;
00196
00197 std::string newFileReference;
00198 if (!urdf_traverser::helpers::getRelativeDirectory(filePath.str(), modelDir, newFileReference))
00199 {
00200 ROS_ERROR_STREAM("Could not determine relative directory between " << filePath.str()
00201 << " and " << modelDir << ".");
00202 continue;
00203 }
00204
00205
00206
00207
00208
00209 modelString = urdf_traverser::helpers::replaceAll(modelString,
00210 absFile, newFileReference);
00211
00212
00213
00214 boost::filesystem::path _absFileMod(absFile);
00215 _absFileMod.replace_extension("");
00216 boost::filesystem::path _texRefMod(newFileReference);
00217 _texRefMod.replace_extension("");
00218 std::string texRefMod = urdf_traverser::helpers::replaceAll(_texRefMod.string(), "/", "_");
00219 texRefMod = urdf_traverser::helpers::replaceAll(texRefMod, ".", "_");
00220 modelString = urdf_traverser::helpers::replaceAll(modelString,
00221 _absFileMod.string(), texRefMod);
00222
00223
00224
00225 filesToCopy[filePath.str()].insert(absFile);
00226 }
00227 return true;
00228 }
00229