00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include <wx/filename.h>
00013 #include <wx/event.h>
00014 #include "stlparser.h"
00015 #include "../../textparser.h"
00016 #include "../../module.h"
00017 #include "../../geometrynode.h"
00018
00019 using namespace VRUT;
00020
00021
00022 STLParser::STLParser(wxInputStream * _inputStream, SCENE_ID _sceneID, const wxString _scenePath, Module * _module)
00023 : inputStream(_inputStream), sceneID(_sceneID), module(_module)
00024 {
00025 fileName = wxFileName(_scenePath).GetName();
00026 }
00027
00028
00029 STLParser::~STLParser()
00030 {
00032 }
00033
00034 bool STLParser::parseASCII(GeometryNode *node, std::vector<VECTOR3> * verts, std::vector<VECTOR3> * normals,
00035 std::vector<GeometryTriangles::Indice> * indices, bool recomputeNormals)
00036 {
00037 TextParser textParser(inputStream, 10000, 1000);
00038 wxString newName = textParser.GetWxString("\r\n");
00039
00041 wxCommandEvent evName = Event::GET_EVT_SCENE_NODE_NAME_SET(sceneID, node->GetName(), newName);
00042 module->PostToKernel(evName);
00043
00045 const char *keywords1[]={"facet normal", "endsolid", ""};
00046 const char *keywords2[]={"vertex", "endloop", ""};
00047 unsigned int index = 0;
00048 VECTOR3 vert;
00049 while (!textParser.IsEmpty())
00050 {
00051 switch (textParser.KeywordsSwitch(keywords1))
00052 {
00053 case 0:
00054 {
00055 VECTOR3 norm;
00056 if (textParser.ParseVector(norm._v, 3, true) != 3)
00057 return false;
00058
00059 while (textParser.NextKeywordIs("outer loop"))
00060 {
00061 bool cycle=true;
00062 while (cycle)
00063 {
00064 switch (textParser.KeywordsSwitch(keywords2))
00065 {
00066 case 0:
00067 if (textParser.ParseVector(vert._v, 3, true) != 3)
00068 return false;
00069 verts->push_back(vert);
00070
00071 indices->push_back(index++);
00072 break;
00073 case 1:
00074 if (recomputeNormals)
00075 {
00076 size_t lastI = verts->size()-3;
00077 norm = (verts->at(lastI+1) - verts->at(lastI)).Cross(verts->at(lastI+2) - verts->at(lastI)).Normalize();
00078 }
00079 normals->push_back(norm);
00080 normals->push_back(norm);
00081 normals->push_back(norm);
00082 cycle = false;
00083 break;
00084 default:
00085 LOGERROR(wxT("<STLParser>Unexpected token: '" + textParser.GetWxLine() + wxT("'")));
00086 return false;
00087 }
00088 }
00089 }
00090
00091 if (!textParser.NextKeywordIs("endfacet"))
00092 {
00093 LOGERROR(wxT("<STLParser>Unexpected token: '" + textParser.GetWxLine() + wxT("'")));
00094 return false;
00095 }
00096 }
00097 break;
00098 case 1:
00099 textParser.GetWxLine();
00100 break;
00101 default:
00102 LOGERROR(wxT("<STLParser>Unexpected token: '" + textParser.GetWxLine() + wxT("'")));
00103 return false;
00104 }
00105 }
00106 return true;
00107 }
00108
00109 bool STLParser::parseBinary(GeometryNode *node, std::vector<VECTOR3> * verts, std::vector<VECTOR3> * normals,
00110 std::vector<GeometryTriangles::Indice> * indices, bool recomputeNormals)
00111 {
00112
00113 char buf[81];
00114 inputStream->Read(buf, 74);
00115
00116 unsigned long count;
00117 inputStream->Read(&count, 4);
00118
00120 STLBinary facet;
00121 unsigned int index = 0;
00122 while (!inputStream->Eof())
00123 {
00124 inputStream->Read(&facet, 50);
00125 if (inputStream->LastRead()!=50)
00126 break;
00127
00128 if (recomputeNormals)
00129 memcpy(facet.norm, (VECTOR3(facet.vert2) - VECTOR3(facet.vert1)).Cross(VECTOR3(facet.vert3) - VECTOR3(facet.vert1)).Normalize()._v, sizeof(float)*3);
00130
00131 verts->push_back(facet.vert1);
00132 normals->push_back(facet.norm);
00133 indices->push_back(index++);
00134
00135 verts->push_back(facet.vert2);
00136 normals->push_back(facet.norm);
00137 indices->push_back(index++);
00138
00139 verts->push_back(facet.vert3);
00140 normals->push_back(facet.norm);
00141 indices->push_back(index++);
00142 }
00143 return true;
00144 }
00145
00146 bool STLParser::Parse(const wxString & rootUid, bool recomputeNormals)
00147 {
00148 wxCommandEvent evName = Event::GET_EVT_SCENE_NODE_NAME_SET(sceneID, rootUid, fileName);
00149 module->PostToKernel(evName);
00150
00151
00152 Material * material = new Material(wxT("STLDefault"));
00153 material->diffuse = VECTOR4(0.5, 0.5, 0.5, 1);
00154 material->specular = VECTOR4(0.5, 0.5, 0.5, 1);
00155 material->flags = Material::DOUBLE_SIDED;
00156 wxCommandEvent evMat = Event::GET_EVT_SCENE_MATERIAL_ADD(sceneID, material);
00157 module->PostToKernel(evMat);
00158
00159
00161 wxString nodeName = fileName + wxT("_node");
00162 GeometryNode * node = new GeometryNode(nodeName, nodeName);
00163 wxCommandEvent evNode = Event::GET_EVT_SCENE_NODE_INSERT(sceneID, node, rootUid);
00164 module->PostToKernel(evNode);
00165 wxCommandEvent evMatSet = Event::GET_EVT_SCENE_NODE_MATERIAL_SET(sceneID, nodeName, material->name);
00166 module->PostToKernel(evMatSet);
00167
00169 GeometryTriangles *geometry = new GeometryTriangles(nodeName);
00170
00172 std::vector<VECTOR3> * verts = &(geometry->vertices);
00173 std::vector<VECTOR3> * normals = &(geometry->normals);
00174 std::vector<GeometryTriangles::Indice> * indices = &(geometry->indices);
00175 std::pair<GeometryTriangles::Indice, GeometryTriangles::PRIMITIVE_TYPE> indType((GeometryTriangles::Indice)indices->size(), GeometryTriangles::TRI_LIST);
00176 geometry->triDescList.push_back(indType);
00177
00178
00179 bool parsedOK = true;
00180 char buf[7];
00181 inputStream->Read(buf, 6);
00182 buf[6]=0;
00183 if (!_strnicmp(buf, "solid ", 6))
00184 parsedOK = parseASCII(node, verts, normals, indices, recomputeNormals);
00185 else
00186 parsedOK = parseBinary(node, verts, normals, indices, recomputeNormals);
00187
00188 if (!parsedOK)
00189 LOGERROR(wxT("<STLParser>Scene not loaded properly"));
00190 else
00191 {
00193 wxCommandEvent evGeom = Event::GET_EVT_SCENE_GEOMETRY_ADD(sceneID, geometry);
00194 module->PostToKernel(evGeom);
00195 wxCommandEvent evGeomSet = Event::GET_EVT_SCENE_NODE_GEOMETRY_SET(sceneID, nodeName, geometry->GetName());
00196 module->PostToKernel(evGeomSet);
00197 }
00198 return parsedOK;
00199 }
00200