00001
00031 #include <urdf2inventor/Helpers.h>
00032 #include <urdf2inventor/IVHelpers.h>
00033 #include <Inventor/nodes/SoMatrixTransform.h>
00034 #include <Inventor/nodes/SoNode.h>
00035 #include <Inventor/nodes/SoSphere.h>
00036 #include <Inventor/nodes/SoCube.h>
00037 #include <Inventor/nodes/SoCylinder.h>
00038 #include <Inventor/nodes/SoTexture2.h>
00039
00040
00041 #include <Inventor/actions/SoWriteAction.h>
00042 #include <Inventor/actions/SoSearchAction.h>
00043 #include <Inventor/SbBox.h>
00044 #include <Inventor/actions/SoGetBoundingBoxAction.h>
00045
00046 #include <iostream>
00047 #include <sstream>
00048
00049 #define BOOST_NO_CXX11_SCOPED_ENUMS
00050 #include <boost/filesystem.hpp>
00051 #undef BOOST_NO_CXX11_SCOPED_ENUMS
00052
00053 void urdf2inventor::getBoundingBox(SoNode* node, Eigen::Vector3d& minPoint, Eigen::Vector3d& maxPoint)
00054 {
00055 minPoint=Eigen::Vector3d(0,0,0);
00056 maxPoint=Eigen::Vector3d(0,0,0);
00057
00058
00059
00060 SbViewportRegion anyVP(0,0);
00061 SoGetBoundingBoxAction bbAction( anyVP );
00062 bbAction.apply( node );
00063 SbBox3f bbox = bbAction.getBoundingBox();
00064 const SbVec3f& minIV = bbox.getMin();
00065 const SbVec3f& maxIV = bbox.getMax();
00066 minPoint=Eigen::Vector3d(minIV[0], minIV[1], minIV[2]);
00067 maxPoint=Eigen::Vector3d(maxIV[0], maxIV[1], maxIV[2]);
00068 }
00069
00070
00071 bool urdf2inventor::writeInventorFileString(SoNode * node, std::string& result)
00072 {
00073 SoOutput out;
00074 out.setBinary(false);
00075 size_t initBufSize = 100;
00076 void * buffer = malloc(initBufSize * sizeof(char));
00077 out.setBuffer(buffer, initBufSize, std::realloc);
00078 SoWriteAction write(&out);
00079 write.apply(node);
00080
00081 void * resBuf = NULL;
00082 size_t resBufSize = 0;
00083
00084 if (!out.getBuffer(resBuf, resBufSize) || (resBufSize == 0))
00085 {
00086 return false;
00087 }
00088
00089 result = std::string(static_cast<char*>(resBuf), resBufSize);
00090
00091 free(resBuf);
00092
00093 return true;
00094 }
00095
00096
00097
00098
00103 std::set<std::string> urdf2inventor::getAllTexturePaths(SoNode * root)
00104 {
00105 std::set<std::string> allFiles;
00106 SoSearchAction sa;
00107 sa.setType(SoTexture2::getClassTypeId());
00108 sa.setInterest(SoSearchAction::ALL);
00109 sa.setSearchingAll(TRUE);
00110 sa.apply(root);
00111 SoPathList & pl = sa.getPaths();
00112
00113 for (int i = 0; i < pl.getLength(); i++)
00114 {
00115 SoFullPath * p = (SoFullPath*) pl[i];
00116 if (!p->getTail()->isOfType(SoTexture2::getClassTypeId())) continue;
00117
00118 SoTexture2 * tex = (SoTexture2*) p->getTail();
00119 if (tex->filename.getValue().getLength() == 0) continue;
00120
00121 std::string name(tex->filename.getValue().getString());
00122 boost::filesystem::path absPath(boost::filesystem::absolute(name));
00123 allFiles.insert(absPath.string());
00124 }
00125 sa.reset();
00126 return allFiles;
00127 }
00128
00129 std::string urdf2inventor::printMatrix(const urdf2inventor::EigenTransform& em)
00130 {
00131 std::stringstream s;
00132 s<< em(0,0)<<","<<em(0,1)<<","<<em(0,2)<<","<<em(0,3)<<","<<std::endl<<
00133 em(1,0)<<","<<em(1,1)<<","<<em(1,2)<<","<<em(1,3)<<","<<std::endl<<
00134 em(2,0)<<","<<em(2,1)<<","<<em(2,2)<<","<<em(2,3)<<","<<std::endl<<
00135 em(3,0)<<","<<em(3,1)<<","<<em(3,2)<<","<<em(3,3)<<","<<std::endl;
00136 return s.str();
00137 }
00138
00139 urdf2inventor::EigenTransform urdf2inventor::getEigenTransform(const SbMatrix& m)
00140 {
00141 Eigen::Matrix3d em;
00142
00143
00144
00145 em(0,0)=m[0][0];
00146 em(0,1)=m[1][0];
00147 em(0,2)=m[2][0];
00148 em(0,3)=m[3][0];
00149 em(1,0)=m[0][1];
00150 em(1,1)=m[1][1];
00151 em(1,2)=m[2][1];
00152 em(1,3)=m[3][1];
00153 em(2,0)=m[0][2];
00154 em(2,1)=m[1][2];
00155 em(2,2)=m[2][2];
00156 em(2,3)=m[3][2];
00157 em(3,0)=m[0][3];
00158 em(3,1)=m[1][3];
00159 em(3,2)=m[2][3];
00160 em(3,3)=m[3][3];
00161
00162 return urdf2inventor::EigenTransform(em);
00163 }
00164
00165 SbMatrix urdf2inventor::getSbMatrix(const urdf2inventor::EigenTransform& m)
00166 {
00167 SbMatrix sm;
00168
00169
00170 sm[0][0]=m(0,0);
00171 sm[0][1]=m(1,0);
00172 sm[0][2]=m(2,0);
00173 sm[0][3]=m(3,0);
00174 sm[1][0]=m(0,1);
00175 sm[1][1]=m(1,1);
00176 sm[1][2]=m(2,1);
00177 sm[1][3]=m(3,1);
00178 sm[2][0]=m(0,2);
00179 sm[2][1]=m(1,2);
00180 sm[2][2]=m(2,2);
00181 sm[2][3]=m(3,2);
00182 sm[3][0]=m(0,3);
00183 sm[3][1]=m(1,3);
00184 sm[3][2]=m(2,3);
00185 sm[3][3]=m(3,3);
00186 return sm;
00187 }
00188
00189
00190 SoTransform * getSoTransform(const urdf2inventor::EigenTransform& eTrans)
00191 {
00192 SoTransform * transform = new SoTransform();
00193
00194 transform->setMatrix(urdf2inventor::getSbMatrix(eTrans));
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205 return transform;
00206 }
00207
00208 bool urdf2inventor::addSubNode(SoNode * addAsChild,
00209 SoNode* parent, const urdf2inventor::EigenTransform& eTrans,
00210 const char * name)
00211 {
00212 SoTransform * transform = getSoTransform(eTrans);
00213 return urdf2inventor::addSubNode(addAsChild, parent, transform, name);
00214 }
00215
00216 bool urdf2inventor::addSubNode(SoNode * addAsChild,
00217 SoNode* parent,
00218 SoTransform * trans,
00219 const char * transName)
00220 {
00221 SoSeparator * sep = dynamic_cast<SoSeparator*>(parent);
00222 if (!sep)
00223 {
00224 std::cerr << "parent is not a separator" << std::endl;
00225 return false;
00226 }
00227
00228 SoSeparator * sepChild = dynamic_cast<SoSeparator*>(addAsChild);
00229 if (!sepChild)
00230 {
00231 std::cerr << "child is not a separator" << std::endl;
00232 return false;
00233 }
00234
00235
00236
00237 SoSeparator * transNode = new SoSeparator();
00238 if (transName) transNode->setName(transName);
00239 transNode->addChild(trans);
00240 transNode->addChild(sepChild);
00241
00242 sep->addChild(transNode);
00243 return true;
00244 }
00245
00246
00247 void urdf2inventor::addSubNode(SoNode * addAsChild, SoSeparator * parent,
00248 const EigenTransform& transform,
00249 SoMaterial * mat, const char * name)
00250 {
00251 SoMatrixTransform * trans = new SoMatrixTransform();
00252 EigenTransform t = transform;
00253 trans->matrix=getSbMatrix(t);
00254
00255
00256
00257
00258
00259
00260 SoSeparator * transSep = new SoSeparator();
00261 if (name) transSep->setName(name);
00262
00263 transSep->addChild(trans);
00264 transSep->addChild(addAsChild);
00265 if (mat) parent->addChild(mat);
00266 parent->addChild(transSep);
00267 }
00268
00269
00270 void urdf2inventor::addBox(SoSeparator * addToNode, const EigenTransform& trans,
00271 float width, float height, float depth,
00272 float r, float g, float b, float a)
00273 {
00274 SoCube * cube = new SoCube();
00275 cube->width.setValue(width);
00276 cube->height.setValue(height);
00277 cube->depth.setValue(depth);
00278 SoMaterial * mat = new SoMaterial();
00279 mat->diffuseColor.setValue(r, g, b);
00280 mat->ambientColor.setValue(0.2, 0.2, 0.2);
00281 mat->transparency.setValue(a);
00282 addSubNode(cube, addToNode, trans, mat);
00283 }
00284
00285
00286 void urdf2inventor::addSphere(SoSeparator * addToNode, const Eigen::Vector3d& pos, float radius,
00287 float r, float g, float b, float a)
00288 {
00289 SoSphere * s = new SoSphere();
00290 s->radius = radius;
00291 SoMaterial * mat = new SoMaterial();
00292 mat->diffuseColor.setValue(r, g, b);
00293 mat->ambientColor.setValue(0.2, 0.2, 0.2);
00294 mat->transparency.setValue(a);
00295 EigenTransform trans;
00296 trans.setIdentity();
00297 trans.translate(pos);
00298 addSubNode(s, addToNode, trans, mat);
00299 }
00300
00301 void urdf2inventor::addCylinder(SoSeparator * addToNode,
00302 const urdf2inventor::EigenTransform& extraTrans,
00303 float radius, float height,
00304 float r, float g, float b, float a,
00305 const char * name)
00306 {
00307 SoCylinder * c = new SoCylinder();
00308 c->radius = radius;
00309 c->height = height;
00310
00311 SoMaterial * mat = new SoMaterial();
00312 mat->diffuseColor.setValue(r, g, b);
00313 mat->ambientColor.setValue(0.2, 0.2, 0.2);
00314 mat->transparency.setValue(a);
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333 Eigen::Quaterniond toZ = Eigen::Quaterniond::FromTwoVectors(Eigen::Vector3d(0, 1, 0), Eigen::Vector3d(0, 0, 1));
00334 EigenTransform trans = extraTrans;
00335 trans.translate(Eigen::Vector3d(0, 0, height / 2.0));
00336 trans.rotate(toZ);
00337
00338 addSubNode(c, addToNode, trans, mat, name);
00339 }
00340
00341 void urdf2inventor::addCylinder(SoSeparator * addToNode, const Eigen::Vector3d& pos,
00342 const Eigen::Quaterniond& rot,
00343 float radius, float height,
00344 float r, float g, float b, float a,
00345 const char * name)
00346 {
00347 EigenTransform trans;
00348 trans.setIdentity();
00349 trans.translate(pos);
00350 trans.rotate(rot);
00351 addCylinder(addToNode, trans, radius, height, r, g, b, a, name);
00352 }
00353
00354 void urdf2inventor::addLocalAxes(SoSeparator * addToNode, float axesRadius, float axesLength)
00355 {
00356 float rx, gx, bx, ry, gy, by, rz, gz, bz;
00357 rx = ry = rz = gx = gy = gz = bx = by = bz = 0;
00358 rx = 1;
00359 gy = 1;
00360 bz = 1;
00361
00362 Eigen::Quaterniond rot;
00363 rot.setIdentity();
00364
00365 addCylinder(addToNode, Eigen::Vector3d(0, 0, 0), rot, axesRadius, axesLength , rz, gz, bz);
00366
00367 Eigen::Vector3d x(1, 0, 0);
00368 Eigen::Vector3d y(0, 1, 0);
00369 Eigen::Vector3d z(0, 0, 1);
00370
00371
00372 Eigen::Quaterniond q = Eigen::Quaterniond::FromTwoVectors(z, y);
00373 addCylinder(addToNode, Eigen::Vector3d(0, 0, 0), q, axesRadius, axesLength, ry, gy, by);
00374
00375
00376 q = Eigen::Quaterniond::FromTwoVectors(z, x);
00377 addCylinder(addToNode, Eigen::Vector3d(0, 0, 0), q, axesRadius, axesLength, rx, gx, bx);
00378 }