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
00035
00036
00037 #include "collada_urdf/stl_loader.h"
00038
00039 #include <ctype.h>
00040 #include <stdio.h>
00041 #include <string.h>
00042
00043 #include <iostream>
00044
00045 using std::string;
00046 using boost::shared_ptr;
00047
00048 namespace collada_urdf {
00049
00050
00051
00052 Vector3::Vector3(float _x, float _y, float _z) : x(_x), y(_y), z(_z) { }
00053
00054 bool Vector3::operator==(Vector3 const& v) const {
00055 return x == v.x && y == v.y && z == v.z;
00056 }
00057
00058
00059
00060 Mesh::Mesh() {
00061 }
00062
00063 int Mesh::getVertexIndex(const Vector3& v) const {
00064 for (unsigned int i = 0; i < vertices.size(); i++)
00065 if (vertices[i] == v)
00066 return i;
00067
00068 return -1;
00069 }
00070
00071 void Mesh::addVertex(Vector3 const& v) { vertices.push_back(v); }
00072 void Mesh::addNormal(Vector3 const& n) { normals.push_back(n); }
00073 void Mesh::addIndex(unsigned int i) { indices.push_back(i); }
00074
00075
00076
00077 shared_ptr<Mesh> STLLoader::load(std::string const& filename) {
00078 file_ = fopen(filename.c_str(), "r");
00079 if (file_ == NULL)
00080 return shared_ptr<Mesh>();
00081
00082 mesh_ = shared_ptr<Mesh>(new Mesh);
00083 readBinary();
00084 fclose(file_);
00085 file_ = NULL;
00086
00087 return mesh_;
00088 }
00089
00090 void STLLoader::readBinary() {
00091
00092 for (int i = 0; i < 80; i++)
00093 fgetc(file_);
00094
00095 int face_num = readLongInt();
00096
00097 for (int iface = 0; iface < face_num; iface++) {
00098 float nx = readFloat();
00099 float ny = readFloat();
00100 float nz = readFloat();
00101 Vector3 normal(nx, ny, nz);
00102
00103 for (int i = 0; i < 3; i++) {
00104 float vx = readFloat();
00105 float vy = readFloat();
00106 float vz = readFloat();
00107 Vector3 vertex(vx, vy, vz);
00108
00109 int index = mesh_->getVertexIndex(vertex);
00110 if (index == -1) {
00111 mesh_->addVertex(vertex);
00112 mesh_->addNormal(normal);
00113 index = mesh_->vertices.size() - 1;
00114 }
00115 mesh_->addIndex(index);
00116 }
00117
00118 readShortInt();
00119 }
00120 }
00121
00122 float STLLoader::readFloat() {
00123 float rval;
00124 if (fread(&rval, sizeof(float), 1, file_) == 0)
00125 std::cerr << "Error in STLLoader::readFloat" << std::endl;
00126
00127 return rval;
00128 }
00129
00130 uint32_t STLLoader::readLongInt() {
00131 union
00132 {
00133 uint32_t yint;
00134 char ychar[4];
00135 } y;
00136 y.ychar[0] = fgetc(file_);
00137 y.ychar[1] = fgetc(file_);
00138 y.ychar[2] = fgetc(file_);
00139 y.ychar[3] = fgetc(file_);
00140
00141 return y.yint;
00142 }
00143
00144 uint16_t STLLoader::readShortInt() {
00145 uint8_t c1 = fgetc(file_);
00146 uint8_t c2 = fgetc(file_);
00147
00148 uint16_t ival = c1 | (c2 << 8);
00149
00150 return ival;
00151 }
00152
00153 }