int main(int argc, char **argv) { GmshInitialize(argc, argv); GmshSetOption("Mesh", "Algorithm", 5.); GmshSetOption("General", "Terminal", 1.); GModel *m = new GModel(); m->readMSH("bunny.msh"); m->fillVertexArrays(); std::vector<GEntity*> entities; m->getEntities(entities); for(unsigned int i = 0; i < entities.size(); i++){ GEntity *ge = entities[i]; printf("coucou entite %d (dimension %d)\n", ge->tag(), ge->dim()); if(ge->va_triangles) printf(" j'ai un va de triangles: %d vertex\n", ge->va_triangles->getNumVertices()); if(ge->va_lines) printf(" j'ai un va de lignes: %d vertex\n", ge->va_lines->getNumVertices()); } delete m; GmshFinalize(); }
void GMSH_SimplePartitionPlugin::run() { #if defined(HAVE_MESH) int numSlicesX = (int)SimplePartitionOptions_Number[0].def; int numSlicesY = (int)SimplePartitionOptions_Number[1].def; int numSlicesZ = (int)SimplePartitionOptions_Number[2].def; int createTopology = (int)SimplePartitionOptions_Number[3].def; std::vector<std::string> exprX(1), exprY(1), exprZ(1); exprX[0] = SimplePartitionOptions_String[0].def; exprY[0] = SimplePartitionOptions_String[1].def; exprZ[0] = SimplePartitionOptions_String[2].def; GModel *m = GModel::current(); if(!m->getNumMeshElements()){ Msg::Error("Plugin(SimplePartition) requires a mesh"); return; } if(numSlicesX < 1 || numSlicesY < 1 || numSlicesZ < 1){ Msg::Error("Number of slices should be strictly positive"); return; } m->unpartitionMesh(); SBoundingBox3d bbox = m->bounds(); double pminX = bbox.min()[0], pmaxX = bbox.max()[0]; double pminY = bbox.min()[1], pmaxY = bbox.max()[1]; double pminZ = bbox.min()[2], pmaxZ = bbox.max()[2]; std::vector<double> ppX(numSlicesX + 1); std::vector<double> ppY(numSlicesY + 1); std::vector<double> ppZ(numSlicesZ + 1); std::vector<std::string> variables(1, "t"); std::vector<double> values(1), res(1); { mathEvaluator f(exprX, variables); for(int p = 0; p <= numSlicesX; p++) { double t = values[0] = (double)p / (double)numSlicesX; if(f.eval(values, res)) t = res[0]; ppX[p] = pminX + t * (pmaxX - pminX); } } bool emptyX = (ppX[0] == ppX[numSlicesX]); { mathEvaluator f(exprY, variables); for(int p = 0; p <= numSlicesY; p++) { double t = values[0] = (double)p / (double)numSlicesY; if(f.eval(values, res)) t = res[0]; ppY[p] = pminY + t * (pmaxY - pminY); } } bool emptyY = (ppY[0] == ppY[numSlicesY]); { mathEvaluator f(exprZ, variables); for(int p = 0; p <= numSlicesZ; p++) { double t = values[0] = (double)p / (double)numSlicesZ; if(f.eval(values, res)) t = res[0]; ppZ[p] = pminZ + t * (pmaxZ - pminZ); } } bool emptyZ = (ppZ[0] == ppZ[numSlicesZ]); std::vector<GEntity *> entities; m->getEntities(entities); hashmap<MElement *, unsigned int> elmToPartition; for(std::size_t i = 0; i < entities.size(); i++) { GEntity *ge = entities[i]; for(std::size_t j = 0; j < ge->getNumMeshElements(); j++) { MElement *e = ge->getMeshElement(j); SPoint3 point = e->barycenter(); int part = 0; for(int kx = 0; kx < numSlicesX; kx++) { if(part) break; for(int ky = 0; ky < numSlicesY; ky++) { if(part) break; for(int kz = 0; kz < numSlicesZ; kz++) { if(part) break; if((emptyX || (kx == 0 && ppX[0] == point[0]) || (ppX[kx] < point[0] && point[0] <= ppX[kx + 1])) && (emptyY || (ky == 0 && ppY[0] == point[1]) || (ppY[ky] < point[1] && point[1] <= ppY[ky + 1])) && (emptyZ || (kz == 0 && ppZ[0] == point[2]) || (ppZ[kz] < point[2] && point[2] <= ppZ[kz + 1]))){ part = kx * numSlicesY * numSlicesZ + ky * numSlicesZ + kz + 1; elmToPartition.insert(std::pair<MElement *, unsigned int>(e, part)); e->setPartition(part); // this will be removed } } } } } } opt_mesh_partition_create_topology(0, GMSH_SET | GMSH_GUI, createTopology); int ier = PartitionUsingThisSplit(m, numSlicesX * numSlicesY * numSlicesZ, elmToPartition); if(!ier) { opt_mesh_color_carousel(0, GMSH_SET | GMSH_GUI, 3.); CTX::instance()->mesh.changed = ENT_ALL; } #else Msg::Error("Gmsh must be compiled with Mesh support to partition meshes"); #endif }
MarkeredSurface MarkeredSurfaceGeoGenerator::generate(string fileName, real size) { Engine& engine = Engine::getInstance(); LOG_INFO("Generating markered surface from Geo file " << fileName); GmshSetOption("General", "Terminal", 1.0); GmshSetOption("General", "Verbosity", engine.getGmshVerbosity()); GmshSetOption("General", "ExpertMode", 1.0); GModel gmshModel; gmshModel.setFactory("Gmsh"); gmshModel.readGEO(fileName); float clmin, clmax; if (size > 0) { clmin = size*0.8; clmax = size*1.2; } else { auto _min = gmshModel.bounds().min(); auto _max = gmshModel.bounds().max(); auto d1 = _max.x() - _min.x(); auto d2 = _max.y() - _min.y(); auto d3 = _max.z() - _min.z(); if ((d1/d2 >= 0.8) && (d1/d2 <= 1.2) && (d1/d3 >= 0.8) && (d1/d3 <= 1.2)) { auto d = gmshModel.bounds().diag(); clmin = d/80; clmax = d/60; } else { auto d = min({d1, d2, d3}); clmin = d/10; clmax = d/5; } } GmshSetOption("Mesh", "CharacteristicLengthMin", clmin); GmshSetOption("Mesh", "CharacteristicLengthMax", clmax); gmshModel.mesh(2); vector<GEntity*> entities; gmshModel.getEntities(entities); auto nverts = gmshModel.getNumMeshVertices(); vector<CalcNode> markers; vector<TriangleFirstOrder> faces; vector<int> regions; int *newVertNums = new int[nverts+1]; for (int i = 0; i <= nverts; i++) newVertNums[i] = -1; MVertex* verts[3]; int nf = 0; int nv = 0; for (auto e: entities) { if (e->geomType() == GEntity::RuledSurface || e->geomType() == GEntity::Plane) { regions.push_back(e->getNumMeshElements()); for (unsigned int i = 0; i < e->getNumMeshElements(); i++) { auto elem = e->getMeshElement(i); assert_eq(elem->getNumFaces(), 1); auto face = elem->getFace(0); for (int j = 0; j < 3; j++) verts[j] = face.getVertex(j); int v[3]; for (int j = 0; j < 3; j++) { if (newVertNums[verts[j]->getNum()] == -1) { newVertNums[verts[j]->getNum()] = nv; markers.push_back(CalcNode(nv, vector3r(verts[j]->x(), verts[j]->y(), verts[j]->z()))); nv++; } v[j] = newVertNums[verts[j]->getNum()]; } faces.push_back(TriangleFirstOrder(nf++, v)); } } } assert_gt(markers.size(), 0); assert_gt(faces.size(), 0); delete[] newVertNums; return MarkeredSurface(markers, faces, regions); }