Shape* StlMesh::CreateShape(const Transform &o2w, bool reverseOrientation, const ParamSet ¶ms) { string name = params.FindOneString("name", "'stlmesh'"); string FileName = params.FindOneString("filename", "none"); string subdivscheme = params.FindOneString("subdivscheme", "loop"); int nsubdivlevels = params.FindOneInt("nsubdivlevels", 0); bool recenterMesh = params.FindOneBool("recenter_mesh", false); Mesh::MeshSubdivType subdivType; if (subdivscheme == "loop") subdivType = Mesh::SUBDIV_LOOP; else if (subdivscheme == "microdisplacement") subdivType = Mesh::SUBDIV_MICRODISPLACEMENT; else { SHAPE_LOG(name, LUX_WARNING,LUX_BADTOKEN) << "Subdivision type '" << subdivscheme << "' unknown. Using \"loop\"."; subdivType = Mesh::SUBDIV_LOOP; } SHAPE_LOG(name, LUX_INFO, LUX_NOERROR) << "Loading STL mesh file: '" << FileName << "'..."; FILE* pFile = fopen(FileName.c_str(), "rb"); if(!pFile) { SHAPE_LOG(name, LUX_ERROR, LUX_SYSTEM) << "Unable to read STL mesh file '" << FileName << "'"; return NULL; } uint32_t uNFaces; std::vector<Point> Vertices; // Checking file format (ASCII or binary) bool bIsBinary = false; do { fseek(pFile, 0, SEEK_END); uint32_t uLength = ftell(pFile); if (80 + sizeof(uint32_t) >= uLength) break; fseek(pFile, 80, SEEK_SET); if (fread(&uNFaces, sizeof(uNFaces), 1, pFile) != 1) break; if (!uNFaces || uNFaces > MAX_STL_FILE_FACES) break; if (80 + sizeof(uint32_t) + uNFaces * (sizeof(float) * 3 * 4 + sizeof(uint16_t)) != uLength) break; bIsBinary = true; }while(false); if(bIsBinary) // binary mode loader { fseek(pFile, 80, SEEK_SET); if(fread(&uNFaces, sizeof(uNFaces), 1, pFile) != 1) { fclose(pFile); SHAPE_LOG(name, LUX_ERROR, LUX_SYSTEM) << "Invalid STL mesh file '" << FileName << "'"; return NULL; } Vertices.resize(uNFaces * 3); const size_t szFaceSize = sizeof(float) * 3 * 4 + sizeof(uint16_t); // Preloading file std::vector<uint8_t> Data(uNFaces * szFaceSize); if(fread(&Data[0], 1, Data.size(), pFile) != Data.size()) { fclose(pFile); SHAPE_LOG(name, LUX_ERROR, LUX_SYSTEM) << "Invalid STL mesh file '" << FileName << "'"; return NULL; } for(uint32_t i = 0 ; i < uNFaces ; i++) { const float* pBaseData = reinterpret_cast<float*>(&Data[0] + i * szFaceSize); Vertices[i*3 + 0].x = pBaseData[3]; Vertices[i*3 + 0].y = pBaseData[4]; Vertices[i*3 + 0].z = pBaseData[5]; Vertices[i*3 + 1].x = pBaseData[6]; Vertices[i*3 + 1].y = pBaseData[7]; Vertices[i*3 + 1].z = pBaseData[8]; Vertices[i*3 + 2].x = pBaseData[9]; Vertices[i*3 + 2].y = pBaseData[10]; Vertices[i*3 + 2].z = pBaseData[11]; } fclose(pFile); } else // ASCII mode loader { // Reopening in text mode fclose(pFile); if(!(pFile = fopen(FileName.c_str(), "rt"))) { SHAPE_LOG(name, LUX_ERROR, LUX_SYSTEM) << "Unable to read STL mesh file '" << FileName << "'"; return NULL; } // Reading file char Token[128]; uNFaces = 0; while(!feof(pFile)) { if(fscanf(pFile, "%127s", Token) != 1) { fclose(pFile); SHAPE_LOG(name, LUX_ERROR, LUX_SYSTEM) << "Invalid STL mesh file '" << FileName << "'"; return NULL; } Token[127] = 0; if(!stricmp(Token, "endsolid")) break; if(!stricmp(Token, "facet")) uNFaces++; } Vertices.resize(uNFaces * 3); // Rewinding file and skipping 'solid ...' header fseek(pFile, 0, SEEK_SET); fgets(Token, sizeof(Token), pFile); // Reading faces for(uint32_t i = 0 ; i < uNFaces ; i++) { fscanf(pFile, "%*s %*s %*f %*f %*f %*s %*s"); // facet normal [nx] [ny] [nz] outer loop if( fscanf( pFile, "%*s %f %f %f", &Vertices[i*3 + 0].x, &Vertices[i*3 + 0].y, &Vertices[i*3 + 0].z) != 3 || // vertex [v1] [v2] [v3] fscanf( pFile, "%*s %f %f %f", &Vertices[i*3 + 1].x, &Vertices[i*3 + 1].y, &Vertices[i*3 + 1].z) != 3 || // vertex [v1] [v2] [v3] fscanf( pFile, "%*s %f %f %f", &Vertices[i*3 + 2].x, &Vertices[i*3 + 2].y, &Vertices[i*3 + 2].z) != 3) // vertex [v1] [v2] [v3] { fclose(pFile); SHAPE_LOG(name, LUX_ERROR, LUX_SYSTEM) << "Invalid STL mesh file '" << FileName << "'"; return NULL; } fscanf(pFile, "%*s %*s"); // endloop endfacet } fclose(pFile); } if (recenterMesh) { // Bringing bounding box center to (0,0,0) BBox bbox; for(size_t i = 0 ; i < Vertices.size() ; i++) bbox = Union(bbox, BBox(Vertices[i])); Vector centerV((bbox.pMin + bbox.pMax) * 0.5f); for(size_t i = 0 ; i < Vertices.size() ; i++) Vertices[i] -= centerV; } // Filling face indices vector<int> Faces(uNFaces * 3); for(uint32_t i = 0 ; i < uNFaces ; i++) { Faces[i*3 + 0] = i*3 + 0; Faces[i*3 + 1] = i*3 + 1; Faces[i*3 + 2] = i*3 + 2; } boost::shared_ptr<Texture<float> > displacementMap; return new Mesh(o2w, reverseOrientation, name, Mesh::ACCEL_AUTO, Vertices.size(), &Vertices[0], NULL, NULL, NULL, NULL, 1.f, Mesh::TRI_AUTO, uNFaces, &Faces[0], Mesh::QUAD_QUADRILATERAL, 0, NULL, subdivType, nsubdivlevels, displacementMap, 0.1f, 0.0f, true, false, false, false); }
//------------------------------------------------------------------------------ Rect& Rect::center (const Rect& rect) { centerH (rect); return centerV (rect); }
void Boonas::doRotate(QString outfile, QString vectx, QString vecty, QString vectz, QString px, QString py, QString pz, QString divisions, QString degrees) { Point centerP(px.toFloat(), py.toFloat(), pz.toFloat()); Vector centerV(vectx.toFloat(), vecty.toFloat(), vectz.toFloat()); Transformation matrix; float theta; float phi; float angleOfRot = degrees.toFloat() / divisions.toFloat(); // translate to x matrix = xt(-px.toFloat(), matrix); matrix = yt(-py.toFloat(), matrix); matrix = zt(-pz.toFloat(), matrix); if(vectz.toFloat() == 0) { if((vectx.toFloat() == 1) && (vectz.toFloat() == 0)) { theta = 1.57079633; } else { theta = 0.0; } } else { theta = atan(vectx.toFloat() / vectz.toFloat()); } matrix = yr(-theta, matrix); phi = atan(vecty.toFloat() / (sqrt((vectx.toFloat() * vectx.toFloat()) + (vectz.toFloat() * vectz.toFloat())))); matrix = xr(phi, matrix); // apply matrix doMult(matrix); // do rotates and divisions along Z doZrm(outfile, angleOfRot, divisions.toFloat()); // have to re-read from a temp file after this delete orig; orig = new LNHHolder(); readTfile(outfile); //unrotate matrix = Transformation(); matrix = xr(-phi, matrix); matrix = yr(theta, matrix); // untranslate matrix = xt(px.toFloat(), matrix); matrix = yt(py.toFloat(), matrix); matrix = zt(pz.toFloat(), matrix); // apply matrix doMult(matrix); return; }