int GModel::readPLY(const std::string &name) { // this is crazy!? replaceCommaByDot(name); FILE *fp = Fopen(name.c_str(), "r"); if(!fp){ Msg::Error("Unable to open file '%s'", name.c_str()); return 0; } std::vector<MVertex*> vertexVector; std::map<int, std::vector<MElement*> > elements[5]; std::map<int, std::vector<double> > properties; char buffer[256], str[256], str2[256], str3[256]; std::string s1; int elementary = getMaxElementaryNumber(-1) + 1; int nbv = 0, nbf = 0; int nbprop = 0; int nbView = 0; std::vector<std::string> propName; while(!feof(fp)) { if(!fgets(buffer, sizeof(buffer), fp)) break; if(buffer[0] != '#'){ // skip comments sscanf(buffer, "%s %s", str, str2); if(!strcmp(str, "element") && !strcmp(str2, "vertex")){ sscanf(buffer, "%s %s %d", str, str2, &nbv); } if(!strcmp(str, "format") && strcmp(str2, "ascii")){ Msg::Error("Only reading of ascii PLY files implemented"); fclose(fp); return 0; } if(!strcmp(str, "property") && strcmp(str2, "list")){ nbprop++; sscanf(buffer, "%s %s %s", str, str2, str3); if (nbprop > 3) propName.push_back(s1+str3); } if(!strcmp(str, "element") && !strcmp(str2, "face")){ sscanf(buffer, "%s %s %d", str, str2, &nbf); } if(!strcmp(str, "end_header")){ nbView = nbprop -3; Msg::Info("%d elements", nbv); Msg::Info("%d triangles", nbf); Msg::Info("%d properties", nbView); vertexVector.resize(nbv); for(int i = 0; i < nbv; i++) { double x,y,z; char line[10000], *pEnd, *pEnd2, *pEnd3; if(!fgets(line, sizeof(line), fp)){ fclose(fp); return 0; } x = strtod(line, &pEnd); y = strtod(pEnd, &pEnd2); z = strtod(pEnd2, &pEnd3); vertexVector[i] = new MVertex(x, y, z); pEnd = pEnd3; std::vector<double> prop(nbView); for (int k = 0; k < nbView; k++){ prop[k]=strtod(pEnd, &pEnd2); pEnd = pEnd2; properties[k].push_back(prop[k]); } } for(int i = 0; i < nbf; i++) { if(!fgets(buffer, sizeof(buffer), fp)) break; int n[3], nbe; sscanf(buffer, "%d %d %d %d", &nbe, &n[0], &n[1], &n[2]); std::vector<MVertex*> vertices; if(!getVertices(3, n, vertexVector, vertices)){ fclose(fp); return 0; } elements[0][elementary].push_back(new MTriangle(vertices)); } } } } for(int i = 0; i < (int)(sizeof(elements) / sizeof(elements[0])); i++) _storeElementsInEntities(elements[i]); _associateEntityWithMeshVertices(); _storeVerticesInEntities(vertexVector); #if defined(HAVE_POST) // create PViews here std::vector<GEntity*> _entities; getEntities(_entities); for (int iV=0; iV< nbView; iV++){ PView *view = new PView(); PViewDataList *data = dynamic_cast<PViewDataList*>(view->getData()); for(unsigned int ii = 0; ii < _entities.size(); ii++){ for(unsigned int i = 0; i < _entities[ii]->getNumMeshElements(); i++){ MElement *e = _entities[ii]->getMeshElement(i); int numNodes = e->getNumVertices(); std::vector<double> x(numNodes), y(numNodes), z(numNodes); std::vector<double> *out = data->incrementList(1, e->getType()); for(int nod = 0; nod < numNodes; nod++) out->push_back((e->getVertex(nod))->x()); for(int nod = 0; nod < numNodes; nod++) out->push_back((e->getVertex(nod))->y()); for(int nod = 0; nod < numNodes; nod++) out->push_back((e->getVertex(nod))->z()); std::vector<double> props; int n[3]; n[0] = e->getVertex(0)->getNum()-1; n[1] = e->getVertex(1)->getNum()-1; n[2] = e->getVertex(2)->getNum()-1; if(!getProperties(3, n, properties[iV], props)){ fclose(fp); return 0; } for(int nod = 0; nod < numNodes; nod++) out->push_back(props[nod]); } } data->setName(propName[iV]); data->Time.push_back(0); data->setFileName("property.pos"); data->finalize(); } #endif fclose(fp); return 1; }
int GModel::readP3D(const std::string &name) { FILE *fp = Fopen(name.c_str(), "r"); if(!fp) { Msg::Error("Unable to open file '%s'", name.c_str()); return 0; } int numBlocks = 0; if(fscanf(fp, "%d", &numBlocks) != 1 || numBlocks <= 0) { fclose(fp); return 0; } std::vector<int> Ni(numBlocks), Nj(numBlocks), Nk(numBlocks); for(int n = 0; n < numBlocks; n++) if(fscanf(fp, "%d %d %d", &Ni[n], &Nj[n], &Nk[n]) != 3) { fclose(fp); return 0; } for(int n = 0; n < numBlocks; n++) { if(Nk[n] == 1) { GFace *gf = new discreteFace(this, getMaxElementaryNumber(2) + 1); add(gf); gf->transfinite_vertices.resize(Ni[n]); for(int i = 0; i < Ni[n]; i++) gf->transfinite_vertices[i].resize(Nj[n]); for(int coord = 0; coord < 3; coord++) { for(int j = 0; j < Nj[n]; j++) { for(int i = 0; i < Ni[n]; i++) { double d; if(fscanf(fp, "%lf", &d) != 1) { fclose(fp); return 0; } if(coord == 0) { MVertex *v = new MVertex(d, 0., 0., gf); gf->transfinite_vertices[i][j] = v; gf->mesh_vertices.push_back(v); } else if(coord == 1) { gf->transfinite_vertices[i][j]->y() = d; } else if(coord == 2) { gf->transfinite_vertices[i][j]->z() = d; } } } } for(std::size_t i = 0; i < gf->transfinite_vertices.size() - 1; i++) for(std::size_t j = 0; j < gf->transfinite_vertices[0].size() - 1; j++) gf->quadrangles.push_back(new MQuadrangle( gf->transfinite_vertices[i][j], gf->transfinite_vertices[i + 1][j], gf->transfinite_vertices[i + 1][j + 1], gf->transfinite_vertices[i][j + 1])); } else { GRegion *gr = new discreteRegion(this, getMaxElementaryNumber(3) + 1); add(gr); gr->transfinite_vertices.resize(Ni[n]); for(int i = 0; i < Ni[n]; i++) { gr->transfinite_vertices[i].resize(Nj[n]); for(int j = 0; j < Nj[n]; j++) { gr->transfinite_vertices[i][j].resize(Nk[n]); } } for(int coord = 0; coord < 3; coord++) { for(int k = 0; k < Nk[n]; k++) { for(int j = 0; j < Nj[n]; j++) { for(int i = 0; i < Ni[n]; i++) { double d; if(fscanf(fp, "%lf", &d) != 1) { fclose(fp); return 0; } if(coord == 0) { MVertex *v = new MVertex(d, 0., 0., gr); gr->transfinite_vertices[i][j][k] = v; gr->mesh_vertices.push_back(v); } else if(coord == 1) { gr->transfinite_vertices[i][j][k]->y() = d; } else if(coord == 2) { gr->transfinite_vertices[i][j][k]->z() = d; } } } } } for(std::size_t i = 0; i < gr->transfinite_vertices.size() - 1; i++) for(std::size_t j = 0; j < gr->transfinite_vertices[0].size() - 1; j++) for(std::size_t k = 0; k < gr->transfinite_vertices[0][0].size() - 1; k++) gr->hexahedra.push_back( new MHexahedron(gr->transfinite_vertices[i][j][k], gr->transfinite_vertices[i + 1][j][k], gr->transfinite_vertices[i + 1][j + 1][k], gr->transfinite_vertices[i][j + 1][k], gr->transfinite_vertices[i][j][k + 1], gr->transfinite_vertices[i + 1][j][k + 1], gr->transfinite_vertices[i + 1][j + 1][k + 1], gr->transfinite_vertices[i][j + 1][k + 1])); } } fclose(fp); return 1; }
int GModel::readPLY2(const std::string &name) { FILE *fp = Fopen(name.c_str(), "r"); if(!fp){ Msg::Error("Unable to open file '%s'", name.c_str()); return 0; } std::vector<MVertex*> vertexVector; std::map<int, std::vector<MElement*> > elements[5]; char buffer[256]; int elementary = getMaxElementaryNumber(-1) + 1; int nbv, nbf; while(!feof(fp)) { if(!fgets(buffer, sizeof(buffer), fp)) break; if(buffer[0] != '#'){ // skip comments sscanf(buffer, "%d", &nbv); if(!fgets(buffer, sizeof(buffer), fp)) break; sscanf(buffer, "%d", &nbf); Msg::Info("%d vertices", nbv); Msg::Info("%d triangles", nbf); vertexVector.resize(nbv); for(int i = 0; i < nbv; i++) { if(!fgets(buffer, sizeof(buffer), fp)) break; double x, y, z; int nb = sscanf(buffer, "%lf %lf %lf", &x, &y, &z); if (nb !=3){ if(!fgets(buffer, sizeof(buffer), fp)) break; sscanf(buffer, "%lf", &y); if(!fgets(buffer, sizeof(buffer), fp)) break; sscanf(buffer, "%lf", &z); } vertexVector[i] = new MVertex(x, y, z); } for(int i = 0; i < nbf; i++) { if(!fgets(buffer, sizeof(buffer), fp)) break; int n[3], nbe; int nb = sscanf(buffer, "%d %d %d %d", &nbe, &n[0], &n[1], &n[2]); if (nb !=4){ if(!fgets(buffer, sizeof(buffer), fp)) break; sscanf(buffer, "%d", &n[0]); if(!fgets(buffer, sizeof(buffer), fp)) break; sscanf(buffer, "%d", &n[1]); if(!fgets(buffer, sizeof(buffer), fp)) break; sscanf(buffer, "%d", &n[2]); } std::vector<MVertex*> vertices; if(!getVertices(3, n, vertexVector, vertices)){ fclose(fp); return 0; } elements[0][elementary].push_back(new MTriangle(vertices)); } } } for(int i = 0; i < (int)(sizeof(elements) / sizeof(elements[0])); i++) _storeElementsInEntities(elements[i]); _associateEntityWithMeshVertices(); _storeVerticesInEntities(vertexVector); fclose(fp); return 1; }
int GModel::readSTL(const std::string &name, double tolerance) { FILE *fp = Fopen(name.c_str(), "rb"); if(!fp){ Msg::Error("Unable to open file '%s'", name.c_str()); return 0; } // store triplets of points for each solid found in the file std::vector<std::vector<SPoint3> > points; SBoundingBox3d bbox; // "solid", or binary data header char buffer[256]; if(!fgets(buffer, sizeof(buffer), fp)){ fclose(fp); return 0; } bool binary = strncmp(buffer, "solid", 5) && strncmp(buffer, "SOLID", 5); // ASCII STL if(!binary){ points.resize(1); while(!feof(fp)) { // "facet normal x y z" or "endsolid" if(!fgets(buffer, sizeof(buffer), fp)) break; if(!strncmp(buffer, "endsolid", 8) || !strncmp(buffer, "ENDSOLID", 8)){ // "solid" if(!fgets(buffer, sizeof(buffer), fp)) break; if(!strncmp(buffer, "solid", 5) || !strncmp(buffer, "SOLID", 5)){ points.resize(points.size() + 1); // "facet normal x y z" if(!fgets(buffer, sizeof(buffer), fp)) break; } } // "outer loop" if(!fgets(buffer, sizeof(buffer), fp)) break; // "vertex x y z" for(int i = 0; i < 3; i++){ if(!fgets(buffer, sizeof(buffer), fp)) break; char s1[256]; double x, y, z; if(sscanf(buffer, "%s %lf %lf %lf", s1, &x, &y, &z) != 4) break; SPoint3 p(x, y, z); points.back().push_back(p); bbox += p; } // "endloop" if(!fgets(buffer, sizeof(buffer), fp)) break; // "endfacet" if(!fgets(buffer, sizeof(buffer), fp)) break; } } // check if we could parse something bool empty = true; for(unsigned int i = 0; i < points.size(); i++){ if(points[i].size()){ empty = false; break; } } if(empty) points.clear(); // binary STL (we also try to read in binary mode if the header told // us the format was ASCII but we could not read any vertices) if(binary || empty){ if(binary) Msg::Info("Mesh is in binary format"); else Msg::Info("Wrong ASCII header or empty file: trying binary read"); rewind(fp); while(!feof(fp)) { char header[80]; if(!fread(header, sizeof(char), 80, fp)) break; unsigned int nfacets = 0; size_t ret = fread(&nfacets, sizeof(unsigned int), 1, fp); bool swap = false; if(nfacets > 100000000){ Msg::Info("Swapping bytes from binary file"); swap = true; SwapBytes((char*)&nfacets, sizeof(unsigned int), 1); } if(ret && nfacets){ points.resize(points.size() + 1); char *data = new char[nfacets * 50 * sizeof(char)]; ret = fread(data, sizeof(char), nfacets * 50, fp); if(ret == nfacets * 50){ for(unsigned int i = 0; i < nfacets; i++) { float *xyz = (float *)&data[i * 50 * sizeof(char)]; if(swap) SwapBytes((char*)xyz, sizeof(float), 12); for(int j = 0; j < 3; j++){ SPoint3 p(xyz[3 + 3 * j], xyz[3 + 3 * j + 1], xyz[3 + 3 * j + 2]); points.back().push_back(p); bbox += p; } } } delete [] data; } } } std::vector<GFace*> faces; for(unsigned int i = 0; i < points.size(); i++){ if(points[i].empty()){ Msg::Error("No facets found in STL file for solid %d", i); fclose(fp); return 0; } if(points[i].size() % 3){ Msg::Error("Wrong number of points (%d) in STL file for solid %d", points[i].size(), i); fclose(fp); return 0; } Msg::Info("%d facets in solid %d", points[i].size() / 3, i); // create face GFace *face = new discreteFace(this, getMaxElementaryNumber(2) + 1); faces.push_back(face); add(face); } // create triangles using unique vertices double eps = norm(SVector3(bbox.max(), bbox.min())) * tolerance; std::vector<MVertex*> vertices; for(unsigned int i = 0; i < points.size(); i++) for(unsigned int j = 0; j < points[i].size(); j++) vertices.push_back(new MVertex(points[i][j].x(), points[i][j].y(), points[i][j].z())); MVertexPositionSet pos(vertices); std::set<MFace,Less_Face> unique; int nbDuplic = 0; for(unsigned int i = 0; i < points.size(); i ++){ for(unsigned int j = 0; j < points[i].size(); j += 3){ MVertex *v[3]; for(int k = 0; k < 3; k++){ double x = points[i][j + k].x(); double y = points[i][j + k].y(); double z = points[i][j + k].z(); v[k] = pos.find(x, y, z, eps); } MFace mf (v[0], v[1], v[2]); if (unique.find(mf) == unique.end()){ faces[i]->triangles.push_back(new MTriangle(v[0], v[1], v[2])); unique.insert(mf); } else{ nbDuplic++; } } } if (nbDuplic) Msg::Warning("%d duplicate triangles in STL file", nbDuplic); _associateEntityWithMeshVertices(); _storeVerticesInEntities(vertices); // will delete unused vertices fclose(fp); return 1; }