00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00037 #include "geometric_shapes/shape_operations.h"
00038
00039 #include <cstdio>
00040 #include <cmath>
00041 #include <algorithm>
00042 #include <set>
00043
00044 #include <ros/console.h>
00045
00046 namespace shapes
00047 {
00048
00049 Shape* cloneShape(const Shape *shape)
00050 {
00051 Shape *result = NULL;
00052 if (shape) {
00053 switch (shape->type)
00054 {
00055 case SPHERE:
00056 result = new Sphere(static_cast<const Sphere*>(shape)->radius);
00057 break;
00058 case CYLINDER:
00059 result = new Cylinder(static_cast<const Cylinder*>(shape)->radius, static_cast<const Cylinder*>(shape)->length);
00060 break;
00061 case BOX:
00062 result = new Box(static_cast<const Box*>(shape)->size[0], static_cast<const Box*>(shape)->size[1], static_cast<const Box*>(shape)->size[2]);
00063 break;
00064 case MESH:
00065 {
00066 const Mesh *src = static_cast<const Mesh*>(shape);
00067 Mesh *dest = new Mesh(src->vertexCount, src->triangleCount);
00068 unsigned int n = 3 * src->vertexCount;
00069 for (unsigned int i = 0 ; i < n ; ++i)
00070 dest->vertices[i] = src->vertices[i];
00071 n = 3 * src->triangleCount;
00072 for (unsigned int i = 0 ; i < n ; ++i)
00073 {
00074 dest->triangles[i] = src->triangles[i];
00075 dest->normals[i] = src->normals[i];
00076 }
00077 result = dest;
00078 }
00079 break;
00080 default:
00081 break;
00082 }
00083 }
00084 return result;
00085 }
00086
00087 StaticShape* cloneShape(const StaticShape *shape)
00088 {
00089 StaticShape *result = NULL;
00090 if (shape) {
00091 switch (shape->type)
00092 {
00093 case PLANE:
00094 result = new Plane(static_cast<const Plane*>(shape)->a, static_cast<const Plane*>(shape)->b,
00095 static_cast<const Plane*>(shape)->c, static_cast<const Plane*>(shape)->d);
00096 break;
00097 default:
00098 break;
00099 }
00100 }
00101
00102 return result;
00103 }
00104
00105
00106 namespace detail
00107 {
00108 struct myVertex
00109 {
00110 btVector3 point;
00111 unsigned int index;
00112 };
00113
00114 struct ltVertexValue
00115 {
00116 bool operator()(const myVertex &p1, const myVertex &p2) const
00117 {
00118 const btVector3 &v1 = p1.point;
00119 const btVector3 &v2 = p2.point;
00120 if (v1.getX() < v2.getX())
00121 return true;
00122 if (v1.getX() > v2.getX())
00123 return false;
00124 if (v1.getY() < v2.getY())
00125 return true;
00126 if (v1.getY() > v2.getY())
00127 return false;
00128 if (v1.getZ() < v2.getZ())
00129 return true;
00130 return false;
00131 }
00132 };
00133
00134 struct ltVertexIndex
00135 {
00136 bool operator()(const myVertex &p1, const myVertex &p2) const
00137 {
00138 return p1.index < p2.index;
00139 }
00140 };
00141
00142 }
00143
00144 shapes::Mesh* createMeshFromVertices(const std::vector<btVector3> &vertices, const std::vector<unsigned int> &triangles)
00145 {
00146 unsigned int nt = triangles.size() / 3;
00147 shapes::Mesh *mesh = new shapes::Mesh(vertices.size(), nt);
00148 for (unsigned int i = 0 ; i < vertices.size() ; ++i)
00149 {
00150 mesh->vertices[3 * i ] = vertices[i].getX();
00151 mesh->vertices[3 * i + 1] = vertices[i].getY();
00152 mesh->vertices[3 * i + 2] = vertices[i].getZ();
00153 }
00154
00155 std::copy(triangles.begin(), triangles.end(), mesh->triangles);
00156
00157
00158 for (unsigned int i = 0 ; i < nt ; ++i)
00159 {
00160 btVector3 s1 = vertices[triangles[i * 3 ]] - vertices[triangles[i * 3 + 1]];
00161 btVector3 s2 = vertices[triangles[i * 3 + 1]] - vertices[triangles[i * 3 + 2]];
00162 btVector3 normal = s1.cross(s2);
00163 normal.normalize();
00164 mesh->normals[3 * i ] = normal.getX();
00165 mesh->normals[3 * i + 1] = normal.getY();
00166 mesh->normals[3 * i + 2] = normal.getZ();
00167 }
00168 return mesh;
00169 }
00170
00171 shapes::Mesh* createMeshFromVertices(const std::vector<btVector3> &source)
00172 {
00173 if (source.size() < 3)
00174 return NULL;
00175
00176 std::set<detail::myVertex, detail::ltVertexValue> vertices;
00177 std::vector<unsigned int> triangles;
00178
00179 for (unsigned int i = 0 ; i < source.size() / 3 ; ++i)
00180 {
00181
00182 detail::myVertex vt;
00183
00184 vt.point = source[3 * i];
00185 std::set<detail::myVertex, detail::ltVertexValue>::iterator p1 = vertices.find(vt);
00186 if (p1 == vertices.end())
00187 {
00188 vt.index = vertices.size();
00189 vertices.insert(vt);
00190 }
00191 else
00192 vt.index = p1->index;
00193 triangles.push_back(vt.index);
00194
00195 vt.point = source[3 * i + 1];
00196 std::set<detail::myVertex, detail::ltVertexValue>::iterator p2 = vertices.find(vt);
00197 if (p2 == vertices.end())
00198 {
00199 vt.index = vertices.size();
00200 vertices.insert(vt);
00201 }
00202 else
00203 vt.index = p2->index;
00204 triangles.push_back(vt.index);
00205
00206 vt.point = source[3 * i + 2];
00207 std::set<detail::myVertex, detail::ltVertexValue>::iterator p3 = vertices.find(vt);
00208 if (p3 == vertices.end())
00209 {
00210 vt.index = vertices.size();
00211 vertices.insert(vt);
00212 }
00213 else
00214 vt.index = p3->index;
00215
00216 triangles.push_back(vt.index);
00217 }
00218
00219
00220 std::vector<detail::myVertex> vt;
00221 vt.insert(vt.begin(), vertices.begin(), vertices.end());
00222 std::sort(vt.begin(), vt.end(), detail::ltVertexIndex());
00223
00224
00225 unsigned int nt = triangles.size() / 3;
00226
00227 shapes::Mesh *mesh = new shapes::Mesh(vt.size(), nt);
00228 for (unsigned int i = 0 ; i < vt.size() ; ++i)
00229 {
00230 mesh->vertices[3 * i ] = vt[i].point.getX();
00231 mesh->vertices[3 * i + 1] = vt[i].point.getY();
00232 mesh->vertices[3 * i + 2] = vt[i].point.getZ();
00233 }
00234
00235 std::copy(triangles.begin(), triangles.end(), mesh->triangles);
00236
00237
00238 for (unsigned int i = 0 ; i < nt ; ++i)
00239 {
00240 btVector3 s1 = vt[triangles[i * 3 ]].point - vt[triangles[i * 3 + 1]].point;
00241 btVector3 s2 = vt[triangles[i * 3 + 1]].point - vt[triangles[i * 3 + 2]].point;
00242 btVector3 normal = s1.cross(s2);
00243 normal.normalize();
00244 mesh->normals[3 * i ] = normal.getX();
00245 mesh->normals[3 * i + 1] = normal.getY();
00246 mesh->normals[3 * i + 2] = normal.getZ();
00247 }
00248
00249 return mesh;
00250 }
00251
00252 shapes::Mesh* createMeshFromAsset(const aiMesh* a, const btVector3& scale)
00253 {
00254 if (!a->HasFaces())
00255 {
00256 ROS_ERROR("Mesh asset has no faces");
00257 return NULL;
00258 }
00259
00260 if (!a->HasPositions())
00261 {
00262 ROS_ERROR("Mesh asset has no positions");
00263 return NULL;
00264 }
00265
00266 for (unsigned int i = 0 ; i < a->mNumFaces ; ++i)
00267 if (a->mFaces[i].mNumIndices != 3)
00268 {
00269 ROS_ERROR("Asset is not a triangle mesh");
00270 return NULL;
00271 }
00272
00273
00274 shapes::Mesh *mesh = new shapes::Mesh(a->mNumVertices, a->mNumFaces);
00275
00276
00277 for (unsigned int i = 0 ; i < a->mNumVertices ; ++i)
00278 {
00279 mesh->vertices[3 * i ] = a->mVertices[i].x*scale.x();
00280 mesh->vertices[3 * i + 1] = a->mVertices[i].y*scale.y();
00281 mesh->vertices[3 * i + 2] = a->mVertices[i].z*scale.z();
00282 }
00283
00284
00285 for (unsigned int i = 0 ; i < a->mNumFaces ; ++i)
00286 {
00287 mesh->triangles[3 * i ] = a->mFaces[i].mIndices[0];
00288 mesh->triangles[3 * i + 1] = a->mFaces[i].mIndices[1];
00289 mesh->triangles[3 * i + 2] = a->mFaces[i].mIndices[2];
00290 }
00291
00292
00293 for (unsigned int i = 0 ; i < a->mNumFaces ; ++i)
00294 {
00295 aiVector3D f1 = a->mVertices[a->mFaces[i].mIndices[0]];
00296 f1.x *= scale.x();
00297 f1.y *= scale.y();
00298 f1.z *= scale.z();
00299 aiVector3D f2 = a->mVertices[a->mFaces[i].mIndices[1]];
00300 f2.x *= scale.x();
00301 f2.y *= scale.y();
00302 f2.z *= scale.z();
00303 aiVector3D f3 = a->mVertices[a->mFaces[i].mIndices[2]];
00304 f3.x *= scale.x();
00305 f3.y *= scale.y();
00306 f3.z *= scale.z();
00307 aiVector3D as1 = f1-f2;
00308 aiVector3D as2 = f2-f3;
00309 btVector3 s1(as1.x, as1.y, as1.z);
00310 btVector3 s2(as2.x, as2.y, as2.z);
00311 btVector3 normal = s1.cross(s2);
00312 normal.normalize();
00313 mesh->normals[3 * i ] = normal.getX();
00314 mesh->normals[3 * i + 1] = normal.getY();
00315 mesh->normals[3 * i + 2] = normal.getZ();
00316 }
00317
00318 return mesh;
00319 }
00320
00321
00322 shapes::Mesh* createMeshFromBinaryStlData(const char *data, unsigned int size)
00323 {
00324 const char* pos = data;
00325 pos += 80;
00326
00327 unsigned int numTriangles = *(unsigned int*)pos;
00328 pos += 4;
00329
00330
00331 if ((long)(50 * numTriangles + 84) <= size)
00332 {
00333 std::vector<btVector3> vertices;
00334
00335 for (unsigned int currentTriangle = 0 ; currentTriangle < numTriangles ; ++currentTriangle)
00336 {
00337
00338 pos += 12;
00339
00340
00341 btVector3 v1(0,0,0);
00342 btVector3 v2(0,0,0);
00343 btVector3 v3(0,0,0);
00344
00345 v1.setX(*(float*)pos);
00346 pos += 4;
00347 v1.setY(*(float*)pos);
00348 pos += 4;
00349 v1.setZ(*(float*)pos);
00350 pos += 4;
00351
00352 v2.setX(*(float*)pos);
00353 pos += 4;
00354 v2.setY(*(float*)pos);
00355 pos += 4;
00356 v2.setZ(*(float*)pos);
00357 pos += 4;
00358
00359 v3.setX(*(float*)pos);
00360 pos += 4;
00361 v3.setY(*(float*)pos);
00362 pos += 4;
00363 v3.setZ(*(float*)pos);
00364 pos += 4;
00365
00366
00367 pos += 2;
00368
00369 vertices.push_back(v1);
00370 vertices.push_back(v2);
00371 vertices.push_back(v3);
00372 }
00373
00374 return createMeshFromVertices(vertices);
00375 }
00376
00377 return NULL;
00378 }
00379
00380 shapes::Mesh* createMeshFromBinaryStl(const char *filename)
00381 {
00382 FILE* input = fopen(filename, "r");
00383 if (!input)
00384 return NULL;
00385
00386 fseek(input, 0, SEEK_END);
00387 long fileSize = ftell(input);
00388 fseek(input, 0, SEEK_SET);
00389
00390 char* buffer = new char[fileSize];
00391 size_t rd = fread(buffer, fileSize, 1, input);
00392
00393 fclose(input);
00394
00395 shapes::Mesh *result = NULL;
00396
00397 if (rd == 1)
00398 result = createMeshFromBinaryStlData(buffer, fileSize);
00399
00400 delete[] buffer;
00401
00402 return result;
00403 }
00404 }