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 #include "ioSTL.hpp"
00033 #include <vlCore/Log.hpp>
00034 #include <vlCore/Say.hpp>
00035 #include <vlCore/VisualizationLibrary.hpp>
00036 #include <vlCore/FileSystem.hpp>
00037 #include <vlCore/TextStream.hpp>
00038 #include <vlCore/VirtualFile.hpp>
00039 #include <vlGraphics/Effect.hpp>
00040 #include <vlGraphics/Actor.hpp>
00041 #include <vlCore/LoadWriterManager.hpp>
00042 #include <stdio.h>
00043
00044 using namespace vl;
00045
00046 ref<ResourceDatabase> vl::loadSTL(const String& path)
00047 {
00048 ref<VirtualFile> file = defFileSystem()->locateFile(path);
00049
00050 if (file)
00051 return loadSTL( file.get() );
00052 else
00053 {
00054 Log::error( Say("Could not locate '%s'.\n") << path );
00055 return NULL;
00056 }
00057 }
00058
00059 ref<ResourceDatabase> vl::loadSTL(VirtualFile* file)
00060 {
00061 STLLoader stl;
00062 ref<ResourceDatabase> res_db = stl.loadSTL(file);
00063 return res_db;
00064 }
00065
00066 ref<ResourceDatabase> STLLoader::loadBinary(VirtualFile* file)
00067 {
00068
00069 char header[80];
00070 file->read(header,80);
00071 unsigned int tri_count = file->readUInt32();
00072
00073 ref<ArrayFloat3> verts = new ArrayFloat3;
00074 ref<ArrayFloat3> normals = new ArrayFloat3;
00075 verts->resize(tri_count*3);
00076 normals->resize(tri_count*3);
00077 ref<DrawArrays> de = new DrawArrays(PT_TRIANGLES,0,tri_count*3);
00078 ref<Geometry> geom = new Geometry;
00079 geom->drawCalls()->push_back(de.get());
00080 geom->setVertexArray(verts.get());
00081 geom->setNormalArray(normals.get());
00082
00083
00084 for(unsigned int i=0; i<tri_count; ++i)
00085 {
00086 fvec3 n,v1,v2,v0;
00087 n.x() = file->readFloat();
00088 n.y() = file->readFloat();
00089 n.z() = file->readFloat();
00090 v0.x() = file->readFloat();
00091 v0.y() = file->readFloat();
00092 v0.z() = file->readFloat();
00093 v1.x() = file->readFloat();
00094 v1.y() = file->readFloat();
00095 v1.z() = file->readFloat();
00096 v2.x() = file->readFloat();
00097 v2.y() = file->readFloat();
00098 v2.z() = file->readFloat();
00099
00100 file->readUInt16();
00101 normals->at(i*3+0) = n;
00102 verts->at(i*3+0) = v0;
00103 normals->at(i*3+1) = n;
00104 verts->at(i*3+1) = v1;
00105 normals->at(i*3+2) = n;
00106 verts->at(i*3+2) = v2;
00107 }
00108
00109 ref<ResourceDatabase> res_db = new ResourceDatabase;
00110 ref<Effect> effect = new Effect;
00111 res_db->resources().push_back( geom );
00112 res_db->resources().push_back( new Actor(geom.get(), effect.get(), NULL ) );
00113 res_db->resources().push_back( effect.get() );
00114 return res_db;
00115 }
00116 ref<ResourceDatabase> STLLoader::loadAscii(VirtualFile* file)
00117 {
00118 TextStream line_reader;
00119 line_reader.setInputFile(file);
00120 std::string str;
00121
00122
00123 line_reader.readLine(str);
00124
00125 std::vector<fvec3> verts;
00126 std::vector<fvec3> norms;
00127
00128 fvec3 v[3], n;
00129 char parola1[32];
00130 char parola2[32];
00131 while( line_reader.readLine(str) )
00132 {
00133 sscanf(str.c_str(), "%s %s %f %f %f", parola1, parola2, &n.x(), &n.y(), &n.z());
00134
00135 line_reader.readLine(str);
00136 line_reader.readLine(str); sscanf(str.c_str(), "%s %f %f %f", parola1, &v[0].x(), &v[0].y(), &v[0].z());
00137 line_reader.readLine(str); sscanf(str.c_str(), "%s %f %f %f", parola1, &v[1].x(), &v[1].y(), &v[1].z());
00138 line_reader.readLine(str); sscanf(str.c_str(), "%s %f %f %f", parola1, &v[2].x(), &v[2].y(), &v[2].z());
00139
00140 line_reader.readLine(str);
00141
00142 line_reader.readLine(str);
00143
00144 norms.push_back(n);
00145 norms.push_back(n);
00146 norms.push_back(n);
00147 verts.push_back(v[0]);
00148 verts.push_back(v[1]);
00149 verts.push_back(v[2]);
00150 }
00151
00152 ref<ArrayFloat3> vertices = new ArrayFloat3;
00153 ref<ArrayFloat3> normals = new ArrayFloat3;
00154 vertices->resize(verts.size());
00155 normals->resize(verts.size());
00156 memcpy(normals ->ptr(), &norms[0], sizeof(norms[0])*norms.size());
00157 memcpy(vertices->ptr(), &verts[0], sizeof(verts[0])*verts.size());
00158 ref<DrawArrays> de = new DrawArrays(PT_TRIANGLES,0,verts.size());
00159 ref<Geometry> geom = new Geometry;
00160 geom->drawCalls()->push_back(de.get());
00161 geom->setVertexArray(vertices.get());
00162 geom->setNormalArray(normals.get());
00163
00164 ref<ResourceDatabase> res_db = new ResourceDatabase;
00165 ref<Effect> effect = new Effect;
00166 res_db->resources().push_back( geom );
00167 res_db->resources().push_back( new Actor(geom.get(), effect.get(), NULL ) );
00168 res_db->resources().push_back( effect.get() );
00169 return res_db;
00170 }
00171 ref<ResourceDatabase> STLLoader::loadSTL(VirtualFile* file)
00172 {
00173 file->open(OM_ReadOnly);
00174
00175 char header[] = {1,2,3,4,5,0};
00176
00177 file->read(header,5);
00178 ref<ResourceDatabase> res_db;
00179 if (strcmp((char*)header,"solid") == 0)
00180 {
00181
00182 file->seekSet(0);
00183 res_db = loadAscii(file);
00184 }
00185 else
00186 {
00187
00188 file->seekSet(0);
00189 res_db = loadBinary(file);
00190 }
00191
00192 file->close();
00193 return res_db;
00194 }
00195