stl_parser.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2008, Willow Garage, Inc.
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions are met:
00007  *
00008  *     * Redistributions of source code must retain the above copyright
00009  *       notice, this list of conditions and the following disclaimer.
00010  *     * Redistributions in binary form must reproduce the above copyright
00011  *       notice, this list of conditions and the following disclaimer in the
00012  *       documentation and/or other materials provided with the distribution.
00013  *     * Neither the name of the Willow Garage, Inc. nor the names of its
00014  *       contributors may be used to endorse or promote products derived from
00015  *       this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00018  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00020  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00021  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00022  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00023  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00024  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00025  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00026  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00027  * POSSIBILITY OF SUCH DAMAGE.
00028  */
00029 
00030 #include <rve_mesh_loader/stl_parser.h>
00031 #include <ros/console.h>
00032 
00033 #include <rve_msgs/Mesh.h>
00034 
00035 #include <Eigen/Geometry>
00036 
00037 namespace rve_mesh_loader
00038 {
00039 
00040 void calculateUV(const Eigen::Vector3f& vec, float& u, float& v)
00041 {
00042   Eigen::Vector3f pos(vec);
00043   pos.normalize();
00044   u = acos( pos.y() / pos.norm() );
00045 
00046   float val = pos.x() / ( sin( u ) );
00047   v = acos( val );
00048 
00049   u /= M_PI;
00050   v /= M_PI;
00051 }
00052 
00053 void parseSTL(uint8_t* buffer, size_t buffer_size, const std::string& extension, rve_msgs::Mesh& out_mesh)
00054 {
00055   out_mesh.submeshes.resize(1);
00056   rve_msgs::SubMesh& submesh = out_mesh.submeshes[0];
00057   uint8_t* pos = buffer;
00058   pos += 80; // skip the 80 byte header
00059 
00060   uint32_t tri_count = *(uint32_t*)pos;
00061   pos += 4;
00062 
00063   submesh.positions.resize(tri_count * 3);
00064   submesh.normals.resize(tri_count * 3);
00065   submesh.indices.resize(tri_count * 3);
00066   submesh.tex_coords.resize(1);
00067   submesh.tex_coords[0].array.resize(tri_count * 3);
00068   submesh.tex_coords[0].dims = 2;
00069   for ( uint32_t tri = 0; tri < tri_count; ++tri )
00070   {
00071     // Read face normal
00072     Eigen::Vector3f normal;
00073 
00074     normal.x() = *(float*)pos;
00075     pos += 4;
00076     normal.y() = *(float*)pos;
00077     pos += 4;
00078     normal.z() = *(float*)pos;
00079     pos += 4;
00080 
00081     // Read 3 vertices
00082     for (uint32_t i = 0; i < 3; ++i)
00083     {
00084       uint32_t vert_index = tri * 3 + i;
00085       rve_msgs::Vector3& p = submesh.positions[vert_index];
00086       p.x = *(float*)pos;
00087       pos += 4;
00088       p.y = *(float*)pos;
00089       pos += 4;
00090       p.z = *(float*)pos;
00091       pos += 4;
00092 
00093       rve_msgs::TexCoord& uvw = submesh.tex_coords[0].array[vert_index];
00094       calculateUV( Eigen::Vector3f(p.x, p.y, p.z), uvw.uvw[0], uvw.uvw[1] );
00095     }
00096 
00097     // Blender was writing a large number into this short... am I misinterpreting what the attribute byte count is supposed to do?
00098     //unsigned short attributeByteCount = *(unsigned short*)pos;
00099     pos += 2;
00100 
00101     //pos += attributeByteCount;
00102 
00103     if (normal.squaredNorm() < 0.001)
00104     {
00105       rve_msgs::Vector3& p0 = submesh.positions[0];
00106       rve_msgs::Vector3& p1 = submesh.positions[1];
00107       rve_msgs::Vector3& p2 = submesh.positions[2];
00108       Eigen::Vector3f side1 = Eigen::Vector3f(p0.x, p0.y, p0.z) - Eigen::Vector3f(p1.x, p1.y, p1.z);
00109       Eigen::Vector3f side2 = Eigen::Vector3f(p1.x, p1.y, p1.z) - Eigen::Vector3f(p2.x, p2.y, p2.z);
00110       normal = side1.cross(side2);
00111       normal.normalize();
00112     }
00113 
00114     // Assign normal
00115     for (uint32_t i = 0; i < 3; ++i)
00116     {
00117       uint32_t vert_index = tri * 3 + i;
00118       rve_msgs::Vector3& n = submesh.normals[vert_index];
00119       n.x = normal.x();
00120       n.y = normal.y();
00121       n.z = normal.z();
00122     }
00123   }
00124 }
00125 
00126 }


rve_mesh_loader
Author(s): Josh Faust
autogenerated on Wed Dec 11 2013 14:31:10